24d93b
From 88b3ac2949cb535c5213324f33e9745d769f7dad Mon Sep 17 00:00:00 2001
24d93b
From: Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
24d93b
Date: Tue, 10 Jan 2017 18:20:48 -0500
24d93b
Subject: [PATCH 06/11] scsi: megaraid_sas: Dynamic Raid Map Changes for SAS3.5
24d93b
 Generic Megaraid Controllers
24d93b
24d93b
SAS3.5 Generic Megaraid Controllers FW will support new dynamic RaidMap to have different
24d93b
sizes for different number of supported VDs.
24d93b
24d93b
Signed-off-by: Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
24d93b
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
24d93b
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
24d93b
---
24d93b
 drivers/scsi/megaraid/megaraid_sas.h        |   7 +
24d93b
 drivers/scsi/megaraid/megaraid_sas_base.c   |  60 ++++--
24d93b
 drivers/scsi/megaraid/megaraid_sas_fp.c     | 301 ++++++++++++++++++++++++----
24d93b
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 225 ++++++++++++++++-----
24d93b
 drivers/scsi/megaraid/megaraid_sas_fusion.h | 240 ++++++++++++++++++----
24d93b
 5 files changed, 695 insertions(+), 138 deletions(-)
24d93b
24d93b
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
24d93b
index 0b4d37b..d5205c4 100644
24d93b
--- a/drivers/scsi/megaraid/megaraid_sas.h
24d93b
+++ b/drivers/scsi/megaraid/megaraid_sas.h
24d93b
@@ -1434,6 +1434,12 @@ enum FW_BOOT_CONTEXT {
24d93b
 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT    14
24d93b
 #define MR_MAX_MSIX_REG_ARRAY                   16
24d93b
 #define MR_RDPQ_MODE_OFFSET			0X00800000
24d93b
+
24d93b
+#define MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT	16
24d93b
+#define MR_MAX_RAID_MAP_SIZE_MASK		0x1FF
24d93b
+#define MR_MIN_MAP_SIZE				0x10000
24d93b
+/* 64k */
24d93b
+
24d93b
 #define MR_CAN_HANDLE_SYNC_CACHE_OFFSET		0X01000000
24d93b
 
24d93b
 /*
24d93b
@@ -2152,6 +2158,7 @@ struct megasas_instance {
24d93b
 	bool fw_sync_cache_support;
24d93b
 	bool is_ventura;
24d93b
 	bool msix_combined;
24d93b
+	u16 max_raid_mapsize;
24d93b
 };
24d93b
 struct MR_LD_VF_MAP {
24d93b
 	u32 size;
24d93b
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
24d93b
index 0722286..1d8cf03 100644
24d93b
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
24d93b
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
24d93b
@@ -4457,8 +4457,7 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
24d93b
 static void megasas_update_ext_vd_details(struct megasas_instance *instance)
24d93b
 {
24d93b
 	struct fusion_context *fusion;
24d93b
-	u32 old_map_sz;
24d93b
-	u32 new_map_sz;
24d93b
+	u32 ventura_map_sz = 0;
24d93b
 
24d93b
 	fusion = instance->ctrl_context;
24d93b
 	/* For MFI based controllers return dummy success */
24d93b
@@ -4488,21 +4487,38 @@ static void megasas_update_ext_vd_details(struct megasas_instance *instance)
24d93b
 		instance->supportmax256vd ? "Extended VD(240 VD)firmware" :
24d93b
 		"Legacy(64 VD) firmware");
24d93b
 
24d93b
-	old_map_sz = sizeof(struct MR_FW_RAID_MAP) +
24d93b
-				(sizeof(struct MR_LD_SPAN_MAP) *
24d93b
-				(instance->fw_supported_vd_count - 1));
24d93b
-	new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT);
24d93b
-	fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP) +
24d93b
-				(sizeof(struct MR_LD_SPAN_MAP) *
24d93b
-				(instance->drv_supported_vd_count - 1));
24d93b
-
24d93b
-	fusion->max_map_sz = max(old_map_sz, new_map_sz);
24d93b
+	if (instance->max_raid_mapsize) {
24d93b
+		ventura_map_sz = instance->max_raid_mapsize *
24d93b
+						MR_MIN_MAP_SIZE; /* 64k */
24d93b
+		fusion->current_map_sz = ventura_map_sz;
24d93b
+		fusion->max_map_sz = ventura_map_sz;
24d93b
+	} else {
24d93b
+		fusion->old_map_sz =  sizeof(struct MR_FW_RAID_MAP) +
24d93b
+					(sizeof(struct MR_LD_SPAN_MAP) *
24d93b
+					(instance->fw_supported_vd_count - 1));
24d93b
+		fusion->new_map_sz =  sizeof(struct MR_FW_RAID_MAP_EXT);
24d93b
 
24d93b
+		fusion->max_map_sz =
24d93b
+			max(fusion->old_map_sz, fusion->new_map_sz);
24d93b
 
24d93b
-	if (instance->supportmax256vd)
24d93b
-		fusion->current_map_sz = new_map_sz;
24d93b
-	else
24d93b
-		fusion->current_map_sz = old_map_sz;
24d93b
+		if (instance->supportmax256vd)
24d93b
+			fusion->current_map_sz = fusion->new_map_sz;
24d93b
+		else
24d93b
+			fusion->current_map_sz = fusion->old_map_sz;
24d93b
+	}
24d93b
+	/* irrespective of FW raid maps, driver raid map is constant */
24d93b
+	fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP_ALL);
24d93b
+
24d93b
+#if VD_EXT_DEBUG
24d93b
+	dev_info(&instance->pdev->dev, "instance->max_raid_mapsize 0x%x\n ",
24d93b
+		instance->max_raid_mapsize);
24d93b
+	dev_info(&instance->pdev->dev, "new_map_sz = 0x%x, old_map_sz = 0x%x\n",
24d93b
+		fusion->new_map_sz, fusion->old_map_sz);
24d93b
+	dev_info(&instance->pdev->dev, "ventura_map_sz = 0x%x, current_map_sz = 0x%x\n",
24d93b
+		ventura_map_sz, fusion->current_map_sz);
24d93b
+	dev_info(&instance->pdev->dev, "fusion->drv_map_sz =0x%x, size of driver raid map 0x%lx\n",
24d93b
+		fusion->drv_map_sz, sizeof(struct MR_DRV_RAID_MAP_ALL));
24d93b
+#endif
24d93b
 }
24d93b
 
24d93b
 /**
24d93b
@@ -5043,7 +5059,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
24d93b
 {
24d93b
 	u32 max_sectors_1;
24d93b
 	u32 max_sectors_2;
24d93b
-	u32 tmp_sectors, msix_enable, scratch_pad_2;
24d93b
+	u32 tmp_sectors, msix_enable, scratch_pad_2, scratch_pad_3;
24d93b
 	resource_size_t base_addr;
24d93b
 	struct megasas_register_set __iomem *reg_set;
24d93b
 	struct megasas_ctrl_info *ctrl_info = NULL;
24d93b
@@ -5119,7 +5135,17 @@ static int megasas_init_fw(struct megasas_instance *instance)
24d93b
 			goto fail_ready_state;
24d93b
 	}
24d93b
 
24d93b
-
24d93b
+	if (instance->is_ventura) {
24d93b
+		scratch_pad_3 =
24d93b
+			readl(&instance->reg_set->outbound_scratch_pad_3);
24d93b
+#if VD_EXT_DEBUG
24d93b
+		dev_info(&instance->pdev->dev, "scratch_pad3 0x%x\n",
24d93b
+			scratch_pad_3);
24d93b
+#endif
24d93b
+		instance->max_raid_mapsize = ((scratch_pad_3 >>
24d93b
+			MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT) &
24d93b
+			MR_MAX_RAID_MAP_SIZE_MASK);
24d93b
+	}
24d93b
 
24d93b
 	/* Check if MSI-X is supported while in ready state */
