aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorChandrakanth patil <chandrakanth.patil@broadcom.com>2025-04-27 23:35:23 +0000
committerWarner Losh <imp@FreeBSD.org>2025-04-28 03:22:55 +0000
commit116c8b18a2b5278df0d1982a683193c3dba6f30c (patch)
tree59dcc4b87af9dc73110df6e214bd2ed9aeb1c0c5 /sys
parente977ed50bb2b9fce5e285756673286c5fcfb1f31 (diff)
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/mpi3mr/mpi3mr.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/sys/dev/mpi3mr/mpi3mr.c b/sys/dev/mpi3mr/mpi3mr.c
index 5688d6bb8d25..c92d05d972de 100644
--- a/sys/dev/mpi3mr/mpi3mr.c
+++ b/sys/dev/mpi3mr/mpi3mr.c
@@ -2784,18 +2784,37 @@ retry_init:
}
if (ioc_state != MRIOC_STATE_RESET) {
- mpi3mr_print_fault_info(sc);
- mpi3mr_dprint(sc, MPI3MR_ERROR, "issuing soft reset to bring to reset state\n");
- retval = mpi3mr_issue_reset(sc,
- MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET,
- MPI3MR_RESET_FROM_BRINGUP);
- if (retval) {
- mpi3mr_dprint(sc, MPI3MR_ERROR,
- "%s :Failed to soft reset IOC, error 0x%d\n",
- __func__, retval);
+ if (ioc_state == MRIOC_STATE_FAULT) {
+ mpi3mr_print_fault_info(sc);
+
+ U32 fault = mpi3mr_regread(sc, MPI3_SYSIF_FAULT_OFFSET) &
+ MPI3_SYSIF_FAULT_CODE_MASK;
+ if (fault == MPI3_SYSIF_FAULT_CODE_INSUFFICIENT_PCI_SLOT_POWER)
+ mpi3mr_dprint(sc, MPI3MR_INFO,
+ "controller faulted due to insufficient power. "
+ "try by connecting it in a different slot\n");
+ goto err;
+
+ U32 host_diagnostic;
+ timeout = MPI3_SYSIF_DIAG_SAVE_TIMEOUT * 10;
+ do {
+ host_diagnostic = mpi3mr_regread(sc, MPI3_SYSIF_HOST_DIAG_OFFSET);
+ if (!(host_diagnostic & MPI3_SYSIF_HOST_DIAG_SAVE_IN_PROGRESS))
+ break;
+ DELAY(100 * 1000);
+ } while (--timeout);
+ }
+ mpi3mr_dprint(sc, MPI3MR_ERROR, "issuing soft reset to bring to reset state\n");
+ retval = mpi3mr_issue_reset(sc,
+ MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET,
+ MPI3MR_RESET_FROM_BRINGUP);
+ if (retval) {
+ mpi3mr_dprint(sc, MPI3MR_ERROR,
+ "%s :Failed to soft reset IOC, error 0x%d\n",
+ __func__, retval);
goto err_retry;
- }
- }
+ }
+ }
ioc_state = mpi3mr_get_iocstate(sc);
@@ -3165,6 +3184,15 @@ mpi3mr_watchdog_thread(void *arg)
sc->unrecoverable = 1;
break;
}
+
+ if (fault == MPI3_SYSIF_FAULT_CODE_INSUFFICIENT_PCI_SLOT_POWER) {
+ mpi3mr_dprint(sc, MPI3MR_INFO,
+ "controller faulted due to insufficient power, marking"
+ " controller as unrecoverable\n");
+ sc->unrecoverable = 1;
+ break;
+ }
+
if ((fault == MPI3_SYSIF_FAULT_CODE_DIAG_FAULT_RESET)
|| (fault == MPI3_SYSIF_FAULT_CODE_SOFT_RESET_IN_PROGRESS)
|| (sc->reset_in_progress))