diff options
-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 | ||||
-rw-r--r-- | include/scsi/scsi_eh.h | 1 | ||||
-rw-r--r-- | include/scsi/scsi_host.h | 1 |
5 files changed, 5 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 */ |
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index d160880b2a87..212c983a6a18 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h | |||
@@ -35,6 +35,7 @@ static inline int scsi_sense_valid(struct scsi_sense_hdr *sshdr) | |||
35 | } | 35 | } |
36 | 36 | ||
37 | 37 | ||
38 | extern void scsi_eh_wakeup(struct Scsi_Host *shost); | ||
38 | extern void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, | 39 | extern void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, |
39 | struct list_head *done_q); | 40 | struct list_head *done_q); |
40 | extern void scsi_eh_flush_done_q(struct list_head *done_q); | 41 | extern void scsi_eh_flush_done_q(struct list_head *done_q); |
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index de6ce541a046..a42efd6e4be8 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
@@ -472,6 +472,7 @@ struct Scsi_Host { | |||
472 | */ | 472 | */ |
473 | unsigned int host_busy; /* commands actually active on low-level */ | 473 | unsigned int host_busy; /* commands actually active on low-level */ |
474 | unsigned int host_failed; /* commands that failed. */ | 474 | unsigned int host_failed; /* commands that failed. */ |
475 | unsigned int host_eh_scheduled; /* EH scheduled without command */ | ||
475 | 476 | ||
476 | unsigned short host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */ | 477 | unsigned short host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */ |
477 | int resetting; /* if set, it means that last_reset is a valid value */ | 478 | int resetting; /* if set, it means that last_reset is a valid value */ |