Blame view

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

6708bb27b   Andy Grover   target: Follow up...
137
  	pr_debug("CORE_HBA[%d] - Attached HBA to Generic Target"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
  			" Core
  ", hba->hba_id);
  
  	return hba;
  
  out_module_put:
  	if (hba->transport->owner)
  		module_put(hba->transport->owner);
  	hba->transport = NULL;
  out_free_hba:
  	kfree(hba);
  	return ERR_PTR(ret);
  }
  
  int
  core_delete_hba(struct se_hba *hba)
  {
05aea6e7e   Fubo Chen   [SCSI] target: Re...
155
156
  	if (!list_empty(&hba->hba_dev_list))
  		dump_stack();
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
157
158
  
  	hba->transport->detach_hba(hba);
e3d6f909e   Andy Grover   target: Core clea...
159
160
161
  	spin_lock(&hba_lock);
  	list_del(&hba->hba_node);
  	spin_unlock(&hba_lock);
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
162

6708bb27b   Andy Grover   target: Follow up...
163
  	pr_debug("CORE_HBA[%d] - Detached HBA from Generic Target"
c66ac9db8   Nicholas Bellinger   [SCSI] target: Ad...
164
165
166
167
168
169
170
171
172
173
  			" Core
  ", hba->hba_id);
  
  	if (hba->transport->owner)
  		module_put(hba->transport->owner);
  
  	hba->transport = NULL;
  	kfree(hba);
  	return 0;
  }