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