aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid
diff options
context:
space:
mode:
authorSumit.Saxena@avagotech.com <Sumit.Saxena@avagotech.com>2014-11-17 04:54:13 -0500
committerChristoph Hellwig <hch@lst.de>2014-11-24 08:38:46 -0500
commitd009b5760f577db3fef5cbda5ccf3304fa4f57d7 (patch)
tree5920cfb34d07ad04fdcf6b25600922e86686381d /drivers/scsi/megaraid
parente399065be090b2d8abd70c72b9632df67ab0413f (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')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h3
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c82
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c55
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.h2
4 files changed, 85 insertions, 57 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 401f4a22b370..0d44d91c2fce 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1931,8 +1931,7 @@ u16 get_updated_dev_handle(struct megasas_instance *instance,
1931 struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *in_info); 1931 struct LD_LOAD_BALANCE_INFO *lbInfo, struct IO_REQUEST_INFO *in_info);
1932void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map, 1932void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map,
1933 struct LD_LOAD_BALANCE_INFO *lbInfo); 1933 struct LD_LOAD_BALANCE_INFO *lbInfo);
1934int megasas_get_ctrl_info(struct megasas_instance *instance, 1934int megasas_get_ctrl_info(struct megasas_instance *instance);
1935 struct megasas_ctrl_info *ctrl_info);
1936int megasas_set_crash_dump_params(struct megasas_instance *instance, 1935int megasas_set_crash_dump_params(struct megasas_instance *instance,
1937 u8 crash_buf_state); 1936 u8 crash_buf_state);
1938void megasas_free_host_crash_buffer(struct megasas_instance *instance); 1937void 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 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*/
4033static 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 */
4038int 4094int
4039megasas_get_ctrl_info(struct megasas_instance *instance, 4095megasas_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,
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 92f33548e924..98dfc1d1079b 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1067,48 +1067,16 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
1067 goto fail_ioc_init; 1067 goto fail_ioc_init;
1068 1068
1069 megasas_display_intel_branding(instance); 1069 megasas_display_intel_branding(instance);
1070 if (megasas_get_ctrl_info(instance, instance->ctrl_info)) { 1070 if (megasas_get_ctrl_info(instance)) {
1071 dev_err(&instance->pdev->dev, 1071 dev_err(&instance->pdev->dev,
1072 "Could not get controller info. Fail from %s %d\n", 1072 "Could not get controller info. Fail from %s %d\n",
1073 __func__, __LINE__); 1073 __func__, __LINE__);
1074 goto fail_ioc_init; 1074 goto fail_ioc_init;
1075 } 1075 }
1076 1076
1077 instance->supportmax256vd =
1078 instance->ctrl_info->adapterOperations3.supportMaxExtLDs;
1079 /* Below is additional check to address future FW enhancement */
1080 if (instance->ctrl_info->max_lds > 64)
1081 instance->supportmax256vd = 1;
1082 instance->drv_supported_vd_count = MEGASAS_MAX_LD_CHANNELS
1083 * MEGASAS_MAX_DEV_PER_CHANNEL;
1084 instance->drv_supported_pd_count = MEGASAS_MAX_PD_CHANNELS
1085 * MEGASAS_MAX_DEV_PER_CHANNEL;
1086 if (instance->supportmax256vd) {
1087 instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES_EXT;
1088 instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
1089 } else {
1090 instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES;
1091 instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
1092 }
1093 dev_info(&instance->pdev->dev, "Firmware supports %d VDs %d PDs\n"
1094 "Driver supports %d VDs %d PDs\n",
1095 instance->fw_supported_vd_count,
1096 instance->fw_supported_pd_count,
1097 instance->drv_supported_vd_count,
1098 instance->drv_supported_pd_count);
1099
1100 instance->flag_ieee = 1; 1077 instance->flag_ieee = 1;
1101 fusion->fast_path_io = 0; 1078 fusion->fast_path_io = 0;
1102 1079
1103 fusion->old_map_sz =
1104 sizeof(struct MR_FW_RAID_MAP) + (sizeof(struct MR_LD_SPAN_MAP) *
1105 (instance->fw_supported_vd_count - 1));
1106 fusion->new_map_sz =
1107 sizeof(struct MR_FW_RAID_MAP_EXT);
1108 fusion->drv_map_sz =
1109 sizeof(struct MR_DRV_RAID_MAP) + (sizeof(struct MR_LD_SPAN_MAP) *
1110 (instance->drv_supported_vd_count - 1));
1111
1112 fusion->drv_map_pages = get_order(fusion->drv_map_sz); 1080 fusion->drv_map_pages = get_order(fusion->drv_map_sz);
1113 for (i = 0; i < 2; i++) { 1081 for (i = 0; i < 2; i++) {
1114 fusion->ld_map[i] = NULL; 1082 fusion->ld_map[i] = NULL;
@@ -1123,16 +1091,10 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
1123 fusion->drv_map_pages); 1091 fusion->drv_map_pages);
1124 goto fail_ioc_init; 1092 goto fail_ioc_init;
1125 } 1093 }
1094 memset(fusion->ld_drv_map[i], 0,
1095 ((1 << PAGE_SHIFT) << fusion->drv_map_pages));
1126 } 1096 }
1127 1097
1128 fusion->max_map_sz = max(fusion->old_map_sz, fusion->new_map_sz);
1129
1130 if (instance->supportmax256vd)
1131 fusion->current_map_sz = fusion->new_map_sz;
1132 else
1133 fusion->current_map_sz = fusion->old_map_sz;
1134
1135
1136 for (i = 0; i < 2; i++) { 1098 for (i = 0; i < 2; i++) {
1137 fusion->ld_map[i] = dma_alloc_coherent(&instance->pdev->dev, 1099 fusion->ld_map[i] = dma_alloc_coherent(&instance->pdev->dev,
1138 fusion->max_map_sz, 1100 fusion->max_map_sz,
@@ -2387,6 +2349,8 @@ megasas_alloc_host_crash_buffer(struct megasas_instance *instance)
2387 "memory allocation failed at index %d\n", i); 2349 "memory allocation failed at index %d\n", i);
2388 break; 2350 break;
2389 } 2351 }
2352 memset(instance->crash_buf[i], 0,
2353 ((1 << PAGE_SHIFT) << instance->crash_buf_pages));
2390 } 2354 }
2391 instance->drv_buf_alloc = i; 2355 instance->drv_buf_alloc = i;
2392} 2356}
@@ -2844,6 +2808,15 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
2844 instance->instancet->enable_intr(instance); 2808 instance->instancet->enable_intr(instance);
2845 instance->adprecovery = MEGASAS_HBA_OPERATIONAL; 2809 instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
2846 2810
2811 if (megasas_get_ctrl_info(instance)) {
2812 dev_info(&instance->pdev->dev,
2813 "Failed from %s %d\n",
2814 __func__, __LINE__);
2815 instance->adprecovery =
2816 MEGASAS_HW_CRITICAL_ERROR;
2817 megaraid_sas_kill_hba(instance);
2818 retval = FAILED;
2819 }
2847 /* Reset load balance info */ 2820 /* Reset load balance info */
2848 memset(fusion->load_balance_info, 0, 2821 memset(fusion->load_balance_info, 0,
2849 sizeof(struct LD_LOAD_BALANCE_INFO) 2822 sizeof(struct LD_LOAD_BALANCE_INFO)
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index 92ecd39373bb..5ab7daee11be 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -836,8 +836,6 @@ struct fusion_context {
836 836
837 u32 max_map_sz; 837 u32 max_map_sz;
838 u32 current_map_sz; 838 u32 current_map_sz;
839 u32 old_map_sz;
840 u32 new_map_sz;
841 u32 drv_map_sz; 839 u32 drv_map_sz;
842 u32 drv_map_pages; 840 u32 drv_map_pages;
843 u8 fast_path_io; 841 u8 fast_path_io;