[SCSI] host state model update: reimplement scsi_host_cancel
Remove the old scsi_host_cancel function as it has not been working for sometime do to the device list possibly being empty when it is called and possible race issues. Add setting of SHOST_CANCEL at the state of beginning of scsi_remove_host. Signed-off-by: Mike Anderson <andmike@us.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
d330187408
commit
d2c9d9eafa
2 changed files with 2 additions and 18 deletions
|
@ -127,30 +127,14 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(scsi_host_set_state);
|
EXPORT_SYMBOL(scsi_host_set_state);
|
||||||
|
|
||||||
/**
|
|
||||||
* scsi_host_cancel - cancel outstanding IO to this host
|
|
||||||
* @shost: pointer to struct Scsi_Host
|
|
||||||
* recovery: recovery requested to run.
|
|
||||||
**/
|
|
||||||
static void scsi_host_cancel(struct Scsi_Host *shost, int recovery)
|
|
||||||
{
|
|
||||||
struct scsi_device *sdev;
|
|
||||||
|
|
||||||
scsi_host_set_state(shost, SHOST_CANCEL);
|
|
||||||
shost_for_each_device(sdev, shost) {
|
|
||||||
scsi_device_cancel(sdev, recovery);
|
|
||||||
}
|
|
||||||
wait_event(shost->host_wait, (shost->shost_state != SHOST_RECOVERY));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* scsi_remove_host - remove a scsi host
|
* scsi_remove_host - remove a scsi host
|
||||||
* @shost: a pointer to a scsi host to remove
|
* @shost: a pointer to a scsi host to remove
|
||||||
**/
|
**/
|
||||||
void scsi_remove_host(struct Scsi_Host *shost)
|
void scsi_remove_host(struct Scsi_Host *shost)
|
||||||
{
|
{
|
||||||
|
scsi_host_set_state(shost, SHOST_CANCEL);
|
||||||
scsi_forget_host(shost);
|
scsi_forget_host(shost);
|
||||||
scsi_host_cancel(shost, 0);
|
|
||||||
scsi_proc_host_rm(shost);
|
scsi_proc_host_rm(shost);
|
||||||
|
|
||||||
scsi_host_set_state(shost, SHOST_DEL);
|
scsi_host_set_state(shost, SHOST_DEL);
|
||||||
|
|
|
@ -627,7 +627,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
|
||||||
spin_lock_irqsave(host->host_lock, flags);
|
spin_lock_irqsave(host->host_lock, flags);
|
||||||
scsi_cmd_get_serial(host, cmd);
|
scsi_cmd_get_serial(host, cmd);
|
||||||
|
|
||||||
if (unlikely(host->shost_state == SHOST_CANCEL)) {
|
if (unlikely(host->shost_state == SHOST_DEL)) {
|
||||||
cmd->result = (DID_NO_CONNECT << 16);
|
cmd->result = (DID_NO_CONNECT << 16);
|
||||||
scsi_done(cmd);
|
scsi_done(cmd);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Reference in a new issue