24d93b
 	msix_enable = (instance->instancet->read_fw_status_reg(reg_set) &
24d93b
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c
24d93b
index 3644dbc..e45affe 100644
24d93b
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
24d93b
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
24d93b
@@ -179,18 +179,204 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
24d93b
 	struct fusion_context *fusion = instance->ctrl_context;
24d93b
 	struct MR_FW_RAID_MAP_ALL     *fw_map_old    = NULL;
24d93b
 	struct MR_FW_RAID_MAP         *pFwRaidMap    = NULL;
24d93b
-	int i;
24d93b
+	int i, j;
24d93b
 	u16 ld_count;
24d93b
+	struct MR_FW_RAID_MAP_DYNAMIC *fw_map_dyn;
24d93b
+	struct MR_FW_RAID_MAP_EXT *fw_map_ext;
24d93b
+	struct MR_RAID_MAP_DESC_TABLE *desc_table;
24d93b
 
24d93b
 
24d93b
 	struct MR_DRV_RAID_MAP_ALL *drv_map =
24d93b
 			fusion->ld_drv_map[(instance->map_id & 1)];
24d93b
 	struct MR_DRV_RAID_MAP *pDrvRaidMap = &drv_map->raidMap;
24d93b
+	void *raid_map_data = NULL;
24d93b
+
24d93b
+	memset(drv_map, 0, fusion->drv_map_sz);
24d93b
+	memset(pDrvRaidMap->ldTgtIdToLd,
24d93b
+		0xff, (sizeof(u16) * MAX_LOGICAL_DRIVES_DYN));
24d93b
+
24d93b
+	if (instance->max_raid_mapsize) {
24d93b
+		fw_map_dyn = fusion->ld_map[(instance->map_id & 1)];
24d93b
+#if VD_EXT_DEBUG
24d93b
+		dev_dbg(&instance->pdev->dev, "raidMapSize 0x%x fw_map_dyn->descTableOffset 0x%x\n",
24d93b
+			le32_to_cpu(fw_map_dyn->raid_map_size),
24d93b
+			le32_to_cpu(fw_map_dyn->desc_table_offset));
24d93b
+		dev_dbg(&instance->pdev->dev, "descTableSize 0x%x descTableNumElements 0x%x\n",
24d93b
+			le32_to_cpu(fw_map_dyn->desc_table_size),
24d93b
+			le32_to_cpu(fw_map_dyn->desc_table_num_elements));
24d93b
+		dev_dbg(&instance->pdev->dev, "drv map %p ldCount %d\n",
24d93b
+			drv_map, fw_map_dyn->ld_count);
24d93b
+#endif
24d93b
+		desc_table =
24d93b
+		(struct MR_RAID_MAP_DESC_TABLE *)((void *)fw_map_dyn + le32_to_cpu(fw_map_dyn->desc_table_offset));
24d93b
+		if (desc_table != fw_map_dyn->raid_map_desc_table)
24d93b
+			dev_dbg(&instance->pdev->dev, "offsets of desc table are not matching desc %p original %p\n",
24d93b
+				desc_table, fw_map_dyn->raid_map_desc_table);
24d93b
+
24d93b
+		ld_count = (u16)le16_to_cpu(fw_map_dyn->ld_count);
24d93b
+		pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count);
24d93b
+		pDrvRaidMap->fpPdIoTimeoutSec =
24d93b
+			fw_map_dyn->fp_pd_io_timeout_sec;
24d93b
+		pDrvRaidMap->totalSize = sizeof(struct MR_DRV_RAID_MAP_ALL);
24d93b
+		/* point to actual data starting point*/
24d93b
+		raid_map_data = (void *)fw_map_dyn +
24d93b
+			le32_to_cpu(fw_map_dyn->desc_table_offset) +
24d93b
+			le32_to_cpu(fw_map_dyn->desc_table_size);
24d93b
+
24d93b
+		for (i = 0; i < le32_to_cpu(fw_map_dyn->desc_table_num_elements); ++i) {
24d93b
+
24d93b
+#if VD_EXT_DEBUG
24d93b
+			dev_dbg(&instance->pdev->dev, "desc table %p\n",
24d93b
+				desc_table);
24d93b
+			dev_dbg(&instance->pdev->dev, "raidmap type %d, raidmapOffset 0x%x\n",
24d93b
+				desc_table->raid_map_desc_type,
24d93b
+				desc_table->raid_map_desc_offset);
24d93b
+			dev_dbg(&instance->pdev->dev, "raid map number of elements 0%x, raidmapsize 0x%x\n",
24d93b
+				desc_table->raid_map_desc_elements,
24d93b
+				desc_table->raid_map_desc_buffer_size);
24d93b
+#endif
24d93b
+			switch (le32_to_cpu(desc_table->raid_map_desc_type)) {
24d93b
+			case RAID_MAP_DESC_TYPE_DEVHDL_INFO:
24d93b
+				fw_map_dyn->dev_hndl_info =
24d93b
+				(struct MR_DEV_HANDLE_INFO *)(raid_map_data + le32_to_cpu(desc_table->raid_map_desc_offset));
24d93b
+#if VD_EXT_DEBUG
24d93b
+				dev_dbg(&instance->pdev->dev, "devHndlInfo  address %p\n",
24d93b
+					fw_map_dyn->dev_hndl_info);
24d93b
+#endif
24d93b
+				memcpy(pDrvRaidMap->devHndlInfo,
24d93b
+				fw_map_dyn->dev_hndl_info,
24d93b
+				sizeof(struct MR_DEV_HANDLE_INFO) *
24d93b
+				le32_to_cpu(desc_table->raid_map_desc_elements));
24d93b
+			break;
24d93b
+			case RAID_MAP_DESC_TYPE_TGTID_INFO:
24d93b
+				fw_map_dyn->ld_tgt_id_to_ld =
24d93b
+				(u16 *) (raid_map_data +
24d93b
+				le32_to_cpu(desc_table->raid_map_desc_offset));
24d93b
+#if VD_EXT_DEBUG
24d93b
+			dev_dbg(&instance->pdev->dev, "ldTgtIdToLd  address %p\n",
24d93b
+				fw_map_dyn->ld_tgt_id_to_ld);
24d93b
+#endif
24d93b
+			for (j = 0; j < le32_to_cpu(desc_table->raid_map_desc_elements); j++) {
24d93b
+				pDrvRaidMap->ldTgtIdToLd[j] =
24d93b
+				fw_map_dyn->ld_tgt_id_to_ld[j];
24d93b
+#if VD_EXT_DEBUG
24d93b
+				dev_dbg(&instance->pdev->dev, " %d drv ldTgtIdToLd %d\n",
24d93b
+					j, pDrvRaidMap->ldTgtIdToLd[j]);
24d93b
+#endif
24d93b
+			}
24d93b
+			break;
24d93b
+			case RAID_MAP_DESC_TYPE_ARRAY_INFO:
24d93b
+				fw_map_dyn->ar_map_info =
24d93b
+				(struct MR_ARRAY_INFO *)
24d93b
+				(raid_map_data + le32_to_cpu(desc_table->raid_map_desc_offset));
24d93b
+#if VD_EXT_DEBUG
24d93b
+				dev_dbg(&instance->pdev->dev, "arMapInfo  address %p\n",
24d93b
+					fw_map_dyn->ar_map_info);
24d93b
+#endif
24d93b
+
24d93b
+				memcpy(pDrvRaidMap->arMapInfo,
24d93b
+				fw_map_dyn->ar_map_info,
24d93b
+				sizeof(struct MR_ARRAY_INFO) * le32_to_cpu(desc_table->raid_map_desc_elements));
24d93b
+			break;
24d93b
+			case RAID_MAP_DESC_TYPE_SPAN_INFO:
24d93b
+				fw_map_dyn->ld_span_map =
24d93b
+				(struct MR_LD_SPAN_MAP *)
24d93b
+				(raid_map_data + le32_to_cpu(desc_table->raid_map_desc_offset));
24d93b
+				memcpy(pDrvRaidMap->ldSpanMap,
24d93b
+				fw_map_dyn->ld_span_map,
24d93b
+				sizeof(struct MR_LD_SPAN_MAP) * le32_to_cpu(desc_table->raid_map_desc_elements));
24d93b
+#if VD_EXT_DEBUG
24d93b
+				dev_dbg(&instance->pdev->dev, "ldSpanMap  address %p\n",
24d93b
+					fw_map_dyn->ld_span_map);
24d93b
+				dev_dbg(&instance->pdev->dev, "MR_LD_SPAN_MAP size 0x%lx\n",
24d93b
+					sizeof(struct MR_LD_SPAN_MAP));
24d93b
+				for (j = 0; j < ld_count; j++) {
24d93b
+					dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : fw_map_dyn->ldSpanMap[%d].ldRaid.targetId 0x%x\n",
24d93b
+					j, j, fw_map_dyn->ld_span_map[j].ldRaid.targetId);
24d93b
+					dev_dbg(&instance->pdev->dev, "fw_map_dyn->ldSpanMap[%d].ldRaid.seqNum 0x%x\n",
24d93b
+					j, fw_map_dyn->ld_span_map[j].ldRaid.seqNum);
24d93b
+					dev_dbg(&instance->pdev->dev, "fw_map_dyn->ld_span_map[%d].ldRaid.rowSize 0x%x\n",
24d93b
+					j, (u32)fw_map_dyn->ld_span_map[j].ldRaid.rowSize);
24d93b
+
24d93b
+					dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) :pDrvRaidMap->ldSpanMap[%d].ldRaid.targetId 0x%x\n",
24d93b
+					j, j, pDrvRaidMap->ldSpanMap[j].ldRaid.targetId);
24d93b
+					dev_dbg(&instance->pdev->dev, "DrvRaidMap->ldSpanMap[%d].ldRaid.seqNum 0x%x\n",
24d93b
+					j, pDrvRaidMap->ldSpanMap[j].ldRaid.seqNum);
24d93b
+					dev_dbg(&instance->pdev->dev, "pDrvRaidMap->ldSpanMap[%d].ldRaid.rowSize 0x%x\n",
24d93b
+					j, (u32)pDrvRaidMap->ldSpanMap[j].ldRaid.rowSize);
24d93b
+
24d93b
+					dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : drv raid map all %p\n",
24d93b
+					instance->unique_id, drv_map);
24d93b
+					dev_dbg(&instance->pdev->dev, "raid map %p LD RAID MAP %p/%p\n",
24d93b
+					pDrvRaidMap,
24d93b
+					&fw_map_dyn->ld_span_map[j].ldRaid,
24d93b
+					&pDrvRaidMap->ldSpanMap[j].ldRaid);
24d93b
+				}
24d93b
+#endif
24d93b
+			break;
24d93b
+			default:
24d93b
+				dev_dbg(&instance->pdev->dev, "wrong number of desctableElements %d\n",
24d93b
+					fw_map_dyn->desc_table_num_elements);
24d93b
+			}
24d93b
+			++desc_table;
24d93b
+		}
24d93b
+
24d93b
+	} else if (instance->supportmax256vd) {
24d93b
+		fw_map_ext =
24d93b
+		(struct MR_FW_RAID_MAP_EXT *) fusion->ld_map[(instance->map_id & 1)];
24d93b
+		ld_count = (u16)le16_to_cpu(fw_map_ext->ldCount);
24d93b
+		if (ld_count > MAX_LOGICAL_DRIVES_EXT) {
24d93b
+			dev_dbg(&instance->pdev->dev, "megaraid_sas: LD count exposed in RAID map in not valid\n");
24d93b
+			return;
24d93b
+		}
24d93b
+#if VD_EXT_DEBUG
24d93b
+		for (i = 0; i < ld_count; i++) {
24d93b
+			dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) :Index 0x%x\n",
24d93b
+				instance->unique_id, i);
24d93b
+			dev_dbg(&instance->pdev->dev, "Target Id 0x%x\n",
24d93b
+				fw_map_ext->ldSpanMap[i].ldRaid.targetId);
24d93b
+			dev_dbg(&instance->pdev->dev, "Seq Num 0x%x Size 0/%llx\n",
24d93b
+				fw_map_ext->ldSpanMap[i].ldRaid.seqNum,
24d93b
+				fw_map_ext->ldSpanMap[i].ldRaid.size);
24d93b
+		}
24d93b
+#endif
24d93b
+
24d93b
+		pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count);
24d93b
+		pDrvRaidMap->fpPdIoTimeoutSec = fw_map_ext->fpPdIoTimeoutSec;
24d93b
+		for (i = 0; i < (MAX_LOGICAL_DRIVES_EXT); i++)
24d93b
+			pDrvRaidMap->ldTgtIdToLd[i] =
24d93b
+				(u16)fw_map_ext->ldTgtIdToLd[i];
24d93b
+		memcpy(pDrvRaidMap->ldSpanMap, fw_map_ext->ldSpanMap,
24d93b
+				sizeof(struct MR_LD_SPAN_MAP) * ld_count);
24d93b
+#if VD_EXT_DEBUG
24d93b
+		for (i = 0; i < ld_count; i++) {
24d93b
+			dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : fw_map_ext->ldSpanMap[%d].ldRaid.targetId 0x%x\n",
24d93b
+			i, i, fw_map_ext->ldSpanMap[i].ldRaid.targetId);
24d93b
+			dev_dbg(&instance->pdev->dev, "fw_map_ext->ldSpanMap[%d].ldRaid.seqNum 0x%x\n",
24d93b
+			i, fw_map_ext->ldSpanMap[i].ldRaid.seqNum);
24d93b
+			dev_dbg(&instance->pdev->dev, "fw_map_ext->ldSpanMap[%d].ldRaid.rowSize 0x%x\n",
24d93b
+			i, (u32)fw_map_ext->ldSpanMap[i].ldRaid.rowSize);
24d93b
+
24d93b
+			dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : pDrvRaidMap->ldSpanMap[%d].ldRaid.targetId 0x%x\n",
24d93b
+			i, i, pDrvRaidMap->ldSpanMap[i].ldRaid.targetId);
24d93b
+			dev_dbg(&instance->pdev->dev, "pDrvRaidMap->ldSpanMap[%d].ldRaid.seqNum 0x%x\n",
24d93b
+			i, pDrvRaidMap->ldSpanMap[i].ldRaid.seqNum);
24d93b
+			dev_dbg(&instance->pdev->dev, "pDrvRaidMap->ldSpanMap[%d].ldRaid.rowSize 0x%x\n",
24d93b
+			i, (u32)pDrvRaidMap->ldSpanMap[i].ldRaid.rowSize);
24d93b
+
24d93b
+			dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : drv raid map all %p\n",
24d93b
+			instance->unique_id, drv_map);
24d93b
+			dev_dbg(&instance->pdev->dev, "raid map %p LD RAID MAP %p %p\n",
24d93b
+			pDrvRaidMap, &fw_map_ext->ldSpanMap[i].ldRaid,
24d93b
+			&pDrvRaidMap->ldSpanMap[i].ldRaid);
24d93b
+		}
24d93b
+#endif
24d93b
+		memcpy(pDrvRaidMap->arMapInfo, fw_map_ext->arMapInfo,
24d93b
+			sizeof(struct MR_ARRAY_INFO) * MAX_API_ARRAYS_EXT);
24d93b
+		memcpy(pDrvRaidMap->devHndlInfo, fw_map_ext->devHndlInfo,
24d93b
+			sizeof(struct MR_DEV_HANDLE_INFO) *
24d93b
+					MAX_RAIDMAP_PHYSICAL_DEVICES);
24d93b
 
