[SCSI] allow sleeping in ->eh_device_reset_handler()
authorJeff Garzik <jgarzik@pobox.com>
Sat, 28 May 2005 11:55:48 +0000 (07:55 -0400)
committerJeff Garzik <jgarzik@pobox.com>
Fri, 17 Jun 2005 17:05:03 +0000 (12:05 -0500)
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
17 files changed:
Documentation/scsi/scsi_mid_low_api.txt
drivers/ieee1394/sbp2.c
drivers/message/fusion/mptscsih.c
drivers/s390/scsi/zfcp_scsi.c
drivers/scsi/aha152x.c
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx_old.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/ipr.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/megaraid.c
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/qla1280.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/scsi_error.c
drivers/scsi/sym53c8xx_2/sym_glue.c
drivers/usb/storage/scsiglue.c

index f4a37ee670f2978f0112e5f7af5f33909f6b39b4..62f7f76f5de8e0ce7850ce6f91242a0c4cc1fc2d 100644 (file)
@@ -973,8 +973,7 @@ Details:
  *
  *      Returns SUCCESS if command aborted else FAILED
  *
- *      Locks: struct Scsi_Host::host_lock held (with irqsave) on entry
- *      and assumed to be held on return.
+ *      Locks: None held
  *
  *      Calling context: kernel thread
  *
index de552486b1c9fca9aa0124ffc890a5b97d392e67..fcfddcc8e7ba1ca6f95b29289004ff66dbc5836f 100644 (file)
@@ -2615,7 +2615,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
 /*
  * Called by scsi stack when something has really gone wrong.
  */
-static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
+static int __sbp2scsi_reset(struct scsi_cmnd *SCpnt)
 {
        struct scsi_id_instance_data *scsi_id =
                (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0];
@@ -2630,6 +2630,18 @@ static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
        return(SUCCESS);
 }
 
+static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
+{
+       unsigned long flags;
+       int rc;
+
+       spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
+       rc = __sbp2scsi_reset(SCpnt);
+       spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
+
+       return rc;
+}
+
 static const char *sbp2scsi_info (struct Scsi_Host *host)
 {
         return "SCSI emulation for IEEE-1394 SBP-2 Devices";
index 6a5851c51a21e1eba78a5cbb0d01c44ed6c5138c..82cd9bc3b024caad19db09cd8830003d6c358a37 100644 (file)
@@ -1801,7 +1801,6 @@ int
 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
 {
        MPT_SCSI_HOST   *hd;
-       spinlock_t      *host_lock = SCpnt->device->host->host_lock;
 
        /* If we can't locate our host adapter structure, return FAILED status.
         */
@@ -1818,7 +1817,6 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
        printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
               hd->ioc->name, SCpnt);
 
-       spin_unlock_irq(host_lock);
        if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
                SCpnt->device->channel, SCpnt->device->id,
                0, 0, 5 /* 5 second timeout */)
@@ -1830,12 +1828,10 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
                                hd->ioc->name, SCpnt);
                hd->tmPending = 0;
                hd->tmState = TM_STATE_NONE;
-               spin_lock_irq(host_lock);
                return FAILED;
        }
-       spin_lock_irq(host_lock);
-       return SUCCESS;
 
+       return SUCCESS;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
index 6e4447598495c3a24d976e7da8fd07ae802bcf85..be7c91d4ae8c49aafea65f2eab7c8cf5c69739cc 100644 (file)
@@ -636,8 +636,6 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
        struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata;
        struct Scsi_Host *scsi_host = scpnt->device->host;
 
-       spin_unlock_irq(scsi_host->host_lock);
-
        if (!unit) {
                ZFCP_LOG_NORMAL("bug: Tried reset for nonexistent unit\n");
                retval = SUCCESS;
@@ -680,7 +678,6 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
                retval = SUCCESS;
        }
  out:
-       spin_lock_irq(scsi_host->host_lock);
        return retval;
 }
 
index 88d119f4b97070d221a9f496625f676401d70401..630b11575230c7920e3aa465d650add5d1dd7243 100644 (file)
@@ -1225,8 +1225,6 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
        }
 
        DO_UNLOCK(flags);
-
-       spin_lock_irq(shpnt->host_lock);
        return ret;
 }
 
index 7fc6c76e519b2a69b53b9ee45e6df3764e1ea00c..31db0edc7cf9b74df040b2d69b1c42ad82ba2d4e 100644 (file)
@@ -1511,17 +1511,17 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
                       ahd_name(ahd), cmd->device->channel, cmd->device->id,
                       cmd->device->lun, cmd);
 #endif
