linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] scsi: mpi3mr: Add ATTO vendor support and disable firmware download
@ 2025-06-13 20:29 Steve Siwinski
  2025-06-13 20:29 ` [PATCH 2/2] scsi: mpi3mr: Add initialization for ATTO 24Gb SAS HBAs Steve Siwinski
  0 siblings, 1 reply; 6+ messages in thread
From: Steve Siwinski @ 2025-06-13 20:29 UTC (permalink / raw)
  To: mpi3mr-linuxdrv.pdl
  Cc: gustavoars, James.Bottomley, kashyap.desai, kees, linux-kernel,
	linux-scsi, martin.petersen, prayas.patel, ranjan.kumar,
	sathya.prakash, sreekanth.reddy, ssiwinski, sumit.saxena, bgrove,
	tdoedline

Add support for ATTO HBAs by defining the ATTO vendor ID and adding an
entry to the PCI device ID table for SAS4116-based ATTO devices.

Since ATTO HBAs use specialized firmware, block firmware downloads
to ATTO devices via the MPI3_FUNCTION_CI_DOWNLOAD command and return
an error.

Signed-off-by: Steve Siwinski <ssiwinski@atto.com>
---
 drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h | 1 +
 drivers/scsi/mpi3mr/mpi3mr_app.c     | 9 +++++++++
 drivers/scsi/mpi3mr/mpi3mr_os.c      | 4 ++++
 3 files changed, 14 insertions(+)

diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
index 96401eb7e231..314eb058c12d 100644
--- a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
+++ b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h
@@ -206,6 +206,7 @@ struct mpi3_config_page_header {
 #define MPI3_TEMP_SENSOR_LOCATION_OUTLET                (0x2)
 #define MPI3_TEMP_SENSOR_LOCATION_DRAM                  (0x3)
 #define MPI3_MFGPAGE_VENDORID_BROADCOM                  (0x1000)
+#define MPI3_MFGPAGE_VENDORID_ATTO                      (0x117C)
 #define MPI3_MFGPAGE_DEVID_SAS4116                      (0x00a5)
 #define MPI3_MFGPAGE_DEVID_SAS5116_MPI			(0x00b3)
 #define MPI3_MFGPAGE_DEVID_SAS5116_NVME			(0x00b4)
diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
index f36663613950..7e2d23204e6c 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_app.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
@@ -2691,6 +2691,15 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
 		goto out;
 	}
 
+	if (mrioc->pdev->subsystem_vendor == MPI3_MFGPAGE_VENDORID_ATTO &&
+		mpi_header->function == MPI3_FUNCTION_CI_DOWNLOAD) {
+		dprint_bsg_err(mrioc, "%s: Firmware download not supported for ATTO HBA.\n",
+				__func__);
+		rval = -EPERM;
+		mutex_unlock(&mrioc->bsg_cmds.mutex);
+		goto out;
+	}
+
 	if (mpi_header->function == MPI3_BSG_FUNCTION_NVME_ENCAPSULATED) {
 		nvme_fmt = mpi3mr_get_nvme_data_fmt(
 			(struct mpi3_nvme_encapsulated_request *)mpi_req);
diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
index ce444efd859e..12914400660a 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
@@ -5931,6 +5931,10 @@ static const struct pci_device_id mpi3mr_pci_id_table[] = {
 		PCI_DEVICE_SUB(MPI3_MFGPAGE_VENDORID_BROADCOM,
 		    MPI3_MFGPAGE_DEVID_SAS5116_MPI_MGMT, PCI_ANY_ID, PCI_ANY_ID)
 	},
+	{
+		PCI_DEVICE_SUB(MPI3_MFGPAGE_VENDORID_ATTO,
+		    MPI3_MFGPAGE_DEVID_SAS4116, PCI_ANY_ID, PCI_ANY_ID)
+	},
 	{ 0 }
 };
 MODULE_DEVICE_TABLE(pci, mpi3mr_pci_id_table);
-- 
2.43.5


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

* [PATCH 2/2] scsi: mpi3mr: Add initialization for ATTO 24Gb SAS HBAs
  2025-06-13 20:29 [PATCH 1/2] scsi: mpi3mr: Add ATTO vendor support and disable firmware download Steve Siwinski
@ 2025-06-13 20:29 ` Steve Siwinski
  2025-06-14  6:44   ` ALOK TIWARI
                     ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Steve Siwinski @ 2025-06-13 20:29 UTC (permalink / raw)
  To: mpi3mr-linuxdrv.pdl
  Cc: gustavoars, James.Bottomley, kashyap.desai, kees, linux-kernel,
	linux-scsi, martin.petersen, prayas.patel, ranjan.kumar,
	sathya.prakash, sreekanth.reddy, ssiwinski, sumit.saxena, bgrove,
	tdoedline

This patch adds initialization routines for ATTO 24Gb SAS HBAs.
It introduces the ATTO NVRAM structure and functions to validate
NVRAM contents.

The `mpi3mr_atto_init` function is added to handle ATTO-specific
controller initialization. This involves reading the ATTO SAS address
from Driver Page 2 and then assigning unique device names and WWIDs
to Manufacturing Page 5.

Signed-off-by: Steve Siwinski <ssiwinski@atto.com>
---
 drivers/scsi/mpi3mr/mpi3mr.h    |  35 ++++
 drivers/scsi/mpi3mr/mpi3mr_fw.c | 310 ++++++++++++++++++++++++++++++++
 2 files changed, 345 insertions(+)

diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
index 9bbc7cb98ca3..05583457ffaa 100644
--- a/drivers/scsi/mpi3mr/mpi3mr.h
+++ b/drivers/scsi/mpi3mr/mpi3mr.h
@@ -1438,6 +1438,35 @@ struct delayed_evt_ack_node {
 	u32 event_ctx;
 };
 
+/*
+ * struct ATTO_SAS_NVRAM - ATTO NVRAM settings
+ * @signature: ATTO NVRAM signature
+ * @version: ATTO NVRAM version
+ * @checksum: NVRAM checksum
+ * @sasaddr: ATTO SAS address
+ */
+struct ATTO_SAS_NVRAM {
+	u8		signature[4];
+	u8		version;
+#define ATTO_SASNVR_VERSION		0
+
+	u8		checksum;
+#define ATTO_SASNVR_CKSUM_SEED	0x5A
+	u8		pad[10];
+	u8		sasaddr[8];
+#define ATTO_SAS_ADDR_ALIGN		64
+	u8		reserved[232];
+};
+
+#define ATTO_SAS_ADDR_DEVNAME_BIAS		63
+
+union ATTO_SAS_ADDRESS {
+	u8		b[8];
+	u16		w[4];
+	u32		d[2];
+	u64		q;
+};
+
 int mpi3mr_setup_resources(struct mpi3mr_ioc *mrioc);
 void mpi3mr_cleanup_resources(struct mpi3mr_ioc *mrioc);
 int mpi3mr_init_ioc(struct mpi3mr_ioc *mrioc);
@@ -1533,10 +1562,16 @@ int mpi3mr_cfg_get_sas_io_unit_pg1(struct mpi3mr_ioc *mrioc,
 	struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1, u16 pg_sz);
 int mpi3mr_cfg_set_sas_io_unit_pg1(struct mpi3mr_ioc *mrioc,
 	struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1, u16 pg_sz);
+int mpi3mr_cfg_get_man_pg5(struct mpi3mr_ioc *mrioc,
+	struct mpi3_man_page5 *man_pg5, u16 pg_sz);
+int mpi3mr_cfg_set_man_pg5(struct mpi3mr_ioc *mrioc,
+	struct mpi3_man_page5 *man_pg5, u16 pg_sz);
 int mpi3mr_cfg_get_driver_pg1(struct mpi3mr_ioc *mrioc,
 	struct mpi3_driver_page1 *driver_pg1, u16 pg_sz);
 int mpi3mr_cfg_get_driver_pg2(struct mpi3mr_ioc *mrioc,
 	struct mpi3_driver_page2 *driver_pg2, u16 pg_sz, u8 page_type);
+int mpi3mr_cfg_get_page_size(struct mpi3mr_ioc *mrioc,
+	int page_type, int page_num);
 
 u8 mpi3mr_is_expander_device(u16 device_info);
 int mpi3mr_expander_add(struct mpi3mr_ioc *mrioc, u16 handle);
diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index 1d7901a8f0e4..c0177ad3d200 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -4203,6 +4203,163 @@ static int mpi3mr_enable_events(struct mpi3mr_ioc *mrioc)
 	return retval;
 }
 
+/**
+ * mpi3mr_atto_validate_nvram - validate the ATTO nvram
+ *
+ * @mrioc:  Adapter instance reference
+ * @nvram: ptr to the ATTO nvram structure
+ * Return: 0 for success, non-zero for failure.
+ */
+static int mpi3mr_atto_validate_nvram(struct mpi3mr_ioc *mrioc, struct ATTO_SAS_NVRAM *nvram)
+{
+	int r = -EINVAL;
+	union ATTO_SAS_ADDRESS *sasaddr;
+	u32 len;
+	u8 *pb;
+	u8 cksum;
+
+	/* validate nvram checksum */
+	pb = (u8 *) nvram;
+	cksum = ATTO_SASNVR_CKSUM_SEED;
+	len = sizeof(struct ATTO_SAS_NVRAM);
+
+	while (len--)
+		cksum = cksum + pb[len];
+
+	if (cksum) {
+		ioc_err(mrioc, "Invalid ATTO NVRAM checksum\n");
+		return r;
+	}
+
+	sasaddr = (union ATTO_SAS_ADDRESS *) nvram->sasaddr;
+
+	if (nvram->signature[0] != 'E'
+	|| nvram->signature[1] != 'S'
+	|| nvram->signature[2] != 'A'
+	|| nvram->signature[3] != 'S')
+		ioc_err(mrioc, "Invalid ATTO NVRAM signature\n");
+	else if (nvram->version > ATTO_SASNVR_VERSION)
+		ioc_info(mrioc, "Invalid ATTO NVRAM version");
+	else if ((nvram->sasaddr[7] & (ATTO_SAS_ADDR_ALIGN - 1))
+			|| sasaddr->b[0] != 0x50
+			|| sasaddr->b[1] != 0x01
+			|| sasaddr->b[2] != 0x08
+			|| (sasaddr->b[3] & 0xF0) != 0x60
+			|| ((sasaddr->b[3] & 0x0F) | le32_to_cpu(sasaddr->d[1])) == 0) {
+		ioc_err(mrioc, "Invalid ATTO SAS address\n");
+	} else
+		r = 0;
+	return r;
+}
+
+/**
+ * mpi3mr_atto_get_sas_addr - get the ATTO SAS address from driver page 2
+ *
+ * @mrioc: Adapter instance reference
+ * @*sas_address: return sas address
+ * Return: 0 for success, non-zero for failure.
+ */
+static int mpi3mr_atto_get_sas_addr(struct mpi3mr_ioc *mrioc, union ATTO_SAS_ADDRESS *sas_address)
+{
+	struct mpi3_driver_page2 *driver_pg2 = NULL;
+	struct ATTO_SAS_NVRAM *nvram;
+	u16 sz;
+	int r;
+	__be64 addr;
+
+	sz = mpi3mr_cfg_get_page_size(mrioc, MPI3_CONFIG_PAGETYPE_DRIVER, 2);
+	driver_pg2 = kzalloc(sz, GFP_KERNEL);
+	if (!driver_pg2)
+		goto out;
+
+	r = mpi3mr_cfg_get_driver_pg2(mrioc, driver_pg2, sz, MPI3_CONFIG_ACTION_READ_PERSISTENT);
+	if (r)
+		goto out;
+
+	nvram = (struct ATTO_SAS_NVRAM *) &driver_pg2->trigger;
+
+	r = mpi3mr_atto_validate_nvram(mrioc, nvram);
+	if (r)
+		goto out;
+
+	addr = *((__be64 *) nvram->sasaddr);
+	sas_address->q = cpu_to_le64(be64_to_cpu(addr));
+
+out:
+	kfree(driver_pg2);
+	return r;
+}
+
+/**
+ * mpi3mr_atto_init - Initialize the controller
+ * @mrioc: Adapter instance reference
+ *
+ * This the ATTO controller initialization routine
+ *
+ * Return: 0 on success and non-zero on failure.
+ */
+static int mpi3mr_atto_init(struct mpi3mr_ioc *mrioc)
+{
+	int i, bias = 0;
+	u16 sz;
+	struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL;
+	struct mpi3_man_page5 *man_pg5 = NULL;
+	union ATTO_SAS_ADDRESS base_address;
+	union ATTO_SAS_ADDRESS dev_address;
+	union ATTO_SAS_ADDRESS sas_address;
+
+	sz = mpi3mr_cfg_get_page_size(mrioc, MPI3_CONFIG_PAGETYPE_SAS_IO_UNIT, 0);
+	sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL);
+	if (!sas_io_unit_pg0)
+		goto out;
+
+	if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) {
+		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
+		    __FILE__, __LINE__, __func__);
+		goto out;
+	}
+
+	sz = mpi3mr_cfg_get_page_size(mrioc, MPI3_CONFIG_PAGETYPE_MANUFACTURING, 5);
+	man_pg5 = kzalloc(sz, GFP_KERNEL);
+	if (!man_pg5)
+		goto out;
+
+	if (mpi3mr_cfg_get_man_pg5(mrioc, man_pg5, sz)) {
+		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
+		    __FILE__, __LINE__, __func__);
+		goto out;
+	}
+
+	mpi3mr_atto_get_sas_addr(mrioc, &base_address);
+
+	dev_address.q = base_address.q;
+	dev_address.b[0] += ATTO_SAS_ADDR_DEVNAME_BIAS;
+
+	for (i = 0; i < man_pg5->num_phys; i++) {
+		if (sas_io_unit_pg0->phy_data[i].phy_flags &
+			(MPI3_SASIOUNIT0_PHYFLAGS_HOST_PHY |
+			MPI3_SASIOUNIT0_PHYFLAGS_VIRTUAL_PHY))
+			continue;
+
+		sas_address.q = base_address.q;
+		sas_address.b[0] += bias++;
+
+		man_pg5->phy[i].device_name = dev_address.q;
+		man_pg5->phy[i].ioc_wwid = sas_address.q;
+		man_pg5->phy[i].sata_wwid = sas_address.q;
+	}
+
+	if (mpi3mr_cfg_set_man_pg5(mrioc, man_pg5, sz))
+		ioc_info(mrioc, "ATTO set manufacuring page 5 failed\n");
+
+out:
+	kfree(sas_io_unit_pg0);
+	kfree(man_pg5);
+
+	return 0;
+}
+
+
 /**
  * mpi3mr_init_ioc - Initialize the controller
  * @mrioc: Adapter instance reference
@@ -4376,6 +4533,9 @@ int mpi3mr_init_ioc(struct mpi3mr_ioc *mrioc)
 		goto out_failed;
 	}
 
+	if (mrioc->pdev->subsystem_vendor == MPI3_MFGPAGE_VENDORID_ATTO)
+		mpi3mr_atto_init(mrioc);
+
 	ioc_info(mrioc, "controller initialization completed successfully\n");
 	return retval;
 out_failed:
@@ -6293,6 +6453,118 @@ int mpi3mr_cfg_set_sas_io_unit_pg1(struct mpi3mr_ioc *mrioc,
 	return -1;
 }
 
+/**
+ * mpi3mr_cfg_get_man_pg5 - Read manufacturing page 5
+ * @mrioc: Adapter instance reference
+ * @io_unit_pg5: Pointer to the manufacturing page 5 to read
+ * @pg_sz: Size of the memory allocated to the page pointer
+ *
+ * This is handler for config page read of manufacturing
+ * page 5.
+ *
+ * Return: 0 on success, non-zero on failure.
+ */
+int mpi3mr_cfg_get_man_pg5(struct mpi3mr_ioc *mrioc,
+	struct mpi3_man_page5 *man_pg5, u16 pg_sz)
+{
+	struct mpi3_config_page_header cfg_hdr;
+	struct mpi3_config_request cfg_req;
+	u16 ioc_status = 0;
+
+	memset(man_pg5, 0, pg_sz);
+	memset(&cfg_hdr, 0, sizeof(cfg_hdr));
+	memset(&cfg_req, 0, sizeof(cfg_req));
+
+	cfg_req.function = MPI3_FUNCTION_CONFIG;
+	cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER;
+	cfg_req.page_type = MPI3_CONFIG_PAGETYPE_MANUFACTURING;
+	cfg_req.page_number = 5;
+	cfg_req.page_address = 0;
+
+	if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL,
+	    MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, &cfg_hdr, sizeof(cfg_hdr))) {
+		ioc_err(mrioc, "manufacturing page5 header read failed\n");
+		goto out_failed;
+	}
+	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
+		ioc_err(mrioc, "manufacturing page5 header read failed with ioc_status(0x%04x)\n",
+		    ioc_status);
+		goto out_failed;
+	}
+
+	cfg_req.action = MPI3_CONFIG_ACTION_READ_CURRENT;
+
+	if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr,
+	    MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, man_pg5, pg_sz)) {
+		ioc_err(mrioc, "manufacturing page5 read failed\n");
+		goto out_failed;
+	}
+	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
+		ioc_err(mrioc, "manufacturing page5 read failed with ioc_status(0x%04x)\n",
+		    ioc_status);
+		goto out_failed;
+	}
+	return 0;
+out_failed:
+	return -1;
+}
+
+/**
+ * mpi3mr_cfg_set_man_pg5 - Write manufacturing page 5
+ * @mrioc: Adapter instance reference
+ * @io_unit_pg5: Pointer to the manufacturing page 5 to write
+ * @pg_sz: Size of the memory allocated to the page pointer
+ *
+ * This is handler for config page write for manufacturing
+ * page 5. This will modify only the current page.
+ *
+ * Return: 0 on success, non-zero on failure.
+ */
+int mpi3mr_cfg_set_man_pg5(struct mpi3mr_ioc *mrioc,
+	struct mpi3_man_page5 *man_pg5, u16 pg_sz)
+{
+	struct mpi3_config_page_header cfg_hdr;
+	struct mpi3_config_request cfg_req;
+	u16 ioc_status = 0;
+
+	memset(&cfg_hdr, 0, sizeof(cfg_hdr));
+	memset(&cfg_req, 0, sizeof(cfg_req));
+
+	cfg_req.function = MPI3_FUNCTION_CONFIG;
+	cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER;
+	cfg_req.page_type = MPI3_CONFIG_PAGETYPE_MANUFACTURING;
+	cfg_req.page_number = 5;
+	cfg_req.page_address = 0;
+
+	if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL,
+	    MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, &cfg_hdr, sizeof(cfg_hdr))) {
+		ioc_err(mrioc, "manufacturing page5 header read failed\n");
+		goto out_failed;
+	}
+	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
+		ioc_err(mrioc, "manufacturing page5 header read failed with ioc_status(0x%04x)\n",
+		    ioc_status);
+		goto out_failed;
+	}
+
+	cfg_req.action = MPI3_CONFIG_ACTION_WRITE_CURRENT;
+
+	if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr,
+	    MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, man_pg5, pg_sz)) {
+		ioc_err(mrioc, "manufacturing page5 write failed\n");
+		goto out_failed;
+	}
+	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
+		ioc_err(mrioc, "manufacturing page5 write failed with ioc_status(0x%04x)\n",
+		    ioc_status);
+		goto out_failed;
+	}
+
+	return 0;
+out_failed:
+	return -1;
+}
+
 /**
  * mpi3mr_cfg_get_driver_pg1 - Read current Driver page1
  * @mrioc: Adapter instance reference
@@ -6409,3 +6681,41 @@ int mpi3mr_cfg_get_driver_pg2(struct mpi3mr_ioc *mrioc,
 	return -1;
 }
 
+/**
+ * mpi3mr_cfg_get_page_size - Get the size of requested page
+ * @mrioc: Adapter instance reference
+ * @page_type: Page type (MPI3_CONFIG_PAGETYPE_XXX)
+ * @page_num: Page number
+ *
+ * Return the specified config page size in bytes.
+ *
+ * Return: Page size in bytes, -1 on failure.
+ */
+int mpi3mr_cfg_get_page_size(struct mpi3mr_ioc *mrioc, int page_type, int page_num)
+{
+	struct mpi3_config_page_header cfg_hdr;
+	struct mpi3_config_request cfg_req;
+	u16 ioc_status = 0;
+
+	memset(&cfg_hdr, 0, sizeof(cfg_hdr));
+	memset(&cfg_req, 0, sizeof(cfg_req));
+
+	cfg_req.function = MPI3_FUNCTION_CONFIG;
+	cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER;
+	cfg_req.page_type = page_type;
+	cfg_req.page_number = page_num;
+	cfg_req.page_address = 0;
+
+	if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL,
+	    MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, &cfg_hdr, sizeof(cfg_hdr))) {
+		ioc_err(mrioc, "header read failed\n");
+		return -1;
+	}
+	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
+		ioc_err(mrioc, "header read failed with ioc_status(0x%04x)\n",
+		    ioc_status);
+		return -1;
+	}
+
+	return cfg_hdr.page_length * 4;
+}
-- 
2.43.5


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

* Re: [PATCH 2/2] scsi: mpi3mr: Add initialization for ATTO 24Gb SAS HBAs
  2025-06-13 20:29 ` [PATCH 2/2] scsi: mpi3mr: Add initialization for ATTO 24Gb SAS HBAs Steve Siwinski
