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:
Родитель
77950f51f5
Коммит
92f4f0f544
|
@ -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,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче