aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian King <brking@linux.vnet.ibm.com>2011-10-15 09:08:56 -0500
committerJames Bottomley <JBottomley@Parallels.com>2011-10-20 10:19:55 -0500
commit4c647e909fceb9df8ec8f06016dd56244045a929 (patch)
tree30203a4611841498e22fe829d2626fc8f38f9cae
parentf575c5d3ebdca3b0482847d8fcba971767754a9e (diff)
[SCSI] ipr: Fix BUG on adapter dump timeout
If an adapter dump times out, the ipr driver will abort the dump and proceed to reset and recover the adapter. When an adapter dump completes, the work thread which is reading the adapter dump will initiate an adapter reset to recover the adapter. However, when the adapter dump gets aborted, the work thread should not initiate an adapter reset, since an adapter reset is already in progress. This fixes a case of calling pci_block_user_cfg_access overlapped, which results in a BUG. Signed-off-by: Brian King <brking@linux.vnet.ibm.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/ipr.c4
-rw-r--r--drivers/scsi/ipr.h1
2 files changed, 4 insertions, 1 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index e16a9cf442c..73e24b48dce 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3109,7 +3109,7 @@ static void ipr_worker_thread(struct work_struct *work)
kref_put(&dump->kref, ipr_release_dump);
spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
- if (ioa_cfg->sdt_state == DUMP_OBTAINED)
+ if (ioa_cfg->sdt_state == DUMP_OBTAINED && !ioa_cfg->dump_timeout)
ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
return;
@@ -7447,6 +7447,7 @@ static int ipr_reset_wait_for_dump(struct ipr_cmnd *ipr_cmd)
else if (ioa_cfg->sdt_state == READ_DUMP)
ioa_cfg->sdt_state = ABORT_DUMP;
+ ioa_cfg->dump_timeout = 1;
ipr_cmd->job_step = ipr_reset_alert;
return IPR_RC_JOB_CONTINUE;
@@ -7611,6 +7612,7 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
if (GET_DUMP == ioa_cfg->sdt_state) {
ioa_cfg->sdt_state = READ_DUMP;
+ ioa_cfg->dump_timeout = 0;
if (ioa_cfg->sis64)
ipr_reset_start_timer(ipr_cmd, IPR_SIS64_DUMP_TIMEOUT);
else
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 0cbf58f6ae5..6d257e0dd6a 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -1385,6 +1385,7 @@ struct ipr_ioa_cfg {
u8 needs_warm_reset:1;
u8 msi_received:1;
u8 sis64:1;
+ u8 dump_timeout:1;
u8 revid;