diff options
Diffstat (limited to 'drivers/scsi/libsas/sas_scsi_host.c')
-rw-r--r-- | drivers/scsi/libsas/sas_scsi_host.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index f0b9b7bf1882..a09da44e282b 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
@@ -667,16 +667,20 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head * | |||
667 | goto out; | 667 | goto out; |
668 | } | 668 | } |
669 | 669 | ||
670 | |||
670 | void sas_scsi_recover_host(struct Scsi_Host *shost) | 671 | void sas_scsi_recover_host(struct Scsi_Host *shost) |
671 | { | 672 | { |
672 | struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost); | 673 | struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost); |
673 | unsigned long flags; | ||
674 | LIST_HEAD(eh_work_q); | 674 | LIST_HEAD(eh_work_q); |
675 | int tries = 0; | ||
676 | bool retry; | ||
675 | 677 | ||
676 | spin_lock_irqsave(shost->host_lock, flags); | 678 | retry: |
679 | tries++; | ||
680 | retry = true; | ||
681 | spin_lock_irq(shost->host_lock); | ||
677 | list_splice_init(&shost->eh_cmd_q, &eh_work_q); | 682 | list_splice_init(&shost->eh_cmd_q, &eh_work_q); |
678 | shost->host_eh_scheduled = 0; | 683 | spin_unlock_irq(shost->host_lock); |
679 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
680 | 684 | ||
681 | SAS_DPRINTK("Enter %s busy: %d failed: %d\n", | 685 | SAS_DPRINTK("Enter %s busy: %d failed: %d\n", |
682 | __func__, shost->host_busy, shost->host_failed); | 686 | __func__, shost->host_busy, shost->host_failed); |
@@ -710,8 +714,19 @@ out: | |||
710 | 714 | ||
711 | scsi_eh_flush_done_q(&ha->eh_done_q); | 715 | scsi_eh_flush_done_q(&ha->eh_done_q); |
712 | 716 | ||
713 | SAS_DPRINTK("--- Exit %s: busy: %d failed: %d\n", | 717 | /* check if any new eh work was scheduled during the last run */ |
714 | __func__, shost->host_busy, shost->host_failed); | 718 | spin_lock_irq(&ha->lock); |
719 | if (ha->eh_active == 0) { | ||
720 | shost->host_eh_scheduled = 0; | ||
721 | retry = false; | ||
722 | } | ||
723 | spin_unlock_irq(&ha->lock); | ||
724 | |||
725 | if (retry) | ||
726 | goto retry; | ||
727 | |||
728 | SAS_DPRINTK("--- Exit %s: busy: %d failed: %d tries: %d\n", | ||
729 | __func__, shost->host_busy, shost->host_failed, tries); | ||
715 | } | 730 | } |
716 | 731 | ||
717 | enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) | 732 | enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) |