diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_config.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_config.c | 67 |
1 files changed, 44 insertions, 23 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index 2b1101076cfe..36ea0b2d8020 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c @@ -1356,6 +1356,9 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle, Mpi2ConfigReply_t mpi_reply; int r, i, config_page_sz; u16 ioc_status; + int config_num; + u16 element_type; + u16 phys_disk_dev_handle; *volume_handle = 0; memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); @@ -1371,35 +1374,53 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle, 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) + if (!config_page) { + r = -1; 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; + } + config_num = 0xff; + while (1) { + mpi_request.PageAddress = cpu_to_le32(config_num + + MPI2_RAID_PGAD_FORM_GET_NEXT_CONFIGNUM); + 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++) { + element_type = le16_to_cpu(config_page-> + ConfigElement[i].ElementFlags) & + MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE; + if (element_type == + MPI2_RAIDCONFIG0_EFLAGS_VOL_PHYS_DISK_ELEMENT || + element_type == + MPI2_RAIDCONFIG0_EFLAGS_OCE_ELEMENT) { + phys_disk_dev_handle = + le16_to_cpu(config_page->ConfigElement[i]. + PhysDiskDevHandle); + if (phys_disk_dev_handle == pd_handle) { + *volume_handle = + le16_to_cpu(config_page-> + ConfigElement[i].VolDevHandle); + r = 0; + goto out; + } + } else if (element_type == + MPI2_RAIDCONFIG0_EFLAGS_HOT_SPARE_ELEMENT) { + *volume_handle = 0; + r = 0; + goto out; + } } + config_num = config_page->ConfigNum; } out: kfree(config_page); |