linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).