/** * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page * @sz: size of buffer passed in config_page * Context: sleep. * * Calling function should call config_get_number_hba_phys prior to * this function, so enough memory is allocated for config_page. * * Returns 0 for success, non-zero for failure. */ int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz) { Mpi2ConfigRequest_t mpi_request; int r; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; mpi_request.Header.PageNumber = 1; mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; r = _config_request(ioc, &mpi_request, mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); out: return r; }
/** * mpt2sas_config_get_sas_device_pg1 - obtain sas device page 1 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page * @form: GET_NEXT_HANDLE or HANDLE * @handle: device handle * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage1_t *config_page, u32 form, u32 handle) { Mpi2ConfigRequest_t mpi_request; int r; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE; mpi_request.Header.PageVersion = MPI2_SASDEVICE1_PAGEVERSION; mpi_request.Header.PageNumber = 1; mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.PageAddress = cpu_to_le32(form | handle); mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; r = _config_request(ioc, &mpi_request, mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sizeof(*config_page)); out: return r; }
/** * mpt2sas_config_get_phys_disk_pg0 - obtain phys disk page 0 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page * @form: GET_NEXT_PHYSDISKNUM, PHYSDISKNUM, DEVHANDLE * @form_specific: specific to the form * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 form, u32 form_specific) { Mpi2ConfigRequest_t mpi_request; int r; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK; mpi_request.Header.PageNumber = 0; mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION; mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.PageAddress = cpu_to_le32(form | form_specific); mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; r = _config_request(ioc, &mpi_request, mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sizeof(*config_page)); out: return r; }
/** * mpt2sas_config_get_ioc_pg8 - obtain ioc page 8 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page) { Mpi2ConfigRequest_t mpi_request; int r; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_IOC; mpi_request.Header.PageNumber = 8; mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; r = _config_request(ioc, &mpi_request, mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sizeof(*config_page)); out: return r; }
/** * mpt2sas_config_get_raid_volume_pg0 - obtain raid volume page 0 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page * @form: GET_NEXT_HANDLE or HANDLE * @handle: volume handle * @sz: size of buffer passed in config_page * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 form, u32 handle, u16 sz) { Mpi2ConfigRequest_t mpi_request; int r; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; mpi_request.Header.PageNumber = 0; mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.PageAddress = cpu_to_le32(form | handle); mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; r = _config_request(ioc, &mpi_request, mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); out: return r; }
/** * mpt2sas_config_get_phy_pg0 - obtain phy page 0 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page * @phy_number: phy number * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2SasPhyPage0_t *config_page, u32 phy_number) { Mpi2ConfigRequest_t mpi_request; int r; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY; mpi_request.Header.PageNumber = 0; mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION; mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.PageAddress = cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number); mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; r = _config_request(ioc, &mpi_request, mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sizeof(*config_page)); out: return r; }
/** * mpt2sas_config_get_expander_pg1 - obtain expander page 1 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page * @phy_number: phy number * @handle: expander handle * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2ExpanderPage1_t *config_page, u32 phy_number, u16 handle) { Mpi2ConfigRequest_t mpi_request; int r; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER; mpi_request.Header.PageNumber = 1; mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION; mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.PageAddress = cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM | (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle); mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; r = _config_request(ioc, &mpi_request, mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sizeof(*config_page)); out: return r; }
/** * mpt2sas_config_get_volume_handle - returns volume handle for give hidden raid components * @ioc: per adapter object * @pd_handle: phys disk handle * @volume_handle: volume handle * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle, u16 *volume_handle) { Mpi2RaidConfigurationPage0_t *config_page = NULL; Mpi2ConfigRequest_t mpi_request; Mpi2ConfigReply_t mpi_reply; int r, i, config_page_sz; u16 ioc_status; *volume_handle = 0; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG; mpi_request.Header.PageVersion = MPI2_RAIDCONFIG0_PAGEVERSION; mpi_request.Header.PageNumber = 0; mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, &mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.PageAddress = cpu_to_le32(MPI2_RAID_PGAD_FORM_ACTIVE_CONFIG); mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4); config_page = kmalloc(config_page_sz, GFP_KERNEL); if (!config_page) goto out; r = _config_request(ioc, &mpi_request, &mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, config_page_sz); if (r) goto out; r = -1; ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) goto out; for (i = 0; i < config_page->NumElements; i++) { if ((le16_to_cpu(config_page->ConfigElement[i].ElementFlags) & MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE) != MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT) continue; if (le16_to_cpu(config_page->ConfigElement[i]. PhysDiskDevHandle) == pd_handle) { *volume_handle = le16_to_cpu(config_page-> ConfigElement[i].VolDevHandle); r = 0; goto out; } } out: kfree(config_page); return r; }
/** * mpt2sas_config_get_number_pds - obtain number of phys disk assigned to volume * @ioc: per adapter object * @handle: volume handle * @num_pds: returns pds count * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 *num_pds) { Mpi2ConfigRequest_t mpi_request; Mpi2RaidVolPage0_t config_page; Mpi2ConfigReply_t mpi_reply; int r; u16 ioc_status; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); *num_pds = 0; mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME; mpi_request.Header.PageNumber = 0; mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, &mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.PageAddress = cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle); mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; r = _config_request(ioc, &mpi_request, &mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, sizeof(Mpi2RaidVolPage0_t)); if (!r) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status == MPI2_IOCSTATUS_SUCCESS) *num_pds = config_page.NumPhysDisks; } out: return r; }
/** * mpt2sas_config_get_number_hba_phys - obtain number of phys on the host * @ioc: per adapter object * @num_phys: pointer returned with the number of phys * Context: sleep. * * Returns 0 for success, non-zero for failure. */ int mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys) { Mpi2ConfigRequest_t mpi_request; int r; u16 ioc_status; Mpi2ConfigReply_t mpi_reply; Mpi2SasIOUnitPage0_t config_page; *num_phys = 0; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); mpi_request.Function = MPI2_FUNCTION_CONFIG; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; mpi_request.Header.PageNumber = 0; mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); r = _config_request(ioc, &mpi_request, &mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); if (r) goto out; mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; r = _config_request(ioc, &mpi_request, &mpi_reply, MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page, sizeof(Mpi2SasIOUnitPage0_t)); if (!r) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status == MPI2_IOCSTATUS_SUCCESS) *num_phys = config_page.NumPhys; } out: return r; }