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>
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
index 0835a2c..157e997 100644
--- a/drivers/scsi/isci/task.c
+++ b/drivers/scsi/isci/task.c
@@ -133,6 +133,15 @@
 	for (; num > 0; num--,\
 	     task = list_entry(task->list.next, struct sas_task, list))
 
+
+static inline int isci_device_io_ready(struct isci_remote_device *idev,
+				       struct sas_task *task)
+{
+	return idev ? test_bit(IDEV_IO_READY, &idev->flags) ||
+		      (test_bit(IDEV_IO_NCQERROR, &idev->flags) &&
+		       isci_task_is_ncq_recovery(task))
+		    : 0;
+}
 /**
  * isci_task_execute_task() - This function is one of the SAS Domain Template
  *    functions. This function is called by libsas to send a task down to
@@ -165,7 +174,7 @@
 	for_each_sas_task(num, task) {
 		spin_lock_irqsave(&ihost->scic_lock, flags);
 		idev = isci_lookup_device(task->dev);
-		io_ready = idev ? test_bit(IDEV_IO_READY, &idev->flags) : 0;
+		io_ready = isci_device_io_ready(idev, task);
 		spin_unlock_irqrestore(&ihost->scic_lock, flags);
 
 		dev_dbg(&ihost->pdev->dev,
@@ -178,6 +187,7 @@
 					 SAS_DEVICE_UNKNOWN);
 			isci_host_can_dequeue(ihost, 1);
 		} else if (!io_ready) {
+
 			/* Indicate QUEUE_FULL so that the scsi midlayer
 			 * retries.
 			  */
@@ -299,7 +309,9 @@
 	/* sanity check, return TMF_RESP_FUNC_FAILED
 	 * if the device is not there and ready.
 	 */
-	if (!isci_device || !test_bit(IDEV_IO_READY, &isci_device->flags)) {
+	if (!isci_device ||
+	    (!test_bit(IDEV_IO_READY, &isci_device->flags) &&
+	     !test_bit(IDEV_IO_NCQERROR, &isci_device->flags))) {
 		dev_dbg(&ihost->pdev->dev,
 			"%s: isci_device = %p not ready (%#lx)\n",
 			__func__,