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