[PATCH 03/39] megaraid_sas: raid 1 fast path code optimize
No functional change. Code refactor. Remove function megasas_fpio_to_ldio as we never require to convert fpio to ldio because of frame unavailability. Grab extra frame of raid 1 write fast path before it creates first frame as Fast Path. Removed is_raid_1_fp_write flag as raid 1 write fast path command is decided using r1_alt_dev_handle only. Move resetting megasas_cmd_fusion fields at common function megasas_return_cmd_fusion. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas_fp.c | 14 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 348 +--- drivers/scsi/megaraid/megaraid_sas_fusion.h | 3 +- 3 files changed, 117 insertions(+), 248 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index f1384b0..24258af 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -1338,20 +1338,8 @@ MR_BuildRaidContext(struct megasas_instance *instance, ref_in_start_stripe, io_info, pRAID_Context, map); /* If IO on an invalid Pd, then FP is not possible.*/ - if (io_info->devHandle == cpu_to_le16(MR_PD_INVALID)) + if (io_info->devHandle == MR_DEVHANDLE_INVALID) io_info->fpOkForIo = FALSE; - /* if FP possible, set the SLUD bit in -* regLockFlags for ventura -*/ - else if ((instance->is_ventura) && (!isRead) && - (raid->writeMode == MR_RL_WRITE_BACK_MODE) && - (raid->capability.fp_cache_bypass_capable)) - ((struct RAID_CONTEXT_G35 *) pRAID_Context)->routing_flags.bits.sld = 1; - /* set raid 1/10 fast path write capable bit in io_info */ - if (io_info->fpOkForIo && - (io_info->r1_alt_dev_handle != MR_PD_INVALID) && - (raid->level == 1) && !isRead) - io_info->is_raid_1_fp_write = 1; return retval; } else if (isRead) { uint stripIdx; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 514c306..de55dce 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -181,7 +181,9 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance, struct megasas_cmd_fusion *cmd) { cmd->scmd = NULL; - memset(cmd->io_request, 0, sizeof(struct MPI2_RAID_SCSI_IO_REQUEST)); + memset(cmd->io_request, 0, MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE); + cmd->r1_alt_dev_handle = MR_DEVHANDLE_INVALID; + cmd->cmd_completed = false; } /** @@ -701,7 +703,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance) memset(cmd->io_request, 0, sizeof(struct MPI2_RAID_SCSI_IO_REQUEST)); cmd->io_request_phys_addr = io_req_base_phys + offset; - cmd->is_raid_1_fp_write = 0; + cmd->r1_alt_dev_handle = MR_DEVHANDLE_INVALID; } if (megasas_create_sg_sense_fusion(instance)) @@ -1984,7 +1986,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, io_info.ldStartBlock = ((u64)start_lba_hi << 32) | start_lba_lo; io_info.numBlocks = datalength; io_info.ldTgtId = device_id; - io_info.r1_alt_dev_handle = MR_PD_INVALID; + io_info.r1_alt_dev_handle = MR_DEVHANDLE_INVALID; scsi_buff_len = scsi_bufflen(scp); io_request->DataLength = cpu_to_le32(scsi_buff_len); @@ -2025,7 +2027,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, io_info.isRead && io_info.ra_capable) fp_possible = false; - if (io_info.r1_alt_dev_handle != MR_PD_INVALID) { + if (io_info.r1_alt_dev_handle != MR_DEVHANDLE_INVALID) { mrdev_priv = scp->device->hostdata; if (atomic_inc_return(&instance->fw_outstanding) > @@ -2090,9 +2092,10 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, } else scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG; - cmd->is_raid_1_fp_write = io_info.is_raid_1_fp_write; - if (io_info.is_raid_1_fp_write) + if (instance->is_ventura) cmd->r1_alt_dev_handle = io_info.r1_alt_dev_handle; + else + cmd->r1_alt_dev_handle = MR_DEVHANDLE_INVALID; if ((raidLUN[0] == 1) && (local_ma
[PATCH 04/39] megaraid_sas: 32 bit descriptor fire cmd optimization
No functional change. Code refactor. megasas_fire_cmd_fusion can always use 32 bit descriptor write for ventura. No need to pass extra flag. Only IOC INIT required 64 bit Descriptor write. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 65 +++-- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index de55dce..09dcc9b 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -188,40 +188,35 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance, /** * megasas_fire_cmd_fusion - Sends command to the FW + * @instance: Adapter soft state + * @req_desc: 32bit or 64bit Request descriptor + * + * Perform PCI Write. Ventura supports 32 bit Descriptor. + * Prior to Ventura (12G) MR controller supports 64 bit Descriptor. */ + static void megasas_fire_cmd_fusion(struct megasas_instance *instance, - union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc, bool is_32bit) + union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc) { - struct megasas_register_set __iomem *regs = instance->reg_set; - unsigned long flags; - - if (is_32bit) + if (instance->is_ventura) writel(le32_to_cpu(req_desc->u.low), - &(regs)->inbound_single_queue_port); - else if (instance->is_ventura) { + &instance->reg_set->inbound_single_queue_port); + else { +#if defined(writeq) && defined(CONFIG_64BIT) + u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) | + le32_to_cpu(req_desc->u.low)); + + writeq(req_data, &instance->reg_set->inbound_low_queue_port); +#else + unsigned long flags; spin_lock_irqsave(&instance->hba_lock, flags); writel(le32_to_cpu(req_desc->u.low), - &(regs)->inbound_low_queue_port); + &instance->reg_set->inbound_low_queue_port); writel(le32_to_cpu(req_desc->u.high), - &(regs)->inbound_high_queue_port); + &instance->reg_set->inbound_high_queue_port); mmiowb(); spin_unlock_irqrestore(&instance->hba_lock, flags); - } else { -#if defined(writeq) && defined(CONFIG_64BIT) - u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) | - le32_to_cpu(req_desc->u.low)); - - writeq(req_data, &instance->reg_set->inbound_low_queue_port); -#else - - spin_lock_irqsave(&instance->hba_lock, flags); - writel(le32_to_cpu(req_desc->u.low), - &instance->reg_set->inbound_low_queue_port); - writel(le32_to_cpu(req_desc->u.high), - &instance->reg_set->inbound_high_queue_port); - mmiowb(); - spin_unlock_irqrestore(&instance->hba_lock, flags); #endif } } @@ -771,6 +766,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) const char *sys_info; MFI_CAPABILITIES *drv_ops; u32 scratch_pad_2; + unsigned long flags; fusion = instance->ctrl_context; @@ -897,7 +893,14 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) break; } - megasas_fire_cmd_fusion(instance, &req_desc, false); + /* For Ventura also IOC INIT required 64 bit Descriptor write. */ + spin_lock_irqsave(&instance->hba_lock, flags); + writel(le32_to_cpu(req_desc.u.low), + &instance->reg_set->inbound_low_queue_port); + writel(le32_to_cpu(req_desc.u.high), + &instance->reg_set->inbound_high_queue_port); + mmiowb(); + spin_unlock_irqrestore(&instance->hba_lock, flags); wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS); @@ -2577,11 +2580,10 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, * Issue the command to the FW */ - megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura); + megasas_fire_cmd_fusion(instance, req_desc); if (r1_cmd) - megasas_fire_cmd_fusion(instance, r1_cmd->request_desc, - instance->is_ventura); + megasas_fire_cmd_fusion(instance, r1_cmd->request_desc); return 0; @@ -3000,7 +3002,7 @@ megasas_issue_dcmd_fusion(struct megasas_instance *instance, return DCMD_NOT_FIRED; } - megasas_fire_cmd_fusion(instance, req_desc, inst
[PATCH 00/39] megaraid_sas: Updates for scsi-next
Shivasharan S (39): Revert "scsi: megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth" megaraid_sas: cpu select rework. megaraid_sas: raid 1 fast path code optimize megaraid_sas: 32 bit descriptor fire cmd optimization megaraid_sas: Refactor MEGASAS_IS_LOGICAL macro using sdev megaraid_sas: RAID map is accessed for SYS PDs when use_seqnum_jbod_fp is not set megaraid_sas: Use DID_REQUEUE megaraid_sas: megasas_get_request_descriptor always return valid desc megaraid_sas: NVME Interface detection and prop settings megaraid_sas: NVME interface target prop added megaraid_sas: NVME interface target prop added megaraid_sas: raid 1 write performance for large io megaraid_sas : set residual bytes count during IO compeltion megaraid_sas: enhance debug logs in OCR context megaraid_sas: add print in device removal path megaraid_sas: reduce size of fusion_context and use vmalloc if kmalloc fails megaraid_sas: In validate raid map, raid capability is not converted to cpu format for all lds megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map access megaraid_sas: Big endian RDPQ mode fix megaraid_sas: big endian support changes megaraid_sas: avoid unaligned access in ioctl path megaraid_sas: latest controller OCR capability from FW before sending shutdown DCMD megaraid_sas: set pd_after_lb from MR_BuildRaidContext and initialize pDevHandle to MR_DEVHANDLE_INVALID megaraid_sas: Change max_cmd from u32 to u16 in all functions megaraid_sas: update can_queue only if the new value is less megaraid_sas: max_fw_cmds are decremented twice, remove duplicate megaraid_sas: megasas_return_cmd does not memset IO frame to zero megaraid_sas: Remove unused pd_index from megasas_build_ld_nonrw_fusion megaraid_sas: Do not set fp_possible if TM capable for non-RW syspdIO, change fp_possible to bool megaraid_sas: During OCR, if get_ctrl_info fails do not continue with OCR megaraid_sas: Change build_mpt_mfi_pass_thru to return void megaraid_sas: Bail out the driver load if ld_list_query fails megaraid_sas: call flush_scheduled_work during controller shutdown/detach megaraid_sas: Use synchronize_irq to wait for IRQs to complete megaraid_sas: Increase internal command pool megaraid_sas: Cleanup VD_EXT_DEBUG and SPAN_DEBUG related debug prints megaraid_sas: Indentation and smatch warning fixes megaraid_sas: Change RAID_1_10_RMW_CMDS to RAID_1_PEER_CMDS and set value to 2 megaraid_sas: driver version upgrade drivers/scsi/megaraid/megaraid_sas.h| 80 +- drivers/scsi/megaraid/megaraid_sas_base.c | 533 +++ drivers/scsi/megaraid/megaraid_sas_fp.c | 427 ++--- drivers/scsi/megaraid/megaraid_sas_fusion.c | 1352 --- drivers/scsi/megaraid/megaraid_sas_fusion.h | 144 ++- 5 files changed, 1422 insertions(+), 1114 deletions(-) -- 2.8.3
[PATCH 02/39] megaraid_sas: cpu select rework.
No functional change. Code refactor. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 175 1 file changed, 100 insertions(+), 75 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 54728b3..514c306 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1819,6 +1819,73 @@ static void megasas_stream_detect(struct megasas_instance *instance, } /** + * megasas_set_raidflag_cpu_affinity - This function sets the cpu + * affinity (cpu of the controller) and raid_flags in the raid context + * based on IO type. + * + * @praid_context: IO RAID context + * @raid: LD raid map + * @fp_possible: Is fast path possible? + * @is_read: Is read IO? + * + */ +static void +megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context, + struct MR_LD_RAID *raid, bool fp_possible, + u8 is_read) +{ + u8 cpu_sel = MR_RAID_CTX_CPUSEL_0; + struct RAID_CONTEXT_G35 *rctx_g35; + + rctx_g35 = &praid_context->raid_context_g35; + if (fp_possible) { + if (is_read) { + if ((raid->cpuAffinity.pdRead.cpu0) && + (raid->cpuAffinity.pdRead.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.pdRead.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + } else { + if ((raid->cpuAffinity.pdWrite.cpu0) && + (raid->cpuAffinity.pdWrite.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.pdWrite.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + /* Fast path cache by pass capable R0/R1 VD */ + if ((raid->level <= 1) && + (raid->capability.fp_cache_bypass_capable)) { + rctx_g35->routing_flags.bits.sld = 1; + rctx_g35->raid_flags = + (MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS + << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT); + } + } + } else { + if (is_read) { + if ((raid->cpuAffinity.ldRead.cpu0) && + (raid->cpuAffinity.ldRead.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.ldRead.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + } else { + if ((raid->cpuAffinity.ldWrite.cpu0) && + (raid->cpuAffinity.ldWrite.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.ldWrite.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + + if (rctx_g35->stream_detected && + (raid->level == 5) && + (raid->writeMode == MR_RL_WRITE_THROUGH_MODE) && + (cpu_sel == MR_RAID_CTX_CPUSEL_FCFS)) + cpu_sel = MR_RAID_CTX_CPUSEL_0; + } + } + + rctx_g35->routing_flags.bits.cpu_sel = cpu_sel; +} + +/** * megasas_build_ldio_fusion - Prepares IOs to devices * @instance: Adapter soft state * @scp: SCSI command @@ -1832,8 +1899,10 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, struct scsi_cmnd *scp, struct megasas_cmd_fusion *cmd) { - u8 fp_possible; - u32 start_lba_lo, start_lba_hi, device_id, datalength = 0, ld; + bool fp_possible; + u16 ld; + u32 start_lba_lo, start_lba_hi, device_id, datalength = 0; + u32 scsi_buff_len; struct MPI2_RAID_SCSI_IO_REQUEST *io_request; union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; struct IO_REQUEST_INFO io_info; @@ -1842,7 +1911,8 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, u8 *raidLUN; unsigned long spinlock_flags; union RAID_CONTEXT_UNION *praid_context; - struct MR_LD_RAID *raid; + struct MR_LD_RAID *raid = NULL; + struct MR_PRIV_DEVICE *mrdev_priv; device_id = MEGASAS_DEV_INDEX(scp); @@ -1858,7 +1928,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, start_lba_lo = 0; start_lba_h
[PATCH 01/39] Revert "scsi: megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth"
This reverts commit "3e5eadb1a881" ("scsi: megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth") This patch was aimed to increase performance of R1 Write operation for large IO size. Since this method used timer approach, it turn on/off fast path did not work as expected. Patch 0011 describes new algorithm and performance number. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas.h| 8 - drivers/scsi/megaraid/megaraid_sas_base.c | 48 - drivers/scsi/megaraid/megaraid_sas_fp.c | 7 - drivers/scsi/megaraid/megaraid_sas_fusion.c | 16 -- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 5 files changed, 7 insertions(+), 74 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index ba9fbb7..f5c4742 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1477,8 +1477,6 @@ enum FW_BOOT_CONTEXT { #define MFI_1068_FW_HANDSHAKE_OFFSET 0x64 #define MFI_1068_FW_READY 0x -#define MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL HZ - #define MR_MAX_REPLY_QUEUES_OFFSET 0X001F #define MR_MAX_REPLY_QUEUES_EXT_OFFSET 0X003FC000 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT14 @@ -2154,10 +2152,6 @@ struct megasas_instance { atomic_t ldio_outstanding; atomic_t fw_reset_no_pci_access; - atomic64_t bytes_wrote; /* used for raid1 fast path enable or disable */ - atomic_t r1_write_fp_capable; - - struct megasas_instance_template *instancet; struct tasklet_struct isr_tasklet; struct work_struct work_init; @@ -2199,7 +2193,6 @@ struct megasas_instance { long reset_flags; struct mutex reset_mutex; struct timer_list sriov_heartbeat_timer; - struct timer_list r1_fp_hold_timer; char skip_heartbeat_timer_del; u8 requestorId; char PlasmaFW111; @@ -2216,7 +2209,6 @@ struct megasas_instance { bool is_ventura; bool msix_combined; u16 max_raid_mapsize; - u64 pci_threshold_bandwidth; /* used to control the fp writes */ }; 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 70891a7..3ed876a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1940,9 +1940,6 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance) } /* Complete outstanding ioctls when adapter is killed */ megasas_complete_outstanding_ioctls(instance); - if (instance->is_ventura) - del_timer_sync(&instance->r1_fp_hold_timer); - } /** @@ -2441,24 +2438,6 @@ void megasas_sriov_heartbeat_handler(unsigned long instance_addr) } } -/*Handler for disabling/enabling raid 1 fast paths*/ -void megasas_change_r1_fp_status(unsigned long instance_addr) -{ - struct megasas_instance *instance = - (struct megasas_instance *)instance_addr; - if (atomic64_read(&instance->bytes_wrote) >= - instance->pci_threshold_bandwidth) { - - atomic64_set(&instance->bytes_wrote, 0); - atomic_set(&instance->r1_write_fp_capable, 0); - } else { - atomic64_set(&instance->bytes_wrote, 0); - atomic_set(&instance->r1_write_fp_capable, 1); - } - mod_timer(&instance->r1_fp_hold_timer, -jiffies + MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); -} - /** * megasas_wait_for_outstanding - Wait for all outstanding cmds * @instance: Adapter soft state @@ -5386,17 +5365,6 @@ static int megasas_init_fw(struct megasas_instance *instance) instance->skip_heartbeat_timer_del = 1; } - if (instance->is_ventura) { - atomic64_set(&instance->bytes_wrote, 0); - atomic_set(&instance->r1_write_fp_capable, 1); - megasas_start_timer(instance, - &instance->r1_fp_hold_timer, - megasas_change_r1_fp_status, - MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); - dev_info(&instance->pdev->dev, "starting the raid 1 fp timer with interval %d\n", - MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); - } - return 0; fail_get_ld_pd_list: @@ -6187,9 +6155,6 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) if (instance->requestorId && !instance->skip_heartbeat_timer_del) del_timer_sync(&instance->srio
[PATCH 06/39] megaraid_sas: RAID map is accessed for SYS PDs when use_seqnum_jbod_fp is not set
Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas_base.c | 25 ++--- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 6ca49ef..67a205a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1756,28 +1756,31 @@ void megasas_update_sdev_properties(struct scsi_device *sdev) fusion = instance->ctrl_context; mr_device_priv_data = sdev->hostdata; - if (!fusion) + if (!fusion || !mr_device_priv_data) return; - if (!MEGASAS_IS_LOGICAL(sdev) && - instance->use_seqnum_jbod_fp) { - pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + - sdev->id; - pd_sync = (void *)fusion->pd_seq_sync - [(instance->pd_seq_map_id - 1) & 1]; - mr_device_priv_data->is_tm_capable = - pd_sync->seq[pd_index].capability.tmCapable; - } else { + if (MEGASAS_IS_LOGICAL(sdev)) { device_id = ((sdev->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id; local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; ld = MR_TargetIdToLdGet(device_id, local_map_ptr); + if (ld >= instance->fw_supported_vd_count) + return; raid = MR_LdRaidGet(ld, local_map_ptr); if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER) - blk_queue_update_dma_alignment(sdev->request_queue, 0x7); + blk_queue_update_dma_alignment(sdev->request_queue, + 0x7); + mr_device_priv_data->is_tm_capable = raid->capability.tmCapable; + } else if (instance->use_seqnum_jbod_fp) { + pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + + sdev->id; + pd_sync = (void *)fusion->pd_seq_sync + [(instance->pd_seq_map_id - 1) & 1]; + mr_device_priv_data->is_tm_capable = + pd_sync->seq[pd_index].capability.tmCapable; } } -- 2.8.3
[PATCH 05/39] megaraid_sas: Refactor MEGASAS_IS_LOGICAL macro using sdev
Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas.h| 4 ++-- drivers/scsi/megaraid/megaraid_sas_base.c | 20 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 12 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index f5c4742..dff877f 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2301,8 +2301,8 @@ struct megasas_instance_template { struct megasas_cmd *cmd); }; -#define MEGASAS_IS_LOGICAL(scp) \ - ((scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1) +#define MEGASAS_IS_LOGICAL(sdev) \ + ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1) #define MEGASAS_DEV_INDEX(scp) \ (((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \ diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 3ed876a..6ca49ef 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1279,7 +1279,7 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, u16 flags = 0; struct megasas_pthru_frame *pthru; - is_logical = MEGASAS_IS_LOGICAL(scp); + is_logical = MEGASAS_IS_LOGICAL(scp->device); device_id = MEGASAS_DEV_INDEX(scp); pthru = (struct megasas_pthru_frame *)cmd->frame; @@ -1519,11 +1519,11 @@ inline int megasas_cmd_type(struct scsi_cmnd *cmd) case WRITE_6: case READ_16: case WRITE_16: - ret = (MEGASAS_IS_LOGICAL(cmd)) ? + ret = (MEGASAS_IS_LOGICAL(cmd->device)) ? READ_WRITE_LDIO : READ_WRITE_SYSPDIO; break; default: - ret = (MEGASAS_IS_LOGICAL(cmd)) ? + ret = (MEGASAS_IS_LOGICAL(cmd->device)) ? NON_READ_WRITE_LDIO : NON_READ_WRITE_SYSPDIO; } return ret; @@ -1699,15 +1699,16 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) scmd->result = 0; - if (MEGASAS_IS_LOGICAL(scmd) && + if (MEGASAS_IS_LOGICAL(scmd->device) && (scmd->device->id >= instance->fw_supported_vd_count || scmd->device->lun)) { scmd->result = DID_BAD_TARGET << 16; goto out_done; } - if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) && MEGASAS_IS_LOGICAL(scmd) && - (!instance->fw_sync_cache_support)) { + if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) && + MEGASAS_IS_LOGICAL(scmd->device) && + (!instance->fw_sync_cache_support)) { scmd->result = DID_OK << 16; goto out_done; } @@ -1758,7 +1759,7 @@ void megasas_update_sdev_properties(struct scsi_device *sdev) if (!fusion) return; - if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && + if (!MEGASAS_IS_LOGICAL(sdev) && instance->use_seqnum_jbod_fp) { pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id; @@ -1826,8 +1827,7 @@ static int megasas_slave_configure(struct scsi_device *sdev) instance = megasas_lookup_instance(sdev->host->host_no); if (instance->pd_list_not_supported) { - if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && - sdev->type == TYPE_DISK) { + if (!MEGASAS_IS_LOGICAL(sdev) && sdev->type == TYPE_DISK) { pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id; if (instance->pd_list[pd_index].driveState != @@ -1854,7 +1854,7 @@ static int megasas_slave_alloc(struct scsi_device *sdev) struct MR_PRIV_DEVICE *mr_device_priv_data; instance = megasas_lookup_instance(sdev->host->host_no); - if (sdev->channel < MEGASAS_MAX_PD_CHANNELS) { + if (!MEGASAS_IS_LOGICAL(sdev)) { /* * Open the OS scan to the SYSTEM PD */ diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 09dcc9b..cdbfe50 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3580,13 +3580,13 @@ static u16 megasas_get_tm_devhandle(struct scsi_device *sdev) instance = (struct megasas_instance *)sdev->host->hostdata;
[PATCH 08/39] megaraid_sas: megasas_get_request_descriptor always return valid desc
No functional change. Code clean up. Removing error code which is not valid scenario. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas_base.c | 4 +--- drivers/scsi/megaraid/megaraid_sas_fusion.c | 33 + 2 files changed, 6 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 80fcdf5..138d028 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5602,9 +5602,7 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num, /* * Issue the aen registration frame */ - instance->instancet->issue_dcmd(instance, cmd); - - return 0; + return instance->instancet->issue_dcmd(instance, cmd); } /** diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index d25268a..1ec482e 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -974,8 +974,7 @@ megasas_sync_pd_seq_num(struct megasas_instance *instance, bool 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; + return instance->instancet->issue_dcmd(instance, cmd); } dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ); @@ -1115,7 +1114,7 @@ megasas_get_map_info(struct megasas_instance *instance) int megasas_sync_map_info(struct megasas_instance *instance) { - int ret = 0, i; + int i; struct megasas_cmd *cmd; struct megasas_dcmd_frame *dcmd; u32 size_sync_info, num_lds; @@ -1182,9 +1181,7 @@ megasas_sync_map_info(struct megasas_instance *instance) instance->map_update_cmd = cmd; - instance->instancet->issue_dcmd(instance, cmd); - - return ret; + return instance->instancet->issue_dcmd(instance, cmd); } /* @@ -2438,18 +2435,12 @@ megasas_build_io_fusion(struct megasas_instance *instance, return 0; } -union MEGASAS_REQUEST_DESCRIPTOR_UNION * +static union MEGASAS_REQUEST_DESCRIPTOR_UNION * megasas_get_request_descriptor(struct megasas_instance *instance, u16 index) { u8 *p; struct fusion_context *fusion; - if (index >= instance->max_mpt_cmds) { - dev_err(&instance->pdev->dev, "Invalid SMID (0x%x)request for " - "descriptor for scsi%d\n", index, - instance->host->host_no); - return NULL; - } fusion = instance->ctrl_context; p = fusion->req_frames_desc + sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) * index; @@ -2959,7 +2950,7 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance, union MEGASAS_REQUEST_DESCRIPTOR_UNION * build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) { - union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; + union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc = NULL; u16 index; if (build_mpt_mfi_pass_thru(instance, cmd)) { @@ -2971,9 +2962,6 @@ build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) req_desc = megasas_get_request_descriptor(instance, index - 1); - if (!req_desc) - return NULL; - req_desc->Words = 0; req_desc->SCSIIO.RequestFlags = (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); @@ -2996,11 +2984,6 @@ megasas_issue_dcmd_fusion(struct megasas_instance *instance, union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; req_desc = build_mpt_cmd(instance, cmd); - if (!req_desc) { - dev_info(&instance->pdev->dev, "Failed from %s %d\n", - __func__, __LINE__); - return DCMD_NOT_FIRED; - } megasas_fire_cmd_fusion(instance, req_desc); return DCMD_SUCCESS; @@ -3437,12 +3420,6 @@ megasas_issue_tm(struct megasas_instance *instance, u16 device_handle, req_desc = megasas_get_request_descriptor(instance, (cmd_fusion->index - 1)); - if (!req_desc) { - dev_err(&instance->pdev->dev, "Failed from %s %d\n", - __func__, __LINE__); - megasas_return_cmd(instance, cmd_mfi); - return -ENOMEM; - } cmd_fusion->request_desc = req_desc; req_desc->Words = 0; -- 2.8.3
[PATCH 09/39] megaraid_sas: NVME Interface detection and prop settings
New functionality Adding detection logic for NVME device attached behind Ventura controller. Driver set HostPageSize in IOC_INIT frame to inform about page size for NVME devices. Firmware reports NVME page size to the driver. PD INFO DCMD provide new interface type NVME_PD. Driver set property of NVME device. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas.h| 23 ++-- drivers/scsi/megaraid/megaraid_sas_base.c | 170 drivers/scsi/megaraid/megaraid_sas_fusion.c | 6 +- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 4 files changed, 142 insertions(+), 59 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index dff877f..c5c55fe 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -733,7 +733,6 @@ struct megasas_pd_list { u16 tid; u8 driveType; u8 driveState; - u8 interface; } __packed; /* @@ -1530,8 +1529,8 @@ struct megasas_register_set { u32 outbound_scratch_pad ; /*00B0h*/ u32 outbound_scratch_pad_2; /*00B4h*/ u32 outbound_scratch_pad_3; /*00B8h*/ + u32 outbound_scratch_pad_4; /*00BCh*/ - u32 reserved_4; /*00BCh*/ u32 inbound_low_queue_port ;/*00C0h*/ @@ -1864,6 +1863,7 @@ union megasas_frame { struct MR_PRIV_DEVICE { bool is_tm_capable; bool tm_busy; + u8 interface_type; }; struct megasas_cmd; @@ -2055,17 +2055,24 @@ struct MR_DRV_SYSTEM_INFO { }; enum MR_PD_TYPE { -UNKNOWN_DRIVE = 0, -PARALLEL_SCSI = 1, -SAS_PD = 2, -SATA_PD = 3, -FC_PD = 4, + UNKNOWN_DRIVE = 0, + PARALLEL_SCSI = 1, + SAS_PD = 2, + SATA_PD = 3, + FC_PD = 4, + NVME_PD = 5, }; /* JBOD Queue depth definitions */ #define MEGASAS_SATA_QD32 #define MEGASAS_SAS_QD 64 #define MEGASAS_DEFAULT_PD_QD 64 +#define MEGASAS_NVME_QD32 + +#define MR_DEFAULT_NVME_PAGE_SIZE 4096 +#define MR_DEFAULT_NVME_PAGE_SHIFT 12 +#define MR_DEFAULT_NVME_MDTS_KB128 +#define MR_NVME_PAGE_SIZE_MASK 0x00FF struct megasas_instance { @@ -2209,6 +2216,7 @@ struct megasas_instance { bool is_ventura; bool msix_combined; u16 max_raid_mapsize; + u32 nvme_page_size; }; struct MR_LD_VF_MAP { u32 size; @@ -2428,6 +2436,7 @@ int megasas_get_ctrl_info(struct megasas_instance *instance); /* PD sequence */ int megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend); +void megasas_set_dynamic_target_properties(struct scsi_device *sdev); int megasas_set_crash_dump_params(struct megasas_instance *instance, u8 crash_buf_state); void megasas_free_host_crash_buffer(struct megasas_instance *instance); diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 138d028..7b47109 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -116,8 +116,8 @@ static int megasas_ld_list_query(struct megasas_instance *instance, static int megasas_issue_init_mfi(struct megasas_instance *instance); static int megasas_register_aen(struct megasas_instance *instance, u32 seq_num, u32 class_locale_word); -static int -megasas_get_pd_info(struct megasas_instance *instance, u16 device_id); +static void megasas_get_pd_info(struct megasas_instance *instance, + struct scsi_device *sdev); /* * PCI ID table for all supported controllers */ @@ -1735,16 +1735,21 @@ static struct megasas_instance *megasas_lookup_instance(u16 host_no) } /* -* megasas_update_sdev_properties - Update sdev structure based on controller's FW capabilities +* megasas_set_dynamic_target_properties - +* Device property set by driver may not be static and it is required to be +* updated after OCR +* +* set tm_capable. +* set dma alignment (only for eedp protection enable vd). * * @sdev: OS provided scsi device * * Returns void */ -void megasas_update_sdev_properties(struct scsi_device *sdev) +void megasas_set_dynamic_target_properties(struct scsi_device *sdev) { - u16 pd_index = 0; - u32 device_id, ld; + u16 pd_index = 0, ld; + u32 device_id; struct megasas_instance *instance; struct fusion_context *fusion; struct MR_PRIV_DEVICE *mr_device_priv_data; @@ -1769,57 +1774,102 @@ void megasas_update_sdev_properties(struct scsi_device *sdev) raid = MR_LdRaidGet(ld, local_map_ptr); if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER) - blk_queue_update_dma_alignm
[PATCH 11/39] megaraid_sas: NVME interface target prop added
This patch depends on patch 0008. This patch fetch true values of NVME property from FW using New DCMD interface MR_DCMD_DEV_GET_TARGET_PROP Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas.h| 10 +- drivers/scsi/megaraid/megaraid_sas_fp.c | 55 +++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 316 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.h | 14 +- 4 files changed, 350 insertions(+), 45 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index f3b3a84..fb3ee17 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2172,6 +2172,11 @@ struct megasas_instance { atomic_t fw_outstanding; atomic_t ldio_outstanding; atomic_t fw_reset_no_pci_access; + atomic_t ieee_sgl; + atomic_t prp_sgl; + atomic_t sge_holes_type1; + atomic_t sge_holes_type2; + atomic_t sge_holes_type3; struct megasas_instance_template *instancet; struct tasklet_struct isr_tasklet; @@ -2443,7 +2448,9 @@ __le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map); u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map); __le16 get_updated_dev_handle(struct megasas_instance *instance, - struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *in_info); + struct LD_LOAD_BALANCE_INFO *lbInfo, + struct IO_REQUEST_INFO *in_info, + struct MR_DRV_RAID_MAP_ALL *drv_map); void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map, struct LD_LOAD_BALANCE_INFO *lbInfo); int megasas_get_ctrl_info(struct megasas_instance *instance); @@ -2472,4 +2479,5 @@ void megasas_update_sdev_properties(struct scsi_device *sdev); int megasas_reset_fusion(struct Scsi_Host *shost, int reason); int megasas_task_abort_fusion(struct scsi_cmnd *scmd); int megasas_reset_target_fusion(struct scsi_cmnd *scmd); +u32 mega_mod64(u64 dividend, u32 divisor); #endif /*LSI_MEGARAID_SAS_H */ diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 24258af..c3ef82d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -155,6 +155,11 @@ __le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map) return map->raidMap.devHndlInfo[pd].curDevHdl; } +static u8 MR_PdInterfaceTypeGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map) +{ + return map->raidMap.devHndlInfo[pd].interfaceType; +} + u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map) { return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId); @@ -929,6 +934,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, u8 retval = TRUE; u64 *pdBlock = &io_info->pdBlock; __le16 *pDevHandle = &io_info->devHandle; + u8 *pPdInterface = &io_info->pd_interface; u32 logArm, rowMod, armQ, arm; struct fusion_context *fusion; @@ -960,15 +966,18 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, if (pd != MR_PD_INVALID) { *pDevHandle = MR_PdDevHandleGet(pd, map); + *pPdInterface = MR_PdInterfaceTypeGet(pd, map); /* get second pd also for raid 1/10 fast path writes*/ - if (raid->level == 1) { + if (instance->is_ventura && + (raid->level == 1) && + !io_info->isRead) { r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map); if (r1_alt_pd != MR_PD_INVALID) io_info->r1_alt_dev_handle = MR_PdDevHandleGet(r1_alt_pd, map); } } else { - *pDevHandle = cpu_to_le16(MR_PD_INVALID); + *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); if ((raid->level >= 5) && ((fusion->adapter_type == THUNDERBOLT_SERIES) || ((fusion->adapter_type == INVADER_SERIES) && @@ -977,8 +986,10 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, else if (raid->level == 1) { physArm = physArm + 1; pd = MR_ArPdGet(arRef, physArm, map); - if (pd != MR_PD_INVALID) + if (pd != MR_PD_INVALID) { *pDevHandle = MR_PdDevHandleGet(pd, map); + *pPdInterface = MR_PdInterfaceTypeGet(pd, map); + } } } @@ -1025,6 +1036,7 @@ u8 MR_GetPhyParams(struct megasas_instance *inst
[PATCH 10/39] megaraid_sas: NVME interface target prop added
This patch depends on patch 0008. This patch fetch true values of NVME property from FW using New DCMD interface MR_DCMD_DEV_GET_TARGET_PROP Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas.h| 14 +++ drivers/scsi/megaraid/megaraid_sas_base.c | 144 +++- drivers/scsi/megaraid/megaraid_sas_fusion.h | 1 + 3 files changed, 155 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index c5c55fe..f3b3a84 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -695,6 +695,18 @@ struct MR_PD_INFO { u8 reserved1[512-428]; } __packed; +/* + * Definition of structure used to expose attributes of VD or JBOD + * (this structure is to be filled by firmware when MR_DCMD_DRV_GET_TARGET_PROP + * is fired by driver) + */ +struct MR_TARGET_PROPERTIES { + u32max_io_size_kb; + u32device_qdepth; + u32sector_size; + u8 reserved[500]; +} __packed; + /* * defines the physical drive address structure */ @@ -2090,6 +2102,8 @@ struct megasas_instance { dma_addr_t hb_host_mem_h; struct MR_PD_INFO *pd_info; dma_addr_t pd_info_h; + struct MR_TARGET_PROPERTIES *tgt_prop; + dma_addr_t tgt_prop_h; __le32 *reply_queue; dma_addr_t reply_queue_h; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 7b47109..3e74f0f 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -118,6 +118,8 @@ static int megasas_register_aen(struct megasas_instance *instance, u32 seq_num, u32 class_locale_word); static void megasas_get_pd_info(struct megasas_instance *instance, struct scsi_device *sdev); +static int megasas_get_target_prop(struct megasas_instance *instance, + struct scsi_device *sdev); /* * PCI ID table for all supported controllers */ @@ -1831,14 +1833,16 @@ megasas_set_nvme_device_properties(struct scsi_device *sdev, u32 max_io_size) * set nvme device properties. see - megasas_set_nvme_device_properties * * @sdev: scsi device - * + * @is_target_prop true, if fw provided target properties. */ -static void megasas_set_static_target_properties(struct scsi_device *sdev) +static void megasas_set_static_target_properties(struct scsi_device *sdev, +bool is_target_prop) { u16 target_index = 0; u8 interface_type; u32 device_qd = MEGASAS_DEFAULT_CMD_PER_LUN; u32 max_io_size_kb = MR_DEFAULT_NVME_MDTS_KB; + u32 tgt_device_qd; struct megasas_instance *instance; struct MR_PRIV_DEVICE *mr_device_priv_data; @@ -1865,6 +1869,18 @@ static void megasas_set_static_target_properties(struct scsi_device *sdev) break; } + if (is_target_prop) { + tgt_device_qd = le32_to_cpu(instance->tgt_prop->device_qdepth); + if (tgt_device_qd && + (tgt_device_qd <= instance->host->can_queue)) + device_qd = tgt_device_qd; + + /* max_io_size_kb will be set to non zero for +* nvme based vd and syspd. +*/ + max_io_size_kb = le32_to_cpu(instance->tgt_prop->max_io_size_kb); + } + if (instance->nvme_page_size && max_io_size_kb) megasas_set_nvme_device_properties(sdev, (max_io_size_kb << 10)); @@ -1877,6 +1893,8 @@ static int megasas_slave_configure(struct scsi_device *sdev) { u16 pd_index = 0; struct megasas_instance *instance; + int ret_target_prop = DCMD_FAILED; + bool is_target_prop = false; instance = megasas_lookup_instance(sdev->host->host_no); if (instance->pd_list_not_supported) { @@ -1894,7 +1912,14 @@ static int megasas_slave_configure(struct scsi_device *sdev) if ((instance->pd_info) && !MEGASAS_IS_LOGICAL(sdev)) megasas_get_pd_info(instance, sdev); - megasas_set_static_target_properties(sdev); + /* Some ventura firmware may not have instance->nvme_page_size set. +* Do not send MR_DCMD_DRV_GET_TARGET_PROP +*/ + if ((instance->tgt_prop) && (instance->nvme_page_size)) + ret_target_prop = megasas_get_target_prop(instance, sdev); + + is_target_prop = (ret_target_prop == DCMD_SUCCESS) ? true : false; + megasas_set_static_target_properties(sdev, is_target_prop); mutex_unlock(&instance->hba_mutex); @@ -5677,6 +5702,98 @@ megasas_register_aen(struct megasas_inst
[PATCH 07/39] megaraid_sas: Use DID_REQUEUE
Moving to use DID_REQUEUE return type for reliable unconditional retries. Driver wants unconditional re-queue, so replace DID_RESET with DID_REQUEUE Discussed below - https://www.spinics.net/lists/linux-scsi/msg102848.html Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas_base.c | 4 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 67a205a..80fcdf5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1668,7 +1668,7 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) /* Check for an mpio path and adjust behavior */ if (atomic_read(&instance->adprecovery) == MEGASAS_ADPRESET_SM_INFAULT) { if (megasas_check_mpio_paths(instance, scmd) == - (DID_RESET << 16)) { + (DID_REQUEUE << 16)) { return SCSI_MLQUEUE_HOST_BUSY; } else { scmd->result = DID_NO_CONNECT << 16; @@ -2492,7 +2492,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) struct megasas_cmd, list); list_del_init(&reset_cmd->list); if (reset_cmd->scmd) { - reset_cmd->scmd->result = DID_RESET << 16; + reset_cmd->scmd->result = DID_REQUEUE << 16; dev_notice(&instance->pdev->dev, "%d:%p reset [%02x]\n", reset_index, reset_cmd, reset_cmd->scmd->cmnd[0]); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index cdbfe50..d25268a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3769,7 +3769,7 @@ int megasas_check_mpio_paths(struct megasas_instance *instance, struct scsi_cmnd *scmd) { struct megasas_instance *peer_instance = NULL; - int retval = (DID_RESET << 16); + int retval = (DID_REQUEUE << 16); if (instance->peerIsPresent) { peer_instance = megasas_get_peer_instance(instance); -- 2.8.3
[PATCH 12/39] megaraid_sas: raid 1 write performance for large io
Avoid Host side PCI bandwidth bottleneck and hint FW to do Write buffering using RaidFlag MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT. Once IO is landed in FW with MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT, it will do single DMA from host and buffer the Write operation. On back end, FW will DMA same buffer to the Mirror and Data Arm. This will improve large block IO performance which bottleneck due to Host side PCI bandwidth limitation. Consistent ~4000MB T.P for 256K Block size is expected performance numbers. IOPS for small Block size should be on par with Disk performance. (E.g 42 SAS Disk in JBOD mode gives 3700MB T.P. Same Drive used in R1 WT mode, should give ~1800MB T.P) Using this patch 24 R1 VDs (HDD) gives below performance for Sequential Write. Without this patch, we cannot reach above 3200MB (Throughput is in MB. ) Block Size 50% 256K and 50% 4K 100% 256K 4K 31002030 8K 31402740 16K31403140 32K34003240 64K35003700 128K 38703870 256K 39203920 Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas.h| 5 + drivers/scsi/megaraid/megaraid_sas_fusion.c | 32 +++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index fb3ee17..6e7cb0b 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1409,6 +1409,8 @@ struct megasas_ctrl_info { #define SCAN_VD_CHANNEL0x2 #define MEGASAS_KDUMP_QUEUE_DEPTH 100 +#define MR_LARGE_IO_MIN_SIZE (32 * 1024) +#define MR_R1_LDIO_PIGGYBACK_DEFAULT 4 enum MR_SCSI_CMD_TYPE { READ_WRITE_LDIO = 0, @@ -1875,6 +1877,7 @@ union megasas_frame { struct MR_PRIV_DEVICE { bool is_tm_capable; bool tm_busy; + atomic_t r1_ldio_hint; u8 interface_type; }; struct megasas_cmd; @@ -2235,6 +2238,8 @@ struct megasas_instance { bool is_ventura; bool msix_combined; u16 max_raid_mapsize; + /* preffered count to send as LDIO irrspective of FP capable.*/ + u8 r1_ldio_hint_default; u32 nvme_page_size; }; struct MR_LD_VF_MAP { diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 80bfb11..83b8482 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1380,6 +1380,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) } instance->flag_ieee = 1; + instance->r1_ldio_hint_default = MR_R1_LDIO_PIGGYBACK_DEFAULT; fusion->fast_path_io = 0; fusion->drv_map_pages = get_order(fusion->drv_map_sz); @@ -2107,7 +2108,7 @@ static void megasas_stream_detect(struct megasas_instance *instance, static void megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context, struct MR_LD_RAID *raid, bool fp_possible, - u8 is_read) + u8 is_read, u32 scsi_buff_len) { u8 cpu_sel = MR_RAID_CTX_CPUSEL_0; struct RAID_CONTEXT_G35 *rctx_g35; @@ -2158,6 +2159,17 @@ megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context, } rctx_g35->routing_flags.bits.cpu_sel = cpu_sel; + + /* Always give priority to MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT +* vs MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS. +* IO Subtype is not bitmap. +*/ + if ((raid->level == 1) && (!is_read)) { + if (scsi_buff_len > MR_LARGE_IO_MIN_SIZE) + praid_context->raid_context_g35.raid_flags = + (MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT + << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT); + } } /** @@ -2300,6 +2312,14 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, io_info.isRead && io_info.ra_capable) fp_possible = false; + /* FP for Optimal raid level 1. +* All large RAID-1 writes (> 32 KiB, both WT and WB modes) +* are built by the driver as LD I/Os. +* All small RAID-1 WT writes (<= 32 KiB) are built as FP I/Os +* (there is never a reason to process these as buffered writes) +* All small RAID-1 WB writes (<= 32 KiB) are built as FP I/Os +* with the SLD bit asserted. +*/ if (io_info.r1_alt_dev_handle != MR_DEV
[PATCH 13/39] megaraid_sas : set residual bytes count during IO compeltion
Fixing issue of not setting residual bytes correctly. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 83b8482..75c4ad1 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1442,6 +1442,7 @@ map_cmd_status(struct fusion_context *fusion, struct scsi_cmnd *scmd, u8 status, u8 ext_status, u32 data_length, u8 *sense) { + int resid; switch (status) { @@ -1464,6 +1465,15 @@ map_cmd_status(struct fusion_context *fusion, SCSI_SENSE_BUFFERSIZE); scmd->result |= DRIVER_SENSE << 24; } + + /* +* If the IO request is partially completed, then MR FW will +* update "io_request->DataLength" field with actual number of +* bytes transferred.Driver will set residual bytes count in +* SCSI command structure. +*/ + resid = (scsi_bufflen(scmd) - data_length); + scsi_set_resid(scmd, resid); break; case MFI_STAT_LD_OFFLINE: -- 2.8.3
[PATCH 22/39] megaraid_sas: latest controller OCR capability from FW before sending shutdown DCMD
Fetch the latest controller OCR capability from FW before sending MR_DCMD_CTRL_SHUTDOWN When application sends a shutdown DCMD (MR_DCMD_CTRL_SHUTDOWN), driver will fetch latest controller information from firmware. This is to ensure that driver always has latest OCR capability of controller before sending the DCMD. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas_base.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 907b2bf..ac88ad6 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6895,6 +6895,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, MFI_FRAME_SGL64 | MFI_FRAME_SENSE64)); + if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_SHUTDOWN) { + if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) { + megasas_return_cmd(instance, cmd); + return -1; + } + } + if (cmd->frame->dcmd.opcode == MR_DRIVER_SET_APP_CRASHDUMP_MODE) { error = megasas_set_crash_dump_params_ioctl(cmd); megasas_return_cmd(instance, cmd); -- 2.8.3
[PATCH 27/39] megaraid_sas: megasas_return_cmd does not memset IO frame to zero
Memset the IO frame to zero after release. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas.h | 1 + drivers/scsi/megaraid/megaraid_sas_base.c | 10 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index ec5f003..59fe39d 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2238,6 +2238,7 @@ struct megasas_instance { u8 is_rdpq; bool dev_handle; bool fw_sync_cache_support; + u32 mfi_frame_size; bool is_ventura; bool msix_combined; u16 max_raid_mapsize; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index e435c2b..2d72460 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -268,6 +268,8 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) cmd->scmd = NULL; cmd->frame_count = 0; cmd->flags = 0; + memset(cmd->frame, 0, instance->mfi_frame_size); + cmd->frame->io.context = cpu_to_le32(cmd->index); if (!fusion && reset_devices) cmd->frame->hdr.cmd = MFI_CMD_INVALID; list_add(&cmd->list, (&instance->cmd_pool)->next); @@ -3886,7 +3888,6 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) int i; u16 max_cmd; u32 sge_sz; - u32 total_sz; u32 frame_count; struct megasas_cmd *cmd; @@ -3914,12 +3915,13 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) * Total 192 byte (3 MFI frame of 64 byte) */ frame_count = instance->ctrl_context ? (3 + 1) : (15 + 1); - total_sz = MEGAMFI_FRAME_SIZE * frame_count; + instance->mfi_frame_size = MEGAMFI_FRAME_SIZE * frame_count; /* * Use DMA pool facility provided by PCI layer */ instance->frame_dma_pool = pci_pool_create("megasas frame pool", - instance->pdev, total_sz, 256, 0); + instance->pdev, instance->mfi_frame_size, + 256, 0); if (!instance->frame_dma_pool) { dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup frame pool\n"); @@ -3963,7 +3965,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) return -ENOMEM; } - memset(cmd->frame, 0, total_sz); + 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) -- 2.8.3
[PATCH 24/39] megaraid_sas: Change max_cmd from u32 to u16 in all functions
Since maximum supported FW commands are all defined as u16, change all local variables referring to max_cmd from u32 to u16. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas_base.c | 10 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index ac88ad6..e435c2b 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1546,7 +1546,7 @@ megasas_dump_pending_frames(struct megasas_instance *instance) struct megasas_io_frame *ldio; struct megasas_pthru_frame *pthru; u32 sgcount; - u32 max_cmd = instance->max_fw_cmds; + u16 max_cmd = instance->max_fw_cmds; dev_err(&instance->pdev->dev, "[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no); dev_err(&instance->pdev->dev, "[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding)); @@ -3464,7 +3464,7 @@ megasas_internal_reset_defer_cmds(struct megasas_instance *instance) { struct megasas_cmd *cmd; int i; - u32 max_cmd = instance->max_fw_cmds; + u16 max_cmd = instance->max_fw_cmds; u32 defer_index; unsigned long flags; @@ -3840,7 +3840,7 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr) static void megasas_teardown_frame_pool(struct megasas_instance *instance) { int i; - u32 max_cmd = instance->max_mfi_cmds; + u16 max_cmd = instance->max_mfi_cmds; struct megasas_cmd *cmd; if (!instance->frame_dma_pool) @@ -3884,7 +3884,7 @@ static void megasas_teardown_frame_pool(struct megasas_instance *instance) static int megasas_create_frame_pool(struct megasas_instance *instance) { int i; - u32 max_cmd; + u16 max_cmd; u32 sge_sz; u32 total_sz; u32 frame_count; @@ -4018,7 +4018,7 @@ int megasas_alloc_cmds(struct megasas_instance *instance) { int i; int j; - u32 max_cmd; + u16 max_cmd; struct megasas_cmd *cmd; struct fusion_context *fusion; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index cf3e2f8..22965b6 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -367,7 +367,7 @@ megasas_free_cmds_fusion(struct megasas_instance *instance) static int megasas_create_sg_sense_fusion(struct megasas_instance *instance) { int i; - u32 max_cmd; + u16 max_cmd; struct fusion_context *fusion; struct megasas_cmd_fusion *cmd; @@ -1271,7 +1271,8 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) { struct megasas_register_set __iomem *reg_set; struct fusion_context *fusion; - u32 max_cmd, scratch_pad_2; + u16 max_cmd; + u32 scratch_pad_2; int i = 0, count; fusion = instance->ctrl_context; -- 2.8.3
[PATCH 18/39] megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map access
If MR_TargetIdToLdGet return >= 0xFF, it is invalid entry. Consider that entry as invalid and do not access raid map for further operation. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas.h| 2 +- drivers/scsi/megaraid/megaraid_sas_fp.c | 5 +++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 25 ++--- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index f023e23..ec5f003 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2448,7 +2448,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, struct IO_REQUEST_INFO *io_info, struct RAID_CONTEXT *pRAID_Context, struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN); -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map); +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map); struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL *map); u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map); u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map); diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index a0b0e68..9d5d485 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -165,7 +165,7 @@ u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map) return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId); } -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map) +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map) { return map->raidMap.ldTgtIdToLd[ldTgtId]; } @@ -1151,7 +1151,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, { struct fusion_context *fusion; struct MR_LD_RAID *raid; - u32 ld, stripSize, stripe_mask; + u32 stripSize, stripe_mask; u64 endLba, endStrip, endRow, start_row, start_strip; u64 regStart; u32 regSize; @@ -1163,6 +1163,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, u8 retval = 0; u8 startlba_span = SPAN_INVALID; u64 *pdBlock = &io_info->pdBlock; + u16 ld; ldStartBlock = io_info->ldStartBlock; numBlocks = io_info->numBlocks; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 2f523f2..3d4d4b8 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1120,7 +1120,8 @@ megasas_sync_map_info(struct megasas_instance *instance) int i; struct megasas_cmd *cmd; struct megasas_dcmd_frame *dcmd; - u32 size_sync_info, num_lds; + u16 num_lds; + u32 size_sync_info; struct fusion_context *fusion; struct MR_LD_TARGET_SYNC *ci = NULL; struct MR_DRV_RAID_MAP_ALL *map; @@ -1867,7 +1868,7 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len, struct MR_DRV_RAID_MAP_ALL *local_map_ptr, u32 ref_tag) { struct MR_LD_RAID *raid; - u32 ld; + u16 ld; u64 start_blk = io_info->pdBlock; u8 *cdb = io_request->CDB.CDB32; u32 num_blocks = io_info->numBlocks; @@ -2300,10 +2301,11 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; ld = MR_TargetIdToLdGet(device_id, local_map_ptr); - raid = MR_LdRaidGet(ld, local_map_ptr); - if ((MR_TargetIdToLdGet(device_id, local_map_ptr) >= - instance->fw_supported_vd_count) || (!fusion->fast_path_io)) { + if (ld < instance->fw_supported_vd_count) + raid = MR_LdRaidGet(ld, local_map_ptr); + + if (!raid || (!fusion->fast_path_io)) { io_request->RaidContext.raid_context.reg_lock_flags = 0; fp_possible = false; } else { @@ -2475,12 +2477,12 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, { u32 device_id; struct MPI2_RAID_SCSI_IO_REQUEST *io_request; - u16 pd_index = 0; + u16 pd_index = 0, ld; struct MR_DRV_RAID_MAP_ALL *local_map_ptr; struct fusion_context *fusion = instance->ctrl_context; u8 span, physArm; __le16 devHandle; - u32 ld, arRef, pd; + u32 arRef, pd; struct MR_LD_RAID *raid; struct RAID_CONTEXT*pRAID_Context; u8 fp_possible = 1; @@ -2503,10 +2505,11 @@ static void megasas_build_ld_no
[PATCH 15/39] megaraid_sas: add print in device removal path
Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas_base.c | 19 +++ 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index d386f69..de01e36 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -7378,6 +7378,13 @@ megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t coun static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUSR, megasas_sysfs_show_dbg_lvl, megasas_sysfs_set_dbg_lvl); +static inline void megasas_remove_scsi_device(struct scsi_device *sdev) +{ + sdev_printk(KERN_INFO, sdev, "SCSI device is removed\n"); + scsi_remove_device(sdev); + scsi_device_put(sdev); +} + static void megasas_aen_polling(struct work_struct *work) { @@ -7482,10 +7489,8 @@ megasas_aen_polling(struct work_struct *work) else scsi_device_put(sdev1); } else { - if (sdev1) { - scsi_remove_device(sdev1); - scsi_device_put(sdev1); - } + if (sdev1) + megasas_remove_scsi_device(sdev1); } } } @@ -7502,10 +7507,8 @@ megasas_aen_polling(struct work_struct *work) else scsi_device_put(sdev1); } else { - if (sdev1) { - scsi_remove_device(sdev1); - scsi_device_put(sdev1); - } + if (sdev1) + megasas_remove_scsi_device(sdev1); } } } -- 2.8.3
[PATCH 25/39] megaraid_sas: update can_queue only if the new value is less
Minor Optimization: No need to update HBA can_queue value if the current max FW commands is equal to earlier value. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 22965b6..2bfdf6b 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -259,7 +259,7 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c if (fw_boot_context == OCR_CONTEXT) { cur_max_fw_cmds = cur_max_fw_cmds - 1; - if (cur_max_fw_cmds <= instance->max_fw_cmds) { + if (cur_max_fw_cmds < instance->max_fw_cmds) { instance->cur_can_queue = cur_max_fw_cmds - (MEGASAS_FUSION_INTERNAL_CMDS + MEGASAS_FUSION_IOCTL_CMDS); -- 2.8.3
[PATCH 29/39] megaraid_sas: Do not set fp_possible if TM capable for non-RW syspdIO, change fp_possible to bool
FIX - firmware wants non-RW SYS PD IOs to avoid FastPath for better tracking and other functionalities if the device is task management capable. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 7f53505..d49f6bd 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2563,7 +2563,8 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, */ static void megasas_build_syspd_fusion(struct megasas_instance *instance, - struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd, u8 fp_possible) + struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd, + bool fp_possible) { u32 device_id; struct MPI2_RAID_SCSI_IO_REQUEST *io_request; @@ -2684,6 +2685,8 @@ megasas_build_io_fusion(struct megasas_instance *instance, int sge_count; u8 cmd_type; struct MPI2_RAID_SCSI_IO_REQUEST *io_request = cmd->io_request; + struct MR_PRIV_DEVICE *mr_device_priv_data; + mr_device_priv_data = scp->device->hostdata; /* Zero out some fields so they don't get reused */ memset(io_request->LUN, 0x0, 8); @@ -2712,12 +2715,14 @@ megasas_build_io_fusion(struct megasas_instance *instance, megasas_build_ld_nonrw_fusion(instance, scp, cmd); break; case READ_WRITE_SYSPDIO: + megasas_build_syspd_fusion(instance, scp, cmd, true); + break; case NON_READ_WRITE_SYSPDIO: - if (instance->secure_jbod_support && - (cmd_type == NON_READ_WRITE_SYSPDIO)) - megasas_build_syspd_fusion(instance, scp, cmd, 0); + if (instance->secure_jbod_support || + mr_device_priv_data->is_tm_capable) + megasas_build_syspd_fusion(instance, scp, cmd, false); else - megasas_build_syspd_fusion(instance, scp, cmd, 1); + megasas_build_syspd_fusion(instance, scp, cmd, true); break; default: break; -- 2.8.3
[PATCH 21/39] megaraid_sas: avoid unaligned access in ioctl path
Fix kernel warning for accessing unaligned memory access in driver. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas_base.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index c38b9c3..907b2bf 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -7002,7 +7003,8 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw + ioc->sense_off); - if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)), + if (copy_to_user((void __user *)((unsigned long) +get_unaligned((unsigned long *)sense_ptr)), sense, ioc->sense_len)) { dev_err(&instance->pdev->dev, "Failed to copy out to user " "sense data\n"); -- 2.8.3
[PATCH 32/39] megaraid_sas: Bail out the driver load if ld_list_query fails
Error handling: Bail out the driver load if key FW cmds (LD_LIST) are not return successful. Clean up error handling in megasas_init_fw. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas_base.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 2d72460..04ef0a0 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5349,7 +5349,7 @@ static int megasas_init_fw(struct megasas_instance *instance) (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list))); if (megasas_get_pd_list(instance) < 0) { dev_err(&instance->pdev->dev, "failed to get PD list\n"); - goto fail_get_pd_list; + goto fail_get_ld_pd_list; } memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); @@ -5385,7 +5385,7 @@ static int megasas_init_fw(struct megasas_instance *instance) if (megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) - megasas_get_ld_list(instance); + goto fail_get_ld_pd_list; /* * Compute the max allowed sectors per IO: The controller info has two @@ -5504,8 +5504,6 @@ static int megasas_init_fw(struct megasas_instance *instance) fail_get_ld_pd_list: instance->instancet->disable_intr(instance); -fail_get_pd_list: - instance->instancet->disable_intr(instance); fail_init_adapter: megasas_destroy_irqs(instance); fail_setup_irqs: @@ -5517,9 +5515,11 @@ static int megasas_init_fw(struct megasas_instance *instance) instance->ctrl_info = NULL; iounmap(instance->reg_set); - fail_ioremap: +fail_ioremap: pci_release_selected_regions(instance->pdev, 1<bar); + dev_err(&instance->pdev->dev, "Failed from %s %d\n", + __func__, __LINE__); return -EINVAL; } -- 2.8.3
[PATCH 30/39] megaraid_sas: During OCR, if get_ctrl_info fails do not continue with OCR
Error handling: If controller reset is not able to recover, kill HBA and quit immediately. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index d49f6bd..9f3cbaa 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -4281,6 +4281,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) __func__, __LINE__); megaraid_sas_kill_hba(instance); retval = FAILED; + goto out; } /* Reset load balance info */ if (fusion->load_balance_info) -- 2.8.3
[PATCH 26/39] megaraid_sas: max_fw_cmds are decremented twice, remove duplicate
Fix to account for the reply_q_sz not exceeding the maximum commands that the firmware can support, instance->max_fw_cmds is already decremented in megasas_fusion_update_can_queue(). Remove the extra decrement logic in code. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 7 --- 1 file changed, 7 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 2bfdf6b..e74cbe6d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1282,13 +1282,6 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) megasas_fusion_update_can_queue(instance, PROBE_CONTEXT); /* -* Reduce the max supported cmds by 1. This is to ensure that the -* reply_q_sz (1 more than the max cmd that driver may send) -* does not exceed max cmds that the FW can support -*/ - instance->max_fw_cmds = instance->max_fw_cmds-1; - - /* * Only Driver's internal DCMDs and IOCTL DCMDs needs to have MFI frames */ instance->max_mfi_cmds = -- 2.8.3
[PATCH 19/39] megaraid_sas: Big endian RDPQ mode fix
Fix if RDPQ mode enabled MR FW is deployed on big endian host machine, driver does not setup reply address correctly. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 3d4d4b8..b68babc 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -580,7 +580,7 @@ megasas_alloc_rdpq_fusion(struct megasas_instance *instance) } fusion->rdpq_virt[i].RDPQBaseAddress = - fusion->reply_frames_desc_phys[i]; + cpu_to_le64(fusion->reply_frames_desc_phys[i]); reply_desc = fusion->reply_frames_desc[i]; for (j = 0; j < fusion->reply_q_depth; j++, reply_desc++) -- 2.8.3
[PATCH 14/39] megaraid_sas: enhance debug logs in OCR context
Add additional logging from driver in OCR context. Add debug logs for partial completion of IOs is iodone context. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas.h| 3 +++ drivers/scsi/megaraid/megaraid_sas_base.c | 38 ++--- drivers/scsi/megaraid/megaraid_sas_fusion.c | 35 +- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 6e7cb0b..ac2aed3 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1405,6 +1405,9 @@ struct megasas_ctrl_info { #define VD_EXT_DEBUG 0 +/* Driver's internal Logging levels*/ +#define OCR_LOGS(1 << 0) + #define SCAN_PD_CHANNEL0x1 #define SCAN_VD_CHANNEL0x2 diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 3e74f0f..d386f69 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -2739,6 +2739,24 @@ blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd) } /** + * megasas_dump_frame -This function will dump MPT/MFI frame + */ +static inline void +megasas_dump_frame(void *mpi_request, int sz) +{ + int i; + __le32 *mfp = (__le32 *)mpi_request; + + printk(KERN_INFO "IO request frame:\n\t"); + for (i = 0; i < sz; i++) { + if (i && ((i % 8) == 0)) + printk("\n\t"); + printk("%08x ", le32_to_cpu(mfp[i])); + } + printk("\n"); +} + +/** * megasas_reset_bus_host -Bus & host reset handler entry point */ static int megasas_reset_bus_host(struct scsi_cmnd *scmd) @@ -2748,12 +2766,26 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd) instance = (struct megasas_instance *)scmd->device->host->hostdata; + scmd_printk(KERN_INFO, scmd, + "Controller reset is requested due to IO timeout\n" + "SCSI command pointer: (%p)\t SCSI host state: %d\t" + " SCSI host busy: %d\t FW outstanding: %d\n", + scmd, scmd->device->host->shost_state, + atomic_read((atomic_t *)&scmd->device->host->host_busy), + atomic_read(&instance->fw_outstanding)); + /* * First wait for all commands to complete */ - if (instance->ctrl_context) - ret = megasas_reset_fusion(scmd->device->host, 1); - else + if (instance->ctrl_context) { + struct megasas_cmd_fusion *cmd; + cmd = (struct megasas_cmd_fusion *)scmd->SCp.ptr; + if (cmd) + megasas_dump_frame(cmd->io_request, + sizeof(struct MPI2_RAID_SCSI_IO_REQUEST)); + ret = megasas_reset_fusion(scmd->device->host, + SCSIIO_TIMEOUT_OCR); + } else ret = megasas_generic_reset(scmd); return ret; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 75c4ad1..8dd4944 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1442,8 +1442,10 @@ map_cmd_status(struct fusion_context *fusion, struct scsi_cmnd *scmd, u8 status, u8 ext_status, u32 data_length, u8 *sense) { + u8 cmd_type; int resid; + cmd_type = megasas_cmd_type(scmd); switch (status) { case MFI_STAT_OK: @@ -1474,6 +1476,13 @@ map_cmd_status(struct fusion_context *fusion, */ resid = (scsi_bufflen(scmd) - data_length); scsi_set_resid(scmd, resid); + + if (resid && + ((cmd_type == READ_WRITE_LDIO) || + (cmd_type == READ_WRITE_SYSPDIO))) + scmd_printk(KERN_INFO, scmd, "BRCM Debug mfi stat 0x%x, data len" + " requested/completed 0x%x/0x%x\n", + status, scsi_bufflen(scmd), data_length); break; case MFI_STAT_LD_OFFLINE: @@ -3473,6 +3482,14 @@ int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance, " will reset adapter scsi%d.\n", instance->host->host_no); megasas_complete_cmd_dpc_fusion((unsigned long)instance); + if (instance->requestorId && reason) { + dev_warn(&instance->pdev->dev, "SR-IOV Found FW in FAULT&quo
[PATCH 20/39] megaraid_sas: big endian support changes
Fix endiannes fixes for Ventura specific. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas_fp.c | 15 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 70 ++--- drivers/scsi/megaraid/megaraid_sas_fusion.h | 115 +--- 3 files changed, 122 insertions(+), 78 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 9d5d485..68582d9 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -210,7 +210,7 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) le32_to_cpu(fw_map_dyn->desc_table_size), le32_to_cpu(fw_map_dyn->desc_table_num_elements)); dev_dbg(&instance->pdev->dev, "drv map %p ldCount %d\n", - drv_map, fw_map_dyn->ld_count); + drv_map, le16_to_cpu(fw_map_dyn->ld_count)); #endif desc_table = (struct MR_RAID_MAP_DESC_TABLE *)((void *)fw_map_dyn + le32_to_cpu(fw_map_dyn->desc_table_offset)); @@ -222,7 +222,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count); pDrvRaidMap->fpPdIoTimeoutSec = fw_map_dyn->fp_pd_io_timeout_sec; - pDrvRaidMap->totalSize = sizeof(struct MR_DRV_RAID_MAP_ALL); + pDrvRaidMap->totalSize = + cpu_to_le32(sizeof(struct MR_DRV_RAID_MAP_ALL)); /* point to actual data starting point*/ raid_map_data = (void *)fw_map_dyn + le32_to_cpu(fw_map_dyn->desc_table_offset) + @@ -234,11 +235,11 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) dev_dbg(&instance->pdev->dev, "desc table %p\n", desc_table); dev_dbg(&instance->pdev->dev, "raidmap type %d, raidmapOffset 0x%x\n", - desc_table->raid_map_desc_type, - desc_table->raid_map_desc_offset); + le32_to_cpu(desc_table->raid_map_desc_type), + le32_to_cpu(desc_table->raid_map_desc_offset)); dev_dbg(&instance->pdev->dev, "raid map number of elements 0%x, raidmapsize 0x%x\n", - desc_table->raid_map_desc_elements, - desc_table->raid_map_desc_buffer_size); + le32_to_cpu(desc_table->raid_map_desc_elements), + le32_to_cpu(desc_table->raid_map_desc_buffer_size)); #endif switch (le32_to_cpu(desc_table->raid_map_desc_type)) { case RAID_MAP_DESC_TYPE_DEVHDL_INFO: @@ -263,7 +264,7 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) #endif for (j = 0; j < le32_to_cpu(desc_table->raid_map_desc_elements); j++) { pDrvRaidMap->ldTgtIdToLd[j] = - fw_map_dyn->ld_tgt_id_to_ld[j]; + le16_to_cpu(fw_map_dyn->ld_tgt_id_to_ld[j]); #if VD_EXT_DEBUG dev_dbg(&instance->pdev->dev, " %d drv ldTgtIdToLd %d\n", j, pDrvRaidMap->ldTgtIdToLd[j]); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index b68babc..cf3e2f8 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2077,7 +2077,7 @@ static void megasas_stream_detect(struct megasas_instance *instance, */ continue; - cmd->io_request->RaidContext.raid_context_g35.stream_detected = true; + SET_STREAM_DETECTED(cmd->io_request->RaidContext.raid_context_g35); current_sd->next_seq_lba = io_info->ldStartBlock + io_info->numBlocks; /* @@ -2151,7 +2151,8 @@ megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context, /* Fast path cache by pass capable R0/R1 VD */ if ((raid->level <= 1) && (raid->capability.fp_cache_bypass_capable)) { - rctx_g35->routing_flags.bits.sld = 1; + rctx_g35->routing_flags |= + (1 << MR_RAID_CTX_ROUTINGFLAGS_SLD_SHIFT); rctx_g35->raid_flags
[PATCH 17/39] megaraid_sas: In validate raid map, raid capability is not converted to cpu format for all lds
On a host, if an ld is deleted there is a hole in the ld array returned by the FW. But in MR_ValidateMapInfo we are not accounting for holes in the ld array and traverse only upto index num_lds. This patch takes care of converting the capability field of all the valid lds in the ld raid map. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas_fp.c | 13 ++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index d9b0f28..a0b0e68 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -452,7 +452,7 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance) struct LD_LOAD_BALANCE_INFO *lbInfo; PLD_SPAN_INFO ldSpanInfo; struct MR_LD_RAID *raid; - u16 ldCount, num_lds; + u16 num_lds, i; u16 ld; u32 expected_size; @@ -495,10 +495,17 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance) num_lds = le16_to_cpu(drv_map->raidMap.ldCount); /*Convert Raid capability values to CPU arch */ - for (ldCount = 0; ldCount < num_lds; ldCount++) { - ld = MR_TargetIdToLdGet(ldCount, drv_map); + for (i = 0; (num_lds > 0) && (i < MAX_LOGICAL_DRIVES_EXT); i++) { + ld = MR_TargetIdToLdGet(i, drv_map); + + /* For non existing VDs, iterate to next VD*/ + if (ld >= (MAX_LOGICAL_DRIVES_EXT - 1)) + continue; + raid = MR_LdRaidGet(ld, drv_map); le32_to_cpus((u32 *)&raid->capability); + + num_lds--; } return 1; -- 2.8.3
[PATCH 16/39] megaraid_sas: reduce size of fusion_context and use vmalloc if kmalloc fails
Currently fusion context has fixed array load_balance_info. Use dynamic allocation. In few places, driver do not want physically contigious memory. Attempt to use vmalloc if physical contiguous memory is not available. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas.h| 2 + drivers/scsi/megaraid/megaraid_sas_base.c | 15 ++ drivers/scsi/megaraid/megaraid_sas_fp.c | 3 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 71 +++-- drivers/scsi/megaraid/megaraid_sas_fusion.h | 3 +- 5 files changed, 76 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index ac2aed3..f023e23 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2488,4 +2488,6 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason); int megasas_task_abort_fusion(struct scsi_cmnd *scmd); 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); #endif /*LSI_MEGARAID_SAS_H */ diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index de01e36..c38b9c3 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6024,18 +6024,12 @@ static int megasas_probe_one(struct pci_dev *pdev, case PCI_DEVICE_ID_LSI_CUTLASS_52: case PCI_DEVICE_ID_LSI_CUTLASS_53: { - instance->ctrl_context_pages = - get_order(sizeof(struct fusion_context)); - instance->ctrl_context = (void *)__get_free_pages(GFP_KERNEL, - instance->ctrl_context_pages); - if (!instance->ctrl_context) { - dev_printk(KERN_DEBUG, &pdev->dev, "Failed to allocate " - "memory for Fusion context info\n"); + if (megasas_alloc_fusion_context(instance)) { + megasas_free_fusion_context(instance); goto fail_alloc_dma_buf; } fusion = instance->ctrl_context; - memset(fusion, 0, - ((1 << PAGE_SHIFT) << instance->ctrl_context_pages)); + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA)) fusion->adapter_type = THUNDERBOLT_SERIES; @@ -6678,8 +6672,7 @@ static void megasas_detach_one(struct pci_dev *pdev) fusion->pd_seq_sync[i], fusion->pd_seq_phys[i]); } - free_pages((ulong)instance->ctrl_context, - instance->ctrl_context_pages); + megasas_free_fusion_context(instance); } else { megasas_release_mfi(instance); pci_free_consistent(pdev, sizeof(u32), diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index c3ef82d..d9b0f28 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -489,7 +489,8 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance) if (instance->UnevenSpanSupport) mr_update_span_set(drv_map, ldSpanInfo); - mr_update_load_balance_params(drv_map, lbInfo); + if (lbInfo) + mr_update_load_balance_params(drv_map, lbInfo); num_lds = le16_to_cpu(drv_map->raidMap.ldCount); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 8dd4944..2f523f2 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -2394,8 +2395,9 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, io_request->IoFlags |= cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH); } - if ((fusion->load_balance_info[device_id].loadBalanceFlag) && - (io_info.isRead)) { + if (fusion->load_balance_info && + (fusion->load_balance_info[device_id].loadBalanceFlag) && + (io_info.isRead)) { io_info.devHandle = get_updated_dev_handle(instance, &fusion->load_balance_info[device_id],
[PATCH 28/39] megaraid_sas: Remove unused pd_index from megasas_build_ld_nonrw_fusion
Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index e74cbe6d..7f53505 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2477,7 +2477,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, { u32 device_id; struct MPI2_RAID_SCSI_IO_REQUEST *io_request; - u16 pd_index = 0, ld; + u16 ld; struct MR_DRV_RAID_MAP_ALL *local_map_ptr; struct fusion_context *fusion = instance->ctrl_context; u8 span, physArm; @@ -2489,7 +2489,6 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, io_request = cmd->io_request; device_id = MEGASAS_DEV_INDEX(scmd); - pd_index = MEGASAS_PD_INDEX(scmd); local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd)); /* get RAID_Context pointer */ -- 2.8.3
[PATCH 23/39] megaraid_sas: set pd_after_lb from MR_BuildRaidContext and initialize pDevHandle to MR_DEVHANDLE_INVALID
Issue is limited for Syncro firmware where pd_after_lb is not set but is accidentally used. Not a functional issue, but results in low performance due to improper load balancing between two LUNs. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas_fp.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 68582d9..a5517e7 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -948,6 +948,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, struct fusion_context *fusion; fusion = instance->ctrl_context; + *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); /*Get row and span from io_info for Uneven Span IO.*/ row = io_info->start_row; @@ -986,7 +987,6 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, MR_PdDevHandleGet(r1_alt_pd, map); } } else { - *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); if ((raid->level >= 5) && ((fusion->adapter_type == THUNDERBOLT_SERIES) || ((fusion->adapter_type == INVADER_SERIES) && @@ -1013,6 +1013,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; io_info->span_arm = pRAID_Context->span_arm; } + io_info->pd_after_lb = pd; return retval; } @@ -1049,7 +1050,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, struct fusion_context *fusion; fusion = instance->ctrl_context; - + *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); row = mega_div64_32(stripRow, raid->rowDataSize); @@ -1102,8 +1103,6 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, MR_PdDevHandleGet(r1_alt_pd, map); } } else { - /* set dev handle as invalid. */ - *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); if ((raid->level >= 5) && ((fusion->adapter_type == THUNDERBOLT_SERIES) || ((fusion->adapter_type == INVADER_SERIES) && @@ -1132,6 +1131,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; io_info->span_arm = pRAID_Context->span_arm; } + io_info->pd_after_lb = pd; return retval; } -- 2.8.3
[PATCH 34/39] megaraid_sas: Use synchronize_irq to wait for IRQs to complete
FIX - Do not use random delay to synchronize with IRQ. Use kernel API. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 20 ++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 8edb6ba..5dda73d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3141,6 +3141,22 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) } /** + * megasas_sync_irqs - Synchronizes all IRQs owned by adapter + * @instance: Adapter soft state + */ +void megasas_sync_irqs(unsigned long instance_addr) +{ + u32 count, i; + struct megasas_instance *instance = + (struct megasas_instance *)instance_addr; + + count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; + + for (i = 0; i < count; i++) + synchronize_irq(pci_irq_vector(instance->pdev, i)); +} + +/** * megasas_complete_cmd_dpc_fusion - Completes command * @instance: Adapter soft state * @@ -3816,7 +3832,7 @@ megasas_issue_tm(struct megasas_instance *instance, u16 device_handle, break; else { instance->instancet->disable_intr(instance); - msleep(1000); + megasas_sync_irqs((unsigned long)instance); megasas_complete_cmd_dpc_fusion ((unsigned long)instance); instance->instancet->enable_intr(instance); @@ -4170,7 +4186,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_POLLING); instance->instancet->disable_intr(instance); - msleep(1000); + megasas_sync_irqs((unsigned long)instance); /* First try waiting for commands to complete */ if (megasas_wait_for_outstanding_fusion(instance, reason, -- 2.8.3
[PATCH 33/39] megaraid_sas: call flush_scheduled_work during controller shutdown/detach
Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas_base.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 04ef0a0..b29cfd3 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6393,6 +6393,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) if (instance->ev != NULL) { struct megasas_aen_event *ev = instance->ev; cancel_delayed_work_sync(&ev->hotplug_work); + flush_scheduled_work(); instance->ev = NULL; } @@ -6619,6 +6620,7 @@ static void megasas_detach_one(struct pci_dev *pdev) if (instance->ev != NULL) { struct megasas_aen_event *ev = instance->ev; cancel_delayed_work_sync(&ev->hotplug_work); + flush_scheduled_work(); instance->ev = NULL; } -- 2.8.3
[PATCH 31/39] megaraid_sas: Change build_mpt_mfi_pass_thru to return void
Code refactoring to build_mpt_mfi_pass_thru to return void. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 10 ++ 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 9f3cbaa..8edb6ba 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3225,7 +3225,7 @@ irqreturn_t megasas_isr_fusion(int irq, void *devp) * mfi_cmd:megasas_cmd pointer * */ -u8 +void build_mpt_mfi_pass_thru(struct megasas_instance *instance, struct megasas_cmd *mfi_cmd) { @@ -3275,8 +3275,6 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance, MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR; mpi25_ieee_chain->Length = cpu_to_le32(instance->max_chain_frame_sz); - - return 0; } /** @@ -3291,11 +3289,7 @@ build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc = NULL; u16 index; - if (build_mpt_mfi_pass_thru(instance, cmd)) { - dev_err(&instance->pdev->dev, "Couldn't build MFI pass thru cmd\n"); - return NULL; - } - + build_mpt_mfi_pass_thru(instance, cmd); index = cmd->context.smid; req_desc = megasas_get_request_descriptor(instance, index - 1); -- 2.8.3
[PATCH 35/39] megaraid_sas: Increase internal command pool
Fix - increase internal command pool to 8. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas.h| 2 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 59fe39d..1a9a283 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1460,7 +1460,7 @@ enum FW_BOOT_CONTEXT { */ #define MEGASAS_INT_CMDS 32 #define MEGASAS_SKINNY_INT_CMDS5 -#define MEGASAS_FUSION_INTERNAL_CMDS 5 +#define MEGASAS_FUSION_INTERNAL_CMDS 8 #define MEGASAS_FUSION_IOCTL_CMDS 3 #define MEGASAS_MFI_IOCTL_CMDS 27 diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 5dda73d..65971a9d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1347,7 +1347,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) fusion->last_reply_idx[i] = 0; /* -* For fusion adapters, 3 commands for IOCTL and 5 commands +* For fusion adapters, 3 commands for IOCTL and 8 commands * for driver's internal DCMDs. */ instance->max_scsi_cmds = instance->max_fw_cmds - -- 2.8.3
[PATCH 39/39] megaraid_sas: driver version upgrade
Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index e810057..f8718ea 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.700.00.00-rc1" -#define MEGASAS_RELDATE"November 29, 2016" +#define MEGASAS_VERSION"07.701.16.00-rc1" +#define MEGASAS_RELDATE"February 2, 2017" /* * Device IDs -- 2.8.3
[PATCH 36/39] megaraid_sas: Cleanup VD_EXT_DEBUG and SPAN_DEBUG related debug prints
Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas.h| 2 - drivers/scsi/megaraid/megaraid_sas_base.c | 15 -- drivers/scsi/megaraid/megaraid_sas_fp.c | 266 +--- drivers/scsi/megaraid/megaraid_sas_fusion.c | 5 - 4 files changed, 2 insertions(+), 286 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 1a9a283..eca6701 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1403,8 +1403,6 @@ struct megasas_ctrl_info { #define MEGASAS_FW_BUSY1 -#define VD_EXT_DEBUG 0 - /* Driver's internal Logging levels*/ #define OCR_LOGS(1 << 0) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index b29cfd3..e282e00 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4598,17 +4598,6 @@ static void megasas_update_ext_vd_details(struct megasas_instance *instance) } /* irrespective of FW raid maps, driver raid map is constant */ fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP_ALL); - -#if VD_EXT_DEBUG - dev_info(&instance->pdev->dev, "instance->max_raid_mapsize 0x%x\n ", - instance->max_raid_mapsize); - dev_info(&instance->pdev->dev, "new_map_sz = 0x%x, old_map_sz = 0x%x\n", - fusion->new_map_sz, fusion->old_map_sz); - dev_info(&instance->pdev->dev, "ventura_map_sz = 0x%x, current_map_sz = 0x%x\n", - ventura_map_sz, fusion->current_map_sz); - dev_info(&instance->pdev->dev, "fusion->drv_map_sz =0x%x, size of driver raid map 0x%lx\n", - fusion->drv_map_sz, sizeof(struct MR_DRV_RAID_MAP_ALL)); -#endif } /** @@ -5212,10 +5201,6 @@ static int megasas_init_fw(struct megasas_instance *instance) if (instance->is_ventura) { scratch_pad_3 = readl(&instance->reg_set->outbound_scratch_pad_3); -#if VD_EXT_DEBUG - dev_info(&instance->pdev->dev, "scratch_pad3 0x%x\n", - scratch_pad_3); -#endif instance->max_raid_mapsize = ((scratch_pad_3 >> MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT) & MR_MAX_RAID_MAP_SIZE_MASK); diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index a5517e7..7dc7708 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -77,7 +77,6 @@ MODULE_PARM_DESC(lb_pending_cmds, "Change raid-1 load balancing outstanding " #endif #define TRUE 1 -#define SPAN_DEBUG 0 #define SPAN_ROW_SIZE(map, ld, index_) (MR_LdSpanPtrGet(ld, index_, map)->spanRowSize) #define SPAN_ROW_DATA_SIZE(map_, ld, index_) (MR_LdSpanPtrGet(ld, index_, map)->spanRowDataSize) #define SPAN_INVALID 0xff @@ -202,16 +201,6 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) if (instance->max_raid_mapsize) { fw_map_dyn = fusion->ld_map[(instance->map_id & 1)]; -#if VD_EXT_DEBUG - dev_dbg(&instance->pdev->dev, "raidMapSize 0x%x fw_map_dyn->descTableOffset 0x%x\n", - le32_to_cpu(fw_map_dyn->raid_map_size), - le32_to_cpu(fw_map_dyn->desc_table_offset)); - dev_dbg(&instance->pdev->dev, "descTableSize 0x%x descTableNumElements 0x%x\n", - le32_to_cpu(fw_map_dyn->desc_table_size), - le32_to_cpu(fw_map_dyn->desc_table_num_elements)); - dev_dbg(&instance->pdev->dev, "drv map %p ldCount %d\n", - drv_map, le16_to_cpu(fw_map_dyn->ld_count)); -#endif desc_table = (struct MR_RAID_MAP_DESC_TABLE *)((void *)fw_map_dyn + le32_to_cpu(fw_map_dyn->desc_table_offset)); if (desc_table != fw_map_dyn->raid_map_desc_table) @@ -230,25 +219,10 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) le32_to_cpu(fw_map_dyn->desc_table_size); for (i = 0; i < le32_to_cpu(fw_map_dyn->desc_table_num_elements); ++i) { - -#if VD_EXT_DEBUG - dev_dbg(&instance->pdev->dev, "desc table %p\n", - desc_table); - dev_dbg(&instance->pdev->dev, "raidmap type %d, raidmapOffset 0x%x\n", - le32_to_cpu(desc_table->raid_map_desc_type), - le32_to_cpu(desc_table->raid_map_d
[PATCH 37/39] megaraid_sas: Indentation and smatch warning fixes
Fix indentation issues and smatch warning reported by Dan Carpenter for previous series as discussed below. http://www.spinics.net/lists/linux-scsi/msg103635.html http://www.spinics.net/lists/linux-scsi/msg103603.html Reported-by: Dan Carpenter Signed-off-by: Kashyap Desai Signed-off-by: Sasikumar Chandrasekaran --- drivers/scsi/megaraid/megaraid_sas.h| 2 +- drivers/scsi/megaraid/megaraid_sas_base.c | 10 ++-- drivers/scsi/megaraid/megaraid_sas_fp.c | 57 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 92 ++--- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 5 files changed, 80 insertions(+), 83 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index eca6701..e810057 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1376,7 +1376,7 @@ struct megasas_ctrl_info { u16 reserved:8; #endif } adapter_operations4; - u8 pad[0x800-0x7FE]; /* 0x7FE pad to 2K for expansion */ + u8 pad[0x800 - 0x7FE]; /* 0x7FE pad to 2K for expansion */ } __packed; /* diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index e282e00..e7085bd 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5340,14 +5340,14 @@ 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) { + if (instance->is_ventura && fusion) { fusion->stream_detect_by_ld = - kzalloc(sizeof(struct LD_STREAM_DETECT *) - * MAX_LOGICAL_DRIVES_EXT, - GFP_KERNEL); + kzalloc(sizeof(struct LD_STREAM_DETECT *) + * MAX_LOGICAL_DRIVES_EXT, + GFP_KERNEL); if (!fusion->stream_detect_by_ld) { dev_err(&instance->pdev->dev, - "unable to allocate stream detection for pool of LDs\n"); + "unable to allocate stream detection for pool of LDs\n"); goto fail_get_ld_pd_list; } for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) { diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 7dc7708..62affa7 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -197,7 +197,7 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) memset(drv_map, 0, fusion->drv_map_sz); memset(pDrvRaidMap->ldTgtIdToLd, - 0xff, (sizeof(u16) * MAX_LOGICAL_DRIVES_DYN)); + 0xff, (sizeof(u16) * MAX_LOGICAL_DRIVES_DYN)); if (instance->max_raid_mapsize) { fw_map_dyn = fusion->ld_map[(instance->map_id & 1)]; @@ -224,34 +224,37 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) fw_map_dyn->dev_hndl_info = (struct MR_DEV_HANDLE_INFO *)(raid_map_data + le32_to_cpu(desc_table->raid_map_desc_offset)); memcpy(pDrvRaidMap->devHndlInfo, - fw_map_dyn->dev_hndl_info, - sizeof(struct MR_DEV_HANDLE_INFO) * - le32_to_cpu(desc_table->raid_map_desc_elements)); + fw_map_dyn->dev_hndl_info, + sizeof(struct MR_DEV_HANDLE_INFO) * + le32_to_cpu(desc_table->raid_map_desc_elements)); break; case RAID_MAP_DESC_TYPE_TGTID_INFO: fw_map_dyn->ld_tgt_id_to_ld = - (u16 *) (raid_map_data + - le32_to_cpu(desc_table->raid_map_desc_offset)); - for (j = 0; j < le32_to_cpu(desc_table->raid_map_desc_elements); j++) { - pDrvRaidMap->ldTgtIdToLd[j] = - le16_to_cpu(fw_map_dyn->ld_tgt_id_to_ld[j]); - } + (u16 *)(raid_map_data + + le32_to_cpu(desc_table->raid_map_desc_offset)); + for (j = 0; j < le32_to_cpu(desc_table->raid_map_desc_elements); j++) { + pDrvRaidMap->ldTgtIdToLd[j] = + le16_to_cpu(fw_map_dyn->ld_tgt_id_to_ld[j]); + } break; case RAID_MAP_DESC_TYPE_ARRAY_INFO: fw_map_dyn->a
[PATCH 38/39] megaraid_sas: Change RAID_1_10_RMW_CMDS to RAID_1_PEER_CMDS and set value to 2
For RAID1 FastPath writes, driver needs to allocate extra commands internally to accommodate for the extra peer command being sent. Currently driver is allocating 2 extra commands for each but only one extra command is necessary. Set RAID_1_10_RMW_CMDS to 2 and also change macro name to RAID_1_PEER_CMDS. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index b5bb33e..6dffb17 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -293,7 +293,7 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c if (instance->is_ventura) instance->max_mpt_cmds = - instance->max_fw_cmds * RAID_1_10_RMW_CMDS; + instance->max_fw_cmds * RAID_1_PEER_CMDS; else instance->max_mpt_cmds = instance->max_fw_cmds; } diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index 60566e4..c36f9f7 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -101,7 +101,7 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE { #define MEGASAS_FP_CMD_LEN 16 #define MEGASAS_FUSION_IN_RESET 0 #define THRESHOLD_REPLY_COUNT 50 -#define RAID_1_10_RMW_CMDS 3 +#define RAID_1_PEER_CMDS 2 #define JBOD_MAPS_COUNT2 enum MR_FUSION_ADAPTER_TYPE { -- 2.8.3
[PATCH v2 27/39] megaraid_sas: max_fw_cmds are decremented twice, remove duplicate
Fix to account for the reply_q_sz not exceeding the maximum commands that the firmware can support, instance->max_fw_cmds is already decremented in megasas_fusion_update_can_queue(). Remove the extra decrement logic in code. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 7 --- 1 file changed, 7 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 02a23d9..9e2a289 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1285,13 +1285,6 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) megasas_fusion_update_can_queue(instance, PROBE_CONTEXT); /* -* Reduce the max supported cmds by 1. This is to ensure that the -* reply_q_sz (1 more than the max cmd that driver may send) -* does not exceed max cmds that the FW can support -*/ - instance->max_fw_cmds = instance->max_fw_cmds-1; - - /* * Only Driver's internal DCMDs and IOCTL DCMDs needs to have MFI frames */ instance->max_mfi_cmds = -- 2.8.3
[PATCH v2 16/39] megaraid_sas: add print in device removal path
Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 19 +++ 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index b41bbea..c8fa480 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -7383,6 +7383,13 @@ megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t coun static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUSR, megasas_sysfs_show_dbg_lvl, megasas_sysfs_set_dbg_lvl); +static inline void megasas_remove_scsi_device(struct scsi_device *sdev) +{ + sdev_printk(KERN_INFO, sdev, "SCSI device is removed\n"); + scsi_remove_device(sdev); + scsi_device_put(sdev); +} + static void megasas_aen_polling(struct work_struct *work) { @@ -7487,10 +7494,8 @@ megasas_aen_polling(struct work_struct *work) else scsi_device_put(sdev1); } else { - if (sdev1) { - scsi_remove_device(sdev1); - scsi_device_put(sdev1); - } + if (sdev1) + megasas_remove_scsi_device(sdev1); } } } @@ -7507,10 +7512,8 @@ megasas_aen_polling(struct work_struct *work) else scsi_device_put(sdev1); } else { - if (sdev1) { - scsi_remove_device(sdev1); - scsi_device_put(sdev1); - } + if (sdev1) + megasas_remove_scsi_device(sdev1); } } } -- 2.8.3
[PATCH v2 09/39] megaraid_sas: change issue_dcmd to return void from int
fix in v2 : 1. split patches into two as discussed below http://marc.info/?l=linux-scsi&m=148638999110404&w=2 2. issue_dcmd return type changed from int to void. With the changes to remove checks for a valid request descriptor, issue_dcmd will now always return DCMD_SUCCESS. This patch changes return type of issue_dcmd to void and change all callers appropriately. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas.h| 2 +- drivers/scsi/megaraid/megaraid_sas_base.c | 19 +++ drivers/scsi/megaraid/megaraid_sas_fusion.c | 8 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index dff877f..d9049d5 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2297,7 +2297,7 @@ struct megasas_instance_template { u32 (*init_adapter)(struct megasas_instance *); u32 (*build_and_issue_cmd) (struct megasas_instance *, struct scsi_cmnd *); - int (*issue_dcmd)(struct megasas_instance *instance, + void (*issue_dcmd)(struct megasas_instance *instance, struct megasas_cmd *cmd); }; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 80fcdf5..23fb78a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -202,12 +202,12 @@ void megasas_fusion_ocr_wq(struct work_struct *work); static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance, int initial); -int +void megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd) { instance->instancet->fire_cmd(instance, cmd->frame_phys_addr, 0, instance->reg_set); - return 0; + return; } /** @@ -995,13 +995,14 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd) frame_hdr->cmd_status = MFI_STAT_INVALID_STATUS; frame_hdr->flags |= cpu_to_le16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE); - if ((atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) || - (instance->instancet->issue_dcmd(instance, cmd))) { + if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); return DCMD_NOT_FIRED; } + instance->instancet->issue_dcmd(instance, cmd); + return wait_and_poll(instance, cmd, instance->requestorId ? MEGASAS_ROUTINE_WAIT_TIME_VF : MFI_IO_TIMEOUT_SECS); } @@ -1023,13 +1024,14 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance, int ret = 0; cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; - if ((atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) || - (instance->instancet->issue_dcmd(instance, cmd))) { + if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); return DCMD_NOT_FIRED; } + instance->instancet->issue_dcmd(instance, cmd); + if (timeout) { ret = wait_event_timeout(instance->int_cmd_wait_q, cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ); @@ -1087,13 +1089,14 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance, cmd->sync_cmd = 1; cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; - if ((atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) || - (instance->instancet->issue_dcmd(instance, cmd))) { + if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); return DCMD_NOT_FIRED; } + instance->instancet->issue_dcmd(instance, cmd); + if (timeout) { ret = wait_event_timeout(instance->abort_cmd_wait_q, cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index b6c5dc5..c38fde0 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1115,7 +1115,7 @@ megasas_get_map_info(struct megasas_instance *instance) int megasas_sync_map_info(struct megasas_ins
[PATCH v2 13/39] megaraid_sas: raid 1 write performance for large io
Avoid Host side PCI bandwidth bottleneck and hint FW to do Write buffering using RaidFlag MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT. Once IO is landed in FW with MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT, it will do single DMA from host and buffer the Write operation. On back end, FW will DMA same buffer to the Mirror and Data Arm. This will improve large block IO performance which bottleneck due to Host side PCI bandwidth limitation. Consistent ~4000MB T.P for 256K Block size is expected performance numbers. IOPS for small Block size should be on par with Disk performance. (E.g 42 SAS Disk in JBOD mode gives 3700MB T.P. Same Drive used in R1 WT mode, should give ~1800MB T.P) Using this patch 24 R1 VDs (HDD) gives below performance for Sequential Write. Without this patch, we cannot reach above 3200MB (Throughput is in MB. ) Block Size 50% 256K and 50% 4K 100% 256K 4K 31002030 8K 31402740 16K31403140 32K34003240 64K35003700 128K 38703870 256K 39203920 Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 5 + drivers/scsi/megaraid/megaraid_sas_fusion.c | 32 +++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 075e2e9..bed8a37 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1409,6 +1409,8 @@ struct megasas_ctrl_info { #define SCAN_VD_CHANNEL0x2 #define MEGASAS_KDUMP_QUEUE_DEPTH 100 +#define MR_LARGE_IO_MIN_SIZE (32 * 1024) +#define MR_R1_LDIO_PIGGYBACK_DEFAULT 4 enum MR_SCSI_CMD_TYPE { READ_WRITE_LDIO = 0, @@ -1875,6 +1877,7 @@ union megasas_frame { struct MR_PRIV_DEVICE { bool is_tm_capable; bool tm_busy; + atomic_t r1_ldio_hint; u8 interface_type; }; struct megasas_cmd; @@ -2235,6 +2238,8 @@ struct megasas_instance { bool is_ventura; bool msix_combined; u16 max_raid_mapsize; + /* preffered count to send as LDIO irrspective of FP capable.*/ + u8 r1_ldio_hint_default; u32 nvme_page_size; }; struct MR_LD_VF_MAP { diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 379c723..edbecc5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1383,6 +1383,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) } instance->flag_ieee = 1; + instance->r1_ldio_hint_default = MR_R1_LDIO_PIGGYBACK_DEFAULT; fusion->fast_path_io = 0; fusion->drv_map_pages = get_order(fusion->drv_map_sz); @@ -2110,7 +2111,7 @@ static void megasas_stream_detect(struct megasas_instance *instance, static void megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context, struct MR_LD_RAID *raid, bool fp_possible, - u8 is_read) + u8 is_read, u32 scsi_buff_len) { u8 cpu_sel = MR_RAID_CTX_CPUSEL_0; struct RAID_CONTEXT_G35 *rctx_g35; @@ -2161,6 +2162,17 @@ megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context, } rctx_g35->routing_flags.bits.cpu_sel = cpu_sel; + + /* Always give priority to MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT +* vs MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS. +* IO Subtype is not bitmap. +*/ + if ((raid->level == 1) && (!is_read)) { + if (scsi_buff_len > MR_LARGE_IO_MIN_SIZE) + praid_context->raid_context_g35.raid_flags = + (MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT + << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT); + } } /** @@ -2303,6 +2315,14 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, io_info.isRead && io_info.ra_capable) fp_possible = false; + /* FP for Optimal raid level 1. +* All large RAID-1 writes (> 32 KiB, both WT and WB modes) +* are built by the driver as LD I/Os. +* All small RAID-1 WT writes (<= 32 KiB) are built as FP I/Os +* (there is never a reason to process these as buffered writes) +* All small RAID-1 WB writes (<= 32 KiB) are built as FP I/Os +* with the SLD bit asserted. +
[PATCH v2 03/39] megaraid_sas: raid 1 fast path code optimize
fix in v2 - ex_status and status was wrongly re-used in megasas_complete_r1_command. discussed below - http://marc.info/?l=linux-scsi&m=148638763409385&w=2 No functional change. Code refactor. Remove function megasas_fpio_to_ldio as we never require to convert fpio to ldio because of frame unavailability. Grab extra frame of raid 1 write fast path before it creates first frame as Fast Path. Removed is_raid_1_fp_write flag as raid 1 write fast path command is decided using r1_alt_dev_handle only. Move resetting megasas_cmd_fusion fields at common function megasas_return_cmd_fusion. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke --- drivers/scsi/megaraid/megaraid_sas_fp.c | 14 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 349 +--- drivers/scsi/megaraid/megaraid_sas_fusion.h | 3 +- 3 files changed, 118 insertions(+), 248 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index f1384b0..24258af 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -1338,20 +1338,8 @@ MR_BuildRaidContext(struct megasas_instance *instance, ref_in_start_stripe, io_info, pRAID_Context, map); /* If IO on an invalid Pd, then FP is not possible.*/ - if (io_info->devHandle == cpu_to_le16(MR_PD_INVALID)) + if (io_info->devHandle == MR_DEVHANDLE_INVALID) io_info->fpOkForIo = FALSE; - /* if FP possible, set the SLUD bit in -* regLockFlags for ventura -*/ - else if ((instance->is_ventura) && (!isRead) && - (raid->writeMode == MR_RL_WRITE_BACK_MODE) && - (raid->capability.fp_cache_bypass_capable)) - ((struct RAID_CONTEXT_G35 *) pRAID_Context)->routing_flags.bits.sld = 1; - /* set raid 1/10 fast path write capable bit in io_info */ - if (io_info->fpOkForIo && - (io_info->r1_alt_dev_handle != MR_PD_INVALID) && - (raid->level == 1) && !isRead) - io_info->is_raid_1_fp_write = 1; return retval; } else if (isRead) { uint stripIdx; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 514c306..7516589 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -181,7 +181,9 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance, struct megasas_cmd_fusion *cmd) { cmd->scmd = NULL; - memset(cmd->io_request, 0, sizeof(struct MPI2_RAID_SCSI_IO_REQUEST)); + memset(cmd->io_request, 0, MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE); + cmd->r1_alt_dev_handle = MR_DEVHANDLE_INVALID; + cmd->cmd_completed = false; } /** @@ -701,7 +703,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance) memset(cmd->io_request, 0, sizeof(struct MPI2_RAID_SCSI_IO_REQUEST)); cmd->io_request_phys_addr = io_req_base_phys + offset; - cmd->is_raid_1_fp_write = 0; + cmd->r1_alt_dev_handle = MR_DEVHANDLE_INVALID; } if (megasas_create_sg_sense_fusion(instance)) @@ -1984,7 +1986,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, io_info.ldStartBlock = ((u64)start_lba_hi << 32) | start_lba_lo; io_info.numBlocks = datalength; io_info.ldTgtId = device_id; - io_info.r1_alt_dev_handle = MR_PD_INVALID; + io_info.r1_alt_dev_handle = MR_DEVHANDLE_INVALID; scsi_buff_len = scsi_bufflen(scp); io_request->DataLength = cpu_to_le32(scsi_buff_len); @@ -2025,7 +2027,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, io_info.isRead && io_info.ra_capable) fp_possible = false; - if (io_info.r1_alt_dev_handle != MR_PD_INVALID) { + if (io_info.r1_alt_dev_handle != MR_DEVHANDLE_INVALID) { mrdev_priv = scp->device->hostdata; if (atomic_inc_return(&instance->fw_outstanding) > @@ -2090,9 +2092,10 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, } else scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG; - cmd->is_raid_1_fp_write = io_info.is_raid_1_fp_write; - if (io_info.is_raid_1_fp_write) + if (instance->is_ventura) cmd->r1_alt_dev_h
[PATCH v2 11/39] megaraid_sas: NVME interface target prop added
This patch fetch true values of NVME property from FW using New DCMD interface MR_DCMD_DEV_GET_TARGET_PROP Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 14 +++ drivers/scsi/megaraid/megaraid_sas_base.c | 144 +++- drivers/scsi/megaraid/megaraid_sas_fusion.h | 1 + 3 files changed, 155 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index f9efddf..a45ff10 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -695,6 +695,18 @@ struct MR_PD_INFO { u8 reserved1[512-428]; } __packed; +/* + * Definition of structure used to expose attributes of VD or JBOD + * (this structure is to be filled by firmware when MR_DCMD_DRV_GET_TARGET_PROP + * is fired by driver) + */ +struct MR_TARGET_PROPERTIES { + u32max_io_size_kb; + u32device_qdepth; + u32sector_size; + u8 reserved[500]; +} __packed; + /* * defines the physical drive address structure */ @@ -2090,6 +2102,8 @@ struct megasas_instance { dma_addr_t hb_host_mem_h; struct MR_PD_INFO *pd_info; dma_addr_t pd_info_h; + struct MR_TARGET_PROPERTIES *tgt_prop; + dma_addr_t tgt_prop_h; __le32 *reply_queue; dma_addr_t reply_queue_h; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index f383bf2..51b35a6 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -118,6 +118,8 @@ static int megasas_register_aen(struct megasas_instance *instance, u32 seq_num, u32 class_locale_word); static void megasas_get_pd_info(struct megasas_instance *instance, struct scsi_device *sdev); +static int megasas_get_target_prop(struct megasas_instance *instance, + struct scsi_device *sdev); /* * PCI ID table for all supported controllers */ @@ -1834,14 +1836,16 @@ megasas_set_nvme_device_properties(struct scsi_device *sdev, u32 max_io_size) * set nvme device properties. see - megasas_set_nvme_device_properties * * @sdev: scsi device - * + * @is_target_prop true, if fw provided target properties. */ -static void megasas_set_static_target_properties(struct scsi_device *sdev) +static void megasas_set_static_target_properties(struct scsi_device *sdev, +bool is_target_prop) { u16 target_index = 0; u8 interface_type; u32 device_qd = MEGASAS_DEFAULT_CMD_PER_LUN; u32 max_io_size_kb = MR_DEFAULT_NVME_MDTS_KB; + u32 tgt_device_qd; struct megasas_instance *instance; struct MR_PRIV_DEVICE *mr_device_priv_data; @@ -1868,6 +1872,18 @@ static void megasas_set_static_target_properties(struct scsi_device *sdev) break; } + if (is_target_prop) { + tgt_device_qd = le32_to_cpu(instance->tgt_prop->device_qdepth); + if (tgt_device_qd && + (tgt_device_qd <= instance->host->can_queue)) + device_qd = tgt_device_qd; + + /* max_io_size_kb will be set to non zero for +* nvme based vd and syspd. +*/ + max_io_size_kb = le32_to_cpu(instance->tgt_prop->max_io_size_kb); + } + if (instance->nvme_page_size && max_io_size_kb) megasas_set_nvme_device_properties(sdev, (max_io_size_kb << 10)); @@ -1880,6 +1896,8 @@ static int megasas_slave_configure(struct scsi_device *sdev) { u16 pd_index = 0; struct megasas_instance *instance; + int ret_target_prop = DCMD_FAILED; + bool is_target_prop = false; instance = megasas_lookup_instance(sdev->host->host_no); if (instance->pd_list_not_supported) { @@ -1897,7 +1915,14 @@ static int megasas_slave_configure(struct scsi_device *sdev) if ((instance->pd_info) && !MEGASAS_IS_LOGICAL(sdev)) megasas_get_pd_info(instance, sdev); - megasas_set_static_target_properties(sdev); + /* Some ventura firmware may not have instance->nvme_page_size set. +* Do not send MR_DCMD_DRV_GET_TARGET_PROP +*/ + if ((instance->tgt_prop) && (instance->nvme_page_size)) + ret_target_prop = megasas_get_target_prop(instance, sdev); + + is_target_prop = (ret_target_prop == DCMD_SUCCESS) ? true : false; + megasas_set_static_target_properties(sdev, is_target_prop); mutex_unlock(&instance->hba_mutex); @@ -5682,6 +5707,98 @@ megasas_register_aen(struct megasas_instance *i
[PATCH v2 17/39] megaraid_sas: reduce size of fusion_context and use vmalloc if kmalloc fails
Currently fusion context has fixed array load_balance_info. Use dynamic allocation. In few places, driver do not want physically contigious memory. Attempt to use vmalloc if physical contiguous memory is not available. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 2 + drivers/scsi/megaraid/megaraid_sas_base.c | 15 ++ drivers/scsi/megaraid/megaraid_sas_fp.c | 3 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 71 +++-- drivers/scsi/megaraid/megaraid_sas_fusion.h | 3 +- 5 files changed, 76 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 93da6dc..0a20fff 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2488,4 +2488,6 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason); int megasas_task_abort_fusion(struct scsi_cmnd *scmd); 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); #endif /*LSI_MEGARAID_SAS_H */ diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index c8fa480..b2da257 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6029,18 +6029,12 @@ static int megasas_probe_one(struct pci_dev *pdev, case PCI_DEVICE_ID_LSI_CUTLASS_52: case PCI_DEVICE_ID_LSI_CUTLASS_53: { - instance->ctrl_context_pages = - get_order(sizeof(struct fusion_context)); - instance->ctrl_context = (void *)__get_free_pages(GFP_KERNEL, - instance->ctrl_context_pages); - if (!instance->ctrl_context) { - dev_printk(KERN_DEBUG, &pdev->dev, "Failed to allocate " - "memory for Fusion context info\n"); + if (megasas_alloc_fusion_context(instance)) { + megasas_free_fusion_context(instance); goto fail_alloc_dma_buf; } fusion = instance->ctrl_context; - memset(fusion, 0, - ((1 << PAGE_SHIFT) << instance->ctrl_context_pages)); + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA)) fusion->adapter_type = THUNDERBOLT_SERIES; @@ -6683,8 +6677,7 @@ static void megasas_detach_one(struct pci_dev *pdev) fusion->pd_seq_sync[i], fusion->pd_seq_phys[i]); } - free_pages((ulong)instance->ctrl_context, - instance->ctrl_context_pages); + megasas_free_fusion_context(instance); } else { megasas_release_mfi(instance); pci_free_consistent(pdev, sizeof(u32), diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index c3ef82d..d9b0f28 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -489,7 +489,8 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance) if (instance->UnevenSpanSupport) mr_update_span_set(drv_map, ldSpanInfo); - mr_update_load_balance_params(drv_map, lbInfo); + if (lbInfo) + mr_update_load_balance_params(drv_map, lbInfo); num_lds = le16_to_cpu(drv_map->raidMap.ldCount); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 1252a3c..9019b82 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -2397,8 +2398,9 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, io_request->IoFlags |= cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH); } - if ((fusion->load_balance_info[device_id].loadBalanceFlag) && - (io_info.isRead)) { + if (fusion->load_balance_info && + (fusion->load_balance_info[device_id].loadBalanceFlag) && + (io_info.isRead)) { io_info.devHandle = get_updated_dev_handle(instance,
[PATCH v2 20/39] megaraid_sas: Big endian RDPQ mode fix
Fix if RDPQ mode enabled MR FW is deployed on big endian host machine, driver does not setup reply address correctly. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 4aaf307..b26ee85 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -580,7 +580,7 @@ megasas_alloc_rdpq_fusion(struct megasas_instance *instance) } fusion->rdpq_virt[i].RDPQBaseAddress = - fusion->reply_frames_desc_phys[i]; + cpu_to_le64(fusion->reply_frames_desc_phys[i]); reply_desc = fusion->reply_frames_desc[i]; for (j = 0; j < fusion->reply_q_depth; j++, reply_desc++) -- 2.8.3
[PATCH v2 19/39] megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map access
fix in v2 - updated description content. Change MR_TargetIdToLdGet return type from u8 to u16. ld id range check is added at two places in this patch - @megasas_build_ldio_fusion and @megasas_build_ld_nonrw_fusion. Previous driver code used different data type for lds TargetId returned from MR_TargetIdToLdGet. Prior to this change, above two functions was safeguarded due to function always return u8 and maximum value of ld id returned was 255. In below check, fw_supported_vd_count as of today is 64 or 256 and valid range to support is either 0-63 or 0-255. Ideally want to filter accessing raid map for ld ids which are not valid. With the u16 change, invalid ld id value is 0x and we will see kernel panic due to random memory access in MR_LdRaidGet. The changes will ensure we do not call MR_LdRaidGet if ld id is beyond size of ldSpanMap array. if (ld < instance->fw_supported_vd_count) >From firmware perspective,ld id 0xFF is invalid and even though current driver code forward such command, firmware fails with target not available. ld target id issue occurs mainly whenever driver loops to populate raid map (ea. MR_ValidateMapInfo). These are the only two places where we may see out of range target ids and wants to protect raid map access based on range provided by Firmware API. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas.h| 2 +- drivers/scsi/megaraid/megaraid_sas_fp.c | 5 +++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 25 ++--- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 0a20fff..efc01a3 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2448,7 +2448,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, struct IO_REQUEST_INFO *io_info, struct RAID_CONTEXT *pRAID_Context, struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN); -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map); +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map); struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL *map); u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map); u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map); diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index a0b0e68..9d5d485 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -165,7 +165,7 @@ u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map) return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId); } -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map) +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map) { return map->raidMap.ldTgtIdToLd[ldTgtId]; } @@ -1151,7 +1151,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, { struct fusion_context *fusion; struct MR_LD_RAID *raid; - u32 ld, stripSize, stripe_mask; + u32 stripSize, stripe_mask; u64 endLba, endStrip, endRow, start_row, start_strip; u64 regStart; u32 regSize; @@ -1163,6 +1163,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, u8 retval = 0; u8 startlba_span = SPAN_INVALID; u64 *pdBlock = &io_info->pdBlock; + u16 ld; ldStartBlock = io_info->ldStartBlock; numBlocks = io_info->numBlocks; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 9019b82..4aaf307 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1121,7 +1121,8 @@ megasas_sync_map_info(struct megasas_instance *instance) int i; struct megasas_cmd *cmd; struct megasas_dcmd_frame *dcmd; - u32 size_sync_info, num_lds; + u16 num_lds; + u32 size_sync_info; struct fusion_context *fusion; struct MR_LD_TARGET_SYNC *ci = NULL; struct MR_DRV_RAID_MAP_ALL *map; @@ -1870,7 +1871,7 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len, struct MR_DRV_RAID_MAP_ALL *local_map_ptr, u32 ref_tag) { struct MR_LD_RAID *raid; - u32 ld; + u16 ld; u64 start_blk = io_info->pdBlock; u8 *cdb = io_request->CDB.CDB32; u32 num_blocks = io_info->numBlocks; @@ -2303,10 +2304,11 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; ld = MR_TargetIdToLdGet(device_id, local_map_ptr); - raid = MR_LdRaidGet(ld, local_map_pt
[PATCH v2 12/39] megaraid_sas: NVME fast path io support
This patch provide true fast path IO support. Driver creates PRP for NVME drives and send Fast Path for performance. Certain h/w requirement needs to be taken care in driver. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 10 +- drivers/scsi/megaraid/megaraid_sas_fp.c | 55 +++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 316 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.h | 14 +- 4 files changed, 350 insertions(+), 45 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index a45ff10..075e2e9 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2172,6 +2172,11 @@ struct megasas_instance { atomic_t fw_outstanding; atomic_t ldio_outstanding; atomic_t fw_reset_no_pci_access; + atomic_t ieee_sgl; + atomic_t prp_sgl; + atomic_t sge_holes_type1; + atomic_t sge_holes_type2; + atomic_t sge_holes_type3; struct megasas_instance_template *instancet; struct tasklet_struct isr_tasklet; @@ -2443,7 +2448,9 @@ __le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map); u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map); __le16 get_updated_dev_handle(struct megasas_instance *instance, - struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *in_info); + struct LD_LOAD_BALANCE_INFO *lbInfo, + struct IO_REQUEST_INFO *in_info, + struct MR_DRV_RAID_MAP_ALL *drv_map); void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map, struct LD_LOAD_BALANCE_INFO *lbInfo); int megasas_get_ctrl_info(struct megasas_instance *instance); @@ -2472,4 +2479,5 @@ void megasas_update_sdev_properties(struct scsi_device *sdev); int megasas_reset_fusion(struct Scsi_Host *shost, int reason); int megasas_task_abort_fusion(struct scsi_cmnd *scmd); int megasas_reset_target_fusion(struct scsi_cmnd *scmd); +u32 mega_mod64(u64 dividend, u32 divisor); #endif /*LSI_MEGARAID_SAS_H */ diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 24258af..c3ef82d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -155,6 +155,11 @@ __le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map) return map->raidMap.devHndlInfo[pd].curDevHdl; } +static u8 MR_PdInterfaceTypeGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map) +{ + return map->raidMap.devHndlInfo[pd].interfaceType; +} + u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map) { return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId); @@ -929,6 +934,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, u8 retval = TRUE; u64 *pdBlock = &io_info->pdBlock; __le16 *pDevHandle = &io_info->devHandle; + u8 *pPdInterface = &io_info->pd_interface; u32 logArm, rowMod, armQ, arm; struct fusion_context *fusion; @@ -960,15 +966,18 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, if (pd != MR_PD_INVALID) { *pDevHandle = MR_PdDevHandleGet(pd, map); + *pPdInterface = MR_PdInterfaceTypeGet(pd, map); /* get second pd also for raid 1/10 fast path writes*/ - if (raid->level == 1) { + if (instance->is_ventura && + (raid->level == 1) && + !io_info->isRead) { r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map); if (r1_alt_pd != MR_PD_INVALID) io_info->r1_alt_dev_handle = MR_PdDevHandleGet(r1_alt_pd, map); } } else { - *pDevHandle = cpu_to_le16(MR_PD_INVALID); + *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); if ((raid->level >= 5) && ((fusion->adapter_type == THUNDERBOLT_SERIES) || ((fusion->adapter_type == INVADER_SERIES) && @@ -977,8 +986,10 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, else if (raid->level == 1) { physArm = physArm + 1; pd = MR_ArPdGet(arRef, physArm, map); - if (pd != MR_PD_INVALID) + if (pd != MR_PD_INVALID) { *pDevHandle = MR_PdDevHandleGet(pd, map); + *pPdInterface = MR_PdInterfaceTypeGet(pd, map); + }
[PATCH v2 28/39] megaraid_sas: megasas_return_cmd does not memset IO frame to zero
Memset the IO frame to zero after release. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h | 1 + drivers/scsi/megaraid/megaraid_sas_base.c | 10 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index efc01a3..508516d 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2238,6 +2238,7 @@ struct megasas_instance { u8 is_rdpq; bool dev_handle; bool fw_sync_cache_support; + u32 mfi_frame_size; bool is_ventura; bool msix_combined; u16 max_raid_mapsize; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 06001b4..30e390c 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -268,6 +268,8 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) cmd->scmd = NULL; cmd->frame_count = 0; cmd->flags = 0; + memset(cmd->frame, 0, instance->mfi_frame_size); + cmd->frame->io.context = cpu_to_le32(cmd->index); if (!fusion && reset_devices) cmd->frame->hdr.cmd = MFI_CMD_INVALID; list_add(&cmd->list, (&instance->cmd_pool)->next); @@ -3889,7 +3891,6 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) int i; u16 max_cmd; u32 sge_sz; - u32 total_sz; u32 frame_count; struct megasas_cmd *cmd; @@ -3917,12 +3918,13 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) * Total 192 byte (3 MFI frame of 64 byte) */ frame_count = instance->ctrl_context ? (3 + 1) : (15 + 1); - total_sz = MEGAMFI_FRAME_SIZE * frame_count; + instance->mfi_frame_size = MEGAMFI_FRAME_SIZE * frame_count; /* * Use DMA pool facility provided by PCI layer */ instance->frame_dma_pool = pci_pool_create("megasas frame pool", - instance->pdev, total_sz, 256, 0); + instance->pdev, instance->mfi_frame_size, + 256, 0); if (!instance->frame_dma_pool) { dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup frame pool\n"); @@ -3966,7 +3968,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) return -ENOMEM; } - memset(cmd->frame, 0, total_sz); + 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) -- 2.8.3
[PATCH v2 24/39] megaraid_sas: set pd_after_lb from MR_BuildRaidContext and initialize pDevHandle to MR_DEVHANDLE_INVALID
Issue is limited for Syncro firmware where pd_after_lb is not set but is accidentally used. Not a functional issue, but results in low performance due to improper load balancing between two LUNs. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fp.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 68582d9..a5517e7 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -948,6 +948,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, struct fusion_context *fusion; fusion = instance->ctrl_context; + *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); /*Get row and span from io_info for Uneven Span IO.*/ row = io_info->start_row; @@ -986,7 +987,6 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, MR_PdDevHandleGet(r1_alt_pd, map); } } else { - *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); if ((raid->level >= 5) && ((fusion->adapter_type == THUNDERBOLT_SERIES) || ((fusion->adapter_type == INVADER_SERIES) && @@ -1013,6 +1013,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; io_info->span_arm = pRAID_Context->span_arm; } + io_info->pd_after_lb = pd; return retval; } @@ -1049,7 +1050,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, struct fusion_context *fusion; fusion = instance->ctrl_context; - + *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); row = mega_div64_32(stripRow, raid->rowDataSize); @@ -1102,8 +1103,6 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, MR_PdDevHandleGet(r1_alt_pd, map); } } else { - /* set dev handle as invalid. */ - *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); if ((raid->level >= 5) && ((fusion->adapter_type == THUNDERBOLT_SERIES) || ((fusion->adapter_type == INVADER_SERIES) && @@ -1132,6 +1131,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; io_info->span_arm = pRAID_Context->span_arm; } + io_info->pd_after_lb = pd; return retval; } -- 2.8.3
[PATCH v2 15/39] megaraid_sas: enhance debug logs in OCR context
Add additional logging from driver in OCR context. Add debug logs for partial completion of IOs is iodone context. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 3 +++ drivers/scsi/megaraid/megaraid_sas_base.c | 38 ++--- drivers/scsi/megaraid/megaraid_sas_fusion.c | 35 +- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index bed8a37..93da6dc 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1405,6 +1405,9 @@ struct megasas_ctrl_info { #define VD_EXT_DEBUG 0 +/* Driver's internal Logging levels*/ +#define OCR_LOGS(1 << 0) + #define SCAN_PD_CHANNEL0x1 #define SCAN_VD_CHANNEL0x2 diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 51b35a6..b41bbea 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -2742,6 +2742,24 @@ blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd) } /** + * megasas_dump_frame -This function will dump MPT/MFI frame + */ +static inline void +megasas_dump_frame(void *mpi_request, int sz) +{ + int i; + __le32 *mfp = (__le32 *)mpi_request; + + printk(KERN_INFO "IO request frame:\n\t"); + for (i = 0; i < sz; i++) { + if (i && ((i % 8) == 0)) + printk("\n\t"); + printk("%08x ", le32_to_cpu(mfp[i])); + } + printk("\n"); +} + +/** * megasas_reset_bus_host -Bus & host reset handler entry point */ static int megasas_reset_bus_host(struct scsi_cmnd *scmd) @@ -2751,12 +2769,26 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd) instance = (struct megasas_instance *)scmd->device->host->hostdata; + scmd_printk(KERN_INFO, scmd, + "Controller reset is requested due to IO timeout\n" + "SCSI command pointer: (%p)\t SCSI host state: %d\t" + " SCSI host busy: %d\t FW outstanding: %d\n", + scmd, scmd->device->host->shost_state, + atomic_read((atomic_t *)&scmd->device->host->host_busy), + atomic_read(&instance->fw_outstanding)); + /* * First wait for all commands to complete */ - if (instance->ctrl_context) - ret = megasas_reset_fusion(scmd->device->host, 1); - else + if (instance->ctrl_context) { + struct megasas_cmd_fusion *cmd; + cmd = (struct megasas_cmd_fusion *)scmd->SCp.ptr; + if (cmd) + megasas_dump_frame(cmd->io_request, + sizeof(struct MPI2_RAID_SCSI_IO_REQUEST)); + ret = megasas_reset_fusion(scmd->device->host, + SCSIIO_TIMEOUT_OCR); + } else ret = megasas_generic_reset(scmd); return ret; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 4628671..1252a3c 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1445,8 +1445,10 @@ map_cmd_status(struct fusion_context *fusion, struct scsi_cmnd *scmd, u8 status, u8 ext_status, u32 data_length, u8 *sense) { + u8 cmd_type; int resid; + cmd_type = megasas_cmd_type(scmd); switch (status) { case MFI_STAT_OK: @@ -1477,6 +1479,13 @@ map_cmd_status(struct fusion_context *fusion, */ resid = (scsi_bufflen(scmd) - data_length); scsi_set_resid(scmd, resid); + + if (resid && + ((cmd_type == READ_WRITE_LDIO) || + (cmd_type == READ_WRITE_SYSPDIO))) + scmd_printk(KERN_INFO, scmd, "BRCM Debug mfi stat 0x%x, data len" + " requested/completed 0x%x/0x%x\n", + status, scsi_bufflen(scmd), data_length); break; case MFI_STAT_LD_OFFLINE: @@ -3477,6 +3486,14 @@ int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance, " will reset adapter scsi%d.\n", instance->host->host_no); megasas_complete_cmd_dpc_fusion((unsigned long)instance); + if (instance->requestorId && reason) { + dev_warn(&instance->pd
[PATCH v2 30/39] megaraid_sas: Do not set fp_possible if TM capable for non-RW syspdIO, change fp_possible to bool
FIX - firmware wants non-RW SYS PD IOs to avoid FastPath for better tracking and other functionalities if the device is task management capable. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 04a4c43..207df1e 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2566,7 +2566,8 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, */ static void megasas_build_syspd_fusion(struct megasas_instance *instance, - struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd, u8 fp_possible) + struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd, + bool fp_possible) { u32 device_id; struct MPI2_RAID_SCSI_IO_REQUEST *io_request; @@ -2687,6 +2688,8 @@ megasas_build_io_fusion(struct megasas_instance *instance, int sge_count; u8 cmd_type; struct MPI2_RAID_SCSI_IO_REQUEST *io_request = cmd->io_request; + struct MR_PRIV_DEVICE *mr_device_priv_data; + mr_device_priv_data = scp->device->hostdata; /* Zero out some fields so they don't get reused */ memset(io_request->LUN, 0x0, 8); @@ -2715,12 +2718,14 @@ megasas_build_io_fusion(struct megasas_instance *instance, megasas_build_ld_nonrw_fusion(instance, scp, cmd); break; case READ_WRITE_SYSPDIO: + megasas_build_syspd_fusion(instance, scp, cmd, true); + break; case NON_READ_WRITE_SYSPDIO: - if (instance->secure_jbod_support && - (cmd_type == NON_READ_WRITE_SYSPDIO)) - megasas_build_syspd_fusion(instance, scp, cmd, 0); + if (instance->secure_jbod_support || + mr_device_priv_data->is_tm_capable) + megasas_build_syspd_fusion(instance, scp, cmd, false); else - megasas_build_syspd_fusion(instance, scp, cmd, 1); + megasas_build_syspd_fusion(instance, scp, cmd, true); break; default: break; -- 2.8.3
[PATCH v2 10/39] megaraid_sas: NVME Interface detection and prop settings
New functionality Adding detection logic for NVME device attached behind Ventura controller. Driver set HostPageSize in IOC_INIT frame to inform about page size for NVME devices. Firmware reports NVME page size to the driver. PD INFO DCMD provide new interface type NVME_PD. Driver set property of NVME device. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas.h| 23 ++-- drivers/scsi/megaraid/megaraid_sas_base.c | 170 drivers/scsi/megaraid/megaraid_sas_fusion.c | 6 +- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 4 files changed, 142 insertions(+), 59 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index d9049d5..f9efddf 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -733,7 +733,6 @@ struct megasas_pd_list { u16 tid; u8 driveType; u8 driveState; - u8 interface; } __packed; /* @@ -1530,8 +1529,8 @@ struct megasas_register_set { u32 outbound_scratch_pad ; /*00B0h*/ u32 outbound_scratch_pad_2; /*00B4h*/ u32 outbound_scratch_pad_3; /*00B8h*/ + u32 outbound_scratch_pad_4; /*00BCh*/ - u32 reserved_4; /*00BCh*/ u32 inbound_low_queue_port ;/*00C0h*/ @@ -1864,6 +1863,7 @@ union megasas_frame { struct MR_PRIV_DEVICE { bool is_tm_capable; bool tm_busy; + u8 interface_type; }; struct megasas_cmd; @@ -2055,17 +2055,24 @@ struct MR_DRV_SYSTEM_INFO { }; enum MR_PD_TYPE { -UNKNOWN_DRIVE = 0, -PARALLEL_SCSI = 1, -SAS_PD = 2, -SATA_PD = 3, -FC_PD = 4, + UNKNOWN_DRIVE = 0, + PARALLEL_SCSI = 1, + SAS_PD = 2, + SATA_PD = 3, + FC_PD = 4, + NVME_PD = 5, }; /* JBOD Queue depth definitions */ #define MEGASAS_SATA_QD32 #define MEGASAS_SAS_QD 64 #define MEGASAS_DEFAULT_PD_QD 64 +#define MEGASAS_NVME_QD32 + +#define MR_DEFAULT_NVME_PAGE_SIZE 4096 +#define MR_DEFAULT_NVME_PAGE_SHIFT 12 +#define MR_DEFAULT_NVME_MDTS_KB128 +#define MR_NVME_PAGE_SIZE_MASK 0x00FF struct megasas_instance { @@ -2209,6 +2216,7 @@ struct megasas_instance { bool is_ventura; bool msix_combined; u16 max_raid_mapsize; + u32 nvme_page_size; }; struct MR_LD_VF_MAP { u32 size; @@ -2428,6 +2436,7 @@ int megasas_get_ctrl_info(struct megasas_instance *instance); /* PD sequence */ int megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend); +void megasas_set_dynamic_target_properties(struct scsi_device *sdev); int megasas_set_crash_dump_params(struct megasas_instance *instance, u8 crash_buf_state); void megasas_free_host_crash_buffer(struct megasas_instance *instance); diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 23fb78a..f383bf2 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -116,8 +116,8 @@ static int megasas_ld_list_query(struct megasas_instance *instance, static int megasas_issue_init_mfi(struct megasas_instance *instance); static int megasas_register_aen(struct megasas_instance *instance, u32 seq_num, u32 class_locale_word); -static int -megasas_get_pd_info(struct megasas_instance *instance, u16 device_id); +static void megasas_get_pd_info(struct megasas_instance *instance, + struct scsi_device *sdev); /* * PCI ID table for all supported controllers */ @@ -1738,16 +1738,21 @@ static struct megasas_instance *megasas_lookup_instance(u16 host_no) } /* -* megasas_update_sdev_properties - Update sdev structure based on controller's FW capabilities +* megasas_set_dynamic_target_properties - +* Device property set by driver may not be static and it is required to be +* updated after OCR +* +* set tm_capable. +* set dma alignment (only for eedp protection enable vd). * * @sdev: OS provided scsi device * * Returns void */ -void megasas_update_sdev_properties(struct scsi_device *sdev) +void megasas_set_dynamic_target_properties(struct scsi_device *sdev) { - u16 pd_index = 0; - u32 device_id, ld; + u16 pd_index = 0, ld; + u32 device_id; struct megasas_instance *instance; struct fusion_context *fusion; struct MR_PRIV_DEVICE *mr_device_priv_data; @@ -1772,57 +1777,102 @@ void megasas_update_sdev_properties(struct scsi_device *sdev) raid = MR_LdRaidGet(ld, local_map_ptr); if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER) - blk_queue_update_dma_alignm
[PATCH v2 33/39] megaraid_sas: Bail out the driver load if ld_list_query fails
Error handling: Bail out the driver load if key FW cmds (LD_LIST) are not return successful. Clean up error handling in megasas_init_fw. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 30e390c..0e7121d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5352,7 +5352,7 @@ static int megasas_init_fw(struct megasas_instance *instance) (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list))); if (megasas_get_pd_list(instance) < 0) { dev_err(&instance->pdev->dev, "failed to get PD list\n"); - goto fail_get_pd_list; + goto fail_get_ld_pd_list; } memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); @@ -5388,7 +5388,7 @@ static int megasas_init_fw(struct megasas_instance *instance) if (megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) - megasas_get_ld_list(instance); + goto fail_get_ld_pd_list; /* * Compute the max allowed sectors per IO: The controller info has two @@ -5507,8 +5507,6 @@ static int megasas_init_fw(struct megasas_instance *instance) fail_get_ld_pd_list: instance->instancet->disable_intr(instance); -fail_get_pd_list: - instance->instancet->disable_intr(instance); fail_init_adapter: megasas_destroy_irqs(instance); fail_setup_irqs: @@ -5520,9 +5518,11 @@ static int megasas_init_fw(struct megasas_instance *instance) instance->ctrl_info = NULL; iounmap(instance->reg_set); - fail_ioremap: +fail_ioremap: pci_release_selected_regions(instance->pdev, 1<bar); + dev_err(&instance->pdev->dev, "Failed from %s %d\n", + __func__, __LINE__); return -EINVAL; } -- 2.8.3
[PATCH v2 18/39] megaraid_sas: In validate raid map, raid capability is not converted to cpu format for all lds
On a host, if an ld is deleted there is a hole in the ld array returned by the FW. But in MR_ValidateMapInfo we are not accounting for holes in the ld array and traverse only upto index num_lds. This patch takes care of converting the capability field of all the valid lds in the ld raid map. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fp.c | 13 ++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index d9b0f28..a0b0e68 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -452,7 +452,7 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance) struct LD_LOAD_BALANCE_INFO *lbInfo; PLD_SPAN_INFO ldSpanInfo; struct MR_LD_RAID *raid; - u16 ldCount, num_lds; + u16 num_lds, i; u16 ld; u32 expected_size; @@ -495,10 +495,17 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance) num_lds = le16_to_cpu(drv_map->raidMap.ldCount); /*Convert Raid capability values to CPU arch */ - for (ldCount = 0; ldCount < num_lds; ldCount++) { - ld = MR_TargetIdToLdGet(ldCount, drv_map); + for (i = 0; (num_lds > 0) && (i < MAX_LOGICAL_DRIVES_EXT); i++) { + ld = MR_TargetIdToLdGet(i, drv_map); + + /* For non existing VDs, iterate to next VD*/ + if (ld >= (MAX_LOGICAL_DRIVES_EXT - 1)) + continue; + raid = MR_LdRaidGet(ld, drv_map); le32_to_cpus((u32 *)&raid->capability); + + num_lds--; } return 1; -- 2.8.3
[PATCH v2 23/39] megaraid_sas: latest controller OCR capability from FW before sending shutdown DCMD
Fetch the latest controller OCR capability from FW before sending MR_DCMD_CTRL_SHUTDOWN When application sends a shutdown DCMD (MR_DCMD_CTRL_SHUTDOWN), driver will fetch latest controller information from firmware. This is to ensure that driver always has latest OCR capability of controller before sending the DCMD. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 5d7aa05..cd9d223 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6900,6 +6900,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, MFI_FRAME_SGL64 | MFI_FRAME_SENSE64)); + if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_SHUTDOWN) { + if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) { + megasas_return_cmd(instance, cmd); + return -1; + } + } + if (cmd->frame->dcmd.opcode == MR_DRIVER_SET_APP_CRASHDUMP_MODE) { error = megasas_set_crash_dump_params_ioctl(cmd); megasas_return_cmd(instance, cmd); -- 2.8.3
[PATCH v2 22/39] megaraid_sas: avoid unaligned access in ioctl path
Fix kernel warning for accessing unaligned memory access in driver. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index b2da257..5d7aa05 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -7007,7 +7008,8 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw + ioc->sense_off); - if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)), + if (copy_to_user((void __user *)((unsigned long) +get_unaligned((unsigned long *)sense_ptr)), sense, ioc->sense_len)) { dev_err(&instance->pdev->dev, "Failed to copy out to user " "sense data\n"); -- 2.8.3
[PATCH v2 29/39] megaraid_sas: Remove unused pd_index from megasas_build_ld_nonrw_fusion
Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 9e2a289..04a4c43 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2480,7 +2480,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, { u32 device_id; struct MPI2_RAID_SCSI_IO_REQUEST *io_request; - u16 pd_index = 0, ld; + u16 ld; struct MR_DRV_RAID_MAP_ALL *local_map_ptr; struct fusion_context *fusion = instance->ctrl_context; u8 span, physArm; @@ -2492,7 +2492,6 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, io_request = cmd->io_request; device_id = MEGASAS_DEV_INDEX(scmd); - pd_index = MEGASAS_PD_INDEX(scmd); local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd)); /* get RAID_Context pointer */ -- 2.8.3
[PATCH v2 32/39] megaraid_sas: Change build_mpt_mfi_pass_thru to return void
Code refactoring to build_mpt_mfi_pass_thru to return void. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 10 ++ 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 00e52a3..b69200b 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3229,7 +3229,7 @@ irqreturn_t megasas_isr_fusion(int irq, void *devp) * mfi_cmd:megasas_cmd pointer * */ -u8 +void build_mpt_mfi_pass_thru(struct megasas_instance *instance, struct megasas_cmd *mfi_cmd) { @@ -3279,8 +3279,6 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance, MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR; mpi25_ieee_chain->Length = cpu_to_le32(instance->max_chain_frame_sz); - - return 0; } /** @@ -3295,11 +3293,7 @@ build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc = NULL; u16 index; - if (build_mpt_mfi_pass_thru(instance, cmd)) { - dev_err(&instance->pdev->dev, "Couldn't build MFI pass thru cmd\n"); - return NULL; - } - + build_mpt_mfi_pass_thru(instance, cmd); index = cmd->context.smid; req_desc = megasas_get_request_descriptor(instance, index - 1); -- 2.8.3
[PATCH v2 14/39] megaraid_sas: set residual bytes count during IO completion
Fixing issue of not setting residual bytes correctly. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index edbecc5..4628671 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1445,6 +1445,7 @@ map_cmd_status(struct fusion_context *fusion, struct scsi_cmnd *scmd, u8 status, u8 ext_status, u32 data_length, u8 *sense) { + int resid; switch (status) { @@ -1467,6 +1468,15 @@ map_cmd_status(struct fusion_context *fusion, SCSI_SENSE_BUFFERSIZE); scmd->result |= DRIVER_SENSE << 24; } + + /* +* If the IO request is partially completed, then MR FW will +* update "io_request->DataLength" field with actual number of +* bytes transferred.Driver will set residual bytes count in +* SCSI command structure. +*/ + resid = (scsi_bufflen(scmd) - data_length); + scsi_set_resid(scmd, resid); break; case MFI_STAT_LD_OFFLINE: -- 2.8.3
[PATCH v2 21/39] megaraid_sas: big endian support changes
Fix endiannes fixes for Ventura specific. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fp.c | 15 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 70 ++--- drivers/scsi/megaraid/megaraid_sas_fusion.h | 115 +--- 3 files changed, 122 insertions(+), 78 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 9d5d485..68582d9 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -210,7 +210,7 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) le32_to_cpu(fw_map_dyn->desc_table_size), le32_to_cpu(fw_map_dyn->desc_table_num_elements)); dev_dbg(&instance->pdev->dev, "drv map %p ldCount %d\n", - drv_map, fw_map_dyn->ld_count); + drv_map, le16_to_cpu(fw_map_dyn->ld_count)); #endif desc_table = (struct MR_RAID_MAP_DESC_TABLE *)((void *)fw_map_dyn + le32_to_cpu(fw_map_dyn->desc_table_offset)); @@ -222,7 +222,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count); pDrvRaidMap->fpPdIoTimeoutSec = fw_map_dyn->fp_pd_io_timeout_sec; - pDrvRaidMap->totalSize = sizeof(struct MR_DRV_RAID_MAP_ALL); + pDrvRaidMap->totalSize = + cpu_to_le32(sizeof(struct MR_DRV_RAID_MAP_ALL)); /* point to actual data starting point*/ raid_map_data = (void *)fw_map_dyn + le32_to_cpu(fw_map_dyn->desc_table_offset) + @@ -234,11 +235,11 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) dev_dbg(&instance->pdev->dev, "desc table %p\n", desc_table); dev_dbg(&instance->pdev->dev, "raidmap type %d, raidmapOffset 0x%x\n", - desc_table->raid_map_desc_type, - desc_table->raid_map_desc_offset); + le32_to_cpu(desc_table->raid_map_desc_type), + le32_to_cpu(desc_table->raid_map_desc_offset)); dev_dbg(&instance->pdev->dev, "raid map number of elements 0%x, raidmapsize 0x%x\n", - desc_table->raid_map_desc_elements, - desc_table->raid_map_desc_buffer_size); + le32_to_cpu(desc_table->raid_map_desc_elements), + le32_to_cpu(desc_table->raid_map_desc_buffer_size)); #endif switch (le32_to_cpu(desc_table->raid_map_desc_type)) { case RAID_MAP_DESC_TYPE_DEVHDL_INFO: @@ -263,7 +264,7 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) #endif for (j = 0; j < le32_to_cpu(desc_table->raid_map_desc_elements); j++) { pDrvRaidMap->ldTgtIdToLd[j] = - fw_map_dyn->ld_tgt_id_to_ld[j]; + le16_to_cpu(fw_map_dyn->ld_tgt_id_to_ld[j]); #if VD_EXT_DEBUG dev_dbg(&instance->pdev->dev, " %d drv ldTgtIdToLd %d\n", j, pDrvRaidMap->ldTgtIdToLd[j]); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index b26ee85..f8b4898 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2080,7 +2080,7 @@ static void megasas_stream_detect(struct megasas_instance *instance, */ continue; - cmd->io_request->RaidContext.raid_context_g35.stream_detected = true; + SET_STREAM_DETECTED(cmd->io_request->RaidContext.raid_context_g35); current_sd->next_seq_lba = io_info->ldStartBlock + io_info->numBlocks; /* @@ -2154,7 +2154,8 @@ megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context, /* Fast path cache by pass capable R0/R1 VD */ if ((raid->level <= 1) && (raid->capability.fp_cache_bypass_capable)) { - rctx_g35->routing_flags.bits.sld = 1; + rctx_g35->routing_flags |= + (1 << MR_RAID_CTX_ROUTINGFLAGS_SLD
[PATCH v2 26/39] megaraid_sas: update can_queue only if the new value is less
Minor Optimization: No need to update HBA can_queue value if the current max FW commands is equal to earlier value. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index b8591de..02a23d9 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -259,7 +259,7 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c if (fw_boot_context == OCR_CONTEXT) { cur_max_fw_cmds = cur_max_fw_cmds - 1; - if (cur_max_fw_cmds <= instance->max_fw_cmds) { + if (cur_max_fw_cmds < instance->max_fw_cmds) { instance->cur_can_queue = cur_max_fw_cmds - (MEGASAS_FUSION_INTERNAL_CMDS + MEGASAS_FUSION_IOCTL_CMDS); -- 2.8.3
[PATCH v2 31/39] megaraid_sas: During OCR, if get_ctrl_info fails do not continue with OCR
Error handling: If controller reset is not able to recover, kill HBA and quit immediately. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 207df1e..00e52a3 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -4285,6 +4285,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) __func__, __LINE__); megaraid_sas_kill_hba(instance); retval = FAILED; + goto out; } /* Reset load balance info */ if (fusion->load_balance_info) -- 2.8.3
[PATCH v2 37/39] megaraid_sas: Indentation and smatch warning fixes
Fix indentation issues and smatch warning reported by Dan Carpenter for previous series as discussed below. http://www.spinics.net/lists/linux-scsi/msg103635.html http://www.spinics.net/lists/linux-scsi/msg103603.html Reported-by: Dan Carpenter Signed-off-by: Kashyap Desai Signed-off-by: Sasikumar Chandrasekaran Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 2 +- drivers/scsi/megaraid/megaraid_sas_base.c | 10 ++-- drivers/scsi/megaraid/megaraid_sas_fp.c | 57 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 92 ++--- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 5 files changed, 80 insertions(+), 83 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index dc331e8..8c06cbf 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1376,7 +1376,7 @@ struct megasas_ctrl_info { u16 reserved:8; #endif } adapter_operations4; - u8 pad[0x800-0x7FE]; /* 0x7FE pad to 2K for expansion */ + u8 pad[0x800 - 0x7FE]; /* 0x7FE pad to 2K for expansion */ } __packed; /* diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 5e0dea1..dc9f42e 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5343,14 +5343,14 @@ 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) { + if (instance->is_ventura && fusion) { fusion->stream_detect_by_ld = - kzalloc(sizeof(struct LD_STREAM_DETECT *) - * MAX_LOGICAL_DRIVES_EXT, - GFP_KERNEL); + kzalloc(sizeof(struct LD_STREAM_DETECT *) + * MAX_LOGICAL_DRIVES_EXT, + GFP_KERNEL); if (!fusion->stream_detect_by_ld) { dev_err(&instance->pdev->dev, - "unable to allocate stream detection for pool of LDs\n"); + "unable to allocate stream detection for pool of LDs\n"); goto fail_get_ld_pd_list; } for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) { diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 7dc7708..62affa7 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -197,7 +197,7 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) memset(drv_map, 0, fusion->drv_map_sz); memset(pDrvRaidMap->ldTgtIdToLd, - 0xff, (sizeof(u16) * MAX_LOGICAL_DRIVES_DYN)); + 0xff, (sizeof(u16) * MAX_LOGICAL_DRIVES_DYN)); if (instance->max_raid_mapsize) { fw_map_dyn = fusion->ld_map[(instance->map_id & 1)]; @@ -224,34 +224,37 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) fw_map_dyn->dev_hndl_info = (struct MR_DEV_HANDLE_INFO *)(raid_map_data + le32_to_cpu(desc_table->raid_map_desc_offset)); memcpy(pDrvRaidMap->devHndlInfo, - fw_map_dyn->dev_hndl_info, - sizeof(struct MR_DEV_HANDLE_INFO) * - le32_to_cpu(desc_table->raid_map_desc_elements)); + fw_map_dyn->dev_hndl_info, + sizeof(struct MR_DEV_HANDLE_INFO) * + le32_to_cpu(desc_table->raid_map_desc_elements)); break; case RAID_MAP_DESC_TYPE_TGTID_INFO: fw_map_dyn->ld_tgt_id_to_ld = - (u16 *) (raid_map_data + - le32_to_cpu(desc_table->raid_map_desc_offset)); - for (j = 0; j < le32_to_cpu(desc_table->raid_map_desc_elements); j++) { - pDrvRaidMap->ldTgtIdToLd[j] = - le16_to_cpu(fw_map_dyn->ld_tgt_id_to_ld[j]); - } + (u16 *)(raid_map_data + + le32_to_cpu(desc_table->raid_map_desc_offset)); + for (j = 0; j < le32_to_cpu(desc_table->raid_map_desc_elements); j++) { + pDrvRaidMap->ldTgtIdToLd[j] = + le16_to_cpu(fw_map_dyn->ld_tgt_id_to_ld[j]); + } break; case RAID_MAP_DESC_TYPE_A
[PATCH v2 25/39] megaraid_sas: Change max_cmd from u32 to u16 in all functions
Since maximum supported FW commands are all defined as u16, change all local variables referring to max_cmd from u32 to u16. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 10 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index cd9d223..06001b4 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1549,7 +1549,7 @@ megasas_dump_pending_frames(struct megasas_instance *instance) struct megasas_io_frame *ldio; struct megasas_pthru_frame *pthru; u32 sgcount; - u32 max_cmd = instance->max_fw_cmds; + u16 max_cmd = instance->max_fw_cmds; dev_err(&instance->pdev->dev, "[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no); dev_err(&instance->pdev->dev, "[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding)); @@ -3467,7 +3467,7 @@ megasas_internal_reset_defer_cmds(struct megasas_instance *instance) { struct megasas_cmd *cmd; int i; - u32 max_cmd = instance->max_fw_cmds; + u16 max_cmd = instance->max_fw_cmds; u32 defer_index; unsigned long flags; @@ -3843,7 +3843,7 @@ megasas_transition_to_ready(struct megasas_instance *instance, int ocr) static void megasas_teardown_frame_pool(struct megasas_instance *instance) { int i; - u32 max_cmd = instance->max_mfi_cmds; + u16 max_cmd = instance->max_mfi_cmds; struct megasas_cmd *cmd; if (!instance->frame_dma_pool) @@ -3887,7 +3887,7 @@ static void megasas_teardown_frame_pool(struct megasas_instance *instance) static int megasas_create_frame_pool(struct megasas_instance *instance) { int i; - u32 max_cmd; + u16 max_cmd; u32 sge_sz; u32 total_sz; u32 frame_count; @@ -4021,7 +4021,7 @@ int megasas_alloc_cmds(struct megasas_instance *instance) { int i; int j; - u32 max_cmd; + u16 max_cmd; struct megasas_cmd *cmd; struct fusion_context *fusion; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index f8b4898..b8591de 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -367,7 +367,7 @@ megasas_free_cmds_fusion(struct megasas_instance *instance) static int megasas_create_sg_sense_fusion(struct megasas_instance *instance) { int i; - u32 max_cmd; + u16 max_cmd; struct fusion_context *fusion; struct megasas_cmd_fusion *cmd; @@ -1274,7 +1274,8 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) { struct megasas_register_set __iomem *reg_set; struct fusion_context *fusion; - u32 max_cmd, scratch_pad_2; + u16 max_cmd; + u32 scratch_pad_2; int i = 0, count; fusion = instance->ctrl_context; -- 2.8.3
[PATCH v2 34/39] megaraid_sas: Use synchronize_irq to wait for IRQs to complete
FIX - Do not use random delay to synchronize with IRQ. Use kernel API. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 20 ++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index b69200b..a9a6e5d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3145,6 +3145,22 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) } /** + * megasas_sync_irqs - Synchronizes all IRQs owned by adapter + * @instance: Adapter soft state + */ +void megasas_sync_irqs(unsigned long instance_addr) +{ + u32 count, i; + struct megasas_instance *instance = + (struct megasas_instance *)instance_addr; + + count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; + + for (i = 0; i < count; i++) + synchronize_irq(pci_irq_vector(instance->pdev, i)); +} + +/** * megasas_complete_cmd_dpc_fusion - Completes command * @instance: Adapter soft state * @@ -3820,7 +3836,7 @@ megasas_issue_tm(struct megasas_instance *instance, u16 device_handle, break; else { instance->instancet->disable_intr(instance); - msleep(1000); + megasas_sync_irqs((unsigned long)instance); megasas_complete_cmd_dpc_fusion ((unsigned long)instance); instance->instancet->enable_intr(instance); @@ -4174,7 +4190,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_POLLING); instance->instancet->disable_intr(instance); - msleep(1000); + megasas_sync_irqs((unsigned long)instance); /* First try waiting for commands to complete */ if (megasas_wait_for_outstanding_fusion(instance, reason, -- 2.8.3
[PATCH v2 36/39] megaraid_sas: Cleanup VD_EXT_DEBUG and SPAN_DEBUG related debug prints
Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 2 - drivers/scsi/megaraid/megaraid_sas_base.c | 15 -- drivers/scsi/megaraid/megaraid_sas_fp.c | 266 +--- drivers/scsi/megaraid/megaraid_sas_fusion.c | 5 - 4 files changed, 2 insertions(+), 286 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 42c0e1f..dc331e8 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1403,8 +1403,6 @@ struct megasas_ctrl_info { #define MEGASAS_FW_BUSY1 -#define VD_EXT_DEBUG 0 - /* Driver's internal Logging levels*/ #define OCR_LOGS(1 << 0) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 0e7121d..5e0dea1 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4601,17 +4601,6 @@ static void megasas_update_ext_vd_details(struct megasas_instance *instance) } /* irrespective of FW raid maps, driver raid map is constant */ fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP_ALL); - -#if VD_EXT_DEBUG - dev_info(&instance->pdev->dev, "instance->max_raid_mapsize 0x%x\n ", - instance->max_raid_mapsize); - dev_info(&instance->pdev->dev, "new_map_sz = 0x%x, old_map_sz = 0x%x\n", - fusion->new_map_sz, fusion->old_map_sz); - dev_info(&instance->pdev->dev, "ventura_map_sz = 0x%x, current_map_sz = 0x%x\n", - ventura_map_sz, fusion->current_map_sz); - dev_info(&instance->pdev->dev, "fusion->drv_map_sz =0x%x, size of driver raid map 0x%lx\n", - fusion->drv_map_sz, sizeof(struct MR_DRV_RAID_MAP_ALL)); -#endif } /** @@ -5215,10 +5204,6 @@ static int megasas_init_fw(struct megasas_instance *instance) if (instance->is_ventura) { scratch_pad_3 = readl(&instance->reg_set->outbound_scratch_pad_3); -#if VD_EXT_DEBUG - dev_info(&instance->pdev->dev, "scratch_pad3 0x%x\n", - scratch_pad_3); -#endif instance->max_raid_mapsize = ((scratch_pad_3 >> MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT) & MR_MAX_RAID_MAP_SIZE_MASK); diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index a5517e7..7dc7708 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -77,7 +77,6 @@ MODULE_PARM_DESC(lb_pending_cmds, "Change raid-1 load balancing outstanding " #endif #define TRUE 1 -#define SPAN_DEBUG 0 #define SPAN_ROW_SIZE(map, ld, index_) (MR_LdSpanPtrGet(ld, index_, map)->spanRowSize) #define SPAN_ROW_DATA_SIZE(map_, ld, index_) (MR_LdSpanPtrGet(ld, index_, map)->spanRowDataSize) #define SPAN_INVALID 0xff @@ -202,16 +201,6 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) if (instance->max_raid_mapsize) { fw_map_dyn = fusion->ld_map[(instance->map_id & 1)]; -#if VD_EXT_DEBUG - dev_dbg(&instance->pdev->dev, "raidMapSize 0x%x fw_map_dyn->descTableOffset 0x%x\n", - le32_to_cpu(fw_map_dyn->raid_map_size), - le32_to_cpu(fw_map_dyn->desc_table_offset)); - dev_dbg(&instance->pdev->dev, "descTableSize 0x%x descTableNumElements 0x%x\n", - le32_to_cpu(fw_map_dyn->desc_table_size), - le32_to_cpu(fw_map_dyn->desc_table_num_elements)); - dev_dbg(&instance->pdev->dev, "drv map %p ldCount %d\n", - drv_map, le16_to_cpu(fw_map_dyn->ld_count)); -#endif desc_table = (struct MR_RAID_MAP_DESC_TABLE *)((void *)fw_map_dyn + le32_to_cpu(fw_map_dyn->desc_table_offset)); if (desc_table != fw_map_dyn->raid_map_desc_table) @@ -230,25 +219,10 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) le32_to_cpu(fw_map_dyn->desc_table_size); for (i = 0; i < le32_to_cpu(fw_map_dyn->desc_table_num_elements); ++i) { - -#if VD_EXT_DEBUG - dev_dbg(&instance->pdev->dev, "desc table %p\n", - desc_table); - dev_dbg(&instance->pdev->dev, "raidmap type %d, raidmapOffset 0x%x\n", - le32_to_cpu(desc_table->raid_map_desc_type),
[PATCH v2 00/39] megaraid_sas: Updates for scsi-next
Changes in v2: Patch 3: Fix to update status and ex_status from failed r1_cmd Patch 8: Split into two separate patches, 1. megasas_get_request_descriptor will always return valid request descriptor 2. With above changes, issue_dcmd always return DCMD_SUCCESS. Change return type to void and update all callers. Patch 11: Update commit description, remove reference to dependent patch. Patch 12: Update with correct commit description Patch 14: Fix typo in commit description Patch 19: Correction to commit description Drop patch 33 of last patch series which added call for flush_scheduled_work Shivasharan S (39): Revert "scsi: megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth" megaraid_sas: cpu select rework. megaraid_sas: raid 1 fast path code optimize megaraid_sas: 32 bit descriptor fire cmd optimization megaraid_sas: Refactor MEGASAS_IS_LOGICAL macro using sdev megaraid_sas: RAID map is accessed for SYS PDs when use_seqnum_jbod_fp is not set megaraid_sas: Use DID_REQUEUE megaraid_sas: megasas_get_request_descriptor always return valid desc megaraid_sas: change issue_dcmd to return void from int megaraid_sas: NVME Interface detection and prop settings megaraid_sas: NVME interface target prop added megaraid_sas: NVME fast path io support megaraid_sas: raid 1 write performance for large io megaraid_sas: set residual bytes count during IO completion megaraid_sas: enhance debug logs in OCR context megaraid_sas: add print in device removal path megaraid_sas: reduce size of fusion_context and use vmalloc if kmalloc fails megaraid_sas: In validate raid map, raid capability is not converted to cpu format for all lds megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map access megaraid_sas: Big endian RDPQ mode fix megaraid_sas: big endian support changes megaraid_sas: avoid unaligned access in ioctl path megaraid_sas: latest controller OCR capability from FW before sending shutdown DCMD megaraid_sas: set pd_after_lb from MR_BuildRaidContext and initialize pDevHandle to MR_DEVHANDLE_INVALID megaraid_sas: Change max_cmd from u32 to u16 in all functions megaraid_sas: update can_queue only if the new value is less megaraid_sas: max_fw_cmds are decremented twice, remove duplicate megaraid_sas: megasas_return_cmd does not memset IO frame to zero megaraid_sas: Remove unused pd_index from megasas_build_ld_nonrw_fusion megaraid_sas: Do not set fp_possible if TM capable for non-RW syspdIO, change fp_possible to bool megaraid_sas: During OCR, if get_ctrl_info fails do not continue with OCR megaraid_sas: Change build_mpt_mfi_pass_thru to return void megaraid_sas: Bail out the driver load if ld_list_query fails megaraid_sas: Use synchronize_irq to wait for IRQs to complete megaraid_sas: Increase internal command pool megaraid_sas: Cleanup VD_EXT_DEBUG and SPAN_DEBUG related debug prints megaraid_sas: Indentation and smatch warning fixes megaraid_sas: Change RAID_1_10_RMW_CMDS to RAID_1_PEER_CMDS and set value to 2 megaraid_sas: driver version upgrade drivers/scsi/megaraid/megaraid_sas.h| 82 +- drivers/scsi/megaraid/megaraid_sas_base.c | 548 +++ drivers/scsi/megaraid/megaraid_sas_fp.c | 427 ++--- drivers/scsi/megaraid/megaraid_sas_fusion.c | 1352 --- drivers/scsi/megaraid/megaraid_sas_fusion.h | 144 ++- 5 files changed, 1434 insertions(+), 1119 deletions(-) -- 2.8.3
[PATCH v2 05/39] megaraid_sas: Refactor MEGASAS_IS_LOGICAL macro using sdev
Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 4 ++-- drivers/scsi/megaraid/megaraid_sas_base.c | 20 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 12 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index f5c4742..dff877f 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2301,8 +2301,8 @@ struct megasas_instance_template { struct megasas_cmd *cmd); }; -#define MEGASAS_IS_LOGICAL(scp) \ - ((scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1) +#define MEGASAS_IS_LOGICAL(sdev) \ + ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1) #define MEGASAS_DEV_INDEX(scp) \ (((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \ diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 3ed876a..6ca49ef 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1279,7 +1279,7 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, u16 flags = 0; struct megasas_pthru_frame *pthru; - is_logical = MEGASAS_IS_LOGICAL(scp); + is_logical = MEGASAS_IS_LOGICAL(scp->device); device_id = MEGASAS_DEV_INDEX(scp); pthru = (struct megasas_pthru_frame *)cmd->frame; @@ -1519,11 +1519,11 @@ inline int megasas_cmd_type(struct scsi_cmnd *cmd) case WRITE_6: case READ_16: case WRITE_16: - ret = (MEGASAS_IS_LOGICAL(cmd)) ? + ret = (MEGASAS_IS_LOGICAL(cmd->device)) ? READ_WRITE_LDIO : READ_WRITE_SYSPDIO; break; default: - ret = (MEGASAS_IS_LOGICAL(cmd)) ? + ret = (MEGASAS_IS_LOGICAL(cmd->device)) ? NON_READ_WRITE_LDIO : NON_READ_WRITE_SYSPDIO; } return ret; @@ -1699,15 +1699,16 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) scmd->result = 0; - if (MEGASAS_IS_LOGICAL(scmd) && + if (MEGASAS_IS_LOGICAL(scmd->device) && (scmd->device->id >= instance->fw_supported_vd_count || scmd->device->lun)) { scmd->result = DID_BAD_TARGET << 16; goto out_done; } - if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) && MEGASAS_IS_LOGICAL(scmd) && - (!instance->fw_sync_cache_support)) { + if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) && + MEGASAS_IS_LOGICAL(scmd->device) && + (!instance->fw_sync_cache_support)) { scmd->result = DID_OK << 16; goto out_done; } @@ -1758,7 +1759,7 @@ void megasas_update_sdev_properties(struct scsi_device *sdev) if (!fusion) return; - if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && + if (!MEGASAS_IS_LOGICAL(sdev) && instance->use_seqnum_jbod_fp) { pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id; @@ -1826,8 +1827,7 @@ static int megasas_slave_configure(struct scsi_device *sdev) instance = megasas_lookup_instance(sdev->host->host_no); if (instance->pd_list_not_supported) { - if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && - sdev->type == TYPE_DISK) { + if (!MEGASAS_IS_LOGICAL(sdev) && sdev->type == TYPE_DISK) { pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id; if (instance->pd_list[pd_index].driveState != @@ -1854,7 +1854,7 @@ static int megasas_slave_alloc(struct scsi_device *sdev) struct MR_PRIV_DEVICE *mr_device_priv_data; instance = megasas_lookup_instance(sdev->host->host_no); - if (sdev->channel < MEGASAS_MAX_PD_CHANNELS) { + if (!MEGASAS_IS_LOGICAL(sdev)) { /* * Open the OS scan to the SYSTEM PD */ diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 24b72c5..675afc9 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3581,13 +3581,13 @@ static u16 megasas_get_tm_devhandle(struct scsi_device *sdev) instance = (struct m
[PATCH v2 01/39] Revert "scsi: megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth"
This reverts commit "3e5eadb1a881" ("scsi: megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth") This patch was aimed to increase performance of R1 Write operation for large IO size. Since this method used timer approach, it turn on/off fast path did not work as expected. Patch 0013 describes new algorithm and performance number. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 8 - drivers/scsi/megaraid/megaraid_sas_base.c | 48 - drivers/scsi/megaraid/megaraid_sas_fp.c | 7 - drivers/scsi/megaraid/megaraid_sas_fusion.c | 16 -- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 5 files changed, 7 insertions(+), 74 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index ba9fbb7..f5c4742 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1477,8 +1477,6 @@ enum FW_BOOT_CONTEXT { #define MFI_1068_FW_HANDSHAKE_OFFSET 0x64 #define MFI_1068_FW_READY 0x -#define MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL HZ - #define MR_MAX_REPLY_QUEUES_OFFSET 0X001F #define MR_MAX_REPLY_QUEUES_EXT_OFFSET 0X003FC000 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT14 @@ -2154,10 +2152,6 @@ struct megasas_instance { atomic_t ldio_outstanding; atomic_t fw_reset_no_pci_access; - atomic64_t bytes_wrote; /* used for raid1 fast path enable or disable */ - atomic_t r1_write_fp_capable; - - struct megasas_instance_template *instancet; struct tasklet_struct isr_tasklet; struct work_struct work_init; @@ -2199,7 +2193,6 @@ struct megasas_instance { long reset_flags; struct mutex reset_mutex; struct timer_list sriov_heartbeat_timer; - struct timer_list r1_fp_hold_timer; char skip_heartbeat_timer_del; u8 requestorId; char PlasmaFW111; @@ -2216,7 +2209,6 @@ struct megasas_instance { bool is_ventura; bool msix_combined; u16 max_raid_mapsize; - u64 pci_threshold_bandwidth; /* used to control the fp writes */ }; 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 70891a7..3ed876a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1940,9 +1940,6 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance) } /* Complete outstanding ioctls when adapter is killed */ megasas_complete_outstanding_ioctls(instance); - if (instance->is_ventura) - del_timer_sync(&instance->r1_fp_hold_timer); - } /** @@ -2441,24 +2438,6 @@ void megasas_sriov_heartbeat_handler(unsigned long instance_addr) } } -/*Handler for disabling/enabling raid 1 fast paths*/ -void megasas_change_r1_fp_status(unsigned long instance_addr) -{ - struct megasas_instance *instance = - (struct megasas_instance *)instance_addr; - if (atomic64_read(&instance->bytes_wrote) >= - instance->pci_threshold_bandwidth) { - - atomic64_set(&instance->bytes_wrote, 0); - atomic_set(&instance->r1_write_fp_capable, 0); - } else { - atomic64_set(&instance->bytes_wrote, 0); - atomic_set(&instance->r1_write_fp_capable, 1); - } - mod_timer(&instance->r1_fp_hold_timer, -jiffies + MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); -} - /** * megasas_wait_for_outstanding - Wait for all outstanding cmds * @instance: Adapter soft state @@ -5386,17 +5365,6 @@ static int megasas_init_fw(struct megasas_instance *instance) instance->skip_heartbeat_timer_del = 1; } - if (instance->is_ventura) { - atomic64_set(&instance->bytes_wrote, 0); - atomic_set(&instance->r1_write_fp_capable, 1); - megasas_start_timer(instance, - &instance->r1_fp_hold_timer, - megasas_change_r1_fp_status, - MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); - dev_info(&instance->pdev->dev, "starting the raid 1 fp timer with interval %d\n", - MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); - } - return 0; fail_get_ld_pd_list: @@ -6187,9 +6155,6 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) if (instance->requestorId && !instance->skip_heartbeat_timer_del)
[PATCH v2 39/39] megaraid_sas: driver version upgrade
Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 8c06cbf..e7e5974 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.700.00.00-rc1" -#define MEGASAS_RELDATE"November 29, 2016" +#define MEGASAS_VERSION"07.701.16.00-rc1" +#define MEGASAS_RELDATE"February 2, 2017" /* * Device IDs -- 2.8.3
[PATCH v2 35/39] megaraid_sas: Increase internal command pool
Fix - increase internal command pool to 8. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 2 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 508516d..42c0e1f 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1460,7 +1460,7 @@ enum FW_BOOT_CONTEXT { */ #define MEGASAS_INT_CMDS 32 #define MEGASAS_SKINNY_INT_CMDS5 -#define MEGASAS_FUSION_INTERNAL_CMDS 5 +#define MEGASAS_FUSION_INTERNAL_CMDS 8 #define MEGASAS_FUSION_IOCTL_CMDS 3 #define MEGASAS_MFI_IOCTL_CMDS 27 diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index a9a6e5d..d8877c0 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1350,7 +1350,7 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) fusion->last_reply_idx[i] = 0; /* -* For fusion adapters, 3 commands for IOCTL and 5 commands +* For fusion adapters, 3 commands for IOCTL and 8 commands * for driver's internal DCMDs. */ instance->max_scsi_cmds = instance->max_fw_cmds - -- 2.8.3
[PATCH v2 38/39] megaraid_sas: Change RAID_1_10_RMW_CMDS to RAID_1_PEER_CMDS and set value to 2
For RAID1 FastPath writes, driver needs to allocate extra commands internally to accommodate for the extra peer command being sent. Currently driver is allocating 2 extra commands for each but only one extra command is necessary. Set RAID_1_10_RMW_CMDS to 2 and also change macro name to RAID_1_PEER_CMDS. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index abd11c3..3f198b5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -293,7 +293,7 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c if (instance->is_ventura) instance->max_mpt_cmds = - instance->max_fw_cmds * RAID_1_10_RMW_CMDS; + instance->max_fw_cmds * RAID_1_PEER_CMDS; else instance->max_mpt_cmds = instance->max_fw_cmds; } diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index 60566e4..c36f9f7 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -101,7 +101,7 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE { #define MEGASAS_FP_CMD_LEN 16 #define MEGASAS_FUSION_IN_RESET 0 #define THRESHOLD_REPLY_COUNT 50 -#define RAID_1_10_RMW_CMDS 3 +#define RAID_1_PEER_CMDS 2 #define JBOD_MAPS_COUNT2 enum MR_FUSION_ADAPTER_TYPE { -- 2.8.3
[PATCH v2 06/39] megaraid_sas: RAID map is accessed for SYS PDs when use_seqnum_jbod_fp is not set
Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas_base.c | 25 ++--- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 6ca49ef..67a205a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1756,28 +1756,31 @@ void megasas_update_sdev_properties(struct scsi_device *sdev) fusion = instance->ctrl_context; mr_device_priv_data = sdev->hostdata; - if (!fusion) + if (!fusion || !mr_device_priv_data) return; - if (!MEGASAS_IS_LOGICAL(sdev) && - instance->use_seqnum_jbod_fp) { - pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + - sdev->id; - pd_sync = (void *)fusion->pd_seq_sync - [(instance->pd_seq_map_id - 1) & 1]; - mr_device_priv_data->is_tm_capable = - pd_sync->seq[pd_index].capability.tmCapable; - } else { + if (MEGASAS_IS_LOGICAL(sdev)) { device_id = ((sdev->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id; local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; ld = MR_TargetIdToLdGet(device_id, local_map_ptr); + if (ld >= instance->fw_supported_vd_count) + return; raid = MR_LdRaidGet(ld, local_map_ptr); if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER) - blk_queue_update_dma_alignment(sdev->request_queue, 0x7); + blk_queue_update_dma_alignment(sdev->request_queue, + 0x7); + mr_device_priv_data->is_tm_capable = raid->capability.tmCapable; + } else if (instance->use_seqnum_jbod_fp) { + pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + + sdev->id; + pd_sync = (void *)fusion->pd_seq_sync + [(instance->pd_seq_map_id - 1) & 1]; + mr_device_priv_data->is_tm_capable = + pd_sync->seq[pd_index].capability.tmCapable; } } -- 2.8.3
[PATCH v2 08/39] megaraid_sas: megasas_get_request_descriptor always return valid desc
fix in v2 - split patches into two. discussed below http://marc.info/?l=linux-scsi&m=148638999110404&w=2 No functional change. Code clean up. Removing error code which is not valid scenario. In megasas_get_request_descriptor we can remove the error handling which is not required. With fusion controllers, if there is a valid message frame available, we are guaranteed to get a corresponding request descriptor. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 24 ++-- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 6ec7a18..b6c5dc5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2438,18 +2438,12 @@ megasas_build_io_fusion(struct megasas_instance *instance, return 0; } -union MEGASAS_REQUEST_DESCRIPTOR_UNION * +static union MEGASAS_REQUEST_DESCRIPTOR_UNION * megasas_get_request_descriptor(struct megasas_instance *instance, u16 index) { u8 *p; struct fusion_context *fusion; - if (index >= instance->max_mpt_cmds) { - dev_err(&instance->pdev->dev, "Invalid SMID (0x%x)request for " - "descriptor for scsi%d\n", index, - instance->host->host_no); - return NULL; - } fusion = instance->ctrl_context; p = fusion->req_frames_desc + sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) * index; @@ -2960,7 +2954,7 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance, union MEGASAS_REQUEST_DESCRIPTOR_UNION * build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) { - union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; + union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc = NULL; u16 index; if (build_mpt_mfi_pass_thru(instance, cmd)) { @@ -2972,9 +2966,6 @@ build_mpt_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) req_desc = megasas_get_request_descriptor(instance, index - 1); - if (!req_desc) - return NULL; - req_desc->Words = 0; req_desc->SCSIIO.RequestFlags = (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); @@ -2997,11 +2988,6 @@ megasas_issue_dcmd_fusion(struct megasas_instance *instance, union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; req_desc = build_mpt_cmd(instance, cmd); - if (!req_desc) { - dev_info(&instance->pdev->dev, "Failed from %s %d\n", - __func__, __LINE__); - return DCMD_NOT_FIRED; - } megasas_fire_cmd_fusion(instance, req_desc); return DCMD_SUCCESS; @@ -3438,12 +3424,6 @@ megasas_issue_tm(struct megasas_instance *instance, u16 device_handle, req_desc = megasas_get_request_descriptor(instance, (cmd_fusion->index - 1)); - if (!req_desc) { - dev_err(&instance->pdev->dev, "Failed from %s %d\n", - __func__, __LINE__); - megasas_return_cmd(instance, cmd_mfi); - return -ENOMEM; - } cmd_fusion->request_desc = req_desc; req_desc->Words = 0; -- 2.8.3
[PATCH v2 02/39] megaraid_sas: cpu select rework.
No functional change. Code refactor. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 175 1 file changed, 100 insertions(+), 75 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 54728b3..514c306 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1819,6 +1819,73 @@ static void megasas_stream_detect(struct megasas_instance *instance, } /** + * megasas_set_raidflag_cpu_affinity - This function sets the cpu + * affinity (cpu of the controller) and raid_flags in the raid context + * based on IO type. + * + * @praid_context: IO RAID context + * @raid: LD raid map + * @fp_possible: Is fast path possible? + * @is_read: Is read IO? + * + */ +static void +megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context, + struct MR_LD_RAID *raid, bool fp_possible, + u8 is_read) +{ + u8 cpu_sel = MR_RAID_CTX_CPUSEL_0; + struct RAID_CONTEXT_G35 *rctx_g35; + + rctx_g35 = &praid_context->raid_context_g35; + if (fp_possible) { + if (is_read) { + if ((raid->cpuAffinity.pdRead.cpu0) && + (raid->cpuAffinity.pdRead.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.pdRead.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + } else { + if ((raid->cpuAffinity.pdWrite.cpu0) && + (raid->cpuAffinity.pdWrite.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.pdWrite.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + /* Fast path cache by pass capable R0/R1 VD */ + if ((raid->level <= 1) && + (raid->capability.fp_cache_bypass_capable)) { + rctx_g35->routing_flags.bits.sld = 1; + rctx_g35->raid_flags = + (MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS + << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT); + } + } + } else { + if (is_read) { + if ((raid->cpuAffinity.ldRead.cpu0) && + (raid->cpuAffinity.ldRead.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.ldRead.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + } else { + if ((raid->cpuAffinity.ldWrite.cpu0) && + (raid->cpuAffinity.ldWrite.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.ldWrite.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + + if (rctx_g35->stream_detected && + (raid->level == 5) && + (raid->writeMode == MR_RL_WRITE_THROUGH_MODE) && + (cpu_sel == MR_RAID_CTX_CPUSEL_FCFS)) + cpu_sel = MR_RAID_CTX_CPUSEL_0; + } + } + + rctx_g35->routing_flags.bits.cpu_sel = cpu_sel; +} + +/** * megasas_build_ldio_fusion - Prepares IOs to devices * @instance: Adapter soft state * @scp: SCSI command @@ -1832,8 +1899,10 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, struct scsi_cmnd *scp, struct megasas_cmd_fusion *cmd) { - u8 fp_possible; - u32 start_lba_lo, start_lba_hi, device_id, datalength = 0, ld; + bool fp_possible; + u16 ld; + u32 start_lba_lo, start_lba_hi, device_id, datalength = 0; + u32 scsi_buff_len; struct MPI2_RAID_SCSI_IO_REQUEST *io_request; union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; struct IO_REQUEST_INFO io_info; @@ -1842,7 +1911,8 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, u8 *raidLUN; unsigned long spinlock_flags; union RAID_CONTEXT_UNION *praid_context; - struct MR_LD_RAID *raid; + struct MR_LD_RAID *raid = NULL; + struct MR_PRIV_DEVICE *mrdev_priv; device_id = MEGASAS_DEV_INDEX(scp); @@ -1858,7 +1928,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
[PATCH v2 07/39] megaraid_sas: Use DID_REQUEUE
Moving to use DID_REQUEUE return type for reliable unconditional retries. Driver wants unconditional re-queue, so replace DID_RESET with DID_REQUEUE Discussed below - https://www.spinics.net/lists/linux-scsi/msg102848.html Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 4 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 67a205a..80fcdf5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1668,7 +1668,7 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) /* Check for an mpio path and adjust behavior */ if (atomic_read(&instance->adprecovery) == MEGASAS_ADPRESET_SM_INFAULT) { if (megasas_check_mpio_paths(instance, scmd) == - (DID_RESET << 16)) { + (DID_REQUEUE << 16)) { return SCSI_MLQUEUE_HOST_BUSY; } else { scmd->result = DID_NO_CONNECT << 16; @@ -2492,7 +2492,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) struct megasas_cmd, list); list_del_init(&reset_cmd->list); if (reset_cmd->scmd) { - reset_cmd->scmd->result = DID_RESET << 16; + reset_cmd->scmd->result = DID_REQUEUE << 16; dev_notice(&instance->pdev->dev, "%d:%p reset [%02x]\n", reset_index, reset_cmd, reset_cmd->scmd->cmnd[0]); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 675afc9..6ec7a18 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3770,7 +3770,7 @@ int megasas_check_mpio_paths(struct megasas_instance *instance, struct scsi_cmnd *scmd) { struct megasas_instance *peer_instance = NULL; - int retval = (DID_RESET << 16); + int retval = (DID_REQUEUE << 16); if (instance->peerIsPresent) { peer_instance = megasas_get_peer_instance(instance); -- 2.8.3
[PATCH v2 04/39] megaraid_sas: 32 bit descriptor fire cmd optimization
No functional change. Code refactor. megasas_fire_cmd_fusion can always use 32 bit descriptor write for ventura. No need to pass extra flag. Only IOC INIT required 64 bit Descriptor write. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 65 +++-- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 7516589..24b72c5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -188,40 +188,35 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance, /** * megasas_fire_cmd_fusion - Sends command to the FW + * @instance: Adapter soft state + * @req_desc: 32bit or 64bit Request descriptor + * + * Perform PCI Write. Ventura supports 32 bit Descriptor. + * Prior to Ventura (12G) MR controller supports 64 bit Descriptor. */ + static void megasas_fire_cmd_fusion(struct megasas_instance *instance, - union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc, bool is_32bit) + union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc) { - struct megasas_register_set __iomem *regs = instance->reg_set; - unsigned long flags; - - if (is_32bit) + if (instance->is_ventura) writel(le32_to_cpu(req_desc->u.low), - &(regs)->inbound_single_queue_port); - else if (instance->is_ventura) { + &instance->reg_set->inbound_single_queue_port); + else { +#if defined(writeq) && defined(CONFIG_64BIT) + u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) | + le32_to_cpu(req_desc->u.low)); + + writeq(req_data, &instance->reg_set->inbound_low_queue_port); +#else + unsigned long flags; spin_lock_irqsave(&instance->hba_lock, flags); writel(le32_to_cpu(req_desc->u.low), - &(regs)->inbound_low_queue_port); + &instance->reg_set->inbound_low_queue_port); writel(le32_to_cpu(req_desc->u.high), - &(regs)->inbound_high_queue_port); + &instance->reg_set->inbound_high_queue_port); mmiowb(); spin_unlock_irqrestore(&instance->hba_lock, flags); - } else { -#if defined(writeq) && defined(CONFIG_64BIT) - u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) | - le32_to_cpu(req_desc->u.low)); - - writeq(req_data, &instance->reg_set->inbound_low_queue_port); -#else - - spin_lock_irqsave(&instance->hba_lock, flags); - writel(le32_to_cpu(req_desc->u.low), - &instance->reg_set->inbound_low_queue_port); - writel(le32_to_cpu(req_desc->u.high), - &instance->reg_set->inbound_high_queue_port); - mmiowb(); - spin_unlock_irqrestore(&instance->hba_lock, flags); #endif } } @@ -771,6 +766,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) const char *sys_info; MFI_CAPABILITIES *drv_ops; u32 scratch_pad_2; + unsigned long flags; fusion = instance->ctrl_context; @@ -897,7 +893,14 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) break; } - megasas_fire_cmd_fusion(instance, &req_desc, false); + /* For Ventura also IOC INIT required 64 bit Descriptor write. */ + spin_lock_irqsave(&instance->hba_lock, flags); + writel(le32_to_cpu(req_desc.u.low), + &instance->reg_set->inbound_low_queue_port); + writel(le32_to_cpu(req_desc.u.high), + &instance->reg_set->inbound_high_queue_port); + mmiowb(); + spin_unlock_irqrestore(&instance->hba_lock, flags); wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS); @@ -2577,11 +2580,10 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, * Issue the command to the FW */ - megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura); + megasas_fire_cmd_fusion(instance, req_desc); if (r1_cmd) - megasas_fire_cmd_fusion(instance, r1_cmd->request_desc, - instance->is_ventura); + megasas_fire_cmd_fusion(instance, r1_cmd->request_desc); return 0; @@ -3001,7 +3003,7 @@ megasas_issue_dcmd_fusion(struct megasas_instance *instance, return DCMD_NOT_FIRED; } - meg
[PATCH v3 12/39] megaraid_sas: NVME fast path io support
This patch provide true fast path IO support. Driver creates PRP for NVME drives and send Fast Path for performance. Certain h/w requirement needs to be taken care in driver. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 10 +- drivers/scsi/megaraid/megaraid_sas_fp.c | 55 +++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 316 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.h | 14 +- 4 files changed, 350 insertions(+), 45 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index a45ff10..075e2e9 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2172,6 +2172,11 @@ struct megasas_instance { atomic_t fw_outstanding; atomic_t ldio_outstanding; atomic_t fw_reset_no_pci_access; + atomic_t ieee_sgl; + atomic_t prp_sgl; + atomic_t sge_holes_type1; + atomic_t sge_holes_type2; + atomic_t sge_holes_type3; struct megasas_instance_template *instancet; struct tasklet_struct isr_tasklet; @@ -2443,7 +2448,9 @@ __le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map); u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map); __le16 get_updated_dev_handle(struct megasas_instance *instance, - struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *in_info); + struct LD_LOAD_BALANCE_INFO *lbInfo, + struct IO_REQUEST_INFO *in_info, + struct MR_DRV_RAID_MAP_ALL *drv_map); void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map, struct LD_LOAD_BALANCE_INFO *lbInfo); int megasas_get_ctrl_info(struct megasas_instance *instance); @@ -2472,4 +2479,5 @@ void megasas_update_sdev_properties(struct scsi_device *sdev); int megasas_reset_fusion(struct Scsi_Host *shost, int reason); int megasas_task_abort_fusion(struct scsi_cmnd *scmd); int megasas_reset_target_fusion(struct scsi_cmnd *scmd); +u32 mega_mod64(u64 dividend, u32 divisor); #endif /*LSI_MEGARAID_SAS_H */ diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 24258af..c3ef82d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -155,6 +155,11 @@ __le16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map) return map->raidMap.devHndlInfo[pd].curDevHdl; } +static u8 MR_PdInterfaceTypeGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map) +{ + return map->raidMap.devHndlInfo[pd].interfaceType; +} + u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map) { return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId); @@ -929,6 +934,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, u8 retval = TRUE; u64 *pdBlock = &io_info->pdBlock; __le16 *pDevHandle = &io_info->devHandle; + u8 *pPdInterface = &io_info->pd_interface; u32 logArm, rowMod, armQ, arm; struct fusion_context *fusion; @@ -960,15 +966,18 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, if (pd != MR_PD_INVALID) { *pDevHandle = MR_PdDevHandleGet(pd, map); + *pPdInterface = MR_PdInterfaceTypeGet(pd, map); /* get second pd also for raid 1/10 fast path writes*/ - if (raid->level == 1) { + if (instance->is_ventura && + (raid->level == 1) && + !io_info->isRead) { r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map); if (r1_alt_pd != MR_PD_INVALID) io_info->r1_alt_dev_handle = MR_PdDevHandleGet(r1_alt_pd, map); } } else { - *pDevHandle = cpu_to_le16(MR_PD_INVALID); + *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); if ((raid->level >= 5) && ((fusion->adapter_type == THUNDERBOLT_SERIES) || ((fusion->adapter_type == INVADER_SERIES) && @@ -977,8 +986,10 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, else if (raid->level == 1) { physArm = physArm + 1; pd = MR_ArPdGet(arRef, physArm, map); - if (pd != MR_PD_INVALID) + if (pd != MR_PD_INVALID) { *pDevHandle = MR_PdDevHandleGet(pd, map); + *pPdInterface = MR_PdInterfaceTypeGet(pd, map); + }
[PATCH v3 28/39] megaraid_sas: megasas_return_cmd does not memset IO frame to zero
Memset the IO frame to zero after release. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h | 1 + drivers/scsi/megaraid/megaraid_sas_base.c | 10 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index efc01a3..508516d 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2238,6 +2238,7 @@ struct megasas_instance { u8 is_rdpq; bool dev_handle; bool fw_sync_cache_support; + u32 mfi_frame_size; bool is_ventura; bool msix_combined; u16 max_raid_mapsize; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 06001b4..30e390c 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -268,6 +268,8 @@ megasas_return_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) cmd->scmd = NULL; cmd->frame_count = 0; cmd->flags = 0; + memset(cmd->frame, 0, instance->mfi_frame_size); + cmd->frame->io.context = cpu_to_le32(cmd->index); if (!fusion && reset_devices) cmd->frame->hdr.cmd = MFI_CMD_INVALID; list_add(&cmd->list, (&instance->cmd_pool)->next); @@ -3889,7 +3891,6 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) int i; u16 max_cmd; u32 sge_sz; - u32 total_sz; u32 frame_count; struct megasas_cmd *cmd; @@ -3917,12 +3918,13 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) * Total 192 byte (3 MFI frame of 64 byte) */ frame_count = instance->ctrl_context ? (3 + 1) : (15 + 1); - total_sz = MEGAMFI_FRAME_SIZE * frame_count; + instance->mfi_frame_size = MEGAMFI_FRAME_SIZE * frame_count; /* * Use DMA pool facility provided by PCI layer */ instance->frame_dma_pool = pci_pool_create("megasas frame pool", - instance->pdev, total_sz, 256, 0); + instance->pdev, instance->mfi_frame_size, + 256, 0); if (!instance->frame_dma_pool) { dev_printk(KERN_DEBUG, &instance->pdev->dev, "failed to setup frame pool\n"); @@ -3966,7 +3968,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) return -ENOMEM; } - memset(cmd->frame, 0, total_sz); + 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) -- 2.8.3
[PATCH v3 06/39] megaraid_sas: RAID map is accessed for SYS PDs when use_seqnum_jbod_fp is not set
Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 25 ++--- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 6ca49ef..67a205a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1756,28 +1756,31 @@ void megasas_update_sdev_properties(struct scsi_device *sdev) fusion = instance->ctrl_context; mr_device_priv_data = sdev->hostdata; - if (!fusion) + if (!fusion || !mr_device_priv_data) return; - if (!MEGASAS_IS_LOGICAL(sdev) && - instance->use_seqnum_jbod_fp) { - pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + - sdev->id; - pd_sync = (void *)fusion->pd_seq_sync - [(instance->pd_seq_map_id - 1) & 1]; - mr_device_priv_data->is_tm_capable = - pd_sync->seq[pd_index].capability.tmCapable; - } else { + if (MEGASAS_IS_LOGICAL(sdev)) { device_id = ((sdev->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id; local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; ld = MR_TargetIdToLdGet(device_id, local_map_ptr); + if (ld >= instance->fw_supported_vd_count) + return; raid = MR_LdRaidGet(ld, local_map_ptr); if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER) - blk_queue_update_dma_alignment(sdev->request_queue, 0x7); + blk_queue_update_dma_alignment(sdev->request_queue, + 0x7); + mr_device_priv_data->is_tm_capable = raid->capability.tmCapable; + } else if (instance->use_seqnum_jbod_fp) { + pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + + sdev->id; + pd_sync = (void *)fusion->pd_seq_sync + [(instance->pd_seq_map_id - 1) & 1]; + mr_device_priv_data->is_tm_capable = + pd_sync->seq[pd_index].capability.tmCapable; } } -- 2.8.3
[PATCH v3 26/39] megaraid_sas: update can_queue only if the new value is less
Minor Optimization: No need to update HBA can_queue value if the current max FW commands is equal to earlier value. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 2d6d979..94b7a68 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -259,7 +259,7 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c if (fw_boot_context == OCR_CONTEXT) { cur_max_fw_cmds = cur_max_fw_cmds - 1; - if (cur_max_fw_cmds <= instance->max_fw_cmds) { + if (cur_max_fw_cmds < instance->max_fw_cmds) { instance->cur_can_queue = cur_max_fw_cmds - (MEGASAS_FUSION_INTERNAL_CMDS + MEGASAS_FUSION_IOCTL_CMDS); -- 2.8.3
[PATCH v3 29/39] megaraid_sas: Remove unused pd_index from megasas_build_ld_nonrw_fusion
Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 74cefae..a9b66ce 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2480,7 +2480,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, { u32 device_id; struct MPI2_RAID_SCSI_IO_REQUEST *io_request; - u16 pd_index = 0, ld; + u16 ld; struct MR_DRV_RAID_MAP_ALL *local_map_ptr; struct fusion_context *fusion = instance->ctrl_context; u8 span, physArm; @@ -2492,7 +2492,6 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, io_request = cmd->io_request; device_id = MEGASAS_DEV_INDEX(scmd); - pd_index = MEGASAS_PD_INDEX(scmd); local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd)); /* get RAID_Context pointer */ -- 2.8.3
[PATCH v3 07/39] megaraid_sas: Use DID_REQUEUE
Moving to use DID_REQUEUE return type for reliable unconditional retries. Driver wants unconditional re-queue, so replace DID_RESET with DID_REQUEUE Discussed below - https://www.spinics.net/lists/linux-scsi/msg102848.html Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 4 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 67a205a..80fcdf5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1668,7 +1668,7 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) /* Check for an mpio path and adjust behavior */ if (atomic_read(&instance->adprecovery) == MEGASAS_ADPRESET_SM_INFAULT) { if (megasas_check_mpio_paths(instance, scmd) == - (DID_RESET << 16)) { + (DID_REQUEUE << 16)) { return SCSI_MLQUEUE_HOST_BUSY; } else { scmd->result = DID_NO_CONNECT << 16; @@ -2492,7 +2492,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance) struct megasas_cmd, list); list_del_init(&reset_cmd->list); if (reset_cmd->scmd) { - reset_cmd->scmd->result = DID_RESET << 16; + reset_cmd->scmd->result = DID_REQUEUE << 16; dev_notice(&instance->pdev->dev, "%d:%p reset [%02x]\n", reset_index, reset_cmd, reset_cmd->scmd->cmnd[0]); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 675afc9..6ec7a18 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3770,7 +3770,7 @@ int megasas_check_mpio_paths(struct megasas_instance *instance, struct scsi_cmnd *scmd) { struct megasas_instance *peer_instance = NULL; - int retval = (DID_RESET << 16); + int retval = (DID_REQUEUE << 16); if (instance->peerIsPresent) { peer_instance = megasas_get_peer_instance(instance); -- 2.8.3
[PATCH v3 04/39] megaraid_sas: 32 bit descriptor fire cmd optimization
No functional change. Code refactor. megasas_fire_cmd_fusion can always use 32 bit descriptor write for ventura. No need to pass extra flag. Only IOC INIT required 64 bit Descriptor write. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Tomas Henzl Reviewed-by: Hannes Reinecke --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 65 +++-- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 7516589..24b72c5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -188,40 +188,35 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance, /** * megasas_fire_cmd_fusion - Sends command to the FW + * @instance: Adapter soft state + * @req_desc: 32bit or 64bit Request descriptor + * + * Perform PCI Write. Ventura supports 32 bit Descriptor. + * Prior to Ventura (12G) MR controller supports 64 bit Descriptor. */ + static void megasas_fire_cmd_fusion(struct megasas_instance *instance, - union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc, bool is_32bit) + union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc) { - struct megasas_register_set __iomem *regs = instance->reg_set; - unsigned long flags; - - if (is_32bit) + if (instance->is_ventura) writel(le32_to_cpu(req_desc->u.low), - &(regs)->inbound_single_queue_port); - else if (instance->is_ventura) { + &instance->reg_set->inbound_single_queue_port); + else { +#if defined(writeq) && defined(CONFIG_64BIT) + u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) | + le32_to_cpu(req_desc->u.low)); + + writeq(req_data, &instance->reg_set->inbound_low_queue_port); +#else + unsigned long flags; spin_lock_irqsave(&instance->hba_lock, flags); writel(le32_to_cpu(req_desc->u.low), - &(regs)->inbound_low_queue_port); + &instance->reg_set->inbound_low_queue_port); writel(le32_to_cpu(req_desc->u.high), - &(regs)->inbound_high_queue_port); + &instance->reg_set->inbound_high_queue_port); mmiowb(); spin_unlock_irqrestore(&instance->hba_lock, flags); - } else { -#if defined(writeq) && defined(CONFIG_64BIT) - u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) | - le32_to_cpu(req_desc->u.low)); - - writeq(req_data, &instance->reg_set->inbound_low_queue_port); -#else - - spin_lock_irqsave(&instance->hba_lock, flags); - writel(le32_to_cpu(req_desc->u.low), - &instance->reg_set->inbound_low_queue_port); - writel(le32_to_cpu(req_desc->u.high), - &instance->reg_set->inbound_high_queue_port); - mmiowb(); - spin_unlock_irqrestore(&instance->hba_lock, flags); #endif } } @@ -771,6 +766,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) const char *sys_info; MFI_CAPABILITIES *drv_ops; u32 scratch_pad_2; + unsigned long flags; fusion = instance->ctrl_context; @@ -897,7 +893,14 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) break; } - megasas_fire_cmd_fusion(instance, &req_desc, false); + /* For Ventura also IOC INIT required 64 bit Descriptor write. */ + spin_lock_irqsave(&instance->hba_lock, flags); + writel(le32_to_cpu(req_desc.u.low), + &instance->reg_set->inbound_low_queue_port); + writel(le32_to_cpu(req_desc.u.high), + &instance->reg_set->inbound_high_queue_port); + mmiowb(); + spin_unlock_irqrestore(&instance->hba_lock, flags); wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS); @@ -2577,11 +2580,10 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, * Issue the command to the FW */ - megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura); + megasas_fire_cmd_fusion(instance, req_desc); if (r1_cmd) - megasas_fire_cmd_fusion(instance, r1_cmd->request_desc, - instance->is_ventura); + megasas_fire_cmd_fusion(instance, r1_cmd->request_desc); return 0; @@ -3001,7 +3003,7 @@ megasas_issue_dcmd_fusion(struct megasas_instance *instance, return DCMD_NOT_FIRED; } - meg
[PATCH v3 14/39] megaraid_sas: set residual bytes count during IO completion
Fixing issue of not setting residual bytes correctly. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index edbecc5..4628671 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1445,6 +1445,7 @@ map_cmd_status(struct fusion_context *fusion, struct scsi_cmnd *scmd, u8 status, u8 ext_status, u32 data_length, u8 *sense) { + int resid; switch (status) { @@ -1467,6 +1468,15 @@ map_cmd_status(struct fusion_context *fusion, SCSI_SENSE_BUFFERSIZE); scmd->result |= DRIVER_SENSE << 24; } + + /* +* If the IO request is partially completed, then MR FW will +* update "io_request->DataLength" field with actual number of +* bytes transferred.Driver will set residual bytes count in +* SCSI command structure. +*/ + resid = (scsi_bufflen(scmd) - data_length); + scsi_set_resid(scmd, resid); break; case MFI_STAT_LD_OFFLINE: -- 2.8.3
[PATCH v3 22/39] megaraid_sas: avoid unaligned access in ioctl path
Fix kernel warning for accessing unaligned memory access in driver. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index b2da257..5d7aa05 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -7007,7 +7008,8 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw + ioc->sense_off); - if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)), + if (copy_to_user((void __user *)((unsigned long) +get_unaligned((unsigned long *)sense_ptr)), sense, ioc->sense_len)) { dev_err(&instance->pdev->dev, "Failed to copy out to user " "sense data\n"); -- 2.8.3
[PATCH v3 09/39] megaraid_sas: change issue_dcmd to return void from int
With the changes to remove checks for a valid request descriptor, issue_dcmd will now always return DCMD_SUCCESS. This patch changes return type of issue_dcmd to void and change all callers appropriately. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- Fix in v2 : 1. split patches into two as discussed below http://marc.info/?l=linux-scsi&m=148638999110404&w=2 2. issue_dcmd return type changed from int to void. drivers/scsi/megaraid/megaraid_sas.h| 2 +- drivers/scsi/megaraid/megaraid_sas_base.c | 19 +++ drivers/scsi/megaraid/megaraid_sas_fusion.c | 8 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index dff877f..d9049d5 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2297,7 +2297,7 @@ struct megasas_instance_template { u32 (*init_adapter)(struct megasas_instance *); u32 (*build_and_issue_cmd) (struct megasas_instance *, struct scsi_cmnd *); - int (*issue_dcmd)(struct megasas_instance *instance, + void (*issue_dcmd)(struct megasas_instance *instance, struct megasas_cmd *cmd); }; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 80fcdf5..23fb78a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -202,12 +202,12 @@ void megasas_fusion_ocr_wq(struct work_struct *work); static int megasas_get_ld_vf_affiliation(struct megasas_instance *instance, int initial); -int +void megasas_issue_dcmd(struct megasas_instance *instance, struct megasas_cmd *cmd) { instance->instancet->fire_cmd(instance, cmd->frame_phys_addr, 0, instance->reg_set); - return 0; + return; } /** @@ -995,13 +995,14 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd) frame_hdr->cmd_status = MFI_STAT_INVALID_STATUS; frame_hdr->flags |= cpu_to_le16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE); - if ((atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) || - (instance->instancet->issue_dcmd(instance, cmd))) { + if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); return DCMD_NOT_FIRED; } + instance->instancet->issue_dcmd(instance, cmd); + return wait_and_poll(instance, cmd, instance->requestorId ? MEGASAS_ROUTINE_WAIT_TIME_VF : MFI_IO_TIMEOUT_SECS); } @@ -1023,13 +1024,14 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance, int ret = 0; cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; - if ((atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) || - (instance->instancet->issue_dcmd(instance, cmd))) { + if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); return DCMD_NOT_FIRED; } + instance->instancet->issue_dcmd(instance, cmd); + if (timeout) { ret = wait_event_timeout(instance->int_cmd_wait_q, cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ); @@ -1087,13 +1089,14 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance, cmd->sync_cmd = 1; cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; - if ((atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) || - (instance->instancet->issue_dcmd(instance, cmd))) { + if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); return DCMD_NOT_FIRED; } + instance->instancet->issue_dcmd(instance, cmd); + if (timeout) { ret = wait_event_timeout(instance->abort_cmd_wait_q, cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index b6c5dc5..c38fde0 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1115,7 +1115,7 @@ megasas_get_map_info(struct megasas_instance *instance) i
[PATCH v3 19/39] megaraid_sas: MR_TargetIdToLdGet u8 to u16 and avoid invalid raid-map access
Change MR_TargetIdToLdGet return type from u8 to u16. ld id range check is added at two places in this patch - @megasas_build_ldio_fusion and @megasas_build_ld_nonrw_fusion. Previous driver code used different data type for lds TargetId returned from MR_TargetIdToLdGet. Prior to this change, above two functions was safeguarded due to function always return u8 and maximum value of ld id returned was 255. In below check, fw_supported_vd_count as of today is 64 or 256 and valid range to support is either 0-63 or 0-255. Ideally want to filter accessing raid map for ld ids which are not valid. With the u16 change, invalid ld id value is 0x and we will see kernel panic due to random memory access in MR_LdRaidGet. The changes will ensure we do not call MR_LdRaidGet if ld id is beyond size of ldSpanMap array. if (ld < instance->fw_supported_vd_count) >From firmware perspective,ld id 0xFF is invalid and even though current driver code forward such command, firmware fails with target not available. ld target id issue occurs mainly whenever driver loops to populate raid map (ea. MR_ValidateMapInfo). These are the only two places where we may see out of range target ids and wants to protect raid map access based on range provided by Firmware API. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai --- fix in v2 - updated description content. drivers/scsi/megaraid/megaraid_sas.h| 2 +- drivers/scsi/megaraid/megaraid_sas_fp.c | 5 +++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 25 ++--- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 0a20fff..efc01a3 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2448,7 +2448,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, struct IO_REQUEST_INFO *io_info, struct RAID_CONTEXT *pRAID_Context, struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN); -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map); +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map); struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL *map); u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map); u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map); diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index a0b0e68..9d5d485 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -165,7 +165,7 @@ u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map) return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId); } -u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map) +u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map) { return map->raidMap.ldTgtIdToLd[ldTgtId]; } @@ -1151,7 +1151,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, { struct fusion_context *fusion; struct MR_LD_RAID *raid; - u32 ld, stripSize, stripe_mask; + u32 stripSize, stripe_mask; u64 endLba, endStrip, endRow, start_row, start_strip; u64 regStart; u32 regSize; @@ -1163,6 +1163,7 @@ MR_BuildRaidContext(struct megasas_instance *instance, u8 retval = 0; u8 startlba_span = SPAN_INVALID; u64 *pdBlock = &io_info->pdBlock; + u16 ld; ldStartBlock = io_info->ldStartBlock; numBlocks = io_info->numBlocks; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 9019b82..4aaf307 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1121,7 +1121,8 @@ megasas_sync_map_info(struct megasas_instance *instance) int i; struct megasas_cmd *cmd; struct megasas_dcmd_frame *dcmd; - u32 size_sync_info, num_lds; + u16 num_lds; + u32 size_sync_info; struct fusion_context *fusion; struct MR_LD_TARGET_SYNC *ci = NULL; struct MR_DRV_RAID_MAP_ALL *map; @@ -1870,7 +1871,7 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len, struct MR_DRV_RAID_MAP_ALL *local_map_ptr, u32 ref_tag) { struct MR_LD_RAID *raid; - u32 ld; + u16 ld; u64 start_blk = io_info->pdBlock; u8 *cdb = io_request->CDB.CDB32; u32 num_blocks = io_info->numBlocks; @@ -2303,10 +2304,11 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; ld = MR_TargetIdToLdGet(device_id, local_map_ptr); - raid = MR_LdRaidGet(ld, local_map_pt
[PATCH v3 17/39] megaraid_sas: reduce size of fusion_context and use vmalloc if kmalloc fails
Currently fusion context has fixed array load_balance_info. Use dynamic allocation. In few places, driver do not want physically contigious memory. Attempt to use vmalloc if physical contiguous memory is not available. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 2 + drivers/scsi/megaraid/megaraid_sas_base.c | 15 ++ drivers/scsi/megaraid/megaraid_sas_fp.c | 3 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 71 +++-- drivers/scsi/megaraid/megaraid_sas_fusion.h | 3 +- 5 files changed, 76 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 93da6dc..0a20fff 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2488,4 +2488,6 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason); int megasas_task_abort_fusion(struct scsi_cmnd *scmd); 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); #endif /*LSI_MEGARAID_SAS_H */ diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index c8fa480..b2da257 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6029,18 +6029,12 @@ static int megasas_probe_one(struct pci_dev *pdev, case PCI_DEVICE_ID_LSI_CUTLASS_52: case PCI_DEVICE_ID_LSI_CUTLASS_53: { - instance->ctrl_context_pages = - get_order(sizeof(struct fusion_context)); - instance->ctrl_context = (void *)__get_free_pages(GFP_KERNEL, - instance->ctrl_context_pages); - if (!instance->ctrl_context) { - dev_printk(KERN_DEBUG, &pdev->dev, "Failed to allocate " - "memory for Fusion context info\n"); + if (megasas_alloc_fusion_context(instance)) { + megasas_free_fusion_context(instance); goto fail_alloc_dma_buf; } fusion = instance->ctrl_context; - memset(fusion, 0, - ((1 << PAGE_SHIFT) << instance->ctrl_context_pages)); + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA)) fusion->adapter_type = THUNDERBOLT_SERIES; @@ -6683,8 +6677,7 @@ static void megasas_detach_one(struct pci_dev *pdev) fusion->pd_seq_sync[i], fusion->pd_seq_phys[i]); } - free_pages((ulong)instance->ctrl_context, - instance->ctrl_context_pages); + megasas_free_fusion_context(instance); } else { megasas_release_mfi(instance); pci_free_consistent(pdev, sizeof(u32), diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index c3ef82d..d9b0f28 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -489,7 +489,8 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance) if (instance->UnevenSpanSupport) mr_update_span_set(drv_map, ldSpanInfo); - mr_update_load_balance_params(drv_map, lbInfo); + if (lbInfo) + mr_update_load_balance_params(drv_map, lbInfo); num_lds = le16_to_cpu(drv_map->raidMap.ldCount); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 1252a3c..9019b82 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -2397,8 +2398,9 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, io_request->IoFlags |= cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH); } - if ((fusion->load_balance_info[device_id].loadBalanceFlag) && - (io_info.isRead)) { + if (fusion->load_balance_info && + (fusion->load_balance_info[device_id].loadBalanceFlag) && + (io_info.isRead)) { io_info.devHandle = get_updated_dev_handle(instance,
[PATCH v3 16/39] megaraid_sas: add print in device removal path
Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 19 +++ 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index b41bbea..c8fa480 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -7383,6 +7383,13 @@ megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t coun static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUSR, megasas_sysfs_show_dbg_lvl, megasas_sysfs_set_dbg_lvl); +static inline void megasas_remove_scsi_device(struct scsi_device *sdev) +{ + sdev_printk(KERN_INFO, sdev, "SCSI device is removed\n"); + scsi_remove_device(sdev); + scsi_device_put(sdev); +} + static void megasas_aen_polling(struct work_struct *work) { @@ -7487,10 +7494,8 @@ megasas_aen_polling(struct work_struct *work) else scsi_device_put(sdev1); } else { - if (sdev1) { - scsi_remove_device(sdev1); - scsi_device_put(sdev1); - } + if (sdev1) + megasas_remove_scsi_device(sdev1); } } } @@ -7507,10 +7512,8 @@ megasas_aen_polling(struct work_struct *work) else scsi_device_put(sdev1); } else { - if (sdev1) { - scsi_remove_device(sdev1); - scsi_device_put(sdev1); - } + if (sdev1) + megasas_remove_scsi_device(sdev1); } } } -- 2.8.3
[PATCH v3 01/39] Revert "scsi: megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth"
This reverts commit "3e5eadb1a881" ("scsi: megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth") This patch was aimed to increase performance of R1 Write operation for large IO size. Since this method used timer approach, it turn on/off fast path did not work as expected. Patch 0013 describes new algorithm and performance number. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 8 - drivers/scsi/megaraid/megaraid_sas_base.c | 48 - drivers/scsi/megaraid/megaraid_sas_fp.c | 7 - drivers/scsi/megaraid/megaraid_sas_fusion.c | 16 -- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 5 files changed, 7 insertions(+), 74 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index ba9fbb7..f5c4742 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1477,8 +1477,6 @@ enum FW_BOOT_CONTEXT { #define MFI_1068_FW_HANDSHAKE_OFFSET 0x64 #define MFI_1068_FW_READY 0x -#define MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL HZ - #define MR_MAX_REPLY_QUEUES_OFFSET 0X001F #define MR_MAX_REPLY_QUEUES_EXT_OFFSET 0X003FC000 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT14 @@ -2154,10 +2152,6 @@ struct megasas_instance { atomic_t ldio_outstanding; atomic_t fw_reset_no_pci_access; - atomic64_t bytes_wrote; /* used for raid1 fast path enable or disable */ - atomic_t r1_write_fp_capable; - - struct megasas_instance_template *instancet; struct tasklet_struct isr_tasklet; struct work_struct work_init; @@ -2199,7 +2193,6 @@ struct megasas_instance { long reset_flags; struct mutex reset_mutex; struct timer_list sriov_heartbeat_timer; - struct timer_list r1_fp_hold_timer; char skip_heartbeat_timer_del; u8 requestorId; char PlasmaFW111; @@ -2216,7 +2209,6 @@ struct megasas_instance { bool is_ventura; bool msix_combined; u16 max_raid_mapsize; - u64 pci_threshold_bandwidth; /* used to control the fp writes */ }; 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 70891a7..3ed876a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1940,9 +1940,6 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance) } /* Complete outstanding ioctls when adapter is killed */ megasas_complete_outstanding_ioctls(instance); - if (instance->is_ventura) - del_timer_sync(&instance->r1_fp_hold_timer); - } /** @@ -2441,24 +2438,6 @@ void megasas_sriov_heartbeat_handler(unsigned long instance_addr) } } -/*Handler for disabling/enabling raid 1 fast paths*/ -void megasas_change_r1_fp_status(unsigned long instance_addr) -{ - struct megasas_instance *instance = - (struct megasas_instance *)instance_addr; - if (atomic64_read(&instance->bytes_wrote) >= - instance->pci_threshold_bandwidth) { - - atomic64_set(&instance->bytes_wrote, 0); - atomic_set(&instance->r1_write_fp_capable, 0); - } else { - atomic64_set(&instance->bytes_wrote, 0); - atomic_set(&instance->r1_write_fp_capable, 1); - } - mod_timer(&instance->r1_fp_hold_timer, -jiffies + MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); -} - /** * megasas_wait_for_outstanding - Wait for all outstanding cmds * @instance: Adapter soft state @@ -5386,17 +5365,6 @@ static int megasas_init_fw(struct megasas_instance *instance) instance->skip_heartbeat_timer_del = 1; } - if (instance->is_ventura) { - atomic64_set(&instance->bytes_wrote, 0); - atomic_set(&instance->r1_write_fp_capable, 1); - megasas_start_timer(instance, - &instance->r1_fp_hold_timer, - megasas_change_r1_fp_status, - MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); - dev_info(&instance->pdev->dev, "starting the raid 1 fp timer with interval %d\n", - MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); - } - return 0; fail_get_ld_pd_list: @@ -6187,9 +6155,6 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) if (instance->requestorId && !instance->skip_heartbeat_timer_del)
[PATCH v3 05/39] megaraid_sas: Refactor MEGASAS_IS_LOGICAL macro using sdev
Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 4 ++-- drivers/scsi/megaraid/megaraid_sas_base.c | 20 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 12 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index f5c4742..dff877f 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2301,8 +2301,8 @@ struct megasas_instance_template { struct megasas_cmd *cmd); }; -#define MEGASAS_IS_LOGICAL(scp) \ - ((scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1) +#define MEGASAS_IS_LOGICAL(sdev) \ + ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1) #define MEGASAS_DEV_INDEX(scp) \ (((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \ diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 3ed876a..6ca49ef 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1279,7 +1279,7 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, u16 flags = 0; struct megasas_pthru_frame *pthru; - is_logical = MEGASAS_IS_LOGICAL(scp); + is_logical = MEGASAS_IS_LOGICAL(scp->device); device_id = MEGASAS_DEV_INDEX(scp); pthru = (struct megasas_pthru_frame *)cmd->frame; @@ -1519,11 +1519,11 @@ inline int megasas_cmd_type(struct scsi_cmnd *cmd) case WRITE_6: case READ_16: case WRITE_16: - ret = (MEGASAS_IS_LOGICAL(cmd)) ? + ret = (MEGASAS_IS_LOGICAL(cmd->device)) ? READ_WRITE_LDIO : READ_WRITE_SYSPDIO; break; default: - ret = (MEGASAS_IS_LOGICAL(cmd)) ? + ret = (MEGASAS_IS_LOGICAL(cmd->device)) ? NON_READ_WRITE_LDIO : NON_READ_WRITE_SYSPDIO; } return ret; @@ -1699,15 +1699,16 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) scmd->result = 0; - if (MEGASAS_IS_LOGICAL(scmd) && + if (MEGASAS_IS_LOGICAL(scmd->device) && (scmd->device->id >= instance->fw_supported_vd_count || scmd->device->lun)) { scmd->result = DID_BAD_TARGET << 16; goto out_done; } - if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) && MEGASAS_IS_LOGICAL(scmd) && - (!instance->fw_sync_cache_support)) { + if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) && + MEGASAS_IS_LOGICAL(scmd->device) && + (!instance->fw_sync_cache_support)) { scmd->result = DID_OK << 16; goto out_done; } @@ -1758,7 +1759,7 @@ void megasas_update_sdev_properties(struct scsi_device *sdev) if (!fusion) return; - if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && + if (!MEGASAS_IS_LOGICAL(sdev) && instance->use_seqnum_jbod_fp) { pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id; @@ -1826,8 +1827,7 @@ static int megasas_slave_configure(struct scsi_device *sdev) instance = megasas_lookup_instance(sdev->host->host_no); if (instance->pd_list_not_supported) { - if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && - sdev->type == TYPE_DISK) { + if (!MEGASAS_IS_LOGICAL(sdev) && sdev->type == TYPE_DISK) { pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id; if (instance->pd_list[pd_index].driveState != @@ -1854,7 +1854,7 @@ static int megasas_slave_alloc(struct scsi_device *sdev) struct MR_PRIV_DEVICE *mr_device_priv_data; instance = megasas_lookup_instance(sdev->host->host_no); - if (sdev->channel < MEGASAS_MAX_PD_CHANNELS) { + if (!MEGASAS_IS_LOGICAL(sdev)) { /* * Open the OS scan to the SYSTEM PD */ diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 24b72c5..675afc9 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3581,13 +3581,13 @@ static u16 megasas_get_tm_devhandle(struct scsi_device *sdev) instance = (struct m
[PATCH v3 02/39] megaraid_sas: cpu select rework.
No functional change. Code refactor. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 175 1 file changed, 100 insertions(+), 75 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 54728b3..514c306 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1819,6 +1819,73 @@ static void megasas_stream_detect(struct megasas_instance *instance, } /** + * megasas_set_raidflag_cpu_affinity - This function sets the cpu + * affinity (cpu of the controller) and raid_flags in the raid context + * based on IO type. + * + * @praid_context: IO RAID context + * @raid: LD raid map + * @fp_possible: Is fast path possible? + * @is_read: Is read IO? + * + */ +static void +megasas_set_raidflag_cpu_affinity(union RAID_CONTEXT_UNION *praid_context, + struct MR_LD_RAID *raid, bool fp_possible, + u8 is_read) +{ + u8 cpu_sel = MR_RAID_CTX_CPUSEL_0; + struct RAID_CONTEXT_G35 *rctx_g35; + + rctx_g35 = &praid_context->raid_context_g35; + if (fp_possible) { + if (is_read) { + if ((raid->cpuAffinity.pdRead.cpu0) && + (raid->cpuAffinity.pdRead.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.pdRead.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + } else { + if ((raid->cpuAffinity.pdWrite.cpu0) && + (raid->cpuAffinity.pdWrite.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.pdWrite.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + /* Fast path cache by pass capable R0/R1 VD */ + if ((raid->level <= 1) && + (raid->capability.fp_cache_bypass_capable)) { + rctx_g35->routing_flags.bits.sld = 1; + rctx_g35->raid_flags = + (MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS + << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT); + } + } + } else { + if (is_read) { + if ((raid->cpuAffinity.ldRead.cpu0) && + (raid->cpuAffinity.ldRead.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.ldRead.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + } else { + if ((raid->cpuAffinity.ldWrite.cpu0) && + (raid->cpuAffinity.ldWrite.cpu1)) + cpu_sel = MR_RAID_CTX_CPUSEL_FCFS; + else if (raid->cpuAffinity.ldWrite.cpu1) + cpu_sel = MR_RAID_CTX_CPUSEL_1; + + if (rctx_g35->stream_detected && + (raid->level == 5) && + (raid->writeMode == MR_RL_WRITE_THROUGH_MODE) && + (cpu_sel == MR_RAID_CTX_CPUSEL_FCFS)) + cpu_sel = MR_RAID_CTX_CPUSEL_0; + } + } + + rctx_g35->routing_flags.bits.cpu_sel = cpu_sel; +} + +/** * megasas_build_ldio_fusion - Prepares IOs to devices * @instance: Adapter soft state * @scp: SCSI command @@ -1832,8 +1899,10 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, struct scsi_cmnd *scp, struct megasas_cmd_fusion *cmd) { - u8 fp_possible; - u32 start_lba_lo, start_lba_hi, device_id, datalength = 0, ld; + bool fp_possible; + u16 ld; + u32 start_lba_lo, start_lba_hi, device_id, datalength = 0; + u32 scsi_buff_len; struct MPI2_RAID_SCSI_IO_REQUEST *io_request; union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; struct IO_REQUEST_INFO io_info; @@ -1842,7 +1911,8 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, u8 *raidLUN; unsigned long spinlock_flags; union RAID_CONTEXT_UNION *praid_context; - struct MR_LD_RAID *raid; + struct MR_LD_RAID *raid = NULL; + struct MR_PRIV_DEVICE *mrdev_priv; device_id = MEGASAS_DEV_INDEX(scp); @@ -1858,7 +1928,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
[PATCH v3 10/39] megaraid_sas: NVME Interface detection and prop settings
New functionality Adding detection logic for NVME device attached behind Ventura controller. Driver set HostPageSize in IOC_INIT frame to inform about page size for NVME devices. Firmware reports NVME page size to the driver. PD INFO DCMD provide new interface type NVME_PD. Driver set property of NVME device. Signed-off-by: Shivasharan S Signed-off-by: Kashyap Desai Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h| 23 ++-- drivers/scsi/megaraid/megaraid_sas_base.c | 170 drivers/scsi/megaraid/megaraid_sas_fusion.c | 6 +- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 4 files changed, 142 insertions(+), 59 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index d9049d5..f9efddf 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -733,7 +733,6 @@ struct megasas_pd_list { u16 tid; u8 driveType; u8 driveState; - u8 interface; } __packed; /* @@ -1530,8 +1529,8 @@ struct megasas_register_set { u32 outbound_scratch_pad ; /*00B0h*/ u32 outbound_scratch_pad_2; /*00B4h*/ u32 outbound_scratch_pad_3; /*00B8h*/ + u32 outbound_scratch_pad_4; /*00BCh*/ - u32 reserved_4; /*00BCh*/ u32 inbound_low_queue_port ;/*00C0h*/ @@ -1864,6 +1863,7 @@ union megasas_frame { struct MR_PRIV_DEVICE { bool is_tm_capable; bool tm_busy; + u8 interface_type; }; struct megasas_cmd; @@ -2055,17 +2055,24 @@ struct MR_DRV_SYSTEM_INFO { }; enum MR_PD_TYPE { -UNKNOWN_DRIVE = 0, -PARALLEL_SCSI = 1, -SAS_PD = 2, -SATA_PD = 3, -FC_PD = 4, + UNKNOWN_DRIVE = 0, + PARALLEL_SCSI = 1, + SAS_PD = 2, + SATA_PD = 3, + FC_PD = 4, + NVME_PD = 5, }; /* JBOD Queue depth definitions */ #define MEGASAS_SATA_QD32 #define MEGASAS_SAS_QD 64 #define MEGASAS_DEFAULT_PD_QD 64 +#define MEGASAS_NVME_QD32 + +#define MR_DEFAULT_NVME_PAGE_SIZE 4096 +#define MR_DEFAULT_NVME_PAGE_SHIFT 12 +#define MR_DEFAULT_NVME_MDTS_KB128 +#define MR_NVME_PAGE_SIZE_MASK 0x00FF struct megasas_instance { @@ -2209,6 +2216,7 @@ struct megasas_instance { bool is_ventura; bool msix_combined; u16 max_raid_mapsize; + u32 nvme_page_size; }; struct MR_LD_VF_MAP { u32 size; @@ -2428,6 +2436,7 @@ int megasas_get_ctrl_info(struct megasas_instance *instance); /* PD sequence */ int megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend); +void megasas_set_dynamic_target_properties(struct scsi_device *sdev); int megasas_set_crash_dump_params(struct megasas_instance *instance, u8 crash_buf_state); void megasas_free_host_crash_buffer(struct megasas_instance *instance); diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 23fb78a..f383bf2 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -116,8 +116,8 @@ static int megasas_ld_list_query(struct megasas_instance *instance, static int megasas_issue_init_mfi(struct megasas_instance *instance); static int megasas_register_aen(struct megasas_instance *instance, u32 seq_num, u32 class_locale_word); -static int -megasas_get_pd_info(struct megasas_instance *instance, u16 device_id); +static void megasas_get_pd_info(struct megasas_instance *instance, + struct scsi_device *sdev); /* * PCI ID table for all supported controllers */ @@ -1738,16 +1738,21 @@ static struct megasas_instance *megasas_lookup_instance(u16 host_no) } /* -* megasas_update_sdev_properties - Update sdev structure based on controller's FW capabilities +* megasas_set_dynamic_target_properties - +* Device property set by driver may not be static and it is required to be +* updated after OCR +* +* set tm_capable. +* set dma alignment (only for eedp protection enable vd). * * @sdev: OS provided scsi device * * Returns void */ -void megasas_update_sdev_properties(struct scsi_device *sdev) +void megasas_set_dynamic_target_properties(struct scsi_device *sdev) { - u16 pd_index = 0; - u32 device_id, ld; + u16 pd_index = 0, ld; + u32 device_id; struct megasas_instance *instance; struct fusion_context *fusion; struct MR_PRIV_DEVICE *mr_device_priv_data; @@ -1772,57 +1777,102 @@ void megasas_update_sdev_properties(struct scsi_device *sdev) raid = MR_LdRaidGet(ld, local_map_ptr); if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CO
[PATCH v3 23/39] megaraid_sas: latest controller OCR capability from FW before sending shutdown DCMD
Fetch the latest controller OCR capability from FW before sending MR_DCMD_CTRL_SHUTDOWN When application sends a shutdown DCMD (MR_DCMD_CTRL_SHUTDOWN), driver will fetch latest controller information from firmware. This is to ensure that driver always has latest OCR capability of controller before sending the DCMD. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 5d7aa05..cd9d223 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -6900,6 +6900,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, MFI_FRAME_SGL64 | MFI_FRAME_SENSE64)); + if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_SHUTDOWN) { + if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) { + megasas_return_cmd(instance, cmd); + return -1; + } + } + if (cmd->frame->dcmd.opcode == MR_DRIVER_SET_APP_CRASHDUMP_MODE) { error = megasas_set_crash_dump_params_ioctl(cmd); megasas_return_cmd(instance, cmd); -- 2.8.3
[PATCH v3 33/39] megaraid_sas: Bail out the driver load if ld_list_query fails
Error handling: Bail out the driver load if key FW cmds (LD_LIST) are not return successful. Clean up error handling in megasas_init_fw. Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas_base.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 30e390c..0e7121d 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5352,7 +5352,7 @@ static int megasas_init_fw(struct megasas_instance *instance) (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list))); if (megasas_get_pd_list(instance) < 0) { dev_err(&instance->pdev->dev, "failed to get PD list\n"); - goto fail_get_pd_list; + goto fail_get_ld_pd_list; } memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); @@ -5388,7 +5388,7 @@ static int megasas_init_fw(struct megasas_instance *instance) if (megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) - megasas_get_ld_list(instance); + goto fail_get_ld_pd_list; /* * Compute the max allowed sectors per IO: The controller info has two @@ -5507,8 +5507,6 @@ static int megasas_init_fw(struct megasas_instance *instance) fail_get_ld_pd_list: instance->instancet->disable_intr(instance); -fail_get_pd_list: - instance->instancet->disable_intr(instance); fail_init_adapter: megasas_destroy_irqs(instance); fail_setup_irqs: @@ -5520,9 +5518,11 @@ static int megasas_init_fw(struct megasas_instance *instance) instance->ctrl_info = NULL; iounmap(instance->reg_set); - fail_ioremap: +fail_ioremap: pci_release_selected_regions(instance->pdev, 1<bar); + dev_err(&instance->pdev->dev, "Failed from %s %d\n", + __func__, __LINE__); return -EINVAL; } -- 2.8.3
[PATCH v3 39/39] megaraid_sas: driver version upgrade
Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Reviewed-by: Hannes Reinecke Reviewed-by: Tomas Henzl --- drivers/scsi/megaraid/megaraid_sas.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 8c06cbf..e7e5974 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.700.00.00-rc1" -#define MEGASAS_RELDATE"November 29, 2016" +#define MEGASAS_VERSION"07.701.16.00-rc1" +#define MEGASAS_RELDATE"February 2, 2017" /* * Device IDs -- 2.8.3