提交 d7a1bb0a 编写于 作者: J James Smart 提交者: James Bottomley

[SCSI] Block I/O while SG reset operation in progress - the midlayer patch

The scsi midlayer portion of the patch
Signed-off-by: NJames Smart <James.Smart@emulex.com>
Signed-off-by: NJames Bottomley <James.Bottomley@SteelEye.com>
上级 12e9b5fb
...@@ -1672,7 +1672,9 @@ int ...@@ -1672,7 +1672,9 @@ int
scsi_reset_provider(struct scsi_device *dev, int flag) scsi_reset_provider(struct scsi_device *dev, int flag)
{ {
struct scsi_cmnd *scmd = scsi_get_command(dev, GFP_KERNEL); struct scsi_cmnd *scmd = scsi_get_command(dev, GFP_KERNEL);
struct Scsi_Host *shost = dev->host;
struct request req; struct request req;
unsigned long flags;
int rtn; int rtn;
scmd->request = &req; scmd->request = &req;
...@@ -1699,6 +1701,10 @@ scsi_reset_provider(struct scsi_device *dev, int flag) ...@@ -1699,6 +1701,10 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
*/ */
scmd->pid = 0; scmd->pid = 0;
spin_lock_irqsave(shost->host_lock, flags);
shost->tmf_in_progress = 1;
spin_unlock_irqrestore(shost->host_lock, flags);
switch (flag) { switch (flag) {
case SCSI_TRY_RESET_DEVICE: case SCSI_TRY_RESET_DEVICE:
rtn = scsi_try_bus_device_reset(scmd); rtn = scsi_try_bus_device_reset(scmd);
...@@ -1717,6 +1723,22 @@ scsi_reset_provider(struct scsi_device *dev, int flag) ...@@ -1717,6 +1723,22 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
rtn = FAILED; rtn = FAILED;
} }
spin_lock_irqsave(shost->host_lock, flags);
shost->tmf_in_progress = 0;
spin_unlock_irqrestore(shost->host_lock, flags);
/*
* be sure to wake up anyone who was sleeping or had their queue
* suspended while we performed the TMF.
*/
SCSI_LOG_ERROR_RECOVERY(3,
printk("%s: waking up host to restart after TMF\n",
__FUNCTION__));
wake_up(&shost->host_wait);
scsi_run_host_queues(shost);
scsi_next_command(scmd); scsi_next_command(scmd);
return rtn; return rtn;
} }
......
...@@ -542,6 +542,9 @@ struct Scsi_Host { ...@@ -542,6 +542,9 @@ struct Scsi_Host {
*/ */
unsigned ordered_tag:1; unsigned ordered_tag:1;
/* task mgmt function in progress */
unsigned tmf_in_progress:1;
/* /*
* Optional work queue to be utilized by the transport * Optional work queue to be utilized by the transport
*/ */
...@@ -619,7 +622,8 @@ static inline int scsi_host_in_recovery(struct Scsi_Host *shost) ...@@ -619,7 +622,8 @@ static inline int scsi_host_in_recovery(struct Scsi_Host *shost)
{ {
return shost->shost_state == SHOST_RECOVERY || return shost->shost_state == SHOST_RECOVERY ||
shost->shost_state == SHOST_CANCEL_RECOVERY || shost->shost_state == SHOST_CANCEL_RECOVERY ||
shost->shost_state == SHOST_DEL_RECOVERY; shost->shost_state == SHOST_DEL_RECOVERY ||
shost->tmf_in_progress;
} }
extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *); extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册