summaryrefslogtreecommitdiff
path: root/drivers/scsi
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
parentc666aae6919114d6cff789d79f80cfa85f3a7339 (diff)
downloadlinux-3.10-92625f9bff3853951cc75f5bc084ee67c1317d2f.tar.gz
linux-3.10-92625f9bff3853951cc75f5bc084ee67c1317d2f.tar.bz2
linux-3.10-92625f9bff3853951cc75f5bc084ee67c1317d2f.zip
[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')
-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 25008a42412..a9ec1643ee9 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)
dev->sata_dev.command_set = ATAPI_COMMAND_SET;
}
-void sas_probe_sata(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_sata -- discover an STP/SATA domain device
* @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 8bcfcaa7b2e..18fa364aa00 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,
};
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index d63f0fbcd10..14e3244c1b2 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(
child->rphy = rphy;
sas_fill_in_rphy(child, rphy);
- spin_lock_irq(&parent->port->dev_list_lock);
- list_add_tail(&child->dev_list_node, &parent->port->dev_list);
- spin_unlock_irq(&parent->port->dev_list_lock);
+ list_add_tail(&child->disco_list_node, &parent->port->disco_list);
res = sas_discover_end_dev(child);
if (res) {