From: root <sasikumar...@broadcom.com>

SAS3.5 Generic Megaraid Controllers FW will support new dynamic RaidMap to have 
different
sizes for different number of supported VDs.

This patch is depending on patch 5

Signed-off-by: Sasikumar Chandrasekaran <sasikumar...@broadcom.com>
---
 drivers/scsi/megaraid/megaraid_sas.h        |   7 +
 drivers/scsi/megaraid/megaraid_sas_base.c   |  57 ++++--
 drivers/scsi/megaraid/megaraid_sas_fp.c     | 278 +++++++++++++++++++++++++---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 148 ++++++++++++++-
 drivers/scsi/megaraid/megaraid_sas_fusion.h | 177 +++++++++++++++++-
 5 files changed, 602 insertions(+), 65 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h 
b/drivers/scsi/megaraid/megaraid_sas.h
index 9263ba3..2da47b9 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1437,6 +1437,12 @@ enum FW_BOOT_CONTEXT {
 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT    14
 #define MR_MAX_MSIX_REG_ARRAY                   16
 #define MR_RDPQ_MODE_OFFSET                    0X00800000
+
+#define MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT      16
+#define MR_MAX_RAID_MAP_SIZE_MASK              0x1FF
+#define MR_MIN_MAP_SIZE                                0x10000
+/* 64k */
+
 #define MR_CAN_HANDLE_SYNC_CACHE_OFFSET                0X01000000
 
 /*
@@ -2155,6 +2161,7 @@ struct megasas_instance {
        bool fw_sync_cache_support;
        bool is_ventura;
        bool msix_combined;
+       u16 maxRaidMapSize;
 };
 struct MR_LD_VF_MAP {
        u32 size;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c 
b/drivers/scsi/megaraid/megaraid_sas_base.c
index 86f25d5..b74609c 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -4427,8 +4427,7 @@ int megasas_alloc_cmds(struct megasas_instance *instance)
 static void megasas_update_ext_vd_details(struct megasas_instance *instance)
 {
        struct fusion_context *fusion;
-       u32 old_map_sz;
-       u32 new_map_sz;
+       u32 ventura_map_sz = 0;
 
        fusion = instance->ctrl_context;
        /* For MFI based controllers return dummy success */
@@ -4458,21 +4457,37 @@ static void megasas_update_ext_vd_details(struct 
megasas_instance *instance)
                instance->supportmax256vd ? "Extended VD(240 VD)firmware" :
                "Legacy(64 VD) firmware");
 
