Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1534398 > unrolled thread

[PATCH 00/11] Updates for scsi-next

Started bySasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
First post2016-12-01 20:30 +0100
Last post2016-12-01 20:30 +0100
Articles 7 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH 00/11] Updates for scsi-next Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com> - 2016-12-01 20:30 +0100
    [PATCH 10/11] megaraid_sas: Implement the PD Map support for SAS3.5 Generic Megaraid Controllers Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com> - 2016-12-01 20:30 +0100
    [PATCH 02/11] megaraid_sas: 128 MSIX Support Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com> - 2016-12-01 20:30 +0100
    [PATCH 04/11] megaraid_sas: SAS3.5 Generic Megaraid Controllers Stream Detection and IO Coalescing Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com> - 2016-12-01 20:30 +0100
    [PATCH 07/11] megaraid_sas: Add the Support for SAS3.5 Generic Megaraid Controllers Capabilities Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com> - 2016-12-01 20:30 +0100
    [PATCH 08/11] megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com> - 2016-12-01 20:30 +0100
    [PATCH 06/11] megaraid_sas: Dynamic Raid Map Changes for SAS3.5 Generic Megaraid Controllers Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com> - 2016-12-01 20:30 +0100

#1534398 — [PATCH 00/11] Updates for scsi-next

FromSasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
Date2016-12-01 20:30 +0100
Subject[PATCH 00/11] Updates for scsi-next
Message-ID<sJFdn-te-3@gated-at.bofh.it>
From: root <sasikumar.pc@broadcom.com>


Sasikumar Chandrasekaran (11):
  megaraid_sas: Add new pci device Ids for SAS3.5 Generic Megaraid
    Controllers
  megaraid_sas: 128 MSIX Support
  megaraid_sas: EEDP Escape Mode Support for SAS3.5 Generic Megaraid
    Controllers
  megaraid_sas: SAS3.5 Generic Megaraid Controllers Stream Detection and
    IO Coalescing
  megaraid_sas: SAS3.5 Generic Megaraid Controllers Fast Path for RAID
    1/10 Writes
  megaraid_sas: Dynamic Raid Map Changes for SAS3.5 Generic Megaraid
    Controllers
  megaraid_sas: Add the Support for SAS3.5 Generic Megaraid Controllers
    Capabilities
  megaraid_sas: Enable or Disable Fast path based on the PCI Threshold
    Bandwidth
  megaraid_sas: ldio_outstanding variable is not decremented in
    completion path
  megaraid_sas: Implement the PD Map support for SAS3.5 Generic Megaraid
    Controllers
  megaraid_sas: driver version upgrade

 drivers/scsi/megaraid/megaraid_sas.h        | 139 ++++--
 drivers/scsi/megaraid/megaraid_sas_base.c   | 242 +++++++---
 drivers/scsi/megaraid/megaraid_sas_fp.c     | 319 +++++++++++--
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 687 ++++++++++++++++++++++++----
 drivers/scsi/megaraid/megaraid_sas_fusion.h | 318 ++++++++++++-
 5 files changed, 1474 insertions(+), 231 deletions(-)

-- 
1.8.3.1

[toc] | [next] | [standalone]


#1534399 — [PATCH 10/11] megaraid_sas: Implement the PD Map support for SAS3.5 Generic Megaraid Controllers

FromSasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
Date2016-12-01 20:30 +0100
Subject[PATCH 10/11] megaraid_sas: Implement the PD Map support for SAS3.5 Generic Megaraid Controllers
Message-ID<sJFdo-te-21@gated-at.bofh.it>
In reply to#1534398
From: root <sasikumar.pc@broadcom.com>

Update Linux driver to use new pdTargetId field for JBOD target ID

This patch is depending on patch 9

Signed-off-by: Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
---
 drivers/scsi/megaraid/megaraid_sas.h        | 106 +++++++++++++++++++++-------
 drivers/scsi/megaraid/megaraid_sas_base.c   |   5 +-
 drivers/scsi/megaraid/megaraid_sas_fusion.c |  11 ++-
 drivers/scsi/megaraid/megaraid_sas_fusion.h |   3 +-
 4 files changed, 94 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 40b8295..e4bb93d 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1320,7 +1320,56 @@ struct megasas_ctrl_info {
 #endif
 	} adapterOperations3;
 
-	u8          pad[0x800-0x7EC];
+	struct {
+#if defined(__BIG_ENDIAN_BITFIELD)
+	u8 reserved:7;
+	/* Indicates whether the CPLD image is part of
+	*  the package and stored in flash   
+	*/
+	u8 cpldInFlash:1;
+#else
+	u8 cpldInFlash:1;
+	u8 reserved:7;
+#endif
+	u8 reserved1[3];
+	/* Null terminated string. Has the version
+	*  information if cpldInFlash = FALSE 
+	*/
+	u8 userCodeDefinition[12];
+	} cpld;  /* Valid only if upgradableCPLD is TRUE */
+
+	struct {
+	#if defined(__BIG_ENDIAN_BITFIELD)
+		u16 reserved			:8;
+		u16 FWSwapsBBUVPDInfo	:1;
+		u16 supportPdMapTargetId:1;
+		u16 supportSESCtrlInMultipathCfg:1;
+		u16 imageUploadSupported:1;
+		u16 supportEncryptedMfc :1;
+		u16 supportedEncAlgo	:1;
+		u16 supportIbuttonLess	:1;
+		u16 ctrlInfoExtSupported:1;
+	#else
+
+		u16 ctrlInfoExtSupported:1;
+		u16 supportIbuttonLess	:1;
+		u16 supportedEncAlgo	:1;
+		u16 supportEncryptedMfc :1;
+		u16 imageUploadSupported:1;
+		/* FW supports LUN based association and target port based */
+		u16 supportSESCtrlInMultipathCfg:1;
+		/* association for the SES device connected in multipath mode */
+		 /* FW defines Jbod target Id within MR_PD_CFG_SEQ */
+		u16 supportPdMapTargetId:1;
+		/* FW swaps relevant fields in MR_BBU_VPD_INFO_FIXED to
+		*  provide the data in little endian order 
+		*/
+		u16 FWSwapsBBUVPDInfo	:1;
+		u16 reserved			:8;
+	#endif
+		} adapterOperations4;
+
+    u8          pad[0x800-0x7FE]; 		/* 0x7FE pad to 2K for expansion */
 } __packed;
 
 /*
@@ -1560,33 +1609,35 @@ struct megasas_header {
 typedef union _MFI_CAPABILITIES {
 	struct {
 #if   defined(__BIG_ENDIAN_BITFIELD)
-		u32     reserved:20;
-		u32     support_qd_throttling:1;
-		u32     support_fp_rlbypass:1;
-		u32     support_vfid_in_ioframe:1;
-		u32     support_ext_io_size:1;
-		u32	support_ext_queue_depth:1;
-		u32     security_protocol_cmds_fw:1;
-		u32     support_core_affinity:1;
-		u32     support_ndrive_r1_lb:1;
-		u32	support_max_255lds:1;
-		u32	support_fastpath_wb:1;
-		u32     support_additional_msix:1;
-		u32     support_fp_remote_lun:1;
+	u32     reserved:19;
+	u32		supportPdMapTargetId:1;
+	u32     support_qd_throttling:1;
+	u32     support_fp_rlbypass:1;
+	u32     support_vfid_in_ioframe:1;
+	u32     support_ext_io_size:1;
+	u32		support_ext_queue_depth:1;
+	u32     security_protocol_cmds_fw:1;
+	u32     support_core_affinity:1;
+	u32     support_ndrive_r1_lb:1;
+	u32		support_max_255lds:1;
+	u32		support_fastpath_wb:1;
+	u32     support_additional_msix:1;
+	u32     support_fp_remote_lun:1;
 #else
-		u32     support_fp_remote_lun:1;
-		u32     support_additional_msix:1;
-		u32	support_fastpath_wb:1;
-		u32	support_max_255lds:1;
-		u32     support_ndrive_r1_lb:1;
-		u32     support_core_affinity:1;
-		u32     security_protocol_cmds_fw:1;
-		u32	support_ext_queue_depth:1;
-		u32     support_ext_io_size:1;
-		u32     support_vfid_in_ioframe:1;
-		u32     support_fp_rlbypass:1;
-		u32     support_qd_throttling:1;
-		u32     reserved:20;
+	u32     support_fp_remote_lun:1;
+	u32     support_additional_msix:1;
+	u32		support_fastpath_wb:1;
+	u32		support_max_255lds:1;
+	u32     support_ndrive_r1_lb:1;
+	u32     support_core_affinity:1;
+	u32     security_protocol_cmds_fw:1;
+	u32		support_ext_queue_depth:1;
+	u32     support_ext_io_size:1;
+	u32     support_vfid_in_ioframe:1;
+	u32     support_fp_rlbypass:1;
+	u32     support_qd_throttling:1;
+	u32		supportPdMapTargetId:1;
+	u32     reserved:19;
 #endif
 	} mfi_capabilities;
 	__le32		reg;
@@ -2055,6 +2106,7 @@ struct megasas_instance {
 	u32 crash_dump_drv_support;
 	u32 crash_dump_app_support;
 	u32 secure_jbod_support;
+	u32 support_morethan256jbod; /* FW support for more than 256 PD/JBOD */
 	bool use_seqnum_jbod_fp;   /* Added for PD sequence */
 	spinlock_t crashdump_lock;
 
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index be11e9d..eb65077 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -4578,6 +4578,7 @@ static void megasas_update_ext_vd_details(struct megasas_instance *instance)
 		le32_to_cpus((u32 *)&ctrl_info->properties.OnOffProperties);
 		le32_to_cpus((u32 *)&ctrl_info->adapterOperations2);
 		le32_to_cpus((u32 *)&ctrl_info->adapterOperations3);
