You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
[SCSI] allow sleeping in ->eh_host_reset_handler()
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
@@ -990,8 +990,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
|
||||
*
|
||||
|
||||
+12
-7
@@ -1005,13 +1005,7 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int fcp_scsi_bus_reset(Scsi_Cmnd *SCpnt)
|
||||
{
|
||||
printk ("FC: bus reset!\n");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
|
||||
static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
|
||||
{
|
||||
fc_channel *fc = FC_SCMND(SCpnt);
|
||||
fcp_cmnd *fcmd = FCP_CMND(SCpnt);
|
||||
@@ -1032,6 +1026,17 @@ int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
|
||||
else return FAILED;
|
||||
}
|
||||
|
||||
int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
|
||||
{
|
||||
int rc;
|
||||
|
||||
spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
|
||||
rc = __fcp_scsi_host_reset(SCpnt);
|
||||
spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int fcp_els_queue_it(fc_channel *fc, fcp_cmnd *fcmd)
|
||||
{
|
||||
long i;
|
||||
|
||||
@@ -27,7 +27,6 @@ EXPORT_SYMBOL(fc_do_prli);
|
||||
EXPORT_SYMBOL(fcp_scsi_queuecommand);
|
||||
EXPORT_SYMBOL(fcp_scsi_abort);
|
||||
EXPORT_SYMBOL(fcp_scsi_dev_reset);
|
||||
EXPORT_SYMBOL(fcp_scsi_bus_reset);
|
||||
EXPORT_SYMBOL(fcp_scsi_host_reset);
|
||||
|
||||
#endif /* CONFIG_MODULES */
|
||||
|
||||
@@ -158,7 +158,6 @@ int fc_do_prli(fc_channel *, unsigned char);
|
||||
int fcp_scsi_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
|
||||
int fcp_scsi_abort(Scsi_Cmnd *);
|
||||
int fcp_scsi_dev_reset(Scsi_Cmnd *);
|
||||
int fcp_scsi_bus_reset(Scsi_Cmnd *);
|
||||
int fcp_scsi_host_reset(Scsi_Cmnd *);
|
||||
|
||||
#endif /* !(_FCP_SCSI_H) */
|
||||
|
||||
@@ -1899,7 +1899,6 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
|
||||
{
|
||||
MPT_SCSI_HOST * hd;
|
||||
int status = SUCCESS;
|
||||
spinlock_t *host_lock = SCpnt->device->host->host_lock;
|
||||
|
||||
/* If we can't locate the host to reset, then we failed. */
|
||||
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
|
||||
@@ -1915,7 +1914,6 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
|
||||
/* If our attempts to reset the host failed, then return a failed
|
||||
* status. The host will be taken off line by the SCSI mid-layer.
|
||||
*/
|
||||
spin_unlock_irq(host_lock);
|
||||
if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
|
||||
status = FAILED;
|
||||
} else {
|
||||
@@ -1925,8 +1923,6 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
|
||||
hd->tmPending = 0;
|
||||
hd->tmState = TM_STATE_NONE;
|
||||
}
|
||||
spin_lock_irq(host_lock);
|
||||
|
||||
|
||||
dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
|
||||
"Status = %s\n",
|
||||
|
||||
@@ -755,8 +755,6 @@ zfcp_scsi_eh_host_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("host reset because of problems with "
|
||||
"unit 0x%016Lx\n", unit->fcp_lun);
|
||||
@@ -764,7 +762,6 @@ zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
|
||||
zfcp_erp_wait(unit->port->adapter);
|
||||
retval = SUCCESS;
|
||||
|
||||
spin_lock_irq(scsi_host->host_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@@ -1695,8 +1695,6 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
|
||||
|
||||
tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
|
||||
|
||||
spin_unlock_irq(tw_dev->host->host_lock);
|
||||
|
||||
tw_dev->num_resets++;
|
||||
|
||||
printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, TW_DRIVER, 0x2c, SCpnt->device->id, SCpnt->cmnd[0]);
|
||||
@@ -1709,7 +1707,6 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
|
||||
|
||||
retval = SUCCESS;
|
||||
out:
|
||||
spin_lock_irq(tw_dev->host->host_lock);
|
||||
return retval;
|
||||
} /* End twa_scsi_eh_reset() */
|
||||
|
||||
|
||||
@@ -1430,8 +1430,6 @@ static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt)
|
||||
|
||||
tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
|
||||
|
||||
spin_unlock_irq(tw_dev->host->host_lock);
|
||||
|
||||
tw_dev->num_resets++;
|
||||
|
||||
printk(KERN_WARNING "3w-xxxx: scsi%d: WARNING: Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, SCpnt->device->id, SCpnt->cmnd[0]);
|
||||
@@ -1444,7 +1442,6 @@ static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt)
|
||||
|
||||
retval = SUCCESS;
|
||||
out:
|
||||
spin_lock_irq(tw_dev->host->host_lock);
|
||||
return retval;
|
||||
} /* End tw_scsi_eh_reset() */
|
||||
|
||||
|
||||
@@ -1991,8 +1991,13 @@ NCR_700_host_reset(struct scsi_cmnd * SCp)
|
||||
SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
|
||||
scsi_print_command(SCp);
|
||||
|
||||
spin_lock_irq(SCp->device->host->host_lock);
|
||||
|
||||
NCR_700_internal_bus_reset(SCp->device->host);
|
||||
NCR_700_chip_reset(SCp->device->host);
|
||||
|
||||
spin_unlock_irq(SCp->device->host->host_lock);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -2746,9 +2746,15 @@ static int BusLogic_host_reset(struct scsi_cmnd * SCpnt)
|
||||
|
||||
unsigned int id = SCpnt->device->id;
|
||||
struct BusLogic_TargetStatistics *stats = &HostAdapter->TargetStatistics[id];
|
||||
int rc;
|
||||
|
||||
spin_lock_irq(SCpnt->device->host->host_lock);
|
||||
|
||||
BusLogic_IncrementErrorCounter(&stats->HostAdapterResetsRequested);
|
||||
|
||||
return BusLogic_ResetHostAdapter(HostAdapter, false);
|
||||
rc = BusLogic_ResetHostAdapter(HostAdapter, false);
|
||||
spin_unlock_irq(SCpnt->device->host->host_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -725,6 +725,9 @@ static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
|
||||
static int NCR53c406a_host_reset(Scsi_Cmnd * SCpnt)
|
||||
{
|
||||
DEB(printk("NCR53c406a_reset called\n"));
|
||||
|
||||
spin_lock_irq(SCpnt->device->host->host_lock);
|
||||
|
||||
outb(C4_IMG, CONFIG4); /* Select reg set 0 */
|
||||
outb(CHIP_RESET, CMD_REG);
|
||||
outb(SCSI_NOP, CMD_REG); /* required after reset */
|
||||
@@ -732,6 +735,9 @@ static int NCR53c406a_host_reset(Scsi_Cmnd * SCpnt)
|
||||
chip_init();
|
||||
|
||||
rtrc(2);
|
||||
|
||||
spin_unlock_irq(SCpnt->device->host->host_lock);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -222,6 +222,9 @@ static int a2091_bus_reset(Scsi_Cmnd *cmd)
|
||||
{
|
||||
/* FIXME perform bus-specific reset */
|
||||
|
||||
/* FIXME 2: kill this function, and let midlayer fall back
|
||||
to the same action, calling wd33c93_host_reset() */
|
||||
|
||||
spin_lock_irq(cmd->device->host->host_lock);
|
||||
wd33c93_host_reset(cmd);
|
||||
spin_unlock_irq(cmd->device->host->host_lock);
|
||||
|
||||
@@ -208,6 +208,9 @@ fail_register:
|
||||
static int a3000_bus_reset(Scsi_Cmnd *cmd)
|
||||
{
|
||||
/* FIXME perform bus-specific reset */
|
||||
|
||||
/* FIXME 2: kill this entire function, which should
|
||||
cause mid-layer to call wd33c93_host_reset anyway? */
|
||||
|
||||
spin_lock_irq(cmd->device->host->host_lock);
|
||||
wd33c93_host_reset(cmd);
|
||||
|
||||
@@ -384,10 +384,13 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
|
||||
AAC_DRIVERNAME);
|
||||
|
||||
|
||||
spin_lock_irq(host->host_lock);
|
||||
|
||||
aac = (struct aac_dev *)host->hostdata;
|
||||
if (aac_adapter_check_health(aac)) {
|
||||
printk(KERN_ERR "%s: Host adapter appears dead\n",
|
||||
AAC_DRIVERNAME);
|
||||
spin_unlock_irq(host->host_lock);
|
||||
return -ENODEV;
|
||||
}
|
||||
/*
|
||||
@@ -418,6 +421,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
|
||||
ssleep(1);
|
||||
spin_lock_irq(host->host_lock);
|
||||
}
|
||||
spin_unlock_irq(host->host_lock);
|
||||
printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@@ -1530,7 +1530,6 @@ static int aha1542_host_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);
|
||||
|
||||
@@ -1574,9 +1573,11 @@ static int aha1542_host_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;
|
||||
}
|
||||
|
||||
|
||||
@@ -10845,6 +10845,8 @@ aic7xxx_reset(Scsi_Cmnd *cmd)
|
||||
struct aic_dev_data *aic_dev;
|
||||
|
||||
p = (struct aic7xxx_host *) cmd->device->host->hostdata;
|
||||
spin_lock_irq(p->host->host_lock);
|
||||
|
||||
aic_dev = AIC_DEV(cmd);
|
||||
if(aic7xxx_position(cmd) < p->scb_data->numscbs)
|
||||
{
|
||||
@@ -10884,6 +10886,7 @@ aic7xxx_reset(Scsi_Cmnd *cmd)
|
||||
* longer have it.
|
||||
*/
|
||||
unpause_sequencer(p, FALSE);
|
||||
spin_unlock_irq(p->host->host_lock);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -10907,7 +10910,6 @@ aic7xxx_reset(Scsi_Cmnd *cmd)
|
||||
unpause_sequencer(p, FALSE);
|
||||
spin_unlock_irq(p->host->host_lock);
|
||||
ssleep(2);
|
||||
spin_lock_irq(p->host->host_lock);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -2659,6 +2659,8 @@ int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
|
||||
{
|
||||
FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
|
||||
|
||||
spin_lock_irq(info->host->host_lock);
|
||||
|
||||
fas216_checkmagic(info);
|
||||
|
||||
printk("scsi%d.%c: %s: resetting host\n",
|
||||
@@ -2686,6 +2688,7 @@ int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
|
||||
|
||||
fas216_init_chip(info);
|
||||
|
||||
spin_unlock_irq(info->host->host_lock);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
+12
-1
@@ -746,7 +746,7 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd)
|
||||
}
|
||||
|
||||
// This version of reset is called by the eh_error_handler
|
||||
static int adpt_reset(struct scsi_cmnd* cmd)
|
||||
static int __adpt_reset(struct scsi_cmnd* cmd)
|
||||
{
|
||||
adpt_hba* pHba;
|
||||
int rcode;
|
||||
@@ -762,6 +762,17 @@ static int adpt_reset(struct scsi_cmnd* cmd)
|
||||
}
|
||||
}
|
||||
|
||||
static int adpt_reset(struct scsi_cmnd* cmd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
spin_lock_irq(cmd->device->host->host_lock);
|
||||
rc = __adpt_reset(cmd);
|
||||
spin_unlock_irq(cmd->device->host->host_lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// This version of reset is called by the ioctls and indirectly from eh_error_handler via adpt_reset
|
||||
static int adpt_hba_reset(adpt_hba* pHba)
|
||||
{
|
||||
|
||||
@@ -1948,16 +1948,20 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
|
||||
ha->board_name, SCarg->device->channel, SCarg->device->id,
|
||||
SCarg->device->lun, SCarg->pid);
|
||||
|
||||
spin_lock_irq(shost->host_lock);
|
||||
|
||||
if (SCarg->host_scribble == NULL)
|
||||
printk("%s: reset, pid %ld inactive.\n", ha->board_name, SCarg->pid);
|
||||
|
||||
if (ha->in_reset) {
|
||||
printk("%s: reset, exit, already in reset.\n", ha->board_name);
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
if (wait_on_busy(shost->io_port, MAXLOOP)) {
|
||||
printk("%s: reset, exit, timeout error.\n", ha->board_name);
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
@@ -2012,6 +2016,7 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
|
||||
|
||||
if (do_dma(shost->io_port, 0, RESET_PIO)) {
|
||||
printk("%s: reset, cannot reset, timeout error.\n", ha->board_name);
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
@@ -2024,9 +2029,12 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
|
||||
ha->in_reset = 1;
|
||||
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
|
||||
/* FIXME: use a sleep instead */
|
||||
time = jiffies;
|
||||
while ((jiffies - time) < (10 * HZ) && limit++ < 200000)
|
||||
udelay(100L);
|
||||
|
||||
spin_lock_irq(shost->host_lock);
|
||||
|
||||
printk("%s: reset, interrupts disabled, loops %d.\n", ha->board_name, limit);
|
||||
@@ -2076,6 +2084,7 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
|
||||
else
|
||||
printk("%s: reset, exit.\n", ha->board_name);
|
||||
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -486,8 +486,11 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd)
|
||||
|
||||
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, cmd->abort_reason));
|
||||
|
||||
spin_lock_irq(host->host_lock);
|
||||
|
||||
if (HD(cmd)->state == RESET) {
|
||||
printk(KERN_WARNING "eata_pio_reset: exit, already in reset.\n");
|
||||
spin_unlock_irq(host->host_lock);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
@@ -536,6 +539,8 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd)
|
||||
|
||||
HD(cmd)->state = 0;
|
||||
|
||||
spin_unlock_irq(host->host_lock);
|
||||
|
||||
if (success) { /* hmmm... */
|
||||
DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, success.\n"));
|
||||
return SUCCESS;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user