aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/isci/task.c149
-rw-r--r--drivers/scsi/isci/task.h2
2 files changed, 109 insertions, 42 deletions
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
index 7180b048c34b..4175f173868e 100644
--- a/drivers/scsi/isci/task.c
+++ b/drivers/scsi/isci/task.c
@@ -338,6 +338,61 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost,
338 return ireq; 338 return ireq;
339} 339}
340 340
341/**
342* isci_request_mark_zombie() - This function must be called with scic_lock held.
343*/
344static void isci_request_mark_zombie(struct isci_host *ihost, struct isci_request *ireq)
345{
346 struct completion *tmf_completion = NULL;
347 struct completion *req_completion;
348
349 /* Set the request state to "dead". */
350 ireq->status = dead;
351
352 req_completion = ireq->io_request_completion;
353 ireq->io_request_completion = NULL;
354
355 if (ireq->ttype == io_task) {
356
357 /* Break links with the sas_task - the callback is done
358 * elsewhere.
359 */
360 struct sas_task *task = isci_request_access_task(ireq);
361
362 if (task)
363 task->lldd_task = NULL;
364
365 ireq->ttype_ptr.io_task_ptr = NULL;
366 } else {
367 /* Break links with the TMF request. */
368 struct isci_tmf *tmf = isci_request_access_tmf(ireq);
369
370 /* In the case where a task request is dying,
371 * the thread waiting on the complete will sit and
372 * timeout unless we wake it now. Since the TMF
373 * has a default error status, complete it here
374 * to wake the waiting thread.
375 */
376 if (tmf) {
377 tmf_completion = tmf->complete;
378 tmf->complete = NULL;
379 }
380 ireq->ttype_ptr.tmf_task_ptr = NULL;
381 dev_dbg(&ihost->pdev->dev, "%s: tmf_code %d, managed tag %#x\n",
382 __func__, tmf->tmf_code, tmf->io_tag);
383 }
384
385 dev_warn(&ihost->pdev->dev, "task context unrecoverable (tag: %#x)\n",
386 ireq->io_tag);
387
388 /* Don't force waiting threads to timeout. */
389 if (req_completion)
390 complete(req_completion);
391
392 if (tmf_completion != NULL)
393 complete(tmf_completion);
394}
395
341static int isci_task_execute_tmf(struct isci_host *ihost, 396static int isci_task_execute_tmf(struct isci_host *ihost,
342 struct isci_remote_device *idev, 397 struct isci_remote_device *idev,
343 struct isci_tmf *tmf, unsigned long timeout_ms) 398 struct isci_tmf *tmf, unsigned long timeout_ms)
@@ -375,6 +430,7 @@ static int isci_task_execute_tmf(struct isci_host *ihost,
375 430
376 /* Assign the pointer to the TMF's completion kernel wait structure. */ 431 /* Assign the pointer to the TMF's completion kernel wait structure. */
377 tmf->complete = &completion; 432 tmf->complete = &completion;
433 tmf->status = SCI_FAILURE_TIMEOUT;
378 434
379 ireq = isci_task_request_build(ihost, idev, tag, tmf); 435 ireq = isci_task_request_build(ihost, idev, tag, tmf);
380 if (!ireq) 436 if (!ireq)
@@ -410,18 +466,35 @@ static int isci_task_execute_tmf(struct isci_host *ihost,
410 msecs_to_jiffies(timeout_ms)); 466 msecs_to_jiffies(timeout_ms));
411 467
412 if (timeleft == 0) { 468 if (timeleft == 0) {
469 /* The TMF did not complete - this could be because
470 * of an unplug. Terminate the TMF request now.
471 */
413 spin_lock_irqsave(&ihost->scic_lock, flags); 472 spin_lock_irqsave(&ihost->scic_lock, flags);
414 473
415 if (tmf->cb_state_func != NULL) 474 if (tmf->cb_state_func != NULL)
416 tmf->cb_state_func(isci_tmf_timed_out, tmf, tmf->cb_data); 475 tmf->cb_state_func(isci_tmf_timed_out, tmf,
476 tmf->cb_data);
417 477
418 sci_controller_terminate_request(ihost, 478 sci_controller_terminate_request(ihost, idev, ireq);
419 idev,
420 ireq);
421 479
422 spin_unlock_irqrestore(&ihost->scic_lock, flags); 480 spin_unlock_irqrestore(&ihost->scic_lock, flags);
423 481
424 wait_for_completion(tmf->complete); 482 timeleft = wait_for_completion_timeout(
483 &completion,
484 msecs_to_jiffies(ISCI_TERMINATION_TIMEOUT_MSEC));
485
486 if (!timeleft) {
487 /* Strange condition - the termination of the TMF
488 * request timed-out.
489 */
490 spin_lock_irqsave(&ihost->scic_lock, flags);
491
492 /* If the TMF status has not changed, kill it. */
493 if (tmf->status == SCI_FAILURE_TIMEOUT)
494 isci_request_mark_zombie(ihost, ireq);
495
496 spin_unlock_irqrestore(&ihost->scic_lock, flags);
497 }
425 } 498 }
426 499
427 isci_print_tmf(tmf); 500 isci_print_tmf(tmf);
@@ -645,42 +718,27 @@ static void isci_terminate_request_core(struct isci_host *ihost,
645 __func__, isci_request, io_request_completion); 718 __func__, isci_request, io_request_completion);
646 719
647 /* Wait here for the request to complete. */ 720 /* Wait here for the request to complete. */
648 #define TERMINATION_TIMEOUT_MSEC 500
649 termination_completed 721 termination_completed
650 = wait_for_completion_timeout( 722 = wait_for_completion_timeout(
651 io_request_completion, 723 io_request_completion,
652 msecs_to_jiffies(TERMINATION_TIMEOUT_MSEC)); 724 msecs_to_jiffies(ISCI_TERMINATION_TIMEOUT_MSEC));
653 725
654 if (!termination_completed) { 726 if (!termination_completed) {
655 727
656 /* The request to terminate has timed out. */ 728 /* The request to terminate has timed out. */
657 spin_lock_irqsave(&ihost->scic_lock, 729 spin_lock_irqsave(&ihost->scic_lock, flags);
658 flags);
659 730
660 /* Check for state changes. */ 731 /* Check for state changes. */
661 if (!test_bit(IREQ_TERMINATED, &isci_request->flags)) { 732 if (!test_bit(IREQ_TERMINATED,
733 &isci_request->flags)) {
662 734
663 /* The best we can do is to have the 735 /* The best we can do is to have the
664 * request die a silent death if it 736 * request die a silent death if it
665 * ever really completes. 737 * ever really completes.
666 *
667 * Set the request state to "dead",
668 * and clear the task pointer so that
669 * an actual completion event callback
670 * doesn't do anything.
671 */ 738 */
672 isci_request->status = dead; 739 isci_request_mark_zombie(ihost,
673 isci_request->io_request_completion 740 isci_request);
674 = NULL; 741 needs_cleanup_handling = true;
675
676 if (isci_request->ttype == io_task) {
677
678 /* Break links with the
679 * sas_task.
680 */
681 isci_request->ttype_ptr.io_task_ptr
682 = NULL;
683 }
684 } else 742 } else
685 termination_completed = 1; 743 termination_completed = 1;
686 744
@@ -1302,7 +1360,8 @@ isci_task_request_complete(struct isci_host *ihost,
1302 enum sci_task_status completion_status) 1360 enum sci_task_status completion_status)
1303{ 1361{
1304 struct isci_tmf *tmf = isci_request_access_tmf(ireq); 1362 struct isci_tmf *tmf = isci_request_access_tmf(ireq);
1305 struct completion *tmf_complete; 1363 struct completion *tmf_complete = NULL;
1364 struct completion *request_complete = ireq->io_request_completion;
1306 1365
1307 dev_dbg(&ihost->pdev->dev, 1366 dev_dbg(&ihost->pdev->dev,
1308 "%s: request = %p, status=%d\n", 1367 "%s: request = %p, status=%d\n",
@@ -1310,22 +1369,23 @@ isci_task_request_complete(struct isci_host *ihost,
1310 1369
1311 isci_request_change_state(ireq, completed); 1370 isci_request_change_state(ireq, completed);
1312 1371
1313 tmf->status = completion_status;
1314 set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags); 1372 set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags);
1315 1373
1316 if (tmf->proto == SAS_PROTOCOL_SSP) { 1374 if (tmf) {
1317 memcpy(&tmf->resp.resp_iu, 1375 tmf->status = completion_status;
1318 &ireq->ssp.rsp, 1376
1319 SSP_RESP_IU_MAX_SIZE); 1377 if (tmf->proto == SAS_PROTOCOL_SSP) {
1320 } else if (tmf->proto == SAS_PROTOCOL_SATA) { 1378 memcpy(&tmf->resp.resp_iu,
1321 memcpy(&tmf->resp.d2h_fis, 1379 &ireq->ssp.rsp,
1322 &ireq->stp.rsp, 1380 SSP_RESP_IU_MAX_SIZE);
1323 sizeof(struct dev_to_host_fis)); 1381 } else if (tmf->proto == SAS_PROTOCOL_SATA) {
1382 memcpy(&tmf->resp.d2h_fis,
1383 &ireq->stp.rsp,
1384 sizeof(struct dev_to_host_fis));
1385 }
1386 /* PRINT_TMF( ((struct isci_tmf *)request->task)); */
1387 tmf_complete = tmf->complete;
1324 } 1388 }
1325
1326 /* PRINT_TMF( ((struct isci_tmf *)request->task)); */
1327 tmf_complete = tmf->complete;
1328
1329 sci_controller_complete_io(ihost, ireq->target_device, ireq); 1389 sci_controller_complete_io(ihost, ireq->target_device, ireq);
1330 /* set the 'terminated' flag handle to make sure it cannot be terminated 1390 /* set the 'terminated' flag handle to make sure it cannot be terminated
1331 * or completed again. 1391 * or completed again.
@@ -1343,8 +1403,13 @@ isci_task_request_complete(struct isci_host *ihost,
1343 list_del_init(&ireq->dev_node); 1403 list_del_init(&ireq->dev_node);
1344 } 1404 }
1345 1405
1406 /* "request_complete" is set if the task was being terminated. */
1407 if (request_complete)
1408 complete(request_complete);
1409
1346 /* The task management part completes last. */ 1410 /* The task management part completes last. */
1347 complete(tmf_complete); 1411 if (tmf_complete)
1412 complete(tmf_complete);
1348} 1413}
1349 1414
1350static void isci_smp_task_timedout(unsigned long _task) 1415static void isci_smp_task_timedout(unsigned long _task)
diff --git a/drivers/scsi/isci/task.h b/drivers/scsi/isci/task.h
index 15b18d158993..c9ccd0b5ff53 100644
--- a/drivers/scsi/isci/task.h
+++ b/drivers/scsi/isci/task.h
@@ -58,6 +58,8 @@
58#include <scsi/sas_ata.h> 58#include <scsi/sas_ata.h>
59#include "host.h" 59#include "host.h"
60 60
61#define ISCI_TERMINATION_TIMEOUT_MSEC 500
62
61struct isci_request; 63struct isci_request;
62 64
63/** 65/**