[SCSI] libsas: mark all domain devices gone if root port disappears
Dan Williams [Tue, 10 Jan 2012 22:39:13 +0000 (14:39 -0800)]
If the top level expander is hot removed, mark all child devices as gone
before unregistration to short circuit futile recovery.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>

drivers/scsi/libsas/sas_discover.c
drivers/scsi/libsas/sas_port.c
include/scsi/libsas.h

index 789b508..b91866a 100644 (file)
@@ -299,12 +299,16 @@ void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev)
        }
 }
 
-void sas_unregister_domain_devices(struct asd_sas_port *port)
+void sas_unregister_domain_devices(struct asd_sas_port *port, int gone)
 {
        struct domain_device *dev, *n;
 
-       list_for_each_entry_safe_reverse(dev, n, &port->dev_list, dev_list_node)
+       list_for_each_entry_safe_reverse(dev, n, &port->dev_list, dev_list_node) {
+               if (gone)
+                       set_bit(SAS_DEV_GONE, &dev->state);
                sas_unregister_dev(port, dev);
+       }
+
        list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node)
                sas_unregister_dev(port, dev);
 
index 31adcd1..59ee8a0 100644 (file)
@@ -167,9 +167,7 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone)
                dev->pathways--;
 
        if (port->num_phys == 1) {
-               if (dev && gone)
-                       set_bit(SAS_DEV_GONE, &dev->state);
-               sas_unregister_domain_devices(port);
+               sas_unregister_domain_devices(port, gone);
                sas_port_delete(port->port);
                port->port = NULL;
        } else {
index 55bab86..4a42be3 100644 (file)
@@ -664,7 +664,7 @@ void sas_init_ex_attr(void);
 
 int  sas_ex_revalidate_domain(struct domain_device *);
 
-void sas_unregister_domain_devices(struct asd_sas_port *port);
+void sas_unregister_domain_devices(struct asd_sas_port *port, int gone);
 void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *);
 int  sas_discover_event(struct asd_sas_port *, enum discover_event ev);