diff --git a/MAINTAINERS b/MAINTAINERS
index 20bdf22601c3f3c94720222e9c1fd363de512de9..b54288db77aa8dd957b30968698c5b42fcb570d8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2565,7 +2565,7 @@ F:	drivers/pci/controller/dwc/pcie-qcom.c
 F:	drivers/phy/qualcomm/
 F:	drivers/power/*/msm*
 F:	drivers/reset/reset-qcom-*
-F:	drivers/scsi/ufs/ufs-qcom*
+F:	drivers/ufs/host/ufs-qcom*
 F:	drivers/spi/spi-geni-qcom.c
 F:	drivers/spi/spi-qcom-qspi.c
 F:	drivers/spi/spi-qup.c
@@ -17755,6 +17755,7 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
 F:	Documentation/devicetree/bindings/scsi/
 F:	drivers/scsi/
+F:	drivers/ufs/
 F:	include/scsi/
 
 SCSI TAPE DRIVER
@@ -20414,24 +20415,25 @@ F:	include/uapi/linux/cdrom.h
 UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER
 R:	Alim Akhtar <alim.akhtar@samsung.com>
 R:	Avri Altman <avri.altman@wdc.com>
+R:	Bart Van Assche <bvanassche@acm.org>
 L:	linux-scsi@vger.kernel.org
 S:	Supported
 F:	Documentation/devicetree/bindings/ufs/
 F:	Documentation/scsi/ufs.rst
-F:	drivers/scsi/ufs/
+F:	drivers/ufs/core/
 
 UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER DWC HOOKS
 M:	Pedro Sousa <pedrom.sousa@synopsys.com>
 L:	linux-scsi@vger.kernel.org
 S:	Supported
-F:	drivers/scsi/ufs/*dwc*
+F:	drivers/ufs/host/*dwc*
 
 UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER MEDIATEK HOOKS
 M:	Stanley Chu <stanley.chu@mediatek.com>
 L:	linux-scsi@vger.kernel.org
 L:	linux-mediatek@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
-F:	drivers/scsi/ufs/ufs-mediatek*
+F:	drivers/ufs/host/ufs-mediatek*
 
 UNSORTED BLOCK IMAGES (UBI)
 M:	Richard Weinberger <richard@nod.at>
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 38af943294cafa3fd4398fe6fdf35bdff63407f7..b6a172d32a7d378bc398ddeed819a0b8688a9abc 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -107,6 +107,8 @@ source "drivers/usb/Kconfig"
 
 source "drivers/mmc/Kconfig"
 
+source "drivers/ufs/Kconfig"
+
 source "drivers/memstick/Kconfig"
 
 source "drivers/leds/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 091627d6099100665dc12a4750aac50d2ac6a0cc..9a30842b22c5411bf00245761f472da9c13370b7 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -128,6 +128,7 @@ obj-$(CONFIG_PM_OPP)		+= opp/
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle/
 obj-y				+= mmc/
+obj-y				+= ufs/
 obj-$(CONFIG_MEMSTICK)		+= memstick/
 obj-$(CONFIG_NEW_LEDS)		+= leds/
 obj-$(CONFIG_INFINIBAND)	+= infiniband/
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index 7ae72c7a211b975ecba3009cb337211dbacbee5d..3c778bb0c2944725ad321c5b5a33df33d516eabf 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -1899,6 +1899,24 @@ nvme_fc_ctrl_ioerr_work(struct work_struct *work)
 	nvme_fc_error_recovery(ctrl, "transport detected io error");
 }
 
+/*
+ * nvme_fc_io_getuuid - Routine called to get the appid field
+ * associated with request by the lldd
+ * @req:IO request from nvme fc to driver
+ * Returns: UUID if there is an appid associated with VM or
+ * NULL if the user/libvirt has not set the appid to VM
+ */
+char *nvme_fc_io_getuuid(struct nvmefc_fcp_req *req)
+{
+	struct nvme_fc_fcp_op *op = fcp_req_to_fcp_op(req);
+	struct request *rq = op->rq;
+
+	if (!IS_ENABLED(CONFIG_BLK_CGROUP_FC_APPID) || !rq->bio)
+		return NULL;
+	return blkcg_get_fc_appid(rq->bio);
+}
+EXPORT_SYMBOL_GPL(nvme_fc_io_getuuid);
+
 static void
 nvme_fc_fcpio_done(struct nvmefc_fcp_req *req)
 {
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 6e3a04107bb657a83e5dc31758b6b343b3b817df..a9fe5152addd3a6703cee5b480a4d698d1ebb565 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -500,7 +500,6 @@ source "drivers/scsi/megaraid/Kconfig.megaraid"
 source "drivers/scsi/mpt3sas/Kconfig"
 source "drivers/scsi/mpi3mr/Kconfig"
 source "drivers/scsi/smartpqi/Kconfig"
-source "drivers/scsi/ufs/Kconfig"
 
 config SCSI_HPTIOP
 	tristate "HighPoint RocketRAID 3xxx/4xxx Controller support"
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 19814c26c9084bdf086ef363e07d9b0d57a4ba71..2ad3bc0525316ad7cce702724b6d4f3321856596 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -101,7 +101,6 @@ obj-$(CONFIG_MEGARAID_NEWGEN)	+= megaraid/
 obj-$(CONFIG_MEGARAID_SAS)	+= megaraid/
 obj-$(CONFIG_SCSI_MPT3SAS)	+= mpt3sas/
 obj-$(CONFIG_SCSI_MPI3MR)	+= mpi3mr/
-obj-$(CONFIG_SCSI_UFSHCD)	+= ufs/
 obj-$(CONFIG_SCSI_ACARD)	+= atp870u.o
 obj-$(CONFIG_SCSI_SUNESP)	+= esp_scsi.o	sun_esp.o
 obj-$(CONFIG_SCSI_INITIO)	+= initio.o
diff --git a/drivers/scsi/esas2r/esas2r_flash.c b/drivers/scsi/esas2r/esas2r_flash.c
index 429d64299fe94645736ba1bda08904c4128f5598..f910e2553fbbedc17e51534798c062d02e765281 100644
--- a/drivers/scsi/esas2r/esas2r_flash.c
+++ b/drivers/scsi/esas2r/esas2r_flash.c
@@ -232,7 +232,7 @@ static bool load_image(struct esas2r_adapter *a, struct esas2r_request *rq)
 	 */
 	rq->req_stat = RS_PENDING;
 	if (test_bit(AF_DEGRADED_MODE, &a->flags))
-		/* not suppported for now */;
+		/* not supported for now */;
 	else
 		build_flash_msg(a, rq);
 
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index ac17e3a35d2c5ec6bdf06fa29a33016230e876fd..6370cdbfba08c407f90503b54905bc1b7454f192 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -2182,7 +2182,7 @@ static enum sci_status atapi_data_tc_completion_handler(struct isci_request *ire
 	case (SCU_TASK_DONE_UNEXP_FIS << SCU_COMPLETION_TL_STATUS_SHIFT): {
 		u16 len = sci_req_tx_bytes(ireq);
 
-		/* likely non-error data underrrun, workaround missing
+		/* likely non-error data underrun, workaround missing
 		 * d2h frame from the controller
 		 */
 		if (d2h->fis_type != FIS_REGD2H) {
diff --git a/drivers/scsi/lpfc/Makefile b/drivers/scsi/lpfc/Makefile
index 092a971d066b1e3cb84c84611be7d420853440d7..bbd1faf41e806569a58b42c9d2126cb551886b9a 100644
--- a/drivers/scsi/lpfc/Makefile
+++ b/drivers/scsi/lpfc/Makefile
@@ -33,4 +33,4 @@ obj-$(CONFIG_SCSI_LPFC) := lpfc.o
 lpfc-objs := lpfc_mem.o lpfc_sli.o lpfc_ct.o lpfc_els.o \
 	lpfc_hbadisc.o	lpfc_init.o lpfc_mbox.o lpfc_nportdisc.o   \
 	lpfc_scsi.o lpfc_attr.o lpfc_vport.o lpfc_debugfs.o lpfc_bsg.o \
-	lpfc_nvme.o lpfc_nvmet.o
+	lpfc_nvme.o lpfc_nvmet.o lpfc_vmid.o
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index b0775be31d5c8d4954bd3633eb069aaf5abda579..b1be0dd0337a52bf5e4517ca76812743a10705fa 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -671,6 +671,9 @@ int lpfc_vmid_cmd(struct lpfc_vport *vport,
 int lpfc_vmid_hash_fn(const char *vmid, int len);
 struct lpfc_vmid *lpfc_get_vmid_from_hashtable(struct lpfc_vport *vport,
 					      uint32_t hash, uint8_t *buf);
+int lpfc_vmid_get_appid(struct lpfc_vport *vport, char *uuid,
+			enum dma_data_direction iodir,
+			union lpfc_vmid_io_tag *tag);
 void lpfc_vmid_vport_cleanup(struct lpfc_vport *vport);
 int lpfc_issue_els_qfpa(struct lpfc_vport *vport);
 
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 748c5321998666038a5d87aa24712e7a06b3c0ce..7b8cf678abb57a61e0c378bbc682ed9cf3a4f064 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1736,6 +1736,28 @@ struct lpfc_fdmi_reg_portattr {
 #define PCI_DEVICE_ID_TOMCAT        0x0714
 #define PCI_DEVICE_ID_SKYHAWK       0x0724
 #define PCI_DEVICE_ID_SKYHAWK_VF    0x072c
+#define PCI_VENDOR_ID_ATTO          0x117c
+#define PCI_DEVICE_ID_CLRY_16XE     0x0064
+#define PCI_DEVICE_ID_CLRY_161E     0x0063
+#define PCI_DEVICE_ID_CLRY_162E     0x0064
+#define PCI_DEVICE_ID_CLRY_164E     0x0065
+#define PCI_DEVICE_ID_CLRY_16XP     0x0094
+#define PCI_DEVICE_ID_CLRY_161P     0x00a0
+#define PCI_DEVICE_ID_CLRY_162P     0x0094
+#define PCI_DEVICE_ID_CLRY_164P     0x00a1
+#define PCI_DEVICE_ID_CLRY_32XE     0x0094
+#define PCI_DEVICE_ID_CLRY_321E     0x00a2
+#define PCI_DEVICE_ID_CLRY_322E     0x00a3
+#define PCI_DEVICE_ID_CLRY_324E     0x00ac
+#define PCI_DEVICE_ID_CLRY_32XP     0x00bb
+#define PCI_DEVICE_ID_CLRY_321P     0x00bc
+#define PCI_DEVICE_ID_CLRY_322P     0x00bd
+#define PCI_DEVICE_ID_CLRY_324P     0x00be
+#define PCI_DEVICE_ID_TLFC_2        0x0064
+#define PCI_DEVICE_ID_TLFC_2XX2     0x4064
+#define PCI_DEVICE_ID_TLFC_3        0x0094
+#define PCI_DEVICE_ID_TLFC_3162     0x40a6
+#define PCI_DEVICE_ID_TLFC_3322     0x40a7
 
 #define JEDEC_ID_ADDRESS            0x0080001c
 #define FIREFLY_JEDEC_ID            0x1ACC
diff --git a/drivers/scsi/lpfc/lpfc_ids.h b/drivers/scsi/lpfc/lpfc_ids.h
index 6a90e6e53d09007e8c423028c41ea652c96debfa..a1b9be2455600787b6fe03323ba04331f6ef175b 100644
--- a/drivers/scsi/lpfc/lpfc_ids.h
+++ b/drivers/scsi/lpfc/lpfc_ids.h
@@ -124,5 +124,35 @@ const struct pci_device_id lpfc_id_table[] = {
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK_VF,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_16XE,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_161E, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_16XE,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_162E, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_16XE,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_164E, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_16XP,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_161P, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_16XP,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_162P, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_16XP,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_164P, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_32XE,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_321E, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_32XE,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_322E, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_32XE,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_324E, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_32XP,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_321P, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_32XP,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_322P, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_32XP,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_CLRY_324P, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_TLFC_2,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_TLFC_2XX2, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_TLFC_3,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_TLFC_3162, },
+	{PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_TLFC_3,
+		PCI_VENDOR_ID_ATTO, PCI_DEVICE_ID_TLFC_3322, },
 	{ 0 }
 };
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 2bffaa681fcc91410e62a900faed0ab4df7e40b6..93b94c64518dffd79caac777b14d0b66f46d2e74 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2414,6 +2414,90 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
 	return(1);
 }
 
+/**
+ * lpfc_get_atto_model_desc - Retrieve ATTO HBA device model name and description
+ * @phba: pointer to lpfc hba data structure.
+ * @mdp: pointer to the data structure to hold the derived model name.
+ * @descp: pointer to the data structure to hold the derived description.
+ *
+ * This routine retrieves HBA's description based on its registered PCI device
+ * ID. The @descp passed into this function points to an array of 256 chars. It
+ * shall be returned with the model name, maximum speed, and the host bus type.
+ * The @mdp passed into this function points to an array of 80 chars. When the
+ * function returns, the @mdp will be filled with the model name.
+ **/
+static void
+lpfc_get_atto_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
+{
+	uint16_t sub_dev_id = phba->pcidev->subsystem_device;
+	char *model = "<Unknown>";
+	int tbolt = 0;
+
+	switch (sub_dev_id) {
+	case PCI_DEVICE_ID_CLRY_161E:
+		model = "161E";
+		break;
+	case PCI_DEVICE_ID_CLRY_162E:
+		model = "162E";
+		break;
+	case PCI_DEVICE_ID_CLRY_164E:
+		model = "164E";
+		break;
+	case PCI_DEVICE_ID_CLRY_161P:
+		model = "161P";
+		break;
+	case PCI_DEVICE_ID_CLRY_162P:
+		model = "162P";
+		break;
+	case PCI_DEVICE_ID_CLRY_164P:
+		model = "164P";
+		break;
+	case PCI_DEVICE_ID_CLRY_321E:
+		model = "321E";
+		break;
+	case PCI_DEVICE_ID_CLRY_322E:
+		model = "322E";
+		break;
+	case PCI_DEVICE_ID_CLRY_324E:
+		model = "324E";
+		break;
+	case PCI_DEVICE_ID_CLRY_321P:
+		model = "321P";
+		break;
+	case PCI_DEVICE_ID_CLRY_322P:
+		model = "322P";
+		break;
+	case PCI_DEVICE_ID_CLRY_324P:
+		model = "324P";
+		break;
+	case PCI_DEVICE_ID_TLFC_2XX2:
+		model = "2XX2";
+		tbolt = 1;
+		break;
+	case PCI_DEVICE_ID_TLFC_3162:
+		model = "3162";
+		tbolt = 1;
+		break;
+	case PCI_DEVICE_ID_TLFC_3322:
+		model = "3322";
+		tbolt = 1;
+		break;
+	default:
+		model = "Unknown";
+		break;
+	}
+
+	if (mdp && mdp[0] == '\0')
+		snprintf(mdp, 79, "%s", model);
+
+	if (descp && descp[0] == '\0')
+		snprintf(descp, 255,
+			 "ATTO %s%s, Fibre Channel Adapter Initiator, Port %s",
+			 (tbolt) ? "ThunderLink FC " : "Celerity FC-",
+			 model,
+			 phba->Port);
+}
+
 /**
  * lpfc_get_hba_model_desc - Retrieve HBA device model name and description
  * @phba: pointer to lpfc hba data structure.
@@ -2444,6 +2528,11 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
 		&& descp && descp[0] != '\0')
 		return;
 
+	if (phba->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
+		lpfc_get_atto_model_desc(phba, mdp, descp);
+		return;
+	}
+
 	if (phba->lmt & LMT_64Gb)
 		max_speed = 64;
 	else if (phba->lmt & LMT_32Gb)
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 5385f4de5523879b62daef0b94788fb730b906ad..335e906339331580042c787f12786903d83be344 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -1279,6 +1279,19 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport,
 
 	/* Words 13 14 15 are for PBDE support */
 
+	/* add the VMID tags as per switch response */
+	if (unlikely(lpfc_ncmd->cur_iocbq.cmd_flag & LPFC_IO_VMID)) {
+		if (phba->pport->vmid_priority_tagging) {
+			bf_set(wqe_ccpe, &wqe->fcp_iwrite.wqe_com, 1);
+			bf_set(wqe_ccp, &wqe->fcp_iwrite.wqe_com,
+			       lpfc_ncmd->cur_iocbq.vmid_tag.cs_ctl_vmid);
+		} else {
+			bf_set(wqe_appid, &wqe->fcp_iwrite.wqe_com, 1);
+			bf_set(wqe_wqes, &wqe->fcp_iwrite.wqe_com, 1);
+			wqe->words[31] = lpfc_ncmd->cur_iocbq.vmid_tag.app_id;
+		}
+	}
+
 	pwqeq->vport = vport;
 	return 0;
 }
@@ -1504,6 +1517,11 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
 	struct lpfc_nvme_fcpreq_priv *freqpriv;
 	struct nvme_common_command *sqe;
 	uint64_t start = 0;
+#if (IS_ENABLED(CONFIG_NVME_FC))
+	u8 *uuid = NULL;
+	int err;
+	enum dma_data_direction iodir;
+#endif
 
 	/* Validate pointers. LLDD fault handling with transport does
 	 * have timing races.
@@ -1662,6 +1680,33 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport,
 	lpfc_ncmd->ndlp = ndlp;
 	lpfc_ncmd->qidx = lpfc_queue_info->qidx;
 
+#if (IS_ENABLED(CONFIG_NVME_FC))
+	/* check the necessary and sufficient condition to support VMID */
+	if (lpfc_is_vmid_enabled(phba) &&
+	    (ndlp->vmid_support ||
+	     phba->pport->vmid_priority_tagging ==
+	     LPFC_VMID_PRIO_TAG_ALL_TARGETS)) {
+		/* is the I/O generated by a VM, get the associated virtual */
+		/* entity id */
+		uuid = nvme_fc_io_getuuid(pnvme_fcreq);
+
+		if (uuid) {
+			if (pnvme_fcreq->io_dir == NVMEFC_FCP_WRITE)
+				iodir = DMA_TO_DEVICE;
+			else if (pnvme_fcreq->io_dir == NVMEFC_FCP_READ)
+				iodir = DMA_FROM_DEVICE;
+			else
+				iodir = DMA_NONE;
+
+			err = lpfc_vmid_get_appid(vport, uuid, iodir,
+					(union lpfc_vmid_io_tag *)
+						&lpfc_ncmd->cur_iocbq.vmid_tag);
+			if (!err)
+				lpfc_ncmd->cur_iocbq.cmd_flag |= LPFC_IO_VMID;
+		}
+	}
+#endif
+
 	/*
 	 * Issue the IO on the WQ indicated by index in the hw_queue_handle.
 	 * This identfier was create in our hardware queue create callback
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 3b8afa9d305690267b6ae20615340794d95aa91e..d439682032489f630675390674bb1224dc7ede28 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -87,14 +87,6 @@ static void
 lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_io_buf *psb);
 static int
 lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc);
-static void
-lpfc_put_vmid_in_hashtable(struct lpfc_vport *vport, u32 hash,
-			   struct lpfc_vmid *vmp);
-static void lpfc_vmid_update_entry(struct lpfc_vport *vport, struct scsi_cmnd
-				   *cmd, struct lpfc_vmid *vmp,
-				   union lpfc_vmid_io_tag *tag);
-static void lpfc_vmid_assign_cs_ctl(struct lpfc_vport *vport,
-				    struct lpfc_vmid *vmid);
 
 /**
  * lpfc_sli4_set_rsp_sgl_last - Set the last bit in the response sge.
@@ -5270,254 +5262,6 @@ void lpfc_poll_timeout(struct timer_list *t)
 	}
 }
 
-/*
- * lpfc_get_vmid_from_hashtable - search the UUID in the hash table
- * @vport: The virtual port for which this call is being executed.
- * @hash: calculated hash value
- * @buf: uuid associated with the VE
- * Return the VMID entry associated with the UUID
- * Make sure to acquire the appropriate lock before invoking this routine.
- */
-struct lpfc_vmid *lpfc_get_vmid_from_hashtable(struct lpfc_vport *vport,
-					      u32 hash, u8 *buf)
-{
-	struct lpfc_vmid *vmp;
-
-	hash_for_each_possible(vport->hash_table, vmp, hnode, hash) {
-		if (memcmp(&vmp->host_vmid[0], buf, 16) == 0)
-			return vmp;
-	}
-	return NULL;
-}
-
-/*
- * lpfc_put_vmid_in_hashtable - put the VMID in the hash table
- * @vport: The virtual port for which this call is being executed.
- * @hash - calculated hash value
- * @vmp: Pointer to a VMID entry representing a VM sending I/O
- *
- * This routine will insert the newly acquired VMID entity in the hash table.
- * Make sure to acquire the appropriate lock before invoking this routine.
- */
-static void
-lpfc_put_vmid_in_hashtable(struct lpfc_vport *vport, u32 hash,
-			   struct lpfc_vmid *vmp)
-{
-	hash_add(vport->hash_table, &vmp->hnode, hash);
-}
-
-/*
- * lpfc_vmid_hash_fn - create a hash value of the UUID
- * @vmid: uuid associated with the VE
- * @len: length of the VMID string
- * Returns the calculated hash value
- */
-int lpfc_vmid_hash_fn(const char *vmid, int len)
-{
-	int c;
-	int hash = 0;
-
-	if (len == 0)
-		return 0;
-	while (len--) {
-		c = *vmid++;
-		if (c >= 'A' && c <= 'Z')
-			c += 'a' - 'A';
-
-		hash = (hash + (c << LPFC_VMID_HASH_SHIFT) +
-			(c >> LPFC_VMID_HASH_SHIFT)) * 19;
-	}
-
-	return hash & LPFC_VMID_HASH_MASK;
-}
-
-/*
- * lpfc_vmid_update_entry - update the vmid entry in the hash table
- * @vport: The virtual port for which this call is being executed.
- * @cmd: address of scsi cmd descriptor
- * @vmp: Pointer to a VMID entry representing a VM sending I/O
- * @tag: VMID tag
- */
-static void lpfc_vmid_update_entry(struct lpfc_vport *vport, struct scsi_cmnd
-				   *cmd, struct lpfc_vmid *vmp,
-				   union lpfc_vmid_io_tag *tag)
-{
-	u64 *lta;
-
-	if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO)
-		tag->cs_ctl_vmid = vmp->un.cs_ctl_vmid;
-	else if (vport->phba->cfg_vmid_app_header)
-		tag->app_id = vmp->un.app_id;
-
-	if (cmd->sc_data_direction == DMA_TO_DEVICE)
-		vmp->io_wr_cnt++;
-	else
-		vmp->io_rd_cnt++;
-
-	/* update the last access timestamp in the table */
-	lta = per_cpu_ptr(vmp->last_io_time, raw_smp_processor_id());
-	*lta = jiffies;
-}
-
-static void lpfc_vmid_assign_cs_ctl(struct lpfc_vport *vport,
-				    struct lpfc_vmid *vmid)
-{
-	u32 hash;
-	struct lpfc_vmid *pvmid;
-
-	if (vport->port_type == LPFC_PHYSICAL_PORT) {
-		vmid->un.cs_ctl_vmid = lpfc_vmid_get_cs_ctl(vport);
-	} else {
-		hash = lpfc_vmid_hash_fn(vmid->host_vmid, vmid->vmid_len);
-		pvmid =
-		    lpfc_get_vmid_from_hashtable(vport->phba->pport, hash,
-						vmid->host_vmid);
-		if (pvmid)
-			vmid->un.cs_ctl_vmid = pvmid->un.cs_ctl_vmid;
-		else
-			vmid->un.cs_ctl_vmid = lpfc_vmid_get_cs_ctl(vport);
-	}
-}
-
-/*
- * lpfc_vmid_get_appid - get the VMID associated with the UUID
- * @vport: The virtual port for which this call is being executed.
- * @uuid: UUID associated with the VE
- * @cmd: address of scsi_cmd descriptor
- * @tag: VMID tag
- * Returns status of the function
- */
-static int lpfc_vmid_get_appid(struct lpfc_vport *vport, char *uuid, struct
-			       scsi_cmnd * cmd, union lpfc_vmid_io_tag *tag)
-{
-	struct lpfc_vmid *vmp = NULL;
-	int hash, len, rc = -EPERM, i;
-
-	/* check if QFPA is complete */
-	if (lpfc_vmid_is_type_priority_tag(vport) &&
-	    !(vport->vmid_flag & LPFC_VMID_QFPA_CMPL) &&
-	    (vport->vmid_flag & LPFC_VMID_ISSUE_QFPA)) {
-		vport->work_port_events |= WORKER_CHECK_VMID_ISSUE_QFPA;
-		return -EAGAIN;
-	}
-
-	/* search if the UUID has already been mapped to the VMID */
-	len = strlen(uuid);
-	hash = lpfc_vmid_hash_fn(uuid, len);
-
-	/* search for the VMID in the table */
-	read_lock(&vport->vmid_lock);
-	vmp = lpfc_get_vmid_from_hashtable(vport, hash, uuid);
-
-	/* if found, check if its already registered  */
-	if (vmp  && vmp->flag & LPFC_VMID_REGISTERED) {
-		read_unlock(&vport->vmid_lock);
-		lpfc_vmid_update_entry(vport, cmd, vmp, tag);
-		rc = 0;
-	} else if (vmp && (vmp->flag & LPFC_VMID_REQ_REGISTER ||
-			   vmp->flag & LPFC_VMID_DE_REGISTER)) {
-		/* else if register or dereg request has already been sent */
-		/* Hence VMID tag will not be added for this I/O */
-		read_unlock(&vport->vmid_lock);
-		rc = -EBUSY;
-	} else {
-		/* The VMID was not found in the hashtable. At this point, */
-		/* drop the read lock first before proceeding further */
-		read_unlock(&vport->vmid_lock);
-		/* start the process to obtain one as per the */
-		/* type of the VMID indicated */
-		write_lock(&vport->vmid_lock);
-		vmp = lpfc_get_vmid_from_hashtable(vport, hash, uuid);
-
-		/* while the read lock was released, in case the entry was */
-		/* added by other context or is in process of being added */
-		if (vmp && vmp->flag & LPFC_VMID_REGISTERED) {
-			lpfc_vmid_update_entry(vport, cmd, vmp, tag);
-			write_unlock(&vport->vmid_lock);
-			return 0;
-		} else if (vmp && vmp->flag & LPFC_VMID_REQ_REGISTER) {
-			write_unlock(&vport->vmid_lock);
-			return -EBUSY;
-		}
-
-		/* else search and allocate a free slot in the hash table */
-		if (vport->cur_vmid_cnt < vport->max_vmid) {
-			for (i = 0; i < vport->max_vmid; i++) {
-				vmp = vport->vmid + i;
-				if (vmp->flag == LPFC_VMID_SLOT_FREE)
-					break;
-			}
-			if (i == vport->max_vmid)
-				vmp = NULL;
-		} else {
-			vmp = NULL;
-		}
-
-		if (!vmp) {
-			write_unlock(&vport->vmid_lock);
-			return -ENOMEM;
-		}
-
-		/* Add the vmid and register */
-		lpfc_put_vmid_in_hashtable(vport, hash, vmp);
-		vmp->vmid_len = len;
-		memcpy(vmp->host_vmid, uuid, vmp->vmid_len);
-		vmp->io_rd_cnt = 0;
-		vmp->io_wr_cnt = 0;
-		vmp->flag = LPFC_VMID_SLOT_USED;
-
-		vmp->delete_inactive =
-			vport->vmid_inactivity_timeout ? 1 : 0;
-
-		/* if type priority tag, get next available VMID */
-		if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO)
-			lpfc_vmid_assign_cs_ctl(vport, vmp);
-
-		/* allocate the per cpu variable for holding */
-		/* the last access time stamp only if VMID is enabled */
-		if (!vmp->last_io_time)
-			vmp->last_io_time = __alloc_percpu(sizeof(u64),
-							   __alignof__(struct
-							   lpfc_vmid));
-		if (!vmp->last_io_time) {
-			hash_del(&vmp->hnode);
-			vmp->flag = LPFC_VMID_SLOT_FREE;
-			write_unlock(&vport->vmid_lock);
-			return -EIO;
-		}
-
-		write_unlock(&vport->vmid_lock);
-
-		/* complete transaction with switch */
-		if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO)
-			rc = lpfc_vmid_uvem(vport, vmp, true);
-		else if (vport->phba->cfg_vmid_app_header)
-			rc = lpfc_vmid_cmd(vport, SLI_CTAS_RAPP_IDENT, vmp);
-		if (!rc) {
-			write_lock(&vport->vmid_lock);
-			vport->cur_vmid_cnt++;
-			vmp->flag |= LPFC_VMID_REQ_REGISTER;
-			write_unlock(&vport->vmid_lock);
-		} else {
-			write_lock(&vport->vmid_lock);
-			hash_del(&vmp->hnode);
-			vmp->flag = LPFC_VMID_SLOT_FREE;
-			free_percpu(vmp->last_io_time);
-			write_unlock(&vport->vmid_lock);
-			return -EIO;
-		}
-
-		/* finally, enable the idle timer once */
-		if (!(vport->phba->pport->vmid_flag & LPFC_VMID_TIMER_ENBLD)) {
-			mod_timer(&vport->phba->inactive_vmid_poll,
-				  jiffies +
-				  msecs_to_jiffies(1000 * LPFC_VMID_TIMER));
-			vport->phba->pport->vmid_flag |= LPFC_VMID_TIMER_ENBLD;
-		}
-	}
-	return rc;
-}
-
 /*
  * lpfc_is_command_vm_io - get the UUID from blk cgroup
  * @cmd: Pointer to scsi_cmnd data structure
@@ -5704,9 +5448,10 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd)
 		uuid = lpfc_is_command_vm_io(cmnd);
 
 		if (uuid) {
-			err = lpfc_vmid_get_appid(vport, uuid, cmnd,
-				(union lpfc_vmid_io_tag *)
-					&cur_iocbq->vmid_tag);
+			err = lpfc_vmid_get_appid(vport, uuid,
+					cmnd->sc_data_direction,
+					(union lpfc_vmid_io_tag *)
+						&cur_iocbq->vmid_tag);
 			if (!err)
 				cur_iocbq->cmd_flag |= LPFC_IO_VMID;
 		}
diff --git a/drivers/scsi/lpfc/lpfc_vmid.c b/drivers/scsi/lpfc/lpfc_vmid.c
new file mode 100644
index 0000000000000000000000000000000000000000..f64ced04b912582998d5cda5bab361f0f6fb271b
--- /dev/null
+++ b/drivers/scsi/lpfc/lpfc_vmid.c
@@ -0,0 +1,288 @@
+/*******************************************************************
+ * This file is part of the Emulex Linux Device Driver for         *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term *
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.     *
+ * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
+ * www.broadcom.com                                                *
+ * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
+ *                                                                 *
+ * This program is free software; you can redistribute it and/or   *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
+ *******************************************************************/
+
+#include <linux/interrupt.h>
+#include <linux/dma-direction.h>
+
+#include <scsi/scsi_transport_fc.h>
+
+#include "lpfc_hw4.h"
+#include "lpfc_hw.h"
+#include "lpfc_sli.h"
+#include "lpfc_sli4.h"
+#include "lpfc_nl.h"
+#include "lpfc_disc.h"
+#include "lpfc.h"
+#include "lpfc_crtn.h"
+
+
+/*
+ * lpfc_get_vmid_from_hashtable - search the UUID in the hash table
+ * @vport: The virtual port for which this call is being executed.
+ * @hash: calculated hash value
+ * @buf: uuid associated with the VE
+ * Return the VMID entry associated with the UUID
+ * Make sure to acquire the appropriate lock before invoking this routine.
+ */
+struct lpfc_vmid *lpfc_get_vmid_from_hashtable(struct lpfc_vport *vport,
+					       u32 hash, u8 *buf)
+{
+	struct lpfc_vmid *vmp;
+
+	hash_for_each_possible(vport->hash_table, vmp, hnode, hash) {
+		if (memcmp(&vmp->host_vmid[0], buf, 16) == 0)
+			return vmp;
+	}
+	return NULL;
+}
+
+/*
+ * lpfc_put_vmid_in_hashtable - put the VMID in the hash table
+ * @vport: The virtual port for which this call is being executed.
+ * @hash - calculated hash value
+ * @vmp: Pointer to a VMID entry representing a VM sending I/O
+ *
+ * This routine will insert the newly acquired VMID entity in the hash table.
+ * Make sure to acquire the appropriate lock before invoking this routine.
+ */
+static void
+lpfc_put_vmid_in_hashtable(struct lpfc_vport *vport, u32 hash,
+			   struct lpfc_vmid *vmp)
+{
+	hash_add(vport->hash_table, &vmp->hnode, hash);
+}
+
+/*
+ * lpfc_vmid_hash_fn - create a hash value of the UUID
+ * @vmid: uuid associated with the VE
+ * @len: length of the VMID string
+ * Returns the calculated hash value
+ */
+int lpfc_vmid_hash_fn(const char *vmid, int len)
+{
+	int c;
+	int hash = 0;
+
+	if (len == 0)
+		return 0;
+	while (len--) {
+		c = *vmid++;
+		if (c >= 'A' && c <= 'Z')
+			c += 'a' - 'A';
+
+		hash = (hash + (c << LPFC_VMID_HASH_SHIFT) +
+			(c >> LPFC_VMID_HASH_SHIFT)) * 19;
+	}
+
+	return hash & LPFC_VMID_HASH_MASK;
+}
+
+/*
+ * lpfc_vmid_update_entry - update the vmid entry in the hash table
+ * @vport: The virtual port for which this call is being executed.
+ * @iodir: io direction
+ * @vmp: Pointer to a VMID entry representing a VM sending I/O
+ * @tag: VMID tag
+ */
+static void lpfc_vmid_update_entry(struct lpfc_vport *vport,
+				   enum dma_data_direction iodir,
+				   struct lpfc_vmid *vmp,
+				   union lpfc_vmid_io_tag *tag)
+{
+	u64 *lta;
+
+	if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO)
+		tag->cs_ctl_vmid = vmp->un.cs_ctl_vmid;
+	else if (vport->phba->cfg_vmid_app_header)
+		tag->app_id = vmp->un.app_id;
+
+	if (iodir == DMA_TO_DEVICE)
+		vmp->io_wr_cnt++;
+	else if (iodir == DMA_FROM_DEVICE)
+		vmp->io_rd_cnt++;
+
+	/* update the last access timestamp in the table */
+	lta = per_cpu_ptr(vmp->last_io_time, raw_smp_processor_id());
+	*lta = jiffies;
+}
+
+static void lpfc_vmid_assign_cs_ctl(struct lpfc_vport *vport,
+				    struct lpfc_vmid *vmid)
+{
+	u32 hash;
+	struct lpfc_vmid *pvmid;
+
+	if (vport->port_type == LPFC_PHYSICAL_PORT) {
+		vmid->un.cs_ctl_vmid = lpfc_vmid_get_cs_ctl(vport);
+	} else {
+		hash = lpfc_vmid_hash_fn(vmid->host_vmid, vmid->vmid_len);
+		pvmid =
+		    lpfc_get_vmid_from_hashtable(vport->phba->pport, hash,
+						 vmid->host_vmid);
+		if (pvmid)
+			vmid->un.cs_ctl_vmid = pvmid->un.cs_ctl_vmid;
+		else
+			vmid->un.cs_ctl_vmid = lpfc_vmid_get_cs_ctl(vport);
+	}
+}
+
+/*
+ * lpfc_vmid_get_appid - get the VMID associated with the UUID
+ * @vport: The virtual port for which this call is being executed.
+ * @uuid: UUID associated with the VE
+ * @cmd: address of scsi_cmd descriptor
+ * @iodir: io direction
+ * @tag: VMID tag
+ * Returns status of the function
+ */
+int lpfc_vmid_get_appid(struct lpfc_vport *vport, char *uuid,
+			enum dma_data_direction iodir,
+			union lpfc_vmid_io_tag *tag)
+{
+	struct lpfc_vmid *vmp = NULL;
+	int hash, len, rc = -EPERM, i;
+
+	/* check if QFPA is complete */
+	if (lpfc_vmid_is_type_priority_tag(vport) &&
+	    !(vport->vmid_flag & LPFC_VMID_QFPA_CMPL) &&
+	    (vport->vmid_flag & LPFC_VMID_ISSUE_QFPA)) {
+		vport->work_port_events |= WORKER_CHECK_VMID_ISSUE_QFPA;
+		return -EAGAIN;
+	}
+
+	/* search if the UUID has already been mapped to the VMID */
+	len = strlen(uuid);
+	hash = lpfc_vmid_hash_fn(uuid, len);
+
+	/* search for the VMID in the table */
+	read_lock(&vport->vmid_lock);
+	vmp = lpfc_get_vmid_from_hashtable(vport, hash, uuid);
+
+	/* if found, check if its already registered  */
+	if (vmp  && vmp->flag & LPFC_VMID_REGISTERED) {
+		read_unlock(&vport->vmid_lock);
+		lpfc_vmid_update_entry(vport, iodir, vmp, tag);
+		rc = 0;
+	} else if (vmp && (vmp->flag & LPFC_VMID_REQ_REGISTER ||
+			   vmp->flag & LPFC_VMID_DE_REGISTER)) {
+		/* else if register or dereg request has already been sent */
+		/* Hence VMID tag will not be added for this I/O */
+		read_unlock(&vport->vmid_lock);
+		rc = -EBUSY;
+	} else {
+		/* The VMID was not found in the hashtable. At this point, */
+		/* drop the read lock first before proceeding further */
+		read_unlock(&vport->vmid_lock);
+		/* start the process to obtain one as per the */
+		/* type of the VMID indicated */
+		write_lock(&vport->vmid_lock);
+		vmp = lpfc_get_vmid_from_hashtable(vport, hash, uuid);
+
+		/* while the read lock was released, in case the entry was */
+		/* added by other context or is in process of being added */
+		if (vmp && vmp->flag & LPFC_VMID_REGISTERED) {
+			lpfc_vmid_update_entry(vport, iodir, vmp, tag);
+			write_unlock(&vport->vmid_lock);
+			return 0;
+		} else if (vmp && vmp->flag & LPFC_VMID_REQ_REGISTER) {
+			write_unlock(&vport->vmid_lock);
+			return -EBUSY;
+		}
+
+		/* else search and allocate a free slot in the hash table */
+		if (vport->cur_vmid_cnt < vport->max_vmid) {
+			for (i = 0; i < vport->max_vmid; i++) {
+				vmp = vport->vmid + i;
+				if (vmp->flag == LPFC_VMID_SLOT_FREE)
+					break;
+			}
+			if (i == vport->max_vmid)
+				vmp = NULL;
+		} else {
+			vmp = NULL;
+		}
+
+		if (!vmp) {
+			write_unlock(&vport->vmid_lock);
+			return -ENOMEM;
+		}
+
+		/* Add the vmid and register */
+		lpfc_put_vmid_in_hashtable(vport, hash, vmp);
+		vmp->vmid_len = len;
+		memcpy(vmp->host_vmid, uuid, vmp->vmid_len);
+		vmp->io_rd_cnt = 0;
+		vmp->io_wr_cnt = 0;
+		vmp->flag = LPFC_VMID_SLOT_USED;
+
+		vmp->delete_inactive =
+			vport->vmid_inactivity_timeout ? 1 : 0;
+
+		/* if type priority tag, get next available VMID */
+		if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO)
+			lpfc_vmid_assign_cs_ctl(vport, vmp);
+
+		/* allocate the per cpu variable for holding */
+		/* the last access time stamp only if VMID is enabled */
+		if (!vmp->last_io_time)
+			vmp->last_io_time = __alloc_percpu(sizeof(u64),
+							   __alignof__(struct
+							   lpfc_vmid));
+		if (!vmp->last_io_time) {
+			hash_del(&vmp->hnode);
+			vmp->flag = LPFC_VMID_SLOT_FREE;
+			write_unlock(&vport->vmid_lock);
+			return -EIO;
+		}
+
+		write_unlock(&vport->vmid_lock);
+
+		/* complete transaction with switch */
+		if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO)
+			rc = lpfc_vmid_uvem(vport, vmp, true);
+		else if (vport->phba->cfg_vmid_app_header)
+			rc = lpfc_vmid_cmd(vport, SLI_CTAS_RAPP_IDENT, vmp);
+		if (!rc) {
+			write_lock(&vport->vmid_lock);
+			vport->cur_vmid_cnt++;
+			vmp->flag |= LPFC_VMID_REQ_REGISTER;
+			write_unlock(&vport->vmid_lock);
+		} else {
+			write_lock(&vport->vmid_lock);
+			hash_del(&vmp->hnode);
+			vmp->flag = LPFC_VMID_SLOT_FREE;
+			free_percpu(vmp->last_io_time);
+			write_unlock(&vport->vmid_lock);
+			return -EIO;
+		}
+
+		/* finally, enable the idle timer once */
+		if (!(vport->phba->pport->vmid_flag & LPFC_VMID_TIMER_ENBLD)) {
+			mod_timer(&vport->phba->inactive_vmid_poll,
+				  jiffies +
+				  msecs_to_jiffies(1000 * LPFC_VMID_TIMER));
+			vport->phba->pport->vmid_flag |= LPFC_VMID_TIMER_ENBLD;
+		}
+	}
+	return rc;
+}
diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
index 01cd01787b0feb57c9a7cfa4706dd7d6cc093284..0e1cb4aa4ca270a8333457c804a72efb7307ebfb 100644
--- a/drivers/scsi/mpi3mr/mpi3mr.h
+++ b/drivers/scsi/mpi3mr/mpi3mr.h
@@ -954,7 +954,7 @@ struct mpi3mr_ioc {
 	u16 active_poll_qcount;
 	u16 requested_poll_qcount;
 
-	struct device *bsg_dev;
+	struct device bsg_dev;
 	struct request_queue *bsg_queue;
 	u8 stop_bsgs;
 	u8 *logdata_buf;
diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
index 9ab1762468ad6ee9ae03483404ec77440eab5ae9..9baac224b2135d399f0550598dc41867dbbbdf73 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_app.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
@@ -1487,28 +1487,28 @@ static int mpi3mr_bsg_request(struct bsg_job *job)
  */
 void mpi3mr_bsg_exit(struct mpi3mr_ioc *mrioc)
 {
+	struct device *bsg_dev = &mrioc->bsg_dev;
 	if (!mrioc->bsg_queue)
 		return;
 
 	bsg_remove_queue(mrioc->bsg_queue);
 	mrioc->bsg_queue = NULL;
 
-	device_del(mrioc->bsg_dev);
-	put_device(mrioc->bsg_dev);
-	kfree(mrioc->bsg_dev);
+	device_del(bsg_dev);
+	put_device(bsg_dev);
 }
 
 /**
  * mpi3mr_bsg_node_release -release bsg device node
  * @dev: bsg device node
  *
- * decrements bsg dev reference count
+ * decrements bsg dev parent reference count
  *
  * Return:Nothing
  */
 static void mpi3mr_bsg_node_release(struct device *dev)
 {
-	put_device(dev);
+	put_device(dev->parent);
 }
 
 /**
@@ -1521,41 +1521,37 @@ static void mpi3mr_bsg_node_release(struct device *dev)
  */
 void mpi3mr_bsg_init(struct mpi3mr_ioc *mrioc)
 {
-	mrioc->bsg_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
-	if (!mrioc->bsg_dev) {
-		ioc_err(mrioc, "bsg device mem allocation failed\n");
-		return;
-	}
+	struct device *bsg_dev = &mrioc->bsg_dev;
+	struct device *parent = &mrioc->shost->shost_gendev;
+
+	device_initialize(bsg_dev);
+
+	bsg_dev->parent = get_device(parent);
+	bsg_dev->release = mpi3mr_bsg_node_release;
 
-	device_initialize(mrioc->bsg_dev);
-	dev_set_name(mrioc->bsg_dev, "mpi3mrctl%u", mrioc->id);
+	dev_set_name(bsg_dev, "mpi3mrctl%u", mrioc->id);
 
-	if (device_add(mrioc->bsg_dev)) {
+	if (device_add(bsg_dev)) {
 		ioc_err(mrioc, "%s: bsg device add failed\n",
-		    dev_name(mrioc->bsg_dev));
-		goto err_device_add;
+		    dev_name(bsg_dev));
+		put_device(bsg_dev);
+		return;
 	}
 
-	mrioc->bsg_dev->release = mpi3mr_bsg_node_release;
-
-	mrioc->bsg_queue = bsg_setup_queue(mrioc->bsg_dev, dev_name(mrioc->bsg_dev),
+	mrioc->bsg_queue = bsg_setup_queue(bsg_dev, dev_name(bsg_dev),
 			mpi3mr_bsg_request, NULL, 0);
 	if (IS_ERR(mrioc->bsg_queue)) {
 		ioc_err(mrioc, "%s: bsg registration failed\n",
-		    dev_name(mrioc->bsg_dev));
-		goto err_setup_queue;
+		    dev_name(bsg_dev));
+		device_del(bsg_dev);
+		put_device(bsg_dev);
+		return;
 	}
 
 	blk_queue_max_segments(mrioc->bsg_queue, MPI3MR_MAX_APP_XFER_SEGMENTS);
 	blk_queue_max_hw_sectors(mrioc->bsg_queue, MPI3MR_MAX_APP_XFER_SECTORS);
 
 	return;
-
-err_setup_queue:
-	device_del(mrioc->bsg_dev);
-	put_device(mrioc->bsg_dev);
-err_device_add:
-	kfree(mrioc->bsg_dev);
 }
 
 /**
@@ -1693,7 +1689,7 @@ logging_level_store(struct device *dev,
 static DEVICE_ATTR_RW(logging_level);
 
 /**
- * adapter_state_show - SysFS callback for adapter state show
+ * adp_state_show() - SysFS callback for adapter state show
  * @dev: class device
  * @attr: Device attributes
  * @buf: Buffer to copy
diff --git a/drivers/scsi/myrb.c b/drivers/scsi/myrb.c
index 71585528e8db995e5e20e91abe804d426f24becf..e885c1dbf61f962aa7706434f6970b37b2fbb9c1 100644
--- a/drivers/scsi/myrb.c
+++ b/drivers/scsi/myrb.c
@@ -1239,7 +1239,8 @@ static void myrb_cleanup(struct myrb_hba *cb)
 	myrb_unmap(cb);
 
 	if (cb->mmio_base) {
-		cb->disable_intr(cb->io_base);
+		if (cb->disable_intr)
+			cb->disable_intr(cb->io_base);
 		iounmap(cb->mmio_base);
 	}
 	if (cb->irq)
@@ -3413,9 +3414,13 @@ static struct myrb_hba *myrb_detect(struct pci_dev *pdev,
 	mutex_init(&cb->dcmd_mutex);
 	mutex_init(&cb->dma_mutex);
 	cb->pdev = pdev;
+	cb->host = shost;
 
-	if (pci_enable_device(pdev))
-		goto failure;
+	if (pci_enable_device(pdev)) {
+		dev_err(&pdev->dev, "Failed to enable PCI device\n");
+		scsi_host_put(shost);
+		return NULL;
+	}
 
 	if (privdata->hw_init == DAC960_PD_hw_init ||
 	    privdata->hw_init == DAC960_P_hw_init) {
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 3d5cd337a2a6168ef32bbef51a52aa5a2212f3b1..bfce60183a6e5173ac556334e3befbf6721892b3 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -1434,7 +1434,7 @@ static int pmcraid_notify_aen(
 		return -EINVAL;
 	}
 
-	/* send genetlink multicast message to notify appplications */
+	/* send genetlink multicast message to notify applications */
 	genlmsg_end(skb, msg_header);
 
 	result = genlmsg_multicast(&pmcraid_event_family, skb,
diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c
index e57cc22453d0e362234500c9dcc85108afb71359..4750ec5789a80db9f07060599d3705ddc6bcc062 100644
--- a/drivers/scsi/qedf/qedf_io.c
+++ b/drivers/scsi/qedf/qedf_io.c
@@ -893,7 +893,7 @@ int qedf_post_io_req(struct qedf_rport *fcport, struct qedf_ioreq *io_req)
 		return -EINVAL;
 	}
 
-	/* Record LUN number for later use if we neeed them */
+	/* Record LUN number for later use if we need them */
 	io_req->lun = (int)sc_cmd->device->lun;
 
 	/* Obtain free SQE */
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 0ab595c0870a43ba92ab10aa97c259b789b419f2..1e7f4d138e06c36ce2798bf1280f8600c214cb94 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -4037,7 +4037,6 @@ qla1280_setup(char *s)
 {
 	char *cp, *ptr;
 	unsigned long val;
-	int toke;
 
 	cp = s;
 
@@ -4052,7 +4051,7 @@ qla1280_setup(char *s)
 		} else
 			val = simple_strtoul(ptr, &ptr, 0);
 
-		switch ((toke = qla1280_get_token(cp))) {
+		switch (qla1280_get_token(cp)) {
 		case TOKEN_NVRAM:
 			if (!val)
 				driver_setup.no_nvram = 1;
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index e6b5c4ccce97ba7d531246838db05e616b643579..346d47b61c0780786afa04671388390839c7ae91 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -591,7 +591,6 @@ qla25xx_free_req_que(struct scsi_qla_host *vha, struct req_que *req)
 	}
 	kfree(req->outstanding_cmds);
 	kfree(req);
-	req = NULL;
 }
 
 static void
@@ -617,7 +616,6 @@ qla25xx_free_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
 		mutex_unlock(&ha->vport_lock);
 	}
 	kfree(rsp);
