aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-05-10 12:14:56 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2015-06-01 03:25:34 -0400
commit0a06d4309dc168dfa70cec3cf0cd9eb7fc15a2fd (patch)
tree38dda3f7dc5e049761c80b55796e48cacbb6924c
parent4624773765699ac3f4e0b918306b638cba385713 (diff)
target: simplify backend driver registration
Rewrite the backend driver registration based on what we did to the fabric drivers: introduce a read-only struct target_bakckend_ops that the driver registers, which is then instanciate as a struct target_backend by the core. This allows the ops vector to be smaller and allows us to mark it const. At the same time the registration function can set up the configfs attributes, avoiding the need to add additional boilerplate code for that to the drivers. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/target_core_configfs.c68
-rw-r--r--drivers/target/target_core_device.c6
-rw-r--r--drivers/target/target_core_file.c16
-rw-r--r--drivers/target/target_core_hba.c96
-rw-r--r--drivers/target/target_core_iblock.c18
-rw-r--r--drivers/target/target_core_internal.h16
-rw-r--r--drivers/target/target_core_pscsi.c14
-rw-r--r--drivers/target/target_core_rd.c22
-rw-r--r--drivers/target/target_core_user.c11
-rw-r--r--include/target/target_core_backend.h22
-rw-r--r--include/target/target_core_base.h4
11 files changed, 135 insertions, 158 deletions
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 4a31d4765390..57c099dd9da5 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -51,15 +51,26 @@
51#include "target_core_xcopy.h" 51#include "target_core_xcopy.h"
52 52
53#define TB_CIT_SETUP(_name, _item_ops, _group_ops, _attrs) \ 53#define TB_CIT_SETUP(_name, _item_ops, _group_ops, _attrs) \
54static void target_core_setup_##_name##_cit(struct se_subsystem_api *sa) \ 54static void target_core_setup_##_name##_cit(struct target_backend *tb) \
55{ \ 55{ \
56 struct target_backend_cits *tbc = &sa->tb_cits; \ 56 struct config_item_type *cit = &tb->tb_##_name##_cit; \
57 struct config_item_type *cit = &tbc->tb_##_name##_cit; \
58 \ 57 \
59 cit->ct_item_ops = _item_ops; \ 58 cit->ct_item_ops = _item_ops; \
60 cit->ct_group_ops = _group_ops; \ 59 cit->ct_group_ops = _group_ops; \
61 cit->ct_attrs = _attrs; \ 60 cit->ct_attrs = _attrs; \
62 cit->ct_owner = sa->owner; \ 61 cit->ct_owner = tb->ops->owner; \
62 pr_debug("Setup generic %s\n", __stringify(_name)); \
63}
64
65#define TB_CIT_SETUP_DRV(_name, _item_ops, _group_ops) \
66static void target_core_setup_##_name##_cit(struct target_backend *tb) \
67{ \
68 struct config_item_type *cit = &tb->tb_##_name##_cit; \
69 \
70 cit->ct_item_ops = _item_ops; \
71 cit->ct_group_ops = _group_ops; \
72 cit->ct_attrs = tb->ops->tb_##_name##_attrs; \
73 cit->ct_owner = tb->ops->owner; \
63 pr_debug("Setup generic %s\n", __stringify(_name)); \ 74 pr_debug("Setup generic %s\n", __stringify(_name)); \
64} 75}
65 76
@@ -469,7 +480,7 @@ static struct configfs_item_operations target_core_dev_attrib_ops = {
469 .store_attribute = target_core_dev_attrib_attr_store, 480 .store_attribute = target_core_dev_attrib_attr_store,
470}; 481};
471 482
472TB_CIT_SETUP(dev_attrib, &target_core_dev_attrib_ops, NULL, NULL); 483TB_CIT_SETUP_DRV(dev_attrib, &target_core_dev_attrib_ops, NULL);
473 484
474/* End functions for struct config_item_type tb_dev_attrib_cit */ 485/* End functions for struct config_item_type tb_dev_attrib_cit */
475 486
@@ -1174,13 +1185,13 @@ TB_CIT_SETUP(dev_pr, &target_core_dev_pr_ops, NULL, target_core_dev_pr_attrs);
1174static ssize_t target_core_show_dev_info(void *p, char *page) 1185static ssize_t target_core_show_dev_info(void *p, char *page)
1175{ 1186{
1176 struct se_device *dev = p; 1187 struct se_device *dev = p;
1177 struct se_subsystem_api *t = dev->transport;
1178 int bl = 0; 1188 int bl = 0;
1179 ssize_t read_bytes = 0; 1189 ssize_t read_bytes = 0;
1180 1190
1181 transport_dump_dev_state(dev, page, &bl); 1191 transport_dump_dev_state(dev, page, &bl);
1182 read_bytes += bl; 1192 read_bytes += bl;
1183 read_bytes += t->show_configfs_dev_params(dev, page+read_bytes); 1193 read_bytes += dev->transport->show_configfs_dev_params(dev,
1194 page+read_bytes);
1184 return read_bytes; 1195 return read_bytes;
1185} 1196}
1186 1197
@@ -1198,9 +1209,8 @@ static ssize_t target_core_store_dev_control(
1198 size_t count) 1209 size_t count)
1199{ 1210{
1200 struct se_device *dev = p; 1211 struct se_device *dev = p;
1201 struct se_subsystem_api *t = dev->transport;
1202 1212
1203 return t->set_configfs_dev_params(dev, page, count); 1213 return dev->transport->set_configfs_dev_params(dev, page, count);
1204} 1214}
1205 1215
1206static struct target_core_configfs_attribute target_core_attr_dev_control = { 1216static struct target_core_configfs_attribute target_core_attr_dev_control = {
@@ -2477,9 +2487,9 @@ static struct config_group *target_core_make_subdev(
2477 const char *name) 2487 const char *name)
2478{ 2488{
2479 struct t10_alua_tg_pt_gp *tg_pt_gp; 2489 struct t10_alua_tg_pt_gp *tg_pt_gp;
2480 struct se_subsystem_api *t;
2481 struct config_item *hba_ci = &group->cg_item; 2490 struct config_item *hba_ci = &group->cg_item;
2482 struct se_hba *hba = item_to_hba(hba_ci); 2491 struct se_hba *hba = item_to_hba(hba_ci);
2492 struct target_backend *tb = hba->backend;
2483 struct se_device *dev; 2493 struct se_device *dev;
2484 struct config_group *dev_cg = NULL, *tg_pt_gp_cg = NULL; 2494 struct config_group *dev_cg = NULL, *tg_pt_gp_cg = NULL;
2485 struct config_group *dev_stat_grp = NULL; 2495 struct config_group *dev_stat_grp = NULL;
@@ -2488,10 +2498,6 @@ static struct config_group *target_core_make_subdev(
2488 ret = mutex_lock_interruptible(&hba->hba_access_mutex); 2498 ret = mutex_lock_interruptible(&hba->hba_access_mutex);
2489 if (ret) 2499 if (ret)
2490 return ERR_PTR(ret); 2500 return ERR_PTR(ret);
2491 /*
2492 * Locate the struct se_subsystem_api from parent's struct se_hba.
2493 */
2494 t = hba->transport;
2495 2501
2496 dev = target_alloc_device(hba, name); 2502 dev = target_alloc_device(hba, name);
2497 if (!dev) 2503 if (!dev)
@@ -2504,17 +2510,17 @@ static struct config_group *target_core_make_subdev(
2504 if (!dev_cg->default_groups) 2510 if (!dev_cg->default_groups)
2505 goto out_free_device; 2511 goto out_free_device;
2506 2512
2507 config_group_init_type_name(dev_cg, name, &t->tb_cits.tb_dev_cit); 2513 config_group_init_type_name(dev_cg, name, &tb->tb_dev_cit);
2508 config_group_init_type_name(&dev->dev_attrib.da_group, "attrib", 2514 config_group_init_type_name(&dev->dev_attrib.da_group, "attrib",
2509 &t->tb_cits.tb_dev_attrib_cit); 2515 &tb->tb_dev_attrib_cit);
2510 config_group_init_type_name(&dev->dev_pr_group, "pr", 2516 config_group_init_type_name(&dev->dev_pr_group, "pr",
2511 &t->tb_cits.tb_dev_pr_cit); 2517 &tb->tb_dev_pr_cit);
2512 config_group_init_type_name(&dev->t10_wwn.t10_wwn_group, "wwn", 2518 config_group_init_type_name(&dev->t10_wwn.t10_wwn_group, "wwn",
2513 &t->tb_cits.tb_dev_wwn_cit); 2519 &tb->tb_dev_wwn_cit);
2514 config_group_init_type_name(&dev->t10_alua.alua_tg_pt_gps_group, 2520 config_group_init_type_name(&dev->t10_alua.alua_tg_pt_gps_group,
2515 "alua", &t->tb_cits.tb_dev_alua_tg_pt_gps_cit); 2521 "alua", &tb->tb_dev_alua_tg_pt_gps_cit);
2516 config_group_init_type_name(&dev->dev_stat_grps.stat_group, 2522 config_group_init_type_name(&dev->dev_stat_grps.stat_group,
2517 "statistics", &t->tb_cits.tb_dev_stat_cit); 2523 "statistics", &tb->tb_dev_stat_cit);
2518 2524
2519 dev_cg->default_groups[0] = &dev->dev_attrib.da_group; 2525 dev_cg->default_groups[0] = &dev->dev_attrib.da_group;
2520 dev_cg->default_groups[1] = &dev->dev_pr_group; 2526 dev_cg->default_groups[1] = &dev->dev_pr_group;
@@ -2644,7 +2650,7 @@ static ssize_t target_core_hba_show_attr_hba_info(
2644 char *page) 2650 char *page)
2645{ 2651{
2646 return sprintf(page, "HBA Index: %d plugin: %s version: %s\n", 2652 return sprintf(page, "HBA Index: %d plugin: %s version: %s\n",
2647 hba->hba_id, hba->transport->name, 2653 hba->hba_id, hba->backend->ops->name,
2648 TARGET_CORE_CONFIGFS_VERSION); 2654 TARGET_CORE_CONFIGFS_VERSION);
2649} 2655}
2650 2656
@@ -2664,11 +2670,10 @@ static ssize_t target_core_hba_show_attr_hba_mode(struct se_hba *hba,
2664static ssize_t target_core_hba_store_attr_hba_mode(struct se_hba *hba, 2670static ssize_t target_core_hba_store_attr_hba_mode(struct se_hba *hba,
2665 const char *page, size_t count) 2671 const char *page, size_t count)
2666{ 2672{
2667 struct se_subsystem_api *transport = hba->transport;
2668 unsigned long mode_flag; 2673 unsigned long mode_flag;
2669 int ret; 2674 int ret;
2670 2675
2671 if (transport->pmode_enable_hba == NULL) 2676 if (hba->backend->ops->pmode_enable_hba == NULL)
2672 return -EINVAL; 2677 return -EINVAL;
2673 2678
2674 ret = kstrtoul(page, 0, &mode_flag); 2679 ret = kstrtoul(page, 0, &mode_flag);
@@ -2682,7 +2687,7 @@ static ssize_t target_core_hba_store_attr_hba_mode(struct se_hba *hba,
2682 return -EINVAL; 2687 return -EINVAL;
2683 } 2688 }
2684 2689
2685 ret = transport->pmode_enable_hba(hba, mode_flag); 2690 ret = hba->backend->ops->pmode_enable_hba(hba, mode_flag);
2686 if (ret < 0) 2691 if (ret < 0)
2687 return -EINVAL; 2692 return -EINVAL;
2688 if (ret > 0) 2693 if (ret > 0)
@@ -2808,16 +2813,15 @@ static struct config_item_type target_core_cit = {
2808 2813
2809/* Stop functions for struct config_item_type target_core_hba_cit */ 2814/* Stop functions for struct config_item_type target_core_hba_cit */
2810 2815
2811void target_core_setup_sub_cits(struct se_subsystem_api *sa) 2816void target_setup_backend_cits(struct target_backend *tb)
2812{ 2817{
2813 target_core_setup_dev_cit(sa); 2818 target_core_setup_dev_cit(tb);
2814 target_core_setup_dev_attrib_cit(sa); 2819 target_core_setup_dev_attrib_cit(tb);
2815 target_core_setup_dev_pr_cit(sa); 2820 target_core_setup_dev_pr_cit(tb);
2816 target_core_setup_dev_wwn_cit(sa); 2821 target_core_setup_dev_wwn_cit(tb);
2817 target_core_setup_dev_alua_tg_pt_gps_cit(sa); 2822 target_core_setup_dev_alua_tg_pt_gps_cit(tb);
2818 target_core_setup_dev_stat_cit(sa); 2823 target_core_setup_dev_stat_cit(tb);
2819} 2824}
2820EXPORT_SYMBOL(target_core_setup_sub_cits);
2821 2825
2822static int __init target_core_init_configfs(void) 2826static int __init target_core_init_configfs(void)
2823{ 2827{
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 47a73609e277..af906f1caaa7 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -1367,13 +1367,13 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
1367 struct se_device *dev; 1367 struct se_device *dev;
1368 struct se_lun *xcopy_lun; 1368 struct se_lun *xcopy_lun;
1369 1369
1370 dev = hba->transport->alloc_device(hba, name); 1370 dev = hba->backend->ops->alloc_device(hba, name);
1371 if (!dev) 1371 if (!dev)
1372 return NULL; 1372 return NULL;
1373 1373
1374 dev->dev_link_magic = SE_DEV_LINK_MAGIC; 1374 dev->dev_link_magic = SE_DEV_LINK_MAGIC;
1375 dev->se_hba = hba; 1375 dev->se_hba = hba;
1376 dev->transport = hba->transport; 1376 dev->transport = hba->backend->ops;
1377 dev->prot_length = sizeof(struct se_dif_v1_tuple); 1377 dev->prot_length = sizeof(struct se_dif_v1_tuple);
1378 1378
1379 INIT_LIST_HEAD(&dev->dev_list); 1379 INIT_LIST_HEAD(&dev->dev_list);
@@ -1571,7 +1571,7 @@ int core_dev_setup_virtual_lun0(void)
1571 goto out_free_hba; 1571 goto out_free_hba;
1572 } 1572 }
1573 1573
1574 hba->transport->set_configfs_dev_params(dev, buf, sizeof(buf)); 1574 hba->backend->ops->set_configfs_dev_params(dev, buf, sizeof(buf));
1575 1575
1576 ret = target_configure_device(dev); 1576 ret = target_configure_device(dev);
1577 if (ret) 1577 if (ret)
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index e865885352da..7c5b1ef57d34 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -46,10 +46,6 @@ static inline struct fd_dev *FD_DEV(struct se_device *dev)
46 return container_of(dev, struct fd_dev, dev); 46 return container_of(dev, struct fd_dev, dev);
47} 47}
48 48
49/* fd_attach_hba(): (Part of se_subsystem_api_t template)
50 *
51 *
52 */
53static int fd_attach_hba(struct se_hba *hba, u32 host_id) 49static int fd_attach_hba(struct se_hba *hba, u32 host_id)
54{ 50{
55 struct fd_host *fd_host; 51 struct fd_host *fd_host;
@@ -881,7 +877,7 @@ static struct configfs_attribute *fileio_backend_dev_attrs[] = {
881 NULL, 877 NULL,
882}; 878};
883 879
884static struct se_subsystem_api fileio_template = { 880static const struct target_backend_ops fileio_ops = {
885 .name = "fileio", 881 .name = "fileio",
886 .inquiry_prod = "FILEIO", 882 .inquiry_prod = "FILEIO",
887 .inquiry_rev = FD_VERSION, 883 .inquiry_rev = FD_VERSION,
@@ -899,21 +895,17 @@ static struct se_subsystem_api fileio_template = {
899 .init_prot = fd_init_prot, 895 .init_prot = fd_init_prot,
900 .format_prot = fd_format_prot, 896 .format_prot = fd_format_prot,
901 .free_prot = fd_free_prot, 897 .free_prot = fd_free_prot,
898 .tb_dev_attrib_attrs = fileio_backend_dev_attrs,
902}; 899};
903 900
904static int __init fileio_module_init(void) 901static int __init fileio_module_init(void)
905{ 902{
906 struct target_backend_cits *tbc = &fileio_template.tb_cits; 903 return transport_backend_register(&fileio_ops);
907
908 target_core_setup_sub_cits(&fileio_template);
909 tbc->tb_dev_attrib_cit.ct_attrs = fileio_backend_dev_attrs;
910
911 return transport_subsystem_register(&fileio_template);
912} 904}
913 905
914static void __exit fileio_module_exit(void) 906static void __exit fileio_module_exit(void)
915{ 907{
916 transport_subsystem_release(&fileio_template); 908 target_backend_unregister(&fileio_ops);
917} 909}
918 910
919MODULE_DESCRIPTION("TCM FILEIO subsystem plugin"); 911MODULE_DESCRIPTION("TCM FILEIO subsystem plugin");
diff --git a/drivers/target/target_core_hba.c b/drivers/target/target_core_hba.c
index e6e496ff9546..62ea4e8e70a8 100644
--- a/drivers/target/target_core_hba.c
+++ b/drivers/target/target_core_hba.c
@@ -39,63 +39,75 @@
39 39
40#include "target_core_internal.h" 40#include "target_core_internal.h"
41 41
42static LIST_HEAD(subsystem_list); 42static LIST_HEAD(backend_list);
43static DEFINE_MUTEX(subsystem_mutex); 43static DEFINE_MUTEX(backend_mutex);
44 44
45static u32 hba_id_counter; 45static u32 hba_id_counter;
46 46
47static DEFINE_SPINLOCK(hba_lock); 47static DEFINE_SPINLOCK(hba_lock);
48static LIST_HEAD(hba_list); 48static LIST_HEAD(hba_list);
49 49
50int transport_subsystem_register(struct se_subsystem_api *sub_api)
51{
52 struct se_subsystem_api *s;
53
54 INIT_LIST_HEAD(&sub_api->sub_api_list);
55 50
56 mutex_lock(&subsystem_mutex); 51int transport_backend_register(const struct target_backend_ops *ops)
57 list_for_each_entry(s, &subsystem_list, sub_api_list) { 52{
58 if (!strcmp(s->name, sub_api->name)) { 53 struct target_backend *tb, *old;
59 pr_err("%p is already registered with" 54
60 " duplicate name %s, unable to process" 55 tb = kzalloc(sizeof(*tb), GFP_KERNEL);
61 " request\n", s, s->name); 56 if (!tb)
62 mutex_unlock(&subsystem_mutex); 57 return -ENOMEM;
58 tb->ops = ops;
59
60 mutex_lock(&backend_mutex);
61 list_for_each_entry(old, &backend_list, list) {
62 if (!strcmp(old->ops->name, ops->name)) {
63 pr_err("backend %s already registered.\n", ops->name);
64 mutex_unlock(&backend_mutex);
65 kfree(tb);
63 return -EEXIST; 66 return -EEXIST;
64 } 67 }
65 } 68 }
66 list_add_tail(&sub_api->sub_api_list, &subsystem_list); 69 target_setup_backend_cits(tb);
67 mutex_unlock(&subsystem_mutex); 70 list_add_tail(&tb->list, &backend_list);
71 mutex_unlock(&backend_mutex);
68 72
69 pr_debug("TCM: Registered subsystem plugin: %s struct module:" 73 pr_debug("TCM: Registered subsystem plugin: %s struct module: %p\n",
70 " %p\n", sub_api->name, sub_api->owner); 74 ops->name, ops->owner);
71 return 0; 75 return 0;
72} 76}
73EXPORT_SYMBOL(transport_subsystem_register); 77EXPORT_SYMBOL(transport_backend_register);
74 78
75void transport_subsystem_release(struct se_subsystem_api *sub_api) 79void target_backend_unregister(const struct target_backend_ops *ops)
76{ 80{
77 mutex_lock(&subsystem_mutex); 81 struct target_backend *tb;
78 list_del(&sub_api->sub_api_list); 82
79 mutex_unlock(&subsystem_mutex); 83 mutex_lock(&backend_mutex);
84 list_for_each_entry(tb, &backend_list, list) {
85 if (tb->ops == ops) {
86 list_del(&tb->list);
87 kfree(tb);
88 break;
89 }
90 }
91 mutex_unlock(&backend_mutex);
80} 92}
81EXPORT_SYMBOL(transport_subsystem_release); 93EXPORT_SYMBOL(target_backend_unregister);
82 94
83static struct se_subsystem_api *core_get_backend(const char *sub_name) 95static struct target_backend *core_get_backend(const char *name)
84{ 96{
85 struct se_subsystem_api *s; 97 struct target_backend *tb;
86 98
87 mutex_lock(&subsystem_mutex); 99 mutex_lock(&backend_mutex);
88 list_for_each_entry(s, &subsystem_list, sub_api_list) { 100 list_for_each_entry(tb, &backend_list, list) {
89 if (!strcmp(s->name, sub_name)) 101 if (!strcmp(tb->ops->name, name))
90 goto found; 102 goto found;
91 } 103 }
92 mutex_unlock(&subsystem_mutex); 104 mutex_unlock(&backend_mutex);
93 return NULL; 105 return NULL;
94found: 106found:
95 if (s->owner && !try_module_get(s->owner)) 107 if (tb->ops->owner && !try_module_get(tb->ops->owner))
96 s = NULL; 108 tb = NULL;
97 mutex_unlock(&subsystem_mutex); 109 mutex_unlock(&backend_mutex);
98 return s; 110 return tb;
99} 111}
100 112
101struct se_hba * 113struct se_hba *
@@ -116,13 +128,13 @@ core_alloc_hba(const char *plugin_name, u32 plugin_dep_id, u32 hba_flags)
116 hba->hba_index = scsi_get_new_index(SCSI_INST_INDEX); 128 hba->hba_index = scsi_get_new_index(SCSI_INST_INDEX);
117 hba->hba_flags |= hba_flags; 129 hba->hba_flags |= hba_flags;
118 130
119 hba->transport = core_get_backend(plugin_name); 131 hba->backend = core_get_backend(plugin_name);
120 if (!hba->transport) { 132 if (!hba->backend) {
121 ret = -EINVAL; 133 ret = -EINVAL;
122 goto out_free_hba; 134 goto out_free_hba;
123 } 135 }
124 136
125 ret = hba->transport->attach_hba(hba, plugin_dep_id); 137 ret = hba->backend->ops->attach_hba(hba, plugin_dep_id);
126 if (ret < 0) 138 if (ret < 0)
127 goto out_module_put; 139 goto out_module_put;
128 140
@@ -137,8 +149,8 @@ core_alloc_hba(const char *plugin_name, u32 plugin_dep_id, u32 hba_flags)
137 return hba; 149 return hba;
138 150
139out_module_put: 151out_module_put:
140 module_put(hba->transport->owner); 152 module_put(hba->backend->ops->owner);
141 hba->transport = NULL; 153 hba->backend = NULL;
142out_free_hba: 154out_free_hba:
143 kfree(hba); 155 kfree(hba);
144 return ERR_PTR(ret); 156 return ERR_PTR(ret);
@@ -149,7 +161,7 @@ core_delete_hba(struct se_hba *hba)
149{ 161{
150 WARN_ON(hba->dev_count); 162 WARN_ON(hba->dev_count);
151 163
152 hba->transport->detach_hba(hba); 164 hba->backend->ops->detach_hba(hba);
153 165
154 spin_lock(&hba_lock); 166 spin_lock(&hba_lock);
155 list_del(&hba->hba_node); 167 list_del(&hba->hba_node);
@@ -158,9 +170,9 @@ core_delete_hba(struct se_hba *hba)
158 pr_debug("CORE_HBA[%d] - Detached HBA from Generic Target" 170 pr_debug("CORE_HBA[%d] - Detached HBA from Generic Target"
159 " Core\n", hba->hba_id); 171 " Core\n", hba->hba_id);
160 172
161 module_put(hba->transport->owner); 173 module_put(hba->backend->ops->owner);
162 174
163 hba->transport = NULL; 175 hba->backend = NULL;
164 kfree(hba); 176 kfree(hba);
165 return 0; 177 return 0;
166} 178}
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 8c965683789f..79f651fb98fb 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -54,12 +54,6 @@ static inline struct iblock_dev *IBLOCK_DEV(struct se_device *dev)
54} 54}
55 55
56 56
57static struct se_subsystem_api iblock_template;
58
59/* iblock_attach_hba(): (Part of se_subsystem_api_t template)
60 *
61 *
62 */
63static int iblock_attach_hba(struct se_hba *hba, u32 host_id) 57static int iblock_attach_hba(struct se_hba *hba, u32 host_id)
64{ 58{
65 pr_debug("CORE_HBA[%d] - TCM iBlock HBA Driver %s on" 59 pr_debug("CORE_HBA[%d] - TCM iBlock HBA Driver %s on"
@@ -899,7 +893,7 @@ static struct configfs_attribute *iblock_backend_dev_attrs[] = {
899 NULL, 893 NULL,
900}; 894};
901 895
902static struct se_subsystem_api iblock_template = { 896static const struct target_backend_ops iblock_ops = {
903 .name = "iblock", 897 .name = "iblock",
904 .inquiry_prod = "IBLOCK", 898 .inquiry_prod = "IBLOCK",
905 .inquiry_rev = IBLOCK_VERSION, 899 .inquiry_rev = IBLOCK_VERSION,
@@ -919,21 +913,17 @@ static struct se_subsystem_api iblock_template = {
919 .get_io_min = iblock_get_io_min, 913 .get_io_min = iblock_get_io_min,
920 .get_io_opt = iblock_get_io_opt, 914 .get_io_opt = iblock_get_io_opt,
921 .get_write_cache = iblock_get_write_cache, 915 .get_write_cache = iblock_get_write_cache,
916 .tb_dev_attrib_attrs = iblock_backend_dev_attrs,
922}; 917};
923 918
924static int __init iblock_module_init(void) 919static int __init iblock_module_init(void)
925{ 920{
926 struct target_backend_cits *tbc = &iblock_template.tb_cits; 921 return transport_backend_register(&iblock_ops);
927
928 target_core_setup_sub_cits(&iblock_template);
929 tbc->tb_dev_attrib_cit.ct_attrs = iblock_backend_dev_attrs;
930
931 return transport_subsystem_register(&iblock_template);
932} 922}
933 923
934static void __exit iblock_module_exit(void) 924static void __exit iblock_module_exit(void)
935{ 925{
936 transport_subsystem_release(&iblock_template); 926 target_backend_unregister(&iblock_ops);
937} 927}
938 928
939MODULE_DESCRIPTION("TCM IBLOCK subsystem plugin"); 929MODULE_DESCRIPTION("TCM IBLOCK subsystem plugin");
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index ce80ca76f68b..01181aed67dc 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -1,6 +1,19 @@
1#ifndef TARGET_CORE_INTERNAL_H 1#ifndef TARGET_CORE_INTERNAL_H
2#define TARGET_CORE_INTERNAL_H 2#define TARGET_CORE_INTERNAL_H
3 3
4struct target_backend {
5 struct list_head list;
6
7 const struct target_backend_ops *ops;
8
9 struct config_item_type tb_dev_cit;
10 struct config_item_type tb_dev_attrib_cit;
11 struct config_item_type tb_dev_pr_cit;
12 struct config_item_type tb_dev_wwn_cit;
13 struct config_item_type tb_dev_alua_tg_pt_gps_cit;
14 struct config_item_type tb_dev_stat_cit;
15};
16
4/* target_core_alua.c */ 17/* target_core_alua.c */
5extern struct t10_alua_lu_gp *default_lu_gp; 18extern struct t10_alua_lu_gp *default_lu_gp;
6 19
@@ -40,6 +53,9 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name);
40int target_configure_device(struct se_device *dev); 53int target_configure_device(struct se_device *dev);
41void target_free_device(struct se_device *); 54void target_free_device(struct se_device *);
42 55
56/* target_core_configfs.c */
57void target_setup_backend_cits(struct target_backend *);
58
43/* target_core_fabric_lib.c */ 59/* target_core_fabric_lib.c */
44int target_get_pr_transport_id_len(struct se_node_acl *nacl, 60int target_get_pr_transport_id_len(struct se_node_acl *nacl,
45 struct t10_pr_registration *pr_reg, int *format_code); 61 struct t10_pr_registration *pr_reg, int *format_code);
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index 21db991b4465..2e3a0b004f9a 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -57,8 +57,6 @@ static inline struct pscsi_dev_virt *PSCSI_DEV(struct se_device *dev)
57 return container_of(dev, struct pscsi_dev_virt, dev); 57 return container_of(dev, struct pscsi_dev_virt, dev);
58} 58}
59 59
60static struct se_subsystem_api pscsi_template;
61
62static sense_reason_t pscsi_execute_cmd(struct se_cmd *cmd); 60static sense_reason_t pscsi_execute_cmd(struct se_cmd *cmd);
63static void pscsi_req_done(struct request *, int); 61static void pscsi_req_done(struct request *, int);
64 62
@@ -1141,7 +1139,7 @@ static struct configfs_attribute *pscsi_backend_dev_attrs[] = {
1141 NULL, 1139 NULL,
1142}; 1140};
1143 1141
1144static struct se_subsystem_api pscsi_template = { 1142static const struct target_backend_ops pscsi_ops = {
1145 .name = "pscsi", 1143 .name = "pscsi",
1146 .owner = THIS_MODULE, 1144 .owner = THIS_MODULE,
1147 .transport_flags = TRANSPORT_FLAG_PASSTHROUGH, 1145 .transport_flags = TRANSPORT_FLAG_PASSTHROUGH,
@@ -1157,21 +1155,17 @@ static struct se_subsystem_api pscsi_template = {
1157 .show_configfs_dev_params = pscsi_show_configfs_dev_params, 1155 .show_configfs_dev_params = pscsi_show_configfs_dev_params,
1158 .get_device_type = pscsi_get_device_type, 1156 .get_device_type = pscsi_get_device_type,
1159 .get_blocks = pscsi_get_blocks, 1157 .get_blocks = pscsi_get_blocks,
1158 .tb_dev_attrib_attrs = pscsi_backend_dev_attrs,
1160}; 1159};
1161 1160
1162static int __init pscsi_module_init(void) 1161static int __init pscsi_module_init(void)
1163{ 1162{
1164 struct target_backend_cits *tbc = &pscsi_template.tb_cits; 1163 return transport_backend_register(&pscsi_ops);
1165
1166 target_core_setup_sub_cits(&pscsi_template);
1167 tbc->tb_dev_attrib_cit.ct_attrs = pscsi_backend_dev_attrs;
1168
1169 return transport_subsystem_register(&pscsi_template);
1170} 1164}
1171 1165
1172static void __exit pscsi_module_exit(void) 1166static void __exit pscsi_module_exit(void)
1173{ 1167{
1174 transport_subsystem_release(&pscsi_template); 1168 target_backend_unregister(&pscsi_ops);
1175} 1169}
1176 1170
1177MODULE_DESCRIPTION("TCM PSCSI subsystem plugin"); 1171MODULE_DESCRIPTION("TCM PSCSI subsystem plugin");
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index 55315fd0f5d3..cf443a8a3cbe 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -43,10 +43,6 @@ static inline struct rd_dev *RD_DEV(struct se_device *dev)
43 return container_of(dev, struct rd_dev, dev); 43 return container_of(dev, struct rd_dev, dev);
44} 44}
45 45
46/* rd_attach_hba(): (Part of se_subsystem_api_t template)
47 *
48 *
49 */
50static int rd_attach_hba(struct se_hba *hba, u32 host_id) 46static int rd_attach_hba(struct se_hba *hba, u32 host_id)
51{ 47{
52 struct rd_host *rd_host; 48 struct rd_host *rd_host;
@@ -735,7 +731,7 @@ static struct configfs_attribute *rd_mcp_backend_dev_attrs[] = {
735 NULL, 731 NULL,
736}; 732};
737 733
738static struct se_subsystem_api rd_mcp_template = { 734static const struct target_backend_ops rd_mcp_ops = {
739 .name = "rd_mcp", 735 .name = "rd_mcp",
740 .inquiry_prod = "RAMDISK-MCP", 736 .inquiry_prod = "RAMDISK-MCP",
741 .inquiry_rev = RD_MCP_VERSION, 737 .inquiry_rev = RD_MCP_VERSION,
@@ -751,25 +747,15 @@ static struct se_subsystem_api rd_mcp_template = {
751 .get_blocks = rd_get_blocks, 747 .get_blocks = rd_get_blocks,
752 .init_prot = rd_init_prot, 748 .init_prot = rd_init_prot,
753 .free_prot = rd_free_prot, 749 .free_prot = rd_free_prot,
750 .tb_dev_attrib_attrs = rd_mcp_backend_dev_attrs,
754}; 751};
755 752
756int __init rd_module_init(void) 753int __init rd_module_init(void)
757{ 754{
758 struct target_backend_cits *tbc = &rd_mcp_template.tb_cits; 755 return transport_backend_register(&rd_mcp_ops);
759 int ret;
760
761 target_core_setup_sub_cits(&rd_mcp_template);
762 tbc->tb_dev_attrib_cit.ct_attrs = rd_mcp_backend_dev_attrs;
763
764 ret = transport_subsystem_register(&rd_mcp_template);
765 if (ret < 0) {
766 return ret;
767 }
768
769 return 0;
770} 756}
771 757
772void rd_module_exit(void) 758void rd_module_exit(void)
773{ 759{
774 transport_subsystem_release(&rd_mcp_template); 760 target_backend_unregister(&rd_mcp_ops);
775} 761}
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index 60330e00f59d..fb67e313dc4f 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -1115,7 +1115,7 @@ static struct configfs_attribute *tcmu_backend_dev_attrs[] = {
1115 NULL, 1115 NULL,
1116}; 1116};
1117 1117
1118static struct se_subsystem_api tcmu_template = { 1118static const struct target_backend_ops tcmu_ops = {
1119 .name = "user", 1119 .name = "user",
1120 .inquiry_prod = "USER", 1120 .inquiry_prod = "USER",
1121 .inquiry_rev = TCMU_VERSION, 1121 .inquiry_rev = TCMU_VERSION,
@@ -1131,11 +1131,11 @@ static struct se_subsystem_api tcmu_template = {
1131 .show_configfs_dev_params = tcmu_show_configfs_dev_params, 1131 .show_configfs_dev_params = tcmu_show_configfs_dev_params,
1132 .get_device_type = sbc_get_device_type, 1132 .get_device_type = sbc_get_device_type,
1133 .get_blocks = tcmu_get_blocks, 1133 .get_blocks = tcmu_get_blocks,
1134 .tb_dev_attrib_attrs = tcmu_backend_dev_attrs,
1134}; 1135};
1135 1136
1136static int __init tcmu_module_init(void) 1137static int __init tcmu_module_init(void)
1137{ 1138{
1138 struct target_backend_cits *tbc = &tcmu_template.tb_cits;
1139 int ret; 1139 int ret;
1140 1140
1141 BUILD_BUG_ON((sizeof(struct tcmu_cmd_entry) % TCMU_OP_ALIGN_SIZE) != 0); 1141 BUILD_BUG_ON((sizeof(struct tcmu_cmd_entry) % TCMU_OP_ALIGN_SIZE) != 0);
@@ -1158,10 +1158,7 @@ static int __init tcmu_module_init(void)
1158 goto out_unreg_device; 1158 goto out_unreg_device;
1159 } 1159 }
1160 1160
1161 target_core_setup_sub_cits(&tcmu_template); 1161 ret = transport_backend_register(&tcmu_ops);
1162 tbc->tb_dev_attrib_cit.ct_attrs = tcmu_backend_dev_attrs;
1163
1164 ret = transport_subsystem_register(&tcmu_template);
1165 if (ret) 1162 if (ret)
1166 goto out_unreg_genl; 1163 goto out_unreg_genl;
1167 1164
@@ -1179,7 +1176,7 @@ out_free_cache:
1179 1176
1180static void __exit tcmu_module_exit(void) 1177static void __exit tcmu_module_exit(void)
1181{ 1178{
1182 transport_subsystem_release(&tcmu_template); 1179 target_backend_unregister(&tcmu_ops);
1183 genl_unregister_family(&tcmu_genl_family); 1180 genl_unregister_family(&tcmu_genl_family);
1184 root_device_unregister(tcmu_root_device); 1181 root_device_unregister(tcmu_root_device);
1185 kmem_cache_destroy(tcmu_cmd_cache); 1182 kmem_cache_destroy(tcmu_cmd_cache);
diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h
index 80d9e486e33e..514b52019380 100644
--- a/include/target/target_core_backend.h
+++ b/include/target/target_core_backend.h
@@ -3,18 +3,7 @@
3 3
4#define TRANSPORT_FLAG_PASSTHROUGH 1 4#define TRANSPORT_FLAG_PASSTHROUGH 1
5 5
6struct target_backend_cits { 6struct target_backend_ops {
7 struct config_item_type tb_dev_cit;
8 struct config_item_type tb_dev_attrib_cit;
9 struct config_item_type tb_dev_pr_cit;
10 struct config_item_type tb_dev_wwn_cit;
11 struct config_item_type tb_dev_alua_tg_pt_gps_cit;
12 struct config_item_type tb_dev_stat_cit;
13};
14
15struct se_subsystem_api {
16 struct list_head sub_api_list;
17
18 char name[16]; 7 char name[16];
19 char inquiry_prod[16]; 8 char inquiry_prod[16];
20 char inquiry_rev[4]; 9 char inquiry_rev[4];
@@ -52,7 +41,7 @@ struct se_subsystem_api {
52 int (*format_prot)(struct se_device *); 41 int (*format_prot)(struct se_device *);
53 void (*free_prot)(struct se_device *); 42 void (*free_prot)(struct se_device *);
54 43
55 struct target_backend_cits tb_cits; 44 struct configfs_attribute **tb_dev_attrib_attrs;
56}; 45};
57 46
58struct sbc_ops { 47struct sbc_ops {
@@ -64,8 +53,8 @@ struct sbc_ops {
64 sense_reason_t (*execute_unmap)(struct se_cmd *cmd); 53 sense_reason_t (*execute_unmap)(struct se_cmd *cmd);
65}; 54};
66 55
67int transport_subsystem_register(struct se_subsystem_api *); 56int transport_backend_register(const struct target_backend_ops *);
68void transport_subsystem_release(struct se_subsystem_api *); 57void target_backend_unregister(const struct target_backend_ops *);
69 58
70void target_complete_cmd(struct se_cmd *, u8); 59void target_complete_cmd(struct se_cmd *, u8);
71void target_complete_cmd_with_length(struct se_cmd *, u8, int); 60void target_complete_cmd_with_length(struct se_cmd *, u8, int);
@@ -103,9 +92,6 @@ sense_reason_t transport_generic_map_mem_to_cmd(struct se_cmd *,
103 92
104bool target_lun_is_rdonly(struct se_cmd *); 93bool target_lun_is_rdonly(struct se_cmd *);
105 94
106/* From target_core_configfs.c to setup default backend config_item_types */
107void target_core_setup_sub_cits(struct se_subsystem_api *);
108
109/* attribute helpers from target_core_device.c for backend drivers */ 95/* attribute helpers from target_core_device.c for backend drivers */
110bool se_dev_check_wce(struct se_device *); 96bool se_dev_check_wce(struct se_device *);
111int se_dev_set_max_unmap_lba_count(struct se_device *, u32); 97int se_dev_set_max_unmap_lba_count(struct se_device *, u32);
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 78ed2a83838c..03e2ee8f8337 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -797,7 +797,7 @@ struct se_device {
797#define SE_UDEV_PATH_LEN 512 /* must be less than PAGE_SIZE */ 797#define SE_UDEV_PATH_LEN 512 /* must be less than PAGE_SIZE */
798 unsigned char udev_path[SE_UDEV_PATH_LEN]; 798 unsigned char udev_path[SE_UDEV_PATH_LEN];
799 /* Pointer to template of function pointers for transport */ 799 /* Pointer to template of function pointers for transport */
800 struct se_subsystem_api *transport; 800 const struct target_backend_ops *transport;
801 /* Linked list for struct se_hba struct se_device list */ 801 /* Linked list for struct se_hba struct se_device list */
802 struct list_head dev_list; 802 struct list_head dev_list;
803 struct se_lun xcopy_lun; 803 struct se_lun xcopy_lun;
@@ -819,7 +819,7 @@ struct se_hba {
819 spinlock_t device_lock; 819 spinlock_t device_lock;
820 struct config_group hba_group; 820 struct config_group hba_group;
821 struct mutex hba_access_mutex; 821 struct mutex hba_access_mutex;
822 struct se_subsystem_api *transport; 822 struct target_backend *backend;
823}; 823};
824 824
825struct scsi_port_stats { 825struct scsi_port_stats {