isci: implement error isr

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
parent 77950f51f5
commit 92f4f0f544
4 changed files with 33 additions and 22 deletions

View 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;
}

View 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,

View 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;

View 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,