summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/libsas/sas_discover.c13
-rw-r--r--drivers/scsi/libsas/sas_expander.c15
-rw-r--r--include/scsi/libsas.h2
3 files changed, 18 insertions, 12 deletions
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index f5831930df9b..54a5199ceb56 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -219,17 +219,20 @@ out_err2:
/* ---------- Device registration and unregistration ---------- */
-static inline void sas_unregister_common_dev(struct domain_device *dev)
+static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_device *dev)
{
sas_notify_lldd_dev_gone(dev);
if (!dev->parent)
dev->port->port_dev = NULL;
else
list_del_init(&dev->siblings);
+
+ spin_lock_irq(&port->dev_list_lock);
list_del_init(&dev->dev_list_node);
+ spin_unlock_irq(&port->dev_list_lock);
}
-void sas_unregister_dev(struct domain_device *dev)
+void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev)
{
if (dev->rphy) {
sas_remove_children(&dev->rphy->dev);
@@ -241,15 +244,15 @@ void sas_unregister_dev(struct domain_device *dev)
kfree(dev->ex_dev.ex_phy);
dev->ex_dev.ex_phy = NULL;
}
- sas_unregister_common_dev(dev);
+ sas_unregister_common_dev(port, dev);
}
void sas_unregister_domain_devices(struct asd_sas_port *port)
{
struct domain_device *dev, *n;
- list_for_each_entry_safe_reverse(dev,n,&port->dev_list,dev_list_node)
- sas_unregister_dev(dev);
+ list_for_each_entry_safe_reverse(dev, n, &port->dev_list, dev_list_node)
+ sas_unregister_dev(port, dev);
port->port->rphy = NULL;
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index b172f1773081..88bbe8e1e844 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -754,7 +754,10 @@ static struct domain_device *sas_ex_discover_end_dev(
out_list_del:
sas_rphy_free(child->rphy);
child->rphy = NULL;
+
+ spin_lock_irq(&parent->port->dev_list_lock);
list_del(&child->dev_list_node);
+ spin_unlock_irq(&parent->port->dev_list_lock);
out_free:
sas_port_delete(phy->port);
out_err:
@@ -1739,7 +1742,7 @@ out:
return res;
}
-static void sas_unregister_ex_tree(struct domain_device *dev)
+static void sas_unregister_ex_tree(struct asd_sas_port *port, struct domain_device *dev)
{
struct expander_device *ex = &dev->ex_dev;
struct domain_device *child, *n;
@@ -1748,11 +1751,11 @@ static void sas_unregister_ex_tree(struct domain_device *dev)
child->gone = 1;
if (child->dev_type == EDGE_DEV ||
child->dev_type == FANOUT_DEV)
- sas_unregister_ex_tree(child);
+ sas_unregister_ex_tree(port, child);
else
- sas_unregister_dev(child);
+ sas_unregister_dev(port, child);
}
- sas_unregister_dev(dev);
+ sas_unregister_dev(port, dev);
}
static void sas_unregister_devs_sas_addr(struct domain_device *parent,
@@ -1769,9 +1772,9 @@ static void sas_unregister_devs_sas_addr(struct domain_device *parent,
child->gone = 1;
if (child->dev_type == EDGE_DEV ||
child->dev_type == FANOUT_DEV)
- sas_unregister_ex_tree(child);
+ sas_unregister_ex_tree(parent->port, child);
else
- sas_unregister_dev(child);
+ sas_unregister_dev(parent->port, child);
break;
}
}
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index c4b7cd0b85e5..6a308d42d98f 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -656,7 +656,7 @@ int sas_discover_event(struct asd_sas_port *, enum discover_event ev);
int sas_discover_sata(struct domain_device *);
int sas_discover_end_dev(struct domain_device *);
-void sas_unregister_dev(struct domain_device *);
+void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *);
void sas_init_dev(struct domain_device *);
OpenPOWER on IntegriCloud