24d93b
-	if (instance->supportmax256vd) {
24d93b
-		memcpy(fusion->ld_drv_map[instance->map_id & 1],
24d93b
-			fusion->ld_map[instance->map_id & 1],
24d93b
-			fusion->current_map_sz);
24d93b
 		/* New Raid map will not set totalSize, so keep expected value
24d93b
 		 * for legacy code in ValidateMapInfo
24d93b
 		 */
24d93b
@@ -213,16 +399,12 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
24d93b
 		}
24d93b
 #endif
24d93b
 
24d93b
-		memset(drv_map, 0, fusion->drv_map_sz);
24d93b
 		pDrvRaidMap->totalSize = pFwRaidMap->totalSize;
24d93b
 		pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count);
24d93b
 		pDrvRaidMap->fpPdIoTimeoutSec = pFwRaidMap->fpPdIoTimeoutSec;
24d93b
 		for (i = 0; i < MAX_RAIDMAP_LOGICAL_DRIVES + MAX_RAIDMAP_VIEWS; i++)
24d93b
 			pDrvRaidMap->ldTgtIdToLd[i] =
24d93b
 				(u8)pFwRaidMap->ldTgtIdToLd[i];
24d93b
-		for (i = (MAX_RAIDMAP_LOGICAL_DRIVES + MAX_RAIDMAP_VIEWS);
24d93b
-			i < MAX_LOGICAL_DRIVES_EXT; i++)
24d93b
-			pDrvRaidMap->ldTgtIdToLd[i] = 0xff;
24d93b
 		for (i = 0; i < ld_count; i++) {
24d93b
 			pDrvRaidMap->ldSpanMap[i] = pFwRaidMap->ldSpanMap[i];
24d93b
 #if VD_EXT_DEBUG
24d93b
@@ -279,7 +461,9 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance)
24d93b
 	lbInfo = fusion->load_balance_info;
24d93b
 	ldSpanInfo = fusion->log_to_span;
24d93b
 
24d93b
-	if (instance->supportmax256vd)
24d93b
+	if (instance->max_raid_mapsize)
24d93b
+		expected_size = sizeof(struct MR_DRV_RAID_MAP_ALL);
24d93b
+	else if (instance->supportmax256vd)
24d93b
 		expected_size = sizeof(struct MR_FW_RAID_MAP_EXT);
24d93b
 	else
24d93b
 		expected_size =
24d93b
@@ -287,8 +471,10 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance)
24d93b
 			(sizeof(struct MR_LD_SPAN_MAP) * le16_to_cpu(pDrvRaidMap->ldCount)));
24d93b
 
24d93b
 	if (le32_to_cpu(pDrvRaidMap->totalSize) != expected_size) {
24d93b
-		dev_err(&instance->pdev->dev, "map info structure size 0x%x is not matching with ld count\n",
24d93b
-		       (unsigned int) expected_size);
24d93b
+		dev_dbg(&instance->pdev->dev, "megasas: map info structure size 0x%x",
24d93b
+			le32_to_cpu(pDrvRaidMap->totalSize));
24d93b
+		dev_dbg(&instance->pdev->dev, "is not matching expected size 0x%x\n",
24d93b
+			(unsigned int) expected_size);
24d93b
 		dev_err(&instance->pdev->dev, "megasas: span map %x, pDrvRaidMap->totalSize : %x\n",
24d93b
 			(unsigned int)sizeof(struct MR_LD_SPAN_MAP),
24d93b
 			le32_to_cpu(pDrvRaidMap->totalSize));
24d93b
@@ -787,7 +973,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
24d93b
 			((fusion->adapter_type == THUNDERBOLT_SERIES)  ||
24d93b
 			((fusion->adapter_type == INVADER_SERIES) &&
24d93b
 			(raid->regTypeReqOnRead != REGION_TYPE_UNUSED))))
24d93b
-			pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
24d93b
+			pRAID_Context->reg_lock_flags = REGION_TYPE_EXCLUSIVE;
24d93b
 		else if (raid->level == 1) {
24d93b
 			pd = MR_ArPdGet(arRef, physArm + 1, map);
24d93b
 			if (pd != MR_PD_INVALID)
24d93b
@@ -796,9 +982,16 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
24d93b
 	}
24d93b
 
24d93b
 	*pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, map)->startBlk);
24d93b
-	pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) |
24d93b
-					physArm;
24d93b
-	io_info->span_arm = pRAID_Context->spanArm;
24d93b
+	if (instance->is_ventura) {
24d93b
+		((struct RAID_CONTEXT_G35 *) pRAID_Context)->span_arm =
24d93b
+			(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
24d93b
+		io_info->span_arm =
24d93b
+			(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
24d93b
+	} else {
24d93b
+		pRAID_Context->span_arm =
24d93b
+			(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
24d93b
+		io_info->span_arm = pRAID_Context->span_arm;
24d93b
+	}
24d93b
 	return retval;
24d93b
 }
24d93b
 
24d93b
@@ -890,7 +1083,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
24d93b
 			((fusion->adapter_type == THUNDERBOLT_SERIES)  ||
24d93b
 			((fusion->adapter_type == INVADER_SERIES) &&
24d93b
 			(raid->regTypeReqOnRead != REGION_TYPE_UNUSED))))
24d93b
-			pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
24d93b
+			pRAID_Context->reg_lock_flags = REGION_TYPE_EXCLUSIVE;
24d93b
 		else if (raid->level == 1) {
24d93b
 			/* Get alternate Pd. */
24d93b
 			pd = MR_ArPdGet(arRef, physArm + 1, map);
24d93b
@@ -901,9 +1094,16 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
24d93b
 	}
24d93b
 
24d93b
 	*pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, map)->startBlk);
