Linux SCSI subsystem development
 help / color / mirror / Atom feed
* [PATCH v1 0/7] mpi3mr: Enhancements for mpi3mr
@ 2026-01-12  8:10 Ranjan Kumar
  2026-01-12  8:10 ` [PATCH v1 1/7] mpi3mr: Add module parameter to control threaded IRQ polling Ranjan Kumar
                   ` (6 more replies)
  0 siblings, 7 replies; 20+ messages in thread
From: Ranjan Kumar @ 2026-01-12  8:10 UTC (permalink / raw)
  To: linux-scsi, martin.petersen
  Cc: rajsekhar.chundru, sathya.prakash, chandrakanth.patil,
	prayas.patel, salomondush, Ranjan Kumar

Enhancements for mpi3mr driver

Ranjan Kumar (7):
  mpi3mr: Add module parameter to control threaded IRQ polling
  mpi3mr: Rename log data save helper to reflect threaded/BH context
  mpi3mr: Avoid redundant diag-fault resets
  mpi3mr: Use negotiated link rate from DevicePage0
  mpi3mr: Update MPI Headers to revision 39
  mpi3mr: Record and report controller firmware faults
  mpi3mr: Driver version update to 8.17.0.3.50

 drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h      |  92 +++++++++++++++++-
 drivers/scsi/mpi3mr/mpi/mpi30_image.h     | 102 +++++++++++++++++++-
 drivers/scsi/mpi3mr/mpi/mpi30_init.h      |   2 +-
 drivers/scsi/mpi3mr/mpi/mpi30_ioc.h       |   9 +-
 drivers/scsi/mpi3mr/mpi/mpi30_pci.h       |   2 +-
 drivers/scsi/mpi3mr/mpi/mpi30_sas.h       |   2 +-
 drivers/scsi/mpi3mr/mpi/mpi30_tool.h      |   6 +-
 drivers/scsi/mpi3mr/mpi/mpi30_transport.h |   4 +-
 drivers/scsi/mpi3mr/mpi3mr.h              |  16 +++-
 drivers/scsi/mpi3mr/mpi3mr_app.c          |  28 +++++-
 drivers/scsi/mpi3mr/mpi3mr_fw.c           | 109 +++++++++++++++++++++-
 drivers/scsi/mpi3mr/mpi3mr_os.c           |  96 ++++++++++++++++++-
 drivers/scsi/mpi3mr/mpi3mr_transport.c    |  30 +++---
 13 files changed, 459 insertions(+), 39 deletions(-)

-- 
2.47.3


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v1 1/7] mpi3mr: Add module parameter to control threaded IRQ polling
  2026-01-12  8:10 [PATCH v1 0/7] mpi3mr: Enhancements for mpi3mr Ranjan Kumar
@ 2026-01-12  8:10 ` Ranjan Kumar
  2026-01-12 14:14   ` Damien Le Moal
  2026-01-12  8:10 ` [PATCH v1 2/7] mpi3mr: Rename log data save helper to reflect threaded/BH context Ranjan Kumar
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Ranjan Kumar @ 2026-01-12  8:10 UTC (permalink / raw)
  To: linux-scsi, martin.petersen
  Cc: rajsekhar.chundru, sathya.prakash, chandrakanth.patil,
	prayas.patel, salomondush, Ranjan Kumar

Add a module parameter to enable or disable threaded IRQ polling
in the driver. The default behavior remains unchanged
with polling enabled.

When disabled, completion processing is kept entirely in the
hard IRQ context, avoiding the threaded polling path.

Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
---
 drivers/scsi/mpi3mr/mpi3mr_fw.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index 8fe6e0bf342e..869e525f3e73 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -21,6 +21,10 @@ static int mpi3mr_check_op_admin_proc(struct mpi3mr_ioc *mrioc);
 static int poll_queues;
 module_param(poll_queues, int, 0444);
 MODULE_PARM_DESC(poll_queues, "Number of queues for io_uring poll mode. (Range 1 - 126)");
+static bool threaded_isr_poll = true;
+module_param(threaded_isr_poll, bool, 0444);
+MODULE_PARM_DESC(threaded_isr_poll,
+			"Enablement of IRQ polling thread (default=true)");
 
 #if defined(writeq) && defined(CONFIG_64BIT)
 static inline void mpi3mr_writeq(__u64 b, void __iomem *addr,
@@ -595,7 +599,8 @@ int mpi3mr_process_op_reply_q(struct mpi3mr_ioc *mrioc,
 		 * Exit completion loop to avoid CPU lockup
 		 * Ensure remaining completion happens from threaded ISR.
 		 */
-		if (num_op_reply > mrioc->max_host_ios) {
+		if ((num_op_reply > mrioc->max_host_ios) &&
+			(threaded_isr_poll == true)) {
 			op_reply_q->enable_irq_poll = true;
 			break;
 		}
@@ -692,7 +697,7 @@ static irqreturn_t mpi3mr_isr(int irq, void *privdata)
 	 * If more IOs are expected, schedule IRQ polling thread.
 	 * Otherwise exit from ISR.
 	 */
-	if (!intr_info->op_reply_q)
+	if ((threaded_isr_poll == false) || !intr_info->op_reply_q)
 		return ret;
 
 	if (!intr_info->op_reply_q->enable_irq_poll ||
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1 2/7] mpi3mr: Rename log data save helper to reflect threaded/BH context
  2026-01-12  8:10 [PATCH v1 0/7] mpi3mr: Enhancements for mpi3mr Ranjan Kumar
  2026-01-12  8:10 ` [PATCH v1 1/7] mpi3mr: Add module parameter to control threaded IRQ polling Ranjan Kumar
