18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
38c2ecf20Sopenharmony_ci#include <linux/list.h>
48c2ecf20Sopenharmony_ci#include <linux/module.h>
58c2ecf20Sopenharmony_ci#include <target/iscsi/iscsi_transport.h>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_cistatic LIST_HEAD(g_transport_list);
88c2ecf20Sopenharmony_cistatic DEFINE_MUTEX(transport_mutex);
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_cistruct iscsit_transport *iscsit_get_transport(int type)
118c2ecf20Sopenharmony_ci{
128c2ecf20Sopenharmony_ci	struct iscsit_transport *t;
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci	mutex_lock(&transport_mutex);
158c2ecf20Sopenharmony_ci	list_for_each_entry(t, &g_transport_list, t_node) {
168c2ecf20Sopenharmony_ci		if (t->transport_type == type) {
178c2ecf20Sopenharmony_ci			if (t->owner && !try_module_get(t->owner)) {
188c2ecf20Sopenharmony_ci				t = NULL;
198c2ecf20Sopenharmony_ci			}
208c2ecf20Sopenharmony_ci			mutex_unlock(&transport_mutex);
218c2ecf20Sopenharmony_ci			return t;
228c2ecf20Sopenharmony_ci		}
238c2ecf20Sopenharmony_ci	}
248c2ecf20Sopenharmony_ci	mutex_unlock(&transport_mutex);
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci	return NULL;
278c2ecf20Sopenharmony_ci}
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_civoid iscsit_put_transport(struct iscsit_transport *t)
308c2ecf20Sopenharmony_ci{
318c2ecf20Sopenharmony_ci	module_put(t->owner);
328c2ecf20Sopenharmony_ci}
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_civoid iscsit_register_transport(struct iscsit_transport *t)
358c2ecf20Sopenharmony_ci{
368c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&t->t_node);
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci	mutex_lock(&transport_mutex);
398c2ecf20Sopenharmony_ci	list_add_tail(&t->t_node, &g_transport_list);
408c2ecf20Sopenharmony_ci	mutex_unlock(&transport_mutex);
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	pr_debug("Registered iSCSI transport: %s\n", t->name);
438c2ecf20Sopenharmony_ci}
448c2ecf20Sopenharmony_ciEXPORT_SYMBOL(iscsit_register_transport);
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_civoid iscsit_unregister_transport(struct iscsit_transport *t)
478c2ecf20Sopenharmony_ci{
488c2ecf20Sopenharmony_ci	mutex_lock(&transport_mutex);
498c2ecf20Sopenharmony_ci	list_del(&t->t_node);
508c2ecf20Sopenharmony_ci	mutex_unlock(&transport_mutex);
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	pr_debug("Unregistered iSCSI transport: %s\n", t->name);
538c2ecf20Sopenharmony_ci}
548c2ecf20Sopenharmony_ciEXPORT_SYMBOL(iscsit_unregister_transport);
55