git: 116c8b18a2b5 - main - mpi3mr: Handle Insufficient Power Fault Code
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 28 Apr 2025 03:25:21 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=116c8b18a2b5278df0d1982a683193c3dba6f30c
commit 116c8b18a2b5278df0d1982a683193c3dba6f30c
Author: Chandrakanth patil <chandrakanth.patil@broadcom.com>
AuthorDate: 2025-04-27 23:35:23 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2025-04-28 03:22:55 +0000
mpi3mr: Handle Insufficient Power Fault Code
The driver now checks for insufficient power faults during the load
phase and immediately fails initialization instead of retrying.
Additionally, if an insufficient power fault is detected by the watchdog
after the controller is up, the controller is marked as unrecoverable
instead of triggering a reset.
This improves fault handling and avoids unnecessary recovery attempts
in low-power conditions.
Reviewed by: ssaxena, imp
Differential Revision: https://reviews.freebsd.org/D49747
---
sys/dev/mpi3mr/mpi3mr.c | 50 ++++++++++++++++++++++++++++++++++++++-----------
1 file 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))