-	rsp = NULL;
 }
 
 int
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index a02235a6a8e9361b55359024b9986001019980fb..cb97f625970d0cac62ed63dce2f68e5af794a6bd 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -48,13 +48,6 @@ MODULE_PARM_DESC(qlini_mode,
 	"when ready "
 	"\"enabled\" (default) - initiator mode will always stay enabled.");
 
-static int ql_dm_tgt_ex_pct = 0;
-module_param(ql_dm_tgt_ex_pct, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(ql_dm_tgt_ex_pct,
-	"For Dual Mode (qlini_mode=dual), this parameter determines "
-	"the percentage of exchanges/cmds FW will allocate resources "
-	"for Target mode.");
-
 int ql2xuctrlirq = 1;
 module_param(ql2xuctrlirq, int, 0644);
 MODULE_PARM_DESC(ql2xuctrlirq,
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index e9db7da0c79c68fb4da856315ce00d42d609d348..6ffc9e4258a8052c0b05083a86361033185620c0 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -779,7 +779,7 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
 					action = ACTION_DELAYED_RETRY;
 					break;
 				case 0x0a: /* ALUA state transition */
-					blk_stat = BLK_STS_AGAIN;
+					blk_stat = BLK_STS_TRANSPORT;
 					fallthrough;
 				default:
 					action = ACTION_FAIL;
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 546a9e3cfbec450fef6e5cadcf3897021f954052..43949798a2e47531245b8799c30fb42c2ec7d61f 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -573,7 +573,6 @@ struct bus_type scsi_bus_type = {
 	.pm		= &scsi_bus_pm_ops,
 #endif
 };
-EXPORT_SYMBOL_GPL(scsi_bus_type);
 
 int scsi_sysfs_register(void)
 {
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 749316462075e9834c7209f19b55baec799f2141..895b56c8f25e3c137afffc41b8a3eb60fe58ac5c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -3521,7 +3521,7 @@ static int sd_probe(struct device *dev)
 	error = device_add_disk(dev, gd, NULL);
 	if (error) {
 		put_device(&sdkp->disk_dev);
-		blk_cleanup_disk(gd);
+		put_disk(gd);
 		goto out;
 	}
 
@@ -3542,7 +3542,6 @@ static int sd_probe(struct device *dev)
  out_put:
 	put_disk(gd);
  out_free:
-	sd_zbc_release_disk(sdkp);
 	kfree(sdkp);
  out:
 	scsi_autopm_put_device(sdp);
@@ -3579,7 +3578,7 @@ static void scsi_disk_release(struct device *dev)
 	struct scsi_disk *sdkp = to_scsi_disk(dev);
 
 	ida_free(&sd_index_ida, sdkp->index);
-	sd_zbc_release_disk(sdkp);
+	sd_zbc_free_zone_info(sdkp);
 	put_device(&sdkp->device->sdev_gendev);
 	free_opal_dev(sdkp->opal_dev);
 
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 2abad54fd23f222056ca0061cde578f22b4c6673..5eea762f84d188e15b516b05f0f98ba3892209a5 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -241,7 +241,7 @@ static inline int sd_is_zoned(struct scsi_disk *sdkp)
 
 #ifdef CONFIG_BLK_DEV_ZONED
 
-void sd_zbc_release_disk(struct scsi_disk *sdkp);
+void sd_zbc_free_zone_info(struct scsi_disk *sdkp);
 int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]);
 int sd_zbc_revalidate_zones(struct scsi_disk *sdkp);
 blk_status_t sd_zbc_setup_zone_mgmt_cmnd(struct scsi_cmnd *cmd,
@@ -256,7 +256,7 @@ blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba,
 
 #else /* CONFIG_BLK_DEV_ZONED */
 
-static inline void sd_zbc_release_disk(struct scsi_disk *sdkp) {}
+static inline void sd_zbc_free_zone_info(struct scsi_disk *sdkp) {}
 
 static inline int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE])
 {
diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
index 5b9fad70aa88a4f1f7a9ea67312d98eb17eb19de..6acc4f406eb8c0652346d597dac1cb55dde71079 100644
--- a/drivers/scsi/sd_zbc.c
+++ b/drivers/scsi/sd_zbc.c
@@ -786,8 +786,11 @@ static int sd_zbc_init_disk(struct scsi_disk *sdkp)
 	return 0;
 }
 
