summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2012-10-08 00:03:19 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2012-11-06 20:55:43 -0800
commit0fd97ccf45be26fb01b3a412f1f6c6b5044b2f16 (patch)
treec642e3da11e534a311a1e998ef740a3d44b9187b /drivers
parent3d70f8c617a436c7146ecb81df2265b4626dfe89 (diff)
downloadlinux-0fd97ccf45be26fb01b3a412f1f6c6b5044b2f16.tar.gz
target: kill struct se_subsystem_dev
Simplify the code a lot by killing the superflous struct se_subsystem_dev.
Instead se_device is allocated early on by the backend driver, which allocates
it as part of its own per-device structure, borrowing the scheme that is for
example used for inode allocation.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/target/loopback/tcm_loop.h1
-rw-r--r--drivers/target/target_core_alua.c152
-rw-r--r--drivers/target/target_core_alua.h4
-rw-r--r--drivers/target/target_core_configfs.c528
-rw-r--r--drivers/target/target_core_device.c613
-rw-r--r--drivers/target/target_core_fabric_configfs.c14
-rw-r--r--drivers/target/target_core_file.c138
-rw-r--r--drivers/target/target_core_file.h2
-rw-r--r--drivers/target/target_core_hba.c4
-rw-r--r--drivers/target/target_core_iblock.c185
-rw-r--r--drivers/target/target_core_iblock.h1
-rw-r--r--drivers/target/target_core_internal.h12
-rw-r--r--drivers/target/target_core_pr.c148
-rw-r--r--drivers/target/target_core_pr.h2
-rw-r--r--drivers/target/target_core_pscsi.c270
-rw-r--r--drivers/target/target_core_pscsi.h2
-rw-r--r--drivers/target/target_core_rd.c94
-rw-r--r--drivers/target/target_core_rd.h1
-rw-r--r--drivers/target/target_core_sbc.c31
-rw-r--r--drivers/target/target_core_spc.c91
-rw-r--r--drivers/target/target_core_stat.c307
-rw-r--r--drivers/target/target_core_tmr.c6
-rw-r--r--drivers/target/target_core_transport.c217
-rw-r--r--drivers/target/target_core_ua.c6
24 files changed, 1011 insertions, 1818 deletions
diff --git a/drivers/target/loopback/tcm_loop.h b/drivers/target/loopback/tcm_loop.h
index 7b54893db665..dd7a84ee78e1 100644
--- a/drivers/target/loopback/tcm_loop.h
+++ b/drivers/target/loopback/tcm_loop.h
@@ -53,7 +53,6 @@ struct tcm_loop_hba {
 	struct se_hba_s *se_hba;
 	struct se_lun *tl_hba_lun;
 	struct se_port *tl_hba_lun_sep;
-	struct se_device_s *se_dev_hba_ptr;
 	struct tcm_loop_nexus *tl_nexus;
 	struct device dev;
 	struct Scsi_Host *sh;
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 9a5f9a7aecd2..15c127b780d8 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -61,7 +61,7 @@ struct t10_alua_lu_gp *default_lu_gp;
  */
 int target_emulate_report_target_port_groups(struct se_cmd *cmd)
 {
-	struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
+	struct se_device *dev = cmd->se_dev;
 	struct se_port *port;
 	struct t10_alua_tg_pt_gp *tg_pt_gp;
 	struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
@@ -86,8 +86,8 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd)
 	}
 	buf = transport_kmap_data_sg(cmd);
 
-	spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
-	list_for_each_entry(tg_pt_gp, &su_dev->t10_alua.tg_pt_gps_list,
+	spin_lock(&dev->t10_alua.tg_pt_gps_lock);
+	list_for_each_entry(tg_pt_gp, &dev->t10_alua.tg_pt_gps_list,
 			tg_pt_gp_list) {
 		/*
 		 * Check if the Target port group and Target port descriptor list
@@ -160,7 +160,7 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd)
 		}
 		spin_unlock(&tg_pt_gp->tg_pt_gp_lock);
 	}
-	spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+	spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 	/*
 	 * Set the RETURN DATA LENGTH set in the header of the DataIN Payload
 	 */
@@ -203,7 +203,6 @@ int target_emulate_report_target_port_groups(struct se_cmd *cmd)
 int target_emulate_set_target_port_groups(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
-	struct se_subsystem_dev *su_dev = dev->se_sub_dev;
 	struct se_port *port, *l_port = cmd->se_lun->lun_sep;
 	struct se_node_acl *nacl = cmd->se_sess->se_node_acl;
 	struct t10_alua_tg_pt_gp *tg_pt_gp = NULL, *l_tg_pt_gp;
@@ -303,9 +302,9 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd)
 			 * Locate the matching target port group ID from
 			 * the global tg_pt_gp list
 			 */
-			spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
+			spin_lock(&dev->t10_alua.tg_pt_gps_lock);
 			list_for_each_entry(tg_pt_gp,
-					&su_dev->t10_alua.tg_pt_gps_list,
+					&dev->t10_alua.tg_pt_gps_list,
 					tg_pt_gp_list) {
 				if (!tg_pt_gp->tg_pt_gp_valid_id)
 					continue;
@@ -315,18 +314,18 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd)
 
 				atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt);
 				smp_mb__after_atomic_inc();
-				spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+				spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 
 				rc = core_alua_do_port_transition(tg_pt_gp,
 						dev, l_port, nacl,
 						alua_access_state, 1);
 
-				spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
+				spin_lock(&dev->t10_alua.tg_pt_gps_lock);
 				atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt);
 				smp_mb__after_atomic_dec();
 				break;
 			}
-			spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+			spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 			/*
 			 * If not matching target port group ID can be located
 			 * throw an exception with ASCQ: INVALID_PARAMETER_LIST
@@ -758,8 +757,7 @@ static int core_alua_update_tpg_primary_metadata(
 	int primary_state,
 	unsigned char *md_buf)
 {
-	struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev;
-	struct t10_wwn *wwn = &su_dev->t10_wwn;
+	struct t10_wwn *wwn = &tg_pt_gp->tg_pt_gp_dev->t10_wwn;
 	char path[ALUA_METADATA_PATH_LEN];
 	int len;
 
@@ -899,7 +897,6 @@ int core_alua_do_port_transition(
 {
 	struct se_device *dev;
 	struct se_port *port;
-	struct se_subsystem_dev *su_dev;
 	struct se_node_acl *nacl;
 	struct t10_alua_lu_gp *lu_gp;
 	struct t10_alua_lu_gp_member *lu_gp_mem, *local_lu_gp_mem;
@@ -949,14 +946,13 @@ int core_alua_do_port_transition(
 				lu_gp_mem_list) {
 
 		dev = lu_gp_mem->lu_gp_mem_dev;
-		su_dev = dev->se_sub_dev;
 		atomic_inc(&lu_gp_mem->lu_gp_mem_ref_cnt);
 		smp_mb__after_atomic_inc();
 		spin_unlock(&lu_gp->lu_gp_lock);
 
-		spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
+		spin_lock(&dev->t10_alua.tg_pt_gps_lock);
 		list_for_each_entry(tg_pt_gp,
-				&su_dev->t10_alua.tg_pt_gps_list,
+				&dev->t10_alua.tg_pt_gps_list,
 				tg_pt_gp_list) {
 
 			if (!tg_pt_gp->tg_pt_gp_valid_id)
@@ -981,7 +977,7 @@ int core_alua_do_port_transition(
 			}
 			atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt);
 			smp_mb__after_atomic_inc();
-			spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+			spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 			/*
 			 * core_alua_do_transition_tg_pt() will always return
 			 * success.
@@ -989,11 +985,11 @@ int core_alua_do_port_transition(
 			core_alua_do_transition_tg_pt(tg_pt_gp, port,
 					nacl, md_buf, new_state, explict);
 
-			spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
+			spin_lock(&dev->t10_alua.tg_pt_gps_lock);
 			atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt);
 			smp_mb__after_atomic_dec();
 		}
-		spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+		spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 
 		spin_lock(&lu_gp->lu_gp_lock);
 		atomic_dec(&lu_gp_mem->lu_gp_mem_ref_cnt);
@@ -1268,8 +1264,7 @@ void core_alua_free_lu_gp(struct t10_alua_lu_gp *lu_gp)
 
 void core_alua_free_lu_gp_mem(struct se_device *dev)
 {
-	struct se_subsystem_dev *su_dev = dev->se_sub_dev;
-	struct t10_alua *alua = &su_dev->t10_alua;
+	struct t10_alua *alua = &dev->t10_alua;
 	struct t10_alua_lu_gp *lu_gp;
 	struct t10_alua_lu_gp_member *lu_gp_mem;
 
@@ -1358,10 +1353,8 @@ void __core_alua_drop_lu_gp_mem(
 	spin_unlock(&lu_gp->lu_gp_lock);
 }
 
-struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(
-	struct se_subsystem_dev *su_dev,
-	const char *name,
-	int def_group)
+struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(struct se_device *dev,
+		const char *name, int def_group)
 {
 	struct t10_alua_tg_pt_gp *tg_pt_gp;
 
@@ -1375,7 +1368,7 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(
 	mutex_init(&tg_pt_gp->tg_pt_gp_md_mutex);
 	spin_lock_init(&tg_pt_gp->tg_pt_gp_lock);
 	atomic_set(&tg_pt_gp->tg_pt_gp_ref_cnt, 0);
-	tg_pt_gp->tg_pt_gp_su_dev = su_dev;
+	tg_pt_gp->tg_pt_gp_dev = dev;
 	tg_pt_gp->tg_pt_gp_md_buf_len = ALUA_MD_BUF_LEN;
 	atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state,
 		ALUA_ACCESS_STATE_ACTIVE_OPTMIZED);
@@ -1392,14 +1385,14 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(
 	tg_pt_gp->tg_pt_gp_implict_trans_secs = ALUA_DEFAULT_IMPLICT_TRANS_SECS;
 
 	if (def_group) {
-		spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
+		spin_lock(&dev->t10_alua.tg_pt_gps_lock);
 		tg_pt_gp->tg_pt_gp_id =
-				su_dev->t10_alua.alua_tg_pt_gps_counter++;
+				dev->t10_alua.alua_tg_pt_gps_counter++;
 		tg_pt_gp->tg_pt_gp_valid_id = 1;
-		su_dev->t10_alua.alua_tg_pt_gps_count++;
+		dev->t10_alua.alua_tg_pt_gps_count++;
 		list_add_tail(&tg_pt_gp->tg_pt_gp_list,
-			      &su_dev->t10_alua.tg_pt_gps_list);
-		spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+			      &dev->t10_alua.tg_pt_gps_list);
+		spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 	}
 
 	return tg_pt_gp;
@@ -1409,9 +1402,10 @@ int core_alua_set_tg_pt_gp_id(
 	struct t10_alua_tg_pt_gp *tg_pt_gp,
 	u16 tg_pt_gp_id)
 {
-	struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev;
+	struct se_device *dev = tg_pt_gp->tg_pt_gp_dev;
 	struct t10_alua_tg_pt_gp *tg_pt_gp_tmp;
 	u16 tg_pt_gp_id_tmp;
+
 	/*
 	 * The tg_pt_gp->tg_pt_gp_id may only be set once..
 	 */
@@ -1421,19 +1415,19 @@ int core_alua_set_tg_pt_gp_id(
 		return -EINVAL;
 	}
 
-	spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
-	if (su_dev->t10_alua.alua_tg_pt_gps_count == 0x0000ffff) {
+	spin_lock(&dev->t10_alua.tg_pt_gps_lock);
+	if (dev->t10_alua.alua_tg_pt_gps_count == 0x0000ffff) {
 		pr_err("Maximum ALUA alua_tg_pt_gps_count:"
 			" 0x0000ffff reached\n");
-		spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+		spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 		kmem_cache_free(t10_alua_tg_pt_gp_cache, tg_pt_gp);
 		return -ENOSPC;
 	}
 again:
 	tg_pt_gp_id_tmp = (tg_pt_gp_id != 0) ? tg_pt_gp_id :
-			su_dev->t10_alua.alua_tg_pt_gps_counter++;
+			dev->t10_alua.alua_tg_pt_gps_counter++;
 
-	list_for_each_entry(tg_pt_gp_tmp, &su_dev->t10_alua.tg_pt_gps_list,
+	list_for_each_entry(tg_pt_gp_tmp, &dev->t10_alua.tg_pt_gps_list,
 			tg_pt_gp_list) {
 		if (tg_pt_gp_tmp->tg_pt_gp_id == tg_pt_gp_id_tmp) {
 			if (!tg_pt_gp_id)
@@ -1441,7 +1435,7 @@ again:
 
 			pr_err("ALUA Target Port Group ID: %hu already"
 				" exists, ignoring request\n", tg_pt_gp_id);
-			spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+			spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 			return -EINVAL;
 		}
 	}
@@ -1449,9 +1443,9 @@ again:
 	tg_pt_gp->tg_pt_gp_id = tg_pt_gp_id_tmp;
 	tg_pt_gp->tg_pt_gp_valid_id = 1;
 	list_add_tail(&tg_pt_gp->tg_pt_gp_list,
-			&su_dev->t10_alua.tg_pt_gps_list);
-	su_dev->t10_alua.alua_tg_pt_gps_count++;
-	spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+			&dev->t10_alua.tg_pt_gps_list);
+	dev->t10_alua.alua_tg_pt_gps_count++;
+	spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 
 	return 0;
 }
