diff options
Diffstat (limited to 'drivers/scsi/megaraid/megaraid_sas_fp.c')
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_fp.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index bfad9bfc313f..59ecbb3b53b5 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -168,7 +168,7 @@ static struct MR_LD_SPAN *MR_LdSpanPtrGet(u32 ld, u32 span, /* * This function will Populate Driver Map using firmware raid map */ -void MR_PopulateDrvRaidMap(struct megasas_instance *instance) +static int MR_PopulateDrvRaidMap(struct megasas_instance *instance, u64 map_id) { struct fusion_context *fusion = instance->ctrl_context; struct MR_FW_RAID_MAP_ALL *fw_map_old = NULL; @@ -181,7 +181,7 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) struct MR_DRV_RAID_MAP_ALL *drv_map = - fusion->ld_drv_map[(instance->map_id & 1)]; + fusion->ld_drv_map[(map_id & 1)]; struct MR_DRV_RAID_MAP *pDrvRaidMap = &drv_map->raidMap; void *raid_map_data = NULL; @@ -190,7 +190,7 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) 0xff, (sizeof(u16) * MAX_LOGICAL_DRIVES_DYN)); if (instance->max_raid_mapsize) { - fw_map_dyn = fusion->ld_map[(instance->map_id & 1)]; + fw_map_dyn = fusion->ld_map[(map_id & 1)]; 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) @@ -255,11 +255,11 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) } else if (instance->supportmax256vd) { fw_map_ext = - (struct MR_FW_RAID_MAP_EXT *)fusion->ld_map[(instance->map_id & 1)]; + (struct MR_FW_RAID_MAP_EXT *)fusion->ld_map[(map_id & 1)]; ld_count = (u16)le16_to_cpu(fw_map_ext->ldCount); if (ld_count > MAX_LOGICAL_DRIVES_EXT) { dev_dbg(&instance->pdev->dev, "megaraid_sas: LD count exposed in RAID map in not valid\n"); - return; + return 1; } pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count); @@ -282,9 +282,15 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) cpu_to_le32(sizeof(struct MR_FW_RAID_MAP_EXT)); } else { fw_map_old = (struct MR_FW_RAID_MAP_ALL *) - fusion->ld_map[(instance->map_id & 1)]; + fusion->ld_map[(map_id & 1)]; pFwRaidMap = &fw_map_old->raidMap; ld_count = (u16)le32_to_cpu(pFwRaidMap->ldCount); + if (ld_count > MAX_LOGICAL_DRIVES) { + dev_dbg(&instance->pdev->dev, + "LD count exposed in RAID map in not valid\n"); + return 1; + } + pDrvRaidMap->totalSize = pFwRaidMap->totalSize; pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count); pDrvRaidMap->fpPdIoTimeoutSec = pFwRaidMap->fpPdIoTimeoutSec; @@ -300,12 +306,14 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) sizeof(struct MR_DEV_HANDLE_INFO) * MAX_RAIDMAP_PHYSICAL_DEVICES); } + + return 0; } /* * This function will validate Map info data provided by FW */ -u8 MR_ValidateMapInfo(struct megasas_instance *instance) +u8 MR_ValidateMapInfo(struct megasas_instance *instance, u64 map_id) { struct fusion_context *fusion; struct MR_DRV_RAID_MAP_ALL *drv_map; @@ -317,11 +325,11 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance) u16 ld; u32 expected_size; - - MR_PopulateDrvRaidMap(instance); + if (MR_PopulateDrvRaidMap(instance, map_id)) + return 0; fusion = instance->ctrl_context; - drv_map = fusion->ld_drv_map[(instance->map_id & 1)]; + drv_map = fusion->ld_drv_map[(map_id & 1)]; pDrvRaidMap = &drv_map->raidMap; lbInfo = fusion->load_balance_info; |