out_err:
sas_notify_lldd_dev_gone(dev);
out_err2:
- sas_rphy_free(dev->rphy);
- dev->rphy = NULL;
return res;
}
if (res)
goto out_err;
- /* do this to get the end device port attributes which will have
- * been scanned in sas_rphy_add */
- sas_notify_lldd_dev_gone(dev);
- res = sas_notify_lldd_dev_found(dev);
- if (res)
- goto out_err3;
-
return 0;
out_err:
sas_notify_lldd_dev_gone(dev);
out_err2:
- sas_rphy_free(dev->rphy);
- dev->rphy = NULL;
- return res;
-out_err3:
- sas_rphy_delete(dev->rphy);
- dev->rphy = NULL;
return res;
}
*/
static void sas_discover_domain(struct work_struct *work)
{
+ struct domain_device *dev;
int error = 0;
struct sas_discovery_event *ev =
container_of(work, struct sas_discovery_event, work);
&port->disc.pending);
if (port->port_dev)
- return ;
- else {
- error = sas_get_port_device(port);
- if (error)
- return;
- }
+ return;
+
+ error = sas_get_port_device(port);
+ if (error)
+ return;
+ dev = port->port_dev;
SAS_DPRINTK("DOING DISCOVERY on port %d, pid:%d\n", port->id,
current->pid);
- switch (port->port_dev->dev_type) {
+ switch (dev->dev_type) {
case SAS_END_DEV:
- error = sas_discover_end_dev(port->port_dev);
+ error = sas_discover_end_dev(dev);
break;
case EDGE_DEV:
case FANOUT_DEV:
- error = sas_discover_root_expander(port->port_dev);
+ error = sas_discover_root_expander(dev);
break;
case SATA_DEV:
case SATA_PM:
- error = sas_discover_sata(port->port_dev);
+ error = sas_discover_sata(dev);
break;
default:
- SAS_DPRINTK("unhandled device %d\n", port->port_dev->dev_type);
+ SAS_DPRINTK("unhandled device %d\n", dev->dev_type);
break;
}
if (error) {
+ sas_rphy_free(dev->rphy);
+ dev->rphy = NULL;
+
spin_lock(&port->dev_list_lock);
- list_del_init(&port->port_dev->dev_list_node);
+ list_del_init(&dev->dev_list_node);
spin_unlock(&port->dev_list_lock);
- kfree(port->port_dev); /* not kobject_register-ed yet */
+ kfree(dev); /* not kobject_register-ed yet */
port->port_dev = NULL;
}
return child;
out_list_del:
+ sas_rphy_free(child->rphy);
+ child->rphy = NULL;
list_del(&child->dev_list_node);
out_free:
sas_port_delete(phy->port);
return res;
out_err2:
- sas_rphy_delete(dev->rphy);
- dev->rphy = NULL;
- return res;
+ sas_rphy_remove(dev->rphy);
out_err:
- sas_rphy_free(dev->rphy);
- dev->rphy = NULL;
return res;
}
* Note:
* This function must only be called on a remote
* PHY that has not sucessfully been added using
- * sas_rphy_add().
+ * sas_rphy_add() (or has been sas_rphy_remove()'d)
*/
void sas_rphy_free(struct sas_rphy *rphy)
{
EXPORT_SYMBOL(sas_rphy_free);
/**
- * sas_rphy_delete -- remove SAS remote PHY
- * @rphy: SAS remote PHY to remove
+ * sas_rphy_delete -- remove and free SAS remote PHY
+ * @rphy: SAS remote PHY to remove and free
*
- * Removes the specified SAS remote PHY.
+ * Removes the specified SAS remote PHY and frees it.
*/
void
sas_rphy_delete(struct sas_rphy *rphy)
+{
+ sas_rphy_remove(rphy);
+ sas_rphy_free(rphy);
+}
+EXPORT_SYMBOL(sas_rphy_delete);
+
+/**
+ * sas_rphy_remove -- remove SAS remote PHY
+ * @rphy: SAS remote phy to remove
+ *
+ * Removes the specified SAS remote PHY.
+ */
+void
+sas_rphy_remove(struct sas_rphy *rphy)
{
struct device *dev = &rphy->dev;
struct sas_port *parent = dev_to_sas_port(dev->parent);
- struct Scsi_Host *shost = dev_to_shost(parent->dev.parent);
- struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
switch (rphy->identify.device_type) {
case SAS_END_DEVICE:
transport_remove_device(dev);
device_del(dev);
- transport_destroy_device(dev);
-
- mutex_lock(&sas_host->lock);
- list_del(&rphy->list);
- mutex_unlock(&sas_host->lock);
parent->rphy = NULL;
-
- put_device(dev);
}
-EXPORT_SYMBOL(sas_rphy_delete);
+EXPORT_SYMBOL(sas_rphy_remove);
/**
* scsi_is_sas_rphy -- check if a struct device represents a SAS remote PHY
extern struct sas_rphy *sas_expander_alloc(struct sas_port *, enum sas_device_type);
void sas_rphy_free(struct sas_rphy *);
extern int sas_rphy_add(struct sas_rphy *);
+extern void sas_rphy_remove(struct sas_rphy *);
extern void sas_rphy_delete(struct sas_rphy *);
extern int scsi_is_sas_rphy(const struct device *);