@@ -1480,8 +1474,9 @@ struct t10_alua_tg_pt_gp_member *core_alua_allocate_tg_pt_gp_mem(
 void core_alua_free_tg_pt_gp(
 	struct t10_alua_tg_pt_gp *tg_pt_gp)
 {
-	struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev;
+	struct se_device *dev = tg_pt_gp->tg_pt_gp_dev;
 	struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem, *tg_pt_gp_mem_tmp;
+
 	/*
 	 * Once we have reached this point, config_item_put() has already
 	 * been called from target_core_alua_drop_tg_pt_gp().
@@ -1490,10 +1485,11 @@ void core_alua_free_tg_pt_gp(
 	 * no assications *OR* explict ALUA via SET_TARGET_PORT_GROUPS
 	 * can be made while we are releasing struct t10_alua_tg_pt_gp.
 	 */
-	spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
+	spin_lock(&dev->t10_alua.tg_pt_gps_lock);
 	list_del(&tg_pt_gp->tg_pt_gp_list);
-	su_dev->t10_alua.alua_tg_pt_gps_counter--;
-	spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+	dev->t10_alua.alua_tg_pt_gps_counter--;
+	spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
+
 	/*
 	 * Allow a struct t10_alua_tg_pt_gp_member * referenced by
 	 * core_alua_get_tg_pt_gp_by_name() in
@@ -1502,6 +1498,7 @@ void core_alua_free_tg_pt_gp(
 	 */
 	while (atomic_read(&tg_pt_gp->tg_pt_gp_ref_cnt))
 		cpu_relax();
+
 	/*
 	 * Release reference to struct t10_alua_tg_pt_gp from all associated
 	 * struct se_port.
@@ -1525,9 +1522,9 @@ void core_alua_free_tg_pt_gp(
 		 * default_tg_pt_gp.
 		 */
 		spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
-		if (tg_pt_gp != su_dev->t10_alua.default_tg_pt_gp) {
+		if (tg_pt_gp != dev->t10_alua.default_tg_pt_gp) {
 			__core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem,
-					su_dev->t10_alua.default_tg_pt_gp);
+					dev->t10_alua.default_tg_pt_gp);
 		} else
 			tg_pt_gp_mem->tg_pt_gp = NULL;
 		spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
@@ -1541,8 +1538,7 @@ void core_alua_free_tg_pt_gp(
 
 void core_alua_free_tg_pt_gp_mem(struct se_port *port)
 {
-	struct se_subsystem_dev *su_dev = port->sep_lun->lun_se_dev->se_sub_dev;
-	struct t10_alua *alua = &su_dev->t10_alua;
+	struct t10_alua *alua = &port->sep_lun->lun_se_dev->t10_alua;
 	struct t10_alua_tg_pt_gp *tg_pt_gp;
 	struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
 
@@ -1574,25 +1570,24 @@ void core_alua_free_tg_pt_gp_mem(struct se_port *port)
 }
 
 static struct t10_alua_tg_pt_gp *core_alua_get_tg_pt_gp_by_name(
-	struct se_subsystem_dev *su_dev,
-	const char *name)
+		struct se_device *dev, const char *name)
 {
 	struct t10_alua_tg_pt_gp *tg_pt_gp;
 	struct config_item *ci;
 
-	spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
-	list_for_each_entry(tg_pt_gp, &su_dev->t10_alua.tg_pt_gps_list,
+	spin_lock(&dev->t10_alua.tg_pt_gps_lock);
+	list_for_each_entry(tg_pt_gp, &dev->t10_alua.tg_pt_gps_list,
 			tg_pt_gp_list) {
 		if (!tg_pt_gp->tg_pt_gp_valid_id)
 			continue;
 		ci = &tg_pt_gp->tg_pt_gp_group.cg_item;
 		if (!strcmp(config_item_name(ci), name)) {
 			atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt);
-			spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+			spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 			return tg_pt_gp;
 		}
 	}
-	spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+	spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 
 	return NULL;
 }
@@ -1600,11 +1595,11 @@ static struct t10_alua_tg_pt_gp *core_alua_get_tg_pt_gp_by_name(
 static void core_alua_put_tg_pt_gp_from_name(
 	struct t10_alua_tg_pt_gp *tg_pt_gp)
 {
-	struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev;
+	struct se_device *dev = tg_pt_gp->tg_pt_gp_dev;
 
-	spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
+	spin_lock(&dev->t10_alua.tg_pt_gps_lock);
 	atomic_dec(&tg_pt_gp->tg_pt_gp_ref_cnt);
-	spin_unlock(&su_dev->t10_alua.tg_pt_gps_lock);
+	spin_unlock(&dev->t10_alua.tg_pt_gps_lock);
 }
 
 /*
@@ -1640,9 +1635,8 @@ static void __core_alua_drop_tg_pt_gp_mem(
 
 ssize_t core_alua_show_tg_pt_gp_info(struct se_port *port, char *page)
 {
-	struct se_subsystem_dev *su_dev = port->sep_lun->lun_se_dev->se_sub_dev;
 	struct config_item *tg_pt_ci;
-	struct t10_alua *alua = &su_dev->t10_alua;
+	struct t10_alua *alua = &port->sep_lun->lun_se_dev->t10_alua;
 	struct t10_alua_tg_pt_gp *tg_pt_gp;
 	struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
 	ssize_t len = 0;
@@ -1683,7 +1677,7 @@ ssize_t core_alua_store_tg_pt_gp_info(
 {
 	struct se_portal_group *tpg;
 	struct se_lun *lun;
-	struct se_subsystem_dev *su_dev = port->sep_lun->lun_se_dev->se_sub_dev;
+	struct se_device *dev = port->sep_lun->lun_se_dev;
 	struct t10_alua_tg_pt_gp *tg_pt_gp = NULL, *tg_pt_gp_new = NULL;
 	struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
 	unsigned char buf[TG_PT_GROUP_NAME_BUF];
@@ -1692,7 +1686,7 @@ ssize_t core_alua_store_tg_pt_gp_info(
 	tpg = port->sep_tpg;
 	lun = port->sep_lun;
 
-	if (su_dev->t10_alua.alua_type != SPC3_ALUA_EMULATED) {
+	if (dev->t10_alua.alua_type != SPC3_ALUA_EMULATED) {
 		pr_warn("SPC3_ALUA_EMULATED not enabled for"
 			" %s/tpgt_%hu/%s\n", tpg->se_tpg_tfo->tpg_get_wwn(tpg),
 			tpg->se_tpg_tfo->tpg_get_tag(tpg),
@@ -1716,7 +1710,7 @@ ssize_t core_alua_store_tg_pt_gp_info(
 		 * struct t10_alua_tg_pt_gp.  This reference is released with
 		 * core_alua_put_tg_pt_gp_from_name() below.
 		 */
-		tg_pt_gp_new = core_alua_get_tg_pt_gp_by_name(su_dev,
+		tg_pt_gp_new = core_alua_get_tg_pt_gp_by_name(dev,
 					strstrip(buf));
 		if (!tg_pt_gp_new)
 			return -ENODEV;
@@ -1750,7 +1744,7 @@ ssize_t core_alua_store_tg_pt_gp_info(
 
 			__core_alua_drop_tg_pt_gp_mem(tg_pt_gp_mem, tg_pt_gp);
 			__core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem,
-					su_dev->t10_alua.default_tg_pt_gp);
+					dev->t10_alua.default_tg_pt_gp);
 			spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
 
 			return count;
@@ -2054,32 +2048,29 @@ ssize_t core_alua_store_secondary_write_metadata(
 	return count;
 }
 
-int core_setup_alua(struct se_device *dev, int force_pt)
+int core_setup_alua(struct se_device *dev)
 {
-	struct se_subsystem_dev *su_dev = dev->se_sub_dev;
-	struct t10_alua *alua = &su_dev->t10_alua;
+	struct t10_alua *alua = &dev->t10_alua;
 	struct t10_alua_lu_gp_member *lu_gp_mem;
+
 	/*
 	 * If this device is from Target_Core_Mod/pSCSI, use the ALUA logic
 	 * of the Underlying SCSI hardware.  In Linux/SCSI terms, this can
 	 * cause a problem because libata and some SATA RAID HBAs appear
 	 * under Linux/SCSI, but emulate SCSI logic themselves.
 	 */
-	if (((dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) &&
-	    !(dev->se_sub_dev->se_dev_attrib.emulate_alua)) || force_pt) {
-		alua->alua_type = SPC_ALUA_PASSTHROUGH;
-		alua->alua_state_check = &core_alua_state_check_nop;
+	if ((dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) ||
+	    (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV &&
+	     !dev->dev_attrib.emulate_alua)) {
 		pr_debug("%s: Using SPC_ALUA_PASSTHROUGH, no ALUA"
 			" emulation\n", dev->transport->name);
-		return 0;
-	}
-	/*
-	 * If SPC-3 or above is reported by real or emulated struct se_device,
-	 * use emulated ALUA.
-	 */
-	if (dev->transport->get_device_rev(dev) >= SCSI_3) {
+
+		alua->alua_type = SPC_ALUA_PASSTHROUGH;
+		alua->alua_state_check = &core_alua_state_check_nop;
+	} else if (dev->transport->get_device_rev(dev) >= SCSI_3) {
 		pr_debug("%s: Enabling ALUA Emulation for SPC-3"
 			" device\n", dev->transport->name);
+
 		/*
 		 * Associate this struct se_device with the default ALUA
 		 * LUN Group.
@@ -2099,10 +2090,11 @@ int core_setup_alua(struct se_device *dev, int force_pt)
 			" core/alua/lu_gps/default_lu_gp\n",
 			dev->transport->name);
 	} else {
-		alua->alua_type = SPC2_ALUA_DISABLED;
-		alua->alua_state_check = &core_alua_state_check_nop;
 		pr_debug("%s: Disabling ALUA Emulation for SPC-2"
 			" device\n", dev->transport->name);
+
+		alua->alua_type = SPC2_ALUA_DISABLED;
+		alua->alua_state_check = &core_alua_state_check_nop;
 	}
 
 	return 0;
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h
index f920c170d47b..5019157ffe69 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -91,7 +91,7 @@ extern void __core_alua_drop_lu_gp_mem(struct t10_alua_lu_gp_member *,
 					struct t10_alua_lu_gp *);
 extern void core_alua_drop_lu_gp_dev(struct se_device *);
 extern struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(
-			struct se_subsystem_dev *, const char *, int);
+			struct se_device *, const char *, int);
 extern int core_alua_set_tg_pt_gp_id(struct t10_alua_tg_pt_gp *, u16);
 extern struct t10_alua_tg_pt_gp_member *core_alua_allocate_tg_pt_gp_mem(
 					struct se_port *);
@@ -131,6 +131,6 @@ extern ssize_t core_alua_show_secondary_write_metadata(struct se_lun *,
 					char *);
 extern ssize_t core_alua_store_secondary_write_metadata(struct se_lun *,
 					const char *, size_t);
-extern int core_setup_alua(struct se_device *, int);
+extern int core_setup_alua(struct se_device *);
 
 #endif /* TARGET_CORE_ALUA_H */
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index c123327499a3..7272016ed05f 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -565,21 +565,8 @@ static ssize_t target_core_dev_show_attr_##_name(			\
 	struct se_dev_attrib *da,					\
 	char *page)							\
 {									\
-	struct se_device *dev;						\
-	struct se_subsystem_dev *se_dev = da->da_sub_dev;			\
-	ssize_t rb;							\
-									\
-	spin_lock(&se_dev->se_dev_lock);				\
-	dev = se_dev->se_dev_ptr;					\
-	if (!dev) {							\
-		spin_unlock(&se_dev->se_dev_lock); 			\
-		return -ENODEV;						\
-	}								\
-	rb = snprintf(page, PAGE_SIZE, "%u\n",				\
-		(u32)dev->se_sub_dev->se_dev_attrib._name);		\
-	spin_unlock(&se_dev->se_dev_lock);				\
-									\
-	return rb;							\
+	return snprintf(page, PAGE_SIZE, "%u\n",			\
+		(u32)da->da_dev->dev_attrib._name);			\
 }
 
 #define DEF_DEV_ATTRIB_STORE(_name)					\
@@ -588,26 +575,16 @@ static ssize_t target_core_dev_store_attr_##_name(			\
 	const char *page,						\
 	size_t count)							\
 {									\
-	struct se_device *dev;						\
-	struct se_subsystem_dev *se_dev = da->da_sub_dev;			\
 	unsigned long val;						\
 	int ret;							\
 									\
-	spin_lock(&se_dev->se_dev_lock);				\
-	dev = se_dev->se_dev_ptr;					\
-	if (!dev) {							\
-		spin_unlock(&se_dev->se_dev_lock);			\
-		return -ENODEV;						\
-	}								\
 	ret = strict_strtoul(page, 0, &val);				\
 	if (ret < 0) {							\
-		spin_unlock(&se_dev->se_dev_lock);                      \
 		pr_err("strict_strtoul() failed with"		\
 			" ret: %d\n", ret);				\
 		return -EINVAL;						\
 	}								\
-	ret = se_dev_set_##_name(dev, (u32)val);			\
-	spin_unlock(&se_dev->se_dev_lock);				\
+	ret = se_dev_set_##_name(da->da_dev, (u32)val);			\
 									\
 	return (!ret) ? count : -EINVAL;				\
 }
@@ -764,13 +741,6 @@ static ssize_t target_core_dev_wwn_show_attr_vpd_unit_serial(
 	struct t10_wwn *t10_wwn,
 	char *page)
 {
-	struct se_subsystem_dev *se_dev = t10_wwn->t10_sub_dev;
-	struct se_device *dev;
-
-	dev = se_dev->se_dev_ptr;
-	if (!dev)
-		return -ENODEV;
-
 	return sprintf(page, "T10 VPD Unit Serial Number: %s\n",
 		&t10_wwn->unit_serial[0]);
 }
@@ -780,8 +750,7 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial(
 	const char *page,
 	size_t count)
 {
-	struct se_subsystem_dev *su_dev = t10_wwn->t10_sub_dev;
-	struct se_device *dev;
+	struct se_device *dev = t10_wwn->t10_dev;
 	unsigned char buf[INQUIRY_VPD_SERIAL_LEN];
 
 	/*
@@ -794,7 +763,7 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial(
 	 * it is doing 'the right thing' wrt a world wide unique
 	 * VPD Unit Serial Number that OS dependent multipath can depend on.
 	 */
-	if (su_dev->su_dev_flags & SDF_FIRMWARE_VPD_UNIT_SERIAL) {
+	if (dev->dev_flags & DF_FIRMWARE_VPD_UNIT_SERIAL) {
 		pr_err("Underlying SCSI device firmware provided VPD"
 			" Unit Serial, ignoring request\n");
 		return -EOPNOTSUPP;
@@ -811,15 +780,13 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial(
 	 * (underneath the initiator side OS dependent multipath code)
 	 * could cause negative effects.
 	 */
-	dev = su_dev->se_dev_ptr;
-	if (dev) {
-		if (atomic_read(&dev->dev_export_obj.obj_access_count)) {
-			pr_err("Unable to set VPD Unit Serial while"
-				" active %d $FABRIC_MOD exports exist\n",
-				atomic_read(&dev->dev_export_obj.obj_access_count));
-			return -EINVAL;
-		}
+	if (dev->export_count) {
+		pr_err("Unable to set VPD Unit Serial while"
+			" active %d $FABRIC_MOD exports exist\n",
+			dev->export_count);
+		return -EINVAL;
 	}
+
 	/*
 	 * This currently assumes ASCII encoding for emulated VPD Unit Serial.
 	 *
@@ -828,12 +795,12 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial(
 	 */
 	memset(buf, 0, INQUIRY_VPD_SERIAL_LEN);
 	snprintf(buf, INQUIRY_VPD_SERIAL_LEN, "%s", page);
-	snprintf(su_dev->t10_wwn.unit_serial, INQUIRY_VPD_SERIAL_LEN,
+	snprintf(dev->t10_wwn.unit_serial, INQUIRY_VPD_SERIAL_LEN,
 			"%s", strstrip(buf));
-	su_dev->su_dev_flags |= SDF_EMULATED_VPD_UNIT_SERIAL;
+	dev->dev_flags |= DF_EMULATED_VPD_UNIT_SERIAL;
 
 	pr_debug("Target_Core_ConfigFS: Set emulated VPD Unit Serial:"
-			" %s\n", su_dev->t10_wwn.unit_serial);
+			" %s\n", dev->t10_wwn.unit_serial);
 
 	return count;
 }
@@ -847,16 +814,10 @@ static ssize_t target_core_dev_wwn_show_attr_vpd_protocol_identifier(
 	struct t10_wwn *t10_wwn,
 	char *page)
 {
-	struct se_subsystem_dev *se_dev = t10_wwn->t10_sub_dev;
-	struct se_device *dev;
 	struct t10_vpd *vpd;
 	unsigned char buf[VPD_TMP_BUF_SIZE];
 	ssize_t len = 0;
 
-	dev = se_dev->se_dev_ptr;
-	if (!dev)
-		return -ENODEV;
-
 	memset(buf, 0, VPD_TMP_BUF_SIZE);
 
 	spin_lock(&t10_wwn->t10_vpd_lock);
@@ -894,16 +855,10 @@ static ssize_t target_core_dev_wwn_show_attr_##_name(			\
 	struct t10_wwn *t10_wwn,					\
 	char *page)							\
 {									\
-	struct se_subsystem_dev *se_dev = t10_wwn->t10_sub_dev;		\
-	struct se_device *dev;						\
 	struct t10_vpd *vpd;							\
 	unsigned char buf[VPD_TMP_BUF_SIZE];				\
 	ssize_t len = 0;						\
 									\
-	dev = se_dev->se_dev_ptr;					\
-	if (!dev)							\
-		return -ENODEV;						\
-									\
 	spin_lock(&t10_wwn->t10_vpd_lock);				\
 	list_for_each_entry(vpd, &t10_wwn->t10_vpd_list, vpd_list) {	\
 		if (vpd->association != _assoc)				\
@@ -1003,7 +958,7 @@ static struct config_item_type target_core_dev_wwn_cit = {
 
 /*  Start functions for struct config_item_type target_core_dev_pr_cit */
 
-CONFIGFS_EATTR_STRUCT(target_core_dev_pr, se_subsystem_dev);
+CONFIGFS_EATTR_STRUCT(target_core_dev_pr, se_device);
 #define SE_DEV_PR_ATTR(_name, _mode)					\
 static struct target_core_dev_pr_attribute target_core_dev_pr_##_name = \
 	__CONFIGFS_EATTR(_name, _mode,					\
@@ -1071,23 +1026,17 @@ static ssize_t target_core_dev_pr_show_spc2_res(
 	return *len;
 }
 
-static ssize_t target_core_dev_pr_show_attr_res_holder(
-	struct se_subsystem_dev *su_dev,
-	char *page)
+static ssize_t target_core_dev_pr_show_attr_res_holder(struct se_device *dev,
+		char *page)
 {
 	ssize_t len = 0;
 
-	if (!su_dev->se_dev_ptr)
-		return -ENODEV;
-
-	switch (su_dev->t10_pr.res_type) {
+	switch (dev->t10_pr.res_type) {
 	case SPC3_PERSISTENT_RESERVATIONS:
-		target_core_dev_pr_show_spc3_res(su_dev->se_dev_ptr,
-				page, &len);
+		target_core_dev_pr_show_spc3_res(dev, page, &len);
 		break;
 	case SPC2_RESERVATIONS:
-		target_core_dev_pr_show_spc2_res(su_dev->se_dev_ptr,
-				page, &len);
+		target_core_dev_pr_show_spc2_res(dev, page, &len);
 		break;
 	case SPC_PASSTHROUGH:
 		len += sprintf(page+len, "Passthrough\n");
@@ -1102,22 +1051,13 @@ static ssize_t target_core_dev_pr_show_attr_res_holder(
 
 SE_DEV_PR_ATTR_RO(res_holder);
 
-/*
- * res_pr_all_tgt_pts
- */
 static ssize_t target_core_dev_pr_show_attr_res_pr_all_tgt_pts(
-	struct se_subsystem_dev *su_dev,
-	char *page)
+		struct se_device *dev, char *page)
 {
-	struct se_device *dev;
 	struct t10_pr_registration *pr_reg;
 	ssize_t len = 0;
 
-	dev = su_dev->se_dev_ptr;
-	if (!dev)
-		return -ENODEV;
-
-	if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
+	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
 		return len;
 
 	spin_lock(&dev->dev_reservation_lock);
@@ -1144,20 +1084,13 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_all_tgt_pts(
 
 SE_DEV_PR_ATTR_RO(res_pr_all_tgt_pts);
 
-/*
- * res_pr_generation
- */
 static ssize_t target_core_dev_pr_show_attr_res_pr_generation(
-	struct se_subsystem_dev *su_dev,
-	char *page)
+		struct se_device *dev, char *page)
 {
-	if (!su_dev->se_dev_ptr)
-		return -ENODEV;
-
-	if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
+	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
 		return 0;
 
-	return sprintf(page, "0x%08x\n", su_dev->t10_pr.pr_generation);
+	return sprintf(page, "0x%08x\n", dev->t10_pr.pr_generation);
 }
 
 SE_DEV_PR_ATTR_RO(res_pr_generation);
@@ -1166,10 +1099,8 @@ SE_DEV_PR_ATTR_RO(res_pr_generation);
  * res_pr_holder_tg_port
  */
 static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port(
-	struct se_subsystem_dev *su_dev,
-	char *page)
+		struct se_device *dev, char *page)
 {
-	struct se_device *dev;
 	struct se_node_acl *se_nacl;
 	struct se_lun *lun;
 	struct se_portal_group *se_tpg;
@@ -1177,11 +1108,7 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port(
 	struct target_core_fabric_ops *tfo;
 	ssize_t len = 0;
 
-	dev = su_dev->se_dev_ptr;
-	if (!dev)
-		return -ENODEV;
-
-	if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
+	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
 		return len;
 
 	spin_lock(&dev->dev_reservation_lock);
@@ -1211,12 +1138,8 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port(
 
 SE_DEV_PR_ATTR_RO(res_pr_holder_tg_port);
 
-/*
- * res_pr_registered_i_pts
- */
 static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts(
-	struct se_subsystem_dev *su_dev,
-	char *page)
+		struct se_device *dev, char *page)
 {
 	struct target_core_fabric_ops *tfo;
 	struct t10_pr_registration *pr_reg;
@@ -1225,16 +1148,13 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts(
 	ssize_t len = 0;
 	int reg_count = 0, prf_isid;
 
-	if (!su_dev->se_dev_ptr)
-		return -ENODEV;
-
-	if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
+	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
 		return len;
 
 	len += sprintf(page+len, "SPC-3 PR Registrations:\n");
 
-	spin_lock(&su_dev->t10_pr.registration_lock);
-	list_for_each_entry(pr_reg, &su_dev->t10_pr.registration_list,
+	spin_lock(&dev->t10_pr.registration_lock);
+	list_for_each_entry(pr_reg, &dev->t10_pr.registration_list,
 			pr_reg_list) {
 
 		memset(buf, 0, 384);
@@ -1254,7 +1174,7 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts(
 		len += sprintf(page+len, "%s", buf);
 		reg_count++;
 	}
-	spin_unlock(&su_dev->t10_pr.registration_lock);
+	spin_unlock(&dev->t10_pr.registration_lock);
 
 	if (!reg_count)
 		len += sprintf(page+len, "None\n");
@@ -1264,22 +1184,13 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts(
 
 SE_DEV_PR_ATTR_RO(res_pr_registered_i_pts);
 
-/*
- * res_pr_type
- */
 static ssize_t target_core_dev_pr_show_attr_res_pr_type(
-	struct se_subsystem_dev *su_dev,
-	char *page)
+		struct se_device *dev, char *page)
 {
-	struct se_device *dev;
 	struct t10_pr_registration *pr_reg;
 	ssize_t len = 0;
 
-	dev = su_dev->se_dev_ptr;
-	if (!dev)
-		return -ENODEV;
-
-	if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
+	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
 		return len;
 
 	spin_lock(&dev->dev_reservation_lock);
@@ -1298,19 +1209,12 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_type(
 
 SE_DEV_PR_ATTR_RO(res_pr_type);
 
-/*
- * res_type
- */
 static ssize_t target_core_dev_pr_show_attr_res_type(
-	struct se_subsystem_dev *su_dev,
-	char *page)
+		struct se_device *dev, char *page)
 {
 	ssize_t len = 0;
 
-	if (!su_dev->se_dev_ptr)
-		return -ENODEV;
-
-	switch (su_dev->t10_pr.res_type) {
+	switch (dev->t10_pr.res_type) {
 	case SPC3_PERSISTENT_RESERVATIONS:
 		len = sprintf(page, "SPC3_PERSISTENT_RESERVATIONS\n");
 		break;
@@ -1330,22 +1234,14 @@ static ssize_t target_core_dev_pr_show_attr_res_type(
 
 SE_DEV_PR_ATTR_RO(res_type);
 
-/*
- * res_aptpl_active
- */
-
 static ssize_t target_core_dev_pr_show_attr_res_aptpl_active(
-	struct se_subsystem_dev *su_dev,
-	char *page)
+		struct se_device *dev, char *page)
 {
-	if (!su_dev->se_dev_ptr)
-		return -ENODEV;
-
-	if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
+	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
 		return 0;
 
 	return sprintf(page, "APTPL Bit Status: %s\n",
-		(su_dev->t10_pr.pr_aptpl_active) ? "Activated" : "Disabled");
+		(dev->t10_pr.pr_aptpl_active) ? "Activated" : "Disabled");
 }
 
 SE_DEV_PR_ATTR_RO(res_aptpl_active);
@@ -1354,13 +1250,9 @@ SE_DEV_PR_ATTR_RO(res_aptpl_active);
  * res_aptpl_metadata
  */
 static ssize_t target_core_dev_pr_show_attr_res_aptpl_metadata(
-	struct se_subsystem_dev *su_dev,
-	char *page)
+		struct se_device *dev, char *page)
 {
-	if (!su_dev->se_dev_ptr)
-		return -ENODEV;
-
-	if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
+	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
 		return 0;
 
 	return sprintf(page, "Ready to process PR APTPL metadata..\n");
@@ -1392,11 +1284,10 @@ static match_table_t tokens = {
 };
 
 static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
-	struct se_subsystem_dev *su_dev,
+	struct se_device *dev,
 	const char *page,
 	size_t count)
 {
-	struct se_device *dev;
 	unsigned char *i_fabric = NULL, *i_port = NULL, *isid = NULL;
 	unsigned char *t_fabric = NULL, *t_port = NULL;
 	char *orig, *ptr, *arg_p, *opts;
@@ -1408,14 +1299,10 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
 	u16 port_rpti = 0, tpgt = 0;
 	u8 type = 0, scope;
 
-	dev = su_dev->se_dev_ptr;
-	if (!dev)
-		return -ENODEV;
-
-	if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
+	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
 		return 0;
 
-	if (atomic_read(&dev->dev_export_obj.obj_access_count)) {
+	if (dev->export_count) {
 		pr_debug("Unable to process APTPL metadata while"
 			" active fabric exports exist\n");
 		return -EINVAL;
@@ -1558,7 +1445,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
 		goto out;
 	}
 
-	ret = core_scsi3_alloc_aptpl_registration(&su_dev->t10_pr, sa_res_key,
+	ret = core_scsi3_alloc_aptpl_registration(&dev->t10_pr, sa_res_key,
 			i_port, isid, mapped_lun, t_port, tpgt, target_lun,
 			res_holder, all_tg_pt, type);
 out:
@@ -1573,7 +1460,7 @@ out:
 
 SE_DEV_PR_ATTR(res_aptpl_metadata, S_IRUGO | S_IWUSR);
 
-CONFIGFS_EATTR_OPS(target_core_dev_pr, se_subsystem_dev, se_dev_pr_group);
+CONFIGFS_EATTR_OPS(target_core_dev_pr, se_device, dev_pr_group);
 
 static struct configfs_attribute *target_core_dev_pr_attrs[] = {
 	&target_core_dev_pr_res_holder.attr,
@@ -1605,18 +1492,14 @@ static struct config_item_type target_core_dev_pr_cit = {
 
 static ssize_t target_core_show_dev_info(void *p, char *page)
 {
-	struct se_subsystem_dev *se_dev = p;
-	struct se_hba *hba = se_dev->se_dev_hba;
-	struct se_subsystem_api *t = hba->transport;
+	struct se_device *dev = p;
+	struct se_subsystem_api *t = dev->transport;
 	int bl = 0;
 	ssize_t read_bytes = 0;
 
-	if (!se_dev->se_dev_ptr)
-		return -ENODEV;
-
-	transport_dump_dev_state(se_dev->se_dev_ptr, page, &bl);
+	transport_dump_dev_state(dev, page, &bl);
 	read_bytes += bl;
-	read_bytes += t->show_configfs_dev_params(hba, se_dev, page+read_bytes);
+	read_bytes += t->show_configfs_dev_params(dev, page+read_bytes);
 	return read_bytes;
 }
 
@@ -1633,17 +1516,10 @@ static ssize_t target_core_store_dev_control(
 	const char *page,
 	size_t count)
 {
-	struct se_subsystem_dev *se_dev = p;
-	struct se_hba *hba = se_dev->se_dev_hba;
-	struct se_subsystem_api *t = hba->transport;
+	struct se_device *dev = p;
+	struct se_subsystem_api *t = dev->transport;
 
-	if (!se_dev->se_dev_su_ptr) {
-		pr_err("Unable to locate struct se_subsystem_dev>se"
-				"_dev_su_ptr\n");
-		return -EINVAL;
-	}
-
-	return t->set_configfs_dev_params(hba, se_dev, page, count);
+	return t->set_configfs_dev_params(dev, page, count);
 }
 
 static struct target_core_configfs_attribute target_core_attr_dev_control = {
@@ -1656,12 +1532,12 @@ static struct target_core_configfs_attribute target_core_attr_dev_control = {
 
 static ssize_t target_core_show_dev_alias(void *p, char *page)
 {
-	struct se_subsystem_dev *se_dev = p;
+	struct se_device *dev = p;
 
-	if (!(se_dev->su_dev_flags & SDF_USING_ALIAS))
+	if (!(dev->dev_flags & DF_USING_ALIAS))
 		return 0;
 
-	return snprintf(page, PAGE_SIZE, "%s\n", se_dev->se_dev_alias);
+	return snprintf(page, PAGE_SIZE, "%s\n", dev->dev_alias);
 }
 
 static ssize_t target_core_store_dev_alias(
@@ -1669,8 +1545,8 @@ static ssize_t target_core_store_dev_alias(
 	const char *page,
 	size_t count)
 {
-	struct se_subsystem_dev *se_dev = p;
-	struct se_hba *hba = se_dev->se_dev_hba;
+	struct se_device *dev = p;
+	struct se_hba *hba = dev->se_hba;
 	ssize_t read_bytes;
 
 	if (count > (SE_DEV_ALIAS_LEN-1)) {
@@ -1680,19 +1556,18 @@ static ssize_t target_core_store_dev_alias(
 		return -EINVAL;
 	}
 
-	read_bytes = snprintf(&se_dev->se_dev_alias[0], SE_DEV_ALIAS_LEN,
-			"%s", page);
+	read_bytes = snprintf(&dev->dev_alias[0], SE_DEV_ALIAS_LEN, "%s", page);
 	if (!read_bytes)
 		return -EINVAL;
-	if (se_dev->se_dev_alias[read_bytes - 1] == '\n')
-		se_dev->se_dev_alias[read_bytes - 1] = '\0';
+	if (dev->dev_alias[read_bytes - 1] == '\n')
+		dev->dev_alias[read_bytes - 1] = '\0';
 
-	se_dev->su_dev_flags |= SDF_USING_ALIAS;
+	dev->dev_flags |= DF_USING_ALIAS;
 
 	pr_debug("Target_Core_ConfigFS: %s/%s set alias: %s\n",
 		config_item_name(&hba->hba_group.cg_item),
-		config_item_name(&se_dev->se_dev_group.cg_item),
-		se_dev->se_dev_alias);
+		config_item_name(&dev->dev_group.cg_item),
+		dev->dev_alias);
 
 	return read_bytes;
 }
@@ -1707,12 +1582,12 @@ static struct target_core_configfs_attribute target_core_attr_dev_alias = {
 
 static ssize_t target_core_show_dev_udev_path(void *p, char *page)
 {
-	struct se_subsystem_dev *se_dev = p;
+	struct se_device *dev = p;
 
-	if (!(se_dev->su_dev_flags & SDF_USING_UDEV_PATH))
+	if (!(dev->dev_flags & DF_USING_UDEV_PATH))
 		return 0;
 
-	return snprintf(page, PAGE_SIZE, "%s\n", se_dev->se_dev_udev_path);
+	return snprintf(page, PAGE_SIZE, "%s\n", dev->udev_path);
 }
 
 static ssize_t target_core_store_dev_udev_path(
@@ -1720,8 +1595,8 @@ static ssize_t target_core_store_dev_udev_path(
 	const char *page,
 	size_t count)
 {
-	struct se_subsystem_dev *se_dev = p;
-	struct se_hba *hba = se_dev->se_dev_hba;
+	struct se_device *dev = p;
+	struct se_hba *hba = dev->se_hba;
 	ssize_t read_bytes;
 
 	if (count > (SE_UDEV_PATH_LEN-1)) {
@@ -1731,19 +1606,19 @@ static ssize_t target_core_store_dev_udev_path(
 		return -EINVAL;
 	}
 
-	read_bytes = snprintf(&se_dev->se_dev_udev_path[0], SE_UDEV_PATH_LEN,
+	read_bytes = snprintf(&dev->udev_path[0], SE_UDEV_PATH_LEN,
 			"%s", page);
 	if (!read_bytes)
 		return -EINVAL;
-	if (se_dev->se_dev_udev_path[read_bytes - 1] == '\n')
-		se_dev->se_dev_udev_path[read_bytes - 1] = '\0';
+	if (dev->udev_path[read_bytes - 1] == '\n')
+		dev->udev_path[read_bytes - 1] = '\0';
 
-	se_dev->su_dev_flags |= SDF_USING_UDEV_PATH;
+	dev->dev_flags |= DF_USING_UDEV_PATH;
 
 	pr_debug("Target_Core_ConfigFS: %s/%s set udev_path: %s\n",
 		config_item_name(&hba->hba_group.cg_item),
-		config_item_name(&se_dev->se_dev_group.cg_item),
-		se_dev->se_dev_udev_path);
+		config_item_name(&dev->dev_group.cg_item),
+		dev->udev_path);
 
 	return read_bytes;
 }
@@ -1761,11 +1636,9 @@ static ssize_t target_core_store_dev_enable(
 	const char *page,
 	size_t count)
 {
-	struct se_subsystem_dev *se_dev = p;
-	struct se_device *dev;
-	struct se_hba *hba = se_dev->se_dev_hba;
-	struct se_subsystem_api *t = hba->transport;
+	struct se_device *dev = p;
 	char *ptr;
+	int ret;
 
 	ptr = strstr(page, "1");
 	if (!ptr) {
@@ -1773,25 +1646,10 @@ static ssize_t target_core_store_dev_enable(
 				" is \"1\"\n");
 		return -EINVAL;
 	}
-	if (se_dev->se_dev_ptr) {
-		pr_err("se_dev->se_dev_ptr already set for storage"
-				" object\n");
-		return -EEXIST;
-	}
-
-	if (t->check_configfs_dev_params(hba, se_dev) < 0)
-		return -EINVAL;
-
-	dev = t->create_virtdevice(hba, se_dev, se_dev->se_dev_su_ptr);
-	if (IS_ERR(dev))
-		return PTR_ERR(dev);
-	else if (!dev)
-		return -EINVAL;
-
-	se_dev->se_dev_ptr = dev;
-	pr_debug("Target_Core_ConfigFS: Registered se_dev->se_dev_ptr:"
-		" %p\n", se_dev->se_dev_ptr);
 
+	ret = target_configure_device(dev);
+	if (ret)
+		return ret;
 	return count;
 }
 
@@ -1805,18 +1663,13 @@ static struct target_core_configfs_attribute target_core_attr_dev_enable = {
 
 static ssize_t target_core_show_alua_lu_gp(void *p, char *page)
 {
-	struct se_device *dev;
-	struct se_subsystem_dev *su_dev = p;
+	struct se_device *dev = p;
 	struct config_item *lu_ci;
 	struct t10_alua_lu_gp *lu_gp;
 	struct t10_alua_lu_gp_member *lu_gp_mem;
 	ssize_t len = 0;
 
-	dev = su_dev->se_dev_ptr;
-	if (!dev)
-		return -ENODEV;
-
-	if (su_dev->t10_alua.alua_type != SPC3_ALUA_EMULATED)
+	if (dev->t10_alua.alua_type != SPC3_ALUA_EMULATED)
 		return len;
 
 	lu_gp_mem = dev->dev_alua_lu_gp_mem;
@@ -1843,22 +1696,17 @@ static ssize_t target_core_store_alua_lu_gp(
 	const char *page,
 	size_t count)
 {
-	struct se_device *dev;
-	struct se_subsystem_dev *su_dev = p;
-	struct se_hba *hba = su_dev->se_dev_hba;
+	struct se_device *dev = p;
+	struct se_hba *hba = dev->se_hba;
 	struct t10_alua_lu_gp *lu_gp = NULL, *lu_gp_new = NULL;
 	struct t10_alua_lu_gp_member *lu_gp_mem;
 	unsigned char buf[LU_GROUP_NAME_BUF];
 	int move = 0;
 
-	dev = su_dev->se_dev_ptr;
-	if (!dev)
-		return -ENODEV;
-
-	if (su_dev->t10_alua.alua_type != SPC3_ALUA_EMULATED) {
+	if (dev->t10_alua.alua_type != SPC3_ALUA_EMULATED) {
 		pr_warn("SPC3_ALUA_EMULATED not enabled for %s/%s\n",
 			config_item_name(&hba->hba_group.cg_item),
-			config_item_name(&su_dev->se_dev_group.cg_item));
+			config_item_name(&dev->dev_group.cg_item));
 		return -EINVAL;
 	}
 	if (count > LU_GROUP_NAME_BUF) {
@@ -1902,7 +1750,7 @@ static ssize_t target_core_store_alua_lu_gp(
 				" from ALUA LU Group: core/alua/lu_gps/%s, ID:"
 				" %hu\n",
 				config_item_name(&hba->hba_group.cg_item),
-				config_item_name(&su_dev->se_dev_group.cg_item),
+				config_item_name(&dev->dev_group.cg_item),
 				config_item_name(&lu_gp->lu_gp_group.cg_item),
 				lu_gp->lu_gp_id);
 
@@ -1927,7 +1775,7 @@ static ssize_t target_core_store_alua_lu_gp(
 		" core/alua/lu_gps/%s, ID: %hu\n",
 		(move) ? "Moving" : "Adding",
 		config_item_name(&hba->hba_group.cg_item),
-		config_item_name(&su_dev->se_dev_group.cg_item),
+		config_item_name(&dev->dev_group.cg_item),
 		config_item_name(&lu_gp_new->lu_gp_group.cg_item),
 		lu_gp_new->lu_gp_id);
 
@@ -1955,69 +1803,44 @@ static struct configfs_attribute *lio_core_dev_attrs[] = {
 
 static void target_core_dev_release(struct config_item *item)
 {
-	struct se_subsystem_dev *se_dev = container_of(to_config_group(item),
-				struct se_subsystem_dev, se_dev_group);
-	struct se_hba *hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item);
-	struct se_subsystem_api *t = hba->transport;
-	struct config_group *dev_cg = &se_dev->se_dev_group;
+	struct config_group *dev_cg = to_config_group(item);
+	struct se_device *dev =
+		container_of(dev_cg, struct se_device, dev_group);
 
 	kfree(dev_cg->default_groups);
-	/*
-	 * This pointer will set when the storage is enabled with:
-	 *`echo 1 > $CONFIGFS/core/$HBA/$DEV/dev_enable`
-	 */
-	if (se_dev->se_dev_ptr) {
-		pr_debug("Target_Core_ConfigFS: Calling se_free_"
-			"virtual_device() for se_dev_ptr: %p\n",
-			se_dev->se_dev_ptr);
-
-		se_free_virtual_device(se_dev->se_dev_ptr, hba);
-	} else {
-		/*
-		 * Release struct se_subsystem_dev->se_dev_su_ptr..
-		 */
-		pr_debug("Target_Core_ConfigFS: Calling t->free_"
-			"device() for se_dev_su_ptr: %p\n",
-			se_dev->se_dev_su_ptr);
-
-		t->free_device(se_dev->se_dev_su_ptr);
-	}
-
-	pr_debug("Target_Core_ConfigFS: Deallocating se_subsystem"
-			"_dev_t: %p\n", se_dev);
-	kfree(se_dev);
+	target_free_device(dev);
 }
 
 static ssize_t target_core_dev_show(struct config_item *item,
 				     struct configfs_attribute *attr,
 				     char *page)
 {
-	struct se_subsystem_dev *se_dev = container_of(
-			to_config_group(item), struct se_subsystem_dev,
-			se_dev_group);
+	struct config_group *dev_cg = to_config_group(item);
+	struct se_device *dev =
+		container_of(dev_cg, struct se_device, dev_group);
 	struct target_core_configfs_attribute *tc_attr = container_of(
 			attr, struct target_core_configfs_attribute, attr);
 
 	if (!tc_attr->show)
 		return -EINVAL;
 
-	return tc_attr->show(se_dev, page);
+	return tc_attr->show(dev, page);
 }
 
 static ssize_t target_core_dev_store(struct config_item *item,
 				      struct configfs_attribute *attr,
 				      const char *page, size_t count)
 {
-	struct se_subsystem_dev *se_dev = container_of(
-			to_config_group(item), struct se_subsystem_dev,
-			se_dev_group);
+	struct config_group *dev_cg = to_config_group(item);
+	struct se_device *dev =
+		container_of(dev_cg, struct se_device, dev_group);
 	struct target_core_configfs_attribute *tc_attr = container_of(
 			attr, struct target_core_configfs_attribute, attr);
 
 	if (!tc_attr->store)
 		return -EINVAL;
 
-	return tc_attr->store(se_dev, page, count);
+	return tc_attr->store(dev, page, count);
 }
 
 static struct configfs_item_operations target_core_dev_item_ops = {
@@ -2107,7 +1930,6 @@ static ssize_t target_core_alua_lu_gp_show_attr_members(
 {
 	struct se_device *dev;
 	struct se_hba *hba;
-	struct se_subsystem_dev *su_dev;
 	struct t10_alua_lu_gp_member *lu_gp_mem;
 	ssize_t len = 0, cur_len;
 	unsigned char buf[LU_GROUP_NAME_BUF];
@@ -2117,12 +1939,11 @@ static ssize_t target_core_alua_lu_gp_show_attr_members(
 	spin_lock(&lu_gp->lu_gp_lock);
 	list_for_each_entry(lu_gp_mem, &lu_gp->lu_gp_mem_list, lu_gp_mem_list) {
 		dev = lu_gp_mem->lu_gp_mem_dev;
-		su_dev = dev->se_sub_dev;
-		hba = su_dev->se_dev_hba;
+		hba = dev->se_hba;
 
 		cur_len = snprintf(buf, LU_GROUP_NAME_BUF, "%s/%s\n",
 			config_item_name(&hba->hba_group.cg_item),
-			config_item_name(&su_dev->se_dev_group.cg_item));
+			config_item_name(&dev->dev_group.cg_item));
 		cur_len++; /* Extra byte for NULL terminator */
 
 		if ((cur_len + len) > PAGE_SIZE) {
@@ -2260,7 +2081,7 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state(
 	const char *page,
 	size_t count)
 {
-	struct se_subsystem_dev *su_dev = tg_pt_gp->tg_pt_gp_su_dev;
+	struct se_device *dev = tg_pt_gp->tg_pt_gp_dev;
 	unsigned long tmp;
 	int new_state, ret;
 
@@ -2284,7 +2105,7 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state(
 		return -EINVAL;
 	}
 
-	ret = core_alua_do_port_transition(tg_pt_gp, su_dev->se_dev_ptr,
+	ret = core_alua_do_port_transition(tg_pt_gp, dev,
 					NULL, NULL, new_state, 0);
 	return (!ret) ? count : -EINVAL;
 }
@@ -2620,11 +2441,10 @@ static struct config_group *target_core_alua_create_tg_pt_gp(
 	struct t10_alua *alua = container_of(group, struct t10_alua,
 					alua_tg_pt_gps_group);
 	struct t10_alua_tg_pt_gp *tg_pt_gp;
-	struct se_subsystem_dev *su_dev = alua->t10_sub_dev;
 	struct config_group *alua_tg_pt_gp_cg = NULL;
 	struct config_item *alua_tg_pt_gp_ci = NULL;
 
-	tg_pt_gp = core_alua_allocate_tg_pt_gp(su_dev, name, 0);
+	tg_pt_gp = core_alua_allocate_tg_pt_gp(alua->t10_dev, name, 0);
 	if (!tg_pt_gp)
 		return NULL;
 
@@ -2721,10 +2541,10 @@ static struct config_group *target_core_make_subdev(
 	const char *name)
 {
 	struct t10_alua_tg_pt_gp *tg_pt_gp;
-	struct se_subsystem_dev *se_dev;
 	struct se_subsystem_api *t;
 	struct config_item *hba_ci = &group->cg_item;
 	struct se_hba *hba = item_to_hba(hba_ci);
+	struct se_device *dev;
 	struct config_group *dev_cg = NULL, *tg_pt_gp_cg = NULL;
 	struct config_group *dev_stat_grp = NULL;
 	int errno = -ENOMEM, ret;
@@ -2737,120 +2557,80 @@ static struct config_group *target_core_make_subdev(
 	 */
 	t = hba->transport;
 
-	se_dev = kzalloc(sizeof(struct se_subsystem_dev), GFP_KERNEL);
-	if (!se_dev) {
-		pr_err("Unable to allocate memory for"
-				" struct se_subsystem_dev\n");
-		goto unlock;
-	}
-	INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list);
-	spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock);
-	INIT_LIST_HEAD(&se_dev->t10_pr.registration_list);
-	INIT_LIST_HEAD(&se_dev->t10_pr.aptpl_reg_list);
-	spin_lock_init(&se_dev->t10_pr.registration_lock);
-	spin_lock_init(&se_dev->t10_pr.aptpl_reg_lock);
-	INIT_LIST_HEAD(&se_dev->t10_alua.tg_pt_gps_list);
-	spin_lock_init(&se_dev->t10_alua.tg_pt_gps_lock);
-	spin_lock_init(&se_dev->se_dev_lock);
-	se_dev->t10_pr.pr_aptpl_buf_len = PR_APTPL_BUF_LEN;
-	se_dev->t10_wwn.t10_sub_dev = se_dev;
-	se_dev->t10_alua.t10_sub_dev = se_dev;
-	se_dev->se_dev_attrib.da_sub_dev = se_dev;
-
-	se_dev->se_dev_hba = hba;
-	dev_cg = &se_dev->se_dev_group;
+	dev = target_alloc_device(hba, name);
+	if (!dev)
+		goto out_unlock;
+
+	dev_cg = &dev->dev_group;
 
 	dev_cg->default_groups = kzalloc(sizeof(struct config_group) * 7,
 			GFP_KERNEL);
 	if (!dev_cg->default_groups)
-		goto out;
-	/*
-	 * Set se_dev_su_ptr from struct se_subsystem_api returned void ptr
-	 * for ->allocate_virtdevice()
-	 *
-	 * se_dev->se_dev_ptr will be set after ->create_virtdev()
-	 * has been called successfully in the next level up in the
-	 * configfs tree for device object's struct config_group.
-	 */
-	se_dev->se_dev_su_ptr = t->allocate_virtdevice(hba, name);
-	if (!se_dev->se_dev_su_ptr) {
-		pr_err("Unable to locate subsystem dependent pointer"
-			" from allocate_virtdevice()\n");
-		goto out;
-	}
+		goto out_free_device;
 
-	config_group_init_type_name(&se_dev->se_dev_group, name,
-			&target_core_dev_cit);
-	config_group_init_type_name(&se_dev->se_dev_attrib.da_group, "attrib",
+	config_group_init_type_name(dev_cg, name, &target_core_dev_cit);
+	config_group_init_type_name(&dev->dev_attrib.da_group, "attrib",
 			&target_core_dev_attrib_cit);
-	config_group_init_type_name(&se_dev->se_dev_pr_group, "pr",
+	config_group_init_type_name(&dev->dev_pr_group, "pr",
 			&target_core_dev_pr_cit);
-	config_group_init_type_name(&se_dev->t10_wwn.t10_wwn_group, "wwn",
+	config_group_init_type_name(&dev->t10_wwn.t10_wwn_group, "wwn",
 			&target_core_dev_wwn_cit);
-	config_group_init_type_name(&se_dev->t10_alua.alua_tg_pt_gps_group,
+	config_group_init_type_name(&dev->t10_alua.alua_tg_pt_gps_group,
 			"alua", &target_core_alua_tg_pt_gps_cit);
-	config_group_init_type_name(&se_dev->dev_stat_grps.stat_group,
+	config_group_init_type_name(&dev->dev_stat_grps.stat_group,
 			"statistics", &target_core_stat_cit);
 
-	dev_cg->default_groups[0] = &se_dev->se_dev_attrib.da_group;
-	dev_cg->default_groups[1] = &se_dev->se_dev_pr_group;
-	dev_cg->default_groups[2] = &se_dev->t10_wwn.t10_wwn_group;
-	dev_cg->default_groups[3] = &se_dev->t10_alua.alua_tg_pt_gps_group;
-	dev_cg->default_groups[4] = &se_dev->dev_stat_grps.stat_group;
+	dev_cg->default_groups[0] = &dev->dev_attrib.da_group;
+	dev_cg->default_groups[1] = &dev->dev_pr_group;
+	dev_cg->default_groups[2] = &dev->t10_wwn.t10_wwn_group;
+	dev_cg->default_groups[3] = &dev->t10_alua.alua_tg_pt_gps_group;
+	dev_cg->default_groups[4] = &dev->dev_stat_grps.stat_group;
 	dev_cg->default_groups[5] = NULL;
 	/*
 	 * Add core/$HBA/$DEV/alua/default_tg_pt_gp
 	 */
-	tg_pt_gp = core_alua_allocate_tg_pt_gp(se_dev, "default_tg_pt_gp", 1);
+	tg_pt_gp = core_alua_allocate_tg_pt_gp(dev, "default_tg_pt_gp", 1);
 	if (!tg_pt_gp)
-		goto out;
+		goto out_free_dev_cg_default_groups;
+	dev->t10_alua.default_tg_pt_gp = tg_pt_gp;
 
-	tg_pt_gp_cg = &se_dev->t10_alua.alua_tg_pt_gps_group;
+	tg_pt_gp_cg = &dev->t10_alua.alua_tg_pt_gps_group;
 	tg_pt_gp_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
 				GFP_KERNEL);
 	if (!tg_pt_gp_cg->default_groups) {
 		pr_err("Unable to allocate tg_pt_gp_cg->"
 				"default_groups\n");
-		goto out;
+		goto out_free_tg_pt_gp;
 	}
 
 	config_group_init_type_name(&tg_pt_gp->tg_pt_gp_group,
 			"default_tg_pt_gp", &target_core_alua_tg_pt_gp_cit);
 	tg_pt_gp_cg->default_groups[0] = &tg_pt_gp->tg_pt_gp_group;
 	tg_pt_gp_cg->default_groups[1] = NULL;
-	se_dev->t10_alua.default_tg_pt_gp = tg_pt_gp;
 	/*
 	 * Add core/$HBA/$DEV/statistics/ default groups
 	 */
-	dev_stat_grp = &se_dev->dev_stat_grps.stat_group;
+	dev_stat_grp = &dev->dev_stat_grps.stat_group;
 	dev_stat_grp->default_groups = kzalloc(sizeof(struct config_group) * 4,
 				GFP_KERNEL);
 	if (!dev_stat_grp->default_groups) {
 		pr_err("Unable to allocate dev_stat_grp->default_groups\n");
-		goto out;
+		goto out_free_tg_pt_gp_cg_default_groups;
 	}
-	target_stat_setup_dev_default_groups(se_dev);
-
-	pr_debug("Target_Core_ConfigFS: Allocated struct se_subsystem_dev:"
-		" %p se_dev_su_ptr: %p\n", se_dev, se_dev->se_dev_su_ptr);
+	target_stat_setup_dev_default_groups(dev);
 
 	mutex_unlock(&hba->hba_access_mutex);
-	return &se_dev->se_dev_group;
-out:
-	if (se_dev->t10_alua.default_tg_pt_gp) {
-		core_alua_free_tg_pt_gp(se_dev->t10_alua.default_tg_pt_gp);
-		se_dev->t10_alua.default_tg_pt_gp = NULL;
-	}
-	if (dev_stat_grp)
-		kfree(dev_stat_grp->default_groups);
-	if (tg_pt_gp_cg)
-		kfree(tg_pt_gp_cg->default_groups);
-	if (dev_cg)
-		kfree(dev_cg->default_groups);
-	if (se_dev->se_dev_su_ptr)
-		t->free_device(se_dev->se_dev_su_ptr);
-	kfree(se_dev);
-unlock:
+	return dev_cg;
+
+out_free_tg_pt_gp_cg_default_groups:
+	kfree(tg_pt_gp_cg->default_groups);
+out_free_tg_pt_gp:
+	core_alua_free_tg_pt_gp(tg_pt_gp);
+out_free_dev_cg_default_groups:
+	kfree(dev_cg->default_groups);
+out_free_device:
+	target_free_device(dev);
+out_unlock:
 	mutex_unlock(&hba->hba_access_mutex);
 	return ERR_PTR(errno);
 }
@@ -2859,18 +2639,19 @@ static void target_core_drop_subdev(
 	struct config_group *group,
 	struct config_item *item)
 {
-	struct se_subsystem_dev *se_dev = container_of(to_config_group(item),
-				struct se_subsystem_dev, se_dev_group);
+	struct config_group *dev_cg = to_config_group(item);
+	struct se_device *dev =
+		container_of(dev_cg, struct se_device, dev_group);
 	struct se_hba *hba;
 	struct config_item *df_item;
-	struct config_group *dev_cg, *tg_pt_gp_cg, *dev_stat_grp;
+	struct config_group *tg_pt_gp_cg, *dev_stat_grp;
 	int i;
 
-	hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item);
+	hba = item_to_hba(&dev->se_hba->hba_group.cg_item);
 
 	mutex_lock(&hba->hba_access_mutex);
 
-	dev_stat_grp = &se_dev->dev_stat_grps.stat_group;
+	dev_stat_grp = &dev->dev_stat_grps.stat_group;
 	for (i = 0; dev_stat_grp->default_groups[i]; i++) {
 		df_item = &dev_stat_grp->default_groups[i]->cg_item;
 		dev_stat_grp->default_groups[i] = NULL;
@@ -2878,7 +2659,7 @@ static void target_core_drop_subdev(
 	}
 	kfree(dev_stat_grp->default_groups);
 
-	tg_pt_gp_cg = &se_dev->t10_alua.alua_tg_pt_gps_group;
+	tg_pt_gp_cg = &dev->t10_alua.alua_tg_pt_gps_group;
 	for (i = 0; tg_pt_gp_cg->default_groups[i]; i++) {
 		df_item = &tg_pt_gp_cg->default_groups[i]->cg_item;
 		tg_pt_gp_cg->default_groups[i] = NULL;
@@ -2889,17 +2670,15 @@ static void target_core_drop_subdev(
 	 * core_alua_free_tg_pt_gp() is called from ->default_tg_pt_gp
 	 * directly from target_core_alua_tg_pt_gp_release().
 	 */
-	se_dev->t10_alua.default_tg_pt_gp = NULL;
+	dev->t10_alua.default_tg_pt_gp = NULL;
 
-	dev_cg = &se_dev->se_dev_group;
 	for (i = 0; dev_cg->default_groups[i]; i++) {
 		df_item = &dev_cg->default_groups[i]->cg_item;
 		dev_cg->default_groups[i] = NULL;
 		config_item_put(df_item);
 	}
 	/*
-	 * The releasing of se_dev and associated se_dev->se_dev_ptr is done
-	 * from target_core_dev_item_ops->release() ->target_core_dev_release().
+	 * se_dev is released from target_core_dev_item_ops->release()
 	 */
 	config_item_put(item);
 	mutex_unlock(&hba->hba_access_mutex);
@@ -2962,13 +2741,10 @@ static ssize_t target_core_hba_store_attr_hba_mode(struct se_hba *hba,
 		return -EINVAL;
 	}
 
-	spin_lock(&hba->device_lock);
-	if (!list_empty(&hba->hba_dev_list)) {
+	if (hba->dev_count) {
 		pr_err("Unable to set hba_mode with active devices\n");
-		spin_unlock(&hba->device_lock);
 		return -EINVAL;
 	}
-	spin_unlock(&hba->device_lock);
 
 	ret = transport->pmode_enable_hba(hba, mode_flag);
 	if (ret < 0)
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 9abef9f8eb76..b27c75a0e2e2 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -50,11 +50,7 @@
 #include "target_core_pr.h"
 #include "target_core_ua.h"
 
-static void se_dev_start(struct se_device *dev);
-static void se_dev_stop(struct se_device *dev);
-
 static struct se_hba *lun0_hba;
-static struct se_subsystem_dev *lun0_su_dev;
 /* not static, needed by tpg.c */
 struct se_device *g_lun0_dev;
 
@@ -136,15 +132,6 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
 		se_cmd->orig_fe_lun = 0;
 		se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD;
 	}
-	/*
-	 * Determine if the struct se_lun is online.
-	 * FIXME: Check for LUN_RESET + UNIT Attention
-	 */
-	if (se_dev_check_online(se_lun->lun_se_dev) != 0) {
-		se_cmd->scsi_sense_reason = TCM_NON_EXISTENT_LUN;
-		se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
-		return -ENODEV;
-	}
 
 	/* Directly associate cmd with se_dev */
 	se_cmd->se_dev = se_lun->lun_se_dev;
@@ -202,14 +189,6 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
 		se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
 		return -ENODEV;
 	}
-	/*
-	 * Determine if the struct se_lun is online.
-	 * FIXME: Check for LUN_RESET + UNIT Attention
-	 */
-	if (se_dev_check_online(se_lun->lun_se_dev) != 0) {
-		se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
-		return -ENODEV;
-	}
 
 	/* Directly associate cmd with se_dev */
 	se_cmd->se_dev = se_lun->lun_se_dev;
@@ -565,7 +544,6 @@ static void core_export_port(
 	struct se_port *port,
 	struct se_lun *lun)
 {
-	struct se_subsystem_dev *su_dev = dev->se_sub_dev;
 	struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem = NULL;
 
 	spin_lock(&dev->se_port_lock);
@@ -578,7 +556,7 @@ static void core_export_port(
 	list_add_tail(&port->sep_list, &dev->dev_sep_list);
 	spin_unlock(&dev->se_port_lock);
 
-	if (su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
+	if (dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
 		tg_pt_gp_mem = core_alua_allocate_tg_pt_gp_mem(port);
 		if (IS_ERR(tg_pt_gp_mem) || !tg_pt_gp_mem) {
 			pr_err("Unable to allocate t10_alua_tg_pt"
@@ -587,7 +565,7 @@ static void core_export_port(
 		}
 		spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
 		__core_alua_attach_tg_pt_gp_mem(tg_pt_gp_mem,
-			su_dev->t10_alua.default_tg_pt_gp);
+			dev->t10_alua.default_tg_pt_gp);
 		spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
 		pr_debug("%s/%s: Adding to default ALUA Target Port"
 			" Group: alua/default_tg_pt_gp\n",
@@ -625,6 +603,7 @@ int core_dev_export(
 	struct se_portal_group *tpg,
 	struct se_lun *lun)
 {
+	struct se_hba *hba = dev->se_hba;
 	struct se_port *port;
 
 	port = core_alloc_port(dev);
@@ -632,9 +611,11 @@ int core_dev_export(
 		return PTR_ERR(port);
 
 	lun->lun_se_dev = dev;
-	se_dev_start(dev);
 
-	atomic_inc(&dev->dev_export_obj.obj_access_count);
+	spin_lock(&hba->device_lock);
+	dev->export_count++;
+	spin_unlock(&hba->device_lock);
+
 	core_export_port(dev, tpg, port, lun);
 	return 0;
 }
@@ -644,6 +625,7 @@ void core_dev_unexport(
 	struct se_portal_group *tpg,
 	struct se_lun *lun)
 {
+	struct se_hba *hba = dev->se_hba;
 	struct se_port *port = lun->lun_sep;
 
 	spin_lock(&lun->lun_sep_lock);
@@ -654,11 +636,13 @@ void core_dev_unexport(
 	spin_unlock(&lun->lun_sep_lock);
 
 	spin_lock(&dev->se_port_lock);
-	atomic_dec(&dev->dev_export_obj.obj_access_count);
 	core_release_port(dev, port);
 	spin_unlock(&dev->se_port_lock);
 
-	se_dev_stop(dev);
+	spin_lock(&hba->device_lock);
+	dev->export_count--;
+	spin_unlock(&hba->device_lock);
+
 	lun->lun_se_dev = NULL;
 }
 
@@ -725,127 +709,17 @@ done:
 	return 0;
 }
 
-/*	se_release_device_for_hba():
- *
- *
- */
-void se_release_device_for_hba(struct se_device *dev)
-{
-	struct se_hba *hba = dev->se_hba;
-
-	if ((dev->dev_status & TRANSPORT_DEVICE_ACTIVATED) ||
-	    (dev->dev_status & TRANSPORT_DEVICE_DEACTIVATED) ||
-	    (dev->dev_status & TRANSPORT_DEVICE_SHUTDOWN) ||
-	    (dev->dev_status & TRANSPORT_DEVICE_OFFLINE_ACTIVATED) ||
-	    (dev->dev_status & TRANSPORT_DEVICE_OFFLINE_DEACTIVATED))
-		se_dev_stop(dev);
-
-	if (dev->dev_ptr) {
-		destroy_workqueue(dev->tmr_wq);
-		if (dev->transport->free_device)
-			dev->transport->free_device(dev->dev_ptr);
-	}
-
-	spin_lock(&hba->device_lock);
-	list_del(&dev->dev_list);
-	hba->dev_count--;
-	spin_unlock(&hba->device_lock);
-
-	core_scsi3_free_all_registrations(dev);
-	se_release_vpd_for_dev(dev);
-
-	kfree(dev);
-}
-
-void se_release_vpd_for_dev(struct se_device *dev)
+static void se_release_vpd_for_dev(struct se_device *dev)
 {
 	struct t10_vpd *vpd, *vpd_tmp;
 
-	spin_lock(&dev->se_sub_dev->t10_wwn.t10_vpd_lock);
+	spin_lock(&dev->t10_wwn.t10_vpd_lock);
 	list_for_each_entry_safe(vpd, vpd_tmp,
-			&dev->se_sub_dev->t10_wwn.t10_vpd_list, vpd_list) {
+			&dev->t10_wwn.t10_vpd_list, vpd_list) {
 		list_del(&vpd->vpd_list);
 		kfree(vpd);
 	}
-	spin_unlock(&dev->se_sub_dev->t10_wwn.t10_vpd_lock);
-}
-
-/*	se_free_virtual_device():
- *
- *	Used for IBLOCK, RAMDISK, and FILEIO Transport Drivers.
- */
-int se_free_virtual_device(struct se_device *dev, struct se_hba *hba)
-{
-	if (!list_empty(&dev->dev_sep_list))
-		dump_stack();
-
-	core_alua_free_lu_gp_mem(dev);
-	se_release_device_for_hba(dev);
-
-	return 0;
-}
-
-static void se_dev_start(struct se_device *dev)
-{
-	struct se_hba *hba = dev->se_hba;
-
-	spin_lock(&hba->device_lock);
-	atomic_inc(&dev->dev_obj.obj_access_count);
-	if (atomic_read(&dev->dev_obj.obj_access_count) == 1) {
-		if (dev->dev_status & TRANSPORT_DEVICE_DEACTIVATED) {
-			dev->dev_status &= ~TRANSPORT_DEVICE_DEACTIVATED;
-			dev->dev_status |= TRANSPORT_DEVICE_ACTIVATED;
-		} else if (dev->dev_status &
-			   TRANSPORT_DEVICE_OFFLINE_DEACTIVATED) {
-			dev->dev_status &=
-				~TRANSPORT_DEVICE_OFFLINE_DEACTIVATED;
-			dev->dev_status |= TRANSPORT_DEVICE_OFFLINE_ACTIVATED;
-		}
-	}
-	spin_unlock(&hba->device_lock);
-}
-
-static void se_dev_stop(struct se_device *dev)
-{
-	struct se_hba *hba = dev->se_hba;
-
-	spin_lock(&hba->device_lock);
-	atomic_dec(&dev->dev_obj.obj_access_count);
-	if (atomic_read(&dev->dev_obj.obj_access_count) == 0) {
-		if (dev->dev_status & TRANSPORT_DEVICE_ACTIVATED) {
-			dev->dev_status &= ~TRANSPORT_DEVICE_ACTIVATED;
-			dev->dev_status |= TRANSPORT_DEVICE_DEACTIVATED;
-		} else if (dev->dev_status &
-			   TRANSPORT_DEVICE_OFFLINE_ACTIVATED) {
-			dev->dev_status &= ~TRANSPORT_DEVICE_OFFLINE_ACTIVATED;
-			dev->dev_status |= TRANSPORT_DEVICE_OFFLINE_DEACTIVATED;
-		}
-	}
-	spin_unlock(&hba->device_lock);
-}
-
-int se_dev_check_online(struct se_device *dev)
-{
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&dev->dev_status_lock, flags);
-	ret = ((dev->dev_status & TRANSPORT_DEVICE_ACTIVATED) ||
-	       (dev->dev_status & TRANSPORT_DEVICE_DEACTIVATED)) ? 0 : 1;
-	spin_unlock_irqrestore(&dev->dev_status_lock, flags);
-
-	return ret;
-}
-
-int se_dev_check_shutdown(struct se_device *dev)
-{
-	int ret;
-
-	spin_lock_irq(&dev->dev_status_lock);
-	ret = (dev->dev_status & TRANSPORT_DEVICE_SHUTDOWN);
-	spin_unlock_irq(&dev->dev_status_lock);
-
-	return ret;
+	spin_unlock(&dev->t10_wwn.t10_vpd_lock);
 }
 
 static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size)
@@ -866,72 +740,13 @@ static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size)
 	return aligned_max_sectors;
 }
 
-void se_dev_set_default_attribs(
-	struct se_device *dev,
-	struct se_dev_limits *dev_limits)
-{
-	struct queue_limits *limits = &dev_limits->limits;
-
-	dev->se_sub_dev->se_dev_attrib.emulate_dpo = DA_EMULATE_DPO;
-	dev->se_sub_dev->se_dev_attrib.emulate_fua_write = DA_EMULATE_FUA_WRITE;
-	dev->se_sub_dev->se_dev_attrib.emulate_fua_read = DA_EMULATE_FUA_READ;
-	dev->se_sub_dev->se_dev_attrib.emulate_write_cache = DA_EMULATE_WRITE_CACHE;
-	dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl = DA_EMULATE_UA_INTLLCK_CTRL;
-	dev->se_sub_dev->se_dev_attrib.emulate_tas = DA_EMULATE_TAS;
-	dev->se_sub_dev->se_dev_attrib.emulate_tpu = DA_EMULATE_TPU;
-	dev->se_sub_dev->se_dev_attrib.emulate_tpws = DA_EMULATE_TPWS;
-	dev->se_sub_dev->se_dev_attrib.emulate_reservations = DA_EMULATE_RESERVATIONS;
-	dev->se_sub_dev->se_dev_attrib.emulate_alua = DA_EMULATE_ALUA;
-	dev->se_sub_dev->se_dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS;
-	dev->se_sub_dev->se_dev_attrib.is_nonrot = DA_IS_NONROT;
-	dev->se_sub_dev->se_dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD;
-	/*
-	 * The TPU=1 and TPWS=1 settings will be set in TCM/IBLOCK
-	 * iblock_create_virtdevice() from struct queue_limits values
-	 * if blk_queue_discard()==1
-	 */
-	dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count = DA_MAX_UNMAP_LBA_COUNT;
-	dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count =
-		DA_MAX_UNMAP_BLOCK_DESC_COUNT;
-	dev->se_sub_dev->se_dev_attrib.unmap_granularity = DA_UNMAP_GRANULARITY_DEFAULT;
-	dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment =
-				DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT;
-	/*
-	 * block_size is based on subsystem plugin dependent requirements.
-	 */
-	dev->se_sub_dev->se_dev_attrib.hw_block_size = limits->logical_block_size;
-	dev->se_sub_dev->se_dev_attrib.block_size = limits->logical_block_size;
-	/*
-	 * Align max_hw_sectors down to PAGE_SIZE I/O transfers
-	 */
-	limits->max_hw_sectors = se_dev_align_max_sectors(limits->max_hw_sectors,
-						limits->logical_block_size);
-	dev->se_sub_dev->se_dev_attrib.hw_max_sectors = limits->max_hw_sectors;
-
-	/*
-	 * Set fabric_max_sectors, which is reported in block limits
-	 * VPD page (B0h).
-	 */
-	dev->se_sub_dev->se_dev_attrib.fabric_max_sectors = DA_FABRIC_MAX_SECTORS;
-	/*
-	 * Set optimal_sectors from fabric_max_sectors, which can be
-	 * lowered via configfs.
-	 */
-	dev->se_sub_dev->se_dev_attrib.optimal_sectors = DA_FABRIC_MAX_SECTORS;
-	/*
-	 * queue_depth is based on subsystem plugin dependent requirements.
-	 */
-	dev->se_sub_dev->se_dev_attrib.hw_queue_depth = dev_limits->hw_queue_depth;
-	dev->se_sub_dev->se_dev_attrib.queue_depth = dev_limits->queue_depth;
-}
-
 int se_dev_set_max_unmap_lba_count(
 	struct se_device *dev,
 	u32 max_unmap_lba_count)
 {
-	dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count = max_unmap_lba_count;
+	dev->dev_attrib.max_unmap_lba_count = max_unmap_lba_count;
 	pr_debug("dev[%p]: Set max_unmap_lba_count: %u\n",
-			dev, dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count);
+			dev, dev->dev_attrib.max_unmap_lba_count);
 	return 0;
 }
 
@@ -939,10 +754,10 @@ int se_dev_set_max_unmap_block_desc_count(
 	struct se_device *dev,
 	u32 max_unmap_block_desc_count)
 {
-	dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count =
+	dev->dev_attrib.max_unmap_block_desc_count =
 		max_unmap_block_desc_count;
 	pr_debug("dev[%p]: Set max_unmap_block_desc_count: %u\n",
-			dev, dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count);
+			dev, dev->dev_attrib.max_unmap_block_desc_count);
 	return 0;
 }
 
@@ -950,9 +765,9 @@ int se_dev_set_unmap_granularity(
 	struct se_device *dev,
 	u32 unmap_granularity)
 {
-	dev->se_sub_dev->se_dev_attrib.unmap_granularity = unmap_granularity;
+	dev->dev_attrib.unmap_granularity = unmap_granularity;
 	pr_debug("dev[%p]: Set unmap_granularity: %u\n",
-			dev, dev->se_sub_dev->se_dev_attrib.unmap_granularity);
+			dev, dev->dev_attrib.unmap_granularity);
 	return 0;
 }
 
@@ -960,9 +775,9 @@ int se_dev_set_unmap_granularity_alignment(
 	struct se_device *dev,
 	u32 unmap_granularity_alignment)
 {
-	dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment = unmap_granularity_alignment;
+	dev->dev_attrib.unmap_granularity_alignment = unmap_granularity_alignment;
 	pr_debug("dev[%p]: Set unmap_granularity_alignment: %u\n",
-			dev, dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment);
+			dev, dev->dev_attrib.unmap_granularity_alignment);
 	return 0;
 }
 
@@ -993,9 +808,9 @@ int se_dev_set_emulate_fua_write(struct se_device *dev, int flag)
 		pr_err("emulate_fua_write not supported for pSCSI\n");
 		return -EINVAL;
 	}
-	dev->se_sub_dev->se_dev_attrib.emulate_fua_write = flag;
+	dev->dev_attrib.emulate_fua_write = flag;
 	pr_debug("dev[%p]: SE Device Forced Unit Access WRITEs: %d\n",
-			dev, dev->se_sub_dev->se_dev_attrib.emulate_fua_write);
+			dev, dev->dev_attrib.emulate_fua_write);
 	return 0;
 }
 
@@ -1025,9 +840,9 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag)
 		pr_err("emulate_write_cache not supported for pSCSI\n");
 		return -EINVAL;
 	}
-	dev->se_sub_dev->se_dev_attrib.emulate_write_cache = flag;
+	dev->dev_attrib.emulate_write_cache = flag;
 	pr_debug("dev[%p]: SE Device WRITE_CACHE_EMULATION flag: %d\n",
-			dev, dev->se_sub_dev->se_dev_attrib.emulate_write_cache);
+			dev, dev->dev_attrib.emulate_write_cache);
 	return 0;
 }
 
@@ -1038,16 +853,15 @@ int se_dev_set_emulate_ua_intlck_ctrl(struct se_device *dev, int flag)
 		return -EINVAL;
 	}
 
-	if (atomic_read(&dev->dev_export_obj.obj_access_count)) {
+	if (dev->export_count) {
 		pr_err("dev[%p]: Unable to change SE Device"
-			" UA_INTRLCK_CTRL while dev_export_obj: %d count"
-			" exists\n", dev,
-			atomic_read(&dev->dev_export_obj.obj_access_count));
+			" UA_INTRLCK_CTRL while export_count is %d\n",
+			dev, dev->export_count);
 		return -EINVAL;
 	}
-	dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl = flag;
+	dev->dev_attrib.emulate_ua_intlck_ctrl = flag;
 	pr_debug("dev[%p]: SE Device UA_INTRLCK_CTRL flag: %d\n",
-		dev, dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl);
+		dev, dev->dev_attrib.emulate_ua_intlck_ctrl);
 
 	return 0;
 }
@@ -1059,15 +873,15 @@ int se_dev_set_emulate_tas(struct se_device *dev, int flag)
 		return -EINVAL;
 	}
 
-	if (atomic_read(&dev->dev_export_obj.obj_access_count)) {
+	if (dev->export_count) {
 		pr_err("dev[%p]: Unable to change SE Device TAS while"
-			" dev_export_obj: %d count exists\n", dev,
-			atomic_read(&dev->dev_export_obj.obj_access_count));
+			" export_count is %d\n",
+			dev, dev->export_count);
 		return -EINVAL;
 	}
-	dev->se_sub_dev->se_dev_attrib.emulate_tas = flag;
+	dev->dev_attrib.emulate_tas = flag;
 	pr_debug("dev[%p]: SE Device TASK_ABORTED status bit: %s\n",
-		dev, (dev->se_sub_dev->se_dev_attrib.emulate_tas) ? "Enabled" : "Disabled");
+		dev, (dev->dev_attrib.emulate_tas) ? "Enabled" : "Disabled");
 
 	return 0;
 }
@@ -1082,12 +896,12 @@ int se_dev_set_emulate_tpu(struct se_device *dev, int flag)
 	 * We expect this value to be non-zero when generic Block Layer
 	 * Discard supported is detected iblock_create_virtdevice().
 	 */
-	if (flag && !dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) {
+	if (flag && !dev->dev_attrib.max_unmap_block_desc_count) {
 		pr_err("Generic Block Discard not supported\n");
 		return -ENOSYS;
 	}
 
-	dev->se_sub_dev->se_dev_attrib.emulate_tpu = flag;
+	dev->dev_attrib.emulate_tpu = flag;
 	pr_debug("dev[%p]: SE Device Thin Provisioning UNMAP bit: %d\n",
 				dev, flag);
 	return 0;
@@ -1103,12 +917,12 @@ int se_dev_set_emulate_tpws(struct se_device *dev, int flag)
 	 * We expect this value to be non-zero when generic Block Layer
 	 * Discard supported is detected iblock_create_virtdevice().
 	 */
-	if (flag && !dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) {
+	if (flag && !dev->dev_attrib.max_unmap_block_desc_count) {
 		pr_err("Generic Block Discard not supported\n");
 		return -ENOSYS;
 	}
 
-	dev->se_sub_dev->se_dev_attrib.emulate_tpws = flag;
+	dev->dev_attrib.emulate_tpws = flag;
 	pr_debug("dev[%p]: SE Device Thin Provisioning WRITE_SAME: %d\n",
 				dev, flag);
 	return 0;
@@ -1120,9 +934,9 @@ int se_dev_set_enforce_pr_isids(struct se_device *dev, int flag)
 		pr_err("Illegal value %d\n", flag);
 		return -EINVAL;
 	}
-	dev->se_sub_dev->se_dev_attrib.enforce_pr_isids = flag;
+	dev->dev_attrib.enforce_pr_isids = flag;
 	pr_debug("dev[%p]: SE Device enforce_pr_isids bit: %s\n", dev,
-		(dev->se_sub_dev->se_dev_attrib.enforce_pr_isids) ? "Enabled" : "Disabled");
+		(dev->dev_attrib.enforce_pr_isids) ? "Enabled" : "Disabled");
 	return 0;
 }
 
@@ -1132,7 +946,7 @@ int se_dev_set_is_nonrot(struct se_device *dev, int flag)
 		printk(KERN_ERR "Illegal value %d\n", flag);
 		return -EINVAL;
 	}
-	dev->se_sub_dev->se_dev_attrib.is_nonrot = flag;
+	dev->dev_attrib.is_nonrot = flag;
 	pr_debug("dev[%p]: SE Device is_nonrot bit: %d\n",
 	       dev, flag);
 	return 0;
@@ -1145,7 +959,7 @@ int se_dev_set_emulate_rest_reord(struct se_device *dev, int flag)
 			" reordering not implemented\n", dev);
 		return -ENOSYS;
 	}
-	dev->se_sub_dev->se_dev_attrib.emulate_rest_reord = flag;
+	dev->dev_attrib.emulate_rest_reord = flag;
 	pr_debug("dev[%p]: SE Device emulate_rest_reord: %d\n", dev, flag);
 	return 0;
 }
@@ -1155,10 +969,10 @@ int se_dev_set_emulate_rest_reord(struct se_device *dev, int flag)
  */
 int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth)
 {
-	if (atomic_read(&dev->dev_export_obj.obj_access_count)) {
+	if (dev->export_count) {
 		pr_err("dev[%p]: Unable to change SE Device TCQ while"
-			" dev_export_obj: %d count exists\n", dev,
-			atomic_read(&dev->dev_export_obj.obj_access_count));
+			" export_count is %d\n",
+			dev, dev->export_count);
 		return -EINVAL;
 	}
 	if (!queue_depth) {
@@ -1168,26 +982,26 @@ int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth)
 	}
 
 	if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) {
-		if (queue_depth > dev->se_sub_dev->se_dev_attrib.hw_queue_depth) {
+		if (queue_depth > dev->dev_attrib.hw_queue_depth) {
 			pr_err("dev[%p]: Passed queue_depth: %u"
 				" exceeds TCM/SE_Device TCQ: %u\n",
 				dev, queue_depth,
-				dev->se_sub_dev->se_dev_attrib.hw_queue_depth);
+				dev->dev_attrib.hw_queue_depth);
 			return -EINVAL;
 		}
 	} else {
-		if (queue_depth > dev->se_sub_dev->se_dev_attrib.queue_depth) {
-			if (queue_depth > dev->se_sub_dev->se_dev_attrib.hw_queue_depth) {
+		if (queue_depth > dev->dev_attrib.queue_depth) {
+			if (queue_depth > dev->dev_attrib.hw_queue_depth) {
 				pr_err("dev[%p]: Passed queue_depth:"
 					" %u exceeds TCM/SE_Device MAX"
 					" TCQ: %u\n", dev, queue_depth,
-					dev->se_sub_dev->se_dev_attrib.hw_queue_depth);
+					dev->dev_attrib.hw_queue_depth);
 				return -EINVAL;
 			}
 		}
 	}
 
-	dev->se_sub_dev->se_dev_attrib.queue_depth = dev->queue_depth = queue_depth;
+	dev->dev_attrib.queue_depth = dev->queue_depth = queue_depth;
 	pr_debug("dev[%p]: SE Device TCQ Depth changed to: %u\n",
 			dev, queue_depth);
 	return 0;
@@ -1195,10 +1009,10 @@ int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth)
 
 int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors)
 {
-	if (atomic_read(&dev->dev_export_obj.obj_access_count)) {
+	if (dev->export_count) {
 		pr_err("dev[%p]: Unable to change SE Device"
-			" fabric_max_sectors while dev_export_obj: %d count exists\n",
-			dev, atomic_read(&dev->dev_export_obj.obj_access_count));
+			" fabric_max_sectors while export_count is %d\n",
+			dev, dev->export_count);
 		return -EINVAL;
 	}
 	if (!fabric_max_sectors) {
@@ -1213,11 +1027,11 @@ int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors)
 		return -EINVAL;
 	}
 	if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) {
-		if (fabric_max_sectors > dev->se_sub_dev->se_dev_attrib.hw_max_sectors) {
+		if (fabric_max_sectors > dev->dev_attrib.hw_max_sectors) {
 			pr_err("dev[%p]: Passed fabric_max_sectors: %u"
 				" greater than TCM/SE_Device max_sectors:"
 				" %u\n", dev, fabric_max_sectors,
-				dev->se_sub_dev->se_dev_attrib.hw_max_sectors);
+				dev->dev_attrib.hw_max_sectors);
 			 return -EINVAL;
 		}
 	} else {
@@ -1233,9 +1047,9 @@ int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors)
 	 * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks()
 	 */
 	fabric_max_sectors = se_dev_align_max_sectors(fabric_max_sectors,
-						      dev->se_sub_dev->se_dev_attrib.block_size);
+						      dev->dev_attrib.block_size);
 
-	dev->se_sub_dev->se_dev_attrib.fabric_max_sectors = fabric_max_sectors;
+	dev->dev_attrib.fabric_max_sectors = fabric_max_sectors;
 	pr_debug("dev[%p]: SE Device max_sectors changed to %u\n",
 			dev, fabric_max_sectors);
 	return 0;
@@ -1243,10 +1057,10 @@ int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors)
 
 int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors)
 {
-	if (atomic_read(&dev->dev_export_obj.obj_access_count)) {
+	if (dev->export_count) {
 		pr_err("dev[%p]: Unable to change SE Device"
-			" optimal_sectors while dev_export_obj: %d count exists\n",
-			dev, atomic_read(&dev->dev_export_obj.obj_access_count));
+			" optimal_sectors while export_count is %d\n",
+			dev, dev->export_count);
 		return -EINVAL;
 	}
 	if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) {
@@ -1254,14 +1068,14 @@ int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors)
 				" changed for TCM/pSCSI\n", dev);
 		return -EINVAL;
 	}
-	if (optimal_sectors > dev->se_sub_dev->se_dev_attrib.fabric_max_sectors) {
+	if (optimal_sectors > dev->dev_attrib.fabric_max_sectors) {
 		pr_err("dev[%p]: Passed optimal_sectors %u cannot be"
 			" greater than fabric_max_sectors: %u\n", dev,
-			optimal_sectors, dev->se_sub_dev->se_dev_attrib.fabric_max_sectors);
+			optimal_sectors, dev->dev_attrib.fabric_max_sectors);
 		return -EINVAL;
 	}
 
-	dev->se_sub_dev->se_dev_attrib.optimal_sectors = optimal_sectors;
+	dev->dev_attrib.optimal_sectors = optimal_sectors;
 	pr_debug("dev[%p]: SE Device optimal_sectors changed to %u\n",
 			dev, optimal_sectors);
 	return 0;
@@ -1269,10 +1083,10 @@ int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors)
 
 int se_dev_set_block_size(struct se_device *dev, u32 block_size)
 {
-	if (atomic_read(&dev->dev_export_obj.obj_access_count)) {
+	if (dev->export_count) {
 		pr_err("dev[%p]: Unable to change SE Device block_size"
-			" while dev_export_obj: %d count exists\n", dev,
-			atomic_read(&dev->dev_export_obj.obj_access_count));
+			" while export_count is %d\n",
+			dev, dev->export_count);
 		return -EINVAL;
 	}
 
@@ -1293,7 +1107,7 @@ int se_dev_set_block_size(struct se_device *dev, u32 block_size)
 		return -EINVAL;
 	}
 
-	dev->se_sub_dev->se_dev_attrib.block_size = block_size;
+	dev->dev_attrib.block_size = block_size;
 	pr_debug("dev[%p]: SE Device block_size changed to %u\n",
 			dev, block_size);
 	return 0;
@@ -1307,12 +1121,6 @@ struct se_lun *core_dev_add_lun(
 	struct se_lun *lun_p;
 	int rc;
 
-	if (atomic_read(&dev->dev_access_obj.obj_access_count) != 0) {
-		pr_err("Unable to export struct se_device while dev_access_obj: %d\n",
-			atomic_read(&dev->dev_access_obj.obj_access_count));
-		return ERR_PTR(-EACCES);
-	}
-
 	lun_p = core_tpg_pre_addlun(tpg, lun);
 	if (IS_ERR(lun_p))
 		return lun_p;
@@ -1568,12 +1376,220 @@ void core_dev_free_initiator_node_lun_acl(
 	kfree(lacl);
 }
 
+static void scsi_dump_inquiry(struct se_device *dev)
+{
+	struct t10_wwn *wwn = &dev->t10_wwn;
+	char buf[17];
+	int i, device_type;
+	/*
+	 * Print Linux/SCSI style INQUIRY formatting to the kernel ring buffer
+	 */
+	for (i = 0; i < 8; i++)
+		if (wwn->vendor[i] >= 0x20)
+			buf[i] = wwn->vendor[i];
+		else
+			buf[i] = ' ';
+	buf[i] = '\0';
+	pr_debug("  Vendor: %s\n", buf);
+
+	for (i = 0; i < 16; i++)
+		if (wwn->model[i] >= 0x20)
+			buf[i] = wwn->model[i];
+		else
+			buf[i] = ' ';
+	buf[i] = '\0';
+	pr_debug("  Model: %s\n", buf);
+
+	for (i = 0; i < 4; i++)
+		if (wwn->revision[i] >= 0x20)
+			buf[i] = wwn->revision[i];
+		else
+			buf[i] = ' ';
+	buf[i] = '\0';
+	pr_debug("  Revision: %s\n", buf);
+
+	device_type = dev->transport->get_device_type(dev);
+	pr_debug("  Type:   %s ", scsi_device_type(device_type));
+	pr_debug("                 ANSI SCSI revision: %02x\n",
+				dev->transport->get_device_rev(dev));
+}
+
+struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
+{
+	struct se_device *dev;
+
+	dev = hba->transport->alloc_device(hba, name);
+	if (!dev)
+		return NULL;
+
+	dev->se_hba = hba;
+	dev->transport = hba->transport;
+
+	INIT_LIST_HEAD(&dev->dev_list);
+	INIT_LIST_HEAD(&dev->dev_sep_list);
+	INIT_LIST_HEAD(&dev->dev_tmr_list);
+	INIT_LIST_HEAD(&dev->delayed_cmd_list);
+	INIT_LIST_HEAD(&dev->state_list);
+	INIT_LIST_HEAD(&dev->qf_cmd_list);
+	spin_lock_init(&dev->stats_lock);
+	spin_lock_init(&dev->execute_task_lock);
+	spin_lock_init(&dev->delayed_cmd_lock);
+	spin_lock_init(&dev->dev_reservation_lock);
+	spin_lock_init(&dev->se_port_lock);
+	spin_lock_init(&dev->se_tmr_lock);
+	spin_lock_init(&dev->qf_cmd_lock);
+	atomic_set(&dev->dev_ordered_id, 0);
+	INIT_LIST_HEAD(&dev->t10_wwn.t10_vpd_list);
+	spin_lock_init(&dev->t10_wwn.t10_vpd_lock);
+	INIT_LIST_HEAD(&dev->t10_pr.registration_list);
+	INIT_LIST_HEAD(&dev->t10_pr.aptpl_reg_list);
+	spin_lock_init(&dev->t10_pr.registration_lock);
+	spin_lock_init(&dev->t10_pr.aptpl_reg_lock);
+	INIT_LIST_HEAD(&dev->t10_alua.tg_pt_gps_list);
+	spin_lock_init(&dev->t10_alua.tg_pt_gps_lock);
+
+	dev->t10_pr.pr_aptpl_buf_len = PR_APTPL_BUF_LEN;
+	dev->t10_wwn.t10_dev = dev;
+	dev->t10_alua.t10_dev = dev;
+
+	dev->dev_attrib.da_dev = dev;
+	dev->dev_attrib.emulate_dpo = DA_EMULATE_DPO;
+	dev->dev_attrib.emulate_fua_write = DA_EMULATE_FUA_WRITE;
+	dev->dev_attrib.emulate_fua_read = DA_EMULATE_FUA_READ;
+	dev->dev_attrib.emulate_write_cache = DA_EMULATE_WRITE_CACHE;
+	dev->dev_attrib.emulate_ua_intlck_ctrl = DA_EMULATE_UA_INTLLCK_CTRL;
+	dev->dev_attrib.emulate_tas = DA_EMULATE_TAS;
+	dev->dev_attrib.emulate_tpu = DA_EMULATE_TPU;
+	dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS;
+	dev->dev_attrib.emulate_reservations = DA_EMULATE_RESERVATIONS;
+	dev->dev_attrib.emulate_alua = DA_EMULATE_ALUA;
+	dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS;
+	dev->dev_attrib.is_nonrot = DA_IS_NONROT;
+	dev->dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD;
+	dev->dev_attrib.max_unmap_lba_count = DA_MAX_UNMAP_LBA_COUNT;
+	dev->dev_attrib.max_unmap_block_desc_count =
+		DA_MAX_UNMAP_BLOCK_DESC_COUNT;
+	dev->dev_attrib.unmap_granularity = DA_UNMAP_GRANULARITY_DEFAULT;
+	dev->dev_attrib.unmap_granularity_alignment =
+				DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT;
+	dev->dev_attrib.fabric_max_sectors = DA_FABRIC_MAX_SECTORS;
+	dev->dev_attrib.optimal_sectors = DA_FABRIC_MAX_SECTORS;
+
+	if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
+		dev->dev_task_attr_type = SAM_TASK_ATTR_PASSTHROUGH;
+	else
+		dev->dev_task_attr_type = SAM_TASK_ATTR_EMULATED;
+
+	return dev;
+}
+
+int target_configure_device(struct se_device *dev)
+{
+	struct se_hba *hba = dev->se_hba;
+	int ret;
+
+	if (dev->dev_flags & DF_CONFIGURED) {
+		pr_err("se_dev->se_dev_ptr already set for storage"
+				" object\n");
+		return -EEXIST;
+	}
+
+	ret = dev->transport->configure_device(dev);
+	if (ret)
+		goto out;
+	dev->dev_flags |= DF_CONFIGURED;
+
+	/*
+	 * XXX: there is not much point to have two different values here..
+	 */
+	dev->dev_attrib.block_size = dev->dev_attrib.hw_block_size;
+	dev->dev_attrib.queue_depth = dev->dev_attrib.hw_queue_depth;
+
+	/*
+	 * Align max_hw_sectors down to PAGE_SIZE I/O transfers
+	 */
+	dev->dev_attrib.hw_max_sectors =
+		se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors,
+					 dev->dev_attrib.hw_block_size);
+
+	dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX);
+	dev->creation_time = get_jiffies_64();
+
+	core_setup_reservations(dev);
+
+	ret = core_setup_alua(dev);
+	if (ret)
+		goto out;
+
+	/*
+	 * Startup the struct se_device processing thread
+	 */
+	dev->tmr_wq = alloc_workqueue("tmr-%s", WQ_MEM_RECLAIM | WQ_UNBOUND, 1,
+				      dev->transport->name);
+	if (!dev->tmr_wq) {
+		pr_err("Unable to create tmr workqueue for %s\n",
+			dev->transport->name);
+		ret = -ENOMEM;
+		goto out_free_alua;
+	}
+
+	/*
+	 * Setup work_queue for QUEUE_FULL
+	 */
+	INIT_WORK(&dev->qf_work_queue, target_qf_do_work);
+
+	/*
+	 * Preload the initial INQUIRY const values if we are doing
+	 * anything virtual (IBLOCK, FILEIO, RAMDISK), but not for TCM/pSCSI
+	 * passthrough because this is being provided by the backend LLD.
+	 */
+	if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) {
+		strncpy(&dev->t10_wwn.vendor[0], "LIO-ORG", 8);
+		strncpy(&dev->t10_wwn.model[0],
+			dev->transport->inquiry_prod, 16);
+		strncpy(&dev->t10_wwn.revision[0],
+			dev->transport->inquiry_rev, 4);
+	}
+
+	scsi_dump_inquiry(dev);
+
+	spin_lock(&hba->device_lock);
+	hba->dev_count++;
+	spin_unlock(&hba->device_lock);
+	return 0;
+
+out_free_alua:
+	core_alua_free_lu_gp_mem(dev);
+out:
+	se_release_vpd_for_dev(dev);
+	return ret;
+}
+
+void target_free_device(struct se_device *dev)
+{
+	struct se_hba *hba = dev->se_hba;
+
+	WARN_ON(!list_empty(&dev->dev_sep_list));
+
+	if (dev->dev_flags & DF_CONFIGURED) {
+		destroy_workqueue(dev->tmr_wq);
+
+		spin_lock(&hba->device_lock);
+		hba->dev_count--;
+		spin_unlock(&hba->device_lock);
+	}
+
+	core_alua_free_lu_gp_mem(dev);
+	core_scsi3_free_all_registrations(dev);
+	se_release_vpd_for_dev(dev);
+
+	dev->transport->free_device(dev);
+}
+
 int core_dev_setup_virtual_lun0(void)
 {
 	struct se_hba *hba;
 	struct se_device *dev;
-	struct se_subsystem_dev *se_dev = NULL;
-	struct se_subsystem_api *t;
 	char buf[16];
 	int ret;
 
@@ -1581,60 +1597,28 @@ int core_dev_setup_virtual_lun0(void)
 	if (IS_ERR(hba))
 		return PTR_ERR(hba);
 
-	lun0_hba = hba;
-	t = hba->transport;
-
-	se_dev = kzalloc(sizeof(struct se_subsystem_dev), GFP_KERNEL);
-	if (!se_dev) {
-		pr_err("Unable to allocate memory for"
-				" struct se_subsystem_dev\n");
+	dev = target_alloc_device(hba, "virt_lun0");
+	if (!dev) {
 		ret = -ENOMEM;
-		goto out;
+		goto out_free_hba;
 	}
-	INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list);
-	spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock);
-	INIT_LIST_HEAD(&se_dev->t10_pr.registration_list);
-	INIT_LIST_HEAD(&se_dev->t10_pr.aptpl_reg_list);
-	spin_lock_init(&se_dev->t10_pr.registration_lock);
-	spin_lock_init(&se_dev->t10_pr.aptpl_reg_lock);
-	INIT_LIST_HEAD(&se_dev->t10_alua.tg_pt_gps_list);
-	spin_lock_init(&se_dev->t10_alua.tg_pt_gps_lock);
-	spin_lock_init(&se_dev->se_dev_lock);
-	se_dev->t10_pr.pr_aptpl_buf_len = PR_APTPL_BUF_LEN;
-	se_dev->t10_wwn.t10_sub_dev = se_dev;
-	se_dev->t10_alua.t10_sub_dev = se_dev;
-	se_dev->se_dev_attrib.da_sub_dev = se_dev;
-	se_dev->se_dev_hba = hba;
-
-	se_dev->se_dev_su_ptr = t->allocate_virtdevice(hba, "virt_lun0");
-	if (!se_dev->se_dev_su_ptr) {
-		pr_err("Unable to locate subsystem dependent pointer"
-			" from allocate_virtdevice()\n");
-		ret = -ENOMEM;
-		goto out;
-	}
-	lun0_su_dev = se_dev;
 
 	memset(buf, 0, 16);
 	sprintf(buf, "rd_pages=8");
-	t->set_configfs_dev_params(hba, se_dev, buf, sizeof(buf));
+	hba->transport->set_configfs_dev_params(dev, buf, sizeof(buf));
 
-	dev = t->create_virtdevice(hba, se_dev, se_dev->se_dev_su_ptr);
-	if (IS_ERR(dev)) {
-		ret = PTR_ERR(dev);
-		goto out;
-	}
-	se_dev->se_dev_ptr = dev;
-	g_lun0_dev = dev;
+	ret = target_configure_device(dev);
+	if (ret)
+		goto out_free_se_dev;
 
+	lun0_hba = hba;
+	g_lun0_dev = dev;
 	return 0;
-out:
-	lun0_su_dev = NULL;
-	kfree(se_dev);
-	if (lun0_hba) {
-		core_delete_hba(lun0_hba);
-		lun0_hba = NULL;
-	}
+
+out_free_se_dev:
+	target_free_device(dev);
+out_free_hba:
+	core_delete_hba(hba);
 	return ret;
 }
 
@@ -1642,14 +1626,11 @@ out:
 void core_dev_release_virtual_lun0(void)
 {
 	struct se_hba *hba = lun0_hba;
-	struct se_subsystem_dev *su_dev = lun0_su_dev;
 
 	if (!hba)
 		return;
 
 	if (g_lun0_dev)
-		se_free_virtual_device(g_lun0_dev, hba);
-
-	kfree(su_dev);
+		target_free_device(g_lun0_dev);
 	core_delete_hba(hba);
 }
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c
index bca737bb813d..aa6731337f84 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -734,14 +734,12 @@ static int target_fabric_port_link(
 	struct config_item *se_dev_ci)
 {
 	struct config_item *tpg_ci;
-	struct se_device *dev;
 	struct se_lun *lun = container_of(to_config_group(lun_ci),
 				struct se_lun, lun_group);
 	struct se_lun *lun_p;
 	struct se_portal_group *se_tpg;
-	struct se_subsystem_dev *se_dev = container_of(
-				to_config_group(se_dev_ci), struct se_subsystem_dev,
-				se_dev_group);
+	struct se_device *dev =
+		container_of(to_config_group(se_dev_ci), struct se_device, dev_group);
 	struct target_fabric_configfs *tf;
 	int ret;
 
@@ -755,14 +753,6 @@ static int target_fabric_port_link(
 		return -EEXIST;
 	}
 
-	dev = se_dev->se_dev_ptr;
-	if (!dev) {
-		pr_err("Unable to locate struct se_device pointer from"
-			" %s\n", config_item_name(se_dev_ci));
-		ret = -ENODEV;
-		goto out;
-	}
-
 	lun_p = core_dev_add_lun(se_tpg, dev, lun->unpacked_lun);
 	if (IS_ERR(lun_p)) {
 		pr_err("core_dev_add_lun() failed\n");
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index 0360383dfb94..a89d80dacad2 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -41,7 +41,10 @@
 
 #include "target_core_file.h"
 
-static struct se_subsystem_api fileio_template;
+static inline struct fd_dev *FD_DEV(struct se_device *dev)
+{
+	return container_of(dev, struct fd_dev, dev);
+}
 
 /*	fd_attach_hba(): (Part of se_subsystem_api_t template)
  *
@@ -82,7 +85,7 @@ static void fd_detach_hba(struct se_hba *hba)
 	hba->hba_ptr = NULL;
 }
 
-static void *fd_allocate_virtdevice(struct se_hba *hba, const char *name)
+static struct se_device *fd_alloc_device(struct se_hba *hba, const char *name)
 {
 	struct fd_dev *fd_dev;
 	struct fd_host *fd_host = hba->hba_ptr;
@@ -97,34 +100,28 @@ static void *fd_allocate_virtdevice(struct se_hba *hba, const char *name)
 
 	pr_debug("FILEIO: Allocated fd_dev for %p\n", name);
 
-	return fd_dev;
+	return &fd_dev->dev;
 }
 
-/*	fd_create_virtdevice(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static struct se_device *fd_create_virtdevice(
-	struct se_hba *hba,
-	struct se_subsystem_dev *se_dev,
-	void *p)
+static int fd_configure_device(struct se_device *dev)
 {
-	struct se_device *dev;
-	struct se_dev_limits dev_limits;
-	struct queue_limits *limits;
-	struct fd_dev *fd_dev = p;
-	struct fd_host *fd_host = hba->hba_ptr;
+	struct fd_dev *fd_dev = FD_DEV(dev);
+	struct fd_host *fd_host = dev->se_hba->hba_ptr;
 	struct file *file;
 	struct inode *inode = NULL;
-	int dev_flags = 0, flags, ret = -EINVAL;
+	int flags, ret = -EINVAL;
 
-	memset(&dev_limits, 0, sizeof(struct se_dev_limits));
+	if (!(fd_dev->fbd_flags & FBDF_HAS_PATH)) {
+		pr_err("Missing fd_dev_name=\n");
+		return -EINVAL;
+	}
 
 	/*
 	 * Use O_DSYNC by default instead of O_SYNC to forgo syncing
 	 * of pure timestamp updates.
 	 */
 	flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC;
+
 	/*
 	 * Optionally allow fd_buffered_io=1 to be enabled for people
 	 * who want use the fs buffer cache as an WriteCache mechanism.
@@ -154,22 +151,17 @@ static struct se_device *fd_create_virtdevice(
 	 */
 	inode = file->f_mapping->host;
 	if (S_ISBLK(inode->i_mode)) {
-		struct request_queue *q;
+		struct request_queue *q = bdev_get_queue(inode->i_bdev);
 		unsigned long long dev_size;
-		/*
-		 * Setup the local scope queue_limits from struct request_queue->limits
-		 * to pass into transport_add_device_to_core_hba() as struct se_dev_limits.
-		 */
-		q = bdev_get_queue(inode->i_bdev);
-		limits = &dev_limits.limits;
-		limits->logical_block_size = bdev_logical_block_size(inode->i_bdev);
-		limits->max_hw_sectors = queue_max_hw_sectors(q);
-		limits->max_sectors = queue_max_sectors(q);
+
+		dev->dev_attrib.hw_block_size =
+			bdev_logical_block_size(inode->i_bdev);
+		dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q);
+
 		/*
 		 * Determine the number of bytes from i_size_read() minus
 		 * one (1) logical sector from underlying struct block_device
 		 */
-		fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev);
 		dev_size = (i_size_read(file->f_mapping->host) -
 				       fd_dev->fd_block_size);
 
@@ -185,26 +177,18 @@ static struct se_device *fd_create_virtdevice(
 			goto fail;
 		}
 
-		limits = &dev_limits.limits;
-		limits->logical_block_size = FD_BLOCKSIZE;
-		limits->max_hw_sectors = FD_MAX_SECTORS;
-		limits->max_sectors = FD_MAX_SECTORS;
-		fd_dev->fd_block_size = FD_BLOCKSIZE;
+		dev->dev_attrib.hw_block_size = FD_BLOCKSIZE;
+		dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS;
 	}
 
-	dev_limits.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH;
-	dev_limits.queue_depth = FD_DEVICE_QUEUE_DEPTH;
+	fd_dev->fd_block_size = dev->dev_attrib.hw_block_size;
 
-	dev = transport_add_device_to_core_hba(hba, &fileio_template,
-				se_dev, dev_flags, fd_dev,
-				&dev_limits, "FILEIO", FD_VERSION);
-	if (!dev)
-		goto fail;
+	dev->dev_attrib.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH;
 
 	if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
 		pr_debug("FILEIO: Forcing setting of emulate_write_cache=1"
 			" with FDBD_HAS_BUFFERED_IO_WCE\n");
-		dev->se_sub_dev->se_dev_attrib.emulate_write_cache = 1;
+		dev->dev_attrib.emulate_write_cache = 1;
 	}
 
 	fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++;
@@ -214,22 +198,18 @@ static struct se_device *fd_create_virtdevice(
 		" %llu total bytes\n", fd_host->fd_host_id, fd_dev->fd_dev_id,
 			fd_dev->fd_dev_name, fd_dev->fd_dev_size);
 
-	return dev;
+	return 0;
 fail:
 	if (fd_dev->fd_file) {
 		filp_close(fd_dev->fd_file, NULL);
 		fd_dev->fd_file = NULL;
 	}
-	return ERR_PTR(ret);
+	return ret;
 }
 
-/*	fd_free_device(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static void fd_free_device(void *p)
+static void fd_free_device(struct se_device *dev)
 {
-	struct fd_dev *fd_dev = p;
+	struct fd_dev *fd_dev = FD_DEV(dev);
 
 	if (fd_dev->fd_file) {
 		filp_close(fd_dev->fd_file, NULL);
@@ -243,13 +223,12 @@ static int fd_do_readv(struct se_cmd *cmd, struct scatterlist *sgl,
 		u32 sgl_nents)
 {
 	struct se_device *se_dev = cmd->se_dev;
-	struct fd_dev *dev = se_dev->dev_ptr;
+	struct fd_dev *dev = FD_DEV(se_dev);
 	struct file *fd = dev->fd_file;
 	struct scatterlist *sg;
 	struct iovec *iov;
 	mm_segment_t old_fs;
-	loff_t pos = (cmd->t_task_lba *
-		      se_dev->se_sub_dev->se_dev_attrib.block_size);
+	loff_t pos = (cmd->t_task_lba * se_dev->dev_attrib.block_size);
 	int ret = 0, i;
 
 	iov = kzalloc(sizeof(struct iovec) * sgl_nents, GFP_KERNEL);
@@ -296,13 +275,12 @@ static int fd_do_writev(struct se_cmd *cmd, struct scatterlist *sgl,
 		u32 sgl_nents)
 {
 	struct se_device *se_dev = cmd->se_dev;
-	struct fd_dev *dev = se_dev->dev_ptr;
+	struct fd_dev *dev = FD_DEV(se_dev);
 	struct file *fd = dev->fd_file;
 	struct scatterlist *sg;
 	struct iovec *iov;
 	mm_segment_t old_fs;
-	loff_t pos = (cmd->t_task_lba *
-		      se_dev->se_sub_dev->se_dev_attrib.block_size);
+	loff_t pos = (cmd->t_task_lba * se_dev->dev_attrib.block_size);
 	int ret, i = 0;
 
 	iov = kzalloc(sizeof(struct iovec) * sgl_nents, GFP_KERNEL);
@@ -334,7 +312,7 @@ static int fd_do_writev(struct se_cmd *cmd, struct scatterlist *sgl,
 static int fd_execute_sync_cache(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
-	struct fd_dev *fd_dev = dev->dev_ptr;
+	struct fd_dev *fd_dev = FD_DEV(dev);
 	int immed = (cmd->t_task_cdb[1] & 0x2);
 	loff_t start, end;
 	int ret;
@@ -353,7 +331,7 @@ static int fd_execute_sync_cache(struct se_cmd *cmd)
 		start = 0;
 		end = LLONG_MAX;
 	} else {
-		start = cmd->t_task_lba * dev->se_sub_dev->se_dev_attrib.block_size;
+		start = cmd->t_task_lba * dev->dev_attrib.block_size;
 		if (cmd->data_length)
 			end = start + cmd->data_length;
 		else
@@ -399,11 +377,11 @@ static int fd_execute_rw(struct se_cmd *cmd)
 		 * Allow this to happen independent of WCE=0 setting.
 		 */
 		if (ret > 0 &&
-		    dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 &&
+		    dev->dev_attrib.emulate_fua_write > 0 &&
 		    (cmd->se_cmd_flags & SCF_FUA)) {
-			struct fd_dev *fd_dev = dev->dev_ptr;
+			struct fd_dev *fd_dev = FD_DEV(dev);
 			loff_t start = cmd->t_task_lba *
-				dev->se_sub_dev->se_dev_attrib.block_size;
+				dev->dev_attrib.block_size;
 			loff_t end = start + cmd->data_length;
 
 			vfs_fsync_range(fd_dev->fd_file, start, end, 1);
@@ -430,12 +408,10 @@ static match_table_t tokens = {
 	{Opt_err, NULL}
 };
 
-static ssize_t fd_set_configfs_dev_params(
-	struct se_hba *hba,
-	struct se_subsystem_dev *se_dev,
-	const char *page, ssize_t count)
+static ssize_t fd_set_configfs_dev_params(struct se_device *dev,
+		const char *page, ssize_t count)
 {
-	struct fd_dev *fd_dev = se_dev->se_dev_su_ptr;
+	struct fd_dev *fd_dev = FD_DEV(dev);
 	char *orig, *ptr, *arg_p, *opts;
 	substring_t args[MAX_OPT_ARGS];
 	int ret = 0, arg, token;
@@ -502,24 +478,9 @@ out:
 	return (!ret) ? count : ret;
 }
 
-static ssize_t fd_check_configfs_dev_params(struct se_hba *hba, struct se_subsystem_dev *se_dev)
-{
-	struct fd_dev *fd_dev = se_dev->se_dev_su_ptr;
-
-	if (!(fd_dev->fbd_flags & FBDF_HAS_PATH)) {
-		pr_err("Missing fd_dev_name=\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static ssize_t fd_show_configfs_dev_params(
-	struct se_hba *hba,
-	struct se_subsystem_dev *se_dev,
-	char *b)
+static ssize_t fd_show_configfs_dev_params(struct se_device *dev, char *b)
 {
-	struct fd_dev *fd_dev = se_dev->se_dev_su_ptr;
+	struct fd_dev *fd_dev = FD_DEV(dev);
 	ssize_t bl = 0;
 
 	bl = sprintf(b + bl, "TCM FILEIO ID: %u", fd_dev->fd_dev_id);
@@ -550,7 +511,7 @@ static u32 fd_get_device_type(struct se_device *dev)
 
 static sector_t fd_get_blocks(struct se_device *dev)
 {
-	struct fd_dev *fd_dev = dev->dev_ptr;
+	struct fd_dev *fd_dev = FD_DEV(dev);
 	struct file *f = fd_dev->fd_file;
 	struct inode *i = f->f_mapping->host;
 	unsigned long long dev_size;
@@ -564,7 +525,7 @@ static sector_t fd_get_blocks(struct se_device *dev)
 	else
 		dev_size = fd_dev->fd_dev_size;
 
-	return div_u64(dev_size, dev->se_sub_dev->se_dev_attrib.block_size);
+	return div_u64(dev_size, dev->dev_attrib.block_size);
 }
 
 static struct spc_ops fd_spc_ops = {
@@ -579,15 +540,16 @@ static int fd_parse_cdb(struct se_cmd *cmd)
 
 static struct se_subsystem_api fileio_template = {
 	.name			= "fileio",
+	.inquiry_prod		= "FILEIO",
+	.inquiry_rev		= FD_VERSION,
 	.owner			= THIS_MODULE,
 	.transport_type		= TRANSPORT_PLUGIN_VHBA_PDEV,
 	.attach_hba		= fd_attach_hba,
 	.detach_hba		= fd_detach_hba,
-	.allocate_virtdevice	= fd_allocate_virtdevice,
-	.create_virtdevice	= fd_create_virtdevice,
+	.alloc_device		= fd_alloc_device,
+	.configure_device	= fd_configure_device,
 	.free_device		= fd_free_device,
 	.parse_cdb		= fd_parse_cdb,
-	.check_configfs_dev_params = fd_check_configfs_dev_params,
 	.set_configfs_dev_params = fd_set_configfs_dev_params,
 	.show_configfs_dev_params = fd_show_configfs_dev_params,
 	.get_device_rev		= fd_get_device_rev,
diff --git a/drivers/target/target_core_file.h b/drivers/target/target_core_file.h
index 876ae53ef5b8..bc02b018ae46 100644
--- a/drivers/target/target_core_file.h
+++ b/drivers/target/target_core_file.h
@@ -17,6 +17,8 @@
 #define FDBD_HAS_BUFFERED_IO_WCE 0x04
 
 struct fd_dev {
+	struct se_device dev;
+
 	u32		fbd_flags;
 	unsigned char	fd_dev_name[FD_MAX_DEV_NAME];
 	/* Unique Ramdisk Device ID in Ramdisk HBA */
diff --git a/drivers/target/target_core_hba.c b/drivers/target/target_core_hba.c
index 3dd1bd4b6f71..048b7b4b9102 100644
--- a/drivers/target/target_core_hba.c
+++ b/drivers/target/target_core_hba.c
@@ -113,7 +113,6 @@ core_alloc_hba(const char *plugin_name, u32 plugin_dep_id, u32 hba_flags)
 		return ERR_PTR(-ENOMEM);
 	}
 
-	INIT_LIST_HEAD(&hba->hba_dev_list);
 	spin_lock_init(&hba->device_lock);
 	mutex_init(&hba->hba_access_mutex);
 
@@ -152,8 +151,7 @@ out_free_hba:
 int
 core_delete_hba(struct se_hba *hba)
 {
-	if (!list_empty(&hba->hba_dev_list))
-		dump_stack();
+	WARN_ON(hba->dev_count);
 
 	hba->transport->detach_hba(hba);
 
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 57d7674c5013..dd6cd92cd9d8 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -50,6 +50,12 @@
 #define IBLOCK_MAX_BIO_PER_TASK	 32	/* max # of bios to submit at a time */
 #define IBLOCK_BIO_POOL_SIZE	128
 
+static inline struct iblock_dev *IBLOCK_DEV(struct se_device *dev)
+{
+	return container_of(dev, struct iblock_dev, dev);
+}
+
+
 static struct se_subsystem_api iblock_template;
 
 static void iblock_bio_done(struct bio *, int);
@@ -70,7 +76,7 @@ static void iblock_detach_hba(struct se_hba *hba)
 {
 }
 
-static void *iblock_allocate_virtdevice(struct se_hba *hba, const char *name)
+static struct se_device *iblock_alloc_device(struct se_hba *hba, const char *name)
 {
 	struct iblock_dev *ib_dev = NULL;
 
@@ -82,40 +88,28 @@ static void *iblock_allocate_virtdevice(struct se_hba *hba, const char *name)
 
 	pr_debug( "IBLOCK: Allocated ib_dev for %s\n", name);
 
-	return ib_dev;
+	return &ib_dev->dev;
 }
 
-static struct se_device *iblock_create_virtdevice(
-	struct se_hba *hba,
-	struct se_subsystem_dev *se_dev,
-	void *p)
+static int iblock_configure_device(struct se_device *dev)
 {
-	struct iblock_dev *ib_dev = p;
-	struct se_device *dev;
-	struct se_dev_limits dev_limits;
-	struct block_device *bd = NULL;
+	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
 	struct request_queue *q;
-	struct queue_limits *limits;
-	u32 dev_flags = 0;
+	struct block_device *bd = NULL;
 	fmode_t mode;
-	int ret = -EINVAL;
+	int ret = -ENOMEM;
 
-	if (!ib_dev) {
-		pr_err("Unable to locate struct iblock_dev parameter\n");
-		return ERR_PTR(ret);
+	if (!(ib_dev->ibd_flags & IBDF_HAS_UDEV_PATH)) {
+		pr_err("Missing udev_path= parameters for IBLOCK\n");
+		return -EINVAL;
 	}
-	memset(&dev_limits, 0, sizeof(struct se_dev_limits));
 
 	ib_dev->ibd_bio_set = bioset_create(IBLOCK_BIO_POOL_SIZE, 0);
 	if (!ib_dev->ibd_bio_set) {
-		pr_err("IBLOCK: Unable to create bioset()\n");
-		return ERR_PTR(-ENOMEM);
+		pr_err("IBLOCK: Unable to create bioset\n");
+		goto out;
 	}
-	pr_debug("IBLOCK: Created bio_set()\n");
-	/*
-	 * iblock_check_configfs_dev_params() ensures that ib_dev->ibd_udev_path
-	 * must already have been set in order for echo 1 > $HBA/$DEV/enable to run.
-	 */
+
 	pr_debug( "IBLOCK: Claiming struct block_device: %s\n",
 			ib_dev->ibd_udev_path);
 
@@ -126,27 +120,15 @@ static struct se_device *iblock_create_virtdevice(
 	bd = blkdev_get_by_path(ib_dev->ibd_udev_path, mode, ib_dev);
 	if (IS_ERR(bd)) {
 		ret = PTR_ERR(bd);
-		goto failed;
+		goto out_free_bioset;
 	}
-	/*
-	 * Setup the local scope queue_limits from struct request_queue->limits
-	 * to pass into transport_add_device_to_core_hba() as struct se_dev_limits.
-	 */
-	q = bdev_get_queue(bd);
-	limits = &dev_limits.limits;
-	limits->logical_block_size = bdev_logical_block_size(bd);
-	limits->max_hw_sectors = UINT_MAX;
-	limits->max_sectors = UINT_MAX;
-	dev_limits.hw_queue_depth = q->nr_requests;
-	dev_limits.queue_depth = q->nr_requests;
-
 	ib_dev->ibd_bd = bd;
 
-	dev = transport_add_device_to_core_hba(hba,
-			&iblock_template, se_dev, dev_flags, ib_dev,
-			&dev_limits, "IBLOCK", IBLOCK_VERSION);
-	if (!dev)
-		goto failed;
+	q = bdev_get_queue(bd);
+
+	dev->dev_attrib.hw_block_size = bdev_logical_block_size(bd);
+	dev->dev_attrib.hw_max_sectors = UINT_MAX;
+	dev->dev_attrib.hw_queue_depth = q->nr_requests;
 
 	/*
 	 * Check if the underlying struct block_device request_queue supports
@@ -154,15 +136,16 @@ static struct se_device *iblock_create_virtdevice(
 	 * in ATA and we need to set TPE=1
 	 */
 	if (blk_queue_discard(q)) {
-		dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count =
+		dev->dev_attrib.max_unmap_lba_count =
 				q->limits.max_discard_sectors;
+
 		/*
 		 * Currently hardcoded to 1 in Linux/SCSI code..
 		 */
-		dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count = 1;
-		dev->se_sub_dev->se_dev_attrib.unmap_granularity =
+		dev->dev_attrib.max_unmap_block_desc_count = 1;
+		dev->dev_attrib.unmap_granularity =
 				q->limits.discard_granularity >> 9;
-		dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment =
+		dev->dev_attrib.unmap_granularity_alignment =
 				q->limits.discard_alignment;
 
 		pr_debug("IBLOCK: BLOCK Discard support available,"
@@ -170,22 +153,19 @@ static struct se_device *iblock_create_virtdevice(
 	}
 
 	if (blk_queue_nonrot(q))
-		dev->se_sub_dev->se_dev_attrib.is_nonrot = 1;
-
-	return dev;
+		dev->dev_attrib.is_nonrot = 1;
+	return 0;
 
-failed:
-	if (ib_dev->ibd_bio_set) {
-		bioset_free(ib_dev->ibd_bio_set);
-		ib_dev->ibd_bio_set = NULL;
-	}
-	ib_dev->ibd_bd = NULL;
-	return ERR_PTR(ret);
+out_free_bioset:
+	bioset_free(ib_dev->ibd_bio_set);
+	ib_dev->ibd_bio_set = NULL;
+out:
+	return ret;
 }
 
-static void iblock_free_device(void *p)
+static void iblock_free_device(struct se_device *dev)
 {
-	struct iblock_dev *ib_dev = p;
+	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
 
 	if (ib_dev->ibd_bd != NULL)
 		blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL);
@@ -203,12 +183,12 @@ static unsigned long long iblock_emulate_read_cap_with_block_size(
 					bdev_logical_block_size(bd)) - 1);
 	u32 block_size = bdev_logical_block_size(bd);
 
-	if (block_size == dev->se_sub_dev->se_dev_attrib.block_size)
+	if (block_size == dev->dev_attrib.block_size)
 		return blocks_long;
 
 	switch (block_size) {
 	case 4096:
-		switch (dev->se_sub_dev->se_dev_attrib.block_size) {
+		switch (dev->dev_attrib.block_size) {
 		case 2048:
 			blocks_long <<= 1;
 			break;
@@ -222,7 +202,7 @@ static unsigned long long iblock_emulate_read_cap_with_block_size(
 		}
 		break;
 	case 2048:
-		switch (dev->se_sub_dev->se_dev_attrib.block_size) {
+		switch (dev->dev_attrib.block_size) {
 		case 4096:
 			blocks_long >>= 1;
 			break;
@@ -237,7 +217,7 @@ static unsigned long long iblock_emulate_read_cap_with_block_size(
 		}
 		break;
 	case 1024:
-		switch (dev->se_sub_dev->se_dev_attrib.block_size) {
+		switch (dev->dev_attrib.block_size) {
 		case 4096:
 			blocks_long >>= 2;
 			break;
@@ -252,7 +232,7 @@ static unsigned long long iblock_emulate_read_cap_with_block_size(
 		}
 		break;
 	case 512:
-		switch (dev->se_sub_dev->se_dev_attrib.block_size) {
+		switch (dev->dev_attrib.block_size) {
 		case 4096:
 			blocks_long >>= 3;
 			break;
@@ -299,7 +279,7 @@ static void iblock_end_io_flush(struct bio *bio, int err)
  */
 static int iblock_execute_sync_cache(struct se_cmd *cmd)
 {
-	struct iblock_dev *ib_dev = cmd->se_dev->dev_ptr;
+	struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev);
 	int immed = (cmd->t_task_cdb[1] & 0x2);
 	struct bio *bio;
 
@@ -322,7 +302,7 @@ static int iblock_execute_sync_cache(struct se_cmd *cmd)
 static int iblock_execute_unmap(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
-	struct iblock_dev *ibd = dev->dev_ptr;
+	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
 	unsigned char *buf, *ptr = NULL;
 	sector_t lba;
 	int size;
@@ -349,7 +329,7 @@ static int iblock_execute_unmap(struct se_cmd *cmd)
 	else
 		size = bd_dl;
 
-	if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) {
+	if (size / 16 > dev->dev_attrib.max_unmap_block_desc_count) {
 		cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
 		ret = -EINVAL;
 		goto err;
@@ -366,7 +346,7 @@ static int iblock_execute_unmap(struct se_cmd *cmd)
 		pr_debug("UNMAP: Using lba: %llu and range: %u\n",
 				 (unsigned long long)lba, range);
 
-		if (range > dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count) {
+		if (range > dev->dev_attrib.max_unmap_lba_count) {
 			cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
 			ret = -EINVAL;
 			goto err;
@@ -378,7 +358,7 @@ static int iblock_execute_unmap(struct se_cmd *cmd)
 			goto err;
 		}
 
-		ret = blkdev_issue_discard(ibd->ibd_bd, lba, range,
+		ret = blkdev_issue_discard(ib_dev->ibd_bd, lba, range,
 					   GFP_KERNEL, 0);
 		if (ret < 0) {
 			pr_err("blkdev_issue_discard() failed: %d\n",
@@ -399,10 +379,10 @@ err:
 
 static int iblock_execute_write_same(struct se_cmd *cmd)
 {
-	struct iblock_dev *ibd = cmd->se_dev->dev_ptr;
+	struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev);
 	int ret;
 
-	ret = blkdev_issue_discard(ibd->ibd_bd, cmd->t_task_lba,
+	ret = blkdev_issue_discard(ib_dev->ibd_bd, cmd->t_task_lba,
 				   spc_get_write_same_sectors(cmd), GFP_KERNEL,
 				   0);
 	if (ret < 0) {
@@ -425,11 +405,10 @@ static match_table_t tokens = {
 	{Opt_err, NULL}
 };
 
-static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba,
-					       struct se_subsystem_dev *se_dev,
-					       const char *page, ssize_t count)
+static ssize_t iblock_set_configfs_dev_params(struct se_device *dev,
+		const char *page, ssize_t count)
 {
-	struct iblock_dev *ib_dev = se_dev->se_dev_su_ptr;
+	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
 	char *orig, *ptr, *arg_p, *opts;
 	substring_t args[MAX_OPT_ARGS];
 	int ret = 0, token;
@@ -491,43 +470,26 @@ out:
 	return (!ret) ? count : ret;
 }
 
-static ssize_t iblock_check_configfs_dev_params(
-	struct se_hba *hba,
-	struct se_subsystem_dev *se_dev)
-{
-	struct iblock_dev *ibd = se_dev->se_dev_su_ptr;
-
-	if (!(ibd->ibd_flags & IBDF_HAS_UDEV_PATH)) {
-		pr_err("Missing udev_path= parameters for IBLOCK\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static ssize_t iblock_show_configfs_dev_params(
-	struct se_hba *hba,
-	struct se_subsystem_dev *se_dev,
-	char *b)
+static ssize_t iblock_show_configfs_dev_params(struct se_device *dev, char *b)
 {
-	struct iblock_dev *ibd = se_dev->se_dev_su_ptr;
-	struct block_device *bd = ibd->ibd_bd;
+	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
+	struct block_device *bd = ib_dev->ibd_bd;
 	char buf[BDEVNAME_SIZE];
 	ssize_t bl = 0;
 
 	if (bd)
 		bl += sprintf(b + bl, "iBlock device: %s",
 				bdevname(bd, buf));
-	if (ibd->ibd_flags & IBDF_HAS_UDEV_PATH)
+	if (ib_dev->ibd_flags & IBDF_HAS_UDEV_PATH)
 		bl += sprintf(b + bl, "  UDEV PATH: %s",
-				ibd->ibd_udev_path);
-	bl += sprintf(b + bl, "  readonly: %d\n", ibd->ibd_readonly);
+				ib_dev->ibd_udev_path);
+	bl += sprintf(b + bl, "  readonly: %d\n", ib_dev->ibd_readonly);
 
 	bl += sprintf(b + bl, "        ");
 	if (bd) {
 		bl += sprintf(b + bl, "Major: %d Minor: %d  %s\n",
 			MAJOR(bd->bd_dev), MINOR(bd->bd_dev), (!bd->bd_contains) ?
-			"" : (bd->bd_holder == ibd) ?
+			"" : (bd->bd_holder == ib_dev) ?
 			"CLAIMED: IBLOCK" : "CLAIMED: OS");
 	} else {
 		bl += sprintf(b + bl, "Major: 0 Minor: 0\n");
@@ -556,7 +518,7 @@ static void iblock_complete_cmd(struct se_cmd *cmd)
 static struct bio *
 iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num)
 {
-	struct iblock_dev *ib_dev = cmd->se_dev->dev_ptr;
+	struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev);
 	struct bio *bio;
 
 	/*
@@ -611,8 +573,8 @@ static int iblock_execute_rw(struct se_cmd *cmd)
 		 * Force data to disk if we pretend to not have a volatile
 		 * write cache, or the initiator set the Force Unit Access bit.
 		 */
-		if (dev->se_sub_dev->se_dev_attrib.emulate_write_cache == 0 ||
-		    (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 &&
+		if (dev->dev_attrib.emulate_write_cache == 0 ||
+		    (dev->dev_attrib.emulate_fua_write > 0 &&
 		     (cmd->se_cmd_flags & SCF_FUA)))
 			rw = WRITE_FUA;
 		else
@@ -625,17 +587,17 @@ static int iblock_execute_rw(struct se_cmd *cmd)
 	 * Convert the blocksize advertised to the initiator to the 512 byte
 	 * units unconditionally used by the Linux block layer.
 	 */
-	if (dev->se_sub_dev->se_dev_attrib.block_size == 4096)
+	if (dev->dev_attrib.block_size == 4096)
 		block_lba = (cmd->t_task_lba << 3);
-	else if (dev->se_sub_dev->se_dev_attrib.block_size == 2048)
+	else if (dev->dev_attrib.block_size == 2048)
 		block_lba = (cmd->t_task_lba << 2);
-	else if (dev->se_sub_dev->se_dev_attrib.block_size == 1024)
+	else if (dev->dev_attrib.block_size == 1024)
 		block_lba = (cmd->t_task_lba << 1);
-	else if (dev->se_sub_dev->se_dev_attrib.block_size == 512)
+	else if (dev->dev_attrib.block_size == 512)
 		block_lba = cmd->t_task_lba;
 	else {
 		pr_err("Unsupported SCSI -> BLOCK LBA conversion:"
-				" %u\n", dev->se_sub_dev->se_dev_attrib.block_size);
+				" %u\n", dev->dev_attrib.block_size);
 		cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 		return -ENOSYS;
 	}
@@ -714,8 +676,8 @@ static u32 iblock_get_device_type(struct se_device *dev)
 
 static sector_t iblock_get_blocks(struct se_device *dev)
 {
-	struct iblock_dev *ibd = dev->dev_ptr;
-	struct block_device *bd = ibd->ibd_bd;
+	struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
+	struct block_device *bd = ib_dev->ibd_bd;
 	struct request_queue *q = bdev_get_queue(bd);
 
 	return iblock_emulate_read_cap_with_block_size(dev, bd, q);
@@ -761,15 +723,16 @@ static int iblock_parse_cdb(struct se_cmd *cmd)
 
 static struct se_subsystem_api iblock_template = {
 	.name			= "iblock",
+	.inquiry_prod		= "IBLOCK",
+	.inquiry_rev		= IBLOCK_VERSION,
 	.owner			= THIS_MODULE,
 	.transport_type		= TRANSPORT_PLUGIN_VHBA_PDEV,
 	.attach_hba		= iblock_attach_hba,
 	.detach_hba		= iblock_detach_hba,
-	.allocate_virtdevice	= iblock_allocate_virtdevice,
-	.create_virtdevice	= iblock_create_virtdevice,
+	.alloc_device		= iblock_alloc_device,
+	.configure_device	= iblock_configure_device,
 	.free_device		= iblock_free_device,
 	.parse_cdb		= iblock_parse_cdb,
-	.check_configfs_dev_params = iblock_check_configfs_dev_params,
 	.set_configfs_dev_params = iblock_set_configfs_dev_params,
 	.show_configfs_dev_params = iblock_show_configfs_dev_params,
 	.get_device_rev		= iblock_get_device_rev,
diff --git a/drivers/target/target_core_iblock.h b/drivers/target/target_core_iblock.h
index 533627ae79ec..01c2afd81500 100644
--- a/drivers/target/target_core_iblock.h
+++ b/drivers/target/target_core_iblock.h
@@ -14,6 +14,7 @@ struct iblock_req {
 #define IBDF_HAS_UDEV_PATH		0x01
 
 struct iblock_dev {
+	struct se_device dev;
 	unsigned char ibd_udev_path[SE_UDEV_PATH_LEN];
 	u32	ibd_flags;
 	struct bio_set	*ibd_bio_set;
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index 0fd428225d11..5854ed67af59 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -20,12 +20,6 @@ int	core_dev_export(struct se_device *, struct se_portal_group *,
 void	core_dev_unexport(struct se_device *, struct se_portal_group *,
 		struct se_lun *);
 int	target_report_luns(struct se_cmd *);
-void	se_release_device_for_hba(struct se_device *);
-void	se_release_vpd_for_dev(struct se_device *);
-int	se_free_virtual_device(struct se_device *, struct se_hba *);
-int	se_dev_check_online(struct se_device *);
-int	se_dev_check_shutdown(struct se_device *);
-void	se_dev_set_default_attribs(struct se_device *, struct se_dev_limits *);
 int	se_dev_set_task_timeout(struct se_device *, u32);
 int	se_dev_set_max_unmap_lba_count(struct se_device *, u32);
 int	se_dev_set_max_unmap_block_desc_count(struct se_device *, u32);
@@ -60,6 +54,9 @@ void	core_dev_free_initiator_node_lun_acl(struct se_portal_group *,
 		struct se_lun_acl *lacl);
 int	core_dev_setup_virtual_lun0(void);
 void	core_dev_release_virtual_lun0(void);
+struct se_device *target_alloc_device(struct se_hba *hba, const char *name);
+int	target_configure_device(struct se_device *dev);
+void	target_free_device(struct se_device *);
 
 /* target_core_hba.c */
 struct se_hba *core_alloc_hba(const char *, u32, u32);
@@ -106,9 +103,10 @@ bool	target_stop_cmd(struct se_cmd *cmd, unsigned long *flags);
 int	transport_clear_lun_from_sessions(struct se_lun *);
 void	transport_send_task_abort(struct se_cmd *);
 int	target_cmd_size_check(struct se_cmd *cmd, unsigned int size);
+void	target_qf_do_work(struct work_struct *work);
 
 /* target_core_stat.c */
-void	target_stat_setup_dev_default_groups(struct se_subsystem_dev *);
+void	target_stat_setup_dev_default_groups(struct se_device *);
 void	target_stat_setup_port_default_groups(struct se_lun *);
 void	target_stat_setup_mappedlun_default_groups(struct se_lun_acl *);
 
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index 8c323a98c4a0..2b289891672f 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -103,7 +103,7 @@ static int core_scsi2_reservation_check(struct se_cmd *cmd, u32 *pr_reg_type)
 		spin_unlock(&dev->dev_reservation_lock);
 		return -EINVAL;
 	}
-	if (!(dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID)) {
+	if (!(dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID)) {
 		spin_unlock(&dev->dev_reservation_lock);
 		return 0;
 	}
@@ -120,10 +120,10 @@ static void core_scsi3_put_pr_reg(struct t10_pr_registration *);
 static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd)
 {
 	struct se_session *se_sess = cmd->se_sess;
-	struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
+	struct se_device *dev = cmd->se_dev;
 	struct t10_pr_registration *pr_reg;
-	struct t10_reservation *pr_tmpl = &su_dev->t10_pr;
-	int crh = (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS);
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
+	int crh = (dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS);
 	int conflict = 0;
 
 	if (!crh)
@@ -223,10 +223,10 @@ int target_scsi2_reservation_release(struct se_cmd *cmd)
 		goto out_unlock;
 
 	dev->dev_reserved_node_acl = NULL;
-	dev->dev_flags &= ~DF_SPC2_RESERVATIONS;
-	if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) {
+	dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS;
+	if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS_WITH_ISID) {
 		dev->dev_res_bin_isid = 0;
-		dev->dev_flags &= ~DF_SPC2_RESERVATIONS_WITH_ISID;
+		dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS_WITH_ISID;
 	}
 	tpg = sess->se_tpg;
 	pr_debug("SCSI-2 Released reservation for %s LUN: %u ->"
@@ -292,10 +292,10 @@ int target_scsi2_reservation_reserve(struct se_cmd *cmd)
 	}
 
 	dev->dev_reserved_node_acl = sess->se_node_acl;
-	dev->dev_flags |= DF_SPC2_RESERVATIONS;
+	dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS;
 	if (sess->sess_bin_isid != 0) {
 		dev->dev_res_bin_isid = sess->sess_bin_isid;
-		dev->dev_flags |= DF_SPC2_RESERVATIONS_WITH_ISID;
+		dev->dev_reservation_flags |= DRF_SPC2_RESERVATIONS_WITH_ISID;
 	}
 	pr_debug("SCSI-2 Reserved %s LUN: %u -> MAPPED LUN: %u"
 		" for %s\n", tpg->se_tpg_tfo->get_fabric_name(),
@@ -333,7 +333,7 @@ static int core_scsi3_pr_seq_non_holder(
 	/*
 	 * A legacy SPC-2 reservation is being held.
 	 */
-	if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS)
+	if (cmd->se_dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)
 		return core_scsi2_reservation_seq_non_holder(cmd,
 					cdb, pr_reg_type);
 
@@ -565,8 +565,8 @@ static int core_scsi3_pr_seq_non_holder(
 
 static u32 core_scsi3_pr_generation(struct se_device *dev)
 {
-	struct se_subsystem_dev *su_dev = dev->se_sub_dev;
 	u32 prg;
+
 	/*
 	 * PRGeneration field shall contain the value of a 32-bit wrapping
 	 * counter mainted by the device server.
@@ -577,7 +577,7 @@ static u32 core_scsi3_pr_generation(struct se_device *dev)
 	 * See spc4r17 section 6.3.12 READ_KEYS service action
 	 */
 	spin_lock(&dev->dev_reservation_lock);
-	prg = su_dev->t10_pr.pr_generation++;
+	prg = dev->t10_pr.pr_generation++;
 	spin_unlock(&dev->dev_reservation_lock);
 
 	return prg;
@@ -596,7 +596,7 @@ static int core_scsi3_pr_reservation_check(
 	/*
 	 * A legacy SPC-2 reservation is being held.
 	 */
-	if (dev->dev_flags & DF_SPC2_RESERVATIONS)
+	if (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)
 		return core_scsi2_reservation_check(cmd, pr_reg_type);
 
 	spin_lock(&dev->dev_reservation_lock);
@@ -636,7 +636,6 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration(
 	int all_tg_pt,
 	int aptpl)
 {
-	struct se_subsystem_dev *su_dev = dev->se_sub_dev;
 	struct t10_pr_registration *pr_reg;
 
 	pr_reg = kmem_cache_zalloc(t10_pr_reg_cache, GFP_ATOMIC);
@@ -645,7 +644,7 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration(
 		return NULL;
 	}
 
-	pr_reg->pr_aptpl_buf = kzalloc(su_dev->t10_pr.pr_aptpl_buf_len,
+	pr_reg->pr_aptpl_buf = kzalloc(dev->t10_pr.pr_aptpl_buf_len,
 					GFP_ATOMIC);
 	if (!pr_reg->pr_aptpl_buf) {
 		pr_err("Unable to allocate pr_reg->pr_aptpl_buf\n");
@@ -929,7 +928,7 @@ static int __core_scsi3_check_aptpl_registration(
 	struct se_dev_entry *deve)
 {
 	struct t10_pr_registration *pr_reg, *pr_reg_tmp;
-	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	unsigned char i_port[PR_APTPL_MAX_IPORT_LEN];
 	unsigned char t_port[PR_APTPL_MAX_TPORT_LEN];
 	u16 tpgt;
@@ -996,11 +995,10 @@ int core_scsi3_check_aptpl_registration(
 	struct se_lun *lun,
 	struct se_lun_acl *lun_acl)
 {
-	struct se_subsystem_dev *su_dev = dev->se_sub_dev;
 	struct se_node_acl *nacl = lun_acl->se_lun_nacl;
 	struct se_dev_entry *deve = nacl->device_list[lun_acl->mapped_lun];
 
-	if (su_dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
+	if (dev->t10_pr.res_type != SPC3_PERSISTENT_RESERVATIONS)
 		return 0;
 
 	return __core_scsi3_check_aptpl_registration(dev, tpg, lun,
@@ -1051,10 +1049,9 @@ static void __core_scsi3_add_registration(
 	int register_type,
 	int register_move)
 {
-	struct se_subsystem_dev *su_dev = dev->se_sub_dev;
 	struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo;
 	struct t10_pr_registration *pr_reg_tmp, *pr_reg_tmp_safe;
-	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 
 	/*
 	 * Increment PRgeneration counter for struct se_device upon a successful
@@ -1066,7 +1063,7 @@ static void __core_scsi3_add_registration(
 	 * for the REGISTER.
 	 */
 	pr_reg->pr_res_generation = (register_move) ?
-			su_dev->t10_pr.pr_generation++ :
+			dev->t10_pr.pr_generation++ :
 			core_scsi3_pr_generation(dev);
 
 	spin_lock(&pr_tmpl->registration_lock);
@@ -1135,7 +1132,7 @@ static struct t10_pr_registration *__core_scsi3_locate_pr_reg(
 	struct se_node_acl *nacl,
 	unsigned char *isid)
 {
-	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	struct t10_pr_registration *pr_reg, *pr_reg_tmp;
 	struct se_portal_group *tpg;
 
@@ -1160,7 +1157,7 @@ static struct t10_pr_registration *__core_scsi3_locate_pr_reg(
 			 * for fabric modules (iSCSI) requiring them.
 			 */
 			if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) {
-				if (dev->se_sub_dev->se_dev_attrib.enforce_pr_isids)
+				if (dev->dev_attrib.enforce_pr_isids)
 					continue;
 			}
 			atomic_inc(&pr_reg->pr_res_holders);
@@ -1274,7 +1271,7 @@ static void __core_scsi3_free_registration(
 {
 	struct target_core_fabric_ops *tfo =
 			pr_reg->pr_reg_nacl->se_tpg->se_tpg_tfo;
-	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	char i_buf[PR_REG_ISID_ID_LEN];
 	int prf_isid;
 
@@ -1335,7 +1332,7 @@ void core_scsi3_free_pr_reg_from_nacl(
 	struct se_device *dev,
 	struct se_node_acl *nacl)
 {
-	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_res_holder;
 	/*
 	 * If the passed se_node_acl matches the reservation holder,
@@ -1365,7 +1362,7 @@ void core_scsi3_free_pr_reg_from_nacl(
 void core_scsi3_free_all_registrations(
 	struct se_device *dev)
 {
-	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_res_holder;
 
 	spin_lock(&dev->dev_reservation_lock);
@@ -1899,7 +1896,6 @@ static int __core_scsi3_update_aptpl_buf(
 {
 	struct se_lun *lun;
 	struct se_portal_group *tpg;
-	struct se_subsystem_dev *su_dev = dev->se_sub_dev;
 	struct t10_pr_registration *pr_reg;
 	unsigned char tmp[512], isid_buf[32];
 	ssize_t len = 0;
@@ -1917,8 +1913,8 @@ static int __core_scsi3_update_aptpl_buf(
 	/*
 	 * Walk the registration list..
 	 */
-	spin_lock(&su_dev->t10_pr.registration_lock);
-	list_for_each_entry(pr_reg, &su_dev->t10_pr.registration_list,
+	spin_lock(&dev->t10_pr.registration_lock);
+	list_for_each_entry(pr_reg, &dev->t10_pr.registration_list,
 			pr_reg_list) {
 
 		tmp[0] = '\0';
@@ -1963,7 +1959,7 @@ static int __core_scsi3_update_aptpl_buf(
 		if ((len + strlen(tmp) >= pr_aptpl_buf_len)) {
 			pr_err("Unable to update renaming"
 				" APTPL metadata\n");
-			spin_unlock(&su_dev->t10_pr.registration_lock);
+			spin_unlock(&dev->t10_pr.registration_lock);
 			return -EMSGSIZE;
 		}
 		len += sprintf(buf+len, "%s", tmp);
@@ -1981,13 +1977,13 @@ static int __core_scsi3_update_aptpl_buf(
 		if ((len + strlen(tmp) >= pr_aptpl_buf_len)) {
 			pr_err("Unable to update renaming"
 				" APTPL metadata\n");
-			spin_unlock(&su_dev->t10_pr.registration_lock);
+			spin_unlock(&dev->t10_pr.registration_lock);
 			return -EMSGSIZE;
 		}
 		len += sprintf(buf+len, "%s", tmp);
 		reg_count++;
 	}
-	spin_unlock(&su_dev->t10_pr.registration_lock);
+	spin_unlock(&dev->t10_pr.registration_lock);
 
 	if (!reg_count)
 		len += sprintf(buf+len, "No Registrations or Reservations");
@@ -2019,7 +2015,7 @@ static int __core_scsi3_write_aptpl_to_file(
 	unsigned char *buf,
 	u32 pr_aptpl_buf_len)
 {
-	struct t10_wwn *wwn = &dev->se_sub_dev->t10_wwn;
+	struct t10_wwn *wwn = &dev->t10_wwn;
 	struct file *file;
 	struct iovec iov[1];
 	mm_segment_t old_fs;
@@ -2120,7 +2116,7 @@ static int core_scsi3_emulate_pro_register(
 	struct se_lun *se_lun = cmd->se_lun;
 	struct se_portal_group *se_tpg;
 	struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_reg_tmp, *pr_reg_e;
-	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	/* Used for APTPL metadata w/ UNREGISTER */
 	unsigned char *pr_aptpl_buf = NULL;
 	unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL;
@@ -2434,7 +2430,7 @@ static int core_scsi3_pro_reserve(
 	struct se_session *se_sess = cmd->se_sess;
 	struct se_lun *se_lun = cmd->se_lun;
 	struct t10_pr_registration *pr_reg, *pr_res_holder;
-	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	char i_buf[PR_REG_ISID_ID_LEN];
 	int ret, prf_isid;
 
@@ -2667,7 +2663,7 @@ static int core_scsi3_emulate_pro_release(
 	struct se_session *se_sess = cmd->se_sess;
 	struct se_lun *se_lun = cmd->se_lun;
 	struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_res_holder;
-	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	int ret, all_reg = 0;
 
 	if (!se_sess || !se_lun) {
@@ -2836,7 +2832,7 @@ static int core_scsi3_emulate_pro_clear(
 	struct se_device *dev = cmd->se_dev;
 	struct se_node_acl *pr_reg_nacl;
 	struct se_session *se_sess = cmd->se_sess;
-	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder;
 	u32 pr_res_mapped_lun = 0;
 	int calling_it_nexus = 0;
@@ -3006,7 +3002,7 @@ static int core_scsi3_pro_preempt(
 	struct se_session *se_sess = cmd->se_sess;
 	LIST_HEAD(preempt_and_abort_list);
 	struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder;
-	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	u32 pr_res_mapped_lun = 0;
 	int all_reg = 0, calling_it_nexus = 0, released_regs = 0;
 	int prh_type = 0, prh_scope = 0, ret;
@@ -3358,7 +3354,7 @@ static int core_scsi3_emulate_pro_register_and_move(
 	struct se_portal_group *se_tpg, *dest_se_tpg = NULL;
 	struct target_core_fabric_ops *dest_tf_ops = NULL, *tf_ops;
 	struct t10_pr_registration *pr_reg, *pr_res_holder, *dest_pr_reg;
-	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	unsigned char *buf;
 	unsigned char *initiator_str;
 	char *iport_ptr = NULL, dest_iport[64], i_buf[PR_REG_ISID_ID_LEN];
@@ -3823,7 +3819,7 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd)
 	 * initiator or service action and shall terminate with a RESERVATION
 	 * CONFLICT status.
 	 */
-	if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) {
+	if (cmd->se_dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) {
 		pr_err("Received PERSISTENT_RESERVE CDB while legacy"
 			" SPC-2 reservation is held, returning"
 			" RESERVATION_CONFLICT\n");
@@ -3959,8 +3955,7 @@ out:
  */
 static int core_scsi3_pri_read_keys(struct se_cmd *cmd)
 {
-	struct se_device *se_dev = cmd->se_dev;
-	struct se_subsystem_dev *su_dev = se_dev->se_sub_dev;
+	struct se_device *dev = cmd->se_dev;
 	struct t10_pr_registration *pr_reg;
 	unsigned char *buf;
 	u32 add_len = 0, off = 8;
@@ -3973,13 +3968,13 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd)
 	}
 
 	buf = transport_kmap_data_sg(cmd);
-	buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
-	buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
-	buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff);
-	buf[3] = (su_dev->t10_pr.pr_generation & 0xff);
+	buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff);
+	buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff);
+	buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff);
+	buf[3] = (dev->t10_pr.pr_generation & 0xff);
 
-	spin_lock(&su_dev->t10_pr.registration_lock);
-	list_for_each_entry(pr_reg, &su_dev->t10_pr.registration_list,
+	spin_lock(&dev->t10_pr.registration_lock);
+	list_for_each_entry(pr_reg, &dev->t10_pr.registration_list,
 			pr_reg_list) {
 		/*
 		 * Check for overflow of 8byte PRI READ_KEYS payload and
@@ -3999,7 +3994,7 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd)
 
 		add_len += 8;
 	}
-	spin_unlock(&su_dev->t10_pr.registration_lock);
+	spin_unlock(&dev->t10_pr.registration_lock);
 
 	buf[4] = ((add_len >> 24) & 0xff);
 	buf[5] = ((add_len >> 16) & 0xff);
@@ -4018,8 +4013,7 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd)
  */
 static int core_scsi3_pri_read_reservation(struct se_cmd *cmd)
 {
-	struct se_device *se_dev = cmd->se_dev;
-	struct se_subsystem_dev *su_dev = se_dev->se_sub_dev;
+	struct se_device *dev = cmd->se_dev;
 	struct t10_pr_registration *pr_reg;
 	unsigned char *buf;
 	u64 pr_res_key;
@@ -4033,13 +4027,13 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd)
 	}
 
 	buf = transport_kmap_data_sg(cmd);
-	buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
-	buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
-	buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff);
-	buf[3] = (su_dev->t10_pr.pr_generation & 0xff);
+	buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff);
+	buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff);
+	buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff);
+	buf[3] = (dev->t10_pr.pr_generation & 0xff);
 
-	spin_lock(&se_dev->dev_reservation_lock);
-	pr_reg = se_dev->dev_pr_res_holder;
+	spin_lock(&dev->dev_reservation_lock);
+	pr_reg = dev->dev_pr_res_holder;
 	if (pr_reg) {
 		/*
 		 * Set the hardcoded Additional Length
@@ -4090,7 +4084,7 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd)
 	}
 
 err:
-	spin_unlock(&se_dev->dev_reservation_lock);
+	spin_unlock(&dev->dev_reservation_lock);
 	transport_kunmap_data_sg(cmd);
 
 	return 0;
@@ -4104,7 +4098,7 @@ err:
 static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
-	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	unsigned char *buf;
 	u16 add_len = 8; /* Hardcoded to 8. */
 
@@ -4159,12 +4153,11 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd)
  */
 static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 {
-	struct se_device *se_dev = cmd->se_dev;
+	struct se_device *dev = cmd->se_dev;
 	struct se_node_acl *se_nacl;
-	struct se_subsystem_dev *su_dev = se_dev->se_sub_dev;
 	struct se_portal_group *se_tpg;
 	struct t10_pr_registration *pr_reg, *pr_reg_tmp;
-	struct t10_reservation *pr_tmpl = &se_dev->se_sub_dev->t10_pr;
+	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	unsigned char *buf;
 	u32 add_desc_len = 0, add_len = 0, desc_len, exp_desc_len;
 	u32 off = 8; /* off into first Full Status descriptor */
@@ -4179,10 +4172,10 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 
 	buf = transport_kmap_data_sg(cmd);
 
-	buf[0] = ((su_dev->t10_pr.pr_generation >> 24) & 0xff);
-	buf[1] = ((su_dev->t10_pr.pr_generation >> 16) & 0xff);
-	buf[2] = ((su_dev->t10_pr.pr_generation >> 8) & 0xff);
-	buf[3] = (su_dev->t10_pr.pr_generation & 0xff);
+	buf[0] = ((dev->t10_pr.pr_generation >> 24) & 0xff);
+	buf[1] = ((dev->t10_pr.pr_generation >> 16) & 0xff);
+	buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff);
+	buf[3] = (dev->t10_pr.pr_generation & 0xff);
 
 	spin_lock(&pr_tmpl->registration_lock);
 	list_for_each_entry_safe(pr_reg, pr_reg_tmp,
@@ -4316,7 +4309,7 @@ int target_scsi3_emulate_pr_in(struct se_cmd *cmd)
 	 * initiator or service action and shall terminate with a RESERVATION
 	 * CONFLICT status.
 	 */
-	if (cmd->se_dev->dev_flags & DF_SPC2_RESERVATIONS) {
+	if (cmd->se_dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS) {
 		pr_err("Received PERSISTENT_RESERVE CDB while legacy"
 			" SPC-2 reservation is held, returning"
 			" RESERVATION_CONFLICT\n");
@@ -4363,30 +4356,25 @@ static int core_pt_seq_non_holder(
 	return 0;
 }
 
-int core_setup_reservations(struct se_device *dev, int force_pt)
+void core_setup_reservations(struct se_device *dev)
 {
-	struct se_subsystem_dev *su_dev = dev->se_sub_dev;
-	struct t10_reservation *rest = &su_dev->t10_pr;
+	struct t10_reservation *rest = &dev->t10_pr;
+
 	/*
 	 * If this device is from Target_Core_Mod/pSCSI, use the reservations
 	 * of the Underlying SCSI hardware.  In Linux/SCSI terms, this can
 	 * cause a problem because libata and some SATA RAID HBAs appear
 	 * under Linux/SCSI, but to emulate reservations themselves.
 	 */
-	if (((dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) &&
-	    !(dev->se_sub_dev->se_dev_attrib.emulate_reservations)) || force_pt) {
+	if ((dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) ||
+	    (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV &&
+	     !dev->dev_attrib.emulate_reservations)) {
 		rest->res_type = SPC_PASSTHROUGH;
 		rest->pr_ops.t10_reservation_check = &core_pt_reservation_check;
 		rest->pr_ops.t10_seq_non_holder = &core_pt_seq_non_holder;
 		pr_debug("%s: Using SPC_PASSTHROUGH, no reservation"
 			" emulation\n", dev->transport->name);
-		return 0;
-	}
-	/*
-	 * If SPC-3 or above is reported by real or emulated struct se_device,
-	 * use emulated Persistent Reservations.
-	 */
-	if (dev->transport->get_device_rev(dev) >= SCSI_3) {
+	} else if (dev->transport->get_device_rev(dev) >= SCSI_3) {
 		rest->res_type = SPC3_PERSISTENT_RESERVATIONS;
 		rest->pr_ops.t10_reservation_check = &core_scsi3_pr_reservation_check;
 		rest->pr_ops.t10_seq_non_holder = &core_scsi3_pr_seq_non_holder;
@@ -4400,6 +4388,4 @@ int core_setup_reservations(struct se_device *dev, int force_pt)
 		pr_debug("%s: Using SPC2_RESERVATIONS emulation\n",
 			dev->transport->name);
 	}
-
-	return 0;
 }
diff --git a/drivers/target/target_core_pr.h b/drivers/target/target_core_pr.h
index af6c460d886d..78451437d2c2 100644
--- a/drivers/target/target_core_pr.h
+++ b/drivers/target/target_core_pr.h
@@ -63,6 +63,6 @@ extern unsigned char *core_scsi3_pr_dump_type(int);
 
 extern int target_scsi3_emulate_pr_in(struct se_cmd *);
 extern int target_scsi3_emulate_pr_out(struct se_cmd *);
-extern int core_setup_reservations(struct se_device *, int);
+extern void core_setup_reservations(struct se_device *);
 
 #endif /* TARGET_CORE_PR_H */
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index 617c086a8a02..b2965084eb4f 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -53,6 +53,11 @@
 
 #define ISPRINT(a)  ((a >= ' ') && (a <= '~'))
 
+static inline struct pscsi_dev_virt *PSCSI_DEV(struct se_device *dev)
+{
+	return container_of(dev, struct pscsi_dev_virt, dev);
+}
+
 static struct se_subsystem_api pscsi_template;
 
 static int pscsi_execute_cmd(struct se_cmd *cmd);
@@ -219,7 +224,7 @@ pscsi_get_inquiry_vpd_serial(struct scsi_device *sdev, struct t10_wwn *wwn)
 
 	snprintf(&wwn->unit_serial[0], INQUIRY_VPD_SERIAL_LEN, "%s", &buf[4]);
 
-	wwn->t10_sub_dev->su_dev_flags |= SDF_FIRMWARE_VPD_UNIT_SERIAL;
+	wwn->t10_dev->dev_flags |= DF_FIRMWARE_VPD_UNIT_SERIAL;
 
 	kfree(buf);
 	return 0;
@@ -299,23 +304,13 @@ out:
 	kfree(buf);
 }
 
-/*	pscsi_add_device_to_list():
- *
- *
- */
-static struct se_device *pscsi_add_device_to_list(
-	struct se_hba *hba,
-	struct se_subsystem_dev *se_dev,
-	struct pscsi_dev_virt *pdv,
-	struct scsi_device *sd,
-	int dev_flags)
+static int pscsi_add_device_to_list(struct se_device *dev,
+		struct scsi_device *sd)
 {
-	struct se_device *dev;
-	struct se_dev_limits dev_limits;
-	struct request_queue *q;
-	struct queue_limits *limits;
+	struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
+	struct request_queue *q = sd->request_queue;
 
-	memset(&dev_limits, 0, sizeof(struct se_dev_limits));
+	pdv->pdv_sd = sd;
 
 	if (!sd->queue_depth) {
 		sd->queue_depth = PSCSI_DEFAULT_QUEUEDEPTH;
@@ -324,54 +319,27 @@ static struct se_device *pscsi_add_device_to_list(
 			" queue_depth to %d\n", sd->channel, sd->id,
 				sd->lun, sd->queue_depth);
 	}
-	/*
-	 * Setup the local scope queue_limits from struct request_queue->limits
-	 * to pass into transport_add_device_to_core_hba() as struct se_dev_limits.
-	 */
-	q = sd->request_queue;
-	limits = &dev_limits.limits;
-	limits->logical_block_size = sd->sector_size;
-	limits->max_hw_sectors = min_t(int, sd->host->max_sectors, queue_max_hw_sectors(q));
-	limits->max_sectors = min_t(int, sd->host->max_sectors, queue_max_sectors(q));
-	dev_limits.hw_queue_depth = sd->queue_depth;
-	dev_limits.queue_depth = sd->queue_depth;
+
+	dev->dev_attrib.hw_block_size = sd->sector_size;
+	dev->dev_attrib.hw_max_sectors =
+		min_t(int, sd->host->max_sectors, queue_max_hw_sectors(q));
+	dev->dev_attrib.hw_queue_depth = sd->queue_depth;
+
 	/*
 	 * Setup our standard INQUIRY info into se_dev->t10_wwn
 	 */
-	pscsi_set_inquiry_info(sd, &se_dev->t10_wwn);
-
-	/*
-	 * Set the pointer pdv->pdv_sd to from passed struct scsi_device,
-	 * which has already been referenced with Linux SCSI code with
-	 * scsi_device_get() in this file's pscsi_create_virtdevice().
-	 *
-	 * The passthrough operations called by the transport_add_device_*
-	 * function below will require this pointer to be set for passthroug
-	 *  ops.
-	 *
-	 * For the shutdown case in pscsi_free_device(), this struct
-	 * scsi_device  reference is released with Linux SCSI code
-	 * scsi_device_put() and the pdv->pdv_sd cleared.
-	 */
-	pdv->pdv_sd = sd;
-	dev = transport_add_device_to_core_hba(hba, &pscsi_template,
-				se_dev, dev_flags, pdv,
-				&dev_limits, NULL, NULL);
-	if (!dev) {
-		pdv->pdv_sd = NULL;
-		return NULL;
-	}
+	pscsi_set_inquiry_info(sd, &dev->t10_wwn);
 
 	/*
 	 * Locate VPD WWN Information used for various purposes within
 	 * the Storage Engine.
 	 */
-	if (!pscsi_get_inquiry_vpd_serial(sd, &se_dev->t10_wwn)) {
+	if (!pscsi_get_inquiry_vpd_serial(sd, &dev->t10_wwn)) {
 		/*
 		 * If VPD Unit Serial returned GOOD status, try
 		 * VPD Device Identification page (0x83).
 		 */
-		pscsi_get_inquiry_vpd_device_ident(sd, &se_dev->t10_wwn);
+		pscsi_get_inquiry_vpd_device_ident(sd, &dev->t10_wwn);
 	}
 
 	/*
@@ -379,10 +347,11 @@ static struct se_device *pscsi_add_device_to_list(
 	 */
 	if (sd->type == TYPE_TAPE)
 		pscsi_tape_read_blocksize(dev, sd);
-	return dev;
+	return 0;
 }
 
-static void *pscsi_allocate_virtdevice(struct se_hba *hba, const char *name)
+static struct se_device *pscsi_alloc_device(struct se_hba *hba,
+		const char *name)
 {
 	struct pscsi_dev_virt *pdv;
 
@@ -391,139 +360,125 @@ static void *pscsi_allocate_virtdevice(struct se_hba *hba, const char *name)
 		pr_err("Unable to allocate memory for struct pscsi_dev_virt\n");
 		return NULL;
 	}
-	pdv->pdv_se_hba = hba;
 
 	pr_debug("PSCSI: Allocated pdv: %p for %s\n", pdv, name);
-	return pdv;
+	return &pdv->dev;
 }
 
 /*
  * Called with struct Scsi_Host->host_lock called.
  */
-static struct se_device *pscsi_create_type_disk(
-	struct scsi_device *sd,
-	struct pscsi_dev_virt *pdv,
-	struct se_subsystem_dev *se_dev,
-	struct se_hba *hba)
+static int pscsi_create_type_disk(struct se_device *dev, struct scsi_device *sd)
 	__releases(sh->host_lock)
 {
-	struct se_device *dev;
-	struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr;
+	struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
+	struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
 	struct Scsi_Host *sh = sd->host;
 	struct block_device *bd;
-	u32 dev_flags = 0;
+	int ret;
 
 	if (scsi_device_get(sd)) {
 		pr_err("scsi_device_get() failed for %d:%d:%d:%d\n",
 			sh->host_no, sd->channel, sd->id, sd->lun);
 		spin_unlock_irq(sh->host_lock);
-		return NULL;
+		return -EIO;
 	}
 	spin_unlock_irq(sh->host_lock);
 	/*
 	 * Claim exclusive struct block_device access to struct scsi_device
 	 * for TYPE_DISK using supplied udev_path
 	 */
-	bd = blkdev_get_by_path(se_dev->se_dev_udev_path,
+	bd = blkdev_get_by_path(dev->udev_path,
 				FMODE_WRITE|FMODE_READ|FMODE_EXCL, pdv);
 	if (IS_ERR(bd)) {
 		pr_err("pSCSI: blkdev_get_by_path() failed\n");
 		scsi_device_put(sd);
-		return NULL;
+		return PTR_ERR(bd);
 	}
 	pdv->pdv_bd = bd;
 
-	dev = pscsi_add_device_to_list(hba, se_dev, pdv, sd, dev_flags);
-	if (!dev) {
+	ret = pscsi_add_device_to_list(dev, sd);
+	if (ret) {
 		blkdev_put(pdv->pdv_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL);
 		scsi_device_put(sd);
-		return NULL;
+		return ret;
 	}
+
 	pr_debug("CORE_PSCSI[%d] - Added TYPE_DISK for %d:%d:%d:%d\n",
 		phv->phv_host_id, sh->host_no, sd->channel, sd->id, sd->lun);
-
-	return dev;
+	return 0;
 }
 
 /*
  * Called with struct Scsi_Host->host_lock called.
  */
-static struct se_device *pscsi_create_type_rom(
-	struct scsi_device *sd,
-	struct pscsi_dev_virt *pdv,
-	struct se_subsystem_dev *se_dev,
-	struct se_hba *hba)
+static int pscsi_create_type_rom(struct se_device *dev, struct scsi_device *sd)
 	__releases(sh->host_lock)
 {
-	struct se_device *dev;
-	struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr;
+	struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
 	struct Scsi_Host *sh = sd->host;
-	u32 dev_flags = 0;
+	int ret;
 
 	if (scsi_device_get(sd)) {
 		pr_err("scsi_device_get() failed for %d:%d:%d:%d\n",
 			sh->host_no, sd->channel, sd->id, sd->lun);
 		spin_unlock_irq(sh->host_lock);
-		return NULL;
+		return -EIO;
 	}
 	spin_unlock_irq(sh->host_lock);
 
-	dev = pscsi_add_device_to_list(hba, se_dev, pdv, sd, dev_flags);
-	if (!dev) {
+	ret = pscsi_add_device_to_list(dev, sd);
+	if (ret) {
 		scsi_device_put(sd);
-		return NULL;
+		return ret;
 	}
 	pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%d\n",
 		phv->phv_host_id, scsi_device_type(sd->type), sh->host_no,
 		sd->channel, sd->id, sd->lun);
 
-	return dev;
+	return 0;
 }
 
 /*
- *Called with struct Scsi_Host->host_lock called.
+ * Called with struct Scsi_Host->host_lock called.
  */
-static struct se_device *pscsi_create_type_other(
-	struct scsi_device *sd,
-	struct pscsi_dev_virt *pdv,
-	struct se_subsystem_dev *se_dev,
-	struct se_hba *hba)
+static int pscsi_create_type_other(struct se_device *dev,
+		struct scsi_device *sd)
 	__releases(sh->host_lock)
 {
-	struct se_device *dev;
-	struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr;
+	struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
 	struct Scsi_Host *sh = sd->host;
-	u32 dev_flags = 0;
+	int ret;
 
 	spin_unlock_irq(sh->host_lock);
-	dev = pscsi_add_device_to_list(hba, se_dev, pdv, sd, dev_flags);
-	if (!dev)
-		return NULL;
+	ret = pscsi_add_device_to_list(dev, sd);
+	if (ret)
+		return ret;
 
 	pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%d\n",
 		phv->phv_host_id, scsi_device_type(sd->type), sh->host_no,
 		sd->channel, sd->id, sd->lun);
-
-	return dev;
+	return 0;
 }
 
-static struct se_device *pscsi_create_virtdevice(
-	struct se_hba *hba,
-	struct se_subsystem_dev *se_dev,
-	void *p)
+int pscsi_configure_device(struct se_device *dev)
 {
-	struct pscsi_dev_virt *pdv = p;
-	struct se_device *dev;
+	struct se_hba *hba = dev->se_hba;
+	struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
 	struct scsi_device *sd;
-	struct pscsi_hba_virt *phv = hba->hba_ptr;
+	struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
 	struct Scsi_Host *sh = phv->phv_lld_host;
 	int legacy_mode_enable = 0;
+	int ret;
 
-	if (!pdv) {
-		pr_err("Unable to locate struct pscsi_dev_virt"
-				" parameter\n");
-		return ERR_PTR(-EINVAL);
+	if (!(pdv->pdv_flags & PDF_HAS_CHANNEL_ID) ||
+	    !(pdv->pdv_flags & PDF_HAS_TARGET_ID) ||
+	    !(pdv->pdv_flags & PDF_HAS_LUN_ID)) {
+		pr_err("Missing scsi_channel_id=, scsi_target_id= and"
+			" scsi_lun_id= parameters\n");
+		return -EINVAL;
 	}
+
 	/*
 	 * If not running in PHV_LLD_SCSI_HOST_NO mode, locate the
 	 * struct Scsi_Host we will need to bring the TCM/pSCSI object online
@@ -532,16 +487,16 @@ static struct se_device *pscsi_create_virtdevice(
 		if (phv->phv_mode == PHV_LLD_SCSI_HOST_NO) {
 			pr_err("pSCSI: Unable to locate struct"
 				" Scsi_Host for PHV_LLD_SCSI_HOST_NO\n");
-			return ERR_PTR(-ENODEV);
+			return -ENODEV;
 		}
 		/*
 		 * For the newer PHV_VIRTUAL_HOST_ID struct scsi_device
 		 * reference, we enforce that udev_path has been set
 		 */
-		if (!(se_dev->su_dev_flags & SDF_USING_UDEV_PATH)) {
+		if (!(dev->dev_flags & DF_USING_UDEV_PATH)) {
 			pr_err("pSCSI: udev_path attribute has not"
 				" been set before ENABLE=1\n");
-			return ERR_PTR(-EINVAL);
+			return -EINVAL;
 		}
 		/*
 		 * If no scsi_host_id= was passed for PHV_VIRTUAL_HOST_ID,
@@ -549,17 +504,14 @@ static struct se_device *pscsi_create_virtdevice(
 		 * and enable for PHV_LLD_SCSI_HOST_NO mode.
 		 */
 		if (!(pdv->pdv_flags & PDF_HAS_VIRT_HOST_ID)) {
-			spin_lock(&hba->device_lock);
-			if (!list_empty(&hba->hba_dev_list)) {
+			if (hba->dev_count) {
 				pr_err("pSCSI: Unable to set hba_mode"
 					" with active devices\n");
-				spin_unlock(&hba->device_lock);
-				return ERR_PTR(-EEXIST);
+				return -EEXIST;
 			}
-			spin_unlock(&hba->device_lock);
 
 			if (pscsi_pmode_enable_hba(hba, 1) != 1)
-				return ERR_PTR(-ENODEV);
+				return -ENODEV;
 
 			legacy_mode_enable = 1;
 			hba->hba_flags |= HBA_FLAGS_PSCSI_MODE;
@@ -569,14 +521,14 @@ static struct se_device *pscsi_create_virtdevice(
 			if (IS_ERR(sh)) {
 				pr_err("pSCSI: Unable to locate"
 					" pdv_host_id: %d\n", pdv->pdv_host_id);
-				return ERR_CAST(sh);
+				return PTR_ERR(sh);
 			}
 		}
 	} else {
 		if (phv->phv_mode == PHV_VIRTUAL_HOST_ID) {
 			pr_err("pSCSI: PHV_VIRTUAL_HOST_ID set while"
 				" struct Scsi_Host exists\n");
-			return ERR_PTR(-EEXIST);
+			return -EEXIST;
 		}
 	}
 
@@ -593,17 +545,17 @@ static struct se_device *pscsi_create_virtdevice(
 		 */
 		switch (sd->type) {
 		case TYPE_DISK:
-			dev = pscsi_create_type_disk(sd, pdv, se_dev, hba);
+			ret = pscsi_create_type_disk(dev, sd);
 			break;
 		case TYPE_ROM:
-			dev = pscsi_create_type_rom(sd, pdv, se_dev, hba);
+			ret = pscsi_create_type_rom(dev, sd);
 			break;
 		default:
-			dev = pscsi_create_type_other(sd, pdv, se_dev, hba);
+			ret = pscsi_create_type_other(dev, sd);
 			break;
 		}
 
-		if (!dev) {
+		if (ret) {
 			if (phv->phv_mode == PHV_VIRTUAL_HOST_ID)
 				scsi_host_put(sh);
 			else if (legacy_mode_enable) {
@@ -611,9 +563,9 @@ static struct se_device *pscsi_create_virtdevice(
 				hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE;
 			}
 			pdv->pdv_sd = NULL;
-			return ERR_PTR(-ENODEV);
+			return ret;
 		}
-		return dev;
+		return 0;
 	}
 	spin_unlock_irq(sh->host_lock);
 
@@ -627,17 +579,13 @@ static struct se_device *pscsi_create_virtdevice(
 		hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE;
 	}
 
-	return ERR_PTR(-ENODEV);
+	return -ENODEV;
 }
 
-/*	pscsi_free_device(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static void pscsi_free_device(void *p)
+static void pscsi_free_device(struct se_device *dev)
 {
-	struct pscsi_dev_virt *pdv = p;
-	struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr;
+	struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
+	struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
 	struct scsi_device *sd = pdv->pdv_sd;
 
 	if (sd) {
@@ -670,7 +618,7 @@ static void pscsi_free_device(void *p)
 static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg,
 				     unsigned char *sense_buffer)
 {
-	struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr;
+	struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev);
 	struct scsi_device *sd = pdv->pdv_sd;
 	int result;
 	struct pscsi_plugin_task *pt = cmd->priv;
@@ -770,13 +718,11 @@ static match_table_t tokens = {
 	{Opt_err, NULL}
 };
 
-static ssize_t pscsi_set_configfs_dev_params(struct se_hba *hba,
-	struct se_subsystem_dev *se_dev,
-	const char *page,
-	ssize_t count)
+static ssize_t pscsi_set_configfs_dev_params(struct se_device *dev,
+		const char *page, ssize_t count)
 {
-	struct pscsi_dev_virt *pdv = se_dev->se_dev_su_ptr;
-	struct pscsi_hba_virt *phv = hba->hba_ptr;
+	struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
+	struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
 	char *orig, *ptr, *opts;
 	substring_t args[MAX_OPT_ARGS];
 	int ret = 0, arg, token;
@@ -841,29 +787,10 @@ out:
 	return (!ret) ? count : ret;
 }
 
-static ssize_t pscsi_check_configfs_dev_params(
-	struct se_hba *hba,
-	struct se_subsystem_dev *se_dev)
-{
-	struct pscsi_dev_virt *pdv = se_dev->se_dev_su_ptr;
-
-	if (!(pdv->pdv_flags & PDF_HAS_CHANNEL_ID) ||
-	    !(pdv->pdv_flags & PDF_HAS_TARGET_ID) ||
-	    !(pdv->pdv_flags & PDF_HAS_LUN_ID)) {
-		pr_err("Missing scsi_channel_id=, scsi_target_id= and"
-			" scsi_lun_id= parameters\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static ssize_t pscsi_show_configfs_dev_params(struct se_hba *hba,
-					      struct se_subsystem_dev *se_dev,
-					      char *b)
+static ssize_t pscsi_show_configfs_dev_params(struct se_device *dev, char *b)
 {
-	struct pscsi_hba_virt *phv = hba->hba_ptr;
-        struct pscsi_dev_virt *pdv = se_dev->se_dev_su_ptr;
+	struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr;
+	struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
 	struct scsi_device *sd = pdv->pdv_sd;
 	unsigned char host_id[16];
 	ssize_t bl;
@@ -933,7 +860,7 @@ static int pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl,
 		u32 sgl_nents, enum dma_data_direction data_direction,
 		struct bio **hbio)
 {
-	struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr;
+	struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev);
 	struct bio *bio = NULL, *tbio = NULL;
 	struct page *page;
 	struct scatterlist *sg;
@@ -1104,7 +1031,7 @@ static int pscsi_execute_cmd(struct se_cmd *cmd)
 	struct scatterlist *sgl = cmd->t_data_sg;
 	u32 sgl_nents = cmd->t_data_nents;
 	enum dma_data_direction data_direction = cmd->data_direction;
-	struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr;
+	struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev);
 	struct pscsi_plugin_task *pt;
 	struct request *req;
 	struct bio *hbio;
@@ -1191,7 +1118,7 @@ fail:
  */
 static u32 pscsi_get_device_rev(struct se_device *dev)
 {
-	struct pscsi_dev_virt *pdv = dev->dev_ptr;
+	struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
 	struct scsi_device *sd = pdv->pdv_sd;
 
 	return (sd->scsi_level - 1) ? sd->scsi_level - 1 : 1;
@@ -1203,7 +1130,7 @@ static u32 pscsi_get_device_rev(struct se_device *dev)
  */
 static u32 pscsi_get_device_type(struct se_device *dev)
 {
-	struct pscsi_dev_virt *pdv = dev->dev_ptr;
+	struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
 	struct scsi_device *sd = pdv->pdv_sd;
 
 	return sd->type;
@@ -1211,7 +1138,7 @@ static u32 pscsi_get_device_type(struct se_device *dev)
 
 static sector_t pscsi_get_blocks(struct se_device *dev)
 {
-	struct pscsi_dev_virt *pdv = dev->dev_ptr;
+	struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
 
 	if (pdv->pdv_bd && pdv->pdv_bd->bd_part)
 		return pdv->pdv_bd->bd_part->nr_sects;
@@ -1259,12 +1186,11 @@ static struct se_subsystem_api pscsi_template = {
 	.attach_hba		= pscsi_attach_hba,
 	.detach_hba		= pscsi_detach_hba,
 	.pmode_enable_hba	= pscsi_pmode_enable_hba,
-	.allocate_virtdevice	= pscsi_allocate_virtdevice,
-	.create_virtdevice	= pscsi_create_virtdevice,
+	.alloc_device		= pscsi_alloc_device,
+	.configure_device	= pscsi_configure_device,
 	.free_device		= pscsi_free_device,
 	.transport_complete	= pscsi_transport_complete,
 	.parse_cdb		= pscsi_parse_cdb,
-	.check_configfs_dev_params = pscsi_check_configfs_dev_params,
 	.set_configfs_dev_params = pscsi_set_configfs_dev_params,
 	.show_configfs_dev_params = pscsi_show_configfs_dev_params,
 	.get_device_rev		= pscsi_get_device_rev,
diff --git a/drivers/target/target_core_pscsi.h b/drivers/target/target_core_pscsi.h
index bc1e5e11eca0..1bd757dff8ee 100644
--- a/drivers/target/target_core_pscsi.h
+++ b/drivers/target/target_core_pscsi.h
@@ -37,6 +37,7 @@ struct pscsi_plugin_task {
 #define PDF_HAS_VIRT_HOST_ID	0x20
 
 struct pscsi_dev_virt {
+	struct se_device dev;
 	int	pdv_flags;
 	int	pdv_host_id;
 	int	pdv_channel_id;
@@ -44,7 +45,6 @@ struct pscsi_dev_virt {
 	int	pdv_lun_id;
 	struct block_device *pdv_bd;
 	struct scsi_device *pdv_sd;
-	struct se_hba *pdv_se_hba;
 } ____cacheline_aligned;
 
 typedef enum phv_modes {
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index d00bbe33ff8b..d083f39c4b67 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -41,7 +41,10 @@
 
 #include "target_core_rd.h"
 
-static struct se_subsystem_api rd_mcp_template;
+static inline struct rd_dev *RD_DEV(struct se_device *dev)
+{
+	return container_of(dev, struct rd_dev, dev);
+}
 
 /*	rd_attach_hba(): (Part of se_subsystem_api_t template)
  *
@@ -196,7 +199,7 @@ static int rd_build_device_space(struct rd_dev *rd_dev)
 	return 0;
 }
 
-static void *rd_allocate_virtdevice(struct se_hba *hba, const char *name)
+static struct se_device *rd_alloc_device(struct se_hba *hba, const char *name)
 {
 	struct rd_dev *rd_dev;
 	struct rd_host *rd_host = hba->hba_ptr;
@@ -209,39 +212,27 @@ static void *rd_allocate_virtdevice(struct se_hba *hba, const char *name)
 
 	rd_dev->rd_host = rd_host;
 
-	return rd_dev;
+	return &rd_dev->dev;
 }
 
-static struct se_device *rd_create_virtdevice(struct se_hba *hba,
-		struct se_subsystem_dev *se_dev, void *p)
+static int rd_configure_device(struct se_device *dev)
 {
-	struct se_device *dev;
-	struct se_dev_limits dev_limits;
-	struct rd_dev *rd_dev = p;
-	struct rd_host *rd_host = hba->hba_ptr;
-	int dev_flags = 0, ret;
-	char prod[16], rev[4];
+	struct rd_dev *rd_dev = RD_DEV(dev);
+	struct rd_host *rd_host = dev->se_hba->hba_ptr;
+	int ret;
 
-	memset(&dev_limits, 0, sizeof(struct se_dev_limits));
+	if (!(rd_dev->rd_flags & RDF_HAS_PAGE_COUNT)) {
+		pr_debug("Missing rd_pages= parameter\n");
+		return -EINVAL;
+	}
 
 	ret = rd_build_device_space(rd_dev);
 	if (ret < 0)
 		goto fail;
 
-	snprintf(prod, 16, "RAMDISK-MCP");
-	snprintf(rev, 4, "%s", RD_MCP_VERSION);
-
-	dev_limits.limits.logical_block_size = RD_BLOCKSIZE;
-	dev_limits.limits.max_hw_sectors = UINT_MAX;
-	dev_limits.limits.max_sectors = UINT_MAX;
-	dev_limits.hw_queue_depth = RD_MAX_DEVICE_QUEUE_DEPTH;
-	dev_limits.queue_depth = RD_DEVICE_QUEUE_DEPTH;
-
-	dev = transport_add_device_to_core_hba(hba,
-			&rd_mcp_template, se_dev, dev_flags, rd_dev,
-			&dev_limits, prod, rev);
-	if (!dev)
-		goto fail;
+	dev->dev_attrib.hw_block_size = RD_BLOCKSIZE;
+	dev->dev_attrib.hw_max_sectors = UINT_MAX;
+	dev->dev_attrib.hw_queue_depth = RD_MAX_DEVICE_QUEUE_DEPTH;
 
 	rd_dev->rd_dev_id = rd_host->rd_host_dev_id_count++;
 
@@ -251,16 +242,16 @@ static struct se_device *rd_create_virtdevice(struct se_hba *hba,
 		rd_dev->sg_table_count,
 		(unsigned long)(rd_dev->rd_page_count * PAGE_SIZE));
 
-	return dev;
+	return 0;
 
 fail:
 	rd_release_device_space(rd_dev);
-	return ERR_PTR(ret);
+	return ret;
 }
 
-static void rd_free_device(void *p)
+static void rd_free_device(struct se_device *dev)
 {
-	struct rd_dev *rd_dev = p;
+	struct rd_dev *rd_dev = RD_DEV(dev);
 
 	rd_release_device_space(rd_dev);
 	kfree(rd_dev);
@@ -290,7 +281,7 @@ static int rd_execute_rw(struct se_cmd *cmd)
 	u32 sgl_nents = cmd->t_data_nents;
 	enum dma_data_direction data_direction = cmd->data_direction;
 	struct se_device *se_dev = cmd->se_dev;
-	struct rd_dev *dev = se_dev->dev_ptr;
+	struct rd_dev *dev = RD_DEV(se_dev);
 	struct rd_dev_sg_table *table;
 	struct scatterlist *rd_sg;
 	struct sg_mapping_iter m;
@@ -300,7 +291,7 @@ static int rd_execute_rw(struct se_cmd *cmd)
 	u32 src_len;
 	u64 tmp;
 
-	tmp = cmd->t_task_lba * se_dev->se_sub_dev->se_dev_attrib.block_size;
+	tmp = cmd->t_task_lba * se_dev->dev_attrib.block_size;
 	rd_offset = do_div(tmp, PAGE_SIZE);
 	rd_page = tmp;
 	rd_size = cmd->data_length;
@@ -378,13 +369,10 @@ static match_table_t tokens = {
 	{Opt_err, NULL}
 };
 
-static ssize_t rd_set_configfs_dev_params(
-	struct se_hba *hba,
-	struct se_subsystem_dev *se_dev,
-	const char *page,
-	ssize_t count)
+static ssize_t rd_set_configfs_dev_params(struct se_device *dev,
+		const char *page, ssize_t count)
 {
-	struct rd_dev *rd_dev = se_dev->se_dev_su_ptr;
+	struct rd_dev *rd_dev = RD_DEV(dev);
 	char *orig, *ptr, *opts;
 	substring_t args[MAX_OPT_ARGS];
 	int ret = 0, arg, token;
@@ -417,24 +405,10 @@ static ssize_t rd_set_configfs_dev_params(
 	return (!ret) ? count : ret;
 }
 
-static ssize_t rd_check_configfs_dev_params(struct se_hba *hba, struct se_subsystem_dev *se_dev)
+static ssize_t rd_show_configfs_dev_params(struct se_device *dev, char *b)
 {
-	struct rd_dev *rd_dev = se_dev->se_dev_su_ptr;
-
-	if (!(rd_dev->rd_flags & RDF_HAS_PAGE_COUNT)) {
-		pr_debug("Missing rd_pages= parameter\n");
-		return -EINVAL;
-	}
+	struct rd_dev *rd_dev = RD_DEV(dev);
 
-	return 0;
-}
-
-static ssize_t rd_show_configfs_dev_params(
-	struct se_hba *hba,
-	struct se_subsystem_dev *se_dev,
-	char *b)
-{
-	struct rd_dev *rd_dev = se_dev->se_dev_su_ptr;
 	ssize_t bl = sprintf(b, "TCM RamDisk ID: %u  RamDisk Makeup: rd_mcp\n",
 			rd_dev->rd_dev_id);
 	bl += sprintf(b + bl, "        PAGES/PAGE_SIZE: %u*%lu"
@@ -455,9 +429,10 @@ static u32 rd_get_device_type(struct se_device *dev)
 
 static sector_t rd_get_blocks(struct se_device *dev)
 {
-	struct rd_dev *rd_dev = dev->dev_ptr;
+	struct rd_dev *rd_dev = RD_DEV(dev);
+
 	unsigned long long blocks_long = ((rd_dev->rd_page_count * PAGE_SIZE) /
-			dev->se_sub_dev->se_dev_attrib.block_size) - 1;
+			dev->dev_attrib.block_size) - 1;
 
 	return blocks_long;
 }
@@ -473,14 +448,15 @@ static int rd_parse_cdb(struct se_cmd *cmd)
 
 static struct se_subsystem_api rd_mcp_template = {
 	.name			= "rd_mcp",
+	.inquiry_prod		= "RAMDISK-MCP",
+	.inquiry_rev		= RD_MCP_VERSION,
 	.transport_type		= TRANSPORT_PLUGIN_VHBA_VDEV,
 	.attach_hba		= rd_attach_hba,
 	.detach_hba		= rd_detach_hba,
-	.allocate_virtdevice	= rd_allocate_virtdevice,
-	.create_virtdevice	= rd_create_virtdevice,
+	.alloc_device		= rd_alloc_device,
+	.configure_device	= rd_configure_device,
 	.free_device		= rd_free_device,
 	.parse_cdb		= rd_parse_cdb,
-	.check_configfs_dev_params = rd_check_configfs_dev_params,
 	.set_configfs_dev_params = rd_set_configfs_dev_params,
 	.show_configfs_dev_params = rd_show_configfs_dev_params,
 	.get_device_rev		= rd_get_device_rev,
diff --git a/drivers/target/target_core_rd.h b/drivers/target/target_core_rd.h
index 21458125fe51..933b38b6e563 100644
--- a/drivers/target/target_core_rd.h
+++ b/drivers/target/target_core_rd.h
@@ -24,6 +24,7 @@ struct rd_dev_sg_table {
 #define RDF_HAS_PAGE_COUNT	0x01
 
 struct rd_dev {
+	struct se_device dev;
 	u32		rd_flags;
 	/* Unique Ramdisk Device ID in Ramdisk HBA */
 	u32		rd_dev_id;
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index a6e27d967c7b..035193d04fa2 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -54,10 +54,10 @@ static int sbc_emulate_readcapacity(struct se_cmd *cmd)
 	buf[1] = (blocks >> 16) & 0xff;
 	buf[2] = (blocks >> 8) & 0xff;
 	buf[3] = blocks & 0xff;
-	buf[4] = (dev->se_sub_dev->se_dev_attrib.block_size >> 24) & 0xff;
-	buf[5] = (dev->se_sub_dev->se_dev_attrib.block_size >> 16) & 0xff;
-	buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff;
-	buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff;
+	buf[4] = (dev->dev_attrib.block_size >> 24) & 0xff;
+	buf[5] = (dev->dev_attrib.block_size >> 16) & 0xff;
+	buf[6] = (dev->dev_attrib.block_size >> 8) & 0xff;
+	buf[7] = dev->dev_attrib.block_size & 0xff;
 
 	rbuf = transport_kmap_data_sg(cmd);
 	if (rbuf) {
@@ -85,15 +85,15 @@ static int sbc_emulate_readcapacity_16(struct se_cmd *cmd)
 	buf[5] = (blocks >> 16) & 0xff;
 	buf[6] = (blocks >> 8) & 0xff;
 	buf[7] = blocks & 0xff;
-	buf[8] = (dev->se_sub_dev->se_dev_attrib.block_size >> 24) & 0xff;
-	buf[9] = (dev->se_sub_dev->se_dev_attrib.block_size >> 16) & 0xff;
-	buf[10] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff;
-	buf[11] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff;
+	buf[8] = (dev->dev_attrib.block_size >> 24) & 0xff;
+	buf[9] = (dev->dev_attrib.block_size >> 16) & 0xff;
+	buf[10] = (dev->dev_attrib.block_size >> 8) & 0xff;
+	buf[11] = dev->dev_attrib.block_size & 0xff;
 	/*
 	 * Set Thin Provisioning Enable bit following sbc3r22 in section
 	 * READ CAPACITY (16) byte 14 if emulate_tpu or emulate_tpws is enabled.
 	 */
-	if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
+	if (dev->dev_attrib.emulate_tpu || dev->dev_attrib.emulate_tpws)
 		buf[14] = 0x80;
 
 	rbuf = transport_kmap_data_sg(cmd);
@@ -143,7 +143,7 @@ static int sbc_emulate_noop(struct se_cmd *cmd)
 
 static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors)
 {
-	return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors;
+	return cmd->se_dev->dev_attrib.block_size * sectors;
 }
 
 static int sbc_check_valid_sectors(struct se_cmd *cmd)
@@ -152,7 +152,7 @@ static int sbc_check_valid_sectors(struct se_cmd *cmd)
 	unsigned long long end_lba;
 	u32 sectors;
 
-	sectors = cmd->data_length / dev->se_sub_dev->se_dev_attrib.block_size;
+	sectors = cmd->data_length / dev->dev_attrib.block_size;
 	end_lba = dev->transport->get_blocks(dev) + 1;
 
 	if (cmd->t_task_lba + sectors > end_lba) {
@@ -315,7 +315,6 @@ out:
 
 int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops)
 {
-	struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
 	struct se_device *dev = cmd->se_dev;
 	unsigned char *cdb = cmd->t_task_cdb;
 	unsigned int size;
@@ -562,18 +561,18 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops)
 	if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) {
 		unsigned long long end_lba;
 
-		if (sectors > su_dev->se_dev_attrib.fabric_max_sectors) {
+		if (sectors > dev->dev_attrib.fabric_max_sectors) {
 			printk_ratelimited(KERN_ERR "SCSI OP %02xh with too"
 				" big sectors %u exceeds fabric_max_sectors:"
 				" %u\n", cdb[0], sectors,
-				su_dev->se_dev_attrib.fabric_max_sectors);
+				dev->dev_attrib.fabric_max_sectors);
 			goto out_invalid_cdb_field;
 		}
-		if (sectors > su_dev->se_dev_attrib.hw_max_sectors) {
+		if (sectors > dev->dev_attrib.hw_max_sectors) {
 			printk_ratelimited(KERN_ERR "SCSI OP %02xh with too"
 				" big sectors %u exceeds backend hw_max_sectors:"
 				" %u\n", cdb[0], sectors,
-				su_dev->se_dev_attrib.hw_max_sectors);
+				dev->dev_attrib.hw_max_sectors);
 			goto out_invalid_cdb_field;
 		}
 
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index 6fd434d3d7e4..0af45ae32f8c 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -95,14 +95,14 @@ static int spc_emulate_inquiry_std(struct se_cmd *cmd, char *buf)
 	/*
 	 * Enable SCCS and TPGS fields for Emulated ALUA
 	 */
-	if (dev->se_sub_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED)
+	if (dev->t10_alua.alua_type == SPC3_ALUA_EMULATED)
 		spc_fill_alua_data(lun->lun_sep, buf);
 
 	buf[7] = 0x2; /* CmdQue=1 */
 
 	snprintf(&buf[8], 8, "LIO-ORG");
-	snprintf(&buf[16], 16, "%s", dev->se_sub_dev->t10_wwn.model);
-	snprintf(&buf[32], 4, "%s", dev->se_sub_dev->t10_wwn.revision);
+	snprintf(&buf[16], 16, "%s", dev->t10_wwn.model);
+	snprintf(&buf[32], 4, "%s", dev->t10_wwn.revision);
 	buf[4] = 31; /* Set additional length to 31 */
 
 	return 0;
@@ -114,15 +114,13 @@ static int spc_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf)
 	struct se_device *dev = cmd->se_dev;
 	u16 len = 0;
 
-	if (dev->se_sub_dev->su_dev_flags &
-			SDF_EMULATED_VPD_UNIT_SERIAL) {
+	if (dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL) {
 		u32 unit_serial_len;
 
-		unit_serial_len = strlen(dev->se_sub_dev->t10_wwn.unit_serial);
+		unit_serial_len = strlen(dev->t10_wwn.unit_serial);
 		unit_serial_len++; /* For NULL Terminator */
 
-		len += sprintf(&buf[4], "%s",
-			dev->se_sub_dev->t10_wwn.unit_serial);
+		len += sprintf(&buf[4], "%s", dev->t10_wwn.unit_serial);
 		len++; /* Extra Byte for NULL Terminator */
 		buf[3] = len;
 	}
@@ -132,7 +130,7 @@ static int spc_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf)
 static void spc_parse_naa_6h_vendor_specific(struct se_device *dev,
 		unsigned char *buf)
 {
-	unsigned char *p = &dev->se_sub_dev->t10_wwn.unit_serial[0];
+	unsigned char *p = &dev->t10_wwn.unit_serial[0];
 	int cnt;
 	bool next = true;
 
@@ -173,7 +171,7 @@ static int spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf)
 	struct t10_alua_lu_gp_member *lu_gp_mem;
 	struct t10_alua_tg_pt_gp *tg_pt_gp;
 	struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
-	unsigned char *prod = &dev->se_sub_dev->t10_wwn.model[0];
+	unsigned char *prod = &dev->t10_wwn.model[0];
 	u32 prod_len;
 	u32 unit_serial_len, off = 0;
 	u16 len = 0, id_len;
@@ -188,7 +186,7 @@ static int spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf)
 	 * /sys/kernel/config/target/core/$HBA/$DEV/wwn/vpd_unit_serial
 	 * value in order to return the NAA id.
 	 */
-	if (!(dev->se_sub_dev->su_dev_flags & SDF_EMULATED_VPD_UNIT_SERIAL))
+	if (!(dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL))
 		goto check_t10_vend_desc;
 
 	/* CODE SET == Binary */
@@ -236,14 +234,12 @@ check_t10_vend_desc:
 	prod_len += strlen(prod);
 	prod_len++; /* For : */
 
-	if (dev->se_sub_dev->su_dev_flags &
-			SDF_EMULATED_VPD_UNIT_SERIAL) {
-		unit_serial_len =
-			strlen(&dev->se_sub_dev->t10_wwn.unit_serial[0]);
+	if (dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL) {
+		unit_serial_len = strlen(&dev->t10_wwn.unit_serial[0]);
 		unit_serial_len++; /* For NULL Terminator */
 
 		id_len += sprintf(&buf[off+12], "%s:%s", prod,
-				&dev->se_sub_dev->t10_wwn.unit_serial[0]);
+				&dev->t10_wwn.unit_serial[0]);
 	}
 	buf[off] = 0x2; /* ASCII */
 	buf[off+1] = 0x1; /* T10 Vendor ID */
@@ -298,8 +294,7 @@ check_t10_vend_desc:
 		 * Get the PROTOCOL IDENTIFIER as defined by spc4r17
 		 * section 7.5.1 Table 362
 		 */
-		if (dev->se_sub_dev->t10_alua.alua_type !=
-				SPC3_ALUA_EMULATED)
+		if (dev->t10_alua.alua_type != SPC3_ALUA_EMULATED)
 			goto check_scsi_name;
 
 		tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
@@ -422,7 +417,7 @@ static int spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf)
 	buf[5] = 0x07;
 
 	/* If WriteCache emulation is enabled, set V_SUP */
-	if (cmd->se_dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0)
+	if (cmd->se_dev->dev_attrib.emulate_write_cache > 0)
 		buf[6] = 0x01;
 	return 0;
 }
@@ -439,7 +434,7 @@ static int spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
 	 * emulate_tpu=1 or emulate_tpws=1 we will be expect a
 	 * different page length for Thin Provisioning.
 	 */
-	if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
+	if (dev->dev_attrib.emulate_tpu || dev->dev_attrib.emulate_tpws)
 		have_tp = 1;
 
 	buf[0] = dev->transport->get_device_type(dev);
@@ -456,14 +451,14 @@ static int spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
 	/*
 	 * Set MAXIMUM TRANSFER LENGTH
 	 */
-	max_sectors = min(dev->se_sub_dev->se_dev_attrib.fabric_max_sectors,
-			  dev->se_sub_dev->se_dev_attrib.hw_max_sectors);
+	max_sectors = min(dev->dev_attrib.fabric_max_sectors,
+			  dev->dev_attrib.hw_max_sectors);
 	put_unaligned_be32(max_sectors, &buf[8]);
 
 	/*
 	 * Set OPTIMAL TRANSFER LENGTH
 	 */
-	put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.optimal_sectors, &buf[12]);
+	put_unaligned_be32(dev->dev_attrib.optimal_sectors, &buf[12]);
 
 	/*
 	 * Exit now if we don't support TP.
@@ -474,25 +469,25 @@ static int spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
 	/*
 	 * Set MAXIMUM UNMAP LBA COUNT
 	 */
-	put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count, &buf[20]);
+	put_unaligned_be32(dev->dev_attrib.max_unmap_lba_count, &buf[20]);
 
 	/*
 	 * Set MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT
 	 */
-	put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count,
+	put_unaligned_be32(dev->dev_attrib.max_unmap_block_desc_count,
 			   &buf[24]);
 
 	/*
 	 * Set OPTIMAL UNMAP GRANULARITY
 	 */
-	put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.unmap_granularity, &buf[28]);
+	put_unaligned_be32(dev->dev_attrib.unmap_granularity, &buf[28]);
 
 	/*
 	 * UNMAP GRANULARITY ALIGNMENT
 	 */
-	put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment,
+	put_unaligned_be32(dev->dev_attrib.unmap_granularity_alignment,
 			   &buf[32]);
-	if (dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment != 0)
+	if (dev->dev_attrib.unmap_granularity_alignment != 0)
 		buf[32] |= 0x80; /* Set the UGAVALID bit */
 
 	return 0;
@@ -505,7 +500,7 @@ static int spc_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf)
 
 	buf[0] = dev->transport->get_device_type(dev);
 	buf[3] = 0x3c;
-	buf[5] = dev->se_sub_dev->se_dev_attrib.is_nonrot ? 1 : 0;
+	buf[5] = dev->dev_attrib.is_nonrot ? 1 : 0;
 
 	return 0;
 }
@@ -546,7 +541,7 @@ static int spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf)
 	 * the UNMAP command (see 5.25). A TPU bit set to zero indicates
 	 * that the device server does not support the UNMAP command.
 	 */
-	if (dev->se_sub_dev->se_dev_attrib.emulate_tpu != 0)
+	if (dev->dev_attrib.emulate_tpu != 0)
 		buf[5] = 0x80;
 
 	/*
@@ -555,7 +550,7 @@ static int spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf)
 	 * A TPWS bit set to zero indicates that the device server does not
 	 * support the use of the WRITE SAME (16) command to unmap LBAs.
 	 */
-	if (dev->se_sub_dev->se_dev_attrib.emulate_tpws != 0)
+	if (dev->dev_attrib.emulate_tpws != 0)
 		buf[5] |= 0x40;
 
 	return 0;
@@ -586,8 +581,7 @@ static int spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf)
 	 * Registered Extended LUN WWN has been set via ConfigFS
 	 * during device creation/restart.
 	 */
-	if (cmd->se_dev->se_sub_dev->su_dev_flags &
-			SDF_EMULATED_VPD_UNIT_SERIAL) {
+	if (cmd->se_dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL) {
 		buf[3] = ARRAY_SIZE(evpd_handlers);
 		for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p)
 			buf[p + 4] = evpd_handlers[p].page;
@@ -690,7 +684,7 @@ static int spc_modesense_control(struct se_device *dev, unsigned char *p)
 	 * command sequence order shall be explicitly handled by the application client
 	 * through the selection of appropriate ommands and task attributes.
 	 */
-	p[3] = (dev->se_sub_dev->se_dev_attrib.emulate_rest_reord == 1) ? 0x00 : 0x10;
+	p[3] = (dev->dev_attrib.emulate_rest_reord == 1) ? 0x00 : 0x10;
 	/*
 	 * From spc4r17, section 7.4.6 Control mode Page
 	 *
@@ -720,8 +714,8 @@ static int spc_modesense_control(struct se_device *dev, unsigned char *p)
 	 * for a BUSY, TASK SET FULL, or RESERVATION CONFLICT status regardless
 	 * to the number of commands completed with one of those status codes.
 	 */
-	p[4] = (dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 2) ? 0x30 :
-	       (dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 1) ? 0x20 : 0x00;
+	p[4] = (dev->dev_attrib.emulate_ua_intlck_ctrl == 2) ? 0x30 :
+	       (dev->dev_attrib.emulate_ua_intlck_ctrl == 1) ? 0x20 : 0x00;
 	/*
 	 * From spc4r17, section 7.4.6 Control mode Page
 	 *
@@ -734,7 +728,7 @@ static int spc_modesense_control(struct se_device *dev, unsigned char *p)
 	 * which the command was received shall be completed with TASK ABORTED
 	 * status (see SAM-4).
 	 */
-	p[5] = (dev->se_sub_dev->se_dev_attrib.emulate_tas) ? 0x40 : 0x00;
+	p[5] = (dev->dev_attrib.emulate_tas) ? 0x40 : 0x00;
 	p[8] = 0xff;
 	p[9] = 0xff;
 	p[11] = 30;
@@ -746,7 +740,7 @@ static int spc_modesense_caching(struct se_device *dev, unsigned char *p)
 {
 	p[0] = 0x08;
 	p[1] = 0x12;
-	if (dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0)
+	if (dev->dev_attrib.emulate_write_cache > 0)
 		p[2] = 0x04; /* Write Cache Enable */
 	p[12] = 0x20; /* Disabled Read Ahead */
 
@@ -826,8 +820,8 @@ static int spc_emulate_modesense(struct se_cmd *cmd)
 		    (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)))
 			spc_modesense_write_protect(&buf[3], type);
 
-		if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) &&
-		    (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0))
+		if ((dev->dev_attrib.emulate_write_cache > 0) &&
+		    (dev->dev_attrib.emulate_fua_write > 0))
 			spc_modesense_dpofua(&buf[3], type);
 	} else {
 		offset -= 1;
@@ -839,8 +833,8 @@ static int spc_emulate_modesense(struct se_cmd *cmd)
 		    (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)))
 			spc_modesense_write_protect(&buf[2], type);
 
-		if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) &&
-		    (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0))
+		if ((dev->dev_attrib.emulate_write_cache > 0) &&
+		    (dev->dev_attrib.emulate_fua_write > 0))
 			spc_modesense_dpofua(&buf[2], type);
 	}
 
@@ -923,7 +917,6 @@ static int spc_emulate_testunitready(struct se_cmd *cmd)
 int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
 {
 	struct se_device *dev = cmd->se_dev;
-	struct se_subsystem_dev *su_dev = dev->se_sub_dev;
 	unsigned char *cdb = cmd->t_task_cdb;
 
 	switch (cdb[0]) {
@@ -946,12 +939,12 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
 		*size = (cdb[7] << 8) + cdb[8];
 		break;
 	case PERSISTENT_RESERVE_IN:
-		if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
+		if (dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
 			cmd->execute_cmd = target_scsi3_emulate_pr_in;
 		*size = (cdb[7] << 8) + cdb[8];
 		break;
 	case PERSISTENT_RESERVE_OUT:
-		if (su_dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
+		if (dev->t10_pr.res_type == SPC3_PERSISTENT_RESERVATIONS)
 			cmd->execute_cmd = target_scsi3_emulate_pr_out;
 		*size = (cdb[7] << 8) + cdb[8];
 		break;
@@ -962,7 +955,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
 		else
 			*size = cmd->data_length;
 
-		if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH)
+		if (dev->t10_pr.res_type != SPC_PASSTHROUGH)
 			cmd->execute_cmd = target_scsi2_reservation_release;
 		break;
 	case RESERVE:
@@ -983,7 +976,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
 		 * is running in SPC_PASSTHROUGH, and wants reservations
 		 * emulation disabled.
 		 */
-		if (su_dev->t10_pr.res_type != SPC_PASSTHROUGH)
+		if (dev->t10_pr.res_type != SPC_PASSTHROUGH)
 			cmd->execute_cmd = target_scsi2_reservation_reserve;
 		break;
 	case REQUEST_SENSE:
@@ -1040,7 +1033,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
 			 * Check for emulated MI_REPORT_TARGET_PGS
 			 */
 			if ((cdb[1] & 0x1f) == MI_REPORT_TARGET_PGS &&
-			    su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
+			    dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
 				cmd->execute_cmd =
 					target_emulate_report_target_port_groups;
 			}
@@ -1059,7 +1052,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
 			 * Check for emulated MO_SET_TARGET_PGS.
 			 */
 			if (cdb[1] == MO_SET_TARGET_PGS &&
-			    su_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
+			    dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
 				cmd->execute_cmd =
 					target_emulate_set_target_port_groups;
 			}
diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c
index cb6b0036ae95..9bbb0170b726 100644
--- a/drivers/target/target_core_stat.c
+++ b/drivers/target/target_core_stat.c
@@ -80,13 +80,9 @@ static struct target_stat_scsi_dev_attribute				\
 static ssize_t target_stat_scsi_dev_show_attr_inst(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_hba *hba = se_subdev->se_dev_hba;
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
+	struct se_hba *hba = dev->se_hba;
 
 	return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
 }
@@ -95,12 +91,8 @@ DEV_STAT_SCSI_DEV_ATTR_RO(inst);
 static ssize_t target_stat_scsi_dev_show_attr_indx(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 
 	return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
 }
@@ -109,13 +101,6 @@ DEV_STAT_SCSI_DEV_ATTR_RO(indx);
 static ssize_t target_stat_scsi_dev_show_attr_role(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
-
 	return snprintf(page, PAGE_SIZE, "Target\n");
 }
 DEV_STAT_SCSI_DEV_ATTR_RO(role);
@@ -123,12 +108,8 @@ DEV_STAT_SCSI_DEV_ATTR_RO(role);
 static ssize_t target_stat_scsi_dev_show_attr_ports(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 
 	return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_port_count);
 }
@@ -176,13 +157,9 @@ static struct target_stat_scsi_tgt_dev_attribute			\
 static ssize_t target_stat_scsi_tgt_dev_show_attr_inst(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_hba *hba = se_subdev->se_dev_hba;
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
+	struct se_hba *hba = dev->se_hba;
 
 	return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
 }
@@ -191,12 +168,8 @@ DEV_STAT_SCSI_TGT_DEV_ATTR_RO(inst);
 static ssize_t target_stat_scsi_tgt_dev_show_attr_indx(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 
 	return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
 }
@@ -205,13 +178,6 @@ DEV_STAT_SCSI_TGT_DEV_ATTR_RO(indx);
 static ssize_t target_stat_scsi_tgt_dev_show_attr_num_lus(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
-
 	return snprintf(page, PAGE_SIZE, "%u\n", LU_COUNT);
 }
 DEV_STAT_SCSI_TGT_DEV_ATTR_RO(num_lus);
@@ -219,60 +185,27 @@ DEV_STAT_SCSI_TGT_DEV_ATTR_RO(num_lus);
 static ssize_t target_stat_scsi_tgt_dev_show_attr_status(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-	char status[16];
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 
-	if (!dev)
-		return -ENODEV;
-
-	switch (dev->dev_status) {
-	case TRANSPORT_DEVICE_ACTIVATED:
-		strcpy(status, "activated");
-		break;
-	case TRANSPORT_DEVICE_DEACTIVATED:
-		strcpy(status, "deactivated");
-		break;
-	case TRANSPORT_DEVICE_SHUTDOWN:
-		strcpy(status, "shutdown");
-		break;
-	case TRANSPORT_DEVICE_OFFLINE_ACTIVATED:
-	case TRANSPORT_DEVICE_OFFLINE_DEACTIVATED:
-		strcpy(status, "offline");
-		break;
-	default:
-		sprintf(status, "unknown(%d)", dev->dev_status);
-		break;
-	}
-
-	return snprintf(page, PAGE_SIZE, "%s\n", status);
+	if (dev->export_count)
+		return snprintf(page, PAGE_SIZE, "activated");
+	else
+		return snprintf(page, PAGE_SIZE, "deactivated");
 }
 DEV_STAT_SCSI_TGT_DEV_ATTR_RO(status);
 
 static ssize_t target_stat_scsi_tgt_dev_show_attr_non_access_lus(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 	int non_accessible_lus;
 
-	if (!dev)
-		return -ENODEV;
-
-	switch (dev->dev_status) {
-	case TRANSPORT_DEVICE_ACTIVATED:
+	if (dev->export_count)
 		non_accessible_lus = 0;
-		break;
-	case TRANSPORT_DEVICE_DEACTIVATED:
-	case TRANSPORT_DEVICE_SHUTDOWN:
-	case TRANSPORT_DEVICE_OFFLINE_ACTIVATED:
-	case TRANSPORT_DEVICE_OFFLINE_DEACTIVATED:
-	default:
+	else
 		non_accessible_lus = 1;
-		break;
-	}
 
 	return snprintf(page, PAGE_SIZE, "%u\n", non_accessible_lus);
 }
@@ -281,12 +214,8 @@ DEV_STAT_SCSI_TGT_DEV_ATTR_RO(non_access_lus);
 static ssize_t target_stat_scsi_tgt_dev_show_attr_resets(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 
 	return snprintf(page, PAGE_SIZE, "%u\n", dev->num_resets);
 }
@@ -335,13 +264,9 @@ static struct target_stat_scsi_lu_attribute target_stat_scsi_lu_##_name = \
 static ssize_t target_stat_scsi_lu_show_attr_inst(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_hba *hba = se_subdev->se_dev_hba;
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
+	struct se_hba *hba = dev->se_hba;
 
 	return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
 }
@@ -350,12 +275,8 @@ DEV_STAT_SCSI_LU_ATTR_RO(inst);
 static ssize_t target_stat_scsi_lu_show_attr_dev(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 
 	return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
 }
@@ -364,13 +285,6 @@ DEV_STAT_SCSI_LU_ATTR_RO(dev);
 static ssize_t target_stat_scsi_lu_show_attr_indx(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
-
 	return snprintf(page, PAGE_SIZE, "%u\n", SCSI_LU_INDEX);
 }
 DEV_STAT_SCSI_LU_ATTR_RO(indx);
@@ -378,12 +292,6 @@ DEV_STAT_SCSI_LU_ATTR_RO(indx);
 static ssize_t target_stat_scsi_lu_show_attr_lun(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
 	/* FIXME: scsiLuDefaultLun */
 	return snprintf(page, PAGE_SIZE, "%llu\n", (unsigned long long)0);
 }
@@ -392,35 +300,28 @@ DEV_STAT_SCSI_LU_ATTR_RO(lun);
 static ssize_t target_stat_scsi_lu_show_attr_lu_name(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 
-	if (!dev)
-		return -ENODEV;
 	/* scsiLuWwnName */
 	return snprintf(page, PAGE_SIZE, "%s\n",
-			(strlen(dev->se_sub_dev->t10_wwn.unit_serial)) ?
-			dev->se_sub_dev->t10_wwn.unit_serial : "None");
+			(strlen(dev->t10_wwn.unit_serial)) ?
+			dev->t10_wwn.unit_serial : "None");
 }
 DEV_STAT_SCSI_LU_ATTR_RO(lu_name);
 
 static ssize_t target_stat_scsi_lu_show_attr_vend(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 	int i;
-	char str[sizeof(dev->se_sub_dev->t10_wwn.vendor)+1];
-
-	if (!dev)
-		return -ENODEV;
+	char str[sizeof(dev->t10_wwn.vendor)+1];
 
 	/* scsiLuVendorId */
-	for (i = 0; i < sizeof(dev->se_sub_dev->t10_wwn.vendor); i++)
-		str[i] = ISPRINT(dev->se_sub_dev->t10_wwn.vendor[i]) ?
-			dev->se_sub_dev->t10_wwn.vendor[i] : ' ';
+	for (i = 0; i < sizeof(dev->t10_wwn.vendor); i++)
+		str[i] = ISPRINT(dev->t10_wwn.vendor[i]) ?
+			dev->t10_wwn.vendor[i] : ' ';
 	str[i] = '\0';
 	return snprintf(page, PAGE_SIZE, "%s\n", str);
 }
@@ -429,19 +330,15 @@ DEV_STAT_SCSI_LU_ATTR_RO(vend);
 static ssize_t target_stat_scsi_lu_show_attr_prod(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 	int i;
-	char str[sizeof(dev->se_sub_dev->t10_wwn.model)+1];
-
-	if (!dev)
-		return -ENODEV;
+	char str[sizeof(dev->t10_wwn.model)+1];
 
 	/* scsiLuProductId */
-	for (i = 0; i < sizeof(dev->se_sub_dev->t10_wwn.vendor); i++)
-		str[i] = ISPRINT(dev->se_sub_dev->t10_wwn.model[i]) ?
-			dev->se_sub_dev->t10_wwn.model[i] : ' ';
+	for (i = 0; i < sizeof(dev->t10_wwn.vendor); i++)
+		str[i] = ISPRINT(dev->t10_wwn.model[i]) ?
+			dev->t10_wwn.model[i] : ' ';
 	str[i] = '\0';
 	return snprintf(page, PAGE_SIZE, "%s\n", str);
 }
@@ -450,19 +347,15 @@ DEV_STAT_SCSI_LU_ATTR_RO(prod);
 static ssize_t target_stat_scsi_lu_show_attr_rev(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 	int i;
-	char str[sizeof(dev->se_sub_dev->t10_wwn.revision)+1];
-
-	if (!dev)
-		return -ENODEV;
+	char str[sizeof(dev->t10_wwn.revision)+1];
 
 	/* scsiLuRevisionId */
-	for (i = 0; i < sizeof(dev->se_sub_dev->t10_wwn.revision); i++)
-		str[i] = ISPRINT(dev->se_sub_dev->t10_wwn.revision[i]) ?
-			dev->se_sub_dev->t10_wwn.revision[i] : ' ';
+	for (i = 0; i < sizeof(dev->t10_wwn.revision); i++)
+		str[i] = ISPRINT(dev->t10_wwn.revision[i]) ?
+			dev->t10_wwn.revision[i] : ' ';
 	str[i] = '\0';
 	return snprintf(page, PAGE_SIZE, "%s\n", str);
 }
@@ -471,12 +364,8 @@ DEV_STAT_SCSI_LU_ATTR_RO(rev);
 static ssize_t target_stat_scsi_lu_show_attr_dev_type(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 
 	/* scsiLuPeripheralType */
 	return snprintf(page, PAGE_SIZE, "%u\n",
@@ -487,30 +376,18 @@ DEV_STAT_SCSI_LU_ATTR_RO(dev_type);
 static ssize_t target_stat_scsi_lu_show_attr_status(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 
 	/* scsiLuStatus */
 	return snprintf(page, PAGE_SIZE, "%s\n",
-		(dev->dev_status == TRANSPORT_DEVICE_ACTIVATED) ?
-		"available" : "notavailable");
+		(dev->export_count) ? "available" : "notavailable");
 }
 DEV_STAT_SCSI_LU_ATTR_RO(status);
 
 static ssize_t target_stat_scsi_lu_show_attr_state_bit(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
-
 	/* scsiLuState */
 	return snprintf(page, PAGE_SIZE, "exposed\n");
 }
@@ -519,12 +396,8 @@ DEV_STAT_SCSI_LU_ATTR_RO(state_bit);
 static ssize_t target_stat_scsi_lu_show_attr_num_cmds(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 
 	/* scsiLuNumCommands */
 	return snprintf(page, PAGE_SIZE, "%llu\n",
@@ -535,12 +408,8 @@ DEV_STAT_SCSI_LU_ATTR_RO(num_cmds);
 static ssize_t target_stat_scsi_lu_show_attr_read_mbytes(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 
 	/* scsiLuReadMegaBytes */
 	return snprintf(page, PAGE_SIZE, "%u\n", (u32)(dev->read_bytes >> 20));
@@ -550,12 +419,8 @@ DEV_STAT_SCSI_LU_ATTR_RO(read_mbytes);
 static ssize_t target_stat_scsi_lu_show_attr_write_mbytes(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 
 	/* scsiLuWrittenMegaBytes */
 	return snprintf(page, PAGE_SIZE, "%u\n", (u32)(dev->write_bytes >> 20));
@@ -565,12 +430,8 @@ DEV_STAT_SCSI_LU_ATTR_RO(write_mbytes);
 static ssize_t target_stat_scsi_lu_show_attr_resets(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 
 	/* scsiLuInResets */
 	return snprintf(page, PAGE_SIZE, "%u\n", dev->num_resets);
@@ -580,13 +441,6 @@ DEV_STAT_SCSI_LU_ATTR_RO(resets);
 static ssize_t target_stat_scsi_lu_show_attr_full_stat(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
-
 	/* FIXME: scsiLuOutTaskSetFullStatus */
 	return snprintf(page, PAGE_SIZE, "%u\n", 0);
 }
@@ -595,13 +449,6 @@ DEV_STAT_SCSI_LU_ATTR_RO(full_stat);
 static ssize_t target_stat_scsi_lu_show_attr_hs_num_cmds(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
-
 	/* FIXME: scsiLuHSInCommands */
 	return snprintf(page, PAGE_SIZE, "%u\n", 0);
 }
@@ -610,12 +457,8 @@ DEV_STAT_SCSI_LU_ATTR_RO(hs_num_cmds);
 static ssize_t target_stat_scsi_lu_show_attr_creation_time(
 	struct se_dev_stat_grps *sgrps, char *page)
 {
-	struct se_subsystem_dev *se_subdev = container_of(sgrps,
-			struct se_subsystem_dev, dev_stat_grps);
-	struct se_device *dev = se_subdev->se_dev_ptr;
-
-	if (!dev)
-		return -ENODEV;
+	struct se_device *dev =
+		container_of(sgrps, struct se_device, dev_stat_grps);
 
 	/* scsiLuCreationTime */
 	return snprintf(page, PAGE_SIZE, "%u\n", (u32)(((u32)dev->creation_time -
@@ -662,20 +505,20 @@ static struct config_item_type target_stat_scsi_lu_cit = {
  * Called from target_core_configfs.c:target_core_make_subdev() to setup
  * the target statistics groups + configfs CITs located in target_core_stat.c
  */
-void target_stat_setup_dev_default_groups(struct se_subsystem_dev *se_subdev)
+void target_stat_setup_dev_default_groups(struct se_device *dev)
 {
-	struct config_group *dev_stat_grp = &se_subdev->dev_stat_grps.stat_group;
+	struct config_group *dev_stat_grp = &dev->dev_stat_grps.stat_group;
 
-	config_group_init_type_name(&se_subdev->dev_stat_grps.scsi_dev_group,
+	config_group_init_type_name(&dev->dev_stat_grps.scsi_dev_group,
 			"scsi_dev", &target_stat_scsi_dev_cit);
-	config_group_init_type_name(&se_subdev->dev_stat_grps.scsi_tgt_dev_group,
+	config_group_init_type_name(&dev->dev_stat_grps.scsi_tgt_dev_group,
 			"scsi_tgt_dev", &target_stat_scsi_tgt_dev_cit);
-	config_group_init_type_name(&se_subdev->dev_stat_grps.scsi_lu_group,
+	config_group_init_type_name(&dev->dev_stat_grps.scsi_lu_group,
 			"scsi_lu", &target_stat_scsi_lu_cit);
 
-	dev_stat_grp->default_groups[0] = &se_subdev->dev_stat_grps.scsi_dev_group;
-	dev_stat_grp->default_groups[1] = &se_subdev->dev_stat_grps.scsi_tgt_dev_group;
-	dev_stat_grp->default_groups[2] = &se_subdev->dev_stat_grps.scsi_lu_group;
+	dev_stat_grp->default_groups[0] = &dev->dev_stat_grps.scsi_dev_group;
+	dev_stat_grp->default_groups[1] = &dev->dev_stat_grps.scsi_tgt_dev_group;
+	dev_stat_grp->default_groups[2] = &dev->dev_stat_grps.scsi_lu_group;
 	dev_stat_grp->default_groups[3] = NULL;
 }
 
@@ -1161,7 +1004,7 @@ static ssize_t target_stat_scsi_transport_show_attr_dev_name(
 		return -ENODEV;
 	}
 	tpg = sep->sep_tpg;
-	wwn = &dev->se_sub_dev->t10_wwn;
+	wwn = &dev->t10_wwn;
 	/* scsiTransportDevName */
 	ret = snprintf(page, PAGE_SIZE, "%s+%s\n",
 			tpg->se_tpg_tfo->tpg_get_wwn(tpg),
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
index be75c4331a92..2aaceae964ee 100644
--- a/drivers/target/target_core_tmr.c
+++ b/drivers/target/target_core_tmr.c
@@ -371,7 +371,7 @@ int core_tmr_lun_reset(
 	 * which the command was received shall be completed with TASK ABORTED
 	 * status (see SAM-4).
 	 */
-	tas = dev->se_sub_dev->se_dev_attrib.emulate_tas;
+	tas = dev->dev_attrib.emulate_tas;
 	/*
 	 * Determine if this se_tmr is coming from a $FABRIC_MOD
 	 * or struct se_device passthrough..
@@ -399,10 +399,10 @@ int core_tmr_lun_reset(
 	 * LOGICAL UNIT RESET
 	 */
 	if (!preempt_and_abort_list &&
-	     (dev->dev_flags & DF_SPC2_RESERVATIONS)) {
+	     (dev->dev_reservation_flags & DRF_SPC2_RESERVATIONS)) {
 		spin_lock(&dev->dev_reservation_lock);
 		dev->dev_reserved_node_acl = NULL;
-		dev->dev_flags &= ~DF_SPC2_RESERVATIONS;
+		dev->dev_reservation_flags &= ~DRF_SPC2_RESERVATIONS;
 		spin_unlock(&dev->dev_reservation_lock);
 		pr_debug("LUN_RESET: SCSI-2 Released reservation\n");
 	}
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 9097155e9ebe..d6d24a47ed66 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -659,7 +659,7 @@ static void target_add_to_state_list(struct se_cmd *cmd)
 static void transport_write_pending_qf(struct se_cmd *cmd);
 static void transport_complete_qf(struct se_cmd *cmd);
 
-static void target_qf_do_work(struct work_struct *work)
+void target_qf_do_work(struct work_struct *work)
 {
 	struct se_device *dev = container_of(work, struct se_device,
 					qf_work_queue);
@@ -712,29 +712,15 @@ void transport_dump_dev_state(
 	int *bl)
 {
 	*bl += sprintf(b + *bl, "Status: ");
-	switch (dev->dev_status) {
-	case TRANSPORT_DEVICE_ACTIVATED:
+	if (dev->export_count)
 		*bl += sprintf(b + *bl, "ACTIVATED");
-		break;
-	case TRANSPORT_DEVICE_DEACTIVATED:
+	else
 		*bl += sprintf(b + *bl, "DEACTIVATED");
-		break;
-	case TRANSPORT_DEVICE_SHUTDOWN:
-		*bl += sprintf(b + *bl, "SHUTDOWN");
-		break;
-	case TRANSPORT_DEVICE_OFFLINE_ACTIVATED:
-	case TRANSPORT_DEVICE_OFFLINE_DEACTIVATED:
-		*bl += sprintf(b + *bl, "OFFLINE");
-		break;
-	default:
-		*bl += sprintf(b + *bl, "UNKNOWN=%d", dev->dev_status);
-		break;
-	}
 
 	*bl += sprintf(b + *bl, "  Max Queue Depth: %d", dev->queue_depth);
 	*bl += sprintf(b + *bl, "  SectorSize: %u  HwMaxSectors: %u\n",
-		dev->se_sub_dev->se_dev_attrib.block_size,
-		dev->se_sub_dev->se_dev_attrib.hw_max_sectors);
+		dev->dev_attrib.block_size,
+		dev->dev_attrib.hw_max_sectors);
 	*bl += sprintf(b + *bl, "        ");
 }
 
@@ -991,185 +977,6 @@ transport_set_vpd_ident(struct t10_vpd *vpd, unsigned char *page_83)
 }
 EXPORT_SYMBOL(transport_set_vpd_ident);
 
-static void core_setup_task_attr_emulation(struct se_device *dev)
-{
-	/*
-	 * If this device is from Target_Core_Mod/pSCSI, disable the
-	 * SAM Task Attribute emulation.
-	 *
-	 * This is currently not available in upsream Linux/SCSI Target
-	 * mode code, and is assumed to be disabled while using TCM/pSCSI.
-	 */
-	if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) {
-		dev->dev_task_attr_type = SAM_TASK_ATTR_PASSTHROUGH;
-		return;
-	}
-
-	dev->dev_task_attr_type = SAM_TASK_ATTR_EMULATED;
-	pr_debug("%s: Using SAM_TASK_ATTR_EMULATED for SPC: 0x%02x"
-		" device\n", dev->transport->name,
-		dev->transport->get_device_rev(dev));
-}
-
-static void scsi_dump_inquiry(struct se_device *dev)
-{
-	struct t10_wwn *wwn = &dev->se_sub_dev->t10_wwn;
-	char buf[17];
-	int i, device_type;
-	/*
-	 * Print Linux/SCSI style INQUIRY formatting to the kernel ring buffer
-	 */
-	for (i = 0; i < 8; i++)
-		if (wwn->vendor[i] >= 0x20)
-			buf[i] = wwn->vendor[i];
-		else
-			buf[i] = ' ';
-	buf[i] = '\0';
-	pr_debug("  Vendor: %s\n", buf);
-
-	for (i = 0; i < 16; i++)
-		if (wwn->model[i] >= 0x20)
-			buf[i] = wwn->model[i];
-		else
-			buf[i] = ' ';
-	buf[i] = '\0';
-	pr_debug("  Model: %s\n", buf);
-
-	for (i = 0; i < 4; i++)
-		if (wwn->revision[i] >= 0x20)
-			buf[i] = wwn->revision[i];
-		else
-			buf[i] = ' ';
-	buf[i] = '\0';
-	pr_debug("  Revision: %s\n", buf);
-
-	device_type = dev->transport->get_device_type(dev);
-	pr_debug("  Type:   %s ", scsi_device_type(device_type));
-	pr_debug("                 ANSI SCSI revision: %02x\n",
-				dev->transport->get_device_rev(dev));
-}
-
-struct se_device *transport_add_device_to_core_hba(
-	struct se_hba *hba,
-	struct se_subsystem_api *transport,
-	struct se_subsystem_dev *se_dev,
-	u32 device_flags,
-	void *transport_dev,
-	struct se_dev_limits *dev_limits,
-	const char *inquiry_prod,
-	const char *inquiry_rev)
-{
-	int force_pt;
-	struct se_device  *dev;
-
-	dev = kzalloc(sizeof(struct se_device), GFP_KERNEL);
-	if (!dev) {
-		pr_err("Unable to allocate memory for se_dev_t\n");
-		return NULL;
-	}
-
-	dev->dev_flags		= device_flags;
-	dev->dev_status		|= TRANSPORT_DEVICE_DEACTIVATED;
-	dev->dev_ptr		= transport_dev;
-	dev->se_hba		= hba;
-	dev->se_sub_dev		= se_dev;
-	dev->transport		= transport;
-	INIT_LIST_HEAD(&dev->dev_list);
-	INIT_LIST_HEAD(&dev->dev_sep_list);
-	INIT_LIST_HEAD(&dev->dev_tmr_list);
-	INIT_LIST_HEAD(&dev->delayed_cmd_list);
-	INIT_LIST_HEAD(&dev->state_list);
-	INIT_LIST_HEAD(&dev->qf_cmd_list);
-	spin_lock_init(&dev->execute_task_lock);
-	spin_lock_init(&dev->delayed_cmd_lock);
-	spin_lock_init(&dev->dev_reservation_lock);
-	spin_lock_init(&dev->dev_status_lock);
-	spin_lock_init(&dev->se_port_lock);
-	spin_lock_init(&dev->se_tmr_lock);
-	spin_lock_init(&dev->qf_cmd_lock);
-	atomic_set(&dev->dev_ordered_id, 0);
-
-	se_dev_set_default_attribs(dev, dev_limits);
-
-	dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX);
-	dev->creation_time = get_jiffies_64();
-	spin_lock_init(&dev->stats_lock);
-
-	spin_lock(&hba->device_lock);
-	list_add_tail(&dev->dev_list, &hba->hba_dev_list);
-	hba->dev_count++;
-	spin_unlock(&hba->device_lock);
-	/*
-	 * Setup the SAM Task Attribute emulation for struct se_device
-	 */
-	core_setup_task_attr_emulation(dev);
-	/*
-	 * Force PR and ALUA passthrough emulation with internal object use.
-	 */
-	force_pt = (hba->hba_flags & HBA_FLAGS_INTERNAL_USE);
-	/*
-	 * Setup the Reservations infrastructure for struct se_device
-	 */
-	core_setup_reservations(dev, force_pt);
-	/*
-	 * Setup the Asymmetric Logical Unit Assignment for struct se_device
-	 */
-	if (core_setup_alua(dev, force_pt) < 0)
-		goto err_dev_list;
-
-	/*
-	 * Startup the struct se_device processing thread
-	 */
-	dev->tmr_wq = alloc_workqueue("tmr-%s", WQ_MEM_RECLAIM | WQ_UNBOUND, 1,
-				      dev->transport->name);
-	if (!dev->tmr_wq) {
-		pr_err("Unable to create tmr workqueue for %s\n",
-			dev->transport->name);
-		goto err_dev_list;
-	}
-	/*
-	 * Setup work_queue for QUEUE_FULL
-	 */
-	INIT_WORK(&dev->qf_work_queue, target_qf_do_work);
-	/*
-	 * Preload the initial INQUIRY const values if we are doing
-	 * anything virtual (IBLOCK, FILEIO, RAMDISK), but not for TCM/pSCSI
-	 * passthrough because this is being provided by the backend LLD.
-	 * This is required so that transport_get_inquiry() copies these
-	 * originals once back into DEV_T10_WWN(dev) for the virtual device
-	 * setup.
-	 */
-	if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) {
-		if (!inquiry_prod || !inquiry_rev) {
-			pr_err("All non TCM/pSCSI plugins require"
-				" INQUIRY consts\n");
-			goto err_wq;
-		}
-
-		strncpy(&dev->se_sub_dev->t10_wwn.vendor[0], "LIO-ORG", 8);
-		strncpy(&dev->se_sub_dev->t10_wwn.model[0], inquiry_prod, 16);
-		strncpy(&dev->se_sub_dev->t10_wwn.revision[0], inquiry_rev, 4);
-	}
-	scsi_dump_inquiry(dev);
-
-	return dev;
-
-err_wq:
-	destroy_workqueue(dev->tmr_wq);
-err_dev_list:
-	spin_lock(&hba->device_lock);
-	list_del(&dev->dev_list);
-	hba->dev_count--;
-	spin_unlock(&hba->device_lock);
-
-	se_release_vpd_for_dev(dev);
-
-	kfree(dev);
-
-	return NULL;
-}
-EXPORT_SYMBOL(transport_add_device_to_core_hba);
-
 int target_cmd_size_check(struct se_cmd *cmd, unsigned int size)
 {
 	struct se_device *dev = cmd->se_dev;
@@ -1191,7 +998,7 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size)
 		 * Reject READ_* or WRITE_* with overflow/underflow for
 		 * type SCF_SCSI_DATA_CDB.
 		 */
-		if (dev->se_sub_dev->se_dev_attrib.block_size != 512)  {
+		if (dev->dev_attrib.block_size != 512)  {
 			pr_err("Failing OVERFLOW/UNDERFLOW for LBA op"
 				" CDB on non 512-byte sector setup subsystem"
 				" plugin: %s\n", dev->transport->name);
@@ -1293,7 +1100,7 @@ int target_setup_cmd_from_cdb(
 	struct se_cmd *cmd,
 	unsigned char *cdb)
 {
-	struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
+	struct se_device *dev = cmd->se_dev;
 	u32 pr_reg_type = 0;
 	u8 alua_ascq = 0;
 	unsigned long flags;
@@ -1345,7 +1152,7 @@ int target_setup_cmd_from_cdb(
 		return -EINVAL;
 	}
 
-	ret = su_dev->t10_alua.alua_state_check(cmd, cdb, &alua_ascq);
+	ret = dev->t10_alua.alua_state_check(cmd, cdb, &alua_ascq);
 	if (ret != 0) {
 		/*
 		 * Set SCSI additional sense code (ASC) to 'LUN Not Accessible';
@@ -1371,8 +1178,8 @@ int target_setup_cmd_from_cdb(
 	/*
 	 * Check status for SPC-3 Persistent Reservations
 	 */
-	if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type)) {
-		if (su_dev->t10_pr.pr_ops.t10_seq_non_holder(
+	if (dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type)) {
+		if (dev->t10_pr.pr_ops.t10_seq_non_holder(
 					cmd, cdb, pr_reg_type) != 0) {
 			cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
 			cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT;
@@ -1387,7 +1194,7 @@ int target_setup_cmd_from_cdb(
 		 */
 	}
 
-	ret = cmd->se_dev->transport->parse_cdb(cmd);
+	ret = dev->transport->parse_cdb(cmd);
 	if (ret < 0)
 		return ret;
 
@@ -1759,7 +1566,7 @@ void transport_generic_request_failure(struct se_cmd *cmd)
 		 * See spc4r17, section 7.4.6 Control Mode Page, Table 349
 		 */
 		if (cmd->se_sess &&
-		    cmd->se_dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 2)
+		    cmd->se_dev->dev_attrib.emulate_ua_intlck_ctrl == 2)
 			core_scsi3_ua_allocate(cmd->se_sess->se_node_acl,
 				cmd->orig_fe_lun, 0x2C,
 				ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS);
diff --git a/drivers/target/target_core_ua.c b/drivers/target/target_core_ua.c
index 6666a0c74f60..59c95ee14749 100644
--- a/drivers/target/target_core_ua.c
+++ b/drivers/target/target_core_ua.c
@@ -237,7 +237,7 @@ void core_scsi3_ua_for_check_condition(
 		 * highest priority UNIT_ATTENTION and ASC/ASCQ without
 		 * clearing it.
 		 */
-		if (dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl != 0) {
+		if (dev->dev_attrib.emulate_ua_intlck_ctrl != 0) {
 			*asc = ua->ua_asc;
 			*ascq = ua->ua_ascq;
 			break;
@@ -265,8 +265,8 @@ void core_scsi3_ua_for_check_condition(
 		" INTLCK_CTRL: %d, mapped LUN: %u, got CDB: 0x%02x"
 		" reported ASC: 0x%02x, ASCQ: 0x%02x\n",
 		nacl->se_tpg->se_tpg_tfo->get_fabric_name(),
-		(dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl != 0) ? "Reporting" :
-		"Releasing", dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl,
+		(dev->dev_attrib.emulate_ua_intlck_ctrl != 0) ? "Reporting" :
+		"Releasing", dev->dev_attrib.emulate_ua_intlck_ctrl,
 		cmd->orig_fe_lun, cmd->t_task_cdb[0], *asc, *ascq);
 }