Add basic support for handling/reporting error interrupts.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
Dan Williams 2011-02-18 09:25:11 -08:00
Родитель 77950f51f5
Коммит 92f4f0f544
4 изменённых файлов: 33 добавлений и 22 удалений

Просмотреть файл

@ -1937,18 +1937,12 @@ void scic_sds_controller_completion_handler(struct scic_sds_controller *scic)
SMU_IMR_WRITE(scic, 0x00000000); SMU_IMR_WRITE(scic, 0x00000000);
} }
/** bool scic_sds_controller_error_isr(struct scic_sds_controller *scic)
* 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)
{ {
u32 interrupt_status; u32 interrupt_status;
interrupt_status = SMU_ISR_READ(scic); interrupt_status = SMU_ISR_READ(scic);
interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND); interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND);
if (interrupt_status != 0) { if (interrupt_status != 0) {
@ -1970,12 +1964,7 @@ static bool scic_sds_controller_error_vector_interrupt_handler(
return false; return false;
} }
/** void scic_sds_controller_error_handler(struct scic_sds_controller *scic)
* 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)
{ {
u32 interrupt_status; u32 interrupt_status;
@ -1988,10 +1977,7 @@ static void scic_sds_controller_error_vector_completion_handler(
SMU_ISR_WRITE(scic, SMU_ISR_QUEUE_SUSPEND); SMU_ISR_WRITE(scic, SMU_ISR_QUEUE_SUSPEND);
} else { } else {
dev_err(scic_to_dev(scic), dev_err(scic_to_dev(scic), "%s: status: %#x\n", __func__,
"%s: SCIC Controller reports CRC error on completion "
"ISR %x\n",
__func__,
interrupt_status); interrupt_status);
sci_base_state_machine_change_state( sci_base_state_machine_change_state(
@ -2585,9 +2571,9 @@ enum sci_status scic_controller_get_handler_methods(
= scic_sds_controller_completion_handler; = scic_sds_controller_completion_handler;
handler_methods[1].interrupt_handler handler_methods[1].interrupt_handler
= scic_sds_controller_error_vector_interrupt_handler; = scic_sds_controller_error_isr;
handler_methods[1].completion_handler handler_methods[1].completion_handler
= scic_sds_controller_error_vector_completion_handler; = scic_sds_controller_error_handler;
status = SCI_SUCCESS; status = SCI_SUCCESS;
} }

Просмотреть файл

@ -85,11 +85,27 @@ irqreturn_t isci_intx_isr(int vec, void *data)
if (scic_sds_controller_isr(scic)) { if (scic_sds_controller_isr(scic)) {
tasklet_schedule(&ihost->completion_tasklet); tasklet_schedule(&ihost->completion_tasklet);
ret = IRQ_HANDLED; 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; 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, * isci_host_start_complete() - This function is called by the core library,

Просмотреть файл

@ -330,11 +330,17 @@ static int isci_setup_interrupts(struct pci_dev *pdev)
int id = i / SCI_NUM_MSI_X_INT; int id = i / SCI_NUM_MSI_X_INT;
struct msix_entry *msix = &pci_info->msix_entries[i]; struct msix_entry *msix = &pci_info->msix_entries[i];
struct isci_host *isci_host = isci_host_by_id(pdev, id); 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); BUG_ON(!isci_host);
/* @todo: need to handle error case. */ err = devm_request_irq(&pdev->dev, msix->vector, isr, 0,
err = devm_request_irq(&pdev->dev, msix->vector, isci_msix_isr, 0,
DRV_NAME"-msix", isci_host); DRV_NAME"-msix", isci_host);
if (!err) if (!err)
continue; continue;

Просмотреть файл

@ -115,9 +115,12 @@ struct isci_firmware {
irqreturn_t isci_msix_isr(int vec, void *data); irqreturn_t isci_msix_isr(int vec, void *data);
irqreturn_t isci_intx_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); bool scic_sds_controller_isr(struct scic_sds_controller *scic);
void scic_sds_controller_completion_handler(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( enum sci_status isci_parse_oem_parameters(
union scic_oem_parameters *oem_params, union scic_oem_parameters *oem_params,