aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorWayne Boyer <wayneb@linux.vnet.ibm.com>2011-05-17 12:18:53 -0400
committerJames Bottomley <jbottomley@parallels.com>2011-05-24 12:37:50 -0400
commita5442ba4a428081ebac7090f46c62ffaa17ca951 (patch)
tree411450d544b51ccda3f60d4ced97eaca744194ec /drivers/scsi
parentd85e607b344d8fcd644456508a5bbe63ce011221 (diff)
[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)
5149 5149
5150 if (ipr_cmd != NULL) { 5150 if (ipr_cmd != NULL) {
5151 /* Clear the PCI interrupt */ 5151 /* Clear the PCI interrupt */
5152 num_hrrq = 0;
5152 do { 5153 do {
5153 writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32); 5154 writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32);
5154 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32); 5155 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32);
5155 } while (int_reg & IPR_PCII_HRRQ_UPDATED && 5156 } while (int_reg & IPR_PCII_HRRQ_UPDATED &&
5156 num_hrrq++ < IPR_MAX_HRRQ_RETRIES); 5157 num_hrrq++ < IPR_MAX_HRRQ_RETRIES);
5157 5158
5158 if (int_reg & IPR_PCII_HRRQ_UPDATED) {
5159 ipr_isr_eh(ioa_cfg, "Error clearing HRRQ");
5160 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
5161 return IRQ_HANDLED;
5162 }
5163
5164 } else if (rc == IRQ_NONE && irq_none == 0) { 5159 } else if (rc == IRQ_NONE && irq_none == 0) {
5165 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32); 5160 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32);
5166 irq_none++; 5161 irq_none++;
5162 } else if (num_hrrq == IPR_MAX_HRRQ_RETRIES &&
5163 int_reg & IPR_PCII_HRRQ_UPDATED) {
5164 ipr_isr_eh(ioa_cfg, "Error clearing HRRQ");
5165 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
5166 return IRQ_HANDLED;
5167 } else 5167 } else
5168 break; 5168 break;
5169 } 5169 }