@ 2026-01-12  8:10 ` Ranjan Kumar
  2026-01-12 14:13   ` Damien Le Moal
  2026-01-12  8:10 ` [PATCH v1 3/7] mpi3mr: Avoid redundant diag-fault resets Ranjan Kumar
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Ranjan Kumar @ 2026-01-12  8:10 UTC (permalink / raw)
  To: linux-scsi, martin.petersen
  Cc: rajsekhar.chundru, sathya.prakash, chandrakanth.patil,
	prayas.patel, salomondush, Ranjan Kumar

Log data events can be processed from BH and threaded contexts.
Rename the save helper to document its intended usage and improve
readability of the event handling flow.

Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
---
 drivers/scsi/mpi3mr/mpi3mr.h     | 2 +-
 drivers/scsi/mpi3mr/mpi3mr_app.c | 4 ++--
 drivers/scsi/mpi3mr/mpi3mr_os.c  | 8 +++++++-
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
index 31d68c151b20..611a51a353c9 100644
--- a/drivers/scsi/mpi3mr/mpi3mr.h
+++ b/drivers/scsi/mpi3mr/mpi3mr.h
@@ -1508,7 +1508,7 @@ void mpi3mr_pel_get_seqnum_complete(struct mpi3mr_ioc *mrioc,
 	struct mpi3mr_drv_cmd *drv_cmd);
 int mpi3mr_pel_get_seqnum_post(struct mpi3mr_ioc *mrioc,
 	struct mpi3mr_drv_cmd *drv_cmd);
-void mpi3mr_app_save_logdata(struct mpi3mr_ioc *mrioc, char *event_data,
+void mpi3mr_app_save_logdata_th(struct mpi3mr_ioc *mrioc, char *event_data,
 	u16 event_data_size);
 struct mpi3mr_enclosure_node *mpi3mr_enclosure_find_by_handle(
 	struct mpi3mr_ioc *mrioc, u16 handle);
diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
index 0e5478d62580..37cca0573ddc 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_app.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
@@ -2920,7 +2920,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
 }
 
 /**
- * mpi3mr_app_save_logdata - Save Log Data events
+ * mpi3mr_app_save_logdata_th - Save Log Data events
  * @mrioc: Adapter instance reference
  * @event_data: event data associated with log data event
  * @event_data_size: event data size to copy
@@ -2932,7 +2932,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
  *
  * Return:Nothing
  */
-void mpi3mr_app_save_logdata(struct mpi3mr_ioc *mrioc, char *event_data,
+void mpi3mr_app_save_logdata_th(struct mpi3mr_ioc *mrioc, char *event_data,
 	u16 event_data_size)
 {
 	u32 index = mrioc->logdata_buf_idx, sz;
diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
index d4ca878d0886..4dbf2f337212 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
@@ -1962,7 +1962,7 @@ static void mpi3mr_pcietopochg_evt_bh(struct mpi3mr_ioc *mrioc,
 static void mpi3mr_logdata_evt_bh(struct mpi3mr_ioc *mrioc,
 	struct mpi3mr_fwevt *fwevt)
 {
-	mpi3mr_app_save_logdata(mrioc, fwevt->event_data,
+	mpi3mr_app_save_logdata_th(mrioc, fwevt->event_data,
 	    fwevt->event_data_size);
 }
 
@@ -3058,6 +3058,12 @@ void mpi3mr_os_handle_events(struct mpi3mr_ioc *mrioc,
 	}
 	case MPI3_EVENT_DEVICE_INFO_CHANGED:
 	case MPI3_EVENT_LOG_DATA:
+	{
+		sz = event_reply->event_data_length * 4;
+		mpi3mr_app_save_logdata_th(mrioc,
+		    (char *)event_reply->event_data, sz);
+		break;
+	}
 	case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE:
 	case MPI3_EVENT_ENCL_DEVICE_ADDED:
 	{
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1 3/7] mpi3mr: Avoid redundant diag-fault resets
  2026-01-12  8:10 [PATCH v1 0/7] mpi3mr: Enhancements for mpi3mr Ranjan Kumar
  2026-01-12  8:10 ` [PATCH v1 1/7] mpi3mr: Add module parameter to control threaded IRQ polling Ranjan Kumar
  2026-01-12  8:10 ` [PATCH v1 2/7] mpi3mr: Rename log data save helper to reflect threaded/BH context Ranjan Kumar
@ 2026-01-12  8:10 ` Ranjan Kumar
  2026-01-12  8:10 ` [PATCH v1 4/7] mpi3mr: Use negotiated link rate from DevicePage0 Ranjan Kumar
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 20+ messages in thread
From: Ranjan Kumar @ 2026-01-12  8:10 UTC (permalink / raw)
  To: linux-scsi, martin.petersen
  Cc: rajsekhar.chundru, sathya.prakash, chandrakanth.patil,
	prayas.patel, salomondush, Ranjan Kumar

Update reset handling to invoke diag-save only for diag-fault resets.
Skip issuing a diagnostic reset if the IOC is already in FAULT state,
preventing repeated fault handling and improving reset stability.

Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
---
 drivers/scsi/mpi3mr/mpi3mr_fw.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index 869e525f3e73..178738850541 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -1707,6 +1707,8 @@ static int mpi3mr_issue_reset(struct mpi3mr_ioc *mrioc, u16 reset_type,
 	    MPI3MR_RESET_REASON_OSTYPE_SHIFT) | (mrioc->facts.ioc_num <<
 	    MPI3MR_RESET_REASON_IOCNUM_SHIFT) | reset_reason);
 	writel(reset_reason, &mrioc->sysif_regs->scratchpad[0]);
+	if (reset_type == MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT)
+		mpi3mr_set_diagsave(mrioc);
 	writel(host_diagnostic | reset_type,
 	    &mrioc->sysif_regs->host_diagnostic);
 	switch (reset_type) {
@@ -5404,6 +5406,7 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
 {
 	int retval = 0, i;
 	unsigned long flags;
+	enum mpi3mr_iocstate ioc_state;
 	u32 host_diagnostic, timeout = MPI3_SYSIF_DIAG_SAVE_TIMEOUT * 10;
 	union mpi3mr_trigger_data trigger_data;
 
@@ -5462,7 +5465,6 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
 	mrioc->io_admin_reset_sync = 1;
 
 	if (snapdump) {
-		mpi3mr_set_diagsave(mrioc);
 		retval = mpi3mr_issue_reset(mrioc,
 		    MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT, reset_reason);
 		if (!retval) {
@@ -5564,8 +5566,13 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
 		if (mrioc->pel_enabled)
 			atomic64_inc(&event_counter);
 	} else {
-		mpi3mr_issue_reset(mrioc,
-		    MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT, reset_reason);
+		dprint_reset(mrioc,
+			"soft_reset_handler failed, marking controller as unrecoverable\n");
+		ioc_state = mpi3mr_get_iocstate(mrioc);
+
+		if (ioc_state != MRIOC_STATE_FAULT)
+			mpi3mr_issue_reset(mrioc,
+				MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT, reset_reason);
 		mrioc->device_refresh_on = 0;
 		mrioc->unrecoverable = 1;
 		mrioc->reset_in_progress = 0;
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1 4/7] mpi3mr: Use negotiated link rate from DevicePage0
  2026-01-12  8:10 [PATCH v1 0/7] mpi3mr: Enhancements for mpi3mr Ranjan Kumar
                   ` (2 preceding siblings ...)
  2026-01-12  8:10 ` [PATCH v1 3/7] mpi3mr: Avoid redundant diag-fault resets Ranjan Kumar
@ 2026-01-12  8:10 ` Ranjan Kumar
  2026-01-12 14:18   ` Damien Le Moal
  2026-01-12 16:38   ` kernel test robot
  2026-01-12  8:10 ` [PATCH v1 5/7] mpi3mr: Update MPI Headers to revision 39 Ranjan Kumar
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 20+ messages in thread
From: Ranjan Kumar @ 2026-01-12  8:10 UTC (permalink / raw)
  To: linux-scsi, martin.petersen
  Cc: rajsekhar.chundru, sathya.prakash, chandrakanth.patil,
	prayas.patel, salomondush, Ranjan Kumar

Firmware populates the negotiated SAS link rate in DevicePage0
during device discovery. Update mpi3mr to cache this value while
initializing the target device.

When available, the cached link rate is used instead of issuing
additional SAS PHY or expander PHY page reads.
If the DevicePage0 value is missing or invalid, the driver
falls back to the existing PHY-based mechanism.

Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
---
 drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h   |  2 +
 drivers/scsi/mpi3mr/mpi3mr.h           |  2 +
 drivers/scsi/mpi3mr/mpi3mr_os.c        | 88 ++++++++++++++++++++++++++
 drivers/scsi/mpi3mr/mpi3mr_transport.c | 30 +++++----
 4 files changed, 110 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
index 8c8bfbbdd34e..67d72b82cbe0 100644
--- a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
+++ b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
@@ -2314,6 +2314,8 @@ struct mpi3_device0_sas_sata_format {
 	u8         attached_phy_identifier;
 	u8         max_port_connections;
 	u8         zone_group;
+	u8         reserved10[3];
+	u8         negotiated_link_rate;
 };
 
 #define MPI3_DEVICE0_SASSATA_FLAGS_WRITE_SAME_UNMAP_NCQ (0x0400)
diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
index 611a51a353c9..590c017acf25 100644
--- a/drivers/scsi/mpi3mr/mpi3mr.h
+++ b/drivers/scsi/mpi3mr/mpi3mr.h
@@ -643,6 +643,7 @@ struct mpi3mr_enclosure_node {
  * @dev_info: Device information bits
  * @phy_id: Phy identifier provided in device page 0
  * @attached_phy_id: Attached phy identifier provided in device page 0
+ * @negotiated_link_rate: Negotiated link rate from device page 0
  * @sas_transport_attached: Is this device exposed to transport
  * @pend_sas_rphy_add: Flag to check device is in process of add
  * @hba_port: HBA port entry
@@ -654,6 +655,7 @@ struct tgt_dev_sas_sata {
 	u16 dev_info;
 	u8 phy_id;
 	u8 attached_phy_id;
+	u8 negotiated_link_rate;
 	u8 sas_transport_attached;
 	u8 pend_sas_rphy_add;
 	struct mpi3mr_hba_port *hba_port;
diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
index 4dbf2f337212..ac94654494ba 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
@@ -1138,6 +1138,90 @@ static void mpi3mr_refresh_tgtdevs(struct mpi3mr_ioc *mrioc)
 	}
 }
 
+/**
+ * mpi3mr_debug_dump_devpg0 - Dump device page0
+ * @mrioc: Adapter instance reference
+ * @dev_pg0: Device page 0.
+ *
+ * Prints pertinent details of the device page 0.
+ *
+ * Return: Nothing.
+ */
+static void
+mpi3mr_debug_dump_devpg0(struct mpi3mr_ioc *mrioc, struct mpi3_device_page0 *dev_pg0)
+{
+
+	if (!(mrioc->logging_level &
+	    (MPI3_DEBUG_EVENT | MPI3_DEBUG_EVENT_WORK_TASK)))
+		return;
+
+	ioc_info(mrioc,
+	    "device_pg0: handle(0x%04x), perst_id(%d), wwid(0x%016llx), encl_handle(0x%04x), slot(%d)\n",
+	    le16_to_cpu(dev_pg0->dev_handle),
+	    le16_to_cpu(dev_pg0->persistent_id),
+	    le64_to_cpu(dev_pg0->wwid), le16_to_cpu(dev_pg0->enclosure_handle),
+	    le16_to_cpu(dev_pg0->slot));
+	ioc_info(mrioc, "device_pg0: access_status(0x%02x), flags(0x%04x), device_form(0x%02x), queue_depth(%d)\n",
+	    dev_pg0->access_status, le16_to_cpu(dev_pg0->flags),
+	    dev_pg0->device_form, le16_to_cpu(dev_pg0->queue_depth));
+	ioc_info(mrioc, "device_pg0: parent_handle(0x%04x), iounit_port(%d)\n",
+	    le16_to_cpu(dev_pg0->parent_dev_handle), dev_pg0->io_unit_port);
+
+	switch (dev_pg0->device_form) {
+	case MPI3_DEVICE_DEVFORM_SAS_SATA:
+	{
+		struct mpi3_device0_sas_sata_format *sasinf =
+		    &dev_pg0->device_specific.sas_sata_format;
+		ioc_info(mrioc,
+		    "device_pg0: sas_sata: sas_address(0x%016llx),flags(0x%04x),\n"
+		    "device_info(0x%04x), phy_num(%d), attached_phy_id(%d),negotiated_link_rate(0x%02x)\n",
+		    le64_to_cpu(sasinf->sas_address),
+		    le16_to_cpu(sasinf->flags),
+		    le16_to_cpu(sasinf->device_info), sasinf->phy_num,
+		    sasinf->attached_phy_identifier, sasinf->negotiated_link_rate);
+		break;
+	}
+	case MPI3_DEVICE_DEVFORM_PCIE:
+	{
+		struct mpi3_device0_pcie_format *pcieinf =
+		    &dev_pg0->device_specific.pcie_format;
+		ioc_info(mrioc,
+		    "device_pg0: pcie: port_num(%d), device_info(0x%04x), mdts(%d), page_sz(0x%02x)\n",
+		    pcieinf->port_num, le16_to_cpu(pcieinf->device_info),
+		    le32_to_cpu(pcieinf->maximum_data_transfer_size),
+		    pcieinf->page_size);
+		ioc_info(mrioc,
+		    "device_pg0: pcie: abort_timeout(%d), reset_timeout(%d) capabilities (0x%08x)\n",
+		    pcieinf->nvme_abort_to, pcieinf->controller_reset_to,
+		    le32_to_cpu(pcieinf->capabilities));
+		break;
+	}
+	case MPI3_DEVICE_DEVFORM_VD:
+	{
+		struct mpi3_device0_vd_format *vdinf =
+		    &dev_pg0->device_specific.vd_format;
+
+		ioc_info(mrioc,
+		    "device_pg0: vd: state(0x%02x), raid_level(%d), flags(0x%04x),\n"
+		    "device_info(0x%04x) abort_timeout(%d), reset_timeout(%d)\n",
+		    vdinf->vd_state, vdinf->raid_level,
+		    le16_to_cpu(vdinf->flags),
+		    le16_to_cpu(vdinf->device_info),
+		    vdinf->vd_abort_to, vdinf->vd_reset_to);
+		ioc_info(mrioc,
+		    "device_pg0: vd: tg_id(%d), high(%dMiB), low(%dMiB), qd_reduction_factor(%d)\n",
+		    vdinf->io_throttle_group,
+		    le16_to_cpu(vdinf->io_throttle_group_high),
+		    le16_to_cpu(vdinf->io_throttle_group_low),
+		    ((le16_to_cpu(vdinf->flags) &
+		       MPI3_DEVICE0_VD_FLAGS_IO_THROTTLE_GROUP_QD_MASK) >> 12));
+
+	}
+	default:
+		break;
+	}
+}
+
 /**
  * mpi3mr_update_tgtdev - DevStatusChange evt bottomhalf
  * @mrioc: Adapter instance reference
@@ -1159,6 +1243,8 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
 	struct mpi3mr_enclosure_node *enclosure_dev = NULL;
 	u8 prot_mask = 0;
 
+	mpi3mr_debug_dump_devpg0(mrioc, dev_pg0);
+
 	tgtdev->perst_id = le16_to_cpu(dev_pg0->persistent_id);
 	tgtdev->dev_handle = le16_to_cpu(dev_pg0->dev_handle);
 	tgtdev->dev_type = dev_pg0->device_form;
@@ -1237,6 +1323,8 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
 		tgtdev->dev_spec.sas_sata_inf.phy_id = sasinf->phy_num;
 		tgtdev->dev_spec.sas_sata_inf.attached_phy_id =
 		    sasinf->attached_phy_identifier;
+		tgtdev->dev_spec.sas_sata_inf.negotiated_link_rate =
+			sasinf->negotiated_link_rate;
 		if ((dev_info & MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_MASK) !=
 		    MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_END_DEVICE)
 			tgtdev->is_hidden = 1;
diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c
index d70f002d6487..101161554ef1 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_transport.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c
@@ -2284,11 +2284,11 @@ void mpi3mr_expander_remove(struct mpi3mr_ioc *mrioc, u64 sas_address,
  * @mrioc: Adapter instance reference
  * @tgtdev: Target device
  *
- * This function identifies whether the target device is
- * attached directly or through expander and issues sas phy
- * page0 or expander phy page1 and gets the link rate, if there
- * is any failure in reading the pages then this returns link
- * rate of 1.5.
+ * This function first tries to use the link rate from DevicePage0
+ * (populated by firmware during device discovery). If the cached
+ * value is not available or invalid, it falls back to reading from
+ * sas phy page0 or expander phy page1.
+ *
  *
  * Return: logical link rate.
  */
@@ -2301,6 +2301,14 @@ static u8 mpi3mr_get_sas_negotiated_logical_linkrate(struct mpi3mr_ioc *mrioc,
 	u32 phynum_handle;
 	u16 ioc_status;
 
+	/* First, try to use link rate from DevicePage0 (populated by firmware) */
+	if (tgtdev->dev_spec.sas_sata_inf.negotiated_link_rate >=
+	    MPI3_SAS_NEG_LINK_RATE_1_5) {
+		link_rate = tgtdev->dev_spec.sas_sata_inf.negotiated_link_rate;
+		goto out;
+	}
+
+	/* Fallback to reading from phy pages if DevicePage0 value not available */
 	phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id;
 	if (!(tgtdev->devpg0_flag & MPI3_DEVICE0_FLAGS_ATT_METHOD_DIR_ATTACHED)) {
 		phynum_handle = ((phy_number<<MPI3_SAS_EXPAND_PGAD_PHYNUM_SHIFT)
@@ -2318,9 +2326,7 @@ static u8 mpi3mr_get_sas_negotiated_logical_linkrate(struct mpi3mr_ioc *mrioc,
 			    __FILE__, __LINE__, __func__);
 			goto out;
 		}
-		link_rate = (expander_pg1.negotiated_link_rate &
-			     MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
-			MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT;
+		link_rate = expander_pg1.negotiated_link_rate;
 		goto out;
 	}
 	if (mpi3mr_cfg_get_sas_phy_pg0(mrioc, &ioc_status, &phy_pg0,
@@ -2335,11 +2341,11 @@ static u8 mpi3mr_get_sas_negotiated_logical_linkrate(struct mpi3mr_ioc *mrioc,
 		    __FILE__, __LINE__, __func__);
 		goto out;
 	}
-	link_rate = (phy_pg0.negotiated_link_rate &
-		     MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
-		MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT;
+	link_rate = phy_pg0.negotiated_link_rate;
+
 out:
-	return link_rate;
+	return ((link_rate & MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
+		MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT);
 }
 
 /**
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1 5/7] mpi3mr: Update MPI Headers to revision 39
  2026-01-12  8:10 [PATCH v1 0/7] mpi3mr: Enhancements for mpi3mr Ranjan Kumar
                   ` (3 preceding siblings ...)
  2026-01-12  8:10 ` [PATCH v1 4/7] mpi3mr: Use negotiated link rate from DevicePage0 Ranjan Kumar
@ 2026-01-12  8:10 ` Ranjan Kumar
  2026-01-12 14:21   ` Damien Le Moal
  2026-01-12  8:10 ` [PATCH v1 6/7] mpi3mr: Record and report controller firmware faults Ranjan Kumar
  2026-01-12  8:10 ` [PATCH v1 7/7] mpi3mr: Driver version update to 8.17.0.3.50 Ranjan Kumar
  6 siblings, 1 reply; 20+ messages in thread
From: Ranjan Kumar @ 2026-01-12  8:10 UTC (permalink / raw)
  To: linux-scsi, martin.petersen
  Cc: rajsekhar.chundru, sathya.prakash, chandrakanth.patil,
	prayas.patel, salomondush, Ranjan Kumar

Update MPI Headers to revision 39

Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
---
 drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h      |  90 ++++++++++++++++++-
 drivers/scsi/mpi3mr/mpi/mpi30_image.h     | 102 +++++++++++++++++++++-
 drivers/scsi/mpi3mr/mpi/mpi30_init.h      |   2 +-
 drivers/scsi/mpi3mr/mpi/mpi30_ioc.h       |   9 +-
 drivers/scsi/mpi3mr/mpi/mpi30_pci.h       |   2 +-
 drivers/scsi/mpi3mr/mpi/mpi30_sas.h       |   2 +-
 drivers/scsi/mpi3mr/mpi/mpi30_tool.h      |   6 +-
 drivers/scsi/mpi3mr/mpi/mpi30_transport.h |   4 +-
 8 files changed, 201 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
index 67d72b82cbe0..33dd303c97bb 100644
--- a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
+++ b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 /*
- *  Copyright 2017-2023 Broadcom Inc. All rights reserved.
+ *  Copyright 2017-2026 Broadcom Inc. All rights reserved.
  */
 #ifndef MPI30_CNFG_H
 #define MPI30_CNFG_H     1
@@ -1037,6 +1037,7 @@ struct mpi3_io_unit_page5 {
 #define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SATA_SSD_SHIFT        (2)
 #define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SAS_SSD_MASK          (0x0003)
 #define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SAS_SSD_SHIFT         (0)
+#define MPI3_IOUNIT5_DEVICE_SHUTDOWN_HDD_SPINDOWN_ENABLE    (0x8000)
 #define MPI3_IOUNIT5_FLAGS_SATAPUIS_MASK                   (0x0c)
 #define MPI3_IOUNIT5_FLAGS_SATAPUIS_NOT_SUPPORTED          (0x00)
 #define MPI3_IOUNIT5_FLAGS_SATAPUIS_OS_CONTROLLED          (0x04)
@@ -1074,7 +1075,8 @@ struct mpi3_io_unit_page8 {
 	u8                                 current_key_encryption_algo;
 	u8                                 key_digest_hash_algo;
 	union mpi3_version_union              current_svn;
-	__le32                             reserved14;
+	__le16                             pending_svn_time;
+	__le16                             reserved16;
 	__le32                             current_key[128];
 	union mpi3_iounit8_digest             digest[MPI3_IOUNIT8_DIGEST_MAX];
 };
@@ -1406,6 +1408,7 @@ struct mpi3_driver_page1 {
 };
 
 #define MPI3_DRIVER1_PAGEVERSION               (0x00)
+#define MPI3_DRIVER1_FLAGS_DEVICE_SHUTDOWN_ON_UNLOAD_DISABLE		(0x0001)
 #ifndef MPI3_DRIVER2_TRIGGER_MAX
 #define MPI3_DRIVER2_TRIGGER_MAX           (1)
 #endif
@@ -1561,7 +1564,9 @@ struct mpi3_security1_key_record {
 	u8                                 consumer;
 	__le16                             key_data_size;
 	__le32                             additional_key_data;
-	__le32                             reserved08[2];
+	u8                                 library_version;
+	u8                                 reserved09[3];
+	__le32                             reserved0c;
 	union mpi3_security1_key_data         key_data;
 };
 
@@ -1614,6 +1619,85 @@ struct mpi3_security_page2 {
 	u8                                 reserved9d[3];
 	struct mpi3_security2_trusted_root     trusted_root[MPI3_SECURITY2_TRUSTED_ROOT_MAX];
 };
+
+struct mpi3_security_page3 {
+	struct mpi3_config_page_header         header;
+	__le16                             key_data_length;
+	__le16                             reserved0a;
+	u8                                 key_number;
+	u8                                 reserved0d[3];
+	union mpi3_security_mac               mac;
+	union mpi3_security_nonce             nonce;
+	__le32                             reserved90[12];
+	u8                                 flags;
+	u8                                 consumer;
+	__le16                             key_data_size;
+	__le32                             additional_key_data;
+	u8                                 library_version;
+	u8                                 reserved_c9[3];
+	__le32                             reserved_cc;
+	u8                                 key_data[];
+};
+
+#define MPI3_SECURITY3_PAGEVERSION               (0x00)
+#define MPI3_SECURITY3_FLAGS_TYPE_MASK           (0x0f)
+#define MPI3_SECURITY3_FLAGS_TYPE_SHIFT          (0)
+#define MPI3_SECURITY3_FLAGS_TYPE_NOT_VALID      (0)
+#define MPI3_SECURITY3_FLAGS_TYPE_MLDSA_PRIVATE  (1)
+#define MPI3_SECURITY3_FLAGS_TYPE_MLDSA_PUBLIC   (2)
+struct mpi3_security_page10 {
+	struct mpi3_config_page_header         header;
+	__le32                             reserved08[2];
+	union mpi3_security_mac               mac;
+	union mpi3_security_nonce             nonce;
+	__le64                             current_token_nonce;
+	__le64                             previous_token_nonce;
+	__le32                             reserved_a0[8];
+	u8                                 diagnostic_auth_id[64];
+};
+#define MPI3_SECURITY10_PAGEVERSION               (0x00)
+
+struct mpi3_security_page11 {
+	struct mpi3_config_page_header         header;
+	u8                                 flags;
+	u8                                 reserved09[3];
+	__le32                             reserved0c;
+	__le32                             diagnostic_token_length;
+	__le32                             reserved14[3];
+	u8                                 diagnostic_token[];
+};
+#define MPI3_SECURITY11_PAGEVERSION               (0x00)
+#define MPI3_SECURITY11_FLAGS_TOKEN_ENABLED       (0x01)
+
+struct mpi3_security12_diag_feature {
+	__le32                             feature_identifier;
+	u8                                 feature_size;
+	u8                                 feature_type;
+	__le16                             reserved06;
+	u8                                 status;
+	u8                                 section;
+	__le16                             reserved0a;
+	__le32                             reserved0c;
+	u8                                 feature_data[64];
+};
+#define MPI3_SECURITY12_DIAG_FEATURE_STATUS_MASK                 (0x03)
+#define MPI3_SECURITY12_DIAG_FEATURE_STATUS_SHIFT                (0)
+#define MPI3_SECURITY12_DIAG_FEATURE_STATUS_UNKNOWN              (0x00)
+#define MPI3_SECURITY12_DIAG_FEATURE_STATUS_DISABLED             (0x01)
+#define MPI3_SECURITY12_DIAG_FEATURE_STATUS_ENABLED              (0x02)
+#define MPI3_SECURITY12_DIAG_FEATURE_SECTION_PROTECTED           (0x00)
+#define MPI3_SECURITY12_DIAG_FEATURE_SECTION_UNPROTECTED         (0x01)
+#define MPI3_SECURITY12_DIAG_FEATURE_SECTION_PAYLOAD             (0x02)
+#define MPI3_SECURITY12_DIAG_FEATURE_SECTION_SIGNATURE           (0x03)
+struct mpi3_security_page12 {
+	struct mpi3_config_page_header         header;
+	__le32                             reserved08[2];
+	u8                                 num_diag_features;
+	u8                                 reserved11[3];
+	__le32                             reserved14[3];
+	struct mpi3_security12_diag_feature    diag_feature[];
+};
+
 #define MPI3_SECURITY2_PAGEVERSION               (0x00)
 struct mpi3_sas_io_unit0_phy_data {
 	u8                 io_unit_port;
diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_image.h b/drivers/scsi/mpi3mr/mpi/mpi30_image.h
index 8d824107a678..62ddf094d46c 100644
--- a/drivers/scsi/mpi3mr/mpi/mpi30_image.h
+++ b/drivers/scsi/mpi3mr/mpi/mpi30_image.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 /*
- *  Copyright 2018-2023 Broadcom Inc. All rights reserved.
+ *  Copyright 2018-2026 Broadcom Inc. All rights reserved.
  */
 #ifndef MPI30_IMAGE_H
 #define MPI30_IMAGE_H     1
@@ -135,7 +135,7 @@ struct mpi3_ci_manifest_mpi {
 	__le32                                   package_version_string_offset;
 	__le32                                   package_build_date_string_offset;
 	__le32                                   package_build_time_string_offset;
-	__le32                                   reserved4c;
+	__le32                                   diag_authorization_key_offset;
 	__le32                                   diag_authorization_identifier[16];
 	struct mpi3_ci_manifest_mpi_comp_image_ref   component_image_ref[MPI3_CI_MANIFEST_MPI_MAX];
 };
@@ -148,16 +148,112 @@ struct mpi3_ci_manifest_mpi {
 #define MPI3_CI_MANIFEST_MPI_RELEASE_LEVEL_GCA                        (0x50)
 #define MPI3_CI_MANIFEST_MPI_RELEASE_LEVEL_POINT                      (0x60)
 #define MPI3_CI_MANIFEST_MPI_FLAGS_DIAG_AUTHORIZATION                 (0x01)
+#define MPI3_CI_MANIFEST_MPI_FLAGS_DIAG_AUTH_ANCHOR_MASK		(0x06)
+#define MPI3_CI_MANIFEST_MPI_FLAGS_DIAG_AUTH_ANCHOR_SHIFT		(1)
+#define MPI3_CI_MANIFEST_MPI_FLAGS_DIAG_AUTH_ANCHOR_IDENTIFIER		(0x00)
+#define MPI3_CI_MANIFEST_MPI_FLAGS_DIAG_AUTH_ANCHOR_KEY_OFFSET		(0x02)
 #define MPI3_CI_MANIFEST_MPI_SUBSYSTEMID_IGNORED                   (0xffff)
 #define MPI3_CI_MANIFEST_MPI_PKG_VER_STR_OFF_UNSPECIFIED           (0x00000000)
 #define MPI3_CI_MANIFEST_MPI_PKG_BUILD_DATE_STR_OFF_UNSPECIFIED    (0x00000000)
 #define MPI3_CI_MANIFEST_MPI_PKG_BUILD_TIME_STR_OFF_UNSPECIFIED    (0x00000000)
+
+struct mpi3_sb_manifest_ci_digest {
+	__le32                      signature1;
+	__le32                      reserved04[2];
+	u8                          hash_algorithm;
+	u8                          reserved09[3];
+	struct mpi3_comp_image_version  component_image_version;
+	__le32                      component_image_version_string_offset;
+	__le32                      digest[16];
+};
+
+struct mpi3_sb_manifest_ci_ref_element {
+	u8                              num_ci_digests;
+	u8                              reserved01[3];
+	struct mpi3_sb_manifest_ci_digest	ci_digest[];
+};
+
+struct mpi3_sb_manifest_embedded_key_element {
+	__le32                      reserved00[3];
+	u8                          key_algorithm;
+	u8                          flags;
+	__le16                      public_key_size;
+	__le32                      start_tag;
+	__le32                      public_key[];
+};
+
+#define MPI3_SB_MANIFEST_EMBEDDED_KEY_FLAGS_KEYINDEX_MASK		(0x03)
+#define MPI3_SB_MANIFEST_EMBEDDED_KEY_FLAGS_KEYINDEX_STRT		(0x00)
+#define MPI3_SB_MANIFEST_EMBEDDED_KEY_FLAGS_KEYINDEX_K2GO		(0x01)
+#define MPI3_SB_MANIFEST_EMBEDDED_KEY_STARTTAG_STRT			(0x54525453)
+#define MPI3_SB_MANIFEST_EMBEDDED_KEY_STARTTAG_K2GO			(0x4f47324b)
+#define MPI3_SB_MANIFEST_EMBEDDED_KEY_ENDTAG_STOP			(0x504f5453)
+#define MPI3_SB_MANIFEST_EMBEDDED_KEY_ENDTAG_K2ST			(0x5453324b)
+
+struct mpi3_sb_manifest_diag_key_element {
+	__le32                      reserved00[3];
+	u8                          key_algorithm;
+	u8                          flags;
+	__le16                      public_key_size;
+	__le32                      public_key[];
+};
+
+#define MPI3_SB_MANIFEST_DIAG_KEY_FLAGS_KEYINDEX_MASK		(0x03)
+#define MPI3_SB_MANIFEST_DIAG_KEY_FLAGS_KEYSELECT_FW_KEY	(0x04)
+union mpi3_sb_manifest_element_data {
+	struct mpi3_sb_manifest_ci_ref_element           ci_ref;
+	struct mpi3_sb_manifest_embedded_key_element     embed_key;
+	struct mpi3_sb_manifest_diag_key_element         diag_key;
+	__le32                                       dword;
+};
+struct mpi3_sb_manifest_element {
+	u8                                   manifest_element_form;
+	u8                                   reserved01[3];
+	union mpi3_sb_manifest_element_data     form_specific[];
+};
+#define MPI3_SB_MANIFEST_ELEMENT_FORM_CI_REFS		(0x01)
+#define MPI3_SB_MANIFEST_ELEMENT_FORM_EMBED_KEY		(0x02)
+#define MPI3_SB_MANIFEST_ELEMENT_FORM_DIAG_KEY		(0x03)
+struct mpi3_sb_manifest_mpi {
+	u8                                       manifest_type;
+	u8                                       reserved01[3];
+	__le32                                   reserved04[3];
+	u8                                       reserved10;
+	u8                                       release_level;
+	__le16                                   reserved12;
+	__le16                                   reserved14;
+	__le16                                   flags;
+	__le32                                   reserved18[2];
+	__le16                                   vendor_id;
+	__le16                                   device_id;
+	__le16                                   subsystem_vendor_id;
+	__le16                                   subsystem_id;
+	__le32                                   reserved28[2];
+	union mpi3_version_union                    package_security_version;
+	__le32                                   reserved34;
+	struct mpi3_comp_image_version               package_version;
+	__le32                                   package_version_string_offset;
+	__le32                                   package_build_date_string_offset;
+	__le32                                   package_build_time_string_offset;
+	__le32                                   component_image_references_offset;
+	__le32                                   embedded_key0offset;
+	__le32                                   embedded_key1offset;
+	__le32                                   diag_authorization_key_offset;
+	__le32                                   reserved5c[9];
+	struct mpi3_sb_manifest_element              manifest_elements[];
+};
+
 union mpi3_ci_manifest {
 	struct mpi3_ci_manifest_mpi               mpi;
+	struct mpi3_sb_manifest_mpi               sb_mpi;
 	__le32                                dword[1];
 };
 
-#define MPI3_CI_MANIFEST_TYPE_MPI                                  (0x00)
+#define MPI3_SB_MANIFEST_APU_IMMEDIATE_DEFER_APU_ENABLE			(0x01)
+
+#define MPI3_CI_MANIFEST_TYPE_MPI			(0x00)
+#define MPI3_CI_MANIFEST_TYPE_SB			(0x01)
+
 struct mpi3_extended_image_header {
 	u8                                image_type;
 	u8                                reserved01[3];
diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_init.h b/drivers/scsi/mpi3mr/mpi/mpi30_init.h
index bbef5bac92ed..745e1101ebf4 100644
--- a/drivers/scsi/mpi3mr/mpi/mpi30_init.h
+++ b/drivers/scsi/mpi3mr/mpi/mpi30_init.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 /*
- *  Copyright 2016-2023 Broadcom Inc. All rights reserved.
+ *  Copyright 2016-2026 Broadcom Inc. All rights reserved.
  */
 #ifndef MPI30_INIT_H
 #define MPI30_INIT_H     1
diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h b/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h
index b42933fcd423..12b8e0632b88 100644
--- a/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h
+++ b/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 /*
- *  Copyright 2016-2023 Broadcom Inc. All rights reserved.
+ *  Copyright 2016-2026 Broadcom Inc. All rights reserved.
  */
 #ifndef MPI30_IOC_H
 #define MPI30_IOC_H     1
@@ -658,9 +658,10 @@ struct mpi3_event_data_diag_buffer_status_change {
 	__le32             reserved04;
 };
 
-#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_RELEASED             (0x01)
-#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_PAUSED               (0x02)
-#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_RESUMED              (0x03)
+#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_RELEASED	(0x01)
+#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_PAUSED		(0x02)
+#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_RESUMED		(0x03)
+#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_CLEARED		(0x04)
 #define MPI3_PEL_LOCALE_FLAGS_NON_BLOCKING_BOOT_EVENT   (0x0200)
 #define MPI3_PEL_LOCALE_FLAGS_BLOCKING_BOOT_EVENT       (0x0100)
 #define MPI3_PEL_LOCALE_FLAGS_PCIE                      (0x0080)
diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_pci.h b/drivers/scsi/mpi3mr/mpi/mpi30_pci.h
index 4eeb11c3c73e..3092dfe6d952 100644
--- a/drivers/scsi/mpi3mr/mpi/mpi30_pci.h
+++ b/drivers/scsi/mpi3mr/mpi/mpi30_pci.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 /*
- *  Copyright 2016-2023 Broadcom Inc. All rights reserved.
+ *  Copyright 2016-2026 Broadcom Inc. All rights reserved.
  *
  */
 #ifndef MPI30_PCI_H
diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_sas.h b/drivers/scsi/mpi3mr/mpi/mpi30_sas.h
index 190b06508b00..f86da445df1e 100644
--- a/drivers/scsi/mpi3mr/mpi/mpi30_sas.h
+++ b/drivers/scsi/mpi3mr/mpi/mpi30_sas.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 /*
- *  Copyright 2016-2023 Broadcom Inc. All rights reserved.
+ *  Copyright 2016-2026 Broadcom Inc. All rights reserved.
  */
 #ifndef MPI30_SAS_H
 #define MPI30_SAS_H     1
diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_tool.h b/drivers/scsi/mpi3mr/mpi/mpi30_tool.h
index 50a65b16a818..72d3e6bc52ec 100644
--- a/drivers/scsi/mpi3mr/mpi/mpi30_tool.h
+++ b/drivers/scsi/mpi3mr/mpi/mpi30_tool.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 /*
- *  Copyright 2016-2024 Broadcom Inc. All rights reserved.
+ *  Copyright 2016-2026 Broadcom Inc. All rights reserved.
  */
 #ifndef MPI30_TOOL_H
 #define MPI30_TOOL_H     1
@@ -8,6 +8,10 @@
 #define MPI3_DIAG_BUFFER_TYPE_TRACE	(0x01)
 #define MPI3_DIAG_BUFFER_TYPE_FW	(0x02)
 #define MPI3_DIAG_BUFFER_ACTION_RELEASE	(0x01)
+#define MPI3_DIAG_BUFFER_ACTION_PAUSE	(0x02)
+#define MPI3_DIAG_BUFFER_ACTION_RESUME	(0x03)
+#define MPI3_DIAG_BUFFER_ACTION_CLEAR	(0x04)
+
 
 #define MPI3_DIAG_BUFFER_POST_MSGFLAGS_SEGMENTED	(0x01)
 struct mpi3_diag_buffer_post_request {
diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_transport.h b/drivers/scsi/mpi3mr/mpi/mpi30_transport.h
index 28ab2efb3baa..290a1f5c2924 100644
--- a/drivers/scsi/mpi3mr/mpi/mpi30_transport.h
+++ b/drivers/scsi/mpi3mr/mpi/mpi30_transport.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 /*
- *  Copyright 2016-2023 Broadcom Inc. All rights reserved.
+ *  Copyright 2016-2026 Broadcom Inc. All rights reserved.
  */
 #ifndef MPI30_TRANSPORT_H
 #define MPI30_TRANSPORT_H     1
@@ -18,7 +18,7 @@ union mpi3_version_union {
 
 #define MPI3_VERSION_MAJOR                                              (3)
 #define MPI3_VERSION_MINOR                                              (0)
-#define MPI3_VERSION_UNIT                                               (37)
+#define MPI3_VERSION_UNIT                                               (39)
 #define MPI3_VERSION_DEV                                                (0)
 #define MPI3_DEVHANDLE_INVALID                                          (0xffff)
 struct mpi3_sysif_oper_queue_indexes {
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1 6/7] mpi3mr: Record and report controller firmware faults
  2026-01-12  8:10 [PATCH v1 0/7] mpi3mr: Enhancements for mpi3mr Ranjan Kumar
                   ` (4 preceding siblings ...)
  2026-01-12  8:10 ` [PATCH v1 5/7] mpi3mr: Update MPI Headers to revision 39 Ranjan Kumar
@ 2026-01-12  8:10 ` Ranjan Kumar
  2026-01-12 14:25   ` Damien Le Moal
  2026-01-12  8:10 ` [PATCH v1 7/7] mpi3mr: Driver version update to 8.17.0.3.50 Ranjan Kumar
  6 siblings, 1 reply; 20+ messages in thread