@ 2025-06-14  6:44   ` ALOK TIWARI
  2025-06-20 20:00     ` [PATCH v2 " Steve Siwinski
  2025-06-14 12:50   ` [PATCH " kernel test robot
  2025-06-14 14:03   ` kernel test robot
  2 siblings, 1 reply; 6+ messages in thread
From: ALOK TIWARI @ 2025-06-14  6:44 UTC (permalink / raw)
  To: Steve Siwinski, mpi3mr-linuxdrv.pdl
  Cc: gustavoars, James.Bottomley, kashyap.desai, kees, linux-kernel,
	linux-scsi, martin.petersen, prayas.patel, ranjan.kumar,
	sathya.prakash, sreekanth.reddy, ssiwinski, sumit.saxena, bgrove,
	tdoedline



On 14-06-2025 01:59, Steve Siwinski wrote:
> This patch adds initialization routines for ATTO 24Gb SAS HBAs.
> It introduces the ATTO NVRAM structure and functions to validate
> NVRAM contents.
> 
> The `mpi3mr_atto_init` function is added to handle ATTO-specific
> controller initialization. This involves reading the ATTO SAS address
> from Driver Page 2 and then assigning unique device names and WWIDs
> to Manufacturing Page 5.
> 
> Signed-off-by: Steve Siwinski <ssiwinski@atto.com>
> ---
>   drivers/scsi/mpi3mr/mpi3mr.h    |  35 ++++
>   drivers/scsi/mpi3mr/mpi3mr_fw.c | 310 ++++++++++++++++++++++++++++++++
>   2 files changed, 345 insertions(+)
> 
> diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
> index 9bbc7cb98ca3..05583457ffaa 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr.h
> +++ b/drivers/scsi/mpi3mr/mpi3mr.h
> @@ -1438,6 +1438,35 @@ struct delayed_evt_ack_node {
>   	u32 event_ctx;
>   };
>   
> +/*
> + * struct ATTO_SAS_NVRAM - ATTO NVRAM settings
> + * @signature: ATTO NVRAM signature
> + * @version: ATTO NVRAM version
> + * @checksum: NVRAM checksum
> + * @sasaddr: ATTO SAS address
> + */
> +struct ATTO_SAS_NVRAM {
> +	u8		signature[4];
> +	u8		version;
> +#define ATTO_SASNVR_VERSION		0
> +
> +	u8		checksum;
> +#define ATTO_SASNVR_CKSUM_SEED	0x5A
> +	u8		pad[10];
> +	u8		sasaddr[8];
> +#define ATTO_SAS_ADDR_ALIGN		64
> +	u8		reserved[232];
> +};
> +
> +#define ATTO_SAS_ADDR_DEVNAME_BIAS		63
> +
> +union ATTO_SAS_ADDRESS {
> +	u8		b[8];
> +	u16		w[4];
> +	u32		d[2];
> +	u64		q;
> +};
> +
>   int mpi3mr_setup_resources(struct mpi3mr_ioc *mrioc);
>   void mpi3mr_cleanup_resources(struct mpi3mr_ioc *mrioc);
>   int mpi3mr_init_ioc(struct mpi3mr_ioc *mrioc);
> @@ -1533,10 +1562,16 @@ int mpi3mr_cfg_get_sas_io_unit_pg1(struct mpi3mr_ioc *mrioc,
>   	struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1, u16 pg_sz);
>   int mpi3mr_cfg_set_sas_io_unit_pg1(struct mpi3mr_ioc *mrioc,
>   	struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1, u16 pg_sz);
> +int mpi3mr_cfg_get_man_pg5(struct mpi3mr_ioc *mrioc,
> +	struct mpi3_man_page5 *man_pg5, u16 pg_sz);
> +int mpi3mr_cfg_set_man_pg5(struct mpi3mr_ioc *mrioc,
> +	struct mpi3_man_page5 *man_pg5, u16 pg_sz);
>   int mpi3mr_cfg_get_driver_pg1(struct mpi3mr_ioc *mrioc,
>   	struct mpi3_driver_page1 *driver_pg1, u16 pg_sz);
>   int mpi3mr_cfg_get_driver_pg2(struct mpi3mr_ioc *mrioc,
>   	struct mpi3_driver_page2 *driver_pg2, u16 pg_sz, u8 page_type);
> +int mpi3mr_cfg_get_page_size(struct mpi3mr_ioc *mrioc,
> +	int page_type, int page_num);
>   
>   u8 mpi3mr_is_expander_device(u16 device_info);
>   int mpi3mr_expander_add(struct mpi3mr_ioc *mrioc, u16 handle);
> diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
> index 1d7901a8f0e4..c0177ad3d200 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
> +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
> @@ -4203,6 +4203,163 @@ static int mpi3mr_enable_events(struct mpi3mr_ioc *mrioc)
>   	return retval;
>   }
>   
> +/**
> + * mpi3mr_atto_validate_nvram - validate the ATTO nvram
> + *
> + * @mrioc:  Adapter instance reference

remove extra " " afetr :

> + * @nvram: ptr to the ATTO nvram structure
> + * Return: 0 for success, non-zero for failure.
> + */
> +static int mpi3mr_atto_validate_nvram(struct mpi3mr_ioc *mrioc, struct ATTO_SAS_NVRAM *nvram)
> +{
> +	int r = -EINVAL;
> +	union ATTO_SAS_ADDRESS *sasaddr;
> +	u32 len;
> +	u8 *pb;
> +	u8 cksum;
> +
> +	/* validate nvram checksum */
> +	pb = (u8 *) nvram;
> +	cksum = ATTO_SASNVR_CKSUM_SEED;
> +	len = sizeof(struct ATTO_SAS_NVRAM);
> +
> +	while (len--)
> +		cksum = cksum + pb[len];
> +
> +	if (cksum) {
> +		ioc_err(mrioc, "Invalid ATTO NVRAM checksum\n");
> +		return r;
> +	}
> +
> +	sasaddr = (union ATTO_SAS_ADDRESS *) nvram->sasaddr;
> +
> +	if (nvram->signature[0] != 'E'
> +	|| nvram->signature[1] != 'S'
> +	|| nvram->signature[2] != 'A'
> +	|| nvram->signature[3] != 'S')
> +		ioc_err(mrioc, "Invalid ATTO NVRAM signature\n");
> +	else if (nvram->version > ATTO_SASNVR_VERSION)
> +		ioc_info(mrioc, "Invalid ATTO NVRAM version");
> +	else if ((nvram->sasaddr[7] & (ATTO_SAS_ADDR_ALIGN - 1))
> +			|| sasaddr->b[0] != 0x50
> +			|| sasaddr->b[1] != 0x01
> +			|| sasaddr->b[2] != 0x08
> +			|| (sasaddr->b[3] & 0xF0) != 0x60
> +			|| ((sasaddr->b[3] & 0x0F) | le32_to_cpu(sasaddr->d[1])) == 0) {
> +		ioc_err(mrioc, "Invalid ATTO SAS address\n");
> +	} else
> +		r = 0;
> +	return r;
> +}
> +
> +/**
> + * mpi3mr_atto_get_sas_addr - get the ATTO SAS address from driver page 2
> + *
> + * @mrioc: Adapter instance reference
> + * @*sas_address: return sas address

it should be @sas_address: Pointer to store the sas address.

> + * Return: 0 for success, non-zero for failure.
> + */
> +static int mpi3mr_atto_get_sas_addr(struct mpi3mr_ioc *mrioc, union ATTO_SAS_ADDRESS *sas_address)
> +{
> +	struct mpi3_driver_page2 *driver_pg2 = NULL;
> +	struct ATTO_SAS_NVRAM *nvram;
> +	u16 sz;
> +	int r;
> +	__be64 addr;
> +
> +	sz = mpi3mr_cfg_get_page_size(mrioc, MPI3_CONFIG_PAGETYPE_DRIVER, 2);
> +	driver_pg2 = kzalloc(sz, GFP_KERNEL);
> +	if (!driver_pg2)
> +		goto out;
> +
> +	r = mpi3mr_cfg_get_driver_pg2(mrioc, driver_pg2, sz, MPI3_CONFIG_ACTION_READ_PERSISTENT);
> +	if (r)
> +		goto out;
> +
> +	nvram = (struct ATTO_SAS_NVRAM *) &driver_pg2->trigger;
> +
> +	r = mpi3mr_atto_validate_nvram(mrioc, nvram);
> +	if (r)
> +		goto out;
> +
> +	addr = *((__be64 *) nvram->sasaddr);
> +	sas_address->q = cpu_to_le64(be64_to_cpu(addr));
> +
> +out:
> +	kfree(driver_pg2);
> +	return r;
> +}
> +
> +/**
> + * mpi3mr_atto_init - Initialize the controller
> + * @mrioc: Adapter instance reference
> + *
> + * This the ATTO controller initialization routine
> + *
> + * Return: 0 on success and non-zero on failure.
> + */
> +static int mpi3mr_atto_init(struct mpi3mr_ioc *mrioc)
> +{
> +	int i, bias = 0;
> +	u16 sz;
> +	struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL;
> +	struct mpi3_man_page5 *man_pg5 = NULL;
> +	union ATTO_SAS_ADDRESS base_address;
> +	union ATTO_SAS_ADDRESS dev_address;
> +	union ATTO_SAS_ADDRESS sas_address;
> +
> +	sz = mpi3mr_cfg_get_page_size(mrioc, MPI3_CONFIG_PAGETYPE_SAS_IO_UNIT, 0);
> +	sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL);
> +	if (!sas_io_unit_pg0)
> +		goto out;
> +
> +	if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) {
> +		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
> +		    __FILE__, __LINE__, __func__);
> +		goto out;
> +	}
> +
> +	sz = mpi3mr_cfg_get_page_size(mrioc, MPI3_CONFIG_PAGETYPE_MANUFACTURING, 5);
> +	man_pg5 = kzalloc(sz, GFP_KERNEL);
> +	if (!man_pg5)
> +		goto out;
> +
> +	if (mpi3mr_cfg_get_man_pg5(mrioc, man_pg5, sz)) {
> +		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
> +		    __FILE__, __LINE__, __func__);
> +		goto out;
> +	}
> +
> +	mpi3mr_atto_get_sas_addr(mrioc, &base_address);
> +
> +	dev_address.q = base_address.q;
> +	dev_address.b[0] += ATTO_SAS_ADDR_DEVNAME_BIAS;
> +
> +	for (i = 0; i < man_pg5->num_phys; i++) {
> +		if (sas_io_unit_pg0->phy_data[i].phy_flags &
> +			(MPI3_SASIOUNIT0_PHYFLAGS_HOST_PHY |
> +			MPI3_SASIOUNIT0_PHYFLAGS_VIRTUAL_PHY))
> +			continue;
> +
> +		sas_address.q = base_address.q;
> +		sas_address.b[0] += bias++;
> +
> +		man_pg5->phy[i].device_name = dev_address.q;
> +		man_pg5->phy[i].ioc_wwid = sas_address.q;
> +		man_pg5->phy[i].sata_wwid = sas_address.q;
> +	}
> +
> +	if (mpi3mr_cfg_set_man_pg5(mrioc, man_pg5, sz))
> +		ioc_info(mrioc, "ATTO set manufacuring page 5 failed\n");

