aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/task.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-11-30 14:57:34 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-29 16:11:54 -0500
commit9277699121b81891e303ada0a53fa1d04b7ffe72 (patch)
treeed8fde54c953025be2a59697dd912f581536c782 /drivers/scsi/isci/task.c
parentfca4ecbdc440337b3c257b38c2f4cc8d0ca0286c (diff)
[SCSI] isci: fix interpretation of "hard" reset
A hard reset to isci in the direct-attached case is one where the driver internally manages debouncing the link. In the sas-expander-attached case a hard reset is one that clears affiliations. The driver should not be prematurely dropping affiliations at run time, that decision (to force expander hard resets to ata devices) is left to userspace to manage. So, arrange for I_T_nexus resets to be sas-link-resets in the expander-attached case and isci-hard-resets in the direct-attached case. 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.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
index b96e6044eda9..c4d324ccee11 100644
--- a/drivers/scsi/isci/task.c
+++ b/drivers/scsi/isci/task.c
@@ -1330,29 +1330,35 @@ isci_task_request_complete(struct isci_host *ihost,
1330} 1330}
1331 1331
1332static int isci_reset_device(struct isci_host *ihost, 1332static int isci_reset_device(struct isci_host *ihost,
1333 struct domain_device *dev,
1333 struct isci_remote_device *idev) 1334 struct isci_remote_device *idev)
1334{ 1335{
1335 struct sas_phy *phy = sas_get_local_phy(idev->domain_dev);
1336 enum sci_status status;
1337 unsigned long flags;
1338 int rc; 1336 int rc;
1337 unsigned long flags;
1338 enum sci_status status;
1339 struct sas_phy *phy = sas_get_local_phy(dev);
1340 struct isci_port *iport = dev->port->lldd_port;
1339 1341
1340 dev_dbg(&ihost->pdev->dev, "%s: idev %p\n", __func__, idev); 1342 dev_dbg(&ihost->pdev->dev, "%s: idev %p\n", __func__, idev);
1341 1343
1342 spin_lock_irqsave(&ihost->scic_lock, flags); 1344 spin_lock_irqsave(&ihost->scic_lock, flags);
1343 status = sci_remote_device_reset(idev); 1345 status = sci_remote_device_reset(idev);
1344 if (status != SCI_SUCCESS) { 1346 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1345 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1346 1347
1348 if (status != SCI_SUCCESS) {
1347 dev_dbg(&ihost->pdev->dev, 1349 dev_dbg(&ihost->pdev->dev,
1348 "%s: sci_remote_device_reset(%p) returned %d!\n", 1350 "%s: sci_remote_device_reset(%p) returned %d!\n",
1349 __func__, idev, status); 1351 __func__, idev, status);
1350 rc = TMF_RESP_FUNC_FAILED; 1352 rc = TMF_RESP_FUNC_FAILED;
1351 goto out; 1353 goto out;
1352 } 1354 }
1353 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1354 1355
1355 rc = sas_phy_reset(phy, true); 1356 if (scsi_is_sas_phy_local(phy)) {
1357 struct isci_phy *iphy = &ihost->phys[phy->number];
1358
1359 rc = isci_port_perform_hard_reset(ihost, iport, iphy);
1360 } else
1361 rc = sas_phy_reset(phy, !dev_is_sata(dev));
1356 1362
1357 /* Terminate in-progress I/O now. */ 1363 /* Terminate in-progress I/O now. */
1358 isci_remote_device_nuke_requests(ihost, idev); 1364 isci_remote_device_nuke_requests(ihost, idev);
@@ -1390,7 +1396,7 @@ int isci_task_I_T_nexus_reset(struct domain_device *dev)
1390 goto out; 1396 goto out;
1391 } 1397 }
1392 1398
1393 ret = isci_reset_device(ihost, idev); 1399 ret = isci_reset_device(ihost, dev, idev);
1394 out: 1400 out:
1395 isci_put_device(idev); 1401 isci_put_device(idev);
1396 return ret; 1402 return ret;
@@ -1413,7 +1419,7 @@ int isci_bus_reset_handler(struct scsi_cmnd *cmd)
1413 goto out; 1419 goto out;
1414 } 1420 }
1415 1421
1416 ret = isci_reset_device(ihost, idev); 1422 ret = isci_reset_device(ihost, dev, idev);
1417 out: 1423 out:
1418 isci_put_device(idev); 1424 isci_put_device(idev);
1419 return ret; 1425 return ret;