162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include <linux/spinlock.h>
362306a36Sopenharmony_ci#include <linux/list.h>
462306a36Sopenharmony_ci#include <linux/module.h>
562306a36Sopenharmony_ci#include <target/iscsi/iscsi_transport.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_cistatic LIST_HEAD(g_transport_list);
862306a36Sopenharmony_cistatic DEFINE_MUTEX(transport_mutex);
962306a36Sopenharmony_ci
1062306a36Sopenharmony_cistruct iscsit_transport *iscsit_get_transport(int type)
1162306a36Sopenharmony_ci{
1262306a36Sopenharmony_ci	struct iscsit_transport *t;
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci	mutex_lock(&transport_mutex);
1562306a36Sopenharmony_ci	list_for_each_entry(t, &g_transport_list, t_node) {
1662306a36Sopenharmony_ci		if (t->transport_type == type) {
1762306a36Sopenharmony_ci			if (t->owner && !try_module_get(t->owner)) {
1862306a36Sopenharmony_ci				t = NULL;
1962306a36Sopenharmony_ci			}
2062306a36Sopenharmony_ci			mutex_unlock(&transport_mutex);
2162306a36Sopenharmony_ci			return t;
2262306a36Sopenharmony_ci		}
2362306a36Sopenharmony_ci	}
2462306a36Sopenharmony_ci	mutex_unlock(&transport_mutex);
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	return NULL;
2762306a36Sopenharmony_ci}
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_civoid iscsit_put_transport(struct iscsit_transport *t)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	module_put(t->owner);
3262306a36Sopenharmony_ci}
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_civoid iscsit_register_transport(struct iscsit_transport *t)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	INIT_LIST_HEAD(&t->t_node);
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	mutex_lock(&transport_mutex);
3962306a36Sopenharmony_ci	list_add_tail(&t->t_node, &g_transport_list);
4062306a36Sopenharmony_ci	mutex_unlock(&transport_mutex);
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	pr_debug("Registered iSCSI transport: %s\n", t->name);
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ciEXPORT_SYMBOL(iscsit_register_transport);
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_civoid iscsit_unregister_transport(struct iscsit_transport *t)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	mutex_lock(&transport_mutex);
4962306a36Sopenharmony_ci	list_del(&t->t_node);
5062306a36Sopenharmony_ci	mutex_unlock(&transport_mutex);
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	pr_debug("Unregistered iSCSI transport: %s\n", t->name);
5362306a36Sopenharmony_ci}
5462306a36Sopenharmony_ciEXPORT_SYMBOL(iscsit_unregister_transport);
55