*
* 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
*
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);
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){
spin_lock_irq(host_lock);
return FAILED;
}
- spin_lock_irq(host_lock);
+
return SUCCESS;
}
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);
zfcp_erp_wait(unit->port->adapter);
retval = SUCCESS;
- spin_lock_irq(scsi_host->host_lock);
return retval;
}
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;
}
* 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;
}
{
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;
}
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;
}
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;
}
* 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),
}
}
+ spin_unlock_irq(SCpnt->device->host->host_lock);
return SUCCESS;
fail:
+ spin_unlock_irq(SCpnt->device->host->host_lock);
return FAILED;
}
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. "
{
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. "
* @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;
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
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;
called_once = 1;
#endif
+ spin_lock_irqsave(shpnt->host_lock, flags);
+
outb(1, SCSI_Cntl_port);
do_pause(2);
outb(0, SCSI_Cntl_port);
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. */
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;
}
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;
}
#include <linux/blkdev.h>
#include <linux/parport.h>
#include <linux/workqueue.h>
+#include <linux/delay.h>
#include <asm/io.h>
#include <scsi/scsi.h>
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);
}
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;
}
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;
hostdata->outgoing_len = 0;
cmd->result = DID_RESET << 16;
+
+ spin_unlock_irqrestore(instance->host_lock, flags);
return SUCCESS;
}
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;
}
* 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];
return ret;
}
+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)
{
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;
}
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);
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. */
}
#include <linux/blkdev.h>
#include <linux/parport.h>
#include <linux/workqueue.h>
+#include <linux/delay.h>
#include <asm/io.h>
#include <scsi/scsi.h>
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;
}
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;
}
/**************************************************************************
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;
qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__,
(ret == FAILED) ? "failed" : "succeded");
- spin_lock_irq(ha->host->host_lock);
-
return ret;
}
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;
}
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)
#include <linux/delay.h>
#include <linux/blkdev.h>
#include <linux/stat.h>
+#include <linux/delay.h>
#include <asm/io.h>
#include <asm/system.h>
/* 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;
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;
}
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)
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 */
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];
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;
}
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. */
up(&(us->dev_semaphore));
/* lock the host for the return */
- scsi_lock(us_to_host(us));
return result < 0 ? FAILED : SUCCESS;
}