isci: implement error isr
authorDan Williams <dan.j.williams@intel.com>
Fri, 18 Feb 2011 17:25:11 +0000 (09:25 -0800)
committerDan Williams <dan.j.williams@intel.com>
Sun, 3 Jul 2011 10:55:27 +0000 (03:55 -0700)
Add basic support for handling/reporting error interrupts.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/scsi/isci/core/scic_sds_controller.c
drivers/scsi/isci/host.c
drivers/scsi/isci/init.c
drivers/scsi/isci/isci.h

index cd8017f048c16674705ff7a10e0189dd2416c9dc..7ea36624f5686cb123bd96cf4c99989e22699fe8 100644 (file)
@@ -1937,18 +1937,12 @@ void scic_sds_controller_completion_handler(struct scic_sds_controller *scic)
        SMU_IMR_WRITE(scic, 0x00000000);
 }
 
-/**
- * This is the method provided to handle the error MSIX message interrupt.
- *    This is the normal operating mode for the hardware if MSIX is enabled.
- *
- * bool true if an interrupt is processed false if no interrupt was processed
- */
-static bool scic_sds_controller_error_vector_interrupt_handler(
-       struct scic_sds_controller *scic)
+bool scic_sds_controller_error_isr(struct scic_sds_controller *scic)
 {
        u32 interrupt_status;
 
        interrupt_status = SMU_ISR_READ(scic);
+
        interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND);
 
        if (interrupt_status != 0) {
@@ -1970,12 +1964,7 @@ static bool scic_sds_controller_error_vector_interrupt_handler(
        return false;
 }
 
-/**
- * This is the method provided to handle the error completions when the
- *    hardware is using two MSIX messages.
- */
-static void scic_sds_controller_error_vector_completion_handler(
-       struct scic_sds_controller *scic)
+void scic_sds_controller_error_handler(struct scic_sds_controller *scic)
 {
        u32 interrupt_status;
 
@@ -1988,10 +1977,7 @@ static void scic_sds_controller_error_vector_completion_handler(
                SMU_ISR_WRITE(scic, SMU_ISR_QUEUE_SUSPEND);
 
        } else {
-               dev_err(scic_to_dev(scic),
-                       "%s: SCIC Controller reports CRC error on completion "
-                       "ISR %x\n",
-                       __func__,
+               dev_err(scic_to_dev(scic), "%s: status: %#x\n", __func__,
                        interrupt_status);
 
                sci_base_state_machine_change_state(
@@ -2585,9 +2571,9 @@ enum sci_status scic_controller_get_handler_methods(
                                = scic_sds_controller_completion_handler;
 
                        handler_methods[1].interrupt_handler
-                               = scic_sds_controller_error_vector_interrupt_handler;
+                               = scic_sds_controller_error_isr;
                        handler_methods[1].completion_handler
-                               = scic_sds_controller_error_vector_completion_handler;
+                               = scic_sds_controller_error_handler;
 
                        status = SCI_SUCCESS;
                }
index 7f351a35e87b0c35cd8a4866052a09347fa656ba..cb2e3f9558e95d6f5f87c023e1cb5c171693022c 100644 (file)
@@ -85,11 +85,27 @@ irqreturn_t isci_intx_isr(int vec, void *data)
                if (scic_sds_controller_isr(scic)) {
                        tasklet_schedule(&ihost->completion_tasklet);
                        ret = IRQ_HANDLED;
+               } else if (scic_sds_controller_error_isr(scic)) {
+                       spin_lock(&ihost->scic_lock);
+                       scic_sds_controller_error_handler(scic);
+                       spin_unlock(&ihost->scic_lock);
+                       ret = IRQ_HANDLED;
                }
        }
+
        return ret;
 }
 
+irqreturn_t isci_error_isr(int vec, void *data)
+{
+       struct isci_host *ihost = data;
+       struct scic_sds_controller *scic = ihost->core_controller;
+
+       if (scic_sds_controller_error_isr(scic))
+               scic_sds_controller_error_handler(scic);
+
+       return IRQ_HANDLED;
+}
 
 /**
  * isci_host_start_complete() - This function is called by the core library,
index f2bd92b81136f67f5ae29adf8ee7e8d07ec05924..4d6decb6d08ce75033a5bf10d6cd9e71409d57cd 100644 (file)
@@ -330,11 +330,17 @@ static int isci_setup_interrupts(struct pci_dev *pdev)
                int id = i / SCI_NUM_MSI_X_INT;
                struct msix_entry *msix = &pci_info->msix_entries[i];
                struct isci_host *isci_host = isci_host_by_id(pdev, id);
+               irq_handler_t isr;
+
+               /* odd numbered vectors are error interrupts */
+               if (i & 1)
+                       isr = isci_error_isr;
+               else
+                       isr = isci_msix_isr;
 
                BUG_ON(!isci_host);
 
-               /* @todo: need to handle error case. */
-               err = devm_request_irq(&pdev->dev, msix->vector, isci_msix_isr, 0,
+               err = devm_request_irq(&pdev->dev, msix->vector, isr, 0,
                                       DRV_NAME"-msix", isci_host);
                if (!err)
                        continue;
index 3dc0f6c211744f7524911ac3dea649388d929fd4..39efd5f272007d63e8c2d78105a0b6be87451f8d 100644 (file)
@@ -115,9 +115,12 @@ struct isci_firmware {
 
 irqreturn_t isci_msix_isr(int vec, void *data);
 irqreturn_t isci_intx_isr(int vec, void *data);
+irqreturn_t isci_error_isr(int vec, void *data);
 
 bool scic_sds_controller_isr(struct scic_sds_controller *scic);
 void scic_sds_controller_completion_handler(struct scic_sds_controller *scic);
+bool scic_sds_controller_error_isr(struct scic_sds_controller *scic);
+void scic_sds_controller_error_handler(struct scic_sds_controller *scic);
 
 enum sci_status isci_parse_oem_parameters(
        union scic_oem_parameters *oem_params,