From 110def851fc823bb1a4584cb6308e30e5ffb3e05 Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Thu, 4 Nov 2010 09:36:16 -0700 Subject: [PATCH] [SCSI] ipr: fix mailbox register definition and add a delay before reading The definition for the mailbox register for new adapters was incorrect. The value has been updated to the correct offset. After an adapter reset, the mailbox register on the new adapters takes a number of seconds to stabilize. A delay has been added before reading the register. Signed-off-by: Wayne Boyer Acked-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/ipr.c | 47 ++++++++++++++++++++++++++++++++++++++++------ drivers/scsi/ipr.h | 2 ++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 04c1cea89dbe..de2e09e49a3e 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -146,7 +146,7 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { } }, { /* CRoC */ - .mailbox = 0x00040, + .mailbox = 0x00044, .cache_line_size = 0x20, { .set_interrupt_mask_reg = 0x00010, @@ -2900,6 +2900,12 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) return; } + if (ioa_cfg->sis64) { + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + ssleep(IPR_DUMP_DELAY_SECONDS); + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + } + start_addr = readl(ioa_cfg->ioa_mailbox); if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(start_addr)) { @@ -7471,6 +7477,29 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg) list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q); } +/** + * ipr_reset_get_unit_check_job - Call to get the unit check buffer. + * @ipr_cmd: ipr command struct + * + * Description: This function will call to get the unit check buffer. + * + * Return value: + * IPR_RC_JOB_RETURN + **/ +static int ipr_reset_get_unit_check_job(struct ipr_cmnd *ipr_cmd) +{ + struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; + + ENTER; + ioa_cfg->ioa_unit_checked = 0; + ipr_get_unit_check_buffer(ioa_cfg); + ipr_cmd->job_step = ipr_reset_alert; + ipr_reset_start_timer(ipr_cmd, 0); + + LEAVE; + return IPR_RC_JOB_RETURN; +} + /** * ipr_reset_restore_cfg_space - Restore PCI config space. * @ipr_cmd: ipr command struct @@ -7511,11 +7540,17 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) } if (ioa_cfg->ioa_unit_checked) { - ioa_cfg->ioa_unit_checked = 0; - ipr_get_unit_check_buffer(ioa_cfg); - ipr_cmd->job_step = ipr_reset_alert; - ipr_reset_start_timer(ipr_cmd, 0); - return IPR_RC_JOB_RETURN; + if (ioa_cfg->sis64) { + ipr_cmd->job_step = ipr_reset_get_unit_check_job; + ipr_reset_start_timer(ipr_cmd, IPR_DUMP_DELAY_TIMEOUT); + return IPR_RC_JOB_RETURN; + } else { + ioa_cfg->ioa_unit_checked = 0; + ipr_get_unit_check_buffer(ioa_cfg); + ipr_cmd->job_step = ipr_reset_alert; + ipr_reset_start_timer(ipr_cmd, 0); + return IPR_RC_JOB_RETURN; + } } if (ioa_cfg->in_ioa_bringdown) { diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index b28a00f1082c..13f425fb8851 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -218,6 +218,8 @@ #define IPR_WAIT_FOR_BIST_TIMEOUT (2 * HZ) #define IPR_PCI_RESET_TIMEOUT (HZ / 2) #define IPR_DUMP_TIMEOUT (15 * HZ) +#define IPR_DUMP_DELAY_SECONDS 4 +#define IPR_DUMP_DELAY_TIMEOUT (IPR_DUMP_DELAY_SECONDS * HZ) /* * SCSI Literals -- 2.39.5