aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ipr.c
diff options
context:
space:
mode:
authorBrian King <brking@linux.vnet.ibm.com>2011-09-21 09:51:11 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-09-22 07:30:28 -0400
commit41e9a69641fb3fa86fa9277a179f3ad261d072f7 (patch)
treecceabbe07245bf46b87278586a273f35a62b17bf /drivers/scsi/ipr.c
parent5f7a643304553e87f531df95de0ed0d60c002627 (diff)
[SCSI] ipr: Stop reading adapter dump prematurely
When the ipr driver decides to dump the adapter, it changes the sdt_state to GET_DUMP, then prepares the adapter so that the dump can be read. However, if the ipr worker thread wakes up for some reason before the driver has put the adapter in a state where it can succesfully dump the adapter, the driver will start dumping the adapter too early, which can potentially trigger a BUG check in the pci config blocking API. Fix this by adding a new sdt_state to differentiate between the ipr driver wanting to dump the adapter in the near future and wanting to dump the adapter now. Signed-off-by: Brian King <brking@linux.vnet.ibm.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r--drivers/scsi/ipr.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index acbb9241262d..f03963a972fc 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -2901,7 +2901,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump)
2901 2901
2902 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); 2902 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
2903 2903
2904 if (ioa_cfg->sdt_state != GET_DUMP) { 2904 if (ioa_cfg->sdt_state != READ_DUMP) {
2905 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 2905 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
2906 return; 2906 return;
2907 } 2907 }
@@ -3097,7 +3097,7 @@ static void ipr_worker_thread(struct work_struct *work)
3097 ENTER; 3097 ENTER;
3098 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); 3098 spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
3099 3099
3100 if (ioa_cfg->sdt_state == GET_DUMP) { 3100 if (ioa_cfg->sdt_state == READ_DUMP) {
3101 dump = ioa_cfg->dump; 3101 dump = ioa_cfg->dump;
3102 if (!dump) { 3102 if (!dump) {
3103 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); 3103 spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -7449,6 +7449,8 @@ static int ipr_reset_wait_for_dump(struct ipr_cmnd *ipr_cmd)
7449 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; 7449 struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
7450 7450
7451 if (ioa_cfg->sdt_state == GET_DUMP) 7451 if (ioa_cfg->sdt_state == GET_DUMP)
7452 ioa_cfg->sdt_state = WAIT_FOR_DUMP;
7453 else if (ioa_cfg->sdt_state == READ_DUMP)
7452 ioa_cfg->sdt_state = ABORT_DUMP; 7454 ioa_cfg->sdt_state = ABORT_DUMP;
7453 7455
7454 ipr_cmd->job_step = ipr_reset_alert; 7456 ipr_cmd->job_step = ipr_reset_alert;
@@ -7614,6 +7616,7 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
7614 ipr_cmd->job_step = ipr_reset_enable_ioa; 7616 ipr_cmd->job_step = ipr_reset_enable_ioa;
7615 7617
7616 if (GET_DUMP == ioa_cfg->sdt_state) { 7618 if (GET_DUMP == ioa_cfg->sdt_state) {
7619 ioa_cfg->sdt_state = READ_DUMP;
7617 if (ioa_cfg->sis64) 7620 if (ioa_cfg->sis64)
7618 ipr_reset_start_timer(ipr_cmd, IPR_SIS64_DUMP_TIMEOUT); 7621 ipr_reset_start_timer(ipr_cmd, IPR_SIS64_DUMP_TIMEOUT);
7619 else 7622 else
@@ -8003,8 +8006,12 @@ static void ipr_initiate_ioa_reset(struct ipr_ioa_cfg *ioa_cfg,
8003 if (ioa_cfg->ioa_is_dead) 8006 if (ioa_cfg->ioa_is_dead)
8004 return; 8007 return;
8005 8008
8006 if (ioa_cfg->in_reset_reload && ioa_cfg->sdt_state == GET_DUMP) 8009 if (ioa_cfg->in_reset_reload) {
8007 ioa_cfg->sdt_state = ABORT_DUMP; 8010 if (ioa_cfg->sdt_state == GET_DUMP)
8011 ioa_cfg->sdt_state = WAIT_FOR_DUMP;
8012 else if (ioa_cfg->sdt_state == READ_DUMP)
8013 ioa_cfg->sdt_state = ABORT_DUMP;
8014 }
8008 8015
8009 if (ioa_cfg->reset_retries++ >= IPR_NUM_RESET_RELOAD_RETRIES) { 8016 if (ioa_cfg->reset_retries++ >= IPR_NUM_RESET_RELOAD_RETRIES) {
8010 dev_err(&ioa_cfg->pdev->dev, 8017 dev_err(&ioa_cfg->pdev->dev,