-       old_map_sz = sizeof(struct MR_FW_RAID_MAP) +
-                               (sizeof(struct MR_LD_SPAN_MAP) *
-                               (instance->fw_supported_vd_count - 1));
-       new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT);
-       fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP) +
-                               (sizeof(struct MR_LD_SPAN_MAP) *
-                               (instance->drv_supported_vd_count - 1));
-
-       fusion->max_map_sz = max(old_map_sz, new_map_sz);
+       if (instance->maxRaidMapSize) {
+               ventura_map_sz = instance->maxRaidMapSize *
+                                               MR_MIN_MAP_SIZE; /* 64k */
+               fusion->current_map_sz = ventura_map_sz;
+               fusion->max_map_sz = ventura_map_sz;
+       } else {
+               fusion->old_map_sz =  sizeof(struct MR_FW_RAID_MAP) +
+                                       (sizeof(struct MR_LD_SPAN_MAP) *
+                                       (instance->fw_supported_vd_count - 1));
+               fusion->new_map_sz =  sizeof(struct MR_FW_RAID_MAP_EXT);
 
+               fusion->max_map_sz = max(fusion->old_map_sz, 
fusion->new_map_sz);
 
-       if (instance->supportmax256vd)
-               fusion->current_map_sz = new_map_sz;
-       else
-               fusion->current_map_sz = old_map_sz;
+               if (instance->supportmax256vd)
+                       fusion->current_map_sz = fusion->new_map_sz;
+               else
+                       fusion->current_map_sz = fusion->old_map_sz;
+       }
+       /* irrespective of FW raid maps, driver raid map is constant */
+       fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP_ALL);
+#if VD_EXT_DEBUG
+       dev_info(&instance->pdev->dev, "instance->maxRaidMapSize 0x%x \n ",
+                       instance->maxRaidMapSize);
+       dev_info(&instance->pdev->dev,
+                               "new_map_sz = 0x%x, old_map_sz = 0x%x, "
+                               "ventura_map_sz = 0x%x, current_map_sz = 0x%x "
+                               "fusion->drv_map_sz =0x%x, size of driver raid 
map 0x%lx\n",
+                               fusion->new_map_sz, fusion->old_map_sz,
+                               ventura_map_sz, fusion->current_map_sz,
+                               fusion->drv_map_sz, sizeof(struct 
MR_DRV_RAID_MAP_ALL));
+#endif
 }
 
 /**
@@ -5013,7 +5028,7 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
 {
        u32 max_sectors_1;
        u32 max_sectors_2;
-       u32 tmp_sectors, msix_enable, scratch_pad_2;
+       u32 tmp_sectors, msix_enable, scratch_pad_2, scratch_pad_3;
        resource_size_t base_addr;
        struct megasas_register_set __iomem *reg_set;
        struct megasas_ctrl_info *ctrl_info = NULL;
@@ -5089,7 +5104,15 @@ static int megasas_init_fw(struct megasas_instance 
*instance)
                        goto fail_ready_state;
        }
 
-
+       if (instance->is_ventura) {
+               scratch_pad_3 = 
readl(&instance->reg_set->outbound_scratch_pad_3);
+#if VD_EXT_DEBUG
+               dev_info(&instance->pdev->dev, "scratch_pad3 0x%x\n", 
scratch_pad_3);
+#endif
+               instance->maxRaidMapSize = ((scratch_pad_3 >>
+                                               
MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT) &
+                                               MR_MAX_RAID_MAP_SIZE_MASK);
+       }
 
        /* Check if MSI-X is supported while in ready state */
        msix_enable = (instance->instancet->read_fw_status_reg(reg_set) &
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c 
b/drivers/scsi/megaraid/megaraid_sas_fp.c
index 5922d15..546a543 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -179,18 +179,208 @@ void MR_PopulateDrvRaidMap(struct megasas_instance 
*instance)
        struct fusion_context *fusion = instance->ctrl_context;
        struct MR_FW_RAID_MAP_ALL     *fw_map_old    = NULL;
        struct MR_FW_RAID_MAP         *pFwRaidMap    = NULL;
-       int i;
+       int i, j;
        u16 ld_count;
+       struct MR_FW_RAID_MAP_DYNAMIC *fw_map_dyn;
+       struct MR_FW_RAID_MAP_EXT *fw_map_ext;
+       MR_RAID_MAP_DESC_TABLE *desc_table;
 
 
        struct MR_DRV_RAID_MAP_ALL *drv_map =
                        fusion->ld_drv_map[(instance->map_id & 1)];
        struct MR_DRV_RAID_MAP *pDrvRaidMap = &drv_map->raidMap;
+       void *raid_map_data = NULL;
+
+       memset(drv_map, 0, fusion->drv_map_sz);
+       memset(pDrvRaidMap->ldTgtIdToLd, 0xff, (sizeof(u16) * 
MAX_LOGICAL_DRIVES_DYN));
+
+       if (instance->maxRaidMapSize) {
+               fw_map_dyn = fusion->ld_map[(instance->map_id & 1)];
+#if VD_EXT_DEBUG
+                       dev_dbg(&instance->pdev->dev,
+                               " raidMapSize 0x%x fw_map_dyn->descTableOffset 
0x%x, "
+                               " descTableSize 0x%x descTableNumElements 
0x%x\n",
+                                       le32_to_cpu(fw_map_dyn->raidMapSize),
+                                       
le32_to_cpu(fw_map_dyn->descTableOffset),
+                                       le32_to_cpu(fw_map_dyn->descTableSize),
+                                       
le32_to_cpu(fw_map_dyn->descTableNumElements));
+               dev_dbg(&instance->pdev->dev,
+                               "drv map %p ldCount %d\n", drv_map, 
fw_map_dyn->ldCount);
+#endif
+               desc_table =
+               (MR_RAID_MAP_DESC_TABLE *)((void *)fw_map_dyn +
+               le32_to_cpu(fw_map_dyn->descTableOffset));
+               if (desc_table != fw_map_dyn->raidMapDescTable) {
+                       dev_err(&instance->pdev->dev,
+                               "offsets of desc table are not matching 
returning "
+                               " FW raid map has been changed: desc %p 
original %p\n",
+                               desc_table, fw_map_dyn->raidMapDescTable);
+               }
+               ld_count = (u16)le16_to_cpu(fw_map_dyn->ldCount);
+               pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count);
+               pDrvRaidMap->fpPdIoTimeoutSec = fw_map_dyn->fpPdIoTimeoutSec;
+               pDrvRaidMap->totalSize = sizeof(struct MR_DRV_RAID_MAP_ALL);
+               /* point to actual data starting point*/
+               raid_map_data = (void *)fw_map_dyn +
+                                               
le32_to_cpu(fw_map_dyn->descTableOffset) +
+                                               
le32_to_cpu(fw_map_dyn->descTableSize);
+
+               for (i = 0; i < le32_to_cpu(fw_map_dyn->descTableNumElements); 
++i) {
+                       if (!desc_table) {
+                               dev_err(&instance->pdev->dev,
+                                       "desc table is null, coming out %p \n", 
desc_table);
+                               return;
+                       }
+#if VD_EXT_DEBUG
+                       dev_err(&instance->pdev->dev,
+                               "desc table %p \n", desc_table);
+                       dev_err(&instance->pdev->dev,
+                                       "raidmap type %d, raidmapOffset 0x%x, "
+                                       " raid map number of elements 0%x, 
raidmapsize 0x%x\n",
+                               desc_table->raidMapDescType,
+                               desc_table->raidMapDescOffset,
+                               desc_table->raidMapDescElements,
+                               desc_table->raidMapDescBufferSize);
+#endif
+                       switch (le32_to_cpu(desc_table->raidMapDescType)) {
+                       case RAID_MAP_DESC_TYPE_DEVHDL_INFO:
+                               fw_map_dyn->devHndlInfo = (struct 
MR_DEV_HANDLE_INFO *)
+                                                             (raid_map_data +
+                                                               
le32_to_cpu(desc_table->raidMapDescOffset));
+#if VD_EXT_DEBUG
+                               dev_err(&instance->pdev->dev,
+                               "devHndlInfo  address %p\n",
+                                fw_map_dyn->devHndlInfo);
+#endif
+                               memcpy(pDrvRaidMap->devHndlInfo, 
fw_map_dyn->devHndlInfo,
+                                       sizeof(struct MR_DEV_HANDLE_INFO) *
+                                                       
le32_to_cpu(desc_table->raidMapDescElements));
+                       break;
+                       case RAID_MAP_DESC_TYPE_TGTID_INFO:
+                                       fw_map_dyn->ldTgtIdToLd = (u16 *) 
(raid_map_data +
+                                                               
le32_to_cpu(desc_table->raidMapDescOffset));
+#if VD_EXT_DEBUG
+                       dev_err(&instance->pdev->dev,
+                               "ldTgtIdToLd  address %p\n",
+                                       fw_map_dyn->ldTgtIdToLd);
+#endif
+                       for (j = 0; j < 
le32_to_cpu(desc_table->raidMapDescElements); j++) {
+                               pDrvRaidMap->ldTgtIdToLd[j] = 
fw_map_dyn->ldTgtIdToLd[j];
+#if VD_EXT_DEBUG
+                               dev_err(&instance->pdev->dev,
+                                       " %d drv ldTgtIdToLd %d\n",
+                                               j, pDrvRaidMap->ldTgtIdToLd[j]);
+#endif
+                       }
+                       break;
+                       case RAID_MAP_DESC_TYPE_ARRAY_INFO:
+                               fw_map_dyn->arMapInfo = (struct MR_ARRAY_INFO *)
+                               (raid_map_data + 
le32_to_cpu(desc_table->raidMapDescOffset));
+#if VD_EXT_DEBUG
+                               dev_err(&instance->pdev->dev,
+                                       "arMapInfo  address %p\n",
+                                        fw_map_dyn->arMapInfo);
+#endif
+
+                               memcpy(pDrvRaidMap->arMapInfo, 
fw_map_dyn->arMapInfo,
+                                       sizeof(struct MR_ARRAY_INFO) *
+                                                               
le32_to_cpu(desc_table->raidMapDescElements));
+                       break;
+                       case RAID_MAP_DESC_TYPE_SPAN_INFO:
+                               fw_map_dyn->ldSpanMap = (struct MR_LD_SPAN_MAP 
*)
+                               (raid_map_data + 
le32_to_cpu(desc_table->raidMapDescOffset));
+                               memcpy(pDrvRaidMap->ldSpanMap,
+                                               fw_map_dyn->ldSpanMap,
+                                               sizeof(struct MR_LD_SPAN_MAP) *
+                                               
le32_to_cpu(desc_table->raidMapDescElements));
+#if VD_EXT_DEBUG
+                               dev_err(&instance->pdev->dev,
+                                       "ldSpanMap  address %p\n",
+                                               fw_map_dyn->ldSpanMap);
+                               dev_err(&instance->pdev->dev,
+                               "MR_LD_SPAN_MAP size 0x%lx\n", sizeof(struct 
MR_LD_SPAN_MAP));
+                               for (j = 0; j < ld_count; j++) {
+                                       printk("megaraid_sas(%d) : "
+                                       
"fw_map_dyn->ldSpanMap[%d].ldRaid.targetId 0x%x "
+                                       
"fw_map_dyn->ldSpanMap[%d].ldRaid.seqNum 0x%x size 0x%x\n",
+                                               j, j, 
fw_map_dyn->ldSpanMap[j].ldRaid.targetId, j,
+                                               
fw_map_dyn->ldSpanMap[j].ldRaid.seqNum,
+                                               
(u32)fw_map_dyn->ldSpanMap[j].ldRaid.rowSize);
+                                               printk("megaraid_sas(%d) : "
+                                               
"pDrvRaidMap->ldSpanMap[%d].ldRaid.targetId 0x%x "
+                                               
"pDrvRaidMap->ldSpanMap[%d].ldRaid.seqNum 0x%x size 0x%x\n",
+                                       j, j, 
pDrvRaidMap->ldSpanMap[j].ldRaid.targetId, j,
+                                       pDrvRaidMap->ldSpanMap[j].ldRaid.seqNum,
+                                       
(u32)pDrvRaidMap->ldSpanMap[j].ldRaid.rowSize);
+                                               printk("megaraid_sas(%d) : "
+                                               "drv raid map all %p raid map 
%p LD RAID MAP %p/%p\n",
+                                       instance->unique_id, drv_map, 
pDrvRaidMap,
+                                       &fw_map_dyn->ldSpanMap[j].ldRaid,
+                                               
&pDrvRaidMap->ldSpanMap[j].ldRaid);
+                               }
+#endif
+                       break;
+                       default:
+                               dev_err(&instance->pdev->dev,
+                                       "wrong number of desctableElements 
%d\n",
+                                                               
fw_map_dyn->descTableNumElements);
+                       }
+                       ++desc_table;
+               }
+
+       } else if (instance->supportmax256vd) {
+               fw_map_ext = (struct MR_FW_RAID_MAP_EXT *) 
fusion->ld_map[(instance->map_id & 1)];
+               ld_count = (u16)le16_to_cpu(fw_map_ext->ldCount);
+               if (ld_count > MAX_LOGICAL_DRIVES_EXT) {
+                       printk("megaraid_sas: LD count exposed in"
+                       " RAID map in not valid\n");
+                       return;
+               }
+#if VD_EXT_DEBUG
+               for (i = 0; i < ld_count; i++) {
+                       printk("megaraid_sas(%d) : "
+                               "Index 0x%x Target Id 0x%x Seq Num 0x%x Size 
0/%llx\n",
+                               instance->unique_id,
+                                       i, 
fw_map_ext->ldSpanMap[i].ldRaid.targetId,
+                                       fw_map_ext->ldSpanMap[i].ldRaid.seqNum,
+                                       fw_map_ext->ldSpanMap[i].ldRaid.size);
+               }
+#endif
+
+               pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count);
+               pDrvRaidMap->fpPdIoTimeoutSec = fw_map_ext->fpPdIoTimeoutSec;
+               for (i = 0; i < (MAX_LOGICAL_DRIVES_EXT); i++)
+                       pDrvRaidMap->ldTgtIdToLd[i] = 
(u16)fw_map_ext->ldTgtIdToLd[i];
+
+               memcpy(pDrvRaidMap->ldSpanMap,
+                               fw_map_ext->ldSpanMap,
+                               sizeof(struct MR_LD_SPAN_MAP) *
+                               ld_count);
+#if VD_EXT_DEBUG
+               for (i = 0; i < ld_count; i++) {
+                               printk("megaraid_sas(%d) :"
+                               " fw_map_ext->ldSpanMap[%d].ldRaid.targetId 
0x%x "
+                       "fw_map_ext->ldSpanMap[%d].ldRaid.seqNum 0x%x size 
0x%x\n",
+                       i, i, fw_map_ext->ldSpanMap[i].ldRaid.targetId, i,
+                       fw_map_ext->ldSpanMap[i].ldRaid.seqNum,
+                       (u32)fw_map_ext->ldSpanMap[i].ldRaid.rowSize);
+                               printk("megaraid_sas(%d) :"
+                               " pDrvRaidMap->ldSpanMap[%d].ldRaid.targetId 
0x%x"
+                       "pDrvRaidMap->ldSpanMap[%d].ldRaid.seqNum 0x%x size 
0x%x\n", i, i,
+                       pDrvRaidMap->ldSpanMap[i].ldRaid.targetId, i,
+                       pDrvRaidMap->ldSpanMap[i].ldRaid.seqNum,
+                       (u32)pDrvRaidMap->ldSpanMap[i].ldRaid.rowSize);
+                               printk("megaraid_sas(%d) :"
+                               " drv raid map all %p raid map %p LD RAID MAP 
%p/%p\n",
+                       instance->unique_id, drv_map, pDrvRaidMap,
+                       &fw_map_ext->ldSpanMap[i].ldRaid, 
&pDrvRaidMap->ldSpanMap[i].ldRaid);
+               }
+#endif
+               memcpy(pDrvRaidMap->arMapInfo, fw_map_ext->arMapInfo,
+                       sizeof(struct MR_ARRAY_INFO) * MAX_API_ARRAYS_EXT);
+               memcpy(pDrvRaidMap->devHndlInfo, fw_map_ext->devHndlInfo,
+                       sizeof(struct MR_DEV_HANDLE_INFO) * 
MAX_RAIDMAP_PHYSICAL_DEVICES);
 
