From: Tomas Henzl <thenzl@redhat.com>
To: Sumit.Saxena@avagotech.com, linux-scsi@vger.kernel.org
Cc: martin.petersen@oracle.com, hch@infradead.org,
jbottomley@parallels.com, kashyap.desai@avagotech.com,
aradford@gmail.com
Subject: Re: [PATCH 05/11] megaraid_sas : Extended VD support
Date: Wed, 10 Sep 2014 15:50:59 +0200 [thread overview]
Message-ID: <54105743.1080609@redhat.com> (raw)
In-Reply-To: <201409061328.s86DS7wD013063@palmhbs0.lsi.com>
On 09/06/2014 03:25 PM, Sumit.Saxena@avagotech.com 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@avagotech.com>
> Signed-off-by: Kashyap Desai <kashyap.desai@avagotech.com>
> ---
> 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_ */
next prev parent reply other threads:[~2014-09-10 13:52 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-06 13:25 [PATCH 05/11] megaraid_sas : Extended VD support Sumit.Saxena
2014-09-10 13:50 ` Tomas Henzl [this message]
2014-09-10 15:01 ` Kashyap Desai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=54105743.1080609@redhat.com \
--to=thenzl@redhat.com \
--cc=Sumit.Saxena@avagotech.com \
--cc=aradford@gmail.com \
--cc=hch@infradead.org \
--cc=jbottomley@parallels.com \
--cc=kashyap.desai@avagotech.com \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox