summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas/sas_discover.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2012-01-18 20:14:01 -0800
committerJames Bottomley <JBottomley@Parallels.com>2012-02-29 15:34:19 -0600
commit92625f9bff3853951cc75f5bc084ee67c1317d2f (patch)
tree9d5d2c89b99cdf73ec3c28703d0d5514e37ec73c /drivers/scsi/libsas/sas_discover.c
parentc666aae6919114d6cff789d79f80cfa85f3a7339 (diff)
downloadlinux-92625f9bff3853951cc75f5bc084ee67c1317d2f.tar.bz2
[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/sas_discover.c')
-rw-r--r--drivers/scsi/libsas/sas_discover.c44
1 files changed, 31 insertions, 13 deletions
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)
dev->rphy = rphy;
- if (dev_is_sata(dev))
+ if (dev_is_sata(dev) || dev->dev_type == SAS_END_DEV)
list_add_tail(&dev->disco_list_node, &port->disco_list);
else {
spin_lock_irq(&port->dev_list_lock);
@@ -198,8 +198,34 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev)
}
}
-/* ---------- Common/dispatchers ---------- */
+static void sas_probe_devices(struct work_struct *work)
+{
+ struct domain_device *dev, *n;
+ struct sas_discovery_event *ev =
+ container_of(work, struct sas_discovery_event, work);
+ struct asd_sas_port *port = ev->port;
+ clear_bit(DISCE_PROBE, &port->disc.pending);
+
+ list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) {
+ int err;
+
+ spin_lock_irq(&port->dev_list_lock);
+ list_add_tail(&dev->dev_list_node, &port->dev_list);
+ spin_unlock_irq(&port->dev_list_lock);
+
+ err = sas_rphy_add(dev->rphy);
+
+ if (err) {
+ SAS_DPRINTK("%s: for %s device %16llx returned %d\n",
+ __func__, dev->parent ? "exp-attached" :
+ "direct-attached",
+ SAS_ADDR(dev->sas_addr), err);
+ sas_unregister_dev(port, dev);
+ } else
+ list_del_init(&dev->disco_list_node);
+ }
+}
/**
* sas_discover_end_dev -- discover an end device (SSP, etc)
@@ -213,18 +239,10 @@ int sas_discover_end_dev(struct domain_device *dev)
res = sas_notify_lldd_dev_found(dev);
if (res)
- goto out_err2;
-
- res = sas_rphy_add(dev->rphy);
- if (res)
- goto out_err;
+ return res;
+ sas_discover_event(dev->port, DISCE_PROBE);
return 0;
-
-out_err:
- sas_notify_lldd_dev_gone(dev);
-out_err2:
- return res;
}
/* ---------- Device registration and unregistration ---------- */
@@ -491,7 +509,7 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port)
static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = {
[DISCE_DISCOVER_DOMAIN] = sas_discover_domain,
[DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain,
- [DISCE_PROBE] = sas_probe_sata,
+ [DISCE_PROBE] = sas_probe_devices,
[DISCE_DESTRUCT] = sas_destruct_devices,
};