-       ahd_midlayer_entrypoint_lock(ahd, &s);
+       ahd_lock(ahd, &s);
 
        dev = ahd_linux_get_device(ahd, cmd->device->channel, cmd->device->id,
                                   cmd->device->lun, /*alloc*/FALSE);
        if (dev == NULL) {
-               ahd_midlayer_entrypoint_unlock(ahd, &s);
+               ahd_unlock(ahd, &s);
                kfree(recovery_cmd);
                return (FAILED);
        }
        if ((scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX)) == NULL) {
-               ahd_midlayer_entrypoint_unlock(ahd, &s);
+               ahd_unlock(ahd, &s);
                kfree(recovery_cmd);
                return (FAILED);
        }
@@ -1570,7 +1570,7 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
        spin_lock_irq(&ahd->platform_data->spin_lock);
        ahd_schedule_runq(ahd);
        ahd_linux_run_complete_queue(ahd);
-       ahd_midlayer_entrypoint_unlock(ahd, &s);
+       ahd_unlock(ahd, &s);
        printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
        return (retval);
 }
index ee127e8aea55694dcde683927426decadbb12cf8..1e83096bb9112ca26ff48015b8279383ebcfcdcf 100644 (file)
@@ -10358,7 +10358,7 @@ aic7xxx_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
  *   Returns an enumerated type that indicates the status of the operation.
  *-F*************************************************************************/
 static int
-aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
+__aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
 {
   struct aic7xxx_host  *p;
   struct aic7xxx_scb   *scb;
@@ -10551,6 +10551,18 @@ aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
     return SUCCESS;
 }
 
