Acked-by: Brian King <brking@xxxxxxxxxxxxxxxxxx> Wayne Boyer wrote: > This patch adds some additional logic to the interrupt service routine to fix > a potential problem where an MSI interrupt does not get cleared the first time. > > Signed-off-by: Wayne Boyer <wayneb@xxxxxxxxxxxxxxxxxx> > --- > ipr.c | 42 +++++++++++++++++++++++++++++++++--------- > ipr.h | 1 + > 2 files changed, 34 insertions(+), 9 deletions(-) > > Index: b/ipr.c > =================================================================== > --- a/ipr.c 2009-09-29 09:34:08.000000000 -0700 > +++ b/ipr.c 2009-09-30 14:16:51.000000000 -0700 > @@ -4189,6 +4189,25 @@ static irqreturn_t ipr_handle_other_inte > } > > /** > + * ipr_isr_eh - Interrupt service routine error handler > + * @ioa_cfg: ioa config struct > + * @msg: message to log > + * > + * Return value: > + * none > + **/ > +static void ipr_isr_eh(struct ipr_ioa_cfg *ioa_cfg, char *msg) > +{ > + ioa_cfg->errors_logged++; > + dev_err(&ioa_cfg->pdev->dev, "%s\n", msg); > + > + if (WAIT_FOR_DUMP == ioa_cfg->sdt_state) > + ioa_cfg->sdt_state = GET_DUMP; > + > + ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); > +} > + > +/** > * ipr_isr - Interrupt service routine > * @irq: irq number > * @devp: pointer to ioa config struct > @@ -4203,6 +4222,7 @@ static irqreturn_t ipr_isr(int irq, void > volatile u32 int_reg, int_mask_reg; > u32 ioasc; > u16 cmd_index; > + int num_hrrq = 0; > struct ipr_cmnd *ipr_cmd; > irqreturn_t rc = IRQ_NONE; > > @@ -4233,13 +4253,7 @@ static irqreturn_t ipr_isr(int irq, void > IPR_HRRQ_REQ_RESP_HANDLE_MASK) >> IPR_HRRQ_REQ_RESP_HANDLE_SHIFT; > > if (unlikely(cmd_index >= IPR_NUM_CMD_BLKS)) { > - ioa_cfg->errors_logged++; > - dev_err(&ioa_cfg->pdev->dev, "Invalid response handle from IOA\n"); > - > - if (WAIT_FOR_DUMP == ioa_cfg->sdt_state) > - ioa_cfg->sdt_state = GET_DUMP; > - > - ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); > + ipr_isr_eh(ioa_cfg, "Invalid response handle from IOA"); > spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); > return IRQ_HANDLED; > } > @@ -4266,8 +4280,18 @@ static irqreturn_t ipr_isr(int irq, void > > if (ipr_cmd != NULL) { > /* Clear the PCI interrupt */ > - writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg); > - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; > + do { > + writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg); > + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; > + } 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 > break; > } > Index: b/ipr.h > =================================================================== > --- a/ipr.h 2009-09-29 14:59:33.000000000 -0700 > +++ b/ipr.h 2009-09-29 15:00:35.000000000 -0700 > @@ -144,6 +144,7 @@ > #define IPR_IOA_MAX_SECTORS 32767 > #define IPR_VSET_MAX_SECTORS 512 > #define IPR_MAX_CDB_LEN 16 > +#define IPR_MAX_HRRQ_RETRIES 3 > > #define IPR_DEFAULT_BUS_WIDTH 16 > #define IPR_80MBs_SCSI_RATE ((80 * 10) / (IPR_DEFAULT_BUS_WIDTH / 8)) > -- Brian King Linux on Power Virtualization IBM Linux Technology Center -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html