-static void sd_zbc_clear_zone_info(struct scsi_disk *sdkp)
+void sd_zbc_free_zone_info(struct scsi_disk *sdkp)
 {
+	if (!sdkp->zone_wp_update_buf)
+		return;
+
 	/* Serialize against revalidate zones */
 	mutex_lock(&sdkp->rev_mutex);
 
@@ -802,12 +805,6 @@ static void sd_zbc_clear_zone_info(struct scsi_disk *sdkp)
 	mutex_unlock(&sdkp->rev_mutex);
 }
 
-void sd_zbc_release_disk(struct scsi_disk *sdkp)
-{
-	if (sd_is_zoned(sdkp))
-		sd_zbc_clear_zone_info(sdkp);
-}
-
 static void sd_zbc_revalidate_zones_cb(struct gendisk *disk)
 {
 	struct scsi_disk *sdkp = scsi_disk(disk);
@@ -914,12 +911,15 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE])
 	u32 zone_blocks = 0;
 	int ret;
 
-	if (!sd_is_zoned(sdkp))
+	if (!sd_is_zoned(sdkp)) {
 		/*
-		 * Device managed or normal SCSI disk,
-		 * no special handling required
+		 * Device managed or normal SCSI disk, no special handling
+		 * required. Nevertheless, free the disk zone information in
+		 * case the device type changed.
 		 */
+		sd_zbc_free_zone_info(sdkp);
 		return 0;
+	}
 
 	/* READ16/WRITE16 is mandatory for ZBC disks */
 	sdkp->device->use_16_for_rw = 1;