+		le16_to_cpus((u16 *)&ctrl_info->adapterOperations4);
 
 		/* Update the latest Ext VD info.
 		 * From Init path, store current firmware details.
@@ -4586,7 +4587,9 @@ static void megasas_update_ext_vd_details(struct megasas_instance *instance)
 		 */
 		megasas_update_ext_vd_details(instance);
 		instance->use_seqnum_jbod_fp =
-			ctrl_info->adapterOperations3.useSeqNumJbodFP;
+					ctrl_info->adapterOperations3.useSeqNumJbodFP;
+		instance->support_morethan256jbod =
+					ctrl_info->adapterOperations4.supportPdMapTargetId;
 
 		/*Check whether controller is iMR or MR */
 		instance->is_imr = (ctrl_info->memory_size ? 0 : 1);
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index e8016bc..7c4f7bf 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -862,6 +862,9 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 		drv_ops->mfi_capabilities.support_ext_queue_depth = 1;
 
 	drv_ops->mfi_capabilities.support_qd_throttling = 1;
+
+	drv_ops->mfi_capabilities.supportPdMapTargetId = 1;
+
 	/* Convert capability to LE32 */
 	cpu_to_le32s((u32 *)&init_frame->driver_operations.mfi_capabilities);
 
@@ -2232,8 +2235,12 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
 	if (instance->use_seqnum_jbod_fp &&
 		instance->pd_list[pd_index].driveType == TYPE_DISK) {
 		/* TgtId must be incremented by 255 as jbod seq number is index
-		 * below raid map
-		 */
+		* below raid map
+		*/
+		/* More than 256 PD/JBOD support for Ventura */
+		if (instance->support_morethan256jbod)
+			pRAID_Context->VirtualDiskTgtId = pd_sync->seq[pd_index].pdTargetId;
+		else
 		pRAID_Context->VirtualDiskTgtId =
 			cpu_to_le16(device_id + (MAX_PHYSICAL_DEVICES - 1));
 		pRAID_Context->configSeqNum = pd_sync->seq[pd_index].seqNum;
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index e7be042..193d119 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -1183,7 +1183,8 @@ struct MR_PD_CFG_SEQ {
 		u8     reserved:7;
 #endif
 	} capability;
-	u8  reserved[3];
+	u8  reserved;
+	u16 pdTargetId;
 } __packed;
 
 struct MR_PD_CFG_SEQ_NUM_SYNC {
-- 
1.8.3.1

[toc] | [prev] | [next] | [standalone]


#1534401 — [PATCH 02/11] megaraid_sas: 128 MSIX Support

FromSasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
Date2016-12-01 20:30 +0100
Subject[PATCH 02/11] megaraid_sas: 128 MSIX Support
Message-ID<sJFdo-te-19@gated-at.bofh.it>
In reply to#1534398
From: root <sasikumar.pc@broadcom.com>

SAS3.5 Generic Megaraid based Controllers will have the support for 128 MSI-X vectors,
resulting in the need to support 128 reply queues

This patch is depending on patch 1

Signed-off-by: Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
---
 drivers/scsi/megaraid/megaraid_sas.h        |  1 +
 drivers/scsi/megaraid/megaraid_sas_base.c   | 24 +++++++++++++++++-------
 drivers/scsi/megaraid/megaraid_sas_fusion.c |  4 ++--
 3 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index f24ce88..af94f58 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2152,6 +2152,7 @@ struct megasas_instance {
 	bool dev_handle;
 	bool fw_sync_cache_support;
 	bool is_ventura;
+	bool msix_combined;
 };
 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 b7166b8..7c8c313 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -5089,13 +5089,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
 			goto fail_ready_state;
 	}
 
