summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/request.c
diff options
context:
space:
mode:
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>2011-06-23 17:09:02 -0700
committerDan Williams <dan.j.williams@intel.com>2011-07-03 04:04:51 -0700
commit9274f45ea551421cd3bf329de9dd8d1e6208285a (patch)
tree25e21494d3c74a5b2965485f2d76c541d49cc68b /drivers/scsi/isci/request.c
parent4cffe13e0dfd00f90c86b0153c751dab61a1bf1d (diff)
isci: Terminate dev requests on FIS err bit rx in NCQ
When the remote device transitions to a not-ready state because of an NCQ error condition, all outstanding requests to that device are terminated and completed to libsas on the normal path. The device then waits for a READ LOG EXT command to issue on the task management path. Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/request.c')
-rw-r--r--drivers/scsi/isci/request.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index 1043fed2a40..08a7340b33b 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -3587,9 +3587,30 @@ int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *ide
spin_lock_irqsave(&ihost->scic_lock, flags);
- /* send the request, let the core assign the IO TAG. */
- status = scic_controller_start_io(&ihost->sci, &idev->sci, &ireq->sci,
- SCI_CONTROLLER_INVALID_IO_TAG);
+ if (test_bit(IDEV_IO_NCQERROR, &idev->flags)) {
+
+ if (isci_task_is_ncq_recovery(task)) {
+
+ /* The device is in an NCQ recovery state. Issue the
+ * request on the task side. Note that it will
+ * complete on the I/O request side because the
+ * request was built that way (ie.
+ * ireq->is_task_management_request is false).
+ */
+ status = scic_controller_start_task(&ihost->sci,
+ &idev->sci,
+ &ireq->sci,
+ SCI_CONTROLLER_INVALID_IO_TAG);
+ } else {
+ status = SCI_FAILURE;
+ }
+ } else {
+
+ /* send the request, let the core assign the IO TAG. */
+ status = scic_controller_start_io(&ihost->sci, &idev->sci,
+ &ireq->sci,
+ SCI_CONTROLLER_INVALID_IO_TAG);
+ }
if (status != SCI_SUCCESS &&
status != SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
dev_warn(&ihost->pdev->dev,