24d93b
-	pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) |
24d93b
-		physArm;
24d93b
-	io_info->span_arm = pRAID_Context->spanArm;
24d93b
+	if (instance->is_ventura) {
24d93b
+		((struct RAID_CONTEXT_G35 *) pRAID_Context)->span_arm =
24d93b
+				(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
24d93b
+		io_info->span_arm =
24d93b
+				(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
24d93b
+	} else {
24d93b
+		pRAID_Context->span_arm =
24d93b
+			(span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
24d93b
+		io_info->span_arm = pRAID_Context->span_arm;
24d93b
+	}
24d93b
 	return retval;
24d93b
 }
24d93b
 
24d93b
@@ -1107,20 +1307,20 @@ MR_BuildRaidContext(struct megasas_instance *instance,
24d93b
 			regSize += stripSize;
24d93b
 	}
24d93b
 
24d93b
-	pRAID_Context->timeoutValue =
24d93b
+	pRAID_Context->timeout_value =
24d93b
 		cpu_to_le16(raid->fpIoTimeoutForLd ?
24d93b
 			    raid->fpIoTimeoutForLd :
24d93b
 			    map->raidMap.fpPdIoTimeoutSec);
24d93b
 	if (fusion->adapter_type == INVADER_SERIES)
24d93b
-		pRAID_Context->regLockFlags = (isRead) ?
24d93b
+		pRAID_Context->reg_lock_flags = (isRead) ?
24d93b
 			raid->regTypeReqOnRead : raid->regTypeReqOnWrite;
24d93b
-	else
24d93b
-		pRAID_Context->regLockFlags = (isRead) ?
24d93b
+	else if (!instance->is_ventura)
24d93b
+		pRAID_Context->reg_lock_flags = (isRead) ?
24d93b
 			REGION_TYPE_SHARED_READ : raid->regTypeReqOnWrite;
24d93b
-	pRAID_Context->VirtualDiskTgtId = raid->targetId;
24d93b
-	pRAID_Context->regLockRowLBA    = cpu_to_le64(regStart);
24d93b
-	pRAID_Context->regLockLength    = cpu_to_le32(regSize);
24d93b
-	pRAID_Context->configSeqNum	= raid->seqNum;
24d93b
+	pRAID_Context->virtual_disk_tgt_id = raid->targetId;
24d93b
+	pRAID_Context->reg_lock_row_lba    = cpu_to_le64(regStart);
24d93b
+	pRAID_Context->reg_lock_length    = cpu_to_le32(regSize);
24d93b
+	pRAID_Context->config_seq_num	= raid->seqNum;
24d93b
 	/* save pointer to raid->LUN array */
24d93b
 	*raidLUN = raid->LUN;
24d93b
 
24d93b
@@ -1138,6 +1338,13 @@ MR_BuildRaidContext(struct megasas_instance *instance,
24d93b
 		/* If IO on an invalid Pd, then FP is not possible.*/
24d93b
 		if (io_info->devHandle == cpu_to_le16(MR_PD_INVALID))
24d93b
 			io_info->fpOkForIo = FALSE;
24d93b
+		/* if FP possible, set the SLUD bit in
24d93b
+		 *  regLockFlags for ventura
24d93b
+		 */
24d93b
+		else if ((instance->is_ventura) && (!isRead) &&
24d93b
+			(raid->writeMode == MR_RL_WRITE_BACK_MODE) &&
24d93b
+			(raid->capability.fp_cache_bypass_capable))
24d93b
+			((struct RAID_CONTEXT_G35 *) pRAID_Context)->routing_flags.bits.sld = 1;
24d93b
 		/* set raid 1/10 fast path write capable bit in io_info */
24d93b
 		if (io_info->fpOkForIo &&
24d93b
 		    (io_info->r1_alt_dev_handle != MR_PD_INVALID) &&
24d93b
@@ -1317,6 +1524,7 @@ u8 megasas_get_best_arm_pd(struct megasas_instance *instance,
24d93b
 	struct fusion_context *fusion;
24d93b
 	struct MR_LD_RAID  *raid;
24d93b
 	struct MR_DRV_RAID_MAP_ALL *drv_map;
24d93b
+	u16	pd1_dev_handle;
24d93b
 	u16     pend0, pend1, ld;
24d93b
 	u64     diff0, diff1;
24d93b
 	u8      bestArm, pd0, pd1, span, arm;
24d93b
@@ -1342,23 +1550,36 @@ u8 megasas_get_best_arm_pd(struct megasas_instance *instance,
24d93b
 	pd1 = MR_ArPdGet(arRef, (arm + 1) >= span_row_size ?
24d93b
 		(arm + 1 - span_row_size) : arm + 1, drv_map);
24d93b
 
24d93b
-	/* get the pending cmds for the data and mirror arms */
24d93b
-	pend0 = atomic_read(&lbInfo->scsi_pending_cmds[pd0]);
24d93b
-	pend1 = atomic_read(&lbInfo->scsi_pending_cmds[pd1]);
24d93b
+	/* Get PD1 Dev Handle */
24d93b
+
24d93b
+	pd1_dev_handle = MR_PdDevHandleGet(pd1, drv_map);
24d93b
+
24d93b
+	if (pd1_dev_handle == MR_PD_INVALID) {
24d93b
+		bestArm = arm;
24d93b
+	} else {
24d93b
+		/* get the pending cmds for the data and mirror arms */
24d93b
+		pend0 = atomic_read(&lbInfo->scsi_pending_cmds[pd0]);
24d93b
+		pend1 = atomic_read(&lbInfo->scsi_pending_cmds[pd1]);
24d93b
 
24d93b
-	/* Determine the disk whose head is nearer to the req. block */
24d93b
-	diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[pd0]);
24d93b
-	diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[pd1]);
24d93b
-	bestArm = (diff0 <= diff1 ? arm : arm ^ 1);
24d93b
+		/* Determine the disk whose head is nearer to the req. block */
24d93b
+		diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[pd0]);
24d93b
+		diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[pd1]);
24d93b
+		bestArm = (diff0 <= diff1 ? arm : arm ^ 1);
24d93b
 
24d93b
-	if ((bestArm == arm && pend0 > pend1 + lb_pending_cmds)  ||
24d93b
+		/* Make balance count from 16 to 4 to
24d93b
+		 *  keep driver in sync with Firmware
24d93b
+		 */
24d93b
+		if ((bestArm == arm && pend0 > pend1 + lb_pending_cmds)  ||
24d93b
 			(bestArm != arm && pend1 > pend0 + lb_pending_cmds))
24d93b
-		bestArm ^= 1;
24d93b
+			bestArm ^= 1;
24d93b
+
24d93b
+		/* Update the last accessed block on the correct pd */
24d93b
+		io_info->span_arm =
24d93b
+			(span << RAID_CTX_SPANARM_SPAN_SHIFT) | bestArm;
24d93b
+		io_info->pd_after_lb = (bestArm == arm) ? pd0 : pd1;
24d93b
+	}
24d93b
 
24d93b
-	/* Update the last accessed block on the correct pd */
24d93b
-	io_info->pd_after_lb = (bestArm == arm) ? pd0 : pd1;
24d93b
 	lbInfo->last_accessed_block[io_info->pd_after_lb] = block + count - 1;
24d93b
-	io_info->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | bestArm;
24d93b
 #if SPAN_DEBUG
24d93b
 	if (arm != bestArm)
24d93b
 		dev_dbg(&instance->pdev->dev, "LSI Debug R1 Load balance "
24d93b
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
24d93b
index b146cd1..178f166 100644
24d93b
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
24d93b
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
24d93b
@@ -1829,7 +1829,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
24d93b
 			  struct megasas_cmd_fusion *cmd)
24d93b
 {
24d93b
 	u8 fp_possible;
24d93b
-	u32 start_lba_lo, start_lba_hi, device_id, datalength = 0;
24d93b
+	u32 start_lba_lo, start_lba_hi, device_id, datalength = 0, ld;
24d93b
 	struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
24d93b
 	union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
24d93b
 	struct IO_REQUEST_INFO io_info;
24d93b
@@ -1837,16 +1837,18 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
24d93b
 	struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
24d93b
 	u8 *raidLUN;
24d93b
 	unsigned long spinlock_flags;
24d93b
+	union RAID_CONTEXT_UNION *praid_context;
24d93b
+	struct MR_LD_RAID *raid;
24d93b
 
24d93b
 	device_id = MEGASAS_DEV_INDEX(scp);
24d93b
 
24d93b
 	fusion = instance->ctrl_context;
24d93b
 
24d93b
 	io_request = cmd->io_request;
24d93b
-	io_request->RaidContext.raid_context.VirtualDiskTgtId =
24d93b
+	io_request->RaidContext.raid_context.virtual_disk_tgt_id =
24d93b
 		cpu_to_le16(device_id);
24d93b
 	io_request->RaidContext.raid_context.status = 0;
24d93b
-	io_request->RaidContext.raid_context.exStatus = 0;
24d93b
+	io_request->RaidContext.raid_context.ex_status = 0;
24d93b
 
24d93b
 	req_desc = (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)cmd->request_desc;
24d93b
 
24d93b
@@ -1915,10 +1917,12 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
24d93b
 		io_info.isRead = 1;
24d93b
 
24d93b
 	local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
24d93b
+	ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
24d93b
+	raid = MR_LdRaidGet(ld, local_map_ptr);
24d93b
 
24d93b
 	if ((MR_TargetIdToLdGet(device_id, local_map_ptr) >=
24d93b
 		instance->fw_supported_vd_count) || (!fusion->fast_path_io)) {
24d93b
-		io_request->RaidContext.raid_context.regLockFlags  = 0;
24d93b
+		io_request->RaidContext.raid_context.reg_lock_flags  = 0;
24d93b
 		fp_possible = 0;
24d93b
 	} else {
24d93b
 		if (MR_BuildRaidContext(instance, &io_info,
24d93b
@@ -1945,6 +1949,8 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
24d93b
 			fp_possible = false;
24d93b
 	}
24d93b
 
24d93b
+	praid_context = &io_request->RaidContext;
24d93b
+
24d93b
 	if (fp_possible) {
24d93b
 		megasas_set_pd_lba(io_request, scp->cmd_len, &io_info, scp,
24d93b
 				   local_map_ptr, start_lba_lo);
24d93b
@@ -1953,18 +1959,25 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
24d93b
 			(MPI2_REQ_DESCRIPT_FLAGS_FP_IO
24d93b
 			 << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
24d93b
 		if (fusion->adapter_type == INVADER_SERIES) {
24d93b
-			if (io_request->RaidContext.raid_context.regLockFlags ==
24d93b
+			if (io_request->RaidContext.raid_context.reg_lock_flags ==
24d93b
 			    REGION_TYPE_UNUSED)
24d93b
 				cmd->request_desc->SCSIIO.RequestFlags =
24d93b
 					(MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK <<
24d93b
 					MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
24d93b
-			io_request->RaidContext.raid_context.Type
24d93b
+			io_request->RaidContext.raid_context.type
24d93b
 				= MPI2_TYPE_CUDA;
24d93b
 			io_request->RaidContext.raid_context.nseg = 0x1;
24d93b
 			io_request->IoFlags |= cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
24d93b
-			io_request->RaidContext.raid_context.regLockFlags |=
24d93b
+			io_request->RaidContext.raid_context.reg_lock_flags |=
24d93b
 			  (MR_RL_FLAGS_GRANT_DESTINATION_CUDA |
24d93b
 			   MR_RL_FLAGS_SEQ_NUM_ENABLE);
24d93b
+		} else if (instance->is_ventura) {
24d93b
+			io_request->RaidContext.raid_context_g35.type
24d93b
+				= MPI2_TYPE_CUDA;
24d93b
+			io_request->RaidContext.raid_context_g35.nseg = 0x1;
24d93b
+			io_request->RaidContext.raid_context_g35.routing_flags.bits.sqn = 1;
24d93b
+			io_request->IoFlags |=
24d93b
+			cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
24d93b
 		}
24d93b
 		if ((fusion->load_balance_info[device_id].loadBalanceFlag) &&
24d93b
 		    (io_info.isRead)) {
24d93b
@@ -1974,6 +1987,13 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
24d93b
 					&io_info);
24d93b
 			scp->SCp.Status |= MEGASAS_LOAD_BALANCE_FLAG;
24d93b
 			cmd->pd_r1_lb = io_info.pd_after_lb;
24d93b
+			if (instance->is_ventura)
24d93b
+				io_request->RaidContext.raid_context_g35.span_arm
24d93b
+					= io_info.span_arm;
24d93b
+			else
24d93b
+				io_request->RaidContext.raid_context.span_arm
24d93b
+					= io_info.span_arm;
24d93b
+
24d93b
 		} else
24d93b
 			scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG;
24d93b
 
24d93b
@@ -1992,28 +2012,98 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
24d93b
 		io_request->DevHandle = io_info.devHandle;
24d93b
 		/* populate the LUN field */
24d93b
 		memcpy(io_request->LUN, raidLUN, 8);
24d93b
+		if (instance->is_ventura) {
24d93b
+			if (io_info.isRead) {
24d93b
+				if ((raid->cpuAffinity.pdRead.cpu0) &&
24d93b
+					(raid->cpuAffinity.pdRead.cpu1))
24d93b
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+					= MR_RAID_CTX_CPUSEL_FCFS;
24d93b
+				else if (raid->cpuAffinity.pdRead.cpu1)
24d93b
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+					= MR_RAID_CTX_CPUSEL_1;
24d93b
+				else
24d93b
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+					= MR_RAID_CTX_CPUSEL_0;
24d93b
+			} else {
24d93b
+			if ((raid->cpuAffinity.pdWrite.cpu0)
24d93b
+			&& (raid->cpuAffinity.pdWrite.cpu1))
24d93b
+				praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+					= MR_RAID_CTX_CPUSEL_FCFS;
24d93b
+				else if (raid->cpuAffinity.pdWrite.cpu1)
24d93b
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+					= MR_RAID_CTX_CPUSEL_1;
24d93b
+				else
24d93b
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+					= MR_RAID_CTX_CPUSEL_0;
24d93b
+				if (praid_context->raid_context_g35.routing_flags.bits.sld) {
24d93b
+					praid_context->raid_context_g35.raid_flags
24d93b
+					= (MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS
24d93b
+					<< MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT);
24d93b
+				}
24d93b
+			}
24d93b
+		}
24d93b
 	} else {
24d93b
-		io_request->RaidContext.raid_context.timeoutValue =
24d93b
+		io_request->RaidContext.raid_context.timeout_value =
24d93b
 			cpu_to_le16(local_map_ptr->raidMap.fpPdIoTimeoutSec);
24d93b
 		cmd->request_desc->SCSIIO.RequestFlags =
24d93b
 			(MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO
24d93b
 			 << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
24d93b
 		if (fusion->adapter_type == INVADER_SERIES) {
24d93b
 			if (io_info.do_fp_rlbypass ||
24d93b
-			(io_request->RaidContext.raid_context.regLockFlags
24d93b
+			(io_request->RaidContext.raid_context.reg_lock_flags
24d93b
 					== REGION_TYPE_UNUSED))
24d93b
 				cmd->request_desc->SCSIIO.RequestFlags =
24d93b
 					(MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK <<
24d93b
 					MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
24d93b
-			io_request->RaidContext.raid_context.Type
24d93b
+			io_request->RaidContext.raid_context.type
24d93b
 				= MPI2_TYPE_CUDA;
24d93b
-			io_request->RaidContext.raid_context.regLockFlags |=
24d93b
+			io_request->RaidContext.raid_context.reg_lock_flags |=
24d93b
 				(MR_RL_FLAGS_GRANT_DESTINATION_CPU0 |
24d93b
 				 MR_RL_FLAGS_SEQ_NUM_ENABLE);
24d93b
 			io_request->RaidContext.raid_context.nseg = 0x1;
24d93b
+		} else if (instance->is_ventura) {
24d93b
+			io_request->RaidContext.raid_context_g35.type
24d93b
+				= MPI2_TYPE_CUDA;
24d93b
+			io_request->RaidContext.raid_context_g35.routing_flags.bits.sqn = 1;
24d93b
+			io_request->RaidContext.raid_context_g35.nseg = 0x1;
24d93b
 		}
24d93b
 		io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
24d93b
 		io_request->DevHandle = cpu_to_le16(device_id);
24d93b
+
24d93b
+		if (instance->is_ventura) {
24d93b
+			if (io_info.isRead) {
24d93b
+				if ((raid->cpuAffinity.ldRead.cpu0)
24d93b
+				&& (raid->cpuAffinity.ldRead.cpu1))
24d93b
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+					= MR_RAID_CTX_CPUSEL_FCFS;
24d93b
+				else if (raid->cpuAffinity.ldRead.cpu1)
24d93b
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+						= MR_RAID_CTX_CPUSEL_1;
24d93b
+				else
24d93b
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+						= MR_RAID_CTX_CPUSEL_0;
24d93b
+			} else {
24d93b
+				if ((raid->cpuAffinity.ldWrite.cpu0) &&
24d93b
+					(raid->cpuAffinity.ldWrite.cpu1))
24d93b
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+						= MR_RAID_CTX_CPUSEL_FCFS;
24d93b
+				else if (raid->cpuAffinity.ldWrite.cpu1)
24d93b
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+						= MR_RAID_CTX_CPUSEL_1;
24d93b
+				else
24d93b
+					praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+					= MR_RAID_CTX_CPUSEL_0;
24d93b
+
24d93b
+				if (io_request->RaidContext.raid_context_g35.stream_detected
24d93b
+					&& (raid->level == 5) &&
24d93b
+					(raid->writeMode == MR_RL_WRITE_THROUGH_MODE)) {
24d93b
+					if (praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+						== MR_RAID_CTX_CPUSEL_FCFS)
24d93b
+						praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+							= MR_RAID_CTX_CPUSEL_0;
24d93b
+				}
24d93b
+			}
24d93b
+		}
24d93b
 	} /* Not FP */
24d93b
 }
24d93b
 
24d93b
@@ -2048,9 +2138,9 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
24d93b
 	/* get RAID_Context pointer */
24d93b
 	pRAID_Context = &io_request->RaidContext.raid_context;
24d93b
 	/* Check with FW team */
24d93b
-	pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
24d93b
-	pRAID_Context->regLockRowLBA    = 0;
24d93b
-	pRAID_Context->regLockLength    = 0;
24d93b
+	pRAID_Context->virtual_disk_tgt_id = cpu_to_le16(device_id);
24d93b
+	pRAID_Context->reg_lock_row_lba    = 0;
24d93b
+	pRAID_Context->reg_lock_length    = 0;
24d93b
 
24d93b
 	if (fusion->fast_path_io && (
24d93b
 		device_id < instance->fw_supported_vd_count)) {
24d93b
@@ -2069,7 +2159,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
24d93b
 		io_request->Function  = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
24d93b
 		io_request->DevHandle = cpu_to_le16(device_id);
24d93b
 		io_request->LUN[1] = scmd->device->lun;
24d93b
-		pRAID_Context->timeoutValue =
24d93b
+		pRAID_Context->timeout_value =
24d93b
 			cpu_to_le16 (scmd->request->timeout / HZ);
24d93b
 		cmd->request_desc->SCSIIO.RequestFlags =
24d93b
 			(MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
24d93b
@@ -2077,9 +2167,11 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
24d93b
 	} else {
24d93b
 
24d93b
 		/* set RAID context values */
24d93b
-		pRAID_Context->configSeqNum = raid->seqNum;
24d93b
-		pRAID_Context->regLockFlags = REGION_TYPE_SHARED_READ;
24d93b
-		pRAID_Context->timeoutValue = cpu_to_le16(raid->fpIoTimeoutForLd);
24d93b
+		pRAID_Context->config_seq_num = raid->seqNum;
24d93b
+		if (!instance->is_ventura)
24d93b
+			pRAID_Context->reg_lock_flags = REGION_TYPE_SHARED_READ;
24d93b
+		pRAID_Context->timeout_value =
24d93b
+			cpu_to_le16(raid->fpIoTimeoutForLd);
24d93b
 
24d93b
 		/* get the DevHandle for the PD (since this is
24d93b
 		   fpNonRWCapable, this is a single disk RAID0) */
24d93b
@@ -2134,12 +2226,12 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
24d93b
 	io_request = cmd->io_request;
24d93b
 	/* get RAID_Context pointer */
24d93b
 	pRAID_Context = &io_request->RaidContext.raid_context;
24d93b
-	pRAID_Context->regLockFlags = 0;
24d93b
-	pRAID_Context->regLockRowLBA = 0;
24d93b
-	pRAID_Context->regLockLength = 0;
24d93b
+	pRAID_Context->reg_lock_flags = 0;
24d93b
+	pRAID_Context->reg_lock_row_lba = 0;
24d93b
+	pRAID_Context->reg_lock_length = 0;
24d93b
 	io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
24d93b
 	io_request->LUN[1] = scmd->device->lun;
24d93b
-	pRAID_Context->RAIDFlags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
24d93b
+	pRAID_Context->raid_flags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
24d93b
 		<< MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
24d93b
 
24d93b
 	/* If FW supports PD sequence number */
24d93b
@@ -2148,24 +2240,27 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
24d93b
 		/* TgtId must be incremented by 255 as jbod seq number is index
24d93b
 		 * below raid map
24d93b
 		 */
24d93b
-		pRAID_Context->VirtualDiskTgtId =
24d93b
+		pRAID_Context->virtual_disk_tgt_id =
24d93b
 			cpu_to_le16(device_id + (MAX_PHYSICAL_DEVICES - 1));
24d93b
-		pRAID_Context->configSeqNum = pd_sync->seq[pd_index].seqNum;
24d93b
+		pRAID_Context->config_seq_num = pd_sync->seq[pd_index].seqNum;
24d93b
 		io_request->DevHandle = pd_sync->seq[pd_index].devHandle;
24d93b
-		pRAID_Context->regLockFlags |=
24d93b
+		if (instance->is_ventura)
24d93b
+			io_request->RaidContext.raid_context_g35.routing_flags.bits.sqn = 1;
24d93b
+		else
24d93b
+		pRAID_Context->reg_lock_flags |=
24d93b
 			(MR_RL_FLAGS_SEQ_NUM_ENABLE|MR_RL_FLAGS_GRANT_DESTINATION_CUDA);
24d93b
-		pRAID_Context->Type = MPI2_TYPE_CUDA;
24d93b
+		pRAID_Context->type = MPI2_TYPE_CUDA;
24d93b
 		pRAID_Context->nseg = 0x1;
24d93b
 	} else if (fusion->fast_path_io) {
24d93b
-		pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
24d93b
-		pRAID_Context->configSeqNum = 0;
24d93b
+		pRAID_Context->virtual_disk_tgt_id = cpu_to_le16(device_id);
24d93b
+		pRAID_Context->config_seq_num = 0;
24d93b
 		local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
24d93b
 		io_request->DevHandle =
24d93b
 			local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
24d93b
 	} else {
24d93b
 		/* Want to send all IO via FW path */
24d93b
-		pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
24d93b
-		pRAID_Context->configSeqNum = 0;
24d93b
+		pRAID_Context->virtual_disk_tgt_id = cpu_to_le16(device_id);
24d93b
+		pRAID_Context->config_seq_num = 0;
24d93b
 		io_request->DevHandle = cpu_to_le16(0xFFFF);
24d93b
 	}
24d93b
 
24d93b
@@ -2181,14 +2276,14 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
24d93b
 		cmd->request_desc->SCSIIO.RequestFlags =
24d93b
 			(MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
24d93b
 				MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
24d93b
-		pRAID_Context->timeoutValue = cpu_to_le16(os_timeout_value);
24d93b
-		pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
24d93b
+		pRAID_Context->timeout_value = cpu_to_le16(os_timeout_value);
24d93b
+		pRAID_Context->virtual_disk_tgt_id = cpu_to_le16(device_id);
24d93b
 	} else {
24d93b
 		/* system pd Fast Path */
24d93b
 		io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
24d93b
 		timeout_limit = (scmd->device->type == TYPE_DISK) ?
24d93b
 				255 : 0xFFFF;
24d93b
-		pRAID_Context->timeoutValue =
24d93b
+		pRAID_Context->timeout_value =
24d93b
 			cpu_to_le16((os_timeout_value > timeout_limit) ?
24d93b
 			timeout_limit : os_timeout_value);
24d93b
 		if (fusion->adapter_type == INVADER_SERIES)
24d93b
@@ -2227,8 +2322,8 @@ megasas_build_io_fusion(struct megasas_instance *instance,
24d93b
 	io_request->Control = 0;
24d93b
 	io_request->EEDPBlockSize = 0;
24d93b
 	io_request->ChainOffset = 0;
24d93b
-	io_request->RaidContext.raid_context.RAIDFlags = 0;
24d93b
-	io_request->RaidContext.raid_context.Type = 0;
24d93b
+	io_request->RaidContext.raid_context.raid_flags = 0;
24d93b
+	io_request->RaidContext.raid_context.type = 0;
24d93b
 	io_request->RaidContext.raid_context.nseg = 0;
24d93b
 
24d93b
 	memcpy(io_request->CDB.CDB32, scp->cmnd, scp->cmd_len);
24d93b
@@ -2273,11 +2368,16 @@ megasas_build_io_fusion(struct megasas_instance *instance,
24d93b
 		return 1;
24d93b
 	}
24d93b
 
24d93b
-	/* numSGE store lower 8 bit of sge_count.
24d93b
-	 * numSGEExt store higher 8 bit of sge_count
24d93b
-	 */
24d93b
-	io_request->RaidContext.raid_context.numSGE = sge_count;
24d93b
-	io_request->RaidContext.raid_context.numSGEExt = (u8)(sge_count >> 8);
24d93b
+	if (instance->is_ventura)
24d93b
+		io_request->RaidContext.raid_context_g35.num_sge = sge_count;
24d93b
+	else {
24d93b
+		/* numSGE store lower 8 bit of sge_count.
24d93b
+		 * numSGEExt store higher 8 bit of sge_count
24d93b
+		 */
24d93b
+		io_request->RaidContext.raid_context.num_sge = sge_count;
24d93b
+		io_request->RaidContext.raid_context.num_sge_ext =
24d93b
+			(u8)(sge_count >> 8);
24d93b
+	}
24d93b
 
24d93b
 	io_request->SGLFlags = cpu_to_le16(MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
24d93b
 
24d93b
@@ -2326,6 +2426,10 @@ void megasas_fpio_to_ldio(struct megasas_instance *instance,
24d93b
 	struct megasas_cmd_fusion *cmd, struct scsi_cmnd *scmd)
24d93b
 {
24d93b
 	struct fusion_context *fusion;
24d93b
+	union RAID_CONTEXT_UNION *praid_context;
24d93b
+	struct MR_LD_RAID *raid;
24d93b
+	struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
24d93b
+	u32 device_id, ld;
24d93b
 
24d93b
 	fusion = instance->ctrl_context;
24d93b
 	cmd->request_desc->SCSIIO.RequestFlags =
24d93b
@@ -2349,6 +2453,35 @@ void megasas_fpio_to_ldio(struct megasas_instance *instance,
24d93b
 	cmd->io_request->Control = 0;
24d93b
 	cmd->io_request->EEDPBlockSize = 0;
24d93b
 	cmd->is_raid_1_fp_write = 0;
24d93b
+
24d93b
+	device_id = MEGASAS_DEV_INDEX(cmd->scmd);
24d93b
+	local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
24d93b
+	ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
24d93b
+	raid = MR_LdRaidGet(ld, local_map_ptr);
24d93b
+	praid_context = &cmd->io_request->RaidContext;
24d93b
+	if (cmd->scmd->sc_data_direction == PCI_DMA_FROMDEVICE) {
24d93b
+		if ((raid->cpuAffinity.ldRead.cpu0)
24d93b
+		&& (raid->cpuAffinity.ldRead.cpu1))
24d93b
+			praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+			= MR_RAID_CTX_CPUSEL_FCFS;
24d93b
+		else if (raid->cpuAffinity.ldRead.cpu1)
24d93b
+			praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+			= MR_RAID_CTX_CPUSEL_1;
24d93b
+		else
24d93b
+			praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+			= MR_RAID_CTX_CPUSEL_0;
24d93b
+	} else {
24d93b
+	if ((raid->cpuAffinity.ldWrite.cpu0)
24d93b
+		&& (raid->cpuAffinity.ldWrite.cpu1))
24d93b
+		praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+			= MR_RAID_CTX_CPUSEL_FCFS;
24d93b
+	else if (raid->cpuAffinity.ldWrite.cpu1)
24d93b
+		praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+			= MR_RAID_CTX_CPUSEL_1;
24d93b
+	else
24d93b
+		praid_context->raid_context_g35.routing_flags.bits.cpu_sel
24d93b
+		= MR_RAID_CTX_CPUSEL_0;
24d93b
+	}
24d93b
 }
24d93b
 
24d93b
 /* megasas_prepate_secondRaid1_IO
24d93b
@@ -2585,7 +2718,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
24d93b
 
24d93b
 		scmd_local = cmd_fusion->scmd;
24d93b
 		status = scsi_io_req->RaidContext.raid_context.status;
24d93b
-		extStatus = scsi_io_req->RaidContext.raid_context.exStatus;
24d93b
+		extStatus = scsi_io_req->RaidContext.raid_context.ex_status;
24d93b
 		sense = cmd_fusion->sense;
24d93b
 		data_length = scsi_io_req->DataLength;
24d93b
 
24d93b
@@ -2653,13 +2786,13 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
24d93b
 					status =
24d93b
 					r1_cmd->io_request->RaidContext.raid_context.status;
24d93b
 					extStatus =
24d93b
-					r1_cmd->io_request->RaidContext.raid_context.exStatus;
24d93b
+					r1_cmd->io_request->RaidContext.raid_context.ex_status;
24d93b
 					data_length =
24d93b
 						r1_cmd->io_request->DataLength;
24d93b
 					sense = r1_cmd->sense;
24d93b
 				}
24d93b
 				r1_cmd->io_request->RaidContext.raid_context.status = 0;
24d93b
-				r1_cmd->io_request->RaidContext.raid_context.exStatus = 0;
24d93b
+				r1_cmd->io_request->RaidContext.raid_context.ex_status = 0;
24d93b
 				cmd_fusion->is_raid_1_fp_write = 0;
24d93b
 				r1_cmd->is_raid_1_fp_write = 0;
24d93b
 				r1_cmd->cmd_completed = false;
24d93b
@@ -2669,10 +2802,8 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
24d93b
 			if (!cmd_fusion->is_raid_1_fp_write) {
24d93b
 				map_cmd_status(fusion, scmd_local, status,
24d93b
 					extStatus, data_length, sense);
24d93b
-				scsi_io_req->RaidContext.raid_context.status
24d93b
-				= 0;
24d93b
-				scsi_io_req->RaidContext.raid_context.exStatus
24d93b
-				= 0;
24d93b
+				scsi_io_req->RaidContext.raid_context.status = 0;
24d93b
+				scsi_io_req->RaidContext.raid_context.ex_status = 0;
24d93b
 				megasas_return_cmd_fusion(instance, cmd_fusion);
24d93b
 				scsi_dma_unmap(scmd_local);
24d93b
 				scmd_local->scsi_done(scmd_local);
24d93b
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
24d93b
index 7a3c3d1..2de12b4 100644
24d93b
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
24d93b
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
24d93b
@@ -59,6 +59,8 @@
24d93b
 #define	MR_RL_FLAGS_GRANT_DESTINATION_CPU1	    0x10
24d93b
 #define	MR_RL_FLAGS_GRANT_DESTINATION_CUDA	    0x80
24d93b
 #define MR_RL_FLAGS_SEQ_NUM_ENABLE		    0x8
24d93b
+#define MR_RL_WRITE_THROUGH_MODE		    0x00
24d93b
+#define MR_RL_WRITE_BACK_MODE			    0x01
24d93b
 
24d93b
 /* T10 PI defines */
24d93b
 #define MR_PROT_INFO_TYPE_CONTROLLER                0x8
24d93b
@@ -81,6 +83,11 @@
24d93b
 enum MR_RAID_FLAGS_IO_SUB_TYPE {
24d93b
 	MR_RAID_FLAGS_IO_SUB_TYPE_NONE = 0,
24d93b
 	MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD = 1,
24d93b
+	MR_RAID_FLAGS_IO_SUB_TYPE_RMW_DATA     = 2,
24d93b
+	MR_RAID_FLAGS_IO_SUB_TYPE_RMW_P        = 3,
24d93b
+	MR_RAID_FLAGS_IO_SUB_TYPE_RMW_Q        = 4,
24d93b
+	MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS = 6,
24d93b
+	MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT = 7
24d93b
 };
24d93b
 
24d93b
 /*
24d93b
@@ -109,29 +116,29 @@ enum MR_FUSION_ADAPTER_TYPE {
24d93b
 
24d93b
 struct RAID_CONTEXT {
24d93b
 #if   defined(__BIG_ENDIAN_BITFIELD)
24d93b
-	u8	nseg:4;
24d93b
-	u8	Type:4;
24d93b
+	u8 nseg:4;
24d93b
+	u8 type:4;
24d93b
 #else
24d93b
-	u8	Type:4;
24d93b
-	u8	nseg:4;
24d93b
+	u8 type:4;
24d93b
+	u8 nseg:4;
24d93b
 #endif
24d93b
-	u8	resvd0;
24d93b
-	__le16	timeoutValue;
24d93b
-	u8      regLockFlags;
24d93b
-	u8      resvd1;
24d93b
-	__le16	VirtualDiskTgtId;
24d93b
-	__le64	regLockRowLBA;
24d93b
-	__le32	regLockLength;
24d93b
-	__le16	nextLMId;
24d93b
-	u8      exStatus;
24d93b
-	u8      status;
24d93b
-	u8      RAIDFlags;
24d93b
-	u8      numSGE;
24d93b
-	__le16	configSeqNum;
24d93b
-	u8      spanArm;
24d93b
-	u8      priority;
24d93b
-	u8	numSGEExt;
24d93b
-	u8      resvd2;
24d93b
+	u8 resvd0;
24d93b
+	__le16 timeout_value;
24d93b
+	u8 reg_lock_flags;
24d93b
+	u8 resvd1;
24d93b
+	__le16 virtual_disk_tgt_id;
24d93b
+	__le64 reg_lock_row_lba;
24d93b
+	__le32 reg_lock_length;
24d93b
+	__le16 next_lmid;
24d93b
+	u8 ex_status;
24d93b
+	u8 status;
24d93b
+	u8 raid_flags;
24d93b
+	u8 num_sge;
24d93b
+	__le16 config_seq_num;
24d93b
+	u8 span_arm;
24d93b
+	u8 priority;
24d93b
+	u8 num_sge_ext;
24d93b
+	u8 resvd2;
24d93b
 };
24d93b
 
24d93b
 /*
24d93b
@@ -187,7 +194,7 @@ struct RAID_CONTEXT_G35 {
24d93b
 	} smid;
24d93b
 	u8 ex_status;       /* 0x16 : OUT */
24d93b
 	u8 status;          /* 0x17 status */
24d93b
-	u8 RAIDFlags;		/* 0x18 resvd[7:6], ioSubType[5:4],
24d93b
+	u8 raid_flags;		/* 0x18 resvd[7:6], ioSubType[5:4],
24d93b
 				 * resvd[3:1], preferredCpu[0]
24d93b
 				 */
24d93b
 	u8 span_arm;            /* 0x1C span[7:5], arm[4:0] */
24d93b
@@ -672,14 +679,17 @@ struct MPI2_IOC_INIT_REQUEST {
24d93b
 #define MAX_RAIDMAP_ROW_SIZE (MAX_ROW_SIZE)
24d93b
 #define MAX_LOGICAL_DRIVES 64
24d93b
 #define MAX_LOGICAL_DRIVES_EXT 256
24d93b
+#define MAX_LOGICAL_DRIVES_DYN 512
24d93b
 #define MAX_RAIDMAP_LOGICAL_DRIVES (MAX_LOGICAL_DRIVES)
24d93b
 #define MAX_RAIDMAP_VIEWS (MAX_LOGICAL_DRIVES)
24d93b
 #define MAX_ARRAYS 128
24d93b
 #define MAX_RAIDMAP_ARRAYS (MAX_ARRAYS)
24d93b
 #define MAX_ARRAYS_EXT	256
24d93b
 #define MAX_API_ARRAYS_EXT (MAX_ARRAYS_EXT)
24d93b
+#define MAX_API_ARRAYS_DYN 512
24d93b
 #define MAX_PHYSICAL_DEVICES 256
24d93b
 #define MAX_RAIDMAP_PHYSICAL_DEVICES (MAX_PHYSICAL_DEVICES)
24d93b
+#define MAX_RAIDMAP_PHYSICAL_DEVICES_DYN 512
24d93b
 #define MR_DCMD_LD_MAP_GET_INFO             0x0300e101
24d93b
 #define MR_DCMD_SYSTEM_PD_MAP_GET_INFO      0x0200e102
24d93b
 #define MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC  0x010e8485   /* SR-IOV HB alloc*/
24d93b
@@ -726,12 +736,56 @@ struct MR_SPAN_BLOCK_INFO {
24d93b
 	struct MR_SPAN_INFO block_span_info;
24d93b
 };
24d93b
 
24d93b
+#define MR_RAID_CTX_CPUSEL_0		0
24d93b
+#define MR_RAID_CTX_CPUSEL_1		1
24d93b
+#define MR_RAID_CTX_CPUSEL_2		2
24d93b
+#define MR_RAID_CTX_CPUSEL_3		3
24d93b
+#define MR_RAID_CTX_CPUSEL_FCFS		0xF
24d93b
+
24d93b
+struct MR_CPU_AFFINITY_MASK {
24d93b
+	union {
24d93b
+		struct {
24d93b
+#ifndef MFI_BIG_ENDIAN
24d93b
+		u8 hw_path:1;
24d93b
+		u8 cpu0:1;
24d93b
+		u8 cpu1:1;
24d93b
+		u8 cpu2:1;
24d93b
+		u8 cpu3:1;
24d93b
+		u8 reserved:3;
24d93b
+#else
24d93b
+		u8 reserved:3;
24d93b
+		u8 cpu3:1;
24d93b
+		u8 cpu2:1;
24d93b
+		u8 cpu1:1;
24d93b
+		u8 cpu0:1;
24d93b
+		u8 hw_path:1;
24d93b
+#endif
24d93b
+		};
24d93b
+		u8 core_mask;
24d93b
+	};
24d93b
+};
24d93b
+
24d93b
+struct MR_IO_AFFINITY {
24d93b
+	union {
24d93b
+		struct {
24d93b
+			struct MR_CPU_AFFINITY_MASK pdRead;
24d93b
+			struct MR_CPU_AFFINITY_MASK pdWrite;
24d93b
+			struct MR_CPU_AFFINITY_MASK ldRead;
24d93b
+			struct MR_CPU_AFFINITY_MASK ldWrite;
24d93b
+			};
24d93b
+		u32 word;
24d93b
+		};
24d93b
+	u8 maxCores;    /* Total cores + HW Path in ROC */
24d93b
+	u8 reserved[3];
24d93b
+};
24d93b
+
24d93b
 struct MR_LD_RAID {
24d93b
 	struct {
24d93b
 #if   defined(__BIG_ENDIAN_BITFIELD)
24d93b
-		u32     reserved4:3;
24d93b
-		u32     fp_cache_bypass_capable:1;
24d93b
-		u32     fp_rmw_capable:1;
24d93b
+		u32 reserved4:2;
24d93b
+		u32 fp_cache_bypass_capable:1;
24d93b
+		u32 fp_rmw_capable:1;
24d93b
+		u32 disable_coalescing:1;
24d93b
 		u32     fpBypassRegionLock:1;
24d93b
 		u32     tmCapable:1;
24d93b
 		u32	fpNonRWCapable:1;
24d93b
@@ -759,9 +813,10 @@ struct MR_LD_RAID {
24d93b
 		u32	fpNonRWCapable:1;
24d93b
 		u32     tmCapable:1;
24d93b
 		u32     fpBypassRegionLock:1;
24d93b
-		u32     fp_rmw_capable:1;
24d93b
-		u32     fp_cache_bypass_capable:1;
24d93b
-		u32     reserved4:3;
24d93b
+		u32 disable_coalescing:1;
24d93b
+		u32 fp_rmw_capable:1;
24d93b
+		u32 fp_cache_bypass_capable:1;
24d93b
+		u32 reserved4:2;
24d93b
 #endif
24d93b
 	} capability;
24d93b
 	__le32     reserved6;
24d93b
@@ -788,7 +843,36 @@ struct MR_LD_RAID {
24d93b
 
24d93b
 	u8	LUN[8]; /* 0x24 8 byte LUN field used for SCSI IO's */
24d93b
 	u8	fpIoTimeoutForLd;/*0x2C timeout value used by driver in FP IO*/
24d93b
-	u8      reserved3[0x80-0x2D]; /* 0x2D */
24d93b
+	/* Ox2D This LD accept priority boost of this type */
24d93b
+	u8 ld_accept_priority_type;
24d93b
+	u8 reserved2[2];	        /* 0x2E - 0x2F */
24d93b
+	/* 0x30 - 0x33, Logical block size for the LD */
24d93b
+	u32 logical_block_length;
24d93b
+	struct {
24d93b
+#ifndef MFI_BIG_ENDIAN
24d93b
+	/* 0x34, P_I_EXPONENT from READ CAPACITY 16 */
24d93b
+	u32 ld_pi_exp:4;
24d93b
+	/* 0x34, LOGICAL BLOCKS PER PHYSICAL
24d93b
+	 *  BLOCK EXPONENT from READ CAPACITY 16
24d93b
+	 */
24d93b
+	u32 ld_logical_block_exp:4;
24d93b
+	u32 reserved1:24;           /* 0x34 */
24d93b
+#else
24d93b
+	u32 reserved1:24;           /* 0x34 */
24d93b
+	/* 0x34, LOGICAL BLOCKS PER PHYSICAL
24d93b
+	 *  BLOCK EXPONENT from READ CAPACITY 16
24d93b
+	 */
24d93b
+	u32 ld_logical_block_exp:4;
24d93b
+	/* 0x34, P_I_EXPONENT from READ CAPACITY 16 */
24d93b
+	u32 ld_pi_exp:4;
24d93b
+#endif
24d93b
+	};                               /* 0x34 - 0x37 */
24d93b
+	 /* 0x38 - 0x3f, This will determine which
24d93b
+	  *  core will process LD IO and PD IO.
24d93b
+	  */
24d93b
+	struct MR_IO_AFFINITY cpuAffinity;
24d93b
+     /* Bit definiations are specified by MR_IO_AFFINITY */
24d93b
+	u8 reserved3[0x80-0x40];    /* 0x40 - 0x7f */
24d93b
 };
24d93b
 
24d93b
 struct MR_LD_SPAN_MAP {
24d93b
@@ -846,6 +930,91 @@ struct MR_LD_TARGET_SYNC {
24d93b
 	__le16 seqNum;
24d93b
 };
24d93b
 
24d93b
+/*
24d93b
+ * RAID Map descriptor Types.
24d93b
+ * Each element should uniquely idetify one data structure in the RAID map
24d93b
+ */
24d93b
+enum MR_RAID_MAP_DESC_TYPE {
24d93b
+	/* MR_DEV_HANDLE_INFO data */
24d93b
+	RAID_MAP_DESC_TYPE_DEVHDL_INFO    = 0x0,
24d93b
+	/* target to Ld num Index map */
24d93b
+	RAID_MAP_DESC_TYPE_TGTID_INFO     = 0x1,
24d93b
+	/* MR_ARRAY_INFO data */
24d93b
+	RAID_MAP_DESC_TYPE_ARRAY_INFO     = 0x2,
24d93b
+	/* MR_LD_SPAN_MAP data */
24d93b
+	RAID_MAP_DESC_TYPE_SPAN_INFO      = 0x3,
24d93b
+	RAID_MAP_DESC_TYPE_COUNT,
24d93b
+};
24d93b
+
24d93b
+/*
24d93b
+ * This table defines the offset, size and num elements  of each descriptor
24d93b
+ * type in the RAID Map buffer
24d93b
+ */
24d93b
+struct MR_RAID_MAP_DESC_TABLE {
24d93b
+	/* Raid map descriptor type */
24d93b
+	u32 raid_map_desc_type;
24d93b
+	/* Offset into the RAID map buffer where
24d93b
+	 *  descriptor data is saved
24d93b
+	 */
24d93b
+	u32 raid_map_desc_offset;
24d93b
+	/* total size of the
24d93b
+	 * descriptor buffer
24d93b
+	 */
24d93b
+	u32 raid_map_desc_buffer_size;
24d93b
+	/* Number of elements contained in the
24d93b
+	 *  descriptor buffer
24d93b
+	 */
24d93b
+	u32 raid_map_desc_elements;
24d93b
+};
24d93b
+
24d93b
+/*
24d93b
+ * Dynamic Raid Map Structure.
24d93b
+ */
24d93b
+struct MR_FW_RAID_MAP_DYNAMIC {
24d93b
+	u32 raid_map_size;   /* total size of RAID Map structure */
24d93b
+	u32 desc_table_offset;/* Offset of desc table into RAID map*/
24d93b
+	u32 desc_table_size;  /* Total Size of desc table */
24d93b
+	/* Total Number of elements in the desc table */
24d93b
+	u32 desc_table_num_elements;
24d93b
+	u64	reserved1;
24d93b
+	u32	reserved2[3];	/*future use */
24d93b
+	/* timeout value used by driver in FP IOs */
24d93b
+	u8 fp_pd_io_timeout_sec;
24d93b
+	u8 reserved3[3];
24d93b
+	/* when this seqNum increments, driver needs to
24d93b
+	 *  release RMW buffers asap
24d93b
+	 */
24d93b
+	u32 rmw_fp_seq_num;
24d93b
+	u16 ld_count;	/* count of lds. */
24d93b
+	u16 ar_count;   /* count of arrays */
24d93b
+	u16 span_count; /* count of spans */
24d93b
+	u16 reserved4[3];
24d93b
+/*
24d93b
+ * The below structure of pointers is only to be used by the driver.
24d93b
+ * This is added in the ,API to reduce the amount of code changes
24d93b
+ * needed in the driver to support dynamic RAID map Firmware should
24d93b
+ * not update these pointers while preparing the raid map
24d93b
+ */
24d93b
+	union {
24d93b
+		struct {
24d93b
+			struct MR_DEV_HANDLE_INFO  *dev_hndl_info;
24d93b
+			u16 *ld_tgt_id_to_ld;
24d93b
+			struct MR_ARRAY_INFO *ar_map_info;
24d93b
+			struct MR_LD_SPAN_MAP *ld_span_map;
24d93b
+			};
24d93b
+		u64 ptr_structure_size[RAID_MAP_DESC_TYPE_COUNT];
24d93b
+		};
24d93b
+/*
24d93b
+ * RAID Map descriptor table defines the layout of data in the RAID Map.
24d93b
+ * The size of the descriptor table itself could change.
24d93b
+ */
24d93b
+	/* Variable Size descriptor Table. */
24d93b
+	struct MR_RAID_MAP_DESC_TABLE
24d93b
+			raid_map_desc_table[RAID_MAP_DESC_TYPE_COUNT];
24d93b
+	/* Variable Size buffer containing all data */
24d93b
+	u32 raid_map_desc_data[1];
24d93b
+}; /* Dynamicaly sized RAID MAp structure */
24d93b
+
24d93b
 #define IEEE_SGE_FLAGS_ADDR_MASK            (0x03)
24d93b
 #define IEEE_SGE_FLAGS_SYSTEM_ADDR          (0x00)
24d93b
 #define IEEE_SGE_FLAGS_IOCDDR_ADDR          (0x01)
24d93b
@@ -955,9 +1124,10 @@ struct MR_DRV_RAID_MAP {
24d93b
 	__le16                 spanCount;
24d93b
 	__le16                 reserve3;
24d93b
 
24d93b
-	struct MR_DEV_HANDLE_INFO  devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES];
24d93b
-	u8                  ldTgtIdToLd[MAX_LOGICAL_DRIVES_EXT];
24d93b
-	struct MR_ARRAY_INFO       arMapInfo[MAX_API_ARRAYS_EXT];
24d93b
+	struct MR_DEV_HANDLE_INFO
24d93b
+		devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES_DYN];
24d93b
+	u16 ldTgtIdToLd[MAX_LOGICAL_DRIVES_DYN];
24d93b
+	struct MR_ARRAY_INFO arMapInfo[MAX_API_ARRAYS_DYN];
24d93b
 	struct MR_LD_SPAN_MAP      ldSpanMap[1];
24d93b
 
24d93b
 };
24d93b
@@ -969,7 +1139,7 @@ struct MR_DRV_RAID_MAP {
24d93b
 struct MR_DRV_RAID_MAP_ALL {
24d93b
 
24d93b
 	struct MR_DRV_RAID_MAP raidMap;
24d93b
-	struct MR_LD_SPAN_MAP      ldSpanMap[MAX_LOGICAL_DRIVES_EXT - 1];
24d93b
+	struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES_DYN - 1];
24d93b
 } __packed;
24d93b
 
24d93b
 
24d93b
@@ -1088,7 +1258,7 @@ struct fusion_context {
24d93b
 	u8	chain_offset_io_request;
24d93b
 	u8	chain_offset_mfi_pthru;
24d93b
 
24d93b
-	struct MR_FW_RAID_MAP_ALL *ld_map[2];
24d93b
+	struct MR_FW_RAID_MAP_DYNAMIC *ld_map[2];
24d93b
 	dma_addr_t ld_map_phys[2];
24d93b
 
24d93b
 	/*Non dma-able memory. Driver local copy.*/
24d93b
@@ -1096,6 +1266,8 @@ struct fusion_context {
24d93b
 
24d93b
 	u32 max_map_sz;
24d93b
 	u32 current_map_sz;
24d93b
+	u32 old_map_sz;
24d93b
+	u32 new_map_sz;
24d93b
 	u32 drv_map_sz;
24d93b
 	u32 drv_map_pages;
24d93b
 	struct MR_PD_CFG_SEQ_NUM_SYNC	*pd_seq_sync[JBOD_MAPS_COUNT];
24d93b
-- 
24d93b
1.8.3.1
24d93b