aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid/megaraid_sas_fusion.c
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/megaraid_sas_fusion.c
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/megaraid_sas_fusion.c')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_fusion.c55
1 files changed, 14 insertions, 41 deletions
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)