1c66ac9dbSNicholas Bellinger /******************************************************************************* 2c66ac9dbSNicholas Bellinger * Filename: target_core_hba.c 3c66ac9dbSNicholas Bellinger * 4e3d6f909SAndy Grover * This file contains the TCM HBA Transport related functions. 5c66ac9dbSNicholas Bellinger * 6c66ac9dbSNicholas Bellinger * Copyright (c) 2003, 2004, 2005 PyX Technologies, Inc. 7c66ac9dbSNicholas Bellinger * Copyright (c) 2005, 2006, 2007 SBE, Inc. 8c66ac9dbSNicholas Bellinger * Copyright (c) 2007-2010 Rising Tide Systems 9c66ac9dbSNicholas Bellinger * Copyright (c) 2008-2010 Linux-iSCSI.org 10c66ac9dbSNicholas Bellinger * 11c66ac9dbSNicholas Bellinger * Nicholas A. Bellinger <nab@kernel.org> 12c66ac9dbSNicholas Bellinger * 13c66ac9dbSNicholas Bellinger * This program is free software; you can redistribute it and/or modify 14c66ac9dbSNicholas Bellinger * it under the terms of the GNU General Public License as published by 15c66ac9dbSNicholas Bellinger * the Free Software Foundation; either version 2 of the License, or 16c66ac9dbSNicholas Bellinger * (at your option) any later version. 17c66ac9dbSNicholas Bellinger * 18c66ac9dbSNicholas Bellinger * This program is distributed in the hope that it will be useful, 19c66ac9dbSNicholas Bellinger * but WITHOUT ANY WARRANTY; without even the implied warranty of 20c66ac9dbSNicholas Bellinger * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21c66ac9dbSNicholas Bellinger * GNU General Public License for more details. 22c66ac9dbSNicholas Bellinger * 23c66ac9dbSNicholas Bellinger * You should have received a copy of the GNU General Public License 24c66ac9dbSNicholas Bellinger * along with this program; if not, write to the Free Software 25c66ac9dbSNicholas Bellinger * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 26c66ac9dbSNicholas Bellinger * 27c66ac9dbSNicholas Bellinger ******************************************************************************/ 28c66ac9dbSNicholas Bellinger 29c66ac9dbSNicholas Bellinger #include <linux/net.h> 30c66ac9dbSNicholas Bellinger #include <linux/string.h> 31c66ac9dbSNicholas Bellinger #include <linux/timer.h> 32c66ac9dbSNicholas Bellinger #include <linux/slab.h> 33c66ac9dbSNicholas Bellinger #include <linux/spinlock.h> 34c66ac9dbSNicholas Bellinger #include <linux/in.h> 35c66ac9dbSNicholas Bellinger #include <net/sock.h> 36c66ac9dbSNicholas Bellinger #include <net/tcp.h> 37c66ac9dbSNicholas Bellinger 38c66ac9dbSNicholas Bellinger #include <target/target_core_base.h> 39c66ac9dbSNicholas Bellinger #include <target/target_core_device.h> 40c66ac9dbSNicholas Bellinger #include <target/target_core_tpg.h> 41c66ac9dbSNicholas Bellinger #include <target/target_core_transport.h> 42c66ac9dbSNicholas Bellinger 43c66ac9dbSNicholas Bellinger #include "target_core_hba.h" 44c66ac9dbSNicholas Bellinger 45c66ac9dbSNicholas Bellinger static LIST_HEAD(subsystem_list); 46c66ac9dbSNicholas Bellinger static DEFINE_MUTEX(subsystem_mutex); 47c66ac9dbSNicholas Bellinger 48e3d6f909SAndy Grover static u32 hba_id_counter; 49e3d6f909SAndy Grover 50e3d6f909SAndy Grover static DEFINE_SPINLOCK(hba_lock); 51e3d6f909SAndy Grover static LIST_HEAD(hba_list); 52e3d6f909SAndy Grover 53c66ac9dbSNicholas Bellinger int transport_subsystem_register(struct se_subsystem_api *sub_api) 54c66ac9dbSNicholas Bellinger { 55c66ac9dbSNicholas Bellinger struct se_subsystem_api *s; 56c66ac9dbSNicholas Bellinger 57c66ac9dbSNicholas Bellinger INIT_LIST_HEAD(&sub_api->sub_api_list); 58c66ac9dbSNicholas Bellinger 59c66ac9dbSNicholas Bellinger mutex_lock(&subsystem_mutex); 60c66ac9dbSNicholas Bellinger list_for_each_entry(s, &subsystem_list, sub_api_list) { 616708bb27SAndy Grover if (!strcmp(s->name, sub_api->name)) { 626708bb27SAndy Grover pr_err("%p is already registered with" 63c66ac9dbSNicholas Bellinger " duplicate name %s, unable to process" 64c66ac9dbSNicholas Bellinger " request\n", s, s->name); 65c66ac9dbSNicholas Bellinger mutex_unlock(&subsystem_mutex); 66c66ac9dbSNicholas Bellinger return -EEXIST; 67c66ac9dbSNicholas Bellinger } 68c66ac9dbSNicholas Bellinger } 69c66ac9dbSNicholas Bellinger list_add_tail(&sub_api->sub_api_list, &subsystem_list); 70c66ac9dbSNicholas Bellinger mutex_unlock(&subsystem_mutex); 71c66ac9dbSNicholas Bellinger 726708bb27SAndy Grover pr_debug("TCM: Registered subsystem plugin: %s struct module:" 73c66ac9dbSNicholas Bellinger " %p\n", sub_api->name, sub_api->owner); 74c66ac9dbSNicholas Bellinger return 0; 75c66ac9dbSNicholas Bellinger } 76c66ac9dbSNicholas Bellinger EXPORT_SYMBOL(transport_subsystem_register); 77c66ac9dbSNicholas Bellinger 78c66ac9dbSNicholas Bellinger void transport_subsystem_release(struct se_subsystem_api *sub_api) 79c66ac9dbSNicholas Bellinger { 80c66ac9dbSNicholas Bellinger mutex_lock(&subsystem_mutex); 81c66ac9dbSNicholas Bellinger list_del(&sub_api->sub_api_list); 82c66ac9dbSNicholas Bellinger mutex_unlock(&subsystem_mutex); 83c66ac9dbSNicholas Bellinger } 84c66ac9dbSNicholas Bellinger EXPORT_SYMBOL(transport_subsystem_release); 85c66ac9dbSNicholas Bellinger 86c66ac9dbSNicholas Bellinger static struct se_subsystem_api *core_get_backend(const char *sub_name) 87c66ac9dbSNicholas Bellinger { 88c66ac9dbSNicholas Bellinger struct se_subsystem_api *s; 89c66ac9dbSNicholas Bellinger 90c66ac9dbSNicholas Bellinger mutex_lock(&subsystem_mutex); 91c66ac9dbSNicholas Bellinger list_for_each_entry(s, &subsystem_list, sub_api_list) { 92c66ac9dbSNicholas Bellinger if (!strcmp(s->name, sub_name)) 93c66ac9dbSNicholas Bellinger goto found; 94c66ac9dbSNicholas Bellinger } 95c66ac9dbSNicholas Bellinger mutex_unlock(&subsystem_mutex); 96c66ac9dbSNicholas Bellinger return NULL; 97c66ac9dbSNicholas Bellinger found: 98c66ac9dbSNicholas Bellinger if (s->owner && !try_module_get(s->owner)) 99c66ac9dbSNicholas Bellinger s = NULL; 100c66ac9dbSNicholas Bellinger mutex_unlock(&subsystem_mutex); 101c66ac9dbSNicholas Bellinger return s; 102c66ac9dbSNicholas Bellinger } 103c66ac9dbSNicholas Bellinger 104c66ac9dbSNicholas Bellinger struct se_hba * 105c66ac9dbSNicholas Bellinger core_alloc_hba(const char *plugin_name, u32 plugin_dep_id, u32 hba_flags) 106c66ac9dbSNicholas Bellinger { 107c66ac9dbSNicholas Bellinger struct se_hba *hba; 108c66ac9dbSNicholas Bellinger int ret = 0; 109c66ac9dbSNicholas Bellinger 110c66ac9dbSNicholas Bellinger hba = kzalloc(sizeof(*hba), GFP_KERNEL); 111c66ac9dbSNicholas Bellinger if (!hba) { 1126708bb27SAndy Grover pr_err("Unable to allocate struct se_hba\n"); 113c66ac9dbSNicholas Bellinger return ERR_PTR(-ENOMEM); 114c66ac9dbSNicholas Bellinger } 115c66ac9dbSNicholas Bellinger 116c66ac9dbSNicholas Bellinger INIT_LIST_HEAD(&hba->hba_dev_list); 117c66ac9dbSNicholas Bellinger spin_lock_init(&hba->device_lock); 118c66ac9dbSNicholas Bellinger mutex_init(&hba->hba_access_mutex); 119c66ac9dbSNicholas Bellinger 120c66ac9dbSNicholas Bellinger hba->hba_index = scsi_get_new_index(SCSI_INST_INDEX); 121c66ac9dbSNicholas Bellinger hba->hba_flags |= hba_flags; 122c66ac9dbSNicholas Bellinger 123c66ac9dbSNicholas Bellinger hba->transport = core_get_backend(plugin_name); 124c66ac9dbSNicholas Bellinger if (!hba->transport) { 125c66ac9dbSNicholas Bellinger ret = -EINVAL; 126c66ac9dbSNicholas Bellinger goto out_free_hba; 127c66ac9dbSNicholas Bellinger } 128c66ac9dbSNicholas Bellinger 129c66ac9dbSNicholas Bellinger ret = hba->transport->attach_hba(hba, plugin_dep_id); 130c66ac9dbSNicholas Bellinger if (ret < 0) 131c66ac9dbSNicholas Bellinger goto out_module_put; 132c66ac9dbSNicholas Bellinger 133e3d6f909SAndy Grover spin_lock(&hba_lock); 134e3d6f909SAndy Grover hba->hba_id = hba_id_counter++; 135e3d6f909SAndy Grover list_add_tail(&hba->hba_node, &hba_list); 136e3d6f909SAndy Grover spin_unlock(&hba_lock); 137c66ac9dbSNicholas Bellinger 1386708bb27SAndy Grover pr_debug("CORE_HBA[%d] - Attached HBA to Generic Target" 139c66ac9dbSNicholas Bellinger " Core\n", hba->hba_id); 140c66ac9dbSNicholas Bellinger 141c66ac9dbSNicholas Bellinger return hba; 142c66ac9dbSNicholas Bellinger 143c66ac9dbSNicholas Bellinger out_module_put: 144c66ac9dbSNicholas Bellinger if (hba->transport->owner) 145c66ac9dbSNicholas Bellinger module_put(hba->transport->owner); 146c66ac9dbSNicholas Bellinger hba->transport = NULL; 147c66ac9dbSNicholas Bellinger out_free_hba: 148c66ac9dbSNicholas Bellinger kfree(hba); 149c66ac9dbSNicholas Bellinger return ERR_PTR(ret); 150c66ac9dbSNicholas Bellinger } 151c66ac9dbSNicholas Bellinger 152c66ac9dbSNicholas Bellinger int 153c66ac9dbSNicholas Bellinger core_delete_hba(struct se_hba *hba) 154c66ac9dbSNicholas Bellinger { 15505aea6e7SFubo Chen if (!list_empty(&hba->hba_dev_list)) 15605aea6e7SFubo Chen dump_stack(); 157c66ac9dbSNicholas Bellinger 158c66ac9dbSNicholas Bellinger hba->transport->detach_hba(hba); 159c66ac9dbSNicholas Bellinger 160e3d6f909SAndy Grover spin_lock(&hba_lock); 161e3d6f909SAndy Grover list_del(&hba->hba_node); 162e3d6f909SAndy Grover spin_unlock(&hba_lock); 163c66ac9dbSNicholas Bellinger 1646708bb27SAndy Grover pr_debug("CORE_HBA[%d] - Detached HBA from Generic Target" 165c66ac9dbSNicholas Bellinger " Core\n", hba->hba_id); 166c66ac9dbSNicholas Bellinger 167c66ac9dbSNicholas Bellinger if (hba->transport->owner) 168c66ac9dbSNicholas Bellinger module_put(hba->transport->owner); 169c66ac9dbSNicholas Bellinger 170c66ac9dbSNicholas Bellinger hba->transport = NULL; 171c66ac9dbSNicholas Bellinger kfree(hba); 172c66ac9dbSNicholas Bellinger return 0; 173c66ac9dbSNicholas Bellinger } 174