git: 14283d89e4a9 - stable/14 - mpi3mr: Adding FreeBSD OS Type to Fault/Reset Reason Code

From: Warner Losh <imp_at_FreeBSD.org>
Date: Wed, 30 Apr 2025 17:21:41 UTC
The branch stable/14 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=14283d89e4a99237384df7227929a3c393216931

commit 14283d89e4a99237384df7227929a3c393216931
Author:     Chandrakanth patil <chandrakanth.patil@broadcom.com>
AuthorDate: 2024-03-19 06:56:44 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2025-04-30 17:05:51 +0000

    mpi3mr: Adding FreeBSD OS Type to Fault/Reset Reason Code
    
    The driver is modified to add FreeBSD OS type in the upper nibble of the
    fault/reset reason code for appropriate qualification of the reason code.
    
    Reviewed by:            imp
    Approved by:            imp
    Differential revision:  https://reviews.freebsd.org/D44427
    
    (cherry picked from commit 3012fa8faef262c615672fc90319c777b4e3dffc)
---
 sys/dev/mpi3mr/mpi3mr.c     | 29 +++++++++++++++++++----------
 sys/dev/mpi3mr/mpi3mr.h     |  7 +++++--
 sys/dev/mpi3mr/mpi3mr_cam.c |  2 +-
 3 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/sys/dev/mpi3mr/mpi3mr.c b/sys/dev/mpi3mr/mpi3mr.c
