Skip to contentSkip to conversation

ipr: fix transition to operational for new adapters

PATCH In review Wayne Boyer 2 participants 2 messages Jul 14, 2010 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/2 ipr: fix transition to operational for new adapters

The method of transitioning to operational for new adapters includes using initialization stages. The current stage is indicated via a register read. The final good stage in the sequence is "operational" but does not necessarily indicate that the driver can proceed. There is another bit that gets set in the adapter->host interrupt register when the adapter has completed enough of its bringup such that it can accept commands. The driver was not checking that bit before proceeding which led to intermittent errors and adapter resets.

The fix is to check the "transition to operational" bit in the interrupt register after detecting that the initialization stage is "operational" and only proceed if both are set.

---
 drivers/scsi/ipr.c |   15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/scsi/ipr.c +9 -6
Index: b/drivers/scsi/ipr.c
===================================================================
@@ -7166,12 +7166,15 @@ static int ipr_reset_next_stage(struct i
 		stage_time = ioa_cfg->transop_timeout;
 		ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
 	} else if (stage == IPR_IPL_INIT_STAGE_TRANSOP) {
-		ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
-		maskval = IPR_PCII_IPL_STAGE_CHANGE;
-		maskval = (maskval << 32) | IPR_PCII_IOA_TRANS_TO_OPER;
-		writeq(maskval, ioa_cfg->regs.set_interrupt_mask_reg);
-		int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
-		return IPR_RC_JOB_CONTINUE;
+		int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32);
+		if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) {
+			ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
+			maskval = IPR_PCII_IPL_STAGE_CHANGE;
+			maskval = (maskval << 32) | IPR_PCII_IOA_TRANS_TO_OPER;
+			writeq(maskval, ioa_cfg->regs.set_interrupt_mask_reg);
+			int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+			return IPR_RC_JOB_CONTINUE;
+		}
 	}
 
 	ipr_cmd->timer.data = (unsigned long) ipr_cmd;
Acked-by on v1 1/2
#2 lore raw
Quoted 48 lines · Wayne Boyer

The method of transitioning to operational for new adapters includes using initialization stages. The current stage is indicated via a register read. The final good stage in the sequence is "operational" but does not necessarily indicate that the driver can proceed. There is another bit that gets set in the adapter->host interrupt register when the adapter has completed enough of its bringup such that it can accept commands. The driver was not checking that bit before proceeding which led to intermittent errors and adapter resets.

The fix is to check the "transition to operational" bit in the interrupt register after detecting that the initialization stage is "operational" and only proceed if both are set.

---
 drivers/scsi/ipr.c |   15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

Index: b/drivers/scsi/ipr.c
===================================================================

drivers/scsi/ipr.c +9 -7
@@ -7166,12 +7166,15 @@ static int ipr_reset_next_stage(struct i
 		stage_time = ioa_cfg->transop_timeout;
 		ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
 	} else if (stage == IPR_IPL_INIT_STAGE_TRANSOP) {
-		ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
-		maskval = IPR_PCII_IPL_STAGE_CHANGE;
-		maskval = (maskval << 32) | IPR_PCII_IOA_TRANS_TO_OPER;
-		writeq(maskval, ioa_cfg->regs.set_interrupt_mask_reg);
-		int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
-		return IPR_RC_JOB_CONTINUE;
+		int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32);
+		if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) {
+			ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
+			maskval = IPR_PCII_IPL_STAGE_CHANGE;
+			maskval = (maskval << 32) | IPR_PCII_IOA_TRANS_TO_OPER;
+			writeq(maskval, ioa_cfg->regs.set_interrupt_mask_reg);
+			int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+			return IPR_RC_JOB_CONTINUE;
+		}
 	}
 
 	ipr_cmd->timer.data = (unsigned long) ipr_cmd;
 
--

To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 3 lines
Brian King
Linux on Power Virtualization
IBM Linux Technology Center