root/drivers/scsi/3w-xxxx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tw_check_bits
  2. tw_decode_bits
  3. tw_poll_status
  4. tw_poll_status_gone
  5. tw_post_command_packet
  6. tw_decode_sense
  7. tw_check_errors
  8. tw_empty_response_que
  9. tw_state_request_finish
  10. tw_state_request_start
  11. tw_show_stats
  12. tw_aen_read_queue
  13. tw_aen_complete
  14. tw_aen_drain_queue
  15. tw_allocate_memory
  16. tw_chrdev_ioctl
  17. tw_chrdev_open
  18. tw_free_device_extension
  19. tw_initconnection
  20. tw_setfeature
  21. tw_reset_sequence
  22. tw_initialize_device_extension
  23. tw_reset_device_extension
  24. tw_scsi_biosparam
  25. tw_scsi_eh_reset
  26. tw_scsiop_inquiry
  27. tw_transfer_internal
  28. tw_scsiop_inquiry_complete
  29. tw_scsiop_mode_sense
  30. tw_scsiop_mode_sense_complete
  31. tw_scsiop_read_capacity
  32. tw_scsiop_read_capacity_complete
  33. tw_scsiop_read_write
  34. tw_scsiop_request_sense
  35. tw_scsiop_synchronize_cache
  36. tw_scsiop_test_unit_ready
  37. tw_scsiop_test_unit_ready_complete
  38. tw_scsi_queue_lck
  39. DEF_SCSI_QCMD
  40. __tw_shutdown
  41. tw_shutdown
  42. tw_slave_configure
  43. tw_probe
  44. tw_remove
  45. tw_init
  46. tw_exit

   1 /* 
   2    3w-xxxx.c -- 3ware Storage Controller device driver for Linux.
   3 
   4    Written By: Adam Radford <aradford@gmail.com>
   5    Modifications By: Joel Jacobson <linux@3ware.com>
   6                      Arnaldo Carvalho de Melo <acme@conectiva.com.br>
   7                      Brad Strand <linux@3ware.com>
   8 
   9    Copyright (C) 1999-2010 3ware Inc.
  10 
  11    Kernel compatibility By:     Andre Hedrick <andre@suse.com>
  12    Non-Copyright (C) 2000       Andre Hedrick <andre@suse.com>
  13    
  14    Further tiny build fixes and trivial hoovering    Alan Cox
  15 
  16    This program is free software; you can redistribute it and/or modify
  17    it under the terms of the GNU General Public License as published by
  18    the Free Software Foundation; version 2 of the License.
  19 
  20    This program is distributed in the hope that it will be useful,           
  21    but WITHOUT ANY WARRANTY; without even the implied warranty of            
  22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             
  23    GNU General Public License for more details.                              
  24 
  25    NO WARRANTY                                                               
  26    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR        
  27    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT      
  28    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,      
  29    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is    
  30    solely responsible for determining the appropriateness of using and       
  31    distributing the Program and assumes all risks associated with its        
  32    exercise of rights under this Agreement, including but not limited to     
  33    the risks and costs of program errors, damage to or loss of data,         
  34    programs or equipment, and unavailability or interruption of operations.  
  35 
  36    DISCLAIMER OF LIABILITY                                                   
  37    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY   
  38    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL        
  39    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND   
  40    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR     
  41    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE    
  42    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED  
  43    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES             
  44 
  45    You should have received a copy of the GNU General Public License         
  46    along with this program; if not, write to the Free Software               
  47    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  48 
  49    Bugs/Comments/Suggestions should be mailed to:                            
  50 
  51    aradford@gmail.com
  52 
  53 
  54    History
  55    -------
  56    0.1.000 -     Initial release.
  57    0.4.000 -     Added support for Asynchronous Event Notification through
  58                  ioctls for 3DM.
  59    1.0.000 -     Added DPO & FUA bit support for WRITE_10 & WRITE_6 cdb
  60                  to disable drive write-cache before writes.
  61    1.1.000 -     Fixed performance bug with DPO & FUA not existing for WRITE_6.
  62    1.2.000 -     Added support for clean shutdown notification/feature table.
  63    1.02.00.001 - Added support for full command packet posts through ioctls
  64                  for 3DM.
  65                  Bug fix so hot spare drives don't show up.
  66    1.02.00.002 - Fix bug with tw_setfeature() call that caused oops on some
  67                  systems.
  68    08/21/00    - release previously allocated resources on failure at
  69                  tw_allocate_memory (acme)
  70    1.02.00.003 - Fix tw_interrupt() to report error to scsi layer when
  71                  controller status is non-zero.
  72                  Added handling of request_sense opcode.
  73                  Fix possible null pointer dereference in 
  74                  tw_reset_device_extension()
  75    1.02.00.004 - Add support for device id of 3ware 7000 series controllers.
  76                  Make tw_setfeature() call with interrupts disabled.
  77                  Register interrupt handler before enabling interrupts.
  78                  Clear attention interrupt before draining aen queue.
  79    1.02.00.005 - Allocate bounce buffers and custom queue depth for raid5 for
  80                  6000 and 5000 series controllers.
  81                  Reduce polling mdelays causing problems on some systems.
  82                  Fix use_sg = 1 calculation bug.
  83                  Check for scsi_register returning NULL.
  84                  Add aen count to /proc/scsi/3w-xxxx.
  85                  Remove aen code unit masking in tw_aen_complete().
  86    1.02.00.006 - Remove unit from printk in tw_scsi_eh_abort(), causing
  87                  possible oops.
  88                  Fix possible null pointer dereference in tw_scsi_queue()
  89                  if done function pointer was invalid.
  90    1.02.00.007 - Fix possible null pointer dereferences in tw_ioctl().
  91                  Remove check for invalid done function pointer from
  92                  tw_scsi_queue().
  93    1.02.00.008 - Set max sectors per io to TW_MAX_SECTORS in tw_findcards().
  94                  Add tw_decode_error() for printing readable error messages.
  95                  Print some useful information on certain aen codes.
  96                  Add tw_decode_bits() for interpreting status register output.
  97                  Make scsi_set_pci_device() for kernels >= 2.4.4
  98                  Fix bug where aen's could be lost before a reset.
  99                  Re-add spinlocks in tw_scsi_detect().
 100                  Fix possible null pointer dereference in tw_aen_drain_queue()
 101                  during initialization.
 102                  Clear pci parity errors during initialization and during io.
 103    1.02.00.009 - Remove redundant increment in tw_state_request_start().
 104                  Add ioctl support for direct ATA command passthru.
 105                  Add entire aen code string list.
 106    1.02.00.010 - Cleanup queueing code, fix jbod thoughput.
 107                  Fix get_param for specific units.
 108    1.02.00.011 - Fix bug in tw_aen_complete() where aen's could be lost.
 109                  Fix tw_aen_drain_queue() to display useful info at init.
 110                  Set tw_host->max_id for 12 port cards.
 111                  Add ioctl support for raw command packet post from userspace
 112                  with sglist fragments (parameter and io).
 113    1.02.00.012 - Fix read capacity to under report by 1 sector to fix get
 114                  last sector ioctl.
 115    1.02.00.013 - Fix bug where more AEN codes weren't coming out during
 116                  driver initialization.
 117                  Improved handling of PCI aborts.
 118    1.02.00.014 - Fix bug in tw_findcards() where AEN code could be lost.
 119                  Increase timeout in tw_aen_drain_queue() to 30 seconds.
 120    1.02.00.015 - Re-write raw command post with data ioctl method.
 121                  Remove raid5 bounce buffers for raid5 for 6XXX for kernel 2.5
 122                  Add tw_map/unmap_scsi_sg/single_data() for kernel 2.5
 123                  Replace io_request_lock with host_lock for kernel 2.5
 124                  Set max_cmd_len to 16 for 3dm for kernel 2.5
 125    1.02.00.016 - Set host->max_sectors back up to 256.
 126    1.02.00.017 - Modified pci parity error handling/clearing from config space
 127                  during initialization.
 128    1.02.00.018 - Better handling of request sense opcode and sense information
 129                  for failed commands.  Add tw_decode_sense().
 130                  Replace all mdelay()'s with scsi_sleep().
 131    1.02.00.019 - Revert mdelay's and scsi_sleep's, this caused problems on
 132                  some SMP systems.
 133    1.02.00.020 - Add pci_set_dma_mask(), rewrite kmalloc()/virt_to_bus() to
 134                  pci_alloc/free_consistent().
 135                  Better alignment checking in tw_allocate_memory().
 136                  Cleanup tw_initialize_device_extension().
 137    1.02.00.021 - Bump cmd_per_lun in SHT to 255 for better jbod performance.
 138                  Improve handling of errors in tw_interrupt().
 139                  Add handling/clearing of controller queue error.
 140                  Empty stale responses before draining aen queue.
 141                  Fix tw_scsi_eh_abort() to not reset on every io abort.
 142                  Set can_queue in SHT to 255 to prevent hang from AEN.
 143    1.02.00.022 - Fix possible null pointer dereference in tw_scsi_release().
 144    1.02.00.023 - Fix bug in tw_aen_drain_queue() where unit # was always zero.
 145    1.02.00.024 - Add severity levels to AEN strings.
 146    1.02.00.025 - Fix command interrupt spurious error messages.
 147                  Fix bug in raw command post with data ioctl method.
 148                  Fix bug where rollcall sometimes failed with cable errors.
 149                  Print unit # on all command timeouts.
 150    1.02.00.026 - Fix possible infinite retry bug with power glitch induced
 151                  drive timeouts.
 152                  Cleanup some AEN severity levels.
 153    1.02.00.027 - Add drive not supported AEN code for SATA controllers.
 154                  Remove spurious unknown ioctl error message.
 155    1.02.00.028 - Fix bug where multiple controllers with no units were the
 156                  same card number.
 157                  Fix bug where cards were being shut down more than once.
 158    1.02.00.029 - Add missing pci_free_consistent() in tw_allocate_memory().
 159                  Replace pci_map_single() with pci_map_page() for highmem.
 160                  Check for tw_setfeature() failure.
 161    1.02.00.030 - Make driver 64-bit clean.
 162    1.02.00.031 - Cleanup polling timeouts/routines in several places.
 163                  Add support for mode sense opcode.
 164                  Add support for cache mode page.
 165                  Add support for synchronize cache opcode.
 166    1.02.00.032 - Fix small multicard rollcall bug.
 167                  Make driver stay loaded with no units for hot add/swap.
 168                  Add support for "twe" character device for ioctls.
 169                  Clean up request_id queueing code.
 170                  Fix tw_scsi_queue() spinlocks.
 171    1.02.00.033 - Fix tw_aen_complete() to not queue 'queue empty' AEN's.
 172                  Initialize queues correctly when loading with no valid units.
 173    1.02.00.034 - Fix tw_decode_bits() to handle multiple errors.
 174                  Add support for user configurable cmd_per_lun.
 175                  Add support for sht->slave_configure().
 176    1.02.00.035 - Improve tw_allocate_memory() memory allocation.
 177                  Fix tw_chrdev_ioctl() to sleep correctly.
 178    1.02.00.036 - Increase character ioctl timeout to 60 seconds.
 179    1.02.00.037 - Fix tw_ioctl() to handle all non-data ATA passthru cmds
 180                  for 'smartmontools' support.
 181    1.26.00.038 - Roll driver minor version to 26 to denote kernel 2.6.
 182                  Add support for cmds_per_lun module parameter.
 183    1.26.00.039 - Fix bug in tw_chrdev_ioctl() polling code.
 184                  Fix data_buffer_length usage in tw_chrdev_ioctl().
 185                  Update contact information.
 186    1.26.02.000 - Convert driver to pci_driver format.
 187    1.26.02.001 - Increase max ioctl buffer size to 512 sectors.
 188                  Make tw_scsi_queue() return 0 for 'Unknown scsi opcode'.
 189                  Fix tw_remove() to free irq handler/unregister_chrdev()
 190                  before shutting down card.
 191                  Change to new 'change_queue_depth' api.
 192                  Fix 'handled=1' ISR usage, remove bogus IRQ check.
 193    1.26.02.002 - Free irq handler in __tw_shutdown().
 194                  Turn on RCD bit for caching mode page.
 195                  Serialize reset code.
 196    1.26.02.003 - Force 60 second timeout default.
 197 */
 198 
 199 #include <linux/module.h>
 200 #include <linux/reboot.h>
 201 #include <linux/spinlock.h>
 202 #include <linux/interrupt.h>
 203 #include <linux/moduleparam.h>
 204 #include <linux/errno.h>
 205 #include <linux/types.h>
 206 #include <linux/delay.h>
 207 #include <linux/gfp.h>
 208 #include <linux/pci.h>
 209 #include <linux/time.h>
 210 #include <linux/mutex.h>
 211 #include <asm/io.h>
 212 #include <asm/irq.h>
 213 #include <linux/uaccess.h>
 214 #include <scsi/scsi.h>
 215 #include <scsi/scsi_host.h>
 216 #include <scsi/scsi_tcq.h>
 217 #include <scsi/scsi_cmnd.h>
 218 #include <scsi/scsi_eh.h>
 219 #include "3w-xxxx.h"
 220 
 221 /* Globals */
 222 #define TW_DRIVER_VERSION "1.26.02.003"
 223 static DEFINE_MUTEX(tw_mutex);
 224 static TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 225 static int tw_device_extension_count = 0;
 226 static int twe_major = -1;
 227 
 228 /* Module parameters */
 229 MODULE_AUTHOR("LSI");
 230 MODULE_DESCRIPTION("3ware Storage Controller Linux Driver");
 231 MODULE_LICENSE("GPL");
 232 MODULE_VERSION(TW_DRIVER_VERSION);
 233 
 234 /* Function prototypes */
 235 static int tw_reset_device_extension(TW_Device_Extension *tw_dev);
 236 
 237 /* Functions */
 238 
 239 /* This function will check the status register for unexpected bits */
 240 static int tw_check_bits(u32 status_reg_value)
 241 {
 242         if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) {  
 243                 dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value);
 244                 return 1;
 245         }
 246         if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0) {
 247                 dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): Found unexpected bits (0x%x).\n", status_reg_value);
 248                 return 1;
 249         }
 250 
 251         return 0;
 252 } /* End tw_check_bits() */
 253 
 254 /* This function will print readable messages from status register errors */
 255 static int tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value, int print_host)
 256 {
 257         char host[16];
 258 
 259         dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
 260 
 261         if (print_host)
 262                 sprintf(host, " scsi%d:", tw_dev->host->host_no);
 263         else
 264                 host[0] = '\0';
 265 
 266         if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) {
 267                 printk(KERN_WARNING "3w-xxxx:%s PCI Parity Error: clearing.\n", host);
 268                 outl(TW_CONTROL_CLEAR_PARITY_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
 269         }
 270 
 271         if (status_reg_value & TW_STATUS_PCI_ABORT) {
 272                 printk(KERN_WARNING "3w-xxxx:%s PCI Abort: clearing.\n", host);
 273                 outl(TW_CONTROL_CLEAR_PCI_ABORT, TW_CONTROL_REG_ADDR(tw_dev));
 274                 pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
 275         }
 276 
 277         if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
 278                 printk(KERN_WARNING "3w-xxxx:%s Controller Queue Error: clearing.\n", host);
 279                 outl(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
 280         }
 281 
 282         if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) {
 283                 printk(KERN_WARNING "3w-xxxx:%s SBUF Write Error: clearing.\n", host);
 284                 outl(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
 285         }
 286 
 287         if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
 288                 if (tw_dev->reset_print == 0) {
 289                         printk(KERN_WARNING "3w-xxxx:%s Microcontroller Error: clearing.\n", host);
 290                         tw_dev->reset_print = 1;
 291                 }
 292                 return 1;
 293         }
 294         
 295         return 0;
 296 } /* End tw_decode_bits() */
 297 
 298 /* This function will poll the status register for a flag */
 299 static int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
 300 {
 301         u32 status_reg_value;
 302         unsigned long before;
 303         int retval = 1;
 304 
 305         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
 306         before = jiffies;
 307 
 308         if (tw_check_bits(status_reg_value))
 309                 tw_decode_bits(tw_dev, status_reg_value, 0);
 310 
 311         while ((status_reg_value & flag) != flag) {
 312                 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
 313 
 314                 if (tw_check_bits(status_reg_value))
 315                         tw_decode_bits(tw_dev, status_reg_value, 0);
 316 
 317                 if (time_after(jiffies, before + HZ * seconds))
 318                         goto out;
 319 
 320                 msleep(50);
 321         }
 322         retval = 0;
 323 out:
 324         return retval;
 325 } /* End tw_poll_status() */
 326 
 327 /* This function will poll the status register for disappearance of a flag */
 328 static int tw_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
 329 {
 330         u32 status_reg_value;
 331         unsigned long before;
 332         int retval = 1;
 333 
 334         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
 335         before = jiffies;
 336 
 337         if (tw_check_bits(status_reg_value))
 338                 tw_decode_bits(tw_dev, status_reg_value, 0);
 339 
 340         while ((status_reg_value & flag) != 0) {
 341                 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
 342 
 343                 if (tw_check_bits(status_reg_value))
 344                         tw_decode_bits(tw_dev, status_reg_value, 0);
 345 
 346                 if (time_after(jiffies, before + HZ * seconds))
 347                         goto out;
 348 
 349                 msleep(50);
 350         }
 351         retval = 0;
 352 out:
 353         return retval;
 354 } /* End tw_poll_status_gone() */
 355 
 356 /* This function will attempt to post a command packet to the board */
 357 static int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
 358 {
 359         u32 status_reg_value;
 360         unsigned long command_que_value;
 361 
 362         dprintk(KERN_NOTICE "3w-xxxx: tw_post_command_packet()\n");
 363         command_que_value = tw_dev->command_packet_physical_address[request_id];
 364         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
 365 
 366         if (tw_check_bits(status_reg_value)) {
 367                 dprintk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
 368                 tw_decode_bits(tw_dev, status_reg_value, 1);
 369         }
 370 
 371         if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
 372                 /* We successfully posted the command packet */
 373                 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
 374                 tw_dev->state[request_id] = TW_S_POSTED;
 375                 tw_dev->posted_request_count++;
 376                 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
 377                         tw_dev->max_posted_request_count = tw_dev->posted_request_count;
 378                 }
 379         } else {
 380                 /* Couldn't post the command packet, so we do it in the isr */
 381                 if (tw_dev->state[request_id] != TW_S_PENDING) {
 382                         tw_dev->state[request_id] = TW_S_PENDING;
 383                         tw_dev->pending_request_count++;
 384                         if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
 385                                 tw_dev->max_pending_request_count = tw_dev->pending_request_count;
 386                         }
 387                         tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
 388                         if (tw_dev->pending_tail == TW_Q_LENGTH-1) {
 389                                 tw_dev->pending_tail = TW_Q_START;
 390                         } else {
 391                                 tw_dev->pending_tail = tw_dev->pending_tail + 1;
 392                         }
 393                 } 
 394                 TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
 395                 return 1;
 396         }
 397         return 0;
 398 } /* End tw_post_command_packet() */
 399 
 400 /* This function will return valid sense buffer information for failed cmds */
 401 static int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill_sense)
 402 {
 403         int i;
 404         TW_Command *command;
 405 
 406         dprintk(KERN_WARNING "3w-xxxx: tw_decode_sense()\n");
 407         command = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
 408 
 409         printk(KERN_WARNING "3w-xxxx: scsi%d: Command failed: status = 0x%x, flags = 0x%x, unit #%d.\n", tw_dev->host->host_no, command->status, command->flags, TW_UNIT_OUT(command->unit__hostid));
 410 
 411         /* Attempt to return intelligent sense information */
 412         if (fill_sense) {
 413                 if ((command->status == 0xc7) || (command->status == 0xcb)) {
 414                         for (i = 0; i < ARRAY_SIZE(tw_sense_table); i++) {
 415                                 if (command->flags == tw_sense_table[i][0]) {
 416 
 417                                         /* Valid bit and 'current errors' */
 418                                         tw_dev->srb[request_id]->sense_buffer[0] = (0x1 << 7 | 0x70);
 419 
 420                                         /* Sense key */
 421                                         tw_dev->srb[request_id]->sense_buffer[2] = tw_sense_table[i][1];
 422 
 423                                         /* Additional sense length */
 424                                         tw_dev->srb[request_id]->sense_buffer[7] = 0xa; /* 10 bytes */
 425 
 426                                         /* Additional sense code */
 427                                         tw_dev->srb[request_id]->sense_buffer[12] = tw_sense_table[i][2];
 428 
 429                                         /* Additional sense code qualifier */
 430                                         tw_dev->srb[request_id]->sense_buffer[13] = tw_sense_table[i][3];
 431 
 432                                         tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
 433                                         return TW_ISR_DONT_RESULT; /* Special case for isr to not over-write result */
 434                                 }
 435                         }
 436                 }
 437 
 438                 /* If no table match, error so we get a reset */
 439                 return 1;
 440         }
 441 
 442         return 0;
 443 } /* End tw_decode_sense() */
 444 
 445 /* This function will report controller error status */
 446 static int tw_check_errors(TW_Device_Extension *tw_dev) 
 447 {
 448         u32 status_reg_value;
 449   
 450         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
 451 
 452         if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value)) {
 453                 tw_decode_bits(tw_dev, status_reg_value, 0);
 454                 return 1;
 455         }
 456 
 457         return 0;
 458 } /* End tw_check_errors() */
 459 
 460 /* This function will empty the response que */
 461 static void tw_empty_response_que(TW_Device_Extension *tw_dev) 
 462 {
 463         u32 status_reg_value, response_que_value;
 464 
 465         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
 466 
 467         while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
 468                 response_que_value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
 469                 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
 470         }
 471 } /* End tw_empty_response_que() */
 472 
 473 /* This function will free a request_id */
 474 static void tw_state_request_finish(TW_Device_Extension *tw_dev, int request_id)
 475 {
 476         tw_dev->free_queue[tw_dev->free_tail] = request_id;
 477         tw_dev->state[request_id] = TW_S_FINISHED;
 478         tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
 479 } /* End tw_state_request_finish() */
 480 
 481 /* This function will assign an available request_id */
 482 static void tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id)
 483 {
 484         *request_id = tw_dev->free_queue[tw_dev->free_head];
 485         tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
 486         tw_dev->state[*request_id] = TW_S_STARTED;
 487 } /* End tw_state_request_start() */
 488 
 489 /* Show some statistics about the card */
 490 static ssize_t tw_show_stats(struct device *dev, struct device_attribute *attr,
 491                              char *buf)
 492 {
 493         struct Scsi_Host *host = class_to_shost(dev);
 494         TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
 495         unsigned long flags = 0;
 496         ssize_t len;
 497 
 498         spin_lock_irqsave(tw_dev->host->host_lock, flags);
 499         len = snprintf(buf, PAGE_SIZE, "3w-xxxx Driver version: %s\n"
 500                        "Current commands posted:   %4d\n"
 501                        "Max commands posted:       %4d\n"
 502                        "Current pending commands:  %4d\n"
 503                        "Max pending commands:      %4d\n"
 504                        "Last sgl length:           %4d\n"
 505                        "Max sgl length:            %4d\n"
 506                        "Last sector count:         %4d\n"
 507                        "Max sector count:          %4d\n"
 508                        "SCSI Host Resets:          %4d\n"
 509                        "AEN's:                     %4d\n", 
 510                        TW_DRIVER_VERSION,
 511                        tw_dev->posted_request_count,
 512                        tw_dev->max_posted_request_count,
 513                        tw_dev->pending_request_count,
 514                        tw_dev->max_pending_request_count,
 515                        tw_dev->sgl_entries,
 516                        tw_dev->max_sgl_entries,
 517                        tw_dev->sector_count,
 518                        tw_dev->max_sector_count,
 519                        tw_dev->num_resets,
 520                        tw_dev->aen_count);
 521         spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
 522         return len;
 523 } /* End tw_show_stats() */
 524 
 525 /* Create sysfs 'stats' entry */
 526 static struct device_attribute tw_host_stats_attr = {
 527         .attr = {
 528                 .name =         "stats",
 529                 .mode =         S_IRUGO,
 530         },
 531         .show = tw_show_stats
 532 };
 533 
 534 /* Host attributes initializer */
 535 static struct device_attribute *tw_host_attrs[] = {
 536         &tw_host_stats_attr,
 537         NULL,
 538 };
 539 
 540 /* This function will read the aen queue from the isr */
 541 static int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id) 
 542 {
 543         TW_Command *command_packet;
 544         TW_Param *param;
 545         unsigned long command_que_value;
 546         u32 status_reg_value;
 547         unsigned long param_value = 0;
 548 
 549         dprintk(KERN_NOTICE "3w-xxxx: tw_aen_read_queue()\n");
 550 
 551         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
 552         if (tw_check_bits(status_reg_value)) {
 553                 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
 554                 tw_decode_bits(tw_dev, status_reg_value, 1);
 555                 return 1;
 556         }
 557         if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
 558                 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet virtual address.\n");
 559                 return 1;
 560         }
 561         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
 562         memset(command_packet, 0, sizeof(TW_Sector));
 563         command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
 564         command_packet->size = 4;
 565         command_packet->request_id = request_id;
 566         command_packet->status = 0;
 567         command_packet->flags = 0;
 568         command_packet->byte6.parameter_count = 1;
 569         command_que_value = tw_dev->command_packet_physical_address[request_id];
 570         if (command_que_value == 0) {
 571                 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet physical address.\n");
 572                 return 1;
 573         }
 574         /* Now setup the param */
 575         if (tw_dev->alignment_virtual_address[request_id] == NULL) {
 576                 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment virtual address.\n");
 577                 return 1;
 578         }
 579         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
 580         memset(param, 0, sizeof(TW_Sector));
 581         param->table_id = 0x401; /* AEN table */
 582         param->parameter_id = 2; /* Unit code */
 583         param->parameter_size_bytes = 2;
 584         param_value = tw_dev->alignment_physical_address[request_id];
 585         if (param_value == 0) {
 586                 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment physical address.\n");
 587                 return 1;
 588         }
 589         command_packet->byte8.param.sgl[0].address = param_value;
 590         command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
 591 
 592         /* Now post the command packet */
 593         if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
 594                 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post succeeded.\n");
 595                 tw_dev->srb[request_id] = NULL; /* Flag internal command */
 596                 tw_dev->state[request_id] = TW_S_POSTED;
 597                 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
 598         } else {
 599                 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post failed, will retry.\n");
 600                 return 1;
 601         }
 602 
 603         return 0;
 604 } /* End tw_aen_read_queue() */
 605 
 606 /* This function will complete an aen request from the isr */
 607 static int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id) 
 608 {
 609         TW_Param *param;
 610         unsigned short aen;
 611         int error = 0, table_max = 0;
 612 
 613         dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
 614         if (tw_dev->alignment_virtual_address[request_id] == NULL) {
 615                 printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
 616                 return 1;
 617         }
 618         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
 619         aen = *(unsigned short *)(param->data);
 620         dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
 621 
 622         /* Print some useful info when certain aen codes come out */
 623         if (aen == 0x0ff) {
 624                 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: INFO: AEN queue overflow.\n", tw_dev->host->host_no);
 625         } else {
 626                 table_max = ARRAY_SIZE(tw_aen_string);
 627                 if ((aen & 0x0ff) < table_max) {
 628                         if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
 629                                 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8);
 630                         } else {
 631                                 if (aen != 0x0) 
 632                                         printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff]);
 633                         }
 634                 } else {
 635                         printk(KERN_WARNING "3w-xxxx: scsi%d: Received AEN %d.\n", tw_dev->host->host_no, aen);
 636                 }
 637         }
 638         if (aen != TW_AEN_QUEUE_EMPTY) {
 639                 tw_dev->aen_count++;
 640 
 641                 /* Now queue the code */
 642                 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
 643                 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
 644                         tw_dev->aen_tail = TW_Q_START;
 645                 } else {
 646                         tw_dev->aen_tail = tw_dev->aen_tail + 1;
 647                 }
 648                 if (tw_dev->aen_head == tw_dev->aen_tail) {
 649                         if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
 650                                 tw_dev->aen_head = TW_Q_START;
 651                         } else {
 652                                 tw_dev->aen_head = tw_dev->aen_head + 1;
 653                         }
 654                 }
 655 
 656                 error = tw_aen_read_queue(tw_dev, request_id);
 657                 if (error) {
 658                         printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing AEN.\n", tw_dev->host->host_no);
 659                         tw_dev->state[request_id] = TW_S_COMPLETED;
 660                         tw_state_request_finish(tw_dev, request_id);
 661                 }
 662         } else {
 663                 tw_dev->state[request_id] = TW_S_COMPLETED;
 664                 tw_state_request_finish(tw_dev, request_id);
 665         }
 666 
 667         return 0;
 668 } /* End tw_aen_complete() */
 669 
 670 /* This function will drain the aen queue after a soft reset */
 671 static int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
 672 {
 673         TW_Command *command_packet;
 674         TW_Param *param;
 675         int request_id = 0;
 676         unsigned long command_que_value;
 677         unsigned long param_value;
 678         TW_Response_Queue response_queue;
 679         unsigned short aen;
 680         unsigned short aen_code;
 681         int finished = 0;
 682         int first_reset = 0;
 683         int queue = 0;
 684         int found = 0, table_max = 0;
 685 
 686         dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n");
 687 
 688         if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT | TW_STATUS_MICROCONTROLLER_READY, 30)) {
 689                 dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d.\n", tw_device_extension_count);
 690                 return 1;
 691         }
 692         TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
 693 
 694         /* Empty response queue */
 695         tw_empty_response_que(tw_dev);
 696 
 697         /* Initialize command packet */
 698         if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
 699                 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet virtual address.\n");
 700                 return 1;
 701         }
 702         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
 703         memset(command_packet, 0, sizeof(TW_Sector));
 704         command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
 705         command_packet->size = 4;
 706         command_packet->request_id = request_id;
 707         command_packet->status = 0;
 708         command_packet->flags = 0;
 709         command_packet->byte6.parameter_count = 1;
 710         command_que_value = tw_dev->command_packet_physical_address[request_id];
 711         if (command_que_value == 0) {
 712                 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet physical address.\n");
 713                 return 1;
 714         }
 715 
 716         /* Now setup the param */
 717         if (tw_dev->alignment_virtual_address[request_id] == NULL) {
 718                 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment virtual address.\n");
 719                 return 1;
 720         }
 721         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
 722         memset(param, 0, sizeof(TW_Sector));
 723         param->table_id = 0x401; /* AEN table */
 724         param->parameter_id = 2; /* Unit code */
 725         param->parameter_size_bytes = 2;
 726         param_value = tw_dev->alignment_physical_address[request_id];
 727         if (param_value == 0) {
 728                 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment physical address.\n");
 729                 return 1;
 730         }
 731         command_packet->byte8.param.sgl[0].address = param_value;
 732         command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
 733 
 734         /* Now drain the controller's aen queue */
 735         do {
 736                 /* Post command packet */
 737                 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
 738 
 739                 /* Now poll for completion */
 740                 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
 741                         response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
 742                         request_id = TW_RESID_OUT(response_queue.response_id);
 743 
 744                         if (request_id != 0) {
 745                                 /* Unexpected request id */
 746                                 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected request id.\n");
 747                                 return 1;
 748                         }
 749                         
 750                         if (command_packet->status != 0) {
 751                                 if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
 752                                         /* Bad response */
 753                                         tw_decode_sense(tw_dev, request_id, 0);
 754                                         return 1;
 755                                 } else {
 756                                         /* We know this is a 3w-1x00, and doesn't support aen's */
 757                                         return 0;
 758                                 }
 759                         }
 760 
 761                         /* Now check the aen */
 762                         aen = *(unsigned short *)(param->data);
 763                         aen_code = (aen & 0x0ff);
 764                         queue = 0;
 765                         switch (aen_code) {
 766                                 case TW_AEN_QUEUE_EMPTY:
 767                                         dprintk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
 768                                         if (first_reset != 1) {
 769                                                 return 1;
 770                                         } else {
 771                                                 finished = 1;
 772                                         }
 773                                         break;
 774                                 case TW_AEN_SOFT_RESET:
 775                                         if (first_reset == 0) {
 776                                                 first_reset = 1;
 777                                         } else {
 778                                                 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
 779                                                 tw_dev->aen_count++;
 780                                                 queue = 1;
 781                                         }
 782                                         break;
 783                                 default:
 784                                         if (aen == 0x0ff) {
 785                                                 printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n");
 786                                         } else {
 787                                                 table_max = ARRAY_SIZE(tw_aen_string);
 788                                                 if ((aen & 0x0ff) < table_max) {
 789                                                         if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
 790                                                                 printk(KERN_WARNING "3w-xxxx: AEN: %s%d.\n", tw_aen_string[aen & 0xff], aen >> 8);
 791                                                         } else {
 792                                                                 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
 793                                                         }
 794                                                 } else
 795                                                         printk(KERN_WARNING "3w-xxxx: Received AEN %d.\n", aen);
 796                                         }
 797                                         tw_dev->aen_count++;
 798                                         queue = 1;
 799                         }
 800 
 801                         /* Now put the aen on the aen_queue */
 802                         if (queue == 1) {
 803                                 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
 804                                 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
 805                                         tw_dev->aen_tail = TW_Q_START;
 806                                 } else {
 807                                         tw_dev->aen_tail = tw_dev->aen_tail + 1;
 808                                 }
 809                                 if (tw_dev->aen_head == tw_dev->aen_tail) {
 810                                         if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
 811                                                 tw_dev->aen_head = TW_Q_START;
 812                                         } else {
 813                                                 tw_dev->aen_head = tw_dev->aen_head + 1;
 814                                         }
 815                                 }
 816                         }
 817                         found = 1;
 818                 }
 819                 if (found == 0) {
 820                         printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Response never received.\n");
 821                         return 1;
 822                 }
 823         } while (finished == 0);
 824 
 825         return 0;
 826 } /* End tw_aen_drain_queue() */
 827 
 828 /* This function will allocate memory */
 829 static int tw_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
 830 {
 831         int i;
 832         dma_addr_t dma_handle;
 833         unsigned long *cpu_addr = NULL;
 834 
 835         dprintk(KERN_NOTICE "3w-xxxx: tw_allocate_memory()\n");
 836 
 837         cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev,
 838                         size * TW_Q_LENGTH, &dma_handle, GFP_KERNEL);
 839         if (cpu_addr == NULL) {
 840                 printk(KERN_WARNING "3w-xxxx: dma_alloc_coherent() failed.\n");
 841                 return 1;
 842         }
 843 
 844         if ((unsigned long)cpu_addr % (tw_dev->tw_pci_dev->device == TW_DEVICE_ID ? TW_ALIGNMENT_6000 : TW_ALIGNMENT_7000)) {
 845                 printk(KERN_WARNING "3w-xxxx: Couldn't allocate correctly aligned memory.\n");
 846                 dma_free_coherent(&tw_dev->tw_pci_dev->dev, size * TW_Q_LENGTH,
 847                                 cpu_addr, dma_handle);
 848                 return 1;
 849         }
 850 
 851         memset(cpu_addr, 0, size*TW_Q_LENGTH);
 852 
 853         for (i=0;i<TW_Q_LENGTH;i++) {
 854                 switch(which) {
 855                 case 0:
 856                         tw_dev->command_packet_physical_address[i] = dma_handle+(i*size);
 857                         tw_dev->command_packet_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
 858                         break;
 859                 case 1:
 860                         tw_dev->alignment_physical_address[i] = dma_handle+(i*size);
 861                         tw_dev->alignment_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
 862                         break;
 863                 default:
 864                         printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): case slip in tw_allocate_memory()\n");
 865                         return 1;
 866                 }
 867         }
 868 
 869         return 0;
 870 } /* End tw_allocate_memory() */
 871 
 872 /* This function handles ioctl for the character device */
 873 static long tw_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 874 {
 875         int request_id;
 876         dma_addr_t dma_handle;
 877         unsigned short tw_aen_code;
 878         unsigned long flags;
 879         unsigned int data_buffer_length = 0;
 880         unsigned long data_buffer_length_adjusted = 0;
 881         struct inode *inode = file_inode(file);
 882         unsigned long *cpu_addr;
 883         long timeout;
 884         TW_New_Ioctl *tw_ioctl;
 885         TW_Passthru *passthru;
 886         TW_Device_Extension *tw_dev = tw_device_extension_list[iminor(inode)];
 887         int retval = -EFAULT;
 888         void __user *argp = (void __user *)arg;
 889 
 890         dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n");
 891 
 892         mutex_lock(&tw_mutex);
 893         /* Only let one of these through at a time */
 894         if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
 895                 mutex_unlock(&tw_mutex);
 896                 return -EINTR;
 897         }
 898 
 899         /* First copy down the buffer length */
 900         if (copy_from_user(&data_buffer_length, argp, sizeof(unsigned int)))
 901                 goto out;
 902 
 903         /* Check size */
 904         if (data_buffer_length > TW_MAX_IOCTL_SECTORS * 512) {
 905                 retval = -EINVAL;
 906                 goto out;
 907         }
 908 
 909         /* Hardware can only do multiple of 512 byte transfers */
 910         data_buffer_length_adjusted = (data_buffer_length + 511) & ~511;
 911         
 912         /* Now allocate ioctl buf memory */
 913         cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle, GFP_KERNEL);
 914         if (cpu_addr == NULL) {
 915                 retval = -ENOMEM;
 916                 goto out;
 917         }
 918 
 919         tw_ioctl = (TW_New_Ioctl *)cpu_addr;
 920 
 921         /* Now copy down the entire ioctl */
 922         if (copy_from_user(tw_ioctl, argp, data_buffer_length + sizeof(TW_New_Ioctl) - 1))
 923                 goto out2;
 924 
 925         passthru = (TW_Passthru *)&tw_ioctl->firmware_command;
 926 
 927         /* See which ioctl we are doing */
 928         switch (cmd) {
 929                 case TW_OP_NOP:
 930                         dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_OP_NOP.\n");
 931                         break;
 932                 case TW_OP_AEN_LISTEN:
 933                         dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_AEN_LISTEN.\n");
 934                         memset(tw_ioctl->data_buffer, 0, data_buffer_length);
 935 
 936                         spin_lock_irqsave(tw_dev->host->host_lock, flags);
 937                         if (tw_dev->aen_head == tw_dev->aen_tail) {
 938                                 tw_aen_code = TW_AEN_QUEUE_EMPTY;
 939                         } else {
 940                                 tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
 941                                 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
 942                                         tw_dev->aen_head = TW_Q_START;
 943                                 } else {
 944                                         tw_dev->aen_head = tw_dev->aen_head + 1;
 945                                 }
 946                         }
 947                         spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
 948                         memcpy(tw_ioctl->data_buffer, &tw_aen_code, sizeof(tw_aen_code));
 949                         break;
 950                 case TW_CMD_PACKET_WITH_DATA:
 951                         dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n");
 952                         spin_lock_irqsave(tw_dev->host->host_lock, flags);
 953 
 954                         tw_state_request_start(tw_dev, &request_id);
 955 
 956                         /* Flag internal command */
 957                         tw_dev->srb[request_id] = NULL;
 958 
 959                         /* Flag chrdev ioctl */
 960                         tw_dev->chrdev_request_id = request_id;
 961 
 962                         tw_ioctl->firmware_command.request_id = request_id;
 963 
 964                         /* Load the sg list */
 965                         switch (TW_SGL_OUT(tw_ioctl->firmware_command.opcode__sgloffset)) {
 966                         case 2:
 967                                 tw_ioctl->firmware_command.byte8.param.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
 968                                 tw_ioctl->firmware_command.byte8.param.sgl[0].length = data_buffer_length_adjusted;
 969                                 break;
 970                         case 3:
 971                                 tw_ioctl->firmware_command.byte8.io.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
 972                                 tw_ioctl->firmware_command.byte8.io.sgl[0].length = data_buffer_length_adjusted;
 973                                 break;
 974                         case 5:
 975                                 passthru->sg_list[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
 976                                 passthru->sg_list[0].length = data_buffer_length_adjusted;
 977                                 break;
 978                         }
 979 
 980                         memcpy(tw_dev->command_packet_virtual_address[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command));
 981 
 982                         /* Now post the command packet to the controller */
 983                         tw_post_command_packet(tw_dev, request_id);
 984                         spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
 985 
 986                         timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
 987 
 988                         /* Now wait for the command to complete */
 989                         timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
 990 
 991                         /* We timed out, and didn't get an interrupt */
 992                         if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
 993                                 /* Now we need to reset the board */
 994                                 printk(KERN_WARNING "3w-xxxx: scsi%d: Character ioctl (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, cmd);
 995                                 retval = -EIO;
 996                                 if (tw_reset_device_extension(tw_dev)) {
 997                                         printk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): Reset failed for card %d.\n", tw_dev->host->host_no);
 998                                 }
 999                                 goto out2;
1000                         }
1001 
1002                         /* Now copy in the command packet response */
1003                         memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
1004 
1005                         /* Now complete the io */
1006                         spin_lock_irqsave(tw_dev->host->host_lock, flags);
1007                         tw_dev->posted_request_count--;
1008                         tw_dev->state[request_id] = TW_S_COMPLETED;
1009                         tw_state_request_finish(tw_dev, request_id);
1010                         spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1011                         break;
1012                 default:
1013                         retval = -ENOTTY;
1014                         goto out2;
1015         }
1016 
1017         /* Now copy the response to userspace */
1018         if (copy_to_user(argp, tw_ioctl, sizeof(TW_New_Ioctl) + data_buffer_length - 1))
1019                 goto out2;
1020         retval = 0;
1021 out2:
1022         /* Now free ioctl buf memory */
1023         dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle);
1024 out:
1025         mutex_unlock(&tw_dev->ioctl_lock);
1026         mutex_unlock(&tw_mutex);
1027         return retval;
1028 } /* End tw_chrdev_ioctl() */
1029 
1030 /* This function handles open for the character device */
1031 /* NOTE that this function races with remove. */
1032 static int tw_chrdev_open(struct inode *inode, struct file *file)
1033 {
1034         unsigned int minor_number;
1035 
1036         dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n");
1037 
1038         if (!capable(CAP_SYS_ADMIN))
1039                 return -EACCES;
1040 
1041         minor_number = iminor(inode);
1042         if (minor_number >= tw_device_extension_count)
1043                 return -ENODEV;
1044 
1045         return 0;
1046 } /* End tw_chrdev_open() */
1047 
1048 /* File operations struct for character device */
1049 static const struct file_operations tw_fops = {
1050         .owner          = THIS_MODULE,
1051         .unlocked_ioctl = tw_chrdev_ioctl,
1052 #ifdef CONFIG_COMPAT
1053         .compat_ioctl   = tw_chrdev_ioctl,
1054 #endif
1055         .open           = tw_chrdev_open,
1056         .release        = NULL,
1057         .llseek         = noop_llseek,
1058 };
1059 
1060 /* This function will free up device extension resources */
1061 static void tw_free_device_extension(TW_Device_Extension *tw_dev)
1062 {
1063         dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n");
1064 
1065         /* Free command packet and generic buffer memory */
1066         if (tw_dev->command_packet_virtual_address[0])
1067                 dma_free_coherent(&tw_dev->tw_pci_dev->dev,
1068                                 sizeof(TW_Command) * TW_Q_LENGTH,
1069                                 tw_dev->command_packet_virtual_address[0],
1070                                 tw_dev->command_packet_physical_address[0]);
1071 
1072         if (tw_dev->alignment_virtual_address[0])
1073                 dma_free_coherent(&tw_dev->tw_pci_dev->dev,
1074                                 sizeof(TW_Sector) * TW_Q_LENGTH,
1075                                 tw_dev->alignment_virtual_address[0],
1076                                 tw_dev->alignment_physical_address[0]);
1077 } /* End tw_free_device_extension() */
1078 
1079 /* This function will send an initconnection command to controller */
1080 static int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits) 
1081 {
1082         unsigned long command_que_value;
1083         TW_Command  *command_packet;
1084         TW_Response_Queue response_queue;
1085         int request_id = 0;
1086 
1087         dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n");
1088 
1089         /* Initialize InitConnection command packet */
1090         if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
1091                 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet virtual address.\n");
1092                 return 1;
1093         }
1094 
1095         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1096         memset(command_packet, 0, sizeof(TW_Sector));
1097         command_packet->opcode__sgloffset = TW_OPSGL_IN(0, TW_OP_INIT_CONNECTION);
1098         command_packet->size = TW_INIT_COMMAND_PACKET_SIZE;
1099         command_packet->request_id = request_id;
1100         command_packet->status = 0x0;
1101         command_packet->flags = 0x0;
1102         command_packet->byte6.message_credits = message_credits; 
1103         command_packet->byte8.init_connection.response_queue_pointer = 0x0;
1104         command_que_value = tw_dev->command_packet_physical_address[request_id];
1105 
1106         if (command_que_value == 0) {
1107                 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n");
1108                 return 1;
1109         }
1110   
1111         /* Send command packet to the board */
1112         outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
1113     
1114         /* Poll for completion */
1115         if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1116                 response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1117                 request_id = TW_RESID_OUT(response_queue.response_id);
1118 
1119                 if (request_id != 0) {
1120                         /* unexpected request id */
1121                         printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
1122                         return 1;
1123                 }
1124                 if (command_packet->status != 0) {
1125                         /* bad response */
1126                         tw_decode_sense(tw_dev, request_id, 0);
1127                         return 1;
1128                 }
1129         }
1130         return 0;
1131 } /* End tw_initconnection() */
1132 
1133 /* Set a value in the features table */
1134 static int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
1135                   unsigned char *val)
1136 {
1137         TW_Param *param;
1138         TW_Command  *command_packet;
1139         TW_Response_Queue response_queue;
1140         int request_id = 0;
1141         unsigned long command_que_value;
1142         unsigned long param_value;
1143 
1144         /* Initialize SetParam command packet */
1145         if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
1146                 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
1147                 return 1;
1148         }
1149         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1150         memset(command_packet, 0, sizeof(TW_Sector));
1151         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1152 
1153         command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
1154         param->table_id = 0x404;  /* Features table */
1155         param->parameter_id = parm;
1156         param->parameter_size_bytes = param_size;
1157         memcpy(param->data, val, param_size);
1158 
1159         param_value = tw_dev->alignment_physical_address[request_id];
1160         if (param_value == 0) {
1161                 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad alignment physical address.\n");
1162                 tw_dev->state[request_id] = TW_S_COMPLETED;
1163                 tw_state_request_finish(tw_dev, request_id);
1164                 tw_dev->srb[request_id]->result = (DID_OK << 16);
1165                 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1166         }
1167         command_packet->byte8.param.sgl[0].address = param_value;
1168         command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1169 
1170         command_packet->size = 4;
1171         command_packet->request_id = request_id;
1172         command_packet->byte6.parameter_count = 1;
1173 
1174         command_que_value = tw_dev->command_packet_physical_address[request_id];
1175         if (command_que_value == 0) {
1176                 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
1177                 return 1;
1178         }
1179 
1180         /* Send command packet to the board */
1181         outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
1182 
1183         /* Poll for completion */
1184         if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1185                 response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1186                 request_id = TW_RESID_OUT(response_queue.response_id);
1187 
1188                 if (request_id != 0) {
1189                         /* unexpected request id */
1190                         printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
1191                         return 1;
1192                 }
1193                 if (command_packet->status != 0) {
1194                         /* bad response */
1195                         tw_decode_sense(tw_dev, request_id, 0);
1196                         return 1;
1197                 }
1198         }
1199 
1200         return 0;
1201 } /* End tw_setfeature() */
1202 
1203 /* This function will reset a controller */
1204 static int tw_reset_sequence(TW_Device_Extension *tw_dev) 
1205 {
1206         int error = 0;
1207         int tries = 0;
1208         unsigned char c = 1;
1209 
1210         /* Reset the board */
1211         while (tries < TW_MAX_RESET_TRIES) {
1212                 TW_SOFT_RESET(tw_dev);
1213 
1214                 error = tw_aen_drain_queue(tw_dev);
1215                 if (error) {
1216                         printk(KERN_WARNING "3w-xxxx: scsi%d: AEN drain failed, retrying.\n", tw_dev->host->host_no);
1217                         tries++;
1218                         continue;
1219                 }
1220 
1221                 /* Check for controller errors */
1222                 if (tw_check_errors(tw_dev)) {
1223                         printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors found, retrying.\n", tw_dev->host->host_no);
1224                         tries++;
1225                         continue;
1226                 }
1227 
1228                 /* Now the controller is in a good state */
1229                 break;
1230         }
1231 
1232         if (tries >= TW_MAX_RESET_TRIES) {
1233                 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors, card not responding, check all cabling.\n", tw_dev->host->host_no);
1234                 return 1;
1235         }
1236 
1237         error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
1238         if (error) {
1239                 printk(KERN_WARNING "3w-xxxx: scsi%d: Connection initialization failed.\n", tw_dev->host->host_no);
1240                 return 1;
1241         }
1242 
1243         error = tw_setfeature(tw_dev, 2, 1, &c);
1244         if (error) {
1245                 printk(KERN_WARNING "3w-xxxx: Unable to set features for card, probable old firmware or card.\n");
1246         }
1247 
1248         return 0;
1249 } /* End tw_reset_sequence() */
1250 
1251 /* This function will initialize the fields of a device extension */
1252 static int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
1253 {
1254         int i, error=0;
1255 
1256         dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_device_extension()\n");
1257 
1258         /* Initialize command packet buffers */
1259         error = tw_allocate_memory(tw_dev, sizeof(TW_Command), 0);
1260         if (error) {
1261                 printk(KERN_WARNING "3w-xxxx: Command packet memory allocation failed.\n");
1262                 return 1;
1263         }
1264 
1265         /* Initialize generic buffer */
1266         error = tw_allocate_memory(tw_dev, sizeof(TW_Sector), 1);
1267         if (error) {
1268                 printk(KERN_WARNING "3w-xxxx: Generic memory allocation failed.\n");
1269                 return 1;
1270         }
1271 
1272         for (i=0;i<TW_Q_LENGTH;i++) {
1273                 tw_dev->free_queue[i] = i;
1274                 tw_dev->state[i] = TW_S_INITIAL;
1275         }
1276 
1277         tw_dev->pending_head = TW_Q_START;
1278         tw_dev->pending_tail = TW_Q_START;
1279         tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1280 
1281         mutex_init(&tw_dev->ioctl_lock);
1282         init_waitqueue_head(&tw_dev->ioctl_wqueue);
1283 
1284         return 0;
1285 } /* End tw_initialize_device_extension() */
1286 
1287 /* This function will reset a device extension */
1288 static int tw_reset_device_extension(TW_Device_Extension *tw_dev)
1289 {
1290         int i = 0;
1291         struct scsi_cmnd *srb;
1292         unsigned long flags = 0;
1293 
1294         dprintk(KERN_NOTICE "3w-xxxx: tw_reset_device_extension()\n");
1295 
1296         set_bit(TW_IN_RESET, &tw_dev->flags);
1297         TW_DISABLE_INTERRUPTS(tw_dev);
1298         TW_MASK_COMMAND_INTERRUPT(tw_dev);
1299         spin_lock_irqsave(tw_dev->host->host_lock, flags);
1300 
1301         /* Abort all requests that are in progress */
1302         for (i=0;i<TW_Q_LENGTH;i++) {
1303                 if ((tw_dev->state[i] != TW_S_FINISHED) && 
1304                     (tw_dev->state[i] != TW_S_INITIAL) &&
1305                     (tw_dev->state[i] != TW_S_COMPLETED)) {
1306                         srb = tw_dev->srb[i];
1307                         if (srb != NULL) {
1308                                 srb->result = (DID_RESET << 16);
1309                                 scsi_dma_unmap(srb);
1310                                 srb->scsi_done(srb);
1311                         }
1312                 }
1313         }
1314 
1315         /* Reset queues and counts */
1316         for (i=0;i<TW_Q_LENGTH;i++) {
1317                 tw_dev->free_queue[i] = i;
1318                 tw_dev->state[i] = TW_S_INITIAL;
1319         }
1320         tw_dev->free_head = TW_Q_START;
1321         tw_dev->free_tail = TW_Q_START;
1322         tw_dev->posted_request_count = 0;
1323         tw_dev->pending_request_count = 0;
1324         tw_dev->pending_head = TW_Q_START;
1325         tw_dev->pending_tail = TW_Q_START;
1326         tw_dev->reset_print = 0;
1327 
1328         spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1329 
1330         if (tw_reset_sequence(tw_dev)) {
1331                 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset sequence failed.\n", tw_dev->host->host_no);
1332                 return 1;
1333         }
1334 
1335         TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
1336         clear_bit(TW_IN_RESET, &tw_dev->flags);
1337         tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1338 
1339         return 0;
1340 } /* End tw_reset_device_extension() */
1341 
1342 /* This funciton returns unit geometry in cylinders/heads/sectors */
1343 static int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1344                 sector_t capacity, int geom[]) 
1345 {
1346         int heads, sectors, cylinders;
1347         TW_Device_Extension *tw_dev;
1348         
1349         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n");
1350         tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1351 
1352         heads = 64;
1353         sectors = 32;
1354         cylinders = sector_div(capacity, heads * sectors);
1355 
1356         if (capacity >= 0x200000) {
1357                 heads = 255;
1358                 sectors = 63;
1359                 cylinders = sector_div(capacity, heads * sectors);
1360         }
1361 
1362         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam(): heads = %d, sectors = %d, cylinders = %d\n", heads, sectors, cylinders);
1363         geom[0] = heads;                         
1364         geom[1] = sectors;
1365         geom[2] = cylinders;
1366 
1367         return 0;
1368 } /* End tw_scsi_biosparam() */
1369 
1370 /* This is the new scsi eh reset function */
1371 static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt) 
1372 {
1373         TW_Device_Extension *tw_dev=NULL;
1374         int retval = FAILED;
1375 
1376         tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1377 
1378         tw_dev->num_resets++;
1379 
1380         sdev_printk(KERN_WARNING, SCpnt->device,
1381                 "WARNING: Command (0x%x) timed out, resetting card.\n",
1382                 SCpnt->cmnd[0]);
1383 
1384         /* Make sure we are not issuing an ioctl or resetting from ioctl */
1385         mutex_lock(&tw_dev->ioctl_lock);
1386 
1387         /* Now reset the card and some of the device extension data */
1388         if (tw_reset_device_extension(tw_dev)) {
1389                 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset failed.\n", tw_dev->host->host_no);
1390                 goto out;
1391         }
1392 
1393         retval = SUCCESS;
1394 out:
1395         mutex_unlock(&tw_dev->ioctl_lock);
1396         return retval;
1397 } /* End tw_scsi_eh_reset() */
1398 
1399 /* This function handles scsi inquiry commands */
1400 static int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
1401 {
1402         TW_Param *param;
1403         TW_Command *command_packet;
1404         unsigned long command_que_value;
1405         unsigned long param_value;
1406 
1407         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry()\n");
1408 
1409         /* Initialize command packet */
1410         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1411         if (command_packet == NULL) {
1412                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet virtual address.\n");
1413                 return 1;
1414         }
1415         memset(command_packet, 0, sizeof(TW_Sector));
1416         command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1417         command_packet->size = 4;
1418         command_packet->request_id = request_id;
1419         command_packet->status = 0;
1420         command_packet->flags = 0;
1421         command_packet->byte6.parameter_count = 1;
1422 
1423         /* Now setup the param */
1424         if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1425                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment virtual address.\n");
1426                 return 1;
1427         }
1428         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1429         memset(param, 0, sizeof(TW_Sector));
1430         param->table_id = 3;     /* unit summary table */
1431         param->parameter_id = 3; /* unitsstatus parameter */
1432         param->parameter_size_bytes = TW_MAX_UNITS;
1433         param_value = tw_dev->alignment_physical_address[request_id];
1434         if (param_value == 0) {
1435                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment physical address.\n");
1436                 return 1;
1437         }
1438 
1439         command_packet->byte8.param.sgl[0].address = param_value;
1440         command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1441         command_que_value = tw_dev->command_packet_physical_address[request_id];
1442         if (command_que_value == 0) {
1443                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet physical address.\n");
1444                 return 1;
1445         }
1446 
1447         /* Now try to post the command packet */
1448         tw_post_command_packet(tw_dev, request_id);
1449 
1450         return 0;
1451 } /* End tw_scsiop_inquiry() */
1452 
1453 static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
1454                                  void *data, unsigned int len)
1455 {
1456         scsi_sg_copy_from_buffer(tw_dev->srb[request_id], data, len);
1457 }
1458 
1459 /* This function is called by the isr to complete an inquiry command */
1460 static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
1461 {
1462         unsigned char *is_unit_present;
1463         unsigned char request_buffer[36];
1464         TW_Param *param;
1465 
1466         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
1467 
1468         memset(request_buffer, 0, sizeof(request_buffer));
1469         request_buffer[0] = TYPE_DISK; /* Peripheral device type */
1470         request_buffer[1] = 0;         /* Device type modifier */
1471         request_buffer[2] = 0;         /* No ansi/iso compliance */
1472         request_buffer[4] = 31;        /* Additional length */
1473         memcpy(&request_buffer[8], "3ware   ", 8);       /* Vendor ID */
1474         sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
1475         memcpy(&request_buffer[32], TW_DRIVER_VERSION, 3);
1476         tw_transfer_internal(tw_dev, request_id, request_buffer,
1477                              sizeof(request_buffer));
1478 
1479         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1480         if (param == NULL) {
1481                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Bad alignment virtual address.\n");
1482                 return 1;
1483         }
1484         is_unit_present = &(param->data[0]);
1485 
1486         if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
1487                 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 1;
1488         } else {
1489                 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 0;
1490                 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1491                 return TW_ISR_DONT_RESULT;
1492         }
1493 
1494         return 0;
1495 } /* End tw_scsiop_inquiry_complete() */
1496 
1497 /* This function handles scsi mode_sense commands */
1498 static int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id)
1499 {
1500         TW_Param *param;
1501         TW_Command *command_packet;
1502         unsigned long command_que_value;
1503         unsigned long param_value;
1504 
1505         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense()\n");
1506 
1507         /* Only page control = 0, page code = 0x8 (cache page) supported */
1508         if (tw_dev->srb[request_id]->cmnd[2] != 0x8) {
1509                 tw_dev->state[request_id] = TW_S_COMPLETED;
1510                 tw_state_request_finish(tw_dev, request_id);
1511                 tw_dev->srb[request_id]->result = (DID_OK << 16);
1512                 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1513                 return 0;
1514         }
1515 
1516         /* Now read firmware cache setting for this unit */
1517         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1518         if (command_packet == NULL) {
1519                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet virtual address.\n");
1520                 return 1;
1521         }
1522 
1523         /* Setup the command packet */
1524         memset(command_packet, 0, sizeof(TW_Sector));
1525         command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1526         command_packet->size = 4;
1527         command_packet->request_id = request_id;
1528         command_packet->status = 0;
1529         command_packet->flags = 0;
1530         command_packet->byte6.parameter_count = 1;
1531 
1532         /* Setup the param */
1533         if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1534                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment virtual address.\n");
1535                 return 1;
1536         }
1537 
1538         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1539         memset(param, 0, sizeof(TW_Sector));
1540         param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->device->id;
1541         param->parameter_id = 7; /* unit flags */
1542         param->parameter_size_bytes = 1;
1543         param_value = tw_dev->alignment_physical_address[request_id];
1544         if (param_value == 0) {
1545                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment physical address.\n");
1546                 return 1;
1547         }
1548 
1549         command_packet->byte8.param.sgl[0].address = param_value;
1550         command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1551         command_que_value = tw_dev->command_packet_physical_address[request_id];
1552         if (command_que_value == 0) {
1553                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet physical address.\n");
1554                 return 1;
1555         }
1556 
1557         /* Now try to post the command packet */
1558         tw_post_command_packet(tw_dev, request_id);
1559         
1560         return 0;
1561 } /* End tw_scsiop_mode_sense() */
1562 
1563 /* This function is called by the isr to complete a mode sense command */
1564 static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int request_id)
1565 {
1566         TW_Param *param;
1567         unsigned char *flags;
1568         unsigned char request_buffer[8];
1569 
1570         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
1571 
1572         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1573         if (param == NULL) {
1574                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense_complete(): Bad alignment virtual address.\n");
1575                 return 1;
1576         }
1577         flags = (char *)&(param->data[0]);
1578         memset(request_buffer, 0, sizeof(request_buffer));
1579 
1580         request_buffer[0] = 0xf;        /* mode data length */
1581         request_buffer[1] = 0;          /* default medium type */
1582         request_buffer[2] = 0x10;       /* dpo/fua support on */
1583         request_buffer[3] = 0;          /* no block descriptors */
1584         request_buffer[4] = 0x8;        /* caching page */
1585         request_buffer[5] = 0xa;        /* page length */
1586         if (*flags & 0x1)
1587                 request_buffer[6] = 0x5;        /* WCE on, RCD on */
1588         else
1589                 request_buffer[6] = 0x1;        /* WCE off, RCD on */
1590         tw_transfer_internal(tw_dev, request_id, request_buffer,
1591                              sizeof(request_buffer));
1592 
1593         return 0;
1594 } /* End tw_scsiop_mode_sense_complete() */
1595 
1596 /* This function handles scsi read_capacity commands */
1597 static int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id) 
1598 {
1599         TW_Param *param;
1600         TW_Command *command_packet;
1601         unsigned long command_que_value;
1602         unsigned long param_value;
1603 
1604         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n");
1605 
1606         /* Initialize command packet */
1607         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1608 
1609         if (command_packet == NULL) {
1610                 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet virtual address.\n");
1611                 return 1;
1612         }
1613         memset(command_packet, 0, sizeof(TW_Sector));
1614         command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1615         command_packet->size = 4;
1616         command_packet->request_id = request_id;
1617         command_packet->unit__hostid = TW_UNITHOST_IN(0, tw_dev->srb[request_id]->device->id);
1618         command_packet->status = 0;
1619         command_packet->flags = 0;
1620         command_packet->byte6.block_count = 1;
1621 
1622         /* Now setup the param */
1623         if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1624                 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment virtual address.\n");
1625                 return 1;
1626         }
1627         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1628         memset(param, 0, sizeof(TW_Sector));
1629         param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + 
1630         tw_dev->srb[request_id]->device->id;
1631         param->parameter_id = 4;        /* unitcapacity parameter */
1632         param->parameter_size_bytes = 4;
1633         param_value = tw_dev->alignment_physical_address[request_id];
1634         if (param_value == 0) {
1635                 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n");
1636                 return 1;
1637         }
1638   
1639         command_packet->byte8.param.sgl[0].address = param_value;
1640         command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1641         command_que_value = tw_dev->command_packet_physical_address[request_id];
1642         if (command_que_value == 0) {
1643                 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet physical address.\n");
1644                 return 1;
1645         }
1646 
1647         /* Now try to post the command to the board */
1648         tw_post_command_packet(tw_dev, request_id);
1649   
1650         return 0;
1651 } /* End tw_scsiop_read_capacity() */
1652 
1653 /* This function is called by the isr to complete a readcapacity command */
1654 static int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id)
1655 {
1656         unsigned char *param_data;
1657         u32 capacity;
1658         char buff[8];
1659         TW_Param *param;
1660 
1661         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
1662 
1663         memset(buff, 0, sizeof(buff));
1664         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1665         if (param == NULL) {
1666                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
1667                 return 1;
1668         }
1669         param_data = &(param->data[0]);
1670 
1671         capacity = (param_data[3] << 24) | (param_data[2] << 16) | 
1672                    (param_data[1] << 8) | param_data[0];
1673 
1674         /* Subtract one sector to fix get last sector ioctl */
1675         capacity -= 1;
1676 
1677         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete(): Capacity = 0x%x.\n", capacity);
1678 
1679         /* Number of LBA's */
1680         buff[0] = (capacity >> 24);
1681         buff[1] = (capacity >> 16) & 0xff;
1682         buff[2] = (capacity >> 8) & 0xff;
1683         buff[3] = capacity & 0xff;
1684 
1685         /* Block size in bytes (512) */
1686         buff[4] = (TW_BLOCK_SIZE >> 24);
1687         buff[5] = (TW_BLOCK_SIZE >> 16) & 0xff;
1688         buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
1689         buff[7] = TW_BLOCK_SIZE & 0xff;
1690 
1691         tw_transfer_internal(tw_dev, request_id, buff, sizeof(buff));
1692 
1693         return 0;
1694 } /* End tw_scsiop_read_capacity_complete() */
1695 
1696 /* This function handles scsi read or write commands */
1697 static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id) 
1698 {
1699         TW_Command *command_packet;
1700         unsigned long command_que_value;
1701         u32 lba = 0x0, num_sectors = 0x0;
1702         int i, use_sg;
1703         struct scsi_cmnd *srb;
1704         struct scatterlist *sglist, *sg;
1705 
1706         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
1707 
1708         srb = tw_dev->srb[request_id];
1709 
1710         sglist = scsi_sglist(srb);
1711         if (!sglist) {
1712                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n");
1713                 return 1;
1714         }
1715 
1716         /* Initialize command packet */
1717         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1718         if (command_packet == NULL) {
1719                 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): Bad command packet virtual address.\n");
1720                 return 1;
1721         }
1722 
1723         if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == READ_10) {
1724                 command_packet->opcode__sgloffset = TW_OPSGL_IN(3, TW_OP_READ);
1725         } else {
1726                 command_packet->opcode__sgloffset = TW_OPSGL_IN(3, TW_OP_WRITE);
1727         }
1728 
1729         command_packet->size = 3;
1730         command_packet->request_id = request_id;
1731         command_packet->unit__hostid = TW_UNITHOST_IN(0, srb->device->id);
1732         command_packet->status = 0;
1733         command_packet->flags = 0;
1734 
1735         if (srb->cmnd[0] == WRITE_10) {
1736                 if ((srb->cmnd[1] & 0x8) || (srb->cmnd[1] & 0x10))
1737                         command_packet->flags = 1;
1738         }
1739 
1740         if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) {
1741                 lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3];
1742                 num_sectors = (u32)srb->cmnd[4];
1743         } else {
1744                 lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
1745                 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
1746         }
1747   
1748         /* Update sector statistic */
1749         tw_dev->sector_count = num_sectors;
1750         if (tw_dev->sector_count > tw_dev->max_sector_count)
1751                 tw_dev->max_sector_count = tw_dev->sector_count;
1752   
1753         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors);
1754         command_packet->byte8.io.lba = lba;
1755         command_packet->byte6.block_count = num_sectors;
1756 
1757         use_sg = scsi_dma_map(srb);
1758         if (use_sg <= 0)
1759                 return 1;
1760 
1761         scsi_for_each_sg(tw_dev->srb[request_id], sg, use_sg, i) {
1762                 command_packet->byte8.io.sgl[i].address = sg_dma_address(sg);
1763                 command_packet->byte8.io.sgl[i].length = sg_dma_len(sg);
1764                 command_packet->size+=2;
1765         }
1766 
1767         /* Update SG statistics */
1768         tw_dev->sgl_entries = scsi_sg_count(tw_dev->srb[request_id]);
1769         if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
1770                 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
1771 
1772         command_que_value = tw_dev->command_packet_physical_address[request_id];
1773         if (command_que_value == 0) {
1774                 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n");
1775                 return 1;
1776         }
1777       
1778         /* Now try to post the command to the board */
1779         tw_post_command_packet(tw_dev, request_id);
1780 
1781         return 0;
1782 } /* End tw_scsiop_read_write() */
1783 
1784 /* This function will handle the request sense scsi command */
1785 static int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
1786 {
1787         char request_buffer[18];
1788 
1789         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
1790 
1791         memset(request_buffer, 0, sizeof(request_buffer));
1792         request_buffer[0] = 0x70; /* Immediate fixed format */
1793         request_buffer[7] = 10; /* minimum size per SPC: 18 bytes */
1794         /* leave all other fields zero, giving effectively NO_SENSE return */
1795         tw_transfer_internal(tw_dev, request_id, request_buffer,
1796                              sizeof(request_buffer));
1797 
1798         tw_dev->state[request_id] = TW_S_COMPLETED;
1799         tw_state_request_finish(tw_dev, request_id);
1800 
1801         /* If we got a request_sense, we probably want a reset, return error */
1802         tw_dev->srb[request_id]->result = (DID_ERROR << 16);
1803         tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1804 
1805         return 0;
1806 } /* End tw_scsiop_request_sense() */
1807 
1808 /* This function will handle synchronize cache scsi command */
1809 static int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id)
1810 {
1811         TW_Command *command_packet;
1812         unsigned long command_que_value;
1813 
1814         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_synchronize_cache()\n");
1815 
1816         /* Send firmware flush command for this unit */
1817         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1818         if (command_packet == NULL) {
1819                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet virtual address.\n");
1820                 return 1;
1821         }
1822 
1823         /* Setup the command packet */
1824         memset(command_packet, 0, sizeof(TW_Sector));
1825         command_packet->opcode__sgloffset = TW_OPSGL_IN(0, TW_OP_FLUSH_CACHE);
1826         command_packet->size = 2;
1827         command_packet->request_id = request_id;
1828         command_packet->unit__hostid = TW_UNITHOST_IN(0, tw_dev->srb[request_id]->device->id);
1829         command_packet->status = 0;
1830         command_packet->flags = 0;
1831         command_packet->byte6.parameter_count = 1;
1832         command_que_value = tw_dev->command_packet_physical_address[request_id];
1833         if (command_que_value == 0) {
1834                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet physical address.\n");
1835                 return 1;
1836         }
1837 
1838         /* Now try to post the command packet */
1839         tw_post_command_packet(tw_dev, request_id);
1840 
1841         return 0;
1842 } /* End tw_scsiop_synchronize_cache() */
1843 
1844 /* This function will handle test unit ready scsi command */
1845 static int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
1846 {
1847         TW_Param *param;
1848         TW_Command *command_packet;
1849         unsigned long command_que_value;
1850         unsigned long param_value;
1851 
1852         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n");
1853 
1854         /* Initialize command packet */
1855         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1856         if (command_packet == NULL) {
1857                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet virtual address.\n");
1858                 return 1;
1859         }
1860         memset(command_packet, 0, sizeof(TW_Sector));
1861         command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1862         command_packet->size = 4;
1863         command_packet->request_id = request_id;
1864         command_packet->status = 0;
1865         command_packet->flags = 0;
1866         command_packet->byte6.parameter_count = 1;
1867 
1868         /* Now setup the param */
1869         if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1870                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment virtual address.\n");
1871                 return 1;
1872         }
1873         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1874         memset(param, 0, sizeof(TW_Sector));
1875         param->table_id = 3;     /* unit summary table */
1876         param->parameter_id = 3; /* unitsstatus parameter */
1877         param->parameter_size_bytes = TW_MAX_UNITS;
1878         param_value = tw_dev->alignment_physical_address[request_id];
1879         if (param_value == 0) {
1880                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment physical address.\n");
1881                 return 1;
1882         }
1883 
1884         command_packet->byte8.param.sgl[0].address = param_value;
1885         command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1886         command_que_value = tw_dev->command_packet_physical_address[request_id];
1887         if (command_que_value == 0) {
1888                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet physical address.\n");
1889                 return 1;
1890         }
1891 
1892         /* Now try to post the command packet */
1893         tw_post_command_packet(tw_dev, request_id);
1894 
1895         return 0;
1896 } /* End tw_scsiop_test_unit_ready() */
1897 
1898 /* This function is called by the isr to complete a testunitready command */
1899 static int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int request_id)
1900 {
1901         unsigned char *is_unit_present;
1902         TW_Param *param;
1903 
1904         dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete()\n");
1905 
1906         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1907         if (param == NULL) {
1908                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete(): Bad alignment virtual address.\n");
1909                 return 1;
1910         }
1911         is_unit_present = &(param->data[0]);
1912 
1913         if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
1914                 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 1;
1915         } else {
1916                 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 0;
1917                 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1918                 return TW_ISR_DONT_RESULT;
1919         }
1920 
1921         return 0;
1922 } /* End tw_scsiop_test_unit_ready_complete() */
1923 
1924 /* This is the main scsi queue function to handle scsi opcodes */
1925 static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1926 {
1927         unsigned char *command = SCpnt->cmnd;
1928         int request_id = 0;
1929         int retval = 1;
1930         TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1931 
1932         /* If we are resetting due to timed out ioctl, report as busy */
1933         if (test_bit(TW_IN_RESET, &tw_dev->flags))
1934                 return SCSI_MLQUEUE_HOST_BUSY;
1935 
1936         /* Save done function into struct scsi_cmnd */
1937         SCpnt->scsi_done = done;
1938                  
1939         /* Queue the command and get a request id */
1940         tw_state_request_start(tw_dev, &request_id);
1941 
1942         /* Save the scsi command for use by the ISR */
1943         tw_dev->srb[request_id] = SCpnt;
1944 
1945         switch (*command) {
1946                 case READ_10:
1947                 case READ_6:
1948                 case WRITE_10:
1949                 case WRITE_6:
1950                         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ/WRITE.\n");
1951                         retval = tw_scsiop_read_write(tw_dev, request_id);
1952                         break;
1953                 case TEST_UNIT_READY:
1954                         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
1955                         retval = tw_scsiop_test_unit_ready(tw_dev, request_id);
1956                         break;
1957                 case INQUIRY:
1958                         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
1959                         retval = tw_scsiop_inquiry(tw_dev, request_id);
1960                         break;
1961                 case READ_CAPACITY:
1962                         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
1963                         retval = tw_scsiop_read_capacity(tw_dev, request_id);
1964                         break;
1965                 case REQUEST_SENSE:
1966                         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
1967                         retval = tw_scsiop_request_sense(tw_dev, request_id);
1968                         break;
1969                 case MODE_SENSE:
1970                         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught MODE_SENSE.\n");
1971                         retval = tw_scsiop_mode_sense(tw_dev, request_id);
1972                         break;
1973                 case SYNCHRONIZE_CACHE:
1974                         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught SYNCHRONIZE_CACHE.\n");
1975                         retval = tw_scsiop_synchronize_cache(tw_dev, request_id);
1976                         break;
1977                 case TW_IOCTL:
1978                         printk(KERN_WARNING "3w-xxxx: SCSI_IOCTL_SEND_COMMAND deprecated, please update your 3ware tools.\n");
1979                         break;
1980                 default:
1981                         printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
1982                         tw_dev->state[request_id] = TW_S_COMPLETED;
1983                         tw_state_request_finish(tw_dev, request_id);
1984                         SCpnt->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
1985                         scsi_build_sense_buffer(1, SCpnt->sense_buffer, ILLEGAL_REQUEST, 0x20, 0);
1986                         done(SCpnt);
1987                         retval = 0;
1988         }
1989         if (retval) {
1990                 tw_dev->state[request_id] = TW_S_COMPLETED;
1991                 tw_state_request_finish(tw_dev, request_id);
1992                 SCpnt->result = (DID_ERROR << 16);
1993                 done(SCpnt);
1994                 retval = 0;
1995         }
1996         return retval;
1997 } /* End tw_scsi_queue() */
1998 
1999 static DEF_SCSI_QCMD(tw_scsi_queue)
2000 
2001 /* This function is the interrupt service routine */
2002 static irqreturn_t tw_interrupt(int irq, void *dev_instance) 
2003 {
2004         int request_id;
2005         u32 status_reg_value;
2006         TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
2007         TW_Response_Queue response_que;
2008         int error = 0, retval = 0;
2009         TW_Command *command_packet;
2010         int handled = 0;
2011 
2012         /* Get the host lock for io completions */
2013         spin_lock(tw_dev->host->host_lock);
2014 
2015         /* Read the registers */
2016         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
2017 
2018         /* Check if this is our interrupt, otherwise bail */
2019         if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
2020                 goto tw_interrupt_bail;
2021 
2022         handled = 1;
2023 
2024         /* If we are resetting, bail */
2025         if (test_bit(TW_IN_RESET, &tw_dev->flags))
2026                 goto tw_interrupt_bail;
2027 
2028         /* Check controller for errors */
2029         if (tw_check_bits(status_reg_value)) {
2030                 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
2031                 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
2032                         TW_CLEAR_ALL_INTERRUPTS(tw_dev);
2033                         goto tw_interrupt_bail;
2034                 }
2035         }
2036 
2037         /* Handle host interrupt */
2038         if (status_reg_value & TW_STATUS_HOST_INTERRUPT) {
2039                 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n");
2040                 TW_CLEAR_HOST_INTERRUPT(tw_dev);
2041         }
2042 
2043         /* Handle attention interrupt */
2044         if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
2045                 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n");
2046                 TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
2047                 tw_state_request_start(tw_dev, &request_id);
2048                 error = tw_aen_read_queue(tw_dev, request_id);
2049                 if (error) {
2050                         printk(KERN_WARNING "3w-xxxx: scsi%d: Error reading aen queue.\n", tw_dev->host->host_no);
2051                         tw_dev->state[request_id] = TW_S_COMPLETED;
2052                         tw_state_request_finish(tw_dev, request_id);
2053                 }
2054         }
2055 
2056         /* Handle command interrupt */
2057         if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
2058                 /* Drain as many pending commands as we can */
2059                 while (tw_dev->pending_request_count > 0) {
2060                         request_id = tw_dev->pending_queue[tw_dev->pending_head];
2061                         if (tw_dev->state[request_id] != TW_S_PENDING) {
2062                                 printk(KERN_WARNING "3w-xxxx: scsi%d: Found request id that wasn't pending.\n", tw_dev->host->host_no);
2063                                 break;
2064                         }
2065                         if (tw_post_command_packet(tw_dev, request_id)==0) {
2066                                 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
2067                                         tw_dev->pending_head = TW_Q_START;
2068                                 } else {
2069                                         tw_dev->pending_head = tw_dev->pending_head + 1;
2070                                 }
2071                                 tw_dev->pending_request_count--;
2072                         } else {
2073                                 /* If we get here, we will continue re-posting on the next command interrupt */
2074                                 break;
2075                         }
2076                 }
2077                 /* If there are no more pending requests, we mask command interrupt */
2078                 if (tw_dev->pending_request_count == 0) 
2079                         TW_MASK_COMMAND_INTERRUPT(tw_dev);
2080         }
2081 
2082         /* Handle response interrupt */
2083         if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
2084                 /* Drain the response queue from the board */
2085                 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
2086                         /* Read response queue register */
2087                         response_que.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
2088                         request_id = TW_RESID_OUT(response_que.response_id);
2089                         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2090                         error = 0;
2091 
2092                         /* Check for bad response */
2093                         if (command_packet->status != 0) {
2094                                 /* If internal command, don't error, don't fill sense */
2095                                 if (tw_dev->srb[request_id] == NULL) {
2096                                         tw_decode_sense(tw_dev, request_id, 0);
2097                                 } else {
2098                                         error = tw_decode_sense(tw_dev, request_id, 1);
2099                                 }
2100                         }
2101 
2102                         /* Check for correct state */
2103                         if (tw_dev->state[request_id] != TW_S_POSTED) {
2104                                 if (tw_dev->srb[request_id] != NULL) {
2105                                         printk(KERN_WARNING "3w-xxxx: scsi%d: Received a request id that wasn't posted.\n", tw_dev->host->host_no);
2106                                         error = 1;
2107                                 }
2108                         }
2109 
2110                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
2111 
2112                         /* Check for internal command completion */
2113                         if (tw_dev->srb[request_id] == NULL) {
2114                                 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
2115                                 /* Check for chrdev ioctl completion */
2116                                 if (request_id != tw_dev->chrdev_request_id) {
2117                                         retval = tw_aen_complete(tw_dev, request_id);
2118                                         if (retval) {
2119                                                 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);
2120                                         }
2121                                 } else {
2122                                         tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
2123                                         wake_up(&tw_dev->ioctl_wqueue);
2124                                 }
2125                         } else {
2126                                 switch (tw_dev->srb[request_id]->cmnd[0]) {
2127                                 case READ_10:
2128                                 case READ_6:
2129                                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10/READ_6\n");
2130                                         break;
2131                                 case WRITE_10:
2132                                 case WRITE_6:
2133                                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10/WRITE_6\n");
2134                                         break;
2135                                 case TEST_UNIT_READY:
2136                                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TEST_UNIT_READY\n");
2137                                         error = tw_scsiop_test_unit_ready_complete(tw_dev, request_id);
2138                                         break;
2139                                 case INQUIRY:
2140                                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");
2141                                         error = tw_scsiop_inquiry_complete(tw_dev, request_id);
2142                                         break;
2143                                 case READ_CAPACITY:
2144                                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");
2145                                         error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
2146                                         break;
2147                                 case MODE_SENSE:
2148                                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught MODE_SENSE\n");
2149                                         error = tw_scsiop_mode_sense_complete(tw_dev, request_id);
2150                                         break;
2151                                 case SYNCHRONIZE_CACHE:
2152                                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught SYNCHRONIZE_CACHE\n");
2153                                         break;
2154                                 default:
2155                                         printk(KERN_WARNING "3w-xxxx: case slip in tw_interrupt()\n");
2156                                         error = 1;
2157                                 }
2158 
2159                                 /* If no error command was a success */
2160                                 if (error == 0) {
2161                                         tw_dev->srb[request_id]->result = (DID_OK << 16);
2162                                 }
2163 
2164                                 /* If error, command failed */
2165                                 if (error == 1) {
2166                                         /* Ask for a host reset */
2167                                         tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
2168                                 }
2169 
2170                                 /* Now complete the io */
2171                                 if ((error != TW_ISR_DONT_COMPLETE)) {
2172                                         scsi_dma_unmap(tw_dev->srb[request_id]);
2173                                         tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2174                                         tw_dev->state[request_id] = TW_S_COMPLETED;
2175                                         tw_state_request_finish(tw_dev, request_id);
2176                                         tw_dev->posted_request_count--;
2177                                 }
2178                         }
2179                                 
2180                         /* Check for valid status after each drain */
2181                         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
2182                         if (tw_check_bits(status_reg_value)) {
2183                                 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
2184                                 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
2185                                         TW_CLEAR_ALL_INTERRUPTS(tw_dev);
2186                                         goto tw_interrupt_bail;
2187                                 }
2188                         }
2189                 }
2190         }
2191 
2192 tw_interrupt_bail:
2193         spin_unlock(tw_dev->host->host_lock);
2194         return IRQ_RETVAL(handled);
2195 } /* End tw_interrupt() */
2196 
2197 /* This function tells the controller to shut down */
2198 static void __tw_shutdown(TW_Device_Extension *tw_dev)
2199 {
2200         /* Disable interrupts */
2201         TW_DISABLE_INTERRUPTS(tw_dev);
2202 
2203         /* Free up the IRQ */
2204         free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2205 
2206         printk(KERN_WARNING "3w-xxxx: Shutting down host %d.\n", tw_dev->host->host_no);
2207 
2208         /* Tell the card we are shutting down */
2209         if (tw_initconnection(tw_dev, 1)) {
2210                 printk(KERN_WARNING "3w-xxxx: Connection shutdown failed.\n");
2211         } else {
2212                 printk(KERN_WARNING "3w-xxxx: Shutdown complete.\n");
2213         }
2214 
2215         /* Clear all interrupts just before exit */
2216         TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2217 } /* End __tw_shutdown() */
2218 
2219 /* Wrapper for __tw_shutdown */
2220 static void tw_shutdown(struct pci_dev *pdev)
2221 {
2222         struct Scsi_Host *host = pci_get_drvdata(pdev);
2223         TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2224 
2225         __tw_shutdown(tw_dev);
2226 } /* End tw_shutdown() */
2227 
2228 /* This function gets called when a disk is coming online */
2229 static int tw_slave_configure(struct scsi_device *sdev)
2230 {
2231         /* Force 60 second timeout */
2232         blk_queue_rq_timeout(sdev->request_queue, 60 * HZ);
2233 
2234         return 0;
2235 } /* End tw_slave_configure() */
2236 
2237 static struct scsi_host_template driver_template = {
2238         .module                 = THIS_MODULE,
2239         .name                   = "3ware Storage Controller",
2240         .queuecommand           = tw_scsi_queue,
2241         .eh_host_reset_handler  = tw_scsi_eh_reset,
2242         .bios_param             = tw_scsi_biosparam,
2243         .change_queue_depth     = scsi_change_queue_depth,
2244         .can_queue              = TW_Q_LENGTH-2,
2245         .slave_configure        = tw_slave_configure,
2246         .this_id                = -1,
2247         .sg_tablesize           = TW_MAX_SGL_LENGTH,
2248         .max_sectors            = TW_MAX_SECTORS,
2249         .cmd_per_lun            = TW_MAX_CMDS_PER_LUN,  
2250         .shost_attrs            = tw_host_attrs,
2251         .emulated               = 1,
2252         .no_write_same          = 1,
2253 };
2254 
2255 /* This function will probe and initialize a card */
2256 static int tw_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
2257 {
2258         struct Scsi_Host *host = NULL;
2259         TW_Device_Extension *tw_dev;
2260         int retval = -ENODEV;
2261 
2262         retval = pci_enable_device(pdev);
2263         if (retval) {
2264                 printk(KERN_WARNING "3w-xxxx: Failed to enable pci device.");
2265                 goto out_disable_device;
2266         }
2267 
2268         pci_set_master(pdev);
2269 
2270         retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
2271         if (retval) {
2272                 printk(KERN_WARNING "3w-xxxx: Failed to set dma mask.");
2273                 goto out_disable_device;
2274         }
2275 
2276         host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
2277         if (!host) {
2278                 printk(KERN_WARNING "3w-xxxx: Failed to allocate memory for device extension.");
2279                 retval = -ENOMEM;
2280                 goto out_disable_device;
2281         }
2282         tw_dev = (TW_Device_Extension *)host->hostdata;
2283 
2284         /* Save values to device extension */
2285         tw_dev->host = host;
2286         tw_dev->tw_pci_dev = pdev;
2287 
2288         if (tw_initialize_device_extension(tw_dev)) {
2289                 printk(KERN_WARNING "3w-xxxx: Failed to initialize device extension.");
2290                 retval = -ENOMEM;
2291                 goto out_free_device_extension;
2292         }
2293 
2294         /* Request IO regions */
2295         retval = pci_request_regions(pdev, "3w-xxxx");
2296         if (retval) {
2297                 printk(KERN_WARNING "3w-xxxx: Failed to get mem region.");
2298                 goto out_free_device_extension;
2299         }
2300 
2301         /* Save base address */
2302         tw_dev->base_addr = pci_resource_start(pdev, 0);
2303         if (!tw_dev->base_addr) {
2304                 printk(KERN_WARNING "3w-xxxx: Failed to get io address.");
2305                 retval = -ENOMEM;
2306                 goto out_release_mem_region;
2307         }
2308 
2309         /* Disable interrupts on the card */
2310         TW_DISABLE_INTERRUPTS(tw_dev);
2311 
2312         /* Initialize the card */
2313         if (tw_reset_sequence(tw_dev))
2314                 goto out_release_mem_region;
2315 
2316         /* Set host specific parameters */
2317         host->max_id = TW_MAX_UNITS;
2318         host->max_cmd_len = TW_MAX_CDB_LEN;
2319 
2320         /* Luns and channels aren't supported by adapter */
2321         host->max_lun = 0;
2322         host->max_channel = 0;
2323 
2324         /* Register the card with the kernel SCSI layer */
2325         retval = scsi_add_host(host, &pdev->dev);
2326         if (retval) {
2327                 printk(KERN_WARNING "3w-xxxx: scsi add host failed");
2328                 goto out_release_mem_region;
2329         }
2330 
2331         pci_set_drvdata(pdev, host);
2332 
2333         printk(KERN_WARNING "3w-xxxx: scsi%d: Found a 3ware Storage Controller at 0x%x, IRQ: %d.\n", host->host_no, tw_dev->base_addr, pdev->irq);
2334 
2335         /* Now setup the interrupt handler */
2336         retval = request_irq(pdev->irq, tw_interrupt, IRQF_SHARED, "3w-xxxx", tw_dev);
2337         if (retval) {
2338                 printk(KERN_WARNING "3w-xxxx: Error requesting IRQ.");
2339                 goto out_remove_host;
2340         }
2341 
2342         tw_device_extension_list[tw_device_extension_count] = tw_dev;
2343         tw_device_extension_count++;
2344 
2345         /* Re-enable interrupts on the card */
2346         TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2347 
2348         /* Finally, scan the host */
2349         scsi_scan_host(host);
2350 
2351         if (twe_major == -1) {
2352                 if ((twe_major = register_chrdev (0, "twe", &tw_fops)) < 0)
2353                         printk(KERN_WARNING "3w-xxxx: Failed to register character device.");
2354         }
2355         return 0;
2356 
2357 out_remove_host:
2358         scsi_remove_host(host);
2359 out_release_mem_region:
2360         pci_release_regions(pdev);
2361 out_free_device_extension:
2362         tw_free_device_extension(tw_dev);
2363         scsi_host_put(host);
2364 out_disable_device:
2365         pci_disable_device(pdev);
2366 
2367         return retval;
2368 } /* End tw_probe() */
2369 
2370 /* This function is called to remove a device */
2371 static void tw_remove(struct pci_dev *pdev)
2372 {
2373         struct Scsi_Host *host = pci_get_drvdata(pdev);
2374         TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2375 
2376         scsi_remove_host(tw_dev->host);
2377 
2378         /* Unregister character device */
2379         if (twe_major >= 0) {
2380                 unregister_chrdev(twe_major, "twe");
2381                 twe_major = -1;
2382         }
2383 
2384         /* Shutdown the card */
2385         __tw_shutdown(tw_dev);
2386 
2387         /* Free up the mem region */
2388         pci_release_regions(pdev);
2389 
2390         /* Free up device extension resources */
2391         tw_free_device_extension(tw_dev);
2392 
2393         scsi_host_put(tw_dev->host);
2394         pci_disable_device(pdev);
2395         tw_device_extension_count--;
2396 } /* End tw_remove() */
2397 
2398 /* PCI Devices supported by this driver */
2399 static struct pci_device_id tw_pci_tbl[] = {
2400         { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_1000,
2401           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2402         { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_7000,
2403           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2404         { }
2405 };
2406 MODULE_DEVICE_TABLE(pci, tw_pci_tbl);
2407 
2408 /* pci_driver initializer */
2409 static struct pci_driver tw_driver = {
2410         .name           = "3w-xxxx",
2411         .id_table       = tw_pci_tbl,
2412         .probe          = tw_probe,
2413         .remove         = tw_remove,
2414         .shutdown       = tw_shutdown,
2415 };
2416 
2417 /* This function is called on driver initialization */
2418 static int __init tw_init(void)
2419 {
2420         printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
2421 
2422         return pci_register_driver(&tw_driver);
2423 } /* End tw_init() */
2424 
2425 /* This function is called on driver exit */
2426 static void __exit tw_exit(void)
2427 {
2428         pci_unregister_driver(&tw_driver);
2429 } /* End tw_exit() */
2430 
2431 module_init(tw_init);
2432 module_exit(tw_exit);
2433 

/* [<][>][^][v][top][bottom][index][help] */