diff options
author | Brian King <brking@linux.vnet.ibm.com> | 2011-09-21 09:51:11 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-09-22 07:30:28 -0400 |
commit | 41e9a69641fb3fa86fa9277a179f3ad261d072f7 (patch) | |
tree | cceabbe07245bf46b87278586a273f35a62b17bf /drivers | |
parent | 5f7a643304553e87f531df95de0ed0d60c002627 (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')
-rw-r--r-- | drivers/scsi/ipr.c | 15 | ||||
-rw-r--r-- | drivers/scsi/ipr.h | 1 |
2 files changed, 12 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, |
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index f93f8637c5a1..f9766f84d91c 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h | |||
@@ -1360,6 +1360,7 @@ enum ipr_sdt_state { | |||
1360 | INACTIVE, | 1360 | INACTIVE, |
1361 | WAIT_FOR_DUMP, | 1361 | WAIT_FOR_DUMP, |
1362 | GET_DUMP, | 1362 | GET_DUMP, |
1363 | READ_DUMP, | ||
1363 | ABORT_DUMP, | 1364 | ABORT_DUMP, |
1364 | DUMP_OBTAINED | 1365 | DUMP_OBTAINED |
1365 | }; | 1366 | }; |