summaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorWayne Boyer2011-05-17 18:18:53 +0200
committerJames Bottomley2011-05-24 18:37:50 +0200
commita5442ba4a428081ebac7090f46c62ffaa17ca951 (patch)
tree411450d544b51ccda3f60d4ced97eaca744194ec /drivers/scsi
parent[SCSI] libfcoe: Remove unnecessary module state checks (diff)
downloadkernel-qcow2-linux-a5442ba4a428081ebac7090f46c62ffaa17ca951.tar.gz
kernel-qcow2-linux-a5442ba4a428081ebac7090f46c62ffaa17ca951.tar.xz
kernel-qcow2-linux-a5442ba4a428081ebac7090f46c62ffaa17ca951.zip
[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/scsi')
-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 12868ca46110..888086c4e709 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;
}