aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2012-01-11 15:08:36 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-29 16:23:24 -0500
commitd230ce691c7712c4f56ba3378d6d2f44628a49f1 (patch)
tree5d8e334e322e26e807d5c186c9aa349c905c0c9d
parent8abda4d28a55ecb91e39ceb5e3ee264c5a3cd1af (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.c8
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c13
-rw-r--r--include/scsi/sas_ata.h9
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
702int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, 702void 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
748void sas_ata_schedule_reset(struct domain_device *dev) 744void 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
700out: 701out:
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
714enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) 715enum 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
42void sas_ata_task_abort(struct sas_task *task); 42void sas_ata_task_abort(struct sas_task *task);
43void sas_ata_strategy_handler(struct Scsi_Host *shost); 43void sas_ata_strategy_handler(struct Scsi_Host *shost);
44int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, 44void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
45 struct list_head *done_q); 45 struct list_head *done_q);
46void sas_probe_sata(struct work_struct *work); 46void sas_probe_sata(struct work_struct *work);
47void sas_ata_schedule_reset(struct domain_device *dev); 47void sas_ata_schedule_reset(struct domain_device *dev);
48void sas_ata_wait_eh(struct domain_device *dev); 48void 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
69static inline int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, 69static 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
75static inline void sas_probe_sata(struct work_struct *work) 74static inline void sas_probe_sata(struct work_struct *work)