diff options
author | Dan Williams <dan.j.williams@intel.com> | 2012-01-11 15:08:36 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-29 16:23:24 -0500 |
commit | d230ce691c7712c4f56ba3378d6d2f44628a49f1 (patch) | |
tree | 5d8e334e322e26e807d5c186c9aa349c905c0c9d | |
parent | 8abda4d28a55ecb91e39ceb5e3ee264c5a3cd1af (diff) |
[SCSI] libsas: fix mixed topology recovery
If we have a domain with sas and sata devices there may still be sas
recovery actions to take after peeling off the commands to send to
libata.
Reported-by: Andrzej Jakowski <andrzej.jakowski@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r-- | drivers/scsi/libsas/sas_ata.c | 8 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_scsi_host.c | 13 | ||||
-rw-r--r-- | include/scsi/sas_ata.h | 9 |
3 files changed, 13 insertions, 17 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 26a943eb153a..40edf520d69a 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -699,10 +699,9 @@ void sas_ata_strategy_handler(struct Scsi_Host *shost) | |||
699 | sas_enable_revalidation(sas_ha); | 699 | sas_enable_revalidation(sas_ha); |
700 | } | 700 | } |
701 | 701 | ||
702 | int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, | 702 | void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, |
703 | struct list_head *done_q) | 703 | struct list_head *done_q) |
704 | { | 704 | { |
705 | int rtn = 0; | ||
706 | struct scsi_cmnd *cmd, *n; | 705 | struct scsi_cmnd *cmd, *n; |
707 | struct ata_port *ap; | 706 | struct ata_port *ap; |
708 | 707 | ||
@@ -719,7 +718,6 @@ int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, | |||
719 | if (ap && ap != ddev->sata_dev.ap) | 718 | if (ap && ap != ddev->sata_dev.ap) |
720 | continue; | 719 | continue; |
721 | ap = ddev->sata_dev.ap; | 720 | ap = ddev->sata_dev.ap; |
722 | rtn = 1; | ||
723 | list_move(&cmd->eh_entry, &sata_q); | 721 | list_move(&cmd->eh_entry, &sata_q); |
724 | } | 722 | } |
725 | 723 | ||
@@ -741,8 +739,6 @@ int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, | |||
741 | list_del_init(sata_q.next); | 739 | list_del_init(sata_q.next); |
742 | } | 740 | } |
743 | } while (ap); | 741 | } while (ap); |
744 | |||
745 | return rtn; | ||
746 | } | 742 | } |
747 | 743 | ||
748 | void sas_ata_schedule_reset(struct domain_device *dev) | 744 | void sas_ata_schedule_reset(struct domain_device *dev) |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index b563ff27626b..e58ca50517d5 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
@@ -678,7 +678,8 @@ void sas_scsi_recover_host(struct Scsi_Host *shost) | |||
678 | shost->host_eh_scheduled = 0; | 678 | shost->host_eh_scheduled = 0; |
679 | spin_unlock_irqrestore(shost->host_lock, flags); | 679 | spin_unlock_irqrestore(shost->host_lock, flags); |
680 | 680 | ||
681 | SAS_DPRINTK("Enter %s\n", __func__); | 681 | SAS_DPRINTK("Enter %s busy: %d failed: %d\n", |
682 | __func__, shost->host_busy, shost->host_failed); | ||
682 | /* | 683 | /* |
683 | * Deal with commands that still have SAS tasks (i.e. they didn't | 684 | * Deal with commands that still have SAS tasks (i.e. they didn't |
684 | * complete via the normal sas_task completion mechanism) | 685 | * complete via the normal sas_task completion mechanism) |
@@ -693,9 +694,9 @@ void sas_scsi_recover_host(struct Scsi_Host *shost) | |||
693 | * scsi_unjam_host does, but we skip scsi_eh_abort_cmds because any | 694 | * scsi_unjam_host does, but we skip scsi_eh_abort_cmds because any |
694 | * command we see here has no sas_task and is thus unknown to the HA. | 695 | * command we see here has no sas_task and is thus unknown to the HA. |
695 | */ | 696 | */ |
696 | if (!sas_ata_eh(shost, &eh_work_q, &ha->eh_done_q)) | 697 | sas_ata_eh(shost, &eh_work_q, &ha->eh_done_q); |
697 | if (!scsi_eh_get_sense(&eh_work_q, &ha->eh_done_q)) | 698 | if (!scsi_eh_get_sense(&eh_work_q, &ha->eh_done_q)) |
698 | scsi_eh_ready_devs(shost, &eh_work_q, &ha->eh_done_q); | 699 | scsi_eh_ready_devs(shost, &eh_work_q, &ha->eh_done_q); |
699 | 700 | ||
700 | out: | 701 | out: |
701 | clear_bit(SAS_HA_FROZEN, &ha->state); | 702 | clear_bit(SAS_HA_FROZEN, &ha->state); |
@@ -707,8 +708,8 @@ out: | |||
707 | 708 | ||
708 | scsi_eh_flush_done_q(&ha->eh_done_q); | 709 | scsi_eh_flush_done_q(&ha->eh_done_q); |
709 | 710 | ||
710 | SAS_DPRINTK("--- Exit %s\n", __func__); | 711 | SAS_DPRINTK("--- Exit %s: busy: %d failed: %d\n", |
711 | return; | 712 | __func__, shost->host_busy, shost->host_failed); |
712 | } | 713 | } |
713 | 714 | ||
714 | enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) | 715 | enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) |
diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h index da3f37727387..cb724fd010f6 100644 --- a/include/scsi/sas_ata.h +++ b/include/scsi/sas_ata.h | |||
@@ -41,8 +41,8 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev, | |||
41 | 41 | ||
42 | void sas_ata_task_abort(struct sas_task *task); | 42 | void sas_ata_task_abort(struct sas_task *task); |
43 | void sas_ata_strategy_handler(struct Scsi_Host *shost); | 43 | void sas_ata_strategy_handler(struct Scsi_Host *shost); |
44 | int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, | 44 | void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, |
45 | struct list_head *done_q); | 45 | struct list_head *done_q); |
46 | void sas_probe_sata(struct work_struct *work); | 46 | void sas_probe_sata(struct work_struct *work); |
47 | void sas_ata_schedule_reset(struct domain_device *dev); | 47 | void sas_ata_schedule_reset(struct domain_device *dev); |
48 | void sas_ata_wait_eh(struct domain_device *dev); | 48 | void sas_ata_wait_eh(struct domain_device *dev); |
@@ -66,10 +66,9 @@ static inline void sas_ata_strategy_handler(struct Scsi_Host *shost) | |||
66 | { | 66 | { |
67 | } | 67 | } |
68 | 68 | ||
69 | static inline int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, | 69 | static inline void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, |
70 | struct list_head *done_q) | 70 | struct list_head *done_q) |
71 | { | 71 | { |
72 | return 0; | ||
73 | } | 72 | } |
74 | 73 | ||
75 | static inline void sas_probe_sata(struct work_struct *work) | 74 | static inline void sas_probe_sata(struct work_struct *work) |