Skip to content

Commit

Permalink
isci: rely on irq core for intx multiplexing, and silence screaming intx
Browse files Browse the repository at this point in the history
Remove the extra logic to poll each controller for interrupts, that's
the core's job for shared interrupts.

While testing noticed that a number of interrupts fire while waiting for
the completion tasklet to run, so added an irq-ack.

Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
Dan Williams committed Jul 3, 2011
1 parent e2023b8 commit 31e824e
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 21 deletions.
26 changes: 11 additions & 15 deletions drivers/scsi/isci/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,23 +77,19 @@ irqreturn_t isci_msix_isr(int vec, void *data)

irqreturn_t isci_intx_isr(int vec, void *data)
{
struct pci_dev *pdev = data;
struct isci_host *ihost;
irqreturn_t ret = IRQ_NONE;
int i;
struct isci_host *ihost = data;
struct scic_sds_controller *scic = ihost->core_controller;

for_each_isci_host(i, ihost, pdev) {
struct scic_sds_controller *scic = ihost->core_controller;

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;
}
if (scic_sds_controller_isr(scic)) {
writel(SMU_ISR_COMPLETION, &scic->smu_registers->interrupt_status);
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;
Expand Down
17 changes: 11 additions & 6 deletions drivers/scsi/isci/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ static int num_controllers(struct pci_dev *pdev)
static int isci_setup_interrupts(struct pci_dev *pdev)
{
int err, i, num_msix;
struct isci_host *ihost;
struct isci_pci_info *pci_info = to_pci_info(pdev);

/*
Expand All @@ -353,35 +354,39 @@ static int isci_setup_interrupts(struct pci_dev *pdev)
for (i = 0; i < num_msix; i++) {
int id = i / SCI_NUM_MSI_X_INT;
struct msix_entry *msix = &pci_info->msix_entries[i];
struct isci_host *isci_host = pci_info->hosts[id];
irq_handler_t isr;

ihost = pci_info->hosts[id];
/* odd numbered vectors are error interrupts */
if (i & 1)
isr = isci_error_isr;
else
isr = isci_msix_isr;

err = devm_request_irq(&pdev->dev, msix->vector, isr, 0,
DRV_NAME"-msix", isci_host);
DRV_NAME"-msix", ihost);
if (!err)
continue;

dev_info(&pdev->dev, "msix setup failed falling back to intx\n");
while (i--) {
id = i / SCI_NUM_MSI_X_INT;
isci_host = pci_info->hosts[id];
ihost = pci_info->hosts[id];
msix = &pci_info->msix_entries[i];
devm_free_irq(&pdev->dev, msix->vector, isci_host);
devm_free_irq(&pdev->dev, msix->vector, ihost);
}
pci_disable_msix(pdev);
goto intx;
}
return 0;

intx:
err = devm_request_irq(&pdev->dev, pdev->irq, isci_intx_isr,
IRQF_SHARED, DRV_NAME"-intx", pdev);
for_each_isci_host(i, ihost, pdev) {
err = devm_request_irq(&pdev->dev, pdev->irq, isci_intx_isr,
IRQF_SHARED, DRV_NAME"-intx", ihost);
if (err)
break;
}
return err;
}

Expand Down

0 comments on commit 31e824e

Please sign in to comment.