aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/task.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/isci/task.c')
-rw-r--r--drivers/scsi/isci/task.c158
1 files changed, 30 insertions, 128 deletions
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
index f5a3f7d2bdab..374254ede9d4 100644
--- a/drivers/scsi/isci/task.c
+++ b/drivers/scsi/isci/task.c
@@ -96,8 +96,7 @@ static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task,
96 __func__, task, response, status); 96 __func__, task, response, status);
97 97
98 task->lldd_task = NULL; 98 task->lldd_task = NULL;
99 99 task->task_done(task);
100 isci_execpath_callback(ihost, task, task->task_done);
101 break; 100 break;
102 101
103 case isci_perform_aborted_io_completion: 102 case isci_perform_aborted_io_completion:
@@ -117,8 +116,7 @@ static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task,
117 "%s: Error - task = %p, response=%d, " 116 "%s: Error - task = %p, response=%d, "
118 "status=%d\n", 117 "status=%d\n",
119 __func__, task, response, status); 118 __func__, task, response, status);
120 119 sas_task_abort(task);
121 isci_execpath_callback(ihost, task, sas_task_abort);
122 break; 120 break;
123 121
124 default: 122 default:
@@ -249,46 +247,6 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
249 return 0; 247 return 0;
250} 248}
251 249
252static enum sci_status isci_sata_management_task_request_build(struct isci_request *ireq)
253{
254 struct isci_tmf *isci_tmf;
255 enum sci_status status;
256
257 if (!test_bit(IREQ_TMF, &ireq->flags))
258 return SCI_FAILURE;
259
260 isci_tmf = isci_request_access_tmf(ireq);
261
262 switch (isci_tmf->tmf_code) {
263
264 case isci_tmf_sata_srst_high:
265 case isci_tmf_sata_srst_low: {
266 struct host_to_dev_fis *fis = &ireq->stp.cmd;
267
268 memset(fis, 0, sizeof(*fis));
269
270 fis->fis_type = 0x27;
271 fis->flags &= ~0x80;
272 fis->flags &= 0xF0;
273 if (isci_tmf->tmf_code == isci_tmf_sata_srst_high)
274 fis->control |= ATA_SRST;
275 else
276 fis->control &= ~ATA_SRST;
277 break;
278 }
279 /* other management commnd go here... */
280 default:
281 return SCI_FAILURE;
282 }
283
284 /* core builds the protocol specific request
285 * based on the h2d fis.
286 */
287 status = sci_task_request_construct_sata(ireq);
288
289 return status;
290}
291
292static struct isci_request *isci_task_request_build(struct isci_host *ihost, 250static struct isci_request *isci_task_request_build(struct isci_host *ihost,
293 struct isci_remote_device *idev, 251 struct isci_remote_device *idev,
294 u16 tag, struct isci_tmf *isci_tmf) 252 u16 tag, struct isci_tmf *isci_tmf)
@@ -328,13 +286,6 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost,
328 return NULL; 286 return NULL;
329 } 287 }
330 288
331 if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
332 isci_tmf->proto = SAS_PROTOCOL_SATA;
333 status = isci_sata_management_task_request_build(ireq);
334
335 if (status != SCI_SUCCESS)
336 return NULL;
337 }
338 return ireq; 289 return ireq;
339} 290}
340 291
@@ -873,53 +824,20 @@ static int isci_task_send_lu_reset_sas(
873 return ret; 824 return ret;
874} 825}
875 826
876static int isci_task_send_lu_reset_sata(struct isci_host *ihost, 827int isci_task_lu_reset(struct domain_device *dev, u8 *lun)
877 struct isci_remote_device *idev, u8 *lun)
878{
879 int ret = TMF_RESP_FUNC_FAILED;
880 struct isci_tmf tmf;
881
882 /* Send the soft reset to the target */
883 #define ISCI_SRST_TIMEOUT_MS 25000 /* 25 second timeout. */
884 isci_task_build_tmf(&tmf, isci_tmf_sata_srst_high, NULL, NULL);
885
886 ret = isci_task_execute_tmf(ihost, idev, &tmf, ISCI_SRST_TIMEOUT_MS);
887
888 if (ret != TMF_RESP_FUNC_COMPLETE) {
889 dev_dbg(&ihost->pdev->dev,
890 "%s: Assert SRST failed (%p) = %x",
891 __func__, idev, ret);
892
893 /* Return the failure so that the LUN reset is escalated
894 * to a target reset.
895 */
896 }
897 return ret;
898}
899
900/**
901 * isci_task_lu_reset() - This function is one of the SAS Domain Template
902 * functions. This is one of the Task Management functoins called by libsas,
903 * to reset the given lun. Note the assumption that while this call is
904 * executing, no I/O will be sent by the host to the device.
905 * @lun: This parameter specifies the lun to be reset.
906 *
907 * status, zero indicates success.
908 */
909int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun)
910{ 828{
911 struct isci_host *isci_host = dev_to_ihost(domain_device); 829 struct isci_host *isci_host = dev_to_ihost(dev);
912 struct isci_remote_device *isci_device; 830 struct isci_remote_device *isci_device;
913 unsigned long flags; 831 unsigned long flags;
914 int ret; 832 int ret;
915 833
916 spin_lock_irqsave(&isci_host->scic_lock, flags); 834 spin_lock_irqsave(&isci_host->scic_lock, flags);
917 isci_device = isci_lookup_device(domain_device); 835 isci_device = isci_lookup_device(dev);
918 spin_unlock_irqrestore(&isci_host->scic_lock, flags); 836 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
919 837
920 dev_dbg(&isci_host->pdev->dev, 838 dev_dbg(&isci_host->pdev->dev,
921 "%s: domain_device=%p, isci_host=%p; isci_device=%p\n", 839 "%s: domain_device=%p, isci_host=%p; isci_device=%p\n",
922 __func__, domain_device, isci_host, isci_device); 840 __func__, dev, isci_host, isci_device);
923 841
924 if (!isci_device) { 842 if (!isci_device) {
925 /* If the device is gone, stop the escalations. */ 843 /* If the device is gone, stop the escalations. */
@@ -928,11 +846,11 @@ int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun)
928 ret = TMF_RESP_FUNC_COMPLETE; 846 ret = TMF_RESP_FUNC_COMPLETE;
929 goto out; 847 goto out;
930 } 848 }
931 set_bit(IDEV_EH, &isci_device->flags);
932 849
933 /* Send the task management part of the reset. */ 850 /* Send the task management part of the reset. */
934 if (sas_protocol_ata(domain_device->tproto)) { 851 if (dev_is_sata(dev)) {
935 ret = isci_task_send_lu_reset_sata(isci_host, isci_device, lun); 852 sas_ata_schedule_reset(dev);
853 ret = TMF_RESP_FUNC_COMPLETE;
936 } else 854 } else
937 ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun); 855 ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun);
938 856
@@ -1062,9 +980,6 @@ int isci_task_abort_task(struct sas_task *task)
1062 "%s: dev = %p, task = %p, old_request == %p\n", 980 "%s: dev = %p, task = %p, old_request == %p\n",
1063 __func__, isci_device, task, old_request); 981 __func__, isci_device, task, old_request);
1064 982
1065 if (isci_device)
1066 set_bit(IDEV_EH, &isci_device->flags);
1067
1068 /* Device reset conditions signalled in task_state_flags are the 983 /* Device reset conditions signalled in task_state_flags are the
1069 * responsbility of libsas to observe at the start of the error 984 * responsbility of libsas to observe at the start of the error
1070 * handler thread. 985 * handler thread.
@@ -1332,29 +1247,35 @@ isci_task_request_complete(struct isci_host *ihost,
1332} 1247}
1333 1248
1334static int isci_reset_device(struct isci_host *ihost, 1249static int isci_reset_device(struct isci_host *ihost,
1250 struct domain_device *dev,
1335 struct isci_remote_device *idev) 1251 struct isci_remote_device *idev)
1336{ 1252{
1337 struct sas_phy *phy = sas_find_local_phy(idev->domain_dev);
1338 enum sci_status status;
1339 unsigned long flags;
1340 int rc; 1253 int rc;
1254 unsigned long flags;
1255 enum sci_status status;
1256 struct sas_phy *phy = sas_get_local_phy(dev);
1257 struct isci_port *iport = dev->port->lldd_port;
1341 1258
1342 dev_dbg(&ihost->pdev->dev, "%s: idev %p\n", __func__, idev); 1259 dev_dbg(&ihost->pdev->dev, "%s: idev %p\n", __func__, idev);
1343 1260
1344 spin_lock_irqsave(&ihost->scic_lock, flags); 1261 spin_lock_irqsave(&ihost->scic_lock, flags);
1345 status = sci_remote_device_reset(idev); 1262 status = sci_remote_device_reset(idev);
1346 if (status != SCI_SUCCESS) { 1263 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1347 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1348 1264
1265 if (status != SCI_SUCCESS) {
1349 dev_dbg(&ihost->pdev->dev, 1266 dev_dbg(&ihost->pdev->dev,
1350 "%s: sci_remote_device_reset(%p) returned %d!\n", 1267 "%s: sci_remote_device_reset(%p) returned %d!\n",
1351 __func__, idev, status); 1268 __func__, idev, status);
1352 1269 rc = TMF_RESP_FUNC_FAILED;
1353 return TMF_RESP_FUNC_FAILED; 1270 goto out;
1354 } 1271 }
1355 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1356 1272
1357 rc = sas_phy_reset(phy, true); 1273 if (scsi_is_sas_phy_local(phy)) {
1274 struct isci_phy *iphy = &ihost->phys[phy->number];
1275
1276 rc = isci_port_perform_hard_reset(ihost, iport, iphy);
1277 } else
1278 rc = sas_phy_reset(phy, !dev_is_sata(dev));
1358 1279
1359 /* Terminate in-progress I/O now. */ 1280 /* Terminate in-progress I/O now. */
1360 isci_remote_device_nuke_requests(ihost, idev); 1281 isci_remote_device_nuke_requests(ihost, idev);
@@ -1371,7 +1292,8 @@ static int isci_reset_device(struct isci_host *ihost,
1371 } 1292 }
1372 1293
1373 dev_dbg(&ihost->pdev->dev, "%s: idev %p complete.\n", __func__, idev); 1294 dev_dbg(&ihost->pdev->dev, "%s: idev %p complete.\n", __func__, idev);
1374 1295 out:
1296 sas_put_local_phy(phy);
1375 return rc; 1297 return rc;
1376} 1298}
1377 1299
@@ -1386,35 +1308,15 @@ int isci_task_I_T_nexus_reset(struct domain_device *dev)
1386 idev = isci_lookup_device(dev); 1308 idev = isci_lookup_device(dev);
1387 spin_unlock_irqrestore(&ihost->scic_lock, flags); 1309 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1388 1310
1389 if (!idev || !test_bit(IDEV_EH, &idev->flags)) {
1390 ret = TMF_RESP_FUNC_COMPLETE;
1391 goto out;
1392 }
1393
1394 ret = isci_reset_device(ihost, idev);
1395 out:
1396 isci_put_device(idev);
1397 return ret;
1398}
1399
1400int isci_bus_reset_handler(struct scsi_cmnd *cmd)
1401{
1402 struct domain_device *dev = sdev_to_domain_dev(cmd->device);
1403 struct isci_host *ihost = dev_to_ihost(dev);
1404 struct isci_remote_device *idev;
1405 unsigned long flags;
1406 int ret;
1407
1408 spin_lock_irqsave(&ihost->scic_lock, flags);
1409 idev = isci_lookup_device(dev);
1410 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1411
1412 if (!idev) { 1311 if (!idev) {
1312 /* XXX: need to cleanup any ireqs targeting this
1313 * domain_device
1314 */
1413 ret = TMF_RESP_FUNC_COMPLETE; 1315 ret = TMF_RESP_FUNC_COMPLETE;
1414 goto out; 1316 goto out;
1415 } 1317 }
1416 1318
1417 ret = isci_reset_device(ihost, idev); 1319 ret = isci_reset_device(ihost, dev, idev);
1418 out: 1320 out:
1419 isci_put_device(idev); 1321 isci_put_device(idev);
1420 return ret; 1322 return ret;