-       if (instance->supportmax256vd) {
-               memcpy(fusion->ld_drv_map[instance->map_id & 1],
-                       fusion->ld_map[instance->map_id & 1],
-                       fusion->current_map_sz);
                /* New Raid map will not set totalSize, so keep expected value
                 * for legacy code in ValidateMapInfo
                 */
@@ -213,16 +403,12 @@ void MR_PopulateDrvRaidMap(struct megasas_instance 
*instance)
                }
 #endif
 
-               memset(drv_map, 0, fusion->drv_map_sz);
                pDrvRaidMap->totalSize = pFwRaidMap->totalSize;
                pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count);
                pDrvRaidMap->fpPdIoTimeoutSec = pFwRaidMap->fpPdIoTimeoutSec;
                for (i = 0; i < MAX_RAIDMAP_LOGICAL_DRIVES + MAX_RAIDMAP_VIEWS; 
i++)
                        pDrvRaidMap->ldTgtIdToLd[i] =
                                (u8)pFwRaidMap->ldTgtIdToLd[i];
-               for (i = (MAX_RAIDMAP_LOGICAL_DRIVES + MAX_RAIDMAP_VIEWS);
-                       i < MAX_LOGICAL_DRIVES_EXT; i++)
-                       pDrvRaidMap->ldTgtIdToLd[i] = 0xff;
                for (i = 0; i < ld_count; i++) {
                        pDrvRaidMap->ldSpanMap[i] = pFwRaidMap->ldSpanMap[i];
 #if VD_EXT_DEBUG
@@ -279,7 +465,9 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance)
        lbInfo = fusion->load_balance_info;
        ldSpanInfo = fusion->log_to_span;
 
