[SCSI] libsas: restore scan order
authorDan Williams <dan.j.williams@intel.com>
Thu, 19 Jan 2012 04:14:01 +0000 (20:14 -0800)
committerJames Bottomley <JBottomley@Parallels.com>
Wed, 29 Feb 2012 21:34:19 +0000 (15:34 -0600)
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>
drivers/scsi/libsas/sas_ata.c
drivers/scsi/libsas/sas_discover.c
drivers/scsi/libsas/sas_expander.c
include/scsi/sas_ata.h

index 25008a42412ff142cd183b565ba0b8a85378f9a3..a9ec1643ee93833ef322a2b9447c417c4995726d 100644 (file)
@@ -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
index 8bcfcaa7b2e1394b63f962a204157459ca3b9a6e..18fa364aa00f697ce211215f83e7c8dea10660d2 100644 (file)
@@ -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,
        };
 
index d63f0fbcd10383219cef6c61dec16d2d62d4a41a..14e3244c1b20768c106bed89710b86ef4dddc164 100644 (file)
@@ -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) {
index 0ca2f8a6bc602958395e1ead03c982530ee958cf..1556eff4cc442b13c23cd64b619885954629a9aa 100644 (file)
@@ -44,7 +44,6 @@ void sas_ata_task_abort(struct sas_task *task);
 void sas_ata_strategy_handler(struct Scsi_Host *shost);
 void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
                struct list_head *done_q);
-void sas_probe_sata(struct work_struct *work);
 void sas_ata_schedule_reset(struct domain_device *dev);
 void sas_ata_wait_eh(struct domain_device *dev);
 #else
@@ -72,10 +71,6 @@ static inline void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
 {
 }
 
-static inline void sas_probe_sata(struct work_struct *work)
-{
-}
-
 static inline void sas_ata_schedule_reset(struct domain_device *dev)
 {
 }