From: Ranjan Kumar @ 2026-01-12  8:10 UTC (permalink / raw)
  To: linux-scsi, martin.petersen
  Cc: rajsekhar.chundru, sathya.prakash, chandrakanth.patil,
	prayas.patel, salomondush, Ranjan Kumar

Capture and retain firmware fault codes and extended fault information
whenever the controller enters a fault state.

Maintain a persistent firmware fault counter, expose it via sysfs,
and generate uevents to aid userspace diagnostics and failure analysis.

Signed-off-by: Salomon Dushimirimana <salomondush@google.com>
Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
---
 drivers/scsi/mpi3mr/mpi3mr.h     |  8 +++
 drivers/scsi/mpi3mr/mpi3mr_app.c | 24 +++++++++
 drivers/scsi/mpi3mr/mpi3mr_fw.c  | 87 ++++++++++++++++++++++++++++++++
 3 files changed, 119 insertions(+)

diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
index 590c017acf25..58db60e13c13 100644
--- a/drivers/scsi/mpi3mr/mpi3mr.h
+++ b/drivers/scsi/mpi3mr/mpi3mr.h
@@ -1137,6 +1137,10 @@ struct scmd_priv {
  * @default_qcount: Total Default queues
  * @active_poll_qcount: Currently active poll queue count
  * @requested_poll_qcount: User requested poll queue count
+ * @fault_during_init: Indicates a firmware fault occurred during initialization
+ * @saved_fault_code: Firmware fault code captured at the time of failure
+ * @saved_fault_info: Additional firmware-provided fault information
+ * @fwfault_counter: Count of firmware faults detected by the driver
  * @bsg_dev: BSG device structure
  * @bsg_queue: Request queue for BSG device
  * @stop_bsgs: Stop BSG request flag
@@ -1340,6 +1344,10 @@ struct mpi3mr_ioc {
 	u16 default_qcount;
 	u16 active_poll_qcount;
 	u16 requested_poll_qcount;
+	u8 fault_during_init;
+	u32 saved_fault_code;
+	u32 saved_fault_info[3];
+	u64 fwfault_counter;
 
 	struct device bsg_dev;
 	struct request_queue *bsg_queue;
diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
index 37cca0573ddc..1353a8ff9c85 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_app.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
@@ -3255,6 +3255,29 @@ adp_state_show(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR_RO(adp_state);
 
+/**
+ * fwfault_count_show() - SysFS callback to show firmware fault count
+ * @dev: class device
+ * @attr: Device attribute
+ * @buf: Buffer to copy data into
+ *
+ * Displays the total number of firmware faults detected by the driver
+ * since the controller was initialized.
+ *
+ * Return: Number of bytes written to @buf
+ */
+
+static ssize_t
+fwfault_count_show(struct device *dev, struct device_attribute *attr,
+	char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct mpi3mr_ioc *mrioc = shost_priv(shost);
+
+	return snprintf(buf, PAGE_SIZE, "%llu\n", mrioc->fwfault_counter);
+}
+static DEVICE_ATTR_RO(fwfault_count);
+
 static struct attribute *mpi3mr_host_attrs[] = {
 	&dev_attr_version_fw.attr,
 	&dev_attr_fw_queue_depth.attr,
@@ -3263,6 +3286,7 @@ static struct attribute *mpi3mr_host_attrs[] = {
 	&dev_attr_reply_qfull_count.attr,
 	&dev_attr_logging_level.attr,
 	&dev_attr_adp_state.attr,
+	&dev_attr_fwfault_count.attr,
 	NULL,
 };
 
diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index 178738850541..ea951ef4b2d9 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -1108,6 +1108,31 @@ void mpi3mr_print_fault_info(struct mpi3mr_ioc *mrioc)
 	}
 }
 
+/**
+ * mpi3mr_save_fault_info - Save fault information
+ * @mrioc: Adapter instance reference
+ *
+ * Save the controller fault information if there is a
+ * controller fault.
+ *
+ * Return: Nothing.
+ */
+static void mpi3mr_save_fault_info(struct mpi3mr_ioc *mrioc)
+{
+	u32 ioc_status, i;
+
+	ioc_status = readl(&mrioc->sysif_regs->ioc_status);
+
+	if (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT) {
+		mrioc->saved_fault_code = readl(&mrioc->sysif_regs->fault) &
+		    MPI3_SYSIF_FAULT_CODE_MASK;
+		for (i = 0; i < 3; i++) {
+			mrioc->saved_fault_info[i] =
+			readl(&mrioc->sysif_regs->fault_info[i]);
+		}
+	}
+}
+
 /**
  * mpi3mr_get_iocstate - Get IOC State
  * @mrioc: Adapter instance reference
@@ -1249,6 +1274,44 @@ static void mpi3mr_alloc_ioctl_dma_memory(struct mpi3mr_ioc *mrioc)
 	mpi3mr_free_ioctl_dma_memory(mrioc);
 }
 
+/**
+ * mpi3mr_fault_uevent_emit - Emit uevent for any controller
+ * fault
+ * @mrioc: Pointer to the mpi3mr_ioc structure for the controller instance
+ *
+ * This function is invoked when the controller undergoes any
+ * type of fault.
+ */
+
+static void mpi3mr_fault_uevent_emit(struct mpi3mr_ioc *mrioc)
+{
+	struct kobj_uevent_env *env;
+
+	env = kzalloc(sizeof(*env), GFP_KERNEL);
+	if (!env)
+		return;
+
+	if (add_uevent_var(env, "DRIVER=%s", mrioc->driver_name))
+		return;
+	if (add_uevent_var(env, "IOC_ID=%u", mrioc->id))
+		return;
+	if (add_uevent_var(env, "FAULT_CODE=0x%08x", mrioc->saved_fault_code))
+		return;
+	if (add_uevent_var(env, "FAULT_INFO0=0x%08x",
+	     mrioc->saved_fault_info[0]))
+		return;
+	if (add_uevent_var(env, "FAULT_INFO1=0x%08x",
+	     mrioc->saved_fault_info[1]))
+		return;
+	if (add_uevent_var(env, "FAULT_INFO2=0x%08x",
+	    mrioc->saved_fault_info[2]))
+		return;
+
+	kobject_uevent_env(&mrioc->shost->shost_gendev.kobj,
+	    KOBJ_CHANGE, env->envp);
+	kfree(env);
+}
+
 /**
  * mpi3mr_clear_reset_history - clear reset history
  * @mrioc: Adapter instance reference
@@ -1480,6 +1543,10 @@ static int mpi3mr_bring_ioc_ready(struct mpi3mr_ioc *mrioc)
 		if (ioc_state == MRIOC_STATE_FAULT) {
 			timeout = MPI3_SYSIF_DIAG_SAVE_TIMEOUT * 10;
 			mpi3mr_print_fault_info(mrioc);
+			mpi3mr_save_fault_info(mrioc);
+			mrioc->fault_during_init = 1;
+			mrioc->fwfault_counter++;
+
 			do {
 				host_diagnostic =
 					readl(&mrioc->sysif_regs->host_diagnostic);
@@ -2577,6 +2644,9 @@ void mpi3mr_check_rh_fault_ioc(struct mpi3mr_ioc *mrioc, u32 reason_code)
 		mpi3mr_set_trigger_data_in_all_hdb(mrioc,
 		    MPI3MR_HDB_TRIGGER_TYPE_FAULT, &trigger_data, 0);
 		mpi3mr_print_fault_info(mrioc);
+		mpi3mr_save_fault_info(mrioc);
+		mrioc->fault_during_init = 1;
+		mrioc->fwfault_counter++;
 		return;
 	}
 
@@ -2594,6 +2664,10 @@ void mpi3mr_check_rh_fault_ioc(struct mpi3mr_ioc *mrioc, u32 reason_code)
 			break;
 		msleep(100);
 	} while (--timeout);
+
+	mpi3mr_save_fault_info(mrioc);
+	mrioc->fault_during_init = 1;
+	mrioc->fwfault_counter++;
 }
 
 /**
@@ -2770,6 +2844,11 @@ static void mpi3mr_watchdog_work(struct work_struct *work)
 	union mpi3mr_trigger_data trigger_data;
 	u16 reset_reason = MPI3MR_RESET_FROM_FAULT_WATCH;
 
+	if (mrioc->fault_during_init) {
+		mpi3mr_fault_uevent_emit(mrioc);
+		mrioc->fault_during_init = 0;
+	}
+
 	if (mrioc->reset_in_progress || mrioc->pci_err_recovery)
 		return;
 
@@ -2842,6 +2921,10 @@ static void mpi3mr_watchdog_work(struct work_struct *work)
 		goto schedule_work;
 	}
 
+	mpi3mr_save_fault_info(mrioc);
+	mpi3mr_fault_uevent_emit(mrioc);
+	mrioc->fwfault_counter++;
+
 	switch (trigger_data.fault) {
 	case MPI3_SYSIF_FAULT_CODE_COMPLETE_RESET_NEEDED:
 	case MPI3_SYSIF_FAULT_CODE_POWER_CYCLE_REQUIRED:
@@ -5478,6 +5561,10 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
 					break;
 				msleep(100);
 			} while (--timeout);
+
+			mpi3mr_save_fault_info(mrioc);
+			mpi3mr_fault_uevent_emit(mrioc);
+			mrioc->fwfault_counter++;
 			mpi3mr_set_trigger_data_in_all_hdb(mrioc,
 			    MPI3MR_HDB_TRIGGER_TYPE_FAULT, &trigger_data, 0);
 		}
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v1 7/7] mpi3mr: Driver version update to 8.17.0.3.50
  2026-01-12  8:10 [PATCH v1 0/7] mpi3mr: Enhancements for mpi3mr Ranjan Kumar
                   ` (5 preceding siblings ...)
  2026-01-12  8:10 ` [PATCH v1 6/7] mpi3mr: Record and report controller firmware faults Ranjan Kumar
@ 2026-01-12  8:10 ` Ranjan Kumar
  6 siblings, 0 replies; 20+ messages in thread
From: Ranjan Kumar @ 2026-01-12  8:10 UTC (permalink / raw)
  To: linux-scsi, martin.petersen
  Cc: rajsekhar.chundru, sathya.prakash, chandrakanth.patil,
	prayas.patel, salomondush, Ranjan Kumar

Update driver version to 8.17.0.3.50

Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
---
 drivers/scsi/mpi3mr/mpi3mr.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
index 58db60e13c13..3c70f570ee0c 100644
--- a/drivers/scsi/mpi3mr/mpi3mr.h
+++ b/drivers/scsi/mpi3mr/mpi3mr.h
@@ -56,8 +56,8 @@ extern struct list_head mrioc_list;
 extern int prot_mask;
 extern atomic64_t event_counter;
 
-#define MPI3MR_DRIVER_VERSION	"8.15.0.5.51"
-#define MPI3MR_DRIVER_RELDATE	"18-November-2025"
+#define MPI3MR_DRIVER_VERSION	"8.17.0.3.50"
+#define MPI3MR_DRIVER_RELDATE	"09-January-2026"
 
 #define MPI3MR_DRIVER_NAME	"mpi3mr"
 #define MPI3MR_DRIVER_LICENSE	"GPL"
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 2/7] mpi3mr: Rename log data save helper to reflect threaded/BH context
  2026-01-12  8:10 ` [PATCH v1 2/7] mpi3mr: Rename log data save helper to reflect threaded/BH context Ranjan Kumar
@ 2026-01-12 14:13   ` Damien Le Moal
  2026-01-13  7:27     ` Ranjan Kumar
  0 siblings, 1 reply; 20+ messages in thread
From: Damien Le Moal @ 2026-01-12 14:13 UTC (permalink / raw)
  To: Ranjan Kumar, linux-scsi, martin.petersen
  Cc: rajsekhar.chundru, sathya.prakash, chandrakanth.patil,
	prayas.patel, salomondush

On 1/12/26 09:10, Ranjan Kumar wrote:
> Log data events can be processed from BH and threaded contexts.
> Rename the save helper to document its intended usage and improve
> readability of the event handling flow.
> 
> Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
> ---
>  drivers/scsi/mpi3mr/mpi3mr.h     | 2 +-
>  drivers/scsi/mpi3mr/mpi3mr_app.c | 4 ++--
>  drivers/scsi/mpi3mr/mpi3mr_os.c  | 8 +++++++-
>  3 files changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
> index 31d68c151b20..611a51a353c9 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr.h
> +++ b/drivers/scsi/mpi3mr/mpi3mr.h
> @@ -1508,7 +1508,7 @@ void mpi3mr_pel_get_seqnum_complete(struct mpi3mr_ioc *mrioc,
>  	struct mpi3mr_drv_cmd *drv_cmd);
>  int mpi3mr_pel_get_seqnum_post(struct mpi3mr_ioc *mrioc,
>  	struct mpi3mr_drv_cmd *drv_cmd);
> -void mpi3mr_app_save_logdata(struct mpi3mr_ioc *mrioc, char *event_data,
> +void mpi3mr_app_save_logdata_th(struct mpi3mr_ioc *mrioc, char *event_data,
>  	u16 event_data_size);
>  struct mpi3mr_enclosure_node *mpi3mr_enclosure_find_by_handle(
>  	struct mpi3mr_ioc *mrioc, u16 handle);
> diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
> index 0e5478d62580..37cca0573ddc 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr_app.c
> +++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
> @@ -2920,7 +2920,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
>  }
>  
>  /**
> - * mpi3mr_app_save_logdata - Save Log Data events
> + * mpi3mr_app_save_logdata_th - Save Log Data events
>   * @mrioc: Adapter instance reference
>   * @event_data: event data associated with log data event
>   * @event_data_size: event data size to copy
> @@ -2932,7 +2932,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
>   *
>   * Return:Nothing
>   */
> -void mpi3mr_app_save_logdata(struct mpi3mr_ioc *mrioc, char *event_data,
> +void mpi3mr_app_save_logdata_th(struct mpi3mr_ioc *mrioc, char *event_data,
>  	u16 event_data_size)
>  {
>  	u32 index = mrioc->logdata_buf_idx, sz;
> diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
> index d4ca878d0886..4dbf2f337212 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr_os.c
> +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
> @@ -1962,7 +1962,7 @@ static void mpi3mr_pcietopochg_evt_bh(struct mpi3mr_ioc *mrioc,
>  static void mpi3mr_logdata_evt_bh(struct mpi3mr_ioc *mrioc,
>  	struct mpi3mr_fwevt *fwevt)
>  {
> -	mpi3mr_app_save_logdata(mrioc, fwevt->event_data,
> +	mpi3mr_app_save_logdata_th(mrioc, fwevt->event_data,
>  	    fwevt->event_data_size);
>  }
>  
> @@ -3058,6 +3058,12 @@ void mpi3mr_os_handle_events(struct mpi3mr_ioc *mrioc,
>  	}
>  	case MPI3_EVENT_DEVICE_INFO_CHANGED:
>  	case MPI3_EVENT_LOG_DATA:
> +	{

The curly brackets are not necessary.

> +		sz = event_reply->event_data_length * 4;
> +		mpi3mr_app_save_logdata_th(mrioc,
> +		    (char *)event_reply->event_data, sz);

Do you really need the cast here ?

> +		break;
> +	}
>  	case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE:
>  	case MPI3_EVENT_ENCL_DEVICE_ADDED:
>  	{


-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 1/7] mpi3mr: Add module parameter to control threaded IRQ polling
  2026-01-12  8:10 ` [PATCH v1 1/7] mpi3mr: Add module parameter to control threaded IRQ polling Ranjan Kumar
@ 2026-01-12 14:14   ` Damien Le Moal
  2026-01-13 17:36     ` Ranjan Kumar
  0 siblings, 1 reply; 20+ messages in thread
From: Damien Le Moal @ 2026-01-12 14:14 UTC (permalink / raw)
  To: Ranjan Kumar, linux-scsi, martin.petersen
  Cc: rajsekhar.chundru, sathya.prakash, chandrakanth.patil,
	prayas.patel, salomondush

On 1/12/26 09:10, Ranjan Kumar wrote:
> Add a module parameter to enable or disable threaded IRQ polling
> in the driver. The default behavior remains unchanged
> with polling enabled.
> 
> When disabled, completion processing is kept entirely in the
> hard IRQ context, avoiding the threaded polling path.

What does that bring ? Better throughput ? Lower latency ? please tell us more
about the benefits of this change.

> 
> Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
> ---
>  drivers/scsi/mpi3mr/mpi3mr_fw.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
> index 8fe6e0bf342e..869e525f3e73 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
> +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
> @@ -21,6 +21,10 @@ static int mpi3mr_check_op_admin_proc(struct mpi3mr_ioc *mrioc);
>  static int poll_queues;
>  module_param(poll_queues, int, 0444);
>  MODULE_PARM_DESC(poll_queues, "Number of queues for io_uring poll mode. (Range 1 - 126)");
> +static bool threaded_isr_poll = true;
> +module_param(threaded_isr_poll, bool, 0444);
> +MODULE_PARM_DESC(threaded_isr_poll,
> +			"Enablement of IRQ polling thread (default=true)");
>  
>  #if defined(writeq) && defined(CONFIG_64BIT)
>  static inline void mpi3mr_writeq(__u64 b, void __iomem *addr,
> @@ -595,7 +599,8 @@ int mpi3mr_process_op_reply_q(struct mpi3mr_ioc *mrioc,
>  		 * Exit completion loop to avoid CPU lockup
>  		 * Ensure remaining completion happens from threaded ISR.
>  		 */
> -		if (num_op_reply > mrioc->max_host_ios) {
> +		if ((num_op_reply > mrioc->max_host_ios) &&
> +			(threaded_isr_poll == true)) {
>  			op_reply_q->enable_irq_poll = true;
>  			break;
>  		}
> @@ -692,7 +697,7 @@ static irqreturn_t mpi3mr_isr(int irq, void *privdata)
>  	 * If more IOs are expected, schedule IRQ polling thread.
>  	 * Otherwise exit from ISR.
>  	 */
> -	if (!intr_info->op_reply_q)
> +	if ((threaded_isr_poll == false) || !intr_info->op_reply_q)
>  		return ret;
>  
>  	if (!intr_info->op_reply_q->enable_irq_poll ||


-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 4/7] mpi3mr: Use negotiated link rate from DevicePage0
  2026-01-12  8:10 ` [PATCH v1 4/7] mpi3mr: Use negotiated link rate from DevicePage0 Ranjan Kumar
@ 2026-01-12 14:18   ` Damien Le Moal
  2026-01-13 17:46     ` Ranjan Kumar
  2026-01-12 16:38   ` kernel test robot
  1 sibling, 1 reply; 20+ messages in thread
From: Damien Le Moal @ 2026-01-12 14:18 UTC (permalink / raw)
  To: Ranjan Kumar, linux-scsi, martin.petersen
  Cc: rajsekhar.chundru, sathya.prakash, chandrakanth.patil,
	prayas.patel, salomondush

On 1/12/26 09:10, Ranjan Kumar wrote:
> Firmware populates the negotiated SAS link rate in DevicePage0
> during device discovery. Update mpi3mr to cache this value while
> initializing the target device.
> 
> When available, the cached link rate is used instead of issuing
> additional SAS PHY or expander PHY page reads.
> If the DevicePage0 value is missing or invalid, the driver
> falls back to the existing PHY-based mechanism.
> 
> Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
> ---
>  drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h   |  2 +
>  drivers/scsi/mpi3mr/mpi3mr.h           |  2 +
>  drivers/scsi/mpi3mr/mpi3mr_os.c        | 88 ++++++++++++++++++++++++++
>  drivers/scsi/mpi3mr/mpi3mr_transport.c | 30 +++++----
>  4 files changed, 110 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
> index 8c8bfbbdd34e..67d72b82cbe0 100644
> --- a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
> +++ b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
> @@ -2314,6 +2314,8 @@ struct mpi3_device0_sas_sata_format {
>  	u8         attached_phy_identifier;
>  	u8         max_port_connections;
>  	u8         zone_group;
> +	u8         reserved10[3];
> +	u8         negotiated_link_rate;
>  };
>  
>  #define MPI3_DEVICE0_SASSATA_FLAGS_WRITE_SAME_UNMAP_NCQ (0x0400)
> diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
> index 611a51a353c9..590c017acf25 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr.h
> +++ b/drivers/scsi/mpi3mr/mpi3mr.h
> @@ -643,6 +643,7 @@ struct mpi3mr_enclosure_node {
>   * @dev_info: Device information bits
>   * @phy_id: Phy identifier provided in device page 0
>   * @attached_phy_id: Attached phy identifier provided in device page 0
> + * @negotiated_link_rate: Negotiated link rate from device page 0
>   * @sas_transport_attached: Is this device exposed to transport
>   * @pend_sas_rphy_add: Flag to check device is in process of add
>   * @hba_port: HBA port entry
> @@ -654,6 +655,7 @@ struct tgt_dev_sas_sata {
>  	u16 dev_info;
>  	u8 phy_id;
>  	u8 attached_phy_id;
> +	u8 negotiated_link_rate;
>  	u8 sas_transport_attached;
>  	u8 pend_sas_rphy_add;
>  	struct mpi3mr_hba_port *hba_port;
> diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
> index 4dbf2f337212..ac94654494ba 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr_os.c
> +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
> @@ -1138,6 +1138,90 @@ static void mpi3mr_refresh_tgtdevs(struct mpi3mr_ioc *mrioc)
>  	}
>  }
>  
> +/**
> + * mpi3mr_debug_dump_devpg0 - Dump device page0
> + * @mrioc: Adapter instance reference
> + * @dev_pg0: Device page 0.
> + *
> + * Prints pertinent details of the device page 0.
> + *
> + * Return: Nothing.
> + */
> +static void
> +mpi3mr_debug_dump_devpg0(struct mpi3mr_ioc *mrioc, struct mpi3_device_page0 *dev_pg0)
> +{
> +

No need for this blank line.

> +	if (!(mrioc->logging_level &
> +	    (MPI3_DEBUG_EVENT | MPI3_DEBUG_EVENT_WORK_TASK)))
> +		return;

Please move this test in the caller so that we can avoid a function call for
nothing if debug is not enabled.

> +
> +	ioc_info(mrioc,
> +	    "device_pg0: handle(0x%04x), perst_id(%d), wwid(0x%016llx), encl_handle(0x%04x), slot(%d)\n",
> +	    le16_to_cpu(dev_pg0->dev_handle),
> +	    le16_to_cpu(dev_pg0->persistent_id),
> +	    le64_to_cpu(dev_pg0->wwid), le16_to_cpu(dev_pg0->enclosure_handle),
> +	    le16_to_cpu(dev_pg0->slot));
> +	ioc_info(mrioc, "device_pg0: access_status(0x%02x), flags(0x%04x), device_form(0x%02x), queue_depth(%d)\n",
> +	    dev_pg0->access_status, le16_to_cpu(dev_pg0->flags),
> +	    dev_pg0->device_form, le16_to_cpu(dev_pg0->queue_depth));
> +	ioc_info(mrioc, "device_pg0: parent_handle(0x%04x), iounit_port(%d)\n",
> +	    le16_to_cpu(dev_pg0->parent_dev_handle), dev_pg0->io_unit_port);
> +
> +	switch (dev_pg0->device_form) {
> +	case MPI3_DEVICE_DEVFORM_SAS_SATA:
> +	{
> +		struct mpi3_device0_sas_sata_format *sasinf =
> +		    &dev_pg0->device_specific.sas_sata_format;

Please add a blank line after declarations. Same comment applies to other cases
below.

> +		ioc_info(mrioc,
> +		    "device_pg0: sas_sata: sas_address(0x%016llx),flags(0x%04x),\n"
> +		    "device_info(0x%04x), phy_num(%d), attached_phy_id(%d),negotiated_link_rate(0x%02x)\n",
> +		    le64_to_cpu(sasinf->sas_address),
> +		    le16_to_cpu(sasinf->flags),
> +		    le16_to_cpu(sasinf->device_info), sasinf->phy_num,
> +		    sasinf->attached_phy_identifier, sasinf->negotiated_link_rate);
> +		break;
> +	}
> +	case MPI3_DEVICE_DEVFORM_PCIE:
> +	{
> +		struct mpi3_device0_pcie_format *pcieinf =
> +		    &dev_pg0->device_specific.pcie_format;
> +		ioc_info(mrioc,
> +		    "device_pg0: pcie: port_num(%d), device_info(0x%04x), mdts(%d), page_sz(0x%02x)\n",
> +		    pcieinf->port_num, le16_to_cpu(pcieinf->device_info),
> +		    le32_to_cpu(pcieinf->maximum_data_transfer_size),
> +		    pcieinf->page_size);
> +		ioc_info(mrioc,
> +		    "device_pg0: pcie: abort_timeout(%d), reset_timeout(%d) capabilities (0x%08x)\n",
> +		    pcieinf->nvme_abort_to, pcieinf->controller_reset_to,
> +		    le32_to_cpu(pcieinf->capabilities));
> +		break;
> +	}
> +	case MPI3_DEVICE_DEVFORM_VD:
> +	{
> +		struct mpi3_device0_vd_format *vdinf =
> +		    &dev_pg0->device_specific.vd_format;
> +
> +		ioc_info(mrioc,
> +		    "device_pg0: vd: state(0x%02x), raid_level(%d), flags(0x%04x),\n"
> +		    "device_info(0x%04x) abort_timeout(%d), reset_timeout(%d)\n",
> +		    vdinf->vd_state, vdinf->raid_level,
> +		    le16_to_cpu(vdinf->flags),
> +		    le16_to_cpu(vdinf->device_info),
> +		    vdinf->vd_abort_to, vdinf->vd_reset_to);
> +		ioc_info(mrioc,
> +		    "device_pg0: vd: tg_id(%d), high(%dMiB), low(%dMiB), qd_reduction_factor(%d)\n",
> +		    vdinf->io_throttle_group,
> +		    le16_to_cpu(vdinf->io_throttle_group_high),
> +		    le16_to_cpu(vdinf->io_throttle_group_low),
> +		    ((le16_to_cpu(vdinf->flags) &
> +		       MPI3_DEVICE0_VD_FLAGS_IO_THROTTLE_GROUP_QD_MASK) >> 12));
> +
> +	}
> +	default:
> +		break;
> +	}
> +}
> +
>  /**
>   * mpi3mr_update_tgtdev - DevStatusChange evt bottomhalf
>   * @mrioc: Adapter instance reference
> @@ -1159,6 +1243,8 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
>  	struct mpi3mr_enclosure_node *enclosure_dev = NULL;
>  	u8 prot_mask = 0;
>  
> +	mpi3mr_debug_dump_devpg0(mrioc, dev_pg0);
> +
>  	tgtdev->perst_id = le16_to_cpu(dev_pg0->persistent_id);
>  	tgtdev->dev_handle = le16_to_cpu(dev_pg0->dev_handle);
>  	tgtdev->dev_type = dev_pg0->device_form;
> @@ -1237,6 +1323,8 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
>  		tgtdev->dev_spec.sas_sata_inf.phy_id = sasinf->phy_num;
>  		tgtdev->dev_spec.sas_sata_inf.attached_phy_id =
>  		    sasinf->attached_phy_identifier;
> +		tgtdev->dev_spec.sas_sata_inf.negotiated_link_rate =
> +			sasinf->negotiated_link_rate;
>  		if ((dev_info & MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_MASK) !=
>  		    MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_END_DEVICE)
>  			tgtdev->is_hidden = 1;
> diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c
> index d70f002d6487..101161554ef1 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr_transport.c
> +++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c
> @@ -2284,11 +2284,11 @@ void mpi3mr_expander_remove(struct mpi3mr_ioc *mrioc, u64 sas_address,
>   * @mrioc: Adapter instance reference
>   * @tgtdev: Target device
>   *
> - * This function identifies whether the target device is
> - * attached directly or through expander and issues sas phy
> - * page0 or expander phy page1 and gets the link rate, if there
> - * is any failure in reading the pages then this returns link
> - * rate of 1.5.
> + * This function first tries to use the link rate from DevicePage0
> + * (populated by firmware during device discovery). If the cached
> + * value is not available or invalid, it falls back to reading from
> + * sas phy page0 or expander phy page1.
> + *
>   *
>   * Return: logical link rate.
>   */
> @@ -2301,6 +2301,14 @@ static u8 mpi3mr_get_sas_negotiated_logical_linkrate(struct mpi3mr_ioc *mrioc,
>  	u32 phynum_handle;
>  	u16 ioc_status;
>  
> +	/* First, try to use link rate from DevicePage0 (populated by firmware) */
> +	if (tgtdev->dev_spec.sas_sata_inf.negotiated_link_rate >=
> +	    MPI3_SAS_NEG_LINK_RATE_1_5) {
> +		link_rate = tgtdev->dev_spec.sas_sata_inf.negotiated_link_rate;
> +		goto out;
> +	}
> +
> +	/* Fallback to reading from phy pages if DevicePage0 value not available */
>  	phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id;
>  	if (!(tgtdev->devpg0_flag & MPI3_DEVICE0_FLAGS_ATT_METHOD_DIR_ATTACHED)) {
>  		phynum_handle = ((phy_number<<MPI3_SAS_EXPAND_PGAD_PHYNUM_SHIFT)
> @@ -2318,9 +2326,7 @@ static u8 mpi3mr_get_sas_negotiated_logical_linkrate(struct mpi3mr_ioc *mrioc,
>  			    __FILE__, __LINE__, __func__);
>  			goto out;
>  		}
> -		link_rate = (expander_pg1.negotiated_link_rate &
> -			     MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
> -			MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT;
> +		link_rate = expander_pg1.negotiated_link_rate;
>  		goto out;
>  	}
>  	if (mpi3mr_cfg_get_sas_phy_pg0(mrioc, &ioc_status, &phy_pg0,
> @@ -2335,11 +2341,11 @@ static u8 mpi3mr_get_sas_negotiated_logical_linkrate(struct mpi3mr_ioc *mrioc,
>  		    __FILE__, __LINE__, __func__);
>  		goto out;
>  	}
> -	link_rate = (phy_pg0.negotiated_link_rate &
> -		     MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
> -		MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT;
> +	link_rate = phy_pg0.negotiated_link_rate;
> +
>  out:
> -	return link_rate;
> +	return ((link_rate & MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
> +		MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT);
>  }
>  
>  /**


-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 5/7] mpi3mr: Update MPI Headers to revision 39
  2026-01-12  8:10 ` [PATCH v1 5/7] mpi3mr: Update MPI Headers to revision 39 Ranjan Kumar
@ 2026-01-12 14:21   ` Damien Le Moal
  2026-01-13 17:39     ` Ranjan Kumar
  0 siblings, 1 reply; 20+ messages in thread
From: Damien Le Moal @ 2026-01-12 14:21 UTC (permalink / raw)
  To: Ranjan Kumar, linux-scsi, martin.petersen
  Cc: rajsekhar.chundru, sathya.prakash, chandrakanth.patil,
	prayas.patel, salomondush

On 1/12/26 09:10, Ranjan Kumar wrote:
> -#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_RELEASED             (0x01)
> -#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_PAUSED               (0x02)
> -#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_RESUMED              (0x03)
> +#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_RELEASED	(0x01)

Why the alignment change ?

> +#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_PAUSED		(0x02)
> +#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_RESUMED		(0x03)
> +#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_CLEARED		(0x04)

A white line here would be nice to separate things.

>  #define MPI3_PEL_LOCALE_FLAGS_NON_BLOCKING_BOOT_EVENT   (0x0200)
>  #define MPI3_PEL_LOCALE_FLAGS_BLOCKING_BOOT_EVENT       (0x0100)
>  #define MPI3_PEL_LOCALE_FLAGS_PCIE                      (0x0080)



-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 6/7] mpi3mr: Record and report controller firmware faults
  2026-01-12  8:10 ` [PATCH v1 6/7] mpi3mr: Record and report controller firmware faults Ranjan Kumar
@ 2026-01-12 14:25   ` Damien Le Moal
  2026-01-13 18:28     ` Ranjan Kumar
  0 siblings, 1 reply; 20+ messages in thread
From: Damien Le Moal @ 2026-01-12 14:25 UTC (permalink / raw)
  To: Ranjan Kumar, linux-scsi, martin.petersen
  Cc: rajsekhar.chundru, sathya.prakash, chandrakanth.patil,
	prayas.patel, salomondush

On 1/12/26 09:10, Ranjan Kumar wrote:
> +static void mpi3mr_fault_uevent_emit(struct mpi3mr_ioc *mrioc)
> +{
> +	struct kobj_uevent_env *env;
> +
> +	env = kzalloc(sizeof(*env), GFP_KERNEL);
> +	if (!env)
> +		return;
> +
> +	if (add_uevent_var(env, "DRIVER=%s", mrioc->driver_name))
> +		return;

All the returns in this function are leaking env...

> +	if (add_uevent_var(env, "IOC_ID=%u", mrioc->id))
> +		return;
> +	if (add_uevent_var(env, "FAULT_CODE=0x%08x", mrioc->saved_fault_code))
> +		return;
> +	if (add_uevent_var(env, "FAULT_INFO0=0x%08x",
> +	     mrioc->saved_fault_info[0]))
> +		return;
> +	if (add_uevent_var(env, "FAULT_INFO1=0x%08x",
> +	     mrioc->saved_fault_info[1]))
> +		return;
> +	if (add_uevent_var(env, "FAULT_INFO2=0x%08x",
> +	    mrioc->saved_fault_info[2]))
> +		return;
> +
> +	kobject_uevent_env(&mrioc->shost->shost_gendev.kobj,
> +	    KOBJ_CHANGE, env->envp);

Please align the arguments after the "(".

> +	kfree(env);
> +}


-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 4/7] mpi3mr: Use negotiated link rate from DevicePage0
  2026-01-12  8:10 ` [PATCH v1 4/7] mpi3mr: Use negotiated link rate from DevicePage0 Ranjan Kumar
  2026-01-12 14:18   ` Damien Le Moal
@ 2026-01-12 16:38   ` kernel test robot
  1 sibling, 0 replies; 20+ messages in thread
From: kernel test robot @ 2026-01-12 16:38 UTC (permalink / raw)
  To: Ranjan Kumar, linux-scsi, martin.petersen
  Cc: llvm, oe-kbuild-all, rajsekhar.chundru, sathya.prakash,
	chandrakanth.patil, prayas.patel, salomondush, Ranjan Kumar

Hi Ranjan,

kernel test robot noticed the following build warnings:

[auto build test WARNING on mkp-scsi/for-next]
[also build test WARNING on jejb-scsi/for-next linus/master v6.19-rc5 next-20260109]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ranjan-Kumar/mpi3mr-Add-module-parameter-to-control-threaded-IRQ-polling/20260112-162241
base:   https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git for-next
patch link:    https://lore.kernel.org/r/20260112081037.74376-5-ranjan.kumar%40broadcom.com
patch subject: [PATCH v1 4/7] mpi3mr: Use negotiated link rate from DevicePage0
config: x86_64-rhel-9.4-rust (https://download.01.org/0day-ci/archive/20260113/202601130005.zkxx1m3u-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
rustc: rustc 1.88.0 (6b00bc388 2025-06-23)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260113/202601130005.zkxx1m3u-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601130005.zkxx1m3u-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/scsi/mpi3mr/mpi3mr_os.c:1220:2: warning: unannotated fall-through between switch labels [-Wimplicit-fallthrough]
    1220 |         default:
         |         ^
   drivers/scsi/mpi3mr/mpi3mr_os.c:1220:2: note: insert 'break;' to avoid fall-through
    1220 |         default:
         |         ^
         |         break; 
   1 warning generated.


vim +1220 drivers/scsi/mpi3mr/mpi3mr_os.c

  1153	
  1154		if (!(mrioc->logging_level &
  1155		    (MPI3_DEBUG_EVENT | MPI3_DEBUG_EVENT_WORK_TASK)))
  1156			return;
  1157	
  1158		ioc_info(mrioc,
  1159		    "device_pg0: handle(0x%04x), perst_id(%d), wwid(0x%016llx), encl_handle(0x%04x), slot(%d)\n",
  1160		    le16_to_cpu(dev_pg0->dev_handle),
  1161		    le16_to_cpu(dev_pg0->persistent_id),
  1162		    le64_to_cpu(dev_pg0->wwid), le16_to_cpu(dev_pg0->enclosure_handle),
  1163		    le16_to_cpu(dev_pg0->slot));
  1164		ioc_info(mrioc, "device_pg0: access_status(0x%02x), flags(0x%04x), device_form(0x%02x), queue_depth(%d)\n",
  1165		    dev_pg0->access_status, le16_to_cpu(dev_pg0->flags),
  1166		    dev_pg0->device_form, le16_to_cpu(dev_pg0->queue_depth));
  1167		ioc_info(mrioc, "device_pg0: parent_handle(0x%04x), iounit_port(%d)\n",
  1168		    le16_to_cpu(dev_pg0->parent_dev_handle), dev_pg0->io_unit_port);
  1169	
  1170		switch (dev_pg0->device_form) {
  1171		case MPI3_DEVICE_DEVFORM_SAS_SATA:
  1172		{
  1173			struct mpi3_device0_sas_sata_format *sasinf =
  1174			    &dev_pg0->device_specific.sas_sata_format;
  1175			ioc_info(mrioc,
  1176			    "device_pg0: sas_sata: sas_address(0x%016llx),flags(0x%04x),\n"
  1177			    "device_info(0x%04x), phy_num(%d), attached_phy_id(%d),negotiated_link_rate(0x%02x)\n",
  1178			    le64_to_cpu(sasinf->sas_address),
  1179			    le16_to_cpu(sasinf->flags),
  1180			    le16_to_cpu(sasinf->device_info), sasinf->phy_num,
  1181			    sasinf->attached_phy_identifier, sasinf->negotiated_link_rate);
  1182			break;
  1183		}
  1184		case MPI3_DEVICE_DEVFORM_PCIE:
  1185		{
  1186			struct mpi3_device0_pcie_format *pcieinf =
  1187			    &dev_pg0->device_specific.pcie_format;
  1188			ioc_info(mrioc,
  1189			    "device_pg0: pcie: port_num(%d), device_info(0x%04x), mdts(%d), page_sz(0x%02x)\n",
  1190			    pcieinf->port_num, le16_to_cpu(pcieinf->device_info),
  1191			    le32_to_cpu(pcieinf->maximum_data_transfer_size),
  1192			    pcieinf->page_size);
  1193			ioc_info(mrioc,
  1194			    "device_pg0: pcie: abort_timeout(%d), reset_timeout(%d) capabilities (0x%08x)\n",
  1195			    pcieinf->nvme_abort_to, pcieinf->controller_reset_to,
  1196			    le32_to_cpu(pcieinf->capabilities));
  1197			break;
  1198		}
  1199		case MPI3_DEVICE_DEVFORM_VD:
  1200		{
  1201			struct mpi3_device0_vd_format *vdinf =
  1202			    &dev_pg0->device_specific.vd_format;
  1203	
  1204			ioc_info(mrioc,
  1205			    "device_pg0: vd: state(0x%02x), raid_level(%d), flags(0x%04x),\n"
  1206			    "device_info(0x%04x) abort_timeout(%d), reset_timeout(%d)\n",
  1207			    vdinf->vd_state, vdinf->raid_level,
  1208			    le16_to_cpu(vdinf->flags),
  1209			    le16_to_cpu(vdinf->device_info),
  1210			    vdinf->vd_abort_to, vdinf->vd_reset_to);
  1211			ioc_info(mrioc,
  1212			    "device_pg0: vd: tg_id(%d), high(%dMiB), low(%dMiB), qd_reduction_factor(%d)\n",
  1213			    vdinf->io_throttle_group,
  1214			    le16_to_cpu(vdinf->io_throttle_group_high),
  1215			    le16_to_cpu(vdinf->io_throttle_group_low),
  1216			    ((le16_to_cpu(vdinf->flags) &
  1217			       MPI3_DEVICE0_VD_FLAGS_IO_THROTTLE_GROUP_QD_MASK) >> 12));
  1218	
  1219		}
> 1220		default:
  1221			break;
  1222		}
  1223	}
  1224	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 2/7] mpi3mr: Rename log data save helper to reflect threaded/BH context
  2026-01-12 14:13   ` Damien Le Moal
@ 2026-01-13  7:27     ` Ranjan Kumar
  2026-01-15  8:45       ` Ranjan Kumar
  0 siblings, 1 reply; 20+ messages in thread
From: Ranjan Kumar @ 2026-01-13  7:27 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, martin.petersen, rajsekhar.chundru, sathya.prakash,
	chandrakanth.patil, prayas.patel, salomondush

[-- Attachment #1: Type: text/plain, Size: 3959 bytes --]

Hi Damien,

On Mon, Jan 12, 2026 at 7:43 PM Damien Le Moal <dlemoal@kernel.org> wrote:
>
> On 1/12/26 09:10, Ranjan Kumar wrote:
> > Log data events can be processed from BH and threaded contexts.
> > Rename the save helper to document its intended usage and improve
> > readability of the event handling flow.
> >
> > Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
> > ---
> >  drivers/scsi/mpi3mr/mpi3mr.h     | 2 +-
> >  drivers/scsi/mpi3mr/mpi3mr_app.c | 4 ++--
> >  drivers/scsi/mpi3mr/mpi3mr_os.c  | 8 +++++++-
> >  3 files changed, 10 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
> > index 31d68c151b20..611a51a353c9 100644
> > --- a/drivers/scsi/mpi3mr/mpi3mr.h
> > +++ b/drivers/scsi/mpi3mr/mpi3mr.h
> > @@ -1508,7 +1508,7 @@ void mpi3mr_pel_get_seqnum_complete(struct mpi3mr_ioc *mrioc,
> >       struct mpi3mr_drv_cmd *drv_cmd);
> >  int mpi3mr_pel_get_seqnum_post(struct mpi3mr_ioc *mrioc,
> >       struct mpi3mr_drv_cmd *drv_cmd);
> > -void mpi3mr_app_save_logdata(struct mpi3mr_ioc *mrioc, char *event_data,
> > +void mpi3mr_app_save_logdata_th(struct mpi3mr_ioc *mrioc, char *event_data,
> >       u16 event_data_size);
> >  struct mpi3mr_enclosure_node *mpi3mr_enclosure_find_by_handle(
> >       struct mpi3mr_ioc *mrioc, u16 handle);
> > diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
> > index 0e5478d62580..37cca0573ddc 100644
> > --- a/drivers/scsi/mpi3mr/mpi3mr_app.c
> > +++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
> > @@ -2920,7 +2920,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
> >  }
> >
> >  /**
> > - * mpi3mr_app_save_logdata - Save Log Data events
> > + * mpi3mr_app_save_logdata_th - Save Log Data events
> >   * @mrioc: Adapter instance reference
> >   * @event_data: event data associated with log data event
> >   * @event_data_size: event data size to copy
> > @@ -2932,7 +2932,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
> >   *
> >   * Return:Nothing
> >   */
> > -void mpi3mr_app_save_logdata(struct mpi3mr_ioc *mrioc, char *event_data,
> > +void mpi3mr_app_save_logdata_th(struct mpi3mr_ioc *mrioc, char *event_data,
> >       u16 event_data_size)
> >  {
> >       u32 index = mrioc->logdata_buf_idx, sz;
> > diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
> > index d4ca878d0886..4dbf2f337212 100644
> > --- a/drivers/scsi/mpi3mr/mpi3mr_os.c
> > +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
> > @@ -1962,7 +1962,7 @@ static void mpi3mr_pcietopochg_evt_bh(struct mpi3mr_ioc *mrioc,
> >  static void mpi3mr_logdata_evt_bh(struct mpi3mr_ioc *mrioc,
> >       struct mpi3mr_fwevt *fwevt)
> >  {
> > -     mpi3mr_app_save_logdata(mrioc, fwevt->event_data,
> > +     mpi3mr_app_save_logdata_th(mrioc, fwevt->event_data,
> >           fwevt->event_data_size);
> >  }
> >
> > @@ -3058,6 +3058,12 @@ void mpi3mr_os_handle_events(struct mpi3mr_ioc *mrioc,
> >       }
> >       case MPI3_EVENT_DEVICE_INFO_CHANGED:
> >       case MPI3_EVENT_LOG_DATA:
> > +     {
>
> The curly brackets are not necessary.
[Ranjan] :  The extra braces around the MPI3_EVENT_LOG_DATA case are
unnecessary.
I’ll remove them in the next revision.
>
> > +             sz = event_reply->event_data_length * 4;
> > +             mpi3mr_app_save_logdata_th(mrioc,
> > +                 (char *)event_reply->event_data, sz);
>
> Do you really need the cast here ?
[Ranjan]:
The cast to (char *) is not required since event_reply->event_data is
already compatible with the helper prototype.
I’ll drop the cast as well.
I’ll address these and resend in v2.

>
> > +             break;
> > +     }
> >       case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE:
> >       case MPI3_EVENT_ENCL_DEVICE_ADDED:
> >       {
>
>
> --
> Damien Le Moal
> Western Digital Research

Thanks,
Ranjan

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5469 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 1/7] mpi3mr: Add module parameter to control threaded IRQ polling
  2026-01-12 14:14   ` Damien Le Moal
@ 2026-01-13 17:36     ` Ranjan Kumar
  0 siblings, 0 replies; 20+ messages in thread
From: Ranjan Kumar @ 2026-01-13 17:36 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, martin.petersen, rajsekhar.chundru, sathya.prakash,
	chandrakanth.patil, prayas.patel, salomondush

[-- Attachment #1: Type: text/plain, Size: 2779 bytes --]

Hi Damien,

On Mon, Jan 12, 2026 at 7:44 PM Damien Le Moal <dlemoal@kernel.org> wrote:
>
> On 1/12/26 09:10, Ranjan Kumar wrote:
> > Add a module parameter to enable or disable threaded IRQ polling
> > in the driver. The default behavior remains unchanged
> > with polling enabled.
> >
> > When disabled, completion processing is kept entirely in the
> > hard IRQ context, avoiding the threaded polling path.
>
> What does that bring ? Better throughput ? Lower latency ? please tell us more
> about the benefits of this change.
>
[Ranjan]: SAS/SATA  completes IOs slowly, so IO polling would increase
CPU utilization, and interrupt-driven
completions are useful whereas for NVMe devices, IO polling is
beneficial as the device completes IOs fast.
> >
> > Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
> > ---
> >  drivers/scsi/mpi3mr/mpi3mr_fw.c | 9 +++++++--
> >  1 file changed, 7 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
> > index 8fe6e0bf342e..869e525f3e73 100644
> > --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
> > +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
> > @@ -21,6 +21,10 @@ static int mpi3mr_check_op_admin_proc(struct mpi3mr_ioc *mrioc);
> >  static int poll_queues;
> >  module_param(poll_queues, int, 0444);
> >  MODULE_PARM_DESC(poll_queues, "Number of queues for io_uring poll mode. (Range 1 - 126)");
> > +static bool threaded_isr_poll = true;
> > +module_param(threaded_isr_poll, bool, 0444);
> > +MODULE_PARM_DESC(threaded_isr_poll,
> > +                     "Enablement of IRQ polling thread (default=true)");
> >
> >  #if defined(writeq) && defined(CONFIG_64BIT)
> >  static inline void mpi3mr_writeq(__u64 b, void __iomem *addr,
> > @@ -595,7 +599,8 @@ int mpi3mr_process_op_reply_q(struct mpi3mr_ioc *mrioc,
> >                * Exit completion loop to avoid CPU lockup
> >                * Ensure remaining completion happens from threaded ISR.
> >                */
> > -             if (num_op_reply > mrioc->max_host_ios) {
> > +             if ((num_op_reply > mrioc->max_host_ios) &&
> > +                     (threaded_isr_poll == true)) {
> >                       op_reply_q->enable_irq_poll = true;
> >                       break;
> >               }
> > @@ -692,7 +697,7 @@ static irqreturn_t mpi3mr_isr(int irq, void *privdata)
> >        * If more IOs are expected, schedule IRQ polling thread.
> >        * Otherwise exit from ISR.
> >        */
> > -     if (!intr_info->op_reply_q)
> > +     if ((threaded_isr_poll == false) || !intr_info->op_reply_q)
> >               return ret;
> >
> >       if (!intr_info->op_reply_q->enable_irq_poll ||
>
>
> --
> Damien Le Moal
> Western Digital Research

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5469 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 5/7] mpi3mr: Update MPI Headers to revision 39
  2026-01-12 14:21   ` Damien Le Moal
@ 2026-01-13 17:39     ` Ranjan Kumar
  0 siblings, 0 replies; 20+ messages in thread
From: Ranjan Kumar @ 2026-01-13 17:39 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, martin.petersen, rajsekhar.chundru, sathya.prakash,
	chandrakanth.patil, prayas.patel, salomondush

[-- Attachment #1: Type: text/plain, Size: 1130 bytes --]

Hi Damien,

On Mon, Jan 12, 2026 at 7:51 PM Damien Le Moal <dlemoal@kernel.org> wrote:
>
> On 1/12/26 09:10, Ranjan Kumar wrote:
> > -#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_RELEASED             (0x01)
> > -#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_PAUSED               (0x02)
> > -#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_RESUMED              (0x03)
> > +#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_RELEASED     (0x01)
>
> Why the alignment change ?
>[Ranjan]: unintentional, will restore original alignment.
> > +#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_PAUSED               (0x02)
> > +#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_RESUMED              (0x03)
> > +#define MPI3_EVENT_DIAG_BUFFER_STATUS_CHANGE_RC_CLEARED              (0x04)
>
> A white line here would be nice to separate things.
>
> >  #define MPI3_PEL_LOCALE_FLAGS_NON_BLOCKING_BOOT_EVENT   (0x0200)
> >  #define MPI3_PEL_LOCALE_FLAGS_BLOCKING_BOOT_EVENT       (0x0100)
> >  #define MPI3_PEL_LOCALE_FLAGS_PCIE                      (0x0080)
>
>
>
> --
> Damien Le Moal
> Western Digital Research

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5469 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 4/7] mpi3mr: Use negotiated link rate from DevicePage0
  2026-01-12 14:18   ` Damien Le Moal
@ 2026-01-13 17:46     ` Ranjan Kumar
  0 siblings, 0 replies; 20+ messages in thread
From: Ranjan Kumar @ 2026-01-13 17:46 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, martin.petersen, rajsekhar.chundru, sathya.prakash,
	chandrakanth.patil, prayas.patel, salomondush

[-- Attachment #1: Type: text/plain, Size: 11560 bytes --]

Hi Damien,

On Mon, Jan 12, 2026 at 7:48 PM Damien Le Moal <dlemoal@kernel.org> wrote:
>
> On 1/12/26 09:10, Ranjan Kumar wrote:
> > Firmware populates the negotiated SAS link rate in DevicePage0
> > during device discovery. Update mpi3mr to cache this value while
> > initializing the target device.
> >
> > When available, the cached link rate is used instead of issuing
> > additional SAS PHY or expander PHY page reads.
> > If the DevicePage0 value is missing or invalid, the driver
> > falls back to the existing PHY-based mechanism.
> >
> > Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
> > ---
> >  drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h   |  2 +
> >  drivers/scsi/mpi3mr/mpi3mr.h           |  2 +
> >  drivers/scsi/mpi3mr/mpi3mr_os.c        | 88 ++++++++++++++++++++++++++
> >  drivers/scsi/mpi3mr/mpi3mr_transport.c | 30 +++++----
> >  4 files changed, 110 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
> > index 8c8bfbbdd34e..67d72b82cbe0 100644
> > --- a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
> > +++ b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
> > @@ -2314,6 +2314,8 @@ struct mpi3_device0_sas_sata_format {
> >       u8         attached_phy_identifier;
> >       u8         max_port_connections;
> >       u8         zone_group;
> > +     u8         reserved10[3];
> > +     u8         negotiated_link_rate;
> >  };
> >
> >  #define MPI3_DEVICE0_SASSATA_FLAGS_WRITE_SAME_UNMAP_NCQ (0x0400)
> > diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
> > index 611a51a353c9..590c017acf25 100644
> > --- a/drivers/scsi/mpi3mr/mpi3mr.h
> > +++ b/drivers/scsi/mpi3mr/mpi3mr.h
> > @@ -643,6 +643,7 @@ struct mpi3mr_enclosure_node {
> >   * @dev_info: Device information bits
> >   * @phy_id: Phy identifier provided in device page 0
> >   * @attached_phy_id: Attached phy identifier provided in device page 0
> > + * @negotiated_link_rate: Negotiated link rate from device page 0
> >   * @sas_transport_attached: Is this device exposed to transport
> >   * @pend_sas_rphy_add: Flag to check device is in process of add
> >   * @hba_port: HBA port entry
> > @@ -654,6 +655,7 @@ struct tgt_dev_sas_sata {
> >       u16 dev_info;
> >       u8 phy_id;
> >       u8 attached_phy_id;
> > +     u8 negotiated_link_rate;
> >       u8 sas_transport_attached;
> >       u8 pend_sas_rphy_add;
> >       struct mpi3mr_hba_port *hba_port;
> > diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
> > index 4dbf2f337212..ac94654494ba 100644
> > --- a/drivers/scsi/mpi3mr/mpi3mr_os.c
> > +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
> > @@ -1138,6 +1138,90 @@ static void mpi3mr_refresh_tgtdevs(struct mpi3mr_ioc *mrioc)
> >       }
> >  }
> >
> > +/**
> > + * mpi3mr_debug_dump_devpg0 - Dump device page0
> > + * @mrioc: Adapter instance reference
> > + * @dev_pg0: Device page 0.
> > + *
> > + * Prints pertinent details of the device page 0.
> > + *
> > + * Return: Nothing.
> > + */
> > +static void
> > +mpi3mr_debug_dump_devpg0(struct mpi3mr_ioc *mrioc, struct mpi3_device_page0 *dev_pg0)
> > +{
> > +
>
> No need for this blank line.
>
> > +     if (!(mrioc->logging_level &
> > +         (MPI3_DEBUG_EVENT | MPI3_DEBUG_EVENT_WORK_TASK)))
> > +             return;
>
> Please move this test in the caller so that we can avoid a function call for
> nothing if debug is not enabled.
>
> > +
> > +     ioc_info(mrioc,
> > +         "device_pg0: handle(0x%04x), perst_id(%d), wwid(0x%016llx), encl_handle(0x%04x), slot(%d)\n",
> > +         le16_to_cpu(dev_pg0->dev_handle),
> > +         le16_to_cpu(dev_pg0->persistent_id),
> > +         le64_to_cpu(dev_pg0->wwid), le16_to_cpu(dev_pg0->enclosure_handle),
> > +         le16_to_cpu(dev_pg0->slot));
> > +     ioc_info(mrioc, "device_pg0: access_status(0x%02x), flags(0x%04x), device_form(0x%02x), queue_depth(%d)\n",
> > +         dev_pg0->access_status, le16_to_cpu(dev_pg0->flags),
> > +         dev_pg0->device_form, le16_to_cpu(dev_pg0->queue_depth));
> > +     ioc_info(mrioc, "device_pg0: parent_handle(0x%04x), iounit_port(%d)\n",
> > +         le16_to_cpu(dev_pg0->parent_dev_handle), dev_pg0->io_unit_port);
> > +
> > +     switch (dev_pg0->device_form) {
> > +     case MPI3_DEVICE_DEVFORM_SAS_SATA:
> > +     {
> > +             struct mpi3_device0_sas_sata_format *sasinf =
> > +                 &dev_pg0->device_specific.sas_sata_format;
>
> Please add a blank line after declarations. Same comment applies to other cases
> below.
>
> > +             ioc_info(mrioc,
> > +                 "device_pg0: sas_sata: sas_address(0x%016llx),flags(0x%04x),\n"
> > +                 "device_info(0x%04x), phy_num(%d), attached_phy_id(%d),negotiated_link_rate(0x%02x)\n",
> > +                 le64_to_cpu(sasinf->sas_address),
> > +                 le16_to_cpu(sasinf->flags),
> > +                 le16_to_cpu(sasinf->device_info), sasinf->phy_num,
> > +                 sasinf->attached_phy_identifier, sasinf->negotiated_link_rate);
> > +             break;
> > +     }
> > +     case MPI3_DEVICE_DEVFORM_PCIE:
> > +     {
> > +             struct mpi3_device0_pcie_format *pcieinf =
> > +                 &dev_pg0->device_specific.pcie_format;
> > +             ioc_info(mrioc,
> > +                 "device_pg0: pcie: port_num(%d), device_info(0x%04x), mdts(%d), page_sz(0x%02x)\n",
> > +                 pcieinf->port_num, le16_to_cpu(pcieinf->device_info),
> > +                 le32_to_cpu(pcieinf->maximum_data_transfer_size),
> > +                 pcieinf->page_size);
> > +             ioc_info(mrioc,
> > +                 "device_pg0: pcie: abort_timeout(%d), reset_timeout(%d) capabilities (0x%08x)\n",
> > +                 pcieinf->nvme_abort_to, pcieinf->controller_reset_to,
> > +                 le32_to_cpu(pcieinf->capabilities));
> > +             break;
> > +     }
> > +     case MPI3_DEVICE_DEVFORM_VD:
> > +     {
> > +             struct mpi3_device0_vd_format *vdinf =
> > +                 &dev_pg0->device_specific.vd_format;
> > +
> > +             ioc_info(mrioc,
> > +                 "device_pg0: vd: state(0x%02x), raid_level(%d), flags(0x%04x),\n"
> > +                 "device_info(0x%04x) abort_timeout(%d), reset_timeout(%d)\n",
> > +                 vdinf->vd_state, vdinf->raid_level,
> > +                 le16_to_cpu(vdinf->flags),
> > +                 le16_to_cpu(vdinf->device_info),
> > +                 vdinf->vd_abort_to, vdinf->vd_reset_to);
> > +             ioc_info(mrioc,
> > +                 "device_pg0: vd: tg_id(%d), high(%dMiB), low(%dMiB), qd_reduction_factor(%d)\n",
> > +                 vdinf->io_throttle_group,
> > +                 le16_to_cpu(vdinf->io_throttle_group_high),
> > +                 le16_to_cpu(vdinf->io_throttle_group_low),
> > +                 ((le16_to_cpu(vdinf->flags) &
> > +                    MPI3_DEVICE0_VD_FLAGS_IO_THROTTLE_GROUP_QD_MASK) >> 12));
> > +
> > +     }
> > +     default:
> > +             break;
> > +     }
> > +}
> > +
> >  /**
> >   * mpi3mr_update_tgtdev - DevStatusChange evt bottomhalf
> >   * @mrioc: Adapter instance reference
> > @@ -1159,6 +1243,8 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
> >       struct mpi3mr_enclosure_node *enclosure_dev = NULL;
> >       u8 prot_mask = 0;
> >
> > +     mpi3mr_debug_dump_devpg0(mrioc, dev_pg0);
> > +
> >       tgtdev->perst_id = le16_to_cpu(dev_pg0->persistent_id);
> >       tgtdev->dev_handle = le16_to_cpu(dev_pg0->dev_handle);
> >       tgtdev->dev_type = dev_pg0->device_form;
> > @@ -1237,6 +1323,8 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
> >               tgtdev->dev_spec.sas_sata_inf.phy_id = sasinf->phy_num;
> >               tgtdev->dev_spec.sas_sata_inf.attached_phy_id =
> >                   sasinf->attached_phy_identifier;
> > +             tgtdev->dev_spec.sas_sata_inf.negotiated_link_rate =
> > +                     sasinf->negotiated_link_rate;
> >               if ((dev_info & MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_MASK) !=
> >                   MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_END_DEVICE)
> >                       tgtdev->is_hidden = 1;
> > diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c
> > index d70f002d6487..101161554ef1 100644
> > --- a/drivers/scsi/mpi3mr/mpi3mr_transport.c
> > +++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c
> > @@ -2284,11 +2284,11 @@ void mpi3mr_expander_remove(struct mpi3mr_ioc *mrioc, u64 sas_address,
> >   * @mrioc: Adapter instance reference
> >   * @tgtdev: Target device
> >   *
> > - * This function identifies whether the target device is
> > - * attached directly or through expander and issues sas phy
> > - * page0 or expander phy page1 and gets the link rate, if there
> > - * is any failure in reading the pages then this returns link
> > - * rate of 1.5.
> > + * This function first tries to use the link rate from DevicePage0
> > + * (populated by firmware during device discovery). If the cached
> > + * value is not available or invalid, it falls back to reading from
> > + * sas phy page0 or expander phy page1.
> > + *
> >   *
> >   * Return: logical link rate.
> >   */
> > @@ -2301,6 +2301,14 @@ static u8 mpi3mr_get_sas_negotiated_logical_linkrate(struct mpi3mr_ioc *mrioc,
> >       u32 phynum_handle;
> >       u16 ioc_status;
> >
> > +     /* First, try to use link rate from DevicePage0 (populated by firmware) */
> > +     if (tgtdev->dev_spec.sas_sata_inf.negotiated_link_rate >=
> > +         MPI3_SAS_NEG_LINK_RATE_1_5) {
> > +             link_rate = tgtdev->dev_spec.sas_sata_inf.negotiated_link_rate;
> > +             goto out;
> > +     }
> > +
> > +     /* Fallback to reading from phy pages if DevicePage0 value not available */
> >       phy_number = tgtdev->dev_spec.sas_sata_inf.phy_id;
> >       if (!(tgtdev->devpg0_flag & MPI3_DEVICE0_FLAGS_ATT_METHOD_DIR_ATTACHED)) {
> >               phynum_handle = ((phy_number<<MPI3_SAS_EXPAND_PGAD_PHYNUM_SHIFT)
> > @@ -2318,9 +2326,7 @@ static u8 mpi3mr_get_sas_negotiated_logical_linkrate(struct mpi3mr_ioc *mrioc,
> >                           __FILE__, __LINE__, __func__);
> >                       goto out;
> >               }
> > -             link_rate = (expander_pg1.negotiated_link_rate &
> > -                          MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
> > -                     MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT;
> > +             link_rate = expander_pg1.negotiated_link_rate;
> >               goto out;
> >       }
> >       if (mpi3mr_cfg_get_sas_phy_pg0(mrioc, &ioc_status, &phy_pg0,
> > @@ -2335,11 +2341,11 @@ static u8 mpi3mr_get_sas_negotiated_logical_linkrate(struct mpi3mr_ioc *mrioc,
> >                   __FILE__, __LINE__, __func__);
> >               goto out;
> >       }
> > -     link_rate = (phy_pg0.negotiated_link_rate &
> > -                  MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
> > -             MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT;
> > +     link_rate = phy_pg0.negotiated_link_rate;
> > +
> >  out:
> > -     return link_rate;
> > +     return ((link_rate & MPI3_SAS_NEG_LINK_RATE_LOGICAL_MASK) >>
> > +             MPI3_SAS_NEG_LINK_RATE_LOGICAL_SHIFT);
> >  }
> >
> >  /**
>
[Ranja]: Thanks for the review. I will do the changes and will resend v2.
>
> --
> Damien Le Moal
> Western Digital Research

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5469 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 6/7] mpi3mr: Record and report controller firmware faults
  2026-01-12 14:25   ` Damien Le Moal
@ 2026-01-13 18:28     ` Ranjan Kumar
  0 siblings, 0 replies; 20+ messages in thread
From: Ranjan Kumar @ 2026-01-13 18:28 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, martin.petersen, rajsekhar.chundru, sathya.prakash,
	chandrakanth.patil, prayas.patel, salomondush

[-- Attachment #1: Type: text/plain, Size: 1419 bytes --]

Hi Damien,

On Mon, Jan 12, 2026 at 7:55 PM Damien Le Moal <dlemoal@kernel.org> wrote:
>
> On 1/12/26 09:10, Ranjan Kumar wrote:
> > +static void mpi3mr_fault_uevent_emit(struct mpi3mr_ioc *mrioc)
> > +{
> > +     struct kobj_uevent_env *env;
> > +
> > +     env = kzalloc(sizeof(*env), GFP_KERNEL);
> > +     if (!env)
> > +             return;
> > +
> > +     if (add_uevent_var(env, "DRIVER=%s", mrioc->driver_name))
> > +             return;
>
> All the returns in this function are leaking env...
>
> > +     if (add_uevent_var(env, "IOC_ID=%u", mrioc->id))
> > +             return;
> > +     if (add_uevent_var(env, "FAULT_CODE=0x%08x", mrioc->saved_fault_code))
> > +             return;
> > +     if (add_uevent_var(env, "FAULT_INFO0=0x%08x",
> > +          mrioc->saved_fault_info[0]))
> > +             return;
> > +     if (add_uevent_var(env, "FAULT_INFO1=0x%08x",
> > +          mrioc->saved_fault_info[1]))
> > +             return;
> > +     if (add_uevent_var(env, "FAULT_INFO2=0x%08x",
> > +         mrioc->saved_fault_info[2]))
> > +             return;
> > +
> > +     kobject_uevent_env(&mrioc->shost->shost_gendev.kobj,
> > +         KOBJ_CHANGE, env->envp);
>
> Please align the arguments after the "(".
>
> > +     kfree(env);
> > +}
>
[Ranjan]: I will resend v2 by fixing the leak and alignment.
>
> --
> Damien Le Moal
> Western Digital Research

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5469 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v1 2/7] mpi3mr: Rename log data save helper to reflect threaded/BH context
  2026-01-13  7:27     ` Ranjan Kumar
@ 2026-01-15  8:45       ` Ranjan Kumar
  0 siblings, 0 replies; 20+ messages in thread
From: Ranjan Kumar @ 2026-01-15  8:45 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: linux-scsi, martin.petersen, rajsekhar.chundru, sathya.prakash,
	chandrakanth.patil, prayas.patel, salomondush

[-- Attachment #1: Type: text/plain, Size: 4503 bytes --]

Hi Damien,

On Tue, Jan 13, 2026 at 12:57 PM Ranjan Kumar <ranjan.kumar@broadcom.com> wrote:
>
> Hi Damien,
>
> On Mon, Jan 12, 2026 at 7:43 PM Damien Le Moal <dlemoal@kernel.org> wrote:
> >
> > On 1/12/26 09:10, Ranjan Kumar wrote:
> > > Log data events can be processed from BH and threaded contexts.
> > > Rename the save helper to document its intended usage and improve
> > > readability of the event handling flow.
> > >
> > > Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
> > > ---
> > >  drivers/scsi/mpi3mr/mpi3mr.h     | 2 +-
> > >  drivers/scsi/mpi3mr/mpi3mr_app.c | 4 ++--
> > >  drivers/scsi/mpi3mr/mpi3mr_os.c  | 8 +++++++-
> > >  3 files changed, 10 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
> > > index 31d68c151b20..611a51a353c9 100644
> > > --- a/drivers/scsi/mpi3mr/mpi3mr.h
> > > +++ b/drivers/scsi/mpi3mr/mpi3mr.h
> > > @@ -1508,7 +1508,7 @@ void mpi3mr_pel_get_seqnum_complete(struct mpi3mr_ioc *mrioc,
> > >       struct mpi3mr_drv_cmd *drv_cmd);
> > >  int mpi3mr_pel_get_seqnum_post(struct mpi3mr_ioc *mrioc,
> > >       struct mpi3mr_drv_cmd *drv_cmd);
> > > -void mpi3mr_app_save_logdata(struct mpi3mr_ioc *mrioc, char *event_data,
> > > +void mpi3mr_app_save_logdata_th(struct mpi3mr_ioc *mrioc, char *event_data,
> > >       u16 event_data_size);
> > >  struct mpi3mr_enclosure_node *mpi3mr_enclosure_find_by_handle(
> > >       struct mpi3mr_ioc *mrioc, u16 handle);
> > > diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
> > > index 0e5478d62580..37cca0573ddc 100644
> > > --- a/drivers/scsi/mpi3mr/mpi3mr_app.c
> > > +++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
> > > @@ -2920,7 +2920,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
> > >  }
> > >
> > >  /**
> > > - * mpi3mr_app_save_logdata - Save Log Data events
> > > + * mpi3mr_app_save_logdata_th - Save Log Data events
> > >   * @mrioc: Adapter instance reference
> > >   * @event_data: event data associated with log data event
> > >   * @event_data_size: event data size to copy
> > > @@ -2932,7 +2932,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
> > >   *
> > >   * Return:Nothing
> > >   */
> > > -void mpi3mr_app_save_logdata(struct mpi3mr_ioc *mrioc, char *event_data,
> > > +void mpi3mr_app_save_logdata_th(struct mpi3mr_ioc *mrioc, char *event_data,
> > >       u16 event_data_size)
> > >  {
> > >       u32 index = mrioc->logdata_buf_idx, sz;
> > > diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
> > > index d4ca878d0886..4dbf2f337212 100644
> > > --- a/drivers/scsi/mpi3mr/mpi3mr_os.c
> > > +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
> > > @@ -1962,7 +1962,7 @@ static void mpi3mr_pcietopochg_evt_bh(struct mpi3mr_ioc *mrioc,
> > >  static void mpi3mr_logdata_evt_bh(struct mpi3mr_ioc *mrioc,
> > >       struct mpi3mr_fwevt *fwevt)
> > >  {
> > > -     mpi3mr_app_save_logdata(mrioc, fwevt->event_data,
> > > +     mpi3mr_app_save_logdata_th(mrioc, fwevt->event_data,
> > >           fwevt->event_data_size);
> > >  }
> > >
> > > @@ -3058,6 +3058,12 @@ void mpi3mr_os_handle_events(struct mpi3mr_ioc *mrioc,
> > >       }
> > >       case MPI3_EVENT_DEVICE_INFO_CHANGED:
> > >       case MPI3_EVENT_LOG_DATA:
> > > +     {
> >
> > The curly brackets are not necessary.
> [Ranjan] :  The extra braces around the MPI3_EVENT_LOG_DATA case are
> unnecessary.
> I’ll remove them in the next revision.
> >
> > > +             sz = event_reply->event_data_length * 4;
> > > +             mpi3mr_app_save_logdata_th(mrioc,
> > > +                 (char *)event_reply->event_data, sz);
> >
> > Do you really need the cast here ?
> [Ranjan]:
> The cast to (char *) is not required since event_reply->event_data is
> already compatible with the helper prototype.
> I’ll drop the cast as well.
> I’ll address these and resend in v2.
>
[Ranjan]: The cast is required here since event_data is __le32 * and
the existing helper takes a byte buffer.
Removing it results in an incompatible pointer type build error.
I’ll keep the cast and remove curly brackets and will resend v2.
> >
> > > +             break;
> > > +     }
> > >       case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE:
> > >       case MPI3_EVENT_ENCL_DEVICE_ADDED:
> > >       {
> >
> >
> > --
> > Damien Le Moal
> > Western Digital Research
>
> Thanks,
> Ranjan

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5469 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2026-01-15  8:46 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-12  8:10 [PATCH v1 0/7] mpi3mr: Enhancements for mpi3mr Ranjan Kumar
2026-01-12  8:10 ` [PATCH v1 1/7] mpi3mr: Add module parameter to control threaded IRQ polling Ranjan Kumar
2026-01-12 14:14   ` Damien Le Moal
2026-01-13 17:36     ` Ranjan Kumar
2026-01-12  8:10 ` [PATCH v1 2/7] mpi3mr: Rename log data save helper to reflect threaded/BH context Ranjan Kumar
2026-01-12 14:13   ` Damien Le Moal
2026-01-13  7:27     ` Ranjan Kumar
2026-01-15  8:45       ` Ranjan Kumar
2026-01-12  8:10 ` [PATCH v1 3/7] mpi3mr: Avoid redundant diag-fault resets Ranjan Kumar
2026-01-12  8:10 ` [PATCH v1 4/7] mpi3mr: Use negotiated link rate from DevicePage0 Ranjan Kumar
2026-01-12 14:18   ` Damien Le Moal
2026-01-13 17:46     ` Ranjan Kumar
2026-01-12 16:38   ` kernel test robot
2026-01-12  8:10 ` [PATCH v1 5/7] mpi3mr: Update MPI Headers to revision 39 Ranjan Kumar
2026-01-12 14:21   ` Damien Le Moal
2026-01-13 17:39     ` Ranjan Kumar
2026-01-12  8:10 ` [PATCH v1 6/7] mpi3mr: Record and report controller firmware faults Ranjan Kumar
2026-01-12 14:25   ` Damien Le Moal
2026-01-13 18:28     ` Ranjan Kumar
2026-01-12  8:10 ` [PATCH v1 7/7] mpi3mr: Driver version update to 8.17.0.3.50 Ranjan Kumar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox