diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index ac19d53..fcf2b86 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -217,6 +217,7 @@
 #define MR_DCMD_CTRL_SET_CRASH_DUMP_PARAMS	0x01190100
 #define MR_DRIVER_SET_APP_CRASHDUMP_MODE	(0xF0010000 | 0x0600)
 #define MR_DCMD_PD_GET_INFO			0x02020000
+#define MR_DCMD_CTRL_BIOS_DATA_GET              0x010c0100
 
 /*
  * Global functions
@@ -763,6 +764,21 @@ struct MR_LD_TARGETID_LIST {
 	u8	targetId[MAX_LOGICAL_DRIVES_EXT];
 };
 
+struct MR_BIOS_DATA {
+	u16     bootTargetId;
+	u8      doNotExpose;
+	u8      continueOnError;
+	u8      verbose;
+	u8      geometry;
+	u8      exposeAllDrives;
+	u8      disableCTO;
+	u8      bootDeviceIsPD;
+	u8      EKMStatus;
+	u8      autoSelectBootLd;
+	u8      reserved[52];
+	u8      checkSum;
+};
+
 
 /*
  * SAS controller properties
@@ -1341,6 +1357,8 @@ struct megasas_ctrl_info {
 #define SCAN_PD_CHANNEL	0x1
 #define SCAN_VD_CHANNEL	0x2
 
+#define MEGASAS_INVALID_TARGET_ID               0xFFFF
+
 enum MR_SCSI_CMD_TYPE {
 	READ_WRITE_LDIO = 0,
 	NON_READ_WRITE_LDIO = 1,
@@ -1994,6 +2012,17 @@ enum MR_PD_TYPE {
 		 FC_PD = 4,
 };
 
+/*
+ *  define the structure specific to drive order feature
+ */
+struct megasas_drive_order {
+	u8 needs_ordering;         /* Drive ordering feature is enabled/disabled */
+	u8 boot_drive_is_pd;       /* Set if boot device is PD */
+	u16 boot_fw_tgt_id;        /* FW Target ID */
+	u8 boot_drive_channel_id;  /* OS Channel ID */
+	u16 boot_drive_tgt_id;     /* OS Target ID */
+};
+
 /* JBOD Queue depth definitions */
 #define MEGASAS_SATA_QD	32
 #define MEGASAS_SAS_QD	64
@@ -2133,7 +2162,9 @@ struct megasas_instance {
 	u8 is_imr;
 	u8 is_rdpq;
 	bool dev_handle;
+	struct megasas_drive_order drive_order;
 };
+
 struct MR_LD_VF_MAP {
 	u32 size;
 	union MR_LD_REF ref;
@@ -2319,6 +2350,7 @@ struct megasas_mgmt_info {
 	int max_index;
 };
 
+
 enum MEGASAS_OCR_CAUSE {
 	FW_FAULT_OCR			= 0,
 	SCSIIO_TIMEOUT_OCR		= 1,
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 316d5a0..b946ecb 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -4445,6 +4445,139 @@ static void megasas_update_ext_vd_details(struct megasas_instance *instance)
 }
 
 /**
+ * megasas_get_bios_data  -	Returns FW's mr_bios_data structure
+ * @instance:			Adapter structure
+ *
+ * Issues an internal command (DCMD) to get the FW's controller BIOS
+ * data structure.  This information is mainly used to find the
+ * boot drive and its target id.
+ */
+
+static int
+megasas_get_bios_data(struct megasas_instance *instance)
+{
+	int ret = 0;
+	struct megasas_cmd *cmd;
+	struct megasas_dcmd_frame *dcmd;
+	struct MR_BIOS_DATA *ci;
+	struct megasas_drive_order *drv_odr;
+	dma_addr_t ci_h = 0;
+
+	drv_odr = &instance->drive_order;
+	cmd = megasas_get_cmd(instance);
+
+	if (!cmd) {
+		dev_info(&instance->pdev->dev, "%s : "
+		    "Failed to get cmd\n", __func__);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	dcmd = &cmd->frame->dcmd;
+
+	ci = pci_alloc_consistent(instance->pdev,
+	    sizeof(struct MR_BIOS_DATA), &ci_h);
+
+	if (!ci) {
+		dev_info(&instance->pdev->dev, "%s : "
+		    "Failed to alloc mem for get_bios_data\n", __func__);
+		ret = -ENOMEM;
+		goto cmd_free;
+	}
+
+	memset(ci, 0, sizeof(struct MR_BIOS_DATA));
+	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+	dcmd->cmd = MFI_CMD_DCMD;
+	dcmd->cmd_status = 0xFF;
+	dcmd->sge_count = 1;
+	dcmd->flags = cpu_to_le16(MFI_FRAME_DIR_READ);
+	dcmd->timeout = 0;
+	dcmd->data_xfer_len = cpu_to_le32(sizeof(struct MR_BIOS_DATA));
+	dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_BIOS_DATA_GET);
+	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
+	dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct MR_BIOS_DATA));
+	dcmd->pad_0  = 0;
+
+	if (instance->ctrl_context && !instance->mask_interrupts)
+		ret = megasas_issue_blocked_cmd(instance, cmd, 60);
+	else
+		ret = megasas_issue_polled(instance, cmd);
+
+	switch (ret) {
+
+	case DCMD_SUCCESS:
+		/* check if boot drive is there */
+		if (le16_to_cpu(ci->bootTargetId) != MEGASAS_INVALID_TARGET_ID) {
+			drv_odr->boot_fw_tgt_id = le16_to_cpu(ci->bootTargetId);
+			drv_odr->boot_drive_is_pd = ci->bootDeviceIsPD;
+
+			if (drv_odr->boot_drive_is_pd) {
+				/* System PD Channel id set to 0 or 1 */
+				drv_odr->boot_drive_channel_id =
+					drv_odr->boot_fw_tgt_id/
+					MEGASAS_MAX_DEV_PER_CHANNEL;
+
+				/* System PD Target id set to 0 - 127 */
+				drv_odr->boot_drive_tgt_id =
+					drv_odr->boot_fw_tgt_id -
+					(drv_odr->boot_drive_channel_id *
+					MEGASAS_MAX_DEV_PER_CHANNEL);
+			} else {
+				/* LD Channel id set to 2 or 3 */
+				drv_odr->boot_drive_channel_id =
+					MEGASAS_MAX_PD_CHANNELS +
+					(drv_odr->boot_fw_tgt_id/
+					MEGASAS_MAX_DEV_PER_CHANNEL);
+
+				/* LD Target id set to 0 - 127 */
+				drv_odr->boot_drive_tgt_id =
+					drv_odr->boot_fw_tgt_id -
+					((drv_odr->boot_drive_channel_id -
+					MEGASAS_MAX_PD_CHANNELS) *
+					MEGASAS_MAX_DEV_PER_CHANNEL);
+			}
+		}
+		break;
+	case DCMD_TIMEOUT:
+		switch (dcmd_timeout_ocr_possible(instance)) {
+		case INITIATE_OCR:
+			cmd->flags |= DRV_DCMD_SKIP_REFIRE;
+			/*
+			 * DCMD failed from AEN path.
+			 * AEN path already hold reset_mutex to avoid PCI access
+			 * while OCR is in progress.
+			 */
+			megasas_reset_fusion(instance->host,
+			MFI_IO_TIMEOUT_OCR);
+			break;
+		case KILL_ADAPTER:
+			megaraid_sas_kill_hba(instance);
+			break;
+		case IGNORE_TIMEOUT:
+			dev_info(&instance->pdev->dev, "Ignore DCMD timeout: %s %d \n",
+						__func__, __LINE__);
+			break;
+
+		}
+		break;
+	case DCMD_FAILED:
+		dev_info(&instance->pdev->dev, "%s : "
+		    "Failed with return(%d)\n", __func__, ret);
+		break;
+	}
+
+	pci_free_consistent(instance->pdev, sizeof(struct MR_BIOS_DATA),
+	    ci, ci_h);
+
+cmd_free:
+	if (ret != DCMD_TIMEOUT)
+		megasas_return_cmd(instance, cmd);
+out:
+	return ret;
+}
+
+/**
  * megasas_get_controller_info -	Returns FW's controller structure
  * @instance:				Adapter soft state
  *
@@ -5653,6 +5786,194 @@ fail_set_dma_mask:
 }
 
 /**
+ * megasas_need_for_drive_ordering - Identify if the card needs drive ordering
+ * @instance:		Adapter structure
+ *
+ * This function looks at the Device ID & SubSystem Vendor ID and decides
+ * whether the drive ordering needs to be performed or not
+ *
+ * returns: 1 - Needs Ordering
+ *          0 - Does Not Need Ordering
+ */
+
+static u8
+megasas_need_for_drive_ordering(struct megasas_instance *instance)
+{
+	u8 ret;
+
+	if (((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+	    (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) &&
+	    (instance->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL))
+		ret = 1; /* Needs ordering */
+	else
+		ret = 0; /* Does NOT need ordering */
+
+	return ret;
+}
+
+/**
+ * megasas_expose_drives_to_os - expose drive to OS by scanning or adding
+ * @instance:		Adapter structure
+ *
+ * This function either invokes scsi_scan_host() to add drives for
+ * cards which doesn't need drive ordering or invokes scsi_add_device()
+ * which needs drive ordering.
+ */
+
+static void
+megasas_expose_drives_to_os(struct megasas_instance *instance)
+{
+	int i, j, ret = 0;
+	struct Scsi_Host *host;
+	struct megasas_drive_order *drv_odr;
+	u16 pd_index = 0;
+	u16 ld_index = 0;
+
+	host = instance->host;
+	drv_odr = &instance->drive_order;
+
+	drv_odr->needs_ordering =
+	    megasas_need_for_drive_ordering(instance);
+
+	/*
+	 * Check if drive ordering is needed, if not
+	 * invoke SCSI layer to scan.
+	 */
+	if (!drv_odr->needs_ordering) {
+		/* Trigger SCSI to scan our drives */
+		scsi_scan_host(host);
+		return;
+	}
+
+	/* Drive ordering is needed, obtain details on boot drive */
+	ret = megasas_get_bios_data(instance);
+	if (ret) {
+		dev_info(&instance->pdev->dev, "%s : Failure in updating "
+			"boot disk data-structure disk_order\n", __func__);
+	}
+
+	/* Check if boot drive is behind this controller, if so
+	 * add that first */
+	if (drv_odr->boot_fw_tgt_id != MEGASAS_INVALID_TARGET_ID) {
+		ret = scsi_add_device(host, drv_odr->boot_drive_channel_id,
+		    drv_odr->boot_drive_tgt_id, 0);
+		if (ret) {
+			dev_info(&instance->pdev->dev, "%s : Failure in "
+			    "scsi_add_device() for boot drive (%d)\n",
+			    __func__, ret);
+		}
+	}
+
+	/* Case 1: Boot drive is not there
+	 * Case 2: Boot drive is there & it is LD
+	 * (which is already exposed above) */
+	if ((drv_odr->boot_fw_tgt_id == MEGASAS_INVALID_TARGET_ID) ||
+	    ((drv_odr->boot_fw_tgt_id != MEGASAS_INVALID_TARGET_ID) &&
+	    (!drv_odr->boot_drive_is_pd))) {
+
+		/* Expose LDs */
+		for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
+			for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
+				ld_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL)
+				    + j;
+
+				/* Check if LD is present and it is not
+				 * the already added boot drive */
+				if ((instance->ld_ids[ld_index] != 0xff) &&
+				    (ld_index != drv_odr->boot_fw_tgt_id)) {
+					ret = scsi_add_device(host,
+					    MEGASAS_MAX_PD_CHANNELS + i, j, 0);
+					if (ret) {
+						dev_info(&instance->pdev->dev,
+						    "%s : Failure (%d) in "
+						    "scsi_add_device() for LD "
+						    "Channel:%d, Target:%d\n",
+						    __func__, ret,
+						    (MEGASAS_MAX_PD_CHANNELS
+						    + i), j);
+					}
+				}
+			}
+		}
+
+		/* Expose System PDs */
+		for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
+			for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
+				pd_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL)
+				    + j;
+				if (instance->pd_list[pd_index].driveState ==
+				    MR_PD_STATE_SYSTEM) {
+					ret = scsi_add_device(host, i, j, 0);
+					if (ret) {
+						dev_info(&instance->pdev->dev,
+						    "%s : Failure (%d) in "
+						    "scsi_add_device() for "
+						    "System PD Channel: %d, "
+						    "Target: %d\n",
+						    __func__, ret, i, j);
+					}
+				}
+			}
+		}
+		return;
+	}
+
+	/* Case 3: Boot drive is there & it is System PD
+	 * (which is already exposed above) */
+	if ((drv_odr->boot_fw_tgt_id != MEGASAS_INVALID_TARGET_ID) &&
+	    (drv_odr->boot_drive_is_pd)) {
+
+		/* Expose System PDs */
+		for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
+			for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
+				pd_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL)
+				    + j;
+
+				/* Check if System PD is present and
+				 * it is not the already added boot drive */
+				if ((instance->pd_list[pd_index].driveState ==
+				    MR_PD_STATE_SYSTEM) &&
+				    (pd_index != drv_odr->boot_fw_tgt_id)) {
+					ret = scsi_add_device(host, i, j, 0);
+					if (ret) {
+						dev_info(&instance->pdev->dev,
+						    "%s : Failure (%d) in "
+						    "scsi_add_device() for "
+						    "System PD Channel: %d, "
+						    "Target: %d\n",
+						    __func__, ret, i, j);
+					}
+				}
+			}
+		}
+
+		/* Expose LDs */
+		for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
+			for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
+				ld_index = (i * MEGASAS_MAX_DEV_PER_CHANNEL)
+				    + j;
+
+				/* Check if LD is present */
+				if (instance->ld_ids[ld_index] != 0xff) {
+					ret = scsi_add_device(host,
+					    MEGASAS_MAX_PD_CHANNELS + i, j, 0);
+					if (ret) {
+						dev_info(&instance->pdev->dev,
+						    "%s : Failure (%d) in "
+						    "scsi_add_device() for LD "
+						    "Channel:%d, Target:%d\n",
+						    __func__, ret,
+						    (MEGASAS_MAX_PD_CHANNELS
+						    + i), j);
+					}
+				}
+			}
+		}
+		return;
+	}
+}
+
+/**
  * megasas_probe_one -	PCI hotplug entry point
  * @pdev:		PCI device structure
  * @id:			PCI ids of supported hotplugged adapter
@@ -5788,6 +6109,8 @@ static int megasas_probe_one(struct pci_dev *pdev,
 	instance->issuepend_done = 1;
 	atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL);
 	instance->is_imr = 0;
+	 /* Setting boot_fw_tgt_id to none */
+	instance->drive_order.boot_fw_tgt_id = MEGASAS_INVALID_TARGET_ID;
 
 	instance->evt_detail = pci_alloc_consistent(pdev,
 						    sizeof(struct
@@ -5895,11 +6218,6 @@ static int megasas_probe_one(struct pci_dev *pdev,
 	if (megasas_io_attach(instance))
 		goto fail_io_attach;
 
-	instance->unload = 0;
-	/*
-	 * Trigger SCSI to scan our drives
-	 */
-	scsi_scan_host(host);
 
 	/*
 	 * Initiate AEN (Asynchronous Event Notification)
@@ -5909,6 +6227,11 @@ static int megasas_probe_one(struct pci_dev *pdev,
 		goto fail_start_aen;
 	}
 
+	instance->unload = 0;
+
+	/* Expose the System PD/LD to Operating System */
+	megasas_expose_drives_to_os(instance);
+
 	/* Get current SR-IOV LD/VF affiliation */
 	if (instance->requestorId)
 		megasas_get_ld_vf_affiliation(instance, 1);
