summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorWayne Boyer <wayneb@linux.vnet.ibm.com>2011-05-17 16:18:53 (GMT)
committerJames Bottomley <jbottomley@parallels.com>2011-05-24 16:37:50 (GMT)
commita5442ba4a428081ebac7090f46c62ffaa17ca951 (patch)
tree411450d544b51ccda3f60d4ced97eaca744194ec /drivers
parentd85e607b344d8fcd644456508a5bbe63ce011221 (diff)
downloadlinux-fsl-qoriq-a5442ba4a428081ebac7090f46c62ffaa17ca951.tar.xz
[SCSI] ipr: fix possible false positive detection of stuck interrupt
If the driver is getting flooded with interrupts, there's a possibility that the interrupt service routine could falsely detect a stuck interrupt condition and reset the adapter. This patch changes the logic such that the routine will loop back into the command processing code one more time after detecting the stuck interrupt signature. If there are no commands to process after that pass, and the interrupt is still not cleared, then the driver will print the "Error clearing HRRQ" message and reset the adapter. Signed-off-by: Wayne Boyer <wayneb@linux.vnet.ibm.com> Acked-by: Brian King <brking@linux.vnet.ibm.com> Signed-off-by: James Bottomley <jbottomley@parallels.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/ipr.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 12868ca..888086c 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -5149,21 +5149,21 @@ static irqreturn_t ipr_isr(int irq, void *devp)
if (ipr_cmd != NULL) {
/* Clear the PCI interrupt */
+ num_hrrq = 0;
do {
writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32);
int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32);
} while (int_reg & IPR_PCII_HRRQ_UPDATED &&
num_hrrq++ < IPR_MAX_HRRQ_RETRIES);
- if (int_reg & IPR_PCII_HRRQ_UPDATED) {
- ipr_isr_eh(ioa_cfg, "Error clearing HRRQ");
- spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
- return IRQ_HANDLED;
- }
-
} else if (rc == IRQ_NONE && irq_none == 0) {
int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32);
irq_none++;
+ } else if (num_hrrq == IPR_MAX_HRRQ_RETRIES &&
+ int_reg & IPR_PCII_HRRQ_UPDATED) {
+ ipr_isr_eh(ioa_cfg, "Error clearing HRRQ");
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ return IRQ_HANDLED;
} else
break;
}