Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=4fe48187da5a0229be3951761b66cd426430a52b
Commit:     4fe48187da5a0229be3951761b66cd426430a52b
Parent:     6397256b0af52082db3b7f804aa3b612a17dcbc9
Author:     adam radford <[EMAIL PROTECTED]>
AuthorDate: Thu Jan 4 18:16:56 2007 -0800
Committer:  James Bottomley <[EMAIL PROTECTED]>
CommitDate: Sat Jan 6 09:18:00 2007 -0600

    [SCSI] 3ware 8000 serialize reset code
    
    The attached patch updates the 3ware 8000 driver:
    
    - Free irq handler in __tw_shutdown().
    - Turn on RCD bit for caching mode page.
    - Serialize reset code.
    
    Signed-off-by: Adam Radford <[EMAIL PROTECTED]>
    Signed-off-by: James Bottomley <[EMAIL PROTECTED]>
---
 drivers/scsi/3w-xxxx.c |   60 +++++++++++++++++++++++------------------------
 drivers/scsi/3w-xxxx.h |    2 +-
 2 files changed, 30 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index 99a259c..e1b44d6 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -6,7 +6,7 @@
                     Arnaldo Carvalho de Melo <[EMAIL PROTECTED]>
                      Brad Strand <[EMAIL PROTECTED]>
 
-   Copyright (C) 1999-2005 3ware Inc.
+   Copyright (C) 1999-2007 3ware Inc.
 
    Kernel compatiblity By:     Andre Hedrick <[EMAIL PROTECTED]>
    Non-Copyright (C) 2000      Andre Hedrick <[EMAIL PROTECTED]>
@@ -191,6 +191,9 @@
                  before shutting down card.
                  Change to new 'change_queue_depth' api.
                  Fix 'handled=1' ISR usage, remove bogus IRQ check.
+   1.26.02.002 - Free irq handler in __tw_shutdown().
+                 Turn on RCD bit for caching mode page.
+                 Serialize reset code.
 */
 
 #include <linux/module.h>
@@ -214,7 +217,7 @@
 #include "3w-xxxx.h"
 
 /* Globals */
-#define TW_DRIVER_VERSION "1.26.02.001"
+#define TW_DRIVER_VERSION "1.26.02.002"
 static TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 static int tw_device_extension_count = 0;
 static int twe_major = -1;
@@ -226,7 +229,7 @@ MODULE_LICENSE("GPL");
 MODULE_VERSION(TW_DRIVER_VERSION);
 
 /* Function prototypes */
-static int tw_reset_device_extension(TW_Device_Extension *tw_dev, int 
ioctl_reset);
+static int tw_reset_device_extension(TW_Device_Extension *tw_dev);
 
 /* Functions */
 
