diff options
author | Sumit.Saxena@avagotech.com <Sumit.Saxena@avagotech.com> | 2014-11-17 04:54:13 -0500 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-11-24 08:38:46 -0500 |
commit | d009b5760f577db3fef5cbda5ccf3304fa4f57d7 (patch) | |
tree | 5920cfb34d07ad04fdcf6b25600922e86686381d /drivers/scsi/megaraid/megaraid_sas_base.c | |
parent | e399065be090b2d8abd70c72b9632df67ab0413f (diff) |
megaraid_sas: online Firmware upgrade support for Extended VD feature
In OCR (Online Controller Reset) path, driver sets adapter state to
MEGASAS_HBA_OPERATIONAL before getting new RAID map. There will be a small
window where IO will come from OS with old RAID map. This patch will
update adapter state to MEGASAS_HBA_OPERATIONAL, only after driver has new
RAID map to avoid any IOs getting build using old RAID map.
Signed-off-by: Sumit Saxena <sumit.saxena@avagotech.com>
Signed-off-by: Kashyap Desai <kashyap.desai@avagotech.com>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/megaraid/megaraid_sas_base.c')
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_base.c | 82 |
1 files changed, 70 insertions, 12 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 7018ec47a43f..5fb265bfc5d1 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
@@ -4026,25 +4026,83 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type) | |||
4026 | return ret; | 4026 | return ret; |
4027 | } | 4027 | } |
4028 | 4028 | ||
4029 | /* | ||
4030 | * megasas_update_ext_vd_details : Update details w.r.t Extended VD | ||
4031 | * instance : Controller's instance | ||
4032 | */ | ||
4033 | static void megasas_update_ext_vd_details(struct megasas_instance *instance) | ||
4034 | { | ||
4035 | struct fusion_context *fusion; | ||
4036 | u32 old_map_sz; | ||
4037 | u32 new_map_sz; | ||
4038 | |||
4039 | fusion = instance->ctrl_context; | ||
4040 | /* For MFI based controllers return dummy success */ | ||
4041 | if (!fusion) | ||
4042 | return; | ||
4043 | |||
4044 | instance->supportmax256vd = | ||
4045 | instance->ctrl_info->adapterOperations3.supportMaxExtLDs; | ||
4046 | /* Below is additional check to address future FW enhancement */ | ||
4047 | if (instance->ctrl_info->max_lds > 64) | ||
4048 | instance->supportmax256vd = 1; | ||
4049 | |||
4050 | instance->drv_supported_vd_count = MEGASAS_MAX_LD_CHANNELS | ||
4051 | * MEGASAS_MAX_DEV_PER_CHANNEL; | ||
4052 | instance->drv_supported_pd_count = MEGASAS_MAX_PD_CHANNELS | ||
4053 | * MEGASAS_MAX_DEV_PER_CHANNEL; | ||
4054 | if (instance->supportmax256vd) { | ||
4055 | instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES_EXT; | ||
4056 | instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES; | ||
4057 | } else { | ||
4058 | instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES; | ||
4059 | instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES; | ||
4060 | } | ||
4061 | dev_info(&instance->pdev->dev, "Firmware supports %d VD %d PD\n", | ||
4062 | instance->fw_supported_vd_count, | ||
4063 | instance->fw_supported_pd_count); | ||
4064 | dev_info(&instance->pdev->dev, "Driver supports %d VD %d PD\n", | ||
4065 | instance->drv_supported_vd_count, | ||
4066 | instance->drv_supported_pd_count); | ||
4067 | |||
4068 | old_map_sz = sizeof(struct MR_FW_RAID_MAP) + | ||
4069 | (sizeof(struct MR_LD_SPAN_MAP) * | ||
4070 | (instance->fw_supported_vd_count - 1)); | ||
4071 | new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT); | ||
4072 | fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP) + | ||
4073 | (sizeof(struct MR_LD_SPAN_MAP) * | ||
4074 | (instance->drv_supported_vd_count - 1)); | ||
4075 | |||
4076 | fusion->max_map_sz = max(old_map_sz, new_map_sz); | ||
4077 | |||
4078 | |||
4079 | if (instance->supportmax256vd) | ||
4080 | fusion->current_map_sz = new_map_sz; | ||
4081 | else | ||
4082 | fusion->current_map_sz = old_map_sz; | ||
4083 | |||
4084 | } | ||
4085 | |||
4029 | /** | 4086 | /** |
4030 | * megasas_get_controller_info - Returns FW's controller structure | 4087 | * megasas_get_controller_info - Returns FW's controller structure |
4031 | * @instance: Adapter soft state | 4088 | * @instance: Adapter soft state |
4032 | * @ctrl_info: Controller information structure | ||
4033 | * | 4089 | * |
4034 | * Issues an internal command (DCMD) to get the FW's controller structure. | 4090 | * Issues an internal command (DCMD) to get the FW's controller structure. |
4035 | * This information is mainly used to find out the maximum IO transfer per | 4091 | * This information is mainly used to find out the maximum IO transfer per |
4036 | * command supported by the FW. | 4092 | * command supported by the FW. |
4037 | */ | 4093 | */ |
4038 | int | 4094 | int |
4039 | megasas_get_ctrl_info(struct megasas_instance *instance, | 4095 | megasas_get_ctrl_info(struct megasas_instance *instance) |
4040 | struct megasas_ctrl_info *ctrl_info) | ||
4041 | { | 4096 | { |
4042 | int ret = 0; | 4097 | int ret = 0; |
4043 | struct megasas_cmd *cmd; | 4098 | struct megasas_cmd *cmd; |
4044 | struct megasas_dcmd_frame *dcmd; | 4099 | struct megasas_dcmd_frame *dcmd; |
4045 | struct megasas_ctrl_info *ci; | 4100 | struct megasas_ctrl_info *ci; |
4101 | struct megasas_ctrl_info *ctrl_info; | ||
4046 | dma_addr_t ci_h = 0; | 4102 | dma_addr_t ci_h = 0; |
4047 | 4103 | ||
4104 | ctrl_info = instance->ctrl_info; | ||
4105 | |||
4048 | cmd = megasas_get_cmd(instance); | 4106 | cmd = megasas_get_cmd(instance); |
4049 | 4107 | ||
4050 | if (!cmd) { | 4108 | if (!cmd) { |
@@ -4084,8 +4142,13 @@ megasas_get_ctrl_info(struct megasas_instance *instance, | |||
4084 | else | 4142 | else |
4085 | ret = megasas_issue_polled(instance, cmd); | 4143 | ret = megasas_issue_polled(instance, cmd); |
4086 | 4144 | ||
4087 | if (!ret) | 4145 | if (!ret) { |
4088 | memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info)); | 4146 | memcpy(ctrl_info, ci, sizeof(struct megasas_ctrl_info)); |
4147 | le32_to_cpus((u32 *)&ctrl_info->properties.OnOffProperties); | ||
4148 | le32_to_cpus((u32 *)&ctrl_info->adapterOperations2); | ||
4149 | le32_to_cpus((u32 *)&ctrl_info->adapterOperations3); | ||
4150 | megasas_update_ext_vd_details(instance); | ||
4151 | } | ||
4089 | 4152 | ||
4090 | pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info), | 4153 | pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info), |
4091 | ci, ci_h); | 4154 | ci, ci_h); |
@@ -4287,7 +4350,7 @@ megasas_init_adapter_mfi(struct megasas_instance *instance) | |||
4287 | if (megasas_issue_init_mfi(instance)) | 4350 | if (megasas_issue_init_mfi(instance)) |
4288 | goto fail_fw_init; | 4351 | goto fail_fw_init; |
4289 | 4352 | ||
4290 | if (megasas_get_ctrl_info(instance, instance->ctrl_info)) { | 4353 | if (megasas_get_ctrl_info(instance)) { |
4291 | dev_err(&instance->pdev->dev, "(%d): Could get controller info " | 4354 | dev_err(&instance->pdev->dev, "(%d): Could get controller info " |
4292 | "Fail from %s %d\n", instance->unique_id, | 4355 | "Fail from %s %d\n", instance->unique_id, |
4293 | __func__, __LINE__); | 4356 | __func__, __LINE__); |
@@ -4525,12 +4588,8 @@ static int megasas_init_fw(struct megasas_instance *instance) | |||
4525 | dev_info(&instance->pdev->dev, | 4588 | dev_info(&instance->pdev->dev, |
4526 | "Controller type: iMR\n"); | 4589 | "Controller type: iMR\n"); |
4527 | } | 4590 | } |
4528 | /* OnOffProperties are converted into CPU arch*/ | ||
4529 | le32_to_cpus((u32 *)&ctrl_info->properties.OnOffProperties); | ||
4530 | instance->disableOnlineCtrlReset = | 4591 | instance->disableOnlineCtrlReset = |
4531 | ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset; | 4592 | ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset; |
4532 | /* adapterOperations2 are converted into CPU arch*/ | ||
4533 | le32_to_cpus((u32 *)&ctrl_info->adapterOperations2); | ||
4534 | instance->mpio = ctrl_info->adapterOperations2.mpio; | 4593 | instance->mpio = ctrl_info->adapterOperations2.mpio; |
4535 | instance->UnevenSpanSupport = | 4594 | instance->UnevenSpanSupport = |
4536 | ctrl_info->adapterOperations2.supportUnevenSpans; | 4595 | ctrl_info->adapterOperations2.supportUnevenSpans; |
@@ -4560,7 +4619,6 @@ static int megasas_init_fw(struct megasas_instance *instance) | |||
4560 | "requestorId %d\n", instance->requestorId); | 4619 | "requestorId %d\n", instance->requestorId); |
4561 | } | 4620 | } |
4562 | 4621 | ||
4563 | le32_to_cpus((u32 *)&ctrl_info->adapterOperations3); | ||
4564 | instance->crash_dump_fw_support = | 4622 | instance->crash_dump_fw_support = |
4565 | ctrl_info->adapterOperations3.supportCrashDump; | 4623 | ctrl_info->adapterOperations3.supportCrashDump; |
4566 | instance->crash_dump_drv_support = | 4624 | instance->crash_dump_drv_support = |
@@ -4585,8 +4643,6 @@ static int megasas_init_fw(struct megasas_instance *instance) | |||
4585 | if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors)) | 4643 | if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors)) |
4586 | instance->max_sectors_per_req = tmp_sectors; | 4644 | instance->max_sectors_per_req = tmp_sectors; |
4587 | 4645 | ||
4588 | kfree(ctrl_info); | ||
4589 | |||
4590 | /* Check for valid throttlequeuedepth module parameter */ | 4646 | /* Check for valid throttlequeuedepth module parameter */ |
4591 | if (instance->is_imr) { | 4647 | if (instance->is_imr) { |
4592 | if (throttlequeuedepth > (instance->max_fw_cmds - | 4648 | if (throttlequeuedepth > (instance->max_fw_cmds - |
@@ -5081,6 +5137,8 @@ static int megasas_probe_one(struct pci_dev *pdev, | |||
5081 | goto fail_alloc_dma_buf; | 5137 | goto fail_alloc_dma_buf; |
5082 | } | 5138 | } |
5083 | fusion = instance->ctrl_context; | 5139 | fusion = instance->ctrl_context; |
5140 | memset(fusion, 0, | ||
5141 | ((1 << PAGE_SHIFT) << instance->ctrl_context_pages)); | ||
5084 | INIT_LIST_HEAD(&fusion->cmd_pool); | 5142 | INIT_LIST_HEAD(&fusion->cmd_pool); |
5085 | spin_lock_init(&fusion->mpt_pool_lock); | 5143 | spin_lock_init(&fusion->mpt_pool_lock); |
5086 | memset(fusion->load_balance_info, 0, | 5144 | memset(fusion->load_balance_info, 0, |