-       if (instance->supportmax256vd)
+       if (instance->maxRaidMapSize)
+               expected_size = sizeof(struct MR_DRV_RAID_MAP_ALL);
+       else if (instance->supportmax256vd)
                expected_size = sizeof(struct MR_FW_RAID_MAP_EXT);
        else
                expected_size =
@@ -287,8 +475,9 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance)
                        (sizeof(struct MR_LD_SPAN_MAP) * 
le16_to_cpu(pDrvRaidMap->ldCount)));
 
        if (le32_to_cpu(pDrvRaidMap->totalSize) != expected_size) {
-               dev_err(&instance->pdev->dev, "map info structure size 0x%x is 
not matching with ld count\n",
-                      (unsigned int) expected_size);
+               dev_err(&instance->pdev->dev, "megasas: map info structure"
+               " size 0x%x is not matching expected size 0x%x\n",
+                       le32_to_cpu(pDrvRaidMap->totalSize), (unsigned int) 
expected_size);
                dev_err(&instance->pdev->dev, "megasas: span map %x, 
pDrvRaidMap->totalSize : %x\n",
                        (unsigned int)sizeof(struct MR_LD_SPAN_MAP),
                        le32_to_cpu(pDrvRaidMap->totalSize));
@@ -796,9 +985,15 @@ static u8 mr_spanset_get_phy_params(struct 
megasas_instance *instance, u32 ld,
        }
 
        *pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, 
map)->startBlk);
-       pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) |
-                                       physArm;
-       io_info->span_arm = pRAID_Context->spanArm;
+       if (instance->is_ventura) {
+               ((RAID_CONTEXT_G35 *) pRAID_Context)->spanArm =
+                               (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+               io_info->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | 
physArm;
+       } else {
+               pRAID_Context->spanArm =
+                       (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+               io_info->span_arm = pRAID_Context->spanArm;
+       }
        return retval;
 }
 
@@ -900,9 +1095,15 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 
ld, u64 stripRow,
        }
 
        *pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, 
