aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/task.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-12-22 00:33:17 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-29 14:01:06 -0500
commitf41a0c441c3fe43e79ebeb75584dbb5bfa83e5cd (patch)
tree5a53adb90ebf31888184a9bff16ccc1869e2e4b3 /drivers/scsi/isci/task.c
parent3a9c5560f677690f65038f399f4f598c79b83186 (diff)
[SCSI] libsas: fix sas_find_local_phy(), take phy references
In the direct-attached case this routine returns the phy on which this device was first discovered. Which is broken if we want to support wide-targets, as this phy reference can become stale even though the port is still active. In the expander-attached case this routine tries to lookup the phy by scanning the attached sas addresses of the parent expander, and BUG_ONs if it can't find it. However since eh and the libsas workqueue run independently we can still be attempting device recovery via eh after libsas has recorded the device as detached. This is even easier to hit now that eh is blocked while device domain rediscovery takes place, and that libata is fed more timed out commands increasing the chances that it will try to recover the ata device. Arrange for dev->phy to always point to a last known good phy, it may be stale after the port is torn down, but it will catch up for wide port reconfigurations, and never be NULL. Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/isci/task.c')
-rw-r--r--drivers/scsi/isci/task.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
index 4bd88ef83cdf..b96e6044eda9 100644
--- a/drivers/scsi/isci/task.c
+++ b/drivers/scsi/isci/task.c
@@ -1332,7 +1332,7 @@ isci_task_request_complete(struct isci_host *ihost,
1332static int isci_reset_device(struct isci_host *ihost, 1332static int isci_reset_device(struct isci_host *ihost,
1333 struct isci_remote_device *idev) 1333 struct isci_remote_device *idev)
1334{ 1334{
1335 struct sas_phy *phy = sas_find_local_phy(idev->domain_dev); 1335 struct sas_phy *phy = sas_get_local_phy(idev->domain_dev);
1336 enum sci_status status; 1336 enum sci_status status;
1337 unsigned long flags; 1337 unsigned long flags;
1338 int rc; 1338 int rc;
@@ -1347,8 +1347,8 @@ static int isci_reset_device(struct isci_host *ihost,
1347 dev_dbg(&ihost->pdev->dev, 1347 dev_dbg(&ihost->pdev->dev,
1348 "%s: sci_remote_device_reset(%p) returned %d!\n", 1348 "%s: sci_remote_device_reset(%p) returned %d!\n",
1349 __func__, idev, status); 1349 __func__, idev, status);
1350 1350 rc = TMF_RESP_FUNC_FAILED;
1351 return TMF_RESP_FUNC_FAILED; 1351 goto out;
1352 } 1352 }
1353 spin_unlock_irqrestore(&ihost->scic_lock, flags); 1353 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1354 1354
@@ -1369,7 +1369,8 @@ static int isci_reset_device(struct isci_host *ihost,
1369 } 1369 }
1370 1370
1371 dev_dbg(&ihost->pdev->dev, "%s: idev %p complete.\n", __func__, idev); 1371 dev_dbg(&ihost->pdev->dev, "%s: idev %p complete.\n", __func__, idev);
1372 1372 out:
1373 sas_put_local_phy(phy);
1373 return rc; 1374 return rc;
1374} 1375}
1375 1376