+static int
+aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
+{
+      int rc;
+
+      spin_lock_irq(cmd->device->host->host_lock);
+      rc = __aic7xxx_bus_device_reset(cmd);
+      spin_unlock_irq(cmd->device->host->host_lock);
+
+      return rc;
+}
+
 
 /*+F*************************************************************************
  * Function:
index d857842bc45b5ab7abf5e50f480113fe41d7b545..d89b8eb3cdf374c9b3ed552b0c66457843f59882 100644 (file)
@@ -976,9 +976,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
                return FAILED;
        }
 
-       spin_unlock_irq(hostdata->host->host_lock);
        wait_for_completion(&evt->comp);
-       spin_lock_irq(hostdata->host->host_lock);
 
        /* make sure we got a good response */
        if (unlikely(srp_rsp.srp.generic.type != SRP_RSP_TYPE)) {
index f9c01a13abef57fa059626b07bcd8fbaa6f88a86..fd8af643feacdf2a85b34ca4d0a15bd2efeeeec9 100644 (file)
@@ -2916,7 +2916,7 @@ static int ipr_eh_host_reset(struct scsi_cmnd * scsi_cmd)
  * Return value:
  *     SUCCESS / FAILED
  **/
-static int ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
+static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
 {
        struct ipr_cmnd *ipr_cmd;
        struct ipr_ioa_cfg *ioa_cfg;
@@ -2970,6 +2970,17 @@ static int ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
        return (IPR_IOASC_SENSE_KEY(ioasc) ? FAILED : SUCCESS);
 }
 
+static int ipr_eh_dev_reset(struct scsi_cmnd * cmd)
+{
+       int rc;
+
+       spin_lock_irq(cmd->device->host->host_lock);
+       rc = __ipr_eh_dev_reset(cmd);
+       spin_unlock_irq(cmd->device->host->host_lock);
+
+       return rc;
+}
+
 /**
  * ipr_bus_reset_done - Op done function for bus reset.
  * @ipr_cmd:   ipr command struct
index e9b84f9d8e81b3ca930586314c46015360830f79..13da26883da31ca82fe0f8c480f3468c3ca4cb18 100644 (file)
@@ -928,7 +928,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
 }
 
 static int
-lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
+__lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
 {
        struct Scsi_Host *shost = cmnd->device->host;
        struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
@@ -1040,6 +1040,16 @@ out:
        return ret;
 }
 
+static int
+lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
+{
+       int rc;
+       spin_lock_irq(cmnd->device->host->host_lock);
+       rc = __lpfc_reset_lun_handler(cmnd);
+       spin_unlock_irq(cmnd->device->host->host_lock);
+       return rc;
+}
+
 /*
  * Note: midlayer calls this function with the host_lock held
  */
index 8d707b29027da4dcab34942adcc7aac9f5e11a8e..80b0c40c522b7023369c6498ad24165892b8ff55 100644 (file)
@@ -1938,7 +1938,7 @@ megaraid_abort(Scsi_Cmnd *cmd)
 
 
 static int
-megaraid_reset(Scsi_Cmnd *cmd)
+__megaraid_reset(Scsi_Cmnd *cmd)
 {
        adapter_t       *adapter;
        megacmd_t       mc;
@@ -1972,6 +1972,18 @@ megaraid_reset(Scsi_Cmnd *cmd)
        return rval;
 }
 
+static int
+megaraid_reset(Scsi_Cmnd *cmd)
+{
+       adapter = (adapter_t *)cmd->device->host->hostdata;
+       int rc;
+
+       spin_lock_irq(&adapter->lock);
+       rc = __megaraid_reset(cmd);
+       spin_unlock_irq(&adapter->lock);
+
+       return rc;
+}
 
 
 /**
index bec4406011aa133ad0a3c88ee768a6cc54ecb643..057ed45b54b28649fca62b3afa2ab2d3f9bdae60 100644 (file)
@@ -2726,7 +2726,7 @@ megaraid_abort_handler(struct scsi_cmnd *scp)
  * host
  **/
 static int
-megaraid_reset_handler(struct scsi_cmnd *scp)
+__megaraid_reset_handler(struct scsi_cmnd *scp)
 {
        adapter_t       *adapter;
        scb_t           *scb;
@@ -2847,6 +2847,18 @@ megaraid_reset_handler(struct scsi_cmnd *scp)
        return rval;
 }
 
+static int
+megaraid_reset_handler(struct scsi_cmnd *cmd)
+{
+       int rc;
+
+       spin_lock_irq(cmd->device->host->host_lock);
+       rc = __megaraid_reset_handler(cmd);
+       spin_unlock_irq(cmd->device->host->host_lock);
+
+       return rc;
+}
+
 
 /*
  * START: internal commands library
index 638be81c45090f2e35495007ae58b3ef13485688..907a1e8cc880230ec34ec43dfd647cd241390ef2 100644 (file)
@@ -1114,7 +1114,13 @@ qla1280_eh_abort(struct scsi_cmnd * cmd)
 static int
 qla1280_eh_device_reset(struct scsi_cmnd *cmd)
 {
-       return qla1280_error_action(cmd, DEVICE_RESET);
+       int rc;
+
+       spin_lock_irq(cmd->device->host->host_lock);
+       rc = qla1280_error_action(cmd, DEVICE_RESET);
+       spin_unlock_irq(cmd->device->host->host_lock);
+
+       return rc;
 }
 
 /**************************************************************************
index 1693998aa727fb77e7169d3a62661e2d7d440554..360974eb2b26e97d2141da983d1e6f7eb7a0ed2e 100644 (file)
@@ -613,12 +613,8 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
        qla_printk(KERN_INFO, ha,
            "scsi(%ld:%d:%d): DEVICE RESET ISSUED.\n", ha->host_no, id, lun);
 
-       spin_unlock_irq(ha->host->host_lock);
-
-       if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) {
-               spin_lock_irq(ha->host->host_lock);
+       if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS)
                goto eh_dev_reset_done;
-       }
 
        if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) {
                if (qla2x00_device_reset(ha, fcport) == 0)
@@ -669,8 +665,6 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
            "scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no, id, lun);
 
 eh_dev_reset_done:
-       spin_lock_irq(ha->host->host_lock);
-
        return ret;
 }
 
index 3877a78f5e50040c179728d40c2f2ccc639dac1d..87d925055b472e5dff106e5d80207a8f3e42eaee 100644 (file)
@@ -857,17 +857,14 @@ static int scsi_eh_abort_cmds(struct list_head *work_q,
  **/
 static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
 {
-       unsigned long flags;
-       int rtn = FAILED;
+       int rtn;
 
        if (!scmd->device->host->hostt->eh_device_reset_handler)
-               return rtn;
+               return FAILED;
 
        scmd->owner = SCSI_OWNER_LOWLEVEL;
 
-       spin_lock_irqsave(scmd->device->host->host_lock, flags);
        rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd);
-       spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
        if (rtn == SUCCESS) {
                scmd->device->was_reset = 1;
index e2d055ed5b6f866447e37ab20600600de38a4ee0..5ea62552d47d3775f0b90a85d6a2b37dd08a2da2 100644 (file)
@@ -867,7 +867,13 @@ static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd)
 
 static int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd)
 {
-       return sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd);
+       int rc;
+
+       spin_lock_irq(cmd->device->host->host_lock);
+       rc = sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd);
+       spin_unlock_irq(cmd->device->host->host_lock);
+
+       return rc;
 }
 
 static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd)
index 7dce9c01c357b878a4266f90e0dd0f3460809b16..739a9143477d56347d9e047b01cfa4a10eb0b092 100644 (file)
@@ -253,8 +253,6 @@ static int device_reset(struct scsi_cmnd *srb)
 
        US_DEBUGP("%s called\n", __FUNCTION__);
 
-       scsi_unlock(us_to_host(us));
-
        /* lock the device pointers and do the reset */
        down(&(us->dev_semaphore));
        if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
@@ -264,8 +262,6 @@ static int device_reset(struct scsi_cmnd *srb)
                result = us->transport_reset(us);
        up(&(us->dev_semaphore));
 
-       /* lock the host for the return */
-       scsi_lock(us_to_host(us));
        return result;
 }