diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-09-24 00:26:49 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-24 00:26:49 -0400 |
commit | 98ed72deebfd2b55b7e1bb94c8175b1169999212 (patch) | |
tree | f1682a68f65e0a38159f55a58c054779d749f8df /drivers/scsi/hosts.c | |
parent | dbaa9a9d2b37d838125fb7f2b9fdc5dc5fa4eaa9 (diff) | |
parent | 87e807b6c461bbd449496a4c3ab78ab164a4ba97 (diff) | |
download | blackbird-op-linux-98ed72deebfd2b55b7e1bb94c8175b1169999212.tar.gz blackbird-op-linux-98ed72deebfd2b55b7e1bb94c8175b1169999212.zip |
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'drivers/scsi/hosts.c')
-rw-r--r-- | drivers/scsi/hosts.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 85503fad789a..f2a72d33132c 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -98,6 +98,7 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state) switch (oldstate) { case SHOST_CREATED: case SHOST_RUNNING: + case SHOST_CANCEL_RECOVERY: break; default: goto illegal; @@ -107,12 +108,31 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state) case SHOST_DEL: switch (oldstate) { case SHOST_CANCEL: + case SHOST_DEL_RECOVERY: break; default: goto illegal; } break; + case SHOST_CANCEL_RECOVERY: + switch (oldstate) { + case SHOST_CANCEL: + case SHOST_RECOVERY: + break; + default: + goto illegal; + } + break; + + case SHOST_DEL_RECOVERY: + switch (oldstate) { + case SHOST_CANCEL_RECOVERY: + break; + default: + goto illegal; + } + break; } shost->shost_state = state; return 0; @@ -134,13 +154,24 @@ EXPORT_SYMBOL(scsi_host_set_state); **/ void scsi_remove_host(struct Scsi_Host *shost) { + unsigned long flags; down(&shost->scan_mutex); - scsi_host_set_state(shost, SHOST_CANCEL); + spin_lock_irqsave(shost->host_lock, flags); + if (scsi_host_set_state(shost, SHOST_CANCEL)) + if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)) { + spin_unlock_irqrestore(shost->host_lock, flags); + up(&shost->scan_mutex); + return; + } + spin_unlock_irqrestore(shost->host_lock, flags); up(&shost->scan_mutex); scsi_forget_host(shost); scsi_proc_host_rm(shost); - scsi_host_set_state(shost, SHOST_DEL); + spin_lock_irqsave(shost->host_lock, flags); + if (scsi_host_set_state(shost, SHOST_DEL)) + BUG_ON(scsi_host_set_state(shost, SHOST_DEL_RECOVERY)); + spin_unlock_irqrestore(shost->host_lock, flags); transport_unregister_device(&shost->shost_gendev); class_device_unregister(&shost->shost_classdev); |