Merge SCSI misc branch into isci-for-3.6 tag
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / isci / host.c
index b425ed523ccc1b43384d97218875defe8c64ac1e..b0afa4486158f7f37537c486853791427c7102f7 100644 (file)
@@ -1044,7 +1044,7 @@ static enum sci_status sci_controller_start(struct isci_host *ihost,
        return SCI_SUCCESS;
 }
 
-void isci_host_scan_start(struct Scsi_Host *shost)
+void isci_host_start(struct Scsi_Host *shost)
 {
        struct isci_host *ihost = SHOST_TO_SAS_HA(shost)->lldd_ha;
        unsigned long tmo = sci_controller_get_suggested_start_timeout(ihost);
@@ -1079,7 +1079,6 @@ static void sci_controller_completion_handler(struct isci_host *ihost)
 
 void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_task *task)
 {
-       task->lldd_task = NULL;
        if (!test_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags) &&
            !(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
                if (test_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags)) {
@@ -1087,16 +1086,19 @@ void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_ta
                        dev_dbg(&ihost->pdev->dev,
                                "%s: Normal - ireq/task = %p/%p\n",
                                __func__, ireq, task);
-
+                       task->lldd_task = NULL;
                        task->task_done(task);
                } else {
                        dev_dbg(&ihost->pdev->dev,
                                "%s: Error - ireq/task = %p/%p\n",
                                __func__, ireq, task);
-
+                       if (sas_protocol_ata(task->task_proto))
+                               task->lldd_task = NULL;
                        sas_task_abort(task);
                }
-       }
+       } else
+               task->lldd_task = NULL;
+
        if (test_and_clear_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags))
                wake_up_all(&ihost->eventq);
 
@@ -1120,10 +1122,16 @@ void isci_host_completion_routine(unsigned long data)
        sci_controller_completion_handler(ihost);
        spin_unlock_irq(&ihost->scic_lock);
 
-       /* the coalesence timeout doubles at each encoding step, so
+       /*
+        * we subtract SCI_MAX_PORTS to account for the number of dummy TCs
+        * issued for hardware issue workaround
+        */
+       active = isci_tci_active(ihost) - SCI_MAX_PORTS;
+
+       /*
+        * the coalesence timeout doubles at each encoding step, so
         * update it based on the ilog2 value of the outstanding requests
         */
-       active = isci_tci_active(ihost);
        writel(SMU_ICC_GEN_VAL(NUMBER, active) |
               SMU_ICC_GEN_VAL(TIMER, ISCI_COALESCE_BASE + ilog2(active)),
               &ihost->smu_registers->interrupt_coalesce_control);