typo manufacuring -> manufacturing

> +
> +out:
> +	kfree(sas_io_unit_pg0);
> +	kfree(man_pg5);
> +
> +	return 0;
> +}
> +
> +



Thanks
Alok


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

* Re: [PATCH 2/2] scsi: mpi3mr: Add initialization for ATTO 24Gb SAS HBAs
  2025-06-13 20:29 ` [PATCH 2/2] scsi: mpi3mr: Add initialization for ATTO 24Gb SAS HBAs Steve Siwinski
  2025-06-14  6:44   ` ALOK TIWARI
@ 2025-06-14 12:50   ` kernel test robot
  2025-06-14 14:03   ` kernel test robot
  2 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2025-06-14 12:50 UTC (permalink / raw)
  To: Steve Siwinski, mpi3mr-linuxdrv.pdl
  Cc: llvm, oe-kbuild-all, gustavoars, James.Bottomley, kashyap.desai,
	kees, linux-kernel, linux-scsi, martin.petersen, prayas.patel,
	ranjan.kumar, sathya.prakash, sreekanth.reddy, ssiwinski,
	sumit.saxena, bgrove, tdoedline

Hi Steve,

kernel test robot noticed the following build warnings:

[auto build test WARNING on jejb-scsi/for-next]
[also build test WARNING on mkp-scsi/for-next linus/master v6.16-rc1 next-20250613]
[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/Steve-Siwinski/scsi-mpi3mr-Add-initialization-for-ATTO-24Gb-SAS-HBAs/20250614-043438
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
patch link:    https://lore.kernel.org/r/20250613202941.62114-2-ssiwinski%40atto.com
patch subject: [PATCH 2/2] scsi: mpi3mr: Add initialization for ATTO 24Gb SAS HBAs
config: x86_64-buildonly-randconfig-002-20250614 (https://download.01.org/0day-ci/archive/20250614/202506142037.j39pVyE8-lkp@intel.com/config)
compiler: clang version 20.1.2 (https://github.com/llvm/llvm-project 58df0ef89dd64126512e4ee27b4ac3fd8ddf6247)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250614/202506142037.j39pVyE8-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/202506142037.j39pVyE8-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/scsi/mpi3mr/mpi3mr_fw.c:1644:47: warning: variable 'scratch_pad0' set but not used [-Wunused-but-set-variable]
    1644 |         u32 host_diagnostic, ioc_status, ioc_config, scratch_pad0;
         |                                                      ^
>> drivers/scsi/mpi3mr/mpi3mr_fw.c:4272:6: warning: variable 'r' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
    4272 |         if (!driver_pg2)
         |             ^~~~~~~~~~~
   drivers/scsi/mpi3mr/mpi3mr_fw.c:4290:9: note: uninitialized use occurs here
    4290 |         return r;
         |                ^
   drivers/scsi/mpi3mr/mpi3mr_fw.c:4272:2: note: remove the 'if' if its condition is always false
    4272 |         if (!driver_pg2)
         |         ^~~~~~~~~~~~~~~~
    4273 |                 goto out;
         |                 ~~~~~~~~
   drivers/scsi/mpi3mr/mpi3mr_fw.c:4267:7: note: initialize the variable 'r' to silence this warning
    4267 |         int r;
         |              ^
         |               = 0
   2 warnings generated.
--
>> Warning: drivers/scsi/mpi3mr/mpi3mr_fw.c:4262 function parameter 'sas_address' not described in 'mpi3mr_atto_get_sas_addr'
>> Warning: drivers/scsi/mpi3mr/mpi3mr_fw.c:6468 function parameter 'man_pg5' not described in 'mpi3mr_cfg_get_man_pg5'
>> Warning: drivers/scsi/mpi3mr/mpi3mr_fw.c:6468 Excess function parameter 'io_unit_pg5' description in 'mpi3mr_cfg_get_man_pg5'
>> Warning: drivers/scsi/mpi3mr/mpi3mr_fw.c:6524 function parameter 'man_pg5' not described in 'mpi3mr_cfg_set_man_pg5'
>> Warning: drivers/scsi/mpi3mr/mpi3mr_fw.c:6524 Excess function parameter 'io_unit_pg5' description in 'mpi3mr_cfg_set_man_pg5'


vim +4272 drivers/scsi/mpi3mr/mpi3mr_fw.c

  4254	
  4255	/**
  4256	 * mpi3mr_atto_get_sas_addr - get the ATTO SAS address from driver page 2
  4257	 *
  4258	 * @mrioc: Adapter instance reference
  4259	 * @*sas_address: return sas address
  4260	 * Return: 0 for success, non-zero for failure.
  4261	 */
> 4262	static int mpi3mr_atto_get_sas_addr(struct mpi3mr_ioc *mrioc, union ATTO_SAS_ADDRESS *sas_address)
  4263	{
  4264		struct mpi3_driver_page2 *driver_pg2 = NULL;
  4265		struct ATTO_SAS_NVRAM *nvram;
  4266		u16 sz;
  4267		int r;
  4268		__be64 addr;
  4269	
  4270		sz = mpi3mr_cfg_get_page_size(mrioc, MPI3_CONFIG_PAGETYPE_DRIVER, 2);
  4271		driver_pg2 = kzalloc(sz, GFP_KERNEL);
> 4272		if (!driver_pg2)
  4273			goto out;
  4274	
  4275		r = mpi3mr_cfg_get_driver_pg2(mrioc, driver_pg2, sz, MPI3_CONFIG_ACTION_READ_PERSISTENT);
  4276		if (r)
  4277			goto out;
  4278	
  4279		nvram = (struct ATTO_SAS_NVRAM *) &driver_pg2->trigger;
  4280	
  4281		r = mpi3mr_atto_validate_nvram(mrioc, nvram);
  4282		if (r)
  4283			goto out;
  4284	
  4285		addr = *((__be64 *) nvram->sasaddr);
  4286		sas_address->q = cpu_to_le64(be64_to_cpu(addr));
  4287	
  4288	out:
  4289		kfree(driver_pg2);
  4290		return r;
  4291	}
  4292	

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

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

* Re: [PATCH 2/2] scsi: mpi3mr: Add initialization for ATTO 24Gb SAS HBAs
  2025-06-13 20:29 ` [PATCH 2/2] scsi: mpi3mr: Add initialization for ATTO 24Gb SAS HBAs Steve Siwinski
  2025-06-14  6:44   ` ALOK TIWARI
  2025-06-14 12:50   ` [PATCH " kernel test robot
@ 2025-06-14 14:03   ` kernel test robot
  2 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2025-06-14 14:03 UTC (permalink / raw)
  To: Steve Siwinski, mpi3mr-linuxdrv.pdl
  Cc: oe-kbuild-all, gustavoars, James.Bottomley, kashyap.desai, kees,
	linux-kernel, linux-scsi, martin.petersen, prayas.patel,
	ranjan.kumar, sathya.prakash, sreekanth.reddy, ssiwinski,
	sumit.saxena, bgrove, tdoedline

Hi Steve,

kernel test robot noticed the following build warnings:

[auto build test WARNING on jejb-scsi/for-next]
[also build test WARNING on mkp-scsi/for-next linus/master v6.16-rc1 next-20250613]
[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/Steve-Siwinski/scsi-mpi3mr-Add-initialization-for-ATTO-24Gb-SAS-HBAs/20250614-043438
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
patch link:    https://lore.kernel.org/r/20250613202941.62114-2-ssiwinski%40atto.com
patch subject: [PATCH 2/2] scsi: mpi3mr: Add initialization for ATTO 24Gb SAS HBAs
config: microblaze-randconfig-r112-20250614 (https://download.01.org/0day-ci/archive/20250614/202506142133.g9g2Gp1d-lkp@intel.com/config)
compiler: microblaze-linux-gcc (GCC) 12.4.0
reproduce: (https://download.01.org/0day-ci/archive/20250614/202506142133.g9g2Gp1d-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/202506142133.g9g2Gp1d-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/scsi/mpi3mr/mpi3mr_fw.c:4248:54: sparse: sparse: cast to restricted __le32
>> drivers/scsi/mpi3mr/mpi3mr_fw.c:4248:54: sparse: sparse: cast to restricted __le32
>> drivers/scsi/mpi3mr/mpi3mr_fw.c:4248:54: sparse: sparse: cast to restricted __le32
>> drivers/scsi/mpi3mr/mpi3mr_fw.c:4248:54: sparse: sparse: cast to restricted __le32
>> drivers/scsi/mpi3mr/mpi3mr_fw.c:4248:54: sparse: sparse: cast to restricted __le32
>> drivers/scsi/mpi3mr/mpi3mr_fw.c:4248:54: sparse: sparse: cast to restricted __le32
>> drivers/scsi/mpi3mr/mpi3mr_fw.c:4286:24: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned long long [usertype] q @@     got restricted __le64 [usertype] @@
   drivers/scsi/mpi3mr/mpi3mr_fw.c:4286:24: sparse:     expected unsigned long long [usertype] q
   drivers/scsi/mpi3mr/mpi3mr_fw.c:4286:24: sparse:     got restricted __le64 [usertype]
>> drivers/scsi/mpi3mr/mpi3mr_fw.c:4347:45: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le64 [usertype] device_name @@     got unsigned long long [addressable] [assigned] [usertype] q @@
   drivers/scsi/mpi3mr/mpi3mr_fw.c:4347:45: sparse:     expected restricted __le64 [usertype] device_name
   drivers/scsi/mpi3mr/mpi3mr_fw.c:4347:45: sparse:     got unsigned long long [addressable] [assigned] [usertype] q
>> drivers/scsi/mpi3mr/mpi3mr_fw.c:4348:42: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le64 [usertype] ioc_wwid @@     got unsigned long long [addressable] [assigned] [usertype] q @@
   drivers/scsi/mpi3mr/mpi3mr_fw.c:4348:42: sparse:     expected restricted __le64 [usertype] ioc_wwid
   drivers/scsi/mpi3mr/mpi3mr_fw.c:4348:42: sparse:     got unsigned long long [addressable] [assigned] [usertype] q
>> drivers/scsi/mpi3mr/mpi3mr_fw.c:4349:43: sparse: sparse: incorrect type in assignment (different base types) @@     expected restricted __le64 [usertype] sata_wwid @@     got unsigned long long [addressable] [assigned] [usertype] q @@
   drivers/scsi/mpi3mr/mpi3mr_fw.c:4349:43: sparse:     expected restricted __le64 [usertype] sata_wwid
   drivers/scsi/mpi3mr/mpi3mr_fw.c:4349:43: sparse:     got unsigned long long [addressable] [assigned] [usertype] q
   drivers/scsi/mpi3mr/mpi3mr_fw.c:5256:24: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned char [addressable] [assigned] [usertype] class @@     got restricted __le16 [usertype] @@
   drivers/scsi/mpi3mr/mpi3mr_fw.c:5256:24: sparse:     expected unsigned char [addressable] [assigned] [usertype] class
   drivers/scsi/mpi3mr/mpi3mr_fw.c:5256:24: sparse:     got restricted __le16 [usertype]
>> drivers/scsi/mpi3mr/mpi3mr_fw.c:6720:23: sparse: sparse: restricted __le16 degrades to integer

vim +4248 drivers/scsi/mpi3mr/mpi3mr_fw.c

  4205	
  4206	/**
  4207	 * mpi3mr_atto_validate_nvram - validate the ATTO nvram
  4208	 *
  4209	 * @mrioc:  Adapter instance reference
  4210	 * @nvram: ptr to the ATTO nvram structure
  4211	 * Return: 0 for success, non-zero for failure.
  4212	 */
  4213	static int mpi3mr_atto_validate_nvram(struct mpi3mr_ioc *mrioc, struct ATTO_SAS_NVRAM *nvram)
  4214	{
  4215		int r = -EINVAL;
  4216		union ATTO_SAS_ADDRESS *sasaddr;
  4217		u32 len;
  4218		u8 *pb;
  4219		u8 cksum;
  4220	
  4221		/* validate nvram checksum */
  4222		pb = (u8 *) nvram;
  4223		cksum = ATTO_SASNVR_CKSUM_SEED;
  4224		len = sizeof(struct ATTO_SAS_NVRAM);
  4225	
  4226		while (len--)
  4227			cksum = cksum + pb[len];
  4228	
  4229		if (cksum) {
  4230			ioc_err(mrioc, "Invalid ATTO NVRAM checksum\n");
  4231			return r;
  4232		}
  4233	
  4234		sasaddr = (union ATTO_SAS_ADDRESS *) nvram->sasaddr;
  4235	
  4236		if (nvram->signature[0] != 'E'
  4237		|| nvram->signature[1] != 'S'
  4238		|| nvram->signature[2] != 'A'
  4239		|| nvram->signature[3] != 'S')
  4240			ioc_err(mrioc, "Invalid ATTO NVRAM signature\n");
  4241		else if (nvram->version > ATTO_SASNVR_VERSION)
  4242			ioc_info(mrioc, "Invalid ATTO NVRAM version");
  4243		else if ((nvram->sasaddr[7] & (ATTO_SAS_ADDR_ALIGN - 1))
  4244				|| sasaddr->b[0] != 0x50
  4245				|| sasaddr->b[1] != 0x01
  4246				|| sasaddr->b[2] != 0x08
  4247				|| (sasaddr->b[3] & 0xF0) != 0x60
> 4248				|| ((sasaddr->b[3] & 0x0F) | le32_to_cpu(sasaddr->d[1])) == 0) {
  4249			ioc_err(mrioc, "Invalid ATTO SAS address\n");
  4250		} else
  4251			r = 0;
  4252		return r;
  4253	}
  4254	
  4255	/**
  4256	 * mpi3mr_atto_get_sas_addr - get the ATTO SAS address from driver page 2
  4257	 *
  4258	 * @mrioc: Adapter instance reference
  4259	 * @*sas_address: return sas address
  4260	 * Return: 0 for success, non-zero for failure.
  4261	 */
  4262	static int mpi3mr_atto_get_sas_addr(struct mpi3mr_ioc *mrioc, union ATTO_SAS_ADDRESS *sas_address)
  4263	{
  4264		struct mpi3_driver_page2 *driver_pg2 = NULL;
  4265		struct ATTO_SAS_NVRAM *nvram;
  4266		u16 sz;
  4267		int r;
  4268		__be64 addr;
  4269	
  4270		sz = mpi3mr_cfg_get_page_size(mrioc, MPI3_CONFIG_PAGETYPE_DRIVER, 2);
  4271		driver_pg2 = kzalloc(sz, GFP_KERNEL);
  4272		if (!driver_pg2)
  4273			goto out;
  4274	
  4275		r = mpi3mr_cfg_get_driver_pg2(mrioc, driver_pg2, sz, MPI3_CONFIG_ACTION_READ_PERSISTENT);
  4276		if (r)
  4277			goto out;
  4278	
  4279		nvram = (struct ATTO_SAS_NVRAM *) &driver_pg2->trigger;
  4280	
  4281		r = mpi3mr_atto_validate_nvram(mrioc, nvram);
  4282		if (r)
  4283			goto out;
  4284	
  4285		addr = *((__be64 *) nvram->sasaddr);
> 4286		sas_address->q = cpu_to_le64(be64_to_cpu(addr));
  4287	
  4288	out:
  4289		kfree(driver_pg2);
  4290		return r;
  4291	}
  4292	
  4293	/**
  4294	 * mpi3mr_atto_init - Initialize the controller
  4295	 * @mrioc: Adapter instance reference
  4296	 *
  4297	 * This the ATTO controller initialization routine
  4298	 *
  4299	 * Return: 0 on success and non-zero on failure.
  4300	 */
  4301	static int mpi3mr_atto_init(struct mpi3mr_ioc *mrioc)
  4302	{
  4303		int i, bias = 0;
  4304		u16 sz;
  4305		struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL;
  4306		struct mpi3_man_page5 *man_pg5 = NULL;
  4307		union ATTO_SAS_ADDRESS base_address;
  4308		union ATTO_SAS_ADDRESS dev_address;
  4309		union ATTO_SAS_ADDRESS sas_address;
  4310	
  4311		sz = mpi3mr_cfg_get_page_size(mrioc, MPI3_CONFIG_PAGETYPE_SAS_IO_UNIT, 0);
  4312		sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL);
  4313		if (!sas_io_unit_pg0)
  4314			goto out;
  4315	
  4316		if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) {
  4317			ioc_err(mrioc, "failure at %s:%d/%s()!\n",
  4318			    __FILE__, __LINE__, __func__);
  4319			goto out;
  4320		}
  4321	
  4322		sz = mpi3mr_cfg_get_page_size(mrioc, MPI3_CONFIG_PAGETYPE_MANUFACTURING, 5);
  4323		man_pg5 = kzalloc(sz, GFP_KERNEL);
  4324		if (!man_pg5)
  4325			goto out;
  4326	
  4327		if (mpi3mr_cfg_get_man_pg5(mrioc, man_pg5, sz)) {
  4328			ioc_err(mrioc, "failure at %s:%d/%s()!\n",
  4329			    __FILE__, __LINE__, __func__);
  4330			goto out;
  4331		}
  4332	
  4333		mpi3mr_atto_get_sas_addr(mrioc, &base_address);
  4334	
  4335		dev_address.q = base_address.q;
  4336		dev_address.b[0] += ATTO_SAS_ADDR_DEVNAME_BIAS;
  4337	
  4338		for (i = 0; i < man_pg5->num_phys; i++) {
  4339			if (sas_io_unit_pg0->phy_data[i].phy_flags &
  4340				(MPI3_SASIOUNIT0_PHYFLAGS_HOST_PHY |
  4341				MPI3_SASIOUNIT0_PHYFLAGS_VIRTUAL_PHY))
  4342				continue;
  4343	
  4344			sas_address.q = base_address.q;
  4345			sas_address.b[0] += bias++;
  4346	
> 4347			man_pg5->phy[i].device_name = dev_address.q;
> 4348			man_pg5->phy[i].ioc_wwid = sas_address.q;
> 4349			man_pg5->phy[i].sata_wwid = sas_address.q;
  4350		}
  4351	
  4352		if (mpi3mr_cfg_set_man_pg5(mrioc, man_pg5, sz))
  4353			ioc_info(mrioc, "ATTO set manufacuring page 5 failed\n");
  4354	
  4355	out:
  4356		kfree(sas_io_unit_pg0);
  4357		kfree(man_pg5);
  4358	
  4359		return 0;
  4360	}
  4361	

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

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

* [PATCH v2 2/2] scsi: mpi3mr: Add initialization for ATTO 24Gb SAS HBAs
  2025-06-14  6:44   ` ALOK TIWARI
@ 2025-06-20 20:00     ` Steve Siwinski
  0 siblings, 0 replies; 6+ messages in thread
From: Steve Siwinski @ 2025-06-20 20:00 UTC (permalink / raw)
  To: alok.a.tiwari
  Cc: James.Bottomley, bgrove, gustavoars, kashyap.desai, kees,
	linux-kernel, linux-scsi, martin.petersen, mpi3mr-linuxdrv.pdl,
	prayas.patel, ranjan.kumar, sathya.prakash, sreekanth.reddy,
	ssiwinski, stevensiwinski, sumit.saxena, tdoedline

This patch adds initialization routines for ATTO 24Gb SAS HBAs.
It introduces the ATTO NVRAM structure and functions to validate
NVRAM contents.

The `mpi3mr_atto_init` function is added to handle ATTO-specific
controller initialization. This involves reading the ATTO SAS address
from Driver Page 2 and then assigning unique device names and WWIDs
to Manufacturing Page 5.

v2:
- Fixed typo and whitespace issues. (Reported by alok.a.tiwari@oracle.com)
- Changed ATTO_SAS_ADDRESS members to __le16/__le32/__le64.
  (Reported by Sparse)
- Initialized 'r' return value in mpi3mr_atto_get_sas_addr.
  (Reported by Sparse)
- Applied le16_to_cpu to return value in mpi3mr_cfg_get_page_size.
  (Reported by Sparse)
- Corrected parameter names in comments. (Reported by Sparse)

Signed-off-by: Steve Siwinski <ssiwinski@atto.com>
---
 drivers/scsi/mpi3mr/mpi3mr.h    |  35 ++++
 drivers/scsi/mpi3mr/mpi3mr_fw.c | 310 ++++++++++++++++++++++++++++++++
 2 files changed, 345 insertions(+)

diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
index 9bbc7cb98ca3..35332c0bcdad 100644
--- a/drivers/scsi/mpi3mr/mpi3mr.h
+++ b/drivers/scsi/mpi3mr/mpi3mr.h
@@ -1438,6 +1438,35 @@ struct delayed_evt_ack_node {
 	u32 event_ctx;
 };
 
+/*
+ * struct ATTO_SAS_NVRAM - ATTO NVRAM settings
+ * @signature: ATTO NVRAM signature
+ * @version: ATTO NVRAM version
+ * @checksum: NVRAM checksum
+ * @sasaddr: ATTO SAS address
+ */
+struct ATTO_SAS_NVRAM {
+	u8		signature[4];
+	u8		version;
+#define ATTO_SASNVR_VERSION		0
+
+	u8		checksum;
+#define ATTO_SASNVR_CKSUM_SEED	0x5A
+	u8		pad[10];
+	u8		sasaddr[8];
+#define ATTO_SAS_ADDR_ALIGN		64
+	u8		reserved[232];
+};
+
+#define ATTO_SAS_ADDR_DEVNAME_BIAS		63
+
+union ATTO_SAS_ADDRESS {
+	u8		b[8];
+	__le16	w[4];
+	__le32	d[2];
+	__le64	q;
+};
+
 int mpi3mr_setup_resources(struct mpi3mr_ioc *mrioc);
 void mpi3mr_cleanup_resources(struct mpi3mr_ioc *mrioc);
 int mpi3mr_init_ioc(struct mpi3mr_ioc *mrioc);
@@ -1533,10 +1562,16 @@ int mpi3mr_cfg_get_sas_io_unit_pg1(struct mpi3mr_ioc *mrioc,
 	struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1, u16 pg_sz);
 int mpi3mr_cfg_set_sas_io_unit_pg1(struct mpi3mr_ioc *mrioc,
 	struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1, u16 pg_sz);
+int mpi3mr_cfg_get_man_pg5(struct mpi3mr_ioc *mrioc,
+	struct mpi3_man_page5 *man_pg5, u16 pg_sz);
+int mpi3mr_cfg_set_man_pg5(struct mpi3mr_ioc *mrioc,
+	struct mpi3_man_page5 *man_pg5, u16 pg_sz);
 int mpi3mr_cfg_get_driver_pg1(struct mpi3mr_ioc *mrioc,
 	struct mpi3_driver_page1 *driver_pg1, u16 pg_sz);
 int mpi3mr_cfg_get_driver_pg2(struct mpi3mr_ioc *mrioc,
 	struct mpi3_driver_page2 *driver_pg2, u16 pg_sz, u8 page_type);
+int mpi3mr_cfg_get_page_size(struct mpi3mr_ioc *mrioc,
+	int page_type, int page_num);
 
 u8 mpi3mr_is_expander_device(u16 device_info);
 int mpi3mr_expander_add(struct mpi3mr_ioc *mrioc, u16 handle);
diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index 1d7901a8f0e4..29b9ae547710 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -4203,6 +4203,163 @@ static int mpi3mr_enable_events(struct mpi3mr_ioc *mrioc)
 	return retval;
 }
 
+/**
+ * mpi3mr_atto_validate_nvram - validate the ATTO nvram
+ *
+ * @mrioc: Adapter instance reference
+ * @nvram: ptr to the ATTO nvram structure
+ * Return: 0 for success, non-zero for failure.
+ */
+static int mpi3mr_atto_validate_nvram(struct mpi3mr_ioc *mrioc, struct ATTO_SAS_NVRAM *nvram)
+{
+	int r = -EINVAL;
+	union ATTO_SAS_ADDRESS *sasaddr;
+	u32 len;
+	u8 *pb;
+	u8 cksum;
+
+	/* validate nvram checksum */
+	pb = (u8 *) nvram;
+	cksum = ATTO_SASNVR_CKSUM_SEED;
+	len = sizeof(struct ATTO_SAS_NVRAM);
+
+	while (len--)
+		cksum = cksum + pb[len];
+
+	if (cksum) {
+		ioc_err(mrioc, "Invalid ATTO NVRAM checksum\n");
+		return r;
+	}
+
+	sasaddr = (union ATTO_SAS_ADDRESS *) nvram->sasaddr;
+
+	if (nvram->signature[0] != 'E'
+	|| nvram->signature[1] != 'S'
+	|| nvram->signature[2] != 'A'
+	|| nvram->signature[3] != 'S')
+		ioc_err(mrioc, "Invalid ATTO NVRAM signature\n");
+	else if (nvram->version > ATTO_SASNVR_VERSION)
+		ioc_info(mrioc, "Invalid ATTO NVRAM version");
+	else if ((nvram->sasaddr[7] & (ATTO_SAS_ADDR_ALIGN - 1))
+			|| sasaddr->b[0] != 0x50
+			|| sasaddr->b[1] != 0x01
+			|| sasaddr->b[2] != 0x08
+			|| (sasaddr->b[3] & 0xF0) != 0x60
+			|| ((sasaddr->b[3] & 0x0F) | le32_to_cpu(sasaddr->d[1])) == 0) {
+		ioc_err(mrioc, "Invalid ATTO SAS address\n");
+	} else
+		r = 0;
+	return r;
+}
+
+/**
+ * mpi3mr_atto_get_sas_addr - get the ATTO SAS address from driver page 2
+ *
+ * @mrioc: Adapter instance reference
+ * @sas_address: Pointer to store the sas address
+ * Return: 0 for success, non-zero for failure.
+ */
+static int mpi3mr_atto_get_sas_addr(struct mpi3mr_ioc *mrioc, union ATTO_SAS_ADDRESS *sas_address)
+{
+	struct mpi3_driver_page2 *driver_pg2 = NULL;
+	struct ATTO_SAS_NVRAM *nvram;
+	u16 sz;
+	int r = -ENOMEM;
+	__be64 addr;
+
+	sz = mpi3mr_cfg_get_page_size(mrioc, MPI3_CONFIG_PAGETYPE_DRIVER, 2);
+	driver_pg2 = kzalloc(sz, GFP_KERNEL);
+	if (!driver_pg2)
+		goto out;
+
+	r = mpi3mr_cfg_get_driver_pg2(mrioc, driver_pg2, sz, MPI3_CONFIG_ACTION_READ_PERSISTENT);
+	if (r)
+		goto out;
+
+	nvram = (struct ATTO_SAS_NVRAM *) &driver_pg2->trigger;
+
+	r = mpi3mr_atto_validate_nvram(mrioc, nvram);
+	if (r)
+		goto out;
+
+	addr = *((__be64 *) nvram->sasaddr);
+	sas_address->q = cpu_to_le64(be64_to_cpu(addr));
+
+out:
+	kfree(driver_pg2);
+	return r;
+}
+
+/**
+ * mpi3mr_atto_init - Initialize the controller
+ * @mrioc: Adapter instance reference
+ *
+ * This the ATTO controller initialization routine
+ *
+ * Return: 0 on success and non-zero on failure.
+ */
+static int mpi3mr_atto_init(struct mpi3mr_ioc *mrioc)
+{
+	int i, bias = 0;
+	u16 sz;
+	struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL;
+	struct mpi3_man_page5 *man_pg5 = NULL;
+	union ATTO_SAS_ADDRESS base_address;
+	union ATTO_SAS_ADDRESS dev_address;
+	union ATTO_SAS_ADDRESS sas_address;
+
+	sz = mpi3mr_cfg_get_page_size(mrioc, MPI3_CONFIG_PAGETYPE_SAS_IO_UNIT, 0);
+	sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL);
+	if (!sas_io_unit_pg0)
+		goto out;
+
+	if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) {
+		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
+		    __FILE__, __LINE__, __func__);
+		goto out;
+	}
+
+	sz = mpi3mr_cfg_get_page_size(mrioc, MPI3_CONFIG_PAGETYPE_MANUFACTURING, 5);
+	man_pg5 = kzalloc(sz, GFP_KERNEL);
+	if (!man_pg5)
+		goto out;
+
+	if (mpi3mr_cfg_get_man_pg5(mrioc, man_pg5, sz)) {
+		ioc_err(mrioc, "failure at %s:%d/%s()!\n",
+		    __FILE__, __LINE__, __func__);
+		goto out;
+	}
+
+	mpi3mr_atto_get_sas_addr(mrioc, &base_address);
+
+	dev_address.q = base_address.q;
+	dev_address.b[0] += ATTO_SAS_ADDR_DEVNAME_BIAS;
+
+	for (i = 0; i < man_pg5->num_phys; i++) {
+		if (sas_io_unit_pg0->phy_data[i].phy_flags &
+			(MPI3_SASIOUNIT0_PHYFLAGS_HOST_PHY |
+			MPI3_SASIOUNIT0_PHYFLAGS_VIRTUAL_PHY))
+			continue;
+
+		sas_address.q = base_address.q;
+		sas_address.b[0] += bias++;
+
+		man_pg5->phy[i].device_name = dev_address.q;
+		man_pg5->phy[i].ioc_wwid = sas_address.q;
+		man_pg5->phy[i].sata_wwid = sas_address.q;
+	}
+
+	if (mpi3mr_cfg_set_man_pg5(mrioc, man_pg5, sz))
+		ioc_info(mrioc, "ATTO set manufacturing page 5 failed\n");
+
+out:
+	kfree(sas_io_unit_pg0);
+	kfree(man_pg5);
+
+	return 0;
+}
+
+
 /**
  * mpi3mr_init_ioc - Initialize the controller
  * @mrioc: Adapter instance reference
@@ -4376,6 +4533,9 @@ int mpi3mr_init_ioc(struct mpi3mr_ioc *mrioc)
 		goto out_failed;
 	}
 
+	if (mrioc->pdev->subsystem_vendor == MPI3_MFGPAGE_VENDORID_ATTO)
+		mpi3mr_atto_init(mrioc);
+
 	ioc_info(mrioc, "controller initialization completed successfully\n");
 	return retval;
 out_failed:
@@ -6293,6 +6453,118 @@ int mpi3mr_cfg_set_sas_io_unit_pg1(struct mpi3mr_ioc *mrioc,
 	return -1;
 }
 
+/**
+ * mpi3mr_cfg_get_man_pg5 - Read manufacturing page 5
+ * @mrioc: Adapter instance reference
+ * @man_pg5: Pointer to the manufacturing page 5 to read
+ * @pg_sz: Size of the memory allocated to the page pointer
+ *
+ * This is handler for config page read of manufacturing
+ * page 5.
+ *
+ * Return: 0 on success, non-zero on failure.
+ */
+int mpi3mr_cfg_get_man_pg5(struct mpi3mr_ioc *mrioc,
+	struct mpi3_man_page5 *man_pg5, u16 pg_sz)
+{
+	struct mpi3_config_page_header cfg_hdr;
+	struct mpi3_config_request cfg_req;
+	u16 ioc_status = 0;
+
+	memset(man_pg5, 0, pg_sz);
+	memset(&cfg_hdr, 0, sizeof(cfg_hdr));
+	memset(&cfg_req, 0, sizeof(cfg_req));
+
+	cfg_req.function = MPI3_FUNCTION_CONFIG;
+	cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER;
+	cfg_req.page_type = MPI3_CONFIG_PAGETYPE_MANUFACTURING;
+	cfg_req.page_number = 5;
+	cfg_req.page_address = 0;
+
+	if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL,
+	    MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, &cfg_hdr, sizeof(cfg_hdr))) {
+		ioc_err(mrioc, "manufacturing page5 header read failed\n");
+		goto out_failed;
+	}
+	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
+		ioc_err(mrioc, "manufacturing page5 header read failed with ioc_status(0x%04x)\n",
+		    ioc_status);
+		goto out_failed;
+	}
+
+	cfg_req.action = MPI3_CONFIG_ACTION_READ_CURRENT;
+
+	if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr,
+	    MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, man_pg5, pg_sz)) {
+		ioc_err(mrioc, "manufacturing page5 read failed\n");
+		goto out_failed;
+	}
+	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
+		ioc_err(mrioc, "manufacturing page5 read failed with ioc_status(0x%04x)\n",
+		    ioc_status);
+		goto out_failed;
+	}
+	return 0;
+out_failed:
+	return -1;
+}
+
+/**
+ * mpi3mr_cfg_set_man_pg5 - Write manufacturing page 5
+ * @mrioc: Adapter instance reference
+ * @man_pg5: Pointer to the manufacturing page 5 to write
+ * @pg_sz: Size of the memory allocated to the page pointer
+ *
+ * This is handler for config page write for manufacturing
+ * page 5. This will modify only the current page.
+ *
+ * Return: 0 on success, non-zero on failure.
+ */
+int mpi3mr_cfg_set_man_pg5(struct mpi3mr_ioc *mrioc,
+	struct mpi3_man_page5 *man_pg5, u16 pg_sz)
+{
+	struct mpi3_config_page_header cfg_hdr;
+	struct mpi3_config_request cfg_req;
+	u16 ioc_status = 0;
+
+	memset(&cfg_hdr, 0, sizeof(cfg_hdr));
+	memset(&cfg_req, 0, sizeof(cfg_req));
+
+	cfg_req.function = MPI3_FUNCTION_CONFIG;
+	cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER;
+	cfg_req.page_type = MPI3_CONFIG_PAGETYPE_MANUFACTURING;
+	cfg_req.page_number = 5;
+	cfg_req.page_address = 0;
+
+	if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL,
+	    MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, &cfg_hdr, sizeof(cfg_hdr))) {
+		ioc_err(mrioc, "manufacturing page5 header read failed\n");
+		goto out_failed;
+	}
+	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
+		ioc_err(mrioc, "manufacturing page5 header read failed with ioc_status(0x%04x)\n",
+		    ioc_status);
+		goto out_failed;
+	}
+
+	cfg_req.action = MPI3_CONFIG_ACTION_WRITE_CURRENT;
+
+	if (mpi3mr_process_cfg_req(mrioc, &cfg_req, &cfg_hdr,
+	    MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, man_pg5, pg_sz)) {
+		ioc_err(mrioc, "manufacturing page5 write failed\n");
+		goto out_failed;
+	}
+	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
+		ioc_err(mrioc, "manufacturing page5 write failed with ioc_status(0x%04x)\n",
+		    ioc_status);
+		goto out_failed;
+	}
+
+	return 0;
+out_failed:
+	return -1;
+}
+
 /**
  * mpi3mr_cfg_get_driver_pg1 - Read current Driver page1
  * @mrioc: Adapter instance reference
@@ -6409,3 +6681,41 @@ int mpi3mr_cfg_get_driver_pg2(struct mpi3mr_ioc *mrioc,
 	return -1;
 }
 
+/**
+ * mpi3mr_cfg_get_page_size - Get the size of requested page
+ * @mrioc: Adapter instance reference
+ * @page_type: Page type (MPI3_CONFIG_PAGETYPE_XXX)
+ * @page_num: Page number
+ *
+ * Return the specified config page size in bytes.
+ *
+ * Return: Page size in bytes, -1 on failure.
+ */
+int mpi3mr_cfg_get_page_size(struct mpi3mr_ioc *mrioc, int page_type, int page_num)
+{
+	struct mpi3_config_page_header cfg_hdr;
+	struct mpi3_config_request cfg_req;
+	u16 ioc_status = 0;
+
+	memset(&cfg_hdr, 0, sizeof(cfg_hdr));
+	memset(&cfg_req, 0, sizeof(cfg_req));
+
+	cfg_req.function = MPI3_FUNCTION_CONFIG;
+	cfg_req.action = MPI3_CONFIG_ACTION_PAGE_HEADER;
+	cfg_req.page_type = page_type;
+	cfg_req.page_number = page_num;
+	cfg_req.page_address = 0;
+
+	if (mpi3mr_process_cfg_req(mrioc, &cfg_req, NULL,
+	    MPI3MR_INTADMCMD_TIMEOUT, &ioc_status, &cfg_hdr, sizeof(cfg_hdr))) {
+		ioc_err(mrioc, "header read failed\n");
+		return -1;
+	}
+	if (ioc_status != MPI3_IOCSTATUS_SUCCESS) {
+		ioc_err(mrioc, "header read failed with ioc_status(0x%04x)\n",
+		    ioc_status);
+		return -1;
+	}
+
+	return le16_to_cpu(cfg_hdr.page_length) * 4;
+}
-- 
2.43.5


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

end of thread, other threads:[~2025-06-20 20:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-13 20:29 [PATCH 1/2] scsi: mpi3mr: Add ATTO vendor support and disable firmware download Steve Siwinski
2025-06-13 20:29 ` [PATCH 2/2] scsi: mpi3mr: Add initialization for ATTO 24Gb SAS HBAs Steve Siwinski
2025-06-14  6:44   ` ALOK TIWARI
2025-06-20 20:00     ` [PATCH v2 " Steve Siwinski
2025-06-14 12:50   ` [PATCH " kernel test robot
2025-06-14 14:03   ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).