diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/scsi_error.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index cf70f0bb8375..99ef1a58f478 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -61,6 +61,12 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd); static int scsi_try_to_abort_cmd(struct scsi_host_template *, struct scsi_cmnd *); +#ifdef CONFIG_AHCI_IMX +extern void *sg_io_buffer_hack; +#else +#define sg_io_buffer_hack NULL +#endif + /* called with shost->host_lock held */ void scsi_eh_wakeup(struct Scsi_Host *shost) { @@ -69,6 +75,11 @@ void scsi_eh_wakeup(struct Scsi_Host *shost) wake_up_process(shost->ehandler); SCSI_LOG_ERROR_RECOVERY(5, shost_printk(KERN_INFO, shost, "Waking error handler thread\n")); + } else if ((shost->host_failed > 0) || (sg_io_buffer_hack != NULL)) { + trace_scsi_eh_wakeup(shost); + wake_up_process(shost->ehandler); + SCSI_LOG_ERROR_RECOVERY(5, shost_printk(KERN_INFO, shost, + "Waking error handler thread\n")); } } @@ -2141,8 +2152,15 @@ int scsi_error_handler(void *data) if (kthread_should_stop()) break; + /* + * Do not go to sleep, when there is host_failed when the + * one-PRD per command workaroud is tiggered. + * Because that ata/scsi subsystem maybe hang, when CD_ROM + * and HDD are accessed simultaneously. + */ if ((shost->host_failed == 0 && shost->host_eh_scheduled == 0) || - shost->host_failed != atomic_read(&shost->host_busy)) { + ((shost->host_failed != atomic_read(&shost->host_busy)) && + (sg_io_buffer_hack == NULL) && (shost->host_failed > 0))) { SCSI_LOG_ERROR_RECOVERY(1, shost_printk(KERN_INFO, shost, "scsi_eh_%d: sleeping\n", |