Skip to contentSkip to conversation

ipr: fix possible false positive detection of stuck interrupt

PATCH In review Wayne Boyer 2 participants 2 messages May 17, 2011 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

PATCH 1/1 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.

---

 drivers/scsi/ipr.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/scsi/ipr.c +6 -6
Index: b/drivers/scsi/ipr.c
===================================================================
@@ -5149,21 +5149,21 @@ static irqreturn_t ipr_isr(int irq, void
 
 		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;
 	}