|
@@ -41,8 +41,7 @@
|
|
|
|
|
|
#define to_tcm_loop_hba(hba) container_of(hba, struct tcm_loop_hba, dev)
|
|
#define to_tcm_loop_hba(hba) container_of(hba, struct tcm_loop_hba, dev)
|
|
|
|
|
|
-/* Local pointer to allocated TCM configfs fabric module */
|
|
|
|
-static struct target_fabric_configfs *tcm_loop_fabric_configfs;
|
|
|
|
|
|
+static const struct target_core_fabric_ops loop_ops;
|
|
|
|
|
|
static struct workqueue_struct *tcm_loop_workqueue;
|
|
static struct workqueue_struct *tcm_loop_workqueue;
|
|
static struct kmem_cache *tcm_loop_cmd_cache;
|
|
static struct kmem_cache *tcm_loop_cmd_cache;
|
|
@@ -1238,8 +1237,7 @@ static struct se_portal_group *tcm_loop_make_naa_tpg(
|
|
/*
|
|
/*
|
|
* Register the tl_tpg as a emulated SAS TCM Target Endpoint
|
|
* Register the tl_tpg as a emulated SAS TCM Target Endpoint
|
|
*/
|
|
*/
|
|
- ret = core_tpg_register(&tcm_loop_fabric_configfs->tf_ops,
|
|
|
|
- wwn, &tl_tpg->tl_se_tpg, tl_tpg,
|
|
|
|
|
|
+ ret = core_tpg_register(&loop_ops, wwn, &tl_tpg->tl_se_tpg, tl_tpg,
|
|
TRANSPORT_TPG_TYPE_NORMAL);
|
|
TRANSPORT_TPG_TYPE_NORMAL);
|
|
if (ret < 0)
|
|
if (ret < 0)
|
|
return ERR_PTR(-ENOMEM);
|
|
return ERR_PTR(-ENOMEM);
|
|
@@ -1387,129 +1385,51 @@ static struct configfs_attribute *tcm_loop_wwn_attrs[] = {
|
|
|
|
|
|
/* End items for tcm_loop_cit */
|
|
/* End items for tcm_loop_cit */
|
|
|
|
|
|
-static int tcm_loop_register_configfs(void)
|
|
|
|
-{
|
|
|
|
- struct target_fabric_configfs *fabric;
|
|
|
|
- int ret;
|
|
|
|
- /*
|
|
|
|
- * Set the TCM Loop HBA counter to zero
|
|
|
|
- */
|
|
|
|
- tcm_loop_hba_no_cnt = 0;
|
|
|
|
- /*
|
|
|
|
- * Register the top level struct config_item_type with TCM core
|
|
|
|
- */
|
|
|
|
- fabric = target_fabric_configfs_init(THIS_MODULE, "loopback");
|
|
|
|
- if (IS_ERR(fabric)) {
|
|
|
|
- pr_err("tcm_loop_register_configfs() failed!\n");
|
|
|
|
- return PTR_ERR(fabric);
|
|
|
|
- }
|
|
|
|
- /*
|
|
|
|
- * Setup the fabric API of function pointers used by target_core_mod
|
|
|
|
- */
|
|
|
|
- fabric->tf_ops.get_fabric_name = &tcm_loop_get_fabric_name;
|
|
|
|
- fabric->tf_ops.get_fabric_proto_ident = &tcm_loop_get_fabric_proto_ident;
|
|
|
|
- fabric->tf_ops.tpg_get_wwn = &tcm_loop_get_endpoint_wwn;
|
|
|
|
- fabric->tf_ops.tpg_get_tag = &tcm_loop_get_tag;
|
|
|
|
- fabric->tf_ops.tpg_get_default_depth = &tcm_loop_get_default_depth;
|
|
|
|
- fabric->tf_ops.tpg_get_pr_transport_id = &tcm_loop_get_pr_transport_id;
|
|
|
|
- fabric->tf_ops.tpg_get_pr_transport_id_len =
|
|
|
|
- &tcm_loop_get_pr_transport_id_len;
|
|
|
|
- fabric->tf_ops.tpg_parse_pr_out_transport_id =
|
|
|
|
- &tcm_loop_parse_pr_out_transport_id;
|
|
|
|
- fabric->tf_ops.tpg_check_demo_mode = &tcm_loop_check_demo_mode;
|
|
|
|
- fabric->tf_ops.tpg_check_demo_mode_cache =
|
|
|
|
- &tcm_loop_check_demo_mode_cache;
|
|
|
|
- fabric->tf_ops.tpg_check_demo_mode_write_protect =
|
|
|
|
- &tcm_loop_check_demo_mode_write_protect;
|
|
|
|
- fabric->tf_ops.tpg_check_prod_mode_write_protect =
|
|
|
|
- &tcm_loop_check_prod_mode_write_protect;
|
|
|
|
- fabric->tf_ops.tpg_check_prot_fabric_only =
|
|
|
|
- &tcm_loop_check_prot_fabric_only;
|
|
|
|
- /*
|
|
|
|
- * The TCM loopback fabric module runs in demo-mode to a local
|
|
|
|
- * virtual SCSI device, so fabric dependent initator ACLs are
|
|
|
|
- * not required.
|
|
|
|
- */
|
|
|
|
- fabric->tf_ops.tpg_alloc_fabric_acl = &tcm_loop_tpg_alloc_fabric_acl;
|
|
|
|
- fabric->tf_ops.tpg_release_fabric_acl =
|
|
|
|
- &tcm_loop_tpg_release_fabric_acl;
|
|
|
|
- fabric->tf_ops.tpg_get_inst_index = &tcm_loop_get_inst_index;
|
|
|
|
- /*
|
|
|
|
- * Used for setting up remaining TCM resources in process context
|
|
|
|
- */
|
|
|
|
- fabric->tf_ops.check_stop_free = &tcm_loop_check_stop_free;
|
|
|
|
- fabric->tf_ops.release_cmd = &tcm_loop_release_cmd;
|
|
|
|
- fabric->tf_ops.shutdown_session = &tcm_loop_shutdown_session;
|
|
|
|
- fabric->tf_ops.close_session = &tcm_loop_close_session;
|
|
|
|
- fabric->tf_ops.sess_get_index = &tcm_loop_sess_get_index;
|
|
|
|
- fabric->tf_ops.sess_get_initiator_sid = NULL;
|
|
|
|
- fabric->tf_ops.write_pending = &tcm_loop_write_pending;
|
|
|
|
- fabric->tf_ops.write_pending_status = &tcm_loop_write_pending_status;
|
|
|
|
- /*
|
|
|
|
- * Not used for TCM loopback
|
|
|
|
- */
|
|
|
|
- fabric->tf_ops.set_default_node_attributes =
|
|
|
|
- &tcm_loop_set_default_node_attributes;
|
|
|
|
- fabric->tf_ops.get_task_tag = &tcm_loop_get_task_tag;
|
|
|
|
- fabric->tf_ops.get_cmd_state = &tcm_loop_get_cmd_state;
|
|
|
|
- fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in;
|
|
|
|
- fabric->tf_ops.queue_status = &tcm_loop_queue_status;
|
|
|
|
- fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp;
|
|
|
|
- fabric->tf_ops.aborted_task = &tcm_loop_aborted_task;
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Setup function pointers for generic logic in target_core_fabric_configfs.c
|
|
|
|
- */
|
|
|
|
- fabric->tf_ops.fabric_make_wwn = &tcm_loop_make_scsi_hba;
|
|
|
|
- fabric->tf_ops.fabric_drop_wwn = &tcm_loop_drop_scsi_hba;
|
|
|
|
- fabric->tf_ops.fabric_make_tpg = &tcm_loop_make_naa_tpg;
|
|
|
|
- fabric->tf_ops.fabric_drop_tpg = &tcm_loop_drop_naa_tpg;
|
|
|
|
- /*
|
|
|
|
- * fabric_post_link() and fabric_pre_unlink() are used for
|
|
|
|
- * registration and release of TCM Loop Virtual SCSI LUNs.
|
|
|
|
- */
|
|
|
|
- fabric->tf_ops.fabric_post_link = &tcm_loop_port_link;
|
|
|
|
- fabric->tf_ops.fabric_pre_unlink = &tcm_loop_port_unlink;
|
|
|
|
- fabric->tf_ops.fabric_make_np = NULL;
|
|
|
|
- fabric->tf_ops.fabric_drop_np = NULL;
|
|
|
|
- /*
|
|
|
|
- * Setup default attribute lists for various fabric->tf_cit_tmpl
|
|
|
|
- */
|
|
|
|
- fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_loop_wwn_attrs;
|
|
|
|
- fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = tcm_loop_tpg_attrs;
|
|
|
|
- fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = tcm_loop_tpg_attrib_attrs;
|
|
|
|
- fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL;
|
|
|
|
- fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL;
|
|
|
|
- /*
|
|
|
|
- * Once fabric->tf_ops has been setup, now register the fabric for
|
|
|
|
- * use within TCM
|
|
|
|
- */
|
|
|
|
- ret = target_fabric_configfs_register(fabric);
|
|
|
|
- if (ret < 0) {
|
|
|
|
- pr_err("target_fabric_configfs_register() for"
|
|
|
|
- " TCM_Loop failed!\n");
|
|
|
|
- target_fabric_configfs_free(fabric);
|
|
|
|
- return -1;
|
|
|
|
- }
|
|
|
|
- /*
|
|
|
|
- * Setup our local pointer to *fabric.
|
|
|
|
- */
|
|
|
|
- tcm_loop_fabric_configfs = fabric;
|
|
|
|
- pr_debug("TCM_LOOP[0] - Set fabric ->"
|
|
|
|
- " tcm_loop_fabric_configfs\n");
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void tcm_loop_deregister_configfs(void)
|
|
|
|
-{
|
|
|
|
- if (!tcm_loop_fabric_configfs)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- target_fabric_configfs_deregister(tcm_loop_fabric_configfs);
|
|
|
|
- tcm_loop_fabric_configfs = NULL;
|
|
|
|
- pr_debug("TCM_LOOP[0] - Cleared"
|
|
|
|
- " tcm_loop_fabric_configfs\n");
|
|
|
|
-}
|
|
|
|
|
|
+static const struct target_core_fabric_ops loop_ops = {
|
|
|
|
+ .module = THIS_MODULE,
|
|
|
|
+ .name = "loopback",
|
|
|
|
+ .get_fabric_name = tcm_loop_get_fabric_name,
|
|
|
|
+ .get_fabric_proto_ident = tcm_loop_get_fabric_proto_ident,
|
|
|
|
+ .tpg_get_wwn = tcm_loop_get_endpoint_wwn,
|
|
|
|
+ .tpg_get_tag = tcm_loop_get_tag,
|
|
|
|
+ .tpg_get_default_depth = tcm_loop_get_default_depth,
|
|
|
|
+ .tpg_get_pr_transport_id = tcm_loop_get_pr_transport_id,
|
|
|
|
+ .tpg_get_pr_transport_id_len = tcm_loop_get_pr_transport_id_len,
|
|
|
|
+ .tpg_parse_pr_out_transport_id = tcm_loop_parse_pr_out_transport_id,
|
|
|
|
+ .tpg_check_demo_mode = tcm_loop_check_demo_mode,
|
|
|
|
+ .tpg_check_demo_mode_cache = tcm_loop_check_demo_mode_cache,
|
|
|
|
+ .tpg_check_demo_mode_write_protect =
|
|
|
|
+ tcm_loop_check_demo_mode_write_protect,
|
|
|
|
+ .tpg_check_prod_mode_write_protect =
|
|
|
|
+ tcm_loop_check_prod_mode_write_protect,
|
|
|
|
+ .tpg_check_prot_fabric_only = tcm_loop_check_prot_fabric_only,
|
|
|
|
+ .tpg_alloc_fabric_acl = tcm_loop_tpg_alloc_fabric_acl,
|
|
|
|
+ .tpg_release_fabric_acl = tcm_loop_tpg_release_fabric_acl,
|
|
|
|
+ .tpg_get_inst_index = tcm_loop_get_inst_index,
|
|
|
|
+ .check_stop_free = tcm_loop_check_stop_free,
|
|
|
|
+ .release_cmd = tcm_loop_release_cmd,
|
|
|
|
+ .shutdown_session = tcm_loop_shutdown_session,
|
|
|
|
+ .close_session = tcm_loop_close_session,
|
|
|
|
+ .sess_get_index = tcm_loop_sess_get_index,
|
|
|
|
+ .write_pending = tcm_loop_write_pending,
|
|
|
|
+ .write_pending_status = tcm_loop_write_pending_status,
|
|
|
|
+ .set_default_node_attributes = tcm_loop_set_default_node_attributes,
|
|
|
|
+ .get_task_tag = tcm_loop_get_task_tag,
|
|
|
|
+ .get_cmd_state = tcm_loop_get_cmd_state,
|
|
|
|
+ .queue_data_in = tcm_loop_queue_data_in,
|
|
|
|
+ .queue_status = tcm_loop_queue_status,
|
|
|
|
+ .queue_tm_rsp = tcm_loop_queue_tm_rsp,
|
|
|
|
+ .aborted_task = tcm_loop_aborted_task,
|
|
|
|
+ .fabric_make_wwn = tcm_loop_make_scsi_hba,
|
|
|
|
+ .fabric_drop_wwn = tcm_loop_drop_scsi_hba,
|
|
|
|
+ .fabric_make_tpg = tcm_loop_make_naa_tpg,
|
|
|
|
+ .fabric_drop_tpg = tcm_loop_drop_naa_tpg,
|
|
|
|
+ .fabric_post_link = tcm_loop_port_link,
|
|
|
|
+ .fabric_pre_unlink = tcm_loop_port_unlink,
|
|
|
|
+ .tfc_wwn_attrs = tcm_loop_wwn_attrs,
|
|
|
|
+ .tfc_tpg_base_attrs = tcm_loop_tpg_attrs,
|
|
|
|
+ .tfc_tpg_attrib_attrs = tcm_loop_tpg_attrib_attrs,
|
|
|
|
+};
|
|
|
|
|
|
static int __init tcm_loop_fabric_init(void)
|
|
static int __init tcm_loop_fabric_init(void)
|
|
{
|
|
{
|
|
@@ -1533,7 +1453,7 @@ static int __init tcm_loop_fabric_init(void)
|
|
if (ret)
|
|
if (ret)
|
|
goto out_destroy_cache;
|
|
goto out_destroy_cache;
|
|
|
|
|
|
- ret = tcm_loop_register_configfs();
|
|
|
|
|
|
+ ret = target_register_template(&loop_ops);
|
|
if (ret)
|
|
if (ret)
|
|
goto out_release_core_bus;
|
|
goto out_release_core_bus;
|
|
|
|
|
|
@@ -1551,7 +1471,7 @@ out:
|
|
|
|
|
|
static void __exit tcm_loop_fabric_exit(void)
|
|
static void __exit tcm_loop_fabric_exit(void)
|
|
{
|
|
{
|
|
- tcm_loop_deregister_configfs();
|
|
|
|
|
|
+ target_unregister_template(&loop_ops);
|
|
tcm_loop_release_core_bus();
|
|
tcm_loop_release_core_bus();
|
|
kmem_cache_destroy(tcm_loop_cmd_cache);
|
|
kmem_cache_destroy(tcm_loop_cmd_cache);
|
|
destroy_workqueue(tcm_loop_workqueue);
|
|
destroy_workqueue(tcm_loop_workqueue);
|