map)->startBlk);
-       pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) |
-               physArm;
-       io_info->span_arm = pRAID_Context->spanArm;
+       if (instance->is_ventura) {
+               ((RAID_CONTEXT_G35 *) pRAID_Context)->spanArm =
+                               (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+               io_info->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | 
physArm;
+       } else {
+               pRAID_Context->spanArm =
+                       (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+               io_info->span_arm = pRAID_Context->spanArm;
+       }
        return retval;
 }
 
@@ -1113,7 +1314,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 
ld, u64 stripRow,
        if (fusion->adapter_type == INVADER_SERIES)
                pRAID_Context->regLockFlags = (isRead) ?
                        raid->regTypeReqOnRead : raid->regTypeReqOnWrite;
-       else
+       else if (!instance->is_ventura)
                pRAID_Context->regLockFlags = (isRead) ?
                        REGION_TYPE_SHARED_READ : raid->regTypeReqOnWrite;
        pRAID_Context->VirtualDiskTgtId = raid->targetId;
@@ -1137,6 +1338,11 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, 
u32 ld, u64 stripRow,
                /* If IO on an invalid Pd, then FP is not possible.*/
                if (io_info->devHandle == cpu_to_le16(MR_PD_INVALID))
                        io_info->fpOkForIo = FALSE;
+               /* if FP possible, set the SLUD bit in regLockFlags for ventura 
*/
+               else if ((instance->is_ventura) &&
+                       !isRead && (raid->writeMode == MR_RL_WRITE_BACK_MODE) &&
+                               raid->capability.fpCacheBypassCapable)
+                ((RAID_CONTEXT_G35 *) pRAID_Context)->routingFlags.bits.sld = 
1;
                /* set raid 1/10 fast path write capable bit in io_info */
                if (io_info->fpOkForIo &&
                    (io_info->r1_alt_dev_handle != MR_PD_INVALID) &&
@@ -1316,6 +1522,7 @@ u8 megasas_get_best_arm_pd(struct megasas_instance 
*instance,
        struct fusion_context *fusion;
        struct MR_LD_RAID  *raid;
        struct MR_DRV_RAID_MAP_ALL *drv_map;
+       u16     pd1_devHandle;
        u16     pend0, pend1, ld;
        u64     diff0, diff1;
        u8      bestArm, pd0, pd1, span, arm;
@@ -1341,23 +1548,34 @@ u8 megasas_get_best_arm_pd(struct megasas_instance 
*instance,
        pd1 = MR_ArPdGet(arRef, (arm + 1) >= span_row_size ?
                (arm + 1 - span_row_size) : arm + 1, drv_map);
 
-       /* get the pending cmds for the data and mirror arms */
-       pend0 = atomic_read(&lbInfo->scsi_pending_cmds[pd0]);
-       pend1 = atomic_read(&lbInfo->scsi_pending_cmds[pd1]);
+       /* Get PD1 Dev Handle */
 
-       /* Determine the disk whose head is nearer to the req. block */
-       diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[pd0]);
-       diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[pd1]);
-       bestArm = (diff0 <= diff1 ? arm : arm ^ 1);
+       pd1_devHandle = MR_PdDevHandleGet(pd1, drv_map);
 
-       if ((bestArm == arm && pend0 > pend1 + lb_pending_cmds)  ||
+       if (pd1_devHandle == MR_PD_INVALID) {
+               bestArm = arm;
+       } else {
+               /* get the pending cmds for the data and mirror arms */
+               pend0 = atomic_read(&lbInfo->scsi_pending_cmds[pd0]);
+               pend1 = atomic_read(&lbInfo->scsi_pending_cmds[pd1]);
+
+               /* Determine the disk whose head is nearer to the req. block */
+               diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[pd0]);
+               diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[pd1]);
+               /*bestArm = diff0<=diff1 ? arm : arm ^ 1;*/
+               bestArm = (diff0 <= diff1 ? arm : arm ^ 1);
+
+               /*Make balance count from 16 to 4 to keep driver in sync with 
Firmware*/
+               if ((bestArm == arm && pend0 > pend1 + lb_pending_cmds)  ||
                        (bestArm != arm && pend1 > pend0 + lb_pending_cmds))
                bestArm ^= 1;
 
-       /* Update the last accessed block on the correct pd */
-       io_info->pd_after_lb = (bestArm == arm) ? pd0 : pd1;
+               /* Update the last accessed block on the correct pd */
+               io_info->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | 
bestArm;
+               io_info->pd_after_lb = (bestArm == arm) ? pd0:pd1;
+       }
+
        lbInfo->last_accessed_block[io_info->pd_after_lb] = block + count - 1;
-       io_info->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | bestArm;
 #if SPAN_DEBUG
        if (arm != bestArm)
                dev_dbg(&instance->pdev->dev, "LSI Debug R1 Load balance "
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 116f300..e0b188d 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1825,7 +1825,7 @@ static void megasas_stream_detect(struct megasas_instance 
*instance,
                          struct megasas_cmd_fusion *cmd)
 {
        u8 fp_possible;
-       u32 start_lba_lo, start_lba_hi, device_id, datalength = 0;
+       u32 start_lba_lo, start_lba_hi, device_id, datalength = 0, ld;
        struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
        union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
        struct IO_REQUEST_INFO io_info;
@@ -1833,6 +1833,8 @@ static void megasas_stream_detect(struct megasas_instance 
*instance,
        struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
        u8 *raidLUN;
        unsigned long spinlock_flags;
+       RAID_CONTEXT_UNION *pRAID_Context;
+       struct MR_LD_RAID *raid;
 
        device_id = MEGASAS_DEV_INDEX(scp);
 
@@ -1911,6 +1913,8 @@ static void megasas_stream_detect(struct megasas_instance 
*instance,
                io_info.isRead = 1;
 
        local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
+       ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
+       raid = MR_LdRaidGet(ld, local_map_ptr);
 
        if ((MR_TargetIdToLdGet(device_id, local_map_ptr) >=
                instance->fw_supported_vd_count) || (!fusion->fast_path_io)) {
@@ -1941,6 +1945,8 @@ static void megasas_stream_detect(struct megasas_instance 
*instance,
                        fp_possible = false;
        }
 
+       pRAID_Context = &io_request->RaidContext;
+
        if (fp_possible) {
                megasas_set_pd_lba(io_request, scp->cmd_len, &io_info, scp,
                                   local_map_ptr, start_lba_lo);
@@ -1960,6 +1966,12 @@ static void megasas_stream_detect(struct 
megasas_instance *instance,
                        io_request->RaidContext.raid_context.regLockFlags |=
                          (MR_RL_FLAGS_GRANT_DESTINATION_CUDA |
                           MR_RL_FLAGS_SEQ_NUM_ENABLE);
+               } else if (instance->is_ventura) {
+                       io_request->RaidContext.raid_context_g35.Type = 
MPI2_TYPE_CUDA;
+                       io_request->RaidContext.raid_context_g35.nseg = 0x1;
+                       
io_request->RaidContext.raid_context_g35.routingFlags.bits.sqn = 1;
+                       io_request->IoFlags |=
+                               
cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
                }
                if ((fusion->load_balance_info[device_id].loadBalanceFlag) &&
                    (io_info.isRead)) {
@@ -1969,6 +1981,13 @@ static void megasas_stream_detect(struct 
megasas_instance *instance,
                                        &io_info);
                        scp->SCp.Status |= MEGASAS_LOAD_BALANCE_FLAG;
                        cmd->pd_r1_lb = io_info.pd_after_lb;
+                       if (instance->is_ventura)
+                               
io_request->RaidContext.raid_context_g35.spanArm =
+                                       io_info.span_arm;
+                       else
+                               io_request->RaidContext.raid_context.spanArm =
+                                       io_info.span_arm;
+
                } else
                        scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG;
 
@@ -1987,6 +2006,36 @@ static void megasas_stream_detect(struct 
megasas_instance *instance,
                io_request->DevHandle = io_info.devHandle;
                /* populate the LUN field */
                memcpy(io_request->LUN, raidLUN, 8);
+               if (instance->is_ventura) {
+                       if (io_info.isRead) {
+                               if ((raid->cpuAffinity.pdRead.cpu0) &&
+                                                       
(raid->cpuAffinity.pdRead.cpu1))
+                                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                                               
MR_RAID_CTX_CPUSEL_FCFS;
+                               else if (raid->cpuAffinity.pdRead.cpu1)
+                                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                                               
MR_RAID_CTX_CPUSEL_1;
+                               else
+                                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                                               
MR_RAID_CTX_CPUSEL_0;
+                       } else {
+                               if ((raid->cpuAffinity.pdWrite.cpu0) &&
+                                                       
(raid->cpuAffinity.pdWrite.cpu1))
+                                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                                               
MR_RAID_CTX_CPUSEL_FCFS;
+                               else if (raid->cpuAffinity.pdWrite.cpu1)
+                                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                                               
MR_RAID_CTX_CPUSEL_1;
+                               else
+                                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                                               
MR_RAID_CTX_CPUSEL_0;
+                               if 
(pRAID_Context->raid_context_g35.routingFlags.bits.sld) {
+                                       
pRAID_Context->raid_context_g35.RAIDFlags =
+                                               
(MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS
+                                               << 
MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT);
+                               }
+                       }
+               }
        } else {
                io_request->RaidContext.raid_context.timeoutValue =
                        cpu_to_le16(local_map_ptr->raidMap.fpPdIoTimeoutSec);
@@ -1996,7 +2045,7 @@ static void megasas_stream_detect(struct megasas_instance 
*instance,
                if (fusion->adapter_type == INVADER_SERIES) {
                        if (io_info.do_fp_rlbypass ||
                                
(io_request->RaidContext.raid_context.regLockFlags ==
-                                                                               
                        REGION_TYPE_UNUSED))
+                                       REGION_TYPE_UNUSED))
                                cmd->request_desc->SCSIIO.RequestFlags =
                                        (MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK <<
                                        MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
@@ -2005,9 +2054,48 @@ static void megasas_stream_detect(struct 
megasas_instance *instance,
                                (MR_RL_FLAGS_GRANT_DESTINATION_CPU0 |
                                 MR_RL_FLAGS_SEQ_NUM_ENABLE);
                        io_request->RaidContext.raid_context.nseg = 0x1;
+               } else if (instance->is_ventura) {
+                       io_request->RaidContext.raid_context_g35.Type = 
MPI2_TYPE_CUDA;
+                       
io_request->RaidContext.raid_context_g35.routingFlags.bits.sqn = 1;
+                       io_request->RaidContext.raid_context_g35.nseg = 0x1;
                }
                io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
                io_request->DevHandle = cpu_to_le16(device_id);
+
+               if (instance->is_ventura) {
+                       if (io_info.isRead) {
+                               if ((raid->cpuAffinity.ldRead.cpu0) &&
+                                               (raid->cpuAffinity.ldRead.cpu1))
+                                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                                               
MR_RAID_CTX_CPUSEL_FCFS;
+                               else if (raid->cpuAffinity.ldRead.cpu1)
+                                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                                               
MR_RAID_CTX_CPUSEL_1;
+                               else
+                                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                                               
MR_RAID_CTX_CPUSEL_0;
+                       } else {
+                               if ((raid->cpuAffinity.ldWrite.cpu0) &&
+                                                       
(raid->cpuAffinity.ldWrite.cpu1))
+                                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                                               
MR_RAID_CTX_CPUSEL_FCFS;
+                               else if (raid->cpuAffinity.ldWrite.cpu1)
+                                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                                               
MR_RAID_CTX_CPUSEL_1;
+                               else
+                                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                                               
MR_RAID_CTX_CPUSEL_0;
+
+                               if 
(io_request->RaidContext.raid_context_g35.streamDetected &&
+                                       (raid->level == 5) &&
+                                                               
(raid->writeMode == MR_RL_WRITE_THROUGH_MODE)) {
+                                       if 
(pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel ==
+                                                               
MR_RAID_CTX_CPUSEL_FCFS)
+                                               
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                               MR_RAID_CTX_CPUSEL_0;
+                               }
+                       }
+               }
        } /* Not FP */
 }
 
@@ -2072,7 +2160,8 @@ static void megasas_build_ld_nonrw_fusion(struct 
megasas_instance *instance,
 
                /* set RAID context values */
                pRAID_Context->configSeqNum = raid->seqNum;
-               pRAID_Context->regLockFlags = REGION_TYPE_SHARED_READ;
+               if (!instance->is_ventura)
+                       pRAID_Context->regLockFlags = REGION_TYPE_SHARED_READ;
                pRAID_Context->timeoutValue = 
cpu_to_le16(raid->fpIoTimeoutForLd);
 
                /* get the DevHandle for the PD (since this is
@@ -2146,8 +2235,11 @@ static void megasas_build_ld_nonrw_fusion(struct 
megasas_instance *instance,
                        cpu_to_le16(device_id + (MAX_PHYSICAL_DEVICES - 1));
                pRAID_Context->configSeqNum = pd_sync->seq[pd_index].seqNum;
                io_request->DevHandle = pd_sync->seq[pd_index].devHandle;
-               pRAID_Context->regLockFlags |=
-                       
(MR_RL_FLAGS_SEQ_NUM_ENABLE|MR_RL_FLAGS_GRANT_DESTINATION_CUDA);
+               if (instance->is_ventura)
+                       
io_request->RaidContext.raid_context_g35.routingFlags.bits.sqn = 1;
+               else
+                       pRAID_Context->regLockFlags |=
+                               
(MR_RL_FLAGS_SEQ_NUM_ENABLE|MR_RL_FLAGS_GRANT_DESTINATION_CUDA);
                pRAID_Context->Type = MPI2_TYPE_CUDA;
                pRAID_Context->nseg = 0x1;
        } else if (fusion->fast_path_io) {
@@ -2267,11 +2359,15 @@ static void megasas_build_ld_nonrw_fusion(struct 
megasas_instance *instance,
                return 1;
        }
 
-       /* numSGE store lower 8 bit of sge_count.
-        * numSGEExt store higher 8 bit of sge_count
-        */
-       io_request->RaidContext.raid_context.numSGE = sge_count;
-       io_request->RaidContext.raid_context.numSGEExt = (u8)(sge_count >> 8);
+       if (instance->is_ventura)
+               io_request->RaidContext.raid_context_g35.numSGE = sge_count;
+       else {
+               /* numSGE store lower 8 bit of sge_count.
+                * numSGEExt store higher 8 bit of sge_count
+                */
+               io_request->RaidContext.raid_context.numSGE = sge_count;
+               io_request->RaidContext.raid_context.numSGEExt = (u8)(sge_count 
>> 8);
+       }
 
        io_request->SGLFlags = cpu_to_le16(MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
 
@@ -2320,6 +2416,10 @@ void megasas_fpio_to_ldio(struct megasas_instance 
*instance,
        struct megasas_cmd_fusion *cmd, struct scsi_cmnd *scmd)
 {
        struct fusion_context *fusion;
+       RAID_CONTEXT_UNION *pRAID_Context;
+       struct MR_LD_RAID *raid;
+       struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
+       u32 device_id, ld;
        fusion = instance->ctrl_context;
        
        cmd->request_desc->SCSIIO.RequestFlags =
@@ -2343,6 +2443,34 @@ void megasas_fpio_to_ldio(struct megasas_instance 
*instance,
        cmd->io_request->Control = 0;
        cmd->io_request->EEDPBlockSize = 0;
        cmd->isRaid_1_fp_write = 0;
+
+       device_id = MEGASAS_DEV_INDEX(cmd->scmd);
+       local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
+       ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
+       raid = MR_LdRaidGet(ld, local_map_ptr);
+       pRAID_Context = &cmd->io_request->RaidContext;
+       if (cmd->scmd->sc_data_direction == PCI_DMA_FROMDEVICE) {
+               if ((raid->cpuAffinity.ldRead.cpu0) && 
(raid->cpuAffinity.ldRead.cpu1))
+                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                               
MR_RAID_CTX_CPUSEL_FCFS;
+               else if (raid->cpuAffinity.ldRead.cpu1)
+                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                               
MR_RAID_CTX_CPUSEL_1;
+               else
+                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                               
MR_RAID_CTX_CPUSEL_0;
+       } else {
+               if ((raid->cpuAffinity.ldWrite.cpu0) &&
+                                               
(raid->cpuAffinity.ldWrite.cpu1))
+                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                               
MR_RAID_CTX_CPUSEL_FCFS;
+               else if (raid->cpuAffinity.ldWrite.cpu1)
+                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                               
MR_RAID_CTX_CPUSEL_1;
+               else
+                       
pRAID_Context->raid_context_g35.routingFlags.bits.cpuSel =
+                                                               
MR_RAID_CTX_CPUSEL_0;
+       }
 }
 /*megasas_prepate_secondRaid1_IO
  * It prepares the raid 1 second IO
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h 
b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index aaa4924..8addf0e 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -59,6 +59,8 @@
 #define        MR_RL_FLAGS_GRANT_DESTINATION_CPU1          0x10
 #define        MR_RL_FLAGS_GRANT_DESTINATION_CUDA          0x80
 #define MR_RL_FLAGS_SEQ_NUM_ENABLE                 0x8
+#define MR_RL_WRITE_THROUGH_MODE                   0x00
+#define MR_RL_WRITE_BACK_MODE                      0x01
 
 /* T10 PI defines */
 #define MR_PROT_INFO_TYPE_CONTROLLER                0x8
@@ -81,6 +83,11 @@
 enum MR_RAID_FLAGS_IO_SUB_TYPE {
        MR_RAID_FLAGS_IO_SUB_TYPE_NONE = 0,
        MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD = 1,
+       MR_RAID_FLAGS_IO_SUB_TYPE_RMW_DATA     = 2,
+       MR_RAID_FLAGS_IO_SUB_TYPE_RMW_P        = 3,
+       MR_RAID_FLAGS_IO_SUB_TYPE_RMW_Q        = 4,
+       MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS = 6,
+       MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT = 7
 };
 
 /*
@@ -677,14 +684,17 @@ struct MPI2_IOC_INIT_REQUEST {
 #define MAX_RAIDMAP_ROW_SIZE (MAX_ROW_SIZE)
 #define MAX_LOGICAL_DRIVES 64
 #define MAX_LOGICAL_DRIVES_EXT 256
+#define MAX_LOGICAL_DRIVES_DYN 512
 #define MAX_RAIDMAP_LOGICAL_DRIVES (MAX_LOGICAL_DRIVES)
 #define MAX_RAIDMAP_VIEWS (MAX_LOGICAL_DRIVES)
 #define MAX_ARRAYS 128
 #define MAX_RAIDMAP_ARRAYS (MAX_ARRAYS)
 #define MAX_ARRAYS_EXT 256
 #define MAX_API_ARRAYS_EXT (MAX_ARRAYS_EXT)
+#define MAX_API_ARRAYS_DYN 512
 #define MAX_PHYSICAL_DEVICES 256
 #define MAX_RAIDMAP_PHYSICAL_DEVICES (MAX_PHYSICAL_DEVICES)
+#define MAX_RAIDMAP_PHYSICAL_DEVICES_DYN 512
 #define MR_DCMD_LD_MAP_GET_INFO             0x0300e101
 #define MR_DCMD_SYSTEM_PD_MAP_GET_INFO      0x0200e102
 #define MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC  0x010e8485   /* SR-IOV HB alloc*/
@@ -731,12 +741,56 @@ struct MR_SPAN_BLOCK_INFO {
        struct MR_SPAN_INFO block_span_info;
 };
 
+#define MR_RAID_CTX_CPUSEL_0           0
+#define MR_RAID_CTX_CPUSEL_1           1
+#define MR_RAID_CTX_CPUSEL_2           2
+#define MR_RAID_CTX_CPUSEL_3           3
+#define MR_RAID_CTX_CPUSEL_FCFS                0xF
+
+struct MR_CPU_AFFINITY_MASK {
+    union {
+               struct {
+#ifndef MFI_BIG_ENDIAN
+               u8  hwPath:1;
+               u8  cpu0:1;
+               u8  cpu1:1;
+               u8  cpu2:1;
+               u8  cpu3:1;
+               u8  reserved:3;
+#else
+               u8  reserved:3;
+               u8  cpu3:1;
+               u8  cpu2:1;
+               u8  cpu1:1;
+               u8  cpu0:1;
+               u8  hwPath:1;
+#endif
+               };
+               u8 coreMask;
+       };
+};
+
+struct MR_IO_AFFINITY {
+       union {
+               struct {
+                       struct MR_CPU_AFFINITY_MASK pdRead;
+                       struct MR_CPU_AFFINITY_MASK pdWrite;
+                       struct MR_CPU_AFFINITY_MASK ldRead;
+                       struct MR_CPU_AFFINITY_MASK ldWrite;
+                       };
+               u32 word;
+               };
+       u8 maxCores;    /* Total cores + HW Path in ROC */
+       u8 reserved[3];
+};
+
 struct MR_LD_RAID {
        struct {
 #if   defined(__BIG_ENDIAN_BITFIELD)
-               u32     reserved4:3;
+               u32     reserved4:2;
                u32     fpCacheBypassCapable:1;
                u32     fpRmwCapable:1;
+               u32     disableCoalescing:1;
                u32     fpBypassRegionLock:1;
                u32     tmCapable:1;
                u32     fpNonRWCapable:1;
@@ -764,9 +818,10 @@ struct MR_LD_RAID {
                u32     fpNonRWCapable:1;
                u32     tmCapable:1;
                u32     fpBypassRegionLock:1;
+               u32     disableCoalescing:1;
                u32     fpRmwCapable:1;
                u32     fpCacheBypassCapable:1;
-               u32     reserved4:3;
+               u32     reserved4:2;
 #endif
        } capability;
        __le32     reserved6;
@@ -793,7 +848,36 @@ struct MR_LD_RAID {
 
        u8      LUN[8]; /* 0x24 8 byte LUN field used for SCSI IO's */
        u8      fpIoTimeoutForLd;/*0x2C timeout value used by driver in FP IO*/
-       u8      reserved3[0x80-0x2D]; /* 0x2D */
+       /* Ox2D This LD accept priority boost of this type */
+       u8      ldAcceptPriorityType;
+       u8      reserved2[2];           /* 0x2E - 0x2F */
+       /* 0x30 - 0x33, Logical block size for the LD */
+       u32     logicalBlockLength;
+       struct {
+#ifndef MFI_BIG_ENDIAN
+       /* 0x34, P_I_EXPONENT from READ CAPACITY 16 */
+       u32  ldPiExp           :4;
+       /* 0x34, LOGICAL BLOCKS PER PHYSICAL
+       *  BLOCK EXPONENT from READ CAPACITY 16 
+       */
+       u32  ldLogicalBlockExp :4;
+       u32  reserved1:24;           /* 0x34 */
+#else
+       u32  reserved1:24;           /* 0x34 */
+       /* 0x34, LOGICAL BLOCKS PER PHYSICAL
+       *  BLOCK EXPONENT from READ CAPACITY 16 
+       */
+       u32  ldLogicalBlockExp :4;
+       /* 0x34, P_I_EXPONENT from READ CAPACITY 16 */
+       u32  ldPiExp           :4;
+#endif
+    };                               /* 0x34 - 0x37 */
+        /* 0x38 - 0x3f, This will determine which
+        *  core will process LD IO and PD IO. 
+        */
+    struct MR_IO_AFFINITY cpuAffinity;
+    /* Bit definiations are specified by MR_IO_AFFINITY */
+       u8      reserved3[0x80-0x40];    /* 0x40 - 0x7f */
 };
 
 struct MR_LD_SPAN_MAP {
@@ -851,6 +935,81 @@ struct MR_LD_TARGET_SYNC {
        __le16 seqNum;
 };
 
+/*
+ * RAID Map descriptor Types.
+ * Each element should uniquely idetify one data structure in the RAID map
+ */
+typedef enum _MR_RAID_MAP_DESC_TYPE {
+       RAID_MAP_DESC_TYPE_DEVHDL_INFO    = 0x0,   /* MR_DEV_HANDLE_INFO data */
+       RAID_MAP_DESC_TYPE_TGTID_INFO     = 0x1,   /* target to Ld num Index 
map */
+       RAID_MAP_DESC_TYPE_ARRAY_INFO     = 0x2,   /* MR_ARRAY_INFO data */
+       RAID_MAP_DESC_TYPE_SPAN_INFO      = 0x3,   /* MR_LD_SPAN_MAP data */
+       RAID_MAP_DESC_TYPE_COUNT,
+} MR_RAID_MAP_DESC_TYPE;
+
+/*
+ * This table defines the offset, size and num elements  of each descriptor
+ * type in the RAID Map buffer
+ */
+typedef struct _MR_RAID_MAP_DESC_TABLE {
+       u32     raidMapDescType;           /* Raid map descriptor type */
+       u32     raidMapDescOffset;         /* Offset into the RAID map buffer 
where
+                                                          *  descriptor data 
is saved 
+                                                                          */
+       u32     raidMapDescBufferSize;    /* total size of the descriptor 
buffer */
+       u32     raidMapDescElements;      /* Number of elements contained in the
+                                                             *  descriptor 
buffer 
+                                                                         */
+} MR_RAID_MAP_DESC_TABLE;
+
+/*
+ * Dynamic Raid Map Structure.
+ */
+struct MR_FW_RAID_MAP_DYNAMIC {
+    u32                 raidMapSize;   /* total size of RAID Map structure */
+    u32                 descTableOffset;/* Offset of desc table into RAID map*/
+    u32                 descTableSize;  /* Total Size of desc table */
+       /* Total Number of elements in the desc table */
+    u32                 descTableNumElements;
+    u64                        reserved1;
+    u32                        reserved2[3];   /*future use */
+       /* timeout value used by driver in FP IOs */
+    u8                  fpPdIoTimeoutSec;
+    u8                  reserved3[3];
+       /* when this seqNum increments, driver needs to release RMW buffers 
asap */
+    u32                 rmwFPSeqNum;
+    u16                 ldCount;         /* count of lds. */
+    u16                 arCount;         /* count of arrays */
+    u16                 spanCount;       /* count of spans */
+    u16                 reserved4[3];
+
+       /*
+       * The below structure of pointers is only to be used by the driver.
+       * This is added in the ,API to reduce the amount of code changes
+       * needed in the driver to support dynamic RAID map Firmware should
+       * not update these pointers while preparing the raid map
+       */
+       union {
+               struct {
+                       struct MR_DEV_HANDLE_INFO  *devHndlInfo;
+                       u16                 *ldTgtIdToLd;
+                       struct MR_ARRAY_INFO       *arMapInfo;
+                       struct MR_LD_SPAN_MAP      *ldSpanMap;
+               };
+               u64 ptrStructureSize[RAID_MAP_DESC_TYPE_COUNT];
+    };
+
+    /*
+     * RAID Map descriptor table defines the layout of data in the RAID Map.
+        * The size of the descriptor table itself could change.
+     */
+        /* Variable Size descriptor Table. */
+    MR_RAID_MAP_DESC_TABLE     raidMapDescTable[RAID_MAP_DESC_TYPE_COUNT];
+       /* Variable Size buffer containing all data */
+    u32                     raidMapDescData[1];
+
+} ; /* Dynamicaly sized RAID MAp structure */
+
 #define IEEE_SGE_FLAGS_ADDR_MASK            (0x03)
 #define IEEE_SGE_FLAGS_SYSTEM_ADDR          (0x00)
 #define IEEE_SGE_FLAGS_IOCDDR_ADDR          (0x01)
@@ -960,9 +1119,9 @@ struct MR_DRV_RAID_MAP {
        __le16                 spanCount;
        __le16                 reserve3;
 
-       struct MR_DEV_HANDLE_INFO  devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES];
-       u8                  ldTgtIdToLd[MAX_LOGICAL_DRIVES_EXT];
-       struct MR_ARRAY_INFO       arMapInfo[MAX_API_ARRAYS_EXT];
+       struct MR_DEV_HANDLE_INFO  
devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES_DYN];
+       u16                 ldTgtIdToLd[MAX_LOGICAL_DRIVES_DYN];
+       struct MR_ARRAY_INFO       arMapInfo[MAX_API_ARRAYS_DYN];
        struct MR_LD_SPAN_MAP      ldSpanMap[1];
 
 };
@@ -974,7 +1133,7 @@ struct MR_DRV_RAID_MAP {
 struct MR_DRV_RAID_MAP_ALL {
 
        struct MR_DRV_RAID_MAP raidMap;
-       struct MR_LD_SPAN_MAP      ldSpanMap[MAX_LOGICAL_DRIVES_EXT - 1];
+       struct MR_LD_SPAN_MAP      ldSpanMap[MAX_LOGICAL_DRIVES_DYN - 1];
 } __packed;
 
 
@@ -1094,7 +1253,7 @@ struct fusion_context {
        u8      chain_offset_io_request;
        u8      chain_offset_mfi_pthru;
 
-       struct MR_FW_RAID_MAP_ALL *ld_map[2];
+       struct MR_FW_RAID_MAP_DYNAMIC *ld_map[2];
        dma_addr_t ld_map_phys[2];
 
        /*Non dma-able memory. Driver local copy.*/
@@ -1102,6 +1261,8 @@ struct fusion_context {
 
        u32 max_map_sz;
        u32 current_map_sz;
+       u32 old_map_sz;
+       u32 new_map_sz;
        u32 drv_map_sz;
        u32 drv_map_pages;
        struct MR_PD_CFG_SEQ_NUM_SYNC   *pd_seq_sync[JBOD_MAPS_COUNT];
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to