diff options
author | Tejun Heo <htejun@gmail.com> | 2006-05-15 07:57:20 -0400 |
---|---|---|
committer | Tejun Heo <htejun@gmail.com> | 2006-05-15 07:57:20 -0400 |
commit | ee7863bc68fa6ad6fe7cfcc0e5ebe9efe0c0664e (patch) | |
tree | 2ca442445403be0101abf0592df3c625633dd49d /drivers/scsi | |
parent | 89f48c4d67dd875cf2216d4402bf77eda41fbdd9 (diff) |
[PATCH] SCSI: implement shost->host_eh_scheduled
libata needs to invoke EH without scmd. This patch adds
shost->host_eh_scheduled to implement such behavior.
Currently the only user of this feature is libata and no general
interface is defined. This patch simply adds handling for
host_eh_scheduled where needed and exports scsi_eh_wakeup() to
modules. The rest is upto libata. This is the result of the
following discussion.
http://thread.gmane.org/gmane.linux.scsi/23853/focus=9760
In short, SCSI host is not supposed to know about exceptions unrelated
to specific device or command. Such exceptions should be handled by
transport layer proper. However, the distinction is not essential to
ATA and libata is planning to depart from SCSI, so, for the time
being, libata will be using SCSI EH to handle such exceptions.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/scsi_error.c | 3 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 2 | ||||
-rw-r--r-- | drivers/scsi/scsi_priv.h | 1 |
3 files changed, 3 insertions, 3 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 1c75646f9689..9ca71cbefce0 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -56,6 +56,7 @@ void scsi_eh_wakeup(struct Scsi_Host *shost) | |||
56 | printk("Waking error handler thread\n")); | 56 | printk("Waking error handler thread\n")); |
57 | } | 57 | } |
58 | } | 58 | } |
59 | EXPORT_SYMBOL_GPL(scsi_eh_wakeup); | ||
59 | 60 | ||
60 | /** | 61 | /** |
61 | * scsi_eh_scmd_add - add scsi cmd to error handling. | 62 | * scsi_eh_scmd_add - add scsi cmd to error handling. |
@@ -1517,7 +1518,7 @@ int scsi_error_handler(void *data) | |||
1517 | */ | 1518 | */ |
1518 | set_current_state(TASK_INTERRUPTIBLE); | 1519 | set_current_state(TASK_INTERRUPTIBLE); |
1519 | while (!kthread_should_stop()) { | 1520 | while (!kthread_should_stop()) { |
1520 | if (shost->host_failed == 0 || | 1521 | if ((shost->host_failed == 0 && shost->host_eh_scheduled == 0) || |
1521 | shost->host_failed != shost->host_busy) { | 1522 | shost->host_failed != shost->host_busy) { |
1522 | SCSI_LOG_ERROR_RECOVERY(1, | 1523 | SCSI_LOG_ERROR_RECOVERY(1, |
1523 | printk("Error handler scsi_eh_%d sleeping\n", | 1524 | printk("Error handler scsi_eh_%d sleeping\n", |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 7b0f9a3810d2..c55d195b6f4f 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -566,7 +566,7 @@ void scsi_device_unbusy(struct scsi_device *sdev) | |||
566 | spin_lock_irqsave(shost->host_lock, flags); | 566 | spin_lock_irqsave(shost->host_lock, flags); |
567 | shost->host_busy--; | 567 | shost->host_busy--; |
568 | if (unlikely(scsi_host_in_recovery(shost) && | 568 | if (unlikely(scsi_host_in_recovery(shost) && |
569 | shost->host_failed)) | 569 | (shost->host_failed || shost->host_eh_scheduled))) |
570 | scsi_eh_wakeup(shost); | 570 | scsi_eh_wakeup(shost); |
571 | spin_unlock(shost->host_lock); | 571 | spin_unlock(shost->host_lock); |
572 | spin_lock(sdev->request_queue->queue_lock); | 572 | spin_lock(sdev->request_queue->queue_lock); |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 27c48274e8cb..0b39081113be 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -63,7 +63,6 @@ extern int scsi_delete_timer(struct scsi_cmnd *); | |||
63 | extern void scsi_times_out(struct scsi_cmnd *cmd); | 63 | extern void scsi_times_out(struct scsi_cmnd *cmd); |
64 | extern int scsi_error_handler(void *host); | 64 | extern int scsi_error_handler(void *host); |
65 | extern int scsi_decide_disposition(struct scsi_cmnd *cmd); | 65 | extern int scsi_decide_disposition(struct scsi_cmnd *cmd); |
66 | extern void scsi_eh_wakeup(struct Scsi_Host *shost); | ||
67 | extern int scsi_eh_scmd_add(struct scsi_cmnd *, int); | 66 | extern int scsi_eh_scmd_add(struct scsi_cmnd *, int); |
68 | 67 | ||
69 | /* scsi_lib.c */ | 68 | /* scsi_lib.c */ |