aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/mrsas/mrsas.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/mrsas/mrsas.c')
-rw-r--r--sys/dev/mrsas/mrsas.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/sys/dev/mrsas/mrsas.c b/sys/dev/mrsas/mrsas.c
index 1727434fc529..8b643d679f78 100644
--- a/sys/dev/mrsas/mrsas.c
+++ b/sys/dev/mrsas/mrsas.c
@@ -95,6 +95,8 @@ mrsas_get_pd_info(struct mrsas_softc *sc, u_int16_t device_id);
static struct mrsas_softc *
mrsas_get_softc_instance(struct cdev *dev,
u_long cmd, caddr_t arg);
+u_int32_t
+mrsas_read_reg_with_retries(struct mrsas_softc *sc, int offset);
u_int32_t mrsas_read_reg(struct mrsas_softc *sc, int offset);
u_int8_t
mrsas_build_mptmfi_passthru(struct mrsas_softc *sc,
@@ -272,6 +274,22 @@ mrsas_write(struct cdev *dev, struct uio *uio, int ioflag)
return (0);
}
+u_int32_t
+mrsas_read_reg_with_retries(struct mrsas_softc *sc, int offset)
+{
+ u_int32_t i = 0, ret_val;
+
+ if (sc->is_aero) {
+ do {
+ ret_val = mrsas_read_reg(sc, offset);
+ i++;
+ } while(ret_val == 0 && i < 3);
+ } else
+ ret_val = mrsas_read_reg(sc, offset);
+
+ return ret_val;
+}
+
/*
* Register Read/Write Functions
*
@@ -332,7 +350,7 @@ mrsas_clear_intr(struct mrsas_softc *sc)
u_int32_t status;
/* Read received interrupt */
- status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_intr_status));
+ status = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set, outbound_intr_status));
/* Not our interrupt, so just return */
if (!(status & MFI_FUSION_ENABLE_INTERRUPT_MASK))
@@ -2314,7 +2332,7 @@ mrsas_init_fw(struct mrsas_softc *sc)
return (ret);
}
if (sc->is_ventura || sc->is_aero) {
- scratch_pad_3 = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_scratch_pad_3));
+ scratch_pad_3 = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set, outbound_scratch_pad_3));
#if VD_EXT_DEBUG
device_printf(sc->mrsas_dev, "scratch_pad_3 0x%x\n", scratch_pad_3);
#endif
@@ -2325,10 +2343,10 @@ mrsas_init_fw(struct mrsas_softc *sc)
/* MSI-x index 0- reply post host index register */
sc->msix_reg_offset[0] = MPI2_REPLY_POST_HOST_INDEX_OFFSET;
/* Check if MSI-X is supported while in ready state */
- msix_enable = (mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_scratch_pad)) & 0x4000000) >> 0x1a;
+ msix_enable = (mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set, outbound_scratch_pad)) & 0x4000000) >> 0x1a;
if (msix_enable) {
- scratch_pad_2 = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ scratch_pad_2 = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
outbound_scratch_pad_2));
/* Check max MSI-X vectors */
@@ -2388,7 +2406,7 @@ mrsas_init_fw(struct mrsas_softc *sc)
}
if (sc->is_ventura || sc->is_aero) {
- scratch_pad_4 = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ scratch_pad_4 = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
outbound_scratch_pad_4));
if ((scratch_pad_4 & MR_NVME_PAGE_SIZE_MASK) >= MR_DEFAULT_NVME_PAGE_SHIFT)
sc->nvme_page_size = 1 << (scratch_pad_4 & MR_NVME_PAGE_SIZE_MASK);
@@ -2529,7 +2547,7 @@ mrsas_init_adapter(struct mrsas_softc *sc)
int i = 0;
/* Read FW status register */
- status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_scratch_pad));
+ status = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set, outbound_scratch_pad));
sc->max_fw_cmds = status & MRSAS_FWSTATE_MAXCMD_MASK;
@@ -2544,7 +2562,7 @@ mrsas_init_adapter(struct mrsas_softc *sc)
sc->reply_alloc_sz = sizeof(MPI2_REPLY_DESCRIPTORS_UNION) * (sc->reply_q_depth);
sc->io_frames_alloc_sz = MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE +
(MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * (sc->max_fw_cmds + 1));
- scratch_pad_2 = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ scratch_pad_2 = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
outbound_scratch_pad_2));
/*
* If scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK is set,
@@ -2682,7 +2700,7 @@ mrsas_ioc_init(struct mrsas_softc *sc)
}
if (!sc->block_sync_cache) {
- scratch_pad_2 = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ scratch_pad_2 = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
outbound_scratch_pad_2));
sc->fw_sync_cache_support = (scratch_pad_2 &
MR_CAN_HANDLE_SYNC_CACHE_OFFSET) ? 1 : 0;
@@ -2758,7 +2776,7 @@ mrsas_ioc_init(struct mrsas_softc *sc)
}
if (sc->is_aero) {
- scratch_pad_2 = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ scratch_pad_2 = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
outbound_scratch_pad_2));
sc->atomic_desc_support = (scratch_pad_2 &
MR_ATOMIC_DESCRIPTOR_SUPPORT_OFFSET) ? 1 : 0;
@@ -2920,7 +2938,7 @@ mrsas_transition_to_ready(struct mrsas_softc *sc, int ocr)
u_int32_t cur_state;
u_int32_t abs_state, curr_abs_state;
- val = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_scratch_pad));
+ val = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set, outbound_scratch_pad));
fw_state = val & MFI_STATE_MASK;
max_wait = MRSAS_RESET_WAIT_TIME;
@@ -2928,7 +2946,7 @@ mrsas_transition_to_ready(struct mrsas_softc *sc, int ocr)
device_printf(sc->mrsas_dev, "Waiting for FW to come to ready state\n");
while (fw_state != MFI_STATE_READY) {
- abs_state = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_scratch_pad));
+ abs_state = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set, outbound_scratch_pad));
switch (fw_state) {
case MFI_STATE_FAULT:
device_printf(sc->mrsas_dev, "FW is in FAULT state!!\n");
@@ -2956,7 +2974,7 @@ mrsas_transition_to_ready(struct mrsas_softc *sc, int ocr)
mrsas_disable_intr(sc);
mrsas_write_reg(sc, offsetof(mrsas_reg_set, doorbell), MFI_RESET_FLAGS);
for (i = 0; i < max_wait * 1000; i++) {
- if (mrsas_read_reg(sc, offsetof(mrsas_reg_set, doorbell)) & 1)
+ if (mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set, doorbell)) & 1)
DELAY(1000);
else
break;
@@ -2994,9 +3012,9 @@ mrsas_transition_to_ready(struct mrsas_softc *sc, int ocr)
* The cur_state should not last for more than max_wait secs
*/
for (i = 0; i < (max_wait * 1000); i++) {
- fw_state = (mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ fw_state = (mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
outbound_scratch_pad)) & MFI_STATE_MASK);
- curr_abs_state = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ curr_abs_state = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
outbound_scratch_pad));
if (abs_state == curr_abs_state)
DELAY(1000);
@@ -3071,7 +3089,7 @@ mrsas_ocr_thread(void *arg)
"Hardware critical error", __func__);
break;
}
- fw_status = mrsas_read_reg(sc,
+ fw_status = mrsas_read_reg_with_retries(sc,
offsetof(mrsas_reg_set, outbound_scratch_pad));
fw_state = fw_status & MFI_STATE_MASK;
if (fw_state == MFI_STATE_FAULT || sc->do_timedout_reset ||
@@ -3230,7 +3248,7 @@ mrsas_reset_ctrl(struct mrsas_softc *sc, u_int8_t reset_reason)
mtx_lock(&sc->sim_lock);
- status_reg = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ status_reg = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
outbound_scratch_pad));
abs_state = status_reg & MFI_STATE_MASK;
reset_adapter = status_reg & MFI_RESET_ADAPTER;
@@ -3260,12 +3278,12 @@ mrsas_reset_ctrl(struct mrsas_softc *sc, u_int8_t reset_reason)
MPI2_WRSEQ_6TH_KEY_VALUE);
/* Check that the diag write enable (DRWE) bit is on */
- host_diag = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ host_diag = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
fusion_host_diag));
retry = 0;
while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) {
DELAY(100 * 1000);
- host_diag = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ host_diag = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
fusion_host_diag));
if (retry++ == 100) {
mrsas_dprint(sc, MRSAS_OCR,
@@ -3282,12 +3300,12 @@ mrsas_reset_ctrl(struct mrsas_softc *sc, u_int8_t reset_reason)
DELAY(3000 * 1000);
/* Make sure reset adapter bit is cleared */
- host_diag = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ host_diag = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
fusion_host_diag));
retry = 0;
while (host_diag & HOST_DIAG_RESET_ADAPTER) {
DELAY(100 * 1000);
- host_diag = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ host_diag = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
fusion_host_diag));
if (retry++ == 1000) {
mrsas_dprint(sc, MRSAS_OCR,
@@ -3298,13 +3316,13 @@ mrsas_reset_ctrl(struct mrsas_softc *sc, u_int8_t reset_reason)
if (host_diag & HOST_DIAG_RESET_ADAPTER)
continue;
- abs_state = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ abs_state = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
outbound_scratch_pad)) & MFI_STATE_MASK;
retry = 0;
while ((abs_state <= MFI_STATE_FW_INIT) && (retry++ < 1000)) {
DELAY(100 * 1000);
- abs_state = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ abs_state = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
outbound_scratch_pad)) & MFI_STATE_MASK;
}
if (abs_state <= MFI_STATE_FW_INIT) {
@@ -3479,7 +3497,7 @@ mrsas_wait_for_outstanding(struct mrsas_softc *sc, u_int8_t check_reason)
goto out;
}
/* Check if firmware is in fault state */
- fw_state = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
+ fw_state = mrsas_read_reg_with_retries(sc, offsetof(mrsas_reg_set,
outbound_scratch_pad)) & MFI_STATE_MASK;
if (fw_state == MFI_STATE_FAULT) {
mrsas_dprint(sc, MRSAS_OCR,