@@ -928,11 +928,11 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE])
 	if (!blk_queue_is_zoned(q)) {
 		/*
 		 * This can happen for a host aware disk with partitions.
-		 * The block device zone information was already cleared
-		 * by blk_queue_set_zoned(). Only clear the scsi disk zone
+		 * The block device zone model was already cleared by
+		 * blk_queue_set_zoned(). Only free the scsi disk zone
 		 * information and exit early.
 		 */
-		sd_zbc_clear_zone_info(sdkp);
+		sd_zbc_free_zone_info(sdkp);
 		return 0;
 	}
 
diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index c4c48272d8adab9fc53d0d29321ba6989ee022ac..2e40320129c08b15d08c44d0560005c4258fdb42 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -1082,7 +1082,7 @@ struct pqi_stream_data {
 };
 
 struct pqi_scsi_dev {
-	int	devtype;		/* as reported by INQUIRY commmand */
+	int	devtype;		/* as reported by INQUIRY command */
 	u8	device_type;		/* as reported by */
 					/* BMIC_IDENTIFY_PHYSICAL_DEVICE */
 					/* only valid for devtype = TYPE_DISK */
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 08ed059a738b92065f7fd0f91608e043267c72a6..ca3530982e52c8f7f219dd51877bc76bc771cc2a 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -479,7 +479,7 @@ static void storvsc_host_scan(struct work_struct *work)
 	host = host_device->host;
 	/*
 	 * Before scanning the host, first check to see if any of the
-	 * currrently known devices have been hot removed. We issue a
+	 * currently known devices have been hot removed. We issue a
 	 * "unit ready" command against all currently known devices.
 	 * This I/O will result in an error for devices that have been
 	 * removed. As part of handling the I/O error, we remove the device.
diff --git a/drivers/ufs/Kconfig b/drivers/ufs/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..90226f72c158aad3253f5854f02c4a66ea25d83f
--- /dev/null
+++ b/drivers/ufs/Kconfig
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# UFS subsystem configuration
+#
+
+menuconfig SCSI_UFSHCD
+	tristate "Universal Flash Storage Controller"
+	depends on SCSI && SCSI_DMA
+	select PM_DEVFREQ
+	select DEVFREQ_GOV_SIMPLE_ONDEMAND
+	select NLS
+	help
+	  Enables support for UFS (Universal Flash Storage) host controllers.
+	  A UFS host controller is an electronic component that is able to
+	  communicate with a UFS card. UFS host controllers occur in
+	  smartphones, laptops, digital cameras and also in cars.
+	  The kernel module will be called ufshcd.
+
+	  To compile this driver as a module, choose M here and read
+	  <file:Documentation/scsi/ufs.rst>.
+	  However, do not compile this as a module if your root file system
+	  (the one containing the directory /) is located on a UFS device.
+
+if SCSI_UFSHCD
+
+source "drivers/ufs/core/Kconfig"
+
+source "drivers/ufs/host/Kconfig"
+
+endif
diff --git a/drivers/ufs/Makefile b/drivers/ufs/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..5a199ef18d4cb1d61041ae89a684735b28ace43c
--- /dev/null
+++ b/drivers/ufs/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# The link order is important here. ufshcd-core must initialize
+# before vendor drivers.
+obj-$(CONFIG_SCSI_UFSHCD)	+= core/ host/
diff --git a/drivers/ufs/core/Kconfig b/drivers/ufs/core/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..e11978171403acd1d7225d48efb4251db8595ffb
--- /dev/null
+++ b/drivers/ufs/core/Kconfig
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Kernel configuration file for the UFS Host Controller core.
+#
+# Copyright (C) 2011-2013 Samsung India Software Operations
+#
+# Authors:
+#	Santosh Yaraganavi <santosh.sy@samsung.com>
+#	Vinayak Holikatti <h.vinayak@samsung.com>
+
+config SCSI_UFS_BSG
+	bool "Universal Flash Storage BSG device node"
+	select BLK_DEV_BSGLIB
+	help
+	  Universal Flash Storage (UFS) is SCSI transport specification for
+	  accessing flash storage on digital cameras, mobile phones and
+	  consumer electronic devices.
+	  A UFS controller communicates with a UFS device by exchanging
+	  UFS Protocol Information Units (UPIUs).
+	  UPIUs can not only be used as a transport layer for the SCSI protocol
+	  but are also used by the UFS native command set.
+	  This transport driver supports exchanging UFS protocol information units
+	  with a UFS device. See also the ufshcd driver, which is a SCSI driver
+	  that supports UFS devices.
+
+	  Select this if you need a bsg device node for your UFS controller.
+	  If unsure, say N.
+
+config SCSI_UFS_CRYPTO
+	bool "UFS Crypto Engine Support"
+	depends on BLK_INLINE_ENCRYPTION
+	help
+	  Enable Crypto Engine Support in UFS.
+	  Enabling this makes it possible for the kernel to use the crypto
+	  capabilities of the UFS device (if present) to perform crypto
+	  operations on data being transferred to/from the device.
+
+config SCSI_UFS_HPB
+	bool "Support UFS Host Performance Booster"
+	help
+	  The UFS HPB feature improves random read performance. It caches
+	  L2P (logical to physical) map of UFS to host DRAM. The driver uses HPB
+	  read command by piggybacking physical page number for bypassing FTL (flash
+	  translation layer)'s L2P address translation.
+
+config SCSI_UFS_FAULT_INJECTION
+	bool "UFS Fault Injection Support"
+	depends on FAULT_INJECTION
+	help
+	  Enable fault injection support in the UFS driver. This makes it easier
+	  to test the UFS error handler and abort handler.
+
+config SCSI_UFS_HWMON
+	bool "UFS Temperature Notification"
+	depends on SCSI_UFSHCD=HWMON || HWMON=y
+	help
+	  This provides support for UFS hardware monitoring. If enabled,
+	  a hardware monitoring device will be created for the UFS device.
+
+	  If unsure, say N.
diff --git a/drivers/ufs/core/Makefile b/drivers/ufs/core/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..62f38c5bf857c7768724e06167e8b6020e993faa
--- /dev/null
+++ b/drivers/ufs/core/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SCSI_UFSHCD)		+= ufshcd-core.o
+ufshcd-core-y				+= ufshcd.o ufs-sysfs.o
+ufshcd-core-$(CONFIG_DEBUG_FS)		+= ufs-debugfs.o
+ufshcd-core-$(CONFIG_SCSI_UFS_BSG)	+= ufs_bsg.o
+ufshcd-core-$(CONFIG_SCSI_UFS_CRYPTO)	+= ufshcd-crypto.o
+ufshcd-core-$(CONFIG_SCSI_UFS_HPB)	+= ufshpb.o
+ufshcd-core-$(CONFIG_SCSI_UFS_FAULT_INJECTION) += ufs-fault-injection.o
+ufshcd-core-$(CONFIG_SCSI_UFS_HWMON)	+= ufs-hwmon.o
diff --git a/drivers/scsi/ufs/ufs-debugfs.c b/drivers/ufs/core/ufs-debugfs.c
similarity index 99%
rename from drivers/scsi/ufs/ufs-debugfs.c
rename to drivers/ufs/core/ufs-debugfs.c
index c10a8f09682b5f0c1f26b9d21359e31d42bb707e..e3baed6c70bd9b839319f106169ee05f35e6e6db 100644
--- a/drivers/scsi/ufs/ufs-debugfs.c
+++ b/drivers/ufs/core/ufs-debugfs.c
@@ -4,7 +4,7 @@
 #include <linux/debugfs.h>
 
 #include "ufs-debugfs.h"
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 #include "ufshcd-priv.h"
 
 static struct dentry *ufs_debugfs_root;
diff --git a/drivers/scsi/ufs/ufs-debugfs.h b/drivers/ufs/core/ufs-debugfs.h
similarity index 100%
rename from drivers/scsi/ufs/ufs-debugfs.h
rename to drivers/ufs/core/ufs-debugfs.h
diff --git a/drivers/scsi/ufs/ufs-fault-injection.c b/drivers/ufs/core/ufs-fault-injection.c
similarity index 100%
rename from drivers/scsi/ufs/ufs-fault-injection.c
rename to drivers/ufs/core/ufs-fault-injection.c
diff --git a/drivers/scsi/ufs/ufs-fault-injection.h b/drivers/ufs/core/ufs-fault-injection.h
similarity index 100%
rename from drivers/scsi/ufs/ufs-fault-injection.h
rename to drivers/ufs/core/ufs-fault-injection.h
diff --git a/drivers/scsi/ufs/ufs-hwmon.c b/drivers/ufs/core/ufs-hwmon.c
similarity index 99%
rename from drivers/scsi/ufs/ufs-hwmon.c
rename to drivers/ufs/core/ufs-hwmon.c
index c38d9d98a86d0ab955301df540bf949bd9fb2ba6..4c6a872b7a7ca9ad8d569854dc3c3e04fc44bcc9 100644
--- a/drivers/scsi/ufs/ufs-hwmon.c
+++ b/drivers/ufs/core/ufs-hwmon.c
@@ -7,7 +7,7 @@
 #include <linux/hwmon.h>
 #include <linux/units.h>
 
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 #include "ufshcd-priv.h"
 
 struct ufs_hwmon_data {
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c
similarity index 99%
rename from drivers/scsi/ufs/ufs-sysfs.c
rename to drivers/ufs/core/ufs-sysfs.c
index 8a3c6442f2911e09d2990e8058dfd3fd0132b9f2..0a088b47d5570047de5457fc93bfc53953f4ebea 100644
--- a/drivers/scsi/ufs/ufs-sysfs.c
+++ b/drivers/ufs/core/ufs-sysfs.c
@@ -6,7 +6,7 @@
 #include <linux/bitfield.h>
 #include <asm/unaligned.h>
 
-#include "ufs.h"
+#include <ufs/ufs.h>
 #include "ufs-sysfs.h"
 #include "ufshcd-priv.h"
 
diff --git a/drivers/scsi/ufs/ufs-sysfs.h b/drivers/ufs/core/ufs-sysfs.h
similarity index 100%
rename from drivers/scsi/ufs/ufs-sysfs.h
rename to drivers/ufs/core/ufs-sysfs.h
diff --git a/drivers/scsi/ufs/ufs_bsg.c b/drivers/ufs/core/ufs_bsg.c
similarity index 99%
rename from drivers/scsi/ufs/ufs_bsg.c
rename to drivers/ufs/core/ufs_bsg.c
index 9e9b93867cab0f9c97c8378e1e5e2665c5fb75b4..b99e3f3dc4efdc421b06ef8e1ffcdd97ad048811 100644
--- a/drivers/scsi/ufs/ufs_bsg.c
+++ b/drivers/ufs/core/ufs_bsg.c
@@ -9,7 +9,7 @@
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 #include "ufs_bsg.h"
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 #include "ufshcd-priv.h"
 
 static int ufs_bsg_get_query_desc_size(struct ufs_hba *hba, int *desc_len,
diff --git a/drivers/scsi/ufs/ufs_bsg.h b/drivers/ufs/core/ufs_bsg.h
similarity index 100%
rename from drivers/scsi/ufs/ufs_bsg.h
rename to drivers/ufs/core/ufs_bsg.h
diff --git a/drivers/scsi/ufs/ufshcd-crypto.c b/drivers/ufs/core/ufshcd-crypto.c
similarity index 99%
rename from drivers/scsi/ufs/ufshcd-crypto.c
rename to drivers/ufs/core/ufshcd-crypto.c
index 67402baf6faee85ed48616004251a35966fecf66..198360fe5e8e1f08c283879768ee6a2d8561a433 100644
--- a/drivers/scsi/ufs/ufshcd-crypto.c
+++ b/drivers/ufs/core/ufshcd-crypto.c
@@ -3,7 +3,7 @@
  * Copyright 2019 Google LLC
  */
 
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 #include "ufshcd-crypto.h"
 
 /* Blk-crypto modes supported by UFS crypto */
diff --git a/drivers/scsi/ufs/ufshcd-crypto.h b/drivers/ufs/core/ufshcd-crypto.h
similarity index 97%
rename from drivers/scsi/ufs/ufshcd-crypto.h
rename to drivers/ufs/core/ufshcd-crypto.h
index 9f98f18f964630f6217ad054fdbb8db2454d54b7..504cc841540b21893fb89e233d4fd9268f771179 100644
--- a/drivers/scsi/ufs/ufshcd-crypto.h
+++ b/drivers/ufs/core/ufshcd-crypto.h
@@ -7,9 +7,9 @@
 #define _UFSHCD_CRYPTO_H
 
 #include <scsi/scsi_cmnd.h>
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 #include "ufshcd-priv.h"
-#include "ufshci.h"
+#include <ufs/ufshci.h>
 
 #ifdef CONFIG_SCSI_UFS_CRYPTO
 
diff --git a/drivers/scsi/ufs/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h
similarity index 99%
rename from drivers/scsi/ufs/ufshcd-priv.h
rename to drivers/ufs/core/ufshcd-priv.h
index 38bc77d3dbbd47bf5ddaf97b4263b367a496a64c..ffb01fc6de75b9bd3c1e5e179dd02504a866100a 100644
--- a/drivers/scsi/ufs/ufshcd-priv.h
+++ b/drivers/ufs/core/ufshcd-priv.h
@@ -4,7 +4,7 @@
 #define _UFSHCD_PRIV_H_
 
 #include <linux/pm_runtime.h>
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 
 static inline bool ufshcd_is_user_access_allowed(struct ufs_hba *hba)
 {
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/ufs/core/ufshcd.c
similarity index 99%
rename from drivers/scsi/ufs/ufshcd.c
rename to drivers/ufs/core/ufshcd.c
index 1fb3a8b9b03ed680af0bb19b68a09c17ebab11ff..01fb4bad86be8293aa8c9e7f57d0c446b8754a29 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -26,8 +26,8 @@
 #include <scsi/scsi_driver.h>
 #include <scsi/scsi_eh.h>
 #include "ufshcd-priv.h"
-#include "ufs_quirks.h"
-#include "unipro.h"
+#include <ufs/ufs_quirks.h>
+#include <ufs/unipro.h>
 #include "ufs-sysfs.h"
 #include "ufs-debugfs.h"
 #include "ufs-fault-injection.h"
@@ -8445,10 +8445,7 @@ static int ufshcd_init_hba_vreg(struct ufs_hba *hba)
 {
 	struct ufs_vreg_info *info = &hba->vreg_info;
 
-	if (info)
-		return ufshcd_get_vreg(hba->dev, info->vdd_hba);
-
-	return 0;
+	return ufshcd_get_vreg(hba->dev, info->vdd_hba);
 }
 
 static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on)
diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/ufs/core/ufshpb.c
similarity index 99%
rename from drivers/scsi/ufs/ufshpb.c
rename to drivers/ufs/core/ufshpb.c
index 002c19c2b31f47e85966c3f092855dae85c6276c..de2bb8401bc4e4fa0b06bc4a124bff27e3522032 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/ufs/core/ufshpb.c
@@ -17,7 +17,7 @@
 
 #include "ufshcd-priv.h"
 #include "ufshpb.h"
-#include "../sd.h"
+#include "../../scsi/sd.h"
 
 #define ACTIVATION_THRESHOLD 8 /* 8 IOs */
 #define READ_TO_MS 1000
diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/ufs/core/ufshpb.h
similarity index 100%
rename from drivers/scsi/ufs/ufshpb.h
rename to drivers/ufs/core/ufshpb.h
diff --git a/drivers/scsi/ufs/Kconfig b/drivers/ufs/host/Kconfig
similarity index 56%
rename from drivers/scsi/ufs/Kconfig
rename to drivers/ufs/host/Kconfig
index 393b9a01da36ba3df5634f8d9c558333e6aaa3c6..82590224da1364e508afb8a693cb3d73322de75b 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/ufs/host/Kconfig
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0+
 #
-# Kernel configuration file for the UFS Host Controller
+# Kernel configuration file for the UFS host controller drivers.
 #
 # Copyright (C) 2011-2013 Samsung India Software Operations
 #
@@ -8,26 +8,6 @@
 #	Santosh Yaraganavi <santosh.sy@samsung.com>
 #	Vinayak Holikatti <h.vinayak@samsung.com>
 
-config SCSI_UFSHCD
-	tristate "Universal Flash Storage Controller Driver Core"
-	depends on SCSI && SCSI_DMA
-	select PM_DEVFREQ
-	select DEVFREQ_GOV_SIMPLE_ONDEMAND
-	select NLS
-	help
-	  This selects the support for UFS devices in Linux, say Y and make
-	  sure that you know the name of your UFS host adapter (the card
-	  inside your computer that "speaks" the UFS protocol, also
-	  called UFS Host Controller), because you will be asked for it.
-	  The module will be called ufshcd.
-
-	  To compile this driver as a module, choose M here and read
-	  <file:Documentation/scsi/ufs.rst>.
-	  However, do not compile this as a module if your root file system
-	  (the one containing the directory /) is located on a UFS device.
-
-if SCSI_UFSHCD
-
 config SCSI_UFSHCD_PCI
 	tristate "PCI bus based UFS Controller support"
 	depends on PCI
@@ -122,24 +102,6 @@ config SCSI_UFS_TI_J721E
 	  Selects this if you have TI platform with UFS controller.
 	  If unsure, say N.
 
-config SCSI_UFS_BSG
-	bool "Universal Flash Storage BSG device node"
-	select BLK_DEV_BSGLIB
-	help
-	  Universal Flash Storage (UFS) is SCSI transport specification for
-	  accessing flash storage on digital cameras, mobile phones and
-	  consumer electronic devices.
-	  A UFS controller communicates with a UFS device by exchanging
-	  UFS Protocol Information Units (UPIUs).
-	  UPIUs can not only be used as a transport layer for the SCSI protocol
-	  but are also used by the UFS native command set.
-	  This transport driver supports exchanging UFS protocol information units
-	  with a UFS device. See also the ufshcd driver, which is a SCSI driver
-	  that supports UFS devices.
-
-	  Select this if you need a bsg device node for your UFS controller.
-	  If unsure, say N.
-
 config SCSI_UFS_EXYNOS
 	tristate "Exynos specific hooks to UFS controller platform driver"
 	depends on SCSI_UFSHCD_PLATFORM && (ARCH_EXYNOS || COMPILE_TEST)
@@ -150,38 +112,3 @@ config SCSI_UFS_EXYNOS
 
 	  Select this if you have UFS host controller on Samsung Exynos SoC.
 	  If unsure, say N.
-
-config SCSI_UFS_CRYPTO
-	bool "UFS Crypto Engine Support"
-	depends on BLK_INLINE_ENCRYPTION
-	help
-	  Enable Crypto Engine Support in UFS.
-	  Enabling this makes it possible for the kernel to use the crypto
-	  capabilities of the UFS device (if present) to perform crypto
-	  operations on data being transferred to/from the device.
-
-config SCSI_UFS_HPB
-	bool "Support UFS Host Performance Booster"
-	help
-	  The UFS HPB feature improves random read performance. It caches
-	  L2P (logical to physical) map of UFS to host DRAM. The driver uses HPB
-	  read command by piggybacking physical page number for bypassing FTL (flash
-	  translation layer)'s L2P address translation.
-
-config SCSI_UFS_FAULT_INJECTION
-	bool "UFS Fault Injection Support"
-	depends on FAULT_INJECTION
-	help
-	  Enable fault injection support in the UFS driver. This makes it easier
-	  to test the UFS error handler and abort handler.
-
-config SCSI_UFS_HWMON
-	bool "UFS Temperature Notification"
-	depends on SCSI_UFSHCD=HWMON || HWMON=y
-	help
-	  This provides support for UFS hardware monitoring. If enabled,
-	  a hardware monitoring device will be created for the UFS device.
-
-	  If unsure, say N.
-
-endif
diff --git a/drivers/scsi/ufs/Makefile b/drivers/ufs/host/Makefile
similarity index 56%
rename from drivers/scsi/ufs/Makefile
rename to drivers/ufs/host/Makefile
index 966048875b50386118cd6baf44d51aa18f43d76f..e4be54273c98b8c5562d75743384530dee200e94 100644
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/ufs/host/Makefile
@@ -1,16 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
-# UFSHCD makefile
-
-# The link order is important here. ufshcd-core must initialize
-# before vendor drivers.
-obj-$(CONFIG_SCSI_UFSHCD)		+= ufshcd-core.o
-ufshcd-core-y				+= ufshcd.o ufs-sysfs.o
-ufshcd-core-$(CONFIG_DEBUG_FS)		+= ufs-debugfs.o
-ufshcd-core-$(CONFIG_SCSI_UFS_BSG)	+= ufs_bsg.o
-ufshcd-core-$(CONFIG_SCSI_UFS_CRYPTO)	+= ufshcd-crypto.o
-ufshcd-core-$(CONFIG_SCSI_UFS_HPB)	+= ufshpb.o
-ufshcd-core-$(CONFIG_SCSI_UFS_FAULT_INJECTION) += ufs-fault-injection.o
-ufshcd-core-$(CONFIG_SCSI_UFS_HWMON) += ufs-hwmon.o
 
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o
diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/ufs/host/cdns-pltfrm.c
similarity index 100%
rename from drivers/scsi/ufs/cdns-pltfrm.c
rename to drivers/ufs/host/cdns-pltfrm.c
diff --git a/drivers/scsi/ufs/tc-dwc-g210-pci.c b/drivers/ufs/host/tc-dwc-g210-pci.c
similarity index 99%
rename from drivers/scsi/ufs/tc-dwc-g210-pci.c
rename to drivers/ufs/host/tc-dwc-g210-pci.c
index e635c211c78389bc88453c07e740b432bdbbd413..92b8ad4b58febe1bf5289ad4eb31846dc6e71880 100644
--- a/drivers/scsi/ufs/tc-dwc-g210-pci.c
+++ b/drivers/ufs/host/tc-dwc-g210-pci.c
@@ -7,7 +7,7 @@
  * Authors: Joao Pinto <jpinto@synopsys.com>
  */
 
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 #include "ufshcd-dwc.h"
 #include "tc-dwc-g210.h"
 
diff --git a/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c b/drivers/ufs/host/tc-dwc-g210-pltfrm.c
similarity index 100%
rename from drivers/scsi/ufs/tc-dwc-g210-pltfrm.c
rename to drivers/ufs/host/tc-dwc-g210-pltfrm.c
diff --git a/drivers/scsi/ufs/tc-dwc-g210.c b/drivers/ufs/host/tc-dwc-g210.c
similarity index 99%
rename from drivers/scsi/ufs/tc-dwc-g210.c
rename to drivers/ufs/host/tc-dwc-g210.c
index 7ef67c9fc5b835c9597b98d964a771101b3e549b..deb93dbd83a433d26d7cf86b62d69bdb93eddc3e 100644
--- a/drivers/scsi/ufs/tc-dwc-g210.c
+++ b/drivers/ufs/host/tc-dwc-g210.c
@@ -9,8 +9,8 @@
 
 #include <linux/module.h>
 
-#include "ufshcd.h"
-#include "unipro.h"
+#include <ufs/ufshcd.h>
+#include <ufs/unipro.h>
 
 #include "ufshcd-dwc.h"
 #include "ufshci-dwc.h"
diff --git a/drivers/scsi/ufs/tc-dwc-g210.h b/drivers/ufs/host/tc-dwc-g210.h
similarity index 100%
rename from drivers/scsi/ufs/tc-dwc-g210.h
rename to drivers/ufs/host/tc-dwc-g210.h
diff --git a/drivers/scsi/ufs/ti-j721e-ufs.c b/drivers/ufs/host/ti-j721e-ufs.c
similarity index 100%
rename from drivers/scsi/ufs/ti-j721e-ufs.c
rename to drivers/ufs/host/ti-j721e-ufs.c
diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c
similarity index 99%
rename from drivers/scsi/ufs/ufs-exynos.c
rename to drivers/ufs/host/ufs-exynos.c
index ddb2d42605c532ecffa92db68cc83d6fbff47bfb..a81d8cbd542f38e7a82bbe58437621aa6029374b 100644
--- a/drivers/scsi/ufs/ufs-exynos.c
+++ b/drivers/ufs/host/ufs-exynos.c
@@ -18,10 +18,10 @@
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 #include "ufshcd-pltfrm.h"
-#include "ufshci.h"
-#include "unipro.h"
+#include <ufs/ufshci.h>
+#include <ufs/unipro.h>
 
 #include "ufs-exynos.h"
 
diff --git a/drivers/scsi/ufs/ufs-exynos.h b/drivers/ufs/host/ufs-exynos.h
similarity index 100%
rename from drivers/scsi/ufs/ufs-exynos.h
rename to drivers/ufs/host/ufs-exynos.h
diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/ufs/host/ufs-hisi.c
similarity index 99%
rename from drivers/scsi/ufs/ufs-hisi.c
rename to drivers/ufs/host/ufs-hisi.c
index 7046143063ee6963c1cc84d3f34f6c53c7277a9a..2eed13bc82ca186f1b6137857f1ad0c3075e8ac1 100644
--- a/drivers/scsi/ufs/ufs-hisi.c
+++ b/drivers/ufs/host/ufs-hisi.c
@@ -15,12 +15,12 @@
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 #include "ufshcd-pltfrm.h"
-#include "unipro.h"
+#include <ufs/unipro.h>
 #include "ufs-hisi.h"
-#include "ufshci.h"
-#include "ufs_quirks.h"
+#include <ufs/ufshci.h>
+#include <ufs/ufs_quirks.h>
 
 static int ufs_hisi_check_hibern8(struct ufs_hba *hba)
 {
diff --git a/drivers/scsi/ufs/ufs-hisi.h b/drivers/ufs/host/ufs-hisi.h
similarity index 100%
rename from drivers/scsi/ufs/ufs-hisi.h
rename to drivers/ufs/host/ufs-hisi.h
diff --git a/drivers/scsi/ufs/ufs-mediatek-trace.h b/drivers/ufs/host/ufs-mediatek-trace.h
similarity index 93%
rename from drivers/scsi/ufs/ufs-mediatek-trace.h
rename to drivers/ufs/host/ufs-mediatek-trace.h
index 895e82ea6ece551d0a5c5fa5c6ba8cf3ee3452e0..7e010848dc993c23ed7e8d6e90c4ebd49b9aeb1e 100644
--- a/drivers/scsi/ufs/ufs-mediatek-trace.h
+++ b/drivers/ufs/host/ufs-mediatek-trace.h
@@ -31,6 +31,6 @@ TRACE_EVENT(ufs_mtk_event,
 
 #undef TRACE_INCLUDE_PATH
 #undef TRACE_INCLUDE_FILE
-#define TRACE_INCLUDE_PATH ../../drivers/scsi/ufs/
+#define TRACE_INCLUDE_PATH ../../drivers/ufs/host
 #define TRACE_INCLUDE_FILE ufs-mediatek-trace
 #include <trace/define_trace.h>
diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
similarity index 99%
rename from drivers/scsi/ufs/ufs-mediatek.c
rename to drivers/ufs/host/ufs-mediatek.c
index 083d6bd4d561bf7655e0c7452a1a8fc3f1b89f04..beabc3ccd30b3653be17e99f99d25b545a584a6a 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -21,10 +21,10 @@
 #include <linux/sched/clock.h>
 #include <linux/soc/mediatek/mtk_sip_svc.h>
 
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 #include "ufshcd-pltfrm.h"
-#include "ufs_quirks.h"
-#include "unipro.h"
+#include <ufs/ufs_quirks.h>
+#include <ufs/unipro.h>
 #include "ufs-mediatek.h"
 
 #define CREATE_TRACE_POINTS
diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/ufs/host/ufs-mediatek.h
similarity index 100%
rename from drivers/scsi/ufs/ufs-mediatek.h
rename to drivers/ufs/host/ufs-mediatek.h
diff --git a/drivers/scsi/ufs/ufs-qcom-ice.c b/drivers/ufs/host/ufs-qcom-ice.c
similarity index 100%
rename from drivers/scsi/ufs/ufs-qcom-ice.c
rename to drivers/ufs/host/ufs-qcom-ice.c
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
similarity index 99%
rename from drivers/scsi/ufs/ufs-qcom.c
rename to drivers/ufs/host/ufs-qcom.c
index 4dcb232facaa9fc4f6ca33730f7573ca6cfbbe4a..f10d4668814cc35e07c1b2a858f61f40440c23ca 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/ufs/host/ufs-qcom.c
@@ -15,12 +15,12 @@
 #include <linux/reset-controller.h>
 #include <linux/devfreq.h>
 
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 #include "ufshcd-pltfrm.h"
-#include "unipro.h"
+#include <ufs/unipro.h>
 #include "ufs-qcom.h"
-#include "ufshci.h"
-#include "ufs_quirks.h"
+#include <ufs/ufshci.h>
+#include <ufs/ufs_quirks.h>
 
 #define UFS_QCOM_DEFAULT_DBG_PRINT_EN	\
 	(UFS_QCOM_DBG_PRINT_REGS_EN | UFS_QCOM_DBG_PRINT_TEST_BUS_EN)
diff --git a/drivers/scsi/ufs/ufs-qcom.h b/drivers/ufs/host/ufs-qcom.h
similarity index 99%
rename from drivers/scsi/ufs/ufs-qcom.h
rename to drivers/ufs/host/ufs-qcom.h
index 771bc95d02c72a8f653bc68384a225a156bbf50a..44466a395bb539a1b2da0fd71550f882c6618b0e 100644
--- a/drivers/scsi/ufs/ufs-qcom.h
+++ b/drivers/ufs/host/ufs-qcom.h
@@ -7,7 +7,7 @@
 
 #include <linux/reset-controller.h>
 #include <linux/reset.h>
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 
 #define MAX_UFS_QCOM_HOSTS	1
 #define MAX_U32                 (~(u32)0)
diff --git a/drivers/scsi/ufs/ufshcd-dwc.c b/drivers/ufs/host/ufshcd-dwc.c
similarity index 98%
rename from drivers/scsi/ufs/ufshcd-dwc.c
rename to drivers/ufs/host/ufshcd-dwc.c
index a57973c8d2a122bbdceee32d4389cb68428761ed..e28a67e1e3145c926f9c4824ef2be5ebd1ecd215 100644
--- a/drivers/scsi/ufs/ufshcd-dwc.c
+++ b/drivers/ufs/host/ufshcd-dwc.c
@@ -9,8 +9,8 @@
 
 #include <linux/module.h>
 
-#include "ufshcd.h"
-#include "unipro.h"
+#include <ufs/ufshcd.h>
+#include <ufs/unipro.h>
 
 #include "ufshcd-dwc.h"
 #include "ufshci-dwc.h"
diff --git a/drivers/scsi/ufs/ufshcd-dwc.h b/drivers/ufs/host/ufshcd-dwc.h
similarity index 95%
rename from drivers/scsi/ufs/ufshcd-dwc.h
rename to drivers/ufs/host/ufshcd-dwc.h
index 43b70794e24ff4d5d18ac143da70cb011d1b2897..ad91ea56662c23bfe8285f87559b1392f34ca87b 100644
--- a/drivers/scsi/ufs/ufshcd-dwc.h
+++ b/drivers/ufs/host/ufshcd-dwc.h
@@ -10,7 +10,7 @@
 #ifndef _UFSHCD_DWC_H
 #define _UFSHCD_DWC_H
 
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 
 struct ufshcd_dme_attr_val {
 	u32 attr_sel;
diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/ufs/host/ufshcd-pci.c
similarity index 99%
rename from drivers/scsi/ufs/ufshcd-pci.c
rename to drivers/ufs/host/ufshcd-pci.c
index 20af2fbc3af145f5119300e563eee101682c6d13..04166bda41daacb25c8c18cfe2c76507dd91efa5 100644
--- a/drivers/scsi/ufs/ufshcd-pci.c
+++ b/drivers/ufs/host/ufshcd-pci.c
@@ -9,7 +9,7 @@
  *	Vinayak Holikatti <h.vinayak@samsung.com>
  */
 
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/pci.h>
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/ufs/host/ufshcd-pltfrm.c
similarity index 99%
rename from drivers/scsi/ufs/ufshcd-pltfrm.c
rename to drivers/ufs/host/ufshcd-pltfrm.c
index f5313f4076175bf022e3f16f428ef773613381ac..e7332cc65b1fecfaa1f62d683ea77391949a5c4e 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
+++ b/drivers/ufs/host/ufshcd-pltfrm.c
@@ -13,9 +13,9 @@
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
 
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 #include "ufshcd-pltfrm.h"
-#include "unipro.h"
+#include <ufs/unipro.h>
 
 #define UFSHCD_DEFAULT_LANES_PER_DIRECTION		2
 
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.h b/drivers/ufs/host/ufshcd-pltfrm.h
similarity index 98%
rename from drivers/scsi/ufs/ufshcd-pltfrm.h
rename to drivers/ufs/host/ufshcd-pltfrm.h
index c33e28ac6ef621d310b82178afb68dbca4253c5a..43c2e412bd9904248a45a87b2b34d6c135498003 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.h
+++ b/drivers/ufs/host/ufshcd-pltfrm.h
@@ -5,7 +5,7 @@
 #ifndef UFSHCD_PLTFRM_H_
 #define UFSHCD_PLTFRM_H_
 
-#include "ufshcd.h"
+#include <ufs/ufshcd.h>
 
 #define UFS_PWM_MODE 1
 #define UFS_HS_MODE  2
diff --git a/drivers/scsi/ufs/ufshci-dwc.h b/drivers/ufs/host/ufshci-dwc.h
similarity index 100%
rename from drivers/scsi/ufs/ufshci-dwc.h
rename to drivers/ufs/host/ufshci-dwc.h
diff --git a/include/linux/nvme-fc-driver.h b/include/linux/nvme-fc-driver.h
index 5358a5facdee6ac4f164dd3323b20cffcc6005df..fa092b9be2fdc46a95c4470c5e6adbc1d9e6d49f 100644
--- a/include/linux/nvme-fc-driver.h
+++ b/include/linux/nvme-fc-driver.h
@@ -564,6 +564,15 @@ int nvme_fc_rcv_ls_req(struct nvme_fc_remote_port *remoteport,
 			void *lsreqbuf, u32 lsreqbuf_len);
 
 
+/*
+ * Routine called to get the appid field associated with request by the lldd
+ *
+ * If the return value is NULL : the user/libvirt has not set the appid to VM
+ * If the return value is non-zero: Returns the appid associated with VM
+ *
+ * @req: IO request from nvme fc to driver
+ */
+char *nvme_fc_io_getuuid(struct nvmefc_fcp_req *req);
 
 /*
  * ***************  LLDD FC-NVME Target/Subsystem API ***************
@@ -1048,5 +1057,10 @@ int nvmet_fc_rcv_fcp_req(struct nvmet_fc_target_port *tgtport,
 
 void nvmet_fc_rcv_fcp_abort(struct nvmet_fc_target_port *tgtport,
 			struct nvmefc_tgt_fcp_req *fcpreq);
+/*
+ * add a define, visible to the compiler, that indicates support
+ * for feature. Allows for conditional compilation in LLDDs.
+ */
+#define NVME_FC_FEAT_UUID	0x0001
 
 #endif /* _NVME_FC_DRIVER_H */
diff --git a/drivers/scsi/ufs/ufs.h b/include/ufs/ufs.h
similarity index 100%
rename from drivers/scsi/ufs/ufs.h
rename to include/ufs/ufs.h
diff --git a/drivers/scsi/ufs/ufs_quirks.h b/include/ufs/ufs_quirks.h
similarity index 100%
rename from drivers/scsi/ufs/ufs_quirks.h
rename to include/ufs/ufs_quirks.h
diff --git a/drivers/scsi/ufs/ufshcd.h b/include/ufs/ufshcd.h
similarity index 99%
rename from drivers/scsi/ufs/ufshcd.h
rename to include/ufs/ufshcd.h
index 2b0f3441b81381bc713a8216901f86f2b756ae18..a92271421718eff1e899709f376ed7d99b25c186 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -18,10 +18,10 @@
 #include <linux/devfreq.h>
 #include <linux/pm_runtime.h>
 #include <scsi/scsi_device.h>
-#include "unipro.h"
-#include "ufs.h"
-#include "ufs_quirks.h"
-#include "ufshci.h"
+#include <ufs/unipro.h>
+#include <ufs/ufs.h>
+#include <ufs/ufs_quirks.h>
+#include <ufs/ufshci.h>
 
 #define UFSHCD "ufshcd"
 
diff --git a/drivers/scsi/ufs/ufshci.h b/include/ufs/ufshci.h
similarity index 100%
rename from drivers/scsi/ufs/ufshci.h
rename to include/ufs/ufshci.h
diff --git a/drivers/scsi/ufs/unipro.h b/include/ufs/unipro.h
similarity index 100%
rename from drivers/scsi/ufs/unipro.h
rename to include/ufs/unipro.h