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