James,

Here is a patch to update a few bugs in the 3ware driver for
5/6/7/8000 controllers.

-Adam

diff -Naur linux-2.6.11-rc2-mm1/drivers/scsi/3w-xxxx.c linux-2.6.11-rc2-mm2/driv
ers/scsi/3w-xxxx.c
--- linux-2.6.11-rc2-mm1/drivers/scsi/3w-xxxx.c 2004-12-24 13:35:28.000000000 -0
800
+++ linux-2.6.11-rc2-mm2/drivers/scsi/3w-xxxx.c 2005-01-26 16:46:02.000000000 -0
800
@@ -6,7 +6,7 @@
                     Arnaldo Carvalho de Melo <[EMAIL PROTECTED]>
                      Brad Strand <[EMAIL PROTECTED]>
 
-   Copyright (C) 1999-2004 3ware Inc.
+   Copyright (C) 1999-2005 3ware Inc.
 
    Kernel compatiblity By:     Andre Hedrick <[EMAIL PROTECTED]>
    Non-Copyright (C) 2000      Andre Hedrick <[EMAIL PROTECTED]>
@@ -185,6 +185,13 @@
                  Fix data_buffer_length usage in tw_chrdev_ioctl().
                  Update contact information.
    1.26.02.000 - Convert driver to pci_driver format.
+   1.26.02.001 - Increase max ioctl buffer size to 512 sectors.
+                 Make tw_scsi_queue() return 0 for 'Unknown scsi opcode'.
+                 Fix tw_interrupt() to ignore interrupts from other devices
+                 during reset.
+                 Fix tw_scsi_queue() to BUSY io's during a reset.
+                 Fix tw_remove() to free irq handler/unregister_chrdev()
+                 before shutting down card.
 */
 
 #include <linux/module.h>
@@ -207,7 +214,7 @@
 #include "3w-xxxx.h"
 
 /* Globals */
-#define TW_DRIVER_VERSION "1.26.02.000"
+#define TW_DRIVER_VERSION "1.26.02.001"
 static TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 static int tw_device_extension_count = 0;
 static int twe_major = -1;
@@ -910,7 +917,7 @@
                goto out;
 
        /* Check size */
-       if (data_buffer_length > TW_MAX_SECTORS * 512) {
+       if (data_buffer_length > TW_MAX_IOCTL_SECTORS * 512) {
                retval = -EINVAL;
                goto out;
        }
@@ -1366,6 +1373,7 @@
        TW_DISABLE_INTERRUPTS(tw_dev);
        TW_MASK_COMMAND_INTERRUPT(tw_dev);
        spin_lock_irqsave(tw_dev->host->host_lock, flags);
+       tw_dev->online = 0;
 
        /* Abort all requests that are in progress */
        for (i=0;i<TW_Q_LENGTH;i++) {
@@ -1401,6 +1409,7 @@
                return 1;
        }
        TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
+       tw_dev->online = 1;
 
        /* Wake up any ioctl that was pending before the reset */
        if ((tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE) || (ioctl_reset)
) {
@@ -2007,6 +2016,12 @@
        int retval = 1;
        TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host
->hostdata;
 
+       /* If we are off-line doing a reset, report as busy */
+       if (!tw_dev->online) {
+               retval = SCSI_MLQUEUE_HOST_BUSY;
+               goto out;
+       }
+
        /* Save done function into Scsi_Cmnd struct */
        SCpnt->scsi_done = done;
                 
@@ -2060,7 +2075,7 @@
                        tw_state_request_finish(tw_dev, request_id);
                        SCpnt->result = (DID_BAD_TARGET << 16);
                        done(SCpnt);
-                       goto out;
+                       retval = 0;
        }
        if (retval) {
                tw_dev->state[request_id] = TW_S_COMPLETED;
@@ -2093,6 +2108,10 @@
 
                handled = 1;
 
+               /* If card is offline, bail */
+               if (!tw_dev->online)
+                       goto tw_interrupt_bail;
+
                /* Read the registers */
                status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
 
@@ -2407,6 +2426,7 @@
 
        /* Re-enable interrupts on the card */
        TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
+       tw_dev->online = 1;
 
        /* Finally, scan the host */
        scsi_scan_host(host);
@@ -2438,23 +2458,24 @@
 
        scsi_remove_host(tw_dev->host);
 
-       __tw_shutdown(tw_dev);
+       /* Unregister character device */
+       if (twe_major >= 0) {
+               unregister_chrdev(twe_major, "twe");
+               twe_major = -1;
+       }
 
        /* Free up the IRQ */
        free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
 
+       /* Shutdown the card */
+       __tw_shutdown(tw_dev);
+
        /* Free up the mem region */
        pci_release_regions(pdev);
 
        /* Free up device extension resources */
        tw_free_device_extension(tw_dev);
 
-       /* Unregister character device */
-       if (twe_major >= 0) {
-               unregister_chrdev(twe_major, "twe");
-               twe_major = -1;
-       }
-
        scsi_host_put(tw_dev->host);
        pci_disable_device(pdev);
        tw_device_extension_count--;
diff -Naur linux-2.6.11-rc2-mm1/drivers/scsi/3w-xxxx.h linux-2.6.11-rc2-mm2/driv
ers/scsi/3w-xxxx.h
--- linux-2.6.11-rc2-mm1/drivers/scsi/3w-xxxx.h 2005-01-26 16:41:52.000000000 -0
800
+++ linux-2.6.11-rc2-mm2/drivers/scsi/3w-xxxx.h 2005-01-26 16:46:04.000000000 -0
800
@@ -6,7 +6,7 @@
                     Arnaldo Carvalho de Melo <[EMAIL PROTECTED]>
                      Brad Strand <[EMAIL PROTECTED]>
 
-   Copyright (C) 1999-2004 3ware Inc.
+   Copyright (C) 1999-2005 3ware Inc.
 
    Kernel compatiblity By:     Andre Hedrick <[EMAIL PROTECTED]>
    Non-Copyright (C) 2000      Andre Hedrick <[EMAIL PROTECTED]>
@@ -227,6 +227,7 @@
 #define TW_IN_RESET                           2
 #define TW_IN_CHRDEV_IOCTL                    3
 #define TW_MAX_SECTORS                        256
+#define TW_MAX_IOCTL_SECTORS                 512
 #define TW_AEN_WAIT_TIME                      1000
 #define TW_IOCTL_WAIT_TIME                    (1 * HZ) /* 1 second */
 #define TW_ISR_DONT_COMPLETE                  2
@@ -428,6 +429,7 @@
        int                     reset_print;
        volatile int            chrdev_request_id;
        wait_queue_head_t       ioctl_wqueue;
+       char                    online;
 } TW_Device_Extension;
 
 #pragma pack()
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to