aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-05-28 07:56:31 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-06-17 12:05:10 -0500
commit68b3aa7c9805aee9005a8ca53c5e99177961fbb9 (patch)
tree3f28891df0b3a1ecdfe6a98547d8f3c43b74e905
parent94d0e7b805961c44e4dc486ffc21075084bb7175 (diff)
[SCSI] allow sleeping in ->eh_bus_reset_handler()
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--Documentation/scsi/scsi_mid_low_api.txt3
-rw-r--r--drivers/fc4/fc.c3
-rw-r--r--drivers/message/fusion/mptscsih.c3
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c3
-rw-r--r--drivers/scsi/53c700.c9
-rw-r--r--drivers/scsi/NCR5380.c14
-rw-r--r--drivers/scsi/NCR53C9x.c4
-rw-r--r--drivers/scsi/a2091.c4
-rw-r--r--drivers/scsi/a3000.c4
-rw-r--r--drivers/scsi/aha1542.c4
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c4
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c4
-rw-r--r--drivers/scsi/dc395x.c12
-rw-r--r--drivers/scsi/fd_mcs.c5
-rw-r--r--drivers/scsi/fdomain.c6
-rw-r--r--drivers/scsi/gvp11.c4
-rw-r--r--drivers/scsi/imm.c9
-rw-r--r--drivers/scsi/in2000.c6
-rw-r--r--drivers/scsi/initio.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c12
-rw-r--r--drivers/scsi/mvme147.c4
-rw-r--r--drivers/scsi/nsp32.c3
-rw-r--r--drivers/scsi/ppa.c5
-rw-r--r--drivers/scsi/qla1280.c8
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c4
-rw-r--r--drivers/scsi/qlogicfas408.c6
-rw-r--r--drivers/scsi/scsi_error.c2
-rw-r--r--drivers/scsi/seagate.c3
-rw-r--r--drivers/scsi/sgiwd93.c4
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c8
-rw-r--r--drivers/scsi/tmscsim.c6
-rw-r--r--drivers/usb/storage/scsiglue.c3
32 files changed, 133 insertions, 40 deletions
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
index 62f7f76f5de..5a066afcc67 100644
--- a/Documentation/scsi/scsi_mid_low_api.txt
+++ b/Documentation/scsi/scsi_mid_low_api.txt
@@ -954,8 +954,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
*
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c
index d9e11b53665..cdea598d0c1 100644
--- a/drivers/fc4/fc.c
+++ b/drivers/fc4/fc.c
@@ -983,7 +983,10 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
fc->rst_pkt->request->rq_status = RQ_SCSI_BUSY;
fc->rst_pkt->done = fcp_scsi_reset_done;
+
+ spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
fcp_scsi_queue_it(fc, fc->rst_pkt, fcmd, 0);
+ spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
down(&sem);
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 82cd9bc3b02..efae9be4537 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1865,7 +1865,6 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
hd->timeouts++;
/* We are now ready to execute the task management request. */
- spin_unlock_irq(host_lock);
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
< 0){
@@ -1881,7 +1880,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
spin_lock_irq(host_lock);
return FAILED;
}
- spin_lock_irq(host_lock);
+
return SUCCESS;
}
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index be7c91d4ae8..ac5a5da434b 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -731,8 +731,6 @@ zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *scpnt)
struct zfcp_unit *unit;
struct Scsi_Host *scsi_host = scpnt->device->host;
- spin_unlock_irq(scsi_host->host_lock);
-
unit = (struct zfcp_unit *) scpnt->device->hostdata;
ZFCP_LOG_NORMAL("bus reset because of problems with "
"unit 0x%016Lx\n", unit->fcp_lun);
@@ -740,7 +738,6 @@ zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *scpnt)
zfcp_erp_wait(unit->port->adapter);
retval = SUCCESS;
- spin_lock_irq(scsi_host->host_lock);
return retval;
}
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index 8c64212e960..47cf9bd55d9 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -1957,23 +1957,30 @@ NCR_700_bus_reset(struct scsi_cmnd * SCp)
printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t",
SCp->device->host->host_no, SCp->device->id, SCp->device->lun, SCp);
scsi_print_command(SCp);
+
/* In theory, eh_complete should always be null because the
* eh is single threaded, but just in case we're handling a
* reset via sg or something */
- while(hostdata->eh_complete != NULL) {
+ spin_lock_irq(SCp->device->host->host_lock);
+ while (hostdata->eh_complete != NULL) {
spin_unlock_irq(SCp->device->host->host_lock);
msleep_interruptible(100);
spin_lock_irq(SCp->device->host->host_lock);
}
+
hostdata->eh_complete = &complete;
NCR_700_internal_bus_reset(SCp->device->host);
+
spin_unlock_irq(SCp->device->host->host_lock);
wait_for_completion(&complete);
spin_lock_irq(SCp->device->host->host_lock);
+
hostdata->eh_complete = NULL;
/* Revalidate the transport parameters of the failing device */
if(hostdata->fast)
spi_schedule_dv_device(SCp->device);
+
+ spin_unlock_irq(SCp->device->host->host_lock);
return SUCCESS;
}
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 7ae19d4181b..f8ec6fe7d85 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -2825,11 +2825,17 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
* Locks: host lock taken by caller
*/
-static int NCR5380_bus_reset(Scsi_Cmnd * cmd) {
+static int NCR5380_bus_reset(Scsi_Cmnd * cmd)
+{
+ struct Scsi_Host *instance = cmd->device->host;
+
NCR5380_local_declare();
- NCR5380_setup(cmd->device->host);
+ NCR5380_setup(instance);
+ NCR5380_print_status(instance);
+
+ spin_lock_irq(instance->host_lock);
+ do_reset(instance);
+ spin_unlock_irq(instance->host_lock);
- NCR5380_print_status(cmd->device->host);
- do_reset(cmd->device->host);
return SUCCESS;
}
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
index 064781a2cb1..6ceabbd42a3 100644
--- a/drivers/scsi/NCR53C9x.c
+++ b/drivers/scsi/NCR53C9x.c
@@ -1467,14 +1467,12 @@ int esp_reset(Scsi_Cmnd *SCptr)
{
struct NCR_ESP *esp = (struct NCR_ESP *) SCptr->device->host->hostdata;
+ spin_lock_irq(esp->ehost->host_lock);
(void) esp_do_resetbus(esp, esp->eregs);
-
spin_unlock_irq(esp->ehost->host_lock);
wait_event(esp->reset_queue, (esp->resetting_bus == 0));
- spin_lock_irq(esp->ehost->host_lock);
-
return SUCCESS;
}
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index 9928a2fbce0..ce3c37610c5 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -221,7 +221,11 @@ int __init a2091_detect(Scsi_Host_Template *tpnt)
static int a2091_bus_reset(Scsi_Cmnd *cmd)
{
/* FIXME perform bus-specific reset */
+
+ spin_lock_irq(cmd->device->host->host_lock);
wd33c93_host_reset(cmd);
+ spin_unlock_irq(cmd->device->host->host_lock);
+
return SUCCESS;
}
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c
index f8a89ec2504..92698f33559 100644
--- a/drivers/scsi/a3000.c
+++ b/drivers/scsi/a3000.c
@@ -208,7 +208,11 @@ fail_register:
static int a3000_bus_reset(Scsi_Cmnd *cmd)
{
/* FIXME perform bus-specific reset */
+
+ spin_lock_irq(cmd->device->host->host_lock);
wd33c93_host_reset(cmd);
+ spin_unlock_irq(cmd->device->host->host_lock);
+
return SUCCESS;
}
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index eb8bc6822cc..f911b51e304 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -1464,8 +1464,8 @@ static int aha1542_bus_reset(Scsi_Cmnd * SCpnt)
* check for timeout, and if we are doing something like this
* we are pretty desperate anyways.
*/
- spin_unlock_irq(SCpnt->device->host->host_lock);
ssleep(4);
+
spin_lock_irq(SCpnt->device->host->host_lock);
WAIT(STATUS(SCpnt->device->host->io_port),
@@ -1503,9 +1503,11 @@ static int aha1542_bus_reset(Scsi_Cmnd * SCpnt)
}
}
+ spin_unlock_irq(SCpnt->device->host->host_lock);
return SUCCESS;
fail:
+ spin_unlock_irq(SCpnt->device->host->host_lock);
return FAILED;
}
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 31db0edc7cf..53b7b2c15f8 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -1591,11 +1591,11 @@ ahd_linux_bus_reset(Scsi_Cmnd *cmd)
printf("%s: Bus reset called for cmd %p\n",
ahd_name(ahd), cmd);
#endif
- ahd_midlayer_entrypoint_lock(ahd, &s);
+ ahd_lock(ahd, &s);
found = ahd_reset_channel(ahd, cmd->device->channel + 'A',
/*initiate reset*/TRUE);
ahd_linux_run_complete_queue(ahd);
- ahd_midlayer_entrypoint_unlock(ahd, &s);
+ ahd_unlock(ahd, &s);
if (bootverbose)
printf("%s: SCSI bus reset delivered. "
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 89f073a3b76..b89094db14c 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -829,10 +829,14 @@ ahc_linux_bus_reset(struct scsi_cmnd *cmd)
{
struct ahc_softc *ahc;
int found;
+ unsigned long flags;
ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
+
+ ahc_lock(ahc, &flags);
found = ahc_reset_channel(ahc, cmd->device->channel + 'A',
/*initiate reset*/TRUE);
+ ahc_unlock(ahc, &flags);
if (bootverbose)
printf("%s: SCSI bus reset delivered. "
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index cca41cf8d3e..ae13c002f60 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -1310,7 +1310,7 @@ static void reset_dev_param(struct AdapterCtlBlk *acb)
* @cmd - some command for this host (for fetching hooks)
* Returns: SUCCESS (0x2002) on success, else FAILED (0x2003).
*/
-static int dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
+static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
{
struct AdapterCtlBlk *acb =
(struct AdapterCtlBlk *)cmd->device->host->hostdata;
@@ -1356,6 +1356,16 @@ static int dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
return SUCCESS;
}
+static int dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
+{
+ int rc;
+
+ spin_lock_irq(cmd->device->host->host_lock);
+ rc = __dc395x_eh_bus_reset(cmd);
+ spin_unlock_irq(cmd->device->host->host_lock);
+
+ return rc;
+}
/*
* abort an errant SCSI command
diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
index 4a358aec2e5..fa652f8aa64 100644
--- a/drivers/scsi/fd_mcs.c
+++ b/drivers/scsi/fd_mcs.c
@@ -1243,6 +1243,7 @@ static int fd_mcs_abort(Scsi_Cmnd * SCpnt)
static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
struct Scsi_Host *shpnt = SCpnt->device->host;
+ unsigned long flags;
#if DEBUG_RESET
static int called_once = 0;
@@ -1259,6 +1260,8 @@ static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
called_once = 1;
#endif
+ spin_lock_irqsave(shpnt->host_lock, flags);
+
outb(1, SCSI_Cntl_port);
do_pause(2);
outb(0, SCSI_Cntl_port);
@@ -1266,6 +1269,8 @@ static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
outb(0, SCSI_Mode_Cntl_port);
outb(PARITY_MASK, TMC_Cntl_port);
+ spin_unlock_irqrestore(shpnt->host_lock, flags);
+
/* Unless this is the very first call (i.e., SCPnt == NULL), everything
is probably hosed at this point. We will, however, try to keep
things going by informing the high-level code that we need help. */
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index a843c080c1d..4ba6a15cf43 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -1543,12 +1543,18 @@ static int fdomain_16x0_abort(struct scsi_cmnd *SCpnt)
int fdomain_16x0_bus_reset(struct scsi_cmnd *SCpnt)
{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
outb(1, port_base + SCSI_Cntl);
do_pause( 2 );
outb(0, port_base + SCSI_Cntl);
do_pause( 115 );
outb(0, port_base + SCSI_Mode_Cntl);
outb(PARITY_MASK, port_base + TMC_Cntl);
+
+ local_irq_restore(flags);
return SUCCESS;
}
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c
index 30cbf73c743..66990af1dc9 100644
--- a/drivers/scsi/gvp11.c
+++ b/drivers/scsi/gvp11.c
@@ -345,7 +345,11 @@ release:
static int gvp11_bus_reset(Scsi_Cmnd *cmd)
{
/* FIXME perform bus-specific reset */
+
+ spin_lock_irq(cmd->device->host->host_lock);
wd33c93_host_reset(cmd);
+ spin_unlock_irq(cmd->device->host->host_lock);
+
return SUCCESS;
}
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index be7f2ca0183..65e845665b8 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -18,6 +18,7 @@
#include <linux/blkdev.h>
#include <linux/parport.h>
#include <linux/workqueue.h>
+#include <linux/delay.h>
#include <asm/io.h>
#include <scsi/scsi.h>
@@ -610,9 +611,9 @@ static int imm_init(imm_struct *dev)
if (imm_connect(dev, 0) != 1)
return -EIO;
imm_reset_pulse(dev->base);
- udelay(1000); /* Delay to allow devices to settle */
+ mdelay(1); /* Delay to allow devices to settle */
imm_disconnect(dev);
- udelay(1000); /* Another delay to allow devices to settle */
+ mdelay(1); /* Another delay to allow devices to settle */
return device_check(dev);
}
@@ -1026,9 +1027,9 @@ static int imm_reset(struct scsi_cmnd *cmd)
imm_connect(dev, CONNECT_NORMAL);
imm_reset_pulse(dev->base);
- udelay(1000); /* device settle delay */
+ mdelay(1); /* device settle delay */
imm_disconnect(dev);
- udelay(1000); /* device settle delay */
+ mdelay(1); /* device settle delay */
return SUCCESS;
}
diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
index fbb29f7971d..aed7e64865f 100644
--- a/drivers/scsi/in2000.c
+++ b/drivers/scsi/in2000.c
@@ -1644,14 +1644,16 @@ static int in2000_bus_reset(Scsi_Cmnd * cmd)
struct Scsi_Host *instance;
struct IN2000_hostdata *hostdata;
int x;
+ unsigned long flags;
instance = cmd->device->host;
hostdata = (struct IN2000_hostdata *) instance->hostdata;
printk(KERN_WARNING "scsi%d: Reset. ", instance->host_no);
- /* do scsi-reset here */
+ spin_lock_irqsave(instance->host_lock, flags);
+ /* do scsi-reset here */
reset_hardware(instance, RESET_CARD_AND_BUS);
for (x = 0; x < 8; x++) {
hostdata->busy[x] = 0;
@@ -1668,6 +1670,8 @@ static int in2000_bus_reset(Scsi_Cmnd * cmd)
hostdata->outgoing_len = 0;
cmd->result = DID_RESET << 16;
+
+ spin_unlock_irqrestore(instance->host_lock, flags);
return SUCCESS;
}
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c
index a7b74d8c53b..f7ddc9f1ba4 100644
--- a/drivers/scsi/initio.c
+++ b/drivers/scsi/initio.c
@@ -3014,7 +3014,11 @@ static int i91u_bus_reset(struct scsi_cmnd * SCpnt)
HCS *pHCB;
pHCB = (HCS *) SCpnt->device->host->base;
+
+ spin_lock_irq(SCpnt->device->host->host_lock);
tul_reset_scsi(pHCB, 0);
+ spin_unlock_irq(SCpnt->device->host->host_lock);
+
return SUCCESS;
}
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 13da26883da..f2aff3f4042 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1054,7 +1054,7 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
* Note: midlayer calls this function with the host_lock held
*/
static int
-lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
+__lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
{
struct Scsi_Host *shost = cmnd->device->host;
struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
@@ -1144,6 +1144,16 @@ out:
}
static int
+lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
+{
+ int rc;
+ spin_lock_irq(cmnd->device->host->host_lock);
+ rc = __lpfc_reset_bus_handler(cmnd);
+ spin_unlock_irq(cmnd->device->host->host_lock);
+ return rc;
+}
+
+static int
lpfc_slave_alloc(struct scsi_device *sdev)
{
struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata[0];
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
index e73b33f293a..5c42021189e 100644
--- a/drivers/scsi/mvme147.c
+++ b/drivers/scsi/mvme147.c
@@ -116,7 +116,11 @@ int mvme147_detect(Scsi_Host_Template *tpnt)
static int mvme147_bus_reset(Scsi_Cmnd *cmd)
{
/* FIXME perform bus-specific reset */
+
+ spin_lock_irq(cmd->device->host->host_lock);
wd33c93_host_reset(cmd);
+ spin_unlock_irq(cmd->device->host->host_lock);
+
return SUCCESS;
}
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
index 029cef4ad69..6f15e7adbc6 100644
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -2987,6 +2987,8 @@ static int nsp32_eh_bus_reset(struct scsi_cmnd *SCpnt)
nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
unsigned int base = SCpnt->device->host->io_port;
+ spin_lock_irq(SCpnt->device->host->host_lock);
+
nsp32_msg(KERN_INFO, "Bus Reset");
nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt);
@@ -2994,6 +2996,7 @@ static int nsp32_eh_bus_reset(struct scsi_cmnd *SCpnt)
nsp32_do_bus_reset(data);
nsp32_write2(base, IRQ_CONTROL, 0);
+ spin_unlock_irq(SCpnt->device->host->host_lock);
return SUCCESS; /* SCSI bus reset is succeeded at any time. */
}
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index 96b4522523d..fafcf5d185e 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -17,6 +17,7 @@
#include <linux/blkdev.h>
#include <linux/parport.h>
#include <linux/workqueue.h>
+#include <linux/delay.h>
#include <asm/io.h>
#include <scsi/scsi.h>
@@ -891,9 +892,9 @@ static int ppa_reset(struct scsi_cmnd *cmd)
ppa_connect(dev, CONNECT_NORMAL);
ppa_reset_pulse(dev->base);
- udelay(1000); /* device settle delay */
+ mdelay(1); /* device settle delay */
ppa_disconnect(dev);
- udelay(1000); /* device settle delay */
+ mdelay(1); /* device settle delay */
return SUCCESS;
}
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 907a1e8cc88..d26dbe2a33f 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -1130,7 +1130,13 @@ qla1280_eh_device_reset(struct scsi_cmnd *cmd)
static int
qla1280_eh_bus_reset(struct scsi_cmnd *cmd)
{
- return qla1280_error_action(cmd, BUS_RESET);
+ int rc;
+
+ spin_lock_irq(cmd->device->host->host_lock);
+ rc = qla1280_error_action(cmd, BUS_RESET);
+ spin_unlock_irq(cmd->device->host->host_lock);
+
+ return rc;
}
/**************************************************************************
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 360974eb2b2..e9091f9fbf2 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -753,8 +753,6 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
qla_printk(KERN_INFO, ha,
"scsi(%ld:%d:%d): LOOP RESET ISSUED.\n", ha->host_no, id, lun);
- spin_unlock_irq(ha->host->host_lock);
-
if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) {
DEBUG2(printk("%s failed:board disabled\n",__func__));
goto eh_bus_reset_done;
@@ -776,8 +774,6 @@ eh_bus_reset_done:
qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__,
(ret == FAILED) ? "failed" : "succeded");
- spin_lock_irq(ha->host->host_lock);
-
return ret;
}
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c
index 575f8a8fcf3..cb75e0b7bae 100644
--- a/drivers/scsi/qlogicfas408.c
+++ b/drivers/scsi/qlogicfas408.c
@@ -511,8 +511,14 @@ int qlogicfas408_abort(Scsi_Cmnd * cmd)
int qlogicfas408_bus_reset(Scsi_Cmnd * cmd)
{
struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
+ unsigned long flags;
+
priv->qabort = 2;
+
+ spin_lock_irqsave(cmd->device->host->host_lock, flags);
ql_zap(priv);
+ spin_unlock_irqrestore(cmd->device->host->host_lock, flags);
+
return SUCCESS;
}
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 87d925055b4..be56ee67b7f 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1053,9 +1053,7 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
if (!scmd->device->host->hostt->eh_bus_reset_handler)
return FAILED;
- spin_lock_irqsave(scmd->device->host->host_lock, flags);
rtn = scmd->device->host->hostt->eh_bus_reset_handler(scmd);
- spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
if (rtn == SUCCESS) {
if (!scmd->device->host->hostt->skip_settle_delay)
diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c
index ae9fdb52847..a0cace9aeb7 100644
--- a/drivers/scsi/seagate.c
+++ b/drivers/scsi/seagate.c
@@ -97,6 +97,7 @@
#include <linux/delay.h>
#include <linux/blkdev.h>
#include <linux/stat.h>
+#include <linux/delay.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -1631,7 +1632,7 @@ static int seagate_st0x_bus_reset(Scsi_Cmnd * SCpnt)
/* assert RESET signal on SCSI bus. */
WRITE_CONTROL (BASE_CMD | CMD_RST);
- udelay (20 * 1000);
+ mdelay (20);
WRITE_CONTROL (BASE_CMD);
st0x_aborted = DID_RESET;
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c
index 270f2aa88fa..ed66828705e 100644
--- a/drivers/scsi/sgiwd93.c
+++ b/drivers/scsi/sgiwd93.c
@@ -310,7 +310,11 @@ int sgiwd93_release(struct Scsi_Host *instance)
static int sgiwd93_bus_reset(Scsi_Cmnd *cmd)
{
/* FIXME perform bus-specific reset */
+
+ spin_lock_irq(cmd->device->host->host_lock);
wd33c93_host_reset(cmd);
+ spin_unlock_irq(cmd->device->host->host_lock);
+
return SUCCESS;
}
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 5ea62552d47..6af9c18b3f9 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -878,7 +878,13 @@ static int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd)
static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd)
{
- return sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd);
+ int rc;
+
+ spin_lock_irq(cmd->device->host->host_lock);
+ rc = sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd);
+ spin_unlock_irq(cmd->device->host->host_lock);
+
+ return rc;
}
static int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd)
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
index ee9df02efd5..9589c67de53 100644
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -2120,6 +2120,8 @@ static int DC390_bus_reset (struct scsi_cmnd *cmd)
struct dc390_acb* pACB = (struct dc390_acb*) cmd->device->host->hostdata;
u8 bval;
+ spin_lock_irq(cmd->device->host->host_lock);
+
bval = DC390_read8(CtrlReg1) | DIS_INT_ON_SCSI_RST;
DC390_write8(CtrlReg1, bval); /* disable IRQ on bus reset */
@@ -2127,7 +2129,7 @@ static int DC390_bus_reset (struct scsi_cmnd *cmd)
dc390_ResetSCSIBus(pACB);
dc390_ResetDevParam(pACB);
- udelay(1000);
+ mdelay(1);
pACB->pScsiHost->last_reset = jiffies + 3*HZ/2
+ HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
@@ -2142,6 +2144,8 @@ static int DC390_bus_reset (struct scsi_cmnd *cmd)
bval = DC390_read8(CtrlReg1) & ~DIS_INT_ON_SCSI_RST;
DC390_write8(CtrlReg1, bval); /* re-enable interrupt */
+ spin_unlock_irq(cmd->device->host->host_lock);
+
return SUCCESS;
}
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 739a9143477..1035b248eff 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -276,8 +276,6 @@ static int bus_reset(struct scsi_cmnd *srb)
US_DEBUGP("%s called\n", __FUNCTION__);
- scsi_unlock(us_to_host(us));
-
/* The USB subsystem doesn't handle synchronisation between
* a device's several drivers. Therefore we reset only devices
* with just one interface, which we of course own. */
@@ -304,7 +302,6 @@ static int bus_reset(struct scsi_cmnd *srb)
up(&(us->dev_semaphore));
/* lock the host for the return */
- scsi_lock(us_to_host(us));
return result < 0 ? FAILED : SUCCESS;
}