index f90fcff69f85..f88e467510a0 100644
--- a/sys/dev/mpi3mr/mpi3mr.c
+++ b/sys/dev/mpi3mr/mpi3mr.c
@@ -84,7 +84,7 @@ static void mpi3mr_port_enable_complete(struct mpi3mr_softc *sc,
 	struct mpi3mr_drvr_cmd *drvrcmd);
 static void mpi3mr_flush_io(struct mpi3mr_softc *sc);
 static int mpi3mr_issue_reset(struct mpi3mr_softc *sc, U16 reset_type,
-	U32 reset_reason);
+	U16 reset_reason);
 static void mpi3mr_dev_rmhs_send_tm(struct mpi3mr_softc *sc, U16 handle,
 	struct mpi3mr_drvr_cmd *cmdparam, U8 iou_rc);
 static void mpi3mr_dev_rmhs_complete_iou(struct mpi3mr_softc *sc,
@@ -187,7 +187,7 @@ poll_for_command_completion(struct mpi3mr_softc *sc,
  * Return:  None.
  */
 static void
-mpi3mr_trigger_snapdump(struct mpi3mr_softc *sc, U32 reason_code)
+mpi3mr_trigger_snapdump(struct mpi3mr_softc *sc, U16 reason_code)
 {
 	U32 host_diagnostic, timeout = MPI3_SYSIF_DIAG_SAVE_TIMEOUT * 10;
 	
@@ -222,7 +222,7 @@ mpi3mr_trigger_snapdump(struct mpi3mr_softc *sc, U32 reason_code)
  *
  * Return:  None.
  */
-static void mpi3mr_check_rh_fault_ioc(struct mpi3mr_softc *sc, U32 reason_code)
+static void mpi3mr_check_rh_fault_ioc(struct mpi3mr_softc *sc, U16 reason_code)
 {
 	U32 ioc_status;
 
@@ -1168,9 +1168,9 @@ static inline void mpi3mr_clear_resethistory(struct mpi3mr_softc *sc)
  *
  * Return: 0 on success, -1 on failure.
  */
-static int mpi3mr_mur_ioc(struct mpi3mr_softc *sc, U32 reset_reason)
+static int mpi3mr_mur_ioc(struct mpi3mr_softc *sc, U16 reset_reason)
 {
-        U32 ioc_config, timeout, ioc_status;
+	U32 ioc_config, timeout, ioc_status, scratch_pad0;
         int retval = -1;
 
         mpi3mr_dprint(sc, MPI3MR_INFO, "Issuing Message Unit Reset(MUR)\n");
@@ -1179,7 +1179,12 @@ static int mpi3mr_mur_ioc(struct mpi3mr_softc *sc, U32 reset_reason)
                 return retval;
         }
         mpi3mr_clear_resethistory(sc);
-	mpi3mr_regwrite(sc, MPI3_SYSIF_SCRATCHPAD0_OFFSET, reset_reason);
+
+	scratch_pad0 = ((MPI3MR_RESET_REASON_OSTYPE_FREEBSD <<
+			MPI3MR_RESET_REASON_OSTYPE_SHIFT) |
+			(sc->facts.ioc_num <<
+			MPI3MR_RESET_REASON_IOCNUM_SHIFT) | reset_reason);
+	mpi3mr_regwrite(sc, MPI3_SYSIF_SCRATCHPAD0_OFFSET, scratch_pad0);
 	ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET);
         ioc_config &= ~MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC;
 	mpi3mr_regwrite(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET, ioc_config);
@@ -5762,11 +5767,11 @@ static inline void mpi3mr_set_diagsave(struct mpi3mr_softc *sc)
  * Return: 0 on success, non-zero on failure.
  */
 static int mpi3mr_issue_reset(struct mpi3mr_softc *sc, U16 reset_type,
-	U32 reset_reason)
+	U16 reset_reason)
 {
 	int retval = -1;
 	U8 unlock_retry_count = 0;
-	U32 host_diagnostic, ioc_status, ioc_config;
+	U32 host_diagnostic, ioc_status, ioc_config, scratch_pad0;
 	U32 timeout = MPI3MR_RESET_ACK_TIMEOUT * 10;
 
 	if ((reset_type != MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET) &&
@@ -5820,7 +5825,11 @@ static int mpi3mr_issue_reset(struct mpi3mr_softc *sc, U16 reset_type,
 		    unlock_retry_count, host_diagnostic);
 	} while (!(host_diagnostic & MPI3_SYSIF_HOST_DIAG_DIAG_WRITE_ENABLE));
 
-	mpi3mr_regwrite(sc, MPI3_SYSIF_SCRATCHPAD0_OFFSET, reset_reason);
+	scratch_pad0 = ((MPI3MR_RESET_REASON_OSTYPE_FREEBSD <<
+			MPI3MR_RESET_REASON_OSTYPE_SHIFT) |
+			(sc->facts.ioc_num <<
+			MPI3MR_RESET_REASON_IOCNUM_SHIFT) | reset_reason);
+	mpi3mr_regwrite(sc, MPI3_SYSIF_SCRATCHPAD0_OFFSET, scratch_pad0);
 	mpi3mr_regwrite(sc, MPI3_SYSIF_HOST_DIAG_OFFSET, host_diagnostic | reset_type);
 	
 	if (reset_type == MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET) {
@@ -5899,7 +5908,7 @@ inline void mpi3mr_cleanup_event_taskq(struct mpi3mr_softc *sc)
  * Return: 0 on success, non-zero on failure.
  */
 int mpi3mr_soft_reset_handler(struct mpi3mr_softc *sc,
-	U32 reset_reason, bool snapdump)
+	U16 reset_reason, bool snapdump)
 {
 	int retval = 0, i = 0;
 	enum mpi3mr_iocstate ioc_state;
diff --git a/sys/dev/mpi3mr/mpi3mr.h b/sys/dev/mpi3mr/mpi3mr.h
index 6838e7fe616a..59d4c64be3cb 100644
--- a/sys/dev/mpi3mr/mpi3mr.h
+++ b/sys/dev/mpi3mr/mpi3mr.h
@@ -142,6 +142,9 @@
 #define MAX_MGMT_ADAPTERS 8
 #define MPI3MR_WAIT_BEFORE_CTRL_RESET 5
 
+#define MPI3MR_RESET_REASON_OSTYPE_FREEBSD        0x4
+#define MPI3MR_RESET_REASON_OSTYPE_SHIFT	  28
+#define MPI3MR_RESET_REASON_IOCNUM_SHIFT          20
 
 struct mpi3mr_mgmt_info {
 	uint16_t count;
@@ -962,7 +965,7 @@ void mpi3mr_cleanup_event_taskq(struct mpi3mr_softc *sc);
 void
 mpi3mr_hexdump(void *buf, int sz, int format);
 int mpi3mr_soft_reset_handler(struct mpi3mr_softc *sc,
-	U32 reset_reason, bool snapdump);
+	U16 reset_reason, bool snapdump);
 void
 mpi3mrsas_release_simq_reinit(struct mpi3mr_cam_softc *cam_sc);
 void
@@ -984,6 +987,6 @@ void mpi3mr_set_io_divert_for_all_vd_in_tg(struct mpi3mr_softc *sc,
 enum mpi3mr_iocstate mpi3mr_get_iocstate(struct mpi3mr_softc *sc);
 void mpi3mr_poll_pend_io_completions(struct mpi3mr_softc *sc);
 void int_to_lun(unsigned int lun, U8 *req_lun);
-void trigger_reset_from_watchdog(struct mpi3mr_softc *sc, U8 reset_type, U32 reset_reason);
+void trigger_reset_from_watchdog(struct mpi3mr_softc *sc, U8 reset_type, U16 reset_reason);
 void mpi3mr_alloc_ioctl_dma_memory(struct mpi3mr_softc *sc);
 #endif /*MPI3MR_H_INCLUDED*/
diff --git a/sys/dev/mpi3mr/mpi3mr_cam.c b/sys/dev/mpi3mr/mpi3mr_cam.c
index c4e08b399712..7a29ec592339 100644
--- a/sys/dev/mpi3mr/mpi3mr_cam.c
+++ b/sys/dev/mpi3mr/mpi3mr_cam.c
@@ -455,7 +455,7 @@ void mpi3mr_poll_pend_io_completions(struct mpi3mr_softc *sc)
 }
 
 void
-trigger_reset_from_watchdog(struct mpi3mr_softc *sc, U8 reset_type, U32 reset_reason)
+trigger_reset_from_watchdog(struct mpi3mr_softc *sc, U8 reset_type, U16 reset_reason)
 {
 	if (sc->reset_in_progress) {
 		mpi3mr_dprint(sc, MPI3MR_INFO, "Another reset is in progress, no need to trigger the reset\n");