From c365178f3147f38d26c15bdf43a363bacb5406ec Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:48:48 -0700 Subject: scsi: megaraid_sas: use adapter_type for all gen controllers No functional change. Refactor adapter_type to set for all generation controllers, not just for fusion controllers. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas.h | 8 +++ drivers/scsi/megaraid/megaraid_sas_base.c | 88 ++++++++++++++++++----------- drivers/scsi/megaraid/megaraid_sas_fp.c | 10 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 18 +++--- drivers/scsi/megaraid/megaraid_sas_fusion.h | 7 --- 5 files changed, 76 insertions(+), 55 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index a6722c93a295..90b9b5d7f0f8 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1504,6 +1504,13 @@ enum FW_BOOT_CONTEXT { #define MR_CAN_HANDLE_SYNC_CACHE_OFFSET 0X01000000 +enum MR_ADAPTER_TYPE { + MFI_SERIES = 1, + THUNDERBOLT_SERIES = 2, + INVADER_SERIES = 3, + VENTURA_SERIES = 4, +}; + /* * register set for both 1068 and 1078 controllers * structure extended for 1078 registers @@ -2242,6 +2249,7 @@ struct megasas_instance { /* preffered count to send as LDIO irrspective of FP capable.*/ u8 r1_ldio_hint_default; u32 nvme_page_size; + u8 adapter_type; }; struct MR_LD_VF_MAP { u32 size; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index e518dadc8161..0db138407198 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5229,7 +5229,8 @@ static int megasas_init_fw(struct megasas_instance *instance) (&instance->reg_set->outbound_scratch_pad_2); /* Check max MSI-X vectors */ if (fusion) { - if (fusion->adapter_type == THUNDERBOLT_SERIES) { /* Thunderbolt Series*/ + if (instance->adapter_type == THUNDERBOLT_SERIES) { + /* Thunderbolt Series*/ instance->msix_vectors = (scratch_pad_2 & MR_MAX_REPLY_QUEUES_OFFSET) + 1; fw_msix_count = instance->msix_vectors; @@ -5965,6 +5966,46 @@ fail_set_dma_mask: return 1; } +/* + * megasas_set_adapter_type - Set adapter type. + * Supported controllers can be divided in + * 4 categories- enum MR_ADAPTER_TYPE { + * MFI_SERIES = 1, + * THUNDERBOLT_SERIES = 2, + * INVADER_SERIES = 3, + * VENTURA_SERIES = 4, + * }; + * @instance: Adapter soft state + * return: void + */ +static inline void megasas_set_adapter_type(struct megasas_instance *instance) +{ + switch (instance->pdev->device) { + case PCI_DEVICE_ID_LSI_VENTURA: + case PCI_DEVICE_ID_LSI_HARPOON: + case PCI_DEVICE_ID_LSI_TOMCAT: + case PCI_DEVICE_ID_LSI_VENTURA_4PORT: + case PCI_DEVICE_ID_LSI_CRUSADER_4PORT: + instance->adapter_type = VENTURA_SERIES; + break; + case PCI_DEVICE_ID_LSI_FUSION: + case PCI_DEVICE_ID_LSI_PLASMA: + instance->adapter_type = THUNDERBOLT_SERIES; + break; + case PCI_DEVICE_ID_LSI_INVADER: + case PCI_DEVICE_ID_LSI_INTRUDER: + case PCI_DEVICE_ID_LSI_INTRUDER_24: + case PCI_DEVICE_ID_LSI_CUTLASS_52: + case PCI_DEVICE_ID_LSI_CUTLASS_53: + case PCI_DEVICE_ID_LSI_FURY: + instance->adapter_type = INVADER_SERIES; + break; + default: /* For all other supported controllers */ + instance->adapter_type = MFI_SERIES; + break; + } +} + /** * megasas_probe_one - PCI hotplug entry point * @pdev: PCI device structure @@ -5977,7 +6018,6 @@ 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) { @@ -6022,39 +6062,10 @@ static int megasas_probe_one(struct pci_dev *pdev, atomic_set(&instance->fw_reset_no_pci_access, 0); instance->pdev = pdev; - switch (instance->pdev->device) { - case PCI_DEVICE_ID_LSI_VENTURA: - case PCI_DEVICE_ID_LSI_HARPOON: - case PCI_DEVICE_ID_LSI_TOMCAT: - case PCI_DEVICE_ID_LSI_VENTURA_4PORT: - case PCI_DEVICE_ID_LSI_CRUSADER_4PORT: - instance->is_ventura = true; - case PCI_DEVICE_ID_LSI_FUSION: - case PCI_DEVICE_ID_LSI_PLASMA: - case PCI_DEVICE_ID_LSI_INVADER: - case PCI_DEVICE_ID_LSI_FURY: - case PCI_DEVICE_ID_LSI_INTRUDER: - case PCI_DEVICE_ID_LSI_INTRUDER_24: - case PCI_DEVICE_ID_LSI_CUTLASS_52: - case PCI_DEVICE_ID_LSI_CUTLASS_53: - { - if (megasas_alloc_fusion_context(instance)) { - megasas_free_fusion_context(instance); - goto fail_alloc_dma_buf; - } - fusion = instance->ctrl_context; - - if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || - (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA)) - fusion->adapter_type = THUNDERBOLT_SERIES; - else if (instance->is_ventura) - fusion->adapter_type = VENTURA_SERIES; - else - fusion->adapter_type = INVADER_SERIES; - } - break; - default: /* For all other supported controllers */ + megasas_set_adapter_type(instance); + switch (instance->adapter_type) { + case MFI_SERIES: instance->producer = pci_alloc_consistent(pdev, sizeof(u32), &instance->producer_h); @@ -6070,7 +6081,16 @@ static int megasas_probe_one(struct pci_dev *pdev, *instance->producer = 0; *instance->consumer = 0; + break; + case VENTURA_SERIES: + instance->is_ventura = 1; + case THUNDERBOLT_SERIES: + case INVADER_SERIES: + if (megasas_alloc_fusion_context(instance)) { + megasas_free_fusion_context(instance); + goto fail_alloc_dma_buf; + } } /* Crash dump feature related initialisation*/ diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index ecc699a65bac..47af0e13b97a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -747,8 +747,8 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, } } else { if ((raid->level >= 5) && - ((fusion->adapter_type == THUNDERBOLT_SERIES) || - ((fusion->adapter_type == INVADER_SERIES) && + ((instance->adapter_type == THUNDERBOLT_SERIES) || + ((instance->adapter_type == INVADER_SERIES) && (raid->regTypeReqOnRead != REGION_TYPE_UNUSED)))) pRAID_Context->reg_lock_flags = REGION_TYPE_EXCLUSIVE; else if (raid->level == 1) { @@ -863,8 +863,8 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, } } else { if ((raid->level >= 5) && - ((fusion->adapter_type == THUNDERBOLT_SERIES) || - ((fusion->adapter_type == INVADER_SERIES) && + ((instance->adapter_type == THUNDERBOLT_SERIES) || + ((instance->adapter_type == INVADER_SERIES) && (raid->regTypeReqOnRead != REGION_TYPE_UNUSED)))) pRAID_Context->reg_lock_flags = REGION_TYPE_EXCLUSIVE; else if (raid->level == 1) { @@ -1088,7 +1088,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, cpu_to_le16(raid->fpIoTimeoutForLd ? raid->fpIoTimeoutForLd : map->raidMap.fpPdIoTimeoutSec); - if (fusion->adapter_type == INVADER_SERIES) + if (instance->adapter_type == INVADER_SERIES) pRAID_Context->reg_lock_flags = (isRead) ? raid->regTypeReqOnRead : raid->regTypeReqOnWrite; else if (!instance->is_ventura) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 11bd2e698b84..cd997ccf5ebf 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -845,7 +845,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) drv_ops = (MFI_CAPABILITIES *) &(init_frame->driver_operations); /* driver support Extended MSIX */ - if (fusion->adapter_type >= INVADER_SERIES) + if (instance->adapter_type >= INVADER_SERIES) drv_ops->mfi_capabilities.support_additional_msix = 1; /* driver supports HA / Remote LUN over Fast Path interface */ drv_ops->mfi_capabilities.support_fp_remote_lun = 1; @@ -1803,7 +1803,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance, fusion = instance->ctrl_context; - if (fusion->adapter_type >= INVADER_SERIES) { + if (instance->adapter_type >= INVADER_SERIES) { struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end = sgl_ptr; sgl_ptr_end += fusion->max_sge_in_main_msg - 1; sgl_ptr_end->Flags = 0; @@ -1813,7 +1813,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance, sgl_ptr->Length = cpu_to_le32(sg_dma_len(os_sgl)); sgl_ptr->Address = cpu_to_le64(sg_dma_address(os_sgl)); sgl_ptr->Flags = 0; - if (fusion->adapter_type >= INVADER_SERIES) + if (instance->adapter_type >= INVADER_SERIES) if (i == sge_count - 1) sgl_ptr->Flags = IEEE_SGE_FLAGS_END_OF_LIST; sgl_ptr++; @@ -1823,7 +1823,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance, (sge_count > fusion->max_sge_in_main_msg)) { struct MPI25_IEEE_SGE_CHAIN64 *sg_chain; - if (fusion->adapter_type >= INVADER_SERIES) { + if (instance->adapter_type >= INVADER_SERIES) { if ((le16_to_cpu(cmd->io_request->IoFlags) & MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) != MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) @@ -1839,7 +1839,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance, sg_chain = sgl_ptr; /* Prepare chain element */ sg_chain->NextChainOffset = 0; - if (fusion->adapter_type >= INVADER_SERIES) + if (instance->adapter_type >= INVADER_SERIES) sg_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT; else sg_chain->Flags = @@ -2416,7 +2416,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, cmd->request_desc->SCSIIO.RequestFlags = (MPI2_REQ_DESCRIPT_FLAGS_FP_IO << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); - if (fusion->adapter_type == INVADER_SERIES) { + if (instance->adapter_type == INVADER_SERIES) { if (io_request->RaidContext.raid_context.reg_lock_flags == REGION_TYPE_UNUSED) cmd->request_desc->SCSIIO.RequestFlags = @@ -2481,7 +2481,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, cmd->request_desc->SCSIIO.RequestFlags = (MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); - if (fusion->adapter_type == INVADER_SERIES) { + if (instance->adapter_type == INVADER_SERIES) { if (io_info.do_fp_rlbypass || (io_request->RaidContext.raid_context.reg_lock_flags == REGION_TYPE_UNUSED)) @@ -2702,7 +2702,7 @@ megasas_build_syspd_fusion(struct megasas_instance *instance, pRAID_Context->timeout_value = cpu_to_le16((os_timeout_value > timeout_limit) ? timeout_limit : os_timeout_value); - if (fusion->adapter_type >= INVADER_SERIES) + if (instance->adapter_type >= INVADER_SERIES) io_request->IoFlags |= cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH); @@ -3315,7 +3315,7 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance, io_req = cmd->io_request; - if (fusion->adapter_type >= INVADER_SERIES) { + if (instance->adapter_type >= INVADER_SERIES) { struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end = (struct MPI25_IEEE_SGE_CHAIN64 *)&io_req->SGL; sgl_ptr_end += fusion->max_sge_in_main_msg - 1; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index d78d76112501..7c1f7ccf031d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -104,12 +104,6 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE { #define RAID_1_PEER_CMDS 2 #define JBOD_MAPS_COUNT 2 -enum MR_FUSION_ADAPTER_TYPE { - THUNDERBOLT_SERIES = 0, - INVADER_SERIES = 1, - VENTURA_SERIES = 2, -}; - /* * Raid Context structure which describes MegaRAID specific IO Parameters * This resides at offset 0x60 where the SGL normally starts in MPT IO Frames @@ -1319,7 +1313,6 @@ struct fusion_context { struct LD_LOAD_BALANCE_INFO *load_balance_info; u32 load_balance_info_pages; LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT]; - u8 adapter_type; struct LD_STREAM_DETECT **stream_detect_by_ld; }; -- cgit v1.2.3 From 754f1bae0f1e306118f1e2628f781eba056874ed Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:48:49 -0700 Subject: scsi: megaraid_sas: Add support for Crusader controllers Add support for PCI VID/DID 0x1000/0x0015 based MegaRAID controllers. Since the DID 0x0015 conflicts with DELL PERC5 controllers, add vendor ID based check specific for DELL PERC5. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas.h | 1 + drivers/scsi/megaraid/megaraid_sas_base.c | 51 ++++++++++++++++++------------- 2 files changed, 30 insertions(+), 22 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 90b9b5d7f0f8..3f20273b115b 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -57,6 +57,7 @@ #define PCI_DEVICE_ID_LSI_CUTLASS_52 0x0052 #define PCI_DEVICE_ID_LSI_CUTLASS_53 0x0053 #define PCI_DEVICE_ID_LSI_VENTURA 0x0014 +#define PCI_DEVICE_ID_LSI_CRUSADER 0x0015 #define PCI_DEVICE_ID_LSI_HARPOON 0x0016 #define PCI_DEVICE_ID_LSI_TOMCAT 0x0017 #define PCI_DEVICE_ID_LSI_VENTURA_4PORT 0x001B diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 0db138407198..2321ec35fd53 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -161,6 +161,7 @@ static struct pci_device_id megasas_pci_table[] = { {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_53)}, /* VENTURA */ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VENTURA)}, + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CRUSADER)}, {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_HARPOON)}, {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_TOMCAT)}, {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VENTURA_4PORT)}, @@ -5980,29 +5981,35 @@ fail_set_dma_mask: */ static inline void megasas_set_adapter_type(struct megasas_instance *instance) { - switch (instance->pdev->device) { - case PCI_DEVICE_ID_LSI_VENTURA: - case PCI_DEVICE_ID_LSI_HARPOON: - case PCI_DEVICE_ID_LSI_TOMCAT: - case PCI_DEVICE_ID_LSI_VENTURA_4PORT: - case PCI_DEVICE_ID_LSI_CRUSADER_4PORT: - instance->adapter_type = VENTURA_SERIES; - break; - case PCI_DEVICE_ID_LSI_FUSION: - case PCI_DEVICE_ID_LSI_PLASMA: - instance->adapter_type = THUNDERBOLT_SERIES; - break; - case PCI_DEVICE_ID_LSI_INVADER: - case PCI_DEVICE_ID_LSI_INTRUDER: - case PCI_DEVICE_ID_LSI_INTRUDER_24: - case PCI_DEVICE_ID_LSI_CUTLASS_52: - case PCI_DEVICE_ID_LSI_CUTLASS_53: - case PCI_DEVICE_ID_LSI_FURY: - instance->adapter_type = INVADER_SERIES; - break; - default: /* For all other supported controllers */ + if ((instance->pdev->vendor == PCI_VENDOR_ID_DELL) && + (instance->pdev->device == PCI_DEVICE_ID_DELL_PERC5)) { instance->adapter_type = MFI_SERIES; - break; + } else { + switch (instance->pdev->device) { + case PCI_DEVICE_ID_LSI_VENTURA: + case PCI_DEVICE_ID_LSI_CRUSADER: + case PCI_DEVICE_ID_LSI_HARPOON: + case PCI_DEVICE_ID_LSI_TOMCAT: + case PCI_DEVICE_ID_LSI_VENTURA_4PORT: + case PCI_DEVICE_ID_LSI_CRUSADER_4PORT: + instance->adapter_type = VENTURA_SERIES; + break; + case PCI_DEVICE_ID_LSI_FUSION: + case PCI_DEVICE_ID_LSI_PLASMA: + instance->adapter_type = THUNDERBOLT_SERIES; + break; + case PCI_DEVICE_ID_LSI_INVADER: + case PCI_DEVICE_ID_LSI_INTRUDER: + case PCI_DEVICE_ID_LSI_INTRUDER_24: + case PCI_DEVICE_ID_LSI_CUTLASS_52: + case PCI_DEVICE_ID_LSI_CUTLASS_53: + case PCI_DEVICE_ID_LSI_FURY: + instance->adapter_type = INVADER_SERIES; + break; + default: /* For all other supported controllers */ + instance->adapter_type = MFI_SERIES; + break; + } } } -- cgit v1.2.3 From e7d36b88435077847e1ea992919c600f3fa9321c Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:48:50 -0700 Subject: scsi: megaraid_sas: replace instance->ctrl_context checks with instance->adapter_type Increase code readability. No functional change. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_base.c | 64 ++++++++++++++++++------------- 1 file changed, 37 insertions(+), 27 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 2321ec35fd53..f1508388c6c9 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -2024,7 +2024,7 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance) msleep(1000); if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) || - (instance->ctrl_context)) { + (instance->adapter_type != MFI_SERIES)) { writel(MFI_STOP_ADP, &instance->reg_set->doorbell); /* Flush */ readl(&instance->reg_set->doorbell); @@ -2495,7 +2495,8 @@ int megasas_sriov_start_heartbeat(struct megasas_instance *instance, dev_warn(&instance->pdev->dev, "SR-IOV: Starting heartbeat for scsi%d\n", instance->host->host_no); - if (instance->ctrl_context && !instance->mask_interrupts) + if ((instance->adapter_type != MFI_SERIES) && + !instance->mask_interrupts) retval = megasas_issue_blocked_cmd(instance, cmd, MEGASAS_ROUTINE_WAIT_TIME_VF); else @@ -2791,7 +2792,9 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd) /* * First wait for all commands to complete */ - if (instance->ctrl_context) { + if (instance->adapter_type == MFI_SERIES) { + ret = megasas_generic_reset(scmd); + } else { struct megasas_cmd_fusion *cmd; cmd = (struct megasas_cmd_fusion *)scmd->SCp.ptr; if (cmd) @@ -2799,8 +2802,7 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd) MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE); ret = megasas_reset_fusion(scmd->device->host, SCSIIO_TIMEOUT_OCR); - } else - ret = megasas_generic_reset(scmd); + } return ret; } @@ -2817,7 +2819,7 @@ static int megasas_task_abort(struct scsi_cmnd *scmd) instance = (struct megasas_instance *)scmd->device->host->hostdata; - if (instance->ctrl_context) + if (instance->adapter_type != MFI_SERIES) ret = megasas_task_abort_fusion(scmd); else { sdev_printk(KERN_NOTICE, scmd->device, "TASK ABORT not supported\n"); @@ -2839,7 +2841,7 @@ static int megasas_reset_target(struct scsi_cmnd *scmd) instance = (struct megasas_instance *)scmd->device->host->hostdata; - if (instance->ctrl_context) + if (instance->adapter_type != MFI_SERIES) ret = megasas_reset_target_fusion(scmd); else { sdev_printk(KERN_NOTICE, scmd->device, "TARGET RESET not supported\n"); @@ -3716,7 +3718,7 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr) PCI_DEVICE_ID_LSI_SAS0073SKINNY) || (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) || - (instance->ctrl_context)) + (instance->adapter_type != MFI_SERIES)) writel( MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG, &instance->reg_set->doorbell); @@ -3734,7 +3736,7 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr) PCI_DEVICE_ID_LSI_SAS0073SKINNY) || (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) || - (instance->ctrl_context)) + (instance->adapter_type != MFI_SERIES)) writel(MFI_INIT_HOTPLUG, &instance->reg_set->doorbell); else @@ -3754,11 +3756,11 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr) PCI_DEVICE_ID_LSI_SAS0073SKINNY) || (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) || - (instance->ctrl_context)) { + (instance->adapter_type != MFI_SERIES)) { writel(MFI_RESET_FLAGS, &instance->reg_set->doorbell); - if (instance->ctrl_context) { + if (instance->adapter_type != MFI_SERIES) { for (i = 0; i < (10 * 1000); i += 20) { if (readl( &instance-> @@ -3925,7 +3927,8 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) * max_sge_sz = 12 byte (sizeof megasas_sge64) * Total 192 byte (3 MFI frame of 64 byte) */ - frame_count = instance->ctrl_context ? (3 + 1) : (15 + 1); + frame_count = (instance->adapter_type == MFI_SERIES) ? + (15 + 1) : (3 + 1); instance->mfi_frame_size = MEGAMFI_FRAME_SIZE * frame_count; /* * Use DMA pool facility provided by PCI layer @@ -3980,7 +3983,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) memset(cmd->frame, 0, instance->mfi_frame_size); cmd->frame->io.context = cpu_to_le32(cmd->index); cmd->frame->io.pad_0 = 0; - if (!instance->ctrl_context && reset_devices) + if ((instance->adapter_type == MFI_SERIES) && reset_devices) cmd->frame->hdr.cmd = MFI_CMD_INVALID; } @@ -4100,7 +4103,7 @@ int megasas_alloc_cmds(struct megasas_instance *instance) inline int dcmd_timeout_ocr_possible(struct megasas_instance *instance) { - if (!instance->ctrl_context) + if (instance->adapter_type == MFI_SERIES) return KILL_ADAPTER; else if (instance->unload || test_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags)) @@ -4144,7 +4147,8 @@ megasas_get_pd_info(struct megasas_instance *instance, struct scsi_device *sdev) dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(instance->pd_info_h); dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_PD_INFO)); - if (instance->ctrl_context && !instance->mask_interrupts) + if ((instance->adapter_type != MFI_SERIES) && + !instance->mask_interrupts) ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS); else ret = megasas_issue_polled(instance, cmd); @@ -4241,7 +4245,8 @@ megasas_get_pd_list(struct megasas_instance *instance) dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h); dcmd->sgl.sge32[0].length = cpu_to_le32(MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST)); - if (instance->ctrl_context && !instance->mask_interrupts) + if ((instance->adapter_type != MFI_SERIES) && + !instance->mask_interrupts) ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS); else @@ -4252,7 +4257,7 @@ megasas_get_pd_list(struct megasas_instance *instance) dev_info(&instance->pdev->dev, "MR_DCMD_PD_LIST_QUERY " "failed/not supported by firmware\n"); - if (instance->ctrl_context) + if (instance->adapter_type != MFI_SERIES) megaraid_sas_kill_hba(instance); else instance->pd_list_not_supported = 1; @@ -4373,7 +4378,8 @@ megasas_get_ld_list(struct megasas_instance *instance) dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_LD_LIST)); dcmd->pad_0 = 0; - if (instance->ctrl_context && !instance->mask_interrupts) + if ((instance->adapter_type != MFI_SERIES) && + !instance->mask_interrupts) ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS); else @@ -4492,7 +4498,8 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type) dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_LD_TARGETID_LIST)); dcmd->pad_0 = 0; - if (instance->ctrl_context && !instance->mask_interrupts) + if ((instance->adapter_type != MFI_SERIES) && + !instance->mask_interrupts) ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS); else ret = megasas_issue_polled(instance, cmd); @@ -4665,7 +4672,8 @@ megasas_get_ctrl_info(struct megasas_instance *instance) dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_ctrl_info)); dcmd->mbox.b[0] = 1; - if (instance->ctrl_context && !instance->mask_interrupts) + if ((instance->adapter_type != MFI_SERIES) && + !instance->mask_interrupts) ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS); else ret = megasas_issue_polled(instance, cmd); @@ -4784,7 +4792,8 @@ int megasas_set_crash_dump_params(struct megasas_instance *instance, dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(instance->crash_dump_h); dcmd->sgl.sge32[0].length = cpu_to_le32(CRASH_DMA_BUF_SIZE); - if (instance->ctrl_context && !instance->mask_interrupts) + if ((instance->adapter_type != MFI_SERIES) && + !instance->mask_interrupts) ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS); else ret = megasas_issue_polled(instance, cmd); @@ -5171,7 +5180,7 @@ static int megasas_init_fw(struct megasas_instance *instance) reg_set = instance->reg_set; - if (fusion) + if (instance->adapter_type != MFI_SERIES) instance->instancet = &megasas_instance_template_fusion; else { switch (instance->pdev->device) { @@ -5806,7 +5815,8 @@ megasas_get_target_prop(struct megasas_instance *instance, dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_TARGET_PROPERTIES)); - if (instance->ctrl_context && !instance->mask_interrupts) + if ((instance->adapter_type != MFI_SERIES) && + !instance->mask_interrupts) ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS); else @@ -6193,7 +6203,7 @@ static int megasas_probe_one(struct pci_dev *pdev, instance->disableOnlineCtrlReset = 1; instance->UnevenSpanSupport = 0; - if (instance->ctrl_context) { + if (instance->adapter_type != MFI_SERIES) { INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq); INIT_WORK(&instance->crash_init, megasas_fusion_crash_dump_wq); } else @@ -6273,7 +6283,7 @@ fail_io_attach: instance->instancet->disable_intr(instance); megasas_destroy_irqs(instance); - if (instance->ctrl_context) + if (instance->adapter_type != MFI_SERIES) megasas_release_fusion(instance); else megasas_release_mfi(instance); @@ -6507,7 +6517,7 @@ megasas_resume(struct pci_dev *pdev) if (rval < 0) goto fail_reenable_msix; - if (instance->ctrl_context) { + if (instance->adapter_type != MFI_SERIES) { megasas_reset_reply_desc(instance); if (megasas_ioc_init_fusion(instance)) { megasas_free_cmds(instance); @@ -6691,7 +6701,7 @@ skip_firing_dcmds: } - if (instance->ctrl_context) { + if (instance->adapter_type != MFI_SERIES) { megasas_release_fusion(instance); pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) + (sizeof(struct MR_PD_CFG_SEQ) * -- cgit v1.2.3 From 55fecaec27d95d57028e584ce69462fdfffa1593 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:48:51 -0700 Subject: scsi: megaraid_sas: Remove redundant checks for ctrl_context Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index cd997ccf5ebf..340079d0bff0 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -991,7 +991,7 @@ megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend) { dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ); /* Below code is only for non pended DCMD */ - if (instance->ctrl_context && !instance->mask_interrupts) + if (!instance->mask_interrupts) ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS); else @@ -1004,7 +1004,7 @@ megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend) { ret = -EINVAL; } - if (ret == DCMD_TIMEOUT && instance->ctrl_context) + if (ret == DCMD_TIMEOUT) megaraid_sas_kill_hba(instance); if (ret == DCMD_SUCCESS) @@ -1080,13 +1080,13 @@ megasas_get_ld_map_info(struct megasas_instance *instance) dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h); dcmd->sgl.sge32[0].length = cpu_to_le32(size_map_info); - if (instance->ctrl_context && !instance->mask_interrupts) + if (!instance->mask_interrupts) ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS); else ret = megasas_issue_polled(instance, cmd); - if (ret == DCMD_TIMEOUT && instance->ctrl_context) + if (ret == DCMD_TIMEOUT) megaraid_sas_kill_hba(instance); megasas_return_cmd(instance, cmd); -- cgit v1.2.3 From f369a31578c461a360f58c7695e5aef931bada13 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:48:52 -0700 Subject: scsi: megaraid_sas: replace is_ventura with adapter_type checks No functional change. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas.h | 1 - drivers/scsi/megaraid/megaraid_sas_base.c | 9 ++++----- drivers/scsi/megaraid/megaraid_sas_fp.c | 10 +++++----- drivers/scsi/megaraid/megaraid_sas_fusion.c | 26 +++++++++++++------------- 4 files changed, 22 insertions(+), 24 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 3f20273b115b..5b36a0103895 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2244,7 +2244,6 @@ struct megasas_instance { bool dev_handle; bool fw_sync_cache_support; u32 mfi_frame_size; - bool is_ventura; bool msix_combined; u16 max_raid_mapsize; /* preffered count to send as LDIO irrspective of FP capable.*/ diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index f1508388c6c9..170de6282c80 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5221,7 +5221,7 @@ static int megasas_init_fw(struct megasas_instance *instance) goto fail_ready_state; } - if (instance->is_ventura) { + if (instance->adapter_type == VENTURA_SERIES) { scratch_pad_3 = readl(&instance->reg_set->outbound_scratch_pad_3); instance->max_raid_mapsize = ((scratch_pad_3 >> @@ -5330,7 +5330,7 @@ static int megasas_init_fw(struct megasas_instance *instance) if (instance->instancet->init_adapter(instance)) goto fail_init_adapter; - if (instance->is_ventura) { + if (instance->adapter_type == VENTURA_SERIES) { scratch_pad_4 = readl(&instance->reg_set->outbound_scratch_pad_4); if ((scratch_pad_4 & MR_NVME_PAGE_SIZE_MASK) >= @@ -5366,7 +5366,7 @@ static int megasas_init_fw(struct megasas_instance *instance) memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); /* stream detection initialization */ - if (instance->is_ventura && fusion) { + if (instance->adapter_type == VENTURA_SERIES) { fusion->stream_detect_by_ld = kzalloc(sizeof(struct LD_STREAM_DETECT *) * MAX_LOGICAL_DRIVES_EXT, @@ -6101,7 +6101,6 @@ static int megasas_probe_one(struct pci_dev *pdev, break; case VENTURA_SERIES: - instance->is_ventura = 1; case THUNDERBOLT_SERIES: case INVADER_SERIES: if (megasas_alloc_fusion_context(instance)) { @@ -6693,7 +6692,7 @@ skip_firing_dcmds: if (instance->msix_vectors) pci_free_irq_vectors(instance->pdev); - if (instance->is_ventura) { + if (instance->adapter_type == VENTURA_SERIES) { for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) kfree(fusion->stream_detect_by_ld[i]); kfree(fusion->stream_detect_by_ld); diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 47af0e13b97a..bfad9bfc313f 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -737,7 +737,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, *pDevHandle = MR_PdDevHandleGet(pd, map); *pPdInterface = MR_PdInterfaceTypeGet(pd, map); /* get second pd also for raid 1/10 fast path writes*/ - if (instance->is_ventura && + if ((instance->adapter_type == VENTURA_SERIES) && (raid->level == 1) && !io_info->isRead) { r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map); @@ -762,7 +762,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, } *pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, map)->startBlk); - if (instance->is_ventura) { + if (instance->adapter_type == VENTURA_SERIES) { ((struct RAID_CONTEXT_G35 *)pRAID_Context)->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; io_info->span_arm = @@ -853,7 +853,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, *pDevHandle = MR_PdDevHandleGet(pd, map); *pPdInterface = MR_PdInterfaceTypeGet(pd, map); /* get second pd also for raid 1/10 fast path writes*/ - if (instance->is_ventura && + if ((instance->adapter_type == VENTURA_SERIES) && (raid->level == 1) && !io_info->isRead) { r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map); @@ -880,7 +880,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, } *pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, map)->startBlk); - if (instance->is_ventura) { + if (instance->adapter_type == VENTURA_SERIES) { ((struct RAID_CONTEXT_G35 *)pRAID_Context)->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; io_info->span_arm = @@ -1091,7 +1091,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, if (instance->adapter_type == INVADER_SERIES) pRAID_Context->reg_lock_flags = (isRead) ? raid->regTypeReqOnRead : raid->regTypeReqOnWrite; - else if (!instance->is_ventura) + else if (instance->adapter_type == THUNDERBOLT_SERIES) pRAID_Context->reg_lock_flags = (isRead) ? REGION_TYPE_SHARED_READ : raid->regTypeReqOnWrite; pRAID_Context->virtual_disk_tgt_id = raid->targetId; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 340079d0bff0..01d42eb6486b 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -200,7 +200,7 @@ static void megasas_fire_cmd_fusion(struct megasas_instance *instance, union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc) { - if (instance->is_ventura) + if (instance->adapter_type == VENTURA_SERIES) writel(le32_to_cpu(req_desc->u.low), &instance->reg_set->inbound_single_queue_port); else { @@ -243,7 +243,7 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c reg_set = instance->reg_set; /* ventura FW does not fill outbound_scratch_pad_3 with queue depth */ - if (!instance->is_ventura) + if (instance->adapter_type < VENTURA_SERIES) cur_max_fw_cmds = readl(&instance->reg_set->outbound_scratch_pad_3) & 0x00FFFF; @@ -291,7 +291,7 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c instance->host->can_queue = instance->cur_can_queue; } - if (instance->is_ventura) + if (instance->adapter_type == VENTURA_SERIES) instance->max_mpt_cmds = instance->max_fw_cmds * RAID_1_PEER_CMDS; else @@ -2363,7 +2363,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, praid_context = &io_request->RaidContext; - if (instance->is_ventura) { + if (instance->adapter_type == VENTURA_SERIES) { spin_lock_irqsave(&instance->stream_lock, spinlock_flags); megasas_stream_detect(instance, cmd, &io_info); spin_unlock_irqrestore(&instance->stream_lock, spinlock_flags); @@ -2429,7 +2429,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, io_request->RaidContext.raid_context.reg_lock_flags |= (MR_RL_FLAGS_GRANT_DESTINATION_CUDA | MR_RL_FLAGS_SEQ_NUM_ENABLE); - } else if (instance->is_ventura) { + } else if (instance->adapter_type == VENTURA_SERIES) { io_request->RaidContext.raid_context_g35.nseg_type |= (1 << RAID_CONTEXT_NSEG_SHIFT); io_request->RaidContext.raid_context_g35.nseg_type |= @@ -2448,7 +2448,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, &io_info, local_map_ptr); scp->SCp.Status |= MEGASAS_LOAD_BALANCE_FLAG; cmd->pd_r1_lb = io_info.pd_after_lb; - if (instance->is_ventura) + if (instance->adapter_type == VENTURA_SERIES) io_request->RaidContext.raid_context_g35.span_arm = io_info.span_arm; else @@ -2458,7 +2458,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, } else scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG; - if (instance->is_ventura) + if (instance->adapter_type == VENTURA_SERIES) cmd->r1_alt_dev_handle = io_info.r1_alt_dev_handle; else cmd->r1_alt_dev_handle = MR_DEVHANDLE_INVALID; @@ -2494,7 +2494,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, (MR_RL_FLAGS_GRANT_DESTINATION_CPU0 | MR_RL_FLAGS_SEQ_NUM_ENABLE); io_request->RaidContext.raid_context.nseg = 0x1; - } else if (instance->is_ventura) { + } else if (instance->adapter_type == VENTURA_SERIES) { io_request->RaidContext.raid_context_g35.routing_flags |= (1 << MR_RAID_CTX_ROUTINGFLAGS_SQN_SHIFT); io_request->RaidContext.raid_context_g35.nseg_type |= @@ -2569,7 +2569,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, /* set RAID context values */ pRAID_Context->config_seq_num = raid->seqNum; - if (!instance->is_ventura) + if (instance->adapter_type != VENTURA_SERIES) pRAID_Context->reg_lock_flags = REGION_TYPE_SHARED_READ; pRAID_Context->timeout_value = cpu_to_le16(raid->fpIoTimeoutForLd); @@ -2654,7 +2654,7 @@ megasas_build_syspd_fusion(struct megasas_instance *instance, cpu_to_le16(device_id + (MAX_PHYSICAL_DEVICES - 1)); pRAID_Context->config_seq_num = pd_sync->seq[pd_index].seqNum; io_request->DevHandle = pd_sync->seq[pd_index].devHandle; - if (instance->is_ventura) { + if (instance->adapter_type == VENTURA_SERIES) { io_request->RaidContext.raid_context_g35.routing_flags |= (1 << MR_RAID_CTX_ROUTINGFLAGS_SQN_SHIFT); io_request->RaidContext.raid_context_g35.nseg_type |= @@ -2785,7 +2785,7 @@ megasas_build_io_fusion(struct megasas_instance *instance, return 1; } - if (instance->is_ventura) { + if (instance->adapter_type == VENTURA_SERIES) { set_num_sge(&io_request->RaidContext.raid_context_g35, sge_count); cpu_to_le16s(&io_request->RaidContext.raid_context_g35.routing_flags); cpu_to_le16s(&io_request->RaidContext.raid_context_g35.nseg_type); @@ -4247,7 +4247,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) for (i = 0 ; i < instance->max_scsi_cmds; i++) { cmd_fusion = fusion->cmd_list[i]; /*check for extra commands issued by driver*/ - if (instance->is_ventura) { + if (instance->adapter_type == VENTURA_SERIES) { r1_cmd = fusion->cmd_list[i + instance->max_fw_cmds]; megasas_return_cmd_fusion(instance, r1_cmd); } @@ -4348,7 +4348,7 @@ transition_to_ready: megasas_set_dynamic_target_properties(sdev); /* reset stream detection array */ - if (instance->is_ventura) { + if (instance->adapter_type == VENTURA_SERIES) { for (j = 0; j < MAX_LOGICAL_DRIVES_EXT; ++j) { memset(fusion->stream_detect_by_ld[j], 0, sizeof(struct LD_STREAM_DETECT)); -- cgit v1.2.3 From 2dd689c808b932379b01228de5b370fc68eb0186 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:48:53 -0700 Subject: scsi: megaraid_sas: reduce size of fusion_context and use kmalloc for allocation fusion_context structure is very large around 180kB and most of the size is contributed by log_to_span array. Move log_to_span out of fusion context and have separate allocation for log_to_span. And use kmalloc to allocate fusion_context. Currently kmemleak reports 1000s of false positives for fusion->cmd_list[]. kmemleak does not track page allocation for fusion_context. This change will also fix the false positives reported by kmemleak. Ref: https://marc.info/?l=linux-scsi&m=150545293900917 Reported-by: Shu Wang Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas.h | 1 - drivers/scsi/megaraid/megaraid_sas_fusion.c | 43 +++++++++++++++++++---------- drivers/scsi/megaraid/megaraid_sas_fusion.h | 3 +- 3 files changed, 31 insertions(+), 16 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 5b36a0103895..1f34577d8982 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2218,7 +2218,6 @@ 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 megasas_irq_context irq_context[MEGASAS_MAX_MSIX_QUEUES]; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 01d42eb6486b..a8055341e875 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -4502,20 +4502,31 @@ megasas_alloc_fusion_context(struct megasas_instance *instance) { struct fusion_context *fusion; - instance->ctrl_context_pages = get_order(sizeof(struct fusion_context)); - instance->ctrl_context = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, - instance->ctrl_context_pages); + instance->ctrl_context = kzalloc(sizeof(struct fusion_context), + GFP_KERNEL); if (!instance->ctrl_context) { - /* fall back to using vmalloc for fusion_context */ - instance->ctrl_context = vzalloc(sizeof(struct fusion_context)); - if (!instance->ctrl_context) { - dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); - return -ENOMEM; - } + dev_err(&instance->pdev->dev, "Failed from %s %d\n", + __func__, __LINE__); + return -ENOMEM; } fusion = instance->ctrl_context; + fusion->log_to_span_pages = get_order(MAX_LOGICAL_DRIVES_EXT * + sizeof(LD_SPAN_INFO)); + fusion->log_to_span = + (PLD_SPAN_INFO)__get_free_pages(GFP_KERNEL | __GFP_ZERO, + fusion->log_to_span_pages); + if (!fusion->log_to_span) { + fusion->log_to_span = vzalloc(MAX_LOGICAL_DRIVES_EXT * + sizeof(LD_SPAN_INFO)); + if (!fusion->log_to_span) { + dev_err(&instance->pdev->dev, "Failed from %s %d\n", + __func__, __LINE__); + return -ENOMEM; + } + } + fusion->load_balance_info_pages = get_order(MAX_LOGICAL_DRIVES_EXT * sizeof(struct LD_LOAD_BALANCE_INFO)); fusion->load_balance_info = @@ -4546,11 +4557,15 @@ megasas_free_fusion_context(struct megasas_instance *instance) fusion->load_balance_info_pages); } - if (is_vmalloc_addr(fusion)) - vfree(fusion); - else - free_pages((ulong)fusion, - instance->ctrl_context_pages); + if (fusion->log_to_span) { + if (is_vmalloc_addr(fusion->log_to_span)) + vfree(fusion->log_to_span); + else + free_pages((ulong)fusion->log_to_span, + fusion->log_to_span_pages); + } + + kfree(fusion); } } diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index 7c1f7ccf031d..a2b56913f382 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -1312,7 +1312,8 @@ struct fusion_context { u8 fast_path_io; struct LD_LOAD_BALANCE_INFO *load_balance_info; u32 load_balance_info_pages; - LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT]; + LD_SPAN_INFO *log_to_span; + u32 log_to_span_pages; struct LD_STREAM_DETECT **stream_detect_by_ld; }; -- cgit v1.2.3 From 49a7a4adb0167b656b8dfb6ccb83220d553a1860 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:48:54 -0700 Subject: scsi: megaraid_sas: Create separate functions to allocate ctrl memory No functional change. Code refactoring to improve readability. Move the code to allocate and free controller memory into separate functions. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_base.c | 122 +++++++++++++++++++----------- 1 file changed, 76 insertions(+), 46 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 170de6282c80..5fdcf5e2b02e 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6023,6 +6023,75 @@ static inline void megasas_set_adapter_type(struct megasas_instance *instance) } } +static inline int megasas_alloc_mfi_ctrl_mem(struct megasas_instance *instance) +{ + instance->producer = pci_alloc_consistent(instance->pdev, sizeof(u32), + &instance->producer_h); + instance->consumer = pci_alloc_consistent(instance->pdev, sizeof(u32), + &instance->consumer_h); + + if (!instance->producer || !instance->consumer) { + dev_err(&instance->pdev->dev, + "Failed to allocate memory for producer, consumer\n"); + return -1; + } + + *instance->producer = 0; + *instance->consumer = 0; + return 0; +} + +/** + * megasas_alloc_ctrl_mem - Allocate per controller memory for core data + * structures which are not common across MFI + * adapters and fusion adapters. + * For MFI based adapters, allocate producer and + * consumer buffers. For fusion adapters, allocate + * memory for fusion context. + * @instance: Adapter soft state + * return: 0 for SUCCESS + */ +static int megasas_alloc_ctrl_mem(struct megasas_instance *instance) +{ + switch (instance->adapter_type) { + case MFI_SERIES: + if (megasas_alloc_mfi_ctrl_mem(instance)) + return -ENOMEM; + break; + case VENTURA_SERIES: + case THUNDERBOLT_SERIES: + case INVADER_SERIES: + if (megasas_alloc_fusion_context(instance)) + return -ENOMEM; + break; + } + + return 0; +} + +/* + * megasas_free_ctrl_mem - Free fusion context for fusion adapters and + * producer, consumer buffers for MFI adapters + * + * @instance - Adapter soft instance + * + */ +static inline void megasas_free_ctrl_mem(struct megasas_instance *instance) +{ + if (instance->adapter_type == MFI_SERIES) { + if (instance->producer) + pci_free_consistent(instance->pdev, sizeof(u32), + instance->producer, + instance->producer_h); + if (instance->consumer) + pci_free_consistent(instance->pdev, sizeof(u32), + instance->consumer, + instance->consumer_h); + } else { + megasas_free_fusion_context(instance); + } +} + /** * megasas_probe_one - PCI hotplug entry point * @pdev: PCI device structure @@ -6081,33 +6150,8 @@ static int megasas_probe_one(struct pci_dev *pdev, megasas_set_adapter_type(instance); - switch (instance->adapter_type) { - case MFI_SERIES: - instance->producer = - pci_alloc_consistent(pdev, sizeof(u32), - &instance->producer_h); - instance->consumer = - pci_alloc_consistent(pdev, sizeof(u32), - &instance->consumer_h); - - if (!instance->producer || !instance->consumer) { - dev_printk(KERN_DEBUG, &pdev->dev, "Failed to allocate " - "memory for producer, consumer\n"); - goto fail_alloc_dma_buf; - } - - *instance->producer = 0; - *instance->consumer = 0; - - break; - case VENTURA_SERIES: - case THUNDERBOLT_SERIES: - case INVADER_SERIES: - if (megasas_alloc_fusion_context(instance)) { - megasas_free_fusion_context(instance); - goto fail_alloc_dma_buf; - } - } + if (megasas_alloc_ctrl_mem(instance)) + goto fail_alloc_dma_buf; /* Crash dump feature related initialisation*/ instance->drv_buf_index = 0; @@ -6303,12 +6347,7 @@ fail_alloc_dma_buf: pci_free_consistent(pdev, sizeof(struct MR_TARGET_PROPERTIES), instance->tgt_prop, instance->tgt_prop_h); - if (instance->producer) - pci_free_consistent(pdev, sizeof(u32), instance->producer, - instance->producer_h); - if (instance->consumer) - pci_free_consistent(pdev, sizeof(u32), instance->consumer, - instance->consumer_h); + megasas_free_ctrl_mem(instance); scsi_host_put(host); fail_alloc_instance: @@ -6579,12 +6618,8 @@ fail_init_mfi: pci_free_consistent(pdev, sizeof(struct MR_TARGET_PROPERTIES), instance->tgt_prop, instance->tgt_prop_h); - if (instance->producer) - pci_free_consistent(pdev, sizeof(u32), instance->producer, - instance->producer_h); - if (instance->consumer) - pci_free_consistent(pdev, sizeof(u32), instance->consumer, - instance->consumer_h); + + megasas_free_ctrl_mem(instance); scsi_host_put(host); fail_set_dma_mask: @@ -6725,15 +6760,8 @@ skip_firing_dcmds: fusion->pd_seq_sync[i], fusion->pd_seq_phys[i]); } - megasas_free_fusion_context(instance); } else { megasas_release_mfi(instance); - pci_free_consistent(pdev, sizeof(u32), - instance->producer, - instance->producer_h); - pci_free_consistent(pdev, sizeof(u32), - instance->consumer, - instance->consumer_h); } kfree(instance->ctrl_info); @@ -6774,6 +6802,8 @@ skip_firing_dcmds: pci_free_consistent(pdev, sizeof(struct MR_DRV_SYSTEM_INFO), instance->system_info_buf, instance->system_info_h); + megasas_free_ctrl_mem(instance); + scsi_host_put(host); pci_disable_device(pdev); -- cgit v1.2.3 From 1b4bed20615959277e369b2de39bc3d7b1809c40 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:48:55 -0700 Subject: scsi: megaraid_sas: Create separate functions for allocating and freeing controller DMA buffers Code refactoring - create separate functions to allocate and free controller DMA buffers Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_base.c | 186 +++++++++++++++++------------- 1 file changed, 103 insertions(+), 83 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 5fdcf5e2b02e..a0f40856711d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6092,6 +6092,103 @@ static inline void megasas_free_ctrl_mem(struct megasas_instance *instance) } } +/** + * megasas_alloc_ctrl_dma_buffers - Allocate consistent DMA buffers during + * driver load time + * + * @instance- Adapter soft instance + * @return- O for SUCCESS + */ +static inline +int megasas_alloc_ctrl_dma_buffers(struct megasas_instance *instance) +{ + struct pci_dev *pdev = instance->pdev; + + instance->evt_detail = + pci_alloc_consistent(pdev, + sizeof(struct megasas_evt_detail), + &instance->evt_detail_h); + + if (!instance->evt_detail) { + dev_err(&instance->pdev->dev, + "Failed to allocate event detail buffer\n"); + return -ENOMEM; + } + + if (!reset_devices) { + instance->system_info_buf = + pci_alloc_consistent(pdev, + sizeof(struct MR_DRV_SYSTEM_INFO), + &instance->system_info_h); + instance->pd_info = + pci_alloc_consistent(pdev, + sizeof(struct MR_PD_INFO), + &instance->pd_info_h); + instance->tgt_prop = + pci_alloc_consistent(pdev, + sizeof(struct MR_TARGET_PROPERTIES), + &instance->tgt_prop_h); + instance->crash_dump_buf = + pci_alloc_consistent(pdev, + CRASH_DMA_BUF_SIZE, + &instance->crash_dump_h); + + if (!instance->system_info_buf) + dev_err(&instance->pdev->dev, + "Failed to allocate system info buffer\n"); + + if (!instance->pd_info) + dev_err(&instance->pdev->dev, + "Failed to allocate pd_info buffer\n"); + + if (!instance->tgt_prop) + dev_err(&instance->pdev->dev, + "Failed to allocate tgt_prop buffer\n"); + + if (!instance->crash_dump_buf) + dev_err(&instance->pdev->dev, + "Failed to allocate crash dump buffer\n"); + } + + return 0; +} + +/* + * megasas_free_ctrl_dma_buffers - Free consistent DMA buffers allocated + * during driver load time + * + * @instance- Adapter soft instance + * + */ +static inline +void megasas_free_ctrl_dma_buffers(struct megasas_instance *instance) +{ + struct pci_dev *pdev = instance->pdev; + + if (instance->evt_detail) + pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), + instance->evt_detail, + instance->evt_detail_h); + + if (instance->system_info_buf) + pci_free_consistent(pdev, sizeof(struct MR_DRV_SYSTEM_INFO), + instance->system_info_buf, + instance->system_info_h); + + if (instance->pd_info) + pci_free_consistent(pdev, sizeof(struct MR_PD_INFO), + instance->pd_info, instance->pd_info_h); + + if (instance->tgt_prop) + pci_free_consistent(pdev, sizeof(struct MR_TARGET_PROPERTIES), + instance->tgt_prop, instance->tgt_prop_h); + + if (instance->crash_dump_buf) + pci_free_consistent(pdev, CRASH_DMA_BUF_SIZE, + instance->crash_dump_buf, + instance->crash_dump_h); +} + /** * megasas_probe_one - PCI hotplug entry point * @pdev: PCI device structure @@ -6153,6 +6250,9 @@ static int megasas_probe_one(struct pci_dev *pdev, if (megasas_alloc_ctrl_mem(instance)) goto fail_alloc_dma_buf; + if (megasas_alloc_ctrl_dma_buffers(instance)) + goto fail_alloc_dma_buf; + /* Crash dump feature related initialisation*/ instance->drv_buf_index = 0; instance->drv_buf_alloc = 0; @@ -6169,44 +6269,6 @@ static int megasas_probe_one(struct pci_dev *pdev, atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL); instance->is_imr = 0; - instance->evt_detail = pci_alloc_consistent(pdev, - sizeof(struct - megasas_evt_detail), - &instance->evt_detail_h); - - if (!instance->evt_detail) { - dev_printk(KERN_DEBUG, &pdev->dev, "Failed to allocate memory for " - "event detail structure\n"); - goto fail_alloc_dma_buf; - } - - if (!reset_devices) { - instance->system_info_buf = pci_zalloc_consistent(pdev, - sizeof(struct MR_DRV_SYSTEM_INFO), - &instance->system_info_h); - if (!instance->system_info_buf) - dev_info(&instance->pdev->dev, "Can't allocate system info buffer\n"); - - instance->pd_info = pci_alloc_consistent(pdev, - sizeof(struct MR_PD_INFO), &instance->pd_info_h); - - if (!instance->pd_info) - dev_err(&instance->pdev->dev, "Failed to alloc mem for pd_info\n"); - - instance->tgt_prop = pci_alloc_consistent(pdev, - sizeof(struct MR_TARGET_PROPERTIES), &instance->tgt_prop_h); - - if (!instance->tgt_prop) - dev_err(&instance->pdev->dev, "Failed to alloc mem for tgt_prop\n"); - - instance->crash_dump_buf = pci_alloc_consistent(pdev, - CRASH_DMA_BUF_SIZE, - &instance->crash_dump_h); - if (!instance->crash_dump_buf) - dev_err(&pdev->dev, "Can't allocate Firmware " - "crash dump DMA buffer\n"); - } - /* * Initialize locks and queues */ @@ -6334,19 +6396,7 @@ fail_io_attach: pci_free_irq_vectors(instance->pdev); fail_init_mfi: fail_alloc_dma_buf: - if (instance->evt_detail) - pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), - instance->evt_detail, - instance->evt_detail_h); - - if (instance->pd_info) - pci_free_consistent(pdev, sizeof(struct MR_PD_INFO), - instance->pd_info, - instance->pd_info_h); - if (instance->tgt_prop) - pci_free_consistent(pdev, sizeof(struct MR_TARGET_PROPERTIES), - instance->tgt_prop, - instance->tgt_prop_h); + megasas_free_ctrl_dma_buffers(instance); megasas_free_ctrl_mem(instance); scsi_host_put(host); @@ -6605,20 +6655,7 @@ megasas_resume(struct pci_dev *pdev) return 0; fail_init_mfi: - if (instance->evt_detail) - pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), - instance->evt_detail, - instance->evt_detail_h); - - if (instance->pd_info) - pci_free_consistent(pdev, sizeof(struct MR_PD_INFO), - instance->pd_info, - instance->pd_info_h); - if (instance->tgt_prop) - pci_free_consistent(pdev, sizeof(struct MR_TARGET_PROPERTIES), - instance->tgt_prop, - instance->tgt_prop_h); - + megasas_free_ctrl_dma_buffers(instance); megasas_free_ctrl_mem(instance); scsi_host_put(host); @@ -6766,17 +6803,6 @@ skip_firing_dcmds: kfree(instance->ctrl_info); - if (instance->evt_detail) - pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), - instance->evt_detail, instance->evt_detail_h); - if (instance->pd_info) - pci_free_consistent(pdev, sizeof(struct MR_PD_INFO), - instance->pd_info, - instance->pd_info_h); - if (instance->tgt_prop) - pci_free_consistent(pdev, sizeof(struct MR_TARGET_PROPERTIES), - instance->tgt_prop, - instance->tgt_prop_h); if (instance->vf_affiliation) pci_free_consistent(pdev, (MAX_LOGICAL_DRIVES + 1) * sizeof(struct MR_LD_VF_AFFILIATION), @@ -6794,13 +6820,7 @@ skip_firing_dcmds: instance->hb_host_mem, instance->hb_host_mem_h); - if (instance->crash_dump_buf) - pci_free_consistent(pdev, CRASH_DMA_BUF_SIZE, - instance->crash_dump_buf, instance->crash_dump_h); - - if (instance->system_info_buf) - pci_free_consistent(pdev, sizeof(struct MR_DRV_SYSTEM_INFO), - instance->system_info_buf, instance->system_info_h); + megasas_free_ctrl_dma_buffers(instance); megasas_free_ctrl_mem(instance); -- cgit v1.2.3 From 9b3d028f34686f16a2eb58ea4ad345d4c080b9a6 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:48:56 -0700 Subject: scsi: megaraid_sas: Pre-allocate frequently used DMA buffers Pre-allocate few of the frequently used DMA buffers during load time. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas.h | 13 +++ drivers/scsi/megaraid/megaraid_sas_base.c | 147 ++++++++++++++++++---------- drivers/scsi/megaraid/megaraid_sas_fusion.c | 19 +--- drivers/scsi/megaraid/megaraid_sas_fusion.h | 3 + 4 files changed, 116 insertions(+), 66 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 1f34577d8982..80ba77b4b9e2 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2122,6 +2122,19 @@ struct megasas_instance { u32 *crash_dump_buf; dma_addr_t crash_dump_h; + + struct MR_PD_LIST *pd_list_buf; + dma_addr_t pd_list_buf_h; + + struct megasas_ctrl_info *ctrl_info_buf; + dma_addr_t ctrl_info_buf_h; + + struct MR_LD_LIST *ld_list_buf; + dma_addr_t ld_list_buf_h; + + struct MR_LD_TARGETID_LIST *ld_targetid_list_buf; + dma_addr_t ld_targetid_list_buf_h; + void *crash_buf[MAX_CRASH_DUMP_SIZE]; unsigned int fw_crash_buffer_size; unsigned int fw_crash_state; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index a0f40856711d..19649ca11a1f 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4211,6 +4211,9 @@ megasas_get_pd_list(struct megasas_instance *instance) return ret; } + ci = instance->pd_list_buf; + ci_h = instance->pd_list_buf_h; + cmd = megasas_get_cmd(instance); if (!cmd) { @@ -4220,15 +4223,6 @@ megasas_get_pd_list(struct megasas_instance *instance) dcmd = &cmd->frame->dcmd; - ci = pci_alloc_consistent(instance->pdev, - MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h); - - if (!ci) { - dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to alloc mem for pd_list\n"); - megasas_return_cmd(instance, cmd); - return -ENOMEM; - } - memset(ci, 0, sizeof(*ci)); memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); @@ -4314,10 +4308,6 @@ megasas_get_pd_list(struct megasas_instance *instance) } - pci_free_consistent(instance->pdev, - MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), - ci, ci_h); - if (ret != DCMD_TIMEOUT) megasas_return_cmd(instance, cmd); @@ -4343,6 +4333,9 @@ megasas_get_ld_list(struct megasas_instance *instance) dma_addr_t ci_h = 0; u32 ld_count; + ci = instance->ld_list_buf; + ci_h = instance->ld_list_buf_h; + cmd = megasas_get_cmd(instance); if (!cmd) { @@ -4352,16 +4345,6 @@ megasas_get_ld_list(struct megasas_instance *instance) dcmd = &cmd->frame->dcmd; - ci = pci_alloc_consistent(instance->pdev, - sizeof(struct MR_LD_LIST), - &ci_h); - - if (!ci) { - dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to alloc mem in get_ld_list\n"); - megasas_return_cmd(instance, cmd); - return -ENOMEM; - } - memset(ci, 0, sizeof(*ci)); memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); @@ -4433,8 +4416,6 @@ megasas_get_ld_list(struct megasas_instance *instance) break; } - pci_free_consistent(instance->pdev, sizeof(struct MR_LD_LIST), ci, ci_h); - if (ret != DCMD_TIMEOUT) megasas_return_cmd(instance, cmd); @@ -4460,6 +4441,9 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type) dma_addr_t ci_h = 0; u32 tgtid_count; + ci = instance->ld_targetid_list_buf; + ci_h = instance->ld_targetid_list_buf_h; + cmd = megasas_get_cmd(instance); if (!cmd) { @@ -4470,16 +4454,6 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type) dcmd = &cmd->frame->dcmd; - ci = pci_alloc_consistent(instance->pdev, - sizeof(struct MR_LD_TARGETID_LIST), &ci_h); - - if (!ci) { - dev_warn(&instance->pdev->dev, - "Failed to alloc mem for ld_list_query\n"); - megasas_return_cmd(instance, cmd); - return -ENOMEM; - } - memset(ci, 0, sizeof(*ci)); memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); @@ -4550,9 +4524,6 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type) break; } - pci_free_consistent(instance->pdev, sizeof(struct MR_LD_TARGETID_LIST), - ci, ci_h); - if (ret != DCMD_TIMEOUT) megasas_return_cmd(instance, cmd); @@ -4639,6 +4610,9 @@ megasas_get_ctrl_info(struct megasas_instance *instance) ctrl_info = instance->ctrl_info; + ci = instance->ctrl_info_buf; + ci_h = instance->ctrl_info_buf_h; + cmd = megasas_get_cmd(instance); if (!cmd) { @@ -4648,15 +4622,6 @@ megasas_get_ctrl_info(struct megasas_instance *instance) dcmd = &cmd->frame->dcmd; - ci = pci_alloc_consistent(instance->pdev, - sizeof(struct megasas_ctrl_info), &ci_h); - - if (!ci) { - dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to alloc mem for ctrl info\n"); - megasas_return_cmd(instance, cmd); - return -ENOMEM; - } - memset(ci, 0, sizeof(*ci)); memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); @@ -4738,9 +4703,6 @@ megasas_get_ctrl_info(struct megasas_instance *instance) } - pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info), - ci, ci_h); - megasas_return_cmd(instance, cmd); @@ -6103,6 +6065,7 @@ static inline int megasas_alloc_ctrl_dma_buffers(struct megasas_instance *instance) { struct pci_dev *pdev = instance->pdev; + struct fusion_context *fusion = instance->ctrl_context; instance->evt_detail = pci_alloc_consistent(pdev, @@ -6115,6 +6078,62 @@ int megasas_alloc_ctrl_dma_buffers(struct megasas_instance *instance) return -ENOMEM; } + if (fusion) { + fusion->ioc_init_request = + dma_alloc_coherent(&pdev->dev, + sizeof(struct MPI2_IOC_INIT_REQUEST), + &fusion->ioc_init_request_phys, + GFP_KERNEL); + + if (!fusion->ioc_init_request) { + dev_err(&pdev->dev, + "Failed to allocate PD list buffer\n"); + return -ENOMEM; + } + } + + instance->pd_list_buf = + pci_alloc_consistent(pdev, + MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), + &instance->pd_list_buf_h); + + if (!instance->pd_list_buf) { + dev_err(&pdev->dev, "Failed to allocate PD list buffer\n"); + return -ENOMEM; + } + + instance->ctrl_info_buf = + pci_alloc_consistent(pdev, + sizeof(struct megasas_ctrl_info), + &instance->ctrl_info_buf_h); + + if (!instance->ctrl_info_buf) { + dev_err(&pdev->dev, + "Failed to allocate controller info buffer\n"); + return -ENOMEM; + } + + instance->ld_list_buf = + pci_alloc_consistent(pdev, + sizeof(struct MR_LD_LIST), + &instance->ld_list_buf_h); + + if (!instance->ld_list_buf) { + dev_err(&pdev->dev, "Failed to allocate LD list buffer\n"); + return -ENOMEM; + } + + instance->ld_targetid_list_buf = + pci_alloc_consistent(pdev, + sizeof(struct MR_LD_TARGETID_LIST), + &instance->ld_targetid_list_buf_h); + + if (!instance->ld_targetid_list_buf) { + dev_err(&pdev->dev, + "Failed to allocate LD targetid list buffer\n"); + return -ENOMEM; + } + if (!reset_devices) { instance->system_info_buf = pci_alloc_consistent(pdev, @@ -6164,12 +6183,40 @@ static inline void megasas_free_ctrl_dma_buffers(struct megasas_instance *instance) { struct pci_dev *pdev = instance->pdev; + struct fusion_context *fusion = instance->ctrl_context; if (instance->evt_detail) pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), instance->evt_detail, instance->evt_detail_h); + if (fusion && fusion->ioc_init_request) + dma_free_coherent(&pdev->dev, + sizeof(struct MPI2_IOC_INIT_REQUEST), + fusion->ioc_init_request, + fusion->ioc_init_request_phys); + + if (instance->pd_list_buf) + pci_free_consistent(pdev, + MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), + instance->pd_list_buf, + instance->pd_list_buf_h); + + if (instance->ld_list_buf) + pci_free_consistent(pdev, sizeof(struct MR_LD_LIST), + instance->ld_list_buf, + instance->ld_list_buf_h); + + if (instance->ld_targetid_list_buf) + pci_free_consistent(pdev, sizeof(struct MR_LD_TARGETID_LIST), + instance->ld_targetid_list_buf, + instance->ld_targetid_list_buf_h); + + if (instance->ctrl_info_buf) + pci_free_consistent(pdev, sizeof(struct megasas_ctrl_info), + instance->ctrl_info_buf, + instance->ctrl_info_buf_h); + if (instance->system_info_buf) pci_free_consistent(pdev, sizeof(struct MR_DRV_SYSTEM_INFO), instance->system_info_buf, diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index a8055341e875..a630a31aecf8 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -776,6 +776,9 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) fusion = instance->ctrl_context; + ioc_init_handle = fusion->ioc_init_request_phys; + IOCInitMessage = fusion->ioc_init_request; + cmd = megasas_get_cmd(instance); if (!cmd) { @@ -801,18 +804,6 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) dev_info(&instance->pdev->dev, "FW supports sync cache\t: %s\n", instance->fw_sync_cache_support ? "Yes" : "No"); - IOCInitMessage = - dma_alloc_coherent(&instance->pdev->dev, - sizeof(struct MPI2_IOC_INIT_REQUEST), - &ioc_init_handle, GFP_KERNEL); - - if (!IOCInitMessage) { - dev_err(&instance->pdev->dev, "Could not allocate memory for " - "IOCInitMessage\n"); - ret = 1; - goto fail_fw_init; - } - memset(IOCInitMessage, 0, sizeof(struct MPI2_IOC_INIT_REQUEST)); IOCInitMessage->Function = MPI2_FUNCTION_IOC_INIT; @@ -921,10 +912,6 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) fail_fw_init: megasas_return_cmd(instance, cmd); - if (IOCInitMessage) - dma_free_coherent(&instance->pdev->dev, - sizeof(struct MPI2_IOC_INIT_REQUEST), - IOCInitMessage, ioc_init_handle); fail_get_cmd: dev_err(&instance->pdev->dev, "Init cmd return status %s for SCSI host %d\n", diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index a2b56913f382..5b3f1dba1ab2 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -1315,6 +1315,9 @@ struct fusion_context { LD_SPAN_INFO *log_to_span; u32 log_to_span_pages; struct LD_STREAM_DETECT **stream_detect_by_ld; + dma_addr_t ioc_init_request_phys; + struct MPI2_IOC_INIT_REQUEST *ioc_init_request; + }; union desc_value { -- cgit v1.2.3 From 9ad18a9c0c972b618ef68ca8c4a3ff7e7d0b49eb Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:48:57 -0700 Subject: scsi: megaraid_sas: remove instance->ctrl_info Re-use the pre-allocated ctrl_info DMA buffer. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas.h | 1 - drivers/scsi/megaraid/megaraid_sas_base.c | 43 ++++++++++--------------------- 2 files changed, 14 insertions(+), 30 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 80ba77b4b9e2..83427b541629 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2231,7 +2231,6 @@ struct megasas_instance { /* Ptr to hba specific information */ void *ctrl_context; - struct megasas_ctrl_info *ctrl_info; unsigned int msix_vectors; struct megasas_irq_context irq_context[MEGASAS_MAX_MSIX_QUEUES]; u64 map_id; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 19649ca11a1f..b30e80cf4c25 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4545,9 +4545,9 @@ static void megasas_update_ext_vd_details(struct megasas_instance *instance) return; instance->supportmax256vd = - instance->ctrl_info->adapterOperations3.supportMaxExtLDs; + instance->ctrl_info_buf->adapterOperations3.supportMaxExtLDs; /* Below is additional check to address future FW enhancement */ - if (instance->ctrl_info->max_lds > 64) + if (instance->ctrl_info_buf->max_lds > 64) instance->supportmax256vd = 1; instance->drv_supported_vd_count = MEGASAS_MAX_LD_CHANNELS @@ -4605,11 +4605,8 @@ megasas_get_ctrl_info(struct megasas_instance *instance) struct megasas_cmd *cmd; struct megasas_dcmd_frame *dcmd; struct megasas_ctrl_info *ci; - struct megasas_ctrl_info *ctrl_info; dma_addr_t ci_h = 0; - ctrl_info = instance->ctrl_info; - ci = instance->ctrl_info_buf; ci_h = instance->ctrl_info_buf_h; @@ -4645,14 +4642,13 @@ megasas_get_ctrl_info(struct megasas_instance *instance) switch (ret) { case DCMD_SUCCESS: - memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info)); /* Save required controller information in * CPU endianness format. */ - le32_to_cpus((u32 *)&ctrl_info->properties.OnOffProperties); - le32_to_cpus((u32 *)&ctrl_info->adapterOperations2); - le32_to_cpus((u32 *)&ctrl_info->adapterOperations3); - le16_to_cpus((u16 *)&ctrl_info->adapter_operations4); + le32_to_cpus((u32 *)&ci->properties.OnOffProperties); + le32_to_cpus((u32 *)&ci->adapterOperations2); + le32_to_cpus((u32 *)&ci->adapterOperations3); + le16_to_cpus((u16 *)&ci->adapter_operations4); /* Update the latest Ext VD info. * From Init path, store current firmware details. @@ -4661,21 +4657,21 @@ megasas_get_ctrl_info(struct megasas_instance *instance) */ megasas_update_ext_vd_details(instance); instance->use_seqnum_jbod_fp = - ctrl_info->adapterOperations3.useSeqNumJbodFP; + ci->adapterOperations3.useSeqNumJbodFP; instance->support_morethan256jbod = - ctrl_info->adapter_operations4.support_pd_map_target_id; + ci->adapter_operations4.support_pd_map_target_id; /*Check whether controller is iMR or MR */ - instance->is_imr = (ctrl_info->memory_size ? 0 : 1); + instance->is_imr = (ci->memory_size ? 0 : 1); dev_info(&instance->pdev->dev, "controller type\t: %s(%dMB)\n", instance->is_imr ? "iMR" : "MR", - le16_to_cpu(ctrl_info->memory_size)); + le16_to_cpu(ci->memory_size)); instance->disableOnlineCtrlReset = - ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset; + ci->properties.OnOffProperties.disableOnlineCtrlReset; instance->secure_jbod_support = - ctrl_info->adapterOperations3.supportSecurityonJBOD; + ci->adapterOperations3.supportSecurityonJBOD; dev_info(&instance->pdev->dev, "Online Controller Reset(OCR)\t: %s\n", instance->disableOnlineCtrlReset ? "Disabled" : "Enabled"); dev_info(&instance->pdev->dev, "Secure JBOD support\t: %s\n", @@ -5063,7 +5059,7 @@ megasas_setup_jbod_map(struct megasas_instance *instance) (sizeof(struct MR_PD_CFG_SEQ) * (MAX_PHYSICAL_DEVICES - 1)); if (reset_devices || !fusion || - !instance->ctrl_info->adapterOperations3.useSeqNumJbodFP) { + !instance->ctrl_info_buf->adapterOperations3.useSeqNumJbodFP) { dev_info(&instance->pdev->dev, "Jbod map is not supported %s %d\n", __func__, __LINE__); @@ -5277,11 +5273,6 @@ static int megasas_init_fw(struct megasas_instance *instance) tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet, (unsigned long)instance); - 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 @@ -5370,7 +5361,7 @@ 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; - ctrl_info = instance->ctrl_info; + ctrl_info = instance->ctrl_info_buf; max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) * le16_to_cpu(ctrl_info->max_strips_per_io); @@ -5485,8 +5476,6 @@ fail_setup_irqs: pci_free_irq_vectors(instance->pdev); instance->msix_vectors = 0; fail_ready_state: - kfree(instance->ctrl_info); - instance->ctrl_info = NULL; iounmap(instance->reg_set); fail_ioremap: @@ -6341,8 +6330,6 @@ 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)) @@ -6848,8 +6835,6 @@ skip_firing_dcmds: megasas_release_mfi(instance); } - kfree(instance->ctrl_info); - if (instance->vf_affiliation) pci_free_consistent(pdev, (MAX_LOGICAL_DRIVES + 1) * sizeof(struct MR_LD_VF_AFFILIATION), -- cgit v1.2.3 From 7535f27d1f1408c25176af86feda846fa3d3d307 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:48:58 -0700 Subject: scsi: megaraid_sas: Move initialization of instance parameters inside newly created function megasas_init_ctrl_params Code refactoring, no functional change. Create new function to initialize all the controller parameters during load time. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_base.c | 119 +++++++++++++++--------------- 1 file changed, 61 insertions(+), 58 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index b30e80cf4c25..a201b6e3fbb1 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6225,6 +6225,59 @@ void megasas_free_ctrl_dma_buffers(struct megasas_instance *instance) instance->crash_dump_h); } +/* + * megasas_init_ctrl_params - Initialize controller's instance + * parameters before FW init + * @instance - Adapter soft instance + * @return - void + */ +static inline void megasas_init_ctrl_params(struct megasas_instance *instance) +{ + instance->fw_crash_state = UNAVAILABLE; + + megasas_poll_wait_aen = 0; + instance->issuepend_done = 1; + atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL); + + /* + * Initialize locks and queues + */ + INIT_LIST_HEAD(&instance->cmd_pool); + INIT_LIST_HEAD(&instance->internal_reset_pending_q); + + atomic_set(&instance->fw_outstanding, 0); + + init_waitqueue_head(&instance->int_cmd_wait_q); + init_waitqueue_head(&instance->abort_cmd_wait_q); + + spin_lock_init(&instance->crashdump_lock); + spin_lock_init(&instance->mfi_pool_lock); + spin_lock_init(&instance->hba_lock); + spin_lock_init(&instance->stream_lock); + spin_lock_init(&instance->completion_lock); + + mutex_init(&instance->hba_mutex); + mutex_init(&instance->reset_mutex); + + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) + instance->flag_ieee = 1; + + megasas_dbg_lvl = 0; + instance->flag = 0; + instance->unload = 1; + instance->last_time = 0; + instance->disableOnlineCtrlReset = 1; + instance->UnevenSpanSupport = 0; + + if (instance->adapter_type != MFI_SERIES) { + INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq); + INIT_WORK(&instance->crash_init, megasas_fusion_crash_dump_wq); + } else { + INIT_WORK(&instance->work_init, process_fw_state_change_wq); + } +} + /** * megasas_probe_one - PCI hotplug entry point * @pdev: PCI device structure @@ -6279,74 +6332,24 @@ static int megasas_probe_one(struct pci_dev *pdev, instance = (struct megasas_instance *)host->hostdata; memset(instance, 0, sizeof(*instance)); atomic_set(&instance->fw_reset_no_pci_access, 0); - instance->pdev = pdev; - - megasas_set_adapter_type(instance); - - if (megasas_alloc_ctrl_mem(instance)) - goto fail_alloc_dma_buf; - - if (megasas_alloc_ctrl_dma_buffers(instance)) - goto fail_alloc_dma_buf; - - /* Crash dump feature related initialisation*/ - instance->drv_buf_index = 0; - instance->drv_buf_alloc = 0; - instance->crash_dump_fw_support = 0; - instance->crash_dump_app_support = 0; - instance->fw_crash_state = UNAVAILABLE; - spin_lock_init(&instance->crashdump_lock); - instance->crash_dump_buf = NULL; - - megasas_poll_wait_aen = 0; - instance->flag_ieee = 0; - instance->ev = NULL; - instance->issuepend_done = 1; - atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL); - instance->is_imr = 0; - - /* - * Initialize locks and queues - */ - INIT_LIST_HEAD(&instance->cmd_pool); - INIT_LIST_HEAD(&instance->internal_reset_pending_q); - - atomic_set(&instance->fw_outstanding,0); - - init_waitqueue_head(&instance->int_cmd_wait_q); - init_waitqueue_head(&instance->abort_cmd_wait_q); - - spin_lock_init(&instance->mfi_pool_lock); - spin_lock_init(&instance->hba_lock); - spin_lock_init(&instance->stream_lock); - spin_lock_init(&instance->completion_lock); - - mutex_init(&instance->reset_mutex); - mutex_init(&instance->hba_mutex); /* * Initialize PCI related and misc parameters */ + instance->pdev = pdev; instance->host = host; instance->unique_id = pdev->bus->number << 8 | pdev->devfn; instance->init_id = MEGASAS_DEFAULT_INIT_ID; - if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) || - (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) - instance->flag_ieee = 1; + megasas_set_adapter_type(instance); - megasas_dbg_lvl = 0; - instance->flag = 0; - instance->unload = 1; - instance->last_time = 0; - instance->disableOnlineCtrlReset = 1; - instance->UnevenSpanSupport = 0; + megasas_init_ctrl_params(instance); - if (instance->adapter_type != MFI_SERIES) { - INIT_WORK(&instance->work_init, megasas_fusion_ocr_wq); - INIT_WORK(&instance->crash_init, megasas_fusion_crash_dump_wq); - } else - INIT_WORK(&instance->work_init, process_fw_state_change_wq); + if (megasas_alloc_ctrl_mem(instance)) + goto fail_alloc_dma_buf; + + if (megasas_alloc_ctrl_dma_buffers(instance)) + goto fail_alloc_dma_buf; /* * Initialize MFI Firmware -- cgit v1.2.3 From e5d65b4b81af41e3d6b8e25f7aabc5256f647d87 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:48:59 -0700 Subject: scsi: megaraid_sas: Move controller memory allocations and DMA mask settings from probe to megasas_init_fw Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_base.c | 43 ++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 15 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index a201b6e3fbb1..79e3e23cd9b7 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -206,6 +206,18 @@ wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd, void megasas_fusion_ocr_wq(struct work_struct *work); static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance, int initial); +static int +megasas_set_dma_mask(struct pci_dev *pdev); +static int +megasas_alloc_ctrl_mem(struct megasas_instance *instance); +static inline void +megasas_free_ctrl_mem(struct megasas_instance *instance); +static inline int +megasas_alloc_ctrl_dma_buffers(struct megasas_instance *instance); +static inline void +megasas_free_ctrl_dma_buffers(struct megasas_instance *instance); +static inline void +megasas_init_ctrl_params(struct megasas_instance *instance); void megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd) @@ -5179,6 +5191,19 @@ static int megasas_init_fw(struct megasas_instance *instance) goto fail_ready_state; } + megasas_init_ctrl_params(instance); + + if (megasas_set_dma_mask(instance->pdev)) + goto fail_ready_state; + + if (megasas_alloc_ctrl_mem(instance)) + goto fail_alloc_dma_buf; + + if (megasas_alloc_ctrl_dma_buffers(instance)) + goto fail_alloc_dma_buf; + + fusion = instance->ctrl_context; + if (instance->adapter_type == VENTURA_SERIES) { scratch_pad_3 = readl(&instance->reg_set->outbound_scratch_pad_3); @@ -5475,6 +5500,9 @@ fail_setup_irqs: if (instance->msix_vectors) pci_free_irq_vectors(instance->pdev); instance->msix_vectors = 0; +fail_alloc_dma_buf: + megasas_free_ctrl_dma_buffers(instance); + megasas_free_ctrl_mem(instance); fail_ready_state: iounmap(instance->reg_set); @@ -6318,9 +6346,6 @@ static int megasas_probe_one(struct pci_dev *pdev, pci_set_master(pdev); - if (megasas_set_dma_mask(pdev)) - goto fail_set_dma_mask; - host = scsi_host_alloc(&megasas_template, sizeof(struct megasas_instance)); @@ -6343,14 +6368,6 @@ static int megasas_probe_one(struct pci_dev *pdev, megasas_set_adapter_type(instance); - megasas_init_ctrl_params(instance); - - if (megasas_alloc_ctrl_mem(instance)) - goto fail_alloc_dma_buf; - - if (megasas_alloc_ctrl_dma_buffers(instance)) - goto fail_alloc_dma_buf; - /* * Initialize MFI Firmware */ @@ -6432,13 +6449,9 @@ fail_io_attach: if (instance->msix_vectors) pci_free_irq_vectors(instance->pdev); fail_init_mfi: -fail_alloc_dma_buf: - megasas_free_ctrl_dma_buffers(instance); - megasas_free_ctrl_mem(instance); scsi_host_put(host); fail_alloc_instance: -fail_set_dma_mask: pci_disable_device(pdev); return -ENODEV; -- cgit v1.2.3 From b99fc20281968b24ef8e3ab56cc5ba78c14b2a24 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:49:00 -0700 Subject: scsi: megaraid_sas: Update current host time to FW during IOC Init Driver needs to send current host time to firmware during init. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index a630a31aecf8..277fd16305ee 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -773,6 +773,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) MFI_CAPABILITIES *drv_ops; u32 scratch_pad_2; unsigned long flags; + struct timeval tv; fusion = instance->ctrl_context; @@ -821,6 +822,12 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) IOCInitMessage->SystemRequestFrameBaseAddress = cpu_to_le64(fusion->io_request_frames_phys); IOCInitMessage->HostMSIxVectors = instance->msix_vectors; IOCInitMessage->HostPageSize = MR_DEFAULT_NVME_PAGE_SHIFT; + + do_gettimeofday(&tv); + /* Convert to milliseconds as per FW requirement */ + IOCInitMessage->TimeStamp = cpu_to_le64((tv.tv_sec * 1000) + + (tv.tv_usec / 1000)); + init_frame = (struct megasas_init_frame *)cmd->frame; memset(init_frame, 0, MEGAMFI_FRAME_SIZE); -- cgit v1.2.3 From b9637d14dc00d91cef0068cde1f9a8959b051028 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:49:01 -0700 Subject: scsi: megaraid_sas: Resize MFA frame used for IOC INIT to 4k Older firmware version unconditionally pulls 4k frame for IOC INIT MFA frame. But driver allocates 1k or 4k max_chain_frame_sz based on FW capability. During boot time, this results in DMA read errors. Workaround fix in driver by allocating separate ioc_init frame of 4k size to support older firmware. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Cc: stable@vger.kernel.org Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 65 +++++++++++++++++++++++++---- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 + 2 files changed, 58 insertions(+), 9 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 277fd16305ee..857bdbb0f79d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -780,13 +780,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) ioc_init_handle = fusion->ioc_init_request_phys; IOCInitMessage = fusion->ioc_init_request; - cmd = megasas_get_cmd(instance); - - if (!cmd) { - dev_err(&instance->pdev->dev, "Could not allocate cmd for INIT Frame\n"); - ret = 1; - goto fail_get_cmd; - } + cmd = fusion->ioc_init_cmd; scratch_pad_2 = readl (&instance->reg_set->outbound_scratch_pad_2); @@ -918,8 +912,6 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) ret = 0; fail_fw_init: - megasas_return_cmd(instance, cmd); -fail_get_cmd: dev_err(&instance->pdev->dev, "Init cmd return status %s for SCSI host %d\n", ret ? "FAILED" : "SUCCESS", instance->host->host_no); @@ -1333,6 +1325,56 @@ ld_drv_map_alloc_fail: return -ENOMEM; } +static int megasas_alloc_ioc_init_frame(struct megasas_instance *instance) +{ + struct fusion_context *fusion; + struct megasas_cmd *cmd; + + fusion = instance->ctrl_context; + + cmd = kmalloc(sizeof(struct megasas_cmd), GFP_KERNEL); + + if (!cmd) { + dev_err(&instance->pdev->dev, "Failed from func: %s line: %d\n", + __func__, __LINE__); + return -ENOMEM; + } + + cmd->frame = dma_alloc_coherent(&instance->pdev->dev, + IOC_INIT_FRAME_SIZE, + &cmd->frame_phys_addr, GFP_KERNEL); + + if (!cmd->frame) { + dev_err(&instance->pdev->dev, "Failed from func: %s line: %d\n", + __func__, __LINE__); + kfree(cmd); + return -ENOMEM; + } + + fusion->ioc_init_cmd = cmd; + return 0; +} + +/** + * megasas_free_ioc_init_cmd - Free IOC INIT command frame + * @instance: Adapter soft state + */ +static inline void megasas_free_ioc_init_cmd(struct megasas_instance *instance) +{ + struct fusion_context *fusion; + + fusion = instance->ctrl_context; + + if (fusion->ioc_init_cmd && fusion->ioc_init_cmd->frame) + dma_free_coherent(&instance->pdev->dev, + IOC_INIT_FRAME_SIZE, + fusion->ioc_init_cmd->frame, + fusion->ioc_init_cmd->frame_phys_addr); + + if (fusion->ioc_init_cmd) + kfree(fusion->ioc_init_cmd); +} + /** * megasas_init_adapter_fusion - Initializes the FW * @instance: Adapter soft state @@ -1428,6 +1470,9 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) MEGASAS_FUSION_IOCTL_CMDS); sema_init(&instance->ioctl_sem, MEGASAS_FUSION_IOCTL_CMDS); + if (megasas_alloc_ioc_init_frame(instance)) + return 1; + /* * Allocate memory for descriptors * Create a pool of commands @@ -1465,6 +1510,7 @@ fail_ioc_init: fail_alloc_cmds: megasas_free_cmds(instance); fail_alloc_mfi_cmds: + megasas_free_ioc_init_cmd(instance); return 1; } @@ -3383,6 +3429,7 @@ megasas_issue_dcmd_fusion(struct megasas_instance *instance, void megasas_release_fusion(struct megasas_instance *instance) { + megasas_free_ioc_init_cmd(instance); megasas_free_cmds(instance); megasas_free_cmds_fusion(instance); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index 5b3f1dba1ab2..549f86b2e871 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -103,6 +103,7 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE { #define THRESHOLD_REPLY_COUNT 50 #define RAID_1_PEER_CMDS 2 #define JBOD_MAPS_COUNT 2 +#define IOC_INIT_FRAME_SIZE 4096 /* * Raid Context structure which describes MegaRAID specific IO Parameters @@ -1317,6 +1318,7 @@ struct fusion_context { struct LD_STREAM_DETECT **stream_detect_by_ld; dma_addr_t ioc_init_request_phys; struct MPI2_IOC_INIT_REQUEST *ioc_init_request; + struct megasas_cmd *ioc_init_cmd; }; -- cgit v1.2.3 From 82add4e1b354f93ca4b986989a94c957cb8b06c5 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:49:02 -0700 Subject: scsi: megaraid_sas: Incorrect processing of IOCTL frames for SMP/STP commands cmd->frame->dcmd.opcode will be valid only for MFI_CMD_DCMD IOCTL frames. Currently driver check for cmd->frame->dcmd.opcode without checking cmd type. Ensure we check dcmd opcode only for MFI_CMD_DCMD commands. Separate handling of MFI_CMD_SMP/STP commands from MFI_CMD_DCMD in completion path. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas.h | 23 +++++++++++++---------- drivers/scsi/megaraid/megaraid_sas_base.c | 22 ++++++++++++++++++---- 2 files changed, 31 insertions(+), 14 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 83427b541629..85ef8415640c 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -187,16 +187,19 @@ /* * MFI command opcodes */ -#define MFI_CMD_INIT 0x00 -#define MFI_CMD_LD_READ 0x01 -#define MFI_CMD_LD_WRITE 0x02 -#define MFI_CMD_LD_SCSI_IO 0x03 -#define MFI_CMD_PD_SCSI_IO 0x04 -#define MFI_CMD_DCMD 0x05 -#define MFI_CMD_ABORT 0x06 -#define MFI_CMD_SMP 0x07 -#define MFI_CMD_STP 0x08 -#define MFI_CMD_INVALID 0xff +enum MFI_CMD_OP { + MFI_CMD_INIT = 0x0, + MFI_CMD_LD_READ = 0x1, + MFI_CMD_LD_WRITE = 0x2, + MFI_CMD_LD_SCSI_IO = 0x3, + MFI_CMD_PD_SCSI_IO = 0x4, + MFI_CMD_DCMD = 0x5, + MFI_CMD_ABORT = 0x6, + MFI_CMD_SMP = 0x7, + MFI_CMD_STP = 0x8, + MFI_CMD_OP_COUNT, + MFI_CMD_INVALID = 0xff +}; #define MR_DCMD_CTRL_GET_INFO 0x01010000 #define MR_DCMD_LD_GET_LIST 0x03010000 diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 79e3e23cd9b7..7e40ff6725e9 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -3298,6 +3298,9 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, case MFI_CMD_SMP: case MFI_CMD_STP: + megasas_complete_int_cmd(instance, cmd); + break; + case MFI_CMD_DCMD: opcode = le32_to_cpu(cmd->frame->dcmd.opcode); /* Check for LD map update */ @@ -3384,6 +3387,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, default: dev_info(&instance->pdev->dev, "Unknown command completed! [0x%X]\n", hdr->cmd); + megasas_complete_int_cmd(instance, cmd); break; } } @@ -7017,7 +7021,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, void *sense = NULL; dma_addr_t sense_handle; unsigned long *sense_ptr; - u32 opcode; + u32 opcode = 0; memset(kbuff_arr, 0, sizeof(kbuff_arr)); @@ -7027,6 +7031,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, return -EINVAL; } + if (ioc->frame.hdr.cmd >= MFI_CMD_OP_COUNT) { + dev_err(&instance->pdev->dev, + "Received invalid ioctl command 0x%x\n", + ioc->frame.hdr.cmd); + return -ENOTSUPP; + } + cmd = megasas_get_cmd(instance); if (!cmd) { dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to get a cmd packet\n"); @@ -7045,7 +7056,9 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, cmd->frame->hdr.flags &= cpu_to_le16(~(MFI_FRAME_IEEE | MFI_FRAME_SGL64 | MFI_FRAME_SENSE64)); - opcode = le32_to_cpu(cmd->frame->dcmd.opcode); + + if (cmd->frame->hdr.cmd == MFI_CMD_DCMD) + opcode = le32_to_cpu(cmd->frame->dcmd.opcode); if (opcode == MR_DCMD_CTRL_SHUTDOWN) { if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) { @@ -7127,8 +7140,9 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, if (megasas_issue_blocked_cmd(instance, cmd, 0) == DCMD_NOT_FIRED) { cmd->sync_cmd = 0; dev_err(&instance->pdev->dev, - "return -EBUSY from %s %d opcode 0x%x cmd->cmd_status_drv 0x%x\n", - __func__, __LINE__, opcode, cmd->cmd_status_drv); + "return -EBUSY from %s %d cmd 0x%x opcode 0x%x cmd->cmd_status_drv 0x%x\n", + __func__, __LINE__, cmd->frame->hdr.cmd, opcode, + cmd->cmd_status_drv); return -EBUSY; } -- cgit v1.2.3 From e97e673ca63bc8f8c1518f66567240fa4e79d2ad Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:49:03 -0700 Subject: scsi: megaraid_sas: Retry with reduced queue depth when alloc fails for higher QD In certain cases, the host memory is limited and with FW supporting higher queue depths there are increasing chances of IO request frame allocation failures that we are seeing. In case of request frame allocation failures, retry allocation with reduced queue depth (in steps of 64) to continue to configure the controller with a reduced performance rather than failing load. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 106 ++++++++++++++++++---------- drivers/scsi/megaraid/megaraid_sas_fusion.h | 1 + 2 files changed, 68 insertions(+), 39 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 857bdbb0f79d..8b7a08af275e 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -96,6 +96,8 @@ extern unsigned int resetwaittime; extern unsigned int dual_qdepth_disable; static void megasas_free_rdpq_fusion(struct megasas_instance *instance); static void megasas_free_reply_fusion(struct megasas_instance *instance); +static inline +void megasas_configure_queue_sizes(struct megasas_instance *instance); @@ -254,8 +256,8 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c (instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF) - MEGASAS_FUSION_IOCTL_CMDS; dev_info(&instance->pdev->dev, - "Current firmware maximum commands: %d\t LDIO threshold: %d\n", - cur_max_fw_cmds, ldio_threshold); + "Current firmware supports maximum commands: %d\t LDIO thershold: %d\n", + cur_max_fw_cmds, ldio_threshold); if (fw_boot_context == OCR_CONTEXT) { cur_max_fw_cmds = cur_max_fw_cmds - 1; @@ -283,19 +285,7 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c * does not exceed max cmds that the FW can support */ instance->max_fw_cmds = instance->max_fw_cmds-1; - - instance->max_scsi_cmds = instance->max_fw_cmds - - (MEGASAS_FUSION_INTERNAL_CMDS + - MEGASAS_FUSION_IOCTL_CMDS); - instance->cur_can_queue = instance->max_scsi_cmds; - instance->host->can_queue = instance->cur_can_queue; } - - if (instance->adapter_type == VENTURA_SERIES) - instance->max_mpt_cmds = - instance->max_fw_cmds * RAID_1_PEER_CMDS; - else - instance->max_mpt_cmds = instance->max_fw_cmds; } /** * megasas_free_cmds_fusion - Free all the cmds in the free cmd pool @@ -468,16 +458,7 @@ megasas_alloc_request_fusion(struct megasas_instance *instance) fusion = instance->ctrl_context; - fusion->req_frames_desc = - dma_alloc_coherent(&instance->pdev->dev, - fusion->request_alloc_sz, - &fusion->req_frames_desc_phys, GFP_KERNEL); - if (!fusion->req_frames_desc) { - dev_err(&instance->pdev->dev, - "Failed from %s %d\n", __func__, __LINE__); - return -ENOMEM; - } - +retry_alloc: fusion->io_request_frames_pool = dma_pool_create("mr_ioreq", &instance->pdev->dev, fusion->io_frames_alloc_sz, 16, 0); @@ -492,10 +473,28 @@ megasas_alloc_request_fusion(struct megasas_instance *instance) dma_pool_alloc(fusion->io_request_frames_pool, GFP_KERNEL, &fusion->io_request_frames_phys); if (!fusion->io_request_frames) { + if (instance->max_fw_cmds >= (MEGASAS_REDUCE_QD_COUNT * 2)) { + instance->max_fw_cmds -= MEGASAS_REDUCE_QD_COUNT; + dma_pool_destroy(fusion->io_request_frames_pool); + megasas_configure_queue_sizes(instance); + goto retry_alloc; + } else { + dev_err(&instance->pdev->dev, + "Failed from %s %d\n", __func__, __LINE__); + return -ENOMEM; + } + } + + fusion->req_frames_desc = + dma_alloc_coherent(&instance->pdev->dev, + fusion->request_alloc_sz, + &fusion->req_frames_desc_phys, GFP_KERNEL); + if (!fusion->req_frames_desc) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); return -ENOMEM; } + return 0; } @@ -664,9 +663,6 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance) fusion = instance->ctrl_context; - if (megasas_alloc_cmdlist_fusion(instance)) - goto fail_exit; - if (megasas_alloc_request_fusion(instance)) goto fail_exit; @@ -677,6 +673,11 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance) if (megasas_alloc_reply_fusion(instance)) goto fail_exit; + if (megasas_alloc_cmdlist_fusion(instance)) + goto fail_exit; + + dev_info(&instance->pdev->dev, "Configured max firmware commands: %d\n", + instance->max_fw_cmds); /* The first 256 bytes (SMID 0) is not used. Don't add to the cmd list */ io_req_base = fusion->io_request_frames + MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE; @@ -1325,6 +1326,44 @@ ld_drv_map_alloc_fail: return -ENOMEM; } +/** + * megasas_configure_queue_sizes - Calculate size of request desc queue, + * reply desc queue, + * IO request frame queue, set can_queue. + * @instance: Adapter soft state + * @return: void + */ +static inline +void megasas_configure_queue_sizes(struct megasas_instance *instance) +{ + struct fusion_context *fusion; + u16 max_cmd; + + fusion = instance->ctrl_context; + max_cmd = instance->max_fw_cmds; + + if (instance->adapter_type == VENTURA_SERIES) + instance->max_mpt_cmds = instance->max_fw_cmds * RAID_1_PEER_CMDS; + else + instance->max_mpt_cmds = instance->max_fw_cmds; + + instance->max_scsi_cmds = instance->max_fw_cmds - + (MEGASAS_FUSION_INTERNAL_CMDS + + MEGASAS_FUSION_IOCTL_CMDS); + instance->cur_can_queue = instance->max_scsi_cmds; + instance->host->can_queue = instance->cur_can_queue; + + fusion->reply_q_depth = 2 * ((max_cmd + 1 + 15) / 16) * 16; + + fusion->request_alloc_sz = sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) * + instance->max_mpt_cmds; + fusion->reply_alloc_sz = sizeof(union MPI2_REPLY_DESCRIPTORS_UNION) * + (fusion->reply_q_depth); + fusion->io_frames_alloc_sz = MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE + + (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE + * (instance->max_mpt_cmds + 1)); /* Extra 1 for SMID 0 */ +} + static int megasas_alloc_ioc_init_frame(struct megasas_instance *instance) { struct fusion_context *fusion; @@ -1386,7 +1425,6 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) { struct megasas_register_set __iomem *reg_set; struct fusion_context *fusion; - u16 max_cmd; u32 scratch_pad_2; int i = 0, count; @@ -1402,17 +1440,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) instance->max_mfi_cmds = MEGASAS_FUSION_INTERNAL_CMDS + MEGASAS_FUSION_IOCTL_CMDS; - max_cmd = instance->max_fw_cmds; - - fusion->reply_q_depth = 2 * (((max_cmd + 1 + 15)/16)*16); - - fusion->request_alloc_sz = - sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) * instance->max_mpt_cmds; - fusion->reply_alloc_sz = sizeof(union MPI2_REPLY_DESCRIPTORS_UNION) - *(fusion->reply_q_depth); - fusion->io_frames_alloc_sz = MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE + - (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE - * (instance->max_mpt_cmds + 1)); /* Extra 1 for SMID 0 */ + megasas_configure_queue_sizes(instance); scratch_pad_2 = readl(&instance->reg_set->outbound_scratch_pad_2); /* If scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK is set, diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index 549f86b2e871..4e229d72dfb0 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -103,6 +103,7 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE { #define THRESHOLD_REPLY_COUNT 50 #define RAID_1_PEER_CMDS 2 #define JBOD_MAPS_COUNT 2 +#define MEGASAS_REDUCE_QD_COUNT 64 #define IOC_INIT_FRAME_SIZE 4096 /* -- cgit v1.2.3 From 2dba66bf8ecb2dd07b721465c25f537acff6eaf1 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:49:04 -0700 Subject: scsi: megaraid_sas: Do not limit queue_depth to 1k in non-RDPQ mode Driver load fails if memory allocation for request frame pool fails due to the higher queue_depth requirement. The driver now allows dynamically reducing queue_depth if memory allocations fail rather than failing load. With this, there is no need to limit queue_depth to 1K. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 8b7a08af275e..745da54c11aa 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -272,10 +272,6 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c instance->max_fw_cmds = cur_max_fw_cmds; instance->ldio_threshold = ldio_threshold; - if (!instance->is_rdpq) - instance->max_fw_cmds = - min_t(u16, instance->max_fw_cmds, 1024); - if (reset_devices) instance->max_fw_cmds = min(instance->max_fw_cmds, (u16)MEGASAS_KDUMP_QUEUE_DEPTH); -- cgit v1.2.3 From 107a60dd71b5f536a68437514f7c15a5dd3a4a9d Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:49:05 -0700 Subject: scsi: megaraid_sas: Add support for 64bit consistent DMA The latest MegaRAID Firmware (for Invader series) has support for 64bit DMA for both streaming and consistent DMA buffers. All Ventura series controller FW always support 64 bit consistent DMA. Also, on a few architectures 32bit DMA is not supported. Current driver always prefers 32bit for consistent DMA and 64bit for streaming DMA. This behavior was unintentional and carried forwarded from legacy controller FW. Need to enhance the driver to support 64bit consistent DMA buffers based on the firmware capability. Below is the DMA setting strategy in driver with this patch. For Ventura series, always try to set 64bit DMA mask. If it fails fall back to 32bit DMA mask. For Invader series and earlier generation controllers, first try to set to 32bit consistent DMA mask irrespective of FW capability. This is needed to ensure firmware downgrades do not break. If 32bit DMA setting fails, check FW capability and try seting to 64bit DMA mask. There are certain restrictions in the hardware for having all sense buffers and all reply descriptors to be in the same 4GB memory region. This limitation is h/w dependent and can not be changed in firmware. This limitation needs to be taken care in driver while allocating the buffers. There was a discussion regarding this - find details at below link. https://www.spinics.net/lists/linux-scsi/msg108251.html Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas.h | 12 +- drivers/scsi/megaraid/megaraid_sas_base.c | 245 ++++++++++++------ drivers/scsi/megaraid/megaraid_sas_fusion.c | 384 ++++++++++++++++++++++------ drivers/scsi/megaraid/megaraid_sas_fusion.h | 13 + 4 files changed, 503 insertions(+), 151 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 85ef8415640c..b34fc68c14c9 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1508,6 +1508,8 @@ enum FW_BOOT_CONTEXT { #define MR_CAN_HANDLE_SYNC_CACHE_OFFSET 0X01000000 +#define MR_CAN_HANDLE_64_BIT_DMA_OFFSET (1 << 25) + enum MR_ADAPTER_TYPE { MFI_SERIES = 1, THUNDERBOLT_SERIES = 2, @@ -1628,7 +1630,8 @@ union megasas_sgl_frame { typedef union _MFI_CAPABILITIES { struct { #if defined(__BIG_ENDIAN_BITFIELD) - u32 reserved:19; + u32 reserved:18; + u32 support_64bit_mode:1; u32 support_pd_map_target_id:1; u32 support_qd_throttling:1; u32 support_fp_rlbypass:1; @@ -1656,7 +1659,8 @@ typedef union _MFI_CAPABILITIES { u32 support_fp_rlbypass:1; u32 support_qd_throttling:1; u32 support_pd_map_target_id:1; - u32 reserved:19; + u32 support_64bit_mode:1; + u32 reserved:18; #endif } mfi_capabilities; __le32 reg; @@ -2264,6 +2268,7 @@ struct megasas_instance { u8 r1_ldio_hint_default; u32 nvme_page_size; u8 adapter_type; + bool consistent_mask_64bit; }; struct MR_LD_VF_MAP { u32 size; @@ -2510,4 +2515,7 @@ int megasas_reset_target_fusion(struct scsi_cmnd *scmd); u32 mega_mod64(u64 dividend, u32 divisor); int megasas_alloc_fusion_context(struct megasas_instance *instance); void megasas_free_fusion_context(struct megasas_instance *instance); +void megasas_set_dma_settings(struct megasas_instance *instance, + struct megasas_dcmd_frame *dcmd, + dma_addr_t dma_addr, u32 dma_len); #endif /*LSI_MEGARAID_SAS_H */ diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 7e40ff6725e9..f14d7cb05280 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -207,7 +207,7 @@ void megasas_fusion_ocr_wq(struct work_struct *work); static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance, int initial); static int -megasas_set_dma_mask(struct pci_dev *pdev); +megasas_set_dma_mask(struct megasas_instance *instance); static int megasas_alloc_ctrl_mem(struct megasas_instance *instance); static inline void @@ -219,6 +219,31 @@ megasas_free_ctrl_dma_buffers(struct megasas_instance *instance); static inline void megasas_init_ctrl_params(struct megasas_instance *instance); +/** + * megasas_set_dma_settings - Populate DMA address, length and flags for DCMDs + * @instance: Adapter soft state + * @dcmd: DCMD frame inside MFI command + * @dma_addr: DMA address of buffer to be passed to FW + * @dma_len: Length of DMA buffer to be passed to FW + * @return: void + */ +void megasas_set_dma_settings(struct megasas_instance *instance, + struct megasas_dcmd_frame *dcmd, + dma_addr_t dma_addr, u32 dma_len) +{ + if (instance->consistent_mask_64bit) { + dcmd->sgl.sge64[0].phys_addr = cpu_to_le64(dma_addr); + dcmd->sgl.sge64[0].length = cpu_to_le32(dma_len); + dcmd->flags = cpu_to_le16(dcmd->flags | MFI_FRAME_SGL64); + + } else { + dcmd->sgl.sge32[0].phys_addr = + cpu_to_le32(lower_32_bits(dma_addr)); + dcmd->sgl.sge32[0].length = cpu_to_le32(dma_len); + dcmd->flags = cpu_to_le16(dcmd->flags); + } +} + void megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd) { @@ -2501,8 +2526,9 @@ int megasas_sriov_start_heartbeat(struct megasas_instance *instance, dcmd->pad_0 = 0; dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_CTRL_HB_HOST_MEM)); dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC); - dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(instance->hb_host_mem_h); - dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_CTRL_HB_HOST_MEM)); + + megasas_set_dma_settings(instance, dcmd, instance->hb_host_mem_h, + sizeof(struct MR_CTRL_HB_HOST_MEM)); dev_warn(&instance->pdev->dev, "SR-IOV: Starting heartbeat for scsi%d\n", instance->host->host_no); @@ -4155,13 +4181,14 @@ megasas_get_pd_info(struct megasas_instance *instance, struct scsi_device *sdev) dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = 0xFF; dcmd->sge_count = 1; - dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ); + dcmd->flags = MFI_FRAME_DIR_READ; dcmd->timeout = 0; dcmd->pad_0 = 0; dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_PD_INFO)); dcmd->opcode = cpu_to_le32(MR_DCMD_PD_GET_INFO); - dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(instance->pd_info_h); - dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_PD_INFO)); + + megasas_set_dma_settings(instance, dcmd, instance->pd_info_h, + sizeof(struct MR_PD_INFO)); if ((instance->adapter_type != MFI_SERIES) && !instance->mask_interrupts) @@ -4247,13 +4274,14 @@ megasas_get_pd_list(struct megasas_instance *instance) dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = MFI_STAT_INVALID_STATUS; dcmd->sge_count = 1; - dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ); + dcmd->flags = MFI_FRAME_DIR_READ; dcmd->timeout = 0; dcmd->pad_0 = 0; dcmd->data_xfer_len = cpu_to_le32(MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST)); dcmd->opcode = cpu_to_le32(MR_DCMD_PD_LIST_QUERY); - dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h); - dcmd->sgl.sge32[0].length = cpu_to_le32(MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST)); + + megasas_set_dma_settings(instance, dcmd, instance->pd_list_buf_h, + (MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST))); if ((instance->adapter_type != MFI_SERIES) && !instance->mask_interrupts) @@ -4369,14 +4397,15 @@ megasas_get_ld_list(struct megasas_instance *instance) dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = MFI_STAT_INVALID_STATUS; dcmd->sge_count = 1; - dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ); + dcmd->flags = MFI_FRAME_DIR_READ; dcmd->timeout = 0; dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_LD_LIST)); dcmd->opcode = cpu_to_le32(MR_DCMD_LD_GET_LIST); - dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h); - dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_LD_LIST)); dcmd->pad_0 = 0; + megasas_set_dma_settings(instance, dcmd, ci_h, + sizeof(struct MR_LD_LIST)); + if ((instance->adapter_type != MFI_SERIES) && !instance->mask_interrupts) ret = megasas_issue_blocked_cmd(instance, cmd, @@ -4480,14 +4509,15 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type) dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = MFI_STAT_INVALID_STATUS; dcmd->sge_count = 1; - dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ); + dcmd->flags = MFI_FRAME_DIR_READ; dcmd->timeout = 0; dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_LD_TARGETID_LIST)); dcmd->opcode = cpu_to_le32(MR_DCMD_LD_LIST_QUERY); - dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h); - dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_LD_TARGETID_LIST)); dcmd->pad_0 = 0; + megasas_set_dma_settings(instance, dcmd, ci_h, + sizeof(struct MR_LD_TARGETID_LIST)); + if ((instance->adapter_type != MFI_SERIES) && !instance->mask_interrupts) ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS); @@ -4641,15 +4671,16 @@ megasas_get_ctrl_info(struct megasas_instance *instance) dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = MFI_STAT_INVALID_STATUS; dcmd->sge_count = 1; - dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ); + dcmd->flags = MFI_FRAME_DIR_READ; dcmd->timeout = 0; dcmd->pad_0 = 0; dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_ctrl_info)); 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; + megasas_set_dma_settings(instance, dcmd, ci_h, + sizeof(struct megasas_ctrl_info)); + if ((instance->adapter_type != MFI_SERIES) && !instance->mask_interrupts) ret = megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS); @@ -4758,13 +4789,14 @@ int megasas_set_crash_dump_params(struct megasas_instance *instance, dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = MFI_STAT_INVALID_STATUS; dcmd->sge_count = 1; - dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_NONE); + dcmd->flags = MFI_FRAME_DIR_NONE; dcmd->timeout = 0; dcmd->pad_0 = 0; dcmd->data_xfer_len = cpu_to_le32(CRASH_DMA_BUF_SIZE); dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_SET_CRASH_DUMP_PARAMS); - dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(instance->crash_dump_h); - dcmd->sgl.sge32[0].length = cpu_to_le32(CRASH_DMA_BUF_SIZE); + + megasas_set_dma_settings(instance, dcmd, instance->crash_dump_h, + CRASH_DMA_BUF_SIZE); if ((instance->adapter_type != MFI_SERIES) && !instance->mask_interrupts) @@ -5197,7 +5229,7 @@ static int megasas_init_fw(struct megasas_instance *instance) megasas_init_ctrl_params(instance); - if (megasas_set_dma_mask(instance->pdev)) + if (megasas_set_dma_mask(instance)) goto fail_ready_state; if (megasas_alloc_ctrl_mem(instance)) @@ -5580,13 +5612,14 @@ megasas_get_seq_num(struct megasas_instance *instance, dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = 0x0; dcmd->sge_count = 1; - dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ); + dcmd->flags = MFI_FRAME_DIR_READ; dcmd->timeout = 0; dcmd->pad_0 = 0; dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_evt_log_info)); dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_EVENT_GET_INFO); - dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(el_info_h); - dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_evt_log_info)); + + megasas_set_dma_settings(instance, dcmd, el_info_h, + sizeof(struct megasas_evt_log_info)); if (megasas_issue_blocked_cmd(instance, cmd, MFI_IO_TIMEOUT_SECS) == DCMD_SUCCESS) { @@ -5711,7 +5744,7 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num, dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = 0x0; dcmd->sge_count = 1; - dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ); + dcmd->flags = MFI_FRAME_DIR_READ; dcmd->timeout = 0; dcmd->pad_0 = 0; dcmd->data_xfer_len = cpu_to_le32(sizeof(struct megasas_evt_detail)); @@ -5719,8 +5752,9 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num, dcmd->mbox.w[0] = cpu_to_le32(seq_num); instance->last_seq_num = seq_num; dcmd->mbox.w[1] = cpu_to_le32(curr_aen.word); - dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(instance->evt_detail_h); - dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_evt_detail)); + + megasas_set_dma_settings(instance, dcmd, instance->evt_detail_h, + sizeof(struct megasas_evt_detail)); if (instance->aen_cmd != NULL) { megasas_return_cmd(instance, cmd); @@ -5787,16 +5821,15 @@ megasas_get_target_prop(struct megasas_instance *instance, dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = 0xFF; dcmd->sge_count = 1; - dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ); + dcmd->flags = MFI_FRAME_DIR_READ; dcmd->timeout = 0; dcmd->pad_0 = 0; dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_TARGET_PROPERTIES)); dcmd->opcode = cpu_to_le32(MR_DCMD_DRV_GET_TARGET_PROP); - dcmd->sgl.sge32[0].phys_addr = - cpu_to_le32(instance->tgt_prop_h); - dcmd->sgl.sge32[0].length = - cpu_to_le32(sizeof(struct MR_TARGET_PROPERTIES)); + + megasas_set_dma_settings(instance, dcmd, instance->tgt_prop_h, + sizeof(struct MR_TARGET_PROPERTIES)); if ((instance->adapter_type != MFI_SERIES) && !instance->mask_interrupts) @@ -5924,40 +5957,73 @@ static int megasas_io_attach(struct megasas_instance *instance) return 0; } +/** + * megasas_set_dma_mask - Set DMA mask for supported controllers + * + * @instance: Adapter soft state + * Description: + * + * For Ventura, driver/FW will operate in 64bit DMA addresses. + * + * For invader- + * By default, driver/FW will operate in 32bit DMA addresses + * for consistent DMA mapping but if 32 bit consistent + * DMA mask fails, driver will try with 64 bit consistent + * mask provided FW is true 64bit DMA capable + * + * For older controllers(Thunderbolt and MFI based adapters)- + * driver/FW will operate in 32 bit consistent DMA addresses. + */ static int -megasas_set_dma_mask(struct pci_dev *pdev) +megasas_set_dma_mask(struct megasas_instance *instance) { - /* - * All our controllers are capable of performing 64-bit DMA - */ + u64 consistent_mask; + struct pci_dev *pdev; + u32 scratch_pad_2; + + pdev = instance->pdev; + consistent_mask = (instance->adapter_type == VENTURA_SERIES) ? + DMA_BIT_MASK(64) : DMA_BIT_MASK(32); + if (IS_DMA64) { - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) { + if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) && + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) + goto fail_set_dma_mask; + + if ((*pdev->dev.dma_mask == DMA_BIT_MASK(64)) && + (dma_set_coherent_mask(&pdev->dev, consistent_mask) && + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))) { + /* + * If 32 bit DMA mask fails, then try for 64 bit mask + * for FW capable of handling 64 bit DMA. + */ + scratch_pad_2 = readl + (&instance->reg_set->outbound_scratch_pad_2); - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) + if (!(scratch_pad_2 & MR_CAN_HANDLE_64_BIT_DMA_OFFSET)) + goto fail_set_dma_mask; + else if (dma_set_mask_and_coherent(&pdev->dev, + DMA_BIT_MASK(64))) goto fail_set_dma_mask; } - } else { - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) - goto fail_set_dma_mask; - } - /* - * Ensure that all data structures are allocated in 32-bit - * memory. - */ - if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) { - /* Try 32bit DMA mask and 32 bit Consistent dma mask */ - if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) - && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) - dev_info(&pdev->dev, "set 32bit DMA mask" - "and 32 bit consistent mask\n"); - else - goto fail_set_dma_mask; - } + } else if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) + goto fail_set_dma_mask; + + if (pdev->dev.coherent_dma_mask == DMA_BIT_MASK(32)) + instance->consistent_mask_64bit = false; + else + instance->consistent_mask_64bit = true; + + dev_info(&pdev->dev, "%s bit DMA mask and %s bit consistent mask\n", + ((*pdev->dev.dma_mask == DMA_BIT_MASK(64)) ? "64" : "32"), + (instance->consistent_mask_64bit ? "64" : "32")); return 0; fail_set_dma_mask: - return 1; + dev_err(&pdev->dev, "Failed to set DMA mask\n"); + return -1; + } /* @@ -6632,7 +6698,13 @@ megasas_resume(struct pci_dev *pdev) pci_set_master(pdev); - if (megasas_set_dma_mask(pdev)) + /* + * We expect the FW state to be READY + */ + if (megasas_transition_to_ready(instance, 0)) + goto fail_ready_state; + + if (megasas_set_dma_mask(instance)) goto fail_set_dma_mask; /* @@ -6641,12 +6713,6 @@ megasas_resume(struct pci_dev *pdev) atomic_set(&instance->fw_outstanding, 0); - /* - * We expect the FW state to be READY - */ - if (megasas_transition_to_ready(instance, 0)) - goto fail_ready_state; - /* Now re-enable MSI-X */ if (instance->msix_vectors) { irq_flags = PCI_IRQ_MSIX; @@ -6713,9 +6779,9 @@ fail_init_mfi: megasas_free_ctrl_mem(instance); scsi_host_put(host); +fail_reenable_msix: fail_set_dma_mask: fail_ready_state: -fail_reenable_msix: pci_disable_device(pdev); @@ -7013,7 +7079,8 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, struct megasas_iocpacket __user * user_ioc, struct megasas_iocpacket *ioc) { - struct megasas_sge32 *kern_sge32; + struct megasas_sge64 *kern_sge64 = NULL; + struct megasas_sge32 *kern_sge32 = NULL; struct megasas_cmd *cmd; void *kbuff_arr[MAX_IOCTL_SGE]; dma_addr_t buf_handle = 0; @@ -7053,8 +7120,14 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE); cmd->frame->hdr.context = cpu_to_le32(cmd->index); cmd->frame->hdr.pad_0 = 0; - cmd->frame->hdr.flags &= cpu_to_le16(~(MFI_FRAME_IEEE | - MFI_FRAME_SGL64 | + + cmd->frame->hdr.flags &= (~MFI_FRAME_IEEE); + + if (instance->consistent_mask_64bit) + cmd->frame->hdr.flags |= cpu_to_le16((MFI_FRAME_SGL64 | + MFI_FRAME_SENSE64)); + else + cmd->frame->hdr.flags &= cpu_to_le16(~(MFI_FRAME_SGL64 | MFI_FRAME_SENSE64)); if (cmd->frame->hdr.cmd == MFI_CMD_DCMD) @@ -7081,8 +7154,12 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, * kernel buffers in SGLs. The location of SGL is embedded in the * struct iocpacket itself. */ - kern_sge32 = (struct megasas_sge32 *) - ((unsigned long)cmd->frame + ioc->sgl_off); + if (instance->consistent_mask_64bit) + kern_sge64 = (struct megasas_sge64 *) + ((unsigned long)cmd->frame + ioc->sgl_off); + else + kern_sge32 = (struct megasas_sge32 *) + ((unsigned long)cmd->frame + ioc->sgl_off); /* * For each user buffer, create a mirror buffer and copy in @@ -7105,8 +7182,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, * We don't change the dma_coherent_mask, so * pci_alloc_consistent only returns 32bit addresses */ - kern_sge32[i].phys_addr = cpu_to_le32(buf_handle); - kern_sge32[i].length = cpu_to_le32(ioc->sgl[i].iov_len); + if (instance->consistent_mask_64bit) { + kern_sge64[i].phys_addr = cpu_to_le64(buf_handle); + kern_sge64[i].length = cpu_to_le32(ioc->sgl[i].iov_len); + } else { + kern_sge32[i].phys_addr = cpu_to_le32(buf_handle); + kern_sge32[i].length = cpu_to_le32(ioc->sgl[i].iov_len); + } /* * We created a kernel buffer corresponding to the @@ -7129,7 +7211,10 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, sense_ptr = (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off); - *sense_ptr = cpu_to_le32(sense_handle); + if (instance->consistent_mask_64bit) + *sense_ptr = cpu_to_le64(sense_handle); + else + *sense_ptr = cpu_to_le32(sense_handle); } /* @@ -7202,10 +7287,16 @@ out: for (i = 0; i < ioc->sge_count; i++) { if (kbuff_arr[i]) { - dma_free_coherent(&instance->pdev->dev, - le32_to_cpu(kern_sge32[i].length), - kbuff_arr[i], - le32_to_cpu(kern_sge32[i].phys_addr)); + if (instance->consistent_mask_64bit) + dma_free_coherent(&instance->pdev->dev, + le32_to_cpu(kern_sge64[i].length), + kbuff_arr[i], + le64_to_cpu(kern_sge64[i].phys_addr)); + else + dma_free_coherent(&instance->pdev->dev, + le32_to_cpu(kern_sge32[i].length), + kbuff_arr[i], + le32_to_cpu(kern_sge32[i].phys_addr)); kbuff_arr[i] = NULL; } } diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 745da54c11aa..ad162fed389c 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -99,7 +99,34 @@ static void megasas_free_reply_fusion(struct megasas_instance *instance); static inline void megasas_configure_queue_sizes(struct megasas_instance *instance); +/** + * megasas_check_same_4gb_region - check if allocation + * crosses same 4GB boundary or not + * @instance - adapter's soft instance + * start_addr - start address of DMA allocation + * size - size of allocation in bytes + * return - true : allocation does not cross same + * 4GB boundary + * false: allocation crosses same + * 4GB boundary + */ +static inline bool megasas_check_same_4gb_region + (struct megasas_instance *instance, dma_addr_t start_addr, size_t size) +{ + dma_addr_t end_addr; + + end_addr = start_addr + size; + if (upper_32_bits(start_addr) != upper_32_bits(end_addr)) { + dev_err(&instance->pdev->dev, + "Failed to get same 4GB boundary: start_addr: 0x%llx end_addr: 0x%llx\n", + (unsigned long long)start_addr, + (unsigned long long)end_addr); + return false; + } + + return true; +} /** * megasas_enable_intr_fusion - Enables interrupts @@ -294,17 +321,23 @@ megasas_free_cmds_fusion(struct megasas_instance *instance) struct fusion_context *fusion = instance->ctrl_context; struct megasas_cmd_fusion *cmd; - /* SG, Sense */ - for (i = 0; i < instance->max_mpt_cmds; i++) { - cmd = fusion->cmd_list[i]; - if (cmd) { - if (cmd->sg_frame) - dma_pool_free(fusion->sg_dma_pool, cmd->sg_frame, - cmd->sg_frame_phys_addr); - if (cmd->sense) - dma_pool_free(fusion->sense_dma_pool, cmd->sense, - cmd->sense_phys_addr); + if (fusion->sense) + dma_pool_free(fusion->sense_dma_pool, fusion->sense, + fusion->sense_phys_addr); + + /* SG */ + if (fusion->cmd_list) { + for (i = 0; i < instance->max_mpt_cmds; i++) { + cmd = fusion->cmd_list[i]; + if (cmd) { + if (cmd->sg_frame) + dma_pool_free(fusion->sg_dma_pool, + cmd->sg_frame, + cmd->sg_frame_phys_addr); + } + kfree(cmd); } + kfree(fusion->cmd_list); } if (fusion->sg_dma_pool) { @@ -336,13 +369,6 @@ megasas_free_cmds_fusion(struct megasas_instance *instance) dma_pool_destroy(fusion->io_request_frames_pool); fusion->io_request_frames_pool = NULL; } - - - /* cmd_list */ - for (i = 0; i < instance->max_mpt_cmds; i++) - kfree(fusion->cmd_list[i]); - - kfree(fusion->cmd_list); } /** @@ -356,10 +382,12 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance) u16 max_cmd; struct fusion_context *fusion; struct megasas_cmd_fusion *cmd; + int sense_sz; + u32 offset; fusion = instance->ctrl_context; max_cmd = instance->max_fw_cmds; - + sense_sz = instance->max_mpt_cmds * SCSI_SENSE_BUFFERSIZE; fusion->sg_dma_pool = dma_pool_create("mr_sg", &instance->pdev->dev, @@ -368,7 +396,7 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance) /* SCSI_SENSE_BUFFERSIZE = 96 bytes */ fusion->sense_dma_pool = dma_pool_create("mr_sense", &instance->pdev->dev, - SCSI_SENSE_BUFFERSIZE, 64, 0); + sense_sz, 64, 0); if (!fusion->sense_dma_pool || !fusion->sg_dma_pool) { dev_err(&instance->pdev->dev, @@ -376,6 +404,51 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance) return -ENOMEM; } + fusion->sense = dma_pool_alloc(fusion->sense_dma_pool, + GFP_KERNEL, &fusion->sense_phys_addr); + if (!fusion->sense) { + dev_err(&instance->pdev->dev, + "failed from %s %d\n", __func__, __LINE__); + return -ENOMEM; + } + + /* sense buffer, request frame and reply desc pool requires to be in + * same 4 gb region. Below function will check this. + * In case of failure, new pci pool will be created with updated + * alignment. + * Older allocation and pool will be destroyed. + * Alignment will be used such a way that next allocation if success, + * will always meet same 4gb region requirement. + * Actual requirement is not alignment, but we need start and end of + * DMA address must have same upper 32 bit address. + */ + + if (!megasas_check_same_4gb_region(instance, fusion->sense_phys_addr, + sense_sz)) { + dma_pool_free(fusion->sense_dma_pool, fusion->sense, + fusion->sense_phys_addr); + fusion->sense = NULL; + dma_pool_destroy(fusion->sense_dma_pool); + + fusion->sense_dma_pool = + dma_pool_create("mr_sense_align", &instance->pdev->dev, + sense_sz, roundup_pow_of_two(sense_sz), + 0); + if (!fusion->sense_dma_pool) { + dev_err(&instance->pdev->dev, + "Failed from %s %d\n", __func__, __LINE__); + return -ENOMEM; + } + fusion->sense = dma_pool_alloc(fusion->sense_dma_pool, + GFP_KERNEL, + &fusion->sense_phys_addr); + if (!fusion->sense) { + dev_err(&instance->pdev->dev, + "failed from %s %d\n", __func__, __LINE__); + return -ENOMEM; + } + } + /* * Allocate and attach a frame to each of the commands in cmd_list */ @@ -384,9 +457,11 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance) cmd->sg_frame = dma_pool_alloc(fusion->sg_dma_pool, GFP_KERNEL, &cmd->sg_frame_phys_addr); - cmd->sense = dma_pool_alloc(fusion->sense_dma_pool, - GFP_KERNEL, &cmd->sense_phys_addr); - if (!cmd->sg_frame || !cmd->sense) { + offset = SCSI_SENSE_BUFFERSIZE * i; + cmd->sense = (u8 *)fusion->sense + offset; + cmd->sense_phys_addr = fusion->sense_phys_addr + offset; + + if (!cmd->sg_frame) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); return -ENOMEM; @@ -396,13 +471,10 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance) /* create sense buffer for the raid 1/10 fp */ for (i = max_cmd; i < instance->max_mpt_cmds; i++) { cmd = fusion->cmd_list[i]; - cmd->sense = dma_pool_alloc(fusion->sense_dma_pool, - GFP_KERNEL, &cmd->sense_phys_addr); - if (!cmd->sense) { - dev_err(&instance->pdev->dev, - "Failed from %s %d\n", __func__, __LINE__); - return -ENOMEM; - } + offset = SCSI_SENSE_BUFFERSIZE * i; + cmd->sense = (u8 *)fusion->sense + offset; + cmd->sense_phys_addr = fusion->sense_phys_addr + offset; + } return 0; @@ -481,6 +553,40 @@ retry_alloc: } } + if (!megasas_check_same_4gb_region(instance, + fusion->io_request_frames_phys, + fusion->io_frames_alloc_sz)) { + dma_pool_free(fusion->io_request_frames_pool, + fusion->io_request_frames, + fusion->io_request_frames_phys); + fusion->io_request_frames = NULL; + dma_pool_destroy(fusion->io_request_frames_pool); + + fusion->io_request_frames_pool = + dma_pool_create("mr_ioreq_align", + &instance->pdev->dev, + fusion->io_frames_alloc_sz, + roundup_pow_of_two(fusion->io_frames_alloc_sz), + 0); + + if (!fusion->io_request_frames_pool) { + dev_err(&instance->pdev->dev, + "Failed from %s %d\n", __func__, __LINE__); + return -ENOMEM; + } + + fusion->io_request_frames = + dma_pool_alloc(fusion->io_request_frames_pool, + GFP_KERNEL, + &fusion->io_request_frames_phys); + + if (!fusion->io_request_frames) { + dev_err(&instance->pdev->dev, + "Failed from %s %d\n", __func__, __LINE__); + return -ENOMEM; + } + } + fusion->req_frames_desc = dma_alloc_coherent(&instance->pdev->dev, fusion->request_alloc_sz, @@ -521,6 +627,41 @@ megasas_alloc_reply_fusion(struct megasas_instance *instance) "Failed from %s %d\n", __func__, __LINE__); return -ENOMEM; } + + if (!megasas_check_same_4gb_region(instance, + fusion->reply_frames_desc_phys[0], + (fusion->reply_alloc_sz * count))) { + dma_pool_free(fusion->reply_frames_desc_pool, + fusion->reply_frames_desc[0], + fusion->reply_frames_desc_phys[0]); + fusion->reply_frames_desc[0] = NULL; + dma_pool_destroy(fusion->reply_frames_desc_pool); + + fusion->reply_frames_desc_pool = + dma_pool_create("mr_reply_align", + &instance->pdev->dev, + fusion->reply_alloc_sz * count, + roundup_pow_of_two(fusion->reply_alloc_sz * count), + 0); + + if (!fusion->reply_frames_desc_pool) { + dev_err(&instance->pdev->dev, + "Failed from %s %d\n", __func__, __LINE__); + return -ENOMEM; + } + + fusion->reply_frames_desc[0] = + dma_pool_alloc(fusion->reply_frames_desc_pool, + GFP_KERNEL, + &fusion->reply_frames_desc_phys[0]); + + if (!fusion->reply_frames_desc[0]) { + dev_err(&instance->pdev->dev, + "Failed from %s %d\n", __func__, __LINE__); + return -ENOMEM; + } + } + reply_desc = fusion->reply_frames_desc[0]; for (i = 0; i < fusion->reply_q_depth * count; i++, reply_desc++) reply_desc->Words = cpu_to_le64(ULLONG_MAX); @@ -539,52 +680,124 @@ megasas_alloc_reply_fusion(struct megasas_instance *instance) int megasas_alloc_rdpq_fusion(struct megasas_instance *instance) { - int i, j, count; + int i, j, k, msix_count; struct fusion_context *fusion; union MPI2_REPLY_DESCRIPTORS_UNION *reply_desc; + union MPI2_REPLY_DESCRIPTORS_UNION *rdpq_chunk_virt[RDPQ_MAX_CHUNK_COUNT]; + dma_addr_t rdpq_chunk_phys[RDPQ_MAX_CHUNK_COUNT]; + u8 dma_alloc_count, abs_index; + u32 chunk_size, array_size, offset; fusion = instance->ctrl_context; + chunk_size = fusion->reply_alloc_sz * RDPQ_MAX_INDEX_IN_ONE_CHUNK; + array_size = sizeof(struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY) * + MAX_MSIX_QUEUES_FUSION; - fusion->rdpq_virt = pci_alloc_consistent(instance->pdev, - sizeof(struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY) * MAX_MSIX_QUEUES_FUSION, - &fusion->rdpq_phys); + fusion->rdpq_virt = pci_alloc_consistent(instance->pdev, array_size, + &fusion->rdpq_phys); if (!fusion->rdpq_virt) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); return -ENOMEM; } - memset(fusion->rdpq_virt, 0, - sizeof(struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY) * MAX_MSIX_QUEUES_FUSION); - count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; + memset(fusion->rdpq_virt, 0, array_size); + msix_count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; + fusion->reply_frames_desc_pool = dma_pool_create("mr_rdpq", &instance->pdev->dev, - fusion->reply_alloc_sz, - 16, 0); - - if (!fusion->reply_frames_desc_pool) { + chunk_size, 16, 0); + fusion->reply_frames_desc_pool_align = + dma_pool_create("mr_rdpq_align", + &instance->pdev->dev, + chunk_size, + roundup_pow_of_two(chunk_size), + 0); + + if (!fusion->reply_frames_desc_pool || + !fusion->reply_frames_desc_pool_align) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); return -ENOMEM; } - for (i = 0; i < count; i++) { - fusion->reply_frames_desc[i] = - dma_pool_alloc(fusion->reply_frames_desc_pool, - GFP_KERNEL, &fusion->reply_frames_desc_phys[i]); - if (!fusion->reply_frames_desc[i]) { +/* + * For INVADER_SERIES each set of 8 reply queues(0-7, 8-15, ..) and + * VENTURA_SERIES each set of 16 reply queues(0-15, 16-31, ..) should be + * within 4GB boundary and also reply queues in a set must have same + * upper 32-bits in their memory address. so here driver is allocating the + * DMA'able memory for reply queues according. Driver uses limitation of + * VENTURA_SERIES to manage INVADER_SERIES as well. + */ + dma_alloc_count = DIV_ROUND_UP(msix_count, RDPQ_MAX_INDEX_IN_ONE_CHUNK); + + for (i = 0; i < dma_alloc_count; i++) { + rdpq_chunk_virt[i] = + dma_pool_alloc(fusion->reply_frames_desc_pool, + GFP_KERNEL, &rdpq_chunk_phys[i]); + if (!rdpq_chunk_virt[i]) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); return -ENOMEM; } + /* reply desc pool requires to be in same 4 gb region. + * Below function will check this. + * In case of failure, new pci pool will be created with updated + * alignment. + * For RDPQ buffers, driver always allocate two separate pci pool. + * Alignment will be used such a way that next allocation if + * success, will always meet same 4gb region requirement. + * rdpq_tracker keep track of each buffer's physical, + * virtual address and pci pool descriptor. It will help driver + * while freeing the resources. + * + */ + if (!megasas_check_same_4gb_region(instance, rdpq_chunk_phys[i], + chunk_size)) { + dma_pool_free(fusion->reply_frames_desc_pool, + rdpq_chunk_virt[i], + rdpq_chunk_phys[i]); + + rdpq_chunk_virt[i] = + dma_pool_alloc(fusion->reply_frames_desc_pool_align, + GFP_KERNEL, &rdpq_chunk_phys[i]); + if (!rdpq_chunk_virt[i]) { + dev_err(&instance->pdev->dev, + "Failed from %s %d\n", + __func__, __LINE__); + return -ENOMEM; + } + fusion->rdpq_tracker[i].dma_pool_ptr = + fusion->reply_frames_desc_pool_align; + } else { + fusion->rdpq_tracker[i].dma_pool_ptr = + fusion->reply_frames_desc_pool; + } - fusion->rdpq_virt[i].RDPQBaseAddress = - cpu_to_le64(fusion->reply_frames_desc_phys[i]); + fusion->rdpq_tracker[i].pool_entry_phys = rdpq_chunk_phys[i]; + fusion->rdpq_tracker[i].pool_entry_virt = rdpq_chunk_virt[i]; + } - reply_desc = fusion->reply_frames_desc[i]; - for (j = 0; j < fusion->reply_q_depth; j++, reply_desc++) - reply_desc->Words = cpu_to_le64(ULLONG_MAX); + for (k = 0; k < dma_alloc_count; k++) { + for (i = 0; i < RDPQ_MAX_INDEX_IN_ONE_CHUNK; i++) { + abs_index = (k * RDPQ_MAX_INDEX_IN_ONE_CHUNK) + i; + + if (abs_index == msix_count) + break; + offset = fusion->reply_alloc_sz * i; + fusion->rdpq_virt[abs_index].RDPQBaseAddress = + cpu_to_le64(rdpq_chunk_phys[k] + offset); + fusion->reply_frames_desc_phys[abs_index] = + rdpq_chunk_phys[k] + offset; + fusion->reply_frames_desc[abs_index] = + (union MPI2_REPLY_DESCRIPTORS_UNION *)((u8 *)rdpq_chunk_virt[k] + offset); + + reply_desc = fusion->reply_frames_desc[abs_index]; + for (j = 0; j < fusion->reply_q_depth; j++, reply_desc++) + reply_desc->Words = ULLONG_MAX; + } } + return 0; } @@ -596,15 +809,18 @@ megasas_free_rdpq_fusion(struct megasas_instance *instance) { fusion = instance->ctrl_context; - for (i = 0; i < MAX_MSIX_QUEUES_FUSION; i++) { - if (fusion->reply_frames_desc[i]) - dma_pool_free(fusion->reply_frames_desc_pool, - fusion->reply_frames_desc[i], - fusion->reply_frames_desc_phys[i]); + for (i = 0; i < RDPQ_MAX_CHUNK_COUNT; i++) { + if (fusion->rdpq_tracker[i].pool_entry_virt) + dma_pool_free(fusion->rdpq_tracker[i].dma_pool_ptr, + fusion->rdpq_tracker[i].pool_entry_virt, + fusion->rdpq_tracker[i].pool_entry_phys); + } if (fusion->reply_frames_desc_pool) dma_pool_destroy(fusion->reply_frames_desc_pool); + if (fusion->reply_frames_desc_pool_align) + dma_pool_destroy(fusion->reply_frames_desc_pool_align); if (fusion->rdpq_virt) pci_free_consistent(instance->pdev, @@ -771,6 +987,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) u32 scratch_pad_2; unsigned long flags; struct timeval tv; + bool cur_fw_64bit_dma_capable; fusion = instance->ctrl_context; @@ -784,6 +1001,19 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) cur_rdpq_mode = (scratch_pad_2 & MR_RDPQ_MODE_OFFSET) ? 1 : 0; + if (instance->adapter_type == INVADER_SERIES) { + cur_fw_64bit_dma_capable = + (scratch_pad_2 & MR_CAN_HANDLE_64_BIT_DMA_OFFSET) ? true : false; + + if (instance->consistent_mask_64bit && !cur_fw_64bit_dma_capable) { + dev_err(&instance->pdev->dev, "Driver was operating on 64bit " + "DMA mask, but upcoming FW does not support 64bit DMA mask\n"); + megaraid_sas_kill_hba(instance); + ret = 1; + goto fail_fw_init; + } + } + if (instance->is_rdpq && !cur_rdpq_mode) { dev_err(&instance->pdev->dev, "Firmware downgrade *NOT SUPPORTED*" " from RDPQ mode to non RDPQ mode\n"); @@ -811,6 +1041,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) IOCInitMessage->MsgFlags = instance->is_rdpq ? MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE : 0; IOCInitMessage->SystemRequestFrameBaseAddress = cpu_to_le64(fusion->io_request_frames_phys); + IOCInitMessage->SenseBufferAddressHigh = cpu_to_le32(upper_32_bits(fusion->sense_phys_addr)); IOCInitMessage->HostMSIxVectors = instance->msix_vectors; IOCInitMessage->HostPageSize = MR_DEFAULT_NVME_PAGE_SHIFT; @@ -852,6 +1083,10 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) drv_ops->mfi_capabilities.support_qd_throttling = 1; drv_ops->mfi_capabilities.support_pd_map_target_id = 1; + + if (instance->consistent_mask_64bit) + drv_ops->mfi_capabilities.support_64bit_mode = 1; + /* Convert capability to LE32 */ cpu_to_le32s((u32 *)&init_frame->driver_operations.mfi_capabilities); @@ -861,8 +1096,8 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) strlen(sys_info) > 64 ? 64 : strlen(sys_info)); instance->system_info_buf->systemIdLength = strlen(sys_info) > 64 ? 64 : strlen(sys_info); - init_frame->system_info_lo = instance->system_info_h; - init_frame->system_info_hi = 0; + init_frame->system_info_lo = cpu_to_le32(lower_32_bits(instance->system_info_h)); + init_frame->system_info_hi = cpu_to_le32(upper_32_bits(instance->system_info_h)); } init_frame->queue_info_new_phys_addr_hi = @@ -953,6 +1188,15 @@ megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend) { memset(pd_sync, 0, pd_seq_map_sz); memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE); + + if (pend) { + dcmd->mbox.b[0] = MEGASAS_DCMD_MBOX_PEND_FLAG; + dcmd->flags = MFI_FRAME_DIR_WRITE; + instance->jbod_seq_cmd = cmd; + } else { + dcmd->flags = MFI_FRAME_DIR_READ; + } + dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = 0xFF; dcmd->sge_count = 1; @@ -960,19 +1204,14 @@ megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend) { dcmd->pad_0 = 0; dcmd->data_xfer_len = cpu_to_le32(pd_seq_map_sz); dcmd->opcode = cpu_to_le32(MR_DCMD_SYSTEM_PD_MAP_GET_INFO); - dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(pd_seq_h); - dcmd->sgl.sge32[0].length = cpu_to_le32(pd_seq_map_sz); + + megasas_set_dma_settings(instance, dcmd, pd_seq_h, pd_seq_map_sz); if (pend) { - dcmd->mbox.b[0] = MEGASAS_DCMD_MBOX_PEND_FLAG; - dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_WRITE); - instance->jbod_seq_cmd = cmd; instance->instancet->issue_dcmd(instance, cmd); return 0; } - dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ); - /* Below code is only for non pended DCMD */ if (!instance->mask_interrupts) ret = megasas_issue_blocked_cmd(instance, cmd, @@ -1055,13 +1294,13 @@ megasas_get_ld_map_info(struct megasas_instance *instance) dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = 0xFF; dcmd->sge_count = 1; - dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ); + dcmd->flags = MFI_FRAME_DIR_READ; dcmd->timeout = 0; dcmd->pad_0 = 0; dcmd->data_xfer_len = cpu_to_le32(size_map_info); dcmd->opcode = cpu_to_le32(MR_DCMD_LD_MAP_GET_INFO); - dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h); - dcmd->sgl.sge32[0].length = cpu_to_le32(size_map_info); + + megasas_set_dma_settings(instance, dcmd, ci_h, size_map_info); if (!instance->mask_interrupts) ret = megasas_issue_blocked_cmd(instance, cmd, @@ -1159,15 +1398,15 @@ megasas_sync_map_info(struct megasas_instance *instance) dcmd->cmd = MFI_CMD_DCMD; dcmd->cmd_status = 0xFF; dcmd->sge_count = 1; - dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_WRITE); + dcmd->flags = MFI_FRAME_DIR_WRITE; dcmd->timeout = 0; dcmd->pad_0 = 0; dcmd->data_xfer_len = cpu_to_le32(size_map_info); dcmd->mbox.b[0] = num_lds; dcmd->mbox.b[1] = MEGASAS_DCMD_MBOX_PEND_FLAG; dcmd->opcode = cpu_to_le32(MR_DCMD_LD_MAP_GET_INFO); - dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h); - dcmd->sgl.sge32[0].length = cpu_to_le32(size_map_info); + + megasas_set_dma_settings(instance, dcmd, ci_h, size_map_info); instance->map_update_cmd = cmd; @@ -2872,7 +3111,8 @@ megasas_build_io_fusion(struct megasas_instance *instance, io_request->SGLOffset0 = offsetof(struct MPI2_RAID_SCSI_IO_REQUEST, SGL) / 4; - io_request->SenseBufferLowAddress = cpu_to_le32(cmd->sense_phys_addr); + io_request->SenseBufferLowAddress = + cpu_to_le32(lower_32_bits(cmd->sense_phys_addr)); io_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE; cmd->scmd = scp; @@ -2913,7 +3153,7 @@ void megasas_prepare_secondRaid1_IO(struct megasas_instance *instance, (fusion->max_sge_in_main_msg * sizeof(union MPI2_SGE_IO_UNION))); /*sense buffer is different for r1 command*/ r1_cmd->io_request->SenseBufferLowAddress = - cpu_to_le32(r1_cmd->sense_phys_addr); + cpu_to_le32(lower_32_bits(r1_cmd->sense_phys_addr)); r1_cmd->scmd = cmd->scmd; req_desc2 = megasas_get_request_descriptor(instance, (r1_cmd->index - 1)); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index 4e229d72dfb0..1814d79cb98d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -51,6 +51,8 @@ #define HOST_DIAG_RESET_ADAPTER 0x4 #define MEGASAS_FUSION_MAX_RESET_TRIES 3 #define MAX_MSIX_QUEUES_FUSION 128 +#define RDPQ_MAX_INDEX_IN_ONE_CHUNK 16 +#define RDPQ_MAX_CHUNK_COUNT (MAX_MSIX_QUEUES_FUSION / RDPQ_MAX_INDEX_IN_ONE_CHUNK) /* Invader defines */ #define MPI2_TYPE_CUDA 0x2 @@ -1266,6 +1268,12 @@ struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY { u32 Reserved2; }; +struct rdpq_alloc_detail { + struct dma_pool *dma_pool_ptr; + dma_addr_t pool_entry_phys; + union MPI2_REPLY_DESCRIPTORS_UNION *pool_entry_virt; +}; + struct fusion_context { struct megasas_cmd_fusion **cmd_list; dma_addr_t req_frames_desc_phys; @@ -1278,9 +1286,14 @@ struct fusion_context { struct dma_pool *sg_dma_pool; struct dma_pool *sense_dma_pool; + u8 *sense; + dma_addr_t sense_phys_addr; + dma_addr_t reply_frames_desc_phys[MAX_MSIX_QUEUES_FUSION]; union MPI2_REPLY_DESCRIPTORS_UNION *reply_frames_desc[MAX_MSIX_QUEUES_FUSION]; + struct rdpq_alloc_detail rdpq_tracker[RDPQ_MAX_CHUNK_COUNT]; struct dma_pool *reply_frames_desc_pool; + struct dma_pool *reply_frames_desc_pool_align; u16 last_reply_idx[MAX_MSIX_QUEUES_FUSION]; -- cgit v1.2.3 From 193ad909eed321b8f1aba4a402e5b6ea0f0e1975 Mon Sep 17 00:00:00 2001 From: Shivasharan S Date: Thu, 19 Oct 2017 02:49:06 -0700 Subject: scsi: megaraid_sas: driver version upgrade Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index b34fc68c14c9..f5a36ccb8606 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -35,8 +35,8 @@ /* * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "07.702.06.00-rc1" -#define MEGASAS_RELDATE "June 21, 2017" +#define MEGASAS_VERSION "07.703.05.00-rc1" +#define MEGASAS_RELDATE "October 5, 2017" /* * Device IDs -- cgit v1.2.3 From ca6958b4da8b7fd9f6ac3bf94def9cfb8a1d6c25 Mon Sep 17 00:00:00 2001 From: Yisheng Xie Date: Wed, 25 Oct 2017 17:57:07 +0800 Subject: scsi: megaraid: Remove redundant code in megasas_alloc_cmds megasas_alloc_cmds is to alloc cmd_list of instance instead of fusion, and fusion is useless in this function. Just remove it. Signed-off-by: Yisheng Xie Acked-by: Sumit Saxena Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_base.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index f14d7cb05280..8c19debbd560 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4079,9 +4079,7 @@ int megasas_alloc_cmds(struct megasas_instance *instance) int j; u16 max_cmd; struct megasas_cmd *cmd; - struct fusion_context *fusion; - fusion = instance->ctrl_context; max_cmd = instance->max_mfi_cmds; /* -- cgit v1.2.3 From b5c5d0adf75cd4c0fb037ba2ca0ed80ae9ba3d05 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 2 Nov 2017 10:18:10 +0000 Subject: scsi: megaraid_sas: fix spelling mistake: "thershold" -> "threshold" Trivial fix to spelling mistake in dev_info message Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/scsi/megaraid') diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index ad162fed389c..569663bab771 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -283,7 +283,7 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c (instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF) - MEGASAS_FUSION_IOCTL_CMDS; dev_info(&instance->pdev->dev, - "Current firmware supports maximum commands: %d\t LDIO thershold: %d\n", + "Current firmware supports maximum commands: %d\t LDIO threshold: %d\n", cur_max_fw_cmds, ldio_threshold); if (fw_boot_context == OCR_CONTEXT) { -- cgit v1.2.3