On 09/06/2014 03:25 PM, Sumit.Saxena@xxxxxxxxxxxxx wrote: > Current MegaRAID firmware and hence the driver only supported 64VDs. > E.g: If the user wants to create more than 64VD on a controller, > it is not possible on current firmware/driver. > > New feature and requirement to support upto 256VD, firmware/driver/apps need changes. > In addition to that there must be a backward compatibility of the new driver with the > older firmware and vice versa. > > RAID map is the interface between Driver and FW to fetch all required > fields(attributes) for each Virtual Drives. > In the earlier design driver was using the FW copy of RAID map where as > in the new design the Driver will keep the RAID map copy of its own; on which > it will operate for any raid map access in fast path. > > Local driver raid map copy will provide ease of access through out the code > and provide generic interface for future FW raid map changes. > > For the backward compatibility driver will notify FW that it supports 256VD > to the FW in driver capability field. > Based on the controller properly returned by the FW, the Driver will know > whether it supports 256VD or not and will copy the RAID map accordingly. > > At any given time, driver will always have old or new Raid map. > So with this changes, driver can also work in host lock less mode. Please > see next patch which enable host lock less mode for megaraid_sas driver. > > Signed-off-by: Sumit Saxena <sumit.saxena@xxxxxxxxxxxxx> > Signed-off-by: Kashyap Desai <kashyap.desai@xxxxxxxxxxxxx> > --- > drivers/scsi/megaraid/megaraid_sas.h | 73 +++++++--- > drivers/scsi/megaraid/megaraid_sas_base.c | 205 ++++++++++++++++------------ > drivers/scsi/megaraid/megaraid_sas_fp.c | 195 ++++++++++++++++++-------- > drivers/scsi/megaraid/megaraid_sas_fusion.c | 118 ++++++++++++---- > drivers/scsi/megaraid/megaraid_sas_fusion.h | 95 ++++++++++++- > 5 files changed, 502 insertions(+), 184 deletions(-) > > diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h > index e0f03e2..5dedf09 100644 > --- a/drivers/scsi/megaraid/megaraid_sas.h > +++ b/drivers/scsi/megaraid/megaraid_sas.h > @@ -390,7 +390,6 @@ enum MR_LD_QUERY_TYPE { > #define MR_EVT_FOREIGN_CFG_IMPORTED 0x00db > #define MR_EVT_LD_OFFLINE 0x00fc > #define MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED 0x0152 > -#define MAX_LOGICAL_DRIVES 64 > > enum MR_PD_STATE { > MR_PD_STATE_UNCONFIGURED_GOOD = 0x00, > @@ -468,14 +467,14 @@ struct MR_LD_LIST { > u8 state; > u8 reserved[3]; > u64 size; > - } ldList[MAX_LOGICAL_DRIVES]; > + } ldList[MAX_LOGICAL_DRIVES_EXT]; > } __packed; > > struct MR_LD_TARGETID_LIST { > u32 size; > u32 count; > u8 pad[3]; > - u8 targetId[MAX_LOGICAL_DRIVES]; > + u8 targetId[MAX_LOGICAL_DRIVES_EXT]; > }; > > > @@ -941,6 +940,15 @@ struct megasas_ctrl_info { > * HA cluster information > */ > struct { > +#if defined(__BIG_ENDIAN_BITFIELD) > + u32 reserved:26; > + u32 premiumFeatureMismatch:1; > + u32 ctrlPropIncompatible:1; > + u32 fwVersionMismatch:1; > + u32 hwIncompatible:1; > + u32 peerIsIncompatible:1; > + u32 peerIsPresent:1; > +#else > u32 peerIsPresent:1; > u32 peerIsIncompatible:1; > u32 hwIncompatible:1; > @@ -948,6 +956,7 @@ struct megasas_ctrl_info { > u32 ctrlPropIncompatible:1; > u32 premiumFeatureMismatch:1; > u32 reserved:26; > +#endif > } cluster; > > char clusterId[16]; /*7D4h */ > @@ -962,9 +971,17 @@ struct megasas_ctrl_info { > #if defined(__BIG_ENDIAN_BITFIELD) > u32 reserved:25; > u32 supportCrashDump:1; > - u32 reserved1:6; > + u32 supportMaxExtLDs:1; > + u32 supportT10RebuildAssist:1; > + u32 supportDisableImmediateIO:1; > + u32 supportThermalPollInterval:1; > + u32 supportPersonalityChange:2; > #else > - u32 reserved1:6; > + u32 supportPersonalityChange:2; > + u32 supportThermalPollInterval:1; > + u32 supportDisableImmediateIO:1; > + u32 supportT10RebuildAssist:1; > + u32 supportMaxExtLDs:1; > u32 supportCrashDump:1; > u32 reserved:25; > #endif > @@ -979,13 +996,12 @@ struct megasas_ctrl_info { > * =============================== > */ > #define MEGASAS_MAX_PD_CHANNELS 2 > -#define MEGASAS_MAX_LD_CHANNELS 1 > +#define MEGASAS_MAX_LD_CHANNELS 2 > #define MEGASAS_MAX_CHANNELS (MEGASAS_MAX_PD_CHANNELS + \ > MEGASAS_MAX_LD_CHANNELS) > #define MEGASAS_MAX_DEV_PER_CHANNEL 128 > #define MEGASAS_DEFAULT_INIT_ID -1 > #define MEGASAS_MAX_LUN 8 > -#define MEGASAS_MAX_LD 64 > #define MEGASAS_DEFAULT_CMD_PER_LUN 256 > #define MEGASAS_MAX_PD (MEGASAS_MAX_PD_CHANNELS * \ > MEGASAS_MAX_DEV_PER_CHANNEL) > @@ -998,6 +1014,8 @@ struct megasas_ctrl_info { > > #define MEGASAS_FW_BUSY 1 > > +#define VD_EXT_DEBUG 0 > + > /* Frame Type */ > #define IO_FRAME 0 > #define PTHRU_FRAME 1 > @@ -1170,13 +1188,17 @@ union megasas_sgl_frame { > typedef union _MFI_CAPABILITIES { > struct { > #if defined(__BIG_ENDIAN_BITFIELD) > - u32 reserved:30; > + u32 reserved:28; > + u32 support_max_255lds:1; > + u32 reserved1:1; > u32 support_additional_msix:1; > u32 support_fp_remote_lun:1; > #else > u32 support_fp_remote_lun:1; > u32 support_additional_msix:1; > - u32 reserved:30; > + u32 reserved1:1; > + u32 support_max_255lds:1; > + u32 reserved:28; > #endif > } mfi_capabilities; > u32 reg; > @@ -1665,6 +1687,14 @@ struct megasas_instance { > u8 issuepend_done; > u8 disableOnlineCtrlReset; > u8 UnevenSpanSupport; > + > + u8 supportmax256vd; > + u16 fw_supported_vd_count; > + u16 fw_supported_pd_count; > + > + u16 drv_supported_vd_count; > + u16 drv_supported_pd_count; > + > u8 adprecovery; > unsigned long last_time; > u32 mfiStatus; > @@ -1674,6 +1704,8 @@ struct megasas_instance { > > /* Ptr to hba specific information */ > void *ctrl_context; > + u32 ctrl_context_pages; > + struct megasas_ctrl_info *ctrl_info; > unsigned int msix_vectors; > struct msix_entry msixentry[MEGASAS_MAX_MSIX_QUEUES]; > struct megasas_irq_context irq_context[MEGASAS_MAX_MSIX_QUEUES]; > @@ -1874,16 +1906,21 @@ u8 > MR_BuildRaidContext(struct megasas_instance *instance, > struct IO_REQUEST_INFO *io_info, > struct RAID_CONTEXT *pRAID_Context, > - struct MR_FW_RAID_MAP_ALL *map, u8 **raidLUN); > -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_FW_RAID_MAP_ALL *map); > -struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_FW_RAID_MAP_ALL *map); > -u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_FW_RAID_MAP_ALL *map); > -u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_FW_RAID_MAP_ALL *map); > -u16 MR_PdDevHandleGet(u32 pd, struct MR_FW_RAID_MAP_ALL *map); > -u16 MR_GetLDTgtId(u32 ld, struct MR_FW_RAID_MAP_ALL *map); > - > + struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN); > +u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map); > +struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL *map); > +u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map); > +u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map); > +u16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map); > +u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map); > + > +void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map, > + struct LD_LOAD_BALANCE_INFO *lbInfo); > +int megasas_get_ctrl_info(struct megasas_instance *instance, > + struct megasas_ctrl_info *ctrl_info); > int megasas_set_crash_dump_params(struct megasas_instance *instance, > - u8 crash_buf_state); > + u8 crash_buf_state); > void megasas_free_host_crash_buffer(struct megasas_instance *instance); > void megasas_fusion_crash_dump_wq(struct work_struct *work); > + > #endif /*LSI_MEGARAID_SAS_H */ > diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c > index 5b58e39d..9dbbd9d 100644 > --- a/drivers/scsi/megaraid/megaraid_sas_base.c > +++ b/drivers/scsi/megaraid/megaraid_sas_base.c > @@ -1581,7 +1581,8 @@ megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd > scmd->result = 0; > > if (MEGASAS_IS_LOGICAL(scmd) && > - (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) { > + (scmd->device->id >= instance->fw_supported_vd_count || > + scmd->device->lun)) { > scmd->result = DID_BAD_TARGET << 16; > goto out_done; > } > @@ -3846,6 +3847,8 @@ megasas_get_ld_list(struct megasas_instance *instance) > memset(ci, 0, sizeof(*ci)); > memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); > > + if (instance->supportmax256vd) > + dcmd->mbox.b[0] = 1; > dcmd->cmd = MFI_CMD_DCMD; > dcmd->cmd_status = 0xFF; > dcmd->sge_count = 1; > @@ -3867,8 +3870,8 @@ megasas_get_ld_list(struct megasas_instance *instance) > > /* the following function will get the instance PD LIST */ > > - if ((ret == 0) && (ld_count <= MAX_LOGICAL_DRIVES)) { > - memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); > + if ((ret == 0) && (ld_count <= instance->fw_supported_vd_count)) { > + memset(instance->ld_ids, 0xff, MAX_LOGICAL_DRIVES_EXT); > > for (ld_index = 0; ld_index < ld_count; ld_index++) { > if (ci->ldList[ld_index].state != 0) { > @@ -3931,6 +3934,8 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type) > memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); > > dcmd->mbox.b[0] = query_type; > + if (instance->supportmax256vd) > + dcmd->mbox.b[2] = 1; > > dcmd->cmd = MFI_CMD_DCMD; > dcmd->cmd_status = 0xFF; > @@ -3952,7 +3957,7 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type) > > tgtid_count = le32_to_cpu(ci->count); > > - if ((ret == 0) && (tgtid_count <= (MAX_LOGICAL_DRIVES))) { > + if ((ret == 0) && (tgtid_count <= (instance->fw_supported_vd_count))) { > memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); > for (ld_index = 0; ld_index < tgtid_count; ld_index++) { > ids = ci->targetId[ld_index]; > @@ -3978,7 +3983,7 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type) > * This information is mainly used to find out the maximum IO transfer per > * command supported by the FW. > */ > -static int > +int > megasas_get_ctrl_info(struct megasas_instance *instance, > struct megasas_ctrl_info *ctrl_info) > { > @@ -4019,6 +4024,7 @@ megasas_get_ctrl_info(struct megasas_instance *instance, > dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_GET_INFO); > dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h); > dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_ctrl_info)); > + dcmd->mbox.b[0] = 1; > > if (!megasas_issue_polled(instance, cmd)) { > ret = 0; > @@ -4217,6 +4223,13 @@ megasas_init_adapter_mfi(struct megasas_instance *instance) > if (megasas_issue_init_mfi(instance)) > goto fail_fw_init; > > + if (megasas_get_ctrl_info(instance, instance->ctrl_info)) { > + dev_err(&instance->pdev->dev, "(%d): Could get controller info " > + "Fail from %s %d\n", instance->unique_id, > + __func__, __LINE__); > + goto fail_fw_init; > + } > + > instance->fw_support_ieee = 0; > instance->fw_support_ieee = > (instance->instancet->read_fw_status_reg(reg_set) & > @@ -4255,7 +4268,7 @@ static int megasas_init_fw(struct megasas_instance *instance) > u32 tmp_sectors, msix_enable, scratch_pad_2; > resource_size_t base_addr; > struct megasas_register_set __iomem *reg_set; > - struct megasas_ctrl_info *ctrl_info; > + struct megasas_ctrl_info *ctrl_info = NULL; > unsigned long bar_list; > int i, loop, fw_msix_count = 0; > struct IOV_111 *iovPtr; > @@ -4386,6 +4399,17 @@ static int megasas_init_fw(struct megasas_instance *instance) > instance->msix_vectors); > } > > + instance->ctrl_info = kzalloc(sizeof(struct megasas_ctrl_info), > + GFP_KERNEL); > + if (instance->ctrl_info == NULL) > + goto fail_init_adapter; > + > + /* > + * Below are default value for legacy Firmware. > + * non-fusion based controllers > + */ > + instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES; > + instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES; > /* Get operational params, sge flags, send init cmd to controller */ > if (instance->instancet->init_adapter(instance)) > goto fail_init_adapter; > @@ -4408,8 +4432,6 @@ static int megasas_init_fw(struct megasas_instance *instance) > MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) > megasas_get_ld_list(instance); > > - ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL); > - > /* > * Compute the max allowed sectors per IO: The controller info has two > * limits on max sectors. Driver should use the minimum of these two. > @@ -4420,79 +4442,79 @@ static int megasas_init_fw(struct megasas_instance *instance) > * to calculate max_sectors_1. So the number ended up as zero always. > */ > tmp_sectors = 0; > - if (ctrl_info && !megasas_get_ctrl_info(instance, ctrl_info)) { > - > - max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) * > - le16_to_cpu(ctrl_info->max_strips_per_io); > - max_sectors_2 = le32_to_cpu(ctrl_info->max_request_size); > + ctrl_info = instance->ctrl_info; > > - tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2); > + max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) * > + le16_to_cpu(ctrl_info->max_strips_per_io); > + max_sectors_2 = le32_to_cpu(ctrl_info->max_request_size); > > - /*Check whether controller is iMR or MR */ > - if (ctrl_info->memory_size) { > - instance->is_imr = 0; > - dev_info(&instance->pdev->dev, "Controller type: MR," > - "Memory size is: %dMB\n", > - le16_to_cpu(ctrl_info->memory_size)); > - } else { > - instance->is_imr = 1; > - dev_info(&instance->pdev->dev, > - "Controller type: iMR\n"); > - } > - /* OnOffProperties are converted into CPU arch*/ > - le32_to_cpus((u32 *)&ctrl_info->properties.OnOffProperties); > - instance->disableOnlineCtrlReset = > - ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset; > - /* adapterOperations2 are converted into CPU arch*/ > - le32_to_cpus((u32 *)&ctrl_info->adapterOperations2); > - instance->mpio = ctrl_info->adapterOperations2.mpio; > - instance->UnevenSpanSupport = > - ctrl_info->adapterOperations2.supportUnevenSpans; > - if (instance->UnevenSpanSupport) { > - struct fusion_context *fusion = instance->ctrl_context; > - dev_info(&instance->pdev->dev, "FW supports: " > - "UnevenSpanSupport=%x\n", instance->UnevenSpanSupport); > - if (MR_ValidateMapInfo(instance)) > - fusion->fast_path_io = 1; > - else > - fusion->fast_path_io = 0; > + tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2); > > - } > - if (ctrl_info->host_interface.SRIOV) { > - if (!ctrl_info->adapterOperations2.activePassive) > - instance->PlasmaFW111 = 1; > - > - if (!instance->PlasmaFW111) > - instance->requestorId = > - ctrl_info->iov.requestorId; > - else { > - iovPtr = (struct IOV_111 *)((unsigned char *)ctrl_info + IOV_111_OFFSET); > - instance->requestorId = iovPtr->requestorId; > - } > - printk(KERN_WARNING "megaraid_sas: I am VF " > - "requestorId %d\n", instance->requestorId); > - } > + /*Check whether controller is iMR or MR */ > + if (ctrl_info->memory_size) { > + instance->is_imr = 0; > + dev_info(&instance->pdev->dev, "Controller type: MR," > + "Memory size is: %dMB\n", > + le16_to_cpu(ctrl_info->memory_size)); > + } else { > + instance->is_imr = 1; > + dev_info(&instance->pdev->dev, > + "Controller type: iMR\n"); > + } > + /* OnOffProperties are converted into CPU arch*/ > + le32_to_cpus((u32 *)&ctrl_info->properties.OnOffProperties); > + instance->disableOnlineCtrlReset = > + ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset; > + /* adapterOperations2 are converted into CPU arch*/ > + le32_to_cpus((u32 *)&ctrl_info->adapterOperations2); > + instance->mpio = ctrl_info->adapterOperations2.mpio; > + instance->UnevenSpanSupport = > + ctrl_info->adapterOperations2.supportUnevenSpans; > + if (instance->UnevenSpanSupport) { > + struct fusion_context *fusion = instance->ctrl_context; > + > + dev_info(&instance->pdev->dev, "FW supports: " > + "UnevenSpanSupport=%x\n", instance->UnevenSpanSupport); > + if (MR_ValidateMapInfo(instance)) > + fusion->fast_path_io = 1; > + else > + fusion->fast_path_io = 0; > > - le32_to_cpus((u32 *)&ctrl_info->adapterOperations3); > - instance->crash_dump_fw_support = > - ctrl_info->adapterOperations3.supportCrashDump; > - instance->crash_dump_drv_support = > - (instance->crash_dump_fw_support && > - instance->crash_dump_buf); > - if (instance->crash_dump_drv_support) { > - dev_info(&instance->pdev->dev, "Firmware Crash dump " > - "feature is supported\n"); > - megasas_set_crash_dump_params(instance, > - MR_CRASH_BUF_TURN_OFF); > + } > + if (ctrl_info->host_interface.SRIOV) { > + if (!ctrl_info->adapterOperations2.activePassive) > + instance->PlasmaFW111 = 1; > > - } else { > - if (instance->crash_dump_buf) > - pci_free_consistent(instance->pdev, > - CRASH_DMA_BUF_SIZE, > - instance->crash_dump_buf, > - instance->crash_dump_h); > - instance->crash_dump_buf = NULL; > + if (!instance->PlasmaFW111) > + instance->requestorId = > + ctrl_info->iov.requestorId; > + else { > + iovPtr = (struct IOV_111 *)((unsigned char *)ctrl_info + IOV_111_OFFSET); > + instance->requestorId = iovPtr->requestorId; > } > + dev_warn(&instance->pdev->dev, "I am VF " > + "requestorId %d\n", instance->requestorId); > + } > + > + le32_to_cpus((u32 *)&ctrl_info->adapterOperations3); > + instance->crash_dump_fw_support = > + ctrl_info->adapterOperations3.supportCrashDump; > + instance->crash_dump_drv_support = > + (instance->crash_dump_fw_support && > + instance->crash_dump_buf); > + if (instance->crash_dump_drv_support) { > + dev_info(&instance->pdev->dev, "Firmware Crash dump " > + "feature is supported\n"); > + megasas_set_crash_dump_params(instance, > + MR_CRASH_BUF_TURN_OFF); > + > + } else { > + if (instance->crash_dump_buf) > + pci_free_consistent(instance->pdev, > + CRASH_DMA_BUF_SIZE, > + instance->crash_dump_buf, > + instance->crash_dump_h); > + instance->crash_dump_buf = NULL; > } > instance->max_sectors_per_req = instance->max_num_sge * > PAGE_SIZE / 512; > @@ -4540,6 +4562,8 @@ static int megasas_init_fw(struct megasas_instance *instance) > > fail_init_adapter: > fail_ready_state: > + kfree(instance->ctrl_info); > + instance->ctrl_info = NULL; > iounmap(instance->reg_set); > > fail_ioremap: > @@ -4918,6 +4942,7 @@ static int megasas_probe_one(struct pci_dev *pdev, > struct Scsi_Host *host; > struct megasas_instance *instance; > u16 control = 0; > + struct fusion_context *fusion = NULL; > > /* Reset MSI-X in the kdump kernel */ > if (reset_devices) { > @@ -4978,10 +5003,10 @@ static int megasas_probe_one(struct pci_dev *pdev, > case PCI_DEVICE_ID_LSI_INVADER: > case PCI_DEVICE_ID_LSI_FURY: > { > - struct fusion_context *fusion; > - > - instance->ctrl_context = > - kzalloc(sizeof(struct fusion_context), GFP_KERNEL); > + instance->ctrl_context_pages = > + get_order(sizeof(struct fusion_context)); > + instance->ctrl_context = (void *)__get_free_pages(GFP_KERNEL, > + instance->ctrl_context_pages); > if (!instance->ctrl_context) { > printk(KERN_DEBUG "megasas: Failed to allocate " > "memory for Fusion context info\n"); > @@ -4990,6 +5015,8 @@ static int megasas_probe_one(struct pci_dev *pdev, > fusion = instance->ctrl_context; > INIT_LIST_HEAD(&fusion->cmd_pool); > spin_lock_init(&fusion->cmd_pool_lock); > + memset(fusion->load_balance_info, 0, > + sizeof(struct LD_LOAD_BALANCE_INFO) * MAX_LOGICAL_DRIVES_EXT); > } > break; > default: /* For all other supported controllers */ > @@ -5033,7 +5060,6 @@ static int megasas_probe_one(struct pci_dev *pdev, > instance->issuepend_done = 1; > instance->adprecovery = MEGASAS_HBA_OPERATIONAL; > instance->is_imr = 0; > - megasas_poll_wait_aen = 0; > > instance->evt_detail = pci_alloc_consistent(pdev, > sizeof(struct > @@ -5070,6 +5096,7 @@ static int megasas_probe_one(struct pci_dev *pdev, > instance->host = host; > instance->unique_id = pdev->bus->number << 8 | pdev->devfn; > instance->init_id = MEGASAS_DEFAULT_INIT_ID; > + instance->ctrl_info = NULL; > > if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || > (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) { > @@ -5630,14 +5657,18 @@ static void megasas_detach_one(struct pci_dev *pdev) > case PCI_DEVICE_ID_LSI_INVADER: > case PCI_DEVICE_ID_LSI_FURY: > megasas_release_fusion(instance); > - for (i = 0; i < 2 ; i++) > + for (i = 0; i < 2 ; i++) { > if (fusion->ld_map[i]) > dma_free_coherent(&instance->pdev->dev, > - fusion->map_sz, > + fusion->max_map_sz, > fusion->ld_map[i], > - fusion-> > - ld_map_phys[i]); > - kfree(instance->ctrl_context); > + fusion->ld_map_phys[i]); > + if (fusion->ld_drv_map[i]) > + free_pages((ulong)fusion->ld_drv_map[i], > + fusion->drv_map_pages); > + } > + free_pages((ulong)instance->ctrl_context, > + instance->ctrl_context_pages); > break; > default: > megasas_release_mfi(instance); > @@ -5650,6 +5681,8 @@ static void megasas_detach_one(struct pci_dev *pdev) > break; > } > > + kfree(instance->ctrl_info); > + > if (instance->evt_detail) > pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), > instance->evt_detail, instance->evt_detail_h); > @@ -5760,8 +5793,10 @@ static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait) > spin_lock_irqsave(&poll_aen_lock, flags); > if (megasas_poll_wait_aen) > mask = (POLLIN | POLLRDNORM); > + > else > mask = 0; > + megasas_poll_wait_aen = 0; > spin_unlock_irqrestore(&poll_aen_lock, flags); > return mask; > } > diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c > index 081bfff..c2eaf6e 100644 > --- a/drivers/scsi/megaraid/megaraid_sas_fp.c > +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c > @@ -66,16 +66,13 @@ > #define SPAN_INVALID 0xff > > /* Prototypes */ > -void mr_update_load_balance_params(struct MR_FW_RAID_MAP_ALL *map, > - struct LD_LOAD_BALANCE_INFO *lbInfo); > - > -static void mr_update_span_set(struct MR_FW_RAID_MAP_ALL *map, > +static void mr_update_span_set(struct MR_DRV_RAID_MAP_ALL *map, > PLD_SPAN_INFO ldSpanInfo); > static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, > u64 stripRow, u16 stripRef, struct IO_REQUEST_INFO *io_info, > - struct RAID_CONTEXT *pRAID_Context, struct MR_FW_RAID_MAP_ALL *map); > + struct RAID_CONTEXT *pRAID_Context, struct MR_DRV_RAID_MAP_ALL *map); > static u64 get_row_from_strip(struct megasas_instance *instance, u32 ld, > - u64 strip, struct MR_FW_RAID_MAP_ALL *map); > + u64 strip, struct MR_DRV_RAID_MAP_ALL *map); > > u32 mega_mod64(u64 dividend, u32 divisor) > { > @@ -109,94 +106,183 @@ u64 mega_div64_32(uint64_t dividend, uint32_t divisor) > return d; > } > > -struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_FW_RAID_MAP_ALL *map) > +struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL *map) > { > return &map->raidMap.ldSpanMap[ld].ldRaid; > } > > static struct MR_SPAN_BLOCK_INFO *MR_LdSpanInfoGet(u32 ld, > - struct MR_FW_RAID_MAP_ALL > + struct MR_DRV_RAID_MAP_ALL > *map) > { > return &map->raidMap.ldSpanMap[ld].spanBlock[0]; > } > > -static u8 MR_LdDataArmGet(u32 ld, u32 armIdx, struct MR_FW_RAID_MAP_ALL *map) > +static u8 MR_LdDataArmGet(u32 ld, u32 armIdx, struct MR_DRV_RAID_MAP_ALL *map) > { > return map->raidMap.ldSpanMap[ld].dataArmMap[armIdx]; > } > > -u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_FW_RAID_MAP_ALL *map) > +u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map) > { > return le16_to_cpu(map->raidMap.arMapInfo[ar].pd[arm]); > } > > -u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_FW_RAID_MAP_ALL *map) > +u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map) > { > return le16_to_cpu(map->raidMap.ldSpanMap[ld].spanBlock[span].span.arrayRef); > } > > -u16 MR_PdDevHandleGet(u32 pd, struct MR_FW_RAID_MAP_ALL *map) > +u16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map) > { > return map->raidMap.devHndlInfo[pd].curDevHdl; > } > > -u16 MR_GetLDTgtId(u32 ld, struct MR_FW_RAID_MAP_ALL *map) > +u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map) > { > return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId); > } > > -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_FW_RAID_MAP_ALL *map) > +u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map) > { > return map->raidMap.ldTgtIdToLd[ldTgtId]; > } > > static struct MR_LD_SPAN *MR_LdSpanPtrGet(u32 ld, u32 span, > - struct MR_FW_RAID_MAP_ALL *map) > + struct MR_DRV_RAID_MAP_ALL *map) > { > return &map->raidMap.ldSpanMap[ld].spanBlock[span].span; > } > > /* > + * This function will Populate Driver Map using firmware raid map > + */ > +void MR_PopulateDrvRaidMap(struct megasas_instance *instance) > +{ > + struct fusion_context *fusion = instance->ctrl_context; > + struct MR_FW_RAID_MAP_ALL *fw_map_old = NULL; > + struct MR_FW_RAID_MAP *pFwRaidMap = NULL; > + int i; > + > + > + struct MR_DRV_RAID_MAP_ALL *drv_map = > + fusion->ld_drv_map[(instance->map_id & 1)]; > + struct MR_DRV_RAID_MAP *pDrvRaidMap = &drv_map->raidMap; > + > + if (instance->supportmax256vd) { > + memcpy(fusion->ld_drv_map[instance->map_id & 1], > + fusion->ld_map[instance->map_id & 1], > + fusion->current_map_sz); > + /* New Raid map will not set totalSize, so keep expected value > + * for legacy code in ValidateMapInfo > + */ > + pDrvRaidMap->totalSize = sizeof(struct MR_FW_RAID_MAP_EXT); > + } else { > + fw_map_old = (struct MR_FW_RAID_MAP_ALL *) > + fusion->ld_map[(instance->map_id & 1)]; > + pFwRaidMap = &fw_map_old->raidMap; > + > +#if VD_EXT_DEBUG > + for (i = 0; i < pFwRaidMap->ldCount; i++) { > + dev_dbg(&instance->pdev->dev, "(%d) :Index 0x%x " > + "Target Id 0x%x Seq Num 0x%x Size 0/%llx\n", > + instance->unique_id, i, > + fw_map_old->raidMap.ldSpanMap[i].ldRaid.targetId, > + fw_map_old->raidMap.ldSpanMap[i].ldRaid.seqNum, > + fw_map_old->raidMap.ldSpanMap[i].ldRaid.size); > + } > +#endif > + > + memset(drv_map, 0, fusion->drv_map_sz); > + pDrvRaidMap->totalSize = pFwRaidMap->totalSize; > + pDrvRaidMap->ldCount = pFwRaidMap->ldCount; > + pDrvRaidMap->fpPdIoTimeoutSec = pFwRaidMap->fpPdIoTimeoutSec; > + for (i = 0; i < MAX_RAIDMAP_LOGICAL_DRIVES + MAX_RAIDMAP_VIEWS; i++) > + pDrvRaidMap->ldTgtIdToLd[i] = > + (u8)pFwRaidMap->ldTgtIdToLd[i]; > + for (i = 0; i < pDrvRaidMap->ldCount; i++) { > + pDrvRaidMap->ldSpanMap[i] = pFwRaidMap->ldSpanMap[i]; > +#if VD_EXT_DEBUG > + dev_dbg(&instance->pdev->dev, > + "pFwRaidMap->ldSpanMap[%d].ldRaid.targetId 0x%x " > + "pFwRaidMap->ldSpanMap[%d].ldRaid.seqNum 0x%x " > + "size 0x%x\n", i, i, > + pFwRaidMap->ldSpanMap[i].ldRaid.targetId, > + pFwRaidMap->ldSpanMap[i].ldRaid.seqNum, > + (u32)pFwRaidMap->ldSpanMap[i].ldRaid.rowSize); > + dev_dbg(&instance->pdev->dev, > + "pDrvRaidMap->ldSpanMap[%d].ldRaid.targetId 0x%x " > + "pDrvRaidMap->ldSpanMap[%d].ldRaid.seqNum 0x%x " > + "size 0x%x\n", i, i, > + pDrvRaidMap->ldSpanMap[i].ldRaid.targetId, > + pDrvRaidMap->ldSpanMap[i].ldRaid.seqNum, > + (u32)pDrvRaidMap->ldSpanMap[i].ldRaid.rowSize); > + dev_dbg(&instance->pdev->dev, "Driver raid map all %p " > + "raid map %p LD RAID MAP %p/%p\n", drv_map, > + pDrvRaidMap, &pFwRaidMap->ldSpanMap[i].ldRaid, > + &pDrvRaidMap->ldSpanMap[i].ldRaid); > +#endif > + } > + memcpy(pDrvRaidMap->arMapInfo, pFwRaidMap->arMapInfo, > + sizeof(struct MR_ARRAY_INFO) * MAX_RAIDMAP_ARRAYS); > + memcpy(pDrvRaidMap->devHndlInfo, pFwRaidMap->devHndlInfo, > + sizeof(struct MR_DEV_HANDLE_INFO) * > + MAX_RAIDMAP_PHYSICAL_DEVICES); > + } > +} > + > +/* > * This function will validate Map info data provided by FW > */ > u8 MR_ValidateMapInfo(struct megasas_instance *instance) > { > - struct fusion_context *fusion = instance->ctrl_context; > - struct MR_FW_RAID_MAP_ALL *map = fusion->ld_map[(instance->map_id & 1)]; > - struct LD_LOAD_BALANCE_INFO *lbInfo = fusion->load_balance_info; > - PLD_SPAN_INFO ldSpanInfo = fusion->log_to_span; > - struct MR_FW_RAID_MAP *pFwRaidMap = &map->raidMap; > + struct fusion_context *fusion; > + struct MR_DRV_RAID_MAP_ALL *drv_map; > + struct MR_DRV_RAID_MAP *pDrvRaidMap; > + struct LD_LOAD_BALANCE_INFO *lbInfo; > + PLD_SPAN_INFO ldSpanInfo; > struct MR_LD_RAID *raid; > int ldCount, num_lds; > u16 ld; > + u32 expected_size; > > > - if (le32_to_cpu(pFwRaidMap->totalSize) != > - (sizeof(struct MR_FW_RAID_MAP) -sizeof(struct MR_LD_SPAN_MAP) + > - (sizeof(struct MR_LD_SPAN_MAP) * le32_to_cpu(pFwRaidMap->ldCount)))) { > - printk(KERN_ERR "megasas: map info structure size 0x%x is not matching with ld count\n", > - (unsigned int)((sizeof(struct MR_FW_RAID_MAP) - > - sizeof(struct MR_LD_SPAN_MAP)) + > - (sizeof(struct MR_LD_SPAN_MAP) * > - le32_to_cpu(pFwRaidMap->ldCount)))); > - printk(KERN_ERR "megasas: span map %x, pFwRaidMap->totalSize " > - ": %x\n", (unsigned int)sizeof(struct MR_LD_SPAN_MAP), > - le32_to_cpu(pFwRaidMap->totalSize)); > + MR_PopulateDrvRaidMap(instance); > + > + fusion = instance->ctrl_context; > + drv_map = fusion->ld_drv_map[(instance->map_id & 1)]; > + pDrvRaidMap = &drv_map->raidMap; > + > + lbInfo = fusion->load_balance_info; > + ldSpanInfo = fusion->log_to_span; > + > + if (instance->supportmax256vd) > + expected_size = sizeof(struct MR_FW_RAID_MAP_EXT); > + else > + expected_size = > + (sizeof(struct MR_FW_RAID_MAP) - sizeof(struct MR_LD_SPAN_MAP) + > + (sizeof(struct MR_LD_SPAN_MAP) * le32_to_cpu(pDrvRaidMap->ldCount))); > + > + if (le32_to_cpu(pDrvRaidMap->totalSize) != expected_size) { > + dev_err(&instance->pdev->dev, "map info structure size 0x%x is not matching with ld count\n", > + (unsigned int) expected_size); > + dev_err(&instance->pdev->dev, "megasas: span map %x, pDrvRaidMap->totalSize : %x\n", > + (unsigned int)sizeof(struct MR_LD_SPAN_MAP), > + le32_to_cpu(pDrvRaidMap->totalSize)); > return 0; > } > > if (instance->UnevenSpanSupport) > - mr_update_span_set(map, ldSpanInfo); > + mr_update_span_set(drv_map, ldSpanInfo); > > - mr_update_load_balance_params(map, lbInfo); > + mr_update_load_balance_params(drv_map, lbInfo); > > - num_lds = le32_to_cpu(map->raidMap.ldCount); > + num_lds = le32_to_cpu(drv_map->raidMap.ldCount); > > /*Convert Raid capability values to CPU arch */ > for (ldCount = 0; ldCount < num_lds; ldCount++) { > - ld = MR_TargetIdToLdGet(ldCount, map); > - raid = MR_LdRaidGet(ld, map); > + ld = MR_TargetIdToLdGet(ldCount, drv_map); > + raid = MR_LdRaidGet(ld, drv_map); > le32_to_cpus((u32 *)&raid->capability); > } > > @@ -204,7 +290,7 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance) > } > > u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk, > - struct MR_FW_RAID_MAP_ALL *map) > + struct MR_DRV_RAID_MAP_ALL *map) > { > struct MR_SPAN_BLOCK_INFO *pSpanBlock = MR_LdSpanInfoGet(ld, map); > struct MR_QUAD_ELEMENT *quad; > @@ -246,7 +332,8 @@ u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk, > * ldSpanInfo - ldSpanInfo per HBA instance > */ > #if SPAN_DEBUG > -static int getSpanInfo(struct MR_FW_RAID_MAP_ALL *map, PLD_SPAN_INFO ldSpanInfo) > +static int getSpanInfo(struct MR_DRV_RAID_MAP_ALL *map, > + PLD_SPAN_INFO ldSpanInfo) > { > > u8 span; > @@ -257,9 +344,9 @@ static int getSpanInfo(struct MR_FW_RAID_MAP_ALL *map, PLD_SPAN_INFO ldSpanInfo) > int ldCount; > u16 ld; > > - for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) { > + for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES_EXT; ldCount++) { > ld = MR_TargetIdToLdGet(ldCount, map); > - if (ld >= MAX_LOGICAL_DRIVES) > + if (ld >= MAX_LOGICAL_DRIVES_EXT) > continue; > raid = MR_LdRaidGet(ld, map); > dev_dbg(&instance->pdev->dev, "LD %x: span_depth=%x\n", > @@ -339,7 +426,7 @@ static int getSpanInfo(struct MR_FW_RAID_MAP_ALL *map, PLD_SPAN_INFO ldSpanInfo) > */ > > u32 mr_spanset_get_span_block(struct megasas_instance *instance, > - u32 ld, u64 row, u64 *span_blk, struct MR_FW_RAID_MAP_ALL *map) > + u32 ld, u64 row, u64 *span_blk, struct MR_DRV_RAID_MAP_ALL *map) > { > struct fusion_context *fusion = instance->ctrl_context; > struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); > @@ -402,7 +489,7 @@ u32 mr_spanset_get_span_block(struct megasas_instance *instance, > */ > > static u64 get_row_from_strip(struct megasas_instance *instance, > - u32 ld, u64 strip, struct MR_FW_RAID_MAP_ALL *map) > + u32 ld, u64 strip, struct MR_DRV_RAID_MAP_ALL *map) > { > struct fusion_context *fusion = instance->ctrl_context; > struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); > @@ -471,7 +558,7 @@ static u64 get_row_from_strip(struct megasas_instance *instance, > */ > > static u64 get_strip_from_row(struct megasas_instance *instance, > - u32 ld, u64 row, struct MR_FW_RAID_MAP_ALL *map) > + u32 ld, u64 row, struct MR_DRV_RAID_MAP_ALL *map) > { > struct fusion_context *fusion = instance->ctrl_context; > struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); > @@ -532,7 +619,7 @@ static u64 get_strip_from_row(struct megasas_instance *instance, > */ > > static u32 get_arm_from_strip(struct megasas_instance *instance, > - u32 ld, u64 strip, struct MR_FW_RAID_MAP_ALL *map) > + u32 ld, u64 strip, struct MR_DRV_RAID_MAP_ALL *map) > { > struct fusion_context *fusion = instance->ctrl_context; > struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); > @@ -580,7 +667,7 @@ static u32 get_arm_from_strip(struct megasas_instance *instance, > > /* This Function will return Phys arm */ > u8 get_arm(struct megasas_instance *instance, u32 ld, u8 span, u64 stripe, > - struct MR_FW_RAID_MAP_ALL *map) > + struct MR_DRV_RAID_MAP_ALL *map) > { > struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); > /* Need to check correct default value */ > @@ -624,7 +711,7 @@ u8 get_arm(struct megasas_instance *instance, u32 ld, u8 span, u64 stripe, > static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, > u64 stripRow, u16 stripRef, struct IO_REQUEST_INFO *io_info, > struct RAID_CONTEXT *pRAID_Context, > - struct MR_FW_RAID_MAP_ALL *map) > + struct MR_DRV_RAID_MAP_ALL *map) > { > struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); > u32 pd, arRef; > @@ -705,7 +792,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, > u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, > u16 stripRef, struct IO_REQUEST_INFO *io_info, > struct RAID_CONTEXT *pRAID_Context, > - struct MR_FW_RAID_MAP_ALL *map) > + struct MR_DRV_RAID_MAP_ALL *map) > { > struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); > u32 pd, arRef; > @@ -794,7 +881,7 @@ u8 > MR_BuildRaidContext(struct megasas_instance *instance, > struct IO_REQUEST_INFO *io_info, > struct RAID_CONTEXT *pRAID_Context, > - struct MR_FW_RAID_MAP_ALL *map, u8 **raidLUN) > + struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN) > { > struct MR_LD_RAID *raid; > u32 ld, stripSize, stripe_mask; > @@ -1043,7 +1130,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, > * ldSpanInfo - ldSpanInfo per HBA instance > * > */ > -void mr_update_span_set(struct MR_FW_RAID_MAP_ALL *map, > +void mr_update_span_set(struct MR_DRV_RAID_MAP_ALL *map, > PLD_SPAN_INFO ldSpanInfo) > { > u8 span, count; > @@ -1056,9 +1143,9 @@ void mr_update_span_set(struct MR_FW_RAID_MAP_ALL *map, > u16 ld; > > > - for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) { > + for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES_EXT; ldCount++) { > ld = MR_TargetIdToLdGet(ldCount, map); > - if (ld >= MAX_LOGICAL_DRIVES) > + if (ld >= MAX_LOGICAL_DRIVES_EXT) > continue; > raid = MR_LdRaidGet(ld, map); > for (element = 0; element < MAX_QUAD_DEPTH; element++) { > @@ -1153,16 +1240,16 @@ void mr_update_span_set(struct MR_FW_RAID_MAP_ALL *map, > } > > void > -mr_update_load_balance_params(struct MR_FW_RAID_MAP_ALL *map, > +mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map, > struct LD_LOAD_BALANCE_INFO *lbInfo) > { > int ldCount; > u16 ld; > struct MR_LD_RAID *raid; > > - for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) { > + for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES_EXT; ldCount++) { > ld = MR_TargetIdToLdGet(ldCount, map); > - if (ld >= MAX_LOGICAL_DRIVES) { > + if (ld >= MAX_LOGICAL_DRIVES_EXT) { > lbInfo[ldCount].loadBalanceFlag = 0; > continue; > } > diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c > index aaba2a7..65f617e 100644 > --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c > +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c > @@ -652,6 +652,8 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) > /* driver supports HA / Remote LUN over Fast Path interface */ > init_frame->driver_operations.mfi_capabilities.support_fp_remote_lun > = 1; > + init_frame->driver_operations.mfi_capabilities.support_max_255lds > + = 1; > /* Convert capability to LE32 */ > cpu_to_le32s((u32 *)&init_frame->driver_operations.mfi_capabilities); > > @@ -711,6 +713,13 @@ fail_get_cmd: > * Issues an internal command (DCMD) to get the FW's controller PD > * list structure. This information is mainly used to find out SYSTEM > * supported by the FW. > + * dcmd.mbox value setting for MR_DCMD_LD_MAP_GET_INFO > + * dcmd.mbox.b[0] - number of LDs being sync'd > + * dcmd.mbox.b[1] - 0 - complete command immediately. > + * - 1 - pend till config change > + * dcmd.mbox.b[2] - 0 - supports max 64 lds and uses legacy MR_FW_RAID_MAP > + * - 1 - supports max MAX_LOGICAL_DRIVES_EXT lds and > + * uses extended struct MR_FW_RAID_MAP_EXT > */ > static int > megasas_get_ld_map_info(struct megasas_instance *instance) > @@ -718,7 +727,7 @@ megasas_get_ld_map_info(struct megasas_instance *instance) > int ret = 0; > struct megasas_cmd *cmd; > struct megasas_dcmd_frame *dcmd; > - struct MR_FW_RAID_MAP_ALL *ci; > + void *ci; > dma_addr_t ci_h = 0; > u32 size_map_info; > struct fusion_context *fusion; > @@ -739,10 +748,9 @@ megasas_get_ld_map_info(struct megasas_instance *instance) > > dcmd = &cmd->frame->dcmd; > > - size_map_info = sizeof(struct MR_FW_RAID_MAP) + > - (sizeof(struct MR_LD_SPAN_MAP) *(MAX_LOGICAL_DRIVES - 1)); > + size_map_info = fusion->current_map_sz; > > - ci = fusion->ld_map[(instance->map_id & 1)]; > + ci = (void *) fusion->ld_map[(instance->map_id & 1)]; > ci_h = fusion->ld_map_phys[(instance->map_id & 1)]; > > if (!ci) { > @@ -751,9 +759,13 @@ megasas_get_ld_map_info(struct megasas_instance *instance) > return -ENOMEM; > } > > - memset(ci, 0, sizeof(*ci)); > + memset(ci, 0, fusion->max_map_sz); > memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); > - > +#if VD_EXT_DEBUG > + dev_dbg(&instance->pdev->dev, > + "%s sending MR_DCMD_LD_MAP_GET_INFO with size %d\n", > + __func__, cpu_to_le32(size_map_info)); > +#endif > dcmd->cmd = MFI_CMD_DCMD; > dcmd->cmd_status = 0xFF; > dcmd->sge_count = 1; > @@ -809,7 +821,7 @@ megasas_sync_map_info(struct megasas_instance *instance) > u32 size_sync_info, num_lds; > struct fusion_context *fusion; > struct MR_LD_TARGET_SYNC *ci = NULL; > - struct MR_FW_RAID_MAP_ALL *map; > + struct MR_DRV_RAID_MAP_ALL *map; > struct MR_LD_RAID *raid; > struct MR_LD_TARGET_SYNC *ld_sync; > dma_addr_t ci_h = 0; > @@ -830,7 +842,7 @@ megasas_sync_map_info(struct megasas_instance *instance) > return 1; > } > > - map = fusion->ld_map[instance->map_id & 1]; > + map = fusion->ld_drv_map[instance->map_id & 1]; > > num_lds = le32_to_cpu(map->raidMap.ldCount); > > @@ -842,7 +854,7 @@ megasas_sync_map_info(struct megasas_instance *instance) > > ci = (struct MR_LD_TARGET_SYNC *) > fusion->ld_map[(instance->map_id - 1) & 1]; > - memset(ci, 0, sizeof(struct MR_FW_RAID_MAP_ALL)); > + memset(ci, 0, fusion->max_map_sz); > > ci_h = fusion->ld_map_phys[(instance->map_id - 1) & 1]; > > @@ -854,8 +866,7 @@ megasas_sync_map_info(struct megasas_instance *instance) > ld_sync->seqNum = raid->seqNum; > } > > - size_map_info = sizeof(struct MR_FW_RAID_MAP) + > - (sizeof(struct MR_LD_SPAN_MAP) *(MAX_LOGICAL_DRIVES - 1)); > + size_map_info = fusion->current_map_sz; > > dcmd->cmd = MFI_CMD_DCMD; > dcmd->cmd_status = 0xFF; > @@ -1018,17 +1029,75 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) > goto fail_ioc_init; > > megasas_display_intel_branding(instance); > + if (megasas_get_ctrl_info(instance, instance->ctrl_info)) { > + dev_err(&instance->pdev->dev, > + "Could not get controller info. Fail from %s %d\n", > + __func__, __LINE__); > + goto fail_ioc_init; > + } > + > + instance->supportmax256vd = > + instance->ctrl_info->adapterOperations3.supportMaxExtLDs; > + /* Below is additional check to address future FW enhancement */ > + if (instance->ctrl_info->max_lds > 64) > + instance->supportmax256vd = 1; > + instance->drv_supported_vd_count = MEGASAS_MAX_LD_CHANNELS > + * MEGASAS_MAX_DEV_PER_CHANNEL; > + instance->drv_supported_pd_count = MEGASAS_MAX_PD_CHANNELS > + * MEGASAS_MAX_DEV_PER_CHANNEL; > + if (instance->supportmax256vd) { > + instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES_EXT; > + instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES; > + } else { > + instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES; > + instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES; > + } > + dev_info(&instance->pdev->dev, "Firmware supports %d VDs %d PDs\n" > + "Driver supports %d VDs %d PDs\n", > + instance->fw_supported_vd_count, > + instance->fw_supported_pd_count, > + instance->drv_supported_vd_count, > + instance->drv_supported_pd_count); > > instance->flag_ieee = 1; > + fusion->fast_path_io = 0; > > - fusion->map_sz = sizeof(struct MR_FW_RAID_MAP) + > - (sizeof(struct MR_LD_SPAN_MAP) *(MAX_LOGICAL_DRIVES - 1)); > + fusion->old_map_sz = > + sizeof(struct MR_FW_RAID_MAP) + (sizeof(struct MR_LD_SPAN_MAP) * > + (instance->fw_supported_vd_count - 1)); > + fusion->new_map_sz = > + sizeof(struct MR_FW_RAID_MAP_EXT); > + fusion->drv_map_sz = > + sizeof(struct MR_DRV_RAID_MAP) + (sizeof(struct MR_LD_SPAN_MAP) * > + (instance->drv_supported_vd_count - 1)); > + > + fusion->drv_map_pages = get_order(fusion->drv_map_sz); > + for (i = 0; i < 2; i++) { > + fusion->ld_map[i] = NULL; > + fusion->ld_drv_map[i] = (void *)__get_free_pages(GFP_KERNEL, > + fusion->drv_map_pages); > + if (!fusion->ld_drv_map[i]) { > + dev_err(&instance->pdev->dev, "Could not allocate " > + "memory for local map info for %d pages\n", > + fusion->drv_map_pages); > + if (i == 1) > + free_pages((ulong)fusion->ld_drv_map[0], > + fusion->drv_map_pages); > + goto fail_ioc_init; > + } > + } > + > + fusion->max_map_sz = max(fusion->old_map_sz, fusion->new_map_sz); > + > + if (instance->supportmax256vd) > + fusion->current_map_sz = fusion->new_map_sz; > + else > + fusion->current_map_sz = fusion->old_map_sz; > > - fusion->fast_path_io = 0; > > for (i = 0; i < 2; i++) { > fusion->ld_map[i] = dma_alloc_coherent(&instance->pdev->dev, > - fusion->map_sz, > + fusion->max_map_sz, > &fusion->ld_map_phys[i], > GFP_KERNEL); > if (!fusion->ld_map[i]) { > @@ -1045,7 +1114,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) > > fail_map_info: > if (i == 1) > - dma_free_coherent(&instance->pdev->dev, fusion->map_sz, > + dma_free_coherent(&instance->pdev->dev, fusion->max_map_sz, > fusion->ld_map[0], fusion->ld_map_phys[0]); > fail_ioc_init: > megasas_free_cmds_fusion(instance); > @@ -1234,7 +1303,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance, > void > megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len, > struct IO_REQUEST_INFO *io_info, struct scsi_cmnd *scp, > - struct MR_FW_RAID_MAP_ALL *local_map_ptr, u32 ref_tag) > + struct MR_DRV_RAID_MAP_ALL *local_map_ptr, u32 ref_tag) > { > struct MR_LD_RAID *raid; > u32 ld; > @@ -1419,7 +1488,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, > union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; > struct IO_REQUEST_INFO io_info; > struct fusion_context *fusion; > - struct MR_FW_RAID_MAP_ALL *local_map_ptr; > + struct MR_DRV_RAID_MAP_ALL *local_map_ptr; > u8 *raidLUN; > > device_id = MEGASAS_DEV_INDEX(instance, scp); > @@ -1496,10 +1565,10 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, > if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) > io_info.isRead = 1; > > - local_map_ptr = fusion->ld_map[(instance->map_id & 1)]; > + local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; > > if ((MR_TargetIdToLdGet(device_id, local_map_ptr) >= > - MAX_LOGICAL_DRIVES) || (!fusion->fast_path_io)) { > + instance->fw_supported_vd_count) || (!fusion->fast_path_io)) { > io_request->RaidContext.regLockFlags = 0; > fp_possible = 0; > } else { > @@ -1589,7 +1658,7 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance, > u32 device_id; > struct MPI2_RAID_SCSI_IO_REQUEST *io_request; > u16 pd_index = 0; > - struct MR_FW_RAID_MAP_ALL *local_map_ptr; > + struct MR_DRV_RAID_MAP_ALL *local_map_ptr; > struct fusion_context *fusion = instance->ctrl_context; > u8 span, physArm; > u16 devHandle; > @@ -1601,7 +1670,7 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance, > device_id = MEGASAS_DEV_INDEX(instance, scmd); > pd_index = (scmd->device->channel * MEGASAS_MAX_DEV_PER_CHANNEL) > +scmd->device->id; > - local_map_ptr = fusion->ld_map[(instance->map_id & 1)]; > + local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; > > io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd)); > > @@ -1649,7 +1718,8 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance, > goto NonFastPath; > > ld = MR_TargetIdToLdGet(device_id, local_map_ptr); > - if ((ld >= MAX_LOGICAL_DRIVES) || (!fusion->fast_path_io)) > + if ((ld >= instance->fw_supported_vd_count) || > + (!fusion->fast_path_io)) > goto NonFastPath; > > raid = MR_LdRaidGet(ld, local_map_ptr); > @@ -2724,7 +2794,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout) > /* Reset load balance info */ > memset(fusion->load_balance_info, 0, > sizeof(struct LD_LOAD_BALANCE_INFO) > - *MAX_LOGICAL_DRIVES); > + *MAX_LOGICAL_DRIVES_EXT); > > if (!megasas_get_map_info(instance)) > megasas_sync_map_info(instance); > diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h > index d660c4d..0a6a430 100644 > --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h > +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h > @@ -479,10 +479,13 @@ struct MPI2_IOC_INIT_REQUEST { > #define MAX_ROW_SIZE 32 > #define MAX_RAIDMAP_ROW_SIZE (MAX_ROW_SIZE) > #define MAX_LOGICAL_DRIVES 64 > +#define MAX_LOGICAL_DRIVES_EXT 256 > #define MAX_RAIDMAP_LOGICAL_DRIVES (MAX_LOGICAL_DRIVES) > #define MAX_RAIDMAP_VIEWS (MAX_LOGICAL_DRIVES) > #define MAX_ARRAYS 128 > #define MAX_RAIDMAP_ARRAYS (MAX_ARRAYS) > +#define MAX_ARRAYS_EXT 256 > +#define MAX_API_ARRAYS_EXT (MAX_ARRAYS_EXT) > #define MAX_PHYSICAL_DEVICES 256 > #define MAX_RAIDMAP_PHYSICAL_DEVICES (MAX_PHYSICAL_DEVICES) > #define MR_DCMD_LD_MAP_GET_INFO 0x0300e101 > @@ -714,6 +717,83 @@ struct MR_FW_RAID_MAP_ALL { > struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES - 1]; > } __attribute__ ((packed)); > > +struct MR_DRV_RAID_MAP { > + /* total size of this structure, including this field. > + * This feild will be manupulated by driver for ext raid map, > + * else pick the value from firmware raid map. > + */ > + u32 totalSize; > + > + union { > + struct { > + u32 maxLd; > + u32 maxSpanDepth; > + u32 maxRowSize; > + u32 maxPdCount; > + u32 maxArrays; > + } validationInfo; > + u32 version[5]; > + u32 reserved1[5]; What is this 'reserved1' used for? In a union it does not reserve additional space, ther already is 'version' with the same size. > + }; > + > + /* timeout value used by driver in FP IOs*/ > + u8 fpPdIoTimeoutSec; > + u8 reserved2[7]; > + > + u16 ldCount; > + u16 arCount; > + u16 spanCount; > + u16 reserve3; > + > + struct MR_DEV_HANDLE_INFO devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES]; > + u8 ldTgtIdToLd[MAX_LOGICAL_DRIVES_EXT]; > + struct MR_ARRAY_INFO arMapInfo[MAX_API_ARRAYS_EXT]; > + struct MR_LD_SPAN_MAP ldSpanMap[1]; > + > +}; > + > +/* Driver raid map size is same as raid map ext > + * MR_DRV_RAID_MAP_ALL is created to sync with old raid. > + * And it is mainly for code re-use purpose. > + */ > +struct MR_DRV_RAID_MAP_ALL { > + > + struct MR_DRV_RAID_MAP raidMap; > + struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES_EXT - 1]; > +} __packed; > + > + > + > +struct MR_FW_RAID_MAP_EXT { > + /* Not usred in new map */ > + u32 reserved; > + > + union { > + struct { > + u32 maxLd; > + u32 maxSpanDepth; > + u32 maxRowSize; > + u32 maxPdCount; > + u32 maxArrays; > + } validationInfo; > + u32 version[5]; > + u32 reserved1[5]; > + }; > + > + u8 fpPdIoTimeoutSec; > + u8 reserved2[7]; > + > + u16 ldCount; > + u16 arCount; > + u16 spanCount; > + u16 reserve3; > + > + struct MR_DEV_HANDLE_INFO devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES]; > + u8 ldTgtIdToLd[MAX_LOGICAL_DRIVES_EXT]; > + struct MR_ARRAY_INFO arMapInfo[MAX_API_ARRAYS_EXT]; > + struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES_EXT]; > +}; > + > struct fusion_context { > struct megasas_cmd_fusion **cmd_list; > struct list_head cmd_pool; > @@ -750,10 +830,18 @@ struct fusion_context { > struct MR_FW_RAID_MAP_ALL *ld_map[2]; > dma_addr_t ld_map_phys[2]; > > - u32 map_sz; > + /*Non dma-able memory. Driver local copy.*/ > + struct MR_DRV_RAID_MAP_ALL *ld_drv_map[2]; > + > + u32 max_map_sz; > + u32 current_map_sz; > + u32 old_map_sz; > + u32 new_map_sz; > + u32 drv_map_sz; > + u32 drv_map_pages; > u8 fast_path_io; > - struct LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES]; > - LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES]; > + struct LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES_EXT]; > + LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT]; > }; > > union desc_value { > @@ -764,4 +852,5 @@ union desc_value { > } u; > }; > > + > #endif /* _MEGARAID_SAS_FUSION_H_ */ -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html