diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_controller.c | 26 | ||||
-rw-r--r-- | drivers/scsi/isci/host.c | 16 | ||||
-rw-r--r-- | drivers/scsi/isci/init.c | 10 | ||||
-rw-r--r-- | drivers/scsi/isci/isci.h | 3 |
4 files changed, 33 insertions, 22 deletions
diff --git a/drivers/scsi/isci/core/scic_sds_controller.c b/drivers/scsi/isci/core/scic_sds_controller.c index cd8017f048c1..7ea36624f568 100644 --- a/drivers/scsi/isci/core/scic_sds_controller.c +++ b/drivers/scsi/isci/core/scic_sds_controller.c | |||
@@ -1937,18 +1937,12 @@ void scic_sds_controller_completion_handler(struct scic_sds_controller *scic) | |||
1937 | SMU_IMR_WRITE(scic, 0x00000000); | 1937 | SMU_IMR_WRITE(scic, 0x00000000); |
1938 | } | 1938 | } |
1939 | 1939 | ||
1940 | /** | 1940 | bool scic_sds_controller_error_isr(struct scic_sds_controller *scic) |
1941 | * This is the method provided to handle the error MSIX message interrupt. | ||
1942 | * This is the normal operating mode for the hardware if MSIX is enabled. | ||
1943 | * | ||
1944 | * bool true if an interrupt is processed false if no interrupt was processed | ||
1945 | */ | ||
1946 | static bool scic_sds_controller_error_vector_interrupt_handler( | ||
1947 | struct scic_sds_controller *scic) | ||
1948 | { | 1941 | { |
1949 | u32 interrupt_status; | 1942 | u32 interrupt_status; |
1950 | 1943 | ||
1951 | interrupt_status = SMU_ISR_READ(scic); | 1944 | interrupt_status = SMU_ISR_READ(scic); |
1945 | |||
1952 | interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND); | 1946 | interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND); |
1953 | 1947 | ||
1954 | if (interrupt_status != 0) { | 1948 | if (interrupt_status != 0) { |
@@ -1970,12 +1964,7 @@ static bool scic_sds_controller_error_vector_interrupt_handler( | |||
1970 | return false; | 1964 | return false; |
1971 | } | 1965 | } |
1972 | 1966 | ||
1973 | /** | 1967 | void scic_sds_controller_error_handler(struct scic_sds_controller *scic) |
1974 | * This is the method provided to handle the error completions when the | ||
1975 | * hardware is using two MSIX messages. | ||
1976 | */ | ||
1977 | static void scic_sds_controller_error_vector_completion_handler( | ||
1978 | struct scic_sds_controller *scic) | ||
1979 | { | 1968 | { |
1980 | u32 interrupt_status; | 1969 | u32 interrupt_status; |
1981 | 1970 | ||
@@ -1988,10 +1977,7 @@ static void scic_sds_controller_error_vector_completion_handler( | |||
1988 | SMU_ISR_WRITE(scic, SMU_ISR_QUEUE_SUSPEND); | 1977 | SMU_ISR_WRITE(scic, SMU_ISR_QUEUE_SUSPEND); |
1989 | 1978 | ||
1990 | } else { | 1979 | } else { |
1991 | dev_err(scic_to_dev(scic), | 1980 | dev_err(scic_to_dev(scic), "%s: status: %#x\n", __func__, |
1992 | "%s: SCIC Controller reports CRC error on completion " | ||
1993 | "ISR %x\n", | ||
1994 | __func__, | ||
1995 | interrupt_status); | 1981 | interrupt_status); |
1996 | 1982 | ||
1997 | sci_base_state_machine_change_state( | 1983 | sci_base_state_machine_change_state( |
@@ -2585,9 +2571,9 @@ enum sci_status scic_controller_get_handler_methods( | |||
2585 | = scic_sds_controller_completion_handler; | 2571 | = scic_sds_controller_completion_handler; |
2586 | 2572 | ||
2587 | handler_methods[1].interrupt_handler | 2573 | handler_methods[1].interrupt_handler |
2588 | = scic_sds_controller_error_vector_interrupt_handler; | 2574 | = scic_sds_controller_error_isr; |
2589 | handler_methods[1].completion_handler | 2575 | handler_methods[1].completion_handler |
2590 | = scic_sds_controller_error_vector_completion_handler; | 2576 | = scic_sds_controller_error_handler; |
2591 | 2577 | ||
2592 | status = SCI_SUCCESS; | 2578 | status = SCI_SUCCESS; |
2593 | } | 2579 | } |
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index 7f351a35e87b..cb2e3f9558e9 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c | |||
@@ -85,11 +85,27 @@ irqreturn_t isci_intx_isr(int vec, void *data) | |||
85 | if (scic_sds_controller_isr(scic)) { | 85 | if (scic_sds_controller_isr(scic)) { |
86 | tasklet_schedule(&ihost->completion_tasklet); | 86 | tasklet_schedule(&ihost->completion_tasklet); |
87 | ret = IRQ_HANDLED; | 87 | ret = IRQ_HANDLED; |
88 | } else if (scic_sds_controller_error_isr(scic)) { | ||
89 | spin_lock(&ihost->scic_lock); | ||
90 | scic_sds_controller_error_handler(scic); | ||
91 | spin_unlock(&ihost->scic_lock); | ||
92 | ret = IRQ_HANDLED; | ||
88 | } | 93 | } |
89 | } | 94 | } |
95 | |||
90 | return ret; | 96 | return ret; |
91 | } | 97 | } |
92 | 98 | ||
99 | irqreturn_t isci_error_isr(int vec, void *data) | ||
100 | { | ||
101 | struct isci_host *ihost = data; | ||
102 | struct scic_sds_controller *scic = ihost->core_controller; | ||
103 | |||
104 | if (scic_sds_controller_error_isr(scic)) | ||
105 | scic_sds_controller_error_handler(scic); | ||
106 | |||
107 | return IRQ_HANDLED; | ||
108 | } | ||
93 | 109 | ||
94 | /** | 110 | /** |
95 | * isci_host_start_complete() - This function is called by the core library, | 111 | * isci_host_start_complete() - This function is called by the core library, |
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index f2bd92b81136..4d6decb6d08c 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c | |||
@@ -330,11 +330,17 @@ static int isci_setup_interrupts(struct pci_dev *pdev) | |||
330 | int id = i / SCI_NUM_MSI_X_INT; | 330 | int id = i / SCI_NUM_MSI_X_INT; |
331 | struct msix_entry *msix = &pci_info->msix_entries[i]; | 331 | struct msix_entry *msix = &pci_info->msix_entries[i]; |
332 | struct isci_host *isci_host = isci_host_by_id(pdev, id); | 332 | struct isci_host *isci_host = isci_host_by_id(pdev, id); |
333 | irq_handler_t isr; | ||
334 | |||
335 | /* odd numbered vectors are error interrupts */ | ||
336 | if (i & 1) | ||
337 | isr = isci_error_isr; | ||
338 | else | ||
339 | isr = isci_msix_isr; | ||
333 | 340 | ||
334 | BUG_ON(!isci_host); | 341 | BUG_ON(!isci_host); |
335 | 342 | ||
336 | /* @todo: need to handle error case. */ | 343 | err = devm_request_irq(&pdev->dev, msix->vector, isr, 0, |
337 | err = devm_request_irq(&pdev->dev, msix->vector, isci_msix_isr, 0, | ||
338 | DRV_NAME"-msix", isci_host); | 344 | DRV_NAME"-msix", isci_host); |
339 | if (!err) | 345 | if (!err) |
340 | continue; | 346 | continue; |
diff --git a/drivers/scsi/isci/isci.h b/drivers/scsi/isci/isci.h index 3dc0f6c21174..39efd5f27200 100644 --- a/drivers/scsi/isci/isci.h +++ b/drivers/scsi/isci/isci.h | |||
@@ -115,9 +115,12 @@ struct isci_firmware { | |||
115 | 115 | ||
116 | irqreturn_t isci_msix_isr(int vec, void *data); | 116 | irqreturn_t isci_msix_isr(int vec, void *data); |
117 | irqreturn_t isci_intx_isr(int vec, void *data); | 117 | irqreturn_t isci_intx_isr(int vec, void *data); |
118 | irqreturn_t isci_error_isr(int vec, void *data); | ||
118 | 119 | ||
119 | bool scic_sds_controller_isr(struct scic_sds_controller *scic); | 120 | bool scic_sds_controller_isr(struct scic_sds_controller *scic); |
120 | void scic_sds_controller_completion_handler(struct scic_sds_controller *scic); | 121 | void scic_sds_controller_completion_handler(struct scic_sds_controller *scic); |
122 | bool scic_sds_controller_error_isr(struct scic_sds_controller *scic); | ||
123 | void scic_sds_controller_error_handler(struct scic_sds_controller *scic); | ||
121 | 124 | ||
122 | enum sci_status isci_parse_oem_parameters( | 125 | enum sci_status isci_parse_oem_parameters( |
123 | union scic_oem_parameters *oem_params, | 126 | union scic_oem_parameters *oem_params, |