Back to home page

OSCL-LXR

 
 

    


0001 /*
0002    3w-xxxx.c -- 3ware Storage Controller device driver for Linux.
0003 
0004    Written By: Adam Radford <aradford@gmail.com>
0005    Modifications By: Joel Jacobson <linux@3ware.com>
0006                      Arnaldo Carvalho de Melo <acme@conectiva.com.br>
0007                      Brad Strand <linux@3ware.com>
0008 
0009    Copyright (C) 1999-2010 3ware Inc.
0010 
0011    Kernel compatibility By: Andre Hedrick <andre@suse.com>
0012    Non-Copyright (C) 2000   Andre Hedrick <andre@suse.com>
0013 
0014    Further tiny build fixes and trivial hoovering    Alan Cox
0015 
0016    This program is free software; you can redistribute it and/or modify
0017    it under the terms of the GNU General Public License as published by
0018    the Free Software Foundation; version 2 of the License.
0019 
0020    This program is distributed in the hope that it will be useful,
0021    but WITHOUT ANY WARRANTY; without even the implied warranty of
0022    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0023    GNU General Public License for more details.
0024 
0025    NO WARRANTY
0026    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
0027    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
0028    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
0029    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
0030    solely responsible for determining the appropriateness of using and
0031    distributing the Program and assumes all risks associated with its
0032    exercise of rights under this Agreement, including but not limited to
0033    the risks and costs of program errors, damage to or loss of data,
0034    programs or equipment, and unavailability or interruption of operations.
0035 
0036    DISCLAIMER OF LIABILITY
0037    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
0038    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0039    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
0040    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
0041    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
0042    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
0043    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
0044 
0045    You should have received a copy of the GNU General Public License
0046    along with this program; if not, write to the Free Software
0047    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0048 
0049    Bugs/Comments/Suggestions should be mailed to:
0050 
0051    aradford@gmail.com
0052 
0053 
0054    History
0055    -------
0056    0.1.000 -     Initial release.
0057    0.4.000 -     Added support for Asynchronous Event Notification through
0058                  ioctls for 3DM.
0059    1.0.000 -     Added DPO & FUA bit support for WRITE_10 & WRITE_6 cdb
0060                  to disable drive write-cache before writes.
0061    1.1.000 -     Fixed performance bug with DPO & FUA not existing for WRITE_6.
0062    1.2.000 -     Added support for clean shutdown notification/feature table.
0063    1.02.00.001 - Added support for full command packet posts through ioctls
0064                  for 3DM.
0065                  Bug fix so hot spare drives don't show up.
0066    1.02.00.002 - Fix bug with tw_setfeature() call that caused oops on some
0067                  systems.
0068    08/21/00    - release previously allocated resources on failure at
0069                  tw_allocate_memory (acme)
0070    1.02.00.003 - Fix tw_interrupt() to report error to scsi layer when
0071                  controller status is non-zero.
0072                  Added handling of request_sense opcode.
0073          Fix possible null pointer dereference in
0074                  tw_reset_device_extension()
0075    1.02.00.004 - Add support for device id of 3ware 7000 series controllers.
0076                  Make tw_setfeature() call with interrupts disabled.
0077                  Register interrupt handler before enabling interrupts.
0078                  Clear attention interrupt before draining aen queue.
0079    1.02.00.005 - Allocate bounce buffers and custom queue depth for raid5 for
0080                  6000 and 5000 series controllers.
0081                  Reduce polling mdelays causing problems on some systems.
0082                  Fix use_sg = 1 calculation bug.
0083                  Check for scsi_register returning NULL.
0084                  Add aen count to /proc/scsi/3w-xxxx.
0085                  Remove aen code unit masking in tw_aen_complete().
0086    1.02.00.006 - Remove unit from printk in tw_scsi_eh_abort(), causing
0087                  possible oops.
0088                  Fix possible null pointer dereference in tw_scsi_queue()
0089                  if done function pointer was invalid.
0090    1.02.00.007 - Fix possible null pointer dereferences in tw_ioctl().
0091                  Remove check for invalid done function pointer from
0092                  tw_scsi_queue().
0093    1.02.00.008 - Set max sectors per io to TW_MAX_SECTORS in tw_findcards().
0094                  Add tw_decode_error() for printing readable error messages.
0095                  Print some useful information on certain aen codes.
0096                  Add tw_decode_bits() for interpreting status register output.
0097                  Make scsi_set_pci_device() for kernels >= 2.4.4
0098                  Fix bug where aen's could be lost before a reset.
0099                  Re-add spinlocks in tw_scsi_detect().
0100                  Fix possible null pointer dereference in tw_aen_drain_queue()
0101                  during initialization.
0102                  Clear pci parity errors during initialization and during io.
0103    1.02.00.009 - Remove redundant increment in tw_state_request_start().
0104                  Add ioctl support for direct ATA command passthru.
0105                  Add entire aen code string list.
0106    1.02.00.010 - Cleanup queueing code, fix jbod thoughput.
0107                  Fix get_param for specific units.
0108    1.02.00.011 - Fix bug in tw_aen_complete() where aen's could be lost.
0109                  Fix tw_aen_drain_queue() to display useful info at init.
0110                  Set tw_host->max_id for 12 port cards.
0111                  Add ioctl support for raw command packet post from userspace
0112                  with sglist fragments (parameter and io).
0113    1.02.00.012 - Fix read capacity to under report by 1 sector to fix get
0114                  last sector ioctl.
0115    1.02.00.013 - Fix bug where more AEN codes weren't coming out during
0116                  driver initialization.
0117                  Improved handling of PCI aborts.
0118    1.02.00.014 - Fix bug in tw_findcards() where AEN code could be lost.
0119                  Increase timeout in tw_aen_drain_queue() to 30 seconds.
0120    1.02.00.015 - Re-write raw command post with data ioctl method.
0121                  Remove raid5 bounce buffers for raid5 for 6XXX for kernel 2.5
0122                  Add tw_map/unmap_scsi_sg/single_data() for kernel 2.5
0123                  Replace io_request_lock with host_lock for kernel 2.5
0124                  Set max_cmd_len to 16 for 3dm for kernel 2.5
0125    1.02.00.016 - Set host->max_sectors back up to 256.
0126    1.02.00.017 - Modified pci parity error handling/clearing from config space
0127                  during initialization.
0128    1.02.00.018 - Better handling of request sense opcode and sense information
0129                  for failed commands.  Add tw_decode_sense().
0130                  Replace all mdelay()'s with scsi_sleep().
0131    1.02.00.019 - Revert mdelay's and scsi_sleep's, this caused problems on
0132                  some SMP systems.
0133    1.02.00.020 - Add pci_set_dma_mask(), rewrite kmalloc()/virt_to_bus() to
0134                  pci_alloc/free_consistent().
0135                  Better alignment checking in tw_allocate_memory().
0136                  Cleanup tw_initialize_device_extension().
0137    1.02.00.021 - Bump cmd_per_lun in SHT to 255 for better jbod performance.
0138                  Improve handling of errors in tw_interrupt().
0139                  Add handling/clearing of controller queue error.
0140                  Empty stale responses before draining aen queue.
0141                  Fix tw_scsi_eh_abort() to not reset on every io abort.
0142                  Set can_queue in SHT to 255 to prevent hang from AEN.
0143    1.02.00.022 - Fix possible null pointer dereference in tw_scsi_release().
0144    1.02.00.023 - Fix bug in tw_aen_drain_queue() where unit # was always zero.
0145    1.02.00.024 - Add severity levels to AEN strings.
0146    1.02.00.025 - Fix command interrupt spurious error messages.
0147                  Fix bug in raw command post with data ioctl method.
0148                  Fix bug where rollcall sometimes failed with cable errors.
0149                  Print unit # on all command timeouts.
0150    1.02.00.026 - Fix possible infinite retry bug with power glitch induced
0151                  drive timeouts.
0152                  Cleanup some AEN severity levels.
0153    1.02.00.027 - Add drive not supported AEN code for SATA controllers.
0154                  Remove spurious unknown ioctl error message.
0155    1.02.00.028 - Fix bug where multiple controllers with no units were the
0156                  same card number.
0157                  Fix bug where cards were being shut down more than once.
0158    1.02.00.029 - Add missing pci_free_consistent() in tw_allocate_memory().
0159                  Replace pci_map_single() with pci_map_page() for highmem.
0160                  Check for tw_setfeature() failure.
0161    1.02.00.030 - Make driver 64-bit clean.
0162    1.02.00.031 - Cleanup polling timeouts/routines in several places.
0163                  Add support for mode sense opcode.
0164                  Add support for cache mode page.
0165                  Add support for synchronize cache opcode.
0166    1.02.00.032 - Fix small multicard rollcall bug.
0167                  Make driver stay loaded with no units for hot add/swap.
0168                  Add support for "twe" character device for ioctls.
0169                  Clean up request_id queueing code.
0170                  Fix tw_scsi_queue() spinlocks.
0171    1.02.00.033 - Fix tw_aen_complete() to not queue 'queue empty' AEN's.
0172                  Initialize queues correctly when loading with no valid units.
0173    1.02.00.034 - Fix tw_decode_bits() to handle multiple errors.
0174                  Add support for user configurable cmd_per_lun.
0175                  Add support for sht->slave_configure().
0176    1.02.00.035 - Improve tw_allocate_memory() memory allocation.
0177                  Fix tw_chrdev_ioctl() to sleep correctly.
0178    1.02.00.036 - Increase character ioctl timeout to 60 seconds.
0179    1.02.00.037 - Fix tw_ioctl() to handle all non-data ATA passthru cmds
0180                  for 'smartmontools' support.
0181    1.26.00.038 - Roll driver minor version to 26 to denote kernel 2.6.
0182                  Add support for cmds_per_lun module parameter.
0183    1.26.00.039 - Fix bug in tw_chrdev_ioctl() polling code.
0184                  Fix data_buffer_length usage in tw_chrdev_ioctl().
0185                  Update contact information.
0186    1.26.02.000 - Convert driver to pci_driver format.
0187    1.26.02.001 - Increase max ioctl buffer size to 512 sectors.
0188                  Make tw_scsi_queue() return 0 for 'Unknown scsi opcode'.
0189                  Fix tw_remove() to free irq handler/unregister_chrdev()
0190                  before shutting down card.
0191                  Change to new 'change_queue_depth' api.
0192                  Fix 'handled=1' ISR usage, remove bogus IRQ check.
0193    1.26.02.002 - Free irq handler in __tw_shutdown().
0194                  Turn on RCD bit for caching mode page.
0195                  Serialize reset code.
0196    1.26.02.003 - Force 60 second timeout default.
0197 */
0198 
0199 #include <linux/module.h>
0200 #include <linux/reboot.h>
0201 #include <linux/spinlock.h>
0202 #include <linux/interrupt.h>
0203 #include <linux/moduleparam.h>
0204 #include <linux/errno.h>
0205 #include <linux/types.h>
0206 #include <linux/delay.h>
0207 #include <linux/gfp.h>
0208 #include <linux/pci.h>
0209 #include <linux/time.h>
0210 #include <linux/mutex.h>
0211 #include <asm/io.h>
0212 #include <asm/irq.h>
0213 #include <linux/uaccess.h>
0214 #include <scsi/scsi.h>
0215 #include <scsi/scsi_host.h>
0216 #include <scsi/scsi_tcq.h>
0217 #include <scsi/scsi_cmnd.h>
0218 #include <scsi/scsi_eh.h>
0219 #include "3w-xxxx.h"
0220 
0221 /* Globals */
0222 #define TW_DRIVER_VERSION "1.26.02.003"
0223 static DEFINE_MUTEX(tw_mutex);
0224 static TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
0225 static int tw_device_extension_count = 0;
0226 static int twe_major = -1;
0227 
0228 /* Module parameters */
0229 MODULE_AUTHOR("LSI");
0230 MODULE_DESCRIPTION("3ware Storage Controller Linux Driver");
0231 MODULE_LICENSE("GPL");
0232 MODULE_VERSION(TW_DRIVER_VERSION);
0233 
0234 /* Function prototypes */
0235 static int tw_reset_device_extension(TW_Device_Extension *tw_dev);
0236 
0237 /* Functions */
0238 
0239 /* This function will check the status register for unexpected bits */
0240 static int tw_check_bits(u32 status_reg_value)
0241 {
0242     if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) {
0243         dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value);
0244         return 1;
0245     }
0246     if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0) {
0247         dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): Found unexpected bits (0x%x).\n", status_reg_value);
0248         return 1;
0249     }
0250 
0251     return 0;
0252 } /* End tw_check_bits() */
0253 
0254 /* This function will print readable messages from status register errors */
0255 static int tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value, int print_host)
0256 {
0257     char host[16];
0258 
0259     dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
0260 
0261     if (print_host)
0262         sprintf(host, " scsi%d:", tw_dev->host->host_no);
0263     else
0264         host[0] = '\0';
0265 
0266     if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) {
0267         printk(KERN_WARNING "3w-xxxx:%s PCI Parity Error: clearing.\n", host);
0268         outl(TW_CONTROL_CLEAR_PARITY_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
0269     }
0270 
0271     if (status_reg_value & TW_STATUS_PCI_ABORT) {
0272         printk(KERN_WARNING "3w-xxxx:%s PCI Abort: clearing.\n", host);
0273         outl(TW_CONTROL_CLEAR_PCI_ABORT, TW_CONTROL_REG_ADDR(tw_dev));
0274         pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
0275     }
0276 
0277     if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
0278         printk(KERN_WARNING "3w-xxxx:%s Controller Queue Error: clearing.\n", host);
0279         outl(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
0280     }
0281 
0282     if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) {
0283         printk(KERN_WARNING "3w-xxxx:%s SBUF Write Error: clearing.\n", host);
0284         outl(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
0285     }
0286 
0287     if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
0288         if (tw_dev->reset_print == 0) {
0289             printk(KERN_WARNING "3w-xxxx:%s Microcontroller Error: clearing.\n", host);
0290             tw_dev->reset_print = 1;
0291         }
0292         return 1;
0293     }
0294 
0295     return 0;
0296 } /* End tw_decode_bits() */
0297 
0298 /* This function will poll the status register for a flag */
0299 static int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
0300 {
0301     u32 status_reg_value;
0302     unsigned long before;
0303     int retval = 1;
0304 
0305     status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
0306     before = jiffies;
0307 
0308     if (tw_check_bits(status_reg_value))
0309         tw_decode_bits(tw_dev, status_reg_value, 0);
0310 
0311     while ((status_reg_value & flag) != flag) {
0312         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
0313 
0314         if (tw_check_bits(status_reg_value))
0315             tw_decode_bits(tw_dev, status_reg_value, 0);
0316 
0317         if (time_after(jiffies, before + HZ * seconds))
0318             goto out;
0319 
0320         msleep(50);
0321     }
0322     retval = 0;
0323 out:
0324     return retval;
0325 } /* End tw_poll_status() */
0326 
0327 /* This function will poll the status register for disappearance of a flag */
0328 static int tw_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
0329 {
0330     u32 status_reg_value;
0331     unsigned long before;
0332     int retval = 1;
0333 
0334     status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
0335     before = jiffies;
0336 
0337     if (tw_check_bits(status_reg_value))
0338         tw_decode_bits(tw_dev, status_reg_value, 0);
0339 
0340     while ((status_reg_value & flag) != 0) {
0341         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
0342 
0343         if (tw_check_bits(status_reg_value))
0344             tw_decode_bits(tw_dev, status_reg_value, 0);
0345 
0346         if (time_after(jiffies, before + HZ * seconds))
0347             goto out;
0348 
0349         msleep(50);
0350     }
0351     retval = 0;
0352 out:
0353     return retval;
0354 } /* End tw_poll_status_gone() */
0355 
0356 /* This function will attempt to post a command packet to the board */
0357 static int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
0358 {
0359     u32 status_reg_value;
0360     unsigned long command_que_value;
0361 
0362     dprintk(KERN_NOTICE "3w-xxxx: tw_post_command_packet()\n");
0363     command_que_value = tw_dev->command_packet_physical_address[request_id];
0364     status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
0365 
0366     if (tw_check_bits(status_reg_value)) {
0367         dprintk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
0368         tw_decode_bits(tw_dev, status_reg_value, 1);
0369     }
0370 
0371     if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
0372         /* We successfully posted the command packet */
0373         outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
0374         tw_dev->state[request_id] = TW_S_POSTED;
0375         tw_dev->posted_request_count++;
0376         if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
0377             tw_dev->max_posted_request_count = tw_dev->posted_request_count;
0378         }
0379     } else {
0380         /* Couldn't post the command packet, so we do it in the isr */
0381         if (tw_dev->state[request_id] != TW_S_PENDING) {
0382             tw_dev->state[request_id] = TW_S_PENDING;
0383             tw_dev->pending_request_count++;
0384             if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
0385                 tw_dev->max_pending_request_count = tw_dev->pending_request_count;
0386             }
0387             tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
0388             if (tw_dev->pending_tail == TW_Q_LENGTH-1) {
0389                 tw_dev->pending_tail = TW_Q_START;
0390             } else {
0391                 tw_dev->pending_tail = tw_dev->pending_tail + 1;
0392             }
0393         }
0394         TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
0395         return 1;
0396     }
0397     return 0;
0398 } /* End tw_post_command_packet() */
0399 
0400 /* This function will return valid sense buffer information for failed cmds */
0401 static int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill_sense)
0402 {
0403     int i;
0404     TW_Command *command;
0405 
0406     dprintk(KERN_WARNING "3w-xxxx: tw_decode_sense()\n");
0407     command = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
0408 
0409     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));
0410 
0411     /* Attempt to return intelligent sense information */
0412     if (fill_sense) {
0413         if ((command->status == 0xc7) || (command->status == 0xcb)) {
0414             for (i = 0; i < ARRAY_SIZE(tw_sense_table); i++) {
0415                 if (command->flags == tw_sense_table[i][0]) {
0416 
0417                     /* Valid bit and 'current errors' */
0418                     tw_dev->srb[request_id]->sense_buffer[0] = (0x1 << 7 | 0x70);
0419 
0420                     /* Sense key */
0421                     tw_dev->srb[request_id]->sense_buffer[2] = tw_sense_table[i][1];
0422 
0423                     /* Additional sense length */
0424                     tw_dev->srb[request_id]->sense_buffer[7] = 0xa; /* 10 bytes */
0425 
0426                     /* Additional sense code */
0427                     tw_dev->srb[request_id]->sense_buffer[12] = tw_sense_table[i][2];
0428 
0429                     /* Additional sense code qualifier */
0430                     tw_dev->srb[request_id]->sense_buffer[13] = tw_sense_table[i][3];
0431 
0432                     tw_dev->srb[request_id]->result = (DID_OK << 16) | SAM_STAT_CHECK_CONDITION;
0433                     return TW_ISR_DONT_RESULT; /* Special case for isr to not over-write result */
0434                 }
0435             }
0436         }
0437 
0438         /* If no table match, error so we get a reset */
0439         return 1;
0440     }
0441 
0442     return 0;
0443 } /* End tw_decode_sense() */
0444 
0445 /* This function will report controller error status */
0446 static int tw_check_errors(TW_Device_Extension *tw_dev)
0447 {
0448     u32 status_reg_value;
0449 
0450     status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
0451 
0452     if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value)) {
0453         tw_decode_bits(tw_dev, status_reg_value, 0);
0454         return 1;
0455     }
0456 
0457     return 0;
0458 } /* End tw_check_errors() */
0459 
0460 /* This function will empty the response que */
0461 static void tw_empty_response_que(TW_Device_Extension *tw_dev)
0462 {
0463     u32 status_reg_value;
0464 
0465     status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
0466 
0467     while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
0468         inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
0469         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
0470     }
0471 } /* End tw_empty_response_que() */
0472 
0473 /* This function will free a request_id */
0474 static void tw_state_request_finish(TW_Device_Extension *tw_dev, int request_id)
0475 {
0476     tw_dev->free_queue[tw_dev->free_tail] = request_id;
0477     tw_dev->state[request_id] = TW_S_FINISHED;
0478     tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
0479 } /* End tw_state_request_finish() */
0480 
0481 /* This function will assign an available request_id */
0482 static void tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id)
0483 {
0484     *request_id = tw_dev->free_queue[tw_dev->free_head];
0485     tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
0486     tw_dev->state[*request_id] = TW_S_STARTED;
0487 } /* End tw_state_request_start() */
0488 
0489 /* Show some statistics about the card */
0490 static ssize_t tw_show_stats(struct device *dev, struct device_attribute *attr,
0491                  char *buf)
0492 {
0493     struct Scsi_Host *host = class_to_shost(dev);
0494     TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
0495     unsigned long flags = 0;
0496     ssize_t len;
0497 
0498     spin_lock_irqsave(tw_dev->host->host_lock, flags);
0499     len = snprintf(buf, PAGE_SIZE, "3w-xxxx Driver version: %s\n"
0500                "Current commands posted:   %4d\n"
0501                "Max commands posted:       %4d\n"
0502                "Current pending commands:  %4d\n"
0503                "Max pending commands:      %4d\n"
0504                "Last sgl length:           %4d\n"
0505                "Max sgl length:            %4d\n"
0506                "Last sector count:         %4d\n"
0507                "Max sector count:          %4d\n"
0508                "SCSI Host Resets:          %4d\n"
0509                "AEN's:                     %4d\n", 
0510                TW_DRIVER_VERSION,
0511                tw_dev->posted_request_count,
0512                tw_dev->max_posted_request_count,
0513                tw_dev->pending_request_count,
0514                tw_dev->max_pending_request_count,
0515                tw_dev->sgl_entries,
0516                tw_dev->max_sgl_entries,
0517                tw_dev->sector_count,
0518                tw_dev->max_sector_count,
0519                tw_dev->num_resets,
0520                tw_dev->aen_count);
0521     spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
0522     return len;
0523 } /* End tw_show_stats() */
0524 
0525 /* Create sysfs 'stats' entry */
0526 static struct device_attribute tw_host_stats_attr = {
0527     .attr = {
0528         .name =     "stats",
0529         .mode =     S_IRUGO,
0530     },
0531     .show = tw_show_stats
0532 };
0533 
0534 /* Host attributes initializer */
0535 static struct attribute *tw_host_attrs[] = {
0536     &tw_host_stats_attr.attr,
0537     NULL,
0538 };
0539 
0540 ATTRIBUTE_GROUPS(tw_host);
0541 
0542 /* This function will read the aen queue from the isr */
0543 static int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
0544 {
0545     TW_Command *command_packet;
0546     TW_Param *param;
0547     unsigned long command_que_value;
0548     u32 status_reg_value;
0549     unsigned long param_value = 0;
0550 
0551     dprintk(KERN_NOTICE "3w-xxxx: tw_aen_read_queue()\n");
0552 
0553     status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
0554     if (tw_check_bits(status_reg_value)) {
0555         dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
0556         tw_decode_bits(tw_dev, status_reg_value, 1);
0557         return 1;
0558     }
0559     if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
0560         printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet virtual address.\n");
0561         return 1;
0562     }
0563     command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
0564     memset(command_packet, 0, sizeof(TW_Sector));
0565     command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
0566     command_packet->size = 4;
0567     command_packet->request_id = request_id;
0568     command_packet->status = 0;
0569     command_packet->flags = 0;
0570     command_packet->byte6.parameter_count = 1;
0571     command_que_value = tw_dev->command_packet_physical_address[request_id];
0572     if (command_que_value == 0) {
0573         printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet physical address.\n");
0574         return 1;
0575     }
0576     /* Now setup the param */
0577     if (tw_dev->alignment_virtual_address[request_id] == NULL) {
0578         printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment virtual address.\n");
0579         return 1;
0580     }
0581     param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
0582     memset(param, 0, sizeof(TW_Sector));
0583     param->table_id = 0x401; /* AEN table */
0584     param->parameter_id = 2; /* Unit code */
0585     param->parameter_size_bytes = 2;
0586     param_value = tw_dev->alignment_physical_address[request_id];
0587     if (param_value == 0) {
0588         printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment physical address.\n");
0589         return 1;
0590     }
0591     command_packet->byte8.param.sgl[0].address = param_value;
0592     command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
0593 
0594     /* Now post the command packet */
0595     if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
0596         dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post succeeded.\n");
0597         tw_dev->srb[request_id] = NULL; /* Flag internal command */
0598         tw_dev->state[request_id] = TW_S_POSTED;
0599         outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
0600     } else {
0601         printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post failed, will retry.\n");
0602         return 1;
0603     }
0604 
0605     return 0;
0606 } /* End tw_aen_read_queue() */
0607 
0608 /* This function will complete an aen request from the isr */
0609 static int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
0610 {
0611     TW_Param *param;
0612     unsigned short aen;
0613     int error = 0, table_max = 0;
0614 
0615     dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
0616     if (tw_dev->alignment_virtual_address[request_id] == NULL) {
0617         printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
0618         return 1;
0619     }
0620     param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
0621     aen = *(unsigned short *)(param->data);
0622     dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
0623 
0624     /* Print some useful info when certain aen codes come out */
0625     if (aen == 0x0ff) {
0626         printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: INFO: AEN queue overflow.\n", tw_dev->host->host_no);
0627     } else {
0628         table_max = ARRAY_SIZE(tw_aen_string);
0629         if ((aen & 0x0ff) < table_max) {
0630             if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
0631                 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8);
0632             } else {
0633                 if (aen != 0x0)
0634                     printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff]);
0635             }
0636         } else {
0637             printk(KERN_WARNING "3w-xxxx: scsi%d: Received AEN %d.\n", tw_dev->host->host_no, aen);
0638         }
0639     }
0640     if (aen != TW_AEN_QUEUE_EMPTY) {
0641         tw_dev->aen_count++;
0642 
0643         /* Now queue the code */
0644         tw_dev->aen_queue[tw_dev->aen_tail] = aen;
0645         if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
0646             tw_dev->aen_tail = TW_Q_START;
0647         } else {
0648             tw_dev->aen_tail = tw_dev->aen_tail + 1;
0649         }
0650         if (tw_dev->aen_head == tw_dev->aen_tail) {
0651             if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
0652                 tw_dev->aen_head = TW_Q_START;
0653             } else {
0654                 tw_dev->aen_head = tw_dev->aen_head + 1;
0655             }
0656         }
0657 
0658         error = tw_aen_read_queue(tw_dev, request_id);
0659         if (error) {
0660             printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing AEN.\n", tw_dev->host->host_no);
0661             tw_dev->state[request_id] = TW_S_COMPLETED;
0662             tw_state_request_finish(tw_dev, request_id);
0663         }
0664     } else {
0665         tw_dev->state[request_id] = TW_S_COMPLETED;
0666         tw_state_request_finish(tw_dev, request_id);
0667     }
0668 
0669     return 0;
0670 } /* End tw_aen_complete() */
0671 
0672 /* This function will drain the aen queue after a soft reset */
0673 static int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
0674 {
0675     TW_Command *command_packet;
0676     TW_Param *param;
0677     int request_id = 0;
0678     unsigned long command_que_value;
0679     unsigned long param_value;
0680     TW_Response_Queue response_queue;
0681     unsigned short aen;
0682     unsigned short aen_code;
0683     int finished = 0;
0684     int first_reset = 0;
0685     int queue = 0;
0686     int found = 0, table_max = 0;
0687 
0688     dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n");
0689 
0690     if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT | TW_STATUS_MICROCONTROLLER_READY, 30)) {
0691         dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d.\n", tw_device_extension_count);
0692         return 1;
0693     }
0694     TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
0695 
0696     /* Empty response queue */
0697     tw_empty_response_que(tw_dev);
0698 
0699     /* Initialize command packet */
0700     if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
0701         printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet virtual address.\n");
0702         return 1;
0703     }
0704     command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
0705     memset(command_packet, 0, sizeof(TW_Sector));
0706     command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
0707     command_packet->size = 4;
0708     command_packet->request_id = request_id;
0709     command_packet->status = 0;
0710     command_packet->flags = 0;
0711     command_packet->byte6.parameter_count = 1;
0712     command_que_value = tw_dev->command_packet_physical_address[request_id];
0713     if (command_que_value == 0) {
0714         printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet physical address.\n");
0715         return 1;
0716     }
0717 
0718     /* Now setup the param */
0719     if (tw_dev->alignment_virtual_address[request_id] == NULL) {
0720         printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment virtual address.\n");
0721         return 1;
0722     }
0723     param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
0724     memset(param, 0, sizeof(TW_Sector));
0725     param->table_id = 0x401; /* AEN table */
0726     param->parameter_id = 2; /* Unit code */
0727     param->parameter_size_bytes = 2;
0728     param_value = tw_dev->alignment_physical_address[request_id];
0729     if (param_value == 0) {
0730         printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment physical address.\n");
0731         return 1;
0732     }
0733     command_packet->byte8.param.sgl[0].address = param_value;
0734     command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
0735 
0736     /* Now drain the controller's aen queue */
0737     do {
0738         /* Post command packet */
0739         outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
0740 
0741         /* Now poll for completion */
0742         if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
0743             response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
0744             request_id = TW_RESID_OUT(response_queue.response_id);
0745 
0746             if (request_id != 0) {
0747                 /* Unexpected request id */
0748                 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected request id.\n");
0749                 return 1;
0750             }
0751 
0752             if (command_packet->status != 0) {
0753                 if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
0754                     /* Bad response */
0755                     tw_decode_sense(tw_dev, request_id, 0);
0756                     return 1;
0757                 } else {
0758                     /* We know this is a 3w-1x00, and doesn't support aen's */
0759                     return 0;
0760                 }
0761             }
0762 
0763             /* Now check the aen */
0764             aen = *(unsigned short *)(param->data);
0765             aen_code = (aen & 0x0ff);
0766             queue = 0;
0767             switch (aen_code) {
0768                 case TW_AEN_QUEUE_EMPTY:
0769                     dprintk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
0770                     if (first_reset != 1) {
0771                         return 1;
0772                     } else {
0773                         finished = 1;
0774                     }
0775                     break;
0776                 case TW_AEN_SOFT_RESET:
0777                     if (first_reset == 0) {
0778                         first_reset = 1;
0779                     } else {
0780                         printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
0781                         tw_dev->aen_count++;
0782                         queue = 1;
0783                     }
0784                     break;
0785                 default:
0786                     if (aen == 0x0ff) {
0787                         printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n");
0788                     } else {
0789                         table_max = ARRAY_SIZE(tw_aen_string);
0790                         if ((aen & 0x0ff) < table_max) {
0791                             if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
0792                                 printk(KERN_WARNING "3w-xxxx: AEN: %s%d.\n", tw_aen_string[aen & 0xff], aen >> 8);
0793                             } else {
0794                                 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
0795                             }
0796                         } else
0797                             printk(KERN_WARNING "3w-xxxx: Received AEN %d.\n", aen);
0798                     }
0799                     tw_dev->aen_count++;
0800                     queue = 1;
0801             }
0802 
0803             /* Now put the aen on the aen_queue */
0804             if (queue == 1) {
0805                 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
0806                 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
0807                     tw_dev->aen_tail = TW_Q_START;
0808                 } else {
0809                     tw_dev->aen_tail = tw_dev->aen_tail + 1;
0810                 }
0811                 if (tw_dev->aen_head == tw_dev->aen_tail) {
0812                     if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
0813                         tw_dev->aen_head = TW_Q_START;
0814                     } else {
0815                         tw_dev->aen_head = tw_dev->aen_head + 1;
0816                     }
0817                 }
0818             }
0819             found = 1;
0820         }
0821         if (found == 0) {
0822             printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Response never received.\n");
0823             return 1;
0824         }
0825     } while (finished == 0);
0826 
0827     return 0;
0828 } /* End tw_aen_drain_queue() */
0829 
0830 /* This function will allocate memory */
0831 static int tw_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
0832 {
0833     int i;
0834     dma_addr_t dma_handle;
0835     unsigned long *cpu_addr = NULL;
0836 
0837     dprintk(KERN_NOTICE "3w-xxxx: tw_allocate_memory()\n");
0838 
0839     cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev,
0840             size * TW_Q_LENGTH, &dma_handle, GFP_KERNEL);
0841     if (cpu_addr == NULL) {
0842         printk(KERN_WARNING "3w-xxxx: dma_alloc_coherent() failed.\n");
0843         return 1;
0844     }
0845 
0846     if ((unsigned long)cpu_addr % (tw_dev->tw_pci_dev->device == TW_DEVICE_ID ? TW_ALIGNMENT_6000 : TW_ALIGNMENT_7000)) {
0847         printk(KERN_WARNING "3w-xxxx: Couldn't allocate correctly aligned memory.\n");
0848         dma_free_coherent(&tw_dev->tw_pci_dev->dev, size * TW_Q_LENGTH,
0849                 cpu_addr, dma_handle);
0850         return 1;
0851     }
0852 
0853     memset(cpu_addr, 0, size*TW_Q_LENGTH);
0854 
0855     for (i=0;i<TW_Q_LENGTH;i++) {
0856         switch(which) {
0857         case 0:
0858             tw_dev->command_packet_physical_address[i] = dma_handle+(i*size);
0859             tw_dev->command_packet_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
0860             break;
0861         case 1:
0862             tw_dev->alignment_physical_address[i] = dma_handle+(i*size);
0863             tw_dev->alignment_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
0864             break;
0865         default:
0866             printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): case slip in tw_allocate_memory()\n");
0867             return 1;
0868         }
0869     }
0870 
0871     return 0;
0872 } /* End tw_allocate_memory() */
0873 
0874 /* This function handles ioctl for the character device */
0875 static long tw_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
0876 {
0877     int request_id;
0878     dma_addr_t dma_handle;
0879     unsigned short tw_aen_code;
0880     unsigned long flags;
0881     unsigned int data_buffer_length = 0;
0882     unsigned long data_buffer_length_adjusted = 0;
0883     struct inode *inode = file_inode(file);
0884     unsigned long *cpu_addr;
0885     long timeout;
0886     TW_New_Ioctl *tw_ioctl;
0887     TW_Passthru *passthru;
0888     TW_Device_Extension *tw_dev = tw_device_extension_list[iminor(inode)];
0889     int retval = -EFAULT;
0890     void __user *argp = (void __user *)arg;
0891 
0892     dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n");
0893 
0894     mutex_lock(&tw_mutex);
0895     /* Only let one of these through at a time */
0896     if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
0897         mutex_unlock(&tw_mutex);
0898         return -EINTR;
0899     }
0900 
0901     /* First copy down the buffer length */
0902     if (copy_from_user(&data_buffer_length, argp, sizeof(unsigned int)))
0903         goto out;
0904 
0905     /* Check size */
0906     if (data_buffer_length > TW_MAX_IOCTL_SECTORS * 512) {
0907         retval = -EINVAL;
0908         goto out;
0909     }
0910 
0911     /* Hardware can only do multiple of 512 byte transfers */
0912     data_buffer_length_adjusted = (data_buffer_length + 511) & ~511;
0913 
0914     /* Now allocate ioctl buf memory */
0915     cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle, GFP_KERNEL);
0916     if (cpu_addr == NULL) {
0917         retval = -ENOMEM;
0918         goto out;
0919     }
0920 
0921     tw_ioctl = (TW_New_Ioctl *)cpu_addr;
0922 
0923     /* Now copy down the entire ioctl */
0924     if (copy_from_user(tw_ioctl, argp, data_buffer_length + sizeof(TW_New_Ioctl) - 1))
0925         goto out2;
0926 
0927     passthru = (TW_Passthru *)&tw_ioctl->firmware_command;
0928 
0929     /* See which ioctl we are doing */
0930     switch (cmd) {
0931         case TW_OP_NOP:
0932             dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_OP_NOP.\n");
0933             break;
0934         case TW_OP_AEN_LISTEN:
0935             dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_AEN_LISTEN.\n");
0936             memset(tw_ioctl->data_buffer, 0, data_buffer_length);
0937 
0938             spin_lock_irqsave(tw_dev->host->host_lock, flags);
0939             if (tw_dev->aen_head == tw_dev->aen_tail) {
0940                 tw_aen_code = TW_AEN_QUEUE_EMPTY;
0941             } else {
0942                 tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
0943                 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
0944                     tw_dev->aen_head = TW_Q_START;
0945                 } else {
0946                     tw_dev->aen_head = tw_dev->aen_head + 1;
0947                 }
0948             }
0949             spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
0950             memcpy(tw_ioctl->data_buffer, &tw_aen_code, sizeof(tw_aen_code));
0951             break;
0952         case TW_CMD_PACKET_WITH_DATA:
0953             dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n");
0954             spin_lock_irqsave(tw_dev->host->host_lock, flags);
0955 
0956             tw_state_request_start(tw_dev, &request_id);
0957 
0958             /* Flag internal command */
0959             tw_dev->srb[request_id] = NULL;
0960 
0961             /* Flag chrdev ioctl */
0962             tw_dev->chrdev_request_id = request_id;
0963 
0964             tw_ioctl->firmware_command.request_id = request_id;
0965 
0966             /* Load the sg list */
0967             switch (TW_SGL_OUT(tw_ioctl->firmware_command.opcode__sgloffset)) {
0968             case 2:
0969                 tw_ioctl->firmware_command.byte8.param.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
0970                 tw_ioctl->firmware_command.byte8.param.sgl[0].length = data_buffer_length_adjusted;
0971                 break;
0972             case 3:
0973                 tw_ioctl->firmware_command.byte8.io.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
0974                 tw_ioctl->firmware_command.byte8.io.sgl[0].length = data_buffer_length_adjusted;
0975                 break;
0976             case 5:
0977                 passthru->sg_list[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
0978                 passthru->sg_list[0].length = data_buffer_length_adjusted;
0979                 break;
0980             }
0981 
0982             memcpy(tw_dev->command_packet_virtual_address[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command));
0983 
0984             /* Now post the command packet to the controller */
0985             tw_post_command_packet(tw_dev, request_id);
0986             spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
0987 
0988             timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
0989 
0990             /* Now wait for the command to complete */
0991             timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
0992 
0993             /* We timed out, and didn't get an interrupt */
0994             if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
0995                 /* Now we need to reset the board */
0996                 printk(KERN_WARNING "3w-xxxx: scsi%d: Character ioctl (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, cmd);
0997                 retval = -EIO;
0998                 if (tw_reset_device_extension(tw_dev)) {
0999                     printk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): Reset failed for card %d.\n", tw_dev->host->host_no);
1000                 }
1001                 goto out2;
1002             }
1003 
1004             /* Now copy in the command packet response */
1005             memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
1006 
1007             /* Now complete the io */
1008             spin_lock_irqsave(tw_dev->host->host_lock, flags);
1009             tw_dev->posted_request_count--;
1010             tw_dev->state[request_id] = TW_S_COMPLETED;
1011             tw_state_request_finish(tw_dev, request_id);
1012             spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1013             break;
1014         default:
1015             retval = -ENOTTY;
1016             goto out2;
1017     }
1018 
1019     /* Now copy the response to userspace */
1020     if (copy_to_user(argp, tw_ioctl, sizeof(TW_New_Ioctl) + data_buffer_length - 1))
1021         goto out2;
1022     retval = 0;
1023 out2:
1024     /* Now free ioctl buf memory */
1025     dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle);
1026 out:
1027     mutex_unlock(&tw_dev->ioctl_lock);
1028     mutex_unlock(&tw_mutex);
1029     return retval;
1030 } /* End tw_chrdev_ioctl() */
1031 
1032 /* This function handles open for the character device */
1033 /* NOTE that this function races with remove. */
1034 static int tw_chrdev_open(struct inode *inode, struct file *file)
1035 {
1036     unsigned int minor_number;
1037 
1038     dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n");
1039 
1040     if (!capable(CAP_SYS_ADMIN))
1041         return -EACCES;
1042 
1043     minor_number = iminor(inode);
1044     if (minor_number >= tw_device_extension_count)
1045         return -ENODEV;
1046 
1047     return 0;
1048 } /* End tw_chrdev_open() */
1049 
1050 /* File operations struct for character device */
1051 static const struct file_operations tw_fops = {
1052     .owner      = THIS_MODULE,
1053     .unlocked_ioctl = tw_chrdev_ioctl,
1054     .compat_ioctl   = compat_ptr_ioctl,
1055     .open       = tw_chrdev_open,
1056     .release    = NULL,
1057     .llseek     = noop_llseek,
1058 };
1059 
1060 /* This function will free up device extension resources */
1061 static void tw_free_device_extension(TW_Device_Extension *tw_dev)
1062 {
1063     dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n");
1064 
1065     /* Free command packet and generic buffer memory */
1066     if (tw_dev->command_packet_virtual_address[0])
1067         dma_free_coherent(&tw_dev->tw_pci_dev->dev,
1068                 sizeof(TW_Command) * TW_Q_LENGTH,
1069                 tw_dev->command_packet_virtual_address[0],
1070                 tw_dev->command_packet_physical_address[0]);
1071 
1072     if (tw_dev->alignment_virtual_address[0])
1073         dma_free_coherent(&tw_dev->tw_pci_dev->dev,
1074                 sizeof(TW_Sector) * TW_Q_LENGTH,
1075                 tw_dev->alignment_virtual_address[0],
1076                 tw_dev->alignment_physical_address[0]);
1077 } /* End tw_free_device_extension() */
1078 
1079 /* This function will send an initconnection command to controller */
1080 static int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
1081 {
1082     unsigned long command_que_value;
1083     TW_Command  *command_packet;
1084     TW_Response_Queue response_queue;
1085     int request_id = 0;
1086 
1087     dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n");
1088 
1089     /* Initialize InitConnection command packet */
1090     if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
1091         printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet virtual address.\n");
1092         return 1;
1093     }
1094 
1095     command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1096     memset(command_packet, 0, sizeof(TW_Sector));
1097     command_packet->opcode__sgloffset = TW_OPSGL_IN(0, TW_OP_INIT_CONNECTION);
1098     command_packet->size = TW_INIT_COMMAND_PACKET_SIZE;
1099     command_packet->request_id = request_id;
1100     command_packet->status = 0x0;
1101     command_packet->flags = 0x0;
1102     command_packet->byte6.message_credits = message_credits; 
1103     command_packet->byte8.init_connection.response_queue_pointer = 0x0;
1104     command_que_value = tw_dev->command_packet_physical_address[request_id];
1105 
1106     if (command_que_value == 0) {
1107         printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n");
1108         return 1;
1109     }
1110 
1111     /* Send command packet to the board */
1112     outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
1113 
1114     /* Poll for completion */
1115     if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1116         response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1117         request_id = TW_RESID_OUT(response_queue.response_id);
1118 
1119         if (request_id != 0) {
1120             /* unexpected request id */
1121             printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
1122             return 1;
1123         }
1124         if (command_packet->status != 0) {
1125             /* bad response */
1126             tw_decode_sense(tw_dev, request_id, 0);
1127             return 1;
1128         }
1129     }
1130     return 0;
1131 } /* End tw_initconnection() */
1132 
1133 /* Set a value in the features table */
1134 static int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
1135              unsigned char *val)
1136 {
1137     TW_Param *param;
1138     TW_Command  *command_packet;
1139     TW_Response_Queue response_queue;
1140     int request_id = 0;
1141     unsigned long command_que_value;
1142     unsigned long param_value;
1143 
1144     /* Initialize SetParam command packet */
1145     if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
1146         printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
1147         return 1;
1148     }
1149     command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1150     memset(command_packet, 0, sizeof(TW_Sector));
1151     param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1152 
1153     command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
1154     param->table_id = 0x404;  /* Features table */
1155     param->parameter_id = parm;
1156     param->parameter_size_bytes = param_size;
1157     memcpy(param->data, val, param_size);
1158 
1159     param_value = tw_dev->alignment_physical_address[request_id];
1160     if (param_value == 0) {
1161         printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad alignment physical address.\n");
1162         tw_dev->state[request_id] = TW_S_COMPLETED;
1163         tw_state_request_finish(tw_dev, request_id);
1164         tw_dev->srb[request_id]->result = (DID_OK << 16);
1165         scsi_done(tw_dev->srb[request_id]);
1166     }
1167     command_packet->byte8.param.sgl[0].address = param_value;
1168     command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1169 
1170     command_packet->size = 4;
1171     command_packet->request_id = request_id;
1172     command_packet->byte6.parameter_count = 1;
1173 
1174     command_que_value = tw_dev->command_packet_physical_address[request_id];
1175     if (command_que_value == 0) {
1176         printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
1177         return 1;
1178     }
1179 
1180     /* Send command packet to the board */
1181     outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
1182 
1183     /* Poll for completion */
1184     if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1185         response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1186         request_id = TW_RESID_OUT(response_queue.response_id);
1187 
1188         if (request_id != 0) {
1189             /* unexpected request id */
1190             printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
1191             return 1;
1192         }
1193         if (command_packet->status != 0) {
1194             /* bad response */
1195             tw_decode_sense(tw_dev, request_id, 0);
1196             return 1;
1197         }
1198     }
1199 
1200     return 0;
1201 } /* End tw_setfeature() */
1202 
1203 /* This function will reset a controller */
1204 static int tw_reset_sequence(TW_Device_Extension *tw_dev)
1205 {
1206     int error = 0;
1207     int tries = 0;
1208     unsigned char c = 1;
1209 
1210     /* Reset the board */
1211     while (tries < TW_MAX_RESET_TRIES) {
1212         TW_SOFT_RESET(tw_dev);
1213 
1214         error = tw_aen_drain_queue(tw_dev);
1215         if (error) {
1216             printk(KERN_WARNING "3w-xxxx: scsi%d: AEN drain failed, retrying.\n", tw_dev->host->host_no);
1217             tries++;
1218             continue;
1219         }
1220 
1221         /* Check for controller errors */
1222         if (tw_check_errors(tw_dev)) {
1223             printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors found, retrying.\n", tw_dev->host->host_no);
1224             tries++;
1225             continue;
1226         }
1227 
1228         /* Now the controller is in a good state */
1229         break;
1230     }
1231 
1232     if (tries >= TW_MAX_RESET_TRIES) {
1233         printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors, card not responding, check all cabling.\n", tw_dev->host->host_no);
1234         return 1;
1235     }
1236 
1237     error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
1238     if (error) {
1239         printk(KERN_WARNING "3w-xxxx: scsi%d: Connection initialization failed.\n", tw_dev->host->host_no);
1240         return 1;
1241     }
1242 
1243     error = tw_setfeature(tw_dev, 2, 1, &c);
1244     if (error) {
1245         printk(KERN_WARNING "3w-xxxx: Unable to set features for card, probable old firmware or card.\n");
1246     }
1247 
1248     return 0;
1249 } /* End tw_reset_sequence() */
1250 
1251 /* This function will initialize the fields of a device extension */
1252 static int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
1253 {
1254     int i, error=0;
1255 
1256     dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_device_extension()\n");
1257 
1258     /* Initialize command packet buffers */
1259     error = tw_allocate_memory(tw_dev, sizeof(TW_Command), 0);
1260     if (error) {
1261         printk(KERN_WARNING "3w-xxxx: Command packet memory allocation failed.\n");
1262         return 1;
1263     }
1264 
1265     /* Initialize generic buffer */
1266     error = tw_allocate_memory(tw_dev, sizeof(TW_Sector), 1);
1267     if (error) {
1268         printk(KERN_WARNING "3w-xxxx: Generic memory allocation failed.\n");
1269         return 1;
1270     }
1271 
1272     for (i=0;i<TW_Q_LENGTH;i++) {
1273         tw_dev->free_queue[i] = i;
1274         tw_dev->state[i] = TW_S_INITIAL;
1275     }
1276 
1277     tw_dev->pending_head = TW_Q_START;
1278     tw_dev->pending_tail = TW_Q_START;
1279     tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1280 
1281     mutex_init(&tw_dev->ioctl_lock);
1282     init_waitqueue_head(&tw_dev->ioctl_wqueue);
1283 
1284     return 0;
1285 } /* End tw_initialize_device_extension() */
1286 
1287 /* This function will reset a device extension */
1288 static int tw_reset_device_extension(TW_Device_Extension *tw_dev)
1289 {
1290     int i = 0;
1291     struct scsi_cmnd *srb;
1292     unsigned long flags = 0;
1293 
1294     dprintk(KERN_NOTICE "3w-xxxx: tw_reset_device_extension()\n");
1295 
1296     set_bit(TW_IN_RESET, &tw_dev->flags);
1297     TW_DISABLE_INTERRUPTS(tw_dev);
1298     TW_MASK_COMMAND_INTERRUPT(tw_dev);
1299     spin_lock_irqsave(tw_dev->host->host_lock, flags);
1300 
1301     /* Abort all requests that are in progress */
1302     for (i=0;i<TW_Q_LENGTH;i++) {
1303         if ((tw_dev->state[i] != TW_S_FINISHED) &&
1304             (tw_dev->state[i] != TW_S_INITIAL) &&
1305             (tw_dev->state[i] != TW_S_COMPLETED)) {
1306             srb = tw_dev->srb[i];
1307             if (srb != NULL) {
1308                 srb->result = (DID_RESET << 16);
1309                 scsi_dma_unmap(srb);
1310                 scsi_done(srb);
1311             }
1312         }
1313     }
1314 
1315     /* Reset queues and counts */
1316     for (i=0;i<TW_Q_LENGTH;i++) {
1317         tw_dev->free_queue[i] = i;
1318         tw_dev->state[i] = TW_S_INITIAL;
1319     }
1320     tw_dev->free_head = TW_Q_START;
1321     tw_dev->free_tail = TW_Q_START;
1322     tw_dev->posted_request_count = 0;
1323     tw_dev->pending_request_count = 0;
1324     tw_dev->pending_head = TW_Q_START;
1325     tw_dev->pending_tail = TW_Q_START;
1326     tw_dev->reset_print = 0;
1327 
1328     spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1329 
1330     if (tw_reset_sequence(tw_dev)) {
1331         printk(KERN_WARNING "3w-xxxx: scsi%d: Reset sequence failed.\n", tw_dev->host->host_no);
1332         return 1;
1333     }
1334 
1335     TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
1336     clear_bit(TW_IN_RESET, &tw_dev->flags);
1337     tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1338 
1339     return 0;
1340 } /* End tw_reset_device_extension() */
1341 
1342 /* This funciton returns unit geometry in cylinders/heads/sectors */
1343 static int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1344                  sector_t capacity, int geom[])
1345 {
1346     int heads, sectors, cylinders;
1347 
1348     dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n");
1349 
1350     heads = 64;
1351     sectors = 32;
1352     cylinders = sector_div(capacity, heads * sectors);
1353 
1354     if (capacity >= 0x200000) {
1355         heads = 255;
1356         sectors = 63;
1357         cylinders = sector_div(capacity, heads * sectors);
1358     }
1359 
1360     dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam(): heads = %d, sectors = %d, cylinders = %d\n", heads, sectors, cylinders);
1361     geom[0] = heads;
1362     geom[1] = sectors;
1363     geom[2] = cylinders;
1364 
1365     return 0;
1366 } /* End tw_scsi_biosparam() */
1367 
1368 /* This is the new scsi eh reset function */
1369 static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1370 {
1371     TW_Device_Extension *tw_dev=NULL;
1372     int retval = FAILED;
1373 
1374     tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1375 
1376     tw_dev->num_resets++;
1377 
1378     sdev_printk(KERN_WARNING, SCpnt->device,
1379         "WARNING: Command (0x%x) timed out, resetting card.\n",
1380         SCpnt->cmnd[0]);
1381 
1382     /* Make sure we are not issuing an ioctl or resetting from ioctl */
1383     mutex_lock(&tw_dev->ioctl_lock);
1384 
1385     /* Now reset the card and some of the device extension data */
1386     if (tw_reset_device_extension(tw_dev)) {
1387         printk(KERN_WARNING "3w-xxxx: scsi%d: Reset failed.\n", tw_dev->host->host_no);
1388         goto out;
1389     }
1390 
1391     retval = SUCCESS;
1392 out:
1393     mutex_unlock(&tw_dev->ioctl_lock);
1394     return retval;
1395 } /* End tw_scsi_eh_reset() */
1396 
1397 /* This function handles scsi inquiry commands */
1398 static int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
1399 {
1400     TW_Param *param;
1401     TW_Command *command_packet;
1402     unsigned long command_que_value;
1403     unsigned long param_value;
1404 
1405     dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry()\n");
1406 
1407     /* Initialize command packet */
1408     command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1409     if (command_packet == NULL) {
1410         printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet virtual address.\n");
1411         return 1;
1412     }
1413     memset(command_packet, 0, sizeof(TW_Sector));
1414     command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1415     command_packet->size = 4;
1416     command_packet->request_id = request_id;
1417     command_packet->status = 0;
1418     command_packet->flags = 0;
1419     command_packet->byte6.parameter_count = 1;
1420 
1421     /* Now setup the param */
1422     if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1423         printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment virtual address.\n");
1424         return 1;
1425     }
1426     param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1427     memset(param, 0, sizeof(TW_Sector));
1428     param->table_id = 3;     /* unit summary table */
1429     param->parameter_id = 3; /* unitsstatus parameter */
1430     param->parameter_size_bytes = TW_MAX_UNITS;
1431     param_value = tw_dev->alignment_physical_address[request_id];
1432     if (param_value == 0) {
1433         printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment physical address.\n");
1434         return 1;
1435     }
1436 
1437     command_packet->byte8.param.sgl[0].address = param_value;
1438     command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1439     command_que_value = tw_dev->command_packet_physical_address[request_id];
1440     if (command_que_value == 0) {
1441         printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet physical address.\n");
1442         return 1;
1443     }
1444 
1445     /* Now try to post the command packet */
1446     tw_post_command_packet(tw_dev, request_id);
1447 
1448     return 0;
1449 } /* End tw_scsiop_inquiry() */
1450 
1451 static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
1452                  void *data, unsigned int len)
1453 {
1454     scsi_sg_copy_from_buffer(tw_dev->srb[request_id], data, len);
1455 }
1456 
1457 /* This function is called by the isr to complete an inquiry command */
1458 static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
1459 {
1460     unsigned char *is_unit_present;
1461     unsigned char request_buffer[36];
1462     TW_Param *param;
1463 
1464     dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
1465 
1466     memset(request_buffer, 0, sizeof(request_buffer));
1467     request_buffer[0] = TYPE_DISK; /* Peripheral device type */
1468     request_buffer[1] = 0;         /* Device type modifier */
1469     request_buffer[2] = 0;         /* No ansi/iso compliance */
1470     request_buffer[4] = 31;        /* Additional length */
1471     memcpy(&request_buffer[8], "3ware   ", 8);   /* Vendor ID */
1472     sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
1473     memcpy(&request_buffer[32], TW_DRIVER_VERSION, 3);
1474     tw_transfer_internal(tw_dev, request_id, request_buffer,
1475                  sizeof(request_buffer));
1476 
1477     param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1478     if (param == NULL) {
1479         printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Bad alignment virtual address.\n");
1480         return 1;
1481     }
1482     is_unit_present = &(param->data[0]);
1483 
1484     if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
1485         tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 1;
1486     } else {
1487         tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 0;
1488         tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1489         return TW_ISR_DONT_RESULT;
1490     }
1491 
1492     return 0;
1493 } /* End tw_scsiop_inquiry_complete() */
1494 
1495 /* This function handles scsi mode_sense commands */
1496 static int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id)
1497 {
1498     TW_Param *param;
1499     TW_Command *command_packet;
1500     unsigned long command_que_value;
1501     unsigned long param_value;
1502 
1503     dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense()\n");
1504 
1505     /* Only page control = 0, page code = 0x8 (cache page) supported */
1506     if (tw_dev->srb[request_id]->cmnd[2] != 0x8) {
1507         tw_dev->state[request_id] = TW_S_COMPLETED;
1508         tw_state_request_finish(tw_dev, request_id);
1509         tw_dev->srb[request_id]->result = (DID_OK << 16);
1510         scsi_done(tw_dev->srb[request_id]);
1511         return 0;
1512     }
1513 
1514     /* Now read firmware cache setting for this unit */
1515     command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1516     if (command_packet == NULL) {
1517         printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet virtual address.\n");
1518         return 1;
1519     }
1520 
1521     /* Setup the command packet */
1522     memset(command_packet, 0, sizeof(TW_Sector));
1523     command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1524     command_packet->size = 4;
1525     command_packet->request_id = request_id;
1526     command_packet->status = 0;
1527     command_packet->flags = 0;
1528     command_packet->byte6.parameter_count = 1;
1529 
1530     /* Setup the param */
1531     if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1532         printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment virtual address.\n");
1533         return 1;
1534     }
1535 
1536     param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1537     memset(param, 0, sizeof(TW_Sector));
1538     param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->device->id;
1539     param->parameter_id = 7; /* unit flags */
1540     param->parameter_size_bytes = 1;
1541     param_value = tw_dev->alignment_physical_address[request_id];
1542     if (param_value == 0) {
1543         printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment physical address.\n");
1544         return 1;
1545     }
1546 
1547     command_packet->byte8.param.sgl[0].address = param_value;
1548     command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1549     command_que_value = tw_dev->command_packet_physical_address[request_id];
1550     if (command_que_value == 0) {
1551         printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet physical address.\n");
1552         return 1;
1553     }
1554 
1555     /* Now try to post the command packet */
1556     tw_post_command_packet(tw_dev, request_id);
1557 
1558     return 0;
1559 } /* End tw_scsiop_mode_sense() */
1560 
1561 /* This function is called by the isr to complete a mode sense command */
1562 static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int request_id)
1563 {
1564     TW_Param *param;
1565     unsigned char *flags;
1566     unsigned char request_buffer[8];
1567 
1568     dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
1569 
1570     param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1571     if (param == NULL) {
1572         printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense_complete(): Bad alignment virtual address.\n");
1573         return 1;
1574     }
1575     flags = (char *)&(param->data[0]);
1576     memset(request_buffer, 0, sizeof(request_buffer));
1577 
1578     request_buffer[0] = 0xf;    /* mode data length */
1579     request_buffer[1] = 0;      /* default medium type */
1580     request_buffer[2] = 0x10;   /* dpo/fua support on */
1581     request_buffer[3] = 0;      /* no block descriptors */
1582     request_buffer[4] = 0x8;    /* caching page */
1583     request_buffer[5] = 0xa;    /* page length */
1584     if (*flags & 0x1)
1585         request_buffer[6] = 0x5;    /* WCE on, RCD on */
1586     else
1587         request_buffer[6] = 0x1;    /* WCE off, RCD on */
1588     tw_transfer_internal(tw_dev, request_id, request_buffer,
1589                  sizeof(request_buffer));
1590 
1591     return 0;
1592 } /* End tw_scsiop_mode_sense_complete() */
1593 
1594 /* This function handles scsi read_capacity commands */
1595 static int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
1596 {
1597     TW_Param *param;
1598     TW_Command *command_packet;
1599     unsigned long command_que_value;
1600     unsigned long param_value;
1601 
1602     dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n");
1603 
1604     /* Initialize command packet */
1605     command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1606 
1607     if (command_packet == NULL) {
1608         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet virtual address.\n");
1609         return 1;
1610     }
1611     memset(command_packet, 0, sizeof(TW_Sector));
1612     command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1613     command_packet->size = 4;
1614     command_packet->request_id = request_id;
1615     command_packet->unit__hostid = TW_UNITHOST_IN(0, tw_dev->srb[request_id]->device->id);
1616     command_packet->status = 0;
1617     command_packet->flags = 0;
1618     command_packet->byte6.block_count = 1;
1619 
1620     /* Now setup the param */
1621     if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1622         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment virtual address.\n");
1623         return 1;
1624     }
1625     param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1626     memset(param, 0, sizeof(TW_Sector));
1627     param->table_id = TW_UNIT_INFORMATION_TABLE_BASE +
1628         tw_dev->srb[request_id]->device->id;
1629     param->parameter_id = 4;    /* unitcapacity parameter */
1630     param->parameter_size_bytes = 4;
1631     param_value = tw_dev->alignment_physical_address[request_id];
1632     if (param_value == 0) {
1633         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n");
1634         return 1;
1635     }
1636 
1637     command_packet->byte8.param.sgl[0].address = param_value;
1638     command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1639     command_que_value = tw_dev->command_packet_physical_address[request_id];
1640     if (command_que_value == 0) {
1641         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet physical address.\n");
1642         return 1;
1643     }
1644 
1645     /* Now try to post the command to the board */
1646     tw_post_command_packet(tw_dev, request_id);
1647 
1648     return 0;
1649 } /* End tw_scsiop_read_capacity() */
1650 
1651 /* This function is called by the isr to complete a readcapacity command */
1652 static int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id)
1653 {
1654     unsigned char *param_data;
1655     u32 capacity;
1656     char buff[8];
1657     TW_Param *param;
1658 
1659     dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
1660 
1661     memset(buff, 0, sizeof(buff));
1662     param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1663     if (param == NULL) {
1664         printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
1665         return 1;
1666     }
1667     param_data = &(param->data[0]);
1668 
1669     capacity = (param_data[3] << 24) | (param_data[2] << 16) |
1670            (param_data[1] << 8) | param_data[0];
1671 
1672     /* Subtract one sector to fix get last sector ioctl */
1673     capacity -= 1;
1674 
1675     dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete(): Capacity = 0x%x.\n", capacity);
1676 
1677     /* Number of LBA's */
1678     buff[0] = (capacity >> 24);
1679     buff[1] = (capacity >> 16) & 0xff;
1680     buff[2] = (capacity >> 8) & 0xff;
1681     buff[3] = capacity & 0xff;
1682 
1683     /* Block size in bytes (512) */
1684     buff[4] = (TW_BLOCK_SIZE >> 24);
1685     buff[5] = (TW_BLOCK_SIZE >> 16) & 0xff;
1686     buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
1687     buff[7] = TW_BLOCK_SIZE & 0xff;
1688 
1689     tw_transfer_internal(tw_dev, request_id, buff, sizeof(buff));
1690 
1691     return 0;
1692 } /* End tw_scsiop_read_capacity_complete() */
1693 
1694 /* This function handles scsi read or write commands */
1695 static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
1696 {
1697     TW_Command *command_packet;
1698     unsigned long command_que_value;
1699     u32 lba = 0x0, num_sectors = 0x0;
1700     int i, use_sg;
1701     struct scsi_cmnd *srb;
1702     struct scatterlist *sglist, *sg;
1703 
1704     dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
1705 
1706     srb = tw_dev->srb[request_id];
1707 
1708     sglist = scsi_sglist(srb);
1709     if (!sglist) {
1710         printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n");
1711         return 1;
1712     }
1713 
1714     /* Initialize command packet */
1715     command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1716     if (command_packet == NULL) {
1717         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): Bad command packet virtual address.\n");
1718         return 1;
1719     }
1720 
1721     if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == READ_10) {
1722         command_packet->opcode__sgloffset = TW_OPSGL_IN(3, TW_OP_READ);
1723     } else {
1724         command_packet->opcode__sgloffset = TW_OPSGL_IN(3, TW_OP_WRITE);
1725     }
1726 
1727     command_packet->size = 3;
1728     command_packet->request_id = request_id;
1729     command_packet->unit__hostid = TW_UNITHOST_IN(0, srb->device->id);
1730     command_packet->status = 0;
1731     command_packet->flags = 0;
1732 
1733     if (srb->cmnd[0] == WRITE_10) {
1734         if ((srb->cmnd[1] & 0x8) || (srb->cmnd[1] & 0x10))
1735             command_packet->flags = 1;
1736     }
1737 
1738     if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) {
1739         lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3];
1740         num_sectors = (u32)srb->cmnd[4];
1741     } else {
1742         lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
1743         num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
1744     }
1745 
1746     /* Update sector statistic */
1747     tw_dev->sector_count = num_sectors;
1748     if (tw_dev->sector_count > tw_dev->max_sector_count)
1749         tw_dev->max_sector_count = tw_dev->sector_count;
1750 
1751     dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors);
1752     command_packet->byte8.io.lba = lba;
1753     command_packet->byte6.block_count = num_sectors;
1754 
1755     use_sg = scsi_dma_map(srb);
1756     if (use_sg <= 0)
1757         return 1;
1758 
1759     scsi_for_each_sg(tw_dev->srb[request_id], sg, use_sg, i) {
1760         command_packet->byte8.io.sgl[i].address = sg_dma_address(sg);
1761         command_packet->byte8.io.sgl[i].length = sg_dma_len(sg);
1762         command_packet->size+=2;
1763     }
1764 
1765     /* Update SG statistics */
1766     tw_dev->sgl_entries = scsi_sg_count(tw_dev->srb[request_id]);
1767     if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
1768         tw_dev->max_sgl_entries = tw_dev->sgl_entries;
1769 
1770     command_que_value = tw_dev->command_packet_physical_address[request_id];
1771     if (command_que_value == 0) {
1772         dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n");
1773         return 1;
1774     }
1775 
1776     /* Now try to post the command to the board */
1777     tw_post_command_packet(tw_dev, request_id);
1778 
1779     return 0;
1780 } /* End tw_scsiop_read_write() */
1781 
1782 /* This function will handle the request sense scsi command */
1783 static int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
1784 {
1785     char request_buffer[18];
1786 
1787     dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
1788 
1789     memset(request_buffer, 0, sizeof(request_buffer));
1790     request_buffer[0] = 0x70; /* Immediate fixed format */
1791     request_buffer[7] = 10; /* minimum size per SPC: 18 bytes */
1792     /* leave all other fields zero, giving effectively NO_SENSE return */
1793     tw_transfer_internal(tw_dev, request_id, request_buffer,
1794                  sizeof(request_buffer));
1795 
1796     tw_dev->state[request_id] = TW_S_COMPLETED;
1797     tw_state_request_finish(tw_dev, request_id);
1798 
1799     /* If we got a request_sense, we probably want a reset, return error */
1800     tw_dev->srb[request_id]->result = (DID_ERROR << 16);
1801     scsi_done(tw_dev->srb[request_id]);
1802 
1803     return 0;
1804 } /* End tw_scsiop_request_sense() */
1805 
1806 /* This function will handle synchronize cache scsi command */
1807 static int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id)
1808 {
1809     TW_Command *command_packet;
1810     unsigned long command_que_value;
1811 
1812     dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_synchronize_cache()\n");
1813 
1814     /* Send firmware flush command for this unit */
1815     command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1816     if (command_packet == NULL) {
1817         printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet virtual address.\n");
1818         return 1;
1819     }
1820 
1821     /* Setup the command packet */
1822     memset(command_packet, 0, sizeof(TW_Sector));
1823     command_packet->opcode__sgloffset = TW_OPSGL_IN(0, TW_OP_FLUSH_CACHE);
1824     command_packet->size = 2;
1825     command_packet->request_id = request_id;
1826     command_packet->unit__hostid = TW_UNITHOST_IN(0, tw_dev->srb[request_id]->device->id);
1827     command_packet->status = 0;
1828     command_packet->flags = 0;
1829     command_packet->byte6.parameter_count = 1;
1830     command_que_value = tw_dev->command_packet_physical_address[request_id];
1831     if (command_que_value == 0) {
1832         printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet physical address.\n");
1833         return 1;
1834     }
1835 
1836     /* Now try to post the command packet */
1837     tw_post_command_packet(tw_dev, request_id);
1838 
1839     return 0;
1840 } /* End tw_scsiop_synchronize_cache() */
1841 
1842 /* This function will handle test unit ready scsi command */
1843 static int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
1844 {
1845     TW_Param *param;
1846     TW_Command *command_packet;
1847     unsigned long command_que_value;
1848     unsigned long param_value;
1849 
1850     dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n");
1851 
1852     /* Initialize command packet */
1853     command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1854     if (command_packet == NULL) {
1855         printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet virtual address.\n");
1856         return 1;
1857     }
1858     memset(command_packet, 0, sizeof(TW_Sector));
1859     command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1860     command_packet->size = 4;
1861     command_packet->request_id = request_id;
1862     command_packet->status = 0;
1863     command_packet->flags = 0;
1864     command_packet->byte6.parameter_count = 1;
1865 
1866     /* Now setup the param */
1867     if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1868         printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment virtual address.\n");
1869         return 1;
1870     }
1871     param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1872     memset(param, 0, sizeof(TW_Sector));
1873     param->table_id = 3;     /* unit summary table */
1874     param->parameter_id = 3; /* unitsstatus parameter */
1875     param->parameter_size_bytes = TW_MAX_UNITS;
1876     param_value = tw_dev->alignment_physical_address[request_id];
1877     if (param_value == 0) {
1878         printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment physical address.\n");
1879         return 1;
1880     }
1881 
1882     command_packet->byte8.param.sgl[0].address = param_value;
1883     command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1884     command_que_value = tw_dev->command_packet_physical_address[request_id];
1885     if (command_que_value == 0) {
1886         printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet physical address.\n");
1887         return 1;
1888     }
1889 
1890     /* Now try to post the command packet */
1891     tw_post_command_packet(tw_dev, request_id);
1892 
1893     return 0;
1894 } /* End tw_scsiop_test_unit_ready() */
1895 
1896 /* This function is called by the isr to complete a testunitready command */
1897 static int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int request_id)
1898 {
1899     unsigned char *is_unit_present;
1900     TW_Param *param;
1901 
1902     dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete()\n");
1903 
1904     param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1905     if (param == NULL) {
1906         printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete(): Bad alignment virtual address.\n");
1907         return 1;
1908     }
1909     is_unit_present = &(param->data[0]);
1910 
1911     if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
1912         tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 1;
1913     } else {
1914         tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 0;
1915         tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1916         return TW_ISR_DONT_RESULT;
1917     }
1918 
1919     return 0;
1920 } /* End tw_scsiop_test_unit_ready_complete() */
1921 
1922 /* This is the main scsi queue function to handle scsi opcodes */
1923 static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt)
1924 {
1925     void (*done)(struct scsi_cmnd *) = scsi_done;
1926     unsigned char *command = SCpnt->cmnd;
1927     int request_id = 0;
1928     int retval = 1;
1929     TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1930 
1931     /* If we are resetting due to timed out ioctl, report as busy */
1932     if (test_bit(TW_IN_RESET, &tw_dev->flags))
1933         return SCSI_MLQUEUE_HOST_BUSY;
1934 
1935     /* Queue the command and get a request id */
1936     tw_state_request_start(tw_dev, &request_id);
1937 
1938     /* Save the scsi command for use by the ISR */
1939     tw_dev->srb[request_id] = SCpnt;
1940 
1941     switch (*command) {
1942     case READ_10:
1943     case READ_6:
1944     case WRITE_10:
1945     case WRITE_6:
1946         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ/WRITE.\n");
1947         retval = tw_scsiop_read_write(tw_dev, request_id);
1948         break;
1949     case TEST_UNIT_READY:
1950         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
1951         retval = tw_scsiop_test_unit_ready(tw_dev, request_id);
1952         break;
1953     case INQUIRY:
1954         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
1955         retval = tw_scsiop_inquiry(tw_dev, request_id);
1956         break;
1957     case READ_CAPACITY:
1958         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
1959         retval = tw_scsiop_read_capacity(tw_dev, request_id);
1960         break;
1961     case REQUEST_SENSE:
1962         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
1963         retval = tw_scsiop_request_sense(tw_dev, request_id);
1964         break;
1965     case MODE_SENSE:
1966         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught MODE_SENSE.\n");
1967         retval = tw_scsiop_mode_sense(tw_dev, request_id);
1968         break;
1969     case SYNCHRONIZE_CACHE:
1970         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught SYNCHRONIZE_CACHE.\n");
1971         retval = tw_scsiop_synchronize_cache(tw_dev, request_id);
1972         break;
1973     case TW_IOCTL:
1974         printk(KERN_WARNING "3w-xxxx: SCSI_IOCTL_SEND_COMMAND deprecated, please update your 3ware tools.\n");
1975         break;
1976     default:
1977         printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
1978         tw_dev->state[request_id] = TW_S_COMPLETED;
1979         tw_state_request_finish(tw_dev, request_id);
1980         scsi_build_sense(SCpnt, 1, ILLEGAL_REQUEST, 0x20, 0);
1981         done(SCpnt);
1982         retval = 0;
1983     }
1984     if (retval) {
1985         tw_dev->state[request_id] = TW_S_COMPLETED;
1986         tw_state_request_finish(tw_dev, request_id);
1987         SCpnt->result = (DID_ERROR << 16);
1988         done(SCpnt);
1989         retval = 0;
1990     }
1991     return retval;
1992 } /* End tw_scsi_queue() */
1993 
1994 static DEF_SCSI_QCMD(tw_scsi_queue)
1995 
1996 /* This function is the interrupt service routine */
1997 static irqreturn_t tw_interrupt(int irq, void *dev_instance)
1998 {
1999     int request_id;
2000     u32 status_reg_value;
2001     TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
2002     TW_Response_Queue response_que;
2003     int error = 0, retval = 0;
2004     TW_Command *command_packet;
2005     int handled = 0;
2006 
2007     /* Get the host lock for io completions */
2008     spin_lock(tw_dev->host->host_lock);
2009 
2010     /* Read the registers */
2011     status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
2012 
2013     /* Check if this is our interrupt, otherwise bail */
2014     if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
2015         goto tw_interrupt_bail;
2016 
2017     handled = 1;
2018 
2019     /* If we are resetting, bail */
2020     if (test_bit(TW_IN_RESET, &tw_dev->flags))
2021         goto tw_interrupt_bail;
2022 
2023     /* Check controller for errors */
2024     if (tw_check_bits(status_reg_value)) {
2025         dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
2026         if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
2027             TW_CLEAR_ALL_INTERRUPTS(tw_dev);
2028             goto tw_interrupt_bail;
2029         }
2030     }
2031 
2032     /* Handle host interrupt */
2033     if (status_reg_value & TW_STATUS_HOST_INTERRUPT) {
2034         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n");
2035         TW_CLEAR_HOST_INTERRUPT(tw_dev);
2036     }
2037 
2038     /* Handle attention interrupt */
2039     if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
2040         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n");
2041         TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
2042         tw_state_request_start(tw_dev, &request_id);
2043         error = tw_aen_read_queue(tw_dev, request_id);
2044         if (error) {
2045             printk(KERN_WARNING "3w-xxxx: scsi%d: Error reading aen queue.\n", tw_dev->host->host_no);
2046             tw_dev->state[request_id] = TW_S_COMPLETED;
2047             tw_state_request_finish(tw_dev, request_id);
2048         }
2049     }
2050 
2051     /* Handle command interrupt */
2052     if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
2053         /* Drain as many pending commands as we can */
2054         while (tw_dev->pending_request_count > 0) {
2055             request_id = tw_dev->pending_queue[tw_dev->pending_head];
2056             if (tw_dev->state[request_id] != TW_S_PENDING) {
2057                 printk(KERN_WARNING "3w-xxxx: scsi%d: Found request id that wasn't pending.\n", tw_dev->host->host_no);
2058                 break;
2059             }
2060             if (tw_post_command_packet(tw_dev, request_id)==0) {
2061                 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
2062                     tw_dev->pending_head = TW_Q_START;
2063                 } else {
2064                     tw_dev->pending_head = tw_dev->pending_head + 1;
2065                 }
2066                 tw_dev->pending_request_count--;
2067             } else {
2068                 /* If we get here, we will continue re-posting on the next command interrupt */
2069                 break;
2070             }
2071         }
2072         /* If there are no more pending requests, we mask command interrupt */
2073         if (tw_dev->pending_request_count == 0)
2074             TW_MASK_COMMAND_INTERRUPT(tw_dev);
2075     }
2076 
2077     /* Handle response interrupt */
2078     if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
2079         /* Drain the response queue from the board */
2080         while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
2081             /* Read response queue register */
2082             response_que.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
2083             request_id = TW_RESID_OUT(response_que.response_id);
2084             command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2085             error = 0;
2086 
2087             /* Check for bad response */
2088             if (command_packet->status != 0) {
2089                 /* If internal command, don't error, don't fill sense */
2090                 if (tw_dev->srb[request_id] == NULL) {
2091                     tw_decode_sense(tw_dev, request_id, 0);
2092                 } else {
2093                     error = tw_decode_sense(tw_dev, request_id, 1);
2094                 }
2095             }
2096 
2097             /* Check for correct state */
2098             if (tw_dev->state[request_id] != TW_S_POSTED) {
2099                 if (tw_dev->srb[request_id] != NULL) {
2100                     printk(KERN_WARNING "3w-xxxx: scsi%d: Received a request id that wasn't posted.\n", tw_dev->host->host_no);
2101                     error = 1;
2102                 }
2103             }
2104 
2105             dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
2106 
2107             /* Check for internal command completion */
2108             if (tw_dev->srb[request_id] == NULL) {
2109                 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
2110                 /* Check for chrdev ioctl completion */
2111                 if (request_id != tw_dev->chrdev_request_id) {
2112                     retval = tw_aen_complete(tw_dev, request_id);
2113                     if (retval) {
2114                         printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);
2115                     }
2116                 } else {
2117                     tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
2118                     wake_up(&tw_dev->ioctl_wqueue);
2119                 }
2120             } else {
2121                 switch (tw_dev->srb[request_id]->cmnd[0]) {
2122                 case READ_10:
2123                 case READ_6:
2124                     dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10/READ_6\n");
2125                     break;
2126                 case WRITE_10:
2127                 case WRITE_6:
2128                     dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10/WRITE_6\n");
2129                     break;
2130                 case TEST_UNIT_READY:
2131                     dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TEST_UNIT_READY\n");
2132                     error = tw_scsiop_test_unit_ready_complete(tw_dev, request_id);
2133                     break;
2134                 case INQUIRY:
2135                     dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");
2136                     error = tw_scsiop_inquiry_complete(tw_dev, request_id);
2137                     break;
2138                 case READ_CAPACITY:
2139                     dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");
2140                     error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
2141                     break;
2142                 case MODE_SENSE:
2143                     dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught MODE_SENSE\n");
2144                     error = tw_scsiop_mode_sense_complete(tw_dev, request_id);
2145                     break;
2146                 case SYNCHRONIZE_CACHE:
2147                     dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught SYNCHRONIZE_CACHE\n");
2148                     break;
2149                 default:
2150                     printk(KERN_WARNING "3w-xxxx: case slip in tw_interrupt()\n");
2151                     error = 1;
2152                 }
2153 
2154                 /* If no error command was a success */
2155                 if (error == 0) {
2156                     tw_dev->srb[request_id]->result = (DID_OK << 16);
2157                 }
2158 
2159                 /* If error, command failed */
2160                 if (error == 1) {
2161                     /* Ask for a host reset */
2162                     tw_dev->srb[request_id]->result = (DID_OK << 16) | SAM_STAT_CHECK_CONDITION;
2163                 }
2164 
2165                 /* Now complete the io */
2166                 if ((error != TW_ISR_DONT_COMPLETE)) {
2167                     scsi_dma_unmap(tw_dev->srb[request_id]);
2168                     scsi_done(tw_dev->srb[request_id]);
2169                     tw_dev->state[request_id] = TW_S_COMPLETED;
2170                     tw_state_request_finish(tw_dev, request_id);
2171                     tw_dev->posted_request_count--;
2172                 }
2173             }
2174 
2175             /* Check for valid status after each drain */
2176             status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
2177             if (tw_check_bits(status_reg_value)) {
2178                 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
2179                 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
2180                     TW_CLEAR_ALL_INTERRUPTS(tw_dev);
2181                     goto tw_interrupt_bail;
2182                 }
2183             }
2184         }
2185     }
2186 
2187 tw_interrupt_bail:
2188     spin_unlock(tw_dev->host->host_lock);
2189     return IRQ_RETVAL(handled);
2190 } /* End tw_interrupt() */
2191 
2192 /* This function tells the controller to shut down */
2193 static void __tw_shutdown(TW_Device_Extension *tw_dev)
2194 {
2195     /* Disable interrupts */
2196     TW_DISABLE_INTERRUPTS(tw_dev);
2197 
2198     /* Free up the IRQ */
2199     free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2200 
2201     printk(KERN_WARNING "3w-xxxx: Shutting down host %d.\n", tw_dev->host->host_no);
2202 
2203     /* Tell the card we are shutting down */
2204     if (tw_initconnection(tw_dev, 1)) {
2205         printk(KERN_WARNING "3w-xxxx: Connection shutdown failed.\n");
2206     } else {
2207         printk(KERN_WARNING "3w-xxxx: Shutdown complete.\n");
2208     }
2209 
2210     /* Clear all interrupts just before exit */
2211     TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2212 } /* End __tw_shutdown() */
2213 
2214 /* Wrapper for __tw_shutdown */
2215 static void tw_shutdown(struct pci_dev *pdev)
2216 {
2217     struct Scsi_Host *host = pci_get_drvdata(pdev);
2218     TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2219 
2220     __tw_shutdown(tw_dev);
2221 } /* End tw_shutdown() */
2222 
2223 /* This function gets called when a disk is coming online */
2224 static int tw_slave_configure(struct scsi_device *sdev)
2225 {
2226     /* Force 60 second timeout */
2227     blk_queue_rq_timeout(sdev->request_queue, 60 * HZ);
2228 
2229     return 0;
2230 } /* End tw_slave_configure() */
2231 
2232 static struct scsi_host_template driver_template = {
2233     .module         = THIS_MODULE,
2234     .name           = "3ware Storage Controller",
2235     .queuecommand       = tw_scsi_queue,
2236     .eh_host_reset_handler  = tw_scsi_eh_reset,
2237     .bios_param     = tw_scsi_biosparam,
2238     .change_queue_depth = scsi_change_queue_depth,
2239     .can_queue      = TW_Q_LENGTH-2,
2240     .slave_configure    = tw_slave_configure,
2241     .this_id        = -1,
2242     .sg_tablesize       = TW_MAX_SGL_LENGTH,
2243     .max_sectors        = TW_MAX_SECTORS,
2244     .cmd_per_lun        = TW_MAX_CMDS_PER_LUN,
2245     .shost_groups       = tw_host_groups,
2246     .emulated       = 1,
2247     .no_write_same      = 1,
2248 };
2249 
2250 /* This function will probe and initialize a card */
2251 static int tw_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
2252 {
2253     struct Scsi_Host *host = NULL;
2254     TW_Device_Extension *tw_dev;
2255     int retval;
2256 
2257     retval = pci_enable_device(pdev);
2258     if (retval) {
2259         printk(KERN_WARNING "3w-xxxx: Failed to enable pci device.");
2260         goto out_disable_device;
2261     }
2262 
2263     pci_set_master(pdev);
2264 
2265     retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
2266     if (retval) {
2267         printk(KERN_WARNING "3w-xxxx: Failed to set dma mask.");
2268         goto out_disable_device;
2269     }
2270 
2271     host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
2272     if (!host) {
2273         printk(KERN_WARNING "3w-xxxx: Failed to allocate memory for device extension.");
2274         retval = -ENOMEM;
2275         goto out_disable_device;
2276     }
2277     tw_dev = (TW_Device_Extension *)host->hostdata;
2278 
2279     /* Save values to device extension */
2280     tw_dev->host = host;
2281     tw_dev->tw_pci_dev = pdev;
2282 
2283     if (tw_initialize_device_extension(tw_dev)) {
2284         printk(KERN_WARNING "3w-xxxx: Failed to initialize device extension.");
2285         retval = -ENOMEM;
2286         goto out_free_device_extension;
2287     }
2288 
2289     /* Request IO regions */
2290     retval = pci_request_regions(pdev, "3w-xxxx");
2291     if (retval) {
2292         printk(KERN_WARNING "3w-xxxx: Failed to get mem region.");
2293         goto out_free_device_extension;
2294     }
2295 
2296     /* Save base address */
2297     tw_dev->base_addr = pci_resource_start(pdev, 0);
2298     if (!tw_dev->base_addr) {
2299         printk(KERN_WARNING "3w-xxxx: Failed to get io address.");
2300         retval = -ENOMEM;
2301         goto out_release_mem_region;
2302     }
2303 
2304     /* Disable interrupts on the card */
2305     TW_DISABLE_INTERRUPTS(tw_dev);
2306 
2307     /* Initialize the card */
2308     if (tw_reset_sequence(tw_dev))
2309         goto out_release_mem_region;
2310 
2311     /* Set host specific parameters */
2312     host->max_id = TW_MAX_UNITS;
2313     host->max_cmd_len = TW_MAX_CDB_LEN;
2314 
2315     /* Luns and channels aren't supported by adapter */
2316     host->max_lun = 0;
2317     host->max_channel = 0;
2318 
2319     /* Register the card with the kernel SCSI layer */
2320     retval = scsi_add_host(host, &pdev->dev);
2321     if (retval) {
2322         printk(KERN_WARNING "3w-xxxx: scsi add host failed");
2323         goto out_release_mem_region;
2324     }
2325 
2326     pci_set_drvdata(pdev, host);
2327 
2328     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);
2329 
2330     /* Now setup the interrupt handler */
2331     retval = request_irq(pdev->irq, tw_interrupt, IRQF_SHARED, "3w-xxxx", tw_dev);
2332     if (retval) {
2333         printk(KERN_WARNING "3w-xxxx: Error requesting IRQ.");
2334         goto out_remove_host;
2335     }
2336 
2337     tw_device_extension_list[tw_device_extension_count] = tw_dev;
2338     tw_device_extension_count++;
2339 
2340     /* Re-enable interrupts on the card */
2341     TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2342 
2343     /* Finally, scan the host */
2344     scsi_scan_host(host);
2345 
2346     if (twe_major == -1) {
2347         if ((twe_major = register_chrdev (0, "twe", &tw_fops)) < 0)
2348             printk(KERN_WARNING "3w-xxxx: Failed to register character device.");
2349     }
2350     return 0;
2351 
2352 out_remove_host:
2353     scsi_remove_host(host);
2354 out_release_mem_region:
2355     pci_release_regions(pdev);
2356 out_free_device_extension:
2357     tw_free_device_extension(tw_dev);
2358     scsi_host_put(host);
2359 out_disable_device:
2360     pci_disable_device(pdev);
2361 
2362     return retval;
2363 } /* End tw_probe() */
2364 
2365 /* This function is called to remove a device */
2366 static void tw_remove(struct pci_dev *pdev)
2367 {
2368     struct Scsi_Host *host = pci_get_drvdata(pdev);
2369     TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2370 
2371     scsi_remove_host(tw_dev->host);
2372 
2373     /* Unregister character device */
2374     if (twe_major >= 0) {
2375         unregister_chrdev(twe_major, "twe");
2376         twe_major = -1;
2377     }
2378 
2379     /* Shutdown the card */
2380     __tw_shutdown(tw_dev);
2381 
2382     /* Free up the mem region */
2383     pci_release_regions(pdev);
2384 
2385     /* Free up device extension resources */
2386     tw_free_device_extension(tw_dev);
2387 
2388     scsi_host_put(tw_dev->host);
2389     pci_disable_device(pdev);
2390     tw_device_extension_count--;
2391 } /* End tw_remove() */
2392 
2393 /* PCI Devices supported by this driver */
2394 static struct pci_device_id tw_pci_tbl[] = {
2395     { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_1000,
2396       PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2397     { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_7000,
2398       PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2399     { }
2400 };
2401 MODULE_DEVICE_TABLE(pci, tw_pci_tbl);
2402 
2403 /* pci_driver initializer */
2404 static struct pci_driver tw_driver = {
2405     .name       = "3w-xxxx",
2406     .id_table   = tw_pci_tbl,
2407     .probe      = tw_probe,
2408     .remove     = tw_remove,
2409     .shutdown   = tw_shutdown,
2410 };
2411 
2412 /* This function is called on driver initialization */
2413 static int __init tw_init(void)
2414 {
2415     printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
2416 
2417     return pci_register_driver(&tw_driver);
2418 } /* End tw_init() */
2419 
2420 /* This function is called on driver exit */
2421 static void __exit tw_exit(void)
2422 {
2423     pci_unregister_driver(&tw_driver);
2424 } /* End tw_exit() */
2425 
2426 module_init(tw_init);
2427 module_exit(tw_exit);
2428