aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2012-01-18 23:14:01 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-29 16:34:19 -0500
commit92625f9bff3853951cc75f5bc084ee67c1317d2f (patch)
tree9d5d2c89b99cdf73ec3c28703d0d5514e37ec73c /drivers/scsi/libsas
parentc666aae6919114d6cff789d79f80cfa85f3a7339 (diff)
[SCSI] libsas: restore scan order
ata devices are always scanned after ssp. Prior to the ata error handling reworks libsas would tend to scan devices in ascending expander phy order. Restore this ordering by deferring ssp discovery to a DISCE_PROBE event, and keep the probe order consistent with the discovery order, not the placement of sata devices. Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/libsas')
-rw-r--r--drivers/scsi/libsas/sas_ata.c29
-rw-r--r--drivers/scsi/libsas/sas_discover.c44
-rw-r--r--drivers/scsi/libsas/sas_expander.c4
3 files changed, 32 insertions, 45 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index 25008a42412f..a9ec1643ee93 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -683,35 +683,6 @@ static void sas_get_ata_command_set(struct domain_device *dev)
683 dev->sata_dev.command_set = ATAPI_COMMAND_SET; 683 dev->sata_dev.command_set = ATAPI_COMMAND_SET;
684} 684}
685 685
686void sas_probe_sata(struct work_struct *work)
687{
688 struct domain_device *dev, *n;
689 struct sas_discovery_event *ev =
690 container_of(work, struct sas_discovery_event, work);
691 struct asd_sas_port *port = ev->port;
692
693 clear_bit(DISCE_PROBE, &port->disc.pending);
694
695 list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) {
696 int err;
697
698 spin_lock_irq(&port->dev_list_lock);
699 list_add_tail(&dev->dev_list_node, &port->dev_list);
700 spin_unlock_irq(&port->dev_list_lock);
701
702 err = sas_rphy_add(dev->rphy);
703
704 if (err) {
705 SAS_DPRINTK("%s: for %s device %16llx returned %d\n",
706 __func__, dev->parent ? "exp-attached" :
707 "direct-attached",
708 SAS_ADDR(dev->sas_addr), err);
709 sas_unregister_dev(port, dev);
710 } else
711 list_del_init(&dev->disco_list_node);
712 }
713}
714
715/** 686/**
716 * sas_discover_sata -- discover an STP/SATA domain device 687 * sas_discover_sata -- discover an STP/SATA domain device
717 * @dev: pointer to struct domain_device of interest 688 * @dev: pointer to struct domain_device of interest
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index 8bcfcaa7b2e1..18fa364aa00f 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -152,7 +152,7 @@ static int sas_get_port_device(struct asd_sas_port *port)
152 152
153 dev->rphy = rphy; 153 dev->rphy = rphy;
154 154
155 if (dev_is_sata(dev)) 155 if (dev_is_sata(dev) || dev->dev_type == SAS_END_DEV)
156 list_add_tail(&dev->disco_list_node, &port->disco_list); 156 list_add_tail(&dev->disco_list_node, &port->disco_list);
157 else { 157 else {
158 spin_lock_irq(&port->dev_list_lock); 158 spin_lock_irq(&port->dev_list_lock);
@@ -198,8 +198,34 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev)
198 } 198 }
199} 199}
200 200
201/* ---------- Common/dispatchers ---------- */ 201static void sas_probe_devices(struct work_struct *work)
202{
203 struct domain_device *dev, *n;
204 struct sas_discovery_event *ev =
205 container_of(work, struct sas_discovery_event, work);
206 struct asd_sas_port *port = ev->port;
202 207
208 clear_bit(DISCE_PROBE, &port->disc.pending);
209
210 list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) {
211 int err;
212
213 spin_lock_irq(&port->dev_list_lock);
214 list_add_tail(&dev->dev_list_node, &port->dev_list);
215 spin_unlock_irq(&port->dev_list_lock);
216
217 err = sas_rphy_add(dev->rphy);
218
219 if (err) {
220 SAS_DPRINTK("%s: for %s device %16llx returned %d\n",
221 __func__, dev->parent ? "exp-attached" :
222 "direct-attached",
223 SAS_ADDR(dev->sas_addr), err);
224 sas_unregister_dev(port, dev);
225 } else
226 list_del_init(&dev->disco_list_node);
227 }
228}
203 229
204/** 230/**
205 * sas_discover_end_dev -- discover an end device (SSP, etc) 231 * sas_discover_end_dev -- discover an end device (SSP, etc)
@@ -213,18 +239,10 @@ int sas_discover_end_dev(struct domain_device *dev)
213 239
214 res = sas_notify_lldd_dev_found(dev); 240 res = sas_notify_lldd_dev_found(dev);
215 if (res) 241 if (res)
216 goto out_err2; 242 return res;
217 243 sas_discover_event(dev->port, DISCE_PROBE);
218 res = sas_rphy_add(dev->rphy);
219 if (res)
220 goto out_err;
221 244
222 return 0; 245 return 0;
223
224out_err:
225 sas_notify_lldd_dev_gone(dev);
226out_err2:
227 return res;
228} 246}
229 247
230/* ---------- Device registration and unregistration ---------- */ 248/* ---------- Device registration and unregistration ---------- */
@@ -491,7 +509,7 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port)
491 static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = { 509 static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = {
492 [DISCE_DISCOVER_DOMAIN] = sas_discover_domain, 510 [DISCE_DISCOVER_DOMAIN] = sas_discover_domain,
493 [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain, 511 [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain,
494 [DISCE_PROBE] = sas_probe_sata, 512 [DISCE_PROBE] = sas_probe_devices,
495 [DISCE_DESTRUCT] = sas_destruct_devices, 513 [DISCE_DESTRUCT] = sas_destruct_devices,
496 }; 514 };
497 515
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index d63f0fbcd103..14e3244c1b20 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -806,9 +806,7 @@ static struct domain_device *sas_ex_discover_end_dev(
806 child->rphy = rphy; 806 child->rphy = rphy;
807 sas_fill_in_rphy(child, rphy); 807 sas_fill_in_rphy(child, rphy);
808 808
809 spin_lock_irq(&parent->port->dev_list_lock); 809 list_add_tail(&child->disco_list_node, &parent->port->disco_list);
810 list_add_tail(&child->dev_list_node, &parent->port->dev_list);
811 spin_unlock_irq(&parent->port->dev_list_lock);
812 810
813 res = sas_discover_end_dev(child); 811 res = sas_discover_end_dev(child);
814 if (res) { 812 if (res) {