@@ -984,24 +987,12 @@ static int tw_chrdev_ioctl(struct inode *inode, struct 
file *file, unsigned int
                        /* Now wait for the command to complete */
                        timeout = wait_event_timeout(tw_dev->ioctl_wqueue, 
tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
 
-                       /* See if we reset while waiting for the ioctl to 
complete */
-                       if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
-                               clear_bit(TW_IN_RESET, &tw_dev->flags);
-                               retval = -ERESTARTSYS;
-                               goto out2;
-                       }
-
                        /* We timed out, and didn't get an interrupt */
                        if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
                                /* Now we need to reset the board */
                                printk(KERN_WARNING "3w-xxxx: scsi%d: Character 
ioctl (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, cmd);
                                retval = -EIO;
-                               spin_lock_irqsave(tw_dev->host->host_lock, 
flags);
-                               tw_dev->state[request_id] = TW_S_COMPLETED;
-                               tw_state_request_finish(tw_dev, request_id);
-                               tw_dev->posted_request_count--;
-                               spin_unlock_irqrestore(tw_dev->host->host_lock, 
flags);
-                               if (tw_reset_device_extension(tw_dev, 1)) {
+                               if (tw_reset_device_extension(tw_dev)) {
                                        printk(KERN_WARNING "3w-xxxx: 
tw_chrdev_ioctl(): Reset failed for card %d.\n", tw_dev->host->host_no);
                                }
                                goto out2;
@@ -1336,7 +1327,7 @@ static void tw_unmap_scsi_data(struct pci_dev *pdev, 
struct scsi_cmnd *cmd)
 } /* End tw_unmap_scsi_data() */
 
 /* This function will reset a device extension */
-static int tw_reset_device_extension(TW_Device_Extension *tw_dev, int 
ioctl_reset) 
+static int tw_reset_device_extension(TW_Device_Extension *tw_dev)
 {
        int i = 0;
        struct scsi_cmnd *srb;
@@ -1382,15 +1373,10 @@ static int 
tw_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_rese
                printk(KERN_WARNING "3w-xxxx: scsi%d: Reset sequence 
failed.\n", tw_dev->host->host_no);
                return 1;
        }
-       TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
 
-       /* Wake up any ioctl that was pending before the reset */
-       if ((tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE) || 
(ioctl_reset)) {
-               clear_bit(TW_IN_RESET, &tw_dev->flags);
-       } else {
-               tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
-               wake_up(&tw_dev->ioctl_wqueue);
-       }
+       TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
+       clear_bit(TW_IN_RESET, &tw_dev->flags);
+       tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
 
        return 0;
 } /* End tw_reset_device_extension() */
@@ -1437,14 +1423,18 @@ static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt)
                "WARNING: Command (0x%x) timed out, resetting card.\n",
                SCpnt->cmnd[0]);
 
+       /* Make sure we are not issuing an ioctl or resetting from ioctl */
+       mutex_lock(&tw_dev->ioctl_lock);
+
        /* Now reset the card and some of the device extension data */
-       if (tw_reset_device_extension(tw_dev, 0)) {
+       if (tw_reset_device_extension(tw_dev)) {
                printk(KERN_WARNING "3w-xxxx: scsi%d: Reset failed.\n", 
tw_dev->host->host_no);
                goto out;
        }
 
        retval = SUCCESS;
 out:
+       mutex_unlock(&tw_dev->ioctl_lock);
        return retval;
 } /* End tw_scsi_eh_reset() */
 
@@ -1660,9 +1650,9 @@ static int 
tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int reques
        request_buffer[4] = 0x8;        /* caching page */
        request_buffer[5] = 0xa;        /* page length */
        if (*flags & 0x1)
-               request_buffer[6] = 0x4;        /* WCE on */
+               request_buffer[6] = 0x5;        /* WCE on, RCD on */
        else
-               request_buffer[6] = 0x0;        /* WCE off */
+               request_buffer[6] = 0x1;        /* WCE off, RCD on */
        tw_transfer_internal(tw_dev, request_id, request_buffer,
                             sizeof(request_buffer));
 
@@ -2012,6 +2002,10 @@ static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void 
(*done)(struct scsi_cmnd
        int retval = 1;
        TW_Device_Extension *tw_dev = (TW_Device_Extension 
*)SCpnt->device->host->hostdata;
 
+       /* If we are resetting due to timed out ioctl, report as busy */
+       if (test_bit(TW_IN_RESET, &tw_dev->flags))
+               return SCSI_MLQUEUE_HOST_BUSY;
+
        /* Save done function into Scsi_Cmnd struct */
        SCpnt->scsi_done = done;
                 
@@ -2100,6 +2094,10 @@ static irqreturn_t tw_interrupt(int irq, void 
*dev_instance)
 
        handled = 1;
 
+       /* If we are resetting, bail */
+       if (test_bit(TW_IN_RESET, &tw_dev->flags))
+               goto tw_interrupt_bail;
+
        /* Check controller for errors */
        if (tw_check_bits(status_reg_value)) {
                dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected 
bits.\n");
@@ -2276,6 +2274,9 @@ static void __tw_shutdown(TW_Device_Extension *tw_dev)
        /* Disable interrupts */
        TW_DISABLE_INTERRUPTS(tw_dev);
 
+       /* Free up the IRQ */
+       free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
+
        printk(KERN_WARNING "3w-xxxx: Shutting down host %d.\n", 
tw_dev->host->host_no);
 
        /* Tell the card we are shutting down */
@@ -2444,9 +2445,6 @@ static void tw_remove(struct pci_dev *pdev)
                twe_major = -1;
        }
 
-       /* Free up the IRQ */
-       free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
-
        /* Shutdown the card */
        __tw_shutdown(tw_dev);
 
diff --git a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
index bbd654a..0742e68 100644
--- a/drivers/scsi/3w-xxxx.h
+++ b/drivers/scsi/3w-xxxx.h
@@ -6,7 +6,7 @@
                     Arnaldo Carvalho de Melo <[EMAIL PROTECTED]>
                      Brad Strand <[EMAIL PROTECTED]>
 
-   Copyright (C) 1999-2005 3ware Inc.
+   Copyright (C) 1999-2007 3ware Inc.
 
    Kernel compatiblity By:     Andre Hedrick <[EMAIL PROTECTED]>
    Non-Copyright (C) 2000      Andre Hedrick <[EMAIL PROTECTED]>
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to