aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ipr.c
diff options
context:
space:
mode:
authorWayne Boyer <wayneb@linux.vnet.ibm.com>2010-07-14 13:49:43 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-28 10:05:39 -0400
commit1df79ca4223632113f14618833b8bb1727a8ca15 (patch)
tree75b7def7758b9bd3f5bd3c2e6ba530abb644f5ca /drivers/scsi/ipr.c
parent82c57028e4bf6e2755de91b36223f57406746fa8 (diff)
[SCSI] 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. Signed-off-by: Wayne Boyer <wayneb@linux.vnet.ibm.com> Acked-by: Brian King <brking@linux.vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r--drivers/scsi/ipr.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index ce839c8eeea3..f73007db2bec 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -7169,12 +7169,15 @@ static int ipr_reset_next_stage(struct ipr_cmnd *ipr_cmd)
7169 stage_time = ioa_cfg->transop_timeout; 7169 stage_time = ioa_cfg->transop_timeout;
7170 ipr_cmd->job_step = ipr_ioafp_identify_hrrq; 7170 ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
7171 } else if (stage == IPR_IPL_INIT_STAGE_TRANSOP) { 7171 } else if (stage == IPR_IPL_INIT_STAGE_TRANSOP) {
7172 ipr_cmd->job_step = ipr_ioafp_identify_hrrq; 7172 int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32);
7173 maskval = IPR_PCII_IPL_STAGE_CHANGE; 7173 if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) {
7174 maskval = (maskval << 32) | IPR_PCII_IOA_TRANS_TO_OPER; 7174 ipr_cmd->job_step = ipr_ioafp_identify_hrrq;
7175 writeq(maskval, ioa_cfg->regs.set_interrupt_mask_reg); 7175 maskval = IPR_PCII_IPL_STAGE_CHANGE;
7176 int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); 7176 maskval = (maskval << 32) | IPR_PCII_IOA_TRANS_TO_OPER;
7177 return IPR_RC_JOB_CONTINUE; 7177 writeq(maskval, ioa_cfg->regs.set_interrupt_mask_reg);
7178 int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
7179 return IPR_RC_JOB_CONTINUE;
7180 }
7178 } 7181 }
7179 7182
7180 ipr_cmd->timer.data = (unsigned long) ipr_cmd; 7183 ipr_cmd->timer.data = (unsigned long) ipr_cmd;