* [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 [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 [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
* [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 [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
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
all inboxes | Powered by JetHome®