-	/*
-	 * MSI-X host index 0 is common for all adapter.
-	 * It is used for all MPT based Adapters.
-	 */
-	instance->reply_post_host_index_addr[0] =
-		(u32 __iomem *)((u8 __iomem *)instance->reg_set +
-		MPI2_REPLY_POST_HOST_INDEX_OFFSET);
+
 
 	/* Check if MSI-X is supported while in ready state */
 	msix_enable = (instance->instancet->read_fw_status_reg(reg_set) &
@@ -5113,6 +5107,9 @@ static int megasas_init_fw(struct megasas_instance *instance)
 				instance->msix_vectors = ((scratch_pad_2
 					& MR_MAX_REPLY_QUEUES_EXT_OFFSET)
 					>> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
+				if (instance->msix_vectors > 16)
+					instance->msix_combined = true;
+
 				if (rdpq_enable)
 					instance->is_rdpq = (scratch_pad_2 & MR_RDPQ_MODE_OFFSET) ?
 								1 : 0;
@@ -5146,6 +5143,19 @@ static int megasas_init_fw(struct megasas_instance *instance)
 		else
 			instance->msix_vectors = 0;
 	}
+	/*
+	 * MSI-X host index 0 is common for all adapter.
+	 * It is used for all MPT based Adapters.
+	 */
+	if (instance->msix_combined) {
+		instance->reply_post_host_index_addr[0] =
+				(u32 *)((u8 *)instance->reg_set +
+				MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET);
+	} else {
+		instance->reply_post_host_index_addr[0] =
+			(u32 *)((u8 *)instance->reg_set +
+			MPI2_REPLY_POST_HOST_INDEX_OFFSET);
+	}
 
 	dev_info(&instance->pdev->dev,
 		"firmware supports msix\t: (%d)", fw_msix_count);
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index e048423..9de9e66 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -2391,7 +2391,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
 		 * pending to be completed
 		 */
 		if (threshold_reply_count >= THRESHOLD_REPLY_COUNT) {
-			if (fusion->adapter_type == INVADER_SERIES)
+			if (instance->msix_combined)
 				writel(((MSIxIndex & 0x7) << 24) |
 					fusion->last_reply_idx[MSIxIndex],
 					instance->reply_post_host_index_addr[MSIxIndex/8]);
@@ -2407,7 +2407,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
 		return IRQ_NONE;
 
 	wmb();
-	if (fusion->adapter_type == INVADER_SERIES)
+	if (instance->msix_combined)
 		writel(((MSIxIndex & 0x7) << 24) |
 			fusion->last_reply_idx[MSIxIndex],
 			instance->reply_post_host_index_addr[MSIxIndex/8]);
-- 
1.8.3.1

[toc] | [prev] | [next] | [standalone]


#1534402 — [PATCH 04/11] megaraid_sas: SAS3.5 Generic Megaraid Controllers Stream Detection and IO Coalescing

FromSasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
Date2016-12-01 20:30 +0100
Subject[PATCH 04/11] megaraid_sas: SAS3.5 Generic Megaraid Controllers Stream Detection and IO Coalescing
Message-ID<sJFdo-te-25@gated-at.bofh.it>
In reply to#1534398
From: root <sasikumar.pc@broadcom.com>

Detect sequential IO streams and pass those IOs directly to FW.

This patch is depending on patch 3

Signed-off-by: Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
---
 drivers/scsi/megaraid/megaraid_sas.h        |   1 +
 drivers/scsi/megaraid/megaraid_sas_base.c   |  40 +++++++-
 drivers/scsi/megaraid/megaraid_sas_fp.c     |   2 +
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 151 +++++++++++++++++++++++-----
 drivers/scsi/megaraid/megaraid_sas_fusion.h | 123 +++++++++++++++++++++-
 5 files changed, 287 insertions(+), 30 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index af94f58..ee6bd5c 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2073,6 +2073,7 @@ struct megasas_instance {
 	/* used to sync fire the cmd to fw */
 	spinlock_t hba_lock;
 	/* used to synch producer, consumer ptrs in dpc */
+	spinlock_t stream_lock;
 	spinlock_t completion_lock;
 	struct dma_pool *frame_dma_pool;
 	struct dma_pool *sense_dma_pool;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 7c8c313..86f25d5 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -5018,7 +5018,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
 	struct megasas_register_set __iomem *reg_set;
 	struct megasas_ctrl_info *ctrl_info = NULL;
 	unsigned long bar_list;
-	int i, loop, fw_msix_count = 0;
+	int i, j, loop, fw_msix_count = 0;
 	struct IOV_111 *iovPtr;
 	struct fusion_context *fusion;
 
@@ -5205,6 +5205,33 @@ static int megasas_init_fw(struct megasas_instance *instance)
 	}
 
 	memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
+
+	/* stream detection initialization */
+	if (instance->is_ventura) {
+		fusion->streamDetectByLD =
+		kzalloc(sizeof(PTR_LD_STREAM_DETECT) * MAX_LOGICAL_DRIVES_EXT,
+				GFP_KERNEL);
+		if (!fusion->streamDetectByLD) {
+			dev_err(&instance->pdev->dev,
+					"unable to allocate stream detection for pool of LDs\n");
+			goto fail_get_ld_pd_list;
+		}
+		for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) {
+			fusion->streamDetectByLD[i] =
+				kmalloc(sizeof(LD_STREAM_DETECT), GFP_KERNEL);
+			if (!fusion->streamDetectByLD[i]) {
+				dev_err(&instance->pdev->dev,
+					"unable to allocate stream detect by LD\n ");
+				 for (j = 0; j < i; ++j)
+					kfree(fusion->streamDetectByLD[j]);
+				kfree(fusion->streamDetectByLD);
+				fusion->streamDetectByLD = NULL;
+				goto fail_get_ld_pd_list;
+			}
+			fusion->streamDetectByLD[i]->mruBitMap = MR_STREAM_BITMAP;
+		}
+	}
+
 	if (megasas_ld_list_query(instance,
 				  MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
 		megasas_get_ld_list(instance);
@@ -5324,6 +5351,8 @@ static int megasas_init_fw(struct megasas_instance *instance)
 
 	return 0;
 
+fail_get_ld_pd_list:
+	instance->instancet->disable_intr(instance);
 fail_get_pd_list:
 	instance->instancet->disable_intr(instance);
 	megasas_destroy_irqs(instance);
@@ -5860,6 +5889,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
 
 	spin_lock_init(&instance->mfi_pool_lock);
 	spin_lock_init(&instance->hba_lock);
+	spin_lock_init(&instance->stream_lock);
 	spin_lock_init(&instance->completion_lock);
 
 	mutex_init(&instance->reset_mutex);
@@ -6360,6 +6390,14 @@ static void megasas_detach_one(struct pci_dev *pdev)
 	if (instance->msix_vectors)
 		pci_disable_msix(instance->pdev);
 
+	if (instance->is_ventura) {
+		for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i)
+			kfree(fusion->streamDetectByLD[i]);
+		kfree(fusion->streamDetectByLD);
+		fusion->streamDetectByLD = NULL;
+	}
+
+
 	if (instance->ctrl_context) {
 		megasas_release_fusion(instance);
 			pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) +
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c
index f237d00..d9483bc 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -935,6 +935,8 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
 
 	ld = MR_TargetIdToLdGet(ldTgtId, map);
 	raid = MR_LdRaidGet(ld, map);
+	/*check read ahead bit*/
+	io_info->raCapable = raid->capability.raCapable;
 
 	/*
 	 * if rowDataSize @RAID map and spanRowDataSize @SPAN INFO are zero
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 7f26b14..3ad929b 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1704,6 +1704,81 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 }
 
 /**
+ * megasas_stream_detect -	stream detection on read and and write IOs
+ * @instance:		Adapter soft state
+ * @cmd:		    Command to be prepared
+ * @io_info:		IO Request info
+ *
+ */
+
+/** stream detection on read and and write IOs */
+static void megasas_stream_detect(struct megasas_instance *instance,
+				struct megasas_cmd_fusion *cmd,
+				struct IO_REQUEST_INFO *io_info)
+{
+	struct fusion_context *fusion = instance->ctrl_context;
+	u32 device_id = io_info->ldTgtId;
+	LD_STREAM_DETECT *current_ld_SD = fusion->streamDetectByLD[device_id];
+	u32 *track_stream = &current_ld_SD->mruBitMap, streamNum;
+	u32 shiftedValues, unshiftedValues;
+	u32 indexValueMask, shiftedValuesMask;
+	int i;
+	bool isReadAhead = false;
+	STREAM_DETECT *current_SD;
+	/* find possible stream */
+	for (i = 0; i < MAX_STREAMS_TRACKED; ++i) {
+		streamNum = (*track_stream >> (i * BITS_PER_INDEX_STREAM)) &
+			STREAM_MASK;
+		current_SD = &current_ld_SD->streamTrack[streamNum];
+	/* if we found a stream, update the raid
+	*  context and also update the mruBitMap 
+	*/
+	/*	boundary condition */
+		if (current_SD->nextSeqLBA && 
+				io_info->ldStartBlock >= current_SD->nextSeqLBA &&
+				(io_info->ldStartBlock <= (current_SD->nextSeqLBA+32)) &&
+				(current_SD->isRead == io_info->isRead)) {
+				if (io_info->ldStartBlock != current_SD->nextSeqLBA &&
+				(!io_info->isRead || !isReadAhead))
+				/*
+				*  Once the API availible we need to change this.
+				* At this point we are not allowing any gap
+				*/
+				continue;
+			cmd->io_request->RaidContext.raid_context_g35.streamDetected =
+																		true;
+			current_SD->nextSeqLBA =
+								io_info->ldStartBlock + io_info->numBlocks;
+			/*
+			*	update the mruBitMap LRU
+			*/
+			shiftedValuesMask = (1 <<  i * BITS_PER_INDEX_STREAM) - 1;
+			shiftedValues = ((*track_stream & shiftedValuesMask)
+						<< BITS_PER_INDEX_STREAM);
+			indexValueMask = STREAM_MASK << i * BITS_PER_INDEX_STREAM;
+			unshiftedValues =
+					*track_stream & ~(shiftedValuesMask | indexValueMask);
+			*track_stream = unshiftedValues | shiftedValues | streamNum;
+			return;
+
+		}
+
+	}
+	/*
+	* if we did not find any stream, create a new one from the least recently used
+	*/
+	streamNum =
+	(*track_stream >> ((MAX_STREAMS_TRACKED - 1) * BITS_PER_INDEX_STREAM)) &
+			STREAM_MASK;
+	current_SD = &current_ld_SD->streamTrack[streamNum];
+	current_SD->isRead = io_info->isRead;
+	current_SD->nextSeqLBA = io_info->ldStartBlock + io_info->numBlocks;
+	*track_stream = (((*track_stream & ZERO_LAST_STREAM) << 4) | streamNum);
+	return;
+
+}
+
+/**
  * megasas_build_ldio_fusion -	Prepares IOs to devices
  * @instance:		Adapter soft state
  * @scp:		SCSI command
@@ -1725,15 +1800,17 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 	struct fusion_context *fusion;
 	struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
 	u8 *raidLUN;
+	unsigned long spinlock_flags;
 
 	device_id = MEGASAS_DEV_INDEX(scp);
 
 	fusion = instance->ctrl_context;
 
 	io_request = cmd->io_request;
-	io_request->RaidContext.VirtualDiskTgtId = cpu_to_le16(device_id);
-	io_request->RaidContext.status = 0;
-	io_request->RaidContext.exStatus = 0;
+	io_request->RaidContext.raid_context.VirtualDiskTgtId =
+										cpu_to_le16(device_id);
+	io_request->RaidContext.raid_context.status = 0;
+	io_request->RaidContext.raid_context.exStatus = 0;
 
 	req_desc = (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)cmd->request_desc;
 
@@ -1804,11 +1881,11 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 
 	if ((MR_TargetIdToLdGet(device_id, local_map_ptr) >=
 		instance->fw_supported_vd_count) || (!fusion->fast_path_io)) {
-		io_request->RaidContext.regLockFlags  = 0;
+		io_request->RaidContext.raid_context.regLockFlags  = 0;
 		fp_possible = 0;
 	} else {
 		if (MR_BuildRaidContext(instance, &io_info,
-					&io_request->RaidContext,
+					&io_request->RaidContext.raid_context,
 					local_map_ptr, &raidLUN))
 			fp_possible = io_info.fpOkForIo;
 	}
@@ -1819,6 +1896,18 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 	cmd->request_desc->SCSIIO.MSIxIndex = instance->msix_vectors ?
 		raw_smp_processor_id() % instance->msix_vectors : 0;
 
+	if (instance->is_ventura) {
+		spin_lock_irqsave(&instance->stream_lock, spinlock_flags);
+		megasas_stream_detect(instance, cmd, &io_info);
+		spin_unlock_irqrestore(&instance->stream_lock, spinlock_flags);
+		/* In ventura if stream detected for a read and it is read ahead
+		*  capable make this IO as LDIO 
+		*/
+		if (io_request->RaidContext.raid_context_g35.streamDetected &&
+				io_info.isRead && io_info.raCapable)
+			fp_possible = false;
+	}
+
 	if (fp_possible) {
 		megasas_set_pd_lba(io_request, scp->cmd_len, &io_info, scp,
 				   local_map_ptr, start_lba_lo);
@@ -1827,15 +1916,15 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 			(MPI2_REQ_DESCRIPT_FLAGS_FP_IO
 			 << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
 		if (fusion->adapter_type == INVADER_SERIES) {
-			if (io_request->RaidContext.regLockFlags ==
+			if (io_request->RaidContext.raid_context.regLockFlags ==
 			    REGION_TYPE_UNUSED)
 				cmd->request_desc->SCSIIO.RequestFlags =
 					(MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK <<
 					MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
-			io_request->RaidContext.Type = MPI2_TYPE_CUDA;
-			io_request->RaidContext.nseg = 0x1;
+			io_request->RaidContext.raid_context.Type = MPI2_TYPE_CUDA;
+			io_request->RaidContext.raid_context.nseg = 0x1;
 			io_request->IoFlags |= cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
-			io_request->RaidContext.regLockFlags |=
+			io_request->RaidContext.raid_context.regLockFlags |=
 			  (MR_RL_FLAGS_GRANT_DESTINATION_CUDA |
 			   MR_RL_FLAGS_SEQ_NUM_ENABLE);
 		}
@@ -1862,22 +1951,23 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 		/* populate the LUN field */
 		memcpy(io_request->LUN, raidLUN, 8);
 	} else {
-		io_request->RaidContext.timeoutValue =
+		io_request->RaidContext.raid_context.timeoutValue =
 			cpu_to_le16(local_map_ptr->raidMap.fpPdIoTimeoutSec);
 		cmd->request_desc->SCSIIO.RequestFlags =
 			(MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO
 			 << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
 		if (fusion->adapter_type == INVADER_SERIES) {
 			if (io_info.do_fp_rlbypass ||
-				(io_request->RaidContext.regLockFlags == REGION_TYPE_UNUSED))
+				(io_request->RaidContext.raid_context.regLockFlags ==
+													REGION_TYPE_UNUSED))
 				cmd->request_desc->SCSIIO.RequestFlags =
 					(MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK <<
 					MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
-			io_request->RaidContext.Type = MPI2_TYPE_CUDA;
-			io_request->RaidContext.regLockFlags |=
+			io_request->RaidContext.raid_context.Type = MPI2_TYPE_CUDA;
+			io_request->RaidContext.raid_context.regLockFlags |=
 				(MR_RL_FLAGS_GRANT_DESTINATION_CPU0 |
 				 MR_RL_FLAGS_SEQ_NUM_ENABLE);
-			io_request->RaidContext.nseg = 0x1;
+			io_request->RaidContext.raid_context.nseg = 0x1;
 		}
 		io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
 		io_request->DevHandle = cpu_to_le16(device_id);
@@ -1913,7 +2003,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
 	local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
 	io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
 	/* get RAID_Context pointer */
-	pRAID_Context = &io_request->RaidContext;
+	pRAID_Context = &io_request->RaidContext.raid_context;
 	/* Check with FW team */
 	pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
 	pRAID_Context->regLockRowLBA    = 0;
@@ -2000,7 +2090,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
 
 	io_request = cmd->io_request;
 	/* get RAID_Context pointer */
-	pRAID_Context = &io_request->RaidContext;
+	pRAID_Context = &io_request->RaidContext.raid_context;
 	pRAID_Context->regLockFlags = 0;
 	pRAID_Context->regLockRowLBA = 0;
 	pRAID_Context->regLockLength = 0;
@@ -2094,9 +2184,9 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
 	io_request->Control = 0;
 	io_request->EEDPBlockSize = 0;
 	io_request->ChainOffset = 0;
-	io_request->RaidContext.RAIDFlags = 0;
-	io_request->RaidContext.Type = 0;
-	io_request->RaidContext.nseg = 0;
+	io_request->RaidContext.raid_context.RAIDFlags = 0;
+	io_request->RaidContext.raid_context.Type = 0;
+	io_request->RaidContext.raid_context.nseg = 0;
 
 	memcpy(io_request->CDB.CDB32, scp->cmnd, scp->cmd_len);
 	/*
@@ -2143,8 +2233,8 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
 	/* numSGE store lower 8 bit of sge_count.
 	 * numSGEExt store higher 8 bit of sge_count
 	 */
-	io_request->RaidContext.numSGE = sge_count;
-	io_request->RaidContext.numSGEExt = (u8)(sge_count >> 8);
+	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);
 
@@ -2303,8 +2393,8 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
 			cmd_fusion->scmd->SCp.ptr = NULL;
 
 		scmd_local = cmd_fusion->scmd;
-		status = scsi_io_req->RaidContext.status;
-		extStatus = scsi_io_req->RaidContext.exStatus;
+		status = scsi_io_req->RaidContext.raid_context.status;
+		extStatus = scsi_io_req->RaidContext.raid_context.exStatus;
 
 		switch (scsi_io_req->Function) {
 		case MPI2_FUNCTION_SCSI_TASK_MGMT:
@@ -2337,8 +2427,8 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
 		case MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST: /* LD-IO Path */
 			/* Map the FW Cmd Status */
 			map_cmd_status(cmd_fusion, status, extStatus);
-			scsi_io_req->RaidContext.status = 0;
-			scsi_io_req->RaidContext.exStatus = 0;
+			scsi_io_req->RaidContext.raid_context.status = 0;
+			scsi_io_req->RaidContext.raid_context.exStatus = 0;
 			if (megasas_cmd_type(scmd_local) == READ_WRITE_LDIO)
 				atomic_dec(&instance->ldio_outstanding);
 			megasas_return_cmd_fusion(instance, cmd_fusion);
@@ -3393,7 +3483,7 @@ int megasas_check_mpio_paths(struct megasas_instance *instance,
 /* Core fusion reset function */
 int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
 {
-	int retval = SUCCESS, i, convert = 0;
+	int retval = SUCCESS, i, j, convert = 0;
 	struct megasas_instance *instance;
 	struct megasas_cmd_fusion *cmd_fusion;
 	struct fusion_context *fusion;
@@ -3558,6 +3648,15 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
 			shost_for_each_device(sdev, shost)
 				megasas_update_sdev_properties(sdev);
 
+			/* reset stream detection array */
+			if (instance->is_ventura) {
+				for (j = 0; j < MAX_LOGICAL_DRIVES_EXT; ++j) {
+					memset(fusion->streamDetectByLD[j], 0,
+									sizeof(LD_STREAM_DETECT));
+					fusion->streamDetectByLD[j]->mruBitMap = MR_STREAM_BITMAP;
+				}
+			}
+
 			clear_bit(MEGASAS_FUSION_IN_RESET,
 				  &instance->reset_flags);
 			instance->instancet->enable_intr(instance);
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index 9d22ade..9bb2f40 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -133,12 +133,100 @@ struct RAID_CONTEXT {
 	u8      resvd2;
 };
 
+/*
+* Raid Context structure which describes ventura MegaRAID specific
+* IO Paramenters ,This resides at offset 0x60 where the SGL normally
+* starts in MPT IO Frames
+*/
+typedef struct _RAID_CONTEXT_G35 {
+#if   defined(__BIG_ENDIAN_BITFIELD)
+	u16	resvd0:8;
+	u16	nseg:4;
+	u16	Type:4;
+#else
+	u16	Type:4;		    /* 0x00 */
+	u16	nseg:4;		    /* 0x00 */
+	u16     resvd0:8;
+#endif
+	u16     timeoutValue; /* 0x02 -0x03 */
+	union {
+		struct {
+#if	defined(__BIG_ENDIAN_BITFIELD)
+		u16	setDivert:4;
+		u16	cpuSel:4;
+		u16	log:1;
+		u16	rw:1;
+		u16	sbs:1;
+		u16	sqn:1;
+		u16	fwn:1;
+		u16	c2f:1;
+		u16	sld:1;
+		u16	reserved:1;
+#else
+		u16	reserved:1;
+		u16	sld:1;
+		u16	c2f:1;
+		u16	fwn:1;
+		u16	sqn:1;
+		u16	sbs:1;
+		u16	rw:1;
+		u16	log:1;
+		u16	cpuSel:4;
+		u16	setDivert:4;
+#endif
+			} bits;
+		u16 s;
+	} routingFlags;	/* 0x04 -0x05 routing flags */
+
+	u16     VirtualDiskTgtId;   /* 0x06 -0x07 */
+
+	u64     regLockRowLBA;      /* 0x08 - 0x0F */
+
+	u32     regLockLength;      /* 0x10 - 0x13 */
+
+	union {
+		u16     nextLMId;           /* 0x14 - 0x15 */
+		u16	peerSMID;	/* used for the raid 1/10 fp writes */
+	} smid;
+	u8      exStatus;       /* 0x16 : OUT */
+	u8      status;             /* 0x17 status */
+
+	u8      RAIDFlags;          /* 0x18 resvd[7:6], ioSubType[5:4],
+								* resvd[3:1], preferredCpu[0] 
+								*/
+	u8      spanArm;            /* 0x1C span[7:5], arm[4:0] */
+	u16	configSeqNum;           /* 0x1A -0x1B */
+#if   defined(__BIG_ENDIAN_BITFIELD)              /* 0x1C – 0x1D */
+	u16     streamDetected:1;
+	u16     reserved:3;
+	u16     numSGE:12;
+#else
+	u16     numSGE:12;
+	u16     reserved:3;
+	u16     streamDetected:1;
+#endif
+	u8      resvd2[2];          /* 0x1E-0x1F */
+} RAID_CONTEXT_G35;
+
+typedef union _RAID_CONTEXT_UNION {
+	struct RAID_CONTEXT raid_context;
+	RAID_CONTEXT_G35 raid_context_g35;
+} RAID_CONTEXT_UNION, *PRAID_CONTEXT_UNION;
+
 #define RAID_CTX_SPANARM_ARM_SHIFT	(0)
 #define RAID_CTX_SPANARM_ARM_MASK	(0x1f)
 
 #define RAID_CTX_SPANARM_SPAN_SHIFT	(5)
 #define RAID_CTX_SPANARM_SPAN_MASK	(0xE0)
 
+/* number of bits per index in U32 TrackStream */
+#define BITS_PER_INDEX_STREAM		4
+#define INVALID_STREAM_NUM              16
+#define MR_STREAM_BITMAP		0x76543210
+#define STREAM_MASK			((1 << BITS_PER_INDEX_STREAM) - 1)
+#define ZERO_LAST_STREAM		0x0fffffff
+#define MAX_STREAMS_TRACKED 		8
+
 /*
  * define region lock types
  */
@@ -409,7 +497,7 @@ struct MPI2_RAID_SCSI_IO_REQUEST {
 	u8                      LUN[8];                         /* 0x34 */
 	__le32			Control;                        /* 0x3C */
 	union MPI2_SCSI_IO_CDB_UNION  CDB;			/* 0x40 */
-	struct RAID_CONTEXT	RaidContext;                    /* 0x60 */
+	RAID_CONTEXT_UNION            RaidContext;  /* 0x60 */
 	union MPI2_SGE_IO_UNION       SGL;			/* 0x80 */
 };
 
@@ -656,11 +744,13 @@ struct MR_LD_RAID {
 		u32     encryptionType:8;
 		u32     pdPiMode:4;
 		u32     ldPiMode:4;
-		u32     reserved5:3;
+		u32     reserved5:2;
+		u32     raCapable:1;
 		u32     fpCapable:1;
 #else
 		u32     fpCapable:1;
-		u32     reserved5:3;
+		u32     raCapable:1;
+		u32     reserved5:2;
 		u32     ldPiMode:4;
 		u32     pdPiMode:4;
 		u32     encryptionType:8;
@@ -745,6 +835,7 @@ struct IO_REQUEST_INFO {
 	u64 start_row;
 	u8  span_arm;	/* span[7:5], arm[4:0] */
 	u8  pd_after_lb;
+	bool raCapable;
 };
 
 struct MR_LD_TARGET_SYNC {
@@ -930,6 +1021,31 @@ struct MR_PD_CFG_SEQ_NUM_SYNC {
 	struct MR_PD_CFG_SEQ seq[1];
 } __packed;
 
+/* stream detection */
+typedef struct _STREAM_DETECT {
+	u64 nextSeqLBA; /* next LBA to match sequential access */
+	struct megasas_cmd_fusion *first_cmd_fusion; /* first cmd in group */
+	struct megasas_cmd_fusion *last_cmd_fusion; /* last cmd in group */
+	u32 countCmdsInStream; /* count of host commands in this stream */
+	u16 numSGEsInGroup; /* total number of SGEs in grouped IOs */
+	u8 isRead; /* SCSI OpCode for this stream */
+	u8 groupDepth; /* total number of host commands in group */
+	bool groupFlush; /* TRUE if cannot add any more commands to this group */
+	u8 reserved[7]; /* pad to 64-bit alignment */
+} STREAM_DETECT, *PTR_STREAM_DETECT;
+
+typedef struct _LD_STREAM_DETECT {
+	bool writeBack; /* TRUE if WB, FALSE if WT */
+	bool FPWriteEnabled;
+	bool membersSSDs;
+	bool fpCacheBypassCapable;
+	u32 mruBitMap; /* bitmap used to track MRU and LRU stream indicies */
+	volatile long iosToFware; /* current count of RW IOs sent to Fware */
+	volatile long writeBytesOutstanding; /* not used in first implementation */
+	/* this is the array of stream detect structures (one per stream) */
+	STREAM_DETECT streamTrack[MAX_STREAMS_TRACKED];
+} LD_STREAM_DETECT, *PTR_LD_STREAM_DETECT;
+
 struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY {
 	u64 RDPQBaseAddress;
 	u32 Reserved1;
@@ -983,6 +1099,7 @@ struct fusion_context {
 	struct LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES_EXT];
 	LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT];
 	u8 adapter_type;
+	PTR_LD_STREAM_DETECT  *streamDetectByLD;
 };
 
 union desc_value {
-- 
1.8.3.1

[toc] | [prev] | [next] | [standalone]


#1534404 — [PATCH 07/11] megaraid_sas: Add the Support for SAS3.5 Generic Megaraid Controllers Capabilities

FromSasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
Date2016-12-01 20:30 +0100
Subject[PATCH 07/11] megaraid_sas: Add the Support for SAS3.5 Generic Megaraid Controllers Capabilities
Message-ID<sJFdo-te-27@gated-at.bofh.it>
In reply to#1534398
From: root <sasikumar.pc@broadcom.com>

The Megaraid driver has to support the SAS3.5 Generic Megaraid Controllers Firmware functionality.

This patch is depending on patch 6

Signed-off-by: Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
---
 drivers/scsi/megaraid/megaraid_sas_base.c   | 53 ++++++++++++++---------------
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 18 +++++-----
 drivers/scsi/megaraid/megaraid_sas_fusion.h |  1 +
 3 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index b74609c..cfd379a 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -5058,34 +5058,29 @@ static int megasas_init_fw(struct megasas_instance *instance)
 
 	reg_set = instance->reg_set;
 
-	switch (instance->pdev->device) {
-	case PCI_DEVICE_ID_LSI_FUSION:
-	case PCI_DEVICE_ID_LSI_PLASMA:
-	case PCI_DEVICE_ID_LSI_INVADER:
-	case PCI_DEVICE_ID_LSI_FURY:
-	case PCI_DEVICE_ID_LSI_INTRUDER:
-	case PCI_DEVICE_ID_LSI_INTRUDER_24:
-	case PCI_DEVICE_ID_LSI_CUTLASS_52:
-	case PCI_DEVICE_ID_LSI_CUTLASS_53:
+	if (fusion)
 		instance->instancet = &megasas_instance_template_fusion;
-		break;
-	case PCI_DEVICE_ID_LSI_SAS1078R:
-	case PCI_DEVICE_ID_LSI_SAS1078DE:
-		instance->instancet = &megasas_instance_template_ppc;
-		break;
-	case PCI_DEVICE_ID_LSI_SAS1078GEN2:
-	case PCI_DEVICE_ID_LSI_SAS0079GEN2:
-		instance->instancet = &megasas_instance_template_gen2;
-		break;
-	case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
-	case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
-		instance->instancet = &megasas_instance_template_skinny;
-		break;
-	case PCI_DEVICE_ID_LSI_SAS1064R:
-	case PCI_DEVICE_ID_DELL_PERC5:
-	default:
-		instance->instancet = &megasas_instance_template_xscale;
-		break;
+	else {
+		switch (instance->pdev->device) {
+		case PCI_DEVICE_ID_LSI_SAS1078R:
+		case PCI_DEVICE_ID_LSI_SAS1078DE:
+			instance->instancet = &megasas_instance_template_ppc;
+			break;
+		case PCI_DEVICE_ID_LSI_SAS1078GEN2:
+		case PCI_DEVICE_ID_LSI_SAS0079GEN2:
+			instance->instancet = &megasas_instance_template_gen2;
+			break;
+		case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
+		case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
+			instance->instancet = &megasas_instance_template_skinny;
+			break;
+		case PCI_DEVICE_ID_LSI_SAS1064R:
+		case PCI_DEVICE_ID_DELL_PERC5:
+		default:
+			instance->instancet = &megasas_instance_template_xscale;
+			instance->pd_list_not_supported = 1;
+			break;
+		}
 	}
 
 	if (megasas_transition_to_ready(instance, 0)) {
@@ -5827,7 +5822,9 @@ static int megasas_probe_one(struct pci_dev *pdev,
 		if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
 			(instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA))
 			fusion->adapter_type = THUNDERBOLT_SERIES;
-		else if (!instance->is_ventura)
+		else if (instance->is_ventura)
+			fusion->adapter_type = VENTURA_SERIES;
+		else
 			fusion->adapter_type = INVADER_SERIES;
 	}
 	break;
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index e0b188d..331cacd 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -244,7 +244,9 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance,
 
 	reg_set = instance->reg_set;
 
-	cur_max_fw_cmds = readl(&instance->reg_set->outbound_scratch_pad_3) & 0x00FFFF;
+	/* ventura FW does not fill outbound_scratch_pad_3 with queue depth */
+	if (!instance->is_ventura)
+		cur_max_fw_cmds = readl(&instance->reg_set->outbound_scratch_pad_3) & 0x00FFFF;
 
 	if (dual_qdepth_disable || !cur_max_fw_cmds)
 		cur_max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
@@ -842,7 +844,7 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 	drv_ops = (MFI_CAPABILITIES *) &(init_frame->driver_operations);
 
 	/* driver support Extended MSIX */
-	if (fusion->adapter_type == INVADER_SERIES)
+	if (fusion->adapter_type >= INVADER_SERIES)
 		drv_ops->mfi_capabilities.support_additional_msix = 1;
 	/* driver supports HA / Remote LUN over Fast Path interface */
 	drv_ops->mfi_capabilities.support_fp_remote_lun = 1;
@@ -1496,7 +1498,7 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 
 	fusion = instance->ctrl_context;
 
-	if (fusion->adapter_type == INVADER_SERIES) {
+	if (fusion->adapter_type >= INVADER_SERIES) {
 		struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end = sgl_ptr;
 		sgl_ptr_end += fusion->max_sge_in_main_msg - 1;
 		sgl_ptr_end->Flags = 0;
@@ -1513,7 +1515,7 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 		sgl_ptr->Length = cpu_to_le32(sg_dma_len(os_sgl));
 		sgl_ptr->Address = cpu_to_le64(sg_dma_address(os_sgl));
 		sgl_ptr->Flags = 0;
-		if (fusion->adapter_type == INVADER_SERIES)
+		if (fusion->adapter_type >= INVADER_SERIES)
 			if (i == sge_count - 1)
 				sgl_ptr->Flags = IEEE_SGE_FLAGS_END_OF_LIST;
 		sgl_ptr++;
@@ -1524,7 +1526,7 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 		    (sge_count > fusion->max_sge_in_main_msg)) {
 
 			struct MPI25_IEEE_SGE_CHAIN64 *sg_chain;
-			if (fusion->adapter_type == INVADER_SERIES) {
+			if (fusion->adapter_type >= INVADER_SERIES) {
 				if ((le16_to_cpu(cmd->io_request->IoFlags) &
 					MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) !=
 					MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH)
@@ -1540,7 +1542,7 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance)
 			sg_chain = sgl_ptr;
 			/* Prepare chain element */
 			sg_chain->NextChainOffset = 0;
-			if (fusion->adapter_type == INVADER_SERIES)
+			if (fusion->adapter_type >= INVADER_SERIES)
 				sg_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT;
 			else
 				sg_chain->Flags =
@@ -2277,7 +2279,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
 		pRAID_Context->timeoutValue =
 			cpu_to_le16((os_timeout_value > timeout_limit) ?
 			timeout_limit : os_timeout_value);
-		if (fusion->adapter_type == INVADER_SERIES)
+		if (fusion->adapter_type >= INVADER_SERIES)
 			io_request->IoFlags |=
 				cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
 
@@ -2974,7 +2976,7 @@ irqreturn_t megasas_isr_fusion(int irq, void *devp)
 
 	io_req = cmd->io_request;
 
-	if (fusion->adapter_type == INVADER_SERIES) {
+	if (fusion->adapter_type >= INVADER_SERIES) {
 		struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end =
 			(struct MPI25_IEEE_SGE_CHAIN64 *)&io_req->SGL;
 		sgl_ptr_end += fusion->max_sge_in_main_msg - 1;
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index 8addf0e..1feaad0 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -107,6 +107,7 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE {
 enum MR_FUSION_ADAPTER_TYPE {
 	THUNDERBOLT_SERIES = 0,
 	INVADER_SERIES = 1,
+	VENTURA_SERIES = 2,
 };
 
 /*
-- 
1.8.3.1

[toc] | [prev] | [next] | [standalone]


#1534405 — [PATCH 08/11] megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth

FromSasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
Date2016-12-01 20:30 +0100
Subject[PATCH 08/11] megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth
Message-ID<sJFdo-te-33@gated-at.bofh.it>
In reply to#1534398
From: root <sasikumar.pc@broadcom.com>

Large SEQ IO workload should sent as non fast path commands

This patch is depending on patch 7

Signed-off-by: Sasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
---
 drivers/scsi/megaraid/megaraid_sas.h        |  8 +++++
 drivers/scsi/megaraid/megaraid_sas_base.c   | 49 +++++++++++++++++++++++++++++
 drivers/scsi/megaraid/megaraid_sas_fp.c     | 21 ++++++++-----
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 20 +++++++-----
 drivers/scsi/megaraid/megaraid_sas_fusion.h |  5 +--
 5 files changed, 86 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 2da47b9..40b8295 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1432,6 +1432,8 @@ enum FW_BOOT_CONTEXT {
 #define MFI_1068_FW_HANDSHAKE_OFFSET		0x64
 #define MFI_1068_FW_READY			0xDDDD0000
 
+#define MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL HZ
+
 #define MR_MAX_REPLY_QUEUES_OFFSET              0X0000001F
 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET          0X003FC000
 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT    14
@@ -2104,6 +2106,10 @@ struct megasas_instance {
 	atomic_t ldio_outstanding;
 	atomic_t fw_reset_no_pci_access;
 
+	atomic64_t bytes_wrote; /* used for raid1 fast path enable or disable */
+	atomic_t r1_write_fp_capable;
+
+
 	struct megasas_instance_template *instancet;
 	struct tasklet_struct isr_tasklet;
 	struct work_struct work_init;
@@ -2146,6 +2152,7 @@ struct megasas_instance {
 	long reset_flags;
 	struct mutex reset_mutex;
 	struct timer_list sriov_heartbeat_timer;
+	struct timer_list r1_fp_hold_timer;
 	char skip_heartbeat_timer_del;
 	u8 requestorId;
 	char PlasmaFW111;
@@ -2162,6 +2169,7 @@ struct megasas_instance {
 	bool is_ventura;
 	bool msix_combined;
 	u16 maxRaidMapSize;
+	u64  pci_threshold_bandwidth; /* used to control the fp writes */
 };
 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 cfd379a..be11e9d 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1943,6 +1943,9 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance)
 	}
 	/* Complete outstanding ioctls when adapter is killed */
 	megasas_complete_outstanding_ioctls(instance);
+	if (instance->is_ventura)
+		del_timer_sync(&instance->r1_fp_hold_timer);
+
 }
 
  /**
@@ -2441,6 +2444,24 @@ void megasas_sriov_heartbeat_handler(unsigned long instance_addr)
 	}
 }
 
+/*Handler for disabling/enabling raid 1 fast paths*/
+void megasas_change_r1_fp_status(unsigned long instance_addr)
+{
+	struct megasas_instance *instance =
+			(struct megasas_instance *)instance_addr;
+	if (atomic64_read(&instance->bytes_wrote) >=
+					instance->pci_threshold_bandwidth) {
+
+		atomic64_set(&instance->bytes_wrote, 0);
+		atomic_set(&instance->r1_write_fp_capable, 0);
+	} else {
+		atomic64_set(&instance->bytes_wrote, 0);
+		atomic_set(&instance->r1_write_fp_capable, 1);
+	}
+	mod_timer(&instance->r1_fp_hold_timer,
+			jiffies + MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
+}
+
 /**
  * megasas_wait_for_outstanding -	Wait for all outstanding cmds
  * @instance:				Adapter soft state
@@ -5367,6 +5388,18 @@ static int megasas_init_fw(struct megasas_instance *instance)
 			instance->skip_heartbeat_timer_del = 1;
 	}
 
+	if (instance->is_ventura) {
+		atomic64_set(&instance->bytes_wrote, 0);
+		atomic_set(&instance->r1_write_fp_capable, 1);
+		megasas_start_timer(instance,
+			    &instance->r1_fp_hold_timer,
+			    megasas_change_r1_fp_status,
+			    MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
+		dev_info(&instance->pdev->dev, "starting the raid 1 fp timer"
+			" with interval %d \n",
+			MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
+	}
+
 	return 0;
 
 fail_get_ld_pd_list:
@@ -6160,6 +6193,9 @@ static void megasas_shutdown_controller(struct megasas_instance *instance,
 	if (instance->requestorId && !instance->skip_heartbeat_timer_del)
 		del_timer_sync(&instance->sriov_heartbeat_timer);
 
+	if (instance->is_ventura)
+		del_timer_sync(&instance->r1_fp_hold_timer);
+
 	megasas_flush_cache(instance);
 	megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
 
@@ -6279,6 +6315,16 @@ static void megasas_shutdown_controller(struct megasas_instance *instance,
 	megasas_setup_jbod_map(instance);
 	instance->unload = 0;
 
+	if (instance->is_ventura) {
+		atomic64_set(&instance->bytes_wrote, 0);
+		atomic_set(&instance->r1_write_fp_capable, 1);
+		megasas_start_timer(instance,
+			    &instance->r1_fp_hold_timer,
+			    megasas_change_r1_fp_status,
+			    MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL);
+	}
+
+
 	/*
 	 * Initiate AEN (Asynchronous Event Notification)
 	 */
@@ -6367,6 +6413,9 @@ static void megasas_detach_one(struct pci_dev *pdev)
 	if (instance->requestorId && !instance->skip_heartbeat_timer_del)
 		del_timer_sync(&instance->sriov_heartbeat_timer);
 
+	if (instance->is_ventura)
+		del_timer_sync(&instance->r1_fp_hold_timer);
+
 	if (instance->fw_crash_state != UNAVAILABLE)
 		megasas_free_host_crash_buffer(instance);
 	scsi_remove_host(instance->host);
diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c
index 546a543..d7d9722 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fp.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fp.c
@@ -196,14 +196,19 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
 
 	if (instance->maxRaidMapSize) {
 		fw_map_dyn = fusion->ld_map[(instance->map_id & 1)];
+		if (fw_map_dyn->PCIThresholdBandwidth)
+			instance->pci_threshold_bandwidth =
+				le64_to_cpu(fw_map_dyn->PCIThresholdBandwidth);
 #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,
+		" raidMapSize 0x%x fw_map_dyn->descTableOffset 0x%x, "
+		" descTableSize 0x%x descTableNumElements 0x%x, "
+		" PCIThreasholdBandwidth %llu\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),
+		instance->pci_threshold_bandwidth);
 		dev_dbg(&instance->pdev->dev,
 				"drv map %p ldCount %d\n", drv_map, fw_map_dyn->ldCount);
 #endif
@@ -438,6 +443,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
 			sizeof(struct MR_DEV_HANDLE_INFO) *
 			MAX_RAIDMAP_PHYSICAL_DEVICES);
 	}
+	if (instance->is_ventura && !instance->pci_threshold_bandwidth)
+		instance->pci_threshold_bandwidth = ULLONG_MAX;
 }
 
 /*
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 331cacd..3aab189 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -95,6 +95,7 @@ void megasas_start_timer(struct megasas_instance *instance,
 extern unsigned int dual_qdepth_disable;
 static void megasas_free_rdpq_fusion(struct megasas_instance *instance);
 static void megasas_free_reply_fusion(struct megasas_instance *instance);
+void megasas_change_r1_fp_status(unsigned long instance_addr);
 
 
 
@@ -2608,8 +2609,9 @@ void megasas_prepare_secondRaid1_IO(struct megasas_instance *instance,
 	* 	to get new command
 	*/
 	if (cmd->isRaid_1_fp_write &&
-		atomic_inc_return(&instance->fw_outstanding) >
-			(instance->host->can_queue)) {
+		(atomic_inc_return(&instance->fw_outstanding) >
+			(instance->host->can_queue) ||
+		(!atomic_read(&instance->r1_write_fp_capable)))) {
 		megasas_fpio_to_ldio(instance, cmd, cmd->scmd);
 		atomic_dec(&instance->fw_outstanding);
 	} else if (cmd->isRaid_1_fp_write) {
@@ -2618,17 +2620,19 @@ void megasas_prepare_secondRaid1_IO(struct megasas_instance *instance,
 		megasas_prepare_secondRaid1_IO(instance, cmd, r1_cmd);
 	}
 
-
 	/*
-	 * Issue the command to the FW
-	 */
+	* Issue the command to the FW
+	*/
+	if (scmd->sc_data_direction == PCI_DMA_TODEVICE && instance->is_ventura)
+		atomic64_add(scsi_bufflen(scmd), &instance->bytes_wrote);
 
 	megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura);
 
-	if (r1_cmd)
+	if (r1_cmd) {
+		atomic64_add(scsi_bufflen(scmd), &instance->bytes_wrote);
 		megasas_fire_cmd_fusion(instance, r1_cmd->request_desc,
-				instance->is_ventura);
-
+			instance->is_ventura);
+	}
 
 	return 0;
 }
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h
index 1feaad0..e7be042 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
@@ -972,7 +972,7 @@ struct MR_FW_RAID_MAP_DYNAMIC {
     u32                 descTableSize;  /* Total Size of desc table */
 	/* Total Number of elements in the desc table */
     u32                 descTableNumElements;
-    u64			reserved1;
+    u64			PCIThresholdBandwidth;
     u32			reserved2[3];	/*future use */
 	/* timeout value used by driver in FP IOs */
     u8                  fpPdIoTimeoutSec;
@@ -1121,7 +1121,7 @@ struct MR_DRV_RAID_MAP {
 	__le16                 reserve3;
 
 	struct MR_DEV_HANDLE_INFO  devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES_DYN];
-	u16                 ldTgtIdToLd[MAX_LOGICAL_DRIVES_DYN];
+	u16                  ldTgtIdToLd[MAX_LOGICAL_DRIVES_DYN];
 	struct MR_ARRAY_INFO       arMapInfo[MAX_API_ARRAYS_DYN];
 	struct MR_LD_SPAN_MAP      ldSpanMap[1];
 
@@ -1265,6 +1265,7 @@ struct fusion_context {
 	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];
 	dma_addr_t pd_seq_phys[JBOD_MAPS_COUNT];
-- 
1.8.3.1

[toc] | [prev] | [next] | [standalone]


#1534406 — [PATCH 06/11] megaraid_sas: Dynamic Raid Map Changes for SAS3.5 Generic Megaraid Controllers

FromSasikumar Chandrasekaran <sasikumar.pc@broadcom.com>
Date2016-12-01 20:30 +0100
Subject[PATCH 06/11] megaraid_sas: Dynamic Raid Map Changes for SAS3.5 Generic Megaraid Controllers
Message-ID<sJFdo-te-31@gated-at.bofh.it>
In reply to#1534398
From: root <sasikumar.pc@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.pc@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

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web