diff options
author | Darrick J. Wong <djwong@us.ibm.com> | 2007-01-26 17:08:43 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-01-27 11:05:15 -0500 |
commit | 6f63caae2172e97e528b58319480217b0b36542e (patch) | |
tree | 641e3d41e05a11d9edec50d56f15be11f7e9cdfb /drivers/scsi/scsi_transport_sas.c | |
parent | 3b6e9fafc40e36f50f0bd0f1ee758eecd79f1098 (diff) |
[SCSI] libsas: Clean up discovery failure handler code
sas_rphy_delete does two things: it removes the sas_rphy from the transport
layer and frees the sas_rphy. This can be broken down into two functions,
sas_rphy_remove and sas_rphy_free; sas_rphy_remove is of interest to
sas_discover_root_expander because it calls functions that require
sas_rphy_add as a prerequisite and can fail (namely sas_discover_expander).
In that case, sas_discover_root_expander needs to be able to undo the effects
of sas_rphy_add yet leave the job of freeing the sas_rphy to the caller of
sas_discover_root_expander.
This patch also removes some unnecessary code from sas_discover_end_dev
to eliminate an unnecessary cycle of sas_notify_lldd_gone/found for SAS
devices, thus eliminating a sas_rphy_remove call (and fixing a race condition
where a SCSI target scan can come in between the gone and found call).
It also moves the sas_rphy_free calls into sas_discover_domain and
sas_ex_discover_end_dev to complement the sas_rphy_allocation via
sas_get_port_device.
This patch does not change the semantics of sas_rphy_delete.
Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/scsi_transport_sas.c')
-rw-r--r-- | drivers/scsi/scsi_transport_sas.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index ce232803f433..010845fd2b85 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
@@ -1299,7 +1299,7 @@ EXPORT_SYMBOL(sas_rphy_add); | |||
1299 | * Note: | 1299 | * Note: |
1300 | * This function must only be called on a remote | 1300 | * This function must only be called on a remote |
1301 | * PHY that has not sucessfully been added using | 1301 | * PHY that has not sucessfully been added using |
1302 | * sas_rphy_add(). | 1302 | * sas_rphy_add() (or has been sas_rphy_remove()'d) |
1303 | */ | 1303 | */ |
1304 | void sas_rphy_free(struct sas_rphy *rphy) | 1304 | void sas_rphy_free(struct sas_rphy *rphy) |
1305 | { | 1305 | { |
@@ -1318,18 +1318,30 @@ void sas_rphy_free(struct sas_rphy *rphy) | |||
1318 | EXPORT_SYMBOL(sas_rphy_free); | 1318 | EXPORT_SYMBOL(sas_rphy_free); |
1319 | 1319 | ||
1320 | /** | 1320 | /** |
1321 | * sas_rphy_delete -- remove SAS remote PHY | 1321 | * sas_rphy_delete -- remove and free SAS remote PHY |
1322 | * @rphy: SAS remote PHY to remove | 1322 | * @rphy: SAS remote PHY to remove and free |
1323 | * | 1323 | * |
1324 | * Removes the specified SAS remote PHY. | 1324 | * Removes the specified SAS remote PHY and frees it. |
1325 | */ | 1325 | */ |
1326 | void | 1326 | void |
1327 | sas_rphy_delete(struct sas_rphy *rphy) | 1327 | sas_rphy_delete(struct sas_rphy *rphy) |
1328 | { | 1328 | { |
1329 | sas_rphy_remove(rphy); | ||
1330 | sas_rphy_free(rphy); | ||
1331 | } | ||
1332 | EXPORT_SYMBOL(sas_rphy_delete); | ||
1333 | |||
1334 | /** | ||
1335 | * sas_rphy_remove -- remove SAS remote PHY | ||
1336 | * @rphy: SAS remote phy to remove | ||
1337 | * | ||
1338 | * Removes the specified SAS remote PHY. | ||
1339 | */ | ||
1340 | void | ||
1341 | sas_rphy_remove(struct sas_rphy *rphy) | ||
1342 | { | ||
1329 | struct device *dev = &rphy->dev; | 1343 | struct device *dev = &rphy->dev; |
1330 | struct sas_port *parent = dev_to_sas_port(dev->parent); | 1344 | struct sas_port *parent = dev_to_sas_port(dev->parent); |
1331 | struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); | ||
1332 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); | ||
1333 | 1345 | ||
1334 | switch (rphy->identify.device_type) { | 1346 | switch (rphy->identify.device_type) { |
1335 | case SAS_END_DEVICE: | 1347 | case SAS_END_DEVICE: |
@@ -1345,17 +1357,10 @@ sas_rphy_delete(struct sas_rphy *rphy) | |||
1345 | 1357 | ||
1346 | transport_remove_device(dev); | 1358 | transport_remove_device(dev); |
1347 | device_del(dev); | 1359 | device_del(dev); |
1348 | transport_destroy_device(dev); | ||
1349 | |||
1350 | mutex_lock(&sas_host->lock); | ||
1351 | list_del(&rphy->list); | ||
1352 | mutex_unlock(&sas_host->lock); | ||
1353 | 1360 | ||
1354 | parent->rphy = NULL; | 1361 | parent->rphy = NULL; |
1355 | |||
1356 | put_device(dev); | ||
1357 | } | 1362 | } |
1358 | EXPORT_SYMBOL(sas_rphy_delete); | 1363 | EXPORT_SYMBOL(sas_rphy_remove); |
1359 | 1364 | ||
1360 | /** | 1365 | /** |
1361 | * scsi_is_sas_rphy -- check if a struct device represents a SAS remote PHY | 1366 | * scsi_is_sas_rphy -- check if a struct device represents a SAS remote PHY |