[SCSI] Block I/O while SG reset operation in progress - the midlayer patch
authorJames Smart <James.Smart@Emulex.Com>
Wed, 8 Mar 2006 19:50:12 +0000 (14:50 -0500)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Tue, 27 Jun 2006 15:48:11 +0000 (10:48 -0500)
The scsi midlayer portion of the patch

Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/scsi_error.c
include/scsi/scsi_host.h

index 6a7a60fc0a4e54eaa069012ed71cfa9b86f4a6df..6683d596234a7acab897066d96cad4f25af49608 100644 (file)
@@ -1672,7 +1672,9 @@ int
 scsi_reset_provider(struct scsi_device *dev, int flag)
 {
        struct scsi_cmnd *scmd = scsi_get_command(dev, GFP_KERNEL);
+       struct Scsi_Host *shost = dev->host;
        struct request req;
+       unsigned long flags;
        int rtn;
 
        scmd->request = &req;
@@ -1699,6 +1701,10 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
         */
        scmd->pid                       = 0;
 
+       spin_lock_irqsave(shost->host_lock, flags);
+       shost->tmf_in_progress = 1;
+       spin_unlock_irqrestore(shost->host_lock, flags);
+
        switch (flag) {
        case SCSI_TRY_RESET_DEVICE:
                rtn = scsi_try_bus_device_reset(scmd);
@@ -1717,6 +1723,22 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
                rtn = FAILED;
        }
 
+       spin_lock_irqsave(shost->host_lock, flags);
+       shost->tmf_in_progress = 0;
+       spin_unlock_irqrestore(shost->host_lock, flags);
+
+       /*
+        * be sure to wake up anyone who was sleeping or had their queue
+        * suspended while we performed the TMF.
+        */
+       SCSI_LOG_ERROR_RECOVERY(3,
+               printk("%s: waking up host to restart after TMF\n",
+               __FUNCTION__));
+
+       wake_up(&shost->host_wait);
+
+       scsi_run_host_queues(shost);
+
        scsi_next_command(scmd);
        return rtn;
 }
index a42efd6e4be88ec79890a4b404f8f02cf4ec99fc..b3dd90f3e85868a4023fecceecefb7336f795324 100644 (file)
@@ -542,6 +542,9 @@ struct Scsi_Host {
         */
        unsigned ordered_tag:1;
 
+       /* task mgmt function in progress */
+       unsigned tmf_in_progress:1;
+
        /*
         * Optional work queue to be utilized by the transport
         */
@@ -619,7 +622,8 @@ static inline int scsi_host_in_recovery(struct Scsi_Host *shost)
 {
        return shost->shost_state == SHOST_RECOVERY ||
                shost->shost_state == SHOST_CANCEL_RECOVERY ||
-               shost->shost_state == SHOST_DEL_RECOVERY;
+               shost->shost_state == SHOST_DEL_RECOVERY ||
+               shost->tmf_in_progress;
 }
 
 extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *);