* [PATCH 1/1] ipr: add workaround for MSI interrupts on P7
[not found] <20090930212120.556737609@linux.vnet.ibm.com>
@ 2009-10-20 18:09 ` Wayne Boyer
2009-10-20 18:29 ` Brian King
0 siblings, 1 reply; 2+ messages in thread
From: Wayne Boyer @ 2009-10-20 18:09 UTC (permalink / raw)
To: linux-scsi; +Cc: Brian King
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@linux.vnet.ibm.com>
---
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))
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH 1/1] ipr: add workaround for MSI interrupts on P7
2009-10-20 18:09 ` [PATCH 1/1] ipr: add workaround for MSI interrupts on P7 Wayne Boyer
@ 2009-10-20 18:29 ` Brian King
0 siblings, 0 replies; 2+ messages in thread
From: Brian King @ 2009-10-20 18:29 UTC (permalink / raw)
To: Wayne Boyer; +Cc: linux-scsi
Acked-by: Brian King <brking@linux.vnet.ibm.com>
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@linux.vnet.ibm.com>
> ---
> 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
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-10-20 18:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20090930212120.556737609@linux.vnet.ibm.com>
2009-10-20 18:09 ` [PATCH 1/1] ipr: add workaround for MSI interrupts on P7 Wayne Boyer
2009-10-20 18:29 ` Brian King
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).