aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/iscsi
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2011-07-23 02:43:04 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2011-07-26 05:16:43 -0400
commite48354ce078c079996f89d715dfa44814b4eba01 (patch)
tree7a593b6dd4864073944160fe227aae5d54e587ab /drivers/target/iscsi
parent8304bbceee505742925b487fd8ea56e1f8b4b805 (diff)
iscsi-target: Add iSCSI fabric support for target v4.1
The Linux-iSCSI.org target module is a full featured in-kernel software implementation of iSCSI target mode (RFC-3720) for the current WIP mainline target v4.1 infrastructure code for the v3.1 kernel. More information can be found here: http://linux-iscsi.org/wiki/ISCSI This includes support for: * RFC-3720 defined request / response state machines and support for all defined iSCSI operation codes from Section 10.2.1.2 using libiscsi include/scsi/iscsi_proto.h PDU definitions * Target v4.1 compatible control plane using the generic layout in target_core_fabric_configfs.c and fabric dependent attributes within /sys/kernel/config/target/iscsi/ subdirectories. * Target v4.1 compatible iSCSI statistics based on RFC-4544 (iSCSI MIBS) * Support for IPv6 and IPv4 network portals in M:N mapping to TPGs * iSCSI Error Recovery Hierarchy support * Per iSCSI connection RX/TX thread pair scheduling affinity * crc32c + crc32c_intel SSEv4 instruction offload support using libcrypto * CHAP Authentication support using libcrypto * Conversion to use internal SGl allocation with iscsit_alloc_buffs() -> transport_generic_map_mem_to_cmd() (nab: Fix iscsi_proto.h struct scsi_lun usage from linux-next in commit: iscsi: Use struct scsi_lun in iscsi structs instead of u8[8]) (nab: Fix 32-bit compile warnings) Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Andy Grover <agrover@redhat.com> Acked-by: Roland Dreier <roland@kernel.org> Signed-off-by: Nicholas A. Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/iscsi')
-rw-r--r--drivers/target/iscsi/Kconfig8
-rw-r--r--drivers/target/iscsi/Makefile20
-rw-r--r--drivers/target/iscsi/iscsi_target.c4559
-rw-r--r--drivers/target/iscsi/iscsi_target.h42
-rw-r--r--drivers/target/iscsi/iscsi_target_auth.c490
-rw-r--r--drivers/target/iscsi/iscsi_target_auth.h31
-rw-r--r--drivers/target/iscsi/iscsi_target_configfs.c1882
-rw-r--r--drivers/target/iscsi/iscsi_target_configfs.h7
-rw-r--r--drivers/target/iscsi/iscsi_target_core.h859
-rw-r--r--drivers/target/iscsi/iscsi_target_datain_values.c531
-rw-r--r--drivers/target/iscsi/iscsi_target_datain_values.h12
-rw-r--r--drivers/target/iscsi/iscsi_target_device.c87
-rw-r--r--drivers/target/iscsi/iscsi_target_device.h9
-rw-r--r--drivers/target/iscsi/iscsi_target_erl0.c1004
-rw-r--r--drivers/target/iscsi/iscsi_target_erl0.h15
-rw-r--r--drivers/target/iscsi/iscsi_target_erl1.c1299
-rw-r--r--drivers/target/iscsi/iscsi_target_erl1.h26
-rw-r--r--drivers/target/iscsi/iscsi_target_erl2.c474
-rw-r--r--drivers/target/iscsi/iscsi_target_erl2.h18
-rw-r--r--drivers/target/iscsi/iscsi_target_login.c1232
-rw-r--r--drivers/target/iscsi/iscsi_target_login.h12
-rw-r--r--drivers/target/iscsi/iscsi_target_nego.c1067
-rw-r--r--drivers/target/iscsi/iscsi_target_nego.h17
-rw-r--r--drivers/target/iscsi/iscsi_target_nodeattrib.c263
-rw-r--r--drivers/target/iscsi/iscsi_target_nodeattrib.h14
-rw-r--r--drivers/target/iscsi/iscsi_target_parameters.c1905
-rw-r--r--drivers/target/iscsi/iscsi_target_parameters.h269
-rw-r--r--drivers/target/iscsi/iscsi_target_seq_pdu_list.c664
-rw-r--r--drivers/target/iscsi/iscsi_target_seq_pdu_list.h86
-rw-r--r--drivers/target/iscsi/iscsi_target_stat.c950
-rw-r--r--drivers/target/iscsi/iscsi_target_stat.h64
-rw-r--r--drivers/target/iscsi/iscsi_target_tmr.c849
-rw-r--r--drivers/target/iscsi/iscsi_target_tmr.h14
-rw-r--r--drivers/target/iscsi/iscsi_target_tpg.c759
-rw-r--r--drivers/target/iscsi/iscsi_target_tpg.h41
-rw-r--r--drivers/target/iscsi/iscsi_target_tq.c551
-rw-r--r--drivers/target/iscsi/iscsi_target_tq.h88
-rw-r--r--drivers/target/iscsi/iscsi_target_util.c1819
-rw-r--r--drivers/target/iscsi/iscsi_target_util.h60
39 files changed, 22097 insertions, 0 deletions
diff --git a/drivers/target/iscsi/Kconfig b/drivers/target/iscsi/Kconfig
new file mode 100644
index 000000000000..564ff4e0dbc4
--- /dev/null
+++ b/drivers/target/iscsi/Kconfig
@@ -0,0 +1,8 @@
1config ISCSI_TARGET
2 tristate "Linux-iSCSI.org iSCSI Target Mode Stack"
3 select CRYPTO
4 select CRYPTO_CRC32C
5 select CRYPTO_CRC32C_INTEL if X86
6 help
7 Say M here to enable the ConfigFS enabled Linux-iSCSI.org iSCSI
8 Target Mode Stack.
diff --git a/drivers/target/iscsi/Makefile b/drivers/target/iscsi/Makefile
new file mode 100644
index 000000000000..5b9a2cf7f0a9
--- /dev/null
+++ b/drivers/target/iscsi/Makefile
@@ -0,0 +1,20 @@
1iscsi_target_mod-y += iscsi_target_parameters.o \
2 iscsi_target_seq_pdu_list.o \
3 iscsi_target_tq.o \
4 iscsi_target_auth.o \
5 iscsi_target_datain_values.o \
6 iscsi_target_device.o \
7 iscsi_target_erl0.o \
8 iscsi_target_erl1.o \
9 iscsi_target_erl2.o \
10 iscsi_target_login.o \
11 iscsi_target_nego.o \
12 iscsi_target_nodeattrib.o \
13 iscsi_target_tmr.o \
14 iscsi_target_tpg.o \
15 iscsi_target_util.o \
16 iscsi_target.o \
17 iscsi_target_configfs.o \
18 iscsi_target_stat.o
19
20obj-$(CONFIG_ISCSI_TARGET) += iscsi_target_mod.o
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
new file mode 100644
index 000000000000..14c81c4265bd
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -0,0 +1,4559 @@
1/*******************************************************************************
2 * This file contains main functions related to the iSCSI Target Core Driver.
3 *
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5 *
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7 *
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.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
21#include <linux/string.h>
22#include <linux/kthread.h>
23#include <linux/crypto.h>
24#include <linux/completion.h>
25#include <asm/unaligned.h>
26#include <scsi/scsi_device.h>
27#include <scsi/iscsi_proto.h>
28#include <target/target_core_base.h>
29#include <target/target_core_tmr.h>
30#include <target/target_core_transport.h>
31
32#include "iscsi_target_core.h"
33#include "iscsi_target_parameters.h"
34#include "iscsi_target_seq_pdu_list.h"
35#include "iscsi_target_tq.h"
36#include "iscsi_target_configfs.h"
37#include "iscsi_target_datain_values.h"
38#include "iscsi_target_erl0.h"
39#include "iscsi_target_erl1.h"
40#include "iscsi_target_erl2.h"
41#include "iscsi_target_login.h"
42#include "iscsi_target_tmr.h"
43#include "iscsi_target_tpg.h"
44#include "iscsi_target_util.h"
45#include "iscsi_target.h"
46#include "iscsi_target_device.h"
47#include "iscsi_target_stat.h"
48
49static LIST_HEAD(g_tiqn_list);
50static LIST_HEAD(g_np_list);
51static DEFINE_SPINLOCK(tiqn_lock);
52static DEFINE_SPINLOCK(np_lock);
53
54static struct idr tiqn_idr;
55struct idr sess_idr;
56struct mutex auth_id_lock;
57spinlock_t sess_idr_lock;
58
59struct iscsit_global *iscsit_global;
60
61struct kmem_cache *lio_cmd_cache;
62struct kmem_cache *lio_qr_cache;
63struct kmem_cache *lio_dr_cache;
64struct kmem_cache *lio_ooo_cache;
65struct kmem_cache *lio_r2t_cache;
66
67static int iscsit_handle_immediate_data(struct iscsi_cmd *,
68 unsigned char *buf, u32);
69static int iscsit_logout_post_handler(struct iscsi_cmd *, struct iscsi_conn *);
70
71struct iscsi_tiqn *iscsit_get_tiqn_for_login(unsigned char *buf)
72{
73 struct iscsi_tiqn *tiqn = NULL;
74
75 spin_lock(&tiqn_lock);
76 list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) {
77 if (!strcmp(tiqn->tiqn, buf)) {
78
79 spin_lock(&tiqn->tiqn_state_lock);
80 if (tiqn->tiqn_state == TIQN_STATE_ACTIVE) {
81 tiqn->tiqn_access_count++;
82 spin_unlock(&tiqn->tiqn_state_lock);
83 spin_unlock(&tiqn_lock);
84 return tiqn;
85 }
86 spin_unlock(&tiqn->tiqn_state_lock);
87 }
88 }
89 spin_unlock(&tiqn_lock);
90
91 return NULL;
92}
93
94static int iscsit_set_tiqn_shutdown(struct iscsi_tiqn *tiqn)
95{
96 spin_lock(&tiqn->tiqn_state_lock);
97 if (tiqn->tiqn_state == TIQN_STATE_ACTIVE) {
98 tiqn->tiqn_state = TIQN_STATE_SHUTDOWN;
99 spin_unlock(&tiqn->tiqn_state_lock);
100 return 0;
101 }
102 spin_unlock(&tiqn->tiqn_state_lock);
103
104 return -1;
105}
106
107void iscsit_put_tiqn_for_login(struct iscsi_tiqn *tiqn)
108{
109 spin_lock(&tiqn->tiqn_state_lock);
110 tiqn->tiqn_access_count--;
111 spin_unlock(&tiqn->tiqn_state_lock);
112}
113
114/*
115 * Note that IQN formatting is expected to be done in userspace, and
116 * no explict IQN format checks are done here.
117 */
118struct iscsi_tiqn *iscsit_add_tiqn(unsigned char *buf)
119{
120 struct iscsi_tiqn *tiqn = NULL;
121 int ret;
122
123 if (strlen(buf) > ISCSI_IQN_LEN) {
124 pr_err("Target IQN exceeds %d bytes\n",
125 ISCSI_IQN_LEN);
126 return ERR_PTR(-EINVAL);
127 }
128
129 tiqn = kzalloc(sizeof(struct iscsi_tiqn), GFP_KERNEL);
130 if (!tiqn) {
131 pr_err("Unable to allocate struct iscsi_tiqn\n");
132 return ERR_PTR(-ENOMEM);
133 }
134
135 sprintf(tiqn->tiqn, "%s", buf);
136 INIT_LIST_HEAD(&tiqn->tiqn_list);
137 INIT_LIST_HEAD(&tiqn->tiqn_tpg_list);
138 spin_lock_init(&tiqn->tiqn_state_lock);
139 spin_lock_init(&tiqn->tiqn_tpg_lock);
140 spin_lock_init(&tiqn->sess_err_stats.lock);
141 spin_lock_init(&tiqn->login_stats.lock);
142 spin_lock_init(&tiqn->logout_stats.lock);
143
144 if (!idr_pre_get(&tiqn_idr, GFP_KERNEL)) {
145 pr_err("idr_pre_get() for tiqn_idr failed\n");
146 kfree(tiqn);
147 return ERR_PTR(-ENOMEM);
148 }
149 tiqn->tiqn_state = TIQN_STATE_ACTIVE;
150
151 spin_lock(&tiqn_lock);
152 ret = idr_get_new(&tiqn_idr, NULL, &tiqn->tiqn_index);
153 if (ret < 0) {
154 pr_err("idr_get_new() failed for tiqn->tiqn_index\n");
155 spin_unlock(&tiqn_lock);
156 kfree(tiqn);
157 return ERR_PTR(ret);
158 }
159 list_add_tail(&tiqn->tiqn_list, &g_tiqn_list);
160 spin_unlock(&tiqn_lock);
161
162 pr_debug("CORE[0] - Added iSCSI Target IQN: %s\n", tiqn->tiqn);
163
164 return tiqn;
165
166}
167
168static void iscsit_wait_for_tiqn(struct iscsi_tiqn *tiqn)
169{
170 /*
171 * Wait for accesses to said struct iscsi_tiqn to end.
172 */
173 spin_lock(&tiqn->tiqn_state_lock);
174 while (tiqn->tiqn_access_count != 0) {
175 spin_unlock(&tiqn->tiqn_state_lock);
176 msleep(10);
177 spin_lock(&tiqn->tiqn_state_lock);
178 }
179 spin_unlock(&tiqn->tiqn_state_lock);
180}
181
182void iscsit_del_tiqn(struct iscsi_tiqn *tiqn)
183{
184 /*
185 * iscsit_set_tiqn_shutdown sets tiqn->tiqn_state = TIQN_STATE_SHUTDOWN
186 * while holding tiqn->tiqn_state_lock. This means that all subsequent
187 * attempts to access this struct iscsi_tiqn will fail from both transport
188 * fabric and control code paths.
189 */
190 if (iscsit_set_tiqn_shutdown(tiqn) < 0) {
191 pr_err("iscsit_set_tiqn_shutdown() failed\n");
192 return;
193 }
194
195 iscsit_wait_for_tiqn(tiqn);
196
197 spin_lock(&tiqn_lock);
198 list_del(&tiqn->tiqn_list);
199 idr_remove(&tiqn_idr, tiqn->tiqn_index);
200 spin_unlock(&tiqn_lock);
201
202 pr_debug("CORE[0] - Deleted iSCSI Target IQN: %s\n",
203 tiqn->tiqn);
204 kfree(tiqn);
205}
206
207int iscsit_access_np(struct iscsi_np *np, struct iscsi_portal_group *tpg)
208{
209 int ret;
210 /*
211 * Determine if the network portal is accepting storage traffic.
212 */
213 spin_lock_bh(&np->np_thread_lock);
214 if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
215 spin_unlock_bh(&np->np_thread_lock);
216 return -1;
217 }
218 if (np->np_login_tpg) {
219 pr_err("np->np_login_tpg() is not NULL!\n");
220 spin_unlock_bh(&np->np_thread_lock);
221 return -1;
222 }
223 spin_unlock_bh(&np->np_thread_lock);
224 /*
225 * Determine if the portal group is accepting storage traffic.
226 */
227 spin_lock_bh(&tpg->tpg_state_lock);
228 if (tpg->tpg_state != TPG_STATE_ACTIVE) {
229 spin_unlock_bh(&tpg->tpg_state_lock);
230 return -1;
231 }
232 spin_unlock_bh(&tpg->tpg_state_lock);
233
234 /*
235 * Here we serialize access across the TIQN+TPG Tuple.
236 */
237 ret = mutex_lock_interruptible(&tpg->np_login_lock);
238 if ((ret != 0) || signal_pending(current))
239 return -1;
240
241 spin_lock_bh(&np->np_thread_lock);
242 np->np_login_tpg = tpg;
243 spin_unlock_bh(&np->np_thread_lock);
244
245 return 0;
246}
247
248int iscsit_deaccess_np(struct iscsi_np *np, struct iscsi_portal_group *tpg)
249{
250 struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
251
252 spin_lock_bh(&np->np_thread_lock);
253 np->np_login_tpg = NULL;
254 spin_unlock_bh(&np->np_thread_lock);
255
256 mutex_unlock(&tpg->np_login_lock);
257
258 if (tiqn)
259 iscsit_put_tiqn_for_login(tiqn);
260
261 return 0;
262}
263
264static struct iscsi_np *iscsit_get_np(
265 struct __kernel_sockaddr_storage *sockaddr,
266 int network_transport)
267{
268 struct sockaddr_in *sock_in, *sock_in_e;
269 struct sockaddr_in6 *sock_in6, *sock_in6_e;
270 struct iscsi_np *np;
271 int ip_match = 0;
272 u16 port;
273
274 spin_lock_bh(&np_lock);
275 list_for_each_entry(np, &g_np_list, np_list) {
276 spin_lock(&np->np_thread_lock);
277 if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
278 spin_unlock(&np->np_thread_lock);
279 continue;
280 }
281
282 if (sockaddr->ss_family == AF_INET6) {
283 sock_in6 = (struct sockaddr_in6 *)sockaddr;
284 sock_in6_e = (struct sockaddr_in6 *)&np->np_sockaddr;
285
286 if (!memcmp((void *)&sock_in6->sin6_addr.in6_u,
287 (void *)&sock_in6_e->sin6_addr.in6_u,
288 sizeof(struct in6_addr)))
289 ip_match = 1;
290
291 port = ntohs(sock_in6->sin6_port);
292 } else {
293 sock_in = (struct sockaddr_in *)sockaddr;
294 sock_in_e = (struct sockaddr_in *)&np->np_sockaddr;
295
296 if (sock_in->sin_addr.s_addr ==
297 sock_in_e->sin_addr.s_addr)
298 ip_match = 1;
299
300 port = ntohs(sock_in->sin_port);
301 }
302
303 if ((ip_match == 1) && (np->np_port == port) &&
304 (np->np_network_transport == network_transport)) {
305 /*
306 * Increment the np_exports reference count now to
307 * prevent iscsit_del_np() below from being called
308 * while iscsi_tpg_add_network_portal() is called.
309 */
310 np->np_exports++;
311 spin_unlock(&np->np_thread_lock);
312 spin_unlock_bh(&np_lock);
313 return np;
314 }
315 spin_unlock(&np->np_thread_lock);
316 }
317 spin_unlock_bh(&np_lock);
318
319 return NULL;
320}
321
322struct iscsi_np *iscsit_add_np(
323 struct __kernel_sockaddr_storage *sockaddr,
324 char *ip_str,
325 int network_transport)
326{
327 struct sockaddr_in *sock_in;
328 struct sockaddr_in6 *sock_in6;
329 struct iscsi_np *np;
330 int ret;
331 /*
332 * Locate the existing struct iscsi_np if already active..
333 */
334 np = iscsit_get_np(sockaddr, network_transport);
335 if (np)
336 return np;
337
338 np = kzalloc(sizeof(struct iscsi_np), GFP_KERNEL);
339 if (!np) {
340 pr_err("Unable to allocate memory for struct iscsi_np\n");
341 return ERR_PTR(-ENOMEM);
342 }
343
344 np->np_flags |= NPF_IP_NETWORK;
345 if (sockaddr->ss_family == AF_INET6) {
346 sock_in6 = (struct sockaddr_in6 *)sockaddr;
347 snprintf(np->np_ip, IPV6_ADDRESS_SPACE, "%s", ip_str);
348 np->np_port = ntohs(sock_in6->sin6_port);
349 } else {
350 sock_in = (struct sockaddr_in *)sockaddr;
351 sprintf(np->np_ip, "%s", ip_str);
352 np->np_port = ntohs(sock_in->sin_port);
353 }
354
355 np->np_network_transport = network_transport;
356 spin_lock_init(&np->np_thread_lock);
357 init_completion(&np->np_restart_comp);
358 INIT_LIST_HEAD(&np->np_list);
359
360 ret = iscsi_target_setup_login_socket(np, sockaddr);
361 if (ret != 0) {
362 kfree(np);
363 return ERR_PTR(ret);
364 }
365
366 np->np_thread = kthread_run(iscsi_target_login_thread, np, "iscsi_np");
367 if (IS_ERR(np->np_thread)) {
368 pr_err("Unable to create kthread: iscsi_np\n");
369 ret = PTR_ERR(np->np_thread);
370 kfree(np);
371 return ERR_PTR(ret);
372 }
373 /*
374 * Increment the np_exports reference count now to prevent
375 * iscsit_del_np() below from being run while a new call to
376 * iscsi_tpg_add_network_portal() for a matching iscsi_np is
377 * active. We don't need to hold np->np_thread_lock at this
378 * point because iscsi_np has not been added to g_np_list yet.
379 */
380 np->np_exports = 1;
381
382 spin_lock_bh(&np_lock);
383 list_add_tail(&np->np_list, &g_np_list);
384 spin_unlock_bh(&np_lock);
385
386 pr_debug("CORE[0] - Added Network Portal: %s:%hu on %s\n",
387 np->np_ip, np->np_port, (np->np_network_transport == ISCSI_TCP) ?
388 "TCP" : "SCTP");
389
390 return np;
391}
392
393int iscsit_reset_np_thread(
394 struct iscsi_np *np,
395 struct iscsi_tpg_np *tpg_np,
396 struct iscsi_portal_group *tpg)
397{
398 spin_lock_bh(&np->np_thread_lock);
399 if (tpg && tpg_np) {
400 /*
401 * The reset operation need only be performed when the
402 * passed struct iscsi_portal_group has a login in progress
403 * to one of the network portals.
404 */
405 if (tpg_np->tpg_np->np_login_tpg != tpg) {
406 spin_unlock_bh(&np->np_thread_lock);
407 return 0;
408 }
409 }
410 if (np->np_thread_state == ISCSI_NP_THREAD_INACTIVE) {
411 spin_unlock_bh(&np->np_thread_lock);
412 return 0;
413 }
414 np->np_thread_state = ISCSI_NP_THREAD_RESET;
415
416 if (np->np_thread) {
417 spin_unlock_bh(&np->np_thread_lock);
418 send_sig(SIGINT, np->np_thread, 1);
419 wait_for_completion(&np->np_restart_comp);
420 spin_lock_bh(&np->np_thread_lock);
421 }
422 spin_unlock_bh(&np->np_thread_lock);
423
424 return 0;
425}
426
427int iscsit_del_np_comm(struct iscsi_np *np)
428{
429 if (!np->np_socket)
430 return 0;
431
432 /*
433 * Some network transports allocate their own struct sock->file,
434 * see if we need to free any additional allocated resources.
435 */
436 if (np->np_flags & NPF_SCTP_STRUCT_FILE) {
437 kfree(np->np_socket->file);
438 np->np_socket->file = NULL;
439 }
440
441 sock_release(np->np_socket);
442 return 0;
443}
444
445int iscsit_del_np(struct iscsi_np *np)
446{
447 spin_lock_bh(&np->np_thread_lock);
448 np->np_exports--;
449 if (np->np_exports) {
450 spin_unlock_bh(&np->np_thread_lock);
451 return 0;
452 }
453 np->np_thread_state = ISCSI_NP_THREAD_SHUTDOWN;
454 spin_unlock_bh(&np->np_thread_lock);
455
456 if (np->np_thread) {
457 /*
458 * We need to send the signal to wakeup Linux/Net
459 * which may be sleeping in sock_accept()..
460 */
461 send_sig(SIGINT, np->np_thread, 1);
462 kthread_stop(np->np_thread);
463 }
464 iscsit_del_np_comm(np);
465
466 spin_lock_bh(&np_lock);
467 list_del(&np->np_list);
468 spin_unlock_bh(&np_lock);
469
470 pr_debug("CORE[0] - Removed Network Portal: %s:%hu on %s\n",
471 np->np_ip, np->np_port, (np->np_network_transport == ISCSI_TCP) ?
472 "TCP" : "SCTP");
473
474 kfree(np);
475 return 0;
476}
477
478static int __init iscsi_target_init_module(void)
479{
480 int ret = 0;
481
482 pr_debug("iSCSI-Target "ISCSIT_VERSION"\n");
483
484 iscsit_global = kzalloc(sizeof(struct iscsit_global), GFP_KERNEL);
485 if (!iscsit_global) {
486 pr_err("Unable to allocate memory for iscsit_global\n");
487 return -1;
488 }
489 mutex_init(&auth_id_lock);
490 spin_lock_init(&sess_idr_lock);
491 idr_init(&tiqn_idr);
492 idr_init(&sess_idr);
493
494 ret = iscsi_target_register_configfs();
495 if (ret < 0)
496 goto out;
497
498 ret = iscsi_thread_set_init();
499 if (ret < 0)
500 goto configfs_out;
501
502 if (iscsi_allocate_thread_sets(TARGET_THREAD_SET_COUNT) !=
503 TARGET_THREAD_SET_COUNT) {
504 pr_err("iscsi_allocate_thread_sets() returned"
505 " unexpected value!\n");
506 goto ts_out1;
507 }
508
509 lio_cmd_cache = kmem_cache_create("lio_cmd_cache",
510 sizeof(struct iscsi_cmd), __alignof__(struct iscsi_cmd),
511 0, NULL);
512 if (!lio_cmd_cache) {
513 pr_err("Unable to kmem_cache_create() for"
514 " lio_cmd_cache\n");
515 goto ts_out2;
516 }
517
518 lio_qr_cache = kmem_cache_create("lio_qr_cache",
519 sizeof(struct iscsi_queue_req),
520 __alignof__(struct iscsi_queue_req), 0, NULL);
521 if (!lio_qr_cache) {
522 pr_err("nable to kmem_cache_create() for"
523 " lio_qr_cache\n");
524 goto cmd_out;
525 }
526
527 lio_dr_cache = kmem_cache_create("lio_dr_cache",
528 sizeof(struct iscsi_datain_req),
529 __alignof__(struct iscsi_datain_req), 0, NULL);
530 if (!lio_dr_cache) {
531 pr_err("Unable to kmem_cache_create() for"
532 " lio_dr_cache\n");
533 goto qr_out;
534 }
535
536 lio_ooo_cache = kmem_cache_create("lio_ooo_cache",
537 sizeof(struct iscsi_ooo_cmdsn),
538 __alignof__(struct iscsi_ooo_cmdsn), 0, NULL);
539 if (!lio_ooo_cache) {
540 pr_err("Unable to kmem_cache_create() for"
541 " lio_ooo_cache\n");
542 goto dr_out;
543 }
544
545 lio_r2t_cache = kmem_cache_create("lio_r2t_cache",
546 sizeof(struct iscsi_r2t), __alignof__(struct iscsi_r2t),
547 0, NULL);
548 if (!lio_r2t_cache) {
549 pr_err("Unable to kmem_cache_create() for"
550 " lio_r2t_cache\n");
551 goto ooo_out;
552 }
553
554 if (iscsit_load_discovery_tpg() < 0)
555 goto r2t_out;
556
557 return ret;
558r2t_out:
559 kmem_cache_destroy(lio_r2t_cache);
560ooo_out:
561 kmem_cache_destroy(lio_ooo_cache);
562dr_out:
563 kmem_cache_destroy(lio_dr_cache);
564qr_out:
565 kmem_cache_destroy(lio_qr_cache);
566cmd_out:
567 kmem_cache_destroy(lio_cmd_cache);
568ts_out2:
569 iscsi_deallocate_thread_sets();
570ts_out1:
571 iscsi_thread_set_free();
572configfs_out:
573 iscsi_target_deregister_configfs();
574out:
575 kfree(iscsit_global);
576 return -ENOMEM;
577}
578
579static void __exit iscsi_target_cleanup_module(void)
580{
581 iscsi_deallocate_thread_sets();
582 iscsi_thread_set_free();
583 iscsit_release_discovery_tpg();
584 kmem_cache_destroy(lio_cmd_cache);
585 kmem_cache_destroy(lio_qr_cache);
586 kmem_cache_destroy(lio_dr_cache);
587 kmem_cache_destroy(lio_ooo_cache);
588 kmem_cache_destroy(lio_r2t_cache);
589
590 iscsi_target_deregister_configfs();
591
592 kfree(iscsit_global);
593}
594
595int iscsit_add_reject(
596 u8 reason,
597 int fail_conn,
598 unsigned char *buf,
599 struct iscsi_conn *conn)
600{
601 struct iscsi_cmd *cmd;
602 struct iscsi_reject *hdr;
603 int ret;
604
605 cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
606 if (!cmd)
607 return -1;
608
609 cmd->iscsi_opcode = ISCSI_OP_REJECT;
610 if (fail_conn)
611 cmd->cmd_flags |= ICF_REJECT_FAIL_CONN;
612
613 hdr = (struct iscsi_reject *) cmd->pdu;
614 hdr->reason = reason;
615
616 cmd->buf_ptr = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL);
617 if (!cmd->buf_ptr) {
618 pr_err("Unable to allocate memory for cmd->buf_ptr\n");
619 iscsit_release_cmd(cmd);
620 return -1;
621 }
622 memcpy(cmd->buf_ptr, buf, ISCSI_HDR_LEN);
623
624 spin_lock_bh(&conn->cmd_lock);
625 list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
626 spin_unlock_bh(&conn->cmd_lock);
627
628 cmd->i_state = ISTATE_SEND_REJECT;
629 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
630
631 ret = wait_for_completion_interruptible(&cmd->reject_comp);
632 if (ret != 0)
633 return -1;
634
635 return (!fail_conn) ? 0 : -1;
636}
637
638int iscsit_add_reject_from_cmd(
639 u8 reason,
640 int fail_conn,
641 int add_to_conn,
642 unsigned char *buf,
643 struct iscsi_cmd *cmd)
644{
645 struct iscsi_conn *conn;
646 struct iscsi_reject *hdr;
647 int ret;
648
649 if (!cmd->conn) {
650 pr_err("cmd->conn is NULL for ITT: 0x%08x\n",
651 cmd->init_task_tag);
652 return -1;
653 }
654 conn = cmd->conn;
655
656 cmd->iscsi_opcode = ISCSI_OP_REJECT;
657 if (fail_conn)
658 cmd->cmd_flags |= ICF_REJECT_FAIL_CONN;
659
660 hdr = (struct iscsi_reject *) cmd->pdu;
661 hdr->reason = reason;
662
663 cmd->buf_ptr = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL);
664 if (!cmd->buf_ptr) {
665 pr_err("Unable to allocate memory for cmd->buf_ptr\n");
666 iscsit_release_cmd(cmd);
667 return -1;
668 }
669 memcpy(cmd->buf_ptr, buf, ISCSI_HDR_LEN);
670
671 if (add_to_conn) {
672 spin_lock_bh(&conn->cmd_lock);
673 list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
674 spin_unlock_bh(&conn->cmd_lock);
675 }
676
677 cmd->i_state = ISTATE_SEND_REJECT;
678 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
679
680 ret = wait_for_completion_interruptible(&cmd->reject_comp);
681 if (ret != 0)
682 return -1;
683
684 return (!fail_conn) ? 0 : -1;
685}
686
687/*
688 * Map some portion of the allocated scatterlist to an iovec, suitable for
689 * kernel sockets to copy data in/out. This handles both pages and slab-allocated
690 * buffers, since we have been tricky and mapped t_mem_sg to the buffer in
691 * either case (see iscsit_alloc_buffs)
692 */
693static int iscsit_map_iovec(
694 struct iscsi_cmd *cmd,
695 struct kvec *iov,
696 u32 data_offset,
697 u32 data_length)
698{
699 u32 i = 0;
700 struct scatterlist *sg;
701 unsigned int page_off;
702
703 /*
704 * We have a private mapping of the allocated pages in t_mem_sg.
705 * At this point, we also know each contains a page.
706 */
707 sg = &cmd->t_mem_sg[data_offset / PAGE_SIZE];
708 page_off = (data_offset % PAGE_SIZE);
709
710 cmd->first_data_sg = sg;
711 cmd->first_data_sg_off = page_off;
712
713 while (data_length) {
714 u32 cur_len = min_t(u32, data_length, sg->length - page_off);
715
716 iov[i].iov_base = kmap(sg_page(sg)) + sg->offset + page_off;
717 iov[i].iov_len = cur_len;
718
719 data_length -= cur_len;
720 page_off = 0;
721 sg = sg_next(sg);
722 i++;
723 }
724
725 cmd->kmapped_nents = i;
726
727 return i;
728}
729
730static void iscsit_unmap_iovec(struct iscsi_cmd *cmd)
731{
732 u32 i;
733 struct scatterlist *sg;
734
735 sg = cmd->first_data_sg;
736
737 for (i = 0; i < cmd->kmapped_nents; i++)
738 kunmap(sg_page(&sg[i]));
739}
740
741static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn)
742{
743 struct iscsi_cmd *cmd;
744
745 conn->exp_statsn = exp_statsn;
746
747 spin_lock_bh(&conn->cmd_lock);
748 list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) {
749 spin_lock(&cmd->istate_lock);
750 if ((cmd->i_state == ISTATE_SENT_STATUS) &&
751 (cmd->stat_sn < exp_statsn)) {
752 cmd->i_state = ISTATE_REMOVE;
753 spin_unlock(&cmd->istate_lock);
754 iscsit_add_cmd_to_immediate_queue(cmd, conn,
755 cmd->i_state);
756 continue;
757 }
758 spin_unlock(&cmd->istate_lock);
759 }
760 spin_unlock_bh(&conn->cmd_lock);
761}
762
763static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd)
764{
765 u32 iov_count = (cmd->se_cmd.t_data_nents == 0) ? 1 :
766 cmd->se_cmd.t_data_nents;
767
768 iov_count += TRANSPORT_IOV_DATA_BUFFER;
769
770 cmd->iov_data = kzalloc(iov_count * sizeof(struct kvec), GFP_KERNEL);
771 if (!cmd->iov_data) {
772 pr_err("Unable to allocate cmd->iov_data\n");
773 return -ENOMEM;
774 }
775
776 cmd->orig_iov_data_count = iov_count;
777 return 0;
778}
779
780static int iscsit_alloc_buffs(struct iscsi_cmd *cmd)
781{
782 struct scatterlist *sgl;
783 u32 length = cmd->se_cmd.data_length;
784 int nents = DIV_ROUND_UP(length, PAGE_SIZE);
785 int i = 0, ret;
786 /*
787 * If no SCSI payload is present, allocate the default iovecs used for
788 * iSCSI PDU Header
789 */
790 if (!length)
791 return iscsit_allocate_iovecs(cmd);
792
793 sgl = kzalloc(sizeof(*sgl) * nents, GFP_KERNEL);
794 if (!sgl)
795 return -ENOMEM;
796
797 sg_init_table(sgl, nents);
798
799 while (length) {
800 int buf_size = min_t(int, length, PAGE_SIZE);
801 struct page *page;
802
803 page = alloc_page(GFP_KERNEL | __GFP_ZERO);
804 if (!page)
805 goto page_alloc_failed;
806
807 sg_set_page(&sgl[i], page, buf_size, 0);
808
809 length -= buf_size;
810 i++;
811 }
812
813 cmd->t_mem_sg = sgl;
814 cmd->t_mem_sg_nents = nents;
815
816 /* BIDI ops not supported */
817
818 /* Tell the core about our preallocated memory */
819 transport_generic_map_mem_to_cmd(&cmd->se_cmd, sgl, nents, NULL, 0);
820 /*
821 * Allocate iovecs for SCSI payload after transport_generic_map_mem_to_cmd
822 * so that cmd->se_cmd.t_tasks_se_num has been set.
823 */
824 ret = iscsit_allocate_iovecs(cmd);
825 if (ret < 0)
826 goto page_alloc_failed;
827
828 return 0;
829
830page_alloc_failed:
831 while (i >= 0) {
832 __free_page(sg_page(&sgl[i]));
833 i--;
834 }
835 kfree(cmd->t_mem_sg);
836 cmd->t_mem_sg = NULL;
837 return -ENOMEM;
838}
839
840static int iscsit_handle_scsi_cmd(
841 struct iscsi_conn *conn,
842 unsigned char *buf)
843{
844 int data_direction, cmdsn_ret = 0, immed_ret, ret, transport_ret;
845 int dump_immediate_data = 0, send_check_condition = 0, payload_length;
846 struct iscsi_cmd *cmd = NULL;
847 struct iscsi_scsi_req *hdr;
848
849 spin_lock_bh(&conn->sess->session_stats_lock);
850 conn->sess->cmd_pdus++;
851 if (conn->sess->se_sess->se_node_acl) {
852 spin_lock(&conn->sess->se_sess->se_node_acl->stats_lock);
853 conn->sess->se_sess->se_node_acl->num_cmds++;
854 spin_unlock(&conn->sess->se_sess->se_node_acl->stats_lock);
855 }
856 spin_unlock_bh(&conn->sess->session_stats_lock);
857
858 hdr = (struct iscsi_scsi_req *) buf;
859 payload_length = ntoh24(hdr->dlength);
860 hdr->itt = be32_to_cpu(hdr->itt);
861 hdr->data_length = be32_to_cpu(hdr->data_length);
862 hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
863 hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
864
865 /* FIXME; Add checks for AdditionalHeaderSegment */
866
867 if (!(hdr->flags & ISCSI_FLAG_CMD_WRITE) &&
868 !(hdr->flags & ISCSI_FLAG_CMD_FINAL)) {
869 pr_err("ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL"
870 " not set. Bad iSCSI Initiator.\n");
871 return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1,
872 buf, conn);
873 }
874
875 if (((hdr->flags & ISCSI_FLAG_CMD_READ) ||
876 (hdr->flags & ISCSI_FLAG_CMD_WRITE)) && !hdr->data_length) {
877 /*
878 * Vmware ESX v3.0 uses a modified Cisco Initiator (v3.4.2)
879 * that adds support for RESERVE/RELEASE. There is a bug
880 * add with this new functionality that sets R/W bits when
881 * neither CDB carries any READ or WRITE datapayloads.
882 */
883 if ((hdr->cdb[0] == 0x16) || (hdr->cdb[0] == 0x17)) {
884 hdr->flags &= ~ISCSI_FLAG_CMD_READ;
885 hdr->flags &= ~ISCSI_FLAG_CMD_WRITE;
886 goto done;
887 }
888
889 pr_err("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE"
890 " set when Expected Data Transfer Length is 0 for"
891 " CDB: 0x%02x. Bad iSCSI Initiator.\n", hdr->cdb[0]);
892 return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1,
893 buf, conn);
894 }
895done:
896
897 if (!(hdr->flags & ISCSI_FLAG_CMD_READ) &&
898 !(hdr->flags & ISCSI_FLAG_CMD_WRITE) && (hdr->data_length != 0)) {
899 pr_err("ISCSI_FLAG_CMD_READ and/or ISCSI_FLAG_CMD_WRITE"
900 " MUST be set if Expected Data Transfer Length is not 0."
901 " Bad iSCSI Initiator\n");
902 return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1,
903 buf, conn);
904 }
905
906 if ((hdr->flags & ISCSI_FLAG_CMD_READ) &&
907 (hdr->flags & ISCSI_FLAG_CMD_WRITE)) {
908 pr_err("Bidirectional operations not supported!\n");
909 return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1,
910 buf, conn);
911 }
912
913 if (hdr->opcode & ISCSI_OP_IMMEDIATE) {
914 pr_err("Illegally set Immediate Bit in iSCSI Initiator"
915 " Scsi Command PDU.\n");
916 return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1,
917 buf, conn);
918 }
919
920 if (payload_length && !conn->sess->sess_ops->ImmediateData) {
921 pr_err("ImmediateData=No but DataSegmentLength=%u,"
922 " protocol error.\n", payload_length);
923 return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
924 buf, conn);
925 }
926
927 if ((hdr->data_length == payload_length) &&
928 (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) {
929 pr_err("Expected Data Transfer Length and Length of"
930 " Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL"
931 " bit is not set protocol error\n");
932 return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
933 buf, conn);
934 }
935
936 if (payload_length > hdr->data_length) {
937 pr_err("DataSegmentLength: %u is greater than"
938 " EDTL: %u, protocol error.\n", payload_length,
939 hdr->data_length);
940 return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
941 buf, conn);
942 }
943
944 if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) {
945 pr_err("DataSegmentLength: %u is greater than"
946 " MaxRecvDataSegmentLength: %u, protocol error.\n",
947 payload_length, conn->conn_ops->MaxRecvDataSegmentLength);
948 return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
949 buf, conn);
950 }
951
952 if (payload_length > conn->sess->sess_ops->FirstBurstLength) {
953 pr_err("DataSegmentLength: %u is greater than"
954 " FirstBurstLength: %u, protocol error.\n",
955 payload_length, conn->sess->sess_ops->FirstBurstLength);
956 return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1,
957 buf, conn);
958 }
959
960 data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE :
961 (hdr->flags & ISCSI_FLAG_CMD_READ) ? DMA_FROM_DEVICE :
962 DMA_NONE;
963
964 cmd = iscsit_allocate_se_cmd(conn, hdr->data_length, data_direction,
965 (hdr->flags & ISCSI_FLAG_CMD_ATTR_MASK));
966 if (!cmd)
967 return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, 1,
968 buf, conn);
969
970 pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x,"
971 " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
972 hdr->cmdsn, hdr->data_length, payload_length, conn->cid);
973
974 cmd->iscsi_opcode = ISCSI_OP_SCSI_CMD;
975 cmd->i_state = ISTATE_NEW_CMD;
976 cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
977 cmd->immediate_data = (payload_length) ? 1 : 0;
978 cmd->unsolicited_data = ((!(hdr->flags & ISCSI_FLAG_CMD_FINAL) &&
979 (hdr->flags & ISCSI_FLAG_CMD_WRITE)) ? 1 : 0);
980 if (cmd->unsolicited_data)
981 cmd->cmd_flags |= ICF_NON_IMMEDIATE_UNSOLICITED_DATA;
982
983 conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
984 if (hdr->flags & ISCSI_FLAG_CMD_READ) {
985 spin_lock_bh(&conn->sess->ttt_lock);
986 cmd->targ_xfer_tag = conn->sess->targ_xfer_tag++;
987 if (cmd->targ_xfer_tag == 0xFFFFFFFF)
988 cmd->targ_xfer_tag = conn->sess->targ_xfer_tag++;
989 spin_unlock_bh(&conn->sess->ttt_lock);
990 } else if (hdr->flags & ISCSI_FLAG_CMD_WRITE)
991 cmd->targ_xfer_tag = 0xFFFFFFFF;
992 cmd->cmd_sn = hdr->cmdsn;
993 cmd->exp_stat_sn = hdr->exp_statsn;
994 cmd->first_burst_len = payload_length;
995
996 if (cmd->data_direction == DMA_FROM_DEVICE) {
997 struct iscsi_datain_req *dr;
998
999 dr = iscsit_allocate_datain_req();
1000 if (!dr)
1001 return iscsit_add_reject_from_cmd(
1002 ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1003 1, 1, buf, cmd);
1004
1005 iscsit_attach_datain_req(cmd, dr);
1006 }
1007
1008 /*
1009 * The CDB is going to an se_device_t.
1010 */
1011 ret = iscsit_get_lun_for_cmd(cmd, hdr->cdb,
1012 get_unaligned_le64(&hdr->lun));
1013 if (ret < 0) {
1014 if (cmd->se_cmd.scsi_sense_reason == TCM_NON_EXISTENT_LUN) {
1015 pr_debug("Responding to non-acl'ed,"
1016 " non-existent or non-exported iSCSI LUN:"
1017 " 0x%016Lx\n", get_unaligned_le64(&hdr->lun));
1018 }
1019 if (ret == PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES)
1020 return iscsit_add_reject_from_cmd(
1021 ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1022 1, 1, buf, cmd);
1023
1024 send_check_condition = 1;
1025 goto attach_cmd;
1026 }
1027 /*
1028 * The Initiator Node has access to the LUN (the addressing method
1029 * is handled inside of iscsit_get_lun_for_cmd()). Now it's time to
1030 * allocate 1->N transport tasks (depending on sector count and
1031 * maximum request size the physical HBA(s) can handle.
1032 */
1033 transport_ret = transport_generic_allocate_tasks(&cmd->se_cmd, hdr->cdb);
1034 if (transport_ret == -ENOMEM) {
1035 return iscsit_add_reject_from_cmd(
1036 ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1037 1, 1, buf, cmd);
1038 } else if (transport_ret == -EINVAL) {
1039 /*
1040 * Unsupported SAM Opcode. CHECK_CONDITION will be sent
1041 * in iscsit_execute_cmd() during the CmdSN OOO Execution
1042 * Mechinism.
1043 */
1044 send_check_condition = 1;
1045 } else {
1046 if (iscsit_decide_list_to_build(cmd, payload_length) < 0)
1047 return iscsit_add_reject_from_cmd(
1048 ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1049 1, 1, buf, cmd);
1050 }
1051
1052attach_cmd:
1053 spin_lock_bh(&conn->cmd_lock);
1054 list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
1055 spin_unlock_bh(&conn->cmd_lock);
1056 /*
1057 * Check if we need to delay processing because of ALUA
1058 * Active/NonOptimized primary access state..
1059 */
1060 core_alua_check_nonop_delay(&cmd->se_cmd);
1061 /*
1062 * Allocate and setup SGL used with transport_generic_map_mem_to_cmd().
1063 * also call iscsit_allocate_iovecs()
1064 */
1065 ret = iscsit_alloc_buffs(cmd);
1066 if (ret < 0)
1067 return iscsit_add_reject_from_cmd(
1068 ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1069 1, 1, buf, cmd);
1070 /*
1071 * Check the CmdSN against ExpCmdSN/MaxCmdSN here if
1072 * the Immediate Bit is not set, and no Immediate
1073 * Data is attached.
1074 *
1075 * A PDU/CmdSN carrying Immediate Data can only
1076 * be processed after the DataCRC has passed.
1077 * If the DataCRC fails, the CmdSN MUST NOT
1078 * be acknowledged. (See below)
1079 */
1080 if (!cmd->immediate_data) {
1081 cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
1082 if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
1083 return iscsit_add_reject_from_cmd(
1084 ISCSI_REASON_PROTOCOL_ERROR,
1085 1, 0, buf, cmd);
1086 }
1087
1088 iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
1089
1090 /*
1091 * If no Immediate Data is attached, it's OK to return now.
1092 */
1093 if (!cmd->immediate_data) {
1094 if (send_check_condition)
1095 return 0;
1096
1097 if (cmd->unsolicited_data) {
1098 iscsit_set_dataout_sequence_values(cmd);
1099
1100 spin_lock_bh(&cmd->dataout_timeout_lock);
1101 iscsit_start_dataout_timer(cmd, cmd->conn);
1102 spin_unlock_bh(&cmd->dataout_timeout_lock);
1103 }
1104
1105 return 0;
1106 }
1107
1108 /*
1109 * Early CHECK_CONDITIONs never make it to the transport processing
1110 * thread. They are processed in CmdSN order by
1111 * iscsit_check_received_cmdsn() below.
1112 */
1113 if (send_check_condition) {
1114 immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
1115 dump_immediate_data = 1;
1116 goto after_immediate_data;
1117 }
1118 /*
1119 * Call directly into transport_generic_new_cmd() to perform
1120 * the backend memory allocation.
1121 */
1122 ret = transport_generic_new_cmd(&cmd->se_cmd);
1123 if ((ret < 0) || (cmd->se_cmd.se_cmd_flags & SCF_SE_CMD_FAILED)) {
1124 immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
1125 dump_immediate_data = 1;
1126 goto after_immediate_data;
1127 }
1128
1129 immed_ret = iscsit_handle_immediate_data(cmd, buf, payload_length);
1130after_immediate_data:
1131 if (immed_ret == IMMEDIATE_DATA_NORMAL_OPERATION) {
1132 /*
1133 * A PDU/CmdSN carrying Immediate Data passed
1134 * DataCRC, check against ExpCmdSN/MaxCmdSN if
1135 * Immediate Bit is not set.
1136 */
1137 cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
1138 /*
1139 * Special case for Unsupported SAM WRITE Opcodes
1140 * and ImmediateData=Yes.
1141 */
1142 if (dump_immediate_data) {
1143 if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
1144 return -1;
1145 } else if (cmd->unsolicited_data) {
1146 iscsit_set_dataout_sequence_values(cmd);
1147
1148 spin_lock_bh(&cmd->dataout_timeout_lock);
1149 iscsit_start_dataout_timer(cmd, cmd->conn);
1150 spin_unlock_bh(&cmd->dataout_timeout_lock);
1151 }
1152
1153 if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
1154 return iscsit_add_reject_from_cmd(
1155 ISCSI_REASON_PROTOCOL_ERROR,
1156 1, 0, buf, cmd);
1157
1158 } else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) {
1159 /*
1160 * Immediate Data failed DataCRC and ERL>=1,
1161 * silently drop this PDU and let the initiator
1162 * plug the CmdSN gap.
1163 *
1164 * FIXME: Send Unsolicited NOPIN with reserved
1165 * TTT here to help the initiator figure out
1166 * the missing CmdSN, although they should be
1167 * intelligent enough to determine the missing
1168 * CmdSN and issue a retry to plug the sequence.
1169 */
1170 cmd->i_state = ISTATE_REMOVE;
1171 iscsit_add_cmd_to_immediate_queue(cmd, conn, cmd->i_state);
1172 } else /* immed_ret == IMMEDIATE_DATA_CANNOT_RECOVER */
1173 return -1;
1174
1175 return 0;
1176}
1177
1178static u32 iscsit_do_crypto_hash_sg(
1179 struct hash_desc *hash,
1180 struct iscsi_cmd *cmd,
1181 u32 data_offset,
1182 u32 data_length,
1183 u32 padding,
1184 u8 *pad_bytes)
1185{
1186 u32 data_crc;
1187 u32 i;
1188 struct scatterlist *sg;
1189 unsigned int page_off;
1190
1191 crypto_hash_init(hash);
1192
1193 sg = cmd->first_data_sg;
1194 page_off = cmd->first_data_sg_off;
1195
1196 i = 0;
1197 while (data_length) {
1198 u32 cur_len = min_t(u32, data_length, (sg[i].length - page_off));
1199
1200 crypto_hash_update(hash, &sg[i], cur_len);
1201
1202 data_length -= cur_len;
1203 page_off = 0;
1204 i++;
1205 }
1206
1207 if (padding) {
1208 struct scatterlist pad_sg;
1209
1210 sg_init_one(&pad_sg, pad_bytes, padding);
1211 crypto_hash_update(hash, &pad_sg, padding);
1212 }
1213 crypto_hash_final(hash, (u8 *) &data_crc);
1214
1215 return data_crc;
1216}
1217
1218static void iscsit_do_crypto_hash_buf(
1219 struct hash_desc *hash,
1220 unsigned char *buf,
1221 u32 payload_length,
1222 u32 padding,
1223 u8 *pad_bytes,
1224 u8 *data_crc)
1225{
1226 struct scatterlist sg;
1227
1228 crypto_hash_init(hash);
1229
1230 sg_init_one(&sg, (u8 *)buf, payload_length);
1231 crypto_hash_update(hash, &sg, payload_length);
1232
1233 if (padding) {
1234 sg_init_one(&sg, pad_bytes, padding);
1235 crypto_hash_update(hash, &sg, padding);
1236 }
1237 crypto_hash_final(hash, data_crc);
1238}
1239
1240static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
1241{
1242 int iov_ret, ooo_cmdsn = 0, ret;
1243 u8 data_crc_failed = 0;
1244 u32 checksum, iov_count = 0, padding = 0, rx_got = 0;
1245 u32 rx_size = 0, payload_length;
1246 struct iscsi_cmd *cmd = NULL;
1247 struct se_cmd *se_cmd;
1248 struct iscsi_data *hdr;
1249 struct kvec *iov;
1250 unsigned long flags;
1251
1252 hdr = (struct iscsi_data *) buf;
1253 payload_length = ntoh24(hdr->dlength);
1254 hdr->itt = be32_to_cpu(hdr->itt);
1255 hdr->ttt = be32_to_cpu(hdr->ttt);
1256 hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
1257 hdr->datasn = be32_to_cpu(hdr->datasn);
1258 hdr->offset = be32_to_cpu(hdr->offset);
1259
1260 if (!payload_length) {
1261 pr_err("DataOUT payload is ZERO, protocol error.\n");
1262 return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
1263 buf, conn);
1264 }
1265
1266 /* iSCSI write */
1267 spin_lock_bh(&conn->sess->session_stats_lock);
1268 conn->sess->rx_data_octets += payload_length;
1269 if (conn->sess->se_sess->se_node_acl) {
1270 spin_lock(&conn->sess->se_sess->se_node_acl->stats_lock);
1271 conn->sess->se_sess->se_node_acl->write_bytes += payload_length;
1272 spin_unlock(&conn->sess->se_sess->se_node_acl->stats_lock);
1273 }
1274 spin_unlock_bh(&conn->sess->session_stats_lock);
1275
1276 if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) {
1277 pr_err("DataSegmentLength: %u is greater than"
1278 " MaxRecvDataSegmentLength: %u\n", payload_length,
1279 conn->conn_ops->MaxRecvDataSegmentLength);
1280 return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
1281 buf, conn);
1282 }
1283
1284 cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt,
1285 payload_length);
1286 if (!cmd)
1287 return 0;
1288
1289 pr_debug("Got DataOut ITT: 0x%08x, TTT: 0x%08x,"
1290 " DataSN: 0x%08x, Offset: %u, Length: %u, CID: %hu\n",
1291 hdr->itt, hdr->ttt, hdr->datasn, hdr->offset,
1292 payload_length, conn->cid);
1293
1294 if (cmd->cmd_flags & ICF_GOT_LAST_DATAOUT) {
1295 pr_err("Command ITT: 0x%08x received DataOUT after"
1296 " last DataOUT received, dumping payload\n",
1297 cmd->init_task_tag);
1298 return iscsit_dump_data_payload(conn, payload_length, 1);
1299 }
1300
1301 if (cmd->data_direction != DMA_TO_DEVICE) {
1302 pr_err("Command ITT: 0x%08x received DataOUT for a"
1303 " NON-WRITE command.\n", cmd->init_task_tag);
1304 return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR,
1305 1, 0, buf, cmd);
1306 }
1307 se_cmd = &cmd->se_cmd;
1308 iscsit_mod_dataout_timer(cmd);
1309
1310 if ((hdr->offset + payload_length) > cmd->data_length) {
1311 pr_err("DataOut Offset: %u, Length %u greater than"
1312 " iSCSI Command EDTL %u, protocol error.\n",
1313 hdr->offset, payload_length, cmd->data_length);
1314 return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
1315 1, 0, buf, cmd);
1316 }
1317
1318 if (cmd->unsolicited_data) {
1319 int dump_unsolicited_data = 0;
1320
1321 if (conn->sess->sess_ops->InitialR2T) {
1322 pr_err("Received unexpected unsolicited data"
1323 " while InitialR2T=Yes, protocol error.\n");
1324 transport_send_check_condition_and_sense(&cmd->se_cmd,
1325 TCM_UNEXPECTED_UNSOLICITED_DATA, 0);
1326 return -1;
1327 }
1328 /*
1329 * Special case for dealing with Unsolicited DataOUT
1330 * and Unsupported SAM WRITE Opcodes and SE resource allocation
1331 * failures;
1332 */
1333
1334 /* Something's amiss if we're not in WRITE_PENDING state... */
1335 spin_lock_irqsave(&se_cmd->t_state_lock, flags);
1336 WARN_ON(se_cmd->t_state != TRANSPORT_WRITE_PENDING);
1337 spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
1338
1339 spin_lock_irqsave(&se_cmd->t_state_lock, flags);
1340 if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) ||
1341 (se_cmd->se_cmd_flags & SCF_SE_CMD_FAILED))
1342 dump_unsolicited_data = 1;
1343 spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
1344
1345 if (dump_unsolicited_data) {
1346 /*
1347 * Check if a delayed TASK_ABORTED status needs to
1348 * be sent now if the ISCSI_FLAG_CMD_FINAL has been
1349 * received with the unsolicitied data out.
1350 */
1351 if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
1352 iscsit_stop_dataout_timer(cmd);
1353
1354 transport_check_aborted_status(se_cmd,
1355 (hdr->flags & ISCSI_FLAG_CMD_FINAL));
1356 return iscsit_dump_data_payload(conn, payload_length, 1);
1357 }
1358 } else {
1359 /*
1360 * For the normal solicited data path:
1361 *
1362 * Check for a delayed TASK_ABORTED status and dump any
1363 * incoming data out payload if one exists. Also, when the
1364 * ISCSI_FLAG_CMD_FINAL is set to denote the end of the current
1365 * data out sequence, we decrement outstanding_r2ts. Once
1366 * outstanding_r2ts reaches zero, go ahead and send the delayed
1367 * TASK_ABORTED status.
1368 */
1369 if (atomic_read(&se_cmd->t_transport_aborted) != 0) {
1370 if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
1371 if (--cmd->outstanding_r2ts < 1) {
1372 iscsit_stop_dataout_timer(cmd);
1373 transport_check_aborted_status(
1374 se_cmd, 1);
1375 }
1376
1377 return iscsit_dump_data_payload(conn, payload_length, 1);
1378 }
1379 }
1380 /*
1381 * Preform DataSN, DataSequenceInOrder, DataPDUInOrder, and
1382 * within-command recovery checks before receiving the payload.
1383 */
1384 ret = iscsit_check_pre_dataout(cmd, buf);
1385 if (ret == DATAOUT_WITHIN_COMMAND_RECOVERY)
1386 return 0;
1387 else if (ret == DATAOUT_CANNOT_RECOVER)
1388 return -1;
1389
1390 rx_size += payload_length;
1391 iov = &cmd->iov_data[0];
1392
1393 iov_ret = iscsit_map_iovec(cmd, iov, hdr->offset, payload_length);
1394 if (iov_ret < 0)
1395 return -1;
1396
1397 iov_count += iov_ret;
1398
1399 padding = ((-payload_length) & 3);
1400 if (padding != 0) {
1401 iov[iov_count].iov_base = cmd->pad_bytes;
1402 iov[iov_count++].iov_len = padding;
1403 rx_size += padding;
1404 pr_debug("Receiving %u padding bytes.\n", padding);
1405 }
1406
1407 if (conn->conn_ops->DataDigest) {
1408 iov[iov_count].iov_base = &checksum;
1409 iov[iov_count++].iov_len = ISCSI_CRC_LEN;
1410 rx_size += ISCSI_CRC_LEN;
1411 }
1412
1413 rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size);
1414
1415 iscsit_unmap_iovec(cmd);
1416
1417 if (rx_got != rx_size)
1418 return -1;
1419
1420 if (conn->conn_ops->DataDigest) {
1421 u32 data_crc;
1422
1423 data_crc = iscsit_do_crypto_hash_sg(&conn->conn_rx_hash, cmd,
1424 hdr->offset, payload_length, padding,
1425 cmd->pad_bytes);
1426
1427 if (checksum != data_crc) {
1428 pr_err("ITT: 0x%08x, Offset: %u, Length: %u,"
1429 " DataSN: 0x%08x, CRC32C DataDigest 0x%08x"
1430 " does not match computed 0x%08x\n",
1431 hdr->itt, hdr->offset, payload_length,
1432 hdr->datasn, checksum, data_crc);
1433 data_crc_failed = 1;
1434 } else {
1435 pr_debug("Got CRC32C DataDigest 0x%08x for"
1436 " %u bytes of Data Out\n", checksum,
1437 payload_length);
1438 }
1439 }
1440 /*
1441 * Increment post receive data and CRC values or perform
1442 * within-command recovery.
1443 */
1444 ret = iscsit_check_post_dataout(cmd, buf, data_crc_failed);
1445 if ((ret == DATAOUT_NORMAL) || (ret == DATAOUT_WITHIN_COMMAND_RECOVERY))
1446 return 0;
1447 else if (ret == DATAOUT_SEND_R2T) {
1448 iscsit_set_dataout_sequence_values(cmd);
1449 iscsit_build_r2ts_for_cmd(cmd, conn, 0);
1450 } else if (ret == DATAOUT_SEND_TO_TRANSPORT) {
1451 /*
1452 * Handle extra special case for out of order
1453 * Unsolicited Data Out.
1454 */
1455 spin_lock_bh(&cmd->istate_lock);
1456 ooo_cmdsn = (cmd->cmd_flags & ICF_OOO_CMDSN);
1457 cmd->cmd_flags |= ICF_GOT_LAST_DATAOUT;
1458 cmd->i_state = ISTATE_RECEIVED_LAST_DATAOUT;
1459 spin_unlock_bh(&cmd->istate_lock);
1460
1461 iscsit_stop_dataout_timer(cmd);
1462 return (!ooo_cmdsn) ? transport_generic_handle_data(
1463 &cmd->se_cmd) : 0;
1464 } else /* DATAOUT_CANNOT_RECOVER */
1465 return -1;
1466
1467 return 0;
1468}
1469
1470static int iscsit_handle_nop_out(
1471 struct iscsi_conn *conn,
1472 unsigned char *buf)
1473{
1474 unsigned char *ping_data = NULL;
1475 int cmdsn_ret, niov = 0, ret = 0, rx_got, rx_size;
1476 u32 checksum, data_crc, padding = 0, payload_length;
1477 u64 lun;
1478 struct iscsi_cmd *cmd = NULL;
1479 struct kvec *iov = NULL;
1480 struct iscsi_nopout *hdr;
1481
1482 hdr = (struct iscsi_nopout *) buf;
1483 payload_length = ntoh24(hdr->dlength);
1484 lun = get_unaligned_le64(&hdr->lun);
1485 hdr->itt = be32_to_cpu(hdr->itt);
1486 hdr->ttt = be32_to_cpu(hdr->ttt);
1487 hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
1488 hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
1489
1490 if ((hdr->itt == 0xFFFFFFFF) && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
1491 pr_err("NOPOUT ITT is reserved, but Immediate Bit is"
1492 " not set, protocol error.\n");
1493 return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
1494 buf, conn);
1495 }
1496
1497 if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) {
1498 pr_err("NOPOUT Ping Data DataSegmentLength: %u is"
1499 " greater than MaxRecvDataSegmentLength: %u, protocol"
1500 " error.\n", payload_length,
1501 conn->conn_ops->MaxRecvDataSegmentLength);
1502 return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
1503 buf, conn);
1504 }
1505
1506 pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%09x,"
1507 " CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n",
1508 (hdr->itt == 0xFFFFFFFF) ? "Response" : "Request",
1509 hdr->itt, hdr->ttt, hdr->cmdsn, hdr->exp_statsn,
1510 payload_length);
1511 /*
1512 * This is not a response to a Unsolicited NopIN, which means
1513 * it can either be a NOPOUT ping request (with a valid ITT),
1514 * or a NOPOUT not requesting a NOPIN (with a reserved ITT).
1515 * Either way, make sure we allocate an struct iscsi_cmd, as both
1516 * can contain ping data.
1517 */
1518 if (hdr->ttt == 0xFFFFFFFF) {
1519 cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
1520 if (!cmd)
1521 return iscsit_add_reject(
1522 ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1523 1, buf, conn);
1524
1525 cmd->iscsi_opcode = ISCSI_OP_NOOP_OUT;
1526 cmd->i_state = ISTATE_SEND_NOPIN;
1527 cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ?
1528 1 : 0);
1529 conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
1530 cmd->targ_xfer_tag = 0xFFFFFFFF;
1531 cmd->cmd_sn = hdr->cmdsn;
1532 cmd->exp_stat_sn = hdr->exp_statsn;
1533 cmd->data_direction = DMA_NONE;
1534 }
1535
1536 if (payload_length && (hdr->ttt == 0xFFFFFFFF)) {
1537 rx_size = payload_length;
1538 ping_data = kzalloc(payload_length + 1, GFP_KERNEL);
1539 if (!ping_data) {
1540 pr_err("Unable to allocate memory for"
1541 " NOPOUT ping data.\n");
1542 ret = -1;
1543 goto out;
1544 }
1545
1546 iov = &cmd->iov_misc[0];
1547 iov[niov].iov_base = ping_data;
1548 iov[niov++].iov_len = payload_length;
1549
1550 padding = ((-payload_length) & 3);
1551 if (padding != 0) {
1552 pr_debug("Receiving %u additional bytes"
1553 " for padding.\n", padding);
1554 iov[niov].iov_base = &cmd->pad_bytes;
1555 iov[niov++].iov_len = padding;
1556 rx_size += padding;
1557 }
1558 if (conn->conn_ops->DataDigest) {
1559 iov[niov].iov_base = &checksum;
1560 iov[niov++].iov_len = ISCSI_CRC_LEN;
1561 rx_size += ISCSI_CRC_LEN;
1562 }
1563
1564 rx_got = rx_data(conn, &cmd->iov_misc[0], niov, rx_size);
1565 if (rx_got != rx_size) {
1566 ret = -1;
1567 goto out;
1568 }
1569
1570 if (conn->conn_ops->DataDigest) {
1571 iscsit_do_crypto_hash_buf(&conn->conn_rx_hash,
1572 ping_data, payload_length,
1573 padding, cmd->pad_bytes,
1574 (u8 *)&data_crc);
1575
1576 if (checksum != data_crc) {
1577 pr_err("Ping data CRC32C DataDigest"
1578 " 0x%08x does not match computed 0x%08x\n",
1579 checksum, data_crc);
1580 if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
1581 pr_err("Unable to recover from"
1582 " NOPOUT Ping DataCRC failure while in"
1583 " ERL=0.\n");
1584 ret = -1;
1585 goto out;
1586 } else {
1587 /*
1588 * Silently drop this PDU and let the
1589 * initiator plug the CmdSN gap.
1590 */
1591 pr_debug("Dropping NOPOUT"
1592 " Command CmdSN: 0x%08x due to"
1593 " DataCRC error.\n", hdr->cmdsn);
1594 ret = 0;
1595 goto out;
1596 }
1597 } else {
1598 pr_debug("Got CRC32C DataDigest"
1599 " 0x%08x for %u bytes of ping data.\n",
1600 checksum, payload_length);
1601 }
1602 }
1603
1604 ping_data[payload_length] = '\0';
1605 /*
1606 * Attach ping data to struct iscsi_cmd->buf_ptr.
1607 */
1608 cmd->buf_ptr = (void *)ping_data;
1609 cmd->buf_ptr_size = payload_length;
1610
1611 pr_debug("Got %u bytes of NOPOUT ping"
1612 " data.\n", payload_length);
1613 pr_debug("Ping Data: \"%s\"\n", ping_data);
1614 }
1615
1616 if (hdr->itt != 0xFFFFFFFF) {
1617 if (!cmd) {
1618 pr_err("Checking CmdSN for NOPOUT,"
1619 " but cmd is NULL!\n");
1620 return -1;
1621 }
1622 /*
1623 * Initiator is expecting a NopIN ping reply,
1624 */
1625 spin_lock_bh(&conn->cmd_lock);
1626 list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
1627 spin_unlock_bh(&conn->cmd_lock);
1628
1629 iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
1630
1631 if (hdr->opcode & ISCSI_OP_IMMEDIATE) {
1632 iscsit_add_cmd_to_response_queue(cmd, conn,
1633 cmd->i_state);
1634 return 0;
1635 }
1636
1637 cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
1638 if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
1639 ret = 0;
1640 goto ping_out;
1641 }
1642 if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
1643 return iscsit_add_reject_from_cmd(
1644 ISCSI_REASON_PROTOCOL_ERROR,
1645 1, 0, buf, cmd);
1646
1647 return 0;
1648 }
1649
1650 if (hdr->ttt != 0xFFFFFFFF) {
1651 /*
1652 * This was a response to a unsolicited NOPIN ping.
1653 */
1654 cmd = iscsit_find_cmd_from_ttt(conn, hdr->ttt);
1655 if (!cmd)
1656 return -1;
1657
1658 iscsit_stop_nopin_response_timer(conn);
1659
1660 cmd->i_state = ISTATE_REMOVE;
1661 iscsit_add_cmd_to_immediate_queue(cmd, conn, cmd->i_state);
1662 iscsit_start_nopin_timer(conn);
1663 } else {
1664 /*
1665 * Initiator is not expecting a NOPIN is response.
1666 * Just ignore for now.
1667 *
1668 * iSCSI v19-91 10.18
1669 * "A NOP-OUT may also be used to confirm a changed
1670 * ExpStatSN if another PDU will not be available
1671 * for a long time."
1672 */
1673 ret = 0;
1674 goto out;
1675 }
1676
1677 return 0;
1678out:
1679 if (cmd)
1680 iscsit_release_cmd(cmd);
1681ping_out:
1682 kfree(ping_data);
1683 return ret;
1684}
1685
1686static int iscsit_handle_task_mgt_cmd(
1687 struct iscsi_conn *conn,
1688 unsigned char *buf)
1689{
1690 struct iscsi_cmd *cmd;
1691 struct se_tmr_req *se_tmr;
1692 struct iscsi_tmr_req *tmr_req;
1693 struct iscsi_tm *hdr;
1694 u32 payload_length;
1695 int out_of_order_cmdsn = 0;
1696 int ret;
1697 u8 function;
1698
1699 hdr = (struct iscsi_tm *) buf;
1700 payload_length = ntoh24(hdr->dlength);
1701 hdr->itt = be32_to_cpu(hdr->itt);
1702 hdr->rtt = be32_to_cpu(hdr->rtt);
1703 hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
1704 hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
1705 hdr->refcmdsn = be32_to_cpu(hdr->refcmdsn);
1706 hdr->exp_datasn = be32_to_cpu(hdr->exp_datasn);
1707 hdr->flags &= ~ISCSI_FLAG_CMD_FINAL;
1708 function = hdr->flags;
1709
1710 pr_debug("Got Task Management Request ITT: 0x%08x, CmdSN:"
1711 " 0x%08x, Function: 0x%02x, RefTaskTag: 0x%08x, RefCmdSN:"
1712 " 0x%08x, CID: %hu\n", hdr->itt, hdr->cmdsn, function,
1713 hdr->rtt, hdr->refcmdsn, conn->cid);
1714
1715 if ((function != ISCSI_TM_FUNC_ABORT_TASK) &&
1716 ((function != ISCSI_TM_FUNC_TASK_REASSIGN) &&
1717 (hdr->rtt != ISCSI_RESERVED_TAG))) {
1718 pr_err("RefTaskTag should be set to 0xFFFFFFFF.\n");
1719 hdr->rtt = ISCSI_RESERVED_TAG;
1720 }
1721
1722 if ((function == ISCSI_TM_FUNC_TASK_REASSIGN) &&
1723 !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
1724 pr_err("Task Management Request TASK_REASSIGN not"
1725 " issued as immediate command, bad iSCSI Initiator"
1726 "implementation\n");
1727 return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
1728 buf, conn);
1729 }
1730 if ((function != ISCSI_TM_FUNC_ABORT_TASK) &&
1731 (hdr->refcmdsn != ISCSI_RESERVED_TAG))
1732 hdr->refcmdsn = ISCSI_RESERVED_TAG;
1733
1734 cmd = iscsit_allocate_se_cmd_for_tmr(conn, function);
1735 if (!cmd)
1736 return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1737 1, buf, conn);
1738
1739 cmd->iscsi_opcode = ISCSI_OP_SCSI_TMFUNC;
1740 cmd->i_state = ISTATE_SEND_TASKMGTRSP;
1741 cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
1742 cmd->init_task_tag = hdr->itt;
1743 cmd->targ_xfer_tag = 0xFFFFFFFF;
1744 cmd->cmd_sn = hdr->cmdsn;
1745 cmd->exp_stat_sn = hdr->exp_statsn;
1746 se_tmr = cmd->se_cmd.se_tmr_req;
1747 tmr_req = cmd->tmr_req;
1748 /*
1749 * Locate the struct se_lun for all TMRs not related to ERL=2 TASK_REASSIGN
1750 */
1751 if (function != ISCSI_TM_FUNC_TASK_REASSIGN) {
1752 ret = iscsit_get_lun_for_tmr(cmd,
1753 get_unaligned_le64(&hdr->lun));
1754 if (ret < 0) {
1755 cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
1756 se_tmr->response = ISCSI_TMF_RSP_NO_LUN;
1757 goto attach;
1758 }
1759 }
1760
1761 switch (function) {
1762 case ISCSI_TM_FUNC_ABORT_TASK:
1763 se_tmr->response = iscsit_tmr_abort_task(cmd, buf);
1764 if (se_tmr->response != ISCSI_TMF_RSP_COMPLETE) {
1765 cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
1766 goto attach;
1767 }
1768 break;
1769 case ISCSI_TM_FUNC_ABORT_TASK_SET:
1770 case ISCSI_TM_FUNC_CLEAR_ACA:
1771 case ISCSI_TM_FUNC_CLEAR_TASK_SET:
1772 case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET:
1773 break;
1774 case ISCSI_TM_FUNC_TARGET_WARM_RESET:
1775 if (iscsit_tmr_task_warm_reset(conn, tmr_req, buf) < 0) {
1776 cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
1777 se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED;
1778 goto attach;
1779 }
1780 break;
1781 case ISCSI_TM_FUNC_TARGET_COLD_RESET:
1782 if (iscsit_tmr_task_cold_reset(conn, tmr_req, buf) < 0) {
1783 cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
1784 se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED;
1785 goto attach;
1786 }
1787 break;
1788 case ISCSI_TM_FUNC_TASK_REASSIGN:
1789 se_tmr->response = iscsit_tmr_task_reassign(cmd, buf);
1790 /*
1791 * Perform sanity checks on the ExpDataSN only if the
1792 * TASK_REASSIGN was successful.
1793 */
1794 if (se_tmr->response != ISCSI_TMF_RSP_COMPLETE)
1795 break;
1796
1797 if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0)
1798 return iscsit_add_reject_from_cmd(
1799 ISCSI_REASON_BOOKMARK_INVALID, 1, 1,
1800 buf, cmd);
1801 break;
1802 default:
1803 pr_err("Unknown TMR function: 0x%02x, protocol"
1804 " error.\n", function);
1805 cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
1806 se_tmr->response = ISCSI_TMF_RSP_NOT_SUPPORTED;
1807 goto attach;
1808 }
1809
1810 if ((function != ISCSI_TM_FUNC_TASK_REASSIGN) &&
1811 (se_tmr->response == ISCSI_TMF_RSP_COMPLETE))
1812 se_tmr->call_transport = 1;
1813attach:
1814 spin_lock_bh(&conn->cmd_lock);
1815 list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
1816 spin_unlock_bh(&conn->cmd_lock);
1817
1818 if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
1819 int cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
1820 if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP)
1821 out_of_order_cmdsn = 1;
1822 else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
1823 return 0;
1824 } else { /* (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) */
1825 return iscsit_add_reject_from_cmd(
1826 ISCSI_REASON_PROTOCOL_ERROR,
1827 1, 0, buf, cmd);
1828 }
1829 }
1830 iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
1831
1832 if (out_of_order_cmdsn)
1833 return 0;
1834 /*
1835 * Found the referenced task, send to transport for processing.
1836 */
1837 if (se_tmr->call_transport)
1838 return transport_generic_handle_tmr(&cmd->se_cmd);
1839
1840 /*
1841 * Could not find the referenced LUN, task, or Task Management
1842 * command not authorized or supported. Change state and
1843 * let the tx_thread send the response.
1844 *
1845 * For connection recovery, this is also the default action for
1846 * TMR TASK_REASSIGN.
1847 */
1848 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
1849 return 0;
1850}
1851
1852/* #warning FIXME: Support Text Command parameters besides SendTargets */
1853static int iscsit_handle_text_cmd(
1854 struct iscsi_conn *conn,
1855 unsigned char *buf)
1856{
1857 char *text_ptr, *text_in;
1858 int cmdsn_ret, niov = 0, rx_got, rx_size;
1859 u32 checksum = 0, data_crc = 0, payload_length;
1860 u32 padding = 0, text_length = 0;
1861 struct iscsi_cmd *cmd;
1862 struct kvec iov[3];
1863 struct iscsi_text *hdr;
1864
1865 hdr = (struct iscsi_text *) buf;
1866 payload_length = ntoh24(hdr->dlength);
1867 hdr->itt = be32_to_cpu(hdr->itt);
1868 hdr->ttt = be32_to_cpu(hdr->ttt);
1869 hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
1870 hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
1871
1872 if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) {
1873 pr_err("Unable to accept text parameter length: %u"
1874 "greater than MaxRecvDataSegmentLength %u.\n",
1875 payload_length, conn->conn_ops->MaxRecvDataSegmentLength);
1876 return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
1877 buf, conn);
1878 }
1879
1880 pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x,"
1881 " ExpStatSN: 0x%08x, Length: %u\n", hdr->itt, hdr->cmdsn,
1882 hdr->exp_statsn, payload_length);
1883
1884 rx_size = text_length = payload_length;
1885 if (text_length) {
1886 text_in = kzalloc(text_length, GFP_KERNEL);
1887 if (!text_in) {
1888 pr_err("Unable to allocate memory for"
1889 " incoming text parameters\n");
1890 return -1;
1891 }
1892
1893 memset(iov, 0, 3 * sizeof(struct kvec));
1894 iov[niov].iov_base = text_in;
1895 iov[niov++].iov_len = text_length;
1896
1897 padding = ((-payload_length) & 3);
1898 if (padding != 0) {
1899 iov[niov].iov_base = cmd->pad_bytes;
1900 iov[niov++].iov_len = padding;
1901 rx_size += padding;
1902 pr_debug("Receiving %u additional bytes"
1903 " for padding.\n", padding);
1904 }
1905 if (conn->conn_ops->DataDigest) {
1906 iov[niov].iov_base = &checksum;
1907 iov[niov++].iov_len = ISCSI_CRC_LEN;
1908 rx_size += ISCSI_CRC_LEN;
1909 }
1910
1911 rx_got = rx_data(conn, &iov[0], niov, rx_size);
1912 if (rx_got != rx_size) {
1913 kfree(text_in);
1914 return -1;
1915 }
1916
1917 if (conn->conn_ops->DataDigest) {
1918 iscsit_do_crypto_hash_buf(&conn->conn_rx_hash,
1919 text_in, text_length,
1920 padding, cmd->pad_bytes,
1921 (u8 *)&data_crc);
1922
1923 if (checksum != data_crc) {
1924 pr_err("Text data CRC32C DataDigest"
1925 " 0x%08x does not match computed"
1926 " 0x%08x\n", checksum, data_crc);
1927 if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
1928 pr_err("Unable to recover from"
1929 " Text Data digest failure while in"
1930 " ERL=0.\n");
1931 kfree(text_in);
1932 return -1;
1933 } else {
1934 /*
1935 * Silently drop this PDU and let the
1936 * initiator plug the CmdSN gap.
1937 */
1938 pr_debug("Dropping Text"
1939 " Command CmdSN: 0x%08x due to"
1940 " DataCRC error.\n", hdr->cmdsn);
1941 kfree(text_in);
1942 return 0;
1943 }
1944 } else {
1945 pr_debug("Got CRC32C DataDigest"
1946 " 0x%08x for %u bytes of text data.\n",
1947 checksum, text_length);
1948 }
1949 }
1950 text_in[text_length - 1] = '\0';
1951 pr_debug("Successfully read %d bytes of text"
1952 " data.\n", text_length);
1953
1954 if (strncmp("SendTargets", text_in, 11) != 0) {
1955 pr_err("Received Text Data that is not"
1956 " SendTargets, cannot continue.\n");
1957 kfree(text_in);
1958 return -1;
1959 }
1960 text_ptr = strchr(text_in, '=');
1961 if (!text_ptr) {
1962 pr_err("No \"=\" separator found in Text Data,"
1963 " cannot continue.\n");
1964 kfree(text_in);
1965 return -1;
1966 }
1967 if (strncmp("=All", text_ptr, 4) != 0) {
1968 pr_err("Unable to locate All value for"
1969 " SendTargets key, cannot continue.\n");
1970 kfree(text_in);
1971 return -1;
1972 }
1973/*#warning Support SendTargets=(iSCSI Target Name/Nothing) values. */
1974 kfree(text_in);
1975 }
1976
1977 cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
1978 if (!cmd)
1979 return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1980 1, buf, conn);
1981
1982 cmd->iscsi_opcode = ISCSI_OP_TEXT;
1983 cmd->i_state = ISTATE_SEND_TEXTRSP;
1984 cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
1985 conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
1986 cmd->targ_xfer_tag = 0xFFFFFFFF;
1987 cmd->cmd_sn = hdr->cmdsn;
1988 cmd->exp_stat_sn = hdr->exp_statsn;
1989 cmd->data_direction = DMA_NONE;
1990
1991 spin_lock_bh(&conn->cmd_lock);
1992 list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
1993 spin_unlock_bh(&conn->cmd_lock);
1994
1995 iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
1996
1997 if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
1998 cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
1999 if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
2000 return iscsit_add_reject_from_cmd(
2001 ISCSI_REASON_PROTOCOL_ERROR,
2002 1, 0, buf, cmd);
2003
2004 return 0;
2005 }
2006
2007 return iscsit_execute_cmd(cmd, 0);
2008}
2009
2010int iscsit_logout_closesession(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
2011{
2012 struct iscsi_conn *conn_p;
2013 struct iscsi_session *sess = conn->sess;
2014
2015 pr_debug("Received logout request CLOSESESSION on CID: %hu"
2016 " for SID: %u.\n", conn->cid, conn->sess->sid);
2017
2018 atomic_set(&sess->session_logout, 1);
2019 atomic_set(&conn->conn_logout_remove, 1);
2020 conn->conn_logout_reason = ISCSI_LOGOUT_REASON_CLOSE_SESSION;
2021
2022 iscsit_inc_conn_usage_count(conn);
2023 iscsit_inc_session_usage_count(sess);
2024
2025 spin_lock_bh(&sess->conn_lock);
2026 list_for_each_entry(conn_p, &sess->sess_conn_list, conn_list) {
2027 if (conn_p->conn_state != TARG_CONN_STATE_LOGGED_IN)
2028 continue;
2029
2030 pr_debug("Moving to TARG_CONN_STATE_IN_LOGOUT.\n");
2031 conn_p->conn_state = TARG_CONN_STATE_IN_LOGOUT;
2032 }
2033 spin_unlock_bh(&sess->conn_lock);
2034
2035 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2036
2037 return 0;
2038}
2039
2040int iscsit_logout_closeconnection(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
2041{
2042 struct iscsi_conn *l_conn;
2043 struct iscsi_session *sess = conn->sess;
2044
2045 pr_debug("Received logout request CLOSECONNECTION for CID:"
2046 " %hu on CID: %hu.\n", cmd->logout_cid, conn->cid);
2047
2048 /*
2049 * A Logout Request with a CLOSECONNECTION reason code for a CID
2050 * can arrive on a connection with a differing CID.
2051 */
2052 if (conn->cid == cmd->logout_cid) {
2053 spin_lock_bh(&conn->state_lock);
2054 pr_debug("Moving to TARG_CONN_STATE_IN_LOGOUT.\n");
2055 conn->conn_state = TARG_CONN_STATE_IN_LOGOUT;
2056
2057 atomic_set(&conn->conn_logout_remove, 1);
2058 conn->conn_logout_reason = ISCSI_LOGOUT_REASON_CLOSE_CONNECTION;
2059 iscsit_inc_conn_usage_count(conn);
2060
2061 spin_unlock_bh(&conn->state_lock);
2062 } else {
2063 /*
2064 * Handle all different cid CLOSECONNECTION requests in
2065 * iscsit_logout_post_handler_diffcid() as to give enough
2066 * time for any non immediate command's CmdSN to be
2067 * acknowledged on the connection in question.
2068 *
2069 * Here we simply make sure the CID is still around.
2070 */
2071 l_conn = iscsit_get_conn_from_cid(sess,
2072 cmd->logout_cid);
2073 if (!l_conn) {
2074 cmd->logout_response = ISCSI_LOGOUT_CID_NOT_FOUND;
2075 iscsit_add_cmd_to_response_queue(cmd, conn,
2076 cmd->i_state);
2077 return 0;
2078 }
2079
2080 iscsit_dec_conn_usage_count(l_conn);
2081 }
2082
2083 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2084
2085 return 0;
2086}
2087
2088int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
2089{
2090 struct iscsi_session *sess = conn->sess;
2091
2092 pr_debug("Received explicit REMOVECONNFORRECOVERY logout for"
2093 " CID: %hu on CID: %hu.\n", cmd->logout_cid, conn->cid);
2094
2095 if (sess->sess_ops->ErrorRecoveryLevel != 2) {
2096 pr_err("Received Logout Request REMOVECONNFORRECOVERY"
2097 " while ERL!=2.\n");
2098 cmd->logout_response = ISCSI_LOGOUT_RECOVERY_UNSUPPORTED;
2099 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2100 return 0;
2101 }
2102
2103 if (conn->cid == cmd->logout_cid) {
2104 pr_err("Received Logout Request REMOVECONNFORRECOVERY"
2105 " with CID: %hu on CID: %hu, implementation error.\n",
2106 cmd->logout_cid, conn->cid);
2107 cmd->logout_response = ISCSI_LOGOUT_CLEANUP_FAILED;
2108 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2109 return 0;
2110 }
2111
2112 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2113
2114 return 0;
2115}
2116
2117static int iscsit_handle_logout_cmd(
2118 struct iscsi_conn *conn,
2119 unsigned char *buf)
2120{
2121 int cmdsn_ret, logout_remove = 0;
2122 u8 reason_code = 0;
2123 struct iscsi_cmd *cmd;
2124 struct iscsi_logout *hdr;
2125 struct iscsi_tiqn *tiqn = iscsit_snmp_get_tiqn(conn);
2126
2127 hdr = (struct iscsi_logout *) buf;
2128 reason_code = (hdr->flags & 0x7f);
2129 hdr->itt = be32_to_cpu(hdr->itt);
2130 hdr->cid = be16_to_cpu(hdr->cid);
2131 hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
2132 hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
2133
2134 if (tiqn) {
2135 spin_lock(&tiqn->logout_stats.lock);
2136 if (reason_code == ISCSI_LOGOUT_REASON_CLOSE_SESSION)
2137 tiqn->logout_stats.normal_logouts++;
2138 else
2139 tiqn->logout_stats.abnormal_logouts++;
2140 spin_unlock(&tiqn->logout_stats.lock);
2141 }
2142
2143 pr_debug("Got Logout Request ITT: 0x%08x CmdSN: 0x%08x"
2144 " ExpStatSN: 0x%08x Reason: 0x%02x CID: %hu on CID: %hu\n",
2145 hdr->itt, hdr->cmdsn, hdr->exp_statsn, reason_code,
2146 hdr->cid, conn->cid);
2147
2148 if (conn->conn_state != TARG_CONN_STATE_LOGGED_IN) {
2149 pr_err("Received logout request on connection that"
2150 " is not in logged in state, ignoring request.\n");
2151 return 0;
2152 }
2153
2154 cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
2155 if (!cmd)
2156 return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES, 1,
2157 buf, conn);
2158
2159 cmd->iscsi_opcode = ISCSI_OP_LOGOUT;
2160 cmd->i_state = ISTATE_SEND_LOGOUTRSP;
2161 cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
2162 conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
2163 cmd->targ_xfer_tag = 0xFFFFFFFF;
2164 cmd->cmd_sn = hdr->cmdsn;
2165 cmd->exp_stat_sn = hdr->exp_statsn;
2166 cmd->logout_cid = hdr->cid;
2167 cmd->logout_reason = reason_code;
2168 cmd->data_direction = DMA_NONE;
2169
2170 /*
2171 * We need to sleep in these cases (by returning 1) until the Logout
2172 * Response gets sent in the tx thread.
2173 */
2174 if ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_SESSION) ||
2175 ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_CONNECTION) &&
2176 (hdr->cid == conn->cid)))
2177 logout_remove = 1;
2178
2179 spin_lock_bh(&conn->cmd_lock);
2180 list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
2181 spin_unlock_bh(&conn->cmd_lock);
2182
2183 if (reason_code != ISCSI_LOGOUT_REASON_RECOVERY)
2184 iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
2185
2186 /*
2187 * Immediate commands are executed, well, immediately.
2188 * Non-Immediate Logout Commands are executed in CmdSN order.
2189 */
2190 if (hdr->opcode & ISCSI_OP_IMMEDIATE) {
2191 int ret = iscsit_execute_cmd(cmd, 0);
2192
2193 if (ret < 0)
2194 return ret;
2195 } else {
2196 cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
2197 if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
2198 logout_remove = 0;
2199 } else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) {
2200 return iscsit_add_reject_from_cmd(
2201 ISCSI_REASON_PROTOCOL_ERROR,
2202 1, 0, buf, cmd);
2203 }
2204 }
2205
2206 return logout_remove;
2207}
2208
2209static int iscsit_handle_snack(
2210 struct iscsi_conn *conn,
2211 unsigned char *buf)
2212{
2213 u32 unpacked_lun;
2214 u64 lun;
2215 struct iscsi_snack *hdr;
2216
2217 hdr = (struct iscsi_snack *) buf;
2218 hdr->flags &= ~ISCSI_FLAG_CMD_FINAL;
2219 lun = get_unaligned_le64(&hdr->lun);
2220 unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun);
2221 hdr->itt = be32_to_cpu(hdr->itt);
2222 hdr->ttt = be32_to_cpu(hdr->ttt);
2223 hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
2224 hdr->begrun = be32_to_cpu(hdr->begrun);
2225 hdr->runlength = be32_to_cpu(hdr->runlength);
2226
2227 pr_debug("Got ISCSI_INIT_SNACK, ITT: 0x%08x, ExpStatSN:"
2228 " 0x%08x, Type: 0x%02x, BegRun: 0x%08x, RunLength: 0x%08x,"
2229 " CID: %hu\n", hdr->itt, hdr->exp_statsn, hdr->flags,
2230 hdr->begrun, hdr->runlength, conn->cid);
2231
2232 if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
2233 pr_err("Initiator sent SNACK request while in"
2234 " ErrorRecoveryLevel=0.\n");
2235 return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
2236 buf, conn);
2237 }
2238 /*
2239 * SNACK_DATA and SNACK_R2T are both 0, so check which function to
2240 * call from inside iscsi_send_recovery_datain_or_r2t().
2241 */
2242 switch (hdr->flags & ISCSI_FLAG_SNACK_TYPE_MASK) {
2243 case 0:
2244 return iscsit_handle_recovery_datain_or_r2t(conn, buf,
2245 hdr->itt, hdr->ttt, hdr->begrun, hdr->runlength);
2246 return 0;
2247 case ISCSI_FLAG_SNACK_TYPE_STATUS:
2248 return iscsit_handle_status_snack(conn, hdr->itt, hdr->ttt,
2249 hdr->begrun, hdr->runlength);
2250 case ISCSI_FLAG_SNACK_TYPE_DATA_ACK:
2251 return iscsit_handle_data_ack(conn, hdr->ttt, hdr->begrun,
2252 hdr->runlength);
2253 case ISCSI_FLAG_SNACK_TYPE_RDATA:
2254 /* FIXME: Support R-Data SNACK */
2255 pr_err("R-Data SNACK Not Supported.\n");
2256 return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
2257 buf, conn);
2258 default:
2259 pr_err("Unknown SNACK type 0x%02x, protocol"
2260 " error.\n", hdr->flags & 0x0f);
2261 return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
2262 buf, conn);
2263 }
2264
2265 return 0;
2266}
2267
2268static void iscsit_rx_thread_wait_for_tcp(struct iscsi_conn *conn)
2269{
2270 if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) ||
2271 (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) {
2272 wait_for_completion_interruptible_timeout(
2273 &conn->rx_half_close_comp,
2274 ISCSI_RX_THREAD_TCP_TIMEOUT * HZ);
2275 }
2276}
2277
2278static int iscsit_handle_immediate_data(
2279 struct iscsi_cmd *cmd,
2280 unsigned char *buf,
2281 u32 length)
2282{
2283 int iov_ret, rx_got = 0, rx_size = 0;
2284 u32 checksum, iov_count = 0, padding = 0;
2285 struct iscsi_conn *conn = cmd->conn;
2286 struct kvec *iov;
2287
2288 iov_ret = iscsit_map_iovec(cmd, cmd->iov_data, cmd->write_data_done, length);
2289 if (iov_ret < 0)
2290 return IMMEDIATE_DATA_CANNOT_RECOVER;
2291
2292 rx_size = length;
2293 iov_count = iov_ret;
2294 iov = &cmd->iov_data[0];
2295
2296 padding = ((-length) & 3);
2297 if (padding != 0) {
2298 iov[iov_count].iov_base = cmd->pad_bytes;
2299 iov[iov_count++].iov_len = padding;
2300 rx_size += padding;
2301 }
2302
2303 if (conn->conn_ops->DataDigest) {
2304 iov[iov_count].iov_base = &checksum;
2305 iov[iov_count++].iov_len = ISCSI_CRC_LEN;
2306 rx_size += ISCSI_CRC_LEN;
2307 }
2308
2309 rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size);
2310
2311 iscsit_unmap_iovec(cmd);
2312
2313 if (rx_got != rx_size) {
2314 iscsit_rx_thread_wait_for_tcp(conn);
2315 return IMMEDIATE_DATA_CANNOT_RECOVER;
2316 }
2317
2318 if (conn->conn_ops->DataDigest) {
2319 u32 data_crc;
2320
2321 data_crc = iscsit_do_crypto_hash_sg(&conn->conn_rx_hash, cmd,
2322 cmd->write_data_done, length, padding,
2323 cmd->pad_bytes);
2324
2325 if (checksum != data_crc) {
2326 pr_err("ImmediateData CRC32C DataDigest 0x%08x"
2327 " does not match computed 0x%08x\n", checksum,
2328 data_crc);
2329
2330 if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
2331 pr_err("Unable to recover from"
2332 " Immediate Data digest failure while"
2333 " in ERL=0.\n");
2334 iscsit_add_reject_from_cmd(
2335 ISCSI_REASON_DATA_DIGEST_ERROR,
2336 1, 0, buf, cmd);
2337 return IMMEDIATE_DATA_CANNOT_RECOVER;
2338 } else {
2339 iscsit_add_reject_from_cmd(
2340 ISCSI_REASON_DATA_DIGEST_ERROR,
2341 0, 0, buf, cmd);
2342 return IMMEDIATE_DATA_ERL1_CRC_FAILURE;
2343 }
2344 } else {
2345 pr_debug("Got CRC32C DataDigest 0x%08x for"
2346 " %u bytes of Immediate Data\n", checksum,
2347 length);
2348 }
2349 }
2350
2351 cmd->write_data_done += length;
2352
2353 if (cmd->write_data_done == cmd->data_length) {
2354 spin_lock_bh(&cmd->istate_lock);
2355 cmd->cmd_flags |= ICF_GOT_LAST_DATAOUT;
2356 cmd->i_state = ISTATE_RECEIVED_LAST_DATAOUT;
2357 spin_unlock_bh(&cmd->istate_lock);
2358 }
2359
2360 return IMMEDIATE_DATA_NORMAL_OPERATION;
2361}
2362
2363/*
2364 * Called with sess->conn_lock held.
2365 */
2366/* #warning iscsi_build_conn_drop_async_message() only sends out on connections
2367 with active network interface */
2368static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn)
2369{
2370 struct iscsi_cmd *cmd;
2371 struct iscsi_conn *conn_p;
2372
2373 /*
2374 * Only send a Asynchronous Message on connections whos network
2375 * interface is still functional.
2376 */
2377 list_for_each_entry(conn_p, &conn->sess->sess_conn_list, conn_list) {
2378 if (conn_p->conn_state == TARG_CONN_STATE_LOGGED_IN) {
2379 iscsit_inc_conn_usage_count(conn_p);
2380 break;
2381 }
2382 }
2383
2384 if (!conn_p)
2385 return;
2386
2387 cmd = iscsit_allocate_cmd(conn_p, GFP_KERNEL);
2388 if (!cmd) {
2389 iscsit_dec_conn_usage_count(conn_p);
2390 return;
2391 }
2392
2393 cmd->logout_cid = conn->cid;
2394 cmd->iscsi_opcode = ISCSI_OP_ASYNC_EVENT;
2395 cmd->i_state = ISTATE_SEND_ASYNCMSG;
2396
2397 spin_lock_bh(&conn_p->cmd_lock);
2398 list_add_tail(&cmd->i_list, &conn_p->conn_cmd_list);
2399 spin_unlock_bh(&conn_p->cmd_lock);
2400
2401 iscsit_add_cmd_to_response_queue(cmd, conn_p, cmd->i_state);
2402 iscsit_dec_conn_usage_count(conn_p);
2403}
2404
2405static int iscsit_send_conn_drop_async_message(
2406 struct iscsi_cmd *cmd,
2407 struct iscsi_conn *conn)
2408{
2409 struct iscsi_async *hdr;
2410
2411 cmd->tx_size = ISCSI_HDR_LEN;
2412 cmd->iscsi_opcode = ISCSI_OP_ASYNC_EVENT;
2413
2414 hdr = (struct iscsi_async *) cmd->pdu;
2415 hdr->opcode = ISCSI_OP_ASYNC_EVENT;
2416 hdr->flags = ISCSI_FLAG_CMD_FINAL;
2417 cmd->init_task_tag = 0xFFFFFFFF;
2418 cmd->targ_xfer_tag = 0xFFFFFFFF;
2419 put_unaligned_be64(0xFFFFFFFFFFFFFFFFULL, &hdr->rsvd4[0]);
2420 cmd->stat_sn = conn->stat_sn++;
2421 hdr->statsn = cpu_to_be32(cmd->stat_sn);
2422 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
2423 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
2424 hdr->async_event = ISCSI_ASYNC_MSG_DROPPING_CONNECTION;
2425 hdr->param1 = cpu_to_be16(cmd->logout_cid);
2426 hdr->param2 = cpu_to_be16(conn->sess->sess_ops->DefaultTime2Wait);
2427 hdr->param3 = cpu_to_be16(conn->sess->sess_ops->DefaultTime2Retain);
2428
2429 if (conn->conn_ops->HeaderDigest) {
2430 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
2431
2432 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
2433 (unsigned char *)hdr, ISCSI_HDR_LEN,
2434 0, NULL, (u8 *)header_digest);
2435
2436 cmd->tx_size += ISCSI_CRC_LEN;
2437 pr_debug("Attaching CRC32C HeaderDigest to"
2438 " Async Message 0x%08x\n", *header_digest);
2439 }
2440
2441 cmd->iov_misc[0].iov_base = cmd->pdu;
2442 cmd->iov_misc[0].iov_len = cmd->tx_size;
2443 cmd->iov_misc_count = 1;
2444
2445 pr_debug("Sending Connection Dropped Async Message StatSN:"
2446 " 0x%08x, for CID: %hu on CID: %hu\n", cmd->stat_sn,
2447 cmd->logout_cid, conn->cid);
2448 return 0;
2449}
2450
2451static int iscsit_send_data_in(
2452 struct iscsi_cmd *cmd,
2453 struct iscsi_conn *conn,
2454 int *eodr)
2455{
2456 int iov_ret = 0, set_statsn = 0;
2457 u32 iov_count = 0, tx_size = 0;
2458 struct iscsi_datain datain;
2459 struct iscsi_datain_req *dr;
2460 struct iscsi_data_rsp *hdr;
2461 struct kvec *iov;
2462
2463 memset(&datain, 0, sizeof(struct iscsi_datain));
2464 dr = iscsit_get_datain_values(cmd, &datain);
2465 if (!dr) {
2466 pr_err("iscsit_get_datain_values failed for ITT: 0x%08x\n",
2467 cmd->init_task_tag);
2468 return -1;
2469 }
2470
2471 /*
2472 * Be paranoid and double check the logic for now.
2473 */
2474 if ((datain.offset + datain.length) > cmd->data_length) {
2475 pr_err("Command ITT: 0x%08x, datain.offset: %u and"
2476 " datain.length: %u exceeds cmd->data_length: %u\n",
2477 cmd->init_task_tag, datain.offset, datain.length,
2478 cmd->data_length);
2479 return -1;
2480 }
2481
2482 spin_lock_bh(&conn->sess->session_stats_lock);
2483 conn->sess->tx_data_octets += datain.length;
2484 if (conn->sess->se_sess->se_node_acl) {
2485 spin_lock(&conn->sess->se_sess->se_node_acl->stats_lock);
2486 conn->sess->se_sess->se_node_acl->read_bytes += datain.length;
2487 spin_unlock(&conn->sess->se_sess->se_node_acl->stats_lock);
2488 }
2489 spin_unlock_bh(&conn->sess->session_stats_lock);
2490 /*
2491 * Special case for successfully execution w/ both DATAIN
2492 * and Sense Data.
2493 */
2494 if ((datain.flags & ISCSI_FLAG_DATA_STATUS) &&
2495 (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE))
2496 datain.flags &= ~ISCSI_FLAG_DATA_STATUS;
2497 else {
2498 if ((dr->dr_complete == DATAIN_COMPLETE_NORMAL) ||
2499 (dr->dr_complete == DATAIN_COMPLETE_CONNECTION_RECOVERY)) {
2500 iscsit_increment_maxcmdsn(cmd, conn->sess);
2501 cmd->stat_sn = conn->stat_sn++;
2502 set_statsn = 1;
2503 } else if (dr->dr_complete ==
2504 DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY)
2505 set_statsn = 1;
2506 }
2507
2508 hdr = (struct iscsi_data_rsp *) cmd->pdu;
2509 memset(hdr, 0, ISCSI_HDR_LEN);
2510 hdr->opcode = ISCSI_OP_SCSI_DATA_IN;
2511 hdr->flags = datain.flags;
2512 if (hdr->flags & ISCSI_FLAG_DATA_STATUS) {
2513 if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) {
2514 hdr->flags |= ISCSI_FLAG_DATA_OVERFLOW;
2515 hdr->residual_count = cpu_to_be32(cmd->residual_count);
2516 } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) {
2517 hdr->flags |= ISCSI_FLAG_DATA_UNDERFLOW;
2518 hdr->residual_count = cpu_to_be32(cmd->residual_count);
2519 }
2520 }
2521 hton24(hdr->dlength, datain.length);
2522 if (hdr->flags & ISCSI_FLAG_DATA_ACK)
2523 int_to_scsilun(cmd->se_cmd.orig_fe_lun,
2524 (struct scsi_lun *)&hdr->lun);
2525 else
2526 put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);
2527
2528 hdr->itt = cpu_to_be32(cmd->init_task_tag);
2529 hdr->ttt = (hdr->flags & ISCSI_FLAG_DATA_ACK) ?
2530 cpu_to_be32(cmd->targ_xfer_tag) :
2531 0xFFFFFFFF;
2532 hdr->statsn = (set_statsn) ? cpu_to_be32(cmd->stat_sn) :
2533 0xFFFFFFFF;
2534 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
2535 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
2536 hdr->datasn = cpu_to_be32(datain.data_sn);
2537 hdr->offset = cpu_to_be32(datain.offset);
2538
2539 iov = &cmd->iov_data[0];
2540 iov[iov_count].iov_base = cmd->pdu;
2541 iov[iov_count++].iov_len = ISCSI_HDR_LEN;
2542 tx_size += ISCSI_HDR_LEN;
2543
2544 if (conn->conn_ops->HeaderDigest) {
2545 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
2546
2547 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
2548 (unsigned char *)hdr, ISCSI_HDR_LEN,
2549 0, NULL, (u8 *)header_digest);
2550
2551 iov[0].iov_len += ISCSI_CRC_LEN;
2552 tx_size += ISCSI_CRC_LEN;
2553
2554 pr_debug("Attaching CRC32 HeaderDigest"
2555 " for DataIN PDU 0x%08x\n", *header_digest);
2556 }
2557
2558 iov_ret = iscsit_map_iovec(cmd, &cmd->iov_data[1], datain.offset, datain.length);
2559 if (iov_ret < 0)
2560 return -1;
2561
2562 iov_count += iov_ret;
2563 tx_size += datain.length;
2564
2565 cmd->padding = ((-datain.length) & 3);
2566 if (cmd->padding) {
2567 iov[iov_count].iov_base = cmd->pad_bytes;
2568 iov[iov_count++].iov_len = cmd->padding;
2569 tx_size += cmd->padding;
2570
2571 pr_debug("Attaching %u padding bytes\n",
2572 cmd->padding);
2573 }
2574 if (conn->conn_ops->DataDigest) {
2575 cmd->data_crc = iscsit_do_crypto_hash_sg(&conn->conn_tx_hash, cmd,
2576 datain.offset, datain.length, cmd->padding, cmd->pad_bytes);
2577
2578 iov[iov_count].iov_base = &cmd->data_crc;
2579 iov[iov_count++].iov_len = ISCSI_CRC_LEN;
2580 tx_size += ISCSI_CRC_LEN;
2581
2582 pr_debug("Attached CRC32C DataDigest %d bytes, crc"
2583 " 0x%08x\n", datain.length+cmd->padding, cmd->data_crc);
2584 }
2585
2586 cmd->iov_data_count = iov_count;
2587 cmd->tx_size = tx_size;
2588
2589 pr_debug("Built DataIN ITT: 0x%08x, StatSN: 0x%08x,"
2590 " DataSN: 0x%08x, Offset: %u, Length: %u, CID: %hu\n",
2591 cmd->init_task_tag, ntohl(hdr->statsn), ntohl(hdr->datasn),
2592 ntohl(hdr->offset), datain.length, conn->cid);
2593
2594 if (dr->dr_complete) {
2595 *eodr = (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ?
2596 2 : 1;
2597 iscsit_free_datain_req(cmd, dr);
2598 }
2599
2600 return 0;
2601}
2602
2603static int iscsit_send_logout_response(
2604 struct iscsi_cmd *cmd,
2605 struct iscsi_conn *conn)
2606{
2607 int niov = 0, tx_size;
2608 struct iscsi_conn *logout_conn = NULL;
2609 struct iscsi_conn_recovery *cr = NULL;
2610 struct iscsi_session *sess = conn->sess;
2611 struct kvec *iov;
2612 struct iscsi_logout_rsp *hdr;
2613 /*
2614 * The actual shutting down of Sessions and/or Connections
2615 * for CLOSESESSION and CLOSECONNECTION Logout Requests
2616 * is done in scsi_logout_post_handler().
2617 */
2618 switch (cmd->logout_reason) {
2619 case ISCSI_LOGOUT_REASON_CLOSE_SESSION:
2620 pr_debug("iSCSI session logout successful, setting"
2621 " logout response to ISCSI_LOGOUT_SUCCESS.\n");
2622 cmd->logout_response = ISCSI_LOGOUT_SUCCESS;
2623 break;
2624 case ISCSI_LOGOUT_REASON_CLOSE_CONNECTION:
2625 if (cmd->logout_response == ISCSI_LOGOUT_CID_NOT_FOUND)
2626 break;
2627 /*
2628 * For CLOSECONNECTION logout requests carrying
2629 * a matching logout CID -> local CID, the reference
2630 * for the local CID will have been incremented in
2631 * iscsi_logout_closeconnection().
2632 *
2633 * For CLOSECONNECTION logout requests carrying
2634 * a different CID than the connection it arrived
2635 * on, the connection responding to cmd->logout_cid
2636 * is stopped in iscsit_logout_post_handler_diffcid().
2637 */
2638
2639 pr_debug("iSCSI CID: %hu logout on CID: %hu"
2640 " successful.\n", cmd->logout_cid, conn->cid);
2641 cmd->logout_response = ISCSI_LOGOUT_SUCCESS;
2642 break;
2643 case ISCSI_LOGOUT_REASON_RECOVERY:
2644 if ((cmd->logout_response == ISCSI_LOGOUT_RECOVERY_UNSUPPORTED) ||
2645 (cmd->logout_response == ISCSI_LOGOUT_CLEANUP_FAILED))
2646 break;
2647 /*
2648 * If the connection is still active from our point of view
2649 * force connection recovery to occur.
2650 */
2651 logout_conn = iscsit_get_conn_from_cid_rcfr(sess,
2652 cmd->logout_cid);
2653 if ((logout_conn)) {
2654 iscsit_connection_reinstatement_rcfr(logout_conn);
2655 iscsit_dec_conn_usage_count(logout_conn);
2656 }
2657
2658 cr = iscsit_get_inactive_connection_recovery_entry(
2659 conn->sess, cmd->logout_cid);
2660 if (!cr) {
2661 pr_err("Unable to locate CID: %hu for"
2662 " REMOVECONNFORRECOVERY Logout Request.\n",
2663 cmd->logout_cid);
2664 cmd->logout_response = ISCSI_LOGOUT_CID_NOT_FOUND;
2665 break;
2666 }
2667
2668 iscsit_discard_cr_cmds_by_expstatsn(cr, cmd->exp_stat_sn);
2669
2670 pr_debug("iSCSI REMOVECONNFORRECOVERY logout"
2671 " for recovery for CID: %hu on CID: %hu successful.\n",
2672 cmd->logout_cid, conn->cid);
2673 cmd->logout_response = ISCSI_LOGOUT_SUCCESS;
2674 break;
2675 default:
2676 pr_err("Unknown cmd->logout_reason: 0x%02x\n",
2677 cmd->logout_reason);
2678 return -1;
2679 }
2680
2681 tx_size = ISCSI_HDR_LEN;
2682 hdr = (struct iscsi_logout_rsp *)cmd->pdu;
2683 memset(hdr, 0, ISCSI_HDR_LEN);
2684 hdr->opcode = ISCSI_OP_LOGOUT_RSP;
2685 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
2686 hdr->response = cmd->logout_response;
2687 hdr->itt = cpu_to_be32(cmd->init_task_tag);
2688 cmd->stat_sn = conn->stat_sn++;
2689 hdr->statsn = cpu_to_be32(cmd->stat_sn);
2690
2691 iscsit_increment_maxcmdsn(cmd, conn->sess);
2692 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
2693 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
2694
2695 iov = &cmd->iov_misc[0];
2696 iov[niov].iov_base = cmd->pdu;
2697 iov[niov++].iov_len = ISCSI_HDR_LEN;
2698
2699 if (conn->conn_ops->HeaderDigest) {
2700 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
2701
2702 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
2703 (unsigned char *)hdr, ISCSI_HDR_LEN,
2704 0, NULL, (u8 *)header_digest);
2705
2706 iov[0].iov_len += ISCSI_CRC_LEN;
2707 tx_size += ISCSI_CRC_LEN;
2708 pr_debug("Attaching CRC32C HeaderDigest to"
2709 " Logout Response 0x%08x\n", *header_digest);
2710 }
2711 cmd->iov_misc_count = niov;
2712 cmd->tx_size = tx_size;
2713
2714 pr_debug("Sending Logout Response ITT: 0x%08x StatSN:"
2715 " 0x%08x Response: 0x%02x CID: %hu on CID: %hu\n",
2716 cmd->init_task_tag, cmd->stat_sn, hdr->response,
2717 cmd->logout_cid, conn->cid);
2718
2719 return 0;
2720}
2721
2722/*
2723 * Unsolicited NOPIN, either requesting a response or not.
2724 */
2725static int iscsit_send_unsolicited_nopin(
2726 struct iscsi_cmd *cmd,
2727 struct iscsi_conn *conn,
2728 int want_response)
2729{
2730 int tx_size = ISCSI_HDR_LEN;
2731 struct iscsi_nopin *hdr;
2732
2733 hdr = (struct iscsi_nopin *) cmd->pdu;
2734 memset(hdr, 0, ISCSI_HDR_LEN);
2735 hdr->opcode = ISCSI_OP_NOOP_IN;
2736 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
2737 hdr->itt = cpu_to_be32(cmd->init_task_tag);
2738 hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
2739 cmd->stat_sn = conn->stat_sn;
2740 hdr->statsn = cpu_to_be32(cmd->stat_sn);
2741 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
2742 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
2743
2744 if (conn->conn_ops->HeaderDigest) {
2745 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
2746
2747 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
2748 (unsigned char *)hdr, ISCSI_HDR_LEN,
2749 0, NULL, (u8 *)header_digest);
2750
2751 tx_size += ISCSI_CRC_LEN;
2752 pr_debug("Attaching CRC32C HeaderDigest to"
2753 " NopIN 0x%08x\n", *header_digest);
2754 }
2755
2756 cmd->iov_misc[0].iov_base = cmd->pdu;
2757 cmd->iov_misc[0].iov_len = tx_size;
2758 cmd->iov_misc_count = 1;
2759 cmd->tx_size = tx_size;
2760
2761 pr_debug("Sending Unsolicited NOPIN TTT: 0x%08x StatSN:"
2762 " 0x%08x CID: %hu\n", hdr->ttt, cmd->stat_sn, conn->cid);
2763
2764 return 0;
2765}
2766
2767static int iscsit_send_nopin_response(
2768 struct iscsi_cmd *cmd,
2769 struct iscsi_conn *conn)
2770{
2771 int niov = 0, tx_size;
2772 u32 padding = 0;
2773 struct kvec *iov;
2774 struct iscsi_nopin *hdr;
2775
2776 tx_size = ISCSI_HDR_LEN;
2777 hdr = (struct iscsi_nopin *) cmd->pdu;
2778 memset(hdr, 0, ISCSI_HDR_LEN);
2779 hdr->opcode = ISCSI_OP_NOOP_IN;
2780 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
2781 hton24(hdr->dlength, cmd->buf_ptr_size);
2782 put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);
2783 hdr->itt = cpu_to_be32(cmd->init_task_tag);
2784 hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
2785 cmd->stat_sn = conn->stat_sn++;
2786 hdr->statsn = cpu_to_be32(cmd->stat_sn);
2787
2788 iscsit_increment_maxcmdsn(cmd, conn->sess);
2789 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
2790 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
2791
2792 iov = &cmd->iov_misc[0];
2793 iov[niov].iov_base = cmd->pdu;
2794 iov[niov++].iov_len = ISCSI_HDR_LEN;
2795
2796 if (conn->conn_ops->HeaderDigest) {
2797 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
2798
2799 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
2800 (unsigned char *)hdr, ISCSI_HDR_LEN,
2801 0, NULL, (u8 *)header_digest);
2802
2803 iov[0].iov_len += ISCSI_CRC_LEN;
2804 tx_size += ISCSI_CRC_LEN;
2805 pr_debug("Attaching CRC32C HeaderDigest"
2806 " to NopIn 0x%08x\n", *header_digest);
2807 }
2808
2809 /*
2810 * NOPOUT Ping Data is attached to struct iscsi_cmd->buf_ptr.
2811 * NOPOUT DataSegmentLength is at struct iscsi_cmd->buf_ptr_size.
2812 */
2813 if (cmd->buf_ptr_size) {
2814 iov[niov].iov_base = cmd->buf_ptr;
2815 iov[niov++].iov_len = cmd->buf_ptr_size;
2816 tx_size += cmd->buf_ptr_size;
2817
2818 pr_debug("Echoing back %u bytes of ping"
2819 " data.\n", cmd->buf_ptr_size);
2820
2821 padding = ((-cmd->buf_ptr_size) & 3);
2822 if (padding != 0) {
2823 iov[niov].iov_base = &cmd->pad_bytes;
2824 iov[niov++].iov_len = padding;
2825 tx_size += padding;
2826 pr_debug("Attaching %u additional"
2827 " padding bytes.\n", padding);
2828 }
2829 if (conn->conn_ops->DataDigest) {
2830 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
2831 cmd->buf_ptr, cmd->buf_ptr_size,
2832 padding, (u8 *)&cmd->pad_bytes,
2833 (u8 *)&cmd->data_crc);
2834
2835 iov[niov].iov_base = &cmd->data_crc;
2836 iov[niov++].iov_len = ISCSI_CRC_LEN;
2837 tx_size += ISCSI_CRC_LEN;
2838 pr_debug("Attached DataDigest for %u"
2839 " bytes of ping data, CRC 0x%08x\n",
2840 cmd->buf_ptr_size, cmd->data_crc);
2841 }
2842 }
2843
2844 cmd->iov_misc_count = niov;
2845 cmd->tx_size = tx_size;
2846
2847 pr_debug("Sending NOPIN Response ITT: 0x%08x, TTT:"
2848 " 0x%08x, StatSN: 0x%08x, Length %u\n", cmd->init_task_tag,
2849 cmd->targ_xfer_tag, cmd->stat_sn, cmd->buf_ptr_size);
2850
2851 return 0;
2852}
2853
2854int iscsit_send_r2t(
2855 struct iscsi_cmd *cmd,
2856 struct iscsi_conn *conn)
2857{
2858 int tx_size = 0;
2859 struct iscsi_r2t *r2t;
2860 struct iscsi_r2t_rsp *hdr;
2861
2862 r2t = iscsit_get_r2t_from_list(cmd);
2863 if (!r2t)
2864 return -1;
2865
2866 hdr = (struct iscsi_r2t_rsp *) cmd->pdu;
2867 memset(hdr, 0, ISCSI_HDR_LEN);
2868 hdr->opcode = ISCSI_OP_R2T;
2869 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
2870 int_to_scsilun(cmd->se_cmd.orig_fe_lun,
2871 (struct scsi_lun *)&hdr->lun);
2872 hdr->itt = cpu_to_be32(cmd->init_task_tag);
2873 spin_lock_bh(&conn->sess->ttt_lock);
2874 r2t->targ_xfer_tag = conn->sess->targ_xfer_tag++;
2875 if (r2t->targ_xfer_tag == 0xFFFFFFFF)
2876 r2t->targ_xfer_tag = conn->sess->targ_xfer_tag++;
2877 spin_unlock_bh(&conn->sess->ttt_lock);
2878 hdr->ttt = cpu_to_be32(r2t->targ_xfer_tag);
2879 hdr->statsn = cpu_to_be32(conn->stat_sn);
2880 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
2881 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
2882 hdr->r2tsn = cpu_to_be32(r2t->r2t_sn);
2883 hdr->data_offset = cpu_to_be32(r2t->offset);
2884 hdr->data_length = cpu_to_be32(r2t->xfer_len);
2885
2886 cmd->iov_misc[0].iov_base = cmd->pdu;
2887 cmd->iov_misc[0].iov_len = ISCSI_HDR_LEN;
2888 tx_size += ISCSI_HDR_LEN;
2889
2890 if (conn->conn_ops->HeaderDigest) {
2891 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
2892
2893 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
2894 (unsigned char *)hdr, ISCSI_HDR_LEN,
2895 0, NULL, (u8 *)header_digest);
2896
2897 cmd->iov_misc[0].iov_len += ISCSI_CRC_LEN;
2898 tx_size += ISCSI_CRC_LEN;
2899 pr_debug("Attaching CRC32 HeaderDigest for R2T"
2900 " PDU 0x%08x\n", *header_digest);
2901 }
2902
2903 pr_debug("Built %sR2T, ITT: 0x%08x, TTT: 0x%08x, StatSN:"
2904 " 0x%08x, R2TSN: 0x%08x, Offset: %u, DDTL: %u, CID: %hu\n",
2905 (!r2t->recovery_r2t) ? "" : "Recovery ", cmd->init_task_tag,
2906 r2t->targ_xfer_tag, ntohl(hdr->statsn), r2t->r2t_sn,
2907 r2t->offset, r2t->xfer_len, conn->cid);
2908
2909 cmd->iov_misc_count = 1;
2910 cmd->tx_size = tx_size;
2911
2912 spin_lock_bh(&cmd->r2t_lock);
2913 r2t->sent_r2t = 1;
2914 spin_unlock_bh(&cmd->r2t_lock);
2915
2916 return 0;
2917}
2918
2919/*
2920 * type 0: Normal Operation.
2921 * type 1: Called from Storage Transport.
2922 * type 2: Called from iscsi_task_reassign_complete_write() for
2923 * connection recovery.
2924 */
2925int iscsit_build_r2ts_for_cmd(
2926 struct iscsi_cmd *cmd,
2927 struct iscsi_conn *conn,
2928 int type)
2929{
2930 int first_r2t = 1;
2931 u32 offset = 0, xfer_len = 0;
2932
2933 spin_lock_bh(&cmd->r2t_lock);
2934 if (cmd->cmd_flags & ICF_SENT_LAST_R2T) {
2935 spin_unlock_bh(&cmd->r2t_lock);
2936 return 0;
2937 }
2938
2939 if (conn->sess->sess_ops->DataSequenceInOrder && (type != 2))
2940 if (cmd->r2t_offset < cmd->write_data_done)
2941 cmd->r2t_offset = cmd->write_data_done;
2942
2943 while (cmd->outstanding_r2ts < conn->sess->sess_ops->MaxOutstandingR2T) {
2944 if (conn->sess->sess_ops->DataSequenceInOrder) {
2945 offset = cmd->r2t_offset;
2946
2947 if (first_r2t && (type == 2)) {
2948 xfer_len = ((offset +
2949 (conn->sess->sess_ops->MaxBurstLength -
2950 cmd->next_burst_len) >
2951 cmd->data_length) ?
2952 (cmd->data_length - offset) :
2953 (conn->sess->sess_ops->MaxBurstLength -
2954 cmd->next_burst_len));
2955 } else {
2956 xfer_len = ((offset +
2957 conn->sess->sess_ops->MaxBurstLength) >
2958 cmd->data_length) ?
2959 (cmd->data_length - offset) :
2960 conn->sess->sess_ops->MaxBurstLength;
2961 }
2962 cmd->r2t_offset += xfer_len;
2963
2964 if (cmd->r2t_offset == cmd->data_length)
2965 cmd->cmd_flags |= ICF_SENT_LAST_R2T;
2966 } else {
2967 struct iscsi_seq *seq;
2968
2969 seq = iscsit_get_seq_holder_for_r2t(cmd);
2970 if (!seq) {
2971 spin_unlock_bh(&cmd->r2t_lock);
2972 return -1;
2973 }
2974
2975 offset = seq->offset;
2976 xfer_len = seq->xfer_len;
2977
2978 if (cmd->seq_send_order == cmd->seq_count)
2979 cmd->cmd_flags |= ICF_SENT_LAST_R2T;
2980 }
2981 cmd->outstanding_r2ts++;
2982 first_r2t = 0;
2983
2984 if (iscsit_add_r2t_to_list(cmd, offset, xfer_len, 0, 0) < 0) {
2985 spin_unlock_bh(&cmd->r2t_lock);
2986 return -1;
2987 }
2988
2989 if (cmd->cmd_flags & ICF_SENT_LAST_R2T)
2990 break;
2991 }
2992 spin_unlock_bh(&cmd->r2t_lock);
2993
2994 return 0;
2995}
2996
2997static int iscsit_send_status(
2998 struct iscsi_cmd *cmd,
2999 struct iscsi_conn *conn)
3000{
3001 u8 iov_count = 0, recovery;
3002 u32 padding = 0, tx_size = 0;
3003 struct iscsi_scsi_rsp *hdr;
3004 struct kvec *iov;
3005
3006 recovery = (cmd->i_state != ISTATE_SEND_STATUS);
3007 if (!recovery)
3008 cmd->stat_sn = conn->stat_sn++;
3009
3010 spin_lock_bh(&conn->sess->session_stats_lock);
3011 conn->sess->rsp_pdus++;
3012 spin_unlock_bh(&conn->sess->session_stats_lock);
3013
3014 hdr = (struct iscsi_scsi_rsp *) cmd->pdu;
3015 memset(hdr, 0, ISCSI_HDR_LEN);
3016 hdr->opcode = ISCSI_OP_SCSI_CMD_RSP;
3017 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
3018 if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) {
3019 hdr->flags |= ISCSI_FLAG_CMD_OVERFLOW;
3020 hdr->residual_count = cpu_to_be32(cmd->residual_count);
3021 } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) {
3022 hdr->flags |= ISCSI_FLAG_CMD_UNDERFLOW;
3023 hdr->residual_count = cpu_to_be32(cmd->residual_count);
3024 }
3025 hdr->response = cmd->iscsi_response;
3026 hdr->cmd_status = cmd->se_cmd.scsi_status;
3027 hdr->itt = cpu_to_be32(cmd->init_task_tag);
3028 hdr->statsn = cpu_to_be32(cmd->stat_sn);
3029
3030 iscsit_increment_maxcmdsn(cmd, conn->sess);
3031 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
3032 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
3033
3034 iov = &cmd->iov_misc[0];
3035 iov[iov_count].iov_base = cmd->pdu;
3036 iov[iov_count++].iov_len = ISCSI_HDR_LEN;
3037 tx_size += ISCSI_HDR_LEN;
3038
3039 /*
3040 * Attach SENSE DATA payload to iSCSI Response PDU
3041 */
3042 if (cmd->se_cmd.sense_buffer &&
3043 ((cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||
3044 (cmd->se_cmd.se_cmd_flags & SCF_EMULATED_TASK_SENSE))) {
3045 padding = -(cmd->se_cmd.scsi_sense_length) & 3;
3046 hton24(hdr->dlength, cmd->se_cmd.scsi_sense_length);
3047 iov[iov_count].iov_base = cmd->se_cmd.sense_buffer;
3048 iov[iov_count++].iov_len =
3049 (cmd->se_cmd.scsi_sense_length + padding);
3050 tx_size += cmd->se_cmd.scsi_sense_length;
3051
3052 if (padding) {
3053 memset(cmd->se_cmd.sense_buffer +
3054 cmd->se_cmd.scsi_sense_length, 0, padding);
3055 tx_size += padding;
3056 pr_debug("Adding %u bytes of padding to"
3057 " SENSE.\n", padding);
3058 }
3059
3060 if (conn->conn_ops->DataDigest) {
3061 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
3062 cmd->se_cmd.sense_buffer,
3063 (cmd->se_cmd.scsi_sense_length + padding),
3064 0, NULL, (u8 *)&cmd->data_crc);
3065
3066 iov[iov_count].iov_base = &cmd->data_crc;
3067 iov[iov_count++].iov_len = ISCSI_CRC_LEN;
3068 tx_size += ISCSI_CRC_LEN;
3069
3070 pr_debug("Attaching CRC32 DataDigest for"
3071 " SENSE, %u bytes CRC 0x%08x\n",
3072 (cmd->se_cmd.scsi_sense_length + padding),
3073 cmd->data_crc);
3074 }
3075
3076 pr_debug("Attaching SENSE DATA: %u bytes to iSCSI"
3077 " Response PDU\n",
3078 cmd->se_cmd.scsi_sense_length);
3079 }
3080
3081 if (conn->conn_ops->HeaderDigest) {
3082 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
3083
3084 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
3085 (unsigned char *)hdr, ISCSI_HDR_LEN,
3086 0, NULL, (u8 *)header_digest);
3087
3088 iov[0].iov_len += ISCSI_CRC_LEN;
3089 tx_size += ISCSI_CRC_LEN;
3090 pr_debug("Attaching CRC32 HeaderDigest for Response"
3091 " PDU 0x%08x\n", *header_digest);
3092 }
3093
3094 cmd->iov_misc_count = iov_count;
3095 cmd->tx_size = tx_size;
3096
3097 pr_debug("Built %sSCSI Response, ITT: 0x%08x, StatSN: 0x%08x,"
3098 " Response: 0x%02x, SAM Status: 0x%02x, CID: %hu\n",
3099 (!recovery) ? "" : "Recovery ", cmd->init_task_tag,
3100 cmd->stat_sn, 0x00, cmd->se_cmd.scsi_status, conn->cid);
3101
3102 return 0;
3103}
3104
3105static u8 iscsit_convert_tcm_tmr_rsp(struct se_tmr_req *se_tmr)
3106{
3107 switch (se_tmr->response) {
3108 case TMR_FUNCTION_COMPLETE:
3109 return ISCSI_TMF_RSP_COMPLETE;
3110 case TMR_TASK_DOES_NOT_EXIST:
3111 return ISCSI_TMF_RSP_NO_TASK;
3112 case TMR_LUN_DOES_NOT_EXIST:
3113 return ISCSI_TMF_RSP_NO_LUN;
3114 case TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED:
3115 return ISCSI_TMF_RSP_NOT_SUPPORTED;
3116 case TMR_FUNCTION_AUTHORIZATION_FAILED:
3117 return ISCSI_TMF_RSP_AUTH_FAILED;
3118 case TMR_FUNCTION_REJECTED:
3119 default:
3120 return ISCSI_TMF_RSP_REJECTED;
3121 }
3122}
3123
3124static int iscsit_send_task_mgt_rsp(
3125 struct iscsi_cmd *cmd,
3126 struct iscsi_conn *conn)
3127{
3128 struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
3129 struct iscsi_tm_rsp *hdr;
3130 u32 tx_size = 0;
3131
3132 hdr = (struct iscsi_tm_rsp *) cmd->pdu;
3133 memset(hdr, 0, ISCSI_HDR_LEN);
3134 hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP;
3135 hdr->response = iscsit_convert_tcm_tmr_rsp(se_tmr);
3136 hdr->itt = cpu_to_be32(cmd->init_task_tag);
3137 cmd->stat_sn = conn->stat_sn++;
3138 hdr->statsn = cpu_to_be32(cmd->stat_sn);
3139
3140 iscsit_increment_maxcmdsn(cmd, conn->sess);
3141 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
3142 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
3143
3144 cmd->iov_misc[0].iov_base = cmd->pdu;
3145 cmd->iov_misc[0].iov_len = ISCSI_HDR_LEN;
3146 tx_size += ISCSI_HDR_LEN;
3147
3148 if (conn->conn_ops->HeaderDigest) {
3149 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
3150
3151 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
3152 (unsigned char *)hdr, ISCSI_HDR_LEN,
3153 0, NULL, (u8 *)header_digest);
3154
3155 cmd->iov_misc[0].iov_len += ISCSI_CRC_LEN;
3156 tx_size += ISCSI_CRC_LEN;
3157 pr_debug("Attaching CRC32 HeaderDigest for Task"
3158 " Mgmt Response PDU 0x%08x\n", *header_digest);
3159 }
3160
3161 cmd->iov_misc_count = 1;
3162 cmd->tx_size = tx_size;
3163
3164 pr_debug("Built Task Management Response ITT: 0x%08x,"
3165 " StatSN: 0x%08x, Response: 0x%02x, CID: %hu\n",
3166 cmd->init_task_tag, cmd->stat_sn, hdr->response, conn->cid);
3167
3168 return 0;
3169}
3170
3171static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd)
3172{
3173 char *payload = NULL;
3174 struct iscsi_conn *conn = cmd->conn;
3175 struct iscsi_portal_group *tpg;
3176 struct iscsi_tiqn *tiqn;
3177 struct iscsi_tpg_np *tpg_np;
3178 int buffer_len, end_of_buf = 0, len = 0, payload_len = 0;
3179 unsigned char buf[256];
3180
3181 buffer_len = (conn->conn_ops->MaxRecvDataSegmentLength > 32768) ?
3182 32768 : conn->conn_ops->MaxRecvDataSegmentLength;
3183
3184 memset(buf, 0, 256);
3185
3186 payload = kzalloc(buffer_len, GFP_KERNEL);
3187 if (!payload) {
3188 pr_err("Unable to allocate memory for sendtargets"
3189 " response.\n");
3190 return -ENOMEM;
3191 }
3192
3193 spin_lock(&tiqn_lock);
3194 list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) {
3195 len = sprintf(buf, "TargetName=%s", tiqn->tiqn);
3196 len += 1;
3197
3198 if ((len + payload_len) > buffer_len) {
3199 spin_unlock(&tiqn->tiqn_tpg_lock);
3200 end_of_buf = 1;
3201 goto eob;
3202 }
3203 memcpy((void *)payload + payload_len, buf, len);
3204 payload_len += len;
3205
3206 spin_lock(&tiqn->tiqn_tpg_lock);
3207 list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
3208
3209 spin_lock(&tpg->tpg_state_lock);
3210 if ((tpg->tpg_state == TPG_STATE_FREE) ||
3211 (tpg->tpg_state == TPG_STATE_INACTIVE)) {
3212 spin_unlock(&tpg->tpg_state_lock);
3213 continue;
3214 }
3215 spin_unlock(&tpg->tpg_state_lock);
3216
3217 spin_lock(&tpg->tpg_np_lock);
3218 list_for_each_entry(tpg_np, &tpg->tpg_gnp_list,
3219 tpg_np_list) {
3220 len = sprintf(buf, "TargetAddress="
3221 "%s%s%s:%hu,%hu",
3222 (tpg_np->tpg_np->np_sockaddr.ss_family == AF_INET6) ?
3223 "[" : "", tpg_np->tpg_np->np_ip,
3224 (tpg_np->tpg_np->np_sockaddr.ss_family == AF_INET6) ?
3225 "]" : "", tpg_np->tpg_np->np_port,
3226 tpg->tpgt);
3227 len += 1;
3228
3229 if ((len + payload_len) > buffer_len) {
3230 spin_unlock(&tpg->tpg_np_lock);
3231 spin_unlock(&tiqn->tiqn_tpg_lock);
3232 end_of_buf = 1;
3233 goto eob;
3234 }
3235 memcpy((void *)payload + payload_len, buf, len);
3236 payload_len += len;
3237 }
3238 spin_unlock(&tpg->tpg_np_lock);
3239 }
3240 spin_unlock(&tiqn->tiqn_tpg_lock);
3241eob:
3242 if (end_of_buf)
3243 break;
3244 }
3245 spin_unlock(&tiqn_lock);
3246
3247 cmd->buf_ptr = payload;
3248
3249 return payload_len;
3250}
3251
3252/*
3253 * FIXME: Add support for F_BIT and C_BIT when the length is longer than
3254 * MaxRecvDataSegmentLength.
3255 */
3256static int iscsit_send_text_rsp(
3257 struct iscsi_cmd *cmd,
3258 struct iscsi_conn *conn)
3259{
3260 struct iscsi_text_rsp *hdr;
3261 struct kvec *iov;
3262 u32 padding = 0, tx_size = 0;
3263 int text_length, iov_count = 0;
3264
3265 text_length = iscsit_build_sendtargets_response(cmd);
3266 if (text_length < 0)
3267 return text_length;
3268
3269 padding = ((-text_length) & 3);
3270 if (padding != 0) {
3271 memset(cmd->buf_ptr + text_length, 0, padding);
3272 pr_debug("Attaching %u additional bytes for"
3273 " padding.\n", padding);
3274 }
3275
3276 hdr = (struct iscsi_text_rsp *) cmd->pdu;
3277 memset(hdr, 0, ISCSI_HDR_LEN);
3278 hdr->opcode = ISCSI_OP_TEXT_RSP;
3279 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
3280 hton24(hdr->dlength, text_length);
3281 hdr->itt = cpu_to_be32(cmd->init_task_tag);
3282 hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
3283 cmd->stat_sn = conn->stat_sn++;
3284 hdr->statsn = cpu_to_be32(cmd->stat_sn);
3285
3286 iscsit_increment_maxcmdsn(cmd, conn->sess);
3287 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
3288 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
3289
3290 iov = &cmd->iov_misc[0];
3291
3292 iov[iov_count].iov_base = cmd->pdu;
3293 iov[iov_count++].iov_len = ISCSI_HDR_LEN;
3294 iov[iov_count].iov_base = cmd->buf_ptr;
3295 iov[iov_count++].iov_len = text_length + padding;
3296
3297 tx_size += (ISCSI_HDR_LEN + text_length + padding);
3298
3299 if (conn->conn_ops->HeaderDigest) {
3300 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
3301
3302 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
3303 (unsigned char *)hdr, ISCSI_HDR_LEN,
3304 0, NULL, (u8 *)header_digest);
3305
3306 iov[0].iov_len += ISCSI_CRC_LEN;
3307 tx_size += ISCSI_CRC_LEN;
3308 pr_debug("Attaching CRC32 HeaderDigest for"
3309 " Text Response PDU 0x%08x\n", *header_digest);
3310 }
3311
3312 if (conn->conn_ops->DataDigest) {
3313 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
3314 cmd->buf_ptr, (text_length + padding),
3315 0, NULL, (u8 *)&cmd->data_crc);
3316
3317 iov[iov_count].iov_base = &cmd->data_crc;
3318 iov[iov_count++].iov_len = ISCSI_CRC_LEN;
3319 tx_size += ISCSI_CRC_LEN;
3320
3321 pr_debug("Attaching DataDigest for %u bytes of text"
3322 " data, CRC 0x%08x\n", (text_length + padding),
3323 cmd->data_crc);
3324 }
3325
3326 cmd->iov_misc_count = iov_count;
3327 cmd->tx_size = tx_size;
3328
3329 pr_debug("Built Text Response: ITT: 0x%08x, StatSN: 0x%08x,"
3330 " Length: %u, CID: %hu\n", cmd->init_task_tag, cmd->stat_sn,
3331 text_length, conn->cid);
3332 return 0;
3333}
3334
3335static int iscsit_send_reject(
3336 struct iscsi_cmd *cmd,
3337 struct iscsi_conn *conn)
3338{
3339 u32 iov_count = 0, tx_size = 0;
3340 struct iscsi_reject *hdr;
3341 struct kvec *iov;
3342
3343 hdr = (struct iscsi_reject *) cmd->pdu;
3344 hdr->opcode = ISCSI_OP_REJECT;
3345 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
3346 hton24(hdr->dlength, ISCSI_HDR_LEN);
3347 cmd->stat_sn = conn->stat_sn++;
3348 hdr->statsn = cpu_to_be32(cmd->stat_sn);
3349 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
3350 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
3351
3352 iov = &cmd->iov_misc[0];
3353
3354 iov[iov_count].iov_base = cmd->pdu;
3355 iov[iov_count++].iov_len = ISCSI_HDR_LEN;
3356 iov[iov_count].iov_base = cmd->buf_ptr;
3357 iov[iov_count++].iov_len = ISCSI_HDR_LEN;
3358
3359 tx_size = (ISCSI_HDR_LEN + ISCSI_HDR_LEN);
3360
3361 if (conn->conn_ops->HeaderDigest) {
3362 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
3363
3364 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
3365 (unsigned char *)hdr, ISCSI_HDR_LEN,
3366 0, NULL, (u8 *)header_digest);
3367
3368 iov[0].iov_len += ISCSI_CRC_LEN;
3369 tx_size += ISCSI_CRC_LEN;
3370 pr_debug("Attaching CRC32 HeaderDigest for"
3371 " REJECT PDU 0x%08x\n", *header_digest);
3372 }
3373
3374 if (conn->conn_ops->DataDigest) {
3375 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
3376 (unsigned char *)cmd->buf_ptr, ISCSI_HDR_LEN,
3377 0, NULL, (u8 *)&cmd->data_crc);
3378
3379 iov[iov_count].iov_base = &cmd->data_crc;
3380 iov[iov_count++].iov_len = ISCSI_CRC_LEN;
3381 tx_size += ISCSI_CRC_LEN;
3382 pr_debug("Attaching CRC32 DataDigest for REJECT"
3383 " PDU 0x%08x\n", cmd->data_crc);
3384 }
3385
3386 cmd->iov_misc_count = iov_count;
3387 cmd->tx_size = tx_size;
3388
3389 pr_debug("Built Reject PDU StatSN: 0x%08x, Reason: 0x%02x,"
3390 " CID: %hu\n", ntohl(hdr->statsn), hdr->reason, conn->cid);
3391
3392 return 0;
3393}
3394
3395static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn)
3396{
3397 if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) ||
3398 (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) {
3399 wait_for_completion_interruptible_timeout(
3400 &conn->tx_half_close_comp,
3401 ISCSI_TX_THREAD_TCP_TIMEOUT * HZ);
3402 }
3403}
3404
3405#ifdef CONFIG_SMP
3406
3407void iscsit_thread_get_cpumask(struct iscsi_conn *conn)
3408{
3409 struct iscsi_thread_set *ts = conn->thread_set;
3410 int ord, cpu;
3411 /*
3412 * thread_id is assigned from iscsit_global->ts_bitmap from
3413 * within iscsi_thread_set.c:iscsi_allocate_thread_sets()
3414 *
3415 * Here we use thread_id to determine which CPU that this
3416 * iSCSI connection's iscsi_thread_set will be scheduled to
3417 * execute upon.
3418 */
3419 ord = ts->thread_id % cpumask_weight(cpu_online_mask);
3420#if 0
3421 pr_debug(">>>>>>>>>>>>>>>>>>>> Generated ord: %d from"
3422 " thread_id: %d\n", ord, ts->thread_id);
3423#endif
3424 for_each_online_cpu(cpu) {
3425 if (ord-- == 0) {
3426 cpumask_set_cpu(cpu, conn->conn_cpumask);
3427 return;
3428 }
3429 }
3430 /*
3431 * This should never be reached..
3432 */
3433 dump_stack();
3434 cpumask_setall(conn->conn_cpumask);
3435}
3436
3437static inline void iscsit_thread_check_cpumask(
3438 struct iscsi_conn *conn,
3439 struct task_struct *p,
3440 int mode)
3441{
3442 char buf[128];
3443 /*
3444 * mode == 1 signals iscsi_target_tx_thread() usage.
3445 * mode == 0 signals iscsi_target_rx_thread() usage.
3446 */
3447 if (mode == 1) {
3448 if (!conn->conn_tx_reset_cpumask)
3449 return;
3450 conn->conn_tx_reset_cpumask = 0;
3451 } else {
3452 if (!conn->conn_rx_reset_cpumask)
3453 return;
3454 conn->conn_rx_reset_cpumask = 0;
3455 }
3456 /*
3457 * Update the CPU mask for this single kthread so that
3458 * both TX and RX kthreads are scheduled to run on the
3459 * same CPU.
3460 */
3461 memset(buf, 0, 128);
3462 cpumask_scnprintf(buf, 128, conn->conn_cpumask);
3463#if 0
3464 pr_debug(">>>>>>>>>>>>>> Calling set_cpus_allowed_ptr():"
3465 " %s for %s\n", buf, p->comm);
3466#endif
3467 set_cpus_allowed_ptr(p, conn->conn_cpumask);
3468}
3469
3470#else
3471#define iscsit_thread_get_cpumask(X) ({})
3472#define iscsit_thread_check_cpumask(X, Y, Z) ({})
3473#endif /* CONFIG_SMP */
3474
3475int iscsi_target_tx_thread(void *arg)
3476{
3477 u8 state;
3478 int eodr = 0;
3479 int ret = 0;
3480 int sent_status = 0;
3481 int use_misc = 0;
3482 int map_sg = 0;
3483 struct iscsi_cmd *cmd = NULL;
3484 struct iscsi_conn *conn;
3485 struct iscsi_queue_req *qr = NULL;
3486 struct se_cmd *se_cmd;
3487 struct iscsi_thread_set *ts = (struct iscsi_thread_set *)arg;
3488 /*
3489 * Allow ourselves to be interrupted by SIGINT so that a
3490 * connection recovery / failure event can be triggered externally.
3491 */
3492 allow_signal(SIGINT);
3493
3494restart:
3495 conn = iscsi_tx_thread_pre_handler(ts);
3496 if (!conn)
3497 goto out;
3498
3499 eodr = map_sg = ret = sent_status = use_misc = 0;
3500
3501 while (!kthread_should_stop()) {
3502 /*
3503 * Ensure that both TX and RX per connection kthreads
3504 * are scheduled to run on the same CPU.
3505 */
3506 iscsit_thread_check_cpumask(conn, current, 1);
3507
3508 schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
3509
3510 if ((ts->status == ISCSI_THREAD_SET_RESET) ||
3511 signal_pending(current))
3512 goto transport_err;
3513
3514get_immediate:
3515 qr = iscsit_get_cmd_from_immediate_queue(conn);
3516 if (qr) {
3517 atomic_set(&conn->check_immediate_queue, 0);
3518 cmd = qr->cmd;
3519 state = qr->state;
3520 kmem_cache_free(lio_qr_cache, qr);
3521
3522 spin_lock_bh(&cmd->istate_lock);
3523 switch (state) {
3524 case ISTATE_SEND_R2T:
3525 spin_unlock_bh(&cmd->istate_lock);
3526 ret = iscsit_send_r2t(cmd, conn);
3527 break;
3528 case ISTATE_REMOVE:
3529 spin_unlock_bh(&cmd->istate_lock);
3530
3531 if (cmd->data_direction == DMA_TO_DEVICE)
3532 iscsit_stop_dataout_timer(cmd);
3533
3534 spin_lock_bh(&conn->cmd_lock);
3535 list_del(&cmd->i_list);
3536 spin_unlock_bh(&conn->cmd_lock);
3537 /*
3538 * Determine if a struct se_cmd is assoicated with
3539 * this struct iscsi_cmd.
3540 */
3541 if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) &&
3542 !(cmd->tmr_req))
3543 iscsit_release_cmd(cmd);
3544 else
3545 transport_generic_free_cmd(&cmd->se_cmd,
3546 1, 0);
3547 goto get_immediate;
3548 case ISTATE_SEND_NOPIN_WANT_RESPONSE:
3549 spin_unlock_bh(&cmd->istate_lock);
3550 iscsit_mod_nopin_response_timer(conn);
3551 ret = iscsit_send_unsolicited_nopin(cmd,
3552 conn, 1);
3553 break;
3554 case ISTATE_SEND_NOPIN_NO_RESPONSE:
3555 spin_unlock_bh(&cmd->istate_lock);
3556 ret = iscsit_send_unsolicited_nopin(cmd,
3557 conn, 0);
3558 break;
3559 default:
3560 pr_err("Unknown Opcode: 0x%02x ITT:"
3561 " 0x%08x, i_state: %d on CID: %hu\n",
3562 cmd->iscsi_opcode, cmd->init_task_tag, state,
3563 conn->cid);
3564 spin_unlock_bh(&cmd->istate_lock);
3565 goto transport_err;
3566 }
3567 if (ret < 0) {
3568 conn->tx_immediate_queue = 0;
3569 goto transport_err;
3570 }
3571
3572 if (iscsit_send_tx_data(cmd, conn, 1) < 0) {
3573 conn->tx_immediate_queue = 0;
3574 iscsit_tx_thread_wait_for_tcp(conn);
3575 goto transport_err;
3576 }
3577
3578 spin_lock_bh(&cmd->istate_lock);
3579 switch (state) {
3580 case ISTATE_SEND_R2T:
3581 spin_unlock_bh(&cmd->istate_lock);
3582 spin_lock_bh(&cmd->dataout_timeout_lock);
3583 iscsit_start_dataout_timer(cmd, conn);
3584 spin_unlock_bh(&cmd->dataout_timeout_lock);
3585 break;
3586 case ISTATE_SEND_NOPIN_WANT_RESPONSE:
3587 cmd->i_state = ISTATE_SENT_NOPIN_WANT_RESPONSE;
3588 spin_unlock_bh(&cmd->istate_lock);
3589 break;
3590 case ISTATE_SEND_NOPIN_NO_RESPONSE:
3591 cmd->i_state = ISTATE_SENT_STATUS;
3592 spin_unlock_bh(&cmd->istate_lock);
3593 break;
3594 default:
3595 pr_err("Unknown Opcode: 0x%02x ITT:"
3596 " 0x%08x, i_state: %d on CID: %hu\n",
3597 cmd->iscsi_opcode, cmd->init_task_tag,
3598 state, conn->cid);
3599 spin_unlock_bh(&cmd->istate_lock);
3600 goto transport_err;
3601 }
3602 goto get_immediate;
3603 } else
3604 conn->tx_immediate_queue = 0;
3605
3606get_response:
3607 qr = iscsit_get_cmd_from_response_queue(conn);
3608 if (qr) {
3609 cmd = qr->cmd;
3610 state = qr->state;
3611 kmem_cache_free(lio_qr_cache, qr);
3612
3613 spin_lock_bh(&cmd->istate_lock);
3614check_rsp_state:
3615 switch (state) {
3616 case ISTATE_SEND_DATAIN:
3617 spin_unlock_bh(&cmd->istate_lock);
3618 ret = iscsit_send_data_in(cmd, conn,
3619 &eodr);
3620 map_sg = 1;
3621 break;
3622 case ISTATE_SEND_STATUS:
3623 case ISTATE_SEND_STATUS_RECOVERY:
3624 spin_unlock_bh(&cmd->istate_lock);
3625 use_misc = 1;
3626 ret = iscsit_send_status(cmd, conn);
3627 break;
3628 case ISTATE_SEND_LOGOUTRSP:
3629 spin_unlock_bh(&cmd->istate_lock);
3630 use_misc = 1;
3631 ret = iscsit_send_logout_response(cmd, conn);
3632 break;
3633 case ISTATE_SEND_ASYNCMSG:
3634 spin_unlock_bh(&cmd->istate_lock);
3635 use_misc = 1;
3636 ret = iscsit_send_conn_drop_async_message(
3637 cmd, conn);
3638 break;
3639 case ISTATE_SEND_NOPIN:
3640 spin_unlock_bh(&cmd->istate_lock);
3641 use_misc = 1;
3642 ret = iscsit_send_nopin_response(cmd, conn);
3643 break;
3644 case ISTATE_SEND_REJECT:
3645 spin_unlock_bh(&cmd->istate_lock);
3646 use_misc = 1;
3647 ret = iscsit_send_reject(cmd, conn);
3648 break;
3649 case ISTATE_SEND_TASKMGTRSP:
3650 spin_unlock_bh(&cmd->istate_lock);
3651 use_misc = 1;
3652 ret = iscsit_send_task_mgt_rsp(cmd, conn);
3653 if (ret != 0)
3654 break;
3655 ret = iscsit_tmr_post_handler(cmd, conn);
3656 if (ret != 0)
3657 iscsit_fall_back_to_erl0(conn->sess);
3658 break;
3659 case ISTATE_SEND_TEXTRSP:
3660 spin_unlock_bh(&cmd->istate_lock);
3661 use_misc = 1;
3662 ret = iscsit_send_text_rsp(cmd, conn);
3663 break;
3664 default:
3665 pr_err("Unknown Opcode: 0x%02x ITT:"
3666 " 0x%08x, i_state: %d on CID: %hu\n",
3667 cmd->iscsi_opcode, cmd->init_task_tag,
3668 state, conn->cid);
3669 spin_unlock_bh(&cmd->istate_lock);
3670 goto transport_err;
3671 }
3672 if (ret < 0) {
3673 conn->tx_response_queue = 0;
3674 goto transport_err;
3675 }
3676
3677 se_cmd = &cmd->se_cmd;
3678
3679 if (map_sg && !conn->conn_ops->IFMarker) {
3680 if (iscsit_fe_sendpage_sg(cmd, conn) < 0) {
3681 conn->tx_response_queue = 0;
3682 iscsit_tx_thread_wait_for_tcp(conn);
3683 iscsit_unmap_iovec(cmd);
3684 goto transport_err;
3685 }
3686 } else {
3687 if (iscsit_send_tx_data(cmd, conn, use_misc) < 0) {
3688 conn->tx_response_queue = 0;
3689 iscsit_tx_thread_wait_for_tcp(conn);
3690 iscsit_unmap_iovec(cmd);
3691 goto transport_err;
3692 }
3693 }
3694 map_sg = 0;
3695 iscsit_unmap_iovec(cmd);
3696
3697 spin_lock_bh(&cmd->istate_lock);
3698 switch (state) {
3699 case ISTATE_SEND_DATAIN:
3700 if (!eodr)
3701 goto check_rsp_state;
3702
3703 if (eodr == 1) {
3704 cmd->i_state = ISTATE_SENT_LAST_DATAIN;
3705 sent_status = 1;
3706 eodr = use_misc = 0;
3707 } else if (eodr == 2) {
3708 cmd->i_state = state =
3709 ISTATE_SEND_STATUS;
3710 sent_status = 0;
3711 eodr = use_misc = 0;
3712 goto check_rsp_state;
3713 }
3714 break;
3715 case ISTATE_SEND_STATUS:
3716 use_misc = 0;
3717 sent_status = 1;
3718 break;
3719 case ISTATE_SEND_ASYNCMSG:
3720 case ISTATE_SEND_NOPIN:
3721 case ISTATE_SEND_STATUS_RECOVERY:
3722 case ISTATE_SEND_TEXTRSP:
3723 use_misc = 0;
3724 sent_status = 1;
3725 break;
3726 case ISTATE_SEND_REJECT:
3727 use_misc = 0;
3728 if (cmd->cmd_flags & ICF_REJECT_FAIL_CONN) {
3729 cmd->cmd_flags &= ~ICF_REJECT_FAIL_CONN;
3730 spin_unlock_bh(&cmd->istate_lock);
3731 complete(&cmd->reject_comp);
3732 goto transport_err;
3733 }
3734 complete(&cmd->reject_comp);
3735 break;
3736 case ISTATE_SEND_TASKMGTRSP:
3737 use_misc = 0;
3738 sent_status = 1;
3739 break;
3740 case ISTATE_SEND_LOGOUTRSP:
3741 spin_unlock_bh(&cmd->istate_lock);
3742 if (!iscsit_logout_post_handler(cmd, conn))
3743 goto restart;
3744 spin_lock_bh(&cmd->istate_lock);
3745 use_misc = 0;
3746 sent_status = 1;
3747 break;
3748 default:
3749 pr_err("Unknown Opcode: 0x%02x ITT:"
3750 " 0x%08x, i_state: %d on CID: %hu\n",
3751 cmd->iscsi_opcode, cmd->init_task_tag,
3752 cmd->i_state, conn->cid);
3753 spin_unlock_bh(&cmd->istate_lock);
3754 goto transport_err;
3755 }
3756
3757 if (sent_status) {
3758 cmd->i_state = ISTATE_SENT_STATUS;
3759 sent_status = 0;
3760 }
3761 spin_unlock_bh(&cmd->istate_lock);
3762
3763 if (atomic_read(&conn->check_immediate_queue))
3764 goto get_immediate;
3765
3766 goto get_response;
3767 } else
3768 conn->tx_response_queue = 0;
3769 }
3770
3771transport_err:
3772 iscsit_take_action_for_connection_exit(conn);
3773 goto restart;
3774out:
3775 return 0;
3776}
3777
3778int iscsi_target_rx_thread(void *arg)
3779{
3780 int ret;
3781 u8 buffer[ISCSI_HDR_LEN], opcode;
3782 u32 checksum = 0, digest = 0;
3783 struct iscsi_conn *conn = NULL;
3784 struct iscsi_thread_set *ts = (struct iscsi_thread_set *)arg;
3785 struct kvec iov;
3786 /*
3787 * Allow ourselves to be interrupted by SIGINT so that a
3788 * connection recovery / failure event can be triggered externally.
3789 */
3790 allow_signal(SIGINT);
3791
3792restart:
3793 conn = iscsi_rx_thread_pre_handler(ts);
3794 if (!conn)
3795 goto out;
3796
3797 while (!kthread_should_stop()) {
3798 /*
3799 * Ensure that both TX and RX per connection kthreads
3800 * are scheduled to run on the same CPU.
3801 */
3802 iscsit_thread_check_cpumask(conn, current, 0);
3803
3804 memset(buffer, 0, ISCSI_HDR_LEN);
3805 memset(&iov, 0, sizeof(struct kvec));
3806
3807 iov.iov_base = buffer;
3808 iov.iov_len = ISCSI_HDR_LEN;
3809
3810 ret = rx_data(conn, &iov, 1, ISCSI_HDR_LEN);
3811 if (ret != ISCSI_HDR_LEN) {
3812 iscsit_rx_thread_wait_for_tcp(conn);
3813 goto transport_err;
3814 }
3815
3816 /*
3817 * Set conn->bad_hdr for use with REJECT PDUs.
3818 */
3819 memcpy(&conn->bad_hdr, &buffer, ISCSI_HDR_LEN);
3820
3821 if (conn->conn_ops->HeaderDigest) {
3822 iov.iov_base = &digest;
3823 iov.iov_len = ISCSI_CRC_LEN;
3824
3825 ret = rx_data(conn, &iov, 1, ISCSI_CRC_LEN);
3826 if (ret != ISCSI_CRC_LEN) {
3827 iscsit_rx_thread_wait_for_tcp(conn);
3828 goto transport_err;
3829 }
3830
3831 iscsit_do_crypto_hash_buf(&conn->conn_rx_hash,
3832 buffer, ISCSI_HDR_LEN,
3833 0, NULL, (u8 *)&checksum);
3834
3835 if (digest != checksum) {
3836 pr_err("HeaderDigest CRC32C failed,"
3837 " received 0x%08x, computed 0x%08x\n",
3838 digest, checksum);
3839 /*
3840 * Set the PDU to 0xff so it will intentionally
3841 * hit default in the switch below.
3842 */
3843 memset(buffer, 0xff, ISCSI_HDR_LEN);
3844 spin_lock_bh(&conn->sess->session_stats_lock);
3845 conn->sess->conn_digest_errors++;
3846 spin_unlock_bh(&conn->sess->session_stats_lock);
3847 } else {
3848 pr_debug("Got HeaderDigest CRC32C"
3849 " 0x%08x\n", checksum);
3850 }
3851 }
3852
3853 if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT)
3854 goto transport_err;
3855
3856 opcode = buffer[0] & ISCSI_OPCODE_MASK;
3857
3858 if (conn->sess->sess_ops->SessionType &&
3859 ((!(opcode & ISCSI_OP_TEXT)) ||
3860 (!(opcode & ISCSI_OP_LOGOUT)))) {
3861 pr_err("Received illegal iSCSI Opcode: 0x%02x"
3862 " while in Discovery Session, rejecting.\n", opcode);
3863 iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
3864 buffer, conn);
3865 goto transport_err;
3866 }
3867
3868 switch (opcode) {
3869 case ISCSI_OP_SCSI_CMD:
3870 if (iscsit_handle_scsi_cmd(conn, buffer) < 0)
3871 goto transport_err;
3872 break;
3873 case ISCSI_OP_SCSI_DATA_OUT:
3874 if (iscsit_handle_data_out(conn, buffer) < 0)
3875 goto transport_err;
3876 break;
3877 case ISCSI_OP_NOOP_OUT:
3878 if (iscsit_handle_nop_out(conn, buffer) < 0)
3879 goto transport_err;
3880 break;
3881 case ISCSI_OP_SCSI_TMFUNC:
3882 if (iscsit_handle_task_mgt_cmd(conn, buffer) < 0)
3883 goto transport_err;
3884 break;
3885 case ISCSI_OP_TEXT:
3886 if (iscsit_handle_text_cmd(conn, buffer) < 0)
3887 goto transport_err;
3888 break;
3889 case ISCSI_OP_LOGOUT:
3890 ret = iscsit_handle_logout_cmd(conn, buffer);
3891 if (ret > 0) {
3892 wait_for_completion_timeout(&conn->conn_logout_comp,
3893 SECONDS_FOR_LOGOUT_COMP * HZ);
3894 goto transport_err;
3895 } else if (ret < 0)
3896 goto transport_err;
3897 break;
3898 case ISCSI_OP_SNACK:
3899 if (iscsit_handle_snack(conn, buffer) < 0)
3900 goto transport_err;
3901 break;
3902 default:
3903 pr_err("Got unknown iSCSI OpCode: 0x%02x\n",
3904 opcode);
3905 if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
3906 pr_err("Cannot recover from unknown"
3907 " opcode while ERL=0, closing iSCSI connection"
3908 ".\n");
3909 goto transport_err;
3910 }
3911 if (!conn->conn_ops->OFMarker) {
3912 pr_err("Unable to recover from unknown"
3913 " opcode while OFMarker=No, closing iSCSI"
3914 " connection.\n");
3915 goto transport_err;
3916 }
3917 if (iscsit_recover_from_unknown_opcode(conn) < 0) {
3918 pr_err("Unable to recover from unknown"
3919 " opcode, closing iSCSI connection.\n");
3920 goto transport_err;
3921 }
3922 break;
3923 }
3924 }
3925
3926transport_err:
3927 if (!signal_pending(current))
3928 atomic_set(&conn->transport_failed, 1);
3929 iscsit_take_action_for_connection_exit(conn);
3930 goto restart;
3931out:
3932 return 0;
3933}
3934
3935static void iscsit_release_commands_from_conn(struct iscsi_conn *conn)
3936{
3937 struct iscsi_cmd *cmd = NULL, *cmd_tmp = NULL;
3938 struct iscsi_session *sess = conn->sess;
3939 struct se_cmd *se_cmd;
3940 /*
3941 * We expect this function to only ever be called from either RX or TX
3942 * thread context via iscsit_close_connection() once the other context
3943 * has been reset -> returned sleeping pre-handler state.
3944 */
3945 spin_lock_bh(&conn->cmd_lock);
3946 list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_list) {
3947 if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD)) {
3948
3949 list_del(&cmd->i_list);
3950 spin_unlock_bh(&conn->cmd_lock);
3951 iscsit_increment_maxcmdsn(cmd, sess);
3952 se_cmd = &cmd->se_cmd;
3953 /*
3954 * Special cases for active iSCSI TMR, and
3955 * transport_lookup_cmd_lun() failing from
3956 * iscsit_get_lun_for_cmd() in iscsit_handle_scsi_cmd().
3957 */
3958 if (cmd->tmr_req && se_cmd->transport_wait_for_tasks)
3959 se_cmd->transport_wait_for_tasks(se_cmd, 1, 1);
3960 else if (cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD)
3961 transport_release_cmd(se_cmd);
3962 else
3963 iscsit_release_cmd(cmd);
3964
3965 spin_lock_bh(&conn->cmd_lock);
3966 continue;
3967 }
3968 list_del(&cmd->i_list);
3969 spin_unlock_bh(&conn->cmd_lock);
3970
3971 iscsit_increment_maxcmdsn(cmd, sess);
3972 se_cmd = &cmd->se_cmd;
3973
3974 if (se_cmd->transport_wait_for_tasks)
3975 se_cmd->transport_wait_for_tasks(se_cmd, 1, 1);
3976
3977 spin_lock_bh(&conn->cmd_lock);
3978 }
3979 spin_unlock_bh(&conn->cmd_lock);
3980}
3981
3982static void iscsit_stop_timers_for_cmds(
3983 struct iscsi_conn *conn)
3984{
3985 struct iscsi_cmd *cmd;
3986
3987 spin_lock_bh(&conn->cmd_lock);
3988 list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) {
3989 if (cmd->data_direction == DMA_TO_DEVICE)
3990 iscsit_stop_dataout_timer(cmd);
3991 }
3992 spin_unlock_bh(&conn->cmd_lock);
3993}
3994
3995int iscsit_close_connection(
3996 struct iscsi_conn *conn)
3997{
3998 int conn_logout = (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT);
3999 struct iscsi_session *sess = conn->sess;
4000
4001 pr_debug("Closing iSCSI connection CID %hu on SID:"
4002 " %u\n", conn->cid, sess->sid);
4003 /*
4004 * Always up conn_logout_comp just in case the RX Thread is sleeping
4005 * and the logout response never got sent because the connection
4006 * failed.
4007 */
4008 complete(&conn->conn_logout_comp);
4009
4010 iscsi_release_thread_set(conn);
4011
4012 iscsit_stop_timers_for_cmds(conn);
4013 iscsit_stop_nopin_response_timer(conn);
4014 iscsit_stop_nopin_timer(conn);
4015 iscsit_free_queue_reqs_for_conn(conn);
4016
4017 /*
4018 * During Connection recovery drop unacknowledged out of order
4019 * commands for this connection, and prepare the other commands
4020 * for realligence.
4021 *
4022 * During normal operation clear the out of order commands (but
4023 * do not free the struct iscsi_ooo_cmdsn's) and release all
4024 * struct iscsi_cmds.
4025 */
4026 if (atomic_read(&conn->connection_recovery)) {
4027 iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(conn);
4028 iscsit_prepare_cmds_for_realligance(conn);
4029 } else {
4030 iscsit_clear_ooo_cmdsns_for_conn(conn);
4031 iscsit_release_commands_from_conn(conn);
4032 }
4033
4034 /*
4035 * Handle decrementing session or connection usage count if
4036 * a logout response was not able to be sent because the
4037 * connection failed. Fall back to Session Recovery here.
4038 */
4039 if (atomic_read(&conn->conn_logout_remove)) {
4040 if (conn->conn_logout_reason == ISCSI_LOGOUT_REASON_CLOSE_SESSION) {
4041 iscsit_dec_conn_usage_count(conn);
4042 iscsit_dec_session_usage_count(sess);
4043 }
4044 if (conn->conn_logout_reason == ISCSI_LOGOUT_REASON_CLOSE_CONNECTION)
4045 iscsit_dec_conn_usage_count(conn);
4046
4047 atomic_set(&conn->conn_logout_remove, 0);
4048 atomic_set(&sess->session_reinstatement, 0);
4049 atomic_set(&sess->session_fall_back_to_erl0, 1);
4050 }
4051
4052 spin_lock_bh(&sess->conn_lock);
4053 list_del(&conn->conn_list);
4054
4055 /*
4056 * Attempt to let the Initiator know this connection failed by
4057 * sending an Connection Dropped Async Message on another
4058 * active connection.
4059 */
4060 if (atomic_read(&conn->connection_recovery))
4061 iscsit_build_conn_drop_async_message(conn);
4062
4063 spin_unlock_bh(&sess->conn_lock);
4064
4065 /*
4066 * If connection reinstatement is being performed on this connection,
4067 * up the connection reinstatement semaphore that is being blocked on
4068 * in iscsit_cause_connection_reinstatement().
4069 */
4070 spin_lock_bh(&conn->state_lock);
4071 if (atomic_read(&conn->sleep_on_conn_wait_comp)) {
4072 spin_unlock_bh(&conn->state_lock);
4073 complete(&conn->conn_wait_comp);
4074 wait_for_completion(&conn->conn_post_wait_comp);
4075 spin_lock_bh(&conn->state_lock);
4076 }
4077
4078 /*
4079 * If connection reinstatement is being performed on this connection
4080 * by receiving a REMOVECONNFORRECOVERY logout request, up the
4081 * connection wait rcfr semaphore that is being blocked on
4082 * an iscsit_connection_reinstatement_rcfr().
4083 */
4084 if (atomic_read(&conn->connection_wait_rcfr)) {
4085 spin_unlock_bh(&conn->state_lock);
4086 complete(&conn->conn_wait_rcfr_comp);
4087 wait_for_completion(&conn->conn_post_wait_comp);
4088 spin_lock_bh(&conn->state_lock);
4089 }
4090 atomic_set(&conn->connection_reinstatement, 1);
4091 spin_unlock_bh(&conn->state_lock);
4092
4093 /*
4094 * If any other processes are accessing this connection pointer we
4095 * must wait until they have completed.
4096 */
4097 iscsit_check_conn_usage_count(conn);
4098
4099 if (conn->conn_rx_hash.tfm)
4100 crypto_free_hash(conn->conn_rx_hash.tfm);
4101 if (conn->conn_tx_hash.tfm)
4102 crypto_free_hash(conn->conn_tx_hash.tfm);
4103
4104 if (conn->conn_cpumask)
4105 free_cpumask_var(conn->conn_cpumask);
4106
4107 kfree(conn->conn_ops);
4108 conn->conn_ops = NULL;
4109
4110 if (conn->sock) {
4111 if (conn->conn_flags & CONNFLAG_SCTP_STRUCT_FILE) {
4112 kfree(conn->sock->file);
4113 conn->sock->file = NULL;
4114 }
4115 sock_release(conn->sock);
4116 }
4117 conn->thread_set = NULL;
4118
4119 pr_debug("Moving to TARG_CONN_STATE_FREE.\n");
4120 conn->conn_state = TARG_CONN_STATE_FREE;
4121 kfree(conn);
4122
4123 spin_lock_bh(&sess->conn_lock);
4124 atomic_dec(&sess->nconn);
4125 pr_debug("Decremented iSCSI connection count to %hu from node:"
4126 " %s\n", atomic_read(&sess->nconn),
4127 sess->sess_ops->InitiatorName);
4128 /*
4129 * Make sure that if one connection fails in an non ERL=2 iSCSI
4130 * Session that they all fail.
4131 */
4132 if ((sess->sess_ops->ErrorRecoveryLevel != 2) && !conn_logout &&
4133 !atomic_read(&sess->session_logout))
4134 atomic_set(&sess->session_fall_back_to_erl0, 1);
4135
4136 /*
4137 * If this was not the last connection in the session, and we are
4138 * performing session reinstatement or falling back to ERL=0, call
4139 * iscsit_stop_session() without sleeping to shutdown the other
4140 * active connections.
4141 */
4142 if (atomic_read(&sess->nconn)) {
4143 if (!atomic_read(&sess->session_reinstatement) &&
4144 !atomic_read(&sess->session_fall_back_to_erl0)) {
4145 spin_unlock_bh(&sess->conn_lock);
4146 return 0;
4147 }
4148 if (!atomic_read(&sess->session_stop_active)) {
4149 atomic_set(&sess->session_stop_active, 1);
4150 spin_unlock_bh(&sess->conn_lock);
4151 iscsit_stop_session(sess, 0, 0);
4152 return 0;
4153 }
4154 spin_unlock_bh(&sess->conn_lock);
4155 return 0;
4156 }
4157
4158 /*
4159 * If this was the last connection in the session and one of the
4160 * following is occurring:
4161 *
4162 * Session Reinstatement is not being performed, and are falling back
4163 * to ERL=0 call iscsit_close_session().
4164 *
4165 * Session Logout was requested. iscsit_close_session() will be called
4166 * elsewhere.
4167 *
4168 * Session Continuation is not being performed, start the Time2Retain
4169 * handler and check if sleep_on_sess_wait_sem is active.
4170 */
4171 if (!atomic_read(&sess->session_reinstatement) &&
4172 atomic_read(&sess->session_fall_back_to_erl0)) {
4173 spin_unlock_bh(&sess->conn_lock);
4174 iscsit_close_session(sess);
4175
4176 return 0;
4177 } else if (atomic_read(&sess->session_logout)) {
4178 pr_debug("Moving to TARG_SESS_STATE_FREE.\n");
4179 sess->session_state = TARG_SESS_STATE_FREE;
4180 spin_unlock_bh(&sess->conn_lock);
4181
4182 if (atomic_read(&sess->sleep_on_sess_wait_comp))
4183 complete(&sess->session_wait_comp);
4184
4185 return 0;
4186 } else {
4187 pr_debug("Moving to TARG_SESS_STATE_FAILED.\n");
4188 sess->session_state = TARG_SESS_STATE_FAILED;
4189
4190 if (!atomic_read(&sess->session_continuation)) {
4191 spin_unlock_bh(&sess->conn_lock);
4192 iscsit_start_time2retain_handler(sess);
4193 } else
4194 spin_unlock_bh(&sess->conn_lock);
4195
4196 if (atomic_read(&sess->sleep_on_sess_wait_comp))
4197 complete(&sess->session_wait_comp);
4198
4199 return 0;
4200 }
4201 spin_unlock_bh(&sess->conn_lock);
4202
4203 return 0;
4204}
4205
4206int iscsit_close_session(struct iscsi_session *sess)
4207{
4208 struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess);
4209 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
4210
4211 if (atomic_read(&sess->nconn)) {
4212 pr_err("%d connection(s) still exist for iSCSI session"
4213 " to %s\n", atomic_read(&sess->nconn),
4214 sess->sess_ops->InitiatorName);
4215 BUG();
4216 }
4217
4218 spin_lock_bh(&se_tpg->session_lock);
4219 atomic_set(&sess->session_logout, 1);
4220 atomic_set(&sess->session_reinstatement, 1);
4221 iscsit_stop_time2retain_timer(sess);
4222 spin_unlock_bh(&se_tpg->session_lock);
4223
4224 /*
4225 * transport_deregister_session_configfs() will clear the
4226 * struct se_node_acl->nacl_sess pointer now as a iscsi_np process context
4227 * can be setting it again with __transport_register_session() in
4228 * iscsi_post_login_handler() again after the iscsit_stop_session()
4229 * completes in iscsi_np context.
4230 */
4231 transport_deregister_session_configfs(sess->se_sess);
4232
4233 /*
4234 * If any other processes are accessing this session pointer we must
4235 * wait until they have completed. If we are in an interrupt (the
4236 * time2retain handler) and contain and active session usage count we
4237 * restart the timer and exit.
4238 */
4239 if (!in_interrupt()) {
4240 if (iscsit_check_session_usage_count(sess) == 1)
4241 iscsit_stop_session(sess, 1, 1);
4242 } else {
4243 if (iscsit_check_session_usage_count(sess) == 2) {
4244 atomic_set(&sess->session_logout, 0);
4245 iscsit_start_time2retain_handler(sess);
4246 return 0;
4247 }
4248 }
4249
4250 transport_deregister_session(sess->se_sess);
4251
4252 if (sess->sess_ops->ErrorRecoveryLevel == 2)
4253 iscsit_free_connection_recovery_entires(sess);
4254
4255 iscsit_free_all_ooo_cmdsns(sess);
4256
4257 spin_lock_bh(&se_tpg->session_lock);
4258 pr_debug("Moving to TARG_SESS_STATE_FREE.\n");
4259 sess->session_state = TARG_SESS_STATE_FREE;
4260 pr_debug("Released iSCSI session from node: %s\n",
4261 sess->sess_ops->InitiatorName);
4262 tpg->nsessions--;
4263 if (tpg->tpg_tiqn)
4264 tpg->tpg_tiqn->tiqn_nsessions--;
4265
4266 pr_debug("Decremented number of active iSCSI Sessions on"
4267 " iSCSI TPG: %hu to %u\n", tpg->tpgt, tpg->nsessions);
4268
4269 spin_lock(&sess_idr_lock);
4270 idr_remove(&sess_idr, sess->session_index);
4271 spin_unlock(&sess_idr_lock);
4272
4273 kfree(sess->sess_ops);
4274 sess->sess_ops = NULL;
4275 spin_unlock_bh(&se_tpg->session_lock);
4276
4277 kfree(sess);
4278 return 0;
4279}
4280
4281static void iscsit_logout_post_handler_closesession(
4282 struct iscsi_conn *conn)
4283{
4284 struct iscsi_session *sess = conn->sess;
4285
4286 iscsi_set_thread_clear(conn, ISCSI_CLEAR_TX_THREAD);
4287 iscsi_set_thread_set_signal(conn, ISCSI_SIGNAL_TX_THREAD);
4288
4289 atomic_set(&conn->conn_logout_remove, 0);
4290 complete(&conn->conn_logout_comp);
4291
4292 iscsit_dec_conn_usage_count(conn);
4293 iscsit_stop_session(sess, 1, 1);
4294 iscsit_dec_session_usage_count(sess);
4295 iscsit_close_session(sess);
4296}
4297
4298static void iscsit_logout_post_handler_samecid(
4299 struct iscsi_conn *conn)
4300{
4301 iscsi_set_thread_clear(conn, ISCSI_CLEAR_TX_THREAD);
4302 iscsi_set_thread_set_signal(conn, ISCSI_SIGNAL_TX_THREAD);
4303
4304 atomic_set(&conn->conn_logout_remove, 0);
4305 complete(&conn->conn_logout_comp);
4306
4307 iscsit_cause_connection_reinstatement(conn, 1);
4308 iscsit_dec_conn_usage_count(conn);
4309}
4310
4311static void iscsit_logout_post_handler_diffcid(
4312 struct iscsi_conn *conn,
4313 u16 cid)
4314{
4315 struct iscsi_conn *l_conn;
4316 struct iscsi_session *sess = conn->sess;
4317
4318 if (!sess)
4319 return;
4320
4321 spin_lock_bh(&sess->conn_lock);
4322 list_for_each_entry(l_conn, &sess->sess_conn_list, conn_list) {
4323 if (l_conn->cid == cid) {
4324 iscsit_inc_conn_usage_count(l_conn);
4325 break;
4326 }
4327 }
4328 spin_unlock_bh(&sess->conn_lock);
4329
4330 if (!l_conn)
4331 return;
4332
4333 if (l_conn->sock)
4334 l_conn->sock->ops->shutdown(l_conn->sock, RCV_SHUTDOWN);
4335
4336 spin_lock_bh(&l_conn->state_lock);
4337 pr_debug("Moving to TARG_CONN_STATE_IN_LOGOUT.\n");
4338 l_conn->conn_state = TARG_CONN_STATE_IN_LOGOUT;
4339 spin_unlock_bh(&l_conn->state_lock);
4340
4341 iscsit_cause_connection_reinstatement(l_conn, 1);
4342 iscsit_dec_conn_usage_count(l_conn);
4343}
4344
4345/*
4346 * Return of 0 causes the TX thread to restart.
4347 */
4348static int iscsit_logout_post_handler(
4349 struct iscsi_cmd *cmd,
4350 struct iscsi_conn *conn)
4351{
4352 int ret = 0;
4353
4354 switch (cmd->logout_reason) {
4355 case ISCSI_LOGOUT_REASON_CLOSE_SESSION:
4356 switch (cmd->logout_response) {
4357 case ISCSI_LOGOUT_SUCCESS:
4358 case ISCSI_LOGOUT_CLEANUP_FAILED:
4359 default:
4360 iscsit_logout_post_handler_closesession(conn);
4361 break;
4362 }
4363 ret = 0;
4364 break;
4365 case ISCSI_LOGOUT_REASON_CLOSE_CONNECTION:
4366 if (conn->cid == cmd->logout_cid) {
4367 switch (cmd->logout_response) {
4368 case ISCSI_LOGOUT_SUCCESS:
4369 case ISCSI_LOGOUT_CLEANUP_FAILED:
4370 default:
4371 iscsit_logout_post_handler_samecid(conn);
4372 break;
4373 }
4374 ret = 0;
4375 } else {
4376 switch (cmd->logout_response) {
4377 case ISCSI_LOGOUT_SUCCESS:
4378 iscsit_logout_post_handler_diffcid(conn,
4379 cmd->logout_cid);
4380 break;
4381 case ISCSI_LOGOUT_CID_NOT_FOUND:
4382 case ISCSI_LOGOUT_CLEANUP_FAILED:
4383 default:
4384 break;
4385 }
4386 ret = 1;
4387 }
4388 break;
4389 case ISCSI_LOGOUT_REASON_RECOVERY:
4390 switch (cmd->logout_response) {
4391 case ISCSI_LOGOUT_SUCCESS:
4392 case ISCSI_LOGOUT_CID_NOT_FOUND:
4393 case ISCSI_LOGOUT_RECOVERY_UNSUPPORTED:
4394 case ISCSI_LOGOUT_CLEANUP_FAILED:
4395 default:
4396 break;
4397 }
4398 ret = 1;
4399 break;
4400 default:
4401 break;
4402
4403 }
4404 return ret;
4405}
4406
4407void iscsit_fail_session(struct iscsi_session *sess)
4408{
4409 struct iscsi_conn *conn;
4410
4411 spin_lock_bh(&sess->conn_lock);
4412 list_for_each_entry(conn, &sess->sess_conn_list, conn_list) {
4413 pr_debug("Moving to TARG_CONN_STATE_CLEANUP_WAIT.\n");
4414 conn->conn_state = TARG_CONN_STATE_CLEANUP_WAIT;
4415 }
4416 spin_unlock_bh(&sess->conn_lock);
4417
4418 pr_debug("Moving to TARG_SESS_STATE_FAILED.\n");
4419 sess->session_state = TARG_SESS_STATE_FAILED;
4420}
4421
4422int iscsit_free_session(struct iscsi_session *sess)
4423{
4424 u16 conn_count = atomic_read(&sess->nconn);
4425 struct iscsi_conn *conn, *conn_tmp = NULL;
4426 int is_last;
4427
4428 spin_lock_bh(&sess->conn_lock);
4429 atomic_set(&sess->sleep_on_sess_wait_comp, 1);
4430
4431 list_for_each_entry_safe(conn, conn_tmp, &sess->sess_conn_list,
4432 conn_list) {
4433 if (conn_count == 0)
4434 break;
4435
4436 if (list_is_last(&conn->conn_list, &sess->sess_conn_list)) {
4437 is_last = 1;
4438 } else {
4439 iscsit_inc_conn_usage_count(conn_tmp);
4440 is_last = 0;
4441 }
4442 iscsit_inc_conn_usage_count(conn);
4443
4444 spin_unlock_bh(&sess->conn_lock);
4445 iscsit_cause_connection_reinstatement(conn, 1);
4446 spin_lock_bh(&sess->conn_lock);
4447
4448 iscsit_dec_conn_usage_count(conn);
4449 if (is_last == 0)
4450 iscsit_dec_conn_usage_count(conn_tmp);
4451
4452 conn_count--;
4453 }
4454
4455 if (atomic_read(&sess->nconn)) {
4456 spin_unlock_bh(&sess->conn_lock);
4457 wait_for_completion(&sess->session_wait_comp);
4458 } else
4459 spin_unlock_bh(&sess->conn_lock);
4460
4461 iscsit_close_session(sess);
4462 return 0;
4463}
4464
4465void iscsit_stop_session(
4466 struct iscsi_session *sess,
4467 int session_sleep,
4468 int connection_sleep)
4469{
4470 u16 conn_count = atomic_read(&sess->nconn);
4471 struct iscsi_conn *conn, *conn_tmp = NULL;
4472 int is_last;
4473
4474 spin_lock_bh(&sess->conn_lock);
4475 if (session_sleep)
4476 atomic_set(&sess->sleep_on_sess_wait_comp, 1);
4477
4478 if (connection_sleep) {
4479 list_for_each_entry_safe(conn, conn_tmp, &sess->sess_conn_list,
4480 conn_list) {
4481 if (conn_count == 0)
4482 break;
4483
4484 if (list_is_last(&conn->conn_list, &sess->sess_conn_list)) {
4485 is_last = 1;
4486 } else {
4487 iscsit_inc_conn_usage_count(conn_tmp);
4488 is_last = 0;
4489 }
4490 iscsit_inc_conn_usage_count(conn);
4491
4492 spin_unlock_bh(&sess->conn_lock);
4493 iscsit_cause_connection_reinstatement(conn, 1);
4494 spin_lock_bh(&sess->conn_lock);
4495
4496 iscsit_dec_conn_usage_count(conn);
4497 if (is_last == 0)
4498 iscsit_dec_conn_usage_count(conn_tmp);
4499 conn_count--;
4500 }
4501 } else {
4502 list_for_each_entry(conn, &sess->sess_conn_list, conn_list)
4503 iscsit_cause_connection_reinstatement(conn, 0);
4504 }
4505
4506 if (session_sleep && atomic_read(&sess->nconn)) {
4507 spin_unlock_bh(&sess->conn_lock);
4508 wait_for_completion(&sess->session_wait_comp);
4509 } else
4510 spin_unlock_bh(&sess->conn_lock);
4511}
4512
4513int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force)
4514{
4515 struct iscsi_session *sess;
4516 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
4517 struct se_session *se_sess, *se_sess_tmp;
4518 int session_count = 0;
4519
4520 spin_lock_bh(&se_tpg->session_lock);
4521 if (tpg->nsessions && !force) {
4522 spin_unlock_bh(&se_tpg->session_lock);
4523 return -1;
4524 }
4525
4526 list_for_each_entry_safe(se_sess, se_sess_tmp, &se_tpg->tpg_sess_list,
4527 sess_list) {
4528 sess = (struct iscsi_session *)se_sess->fabric_sess_ptr;
4529
4530 spin_lock(&sess->conn_lock);
4531 if (atomic_read(&sess->session_fall_back_to_erl0) ||
4532 atomic_read(&sess->session_logout) ||
4533 (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)) {
4534 spin_unlock(&sess->conn_lock);
4535 continue;
4536 }
4537 atomic_set(&sess->session_reinstatement, 1);
4538 spin_unlock(&sess->conn_lock);
4539 spin_unlock_bh(&se_tpg->session_lock);
4540
4541 iscsit_free_session(sess);
4542 spin_lock_bh(&se_tpg->session_lock);
4543
4544 session_count++;
4545 }
4546 spin_unlock_bh(&se_tpg->session_lock);
4547
4548 pr_debug("Released %d iSCSI Session(s) from Target Portal"
4549 " Group: %hu\n", session_count, tpg->tpgt);
4550 return 0;
4551}
4552
4553MODULE_DESCRIPTION("iSCSI-Target Driver for mainline target infrastructure");
4554MODULE_VERSION("4.1.x");
4555MODULE_AUTHOR("nab@Linux-iSCSI.org");
4556MODULE_LICENSE("GPL");
4557
4558module_init(iscsi_target_init_module);
4559module_exit(iscsi_target_cleanup_module);
diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h
new file mode 100644
index 000000000000..5db2ddeed5eb
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target.h
@@ -0,0 +1,42 @@
1#ifndef ISCSI_TARGET_H
2#define ISCSI_TARGET_H
3
4extern struct iscsi_tiqn *iscsit_get_tiqn_for_login(unsigned char *);
5extern struct iscsi_tiqn *iscsit_get_tiqn(unsigned char *, int);
6extern void iscsit_put_tiqn_for_login(struct iscsi_tiqn *);
7extern struct iscsi_tiqn *iscsit_add_tiqn(unsigned char *);
8extern void iscsit_del_tiqn(struct iscsi_tiqn *);
9extern int iscsit_access_np(struct iscsi_np *, struct iscsi_portal_group *);
10extern int iscsit_deaccess_np(struct iscsi_np *, struct iscsi_portal_group *);
11extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *,
12 char *, int);
13extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *,
14 struct iscsi_portal_group *);
15extern int iscsit_del_np(struct iscsi_np *);
16extern int iscsit_add_reject_from_cmd(u8, int, int, unsigned char *, struct iscsi_cmd *);
17extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *);
18extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *);
19extern int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *, struct iscsi_conn *);
20extern int iscsit_send_async_msg(struct iscsi_conn *, u16, u8, u8);
21extern int iscsit_send_r2t(struct iscsi_cmd *, struct iscsi_conn *);
22extern int iscsit_build_r2ts_for_cmd(struct iscsi_cmd *, struct iscsi_conn *, int);
23extern void iscsit_thread_get_cpumask(struct iscsi_conn *);
24extern int iscsi_target_tx_thread(void *);
25extern int iscsi_target_rx_thread(void *);
26extern int iscsit_close_connection(struct iscsi_conn *);
27extern int iscsit_close_session(struct iscsi_session *);
28extern void iscsit_fail_session(struct iscsi_session *);
29extern int iscsit_free_session(struct iscsi_session *);
30extern void iscsit_stop_session(struct iscsi_session *, int, int);
31extern int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *, int);
32
33extern struct iscsit_global *iscsit_global;
34extern struct target_fabric_configfs *lio_target_fabric_configfs;
35
36extern struct kmem_cache *lio_dr_cache;
37extern struct kmem_cache *lio_ooo_cache;
38extern struct kmem_cache *lio_cmd_cache;
39extern struct kmem_cache *lio_qr_cache;
40extern struct kmem_cache *lio_r2t_cache;
41
42#endif /*** ISCSI_TARGET_H ***/
diff --git a/drivers/target/iscsi/iscsi_target_auth.c b/drivers/target/iscsi/iscsi_target_auth.c
new file mode 100644
index 000000000000..11fd74307811
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_auth.c
@@ -0,0 +1,490 @@
1/*******************************************************************************
2 * This file houses the main functions for the iSCSI CHAP support
3 *
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5 *
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7 *
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.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
21#include <linux/string.h>
22#include <linux/crypto.h>
23#include <linux/err.h>
24#include <linux/scatterlist.h>
25
26#include "iscsi_target_core.h"
27#include "iscsi_target_nego.h"
28#include "iscsi_target_auth.h"
29
30static unsigned char chap_asciihex_to_binaryhex(unsigned char val[2])
31{
32 unsigned char result = 0;
33 /*
34 * MSB
35 */
36 if ((val[0] >= 'a') && (val[0] <= 'f'))
37 result = ((val[0] - 'a' + 10) & 0xf) << 4;
38 else
39 if ((val[0] >= 'A') && (val[0] <= 'F'))
40 result = ((val[0] - 'A' + 10) & 0xf) << 4;
41 else /* digit */
42 result = ((val[0] - '0') & 0xf) << 4;
43 /*
44 * LSB
45 */
46 if ((val[1] >= 'a') && (val[1] <= 'f'))
47 result |= ((val[1] - 'a' + 10) & 0xf);
48 else
49 if ((val[1] >= 'A') && (val[1] <= 'F'))
50 result |= ((val[1] - 'A' + 10) & 0xf);
51 else /* digit */
52 result |= ((val[1] - '0') & 0xf);
53
54 return result;
55}
56
57static int chap_string_to_hex(unsigned char *dst, unsigned char *src, int len)
58{
59 int i, j = 0;
60
61 for (i = 0; i < len; i += 2) {
62 dst[j++] = (unsigned char) chap_asciihex_to_binaryhex(&src[i]);
63 }
64
65 dst[j] = '\0';
66 return j;
67}
68
69static void chap_binaryhex_to_asciihex(char *dst, char *src, int src_len)
70{
71 int i;
72
73 for (i = 0; i < src_len; i++) {
74 sprintf(&dst[i*2], "%02x", (int) src[i] & 0xff);
75 }
76}
77
78static void chap_set_random(char *data, int length)
79{
80 long r;
81 unsigned n;
82
83 while (length > 0) {
84 get_random_bytes(&r, sizeof(long));
85 r = r ^ (r >> 8);
86 r = r ^ (r >> 4);
87 n = r & 0x7;
88
89 get_random_bytes(&r, sizeof(long));
90 r = r ^ (r >> 8);
91 r = r ^ (r >> 5);
92 n = (n << 3) | (r & 0x7);
93
94 get_random_bytes(&r, sizeof(long));
95 r = r ^ (r >> 8);
96 r = r ^ (r >> 5);
97 n = (n << 2) | (r & 0x3);
98
99 *data++ = n;
100 length--;
101 }
102}
103
104static void chap_gen_challenge(
105 struct iscsi_conn *conn,
106 int caller,
107 char *c_str,
108 unsigned int *c_len)
109{
110 unsigned char challenge_asciihex[CHAP_CHALLENGE_LENGTH * 2 + 1];
111 struct iscsi_chap *chap = (struct iscsi_chap *) conn->auth_protocol;
112
113 memset(challenge_asciihex, 0, CHAP_CHALLENGE_LENGTH * 2 + 1);
114
115 chap_set_random(chap->challenge, CHAP_CHALLENGE_LENGTH);
116 chap_binaryhex_to_asciihex(challenge_asciihex, chap->challenge,
117 CHAP_CHALLENGE_LENGTH);
118 /*
119 * Set CHAP_C, and copy the generated challenge into c_str.
120 */
121 *c_len += sprintf(c_str + *c_len, "CHAP_C=0x%s", challenge_asciihex);
122 *c_len += 1;
123
124 pr_debug("[%s] Sending CHAP_C=0x%s\n\n", (caller) ? "server" : "client",
125 challenge_asciihex);
126}
127
128
129static struct iscsi_chap *chap_server_open(
130 struct iscsi_conn *conn,
131 struct iscsi_node_auth *auth,
132 const char *a_str,
133 char *aic_str,
134 unsigned int *aic_len)
135{
136 struct iscsi_chap *chap;
137
138 if (!(auth->naf_flags & NAF_USERID_SET) ||
139 !(auth->naf_flags & NAF_PASSWORD_SET)) {
140 pr_err("CHAP user or password not set for"
141 " Initiator ACL\n");
142 return NULL;
143 }
144
145 conn->auth_protocol = kzalloc(sizeof(struct iscsi_chap), GFP_KERNEL);
146 if (!conn->auth_protocol)
147 return NULL;
148
149 chap = (struct iscsi_chap *) conn->auth_protocol;
150 /*
151 * We only support MD5 MDA presently.
152 */
153 if (strncmp(a_str, "CHAP_A=5", 8)) {
154 pr_err("CHAP_A is not MD5.\n");
155 return NULL;
156 }
157 pr_debug("[server] Got CHAP_A=5\n");
158 /*
159 * Send back CHAP_A set to MD5.
160 */
161 *aic_len = sprintf(aic_str, "CHAP_A=5");
162 *aic_len += 1;
163 chap->digest_type = CHAP_DIGEST_MD5;
164 pr_debug("[server] Sending CHAP_A=%d\n", chap->digest_type);
165 /*
166 * Set Identifier.
167 */
168 chap->id = ISCSI_TPG_C(conn)->tpg_chap_id++;
169 *aic_len += sprintf(aic_str + *aic_len, "CHAP_I=%d", chap->id);
170 *aic_len += 1;
171 pr_debug("[server] Sending CHAP_I=%d\n", chap->id);
172 /*
173 * Generate Challenge.
174 */
175 chap_gen_challenge(conn, 1, aic_str, aic_len);
176
177 return chap;
178}
179
180static void chap_close(struct iscsi_conn *conn)
181{
182 kfree(conn->auth_protocol);
183 conn->auth_protocol = NULL;
184}
185
186static int chap_server_compute_md5(
187 struct iscsi_conn *conn,
188 struct iscsi_node_auth *auth,
189 char *nr_in_ptr,
190 char *nr_out_ptr,
191 unsigned int *nr_out_len)
192{
193 char *endptr;
194 unsigned char id, digest[MD5_SIGNATURE_SIZE];
195 unsigned char type, response[MD5_SIGNATURE_SIZE * 2 + 2];
196 unsigned char identifier[10], *challenge = NULL;
197 unsigned char *challenge_binhex = NULL;
198 unsigned char client_digest[MD5_SIGNATURE_SIZE];
199 unsigned char server_digest[MD5_SIGNATURE_SIZE];
200 unsigned char chap_n[MAX_CHAP_N_SIZE], chap_r[MAX_RESPONSE_LENGTH];
201 struct iscsi_chap *chap = (struct iscsi_chap *) conn->auth_protocol;
202 struct crypto_hash *tfm;
203 struct hash_desc desc;
204 struct scatterlist sg;
205 int auth_ret = -1, ret, challenge_len;
206
207 memset(identifier, 0, 10);
208 memset(chap_n, 0, MAX_CHAP_N_SIZE);
209 memset(chap_r, 0, MAX_RESPONSE_LENGTH);
210 memset(digest, 0, MD5_SIGNATURE_SIZE);
211 memset(response, 0, MD5_SIGNATURE_SIZE * 2 + 2);
212 memset(client_digest, 0, MD5_SIGNATURE_SIZE);
213 memset(server_digest, 0, MD5_SIGNATURE_SIZE);
214
215 challenge = kzalloc(CHAP_CHALLENGE_STR_LEN, GFP_KERNEL);
216 if (!challenge) {
217 pr_err("Unable to allocate challenge buffer\n");
218 goto out;
219 }
220
221 challenge_binhex = kzalloc(CHAP_CHALLENGE_STR_LEN, GFP_KERNEL);
222 if (!challenge_binhex) {
223 pr_err("Unable to allocate challenge_binhex buffer\n");
224 goto out;
225 }
226 /*
227 * Extract CHAP_N.
228 */
229 if (extract_param(nr_in_ptr, "CHAP_N", MAX_CHAP_N_SIZE, chap_n,
230 &type) < 0) {
231 pr_err("Could not find CHAP_N.\n");
232 goto out;
233 }
234 if (type == HEX) {
235 pr_err("Could not find CHAP_N.\n");
236 goto out;
237 }
238
239 if (memcmp(chap_n, auth->userid, strlen(auth->userid)) != 0) {
240 pr_err("CHAP_N values do not match!\n");
241 goto out;
242 }
243 pr_debug("[server] Got CHAP_N=%s\n", chap_n);
244 /*
245 * Extract CHAP_R.
246 */
247 if (extract_param(nr_in_ptr, "CHAP_R", MAX_RESPONSE_LENGTH, chap_r,
248 &type) < 0) {
249 pr_err("Could not find CHAP_R.\n");
250 goto out;
251 }
252 if (type != HEX) {
253 pr_err("Could not find CHAP_R.\n");
254 goto out;
255 }
256
257 pr_debug("[server] Got CHAP_R=%s\n", chap_r);
258 chap_string_to_hex(client_digest, chap_r, strlen(chap_r));
259
260 tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
261 if (IS_ERR(tfm)) {
262 pr_err("Unable to allocate struct crypto_hash\n");
263 goto out;
264 }
265 desc.tfm = tfm;
266 desc.flags = 0;
267
268 ret = crypto_hash_init(&desc);
269 if (ret < 0) {
270 pr_err("crypto_hash_init() failed\n");
271 crypto_free_hash(tfm);
272 goto out;
273 }
274
275 sg_init_one(&sg, (void *)&chap->id, 1);
276 ret = crypto_hash_update(&desc, &sg, 1);
277 if (ret < 0) {
278 pr_err("crypto_hash_update() failed for id\n");
279 crypto_free_hash(tfm);
280 goto out;
281 }
282
283 sg_init_one(&sg, (void *)&auth->password, strlen(auth->password));
284 ret = crypto_hash_update(&desc, &sg, strlen(auth->password));
285 if (ret < 0) {
286 pr_err("crypto_hash_update() failed for password\n");
287 crypto_free_hash(tfm);
288 goto out;
289 }
290
291 sg_init_one(&sg, (void *)chap->challenge, CHAP_CHALLENGE_LENGTH);
292 ret = crypto_hash_update(&desc, &sg, CHAP_CHALLENGE_LENGTH);
293 if (ret < 0) {
294 pr_err("crypto_hash_update() failed for challenge\n");
295 crypto_free_hash(tfm);
296 goto out;
297 }
298
299 ret = crypto_hash_final(&desc, server_digest);
300 if (ret < 0) {
301 pr_err("crypto_hash_final() failed for server digest\n");
302 crypto_free_hash(tfm);
303 goto out;
304 }
305 crypto_free_hash(tfm);
306
307 chap_binaryhex_to_asciihex(response, server_digest, MD5_SIGNATURE_SIZE);
308 pr_debug("[server] MD5 Server Digest: %s\n", response);
309
310 if (memcmp(server_digest, client_digest, MD5_SIGNATURE_SIZE) != 0) {
311 pr_debug("[server] MD5 Digests do not match!\n\n");
312 goto out;
313 } else
314 pr_debug("[server] MD5 Digests match, CHAP connetication"
315 " successful.\n\n");
316 /*
317 * One way authentication has succeeded, return now if mutual
318 * authentication is not enabled.
319 */
320 if (!auth->authenticate_target) {
321 kfree(challenge);
322 kfree(challenge_binhex);
323 return 0;
324 }
325 /*
326 * Get CHAP_I.
327 */
328 if (extract_param(nr_in_ptr, "CHAP_I", 10, identifier, &type) < 0) {
329 pr_err("Could not find CHAP_I.\n");
330 goto out;
331 }
332
333 if (type == HEX)
334 id = (unsigned char)simple_strtoul((char *)&identifier[2],
335 &endptr, 0);
336 else
337 id = (unsigned char)simple_strtoul(identifier, &endptr, 0);
338 /*
339 * RFC 1994 says Identifier is no more than octet (8 bits).
340 */
341 pr_debug("[server] Got CHAP_I=%d\n", id);
342 /*
343 * Get CHAP_C.
344 */
345 if (extract_param(nr_in_ptr, "CHAP_C", CHAP_CHALLENGE_STR_LEN,
346 challenge, &type) < 0) {
347 pr_err("Could not find CHAP_C.\n");
348 goto out;
349 }
350
351 if (type != HEX) {
352 pr_err("Could not find CHAP_C.\n");
353 goto out;
354 }
355 pr_debug("[server] Got CHAP_C=%s\n", challenge);
356 challenge_len = chap_string_to_hex(challenge_binhex, challenge,
357 strlen(challenge));
358 if (!challenge_len) {
359 pr_err("Unable to convert incoming challenge\n");
360 goto out;
361 }
362 /*
363 * Generate CHAP_N and CHAP_R for mutual authentication.
364 */
365 tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
366 if (IS_ERR(tfm)) {
367 pr_err("Unable to allocate struct crypto_hash\n");
368 goto out;
369 }
370 desc.tfm = tfm;
371 desc.flags = 0;
372
373 ret = crypto_hash_init(&desc);
374 if (ret < 0) {
375 pr_err("crypto_hash_init() failed\n");
376 crypto_free_hash(tfm);
377 goto out;
378 }
379
380 sg_init_one(&sg, (void *)&id, 1);
381 ret = crypto_hash_update(&desc, &sg, 1);
382 if (ret < 0) {
383 pr_err("crypto_hash_update() failed for id\n");
384 crypto_free_hash(tfm);
385 goto out;
386 }
387
388 sg_init_one(&sg, (void *)auth->password_mutual,
389 strlen(auth->password_mutual));
390 ret = crypto_hash_update(&desc, &sg, strlen(auth->password_mutual));
391 if (ret < 0) {
392 pr_err("crypto_hash_update() failed for"
393 " password_mutual\n");
394 crypto_free_hash(tfm);
395 goto out;
396 }
397 /*
398 * Convert received challenge to binary hex.
399 */
400 sg_init_one(&sg, (void *)challenge_binhex, challenge_len);
401 ret = crypto_hash_update(&desc, &sg, challenge_len);
402 if (ret < 0) {
403 pr_err("crypto_hash_update() failed for ma challenge\n");
404 crypto_free_hash(tfm);
405 goto out;
406 }
407
408 ret = crypto_hash_final(&desc, digest);
409 if (ret < 0) {
410 pr_err("crypto_hash_final() failed for ma digest\n");
411 crypto_free_hash(tfm);
412 goto out;
413 }
414 crypto_free_hash(tfm);
415 /*
416 * Generate CHAP_N and CHAP_R.
417 */
418 *nr_out_len = sprintf(nr_out_ptr, "CHAP_N=%s", auth->userid_mutual);
419 *nr_out_len += 1;
420 pr_debug("[server] Sending CHAP_N=%s\n", auth->userid_mutual);
421 /*
422 * Convert response from binary hex to ascii hext.
423 */
424 chap_binaryhex_to_asciihex(response, digest, MD5_SIGNATURE_SIZE);
425 *nr_out_len += sprintf(nr_out_ptr + *nr_out_len, "CHAP_R=0x%s",
426 response);
427 *nr_out_len += 1;
428 pr_debug("[server] Sending CHAP_R=0x%s\n", response);
429 auth_ret = 0;
430out:
431 kfree(challenge);
432 kfree(challenge_binhex);
433 return auth_ret;
434}
435
436static int chap_got_response(
437 struct iscsi_conn *conn,
438 struct iscsi_node_auth *auth,
439 char *nr_in_ptr,
440 char *nr_out_ptr,
441 unsigned int *nr_out_len)
442{
443 struct iscsi_chap *chap = (struct iscsi_chap *) conn->auth_protocol;
444
445 switch (chap->digest_type) {
446 case CHAP_DIGEST_MD5:
447 if (chap_server_compute_md5(conn, auth, nr_in_ptr,
448 nr_out_ptr, nr_out_len) < 0)
449 return -1;
450 return 0;
451 default:
452 pr_err("Unknown CHAP digest type %d!\n",
453 chap->digest_type);
454 return -1;
455 }
456}
457
458u32 chap_main_loop(
459 struct iscsi_conn *conn,
460 struct iscsi_node_auth *auth,
461 char *in_text,
462 char *out_text,
463 int *in_len,
464 int *out_len)
465{
466 struct iscsi_chap *chap = (struct iscsi_chap *) conn->auth_protocol;
467
468 if (!chap) {
469 chap = chap_server_open(conn, auth, in_text, out_text, out_len);
470 if (!chap)
471 return 2;
472 chap->chap_state = CHAP_STAGE_SERVER_AIC;
473 return 0;
474 } else if (chap->chap_state == CHAP_STAGE_SERVER_AIC) {
475 convert_null_to_semi(in_text, *in_len);
476 if (chap_got_response(conn, auth, in_text, out_text,
477 out_len) < 0) {
478 chap_close(conn);
479 return 2;
480 }
481 if (auth->authenticate_target)
482 chap->chap_state = CHAP_STAGE_SERVER_NR;
483 else
484 *out_len = 0;
485 chap_close(conn);
486 return 1;
487 }
488
489 return 2;
490}
diff --git a/drivers/target/iscsi/iscsi_target_auth.h b/drivers/target/iscsi/iscsi_target_auth.h
new file mode 100644
index 000000000000..2f463c09626d
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_auth.h
@@ -0,0 +1,31 @@
1#ifndef _ISCSI_CHAP_H_
2#define _ISCSI_CHAP_H_
3
4#define CHAP_DIGEST_MD5 5
5#define CHAP_DIGEST_SHA 6
6
7#define CHAP_CHALLENGE_LENGTH 16
8#define CHAP_CHALLENGE_STR_LEN 4096
9#define MAX_RESPONSE_LENGTH 64 /* sufficient for MD5 */
10#define MAX_CHAP_N_SIZE 512
11
12#define MD5_SIGNATURE_SIZE 16 /* 16 bytes in a MD5 message digest */
13
14#define CHAP_STAGE_CLIENT_A 1
15#define CHAP_STAGE_SERVER_AIC 2
16#define CHAP_STAGE_CLIENT_NR 3
17#define CHAP_STAGE_CLIENT_NRIC 4
18#define CHAP_STAGE_SERVER_NR 5
19
20extern u32 chap_main_loop(struct iscsi_conn *, struct iscsi_node_auth *, char *, char *,
21 int *, int *);
22
23struct iscsi_chap {
24 unsigned char digest_type;
25 unsigned char id;
26 unsigned char challenge[CHAP_CHALLENGE_LENGTH];
27 unsigned int authenticate_target;
28 unsigned int chap_state;
29} ____cacheline_aligned;
30
31#endif /*** _ISCSI_CHAP_H_ ***/
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
new file mode 100644
index 000000000000..32bb92c44450
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -0,0 +1,1882 @@
1/*******************************************************************************
2 * This file contains the configfs implementation for iSCSI Target mode
3 * from the LIO-Target Project.
4 *
5 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
6 *
7 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
8 *
9 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 ****************************************************************************/
21
22#include <linux/configfs.h>
23#include <target/target_core_base.h>
24#include <target/target_core_transport.h>
25#include <target/target_core_fabric_ops.h>
26#include <target/target_core_fabric_configfs.h>
27#include <target/target_core_fabric_lib.h>
28#include <target/target_core_device.h>
29#include <target/target_core_tpg.h>
30#include <target/target_core_configfs.h>
31#include <target/configfs_macros.h>
32
33#include "iscsi_target_core.h"
34#include "iscsi_target_parameters.h"
35#include "iscsi_target_device.h"
36#include "iscsi_target_erl0.h"
37#include "iscsi_target_nodeattrib.h"
38#include "iscsi_target_tpg.h"
39#include "iscsi_target_util.h"
40#include "iscsi_target.h"
41#include "iscsi_target_stat.h"
42#include "iscsi_target_configfs.h"
43
44struct target_fabric_configfs *lio_target_fabric_configfs;
45
46struct lio_target_configfs_attribute {
47 struct configfs_attribute attr;
48 ssize_t (*show)(void *, char *);
49 ssize_t (*store)(void *, const char *, size_t);
50};
51
52struct iscsi_portal_group *lio_get_tpg_from_tpg_item(
53 struct config_item *item,
54 struct iscsi_tiqn **tiqn_out)
55{
56 struct se_portal_group *se_tpg = container_of(to_config_group(item),
57 struct se_portal_group, tpg_group);
58 struct iscsi_portal_group *tpg =
59 (struct iscsi_portal_group *)se_tpg->se_tpg_fabric_ptr;
60 int ret;
61
62 if (!tpg) {
63 pr_err("Unable to locate struct iscsi_portal_group "
64 "pointer\n");
65 return NULL;
66 }
67 ret = iscsit_get_tpg(tpg);
68 if (ret < 0)
69 return NULL;
70
71 *tiqn_out = tpg->tpg_tiqn;
72 return tpg;
73}
74
75/* Start items for lio_target_portal_cit */
76
77static ssize_t lio_target_np_show_sctp(
78 struct se_tpg_np *se_tpg_np,
79 char *page)
80{
81 struct iscsi_tpg_np *tpg_np = container_of(se_tpg_np,
82 struct iscsi_tpg_np, se_tpg_np);
83 struct iscsi_tpg_np *tpg_np_sctp;
84 ssize_t rb;
85
86 tpg_np_sctp = iscsit_tpg_locate_child_np(tpg_np, ISCSI_SCTP_TCP);
87 if (tpg_np_sctp)
88 rb = sprintf(page, "1\n");
89 else
90 rb = sprintf(page, "0\n");
91
92 return rb;
93}
94
95static ssize_t lio_target_np_store_sctp(
96 struct se_tpg_np *se_tpg_np,
97 const char *page,
98 size_t count)
99{
100 struct iscsi_np *np;
101 struct iscsi_portal_group *tpg;
102 struct iscsi_tpg_np *tpg_np = container_of(se_tpg_np,
103 struct iscsi_tpg_np, se_tpg_np);
104 struct iscsi_tpg_np *tpg_np_sctp = NULL;
105 char *endptr;
106 u32 op;
107 int ret;
108
109 op = simple_strtoul(page, &endptr, 0);
110 if ((op != 1) && (op != 0)) {
111 pr_err("Illegal value for tpg_enable: %u\n", op);
112 return -EINVAL;
113 }
114 np = tpg_np->tpg_np;
115 if (!np) {
116 pr_err("Unable to locate struct iscsi_np from"
117 " struct iscsi_tpg_np\n");
118 return -EINVAL;
119 }
120
121 tpg = tpg_np->tpg;
122 if (iscsit_get_tpg(tpg) < 0)
123 return -EINVAL;
124
125 if (op) {
126 /*
127 * Use existing np->np_sockaddr for SCTP network portal reference
128 */
129 tpg_np_sctp = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr,
130 np->np_ip, tpg_np, ISCSI_SCTP_TCP);
131 if (!tpg_np_sctp || IS_ERR(tpg_np_sctp))
132 goto out;
133 } else {
134 tpg_np_sctp = iscsit_tpg_locate_child_np(tpg_np, ISCSI_SCTP_TCP);
135 if (!tpg_np_sctp)
136 goto out;
137
138 ret = iscsit_tpg_del_network_portal(tpg, tpg_np_sctp);
139 if (ret < 0)
140 goto out;
141 }
142
143 iscsit_put_tpg(tpg);
144 return count;
145out:
146 iscsit_put_tpg(tpg);
147 return -EINVAL;
148}
149
150TF_NP_BASE_ATTR(lio_target, sctp, S_IRUGO | S_IWUSR);
151
152static struct configfs_attribute *lio_target_portal_attrs[] = {
153 &lio_target_np_sctp.attr,
154 NULL,
155};
156
157/* Stop items for lio_target_portal_cit */
158
159/* Start items for lio_target_np_cit */
160
161#define MAX_PORTAL_LEN 256
162
163struct se_tpg_np *lio_target_call_addnptotpg(
164 struct se_portal_group *se_tpg,
165 struct config_group *group,
166 const char *name)
167{
168 struct iscsi_portal_group *tpg;
169 struct iscsi_tpg_np *tpg_np;
170 char *str, *str2, *ip_str, *port_str;
171 struct __kernel_sockaddr_storage sockaddr;
172 struct sockaddr_in *sock_in;
173 struct sockaddr_in6 *sock_in6;
174 unsigned long port;
175 int ret;
176 char buf[MAX_PORTAL_LEN + 1];
177
178 if (strlen(name) > MAX_PORTAL_LEN) {
179 pr_err("strlen(name): %d exceeds MAX_PORTAL_LEN: %d\n",
180 (int)strlen(name), MAX_PORTAL_LEN);
181 return ERR_PTR(-EOVERFLOW);
182 }
183 memset(buf, 0, MAX_PORTAL_LEN + 1);
184 snprintf(buf, MAX_PORTAL_LEN, "%s", name);
185
186 memset(&sockaddr, 0, sizeof(struct __kernel_sockaddr_storage));
187
188 str = strstr(buf, "[");
189 if (str) {
190 const char *end;
191
192 str2 = strstr(str, "]");
193 if (!str2) {
194 pr_err("Unable to locate trailing \"]\""
195 " in IPv6 iSCSI network portal address\n");
196 return ERR_PTR(-EINVAL);
197 }
198 str++; /* Skip over leading "[" */
199 *str2 = '\0'; /* Terminate the IPv6 address */
200 str2++; /* Skip over the "]" */
201 port_str = strstr(str2, ":");
202 if (!port_str) {
203 pr_err("Unable to locate \":port\""
204 " in IPv6 iSCSI network portal address\n");
205 return ERR_PTR(-EINVAL);
206 }
207 *port_str = '\0'; /* Terminate string for IP */
208 port_str++; /* Skip over ":" */
209
210 ret = strict_strtoul(port_str, 0, &port);
211 if (ret < 0) {
212 pr_err("strict_strtoul() failed for port_str: %d\n", ret);
213 return ERR_PTR(ret);
214 }
215 sock_in6 = (struct sockaddr_in6 *)&sockaddr;
216 sock_in6->sin6_family = AF_INET6;
217 sock_in6->sin6_port = htons((unsigned short)port);
218 ret = in6_pton(str, IPV6_ADDRESS_SPACE,
219 (void *)&sock_in6->sin6_addr.in6_u, -1, &end);
220 if (ret <= 0) {
221 pr_err("in6_pton returned: %d\n", ret);
222 return ERR_PTR(-EINVAL);
223 }
224 } else {
225 str = ip_str = &buf[0];
226 port_str = strstr(ip_str, ":");
227 if (!port_str) {
228 pr_err("Unable to locate \":port\""
229 " in IPv4 iSCSI network portal address\n");
230 return ERR_PTR(-EINVAL);
231 }
232 *port_str = '\0'; /* Terminate string for IP */
233 port_str++; /* Skip over ":" */
234
235 ret = strict_strtoul(port_str, 0, &port);
236 if (ret < 0) {
237 pr_err("strict_strtoul() failed for port_str: %d\n", ret);
238 return ERR_PTR(ret);
239 }
240 sock_in = (struct sockaddr_in *)&sockaddr;
241 sock_in->sin_family = AF_INET;
242 sock_in->sin_port = htons((unsigned short)port);
243 sock_in->sin_addr.s_addr = in_aton(ip_str);
244 }
245 tpg = container_of(se_tpg, struct iscsi_portal_group, tpg_se_tpg);
246 ret = iscsit_get_tpg(tpg);
247 if (ret < 0)
248 return ERR_PTR(-EINVAL);
249
250 pr_debug("LIO_Target_ConfigFS: REGISTER -> %s TPGT: %hu"
251 " PORTAL: %s\n",
252 config_item_name(&se_tpg->se_tpg_wwn->wwn_group.cg_item),
253 tpg->tpgt, name);
254 /*
255 * Assume ISCSI_TCP by default. Other network portals for other
256 * iSCSI fabrics:
257 *
258 * Traditional iSCSI over SCTP (initial support)
259 * iSER/TCP (TODO, hardware available)
260 * iSER/SCTP (TODO, software emulation with osc-iwarp)
261 * iSER/IB (TODO, hardware available)
262 *
263 * can be enabled with atributes under
264 * sys/kernel/config/iscsi/$IQN/$TPG/np/$IP:$PORT/
265 *
266 */
267 tpg_np = iscsit_tpg_add_network_portal(tpg, &sockaddr, str, NULL,
268 ISCSI_TCP);
269 if (IS_ERR(tpg_np)) {
270 iscsit_put_tpg(tpg);
271 return ERR_PTR(PTR_ERR(tpg_np));
272 }
273 pr_debug("LIO_Target_ConfigFS: addnptotpg done!\n");
274
275 iscsit_put_tpg(tpg);
276 return &tpg_np->se_tpg_np;
277}
278
279static void lio_target_call_delnpfromtpg(
280 struct se_tpg_np *se_tpg_np)
281{
282 struct iscsi_portal_group *tpg;
283 struct iscsi_tpg_np *tpg_np;
284 struct se_portal_group *se_tpg;
285 int ret;
286
287 tpg_np = container_of(se_tpg_np, struct iscsi_tpg_np, se_tpg_np);
288 tpg = tpg_np->tpg;
289 ret = iscsit_get_tpg(tpg);
290 if (ret < 0)
291 return;
292
293 se_tpg = &tpg->tpg_se_tpg;
294 pr_debug("LIO_Target_ConfigFS: DEREGISTER -> %s TPGT: %hu"
295 " PORTAL: %s:%hu\n", config_item_name(&se_tpg->se_tpg_wwn->wwn_group.cg_item),
296 tpg->tpgt, tpg_np->tpg_np->np_ip, tpg_np->tpg_np->np_port);
297
298 ret = iscsit_tpg_del_network_portal(tpg, tpg_np);
299 if (ret < 0)
300 goto out;
301
302 pr_debug("LIO_Target_ConfigFS: delnpfromtpg done!\n");
303out:
304 iscsit_put_tpg(tpg);
305}
306
307/* End items for lio_target_np_cit */
308
309/* Start items for lio_target_nacl_attrib_cit */
310
311#define DEF_NACL_ATTRIB(name) \
312static ssize_t iscsi_nacl_attrib_show_##name( \
313 struct se_node_acl *se_nacl, \
314 char *page) \
315{ \
316 struct iscsi_node_acl *nacl = container_of(se_nacl, struct iscsi_node_acl, \
317 se_node_acl); \
318 \
319 return sprintf(page, "%u\n", ISCSI_NODE_ATTRIB(nacl)->name); \
320} \
321 \
322static ssize_t iscsi_nacl_attrib_store_##name( \
323 struct se_node_acl *se_nacl, \
324 const char *page, \
325 size_t count) \
326{ \
327 struct iscsi_node_acl *nacl = container_of(se_nacl, struct iscsi_node_acl, \
328 se_node_acl); \
329 char *endptr; \
330 u32 val; \
331 int ret; \
332 \
333 val = simple_strtoul(page, &endptr, 0); \
334 ret = iscsit_na_##name(nacl, val); \
335 if (ret < 0) \
336 return ret; \
337 \
338 return count; \
339}
340
341#define NACL_ATTR(_name, _mode) TF_NACL_ATTRIB_ATTR(iscsi, _name, _mode);
342/*
343 * Define iscsi_node_attrib_s_dataout_timeout
344 */
345DEF_NACL_ATTRIB(dataout_timeout);
346NACL_ATTR(dataout_timeout, S_IRUGO | S_IWUSR);
347/*
348 * Define iscsi_node_attrib_s_dataout_timeout_retries
349 */
350DEF_NACL_ATTRIB(dataout_timeout_retries);
351NACL_ATTR(dataout_timeout_retries, S_IRUGO | S_IWUSR);
352/*
353 * Define iscsi_node_attrib_s_default_erl
354 */
355DEF_NACL_ATTRIB(default_erl);
356NACL_ATTR(default_erl, S_IRUGO | S_IWUSR);
357/*
358 * Define iscsi_node_attrib_s_nopin_timeout
359 */
360DEF_NACL_ATTRIB(nopin_timeout);
361NACL_ATTR(nopin_timeout, S_IRUGO | S_IWUSR);
362/*
363 * Define iscsi_node_attrib_s_nopin_response_timeout
364 */
365DEF_NACL_ATTRIB(nopin_response_timeout);
366NACL_ATTR(nopin_response_timeout, S_IRUGO | S_IWUSR);
367/*
368 * Define iscsi_node_attrib_s_random_datain_pdu_offsets
369 */
370DEF_NACL_ATTRIB(random_datain_pdu_offsets);
371NACL_ATTR(random_datain_pdu_offsets, S_IRUGO | S_IWUSR);
372/*
373 * Define iscsi_node_attrib_s_random_datain_seq_offsets
374 */
375DEF_NACL_ATTRIB(random_datain_seq_offsets);
376NACL_ATTR(random_datain_seq_offsets, S_IRUGO | S_IWUSR);
377/*
378 * Define iscsi_node_attrib_s_random_r2t_offsets
379 */
380DEF_NACL_ATTRIB(random_r2t_offsets);
381NACL_ATTR(random_r2t_offsets, S_IRUGO | S_IWUSR);
382
383static struct configfs_attribute *lio_target_nacl_attrib_attrs[] = {
384 &iscsi_nacl_attrib_dataout_timeout.attr,
385 &iscsi_nacl_attrib_dataout_timeout_retries.attr,
386 &iscsi_nacl_attrib_default_erl.attr,
387 &iscsi_nacl_attrib_nopin_timeout.attr,
388 &iscsi_nacl_attrib_nopin_response_timeout.attr,
389 &iscsi_nacl_attrib_random_datain_pdu_offsets.attr,
390 &iscsi_nacl_attrib_random_datain_seq_offsets.attr,
391 &iscsi_nacl_attrib_random_r2t_offsets.attr,
392 NULL,
393};
394
395/* End items for lio_target_nacl_attrib_cit */
396
397/* Start items for lio_target_nacl_auth_cit */
398
399#define __DEF_NACL_AUTH_STR(prefix, name, flags) \
400static ssize_t __iscsi_##prefix##_show_##name( \
401 struct iscsi_node_acl *nacl, \
402 char *page) \
403{ \
404 struct iscsi_node_auth *auth = &nacl->node_auth; \
405 \
406 if (!capable(CAP_SYS_ADMIN)) \
407 return -EPERM; \
408 return snprintf(page, PAGE_SIZE, "%s\n", auth->name); \
409} \
410 \
411static ssize_t __iscsi_##prefix##_store_##name( \
412 struct iscsi_node_acl *nacl, \
413 const char *page, \
414 size_t count) \
415{ \
416 struct iscsi_node_auth *auth = &nacl->node_auth; \
417 \
418 if (!capable(CAP_SYS_ADMIN)) \
419 return -EPERM; \
420 \
421 snprintf(auth->name, PAGE_SIZE, "%s", page); \
422 if (!strncmp("NULL", auth->name, 4)) \
423 auth->naf_flags &= ~flags; \
424 else \
425 auth->naf_flags |= flags; \
426 \
427 if ((auth->naf_flags & NAF_USERID_IN_SET) && \
428 (auth->naf_flags & NAF_PASSWORD_IN_SET)) \
429 auth->authenticate_target = 1; \
430 else \
431 auth->authenticate_target = 0; \
432 \
433 return count; \
434}
435
436#define __DEF_NACL_AUTH_INT(prefix, name) \
437static ssize_t __iscsi_##prefix##_show_##name( \
438 struct iscsi_node_acl *nacl, \
439 char *page) \
440{ \
441 struct iscsi_node_auth *auth = &nacl->node_auth; \
442 \
443 if (!capable(CAP_SYS_ADMIN)) \
444 return -EPERM; \
445 \
446 return snprintf(page, PAGE_SIZE, "%d\n", auth->name); \
447}
448
449#define DEF_NACL_AUTH_STR(name, flags) \
450 __DEF_NACL_AUTH_STR(nacl_auth, name, flags) \
451static ssize_t iscsi_nacl_auth_show_##name( \
452 struct se_node_acl *nacl, \
453 char *page) \
454{ \
455 return __iscsi_nacl_auth_show_##name(container_of(nacl, \
456 struct iscsi_node_acl, se_node_acl), page); \
457} \
458static ssize_t iscsi_nacl_auth_store_##name( \
459 struct se_node_acl *nacl, \
460 const char *page, \
461 size_t count) \
462{ \
463 return __iscsi_nacl_auth_store_##name(container_of(nacl, \
464 struct iscsi_node_acl, se_node_acl), page, count); \
465}
466
467#define DEF_NACL_AUTH_INT(name) \
468 __DEF_NACL_AUTH_INT(nacl_auth, name) \
469static ssize_t iscsi_nacl_auth_show_##name( \
470 struct se_node_acl *nacl, \
471 char *page) \
472{ \
473 return __iscsi_nacl_auth_show_##name(container_of(nacl, \
474 struct iscsi_node_acl, se_node_acl), page); \
475}
476
477#define AUTH_ATTR(_name, _mode) TF_NACL_AUTH_ATTR(iscsi, _name, _mode);
478#define AUTH_ATTR_RO(_name) TF_NACL_AUTH_ATTR_RO(iscsi, _name);
479
480/*
481 * One-way authentication userid
482 */
483DEF_NACL_AUTH_STR(userid, NAF_USERID_SET);
484AUTH_ATTR(userid, S_IRUGO | S_IWUSR);
485/*
486 * One-way authentication password
487 */
488DEF_NACL_AUTH_STR(password, NAF_PASSWORD_SET);
489AUTH_ATTR(password, S_IRUGO | S_IWUSR);
490/*
491 * Enforce mutual authentication
492 */
493DEF_NACL_AUTH_INT(authenticate_target);
494AUTH_ATTR_RO(authenticate_target);
495/*
496 * Mutual authentication userid
497 */
498DEF_NACL_AUTH_STR(userid_mutual, NAF_USERID_IN_SET);
499AUTH_ATTR(userid_mutual, S_IRUGO | S_IWUSR);
500/*
501 * Mutual authentication password
502 */
503DEF_NACL_AUTH_STR(password_mutual, NAF_PASSWORD_IN_SET);
504AUTH_ATTR(password_mutual, S_IRUGO | S_IWUSR);
505
506static struct configfs_attribute *lio_target_nacl_auth_attrs[] = {
507 &iscsi_nacl_auth_userid.attr,
508 &iscsi_nacl_auth_password.attr,
509 &iscsi_nacl_auth_authenticate_target.attr,
510 &iscsi_nacl_auth_userid_mutual.attr,
511 &iscsi_nacl_auth_password_mutual.attr,
512 NULL,
513};
514
515/* End items for lio_target_nacl_auth_cit */
516
517/* Start items for lio_target_nacl_param_cit */
518
519#define DEF_NACL_PARAM(name) \
520static ssize_t iscsi_nacl_param_show_##name( \
521 struct se_node_acl *se_nacl, \
522 char *page) \
523{ \
524 struct iscsi_session *sess; \
525 struct se_session *se_sess; \
526 ssize_t rb; \
527 \
528 spin_lock_bh(&se_nacl->nacl_sess_lock); \
529 se_sess = se_nacl->nacl_sess; \
530 if (!se_sess) { \
531 rb = snprintf(page, PAGE_SIZE, \
532 "No Active iSCSI Session\n"); \
533 } else { \
534 sess = se_sess->fabric_sess_ptr; \
535 rb = snprintf(page, PAGE_SIZE, "%u\n", \
536 (u32)sess->sess_ops->name); \
537 } \
538 spin_unlock_bh(&se_nacl->nacl_sess_lock); \
539 \
540 return rb; \
541}
542
543#define NACL_PARAM_ATTR(_name) TF_NACL_PARAM_ATTR_RO(iscsi, _name);
544
545DEF_NACL_PARAM(MaxConnections);
546NACL_PARAM_ATTR(MaxConnections);
547
548DEF_NACL_PARAM(InitialR2T);
549NACL_PARAM_ATTR(InitialR2T);
550
551DEF_NACL_PARAM(ImmediateData);
552NACL_PARAM_ATTR(ImmediateData);
553
554DEF_NACL_PARAM(MaxBurstLength);
555NACL_PARAM_ATTR(MaxBurstLength);
556
557DEF_NACL_PARAM(FirstBurstLength);
558NACL_PARAM_ATTR(FirstBurstLength);
559
560DEF_NACL_PARAM(DefaultTime2Wait);
561NACL_PARAM_ATTR(DefaultTime2Wait);
562
563DEF_NACL_PARAM(DefaultTime2Retain);
564NACL_PARAM_ATTR(DefaultTime2Retain);
565
566DEF_NACL_PARAM(MaxOutstandingR2T);
567NACL_PARAM_ATTR(MaxOutstandingR2T);
568
569DEF_NACL_PARAM(DataPDUInOrder);
570NACL_PARAM_ATTR(DataPDUInOrder);
571
572DEF_NACL_PARAM(DataSequenceInOrder);
573NACL_PARAM_ATTR(DataSequenceInOrder);
574
575DEF_NACL_PARAM(ErrorRecoveryLevel);
576NACL_PARAM_ATTR(ErrorRecoveryLevel);
577
578static struct configfs_attribute *lio_target_nacl_param_attrs[] = {
579 &iscsi_nacl_param_MaxConnections.attr,
580 &iscsi_nacl_param_InitialR2T.attr,
581 &iscsi_nacl_param_ImmediateData.attr,
582 &iscsi_nacl_param_MaxBurstLength.attr,
583 &iscsi_nacl_param_FirstBurstLength.attr,
584 &iscsi_nacl_param_DefaultTime2Wait.attr,
585 &iscsi_nacl_param_DefaultTime2Retain.attr,
586 &iscsi_nacl_param_MaxOutstandingR2T.attr,
587 &iscsi_nacl_param_DataPDUInOrder.attr,
588 &iscsi_nacl_param_DataSequenceInOrder.attr,
589 &iscsi_nacl_param_ErrorRecoveryLevel.attr,
590 NULL,
591};
592
593/* End items for lio_target_nacl_param_cit */
594
595/* Start items for lio_target_acl_cit */
596
597static ssize_t lio_target_nacl_show_info(
598 struct se_node_acl *se_nacl,
599 char *page)
600{
601 struct iscsi_session *sess;
602 struct iscsi_conn *conn;
603 struct se_session *se_sess;
604 ssize_t rb = 0;
605
606 spin_lock_bh(&se_nacl->nacl_sess_lock);
607 se_sess = se_nacl->nacl_sess;
608 if (!se_sess) {
609 rb += sprintf(page+rb, "No active iSCSI Session for Initiator"
610 " Endpoint: %s\n", se_nacl->initiatorname);
611 } else {
612 sess = se_sess->fabric_sess_ptr;
613
614 if (sess->sess_ops->InitiatorName)
615 rb += sprintf(page+rb, "InitiatorName: %s\n",
616 sess->sess_ops->InitiatorName);
617 if (sess->sess_ops->InitiatorAlias)
618 rb += sprintf(page+rb, "InitiatorAlias: %s\n",
619 sess->sess_ops->InitiatorAlias);
620
621 rb += sprintf(page+rb, "LIO Session ID: %u "
622 "ISID: 0x%02x %02x %02x %02x %02x %02x "
623 "TSIH: %hu ", sess->sid,
624 sess->isid[0], sess->isid[1], sess->isid[2],
625 sess->isid[3], sess->isid[4], sess->isid[5],
626 sess->tsih);
627 rb += sprintf(page+rb, "SessionType: %s\n",
628 (sess->sess_ops->SessionType) ?
629 "Discovery" : "Normal");
630 rb += sprintf(page+rb, "Session State: ");
631 switch (sess->session_state) {
632 case TARG_SESS_STATE_FREE:
633 rb += sprintf(page+rb, "TARG_SESS_FREE\n");
634 break;
635 case TARG_SESS_STATE_ACTIVE:
636 rb += sprintf(page+rb, "TARG_SESS_STATE_ACTIVE\n");
637 break;
638 case TARG_SESS_STATE_LOGGED_IN:
639 rb += sprintf(page+rb, "TARG_SESS_STATE_LOGGED_IN\n");
640 break;
641 case TARG_SESS_STATE_FAILED:
642 rb += sprintf(page+rb, "TARG_SESS_STATE_FAILED\n");
643 break;
644 case TARG_SESS_STATE_IN_CONTINUE:
645 rb += sprintf(page+rb, "TARG_SESS_STATE_IN_CONTINUE\n");
646 break;
647 default:
648 rb += sprintf(page+rb, "ERROR: Unknown Session"
649 " State!\n");
650 break;
651 }
652
653 rb += sprintf(page+rb, "---------------------[iSCSI Session"
654 " Values]-----------------------\n");
655 rb += sprintf(page+rb, " CmdSN/WR : CmdSN/WC : ExpCmdSN"
656 " : MaxCmdSN : ITT : TTT\n");
657 rb += sprintf(page+rb, " 0x%08x 0x%08x 0x%08x 0x%08x"
658 " 0x%08x 0x%08x\n",
659 sess->cmdsn_window,
660 (sess->max_cmd_sn - sess->exp_cmd_sn) + 1,
661 sess->exp_cmd_sn, sess->max_cmd_sn,
662 sess->init_task_tag, sess->targ_xfer_tag);
663 rb += sprintf(page+rb, "----------------------[iSCSI"
664 " Connections]-------------------------\n");
665
666 spin_lock(&sess->conn_lock);
667 list_for_each_entry(conn, &sess->sess_conn_list, conn_list) {
668 rb += sprintf(page+rb, "CID: %hu Connection"
669 " State: ", conn->cid);
670 switch (conn->conn_state) {
671 case TARG_CONN_STATE_FREE:
672 rb += sprintf(page+rb,
673 "TARG_CONN_STATE_FREE\n");
674 break;
675 case TARG_CONN_STATE_XPT_UP:
676 rb += sprintf(page+rb,
677 "TARG_CONN_STATE_XPT_UP\n");
678 break;
679 case TARG_CONN_STATE_IN_LOGIN:
680 rb += sprintf(page+rb,
681 "TARG_CONN_STATE_IN_LOGIN\n");
682 break;
683 case TARG_CONN_STATE_LOGGED_IN:
684 rb += sprintf(page+rb,
685 "TARG_CONN_STATE_LOGGED_IN\n");
686 break;
687 case TARG_CONN_STATE_IN_LOGOUT:
688 rb += sprintf(page+rb,
689 "TARG_CONN_STATE_IN_LOGOUT\n");
690 break;
691 case TARG_CONN_STATE_LOGOUT_REQUESTED:
692 rb += sprintf(page+rb,
693 "TARG_CONN_STATE_LOGOUT_REQUESTED\n");
694 break;
695 case TARG_CONN_STATE_CLEANUP_WAIT:
696 rb += sprintf(page+rb,
697 "TARG_CONN_STATE_CLEANUP_WAIT\n");
698 break;
699 default:
700 rb += sprintf(page+rb,
701 "ERROR: Unknown Connection State!\n");
702 break;
703 }
704
705 rb += sprintf(page+rb, " Address %s %s", conn->login_ip,
706 (conn->network_transport == ISCSI_TCP) ?
707 "TCP" : "SCTP");
708 rb += sprintf(page+rb, " StatSN: 0x%08x\n",
709 conn->stat_sn);
710 }
711 spin_unlock(&sess->conn_lock);
712 }
713 spin_unlock_bh(&se_nacl->nacl_sess_lock);
714
715 return rb;
716}
717
718TF_NACL_BASE_ATTR_RO(lio_target, info);
719
720static ssize_t lio_target_nacl_show_cmdsn_depth(
721 struct se_node_acl *se_nacl,
722 char *page)
723{
724 return sprintf(page, "%u\n", se_nacl->queue_depth);
725}
726
727static ssize_t lio_target_nacl_store_cmdsn_depth(
728 struct se_node_acl *se_nacl,
729 const char *page,
730 size_t count)
731{
732 struct se_portal_group *se_tpg = se_nacl->se_tpg;
733 struct iscsi_portal_group *tpg = container_of(se_tpg,
734 struct iscsi_portal_group, tpg_se_tpg);
735 struct config_item *acl_ci, *tpg_ci, *wwn_ci;
736 char *endptr;
737 u32 cmdsn_depth = 0;
738 int ret;
739
740 cmdsn_depth = simple_strtoul(page, &endptr, 0);
741 if (cmdsn_depth > TA_DEFAULT_CMDSN_DEPTH_MAX) {
742 pr_err("Passed cmdsn_depth: %u exceeds"
743 " TA_DEFAULT_CMDSN_DEPTH_MAX: %u\n", cmdsn_depth,
744 TA_DEFAULT_CMDSN_DEPTH_MAX);
745 return -EINVAL;
746 }
747 acl_ci = &se_nacl->acl_group.cg_item;
748 if (!acl_ci) {
749 pr_err("Unable to locatel acl_ci\n");
750 return -EINVAL;
751 }
752 tpg_ci = &acl_ci->ci_parent->ci_group->cg_item;
753 if (!tpg_ci) {
754 pr_err("Unable to locate tpg_ci\n");
755 return -EINVAL;
756 }
757 wwn_ci = &tpg_ci->ci_group->cg_item;
758 if (!wwn_ci) {
759 pr_err("Unable to locate config_item wwn_ci\n");
760 return -EINVAL;
761 }
762
763 if (iscsit_get_tpg(tpg) < 0)
764 return -EINVAL;
765 /*
766 * iscsit_tpg_set_initiator_node_queue_depth() assumes force=1
767 */
768 ret = iscsit_tpg_set_initiator_node_queue_depth(tpg,
769 config_item_name(acl_ci), cmdsn_depth, 1);
770
771 pr_debug("LIO_Target_ConfigFS: %s/%s Set CmdSN Window: %u for"
772 "InitiatorName: %s\n", config_item_name(wwn_ci),
773 config_item_name(tpg_ci), cmdsn_depth,
774 config_item_name(acl_ci));
775
776 iscsit_put_tpg(tpg);
777 return (!ret) ? count : (ssize_t)ret;
778}
779
780TF_NACL_BASE_ATTR(lio_target, cmdsn_depth, S_IRUGO | S_IWUSR);
781
782static struct configfs_attribute *lio_target_initiator_attrs[] = {
783 &lio_target_nacl_info.attr,
784 &lio_target_nacl_cmdsn_depth.attr,
785 NULL,
786};
787
788static struct se_node_acl *lio_tpg_alloc_fabric_acl(
789 struct se_portal_group *se_tpg)
790{
791 struct iscsi_node_acl *acl;
792
793 acl = kzalloc(sizeof(struct iscsi_node_acl), GFP_KERNEL);
794 if (!acl) {
795 pr_err("Unable to allocate memory for struct iscsi_node_acl\n");
796 return NULL;
797 }
798
799 return &acl->se_node_acl;
800}
801
802static struct se_node_acl *lio_target_make_nodeacl(
803 struct se_portal_group *se_tpg,
804 struct config_group *group,
805 const char *name)
806{
807 struct config_group *stats_cg;
808 struct iscsi_node_acl *acl;
809 struct se_node_acl *se_nacl_new, *se_nacl;
810 struct iscsi_portal_group *tpg = container_of(se_tpg,
811 struct iscsi_portal_group, tpg_se_tpg);
812 u32 cmdsn_depth;
813
814 se_nacl_new = lio_tpg_alloc_fabric_acl(se_tpg);
815 if (!se_nacl_new)
816 return ERR_PTR(-ENOMEM);
817
818 acl = container_of(se_nacl_new, struct iscsi_node_acl,
819 se_node_acl);
820
821 cmdsn_depth = ISCSI_TPG_ATTRIB(tpg)->default_cmdsn_depth;
822 /*
823 * se_nacl_new may be released by core_tpg_add_initiator_node_acl()
824 * when converting a NdoeACL from demo mode -> explict
825 */
826 se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new,
827 name, cmdsn_depth);
828 if (IS_ERR(se_nacl))
829 return se_nacl;
830
831 stats_cg = &acl->se_node_acl.acl_fabric_stat_group;
832
833 stats_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
834 GFP_KERNEL);
835 if (!stats_cg->default_groups) {
836 pr_err("Unable to allocate memory for"
837 " stats_cg->default_groups\n");
838 core_tpg_del_initiator_node_acl(se_tpg, se_nacl, 1);
839 kfree(acl);
840 return ERR_PTR(-ENOMEM);
841 }
842
843 stats_cg->default_groups[0] = &NODE_STAT_GRPS(acl)->iscsi_sess_stats_group;
844 stats_cg->default_groups[1] = NULL;
845 config_group_init_type_name(&NODE_STAT_GRPS(acl)->iscsi_sess_stats_group,
846 "iscsi_sess_stats", &iscsi_stat_sess_cit);
847
848 return se_nacl;
849}
850
851static void lio_target_drop_nodeacl(
852 struct se_node_acl *se_nacl)
853{
854 struct se_portal_group *se_tpg = se_nacl->se_tpg;
855 struct iscsi_node_acl *acl = container_of(se_nacl,
856 struct iscsi_node_acl, se_node_acl);
857 struct config_item *df_item;
858 struct config_group *stats_cg;
859 int i;
860
861 stats_cg = &acl->se_node_acl.acl_fabric_stat_group;
862 for (i = 0; stats_cg->default_groups[i]; i++) {
863 df_item = &stats_cg->default_groups[i]->cg_item;
864 stats_cg->default_groups[i] = NULL;
865 config_item_put(df_item);
866 }
867 kfree(stats_cg->default_groups);
868
869 core_tpg_del_initiator_node_acl(se_tpg, se_nacl, 1);
870 kfree(acl);
871}
872
873/* End items for lio_target_acl_cit */
874
875/* Start items for lio_target_tpg_attrib_cit */
876
877#define DEF_TPG_ATTRIB(name) \
878 \
879static ssize_t iscsi_tpg_attrib_show_##name( \
880 struct se_portal_group *se_tpg, \
881 char *page) \
882{ \
883 struct iscsi_portal_group *tpg = container_of(se_tpg, \
884 struct iscsi_portal_group, tpg_se_tpg); \
885 ssize_t rb; \
886 \
887 if (iscsit_get_tpg(tpg) < 0) \
888 return -EINVAL; \
889 \
890 rb = sprintf(page, "%u\n", ISCSI_TPG_ATTRIB(tpg)->name); \
891 iscsit_put_tpg(tpg); \
892 return rb; \
893} \
894 \
895static ssize_t iscsi_tpg_attrib_store_##name( \
896 struct se_portal_group *se_tpg, \
897 const char *page, \
898 size_t count) \
899{ \
900 struct iscsi_portal_group *tpg = container_of(se_tpg, \
901 struct iscsi_portal_group, tpg_se_tpg); \
902 char *endptr; \
903 u32 val; \
904 int ret; \
905 \
906 if (iscsit_get_tpg(tpg) < 0) \
907 return -EINVAL; \
908 \
909 val = simple_strtoul(page, &endptr, 0); \
910 ret = iscsit_ta_##name(tpg, val); \
911 if (ret < 0) \
912 goto out; \
913 \
914 iscsit_put_tpg(tpg); \
915 return count; \
916out: \
917 iscsit_put_tpg(tpg); \
918 return ret; \
919}
920
921#define TPG_ATTR(_name, _mode) TF_TPG_ATTRIB_ATTR(iscsi, _name, _mode);
922
923/*
924 * Define iscsi_tpg_attrib_s_authentication
925 */
926DEF_TPG_ATTRIB(authentication);
927TPG_ATTR(authentication, S_IRUGO | S_IWUSR);
928/*
929 * Define iscsi_tpg_attrib_s_login_timeout
930 */
931DEF_TPG_ATTRIB(login_timeout);
932TPG_ATTR(login_timeout, S_IRUGO | S_IWUSR);
933/*
934 * Define iscsi_tpg_attrib_s_netif_timeout
935 */
936DEF_TPG_ATTRIB(netif_timeout);
937TPG_ATTR(netif_timeout, S_IRUGO | S_IWUSR);
938/*
939 * Define iscsi_tpg_attrib_s_generate_node_acls
940 */
941DEF_TPG_ATTRIB(generate_node_acls);
942TPG_ATTR(generate_node_acls, S_IRUGO | S_IWUSR);
943/*
944 * Define iscsi_tpg_attrib_s_default_cmdsn_depth
945 */
946DEF_TPG_ATTRIB(default_cmdsn_depth);
947TPG_ATTR(default_cmdsn_depth, S_IRUGO | S_IWUSR);
948/*
949 Define iscsi_tpg_attrib_s_cache_dynamic_acls
950 */
951DEF_TPG_ATTRIB(cache_dynamic_acls);
952TPG_ATTR(cache_dynamic_acls, S_IRUGO | S_IWUSR);
953/*
954 * Define iscsi_tpg_attrib_s_demo_mode_write_protect
955 */
956DEF_TPG_ATTRIB(demo_mode_write_protect);
957TPG_ATTR(demo_mode_write_protect, S_IRUGO | S_IWUSR);
958/*
959 * Define iscsi_tpg_attrib_s_prod_mode_write_protect
960 */
961DEF_TPG_ATTRIB(prod_mode_write_protect);
962TPG_ATTR(prod_mode_write_protect, S_IRUGO | S_IWUSR);
963
964static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
965 &iscsi_tpg_attrib_authentication.attr,
966 &iscsi_tpg_attrib_login_timeout.attr,
967 &iscsi_tpg_attrib_netif_timeout.attr,
968 &iscsi_tpg_attrib_generate_node_acls.attr,
969 &iscsi_tpg_attrib_default_cmdsn_depth.attr,
970 &iscsi_tpg_attrib_cache_dynamic_acls.attr,
971 &iscsi_tpg_attrib_demo_mode_write_protect.attr,
972 &iscsi_tpg_attrib_prod_mode_write_protect.attr,
973 NULL,
974};
975
976/* End items for lio_target_tpg_attrib_cit */
977
978/* Start items for lio_target_tpg_param_cit */
979
980#define DEF_TPG_PARAM(name) \
981static ssize_t iscsi_tpg_param_show_##name( \
982 struct se_portal_group *se_tpg, \
983 char *page) \
984{ \
985 struct iscsi_portal_group *tpg = container_of(se_tpg, \
986 struct iscsi_portal_group, tpg_se_tpg); \
987 struct iscsi_param *param; \
988 ssize_t rb; \
989 \
990 if (iscsit_get_tpg(tpg) < 0) \
991 return -EINVAL; \
992 \
993 param = iscsi_find_param_from_key(__stringify(name), \
994 tpg->param_list); \
995 if (!param) { \
996 iscsit_put_tpg(tpg); \
997 return -EINVAL; \
998 } \
999 rb = snprintf(page, PAGE_SIZE, "%s\n", param->value); \
1000 \
1001 iscsit_put_tpg(tpg); \
1002 return rb; \
1003} \
1004static ssize_t iscsi_tpg_param_store_##name( \
1005 struct se_portal_group *se_tpg, \
1006 const char *page, \
1007 size_t count) \
1008{ \
1009 struct iscsi_portal_group *tpg = container_of(se_tpg, \
1010 struct iscsi_portal_group, tpg_se_tpg); \
1011 char *buf; \
1012 int ret; \
1013 \
1014 buf = kzalloc(PAGE_SIZE, GFP_KERNEL); \
1015 if (!buf) \
1016 return -ENOMEM; \
1017 snprintf(buf, PAGE_SIZE, "%s=%s", __stringify(name), page); \
1018 buf[strlen(buf)-1] = '\0'; /* Kill newline */ \
1019 \
1020 if (iscsit_get_tpg(tpg) < 0) { \
1021 kfree(buf); \
1022 return -EINVAL; \
1023 } \
1024 \
1025 ret = iscsi_change_param_value(buf, tpg->param_list, 1); \
1026 if (ret < 0) \
1027 goto out; \
1028 \
1029 kfree(buf); \
1030 iscsit_put_tpg(tpg); \
1031 return count; \
1032out: \
1033 kfree(buf); \
1034 iscsit_put_tpg(tpg); \
1035 return -EINVAL; \
1036}
1037
1038#define TPG_PARAM_ATTR(_name, _mode) TF_TPG_PARAM_ATTR(iscsi, _name, _mode);
1039
1040DEF_TPG_PARAM(AuthMethod);
1041TPG_PARAM_ATTR(AuthMethod, S_IRUGO | S_IWUSR);
1042
1043DEF_TPG_PARAM(HeaderDigest);
1044TPG_PARAM_ATTR(HeaderDigest, S_IRUGO | S_IWUSR);
1045
1046DEF_TPG_PARAM(DataDigest);
1047TPG_PARAM_ATTR(DataDigest, S_IRUGO | S_IWUSR);
1048
1049DEF_TPG_PARAM(MaxConnections);
1050TPG_PARAM_ATTR(MaxConnections, S_IRUGO | S_IWUSR);
1051
1052DEF_TPG_PARAM(TargetAlias);
1053TPG_PARAM_ATTR(TargetAlias, S_IRUGO | S_IWUSR);
1054
1055DEF_TPG_PARAM(InitialR2T);
1056TPG_PARAM_ATTR(InitialR2T, S_IRUGO | S_IWUSR);
1057
1058DEF_TPG_PARAM(ImmediateData);
1059TPG_PARAM_ATTR(ImmediateData, S_IRUGO | S_IWUSR);
1060
1061DEF_TPG_PARAM(MaxRecvDataSegmentLength);
1062TPG_PARAM_ATTR(MaxRecvDataSegmentLength, S_IRUGO | S_IWUSR);
1063
1064DEF_TPG_PARAM(MaxBurstLength);
1065TPG_PARAM_ATTR(MaxBurstLength, S_IRUGO | S_IWUSR);
1066
1067DEF_TPG_PARAM(FirstBurstLength);
1068TPG_PARAM_ATTR(FirstBurstLength, S_IRUGO | S_IWUSR);
1069
1070DEF_TPG_PARAM(DefaultTime2Wait);
1071TPG_PARAM_ATTR(DefaultTime2Wait, S_IRUGO | S_IWUSR);
1072
1073DEF_TPG_PARAM(DefaultTime2Retain);
1074TPG_PARAM_ATTR(DefaultTime2Retain, S_IRUGO | S_IWUSR);
1075
1076DEF_TPG_PARAM(MaxOutstandingR2T);
1077TPG_PARAM_ATTR(MaxOutstandingR2T, S_IRUGO | S_IWUSR);
1078
1079DEF_TPG_PARAM(DataPDUInOrder);
1080TPG_PARAM_ATTR(DataPDUInOrder, S_IRUGO | S_IWUSR);
1081
1082DEF_TPG_PARAM(DataSequenceInOrder);
1083TPG_PARAM_ATTR(DataSequenceInOrder, S_IRUGO | S_IWUSR);
1084
1085DEF_TPG_PARAM(ErrorRecoveryLevel);
1086TPG_PARAM_ATTR(ErrorRecoveryLevel, S_IRUGO | S_IWUSR);
1087
1088DEF_TPG_PARAM(IFMarker);
1089TPG_PARAM_ATTR(IFMarker, S_IRUGO | S_IWUSR);
1090
1091DEF_TPG_PARAM(OFMarker);
1092TPG_PARAM_ATTR(OFMarker, S_IRUGO | S_IWUSR);
1093
1094DEF_TPG_PARAM(IFMarkInt);
1095TPG_PARAM_ATTR(IFMarkInt, S_IRUGO | S_IWUSR);
1096
1097DEF_TPG_PARAM(OFMarkInt);
1098TPG_PARAM_ATTR(OFMarkInt, S_IRUGO | S_IWUSR);
1099
1100static struct configfs_attribute *lio_target_tpg_param_attrs[] = {
1101 &iscsi_tpg_param_AuthMethod.attr,
1102 &iscsi_tpg_param_HeaderDigest.attr,
1103 &iscsi_tpg_param_DataDigest.attr,
1104 &iscsi_tpg_param_MaxConnections.attr,
1105 &iscsi_tpg_param_TargetAlias.attr,
1106 &iscsi_tpg_param_InitialR2T.attr,
1107 &iscsi_tpg_param_ImmediateData.attr,
1108 &iscsi_tpg_param_MaxRecvDataSegmentLength.attr,
1109 &iscsi_tpg_param_MaxBurstLength.attr,
1110 &iscsi_tpg_param_FirstBurstLength.attr,
1111 &iscsi_tpg_param_DefaultTime2Wait.attr,
1112 &iscsi_tpg_param_DefaultTime2Retain.attr,
1113 &iscsi_tpg_param_MaxOutstandingR2T.attr,
1114 &iscsi_tpg_param_DataPDUInOrder.attr,
1115 &iscsi_tpg_param_DataSequenceInOrder.attr,
1116 &iscsi_tpg_param_ErrorRecoveryLevel.attr,
1117 &iscsi_tpg_param_IFMarker.attr,
1118 &iscsi_tpg_param_OFMarker.attr,
1119 &iscsi_tpg_param_IFMarkInt.attr,
1120 &iscsi_tpg_param_OFMarkInt.attr,
1121 NULL,
1122};
1123
1124/* End items for lio_target_tpg_param_cit */
1125
1126/* Start items for lio_target_tpg_cit */
1127
1128static ssize_t lio_target_tpg_show_enable(
1129 struct se_portal_group *se_tpg,
1130 char *page)
1131{
1132 struct iscsi_portal_group *tpg = container_of(se_tpg,
1133 struct iscsi_portal_group, tpg_se_tpg);
1134 ssize_t len;
1135
1136 spin_lock(&tpg->tpg_state_lock);
1137 len = sprintf(page, "%d\n",
1138 (tpg->tpg_state == TPG_STATE_ACTIVE) ? 1 : 0);
1139 spin_unlock(&tpg->tpg_state_lock);
1140
1141 return len;
1142}
1143
1144static ssize_t lio_target_tpg_store_enable(
1145 struct se_portal_group *se_tpg,
1146 const char *page,
1147 size_t count)
1148{
1149 struct iscsi_portal_group *tpg = container_of(se_tpg,
1150 struct iscsi_portal_group, tpg_se_tpg);
1151 char *endptr;
1152 u32 op;
1153 int ret = 0;
1154
1155 op = simple_strtoul(page, &endptr, 0);
1156 if ((op != 1) && (op != 0)) {
1157 pr_err("Illegal value for tpg_enable: %u\n", op);
1158 return -EINVAL;
1159 }
1160
1161 ret = iscsit_get_tpg(tpg);
1162 if (ret < 0)
1163 return -EINVAL;
1164
1165 if (op) {
1166 ret = iscsit_tpg_enable_portal_group(tpg);
1167 if (ret < 0)
1168 goto out;
1169 } else {
1170 /*
1171 * iscsit_tpg_disable_portal_group() assumes force=1
1172 */
1173 ret = iscsit_tpg_disable_portal_group(tpg, 1);
1174 if (ret < 0)
1175 goto out;
1176 }
1177
1178 iscsit_put_tpg(tpg);
1179 return count;
1180out:
1181 iscsit_put_tpg(tpg);
1182 return -EINVAL;
1183}
1184
1185TF_TPG_BASE_ATTR(lio_target, enable, S_IRUGO | S_IWUSR);
1186
1187static struct configfs_attribute *lio_target_tpg_attrs[] = {
1188 &lio_target_tpg_enable.attr,
1189 NULL,
1190};
1191
1192/* End items for lio_target_tpg_cit */
1193
1194/* Start items for lio_target_tiqn_cit */
1195
1196struct se_portal_group *lio_target_tiqn_addtpg(
1197 struct se_wwn *wwn,
1198 struct config_group *group,
1199 const char *name)
1200{
1201 struct iscsi_portal_group *tpg;
1202 struct iscsi_tiqn *tiqn;
1203 char *tpgt_str, *end_ptr;
1204 int ret = 0;
1205 unsigned short int tpgt;
1206
1207 tiqn = container_of(wwn, struct iscsi_tiqn, tiqn_wwn);
1208 /*
1209 * Only tpgt_# directory groups can be created below
1210 * target/iscsi/iqn.superturodiskarry/
1211 */
1212 tpgt_str = strstr(name, "tpgt_");
1213 if (!tpgt_str) {
1214 pr_err("Unable to locate \"tpgt_#\" directory"
1215 " group\n");
1216 return NULL;
1217 }
1218 tpgt_str += 5; /* Skip ahead of "tpgt_" */
1219 tpgt = (unsigned short int) simple_strtoul(tpgt_str, &end_ptr, 0);
1220
1221 tpg = iscsit_alloc_portal_group(tiqn, tpgt);
1222 if (!tpg)
1223 return NULL;
1224
1225 ret = core_tpg_register(
1226 &lio_target_fabric_configfs->tf_ops,
1227 wwn, &tpg->tpg_se_tpg, (void *)tpg,
1228 TRANSPORT_TPG_TYPE_NORMAL);
1229 if (ret < 0)
1230 return NULL;
1231
1232 ret = iscsit_tpg_add_portal_group(tiqn, tpg);
1233 if (ret != 0)
1234 goto out;
1235
1236 pr_debug("LIO_Target_ConfigFS: REGISTER -> %s\n", tiqn->tiqn);
1237 pr_debug("LIO_Target_ConfigFS: REGISTER -> Allocated TPG: %s\n",
1238 name);
1239 return &tpg->tpg_se_tpg;
1240out:
1241 core_tpg_deregister(&tpg->tpg_se_tpg);
1242 kfree(tpg);
1243 return NULL;
1244}
1245
1246void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg)
1247{
1248 struct iscsi_portal_group *tpg;
1249 struct iscsi_tiqn *tiqn;
1250
1251 tpg = container_of(se_tpg, struct iscsi_portal_group, tpg_se_tpg);
1252 tiqn = tpg->tpg_tiqn;
1253 /*
1254 * iscsit_tpg_del_portal_group() assumes force=1
1255 */
1256 pr_debug("LIO_Target_ConfigFS: DEREGISTER -> Releasing TPG\n");
1257 iscsit_tpg_del_portal_group(tiqn, tpg, 1);
1258}
1259
1260/* End items for lio_target_tiqn_cit */
1261
1262/* Start LIO-Target TIQN struct contig_item lio_target_cit */
1263
1264static ssize_t lio_target_wwn_show_attr_lio_version(
1265 struct target_fabric_configfs *tf,
1266 char *page)
1267{
1268 return sprintf(page, "RisingTide Systems Linux-iSCSI Target "ISCSIT_VERSION"\n");
1269}
1270
1271TF_WWN_ATTR_RO(lio_target, lio_version);
1272
1273static struct configfs_attribute *lio_target_wwn_attrs[] = {
1274 &lio_target_wwn_lio_version.attr,
1275 NULL,
1276};
1277
1278struct se_wwn *lio_target_call_coreaddtiqn(
1279 struct target_fabric_configfs *tf,
1280 struct config_group *group,
1281 const char *name)
1282{
1283 struct config_group *stats_cg;
1284 struct iscsi_tiqn *tiqn;
1285
1286 tiqn = iscsit_add_tiqn((unsigned char *)name);
1287 if (IS_ERR(tiqn))
1288 return ERR_PTR(PTR_ERR(tiqn));
1289 /*
1290 * Setup struct iscsi_wwn_stat_grps for se_wwn->fabric_stat_group.
1291 */
1292 stats_cg = &tiqn->tiqn_wwn.fabric_stat_group;
1293
1294 stats_cg->default_groups = kzalloc(sizeof(struct config_group) * 6,
1295 GFP_KERNEL);
1296 if (!stats_cg->default_groups) {
1297 pr_err("Unable to allocate memory for"
1298 " stats_cg->default_groups\n");
1299 iscsit_del_tiqn(tiqn);
1300 return ERR_PTR(-ENOMEM);
1301 }
1302
1303 stats_cg->default_groups[0] = &WWN_STAT_GRPS(tiqn)->iscsi_instance_group;
1304 stats_cg->default_groups[1] = &WWN_STAT_GRPS(tiqn)->iscsi_sess_err_group;
1305 stats_cg->default_groups[2] = &WWN_STAT_GRPS(tiqn)->iscsi_tgt_attr_group;
1306 stats_cg->default_groups[3] = &WWN_STAT_GRPS(tiqn)->iscsi_login_stats_group;
1307 stats_cg->default_groups[4] = &WWN_STAT_GRPS(tiqn)->iscsi_logout_stats_group;
1308 stats_cg->default_groups[5] = NULL;
1309 config_group_init_type_name(&WWN_STAT_GRPS(tiqn)->iscsi_instance_group,
1310 "iscsi_instance", &iscsi_stat_instance_cit);
1311 config_group_init_type_name(&WWN_STAT_GRPS(tiqn)->iscsi_sess_err_group,
1312 "iscsi_sess_err", &iscsi_stat_sess_err_cit);
1313 config_group_init_type_name(&WWN_STAT_GRPS(tiqn)->iscsi_tgt_attr_group,
1314 "iscsi_tgt_attr", &iscsi_stat_tgt_attr_cit);
1315 config_group_init_type_name(&WWN_STAT_GRPS(tiqn)->iscsi_login_stats_group,
1316 "iscsi_login_stats", &iscsi_stat_login_cit);
1317 config_group_init_type_name(&WWN_STAT_GRPS(tiqn)->iscsi_logout_stats_group,
1318 "iscsi_logout_stats", &iscsi_stat_logout_cit);
1319
1320 pr_debug("LIO_Target_ConfigFS: REGISTER -> %s\n", tiqn->tiqn);
1321 pr_debug("LIO_Target_ConfigFS: REGISTER -> Allocated Node:"
1322 " %s\n", name);
1323 return &tiqn->tiqn_wwn;
1324}
1325
1326void lio_target_call_coredeltiqn(
1327 struct se_wwn *wwn)
1328{
1329 struct iscsi_tiqn *tiqn = container_of(wwn, struct iscsi_tiqn, tiqn_wwn);
1330 struct config_item *df_item;
1331 struct config_group *stats_cg;
1332 int i;
1333
1334 stats_cg = &tiqn->tiqn_wwn.fabric_stat_group;
1335 for (i = 0; stats_cg->default_groups[i]; i++) {
1336 df_item = &stats_cg->default_groups[i]->cg_item;
1337 stats_cg->default_groups[i] = NULL;
1338 config_item_put(df_item);
1339 }
1340 kfree(stats_cg->default_groups);
1341
1342 pr_debug("LIO_Target_ConfigFS: DEREGISTER -> %s\n",
1343 tiqn->tiqn);
1344 iscsit_del_tiqn(tiqn);
1345}
1346
1347/* End LIO-Target TIQN struct contig_lio_target_cit */
1348
1349/* Start lio_target_discovery_auth_cit */
1350
1351#define DEF_DISC_AUTH_STR(name, flags) \
1352 __DEF_NACL_AUTH_STR(disc, name, flags) \
1353static ssize_t iscsi_disc_show_##name( \
1354 struct target_fabric_configfs *tf, \
1355 char *page) \
1356{ \
1357 return __iscsi_disc_show_##name(&iscsit_global->discovery_acl, \
1358 page); \
1359} \
1360static ssize_t iscsi_disc_store_##name( \
1361 struct target_fabric_configfs *tf, \
1362 const char *page, \
1363 size_t count) \
1364{ \
1365 return __iscsi_disc_store_##name(&iscsit_global->discovery_acl, \
1366 page, count); \
1367}
1368
1369#define DEF_DISC_AUTH_INT(name) \
1370 __DEF_NACL_AUTH_INT(disc, name) \
1371static ssize_t iscsi_disc_show_##name( \
1372 struct target_fabric_configfs *tf, \
1373 char *page) \
1374{ \
1375 return __iscsi_disc_show_##name(&iscsit_global->discovery_acl, \
1376 page); \
1377}
1378
1379#define DISC_AUTH_ATTR(_name, _mode) TF_DISC_ATTR(iscsi, _name, _mode)
1380#define DISC_AUTH_ATTR_RO(_name) TF_DISC_ATTR_RO(iscsi, _name)
1381
1382/*
1383 * One-way authentication userid
1384 */
1385DEF_DISC_AUTH_STR(userid, NAF_USERID_SET);
1386DISC_AUTH_ATTR(userid, S_IRUGO | S_IWUSR);
1387/*
1388 * One-way authentication password
1389 */
1390DEF_DISC_AUTH_STR(password, NAF_PASSWORD_SET);
1391DISC_AUTH_ATTR(password, S_IRUGO | S_IWUSR);
1392/*
1393 * Enforce mutual authentication
1394 */
1395DEF_DISC_AUTH_INT(authenticate_target);
1396DISC_AUTH_ATTR_RO(authenticate_target);
1397/*
1398 * Mutual authentication userid
1399 */
1400DEF_DISC_AUTH_STR(userid_mutual, NAF_USERID_IN_SET);
1401DISC_AUTH_ATTR(userid_mutual, S_IRUGO | S_IWUSR);
1402/*
1403 * Mutual authentication password
1404 */
1405DEF_DISC_AUTH_STR(password_mutual, NAF_PASSWORD_IN_SET);
1406DISC_AUTH_ATTR(password_mutual, S_IRUGO | S_IWUSR);
1407
1408/*
1409 * enforce_discovery_auth
1410 */
1411static ssize_t iscsi_disc_show_enforce_discovery_auth(
1412 struct target_fabric_configfs *tf,
1413 char *page)
1414{
1415 struct iscsi_node_auth *discovery_auth = &iscsit_global->discovery_acl.node_auth;
1416
1417 return sprintf(page, "%d\n", discovery_auth->enforce_discovery_auth);
1418}
1419
1420static ssize_t iscsi_disc_store_enforce_discovery_auth(
1421 struct target_fabric_configfs *tf,
1422 const char *page,
1423 size_t count)
1424{
1425 struct iscsi_param *param;
1426 struct iscsi_portal_group *discovery_tpg = iscsit_global->discovery_tpg;
1427 char *endptr;
1428 u32 op;
1429
1430 op = simple_strtoul(page, &endptr, 0);
1431 if ((op != 1) && (op != 0)) {
1432 pr_err("Illegal value for enforce_discovery_auth:"
1433 " %u\n", op);
1434 return -EINVAL;
1435 }
1436
1437 if (!discovery_tpg) {
1438 pr_err("iscsit_global->discovery_tpg is NULL\n");
1439 return -EINVAL;
1440 }
1441
1442 param = iscsi_find_param_from_key(AUTHMETHOD,
1443 discovery_tpg->param_list);
1444 if (!param)
1445 return -EINVAL;
1446
1447 if (op) {
1448 /*
1449 * Reset the AuthMethod key to CHAP.
1450 */
1451 if (iscsi_update_param_value(param, CHAP) < 0)
1452 return -EINVAL;
1453
1454 discovery_tpg->tpg_attrib.authentication = 1;
1455 iscsit_global->discovery_acl.node_auth.enforce_discovery_auth = 1;
1456 pr_debug("LIO-CORE[0] Successfully enabled"
1457 " authentication enforcement for iSCSI"
1458 " Discovery TPG\n");
1459 } else {
1460 /*
1461 * Reset the AuthMethod key to CHAP,None
1462 */
1463 if (iscsi_update_param_value(param, "CHAP,None") < 0)
1464 return -EINVAL;
1465
1466 discovery_tpg->tpg_attrib.authentication = 0;
1467 iscsit_global->discovery_acl.node_auth.enforce_discovery_auth = 0;
1468 pr_debug("LIO-CORE[0] Successfully disabled"
1469 " authentication enforcement for iSCSI"
1470 " Discovery TPG\n");
1471 }
1472
1473 return count;
1474}
1475
1476DISC_AUTH_ATTR(enforce_discovery_auth, S_IRUGO | S_IWUSR);
1477
1478static struct configfs_attribute *lio_target_discovery_auth_attrs[] = {
1479 &iscsi_disc_userid.attr,
1480 &iscsi_disc_password.attr,
1481 &iscsi_disc_authenticate_target.attr,
1482 &iscsi_disc_userid_mutual.attr,
1483 &iscsi_disc_password_mutual.attr,
1484 &iscsi_disc_enforce_discovery_auth.attr,
1485 NULL,
1486};
1487
1488/* End lio_target_discovery_auth_cit */
1489
1490/* Start functions for target_core_fabric_ops */
1491
1492static char *iscsi_get_fabric_name(void)
1493{
1494 return "iSCSI";
1495}
1496
1497static u32 iscsi_get_task_tag(struct se_cmd *se_cmd)
1498{
1499 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
1500
1501 return cmd->init_task_tag;
1502}
1503
1504static int iscsi_get_cmd_state(struct se_cmd *se_cmd)
1505{
1506 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
1507
1508 return cmd->i_state;
1509}
1510
1511static int iscsi_is_state_remove(struct se_cmd *se_cmd)
1512{
1513 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
1514
1515 return (cmd->i_state == ISTATE_REMOVE);
1516}
1517
1518static int lio_sess_logged_in(struct se_session *se_sess)
1519{
1520 struct iscsi_session *sess = se_sess->fabric_sess_ptr;
1521 int ret;
1522 /*
1523 * Called with spin_lock_bh(&tpg_lock); and
1524 * spin_lock(&se_tpg->session_lock); held.
1525 */
1526 spin_lock(&sess->conn_lock);
1527 ret = (sess->session_state != TARG_SESS_STATE_LOGGED_IN);
1528 spin_unlock(&sess->conn_lock);
1529
1530 return ret;
1531}
1532
1533static u32 lio_sess_get_index(struct se_session *se_sess)
1534{
1535 struct iscsi_session *sess = se_sess->fabric_sess_ptr;
1536
1537 return sess->session_index;
1538}
1539
1540static u32 lio_sess_get_initiator_sid(
1541 struct se_session *se_sess,
1542 unsigned char *buf,
1543 u32 size)
1544{
1545 struct iscsi_session *sess = se_sess->fabric_sess_ptr;
1546 /*
1547 * iSCSI Initiator Session Identifier from RFC-3720.
1548 */
1549 return snprintf(buf, size, "%02x%02x%02x%02x%02x%02x",
1550 sess->isid[0], sess->isid[1], sess->isid[2],
1551 sess->isid[3], sess->isid[4], sess->isid[5]);
1552}
1553
1554static int lio_queue_data_in(struct se_cmd *se_cmd)
1555{
1556 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
1557
1558 cmd->i_state = ISTATE_SEND_DATAIN;
1559 iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
1560 return 0;
1561}
1562
1563static int lio_write_pending(struct se_cmd *se_cmd)
1564{
1565 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
1566
1567 if (!cmd->immediate_data && !cmd->unsolicited_data)
1568 return iscsit_build_r2ts_for_cmd(cmd, cmd->conn, 1);
1569
1570 return 0;
1571}
1572
1573static int lio_write_pending_status(struct se_cmd *se_cmd)
1574{
1575 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
1576 int ret;
1577
1578 spin_lock_bh(&cmd->istate_lock);
1579 ret = !(cmd->cmd_flags & ICF_GOT_LAST_DATAOUT);
1580 spin_unlock_bh(&cmd->istate_lock);
1581
1582 return ret;
1583}
1584
1585static int lio_queue_status(struct se_cmd *se_cmd)
1586{
1587 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
1588
1589 cmd->i_state = ISTATE_SEND_STATUS;
1590 iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
1591 return 0;
1592}
1593
1594static u16 lio_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
1595{
1596 unsigned char *buffer = se_cmd->sense_buffer;
1597 /*
1598 * From RFC-3720 10.4.7. Data Segment - Sense and Response Data Segment
1599 * 16-bit SenseLength.
1600 */
1601 buffer[0] = ((sense_length >> 8) & 0xff);
1602 buffer[1] = (sense_length & 0xff);
1603 /*
1604 * Return two byte offset into allocated sense_buffer.
1605 */
1606 return 2;
1607}
1608
1609static u16 lio_get_fabric_sense_len(void)
1610{
1611 /*
1612 * Return two byte offset into allocated sense_buffer.
1613 */
1614 return 2;
1615}
1616
1617static int lio_queue_tm_rsp(struct se_cmd *se_cmd)
1618{
1619 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
1620
1621 cmd->i_state = ISTATE_SEND_TASKMGTRSP;
1622 iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
1623 return 0;
1624}
1625
1626static char *lio_tpg_get_endpoint_wwn(struct se_portal_group *se_tpg)
1627{
1628 struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
1629
1630 return &tpg->tpg_tiqn->tiqn[0];
1631}
1632
1633static u16 lio_tpg_get_tag(struct se_portal_group *se_tpg)
1634{
1635 struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
1636
1637 return tpg->tpgt;
1638}
1639
1640static u32 lio_tpg_get_default_depth(struct se_portal_group *se_tpg)
1641{
1642 struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
1643
1644 return ISCSI_TPG_ATTRIB(tpg)->default_cmdsn_depth;
1645}
1646
1647static int lio_tpg_check_demo_mode(struct se_portal_group *se_tpg)
1648{
1649 struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
1650
1651 return ISCSI_TPG_ATTRIB(tpg)->generate_node_acls;
1652}
1653
1654static int lio_tpg_check_demo_mode_cache(struct se_portal_group *se_tpg)
1655{
1656 struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
1657
1658 return ISCSI_TPG_ATTRIB(tpg)->cache_dynamic_acls;
1659}
1660
1661static int lio_tpg_check_demo_mode_write_protect(
1662 struct se_portal_group *se_tpg)
1663{
1664 struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
1665
1666 return ISCSI_TPG_ATTRIB(tpg)->demo_mode_write_protect;
1667}
1668
1669static int lio_tpg_check_prod_mode_write_protect(
1670 struct se_portal_group *se_tpg)
1671{
1672 struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
1673
1674 return ISCSI_TPG_ATTRIB(tpg)->prod_mode_write_protect;
1675}
1676
1677static void lio_tpg_release_fabric_acl(
1678 struct se_portal_group *se_tpg,
1679 struct se_node_acl *se_acl)
1680{
1681 struct iscsi_node_acl *acl = container_of(se_acl,
1682 struct iscsi_node_acl, se_node_acl);
1683 kfree(acl);
1684}
1685
1686/*
1687 * Called with spin_lock_bh(struct se_portal_group->session_lock) held..
1688 *
1689 * Also, this function calls iscsit_inc_session_usage_count() on the
1690 * struct iscsi_session in question.
1691 */
1692static int lio_tpg_shutdown_session(struct se_session *se_sess)
1693{
1694 struct iscsi_session *sess = se_sess->fabric_sess_ptr;
1695
1696 spin_lock(&sess->conn_lock);
1697 if (atomic_read(&sess->session_fall_back_to_erl0) ||
1698 atomic_read(&sess->session_logout) ||
1699 (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)) {
1700 spin_unlock(&sess->conn_lock);
1701 return 0;
1702 }
1703 atomic_set(&sess->session_reinstatement, 1);
1704 spin_unlock(&sess->conn_lock);
1705
1706 iscsit_inc_session_usage_count(sess);
1707 iscsit_stop_time2retain_timer(sess);
1708
1709 return 1;
1710}
1711
1712/*
1713 * Calls iscsit_dec_session_usage_count() as inverse of
1714 * lio_tpg_shutdown_session()
1715 */
1716static void lio_tpg_close_session(struct se_session *se_sess)
1717{
1718 struct iscsi_session *sess = se_sess->fabric_sess_ptr;
1719 /*
1720 * If the iSCSI Session for the iSCSI Initiator Node exists,
1721 * forcefully shutdown the iSCSI NEXUS.
1722 */
1723 iscsit_stop_session(sess, 1, 1);
1724 iscsit_dec_session_usage_count(sess);
1725 iscsit_close_session(sess);
1726}
1727
1728static void lio_tpg_stop_session(
1729 struct se_session *se_sess,
1730 int sess_sleep,
1731 int conn_sleep)
1732{
1733 struct iscsi_session *sess = se_sess->fabric_sess_ptr;
1734
1735 iscsit_stop_session(sess, sess_sleep, conn_sleep);
1736}
1737
1738static void lio_tpg_fall_back_to_erl0(struct se_session *se_sess)
1739{
1740 struct iscsi_session *sess = se_sess->fabric_sess_ptr;
1741
1742 iscsit_fall_back_to_erl0(sess);
1743}
1744
1745static u32 lio_tpg_get_inst_index(struct se_portal_group *se_tpg)
1746{
1747 struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
1748
1749 return tpg->tpg_tiqn->tiqn_index;
1750}
1751
1752static void lio_set_default_node_attributes(struct se_node_acl *se_acl)
1753{
1754 struct iscsi_node_acl *acl = container_of(se_acl, struct iscsi_node_acl,
1755 se_node_acl);
1756
1757 ISCSI_NODE_ATTRIB(acl)->nacl = acl;
1758 iscsit_set_default_node_attribues(acl);
1759}
1760
1761static void lio_release_cmd(struct se_cmd *se_cmd)
1762{
1763 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
1764
1765 iscsit_release_cmd(cmd);
1766}
1767
1768/* End functions for target_core_fabric_ops */
1769
1770int iscsi_target_register_configfs(void)
1771{
1772 struct target_fabric_configfs *fabric;
1773 int ret;
1774
1775 lio_target_fabric_configfs = NULL;
1776 fabric = target_fabric_configfs_init(THIS_MODULE, "iscsi");
1777 if (IS_ERR(fabric)) {
1778 pr_err("target_fabric_configfs_init() for"
1779 " LIO-Target failed!\n");
1780 return PTR_ERR(fabric);
1781 }
1782 /*
1783 * Setup the fabric API of function pointers used by target_core_mod..
1784 */
1785 fabric->tf_ops.get_fabric_name = &iscsi_get_fabric_name;
1786 fabric->tf_ops.get_fabric_proto_ident = &iscsi_get_fabric_proto_ident;
1787 fabric->tf_ops.tpg_get_wwn = &lio_tpg_get_endpoint_wwn;
1788 fabric->tf_ops.tpg_get_tag = &lio_tpg_get_tag;
1789 fabric->tf_ops.tpg_get_default_depth = &lio_tpg_get_default_depth;
1790 fabric->tf_ops.tpg_get_pr_transport_id = &iscsi_get_pr_transport_id;
1791 fabric->tf_ops.tpg_get_pr_transport_id_len =
1792 &iscsi_get_pr_transport_id_len;
1793 fabric->tf_ops.tpg_parse_pr_out_transport_id =
1794 &iscsi_parse_pr_out_transport_id;
1795 fabric->tf_ops.tpg_check_demo_mode = &lio_tpg_check_demo_mode;
1796 fabric->tf_ops.tpg_check_demo_mode_cache =
1797 &lio_tpg_check_demo_mode_cache;
1798 fabric->tf_ops.tpg_check_demo_mode_write_protect =
1799 &lio_tpg_check_demo_mode_write_protect;
1800 fabric->tf_ops.tpg_check_prod_mode_write_protect =
1801 &lio_tpg_check_prod_mode_write_protect;
1802 fabric->tf_ops.tpg_alloc_fabric_acl = &lio_tpg_alloc_fabric_acl;
1803 fabric->tf_ops.tpg_release_fabric_acl = &lio_tpg_release_fabric_acl;
1804 fabric->tf_ops.tpg_get_inst_index = &lio_tpg_get_inst_index;
1805 fabric->tf_ops.release_cmd = &lio_release_cmd;
1806 fabric->tf_ops.shutdown_session = &lio_tpg_shutdown_session;
1807 fabric->tf_ops.close_session = &lio_tpg_close_session;
1808 fabric->tf_ops.stop_session = &lio_tpg_stop_session;
1809 fabric->tf_ops.fall_back_to_erl0 = &lio_tpg_fall_back_to_erl0;
1810 fabric->tf_ops.sess_logged_in = &lio_sess_logged_in;
1811 fabric->tf_ops.sess_get_index = &lio_sess_get_index;
1812 fabric->tf_ops.sess_get_initiator_sid = &lio_sess_get_initiator_sid;
1813 fabric->tf_ops.write_pending = &lio_write_pending;
1814 fabric->tf_ops.write_pending_status = &lio_write_pending_status;
1815 fabric->tf_ops.set_default_node_attributes =
1816 &lio_set_default_node_attributes;
1817 fabric->tf_ops.get_task_tag = &iscsi_get_task_tag;
1818 fabric->tf_ops.get_cmd_state = &iscsi_get_cmd_state;
1819 fabric->tf_ops.queue_data_in = &lio_queue_data_in;
1820 fabric->tf_ops.queue_status = &lio_queue_status;
1821 fabric->tf_ops.queue_tm_rsp = &lio_queue_tm_rsp;
1822 fabric->tf_ops.set_fabric_sense_len = &lio_set_fabric_sense_len;
1823 fabric->tf_ops.get_fabric_sense_len = &lio_get_fabric_sense_len;
1824 fabric->tf_ops.is_state_remove = &iscsi_is_state_remove;
1825 /*
1826 * Setup function pointers for generic logic in target_core_fabric_configfs.c
1827 */
1828 fabric->tf_ops.fabric_make_wwn = &lio_target_call_coreaddtiqn;
1829 fabric->tf_ops.fabric_drop_wwn = &lio_target_call_coredeltiqn;
1830 fabric->tf_ops.fabric_make_tpg = &lio_target_tiqn_addtpg;
1831 fabric->tf_ops.fabric_drop_tpg = &lio_target_tiqn_deltpg;
1832 fabric->tf_ops.fabric_post_link = NULL;
1833 fabric->tf_ops.fabric_pre_unlink = NULL;
1834 fabric->tf_ops.fabric_make_np = &lio_target_call_addnptotpg;
1835 fabric->tf_ops.fabric_drop_np = &lio_target_call_delnpfromtpg;
1836 fabric->tf_ops.fabric_make_nodeacl = &lio_target_make_nodeacl;
1837 fabric->tf_ops.fabric_drop_nodeacl = &lio_target_drop_nodeacl;
1838 /*
1839 * Setup default attribute lists for various fabric->tf_cit_tmpl
1840 * sturct config_item_type's
1841 */
1842 TF_CIT_TMPL(fabric)->tfc_discovery_cit.ct_attrs = lio_target_discovery_auth_attrs;
1843 TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = lio_target_wwn_attrs;
1844 TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = lio_target_tpg_attrs;
1845 TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = lio_target_tpg_attrib_attrs;
1846 TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = lio_target_tpg_param_attrs;
1847 TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = lio_target_portal_attrs;
1848 TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = lio_target_initiator_attrs;
1849 TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = lio_target_nacl_attrib_attrs;
1850 TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = lio_target_nacl_auth_attrs;
1851 TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = lio_target_nacl_param_attrs;
1852
1853 ret = target_fabric_configfs_register(fabric);
1854 if (ret < 0) {
1855 pr_err("target_fabric_configfs_register() for"
1856 " LIO-Target failed!\n");
1857 target_fabric_configfs_free(fabric);
1858 return ret;
1859 }
1860
1861 lio_target_fabric_configfs = fabric;
1862 pr_debug("LIO_TARGET[0] - Set fabric ->"
1863 " lio_target_fabric_configfs\n");
1864 return 0;
1865}
1866
1867
1868void iscsi_target_deregister_configfs(void)
1869{
1870 if (!lio_target_fabric_configfs)
1871 return;
1872 /*
1873 * Shutdown discovery sessions and disable discovery TPG
1874 */
1875 if (iscsit_global->discovery_tpg)
1876 iscsit_tpg_disable_portal_group(iscsit_global->discovery_tpg, 1);
1877
1878 target_fabric_configfs_deregister(lio_target_fabric_configfs);
1879 lio_target_fabric_configfs = NULL;
1880 pr_debug("LIO_TARGET[0] - Cleared"
1881 " lio_target_fabric_configfs\n");
1882}
diff --git a/drivers/target/iscsi/iscsi_target_configfs.h b/drivers/target/iscsi/iscsi_target_configfs.h
new file mode 100644
index 000000000000..8cd5a63c4edc
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_configfs.h
@@ -0,0 +1,7 @@
1#ifndef ISCSI_TARGET_CONFIGFS_H
2#define ISCSI_TARGET_CONFIGFS_H
3
4extern int iscsi_target_register_configfs(void);
5extern void iscsi_target_deregister_configfs(void);
6
7#endif /* ISCSI_TARGET_CONFIGFS_H */
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h
new file mode 100644
index 000000000000..470ed551eeb5
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_core.h
@@ -0,0 +1,859 @@
1#ifndef ISCSI_TARGET_CORE_H
2#define ISCSI_TARGET_CORE_H
3
4#include <linux/in.h>
5#include <linux/configfs.h>
6#include <net/sock.h>
7#include <net/tcp.h>
8#include <scsi/scsi_cmnd.h>
9#include <scsi/iscsi_proto.h>
10#include <target/target_core_base.h>
11
12#define ISCSIT_VERSION "v4.1.0-rc1"
13#define ISCSI_MAX_DATASN_MISSING_COUNT 16
14#define ISCSI_TX_THREAD_TCP_TIMEOUT 2
15#define ISCSI_RX_THREAD_TCP_TIMEOUT 2
16#define SECONDS_FOR_ASYNC_LOGOUT 10
17#define SECONDS_FOR_ASYNC_TEXT 10
18#define SECONDS_FOR_LOGOUT_COMP 15
19#define WHITE_SPACE " \t\v\f\n\r"
20
21/* struct iscsi_node_attrib sanity values */
22#define NA_DATAOUT_TIMEOUT 3
23#define NA_DATAOUT_TIMEOUT_MAX 60
24#define NA_DATAOUT_TIMEOUT_MIX 2
25#define NA_DATAOUT_TIMEOUT_RETRIES 5
26#define NA_DATAOUT_TIMEOUT_RETRIES_MAX 15
27#define NA_DATAOUT_TIMEOUT_RETRIES_MIN 1
28#define NA_NOPIN_TIMEOUT 5
29#define NA_NOPIN_TIMEOUT_MAX 60
30#define NA_NOPIN_TIMEOUT_MIN 3
31#define NA_NOPIN_RESPONSE_TIMEOUT 5
32#define NA_NOPIN_RESPONSE_TIMEOUT_MAX 60
33#define NA_NOPIN_RESPONSE_TIMEOUT_MIN 3
34#define NA_RANDOM_DATAIN_PDU_OFFSETS 0
35#define NA_RANDOM_DATAIN_SEQ_OFFSETS 0
36#define NA_RANDOM_R2T_OFFSETS 0
37#define NA_DEFAULT_ERL 0
38#define NA_DEFAULT_ERL_MAX 2
39#define NA_DEFAULT_ERL_MIN 0
40
41/* struct iscsi_tpg_attrib sanity values */
42#define TA_AUTHENTICATION 1
43#define TA_LOGIN_TIMEOUT 15
44#define TA_LOGIN_TIMEOUT_MAX 30
45#define TA_LOGIN_TIMEOUT_MIN 5
46#define TA_NETIF_TIMEOUT 2
47#define TA_NETIF_TIMEOUT_MAX 15
48#define TA_NETIF_TIMEOUT_MIN 2
49#define TA_GENERATE_NODE_ACLS 0
50#define TA_DEFAULT_CMDSN_DEPTH 16
51#define TA_DEFAULT_CMDSN_DEPTH_MAX 512
52#define TA_DEFAULT_CMDSN_DEPTH_MIN 1
53#define TA_CACHE_DYNAMIC_ACLS 0
54/* Enabled by default in demo mode (generic_node_acls=1) */
55#define TA_DEMO_MODE_WRITE_PROTECT 1
56/* Disabled by default in production mode w/ explict ACLs */
57#define TA_PROD_MODE_WRITE_PROTECT 0
58#define TA_CACHE_CORE_NPS 0
59
60enum tpg_np_network_transport_table {
61 ISCSI_TCP = 0,
62 ISCSI_SCTP_TCP = 1,
63 ISCSI_SCTP_UDP = 2,
64 ISCSI_IWARP_TCP = 3,
65 ISCSI_IWARP_SCTP = 4,
66 ISCSI_INFINIBAND = 5,
67};
68
69/* RFC-3720 7.1.4 Standard Connection State Diagram for a Target */
70enum target_conn_state_table {
71 TARG_CONN_STATE_FREE = 0x1,
72 TARG_CONN_STATE_XPT_UP = 0x3,
73 TARG_CONN_STATE_IN_LOGIN = 0x4,
74 TARG_CONN_STATE_LOGGED_IN = 0x5,
75 TARG_CONN_STATE_IN_LOGOUT = 0x6,
76 TARG_CONN_STATE_LOGOUT_REQUESTED = 0x7,
77 TARG_CONN_STATE_CLEANUP_WAIT = 0x8,
78};
79
80/* RFC-3720 7.3.2 Session State Diagram for a Target */
81enum target_sess_state_table {
82 TARG_SESS_STATE_FREE = 0x1,
83 TARG_SESS_STATE_ACTIVE = 0x2,
84 TARG_SESS_STATE_LOGGED_IN = 0x3,
85 TARG_SESS_STATE_FAILED = 0x4,
86 TARG_SESS_STATE_IN_CONTINUE = 0x5,
87};
88
89/* struct iscsi_data_count->type */
90enum data_count_type {
91 ISCSI_RX_DATA = 1,
92 ISCSI_TX_DATA = 2,
93};
94
95/* struct iscsi_datain_req->dr_complete */
96enum datain_req_comp_table {
97 DATAIN_COMPLETE_NORMAL = 1,
98 DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY = 2,
99 DATAIN_COMPLETE_CONNECTION_RECOVERY = 3,
100};
101
102/* struct iscsi_datain_req->recovery */
103enum datain_req_rec_table {
104 DATAIN_WITHIN_COMMAND_RECOVERY = 1,
105 DATAIN_CONNECTION_RECOVERY = 2,
106};
107
108/* struct iscsi_portal_group->state */
109enum tpg_state_table {
110 TPG_STATE_FREE = 0,
111 TPG_STATE_ACTIVE = 1,
112 TPG_STATE_INACTIVE = 2,
113 TPG_STATE_COLD_RESET = 3,
114};
115
116/* struct iscsi_tiqn->tiqn_state */
117enum tiqn_state_table {
118 TIQN_STATE_ACTIVE = 1,
119 TIQN_STATE_SHUTDOWN = 2,
120};
121
122/* struct iscsi_cmd->cmd_flags */
123enum cmd_flags_table {
124 ICF_GOT_LAST_DATAOUT = 0x00000001,
125 ICF_GOT_DATACK_SNACK = 0x00000002,
126 ICF_NON_IMMEDIATE_UNSOLICITED_DATA = 0x00000004,
127 ICF_SENT_LAST_R2T = 0x00000008,
128 ICF_WITHIN_COMMAND_RECOVERY = 0x00000010,
129 ICF_CONTIG_MEMORY = 0x00000020,
130 ICF_ATTACHED_TO_RQUEUE = 0x00000040,
131 ICF_OOO_CMDSN = 0x00000080,
132 ICF_REJECT_FAIL_CONN = 0x00000100,
133};
134
135/* struct iscsi_cmd->i_state */
136enum cmd_i_state_table {
137 ISTATE_NO_STATE = 0,
138 ISTATE_NEW_CMD = 1,
139 ISTATE_DEFERRED_CMD = 2,
140 ISTATE_UNSOLICITED_DATA = 3,
141 ISTATE_RECEIVE_DATAOUT = 4,
142 ISTATE_RECEIVE_DATAOUT_RECOVERY = 5,
143 ISTATE_RECEIVED_LAST_DATAOUT = 6,
144 ISTATE_WITHIN_DATAOUT_RECOVERY = 7,
145 ISTATE_IN_CONNECTION_RECOVERY = 8,
146 ISTATE_RECEIVED_TASKMGT = 9,
147 ISTATE_SEND_ASYNCMSG = 10,
148 ISTATE_SENT_ASYNCMSG = 11,
149 ISTATE_SEND_DATAIN = 12,
150 ISTATE_SEND_LAST_DATAIN = 13,
151 ISTATE_SENT_LAST_DATAIN = 14,
152 ISTATE_SEND_LOGOUTRSP = 15,
153 ISTATE_SENT_LOGOUTRSP = 16,
154 ISTATE_SEND_NOPIN = 17,
155 ISTATE_SENT_NOPIN = 18,
156 ISTATE_SEND_REJECT = 19,
157 ISTATE_SENT_REJECT = 20,
158 ISTATE_SEND_R2T = 21,
159 ISTATE_SENT_R2T = 22,
160 ISTATE_SEND_R2T_RECOVERY = 23,
161 ISTATE_SENT_R2T_RECOVERY = 24,
162 ISTATE_SEND_LAST_R2T = 25,
163 ISTATE_SENT_LAST_R2T = 26,
164 ISTATE_SEND_LAST_R2T_RECOVERY = 27,
165 ISTATE_SENT_LAST_R2T_RECOVERY = 28,
166 ISTATE_SEND_STATUS = 29,
167 ISTATE_SEND_STATUS_BROKEN_PC = 30,
168 ISTATE_SENT_STATUS = 31,
169 ISTATE_SEND_STATUS_RECOVERY = 32,
170 ISTATE_SENT_STATUS_RECOVERY = 33,
171 ISTATE_SEND_TASKMGTRSP = 34,
172 ISTATE_SENT_TASKMGTRSP = 35,
173 ISTATE_SEND_TEXTRSP = 36,
174 ISTATE_SENT_TEXTRSP = 37,
175 ISTATE_SEND_NOPIN_WANT_RESPONSE = 38,
176 ISTATE_SENT_NOPIN_WANT_RESPONSE = 39,
177 ISTATE_SEND_NOPIN_NO_RESPONSE = 40,
178 ISTATE_REMOVE = 41,
179 ISTATE_FREE = 42,
180};
181
182/* Used for iscsi_recover_cmdsn() return values */
183enum recover_cmdsn_ret_table {
184 CMDSN_ERROR_CANNOT_RECOVER = -1,
185 CMDSN_NORMAL_OPERATION = 0,
186 CMDSN_LOWER_THAN_EXP = 1,
187 CMDSN_HIGHER_THAN_EXP = 2,
188};
189
190/* Used for iscsi_handle_immediate_data() return values */
191enum immedate_data_ret_table {
192 IMMEDIATE_DATA_CANNOT_RECOVER = -1,
193 IMMEDIATE_DATA_NORMAL_OPERATION = 0,
194 IMMEDIATE_DATA_ERL1_CRC_FAILURE = 1,
195};
196
197/* Used for iscsi_decide_dataout_action() return values */
198enum dataout_action_ret_table {
199 DATAOUT_CANNOT_RECOVER = -1,
200 DATAOUT_NORMAL = 0,
201 DATAOUT_SEND_R2T = 1,
202 DATAOUT_SEND_TO_TRANSPORT = 2,
203 DATAOUT_WITHIN_COMMAND_RECOVERY = 3,
204};
205
206/* Used for struct iscsi_node_auth->naf_flags */
207enum naf_flags_table {
208 NAF_USERID_SET = 0x01,
209 NAF_PASSWORD_SET = 0x02,
210 NAF_USERID_IN_SET = 0x04,
211 NAF_PASSWORD_IN_SET = 0x08,
212};
213
214/* Used by various struct timer_list to manage iSCSI specific state */
215enum iscsi_timer_flags_table {
216 ISCSI_TF_RUNNING = 0x01,
217 ISCSI_TF_STOP = 0x02,
218 ISCSI_TF_EXPIRED = 0x04,
219};
220
221/* Used for struct iscsi_np->np_flags */
222enum np_flags_table {
223 NPF_IP_NETWORK = 0x00,
224 NPF_SCTP_STRUCT_FILE = 0x01 /* Bugfix */
225};
226
227/* Used for struct iscsi_np->np_thread_state */
228enum np_thread_state_table {
229 ISCSI_NP_THREAD_ACTIVE = 1,
230 ISCSI_NP_THREAD_INACTIVE = 2,
231 ISCSI_NP_THREAD_RESET = 3,
232 ISCSI_NP_THREAD_SHUTDOWN = 4,
233 ISCSI_NP_THREAD_EXIT = 5,
234};
235
236struct iscsi_conn_ops {
237 u8 HeaderDigest; /* [0,1] == [None,CRC32C] */
238 u8 DataDigest; /* [0,1] == [None,CRC32C] */
239 u32 MaxRecvDataSegmentLength; /* [512..2**24-1] */
240 u8 OFMarker; /* [0,1] == [No,Yes] */
241 u8 IFMarker; /* [0,1] == [No,Yes] */
242 u32 OFMarkInt; /* [1..65535] */
243 u32 IFMarkInt; /* [1..65535] */
244};
245
246struct iscsi_sess_ops {
247 char InitiatorName[224];
248 char InitiatorAlias[256];
249 char TargetName[224];
250 char TargetAlias[256];
251 char TargetAddress[256];
252 u16 TargetPortalGroupTag; /* [0..65535] */
253 u16 MaxConnections; /* [1..65535] */
254 u8 InitialR2T; /* [0,1] == [No,Yes] */
255 u8 ImmediateData; /* [0,1] == [No,Yes] */
256 u32 MaxBurstLength; /* [512..2**24-1] */
257 u32 FirstBurstLength; /* [512..2**24-1] */
258 u16 DefaultTime2Wait; /* [0..3600] */
259 u16 DefaultTime2Retain; /* [0..3600] */
260 u16 MaxOutstandingR2T; /* [1..65535] */
261 u8 DataPDUInOrder; /* [0,1] == [No,Yes] */
262 u8 DataSequenceInOrder; /* [0,1] == [No,Yes] */
263 u8 ErrorRecoveryLevel; /* [0..2] */
264 u8 SessionType; /* [0,1] == [Normal,Discovery]*/
265};
266
267struct iscsi_queue_req {
268 int state;
269 struct iscsi_cmd *cmd;
270 struct list_head qr_list;
271};
272
273struct iscsi_data_count {
274 int data_length;
275 int sync_and_steering;
276 enum data_count_type type;
277 u32 iov_count;
278 u32 ss_iov_count;
279 u32 ss_marker_count;
280 struct kvec *iov;
281};
282
283struct iscsi_param_list {
284 struct list_head param_list;
285 struct list_head extra_response_list;
286};
287
288struct iscsi_datain_req {
289 enum datain_req_comp_table dr_complete;
290 int generate_recovery_values;
291 enum datain_req_rec_table recovery;
292 u32 begrun;
293 u32 runlength;
294 u32 data_length;
295 u32 data_offset;
296 u32 data_offset_end;
297 u32 data_sn;
298 u32 next_burst_len;
299 u32 read_data_done;
300 u32 seq_send_order;
301 struct list_head dr_list;
302} ____cacheline_aligned;
303
304struct iscsi_ooo_cmdsn {
305 u16 cid;
306 u32 batch_count;
307 u32 cmdsn;
308 u32 exp_cmdsn;
309 struct iscsi_cmd *cmd;
310 struct list_head ooo_list;
311} ____cacheline_aligned;
312
313struct iscsi_datain {
314 u8 flags;
315 u32 data_sn;
316 u32 length;
317 u32 offset;
318} ____cacheline_aligned;
319
320struct iscsi_r2t {
321 int seq_complete;
322 int recovery_r2t;
323 int sent_r2t;
324 u32 r2t_sn;
325 u32 offset;
326 u32 targ_xfer_tag;
327 u32 xfer_len;
328 struct list_head r2t_list;
329} ____cacheline_aligned;
330
331struct iscsi_cmd {
332 enum iscsi_timer_flags_table dataout_timer_flags;
333 /* DataOUT timeout retries */
334 u8 dataout_timeout_retries;
335 /* Within command recovery count */
336 u8 error_recovery_count;
337 /* iSCSI dependent state for out or order CmdSNs */
338 enum cmd_i_state_table deferred_i_state;
339 /* iSCSI dependent state */
340 enum cmd_i_state_table i_state;
341 /* Command is an immediate command (ISCSI_OP_IMMEDIATE set) */
342 u8 immediate_cmd;
343 /* Immediate data present */
344 u8 immediate_data;
345 /* iSCSI Opcode */
346 u8 iscsi_opcode;
347 /* iSCSI Response Code */
348 u8 iscsi_response;
349 /* Logout reason when iscsi_opcode == ISCSI_INIT_LOGOUT_CMND */
350 u8 logout_reason;
351 /* Logout response code when iscsi_opcode == ISCSI_INIT_LOGOUT_CMND */
352 u8 logout_response;
353 /* MaxCmdSN has been incremented */
354 u8 maxcmdsn_inc;
355 /* Immediate Unsolicited Dataout */
356 u8 unsolicited_data;
357 /* CID contained in logout PDU when opcode == ISCSI_INIT_LOGOUT_CMND */
358 u16 logout_cid;
359 /* Command flags */
360 enum cmd_flags_table cmd_flags;
361 /* Initiator Task Tag assigned from Initiator */
362 u32 init_task_tag;
363 /* Target Transfer Tag assigned from Target */
364 u32 targ_xfer_tag;
365 /* CmdSN assigned from Initiator */
366 u32 cmd_sn;
367 /* ExpStatSN assigned from Initiator */
368 u32 exp_stat_sn;
369 /* StatSN assigned to this ITT */
370 u32 stat_sn;
371 /* DataSN Counter */
372 u32 data_sn;
373 /* R2TSN Counter */
374 u32 r2t_sn;
375 /* Last DataSN acknowledged via DataAck SNACK */
376 u32 acked_data_sn;
377 /* Used for echoing NOPOUT ping data */
378 u32 buf_ptr_size;
379 /* Used to store DataDigest */
380 u32 data_crc;
381 /* Total size in bytes associated with command */
382 u32 data_length;
383 /* Counter for MaxOutstandingR2T */
384 u32 outstanding_r2ts;
385 /* Next R2T Offset when DataSequenceInOrder=Yes */
386 u32 r2t_offset;
387 /* Iovec current and orig count for iscsi_cmd->iov_data */
388 u32 iov_data_count;
389 u32 orig_iov_data_count;
390 /* Number of miscellaneous iovecs used for IP stack calls */
391 u32 iov_misc_count;
392 /* Number of struct iscsi_pdu in struct iscsi_cmd->pdu_list */
393 u32 pdu_count;
394 /* Next struct iscsi_pdu to send in struct iscsi_cmd->pdu_list */
395 u32 pdu_send_order;
396 /* Current struct iscsi_pdu in struct iscsi_cmd->pdu_list */
397 u32 pdu_start;
398 u32 residual_count;
399 /* Next struct iscsi_seq to send in struct iscsi_cmd->seq_list */
400 u32 seq_send_order;
401 /* Number of struct iscsi_seq in struct iscsi_cmd->seq_list */
402 u32 seq_count;
403 /* Current struct iscsi_seq in struct iscsi_cmd->seq_list */
404 u32 seq_no;
405 /* Lowest offset in current DataOUT sequence */
406 u32 seq_start_offset;
407 /* Highest offset in current DataOUT sequence */
408 u32 seq_end_offset;
409 /* Total size in bytes received so far of READ data */
410 u32 read_data_done;
411 /* Total size in bytes received so far of WRITE data */
412 u32 write_data_done;
413 /* Counter for FirstBurstLength key */
414 u32 first_burst_len;
415 /* Counter for MaxBurstLength key */
416 u32 next_burst_len;
417 /* Transfer size used for IP stack calls */
418 u32 tx_size;
419 /* Buffer used for various purposes */
420 void *buf_ptr;
421 /* See include/linux/dma-mapping.h */
422 enum dma_data_direction data_direction;
423 /* iSCSI PDU Header + CRC */
424 unsigned char pdu[ISCSI_HDR_LEN + ISCSI_CRC_LEN];
425 /* Number of times struct iscsi_cmd is present in immediate queue */
426 atomic_t immed_queue_count;
427 atomic_t response_queue_count;
428 atomic_t transport_sent;
429 spinlock_t datain_lock;
430 spinlock_t dataout_timeout_lock;
431 /* spinlock for protecting struct iscsi_cmd->i_state */
432 spinlock_t istate_lock;
433 /* spinlock for adding within command recovery entries */
434 spinlock_t error_lock;
435 /* spinlock for adding R2Ts */
436 spinlock_t r2t_lock;
437 /* DataIN List */
438 struct list_head datain_list;
439 /* R2T List */
440 struct list_head cmd_r2t_list;
441 struct completion reject_comp;
442 /* Timer for DataOUT */
443 struct timer_list dataout_timer;
444 /* Iovecs for SCSI data payload RX/TX w/ kernel level sockets */
445 struct kvec *iov_data;
446 /* Iovecs for miscellaneous purposes */
447#define ISCSI_MISC_IOVECS 5
448 struct kvec iov_misc[ISCSI_MISC_IOVECS];
449 /* Array of struct iscsi_pdu used for DataPDUInOrder=No */
450 struct iscsi_pdu *pdu_list;
451 /* Current struct iscsi_pdu used for DataPDUInOrder=No */
452 struct iscsi_pdu *pdu_ptr;
453 /* Array of struct iscsi_seq used for DataSequenceInOrder=No */
454 struct iscsi_seq *seq_list;
455 /* Current struct iscsi_seq used for DataSequenceInOrder=No */
456 struct iscsi_seq *seq_ptr;
457 /* TMR Request when iscsi_opcode == ISCSI_OP_SCSI_TMFUNC */
458 struct iscsi_tmr_req *tmr_req;
459 /* Connection this command is alligient to */
460 struct iscsi_conn *conn;
461 /* Pointer to connection recovery entry */
462 struct iscsi_conn_recovery *cr;
463 /* Session the command is part of, used for connection recovery */
464 struct iscsi_session *sess;
465 /* list_head for connection list */
466 struct list_head i_list;
467 /* The TCM I/O descriptor that is accessed via container_of() */
468 struct se_cmd se_cmd;
469 /* Sense buffer that will be mapped into outgoing status */
470#define ISCSI_SENSE_BUFFER_LEN (TRANSPORT_SENSE_BUFFER + 2)
471 unsigned char sense_buffer[ISCSI_SENSE_BUFFER_LEN];
472
473 struct scatterlist *t_mem_sg;
474 u32 t_mem_sg_nents;
475
476 u32 padding;
477 u8 pad_bytes[4];
478
479 struct scatterlist *first_data_sg;
480 u32 first_data_sg_off;
481 u32 kmapped_nents;
482
483} ____cacheline_aligned;
484
485struct iscsi_tmr_req {
486 bool task_reassign:1;
487 u32 ref_cmd_sn;
488 u32 exp_data_sn;
489 struct iscsi_conn_recovery *conn_recovery;
490 struct se_tmr_req *se_tmr_req;
491};
492
493struct iscsi_conn {
494 /* Authentication Successful for this connection */
495 u8 auth_complete;
496 /* State connection is currently in */
497 u8 conn_state;
498 u8 conn_logout_reason;
499 u8 network_transport;
500 enum iscsi_timer_flags_table nopin_timer_flags;
501 enum iscsi_timer_flags_table nopin_response_timer_flags;
502 u8 tx_immediate_queue;
503 u8 tx_response_queue;
504 /* Used to know what thread encountered a transport failure */
505 u8 which_thread;
506 /* connection id assigned by the Initiator */
507 u16 cid;
508 /* Remote TCP Port */
509 u16 login_port;
510 int net_size;
511 u32 auth_id;
512#define CONNFLAG_SCTP_STRUCT_FILE 0x01
513 u32 conn_flags;
514 /* Used for iscsi_tx_login_rsp() */
515 u32 login_itt;
516 u32 exp_statsn;
517 /* Per connection status sequence number */
518 u32 stat_sn;
519 /* IFMarkInt's Current Value */
520 u32 if_marker;
521 /* OFMarkInt's Current Value */
522 u32 of_marker;
523 /* Used for calculating OFMarker offset to next PDU */
524 u32 of_marker_offset;
525 /* Complete Bad PDU for sending reject */
526 unsigned char bad_hdr[ISCSI_HDR_LEN];
527#define IPV6_ADDRESS_SPACE 48
528 unsigned char login_ip[IPV6_ADDRESS_SPACE];
529 int conn_usage_count;
530 int conn_waiting_on_uc;
531 atomic_t check_immediate_queue;
532 atomic_t conn_logout_remove;
533 atomic_t connection_exit;
534 atomic_t connection_recovery;
535 atomic_t connection_reinstatement;
536 atomic_t connection_wait;
537 atomic_t connection_wait_rcfr;
538 atomic_t sleep_on_conn_wait_comp;
539 atomic_t transport_failed;
540 struct completion conn_post_wait_comp;
541 struct completion conn_wait_comp;
542 struct completion conn_wait_rcfr_comp;
543 struct completion conn_waiting_on_uc_comp;
544 struct completion conn_logout_comp;
545 struct completion tx_half_close_comp;
546 struct completion rx_half_close_comp;
547 /* socket used by this connection */
548 struct socket *sock;
549 struct timer_list nopin_timer;
550 struct timer_list nopin_response_timer;
551 struct timer_list transport_timer;
552 /* Spinlock used for add/deleting cmd's from conn_cmd_list */
553 spinlock_t cmd_lock;
554 spinlock_t conn_usage_lock;
555 spinlock_t immed_queue_lock;
556 spinlock_t nopin_timer_lock;
557 spinlock_t response_queue_lock;
558 spinlock_t state_lock;
559 /* libcrypto RX and TX contexts for crc32c */
560 struct hash_desc conn_rx_hash;
561 struct hash_desc conn_tx_hash;
562 /* Used for scheduling TX and RX connection kthreads */
563 cpumask_var_t conn_cpumask;
564 int conn_rx_reset_cpumask:1;
565 int conn_tx_reset_cpumask:1;
566 /* list_head of struct iscsi_cmd for this connection */
567 struct list_head conn_cmd_list;
568 struct list_head immed_queue_list;
569 struct list_head response_queue_list;
570 struct iscsi_conn_ops *conn_ops;
571 struct iscsi_param_list *param_list;
572 /* Used for per connection auth state machine */
573 void *auth_protocol;
574 struct iscsi_login_thread_s *login_thread;
575 struct iscsi_portal_group *tpg;
576 /* Pointer to parent session */
577 struct iscsi_session *sess;
578 /* Pointer to thread_set in use for this conn's threads */
579 struct iscsi_thread_set *thread_set;
580 /* list_head for session connection list */
581 struct list_head conn_list;
582} ____cacheline_aligned;
583
584struct iscsi_conn_recovery {
585 u16 cid;
586 u32 cmd_count;
587 u32 maxrecvdatasegmentlength;
588 int ready_for_reallegiance;
589 struct list_head conn_recovery_cmd_list;
590 spinlock_t conn_recovery_cmd_lock;
591 struct timer_list time2retain_timer;
592 struct iscsi_session *sess;
593 struct list_head cr_list;
594} ____cacheline_aligned;
595
596struct iscsi_session {
597 u8 initiator_vendor;
598 u8 isid[6];
599 enum iscsi_timer_flags_table time2retain_timer_flags;
600 u8 version_active;
601 u16 cid_called;
602 u16 conn_recovery_count;
603 u16 tsih;
604 /* state session is currently in */
605 u32 session_state;
606 /* session wide counter: initiator assigned task tag */
607 u32 init_task_tag;
608 /* session wide counter: target assigned task tag */
609 u32 targ_xfer_tag;
610 u32 cmdsn_window;
611
612 /* protects cmdsn values */
613 struct mutex cmdsn_mutex;
614 /* session wide counter: expected command sequence number */
615 u32 exp_cmd_sn;
616 /* session wide counter: maximum allowed command sequence number */
617 u32 max_cmd_sn;
618 struct list_head sess_ooo_cmdsn_list;
619
620 /* LIO specific session ID */
621 u32 sid;
622 char auth_type[8];
623 /* unique within the target */
624 int session_index;
625 /* Used for session reference counting */
626 int session_usage_count;
627 int session_waiting_on_uc;
628 u32 cmd_pdus;
629 u32 rsp_pdus;
630 u64 tx_data_octets;
631 u64 rx_data_octets;
632 u32 conn_digest_errors;
633 u32 conn_timeout_errors;
634 u64 creation_time;
635 spinlock_t session_stats_lock;
636 /* Number of active connections */
637 atomic_t nconn;
638 atomic_t session_continuation;
639 atomic_t session_fall_back_to_erl0;
640 atomic_t session_logout;
641 atomic_t session_reinstatement;
642 atomic_t session_stop_active;
643 atomic_t sleep_on_sess_wait_comp;
644 atomic_t transport_wait_cmds;
645 /* connection list */
646 struct list_head sess_conn_list;
647 struct list_head cr_active_list;
648 struct list_head cr_inactive_list;
649 spinlock_t conn_lock;
650 spinlock_t cr_a_lock;
651 spinlock_t cr_i_lock;
652 spinlock_t session_usage_lock;
653 spinlock_t ttt_lock;
654 struct completion async_msg_comp;
655 struct completion reinstatement_comp;
656 struct completion session_wait_comp;
657 struct completion session_waiting_on_uc_comp;
658 struct timer_list time2retain_timer;
659 struct iscsi_sess_ops *sess_ops;
660 struct se_session *se_sess;
661 struct iscsi_portal_group *tpg;
662} ____cacheline_aligned;
663
664struct iscsi_login {
665 u8 auth_complete;
666 u8 checked_for_existing;
667 u8 current_stage;
668 u8 leading_connection;
669 u8 first_request;
670 u8 version_min;
671 u8 version_max;
672 char isid[6];
673 u32 cmd_sn;
674 u32 init_task_tag;
675 u32 initial_exp_statsn;
676 u32 rsp_length;
677 u16 cid;
678 u16 tsih;
679 char *req;
680 char *rsp;
681 char *req_buf;
682 char *rsp_buf;
683} ____cacheline_aligned;
684
685struct iscsi_node_attrib {
686 u32 dataout_timeout;
687 u32 dataout_timeout_retries;
688 u32 default_erl;
689 u32 nopin_timeout;
690 u32 nopin_response_timeout;
691 u32 random_datain_pdu_offsets;
692 u32 random_datain_seq_offsets;
693 u32 random_r2t_offsets;
694 u32 tmr_cold_reset;
695 u32 tmr_warm_reset;
696 struct iscsi_node_acl *nacl;
697};
698
699struct se_dev_entry_s;
700
701struct iscsi_node_auth {
702 enum naf_flags_table naf_flags;
703 int authenticate_target;
704 /* Used for iscsit_global->discovery_auth,
705 * set to zero (auth disabled) by default */
706 int enforce_discovery_auth;
707#define MAX_USER_LEN 256
708#define MAX_PASS_LEN 256
709 char userid[MAX_USER_LEN];
710 char password[MAX_PASS_LEN];
711 char userid_mutual[MAX_USER_LEN];
712 char password_mutual[MAX_PASS_LEN];
713};
714
715#include "iscsi_target_stat.h"
716
717struct iscsi_node_stat_grps {
718 struct config_group iscsi_sess_stats_group;
719 struct config_group iscsi_conn_stats_group;
720};
721
722struct iscsi_node_acl {
723 struct iscsi_node_attrib node_attrib;
724 struct iscsi_node_auth node_auth;
725 struct iscsi_node_stat_grps node_stat_grps;
726 struct se_node_acl se_node_acl;
727};
728
729#define NODE_STAT_GRPS(nacl) (&(nacl)->node_stat_grps)
730
731#define ISCSI_NODE_ATTRIB(t) (&(t)->node_attrib)
732#define ISCSI_NODE_AUTH(t) (&(t)->node_auth)
733
734struct iscsi_tpg_attrib {
735 u32 authentication;
736 u32 login_timeout;
737 u32 netif_timeout;
738 u32 generate_node_acls;
739 u32 cache_dynamic_acls;
740 u32 default_cmdsn_depth;
741 u32 demo_mode_write_protect;
742 u32 prod_mode_write_protect;
743 struct iscsi_portal_group *tpg;
744};
745
746struct iscsi_np {
747 int np_network_transport;
748 int np_ip_proto;
749 int np_sock_type;
750 enum np_thread_state_table np_thread_state;
751 enum iscsi_timer_flags_table np_login_timer_flags;
752 u32 np_exports;
753 enum np_flags_table np_flags;
754 unsigned char np_ip[IPV6_ADDRESS_SPACE];
755 u16 np_port;
756 spinlock_t np_thread_lock;
757 struct completion np_restart_comp;
758 struct socket *np_socket;
759 struct __kernel_sockaddr_storage np_sockaddr;
760 struct task_struct *np_thread;
761 struct timer_list np_login_timer;
762 struct iscsi_portal_group *np_login_tpg;
763 struct list_head np_list;
764} ____cacheline_aligned;
765
766struct iscsi_tpg_np {
767 struct iscsi_np *tpg_np;
768 struct iscsi_portal_group *tpg;
769 struct iscsi_tpg_np *tpg_np_parent;
770 struct list_head tpg_np_list;
771 struct list_head tpg_np_child_list;
772 struct list_head tpg_np_parent_list;
773 struct se_tpg_np se_tpg_np;
774 spinlock_t tpg_np_parent_lock;
775};
776
777struct iscsi_portal_group {
778 unsigned char tpg_chap_id;
779 /* TPG State */
780 enum tpg_state_table tpg_state;
781 /* Target Portal Group Tag */
782 u16 tpgt;
783 /* Id assigned to target sessions */
784 u16 ntsih;
785 /* Number of active sessions */
786 u32 nsessions;
787 /* Number of Network Portals available for this TPG */
788 u32 num_tpg_nps;
789 /* Per TPG LIO specific session ID. */
790 u32 sid;
791 /* Spinlock for adding/removing Network Portals */
792 spinlock_t tpg_np_lock;
793 spinlock_t tpg_state_lock;
794 struct se_portal_group tpg_se_tpg;
795 struct mutex tpg_access_lock;
796 struct mutex np_login_lock;
797 struct iscsi_tpg_attrib tpg_attrib;
798 /* Pointer to default list of iSCSI parameters for TPG */
799 struct iscsi_param_list *param_list;
800 struct iscsi_tiqn *tpg_tiqn;
801 struct list_head tpg_gnp_list;
802 struct list_head tpg_list;
803} ____cacheline_aligned;
804
805#define ISCSI_TPG_C(c) ((struct iscsi_portal_group *)(c)->tpg)
806#define ISCSI_TPG_LUN(c, l) ((iscsi_tpg_list_t *)(c)->tpg->tpg_lun_list_t[l])
807#define ISCSI_TPG_S(s) ((struct iscsi_portal_group *)(s)->tpg)
808#define ISCSI_TPG_ATTRIB(t) (&(t)->tpg_attrib)
809#define SE_TPG(tpg) (&(tpg)->tpg_se_tpg)
810
811struct iscsi_wwn_stat_grps {
812 struct config_group iscsi_stat_group;
813 struct config_group iscsi_instance_group;
814 struct config_group iscsi_sess_err_group;
815 struct config_group iscsi_tgt_attr_group;
816 struct config_group iscsi_login_stats_group;
817 struct config_group iscsi_logout_stats_group;
818};
819
820struct iscsi_tiqn {
821#define ISCSI_IQN_LEN 224
822 unsigned char tiqn[ISCSI_IQN_LEN];
823 enum tiqn_state_table tiqn_state;
824 int tiqn_access_count;
825 u32 tiqn_active_tpgs;
826 u32 tiqn_ntpgs;
827 u32 tiqn_num_tpg_nps;
828 u32 tiqn_nsessions;
829 struct list_head tiqn_list;
830 struct list_head tiqn_tpg_list;
831 spinlock_t tiqn_state_lock;
832 spinlock_t tiqn_tpg_lock;
833 struct se_wwn tiqn_wwn;
834 struct iscsi_wwn_stat_grps tiqn_stat_grps;
835 int tiqn_index;
836 struct iscsi_sess_err_stats sess_err_stats;
837 struct iscsi_login_stats login_stats;
838 struct iscsi_logout_stats logout_stats;
839} ____cacheline_aligned;
840
841#define WWN_STAT_GRPS(tiqn) (&(tiqn)->tiqn_stat_grps)
842
843struct iscsit_global {
844 /* In core shutdown */
845 u32 in_shutdown;
846 u32 active_ts;
847 /* Unique identifier used for the authentication daemon */
848 u32 auth_id;
849 u32 inactive_ts;
850 /* Thread Set bitmap count */
851 int ts_bitmap_count;
852 /* Thread Set bitmap pointer */
853 unsigned long *ts_bitmap;
854 /* Used for iSCSI discovery session authentication */
855 struct iscsi_node_acl discovery_acl;
856 struct iscsi_portal_group *discovery_tpg;
857};
858
859#endif /* ISCSI_TARGET_CORE_H */
diff --git a/drivers/target/iscsi/iscsi_target_datain_values.c b/drivers/target/iscsi/iscsi_target_datain_values.c
new file mode 100644
index 000000000000..8c0495129513
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_datain_values.c
@@ -0,0 +1,531 @@
1/*******************************************************************************
2 * This file contains the iSCSI Target DataIN value generation functions.
3 *
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5 *
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7 *
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.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
21#include <scsi/iscsi_proto.h>
22
23#include "iscsi_target_core.h"
24#include "iscsi_target_seq_pdu_list.h"
25#include "iscsi_target_erl1.h"
26#include "iscsi_target_util.h"
27#include "iscsi_target.h"
28#include "iscsi_target_datain_values.h"
29
30struct iscsi_datain_req *iscsit_allocate_datain_req(void)
31{
32 struct iscsi_datain_req *dr;
33
34 dr = kmem_cache_zalloc(lio_dr_cache, GFP_ATOMIC);
35 if (!dr) {
36 pr_err("Unable to allocate memory for"
37 " struct iscsi_datain_req\n");
38 return NULL;
39 }
40 INIT_LIST_HEAD(&dr->dr_list);
41
42 return dr;
43}
44
45void iscsit_attach_datain_req(struct iscsi_cmd *cmd, struct iscsi_datain_req *dr)
46{
47 spin_lock(&cmd->datain_lock);
48 list_add_tail(&dr->dr_list, &cmd->datain_list);
49 spin_unlock(&cmd->datain_lock);
50}
51
52void iscsit_free_datain_req(struct iscsi_cmd *cmd, struct iscsi_datain_req *dr)
53{
54 spin_lock(&cmd->datain_lock);
55 list_del(&dr->dr_list);
56 spin_unlock(&cmd->datain_lock);
57
58 kmem_cache_free(lio_dr_cache, dr);
59}
60
61void iscsit_free_all_datain_reqs(struct iscsi_cmd *cmd)
62{
63 struct iscsi_datain_req *dr, *dr_tmp;
64
65 spin_lock(&cmd->datain_lock);
66 list_for_each_entry_safe(dr, dr_tmp, &cmd->datain_list, dr_list) {
67 list_del(&dr->dr_list);
68 kmem_cache_free(lio_dr_cache, dr);
69 }
70 spin_unlock(&cmd->datain_lock);
71}
72
73struct iscsi_datain_req *iscsit_get_datain_req(struct iscsi_cmd *cmd)
74{
75 struct iscsi_datain_req *dr;
76
77 if (list_empty(&cmd->datain_list)) {
78 pr_err("cmd->datain_list is empty for ITT:"
79 " 0x%08x\n", cmd->init_task_tag);
80 return NULL;
81 }
82 list_for_each_entry(dr, &cmd->datain_list, dr_list)
83 break;
84
85 return dr;
86}
87
88/*
89 * For Normal and Recovery DataSequenceInOrder=Yes and DataPDUInOrder=Yes.
90 */
91static struct iscsi_datain_req *iscsit_set_datain_values_yes_and_yes(
92 struct iscsi_cmd *cmd,
93 struct iscsi_datain *datain)
94{
95 u32 next_burst_len, read_data_done, read_data_left;
96 struct iscsi_conn *conn = cmd->conn;
97 struct iscsi_datain_req *dr;
98
99 dr = iscsit_get_datain_req(cmd);
100 if (!dr)
101 return NULL;
102
103 if (dr->recovery && dr->generate_recovery_values) {
104 if (iscsit_create_recovery_datain_values_datasequenceinorder_yes(
105 cmd, dr) < 0)
106 return NULL;
107
108 dr->generate_recovery_values = 0;
109 }
110
111 next_burst_len = (!dr->recovery) ?
112 cmd->next_burst_len : dr->next_burst_len;
113 read_data_done = (!dr->recovery) ?
114 cmd->read_data_done : dr->read_data_done;
115
116 read_data_left = (cmd->data_length - read_data_done);
117 if (!read_data_left) {
118 pr_err("ITT: 0x%08x read_data_left is zero!\n",
119 cmd->init_task_tag);
120 return NULL;
121 }
122
123 if ((read_data_left <= conn->conn_ops->MaxRecvDataSegmentLength) &&
124 (read_data_left <= (conn->sess->sess_ops->MaxBurstLength -
125 next_burst_len))) {
126 datain->length = read_data_left;
127
128 datain->flags |= (ISCSI_FLAG_CMD_FINAL | ISCSI_FLAG_DATA_STATUS);
129 if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
130 datain->flags |= ISCSI_FLAG_DATA_ACK;
131 } else {
132 if ((next_burst_len +
133 conn->conn_ops->MaxRecvDataSegmentLength) <
134 conn->sess->sess_ops->MaxBurstLength) {
135 datain->length =
136 conn->conn_ops->MaxRecvDataSegmentLength;
137 next_burst_len += datain->length;
138 } else {
139 datain->length = (conn->sess->sess_ops->MaxBurstLength -
140 next_burst_len);
141 next_burst_len = 0;
142
143 datain->flags |= ISCSI_FLAG_CMD_FINAL;
144 if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
145 datain->flags |= ISCSI_FLAG_DATA_ACK;
146 }
147 }
148
149 datain->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++;
150 datain->offset = read_data_done;
151
152 if (!dr->recovery) {
153 cmd->next_burst_len = next_burst_len;
154 cmd->read_data_done += datain->length;
155 } else {
156 dr->next_burst_len = next_burst_len;
157 dr->read_data_done += datain->length;
158 }
159
160 if (!dr->recovery) {
161 if (datain->flags & ISCSI_FLAG_DATA_STATUS)
162 dr->dr_complete = DATAIN_COMPLETE_NORMAL;
163
164 return dr;
165 }
166
167 if (!dr->runlength) {
168 if (datain->flags & ISCSI_FLAG_DATA_STATUS) {
169 dr->dr_complete =
170 (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
171 DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
172 DATAIN_COMPLETE_CONNECTION_RECOVERY;
173 }
174 } else {
175 if ((dr->begrun + dr->runlength) == dr->data_sn) {
176 dr->dr_complete =
177 (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
178 DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
179 DATAIN_COMPLETE_CONNECTION_RECOVERY;
180 }
181 }
182
183 return dr;
184}
185
186/*
187 * For Normal and Recovery DataSequenceInOrder=No and DataPDUInOrder=Yes.
188 */
189static struct iscsi_datain_req *iscsit_set_datain_values_no_and_yes(
190 struct iscsi_cmd *cmd,
191 struct iscsi_datain *datain)
192{
193 u32 offset, read_data_done, read_data_left, seq_send_order;
194 struct iscsi_conn *conn = cmd->conn;
195 struct iscsi_datain_req *dr;
196 struct iscsi_seq *seq;
197
198 dr = iscsit_get_datain_req(cmd);
199 if (!dr)
200 return NULL;
201
202 if (dr->recovery && dr->generate_recovery_values) {
203 if (iscsit_create_recovery_datain_values_datasequenceinorder_no(
204 cmd, dr) < 0)
205 return NULL;
206
207 dr->generate_recovery_values = 0;
208 }
209
210 read_data_done = (!dr->recovery) ?
211 cmd->read_data_done : dr->read_data_done;
212 seq_send_order = (!dr->recovery) ?
213 cmd->seq_send_order : dr->seq_send_order;
214
215 read_data_left = (cmd->data_length - read_data_done);
216 if (!read_data_left) {
217 pr_err("ITT: 0x%08x read_data_left is zero!\n",
218 cmd->init_task_tag);
219 return NULL;
220 }
221
222 seq = iscsit_get_seq_holder_for_datain(cmd, seq_send_order);
223 if (!seq)
224 return NULL;
225
226 seq->sent = 1;
227
228 if (!dr->recovery && !seq->next_burst_len)
229 seq->first_datasn = cmd->data_sn;
230
231 offset = (seq->offset + seq->next_burst_len);
232
233 if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >=
234 cmd->data_length) {
235 datain->length = (cmd->data_length - offset);
236 datain->offset = offset;
237
238 datain->flags |= ISCSI_FLAG_CMD_FINAL;
239 if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
240 datain->flags |= ISCSI_FLAG_DATA_ACK;
241
242 seq->next_burst_len = 0;
243 seq_send_order++;
244 } else {
245 if ((seq->next_burst_len +
246 conn->conn_ops->MaxRecvDataSegmentLength) <
247 conn->sess->sess_ops->MaxBurstLength) {
248 datain->length =
249 conn->conn_ops->MaxRecvDataSegmentLength;
250 datain->offset = (seq->offset + seq->next_burst_len);
251
252 seq->next_burst_len += datain->length;
253 } else {
254 datain->length = (conn->sess->sess_ops->MaxBurstLength -
255 seq->next_burst_len);
256 datain->offset = (seq->offset + seq->next_burst_len);
257
258 datain->flags |= ISCSI_FLAG_CMD_FINAL;
259 if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
260 datain->flags |= ISCSI_FLAG_DATA_ACK;
261
262 seq->next_burst_len = 0;
263 seq_send_order++;
264 }
265 }
266
267 if ((read_data_done + datain->length) == cmd->data_length)
268 datain->flags |= ISCSI_FLAG_DATA_STATUS;
269
270 datain->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++;
271 if (!dr->recovery) {
272 cmd->seq_send_order = seq_send_order;
273 cmd->read_data_done += datain->length;
274 } else {
275 dr->seq_send_order = seq_send_order;
276 dr->read_data_done += datain->length;
277 }
278
279 if (!dr->recovery) {
280 if (datain->flags & ISCSI_FLAG_CMD_FINAL)
281 seq->last_datasn = datain->data_sn;
282 if (datain->flags & ISCSI_FLAG_DATA_STATUS)
283 dr->dr_complete = DATAIN_COMPLETE_NORMAL;
284
285 return dr;
286 }
287
288 if (!dr->runlength) {
289 if (datain->flags & ISCSI_FLAG_DATA_STATUS) {
290 dr->dr_complete =
291 (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
292 DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
293 DATAIN_COMPLETE_CONNECTION_RECOVERY;
294 }
295 } else {
296 if ((dr->begrun + dr->runlength) == dr->data_sn) {
297 dr->dr_complete =
298 (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
299 DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
300 DATAIN_COMPLETE_CONNECTION_RECOVERY;
301 }
302 }
303
304 return dr;
305}
306
307/*
308 * For Normal and Recovery DataSequenceInOrder=Yes and DataPDUInOrder=No.
309 */
310static struct iscsi_datain_req *iscsit_set_datain_values_yes_and_no(
311 struct iscsi_cmd *cmd,
312 struct iscsi_datain *datain)
313{
314 u32 next_burst_len, read_data_done, read_data_left;
315 struct iscsi_conn *conn = cmd->conn;
316 struct iscsi_datain_req *dr;
317 struct iscsi_pdu *pdu;
318
319 dr = iscsit_get_datain_req(cmd);
320 if (!dr)
321 return NULL;
322
323 if (dr->recovery && dr->generate_recovery_values) {
324 if (iscsit_create_recovery_datain_values_datasequenceinorder_yes(
325 cmd, dr) < 0)
326 return NULL;
327
328 dr->generate_recovery_values = 0;
329 }
330
331 next_burst_len = (!dr->recovery) ?
332 cmd->next_burst_len : dr->next_burst_len;
333 read_data_done = (!dr->recovery) ?
334 cmd->read_data_done : dr->read_data_done;
335
336 read_data_left = (cmd->data_length - read_data_done);
337 if (!read_data_left) {
338 pr_err("ITT: 0x%08x read_data_left is zero!\n",
339 cmd->init_task_tag);
340 return dr;
341 }
342
343 pdu = iscsit_get_pdu_holder_for_seq(cmd, NULL);
344 if (!pdu)
345 return dr;
346
347 if ((read_data_done + pdu->length) == cmd->data_length) {
348 pdu->flags |= (ISCSI_FLAG_CMD_FINAL | ISCSI_FLAG_DATA_STATUS);
349 if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
350 pdu->flags |= ISCSI_FLAG_DATA_ACK;
351
352 next_burst_len = 0;
353 } else {
354 if ((next_burst_len + conn->conn_ops->MaxRecvDataSegmentLength) <
355 conn->sess->sess_ops->MaxBurstLength)
356 next_burst_len += pdu->length;
357 else {
358 pdu->flags |= ISCSI_FLAG_CMD_FINAL;
359 if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
360 pdu->flags |= ISCSI_FLAG_DATA_ACK;
361
362 next_burst_len = 0;
363 }
364 }
365
366 pdu->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++;
367 if (!dr->recovery) {
368 cmd->next_burst_len = next_burst_len;
369 cmd->read_data_done += pdu->length;
370 } else {
371 dr->next_burst_len = next_burst_len;
372 dr->read_data_done += pdu->length;
373 }
374
375 datain->flags = pdu->flags;
376 datain->length = pdu->length;
377 datain->offset = pdu->offset;
378 datain->data_sn = pdu->data_sn;
379
380 if (!dr->recovery) {
381 if (datain->flags & ISCSI_FLAG_DATA_STATUS)
382 dr->dr_complete = DATAIN_COMPLETE_NORMAL;
383
384 return dr;
385 }
386
387 if (!dr->runlength) {
388 if (datain->flags & ISCSI_FLAG_DATA_STATUS) {
389 dr->dr_complete =
390 (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
391 DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
392 DATAIN_COMPLETE_CONNECTION_RECOVERY;
393 }
394 } else {
395 if ((dr->begrun + dr->runlength) == dr->data_sn) {
396 dr->dr_complete =
397 (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
398 DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
399 DATAIN_COMPLETE_CONNECTION_RECOVERY;
400 }
401 }
402
403 return dr;
404}
405
406/*
407 * For Normal and Recovery DataSequenceInOrder=No and DataPDUInOrder=No.
408 */
409static struct iscsi_datain_req *iscsit_set_datain_values_no_and_no(
410 struct iscsi_cmd *cmd,
411 struct iscsi_datain *datain)
412{
413 u32 read_data_done, read_data_left, seq_send_order;
414 struct iscsi_conn *conn = cmd->conn;
415 struct iscsi_datain_req *dr;
416 struct iscsi_pdu *pdu;
417 struct iscsi_seq *seq = NULL;
418
419 dr = iscsit_get_datain_req(cmd);
420 if (!dr)
421 return NULL;
422
423 if (dr->recovery && dr->generate_recovery_values) {
424 if (iscsit_create_recovery_datain_values_datasequenceinorder_no(
425 cmd, dr) < 0)
426 return NULL;
427
428 dr->generate_recovery_values = 0;
429 }
430
431 read_data_done = (!dr->recovery) ?
432 cmd->read_data_done : dr->read_data_done;
433 seq_send_order = (!dr->recovery) ?
434 cmd->seq_send_order : dr->seq_send_order;
435
436 read_data_left = (cmd->data_length - read_data_done);
437 if (!read_data_left) {
438 pr_err("ITT: 0x%08x read_data_left is zero!\n",
439 cmd->init_task_tag);
440 return NULL;
441 }
442
443 seq = iscsit_get_seq_holder_for_datain(cmd, seq_send_order);
444 if (!seq)
445 return NULL;
446
447 seq->sent = 1;
448
449 if (!dr->recovery && !seq->next_burst_len)
450 seq->first_datasn = cmd->data_sn;
451
452 pdu = iscsit_get_pdu_holder_for_seq(cmd, seq);
453 if (!pdu)
454 return NULL;
455
456 if (seq->pdu_send_order == seq->pdu_count) {
457 pdu->flags |= ISCSI_FLAG_CMD_FINAL;
458 if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
459 pdu->flags |= ISCSI_FLAG_DATA_ACK;
460
461 seq->next_burst_len = 0;
462 seq_send_order++;
463 } else
464 seq->next_burst_len += pdu->length;
465
466 if ((read_data_done + pdu->length) == cmd->data_length)
467 pdu->flags |= ISCSI_FLAG_DATA_STATUS;
468
469 pdu->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++;
470 if (!dr->recovery) {
471 cmd->seq_send_order = seq_send_order;
472 cmd->read_data_done += pdu->length;
473 } else {
474 dr->seq_send_order = seq_send_order;
475 dr->read_data_done += pdu->length;
476 }
477
478 datain->flags = pdu->flags;
479 datain->length = pdu->length;
480 datain->offset = pdu->offset;
481 datain->data_sn = pdu->data_sn;
482
483 if (!dr->recovery) {
484 if (datain->flags & ISCSI_FLAG_CMD_FINAL)
485 seq->last_datasn = datain->data_sn;
486 if (datain->flags & ISCSI_FLAG_DATA_STATUS)
487 dr->dr_complete = DATAIN_COMPLETE_NORMAL;
488
489 return dr;
490 }
491
492 if (!dr->runlength) {
493 if (datain->flags & ISCSI_FLAG_DATA_STATUS) {
494 dr->dr_complete =
495 (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
496 DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
497 DATAIN_COMPLETE_CONNECTION_RECOVERY;
498 }
499 } else {
500 if ((dr->begrun + dr->runlength) == dr->data_sn) {
501 dr->dr_complete =
502 (dr->recovery == DATAIN_WITHIN_COMMAND_RECOVERY) ?
503 DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY :
504 DATAIN_COMPLETE_CONNECTION_RECOVERY;
505 }
506 }
507
508 return dr;
509}
510
511struct iscsi_datain_req *iscsit_get_datain_values(
512 struct iscsi_cmd *cmd,
513 struct iscsi_datain *datain)
514{
515 struct iscsi_conn *conn = cmd->conn;
516
517 if (conn->sess->sess_ops->DataSequenceInOrder &&
518 conn->sess->sess_ops->DataPDUInOrder)
519 return iscsit_set_datain_values_yes_and_yes(cmd, datain);
520 else if (!conn->sess->sess_ops->DataSequenceInOrder &&
521 conn->sess->sess_ops->DataPDUInOrder)
522 return iscsit_set_datain_values_no_and_yes(cmd, datain);
523 else if (conn->sess->sess_ops->DataSequenceInOrder &&
524 !conn->sess->sess_ops->DataPDUInOrder)
525 return iscsit_set_datain_values_yes_and_no(cmd, datain);
526 else if (!conn->sess->sess_ops->DataSequenceInOrder &&
527 !conn->sess->sess_ops->DataPDUInOrder)
528 return iscsit_set_datain_values_no_and_no(cmd, datain);
529
530 return NULL;
531}
diff --git a/drivers/target/iscsi/iscsi_target_datain_values.h b/drivers/target/iscsi/iscsi_target_datain_values.h
new file mode 100644
index 000000000000..646429ac5a02
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_datain_values.h
@@ -0,0 +1,12 @@
1#ifndef ISCSI_TARGET_DATAIN_VALUES_H
2#define ISCSI_TARGET_DATAIN_VALUES_H
3
4extern struct iscsi_datain_req *iscsit_allocate_datain_req(void);
5extern void iscsit_attach_datain_req(struct iscsi_cmd *, struct iscsi_datain_req *);
6extern void iscsit_free_datain_req(struct iscsi_cmd *, struct iscsi_datain_req *);
7extern void iscsit_free_all_datain_reqs(struct iscsi_cmd *);
8extern struct iscsi_datain_req *iscsit_get_datain_req(struct iscsi_cmd *);
9extern struct iscsi_datain_req *iscsit_get_datain_values(struct iscsi_cmd *,
10 struct iscsi_datain *);
11
12#endif /*** ISCSI_TARGET_DATAIN_VALUES_H ***/
diff --git a/drivers/target/iscsi/iscsi_target_device.c b/drivers/target/iscsi/iscsi_target_device.c
new file mode 100644
index 000000000000..a19fa5eea88e
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_device.c
@@ -0,0 +1,87 @@
1/*******************************************************************************
2 * This file contains the iSCSI Virtual Device and Disk Transport
3 * agnostic related functions.
4 *
5 \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
6 *
7 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
8 *
9 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 ******************************************************************************/
21
22#include <scsi/scsi_device.h>
23#include <target/target_core_base.h>
24#include <target/target_core_device.h>
25#include <target/target_core_transport.h>
26
27#include "iscsi_target_core.h"
28#include "iscsi_target_device.h"
29#include "iscsi_target_tpg.h"
30#include "iscsi_target_util.h"
31
32int iscsit_get_lun_for_tmr(
33 struct iscsi_cmd *cmd,
34 u64 lun)
35{
36 u32 unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun);
37
38 return transport_lookup_tmr_lun(&cmd->se_cmd, unpacked_lun);
39}
40
41int iscsit_get_lun_for_cmd(
42 struct iscsi_cmd *cmd,
43 unsigned char *cdb,
44 u64 lun)
45{
46 u32 unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun);
47
48 return transport_lookup_cmd_lun(&cmd->se_cmd, unpacked_lun);
49}
50
51void iscsit_determine_maxcmdsn(struct iscsi_session *sess)
52{
53 struct se_node_acl *se_nacl;
54
55 /*
56 * This is a discovery session, the single queue slot was already
57 * assigned in iscsi_login_zero_tsih(). Since only Logout and
58 * Text Opcodes are allowed during discovery we do not have to worry
59 * about the HBA's queue depth here.
60 */
61 if (sess->sess_ops->SessionType)
62 return;
63
64 se_nacl = sess->se_sess->se_node_acl;
65
66 /*
67 * This is a normal session, set the Session's CmdSN window to the
68 * struct se_node_acl->queue_depth. The value in struct se_node_acl->queue_depth
69 * has already been validated as a legal value in
70 * core_set_queue_depth_for_node().
71 */
72 sess->cmdsn_window = se_nacl->queue_depth;
73 sess->max_cmd_sn = (sess->max_cmd_sn + se_nacl->queue_depth) - 1;
74}
75
76void iscsit_increment_maxcmdsn(struct iscsi_cmd *cmd, struct iscsi_session *sess)
77{
78 if (cmd->immediate_cmd || cmd->maxcmdsn_inc)
79 return;
80
81 cmd->maxcmdsn_inc = 1;
82
83 mutex_lock(&sess->cmdsn_mutex);
84 sess->max_cmd_sn += 1;
85 pr_debug("Updated MaxCmdSN to 0x%08x\n", sess->max_cmd_sn);
86 mutex_unlock(&sess->cmdsn_mutex);
87}
diff --git a/drivers/target/iscsi/iscsi_target_device.h b/drivers/target/iscsi/iscsi_target_device.h
new file mode 100644
index 000000000000..bef1cada15f8
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_device.h
@@ -0,0 +1,9 @@
1#ifndef ISCSI_TARGET_DEVICE_H
2#define ISCSI_TARGET_DEVICE_H
3
4extern int iscsit_get_lun_for_tmr(struct iscsi_cmd *, u64);
5extern int iscsit_get_lun_for_cmd(struct iscsi_cmd *, unsigned char *, u64);
6extern void iscsit_determine_maxcmdsn(struct iscsi_session *);
7extern void iscsit_increment_maxcmdsn(struct iscsi_cmd *, struct iscsi_session *);
8
9#endif /* ISCSI_TARGET_DEVICE_H */
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c
new file mode 100644
index 000000000000..b7ffc3cd40cc
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_erl0.c
@@ -0,0 +1,1004 @@
1/******************************************************************************
2 * This file contains error recovery level zero functions used by
3 * the iSCSI Target driver.
4 *
5 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
6 *
7 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
8 *
9 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 ******************************************************************************/
21
22#include <scsi/iscsi_proto.h>
23#include <target/target_core_base.h>
24#include <target/target_core_transport.h>
25
26#include "iscsi_target_core.h"
27#include "iscsi_target_seq_pdu_list.h"
28#include "iscsi_target_tq.h"
29#include "iscsi_target_erl0.h"
30#include "iscsi_target_erl1.h"
31#include "iscsi_target_erl2.h"
32#include "iscsi_target_util.h"
33#include "iscsi_target.h"
34
35/*
36 * Used to set values in struct iscsi_cmd that iscsit_dataout_check_sequence()
37 * checks against to determine a PDU's Offset+Length is within the current
38 * DataOUT Sequence. Used for DataSequenceInOrder=Yes only.
39 */
40void iscsit_set_dataout_sequence_values(
41 struct iscsi_cmd *cmd)
42{
43 struct iscsi_conn *conn = cmd->conn;
44 /*
45 * Still set seq_start_offset and seq_end_offset for Unsolicited
46 * DataOUT, even if DataSequenceInOrder=No.
47 */
48 if (cmd->unsolicited_data) {
49 cmd->seq_start_offset = cmd->write_data_done;
50 cmd->seq_end_offset = (cmd->write_data_done +
51 (cmd->data_length >
52 conn->sess->sess_ops->FirstBurstLength) ?
53 conn->sess->sess_ops->FirstBurstLength : cmd->data_length);
54 return;
55 }
56
57 if (!conn->sess->sess_ops->DataSequenceInOrder)
58 return;
59
60 if (!cmd->seq_start_offset && !cmd->seq_end_offset) {
61 cmd->seq_start_offset = cmd->write_data_done;
62 cmd->seq_end_offset = (cmd->data_length >
63 conn->sess->sess_ops->MaxBurstLength) ?
64 (cmd->write_data_done +
65 conn->sess->sess_ops->MaxBurstLength) : cmd->data_length;
66 } else {
67 cmd->seq_start_offset = cmd->seq_end_offset;
68 cmd->seq_end_offset = ((cmd->seq_end_offset +
69 conn->sess->sess_ops->MaxBurstLength) >=
70 cmd->data_length) ? cmd->data_length :
71 (cmd->seq_end_offset +
72 conn->sess->sess_ops->MaxBurstLength);
73 }
74}
75
76static int iscsit_dataout_within_command_recovery_check(
77 struct iscsi_cmd *cmd,
78 unsigned char *buf)
79{
80 struct iscsi_conn *conn = cmd->conn;
81 struct iscsi_data *hdr = (struct iscsi_data *) buf;
82 u32 payload_length = ntoh24(hdr->dlength);
83
84 /*
85 * We do the within-command recovery checks here as it is
86 * the first function called in iscsi_check_pre_dataout().
87 * Basically, if we are in within-command recovery and
88 * the PDU does not contain the offset the sequence needs,
89 * dump the payload.
90 *
91 * This only applies to DataPDUInOrder=Yes, for
92 * DataPDUInOrder=No we only re-request the failed PDU
93 * and check that all PDUs in a sequence are received
94 * upon end of sequence.
95 */
96 if (conn->sess->sess_ops->DataSequenceInOrder) {
97 if ((cmd->cmd_flags & ICF_WITHIN_COMMAND_RECOVERY) &&
98 (cmd->write_data_done != hdr->offset))
99 goto dump;
100
101 cmd->cmd_flags &= ~ICF_WITHIN_COMMAND_RECOVERY;
102 } else {
103 struct iscsi_seq *seq;
104
105 seq = iscsit_get_seq_holder(cmd, hdr->offset, payload_length);
106 if (!seq)
107 return DATAOUT_CANNOT_RECOVER;
108 /*
109 * Set the struct iscsi_seq pointer to reuse later.
110 */
111 cmd->seq_ptr = seq;
112
113 if (conn->sess->sess_ops->DataPDUInOrder) {
114 if ((seq->status ==
115 DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY) &&
116 ((seq->offset != hdr->offset) ||
117 (seq->data_sn != hdr->datasn)))
118 goto dump;
119 } else {
120 if ((seq->status ==
121 DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY) &&
122 (seq->data_sn != hdr->datasn))
123 goto dump;
124 }
125
126 if (seq->status == DATAOUT_SEQUENCE_COMPLETE)
127 goto dump;
128
129 if (seq->status != DATAOUT_SEQUENCE_COMPLETE)
130 seq->status = 0;
131 }
132
133 return DATAOUT_NORMAL;
134
135dump:
136 pr_err("Dumping DataOUT PDU Offset: %u Length: %d DataSN:"
137 " 0x%08x\n", hdr->offset, payload_length, hdr->datasn);
138 return iscsit_dump_data_payload(conn, payload_length, 1);
139}
140
141static int iscsit_dataout_check_unsolicited_sequence(
142 struct iscsi_cmd *cmd,
143 unsigned char *buf)
144{
145 u32 first_burst_len;
146 struct iscsi_conn *conn = cmd->conn;
147 struct iscsi_data *hdr = (struct iscsi_data *) buf;
148 u32 payload_length = ntoh24(hdr->dlength);
149
150
151 if ((hdr->offset < cmd->seq_start_offset) ||
152 ((hdr->offset + payload_length) > cmd->seq_end_offset)) {
153 pr_err("Command ITT: 0x%08x with Offset: %u,"
154 " Length: %u outside of Unsolicited Sequence %u:%u while"
155 " DataSequenceInOrder=Yes.\n", cmd->init_task_tag,
156 hdr->offset, payload_length, cmd->seq_start_offset,
157 cmd->seq_end_offset);
158 return DATAOUT_CANNOT_RECOVER;
159 }
160
161 first_burst_len = (cmd->first_burst_len + payload_length);
162
163 if (first_burst_len > conn->sess->sess_ops->FirstBurstLength) {
164 pr_err("Total %u bytes exceeds FirstBurstLength: %u"
165 " for this Unsolicited DataOut Burst.\n",
166 first_burst_len, conn->sess->sess_ops->FirstBurstLength);
167 transport_send_check_condition_and_sense(&cmd->se_cmd,
168 TCM_INCORRECT_AMOUNT_OF_DATA, 0);
169 return DATAOUT_CANNOT_RECOVER;
170 }
171
172 /*
173 * Perform various MaxBurstLength and ISCSI_FLAG_CMD_FINAL sanity
174 * checks for the current Unsolicited DataOUT Sequence.
175 */
176 if (hdr->flags & ISCSI_FLAG_CMD_FINAL) {
177 /*
178 * Ignore ISCSI_FLAG_CMD_FINAL checks while DataPDUInOrder=No, end of
179 * sequence checks are handled in
180 * iscsit_dataout_datapduinorder_no_fbit().
181 */
182 if (!conn->sess->sess_ops->DataPDUInOrder)
183 goto out;
184
185 if ((first_burst_len != cmd->data_length) &&
186 (first_burst_len != conn->sess->sess_ops->FirstBurstLength)) {
187 pr_err("Unsolicited non-immediate data"
188 " received %u does not equal FirstBurstLength: %u, and"
189 " does not equal ExpXferLen %u.\n", first_burst_len,
190 conn->sess->sess_ops->FirstBurstLength,
191 cmd->data_length);
192 transport_send_check_condition_and_sense(&cmd->se_cmd,
193 TCM_INCORRECT_AMOUNT_OF_DATA, 0);
194 return DATAOUT_CANNOT_RECOVER;
195 }
196 } else {
197 if (first_burst_len == conn->sess->sess_ops->FirstBurstLength) {
198 pr_err("Command ITT: 0x%08x reached"
199 " FirstBurstLength: %u, but ISCSI_FLAG_CMD_FINAL is not set. protocol"
200 " error.\n", cmd->init_task_tag,
201 conn->sess->sess_ops->FirstBurstLength);
202 return DATAOUT_CANNOT_RECOVER;
203 }
204 if (first_burst_len == cmd->data_length) {
205 pr_err("Command ITT: 0x%08x reached"
206 " ExpXferLen: %u, but ISCSI_FLAG_CMD_FINAL is not set. protocol"
207 " error.\n", cmd->init_task_tag, cmd->data_length);
208 return DATAOUT_CANNOT_RECOVER;
209 }
210 }
211
212out:
213 return DATAOUT_NORMAL;
214}
215
216static int iscsit_dataout_check_sequence(
217 struct iscsi_cmd *cmd,
218 unsigned char *buf)
219{
220 u32 next_burst_len;
221 struct iscsi_conn *conn = cmd->conn;
222 struct iscsi_seq *seq = NULL;
223 struct iscsi_data *hdr = (struct iscsi_data *) buf;
224 u32 payload_length = ntoh24(hdr->dlength);
225
226 /*
227 * For DataSequenceInOrder=Yes: Check that the offset and offset+length
228 * is within range as defined by iscsi_set_dataout_sequence_values().
229 *
230 * For DataSequenceInOrder=No: Check that an struct iscsi_seq exists for
231 * offset+length tuple.
232 */
233 if (conn->sess->sess_ops->DataSequenceInOrder) {
234 /*
235 * Due to possibility of recovery DataOUT sent by the initiator
236 * fullfilling an Recovery R2T, it's best to just dump the
237 * payload here, instead of erroring out.
238 */
239 if ((hdr->offset < cmd->seq_start_offset) ||
240 ((hdr->offset + payload_length) > cmd->seq_end_offset)) {
241 pr_err("Command ITT: 0x%08x with Offset: %u,"
242 " Length: %u outside of Sequence %u:%u while"
243 " DataSequenceInOrder=Yes.\n", cmd->init_task_tag,
244 hdr->offset, payload_length, cmd->seq_start_offset,
245 cmd->seq_end_offset);
246
247 if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
248 return DATAOUT_CANNOT_RECOVER;
249 return DATAOUT_WITHIN_COMMAND_RECOVERY;
250 }
251
252 next_burst_len = (cmd->next_burst_len + payload_length);
253 } else {
254 seq = iscsit_get_seq_holder(cmd, hdr->offset, payload_length);
255 if (!seq)
256 return DATAOUT_CANNOT_RECOVER;
257 /*
258 * Set the struct iscsi_seq pointer to reuse later.
259 */
260 cmd->seq_ptr = seq;
261
262 if (seq->status == DATAOUT_SEQUENCE_COMPLETE) {
263 if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
264 return DATAOUT_CANNOT_RECOVER;
265 return DATAOUT_WITHIN_COMMAND_RECOVERY;
266 }
267
268 next_burst_len = (seq->next_burst_len + payload_length);
269 }
270
271 if (next_burst_len > conn->sess->sess_ops->MaxBurstLength) {
272 pr_err("Command ITT: 0x%08x, NextBurstLength: %u and"
273 " Length: %u exceeds MaxBurstLength: %u. protocol"
274 " error.\n", cmd->init_task_tag,
275 (next_burst_len - payload_length),
276 payload_length, conn->sess->sess_ops->MaxBurstLength);
277 return DATAOUT_CANNOT_RECOVER;
278 }
279
280 /*
281 * Perform various MaxBurstLength and ISCSI_FLAG_CMD_FINAL sanity
282 * checks for the current DataOUT Sequence.
283 */
284 if (hdr->flags & ISCSI_FLAG_CMD_FINAL) {
285 /*
286 * Ignore ISCSI_FLAG_CMD_FINAL checks while DataPDUInOrder=No, end of
287 * sequence checks are handled in
288 * iscsit_dataout_datapduinorder_no_fbit().
289 */
290 if (!conn->sess->sess_ops->DataPDUInOrder)
291 goto out;
292
293 if (conn->sess->sess_ops->DataSequenceInOrder) {
294 if ((next_burst_len <
295 conn->sess->sess_ops->MaxBurstLength) &&
296 ((cmd->write_data_done + payload_length) <
297 cmd->data_length)) {
298 pr_err("Command ITT: 0x%08x set ISCSI_FLAG_CMD_FINAL"
299 " before end of DataOUT sequence, protocol"
300 " error.\n", cmd->init_task_tag);
301 return DATAOUT_CANNOT_RECOVER;
302 }
303 } else {
304 if (next_burst_len < seq->xfer_len) {
305 pr_err("Command ITT: 0x%08x set ISCSI_FLAG_CMD_FINAL"
306 " before end of DataOUT sequence, protocol"
307 " error.\n", cmd->init_task_tag);
308 return DATAOUT_CANNOT_RECOVER;
309 }
310 }
311 } else {
312 if (conn->sess->sess_ops->DataSequenceInOrder) {
313 if (next_burst_len ==
314 conn->sess->sess_ops->MaxBurstLength) {
315 pr_err("Command ITT: 0x%08x reached"
316 " MaxBurstLength: %u, but ISCSI_FLAG_CMD_FINAL is"
317 " not set, protocol error.", cmd->init_task_tag,
318 conn->sess->sess_ops->MaxBurstLength);
319 return DATAOUT_CANNOT_RECOVER;
320 }
321 if ((cmd->write_data_done + payload_length) ==
322 cmd->data_length) {
323 pr_err("Command ITT: 0x%08x reached"
324 " last DataOUT PDU in sequence but ISCSI_FLAG_"
325 "CMD_FINAL is not set, protocol error.\n",
326 cmd->init_task_tag);
327 return DATAOUT_CANNOT_RECOVER;
328 }
329 } else {
330 if (next_burst_len == seq->xfer_len) {
331 pr_err("Command ITT: 0x%08x reached"
332 " last DataOUT PDU in sequence but ISCSI_FLAG_"
333 "CMD_FINAL is not set, protocol error.\n",
334 cmd->init_task_tag);
335 return DATAOUT_CANNOT_RECOVER;
336 }
337 }
338 }
339
340out:
341 return DATAOUT_NORMAL;
342}
343
344static int iscsit_dataout_check_datasn(
345 struct iscsi_cmd *cmd,
346 unsigned char *buf)
347{
348 int dump = 0, recovery = 0;
349 u32 data_sn = 0;
350 struct iscsi_conn *conn = cmd->conn;
351 struct iscsi_data *hdr = (struct iscsi_data *) buf;
352 u32 payload_length = ntoh24(hdr->dlength);
353
354 /*
355 * Considering the target has no method of re-requesting DataOUT
356 * by DataSN, if we receieve a greater DataSN than expected we
357 * assume the functions for DataPDUInOrder=[Yes,No] below will
358 * handle it.
359 *
360 * If the DataSN is less than expected, dump the payload.
361 */
362 if (conn->sess->sess_ops->DataSequenceInOrder)
363 data_sn = cmd->data_sn;
364 else {
365 struct iscsi_seq *seq = cmd->seq_ptr;
366 data_sn = seq->data_sn;
367 }
368
369 if (hdr->datasn > data_sn) {
370 pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
371 " higher than expected 0x%08x.\n", cmd->init_task_tag,
372 hdr->datasn, data_sn);
373 recovery = 1;
374 goto recover;
375 } else if (hdr->datasn < data_sn) {
376 pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
377 " lower than expected 0x%08x, discarding payload.\n",
378 cmd->init_task_tag, hdr->datasn, data_sn);
379 dump = 1;
380 goto dump;
381 }
382
383 return DATAOUT_NORMAL;
384
385recover:
386 if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
387 pr_err("Unable to perform within-command recovery"
388 " while ERL=0.\n");
389 return DATAOUT_CANNOT_RECOVER;
390 }
391dump:
392 if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
393 return DATAOUT_CANNOT_RECOVER;
394
395 return (recovery || dump) ? DATAOUT_WITHIN_COMMAND_RECOVERY :
396 DATAOUT_NORMAL;
397}
398
399static int iscsit_dataout_pre_datapduinorder_yes(
400 struct iscsi_cmd *cmd,
401 unsigned char *buf)
402{
403 int dump = 0, recovery = 0;
404 struct iscsi_conn *conn = cmd->conn;
405 struct iscsi_data *hdr = (struct iscsi_data *) buf;
406 u32 payload_length = ntoh24(hdr->dlength);
407
408 /*
409 * For DataSequenceInOrder=Yes: If the offset is greater than the global
410 * DataPDUInOrder=Yes offset counter in struct iscsi_cmd a protcol error has
411 * occured and fail the connection.
412 *
413 * For DataSequenceInOrder=No: If the offset is greater than the per
414 * sequence DataPDUInOrder=Yes offset counter in struct iscsi_seq a protocol
415 * error has occured and fail the connection.
416 */
417 if (conn->sess->sess_ops->DataSequenceInOrder) {
418 if (hdr->offset != cmd->write_data_done) {
419 pr_err("Command ITT: 0x%08x, received offset"
420 " %u different than expected %u.\n", cmd->init_task_tag,
421 hdr->offset, cmd->write_data_done);
422 recovery = 1;
423 goto recover;
424 }
425 } else {
426 struct iscsi_seq *seq = cmd->seq_ptr;
427
428 if (hdr->offset > seq->offset) {
429 pr_err("Command ITT: 0x%08x, received offset"
430 " %u greater than expected %u.\n", cmd->init_task_tag,
431 hdr->offset, seq->offset);
432 recovery = 1;
433 goto recover;
434 } else if (hdr->offset < seq->offset) {
435 pr_err("Command ITT: 0x%08x, received offset"
436 " %u less than expected %u, discarding payload.\n",
437 cmd->init_task_tag, hdr->offset, seq->offset);
438 dump = 1;
439 goto dump;
440 }
441 }
442
443 return DATAOUT_NORMAL;
444
445recover:
446 if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
447 pr_err("Unable to perform within-command recovery"
448 " while ERL=0.\n");
449 return DATAOUT_CANNOT_RECOVER;
450 }
451dump:
452 if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
453 return DATAOUT_CANNOT_RECOVER;
454
455 return (recovery) ? iscsit_recover_dataout_sequence(cmd,
456 hdr->offset, payload_length) :
457 (dump) ? DATAOUT_WITHIN_COMMAND_RECOVERY : DATAOUT_NORMAL;
458}
459
460static int iscsit_dataout_pre_datapduinorder_no(
461 struct iscsi_cmd *cmd,
462 unsigned char *buf)
463{
464 struct iscsi_pdu *pdu;
465 struct iscsi_data *hdr = (struct iscsi_data *) buf;
466 u32 payload_length = ntoh24(hdr->dlength);
467
468 pdu = iscsit_get_pdu_holder(cmd, hdr->offset, payload_length);
469 if (!pdu)
470 return DATAOUT_CANNOT_RECOVER;
471
472 cmd->pdu_ptr = pdu;
473
474 switch (pdu->status) {
475 case ISCSI_PDU_NOT_RECEIVED:
476 case ISCSI_PDU_CRC_FAILED:
477 case ISCSI_PDU_TIMED_OUT:
478 break;
479 case ISCSI_PDU_RECEIVED_OK:
480 pr_err("Command ITT: 0x%08x received already gotten"
481 " Offset: %u, Length: %u\n", cmd->init_task_tag,
482 hdr->offset, payload_length);
483 return iscsit_dump_data_payload(cmd->conn, payload_length, 1);
484 default:
485 return DATAOUT_CANNOT_RECOVER;
486 }
487
488 return DATAOUT_NORMAL;
489}
490
491static int iscsit_dataout_update_r2t(struct iscsi_cmd *cmd, u32 offset, u32 length)
492{
493 struct iscsi_r2t *r2t;
494
495 if (cmd->unsolicited_data)
496 return 0;
497
498 r2t = iscsit_get_r2t_for_eos(cmd, offset, length);
499 if (!r2t)
500 return -1;
501
502 spin_lock_bh(&cmd->r2t_lock);
503 r2t->seq_complete = 1;
504 cmd->outstanding_r2ts--;
505 spin_unlock_bh(&cmd->r2t_lock);
506
507 return 0;
508}
509
510static int iscsit_dataout_update_datapduinorder_no(
511 struct iscsi_cmd *cmd,
512 u32 data_sn,
513 int f_bit)
514{
515 int ret = 0;
516 struct iscsi_pdu *pdu = cmd->pdu_ptr;
517
518 pdu->data_sn = data_sn;
519
520 switch (pdu->status) {
521 case ISCSI_PDU_NOT_RECEIVED:
522 pdu->status = ISCSI_PDU_RECEIVED_OK;
523 break;
524 case ISCSI_PDU_CRC_FAILED:
525 pdu->status = ISCSI_PDU_RECEIVED_OK;
526 break;
527 case ISCSI_PDU_TIMED_OUT:
528 pdu->status = ISCSI_PDU_RECEIVED_OK;
529 break;
530 default:
531 return DATAOUT_CANNOT_RECOVER;
532 }
533
534 if (f_bit) {
535 ret = iscsit_dataout_datapduinorder_no_fbit(cmd, pdu);
536 if (ret == DATAOUT_CANNOT_RECOVER)
537 return ret;
538 }
539
540 return DATAOUT_NORMAL;
541}
542
543static int iscsit_dataout_post_crc_passed(
544 struct iscsi_cmd *cmd,
545 unsigned char *buf)
546{
547 int ret, send_r2t = 0;
548 struct iscsi_conn *conn = cmd->conn;
549 struct iscsi_seq *seq = NULL;
550 struct iscsi_data *hdr = (struct iscsi_data *) buf;
551 u32 payload_length = ntoh24(hdr->dlength);
552
553 if (cmd->unsolicited_data) {
554 if ((cmd->first_burst_len + payload_length) ==
555 conn->sess->sess_ops->FirstBurstLength) {
556 if (iscsit_dataout_update_r2t(cmd, hdr->offset,
557 payload_length) < 0)
558 return DATAOUT_CANNOT_RECOVER;
559 send_r2t = 1;
560 }
561
562 if (!conn->sess->sess_ops->DataPDUInOrder) {
563 ret = iscsit_dataout_update_datapduinorder_no(cmd,
564 hdr->datasn, (hdr->flags & ISCSI_FLAG_CMD_FINAL));
565 if (ret == DATAOUT_CANNOT_RECOVER)
566 return ret;
567 }
568
569 cmd->first_burst_len += payload_length;
570
571 if (conn->sess->sess_ops->DataSequenceInOrder)
572 cmd->data_sn++;
573 else {
574 seq = cmd->seq_ptr;
575 seq->data_sn++;
576 seq->offset += payload_length;
577 }
578
579 if (send_r2t) {
580 if (seq)
581 seq->status = DATAOUT_SEQUENCE_COMPLETE;
582 cmd->first_burst_len = 0;
583 cmd->unsolicited_data = 0;
584 }
585 } else {
586 if (conn->sess->sess_ops->DataSequenceInOrder) {
587 if ((cmd->next_burst_len + payload_length) ==
588 conn->sess->sess_ops->MaxBurstLength) {
589 if (iscsit_dataout_update_r2t(cmd, hdr->offset,
590 payload_length) < 0)
591 return DATAOUT_CANNOT_RECOVER;
592 send_r2t = 1;
593 }
594
595 if (!conn->sess->sess_ops->DataPDUInOrder) {
596 ret = iscsit_dataout_update_datapduinorder_no(
597 cmd, hdr->datasn,
598 (hdr->flags & ISCSI_FLAG_CMD_FINAL));
599 if (ret == DATAOUT_CANNOT_RECOVER)
600 return ret;
601 }
602
603 cmd->next_burst_len += payload_length;
604 cmd->data_sn++;
605
606 if (send_r2t)
607 cmd->next_burst_len = 0;
608 } else {
609 seq = cmd->seq_ptr;
610
611 if ((seq->next_burst_len + payload_length) ==
612 seq->xfer_len) {
613 if (iscsit_dataout_update_r2t(cmd, hdr->offset,
614 payload_length) < 0)
615 return DATAOUT_CANNOT_RECOVER;
616 send_r2t = 1;
617 }
618
619 if (!conn->sess->sess_ops->DataPDUInOrder) {
620 ret = iscsit_dataout_update_datapduinorder_no(
621 cmd, hdr->datasn,
622 (hdr->flags & ISCSI_FLAG_CMD_FINAL));
623 if (ret == DATAOUT_CANNOT_RECOVER)
624 return ret;
625 }
626
627 seq->data_sn++;
628 seq->offset += payload_length;
629 seq->next_burst_len += payload_length;
630
631 if (send_r2t) {
632 seq->next_burst_len = 0;
633 seq->status = DATAOUT_SEQUENCE_COMPLETE;
634 }
635 }
636 }
637
638 if (send_r2t && conn->sess->sess_ops->DataSequenceInOrder)
639 cmd->data_sn = 0;
640
641 cmd->write_data_done += payload_length;
642
643 return (cmd->write_data_done == cmd->data_length) ?
644 DATAOUT_SEND_TO_TRANSPORT : (send_r2t) ?
645 DATAOUT_SEND_R2T : DATAOUT_NORMAL;
646}
647
648static int iscsit_dataout_post_crc_failed(
649 struct iscsi_cmd *cmd,
650 unsigned char *buf)
651{
652 struct iscsi_conn *conn = cmd->conn;
653 struct iscsi_pdu *pdu;
654 struct iscsi_data *hdr = (struct iscsi_data *) buf;
655 u32 payload_length = ntoh24(hdr->dlength);
656
657 if (conn->sess->sess_ops->DataPDUInOrder)
658 goto recover;
659 /*
660 * The rest of this function is only called when DataPDUInOrder=No.
661 */
662 pdu = cmd->pdu_ptr;
663
664 switch (pdu->status) {
665 case ISCSI_PDU_NOT_RECEIVED:
666 pdu->status = ISCSI_PDU_CRC_FAILED;
667 break;
668 case ISCSI_PDU_CRC_FAILED:
669 break;
670 case ISCSI_PDU_TIMED_OUT:
671 pdu->status = ISCSI_PDU_CRC_FAILED;
672 break;
673 default:
674 return DATAOUT_CANNOT_RECOVER;
675 }
676
677recover:
678 return iscsit_recover_dataout_sequence(cmd, hdr->offset, payload_length);
679}
680
681/*
682 * Called from iscsit_handle_data_out() before DataOUT Payload is received
683 * and CRC computed.
684 */
685extern int iscsit_check_pre_dataout(
686 struct iscsi_cmd *cmd,
687 unsigned char *buf)
688{
689 int ret;
690 struct iscsi_conn *conn = cmd->conn;
691
692 ret = iscsit_dataout_within_command_recovery_check(cmd, buf);
693 if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
694 (ret == DATAOUT_CANNOT_RECOVER))
695 return ret;
696
697 ret = iscsit_dataout_check_datasn(cmd, buf);
698 if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
699 (ret == DATAOUT_CANNOT_RECOVER))
700 return ret;
701
702 if (cmd->unsolicited_data) {
703 ret = iscsit_dataout_check_unsolicited_sequence(cmd, buf);
704 if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
705 (ret == DATAOUT_CANNOT_RECOVER))
706 return ret;
707 } else {
708 ret = iscsit_dataout_check_sequence(cmd, buf);
709 if ((ret == DATAOUT_WITHIN_COMMAND_RECOVERY) ||
710 (ret == DATAOUT_CANNOT_RECOVER))
711 return ret;
712 }
713
714 return (conn->sess->sess_ops->DataPDUInOrder) ?
715 iscsit_dataout_pre_datapduinorder_yes(cmd, buf) :
716 iscsit_dataout_pre_datapduinorder_no(cmd, buf);
717}
718
719/*
720 * Called from iscsit_handle_data_out() after DataOUT Payload is received
721 * and CRC computed.
722 */
723int iscsit_check_post_dataout(
724 struct iscsi_cmd *cmd,
725 unsigned char *buf,
726 u8 data_crc_failed)
727{
728 struct iscsi_conn *conn = cmd->conn;
729
730 cmd->dataout_timeout_retries = 0;
731
732 if (!data_crc_failed)
733 return iscsit_dataout_post_crc_passed(cmd, buf);
734 else {
735 if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
736 pr_err("Unable to recover from DataOUT CRC"
737 " failure while ERL=0, closing session.\n");
738 iscsit_add_reject_from_cmd(ISCSI_REASON_DATA_DIGEST_ERROR,
739 1, 0, buf, cmd);
740 return DATAOUT_CANNOT_RECOVER;
741 }
742
743 iscsit_add_reject_from_cmd(ISCSI_REASON_DATA_DIGEST_ERROR,
744 0, 0, buf, cmd);
745 return iscsit_dataout_post_crc_failed(cmd, buf);
746 }
747}
748
749static void iscsit_handle_time2retain_timeout(unsigned long data)
750{
751 struct iscsi_session *sess = (struct iscsi_session *) data;
752 struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess);
753 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
754
755 spin_lock_bh(&se_tpg->session_lock);
756 if (sess->time2retain_timer_flags & ISCSI_TF_STOP) {
757 spin_unlock_bh(&se_tpg->session_lock);
758 return;
759 }
760 if (atomic_read(&sess->session_reinstatement)) {
761 pr_err("Exiting Time2Retain handler because"
762 " session_reinstatement=1\n");
763 spin_unlock_bh(&se_tpg->session_lock);
764 return;
765 }
766 sess->time2retain_timer_flags |= ISCSI_TF_EXPIRED;
767
768 pr_err("Time2Retain timer expired for SID: %u, cleaning up"
769 " iSCSI session.\n", sess->sid);
770 {
771 struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
772
773 if (tiqn) {
774 spin_lock(&tiqn->sess_err_stats.lock);
775 strcpy(tiqn->sess_err_stats.last_sess_fail_rem_name,
776 (void *)sess->sess_ops->InitiatorName);
777 tiqn->sess_err_stats.last_sess_failure_type =
778 ISCSI_SESS_ERR_CXN_TIMEOUT;
779 tiqn->sess_err_stats.cxn_timeout_errors++;
780 sess->conn_timeout_errors++;
781 spin_unlock(&tiqn->sess_err_stats.lock);
782 }
783 }
784
785 spin_unlock_bh(&se_tpg->session_lock);
786 iscsit_close_session(sess);
787}
788
789extern void iscsit_start_time2retain_handler(struct iscsi_session *sess)
790{
791 int tpg_active;
792 /*
793 * Only start Time2Retain timer when the assoicated TPG is still in
794 * an ACTIVE (eg: not disabled or shutdown) state.
795 */
796 spin_lock(&ISCSI_TPG_S(sess)->tpg_state_lock);
797 tpg_active = (ISCSI_TPG_S(sess)->tpg_state == TPG_STATE_ACTIVE);
798 spin_unlock(&ISCSI_TPG_S(sess)->tpg_state_lock);
799
800 if (!tpg_active)
801 return;
802
803 if (sess->time2retain_timer_flags & ISCSI_TF_RUNNING)
804 return;
805
806 pr_debug("Starting Time2Retain timer for %u seconds on"
807 " SID: %u\n", sess->sess_ops->DefaultTime2Retain, sess->sid);
808
809 init_timer(&sess->time2retain_timer);
810 sess->time2retain_timer.expires =
811 (get_jiffies_64() + sess->sess_ops->DefaultTime2Retain * HZ);
812 sess->time2retain_timer.data = (unsigned long)sess;
813 sess->time2retain_timer.function = iscsit_handle_time2retain_timeout;
814 sess->time2retain_timer_flags &= ~ISCSI_TF_STOP;
815 sess->time2retain_timer_flags |= ISCSI_TF_RUNNING;
816 add_timer(&sess->time2retain_timer);
817}
818
819/*
820 * Called with spin_lock_bh(&struct se_portal_group->session_lock) held
821 */
822extern int iscsit_stop_time2retain_timer(struct iscsi_session *sess)
823{
824 struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess);
825 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
826
827 if (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)
828 return -1;
829
830 if (!(sess->time2retain_timer_flags & ISCSI_TF_RUNNING))
831 return 0;
832
833 sess->time2retain_timer_flags |= ISCSI_TF_STOP;
834 spin_unlock_bh(&se_tpg->session_lock);
835
836 del_timer_sync(&sess->time2retain_timer);
837
838 spin_lock_bh(&se_tpg->session_lock);
839 sess->time2retain_timer_flags &= ~ISCSI_TF_RUNNING;
840 pr_debug("Stopped Time2Retain Timer for SID: %u\n",
841 sess->sid);
842 return 0;
843}
844
845void iscsit_connection_reinstatement_rcfr(struct iscsi_conn *conn)
846{
847 spin_lock_bh(&conn->state_lock);
848 if (atomic_read(&conn->connection_exit)) {
849 spin_unlock_bh(&conn->state_lock);
850 goto sleep;
851 }
852
853 if (atomic_read(&conn->transport_failed)) {
854 spin_unlock_bh(&conn->state_lock);
855 goto sleep;
856 }
857 spin_unlock_bh(&conn->state_lock);
858
859 iscsi_thread_set_force_reinstatement(conn);
860
861sleep:
862 wait_for_completion(&conn->conn_wait_rcfr_comp);
863 complete(&conn->conn_post_wait_comp);
864}
865
866void iscsit_cause_connection_reinstatement(struct iscsi_conn *conn, int sleep)
867{
868 spin_lock_bh(&conn->state_lock);
869 if (atomic_read(&conn->connection_exit)) {
870 spin_unlock_bh(&conn->state_lock);
871 return;
872 }
873
874 if (atomic_read(&conn->transport_failed)) {
875 spin_unlock_bh(&conn->state_lock);
876 return;
877 }
878
879 if (atomic_read(&conn->connection_reinstatement)) {
880 spin_unlock_bh(&conn->state_lock);
881 return;
882 }
883
884 if (iscsi_thread_set_force_reinstatement(conn) < 0) {
885 spin_unlock_bh(&conn->state_lock);
886 return;
887 }
888
889 atomic_set(&conn->connection_reinstatement, 1);
890 if (!sleep) {
891 spin_unlock_bh(&conn->state_lock);
892 return;
893 }
894
895 atomic_set(&conn->sleep_on_conn_wait_comp, 1);
896 spin_unlock_bh(&conn->state_lock);
897
898 wait_for_completion(&conn->conn_wait_comp);
899 complete(&conn->conn_post_wait_comp);
900}
901
902void iscsit_fall_back_to_erl0(struct iscsi_session *sess)
903{
904 pr_debug("Falling back to ErrorRecoveryLevel=0 for SID:"
905 " %u\n", sess->sid);
906
907 atomic_set(&sess->session_fall_back_to_erl0, 1);
908}
909
910static void iscsit_handle_connection_cleanup(struct iscsi_conn *conn)
911{
912 struct iscsi_session *sess = conn->sess;
913
914 if ((sess->sess_ops->ErrorRecoveryLevel == 2) &&
915 !atomic_read(&sess->session_reinstatement) &&
916 !atomic_read(&sess->session_fall_back_to_erl0))
917 iscsit_connection_recovery_transport_reset(conn);
918 else {
919 pr_debug("Performing cleanup for failed iSCSI"
920 " Connection ID: %hu from %s\n", conn->cid,
921 sess->sess_ops->InitiatorName);
922 iscsit_close_connection(conn);
923 }
924}
925
926extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn)
927{
928 spin_lock_bh(&conn->state_lock);
929 if (atomic_read(&conn->connection_exit)) {
930 spin_unlock_bh(&conn->state_lock);
931 return;
932 }
933 atomic_set(&conn->connection_exit, 1);
934
935 if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) {
936 spin_unlock_bh(&conn->state_lock);
937 iscsit_close_connection(conn);
938 return;
939 }
940
941 if (conn->conn_state == TARG_CONN_STATE_CLEANUP_WAIT) {
942 spin_unlock_bh(&conn->state_lock);
943 return;
944 }
945
946 pr_debug("Moving to TARG_CONN_STATE_CLEANUP_WAIT.\n");
947 conn->conn_state = TARG_CONN_STATE_CLEANUP_WAIT;
948 spin_unlock_bh(&conn->state_lock);
949
950 iscsit_handle_connection_cleanup(conn);
951}
952
953/*
954 * This is the simple function that makes the magic of
955 * sync and steering happen in the follow paradoxical order:
956 *
957 * 0) Receive conn->of_marker (bytes left until next OFMarker)
958 * bytes into an offload buffer. When we pass the exact number
959 * of bytes in conn->of_marker, iscsit_dump_data_payload() and hence
960 * rx_data() will automatically receive the identical u32 marker
961 * values and store it in conn->of_marker_offset;
962 * 1) Now conn->of_marker_offset will contain the offset to the start
963 * of the next iSCSI PDU. Dump these remaining bytes into another
964 * offload buffer.
965 * 2) We are done!
966 * Next byte in the TCP stream will contain the next iSCSI PDU!
967 * Cool Huh?!
968 */
969int iscsit_recover_from_unknown_opcode(struct iscsi_conn *conn)
970{
971 /*
972 * Make sure the remaining bytes to next maker is a sane value.
973 */
974 if (conn->of_marker > (conn->conn_ops->OFMarkInt * 4)) {
975 pr_err("Remaining bytes to OFMarker: %u exceeds"
976 " OFMarkInt bytes: %u.\n", conn->of_marker,
977 conn->conn_ops->OFMarkInt * 4);
978 return -1;
979 }
980
981 pr_debug("Advancing %u bytes in TCP stream to get to the"
982 " next OFMarker.\n", conn->of_marker);
983
984 if (iscsit_dump_data_payload(conn, conn->of_marker, 0) < 0)
985 return -1;
986
987 /*
988 * Make sure the offset marker we retrived is a valid value.
989 */
990 if (conn->of_marker_offset > (ISCSI_HDR_LEN + (ISCSI_CRC_LEN * 2) +
991 conn->conn_ops->MaxRecvDataSegmentLength)) {
992 pr_err("OfMarker offset value: %u exceeds limit.\n",
993 conn->of_marker_offset);
994 return -1;
995 }
996
997 pr_debug("Discarding %u bytes of TCP stream to get to the"
998 " next iSCSI Opcode.\n", conn->of_marker_offset);
999
1000 if (iscsit_dump_data_payload(conn, conn->of_marker_offset, 0) < 0)
1001 return -1;
1002
1003 return 0;
1004}
diff --git a/drivers/target/iscsi/iscsi_target_erl0.h b/drivers/target/iscsi/iscsi_target_erl0.h
new file mode 100644
index 000000000000..21acc9a06376
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_erl0.h
@@ -0,0 +1,15 @@
1#ifndef ISCSI_TARGET_ERL0_H
2#define ISCSI_TARGET_ERL0_H
3
4extern void iscsit_set_dataout_sequence_values(struct iscsi_cmd *);
5extern int iscsit_check_pre_dataout(struct iscsi_cmd *, unsigned char *);
6extern int iscsit_check_post_dataout(struct iscsi_cmd *, unsigned char *, u8);
7extern void iscsit_start_time2retain_handler(struct iscsi_session *);
8extern int iscsit_stop_time2retain_timer(struct iscsi_session *);
9extern void iscsit_connection_reinstatement_rcfr(struct iscsi_conn *);
10extern void iscsit_cause_connection_reinstatement(struct iscsi_conn *, int);
11extern void iscsit_fall_back_to_erl0(struct iscsi_session *);
12extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *);
13extern int iscsit_recover_from_unknown_opcode(struct iscsi_conn *);
14
15#endif /*** ISCSI_TARGET_ERL0_H ***/
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c
new file mode 100644
index 000000000000..980650792cf6
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_erl1.c
@@ -0,0 +1,1299 @@
1/*******************************************************************************
2 * This file contains error recovery level one used by the iSCSI Target driver.
3 *
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5 *
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7 *
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.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
21#include <linux/list.h>
22#include <scsi/iscsi_proto.h>
23#include <target/target_core_base.h>
24#include <target/target_core_transport.h>
25
26#include "iscsi_target_core.h"
27#include "iscsi_target_seq_pdu_list.h"
28#include "iscsi_target_datain_values.h"
29#include "iscsi_target_device.h"
30#include "iscsi_target_tpg.h"
31#include "iscsi_target_util.h"
32#include "iscsi_target_erl0.h"
33#include "iscsi_target_erl1.h"
34#include "iscsi_target_erl2.h"
35#include "iscsi_target.h"
36
37#define OFFLOAD_BUF_SIZE 32768
38
39/*
40 * Used to dump excess datain payload for certain error recovery
41 * situations. Receive in OFFLOAD_BUF_SIZE max of datain per rx_data().
42 *
43 * dump_padding_digest denotes if padding and data digests need
44 * to be dumped.
45 */
46int iscsit_dump_data_payload(
47 struct iscsi_conn *conn,
48 u32 buf_len,
49 int dump_padding_digest)
50{
51 char *buf, pad_bytes[4];
52 int ret = DATAOUT_WITHIN_COMMAND_RECOVERY, rx_got;
53 u32 length, padding, offset = 0, size;
54 struct kvec iov;
55
56 length = (buf_len > OFFLOAD_BUF_SIZE) ? OFFLOAD_BUF_SIZE : buf_len;
57
58 buf = kzalloc(length, GFP_ATOMIC);
59 if (!buf) {
60 pr_err("Unable to allocate %u bytes for offload"
61 " buffer.\n", length);
62 return -1;
63 }
64 memset(&iov, 0, sizeof(struct kvec));
65
66 while (offset < buf_len) {
67 size = ((offset + length) > buf_len) ?
68 (buf_len - offset) : length;
69
70 iov.iov_len = size;
71 iov.iov_base = buf;
72
73 rx_got = rx_data(conn, &iov, 1, size);
74 if (rx_got != size) {
75 ret = DATAOUT_CANNOT_RECOVER;
76 goto out;
77 }
78
79 offset += size;
80 }
81
82 if (!dump_padding_digest)
83 goto out;
84
85 padding = ((-buf_len) & 3);
86 if (padding != 0) {
87 iov.iov_len = padding;
88 iov.iov_base = pad_bytes;
89
90 rx_got = rx_data(conn, &iov, 1, padding);
91 if (rx_got != padding) {
92 ret = DATAOUT_CANNOT_RECOVER;
93 goto out;
94 }
95 }
96
97 if (conn->conn_ops->DataDigest) {
98 u32 data_crc;
99
100 iov.iov_len = ISCSI_CRC_LEN;
101 iov.iov_base = &data_crc;
102
103 rx_got = rx_data(conn, &iov, 1, ISCSI_CRC_LEN);
104 if (rx_got != ISCSI_CRC_LEN) {
105 ret = DATAOUT_CANNOT_RECOVER;
106 goto out;
107 }
108 }
109
110out:
111 kfree(buf);
112 return ret;
113}
114
115/*
116 * Used for retransmitting R2Ts from a R2T SNACK request.
117 */
118static int iscsit_send_recovery_r2t_for_snack(
119 struct iscsi_cmd *cmd,
120 struct iscsi_r2t *r2t)
121{
122 /*
123 * If the struct iscsi_r2t has not been sent yet, we can safely
124 * ignore retransmission
125 * of the R2TSN in question.
126 */
127 spin_lock_bh(&cmd->r2t_lock);
128 if (!r2t->sent_r2t) {
129 spin_unlock_bh(&cmd->r2t_lock);
130 return 0;
131 }
132 r2t->sent_r2t = 0;
133 spin_unlock_bh(&cmd->r2t_lock);
134
135 iscsit_add_cmd_to_immediate_queue(cmd, cmd->conn, ISTATE_SEND_R2T);
136
137 return 0;
138}
139
140static int iscsit_handle_r2t_snack(
141 struct iscsi_cmd *cmd,
142 unsigned char *buf,
143 u32 begrun,
144 u32 runlength)
145{
146 u32 last_r2tsn;
147 struct iscsi_r2t *r2t;
148
149 /*
150 * Make sure the initiator is not requesting retransmission
151 * of R2TSNs already acknowledged by a TMR TASK_REASSIGN.
152 */
153 if ((cmd->cmd_flags & ICF_GOT_DATACK_SNACK) &&
154 (begrun <= cmd->acked_data_sn)) {
155 pr_err("ITT: 0x%08x, R2T SNACK requesting"
156 " retransmission of R2TSN: 0x%08x to 0x%08x but already"
157 " acked to R2TSN: 0x%08x by TMR TASK_REASSIGN,"
158 " protocol error.\n", cmd->init_task_tag, begrun,
159 (begrun + runlength), cmd->acked_data_sn);
160
161 return iscsit_add_reject_from_cmd(
162 ISCSI_REASON_PROTOCOL_ERROR,
163 1, 0, buf, cmd);
164 }
165
166 if (runlength) {
167 if ((begrun + runlength) > cmd->r2t_sn) {
168 pr_err("Command ITT: 0x%08x received R2T SNACK"
169 " with BegRun: 0x%08x, RunLength: 0x%08x, exceeds"
170 " current R2TSN: 0x%08x, protocol error.\n",
171 cmd->init_task_tag, begrun, runlength, cmd->r2t_sn);
172 return iscsit_add_reject_from_cmd(
173 ISCSI_REASON_BOOKMARK_INVALID, 1, 0, buf, cmd);
174 }
175 last_r2tsn = (begrun + runlength);
176 } else
177 last_r2tsn = cmd->r2t_sn;
178
179 while (begrun < last_r2tsn) {
180 r2t = iscsit_get_holder_for_r2tsn(cmd, begrun);
181 if (!r2t)
182 return -1;
183 if (iscsit_send_recovery_r2t_for_snack(cmd, r2t) < 0)
184 return -1;
185
186 begrun++;
187 }
188
189 return 0;
190}
191
192/*
193 * Generates Offsets and NextBurstLength based on Begrun and Runlength
194 * carried in a Data SNACK or ExpDataSN in TMR TASK_REASSIGN.
195 *
196 * For DataSequenceInOrder=Yes and DataPDUInOrder=[Yes,No] only.
197 *
198 * FIXME: How is this handled for a RData SNACK?
199 */
200int iscsit_create_recovery_datain_values_datasequenceinorder_yes(
201 struct iscsi_cmd *cmd,
202 struct iscsi_datain_req *dr)
203{
204 u32 data_sn = 0, data_sn_count = 0;
205 u32 pdu_start = 0, seq_no = 0;
206 u32 begrun = dr->begrun;
207 struct iscsi_conn *conn = cmd->conn;
208
209 while (begrun > data_sn++) {
210 data_sn_count++;
211 if ((dr->next_burst_len +
212 conn->conn_ops->MaxRecvDataSegmentLength) <
213 conn->sess->sess_ops->MaxBurstLength) {
214 dr->read_data_done +=
215 conn->conn_ops->MaxRecvDataSegmentLength;
216 dr->next_burst_len +=
217 conn->conn_ops->MaxRecvDataSegmentLength;
218 } else {
219 dr->read_data_done +=
220 (conn->sess->sess_ops->MaxBurstLength -
221 dr->next_burst_len);
222 dr->next_burst_len = 0;
223 pdu_start += data_sn_count;
224 data_sn_count = 0;
225 seq_no++;
226 }
227 }
228
229 if (!conn->sess->sess_ops->DataPDUInOrder) {
230 cmd->seq_no = seq_no;
231 cmd->pdu_start = pdu_start;
232 cmd->pdu_send_order = data_sn_count;
233 }
234
235 return 0;
236}
237
238/*
239 * Generates Offsets and NextBurstLength based on Begrun and Runlength
240 * carried in a Data SNACK or ExpDataSN in TMR TASK_REASSIGN.
241 *
242 * For DataSequenceInOrder=No and DataPDUInOrder=[Yes,No] only.
243 *
244 * FIXME: How is this handled for a RData SNACK?
245 */
246int iscsit_create_recovery_datain_values_datasequenceinorder_no(
247 struct iscsi_cmd *cmd,
248 struct iscsi_datain_req *dr)
249{
250 int found_seq = 0, i;
251 u32 data_sn, read_data_done = 0, seq_send_order = 0;
252 u32 begrun = dr->begrun;
253 u32 runlength = dr->runlength;
254 struct iscsi_conn *conn = cmd->conn;
255 struct iscsi_seq *first_seq = NULL, *seq = NULL;
256
257 if (!cmd->seq_list) {
258 pr_err("struct iscsi_cmd->seq_list is NULL!\n");
259 return -1;
260 }
261
262 /*
263 * Calculate read_data_done for all sequences containing a
264 * first_datasn and last_datasn less than the BegRun.
265 *
266 * Locate the struct iscsi_seq the BegRun lies within and calculate
267 * NextBurstLenghth up to the DataSN based on MaxRecvDataSegmentLength.
268 *
269 * Also use struct iscsi_seq->seq_send_order to determine where to start.
270 */
271 for (i = 0; i < cmd->seq_count; i++) {
272 seq = &cmd->seq_list[i];
273
274 if (!seq->seq_send_order)
275 first_seq = seq;
276
277 /*
278 * No data has been transferred for this DataIN sequence, so the
279 * seq->first_datasn and seq->last_datasn have not been set.
280 */
281 if (!seq->sent) {
282#if 0
283 pr_err("Ignoring non-sent sequence 0x%08x ->"
284 " 0x%08x\n\n", seq->first_datasn,
285 seq->last_datasn);
286#endif
287 continue;
288 }
289
290 /*
291 * This DataIN sequence is precedes the received BegRun, add the
292 * total xfer_len of the sequence to read_data_done and reset
293 * seq->pdu_send_order.
294 */
295 if ((seq->first_datasn < begrun) &&
296 (seq->last_datasn < begrun)) {
297#if 0
298 pr_err("Pre BegRun sequence 0x%08x ->"
299 " 0x%08x\n", seq->first_datasn,
300 seq->last_datasn);
301#endif
302 read_data_done += cmd->seq_list[i].xfer_len;
303 seq->next_burst_len = seq->pdu_send_order = 0;
304 continue;
305 }
306
307 /*
308 * The BegRun lies within this DataIN sequence.
309 */
310 if ((seq->first_datasn <= begrun) &&
311 (seq->last_datasn >= begrun)) {
312#if 0
313 pr_err("Found sequence begrun: 0x%08x in"
314 " 0x%08x -> 0x%08x\n", begrun,
315 seq->first_datasn, seq->last_datasn);
316#endif
317 seq_send_order = seq->seq_send_order;
318 data_sn = seq->first_datasn;
319 seq->next_burst_len = seq->pdu_send_order = 0;
320 found_seq = 1;
321
322 /*
323 * For DataPDUInOrder=Yes, while the first DataSN of
324 * the sequence is less than the received BegRun, add
325 * the MaxRecvDataSegmentLength to read_data_done and
326 * to the sequence's next_burst_len;
327 *
328 * For DataPDUInOrder=No, while the first DataSN of the
329 * sequence is less than the received BegRun, find the
330 * struct iscsi_pdu of the DataSN in question and add the
331 * MaxRecvDataSegmentLength to read_data_done and to the
332 * sequence's next_burst_len;
333 */
334 if (conn->sess->sess_ops->DataPDUInOrder) {
335 while (data_sn < begrun) {
336 seq->pdu_send_order++;
337 read_data_done +=
338 conn->conn_ops->MaxRecvDataSegmentLength;
339 seq->next_burst_len +=
340 conn->conn_ops->MaxRecvDataSegmentLength;
341 data_sn++;
342 }
343 } else {
344 int j;
345 struct iscsi_pdu *pdu;
346
347 while (data_sn < begrun) {
348 seq->pdu_send_order++;
349
350 for (j = 0; j < seq->pdu_count; j++) {
351 pdu = &cmd->pdu_list[
352 seq->pdu_start + j];
353 if (pdu->data_sn == data_sn) {
354 read_data_done +=
355 pdu->length;
356 seq->next_burst_len +=
357 pdu->length;
358 }
359 }
360 data_sn++;
361 }
362 }
363 continue;
364 }
365
366 /*
367 * This DataIN sequence is larger than the received BegRun,
368 * reset seq->pdu_send_order and continue.
369 */
370 if ((seq->first_datasn > begrun) ||
371 (seq->last_datasn > begrun)) {
372#if 0
373 pr_err("Post BegRun sequence 0x%08x -> 0x%08x\n",
374 seq->first_datasn, seq->last_datasn);
375#endif
376 seq->next_burst_len = seq->pdu_send_order = 0;
377 continue;
378 }
379 }
380
381 if (!found_seq) {
382 if (!begrun) {
383 if (!first_seq) {
384 pr_err("ITT: 0x%08x, Begrun: 0x%08x"
385 " but first_seq is NULL\n",
386 cmd->init_task_tag, begrun);
387 return -1;
388 }
389 seq_send_order = first_seq->seq_send_order;
390 seq->next_burst_len = seq->pdu_send_order = 0;
391 goto done;
392 }
393
394 pr_err("Unable to locate struct iscsi_seq for ITT: 0x%08x,"
395 " BegRun: 0x%08x, RunLength: 0x%08x while"
396 " DataSequenceInOrder=No and DataPDUInOrder=%s.\n",
397 cmd->init_task_tag, begrun, runlength,
398 (conn->sess->sess_ops->DataPDUInOrder) ? "Yes" : "No");
399 return -1;
400 }
401
402done:
403 dr->read_data_done = read_data_done;
404 dr->seq_send_order = seq_send_order;
405
406 return 0;
407}
408
409static int iscsit_handle_recovery_datain(
410 struct iscsi_cmd *cmd,
411 unsigned char *buf,
412 u32 begrun,
413 u32 runlength)
414{
415 struct iscsi_conn *conn = cmd->conn;
416 struct iscsi_datain_req *dr;
417 struct se_cmd *se_cmd = &cmd->se_cmd;
418
419 if (!atomic_read(&se_cmd->t_transport_complete)) {
420 pr_err("Ignoring ITT: 0x%08x Data SNACK\n",
421 cmd->init_task_tag);
422 return 0;
423 }
424
425 /*
426 * Make sure the initiator is not requesting retransmission
427 * of DataSNs already acknowledged by a Data ACK SNACK.
428 */
429 if ((cmd->cmd_flags & ICF_GOT_DATACK_SNACK) &&
430 (begrun <= cmd->acked_data_sn)) {
431 pr_err("ITT: 0x%08x, Data SNACK requesting"
432 " retransmission of DataSN: 0x%08x to 0x%08x but"
433 " already acked to DataSN: 0x%08x by Data ACK SNACK,"
434 " protocol error.\n", cmd->init_task_tag, begrun,
435 (begrun + runlength), cmd->acked_data_sn);
436
437 return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR,
438 1, 0, buf, cmd);
439 }
440
441 /*
442 * Make sure BegRun and RunLength in the Data SNACK are sane.
443 * Note: (cmd->data_sn - 1) will carry the maximum DataSN sent.
444 */
445 if ((begrun + runlength) > (cmd->data_sn - 1)) {
446 pr_err("Initiator requesting BegRun: 0x%08x, RunLength"
447 ": 0x%08x greater than maximum DataSN: 0x%08x.\n",
448 begrun, runlength, (cmd->data_sn - 1));
449 return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
450 1, 0, buf, cmd);
451 }
452
453 dr = iscsit_allocate_datain_req();
454 if (!dr)
455 return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_NO_RESOURCES,
456 1, 0, buf, cmd);
457
458 dr->data_sn = dr->begrun = begrun;
459 dr->runlength = runlength;
460 dr->generate_recovery_values = 1;
461 dr->recovery = DATAIN_WITHIN_COMMAND_RECOVERY;
462
463 iscsit_attach_datain_req(cmd, dr);
464
465 cmd->i_state = ISTATE_SEND_DATAIN;
466 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
467
468 return 0;
469}
470
471int iscsit_handle_recovery_datain_or_r2t(
472 struct iscsi_conn *conn,
473 unsigned char *buf,
474 u32 init_task_tag,
475 u32 targ_xfer_tag,
476 u32 begrun,
477 u32 runlength)
478{
479 struct iscsi_cmd *cmd;
480
481 cmd = iscsit_find_cmd_from_itt(conn, init_task_tag);
482 if (!cmd)
483 return 0;
484
485 /*
486 * FIXME: This will not work for bidi commands.
487 */
488 switch (cmd->data_direction) {
489 case DMA_TO_DEVICE:
490 return iscsit_handle_r2t_snack(cmd, buf, begrun, runlength);
491 case DMA_FROM_DEVICE:
492 return iscsit_handle_recovery_datain(cmd, buf, begrun,
493 runlength);
494 default:
495 pr_err("Unknown cmd->data_direction: 0x%02x\n",
496 cmd->data_direction);
497 return -1;
498 }
499
500 return 0;
501}
502
503/* #warning FIXME: Status SNACK needs to be dependent on OPCODE!!! */
504int iscsit_handle_status_snack(
505 struct iscsi_conn *conn,
506 u32 init_task_tag,
507 u32 targ_xfer_tag,
508 u32 begrun,
509 u32 runlength)
510{
511 struct iscsi_cmd *cmd = NULL;
512 u32 last_statsn;
513 int found_cmd;
514
515 if (conn->exp_statsn > begrun) {
516 pr_err("Got Status SNACK Begrun: 0x%08x, RunLength:"
517 " 0x%08x but already got ExpStatSN: 0x%08x on CID:"
518 " %hu.\n", begrun, runlength, conn->exp_statsn,
519 conn->cid);
520 return 0;
521 }
522
523 last_statsn = (!runlength) ? conn->stat_sn : (begrun + runlength);
524
525 while (begrun < last_statsn) {
526 found_cmd = 0;
527
528 spin_lock_bh(&conn->cmd_lock);
529 list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) {
530 if (cmd->stat_sn == begrun) {
531 found_cmd = 1;
532 break;
533 }
534 }
535 spin_unlock_bh(&conn->cmd_lock);
536
537 if (!found_cmd) {
538 pr_err("Unable to find StatSN: 0x%08x for"
539 " a Status SNACK, assuming this was a"
540 " protactic SNACK for an untransmitted"
541 " StatSN, ignoring.\n", begrun);
542 begrun++;
543 continue;
544 }
545
546 spin_lock_bh(&cmd->istate_lock);
547 if (cmd->i_state == ISTATE_SEND_DATAIN) {
548 spin_unlock_bh(&cmd->istate_lock);
549 pr_err("Ignoring Status SNACK for BegRun:"
550 " 0x%08x, RunLength: 0x%08x, assuming this was"
551 " a protactic SNACK for an untransmitted"
552 " StatSN\n", begrun, runlength);
553 begrun++;
554 continue;
555 }
556 spin_unlock_bh(&cmd->istate_lock);
557
558 cmd->i_state = ISTATE_SEND_STATUS_RECOVERY;
559 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
560 begrun++;
561 }
562
563 return 0;
564}
565
566int iscsit_handle_data_ack(
567 struct iscsi_conn *conn,
568 u32 targ_xfer_tag,
569 u32 begrun,
570 u32 runlength)
571{
572 struct iscsi_cmd *cmd = NULL;
573
574 cmd = iscsit_find_cmd_from_ttt(conn, targ_xfer_tag);
575 if (!cmd) {
576 pr_err("Data ACK SNACK for TTT: 0x%08x is"
577 " invalid.\n", targ_xfer_tag);
578 return -1;
579 }
580
581 if (begrun <= cmd->acked_data_sn) {
582 pr_err("ITT: 0x%08x Data ACK SNACK BegRUN: 0x%08x is"
583 " less than the already acked DataSN: 0x%08x.\n",
584 cmd->init_task_tag, begrun, cmd->acked_data_sn);
585 return -1;
586 }
587
588 /*
589 * For Data ACK SNACK, BegRun is the next expected DataSN.
590 * (see iSCSI v19: 10.16.6)
591 */
592 cmd->cmd_flags |= ICF_GOT_DATACK_SNACK;
593 cmd->acked_data_sn = (begrun - 1);
594
595 pr_debug("Received Data ACK SNACK for ITT: 0x%08x,"
596 " updated acked DataSN to 0x%08x.\n",
597 cmd->init_task_tag, cmd->acked_data_sn);
598
599 return 0;
600}
601
602static int iscsit_send_recovery_r2t(
603 struct iscsi_cmd *cmd,
604 u32 offset,
605 u32 xfer_len)
606{
607 int ret;
608
609 spin_lock_bh(&cmd->r2t_lock);
610 ret = iscsit_add_r2t_to_list(cmd, offset, xfer_len, 1, 0);
611 spin_unlock_bh(&cmd->r2t_lock);
612
613 return ret;
614}
615
616int iscsit_dataout_datapduinorder_no_fbit(
617 struct iscsi_cmd *cmd,
618 struct iscsi_pdu *pdu)
619{
620 int i, send_recovery_r2t = 0, recovery = 0;
621 u32 length = 0, offset = 0, pdu_count = 0, xfer_len = 0;
622 struct iscsi_conn *conn = cmd->conn;
623 struct iscsi_pdu *first_pdu = NULL;
624
625 /*
626 * Get an struct iscsi_pdu pointer to the first PDU, and total PDU count
627 * of the DataOUT sequence.
628 */
629 if (conn->sess->sess_ops->DataSequenceInOrder) {
630 for (i = 0; i < cmd->pdu_count; i++) {
631 if (cmd->pdu_list[i].seq_no == pdu->seq_no) {
632 if (!first_pdu)
633 first_pdu = &cmd->pdu_list[i];
634 xfer_len += cmd->pdu_list[i].length;
635 pdu_count++;
636 } else if (pdu_count)
637 break;
638 }
639 } else {
640 struct iscsi_seq *seq = cmd->seq_ptr;
641
642 first_pdu = &cmd->pdu_list[seq->pdu_start];
643 pdu_count = seq->pdu_count;
644 }
645
646 if (!first_pdu || !pdu_count)
647 return DATAOUT_CANNOT_RECOVER;
648
649 /*
650 * Loop through the ending DataOUT Sequence checking each struct iscsi_pdu.
651 * The following ugly logic does batching of not received PDUs.
652 */
653 for (i = 0; i < pdu_count; i++) {
654 if (first_pdu[i].status == ISCSI_PDU_RECEIVED_OK) {
655 if (!send_recovery_r2t)
656 continue;
657
658 if (iscsit_send_recovery_r2t(cmd, offset, length) < 0)
659 return DATAOUT_CANNOT_RECOVER;
660
661 send_recovery_r2t = length = offset = 0;
662 continue;
663 }
664 /*
665 * Set recovery = 1 for any missing, CRC failed, or timed
666 * out PDUs to let the DataOUT logic know that this sequence
667 * has not been completed yet.
668 *
669 * Also, only send a Recovery R2T for ISCSI_PDU_NOT_RECEIVED.
670 * We assume if the PDU either failed CRC or timed out
671 * that a Recovery R2T has already been sent.
672 */
673 recovery = 1;
674
675 if (first_pdu[i].status != ISCSI_PDU_NOT_RECEIVED)
676 continue;
677
678 if (!offset)
679 offset = first_pdu[i].offset;
680 length += first_pdu[i].length;
681
682 send_recovery_r2t = 1;
683 }
684
685 if (send_recovery_r2t)
686 if (iscsit_send_recovery_r2t(cmd, offset, length) < 0)
687 return DATAOUT_CANNOT_RECOVER;
688
689 return (!recovery) ? DATAOUT_NORMAL : DATAOUT_WITHIN_COMMAND_RECOVERY;
690}
691
692static int iscsit_recalculate_dataout_values(
693 struct iscsi_cmd *cmd,
694 u32 pdu_offset,
695 u32 pdu_length,
696 u32 *r2t_offset,
697 u32 *r2t_length)
698{
699 int i;
700 struct iscsi_conn *conn = cmd->conn;
701 struct iscsi_pdu *pdu = NULL;
702
703 if (conn->sess->sess_ops->DataSequenceInOrder) {
704 cmd->data_sn = 0;
705
706 if (conn->sess->sess_ops->DataPDUInOrder) {
707 *r2t_offset = cmd->write_data_done;
708 *r2t_length = (cmd->seq_end_offset -
709 cmd->write_data_done);
710 return 0;
711 }
712
713 *r2t_offset = cmd->seq_start_offset;
714 *r2t_length = (cmd->seq_end_offset - cmd->seq_start_offset);
715
716 for (i = 0; i < cmd->pdu_count; i++) {
717 pdu = &cmd->pdu_list[i];
718
719 if (pdu->status != ISCSI_PDU_RECEIVED_OK)
720 continue;
721
722 if ((pdu->offset >= cmd->seq_start_offset) &&
723 ((pdu->offset + pdu->length) <=
724 cmd->seq_end_offset)) {
725 if (!cmd->unsolicited_data)
726 cmd->next_burst_len -= pdu->length;
727 else
728 cmd->first_burst_len -= pdu->length;
729
730 cmd->write_data_done -= pdu->length;
731 pdu->status = ISCSI_PDU_NOT_RECEIVED;
732 }
733 }
734 } else {
735 struct iscsi_seq *seq = NULL;
736
737 seq = iscsit_get_seq_holder(cmd, pdu_offset, pdu_length);
738 if (!seq)
739 return -1;
740
741 *r2t_offset = seq->orig_offset;
742 *r2t_length = seq->xfer_len;
743
744 cmd->write_data_done -= (seq->offset - seq->orig_offset);
745 if (cmd->immediate_data)
746 cmd->first_burst_len = cmd->write_data_done;
747
748 seq->data_sn = 0;
749 seq->offset = seq->orig_offset;
750 seq->next_burst_len = 0;
751 seq->status = DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY;
752
753 if (conn->sess->sess_ops->DataPDUInOrder)
754 return 0;
755
756 for (i = 0; i < seq->pdu_count; i++) {
757 pdu = &cmd->pdu_list[i+seq->pdu_start];
758
759 if (pdu->status != ISCSI_PDU_RECEIVED_OK)
760 continue;
761
762 pdu->status = ISCSI_PDU_NOT_RECEIVED;
763 }
764 }
765
766 return 0;
767}
768
769int iscsit_recover_dataout_sequence(
770 struct iscsi_cmd *cmd,
771 u32 pdu_offset,
772 u32 pdu_length)
773{
774 u32 r2t_length = 0, r2t_offset = 0;
775
776 spin_lock_bh(&cmd->istate_lock);
777 cmd->cmd_flags |= ICF_WITHIN_COMMAND_RECOVERY;
778 spin_unlock_bh(&cmd->istate_lock);
779
780 if (iscsit_recalculate_dataout_values(cmd, pdu_offset, pdu_length,
781 &r2t_offset, &r2t_length) < 0)
782 return DATAOUT_CANNOT_RECOVER;
783
784 iscsit_send_recovery_r2t(cmd, r2t_offset, r2t_length);
785
786 return DATAOUT_WITHIN_COMMAND_RECOVERY;
787}
788
789static struct iscsi_ooo_cmdsn *iscsit_allocate_ooo_cmdsn(void)
790{
791 struct iscsi_ooo_cmdsn *ooo_cmdsn = NULL;
792
793 ooo_cmdsn = kmem_cache_zalloc(lio_ooo_cache, GFP_ATOMIC);
794 if (!ooo_cmdsn) {
795 pr_err("Unable to allocate memory for"
796 " struct iscsi_ooo_cmdsn.\n");
797 return NULL;
798 }
799 INIT_LIST_HEAD(&ooo_cmdsn->ooo_list);
800
801 return ooo_cmdsn;
802}
803
804/*
805 * Called with sess->cmdsn_mutex held.
806 */
807static int iscsit_attach_ooo_cmdsn(
808 struct iscsi_session *sess,
809 struct iscsi_ooo_cmdsn *ooo_cmdsn)
810{
811 struct iscsi_ooo_cmdsn *ooo_tail, *ooo_tmp;
812 /*
813 * We attach the struct iscsi_ooo_cmdsn entry to the out of order
814 * list in increasing CmdSN order.
815 * This allows iscsi_execute_ooo_cmdsns() to detect any
816 * additional CmdSN holes while performing delayed execution.
817 */
818 if (list_empty(&sess->sess_ooo_cmdsn_list))
819 list_add_tail(&ooo_cmdsn->ooo_list,
820 &sess->sess_ooo_cmdsn_list);
821 else {
822 ooo_tail = list_entry(sess->sess_ooo_cmdsn_list.prev,
823 typeof(*ooo_tail), ooo_list);
824 /*
825 * CmdSN is greater than the tail of the list.
826 */
827 if (ooo_tail->cmdsn < ooo_cmdsn->cmdsn)
828 list_add_tail(&ooo_cmdsn->ooo_list,
829 &sess->sess_ooo_cmdsn_list);
830 else {
831 /*
832 * CmdSN is either lower than the head, or somewhere
833 * in the middle.
834 */
835 list_for_each_entry(ooo_tmp, &sess->sess_ooo_cmdsn_list,
836 ooo_list) {
837 while (ooo_tmp->cmdsn < ooo_cmdsn->cmdsn)
838 continue;
839
840 list_add(&ooo_cmdsn->ooo_list,
841 &ooo_tmp->ooo_list);
842 break;
843 }
844 }
845 }
846
847 return 0;
848}
849
850/*
851 * Removes an struct iscsi_ooo_cmdsn from a session's list,
852 * called with struct iscsi_session->cmdsn_mutex held.
853 */
854void iscsit_remove_ooo_cmdsn(
855 struct iscsi_session *sess,
856 struct iscsi_ooo_cmdsn *ooo_cmdsn)
857{
858 list_del(&ooo_cmdsn->ooo_list);
859 kmem_cache_free(lio_ooo_cache, ooo_cmdsn);
860}
861
862void iscsit_clear_ooo_cmdsns_for_conn(struct iscsi_conn *conn)
863{
864 struct iscsi_ooo_cmdsn *ooo_cmdsn;
865 struct iscsi_session *sess = conn->sess;
866
867 mutex_lock(&sess->cmdsn_mutex);
868 list_for_each_entry(ooo_cmdsn, &sess->sess_ooo_cmdsn_list, ooo_list) {
869 if (ooo_cmdsn->cid != conn->cid)
870 continue;
871
872 ooo_cmdsn->cmd = NULL;
873 }
874 mutex_unlock(&sess->cmdsn_mutex);
875}
876
877/*
878 * Called with sess->cmdsn_mutex held.
879 */
880int iscsit_execute_ooo_cmdsns(struct iscsi_session *sess)
881{
882 int ooo_count = 0;
883 struct iscsi_cmd *cmd = NULL;
884 struct iscsi_ooo_cmdsn *ooo_cmdsn, *ooo_cmdsn_tmp;
885
886 list_for_each_entry_safe(ooo_cmdsn, ooo_cmdsn_tmp,
887 &sess->sess_ooo_cmdsn_list, ooo_list) {
888 if (ooo_cmdsn->cmdsn != sess->exp_cmd_sn)
889 continue;
890
891 if (!ooo_cmdsn->cmd) {
892 sess->exp_cmd_sn++;
893 iscsit_remove_ooo_cmdsn(sess, ooo_cmdsn);
894 continue;
895 }
896
897 cmd = ooo_cmdsn->cmd;
898 cmd->i_state = cmd->deferred_i_state;
899 ooo_count++;
900 sess->exp_cmd_sn++;
901 pr_debug("Executing out of order CmdSN: 0x%08x,"
902 " incremented ExpCmdSN to 0x%08x.\n",
903 cmd->cmd_sn, sess->exp_cmd_sn);
904
905 iscsit_remove_ooo_cmdsn(sess, ooo_cmdsn);
906
907 if (iscsit_execute_cmd(cmd, 1) < 0)
908 return -1;
909
910 continue;
911 }
912
913 return ooo_count;
914}
915
916/*
917 * Called either:
918 *
919 * 1. With sess->cmdsn_mutex held from iscsi_execute_ooo_cmdsns()
920 * or iscsi_check_received_cmdsn().
921 * 2. With no locks held directly from iscsi_handle_XXX_pdu() functions
922 * for immediate commands.
923 */
924int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
925{
926 struct se_cmd *se_cmd = &cmd->se_cmd;
927 int lr = 0;
928
929 spin_lock_bh(&cmd->istate_lock);
930 if (ooo)
931 cmd->cmd_flags &= ~ICF_OOO_CMDSN;
932
933 switch (cmd->iscsi_opcode) {
934 case ISCSI_OP_SCSI_CMD:
935 /*
936 * Go ahead and send the CHECK_CONDITION status for
937 * any SCSI CDB exceptions that may have occurred, also
938 * handle the SCF_SCSI_RESERVATION_CONFLICT case here as well.
939 */
940 if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) {
941 if (se_cmd->se_cmd_flags &
942 SCF_SCSI_RESERVATION_CONFLICT) {
943 cmd->i_state = ISTATE_SEND_STATUS;
944 spin_unlock_bh(&cmd->istate_lock);
945 iscsit_add_cmd_to_response_queue(cmd, cmd->conn,
946 cmd->i_state);
947 return 0;
948 }
949 spin_unlock_bh(&cmd->istate_lock);
950 /*
951 * Determine if delayed TASK_ABORTED status for WRITEs
952 * should be sent now if no unsolicited data out
953 * payloads are expected, or if the delayed status
954 * should be sent after unsolicited data out with
955 * ISCSI_FLAG_CMD_FINAL set in iscsi_handle_data_out()
956 */
957 if (transport_check_aborted_status(se_cmd,
958 (cmd->unsolicited_data == 0)) != 0)
959 return 0;
960 /*
961 * Otherwise send CHECK_CONDITION and sense for
962 * exception
963 */
964 return transport_send_check_condition_and_sense(se_cmd,
965 se_cmd->scsi_sense_reason, 0);
966 }
967 /*
968 * Special case for delayed CmdSN with Immediate
969 * Data and/or Unsolicited Data Out attached.
970 */
971 if (cmd->immediate_data) {
972 if (cmd->cmd_flags & ICF_GOT_LAST_DATAOUT) {
973 spin_unlock_bh(&cmd->istate_lock);
974 return transport_generic_handle_data(
975 &cmd->se_cmd);
976 }
977 spin_unlock_bh(&cmd->istate_lock);
978
979 if (!(cmd->cmd_flags &
980 ICF_NON_IMMEDIATE_UNSOLICITED_DATA)) {
981 /*
982 * Send the delayed TASK_ABORTED status for
983 * WRITEs if no more unsolicitied data is
984 * expected.
985 */
986 if (transport_check_aborted_status(se_cmd, 1)
987 != 0)
988 return 0;
989
990 iscsit_set_dataout_sequence_values(cmd);
991 iscsit_build_r2ts_for_cmd(cmd, cmd->conn, 0);
992 }
993 return 0;
994 }
995 /*
996 * The default handler.
997 */
998 spin_unlock_bh(&cmd->istate_lock);
999
1000 if ((cmd->data_direction == DMA_TO_DEVICE) &&
1001 !(cmd->cmd_flags & ICF_NON_IMMEDIATE_UNSOLICITED_DATA)) {
1002 /*
1003 * Send the delayed TASK_ABORTED status for WRITEs if
1004 * no more nsolicitied data is expected.
1005 */
1006 if (transport_check_aborted_status(se_cmd, 1) != 0)
1007 return 0;
1008
1009 iscsit_set_dataout_sequence_values(cmd);
1010 spin_lock_bh(&cmd->dataout_timeout_lock);
1011 iscsit_start_dataout_timer(cmd, cmd->conn);
1012 spin_unlock_bh(&cmd->dataout_timeout_lock);
1013 }
1014 return transport_handle_cdb_direct(&cmd->se_cmd);
1015
1016 case ISCSI_OP_NOOP_OUT:
1017 case ISCSI_OP_TEXT:
1018 spin_unlock_bh(&cmd->istate_lock);
1019 iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
1020 break;
1021 case ISCSI_OP_SCSI_TMFUNC:
1022 if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) {
1023 spin_unlock_bh(&cmd->istate_lock);
1024 iscsit_add_cmd_to_response_queue(cmd, cmd->conn,
1025 cmd->i_state);
1026 return 0;
1027 }
1028 spin_unlock_bh(&cmd->istate_lock);
1029
1030 return transport_generic_handle_tmr(&cmd->se_cmd);
1031 case ISCSI_OP_LOGOUT:
1032 spin_unlock_bh(&cmd->istate_lock);
1033 switch (cmd->logout_reason) {
1034 case ISCSI_LOGOUT_REASON_CLOSE_SESSION:
1035 lr = iscsit_logout_closesession(cmd, cmd->conn);
1036 break;
1037 case ISCSI_LOGOUT_REASON_CLOSE_CONNECTION:
1038 lr = iscsit_logout_closeconnection(cmd, cmd->conn);
1039 break;
1040 case ISCSI_LOGOUT_REASON_RECOVERY:
1041 lr = iscsit_logout_removeconnforrecovery(cmd, cmd->conn);
1042 break;
1043 default:
1044 pr_err("Unknown iSCSI Logout Request Code:"
1045 " 0x%02x\n", cmd->logout_reason);
1046 return -1;
1047 }
1048
1049 return lr;
1050 default:
1051 spin_unlock_bh(&cmd->istate_lock);
1052 pr_err("Cannot perform out of order execution for"
1053 " unknown iSCSI Opcode: 0x%02x\n", cmd->iscsi_opcode);
1054 return -1;
1055 }
1056
1057 return 0;
1058}
1059
1060void iscsit_free_all_ooo_cmdsns(struct iscsi_session *sess)
1061{
1062 struct iscsi_ooo_cmdsn *ooo_cmdsn, *ooo_cmdsn_tmp;
1063
1064 mutex_lock(&sess->cmdsn_mutex);
1065 list_for_each_entry_safe(ooo_cmdsn, ooo_cmdsn_tmp,
1066 &sess->sess_ooo_cmdsn_list, ooo_list) {
1067
1068 list_del(&ooo_cmdsn->ooo_list);
1069 kmem_cache_free(lio_ooo_cache, ooo_cmdsn);
1070 }
1071 mutex_unlock(&sess->cmdsn_mutex);
1072}
1073
1074int iscsit_handle_ooo_cmdsn(
1075 struct iscsi_session *sess,
1076 struct iscsi_cmd *cmd,
1077 u32 cmdsn)
1078{
1079 int batch = 0;
1080 struct iscsi_ooo_cmdsn *ooo_cmdsn = NULL, *ooo_tail = NULL;
1081
1082 cmd->deferred_i_state = cmd->i_state;
1083 cmd->i_state = ISTATE_DEFERRED_CMD;
1084 cmd->cmd_flags |= ICF_OOO_CMDSN;
1085
1086 if (list_empty(&sess->sess_ooo_cmdsn_list))
1087 batch = 1;
1088 else {
1089 ooo_tail = list_entry(sess->sess_ooo_cmdsn_list.prev,
1090 typeof(*ooo_tail), ooo_list);
1091 if (ooo_tail->cmdsn != (cmdsn - 1))
1092 batch = 1;
1093 }
1094
1095 ooo_cmdsn = iscsit_allocate_ooo_cmdsn();
1096 if (!ooo_cmdsn)
1097 return CMDSN_ERROR_CANNOT_RECOVER;
1098
1099 ooo_cmdsn->cmd = cmd;
1100 ooo_cmdsn->batch_count = (batch) ?
1101 (cmdsn - sess->exp_cmd_sn) : 1;
1102 ooo_cmdsn->cid = cmd->conn->cid;
1103 ooo_cmdsn->exp_cmdsn = sess->exp_cmd_sn;
1104 ooo_cmdsn->cmdsn = cmdsn;
1105
1106 if (iscsit_attach_ooo_cmdsn(sess, ooo_cmdsn) < 0) {
1107 kmem_cache_free(lio_ooo_cache, ooo_cmdsn);
1108 return CMDSN_ERROR_CANNOT_RECOVER;
1109 }
1110
1111 return CMDSN_HIGHER_THAN_EXP;
1112}
1113
1114static int iscsit_set_dataout_timeout_values(
1115 struct iscsi_cmd *cmd,
1116 u32 *offset,
1117 u32 *length)
1118{
1119 struct iscsi_conn *conn = cmd->conn;
1120 struct iscsi_r2t *r2t;
1121
1122 if (cmd->unsolicited_data) {
1123 *offset = 0;
1124 *length = (conn->sess->sess_ops->FirstBurstLength >
1125 cmd->data_length) ?
1126 cmd->data_length :
1127 conn->sess->sess_ops->FirstBurstLength;
1128 return 0;
1129 }
1130
1131 spin_lock_bh(&cmd->r2t_lock);
1132 if (list_empty(&cmd->cmd_r2t_list)) {
1133 pr_err("cmd->cmd_r2t_list is empty!\n");
1134 spin_unlock_bh(&cmd->r2t_lock);
1135 return -1;
1136 }
1137
1138 list_for_each_entry(r2t, &cmd->cmd_r2t_list, r2t_list) {
1139 if (r2t->sent_r2t && !r2t->recovery_r2t && !r2t->seq_complete) {
1140 *offset = r2t->offset;
1141 *length = r2t->xfer_len;
1142 spin_unlock_bh(&cmd->r2t_lock);
1143 return 0;
1144 }
1145 }
1146 spin_unlock_bh(&cmd->r2t_lock);
1147
1148 pr_err("Unable to locate any incomplete DataOUT"
1149 " sequences for ITT: 0x%08x.\n", cmd->init_task_tag);
1150
1151 return -1;
1152}
1153
1154/*
1155 * NOTE: Called from interrupt (timer) context.
1156 */
1157static void iscsit_handle_dataout_timeout(unsigned long data)
1158{
1159 u32 pdu_length = 0, pdu_offset = 0;
1160 u32 r2t_length = 0, r2t_offset = 0;
1161 struct iscsi_cmd *cmd = (struct iscsi_cmd *) data;
1162 struct iscsi_conn *conn = cmd->conn;
1163 struct iscsi_session *sess = NULL;
1164 struct iscsi_node_attrib *na;
1165
1166 iscsit_inc_conn_usage_count(conn);
1167
1168 spin_lock_bh(&cmd->dataout_timeout_lock);
1169 if (cmd->dataout_timer_flags & ISCSI_TF_STOP) {
1170 spin_unlock_bh(&cmd->dataout_timeout_lock);
1171 iscsit_dec_conn_usage_count(conn);
1172 return;
1173 }
1174 cmd->dataout_timer_flags &= ~ISCSI_TF_RUNNING;
1175 sess = conn->sess;
1176 na = iscsit_tpg_get_node_attrib(sess);
1177
1178 if (!sess->sess_ops->ErrorRecoveryLevel) {
1179 pr_debug("Unable to recover from DataOut timeout while"
1180 " in ERL=0.\n");
1181 goto failure;
1182 }
1183
1184 if (++cmd->dataout_timeout_retries == na->dataout_timeout_retries) {
1185 pr_debug("Command ITT: 0x%08x exceeded max retries"
1186 " for DataOUT timeout %u, closing iSCSI connection.\n",
1187 cmd->init_task_tag, na->dataout_timeout_retries);
1188 goto failure;
1189 }
1190
1191 cmd->cmd_flags |= ICF_WITHIN_COMMAND_RECOVERY;
1192
1193 if (conn->sess->sess_ops->DataSequenceInOrder) {
1194 if (conn->sess->sess_ops->DataPDUInOrder) {
1195 pdu_offset = cmd->write_data_done;
1196 if ((pdu_offset + (conn->sess->sess_ops->MaxBurstLength -
1197 cmd->next_burst_len)) > cmd->data_length)
1198 pdu_length = (cmd->data_length -
1199 cmd->write_data_done);
1200 else
1201 pdu_length = (conn->sess->sess_ops->MaxBurstLength -
1202 cmd->next_burst_len);
1203 } else {
1204 pdu_offset = cmd->seq_start_offset;
1205 pdu_length = (cmd->seq_end_offset -
1206 cmd->seq_start_offset);
1207 }
1208 } else {
1209 if (iscsit_set_dataout_timeout_values(cmd, &pdu_offset,
1210 &pdu_length) < 0)
1211 goto failure;
1212 }
1213
1214 if (iscsit_recalculate_dataout_values(cmd, pdu_offset, pdu_length,
1215 &r2t_offset, &r2t_length) < 0)
1216 goto failure;
1217
1218 pr_debug("Command ITT: 0x%08x timed out waiting for"
1219 " completion of %sDataOUT Sequence Offset: %u, Length: %u\n",
1220 cmd->init_task_tag, (cmd->unsolicited_data) ? "Unsolicited " :
1221 "", r2t_offset, r2t_length);
1222
1223 if (iscsit_send_recovery_r2t(cmd, r2t_offset, r2t_length) < 0)
1224 goto failure;
1225
1226 iscsit_start_dataout_timer(cmd, conn);
1227 spin_unlock_bh(&cmd->dataout_timeout_lock);
1228 iscsit_dec_conn_usage_count(conn);
1229
1230 return;
1231
1232failure:
1233 spin_unlock_bh(&cmd->dataout_timeout_lock);
1234 iscsit_cause_connection_reinstatement(conn, 0);
1235 iscsit_dec_conn_usage_count(conn);
1236}
1237
1238void iscsit_mod_dataout_timer(struct iscsi_cmd *cmd)
1239{
1240 struct iscsi_conn *conn = cmd->conn;
1241 struct iscsi_session *sess = conn->sess;
1242 struct iscsi_node_attrib *na = na = iscsit_tpg_get_node_attrib(sess);
1243
1244 spin_lock_bh(&cmd->dataout_timeout_lock);
1245 if (!(cmd->dataout_timer_flags & ISCSI_TF_RUNNING)) {
1246 spin_unlock_bh(&cmd->dataout_timeout_lock);
1247 return;
1248 }
1249
1250 mod_timer(&cmd->dataout_timer,
1251 (get_jiffies_64() + na->dataout_timeout * HZ));
1252 pr_debug("Updated DataOUT timer for ITT: 0x%08x",
1253 cmd->init_task_tag);
1254 spin_unlock_bh(&cmd->dataout_timeout_lock);
1255}
1256
1257/*
1258 * Called with cmd->dataout_timeout_lock held.
1259 */
1260void iscsit_start_dataout_timer(
1261 struct iscsi_cmd *cmd,
1262 struct iscsi_conn *conn)
1263{
1264 struct iscsi_session *sess = conn->sess;
1265 struct iscsi_node_attrib *na = na = iscsit_tpg_get_node_attrib(sess);
1266
1267 if (cmd->dataout_timer_flags & ISCSI_TF_RUNNING)
1268 return;
1269
1270 pr_debug("Starting DataOUT timer for ITT: 0x%08x on"
1271 " CID: %hu.\n", cmd->init_task_tag, conn->cid);
1272
1273 init_timer(&cmd->dataout_timer);
1274 cmd->dataout_timer.expires = (get_jiffies_64() + na->dataout_timeout * HZ);
1275 cmd->dataout_timer.data = (unsigned long)cmd;
1276 cmd->dataout_timer.function = iscsit_handle_dataout_timeout;
1277 cmd->dataout_timer_flags &= ~ISCSI_TF_STOP;
1278 cmd->dataout_timer_flags |= ISCSI_TF_RUNNING;
1279 add_timer(&cmd->dataout_timer);
1280}
1281
1282void iscsit_stop_dataout_timer(struct iscsi_cmd *cmd)
1283{
1284 spin_lock_bh(&cmd->dataout_timeout_lock);
1285 if (!(cmd->dataout_timer_flags & ISCSI_TF_RUNNING)) {
1286 spin_unlock_bh(&cmd->dataout_timeout_lock);
1287 return;
1288 }
1289 cmd->dataout_timer_flags |= ISCSI_TF_STOP;
1290 spin_unlock_bh(&cmd->dataout_timeout_lock);
1291
1292 del_timer_sync(&cmd->dataout_timer);
1293
1294 spin_lock_bh(&cmd->dataout_timeout_lock);
1295 cmd->dataout_timer_flags &= ~ISCSI_TF_RUNNING;
1296 pr_debug("Stopped DataOUT Timer for ITT: 0x%08x\n",
1297 cmd->init_task_tag);
1298 spin_unlock_bh(&cmd->dataout_timeout_lock);
1299}
diff --git a/drivers/target/iscsi/iscsi_target_erl1.h b/drivers/target/iscsi/iscsi_target_erl1.h
new file mode 100644
index 000000000000..85e67e29de6b
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_erl1.h
@@ -0,0 +1,26 @@
1#ifndef ISCSI_TARGET_ERL1_H
2#define ISCSI_TARGET_ERL1_H
3
4extern int iscsit_dump_data_payload(struct iscsi_conn *, u32, int);
5extern int iscsit_create_recovery_datain_values_datasequenceinorder_yes(
6 struct iscsi_cmd *, struct iscsi_datain_req *);
7extern int iscsit_create_recovery_datain_values_datasequenceinorder_no(
8 struct iscsi_cmd *, struct iscsi_datain_req *);
9extern int iscsit_handle_recovery_datain_or_r2t(struct iscsi_conn *, unsigned char *,
10 u32, u32, u32, u32);
11extern int iscsit_handle_status_snack(struct iscsi_conn *, u32, u32,
12 u32, u32);
13extern int iscsit_handle_data_ack(struct iscsi_conn *, u32, u32, u32);
14extern int iscsit_dataout_datapduinorder_no_fbit(struct iscsi_cmd *, struct iscsi_pdu *);
15extern int iscsit_recover_dataout_sequence(struct iscsi_cmd *, u32, u32);
16extern void iscsit_clear_ooo_cmdsns_for_conn(struct iscsi_conn *);
17extern void iscsit_free_all_ooo_cmdsns(struct iscsi_session *);
18extern int iscsit_execute_ooo_cmdsns(struct iscsi_session *);
19extern int iscsit_execute_cmd(struct iscsi_cmd *, int);
20extern int iscsit_handle_ooo_cmdsn(struct iscsi_session *, struct iscsi_cmd *, u32);
21extern void iscsit_remove_ooo_cmdsn(struct iscsi_session *, struct iscsi_ooo_cmdsn *);
22extern void iscsit_mod_dataout_timer(struct iscsi_cmd *);
23extern void iscsit_start_dataout_timer(struct iscsi_cmd *, struct iscsi_conn *);
24extern void iscsit_stop_dataout_timer(struct iscsi_cmd *);
25
26#endif /* ISCSI_TARGET_ERL1_H */
diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c
new file mode 100644
index 000000000000..91a4d170bda4
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_erl2.c
@@ -0,0 +1,474 @@
1/*******************************************************************************
2 * This file contains error recovery level two functions used by
3 * the iSCSI Target driver.
4 *
5 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
6 *
7 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
8 *
9 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 ******************************************************************************/
21
22#include <scsi/iscsi_proto.h>
23#include <target/target_core_base.h>
24#include <target/target_core_transport.h>
25
26#include "iscsi_target_core.h"
27#include "iscsi_target_datain_values.h"
28#include "iscsi_target_util.h"
29#include "iscsi_target_erl0.h"
30#include "iscsi_target_erl1.h"
31#include "iscsi_target_erl2.h"
32#include "iscsi_target.h"
33
34/*
35 * FIXME: Does RData SNACK apply here as well?
36 */
37void iscsit_create_conn_recovery_datain_values(
38 struct iscsi_cmd *cmd,
39 u32 exp_data_sn)
40{
41 u32 data_sn = 0;
42 struct iscsi_conn *conn = cmd->conn;
43
44 cmd->next_burst_len = 0;
45 cmd->read_data_done = 0;
46
47 while (exp_data_sn > data_sn) {
48 if ((cmd->next_burst_len +
49 conn->conn_ops->MaxRecvDataSegmentLength) <
50 conn->sess->sess_ops->MaxBurstLength) {
51 cmd->read_data_done +=
52 conn->conn_ops->MaxRecvDataSegmentLength;
53 cmd->next_burst_len +=
54 conn->conn_ops->MaxRecvDataSegmentLength;
55 } else {
56 cmd->read_data_done +=
57 (conn->sess->sess_ops->MaxBurstLength -
58 cmd->next_burst_len);
59 cmd->next_burst_len = 0;
60 }
61 data_sn++;
62 }
63}
64
65void iscsit_create_conn_recovery_dataout_values(
66 struct iscsi_cmd *cmd)
67{
68 u32 write_data_done = 0;
69 struct iscsi_conn *conn = cmd->conn;
70
71 cmd->data_sn = 0;
72 cmd->next_burst_len = 0;
73
74 while (cmd->write_data_done > write_data_done) {
75 if ((write_data_done + conn->sess->sess_ops->MaxBurstLength) <=
76 cmd->write_data_done)
77 write_data_done += conn->sess->sess_ops->MaxBurstLength;
78 else
79 break;
80 }
81
82 cmd->write_data_done = write_data_done;
83}
84
85static int iscsit_attach_active_connection_recovery_entry(
86 struct iscsi_session *sess,
87 struct iscsi_conn_recovery *cr)
88{
89 spin_lock(&sess->cr_a_lock);
90 list_add_tail(&cr->cr_list, &sess->cr_active_list);
91 spin_unlock(&sess->cr_a_lock);
92
93 return 0;
94}
95
96static int iscsit_attach_inactive_connection_recovery_entry(
97 struct iscsi_session *sess,
98 struct iscsi_conn_recovery *cr)
99{
100 spin_lock(&sess->cr_i_lock);
101 list_add_tail(&cr->cr_list, &sess->cr_inactive_list);
102
103 sess->conn_recovery_count++;
104 pr_debug("Incremented connection recovery count to %u for"
105 " SID: %u\n", sess->conn_recovery_count, sess->sid);
106 spin_unlock(&sess->cr_i_lock);
107
108 return 0;
109}
110
111struct iscsi_conn_recovery *iscsit_get_inactive_connection_recovery_entry(
112 struct iscsi_session *sess,
113 u16 cid)
114{
115 struct iscsi_conn_recovery *cr;
116
117 spin_lock(&sess->cr_i_lock);
118 list_for_each_entry(cr, &sess->cr_inactive_list, cr_list) {
119 if (cr->cid == cid) {
120 spin_unlock(&sess->cr_i_lock);
121 return cr;
122 }
123 }
124 spin_unlock(&sess->cr_i_lock);
125
126 return NULL;
127}
128
129void iscsit_free_connection_recovery_entires(struct iscsi_session *sess)
130{
131 struct iscsi_cmd *cmd, *cmd_tmp;
132 struct iscsi_conn_recovery *cr, *cr_tmp;
133
134 spin_lock(&sess->cr_a_lock);
135 list_for_each_entry_safe(cr, cr_tmp, &sess->cr_active_list, cr_list) {
136 list_del(&cr->cr_list);
137 spin_unlock(&sess->cr_a_lock);
138
139 spin_lock(&cr->conn_recovery_cmd_lock);
140 list_for_each_entry_safe(cmd, cmd_tmp,
141 &cr->conn_recovery_cmd_list, i_list) {
142
143 list_del(&cmd->i_list);
144 cmd->conn = NULL;
145 spin_unlock(&cr->conn_recovery_cmd_lock);
146 if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) ||
147 !(cmd->se_cmd.transport_wait_for_tasks))
148 iscsit_release_cmd(cmd);
149 else
150 cmd->se_cmd.transport_wait_for_tasks(
151 &cmd->se_cmd, 1, 1);
152 spin_lock(&cr->conn_recovery_cmd_lock);
153 }
154 spin_unlock(&cr->conn_recovery_cmd_lock);
155 spin_lock(&sess->cr_a_lock);
156
157 kfree(cr);
158 }
159 spin_unlock(&sess->cr_a_lock);
160
161 spin_lock(&sess->cr_i_lock);
162 list_for_each_entry_safe(cr, cr_tmp, &sess->cr_inactive_list, cr_list) {
163 list_del(&cr->cr_list);
164 spin_unlock(&sess->cr_i_lock);
165
166 spin_lock(&cr->conn_recovery_cmd_lock);
167 list_for_each_entry_safe(cmd, cmd_tmp,
168 &cr->conn_recovery_cmd_list, i_list) {
169
170 list_del(&cmd->i_list);
171 cmd->conn = NULL;
172 spin_unlock(&cr->conn_recovery_cmd_lock);
173 if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) ||
174 !(cmd->se_cmd.transport_wait_for_tasks))
175 iscsit_release_cmd(cmd);
176 else
177 cmd->se_cmd.transport_wait_for_tasks(
178 &cmd->se_cmd, 1, 1);
179 spin_lock(&cr->conn_recovery_cmd_lock);
180 }
181 spin_unlock(&cr->conn_recovery_cmd_lock);
182 spin_lock(&sess->cr_i_lock);
183
184 kfree(cr);
185 }
186 spin_unlock(&sess->cr_i_lock);
187}
188
189int iscsit_remove_active_connection_recovery_entry(
190 struct iscsi_conn_recovery *cr,
191 struct iscsi_session *sess)
192{
193 spin_lock(&sess->cr_a_lock);
194 list_del(&cr->cr_list);
195
196 sess->conn_recovery_count--;
197 pr_debug("Decremented connection recovery count to %u for"
198 " SID: %u\n", sess->conn_recovery_count, sess->sid);
199 spin_unlock(&sess->cr_a_lock);
200
201 kfree(cr);
202
203 return 0;
204}
205
206int iscsit_remove_inactive_connection_recovery_entry(
207 struct iscsi_conn_recovery *cr,
208 struct iscsi_session *sess)
209{
210 spin_lock(&sess->cr_i_lock);
211 list_del(&cr->cr_list);
212 spin_unlock(&sess->cr_i_lock);
213
214 return 0;
215}
216
217/*
218 * Called with cr->conn_recovery_cmd_lock help.
219 */
220int iscsit_remove_cmd_from_connection_recovery(
221 struct iscsi_cmd *cmd,
222 struct iscsi_session *sess)
223{
224 struct iscsi_conn_recovery *cr;
225
226 if (!cmd->cr) {
227 pr_err("struct iscsi_conn_recovery pointer for ITT: 0x%08x"
228 " is NULL!\n", cmd->init_task_tag);
229 BUG();
230 }
231 cr = cmd->cr;
232
233 list_del(&cmd->i_list);
234 return --cr->cmd_count;
235}
236
237void iscsit_discard_cr_cmds_by_expstatsn(
238 struct iscsi_conn_recovery *cr,
239 u32 exp_statsn)
240{
241 u32 dropped_count = 0;
242 struct iscsi_cmd *cmd, *cmd_tmp;
243 struct iscsi_session *sess = cr->sess;
244
245 spin_lock(&cr->conn_recovery_cmd_lock);
246 list_for_each_entry_safe(cmd, cmd_tmp,
247 &cr->conn_recovery_cmd_list, i_list) {
248
249 if (((cmd->deferred_i_state != ISTATE_SENT_STATUS) &&
250 (cmd->deferred_i_state != ISTATE_REMOVE)) ||
251 (cmd->stat_sn >= exp_statsn)) {
252 continue;
253 }
254
255 dropped_count++;
256 pr_debug("Dropping Acknowledged ITT: 0x%08x, StatSN:"
257 " 0x%08x, CID: %hu.\n", cmd->init_task_tag,
258 cmd->stat_sn, cr->cid);
259
260 iscsit_remove_cmd_from_connection_recovery(cmd, sess);
261
262 spin_unlock(&cr->conn_recovery_cmd_lock);
263 if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) ||
264 !(cmd->se_cmd.transport_wait_for_tasks))
265 iscsit_release_cmd(cmd);
266 else
267 cmd->se_cmd.transport_wait_for_tasks(
268 &cmd->se_cmd, 1, 0);
269 spin_lock(&cr->conn_recovery_cmd_lock);
270 }
271 spin_unlock(&cr->conn_recovery_cmd_lock);
272
273 pr_debug("Dropped %u total acknowledged commands on"
274 " CID: %hu less than old ExpStatSN: 0x%08x\n",
275 dropped_count, cr->cid, exp_statsn);
276
277 if (!cr->cmd_count) {
278 pr_debug("No commands to be reassigned for failed"
279 " connection CID: %hu on SID: %u\n",
280 cr->cid, sess->sid);
281 iscsit_remove_inactive_connection_recovery_entry(cr, sess);
282 iscsit_attach_active_connection_recovery_entry(sess, cr);
283 pr_debug("iSCSI connection recovery successful for CID:"
284 " %hu on SID: %u\n", cr->cid, sess->sid);
285 iscsit_remove_active_connection_recovery_entry(cr, sess);
286 } else {
287 iscsit_remove_inactive_connection_recovery_entry(cr, sess);
288 iscsit_attach_active_connection_recovery_entry(sess, cr);
289 }
290}
291
292int iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(struct iscsi_conn *conn)
293{
294 u32 dropped_count = 0;
295 struct iscsi_cmd *cmd, *cmd_tmp;
296 struct iscsi_ooo_cmdsn *ooo_cmdsn, *ooo_cmdsn_tmp;
297 struct iscsi_session *sess = conn->sess;
298
299 mutex_lock(&sess->cmdsn_mutex);
300 list_for_each_entry_safe(ooo_cmdsn, ooo_cmdsn_tmp,
301 &sess->sess_ooo_cmdsn_list, ooo_list) {
302
303 if (ooo_cmdsn->cid != conn->cid)
304 continue;
305
306 dropped_count++;
307 pr_debug("Dropping unacknowledged CmdSN:"
308 " 0x%08x during connection recovery on CID: %hu\n",
309 ooo_cmdsn->cmdsn, conn->cid);
310 iscsit_remove_ooo_cmdsn(sess, ooo_cmdsn);
311 }
312 mutex_unlock(&sess->cmdsn_mutex);
313
314 spin_lock_bh(&conn->cmd_lock);
315 list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_list) {
316 if (!(cmd->cmd_flags & ICF_OOO_CMDSN))
317 continue;
318
319 list_del(&cmd->i_list);
320
321 spin_unlock_bh(&conn->cmd_lock);
322 if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) ||
323 !(cmd->se_cmd.transport_wait_for_tasks))
324 iscsit_release_cmd(cmd);
325 else
326 cmd->se_cmd.transport_wait_for_tasks(
327 &cmd->se_cmd, 1, 1);
328 spin_lock_bh(&conn->cmd_lock);
329 }
330 spin_unlock_bh(&conn->cmd_lock);
331
332 pr_debug("Dropped %u total unacknowledged commands on CID:"
333 " %hu for ExpCmdSN: 0x%08x.\n", dropped_count, conn->cid,
334 sess->exp_cmd_sn);
335 return 0;
336}
337
338int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn)
339{
340 u32 cmd_count = 0;
341 struct iscsi_cmd *cmd, *cmd_tmp;
342 struct iscsi_conn_recovery *cr;
343
344 /*
345 * Allocate an struct iscsi_conn_recovery for this connection.
346 * Each struct iscsi_cmd contains an struct iscsi_conn_recovery pointer
347 * (struct iscsi_cmd->cr) so we need to allocate this before preparing the
348 * connection's command list for connection recovery.
349 */
350 cr = kzalloc(sizeof(struct iscsi_conn_recovery), GFP_KERNEL);
351 if (!cr) {
352 pr_err("Unable to allocate memory for"
353 " struct iscsi_conn_recovery.\n");
354 return -1;
355 }
356 INIT_LIST_HEAD(&cr->cr_list);
357 INIT_LIST_HEAD(&cr->conn_recovery_cmd_list);
358 spin_lock_init(&cr->conn_recovery_cmd_lock);
359 /*
360 * Only perform connection recovery on ISCSI_OP_SCSI_CMD or
361 * ISCSI_OP_NOOP_OUT opcodes. For all other opcodes call
362 * list_del(&cmd->i_list); to release the command to the
363 * session pool and remove it from the connection's list.
364 *
365 * Also stop the DataOUT timer, which will be restarted after
366 * sending the TMR response.
367 */
368 spin_lock_bh(&conn->cmd_lock);
369 list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_list) {
370
371 if ((cmd->iscsi_opcode != ISCSI_OP_SCSI_CMD) &&
372 (cmd->iscsi_opcode != ISCSI_OP_NOOP_OUT)) {
373 pr_debug("Not performing realligence on"
374 " Opcode: 0x%02x, ITT: 0x%08x, CmdSN: 0x%08x,"
375 " CID: %hu\n", cmd->iscsi_opcode,
376 cmd->init_task_tag, cmd->cmd_sn, conn->cid);
377
378 list_del(&cmd->i_list);
379 spin_unlock_bh(&conn->cmd_lock);
380
381 if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) ||
382 !(cmd->se_cmd.transport_wait_for_tasks))
383 iscsit_release_cmd(cmd);
384 else
385 cmd->se_cmd.transport_wait_for_tasks(
386 &cmd->se_cmd, 1, 0);
387 spin_lock_bh(&conn->cmd_lock);
388 continue;
389 }
390
391 /*
392 * Special case where commands greater than or equal to
393 * the session's ExpCmdSN are attached to the connection
394 * list but not to the out of order CmdSN list. The one
395 * obvious case is when a command with immediate data
396 * attached must only check the CmdSN against ExpCmdSN
397 * after the data is received. The special case below
398 * is when the connection fails before data is received,
399 * but also may apply to other PDUs, so it has been
400 * made generic here.
401 */
402 if (!(cmd->cmd_flags & ICF_OOO_CMDSN) && !cmd->immediate_cmd &&
403 (cmd->cmd_sn >= conn->sess->exp_cmd_sn)) {
404 list_del(&cmd->i_list);
405 spin_unlock_bh(&conn->cmd_lock);
406
407 if (!(cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) ||
408 !(cmd->se_cmd.transport_wait_for_tasks))
409 iscsit_release_cmd(cmd);
410 else
411 cmd->se_cmd.transport_wait_for_tasks(
412 &cmd->se_cmd, 1, 1);
413 spin_lock_bh(&conn->cmd_lock);
414 continue;
415 }
416
417 cmd_count++;
418 pr_debug("Preparing Opcode: 0x%02x, ITT: 0x%08x,"
419 " CmdSN: 0x%08x, StatSN: 0x%08x, CID: %hu for"
420 " realligence.\n", cmd->iscsi_opcode,
421 cmd->init_task_tag, cmd->cmd_sn, cmd->stat_sn,
422 conn->cid);
423
424 cmd->deferred_i_state = cmd->i_state;
425 cmd->i_state = ISTATE_IN_CONNECTION_RECOVERY;
426
427 if (cmd->data_direction == DMA_TO_DEVICE)
428 iscsit_stop_dataout_timer(cmd);
429
430 cmd->sess = conn->sess;
431
432 list_del(&cmd->i_list);
433 spin_unlock_bh(&conn->cmd_lock);
434
435 iscsit_free_all_datain_reqs(cmd);
436
437 if ((cmd->se_cmd.se_cmd_flags & SCF_SE_LUN_CMD) &&
438 cmd->se_cmd.transport_wait_for_tasks)
439 cmd->se_cmd.transport_wait_for_tasks(&cmd->se_cmd,
440 0, 0);
441 /*
442 * Add the struct iscsi_cmd to the connection recovery cmd list
443 */
444 spin_lock(&cr->conn_recovery_cmd_lock);
445 list_add_tail(&cmd->i_list, &cr->conn_recovery_cmd_list);
446 spin_unlock(&cr->conn_recovery_cmd_lock);
447
448 spin_lock_bh(&conn->cmd_lock);
449 cmd->cr = cr;
450 cmd->conn = NULL;
451 }
452 spin_unlock_bh(&conn->cmd_lock);
453 /*
454 * Fill in the various values in the preallocated struct iscsi_conn_recovery.
455 */
456 cr->cid = conn->cid;
457 cr->cmd_count = cmd_count;
458 cr->maxrecvdatasegmentlength = conn->conn_ops->MaxRecvDataSegmentLength;
459 cr->sess = conn->sess;
460
461 iscsit_attach_inactive_connection_recovery_entry(conn->sess, cr);
462
463 return 0;
464}
465
466int iscsit_connection_recovery_transport_reset(struct iscsi_conn *conn)
467{
468 atomic_set(&conn->connection_recovery, 1);
469
470 if (iscsit_close_connection(conn) < 0)
471 return -1;
472
473 return 0;
474}
diff --git a/drivers/target/iscsi/iscsi_target_erl2.h b/drivers/target/iscsi/iscsi_target_erl2.h
new file mode 100644
index 000000000000..22f8d24780a6
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_erl2.h
@@ -0,0 +1,18 @@
1#ifndef ISCSI_TARGET_ERL2_H
2#define ISCSI_TARGET_ERL2_H
3
4extern void iscsit_create_conn_recovery_datain_values(struct iscsi_cmd *, u32);
5extern void iscsit_create_conn_recovery_dataout_values(struct iscsi_cmd *);
6extern struct iscsi_conn_recovery *iscsit_get_inactive_connection_recovery_entry(
7 struct iscsi_session *, u16);
8extern void iscsit_free_connection_recovery_entires(struct iscsi_session *);
9extern int iscsit_remove_active_connection_recovery_entry(
10 struct iscsi_conn_recovery *, struct iscsi_session *);
11extern int iscsit_remove_cmd_from_connection_recovery(struct iscsi_cmd *,
12 struct iscsi_session *);
13extern void iscsit_discard_cr_cmds_by_expstatsn(struct iscsi_conn_recovery *, u32);
14extern int iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(struct iscsi_conn *);
15extern int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *);
16extern int iscsit_connection_recovery_transport_reset(struct iscsi_conn *);
17
18#endif /*** ISCSI_TARGET_ERL2_H ***/
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
new file mode 100644
index 000000000000..bcaf82f47037
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -0,0 +1,1232 @@
1/*******************************************************************************
2 * This file contains the login functions used by the iSCSI Target driver.
3 *
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5 *
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7 *
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.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
21#include <linux/string.h>
22#include <linux/kthread.h>
23#include <linux/crypto.h>
24#include <scsi/iscsi_proto.h>
25#include <target/target_core_base.h>
26#include <target/target_core_transport.h>
27
28#include "iscsi_target_core.h"
29#include "iscsi_target_tq.h"
30#include "iscsi_target_device.h"
31#include "iscsi_target_nego.h"
32#include "iscsi_target_erl0.h"
33#include "iscsi_target_erl2.h"
34#include "iscsi_target_login.h"
35#include "iscsi_target_stat.h"
36#include "iscsi_target_tpg.h"
37#include "iscsi_target_util.h"
38#include "iscsi_target.h"
39#include "iscsi_target_parameters.h"
40
41extern struct idr sess_idr;
42extern struct mutex auth_id_lock;
43extern spinlock_t sess_idr_lock;
44
45static int iscsi_login_init_conn(struct iscsi_conn *conn)
46{
47 INIT_LIST_HEAD(&conn->conn_list);
48 INIT_LIST_HEAD(&conn->conn_cmd_list);
49 INIT_LIST_HEAD(&conn->immed_queue_list);
50 INIT_LIST_HEAD(&conn->response_queue_list);
51 init_completion(&conn->conn_post_wait_comp);
52 init_completion(&conn->conn_wait_comp);
53 init_completion(&conn->conn_wait_rcfr_comp);
54 init_completion(&conn->conn_waiting_on_uc_comp);
55 init_completion(&conn->conn_logout_comp);
56 init_completion(&conn->rx_half_close_comp);
57 init_completion(&conn->tx_half_close_comp);
58 spin_lock_init(&conn->cmd_lock);
59 spin_lock_init(&conn->conn_usage_lock);
60 spin_lock_init(&conn->immed_queue_lock);
61 spin_lock_init(&conn->nopin_timer_lock);
62 spin_lock_init(&conn->response_queue_lock);
63 spin_lock_init(&conn->state_lock);
64
65 if (!zalloc_cpumask_var(&conn->conn_cpumask, GFP_KERNEL)) {
66 pr_err("Unable to allocate conn->conn_cpumask\n");
67 return -ENOMEM;
68 }
69
70 return 0;
71}
72
73/*
74 * Used by iscsi_target_nego.c:iscsi_target_locate_portal() to setup
75 * per struct iscsi_conn libcrypto contexts for crc32c and crc32-intel
76 */
77int iscsi_login_setup_crypto(struct iscsi_conn *conn)
78{
79 /*
80 * Setup slicing by CRC32C algorithm for RX and TX libcrypto contexts
81 * which will default to crc32c_intel.ko for cpu_has_xmm4_2, or fallback
82 * to software 1x8 byte slicing from crc32c.ko
83 */
84 conn->conn_rx_hash.flags = 0;
85 conn->conn_rx_hash.tfm = crypto_alloc_hash("crc32c", 0,
86 CRYPTO_ALG_ASYNC);
87 if (IS_ERR(conn->conn_rx_hash.tfm)) {
88 pr_err("crypto_alloc_hash() failed for conn_rx_tfm\n");
89 return -ENOMEM;
90 }
91
92 conn->conn_tx_hash.flags = 0;
93 conn->conn_tx_hash.tfm = crypto_alloc_hash("crc32c", 0,
94 CRYPTO_ALG_ASYNC);
95 if (IS_ERR(conn->conn_tx_hash.tfm)) {
96 pr_err("crypto_alloc_hash() failed for conn_tx_tfm\n");
97 crypto_free_hash(conn->conn_rx_hash.tfm);
98 return -ENOMEM;
99 }
100
101 return 0;
102}
103
104static int iscsi_login_check_initiator_version(
105 struct iscsi_conn *conn,
106 u8 version_max,
107 u8 version_min)
108{
109 if ((version_max != 0x00) || (version_min != 0x00)) {
110 pr_err("Unsupported iSCSI IETF Pre-RFC Revision,"
111 " version Min/Max 0x%02x/0x%02x, rejecting login.\n",
112 version_min, version_max);
113 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
114 ISCSI_LOGIN_STATUS_NO_VERSION);
115 return -1;
116 }
117
118 return 0;
119}
120
121int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn)
122{
123 int sessiontype;
124 struct iscsi_param *initiatorname_param = NULL, *sessiontype_param = NULL;
125 struct iscsi_portal_group *tpg = conn->tpg;
126 struct iscsi_session *sess = NULL, *sess_p = NULL;
127 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
128 struct se_session *se_sess, *se_sess_tmp;
129
130 initiatorname_param = iscsi_find_param_from_key(
131 INITIATORNAME, conn->param_list);
132 if (!initiatorname_param)
133 return -1;
134
135 sessiontype_param = iscsi_find_param_from_key(
136 SESSIONTYPE, conn->param_list);
137 if (!sessiontype_param)
138 return -1;
139
140 sessiontype = (strncmp(sessiontype_param->value, NORMAL, 6)) ? 1 : 0;
141
142 spin_lock_bh(&se_tpg->session_lock);
143 list_for_each_entry_safe(se_sess, se_sess_tmp, &se_tpg->tpg_sess_list,
144 sess_list) {
145
146 sess_p = (struct iscsi_session *)se_sess->fabric_sess_ptr;
147 spin_lock(&sess_p->conn_lock);
148 if (atomic_read(&sess_p->session_fall_back_to_erl0) ||
149 atomic_read(&sess_p->session_logout) ||
150 (sess_p->time2retain_timer_flags & ISCSI_TF_EXPIRED)) {
151 spin_unlock(&sess_p->conn_lock);
152 continue;
153 }
154 if (!memcmp((void *)sess_p->isid, (void *)conn->sess->isid, 6) &&
155 (!strcmp((void *)sess_p->sess_ops->InitiatorName,
156 (void *)initiatorname_param->value) &&
157 (sess_p->sess_ops->SessionType == sessiontype))) {
158 atomic_set(&sess_p->session_reinstatement, 1);
159 spin_unlock(&sess_p->conn_lock);
160 iscsit_inc_session_usage_count(sess_p);
161 iscsit_stop_time2retain_timer(sess_p);
162 sess = sess_p;
163 break;
164 }
165 spin_unlock(&sess_p->conn_lock);
166 }
167 spin_unlock_bh(&se_tpg->session_lock);
168 /*
169 * If the Time2Retain handler has expired, the session is already gone.
170 */
171 if (!sess)
172 return 0;
173
174 pr_debug("%s iSCSI Session SID %u is still active for %s,"
175 " preforming session reinstatement.\n", (sessiontype) ?
176 "Discovery" : "Normal", sess->sid,
177 sess->sess_ops->InitiatorName);
178
179 spin_lock_bh(&sess->conn_lock);
180 if (sess->session_state == TARG_SESS_STATE_FAILED) {
181 spin_unlock_bh(&sess->conn_lock);
182 iscsit_dec_session_usage_count(sess);
183 return iscsit_close_session(sess);
184 }
185 spin_unlock_bh(&sess->conn_lock);
186
187 iscsit_stop_session(sess, 1, 1);
188 iscsit_dec_session_usage_count(sess);
189
190 return iscsit_close_session(sess);
191}
192
193static void iscsi_login_set_conn_values(
194 struct iscsi_session *sess,
195 struct iscsi_conn *conn,
196 u16 cid)
197{
198 conn->sess = sess;
199 conn->cid = cid;
200 /*
201 * Generate a random Status sequence number (statsn) for the new
202 * iSCSI connection.
203 */
204 get_random_bytes(&conn->stat_sn, sizeof(u32));
205
206 mutex_lock(&auth_id_lock);
207 conn->auth_id = iscsit_global->auth_id++;
208 mutex_unlock(&auth_id_lock);
209}
210
211/*
212 * This is the leading connection of a new session,
213 * or session reinstatement.
214 */
215static int iscsi_login_zero_tsih_s1(
216 struct iscsi_conn *conn,
217 unsigned char *buf)
218{
219 struct iscsi_session *sess = NULL;
220 struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf;
221
222 sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL);
223 if (!sess) {
224 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
225 ISCSI_LOGIN_STATUS_NO_RESOURCES);
226 pr_err("Could not allocate memory for session\n");
227 return -1;
228 }
229
230 iscsi_login_set_conn_values(sess, conn, pdu->cid);
231 sess->init_task_tag = pdu->itt;
232 memcpy((void *)&sess->isid, (void *)pdu->isid, 6);
233 sess->exp_cmd_sn = pdu->cmdsn;
234 INIT_LIST_HEAD(&sess->sess_conn_list);
235 INIT_LIST_HEAD(&sess->sess_ooo_cmdsn_list);
236 INIT_LIST_HEAD(&sess->cr_active_list);
237 INIT_LIST_HEAD(&sess->cr_inactive_list);
238 init_completion(&sess->async_msg_comp);
239 init_completion(&sess->reinstatement_comp);
240 init_completion(&sess->session_wait_comp);
241 init_completion(&sess->session_waiting_on_uc_comp);
242 mutex_init(&sess->cmdsn_mutex);
243 spin_lock_init(&sess->conn_lock);
244 spin_lock_init(&sess->cr_a_lock);
245 spin_lock_init(&sess->cr_i_lock);
246 spin_lock_init(&sess->session_usage_lock);
247 spin_lock_init(&sess->ttt_lock);
248
249 if (!idr_pre_get(&sess_idr, GFP_KERNEL)) {
250 pr_err("idr_pre_get() for sess_idr failed\n");
251 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
252 ISCSI_LOGIN_STATUS_NO_RESOURCES);
253 return -1;
254 }
255 spin_lock(&sess_idr_lock);
256 idr_get_new(&sess_idr, NULL, &sess->session_index);
257 spin_unlock(&sess_idr_lock);
258
259 sess->creation_time = get_jiffies_64();
260 spin_lock_init(&sess->session_stats_lock);
261 /*
262 * The FFP CmdSN window values will be allocated from the TPG's
263 * Initiator Node's ACL once the login has been successfully completed.
264 */
265 sess->max_cmd_sn = pdu->cmdsn;
266
267 sess->sess_ops = kzalloc(sizeof(struct iscsi_sess_ops), GFP_KERNEL);
268 if (!sess->sess_ops) {
269 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
270 ISCSI_LOGIN_STATUS_NO_RESOURCES);
271 pr_err("Unable to allocate memory for"
272 " struct iscsi_sess_ops.\n");
273 return -1;
274 }
275
276 sess->se_sess = transport_init_session();
277 if (!sess->se_sess) {
278 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
279 ISCSI_LOGIN_STATUS_NO_RESOURCES);
280 return -1;
281 }
282
283 return 0;
284}
285
286static int iscsi_login_zero_tsih_s2(
287 struct iscsi_conn *conn)
288{
289 struct iscsi_node_attrib *na;
290 struct iscsi_session *sess = conn->sess;
291 unsigned char buf[32];
292
293 sess->tpg = conn->tpg;
294
295 /*
296 * Assign a new TPG Session Handle. Note this is protected with
297 * struct iscsi_portal_group->np_login_sem from iscsit_access_np().
298 */
299 sess->tsih = ++ISCSI_TPG_S(sess)->ntsih;
300 if (!sess->tsih)
301 sess->tsih = ++ISCSI_TPG_S(sess)->ntsih;
302
303 /*
304 * Create the default params from user defined values..
305 */
306 if (iscsi_copy_param_list(&conn->param_list,
307 ISCSI_TPG_C(conn)->param_list, 1) < 0) {
308 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
309 ISCSI_LOGIN_STATUS_NO_RESOURCES);
310 return -1;
311 }
312
313 iscsi_set_keys_to_negotiate(0, conn->param_list);
314
315 if (sess->sess_ops->SessionType)
316 return iscsi_set_keys_irrelevant_for_discovery(
317 conn->param_list);
318
319 na = iscsit_tpg_get_node_attrib(sess);
320
321 /*
322 * Need to send TargetPortalGroupTag back in first login response
323 * on any iSCSI connection where the Initiator provides TargetName.
324 * See 5.3.1. Login Phase Start
325 *
326 * In our case, we have already located the struct iscsi_tiqn at this point.
327 */
328 memset(buf, 0, 32);
329 sprintf(buf, "TargetPortalGroupTag=%hu", ISCSI_TPG_S(sess)->tpgt);
330 if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
331 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
332 ISCSI_LOGIN_STATUS_NO_RESOURCES);
333 return -1;
334 }
335
336 /*
337 * Workaround for Initiators that have broken connection recovery logic.
338 *
339 * "We would really like to get rid of this." Linux-iSCSI.org team
340 */
341 memset(buf, 0, 32);
342 sprintf(buf, "ErrorRecoveryLevel=%d", na->default_erl);
343 if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
344 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
345 ISCSI_LOGIN_STATUS_NO_RESOURCES);
346 return -1;
347 }
348
349 if (iscsi_login_disable_FIM_keys(conn->param_list, conn) < 0)
350 return -1;
351
352 return 0;
353}
354
355/*
356 * Remove PSTATE_NEGOTIATE for the four FIM related keys.
357 * The Initiator node will be able to enable FIM by proposing them itself.
358 */
359int iscsi_login_disable_FIM_keys(
360 struct iscsi_param_list *param_list,
361 struct iscsi_conn *conn)
362{
363 struct iscsi_param *param;
364
365 param = iscsi_find_param_from_key("OFMarker", param_list);
366 if (!param) {
367 pr_err("iscsi_find_param_from_key() for"
368 " OFMarker failed\n");
369 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
370 ISCSI_LOGIN_STATUS_NO_RESOURCES);
371 return -1;
372 }
373 param->state &= ~PSTATE_NEGOTIATE;
374
375 param = iscsi_find_param_from_key("OFMarkInt", param_list);
376 if (!param) {
377 pr_err("iscsi_find_param_from_key() for"
378 " IFMarker failed\n");
379 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
380 ISCSI_LOGIN_STATUS_NO_RESOURCES);
381 return -1;
382 }
383 param->state &= ~PSTATE_NEGOTIATE;
384
385 param = iscsi_find_param_from_key("IFMarker", param_list);
386 if (!param) {
387 pr_err("iscsi_find_param_from_key() for"
388 " IFMarker failed\n");
389 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
390 ISCSI_LOGIN_STATUS_NO_RESOURCES);
391 return -1;
392 }
393 param->state &= ~PSTATE_NEGOTIATE;
394
395 param = iscsi_find_param_from_key("IFMarkInt", param_list);
396 if (!param) {
397 pr_err("iscsi_find_param_from_key() for"
398 " IFMarker failed\n");
399 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
400 ISCSI_LOGIN_STATUS_NO_RESOURCES);
401 return -1;
402 }
403 param->state &= ~PSTATE_NEGOTIATE;
404
405 return 0;
406}
407
408static int iscsi_login_non_zero_tsih_s1(
409 struct iscsi_conn *conn,
410 unsigned char *buf)
411{
412 struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf;
413
414 iscsi_login_set_conn_values(NULL, conn, pdu->cid);
415 return 0;
416}
417
418/*
419 * Add a new connection to an existing session.
420 */
421static int iscsi_login_non_zero_tsih_s2(
422 struct iscsi_conn *conn,
423 unsigned char *buf)
424{
425 struct iscsi_portal_group *tpg = conn->tpg;
426 struct iscsi_session *sess = NULL, *sess_p = NULL;
427 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
428 struct se_session *se_sess, *se_sess_tmp;
429 struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf;
430
431 spin_lock_bh(&se_tpg->session_lock);
432 list_for_each_entry_safe(se_sess, se_sess_tmp, &se_tpg->tpg_sess_list,
433 sess_list) {
434
435 sess_p = (struct iscsi_session *)se_sess->fabric_sess_ptr;
436 if (atomic_read(&sess_p->session_fall_back_to_erl0) ||
437 atomic_read(&sess_p->session_logout) ||
438 (sess_p->time2retain_timer_flags & ISCSI_TF_EXPIRED))
439 continue;
440 if (!memcmp((const void *)sess_p->isid,
441 (const void *)pdu->isid, 6) &&
442 (sess_p->tsih == pdu->tsih)) {
443 iscsit_inc_session_usage_count(sess_p);
444 iscsit_stop_time2retain_timer(sess_p);
445 sess = sess_p;
446 break;
447 }
448 }
449 spin_unlock_bh(&se_tpg->session_lock);
450
451 /*
452 * If the Time2Retain handler has expired, the session is already gone.
453 */
454 if (!sess) {
455 pr_err("Initiator attempting to add a connection to"
456 " a non-existent session, rejecting iSCSI Login.\n");
457 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
458 ISCSI_LOGIN_STATUS_NO_SESSION);
459 return -1;
460 }
461
462 /*
463 * Stop the Time2Retain timer if this is a failed session, we restart
464 * the timer if the login is not successful.
465 */
466 spin_lock_bh(&sess->conn_lock);
467 if (sess->session_state == TARG_SESS_STATE_FAILED)
468 atomic_set(&sess->session_continuation, 1);
469 spin_unlock_bh(&sess->conn_lock);
470
471 iscsi_login_set_conn_values(sess, conn, pdu->cid);
472
473 if (iscsi_copy_param_list(&conn->param_list,
474 ISCSI_TPG_C(conn)->param_list, 0) < 0) {
475 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
476 ISCSI_LOGIN_STATUS_NO_RESOURCES);
477 return -1;
478 }
479
480 iscsi_set_keys_to_negotiate(0, conn->param_list);
481 /*
482 * Need to send TargetPortalGroupTag back in first login response
483 * on any iSCSI connection where the Initiator provides TargetName.
484 * See 5.3.1. Login Phase Start
485 *
486 * In our case, we have already located the struct iscsi_tiqn at this point.
487 */
488 memset(buf, 0, 32);
489 sprintf(buf, "TargetPortalGroupTag=%hu", ISCSI_TPG_S(sess)->tpgt);
490 if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
491 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
492 ISCSI_LOGIN_STATUS_NO_RESOURCES);
493 return -1;
494 }
495
496 return iscsi_login_disable_FIM_keys(conn->param_list, conn);
497}
498
499int iscsi_login_post_auth_non_zero_tsih(
500 struct iscsi_conn *conn,
501 u16 cid,
502 u32 exp_statsn)
503{
504 struct iscsi_conn *conn_ptr = NULL;
505 struct iscsi_conn_recovery *cr = NULL;
506 struct iscsi_session *sess = conn->sess;
507
508 /*
509 * By following item 5 in the login table, if we have found
510 * an existing ISID and a valid/existing TSIH and an existing
511 * CID we do connection reinstatement. Currently we dont not
512 * support it so we send back an non-zero status class to the
513 * initiator and release the new connection.
514 */
515 conn_ptr = iscsit_get_conn_from_cid_rcfr(sess, cid);
516 if ((conn_ptr)) {
517 pr_err("Connection exists with CID %hu for %s,"
518 " performing connection reinstatement.\n",
519 conn_ptr->cid, sess->sess_ops->InitiatorName);
520
521 iscsit_connection_reinstatement_rcfr(conn_ptr);
522 iscsit_dec_conn_usage_count(conn_ptr);
523 }
524
525 /*
526 * Check for any connection recovery entires containing CID.
527 * We use the original ExpStatSN sent in the first login request
528 * to acknowledge commands for the failed connection.
529 *
530 * Also note that an explict logout may have already been sent,
531 * but the response may not be sent due to additional connection
532 * loss.
533 */
534 if (sess->sess_ops->ErrorRecoveryLevel == 2) {
535 cr = iscsit_get_inactive_connection_recovery_entry(
536 sess, cid);
537 if ((cr)) {
538 pr_debug("Performing implicit logout"
539 " for connection recovery on CID: %hu\n",
540 conn->cid);
541 iscsit_discard_cr_cmds_by_expstatsn(cr, exp_statsn);
542 }
543 }
544
545 /*
546 * Else we follow item 4 from the login table in that we have
547 * found an existing ISID and a valid/existing TSIH and a new
548 * CID we go ahead and continue to add a new connection to the
549 * session.
550 */
551 pr_debug("Adding CID %hu to existing session for %s.\n",
552 cid, sess->sess_ops->InitiatorName);
553
554 if ((atomic_read(&sess->nconn) + 1) > sess->sess_ops->MaxConnections) {
555 pr_err("Adding additional connection to this session"
556 " would exceed MaxConnections %d, login failed.\n",
557 sess->sess_ops->MaxConnections);
558 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
559 ISCSI_LOGIN_STATUS_ISID_ERROR);
560 return -1;
561 }
562
563 return 0;
564}
565
566static void iscsi_post_login_start_timers(struct iscsi_conn *conn)
567{
568 struct iscsi_session *sess = conn->sess;
569
570 if (!sess->sess_ops->SessionType)
571 iscsit_start_nopin_timer(conn);
572}
573
574static int iscsi_post_login_handler(
575 struct iscsi_np *np,
576 struct iscsi_conn *conn,
577 u8 zero_tsih)
578{
579 int stop_timer = 0;
580 struct iscsi_session *sess = conn->sess;
581 struct se_session *se_sess = sess->se_sess;
582 struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess);
583 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
584 struct iscsi_thread_set *ts;
585
586 iscsit_inc_conn_usage_count(conn);
587
588 iscsit_collect_login_stats(conn, ISCSI_STATUS_CLS_SUCCESS,
589 ISCSI_LOGIN_STATUS_ACCEPT);
590
591 pr_debug("Moving to TARG_CONN_STATE_LOGGED_IN.\n");
592 conn->conn_state = TARG_CONN_STATE_LOGGED_IN;
593
594 iscsi_set_connection_parameters(conn->conn_ops, conn->param_list);
595 iscsit_set_sync_and_steering_values(conn);
596 /*
597 * SCSI Initiator -> SCSI Target Port Mapping
598 */
599 ts = iscsi_get_thread_set();
600 if (!zero_tsih) {
601 iscsi_set_session_parameters(sess->sess_ops,
602 conn->param_list, 0);
603 iscsi_release_param_list(conn->param_list);
604 conn->param_list = NULL;
605
606 spin_lock_bh(&sess->conn_lock);
607 atomic_set(&sess->session_continuation, 0);
608 if (sess->session_state == TARG_SESS_STATE_FAILED) {
609 pr_debug("Moving to"
610 " TARG_SESS_STATE_LOGGED_IN.\n");
611 sess->session_state = TARG_SESS_STATE_LOGGED_IN;
612 stop_timer = 1;
613 }
614
615 pr_debug("iSCSI Login successful on CID: %hu from %s to"
616 " %s:%hu,%hu\n", conn->cid, conn->login_ip, np->np_ip,
617 np->np_port, tpg->tpgt);
618
619 list_add_tail(&conn->conn_list, &sess->sess_conn_list);
620 atomic_inc(&sess->nconn);
621 pr_debug("Incremented iSCSI Connection count to %hu"
622 " from node: %s\n", atomic_read(&sess->nconn),
623 sess->sess_ops->InitiatorName);
624 spin_unlock_bh(&sess->conn_lock);
625
626 iscsi_post_login_start_timers(conn);
627 iscsi_activate_thread_set(conn, ts);
628 /*
629 * Determine CPU mask to ensure connection's RX and TX kthreads
630 * are scheduled on the same CPU.
631 */
632 iscsit_thread_get_cpumask(conn);
633 conn->conn_rx_reset_cpumask = 1;
634 conn->conn_tx_reset_cpumask = 1;
635
636 iscsit_dec_conn_usage_count(conn);
637 if (stop_timer) {
638 spin_lock_bh(&se_tpg->session_lock);
639 iscsit_stop_time2retain_timer(sess);
640 spin_unlock_bh(&se_tpg->session_lock);
641 }
642 iscsit_dec_session_usage_count(sess);
643 return 0;
644 }
645
646 iscsi_set_session_parameters(sess->sess_ops, conn->param_list, 1);
647 iscsi_release_param_list(conn->param_list);
648 conn->param_list = NULL;
649
650 iscsit_determine_maxcmdsn(sess);
651
652 spin_lock_bh(&se_tpg->session_lock);
653 __transport_register_session(&sess->tpg->tpg_se_tpg,
654 se_sess->se_node_acl, se_sess, (void *)sess);
655 pr_debug("Moving to TARG_SESS_STATE_LOGGED_IN.\n");
656 sess->session_state = TARG_SESS_STATE_LOGGED_IN;
657
658 pr_debug("iSCSI Login successful on CID: %hu from %s to %s:%hu,%hu\n",
659 conn->cid, conn->login_ip, np->np_ip, np->np_port, tpg->tpgt);
660
661 spin_lock_bh(&sess->conn_lock);
662 list_add_tail(&conn->conn_list, &sess->sess_conn_list);
663 atomic_inc(&sess->nconn);
664 pr_debug("Incremented iSCSI Connection count to %hu from node:"
665 " %s\n", atomic_read(&sess->nconn),
666 sess->sess_ops->InitiatorName);
667 spin_unlock_bh(&sess->conn_lock);
668
669 sess->sid = tpg->sid++;
670 if (!sess->sid)
671 sess->sid = tpg->sid++;
672 pr_debug("Established iSCSI session from node: %s\n",
673 sess->sess_ops->InitiatorName);
674
675 tpg->nsessions++;
676 if (tpg->tpg_tiqn)
677 tpg->tpg_tiqn->tiqn_nsessions++;
678
679 pr_debug("Incremented number of active iSCSI sessions to %u on"
680 " iSCSI Target Portal Group: %hu\n", tpg->nsessions, tpg->tpgt);
681 spin_unlock_bh(&se_tpg->session_lock);
682
683 iscsi_post_login_start_timers(conn);
684 iscsi_activate_thread_set(conn, ts);
685 /*
686 * Determine CPU mask to ensure connection's RX and TX kthreads
687 * are scheduled on the same CPU.
688 */
689 iscsit_thread_get_cpumask(conn);
690 conn->conn_rx_reset_cpumask = 1;
691 conn->conn_tx_reset_cpumask = 1;
692
693 iscsit_dec_conn_usage_count(conn);
694
695 return 0;
696}
697
698static void iscsi_handle_login_thread_timeout(unsigned long data)
699{
700 struct iscsi_np *np = (struct iscsi_np *) data;
701
702 spin_lock_bh(&np->np_thread_lock);
703 pr_err("iSCSI Login timeout on Network Portal %s:%hu\n",
704 np->np_ip, np->np_port);
705
706 if (np->np_login_timer_flags & ISCSI_TF_STOP) {
707 spin_unlock_bh(&np->np_thread_lock);
708 return;
709 }
710
711 if (np->np_thread)
712 send_sig(SIGINT, np->np_thread, 1);
713
714 np->np_login_timer_flags &= ~ISCSI_TF_RUNNING;
715 spin_unlock_bh(&np->np_thread_lock);
716}
717
718static void iscsi_start_login_thread_timer(struct iscsi_np *np)
719{
720 /*
721 * This used the TA_LOGIN_TIMEOUT constant because at this
722 * point we do not have access to ISCSI_TPG_ATTRIB(tpg)->login_timeout
723 */
724 spin_lock_bh(&np->np_thread_lock);
725 init_timer(&np->np_login_timer);
726 np->np_login_timer.expires = (get_jiffies_64() + TA_LOGIN_TIMEOUT * HZ);
727 np->np_login_timer.data = (unsigned long)np;
728 np->np_login_timer.function = iscsi_handle_login_thread_timeout;
729 np->np_login_timer_flags &= ~ISCSI_TF_STOP;
730 np->np_login_timer_flags |= ISCSI_TF_RUNNING;
731 add_timer(&np->np_login_timer);
732
733 pr_debug("Added timeout timer to iSCSI login request for"
734 " %u seconds.\n", TA_LOGIN_TIMEOUT);
735 spin_unlock_bh(&np->np_thread_lock);
736}
737
738static void iscsi_stop_login_thread_timer(struct iscsi_np *np)
739{
740 spin_lock_bh(&np->np_thread_lock);
741 if (!(np->np_login_timer_flags & ISCSI_TF_RUNNING)) {
742 spin_unlock_bh(&np->np_thread_lock);
743 return;
744 }
745 np->np_login_timer_flags |= ISCSI_TF_STOP;
746 spin_unlock_bh(&np->np_thread_lock);
747
748 del_timer_sync(&np->np_login_timer);
749
750 spin_lock_bh(&np->np_thread_lock);
751 np->np_login_timer_flags &= ~ISCSI_TF_RUNNING;
752 spin_unlock_bh(&np->np_thread_lock);
753}
754
755int iscsi_target_setup_login_socket(
756 struct iscsi_np *np,
757 struct __kernel_sockaddr_storage *sockaddr)
758{
759 struct socket *sock;
760 int backlog = 5, ret, opt = 0, len;
761
762 switch (np->np_network_transport) {
763 case ISCSI_TCP:
764 np->np_ip_proto = IPPROTO_TCP;
765 np->np_sock_type = SOCK_STREAM;
766 break;
767 case ISCSI_SCTP_TCP:
768 np->np_ip_proto = IPPROTO_SCTP;
769 np->np_sock_type = SOCK_STREAM;
770 break;
771 case ISCSI_SCTP_UDP:
772 np->np_ip_proto = IPPROTO_SCTP;
773 np->np_sock_type = SOCK_SEQPACKET;
774 break;
775 case ISCSI_IWARP_TCP:
776 case ISCSI_IWARP_SCTP:
777 case ISCSI_INFINIBAND:
778 default:
779 pr_err("Unsupported network_transport: %d\n",
780 np->np_network_transport);
781 return -EINVAL;
782 }
783
784 ret = sock_create(sockaddr->ss_family, np->np_sock_type,
785 np->np_ip_proto, &sock);
786 if (ret < 0) {
787 pr_err("sock_create() failed.\n");
788 return ret;
789 }
790 np->np_socket = sock;
791 /*
792 * The SCTP stack needs struct socket->file.
793 */
794 if ((np->np_network_transport == ISCSI_SCTP_TCP) ||
795 (np->np_network_transport == ISCSI_SCTP_UDP)) {
796 if (!sock->file) {
797 sock->file = kzalloc(sizeof(struct file), GFP_KERNEL);
798 if (!sock->file) {
799 pr_err("Unable to allocate struct"
800 " file for SCTP\n");
801 ret = -ENOMEM;
802 goto fail;
803 }
804 np->np_flags |= NPF_SCTP_STRUCT_FILE;
805 }
806 }
807 /*
808 * Setup the np->np_sockaddr from the passed sockaddr setup
809 * in iscsi_target_configfs.c code..
810 */
811 memcpy((void *)&np->np_sockaddr, (void *)sockaddr,
812 sizeof(struct __kernel_sockaddr_storage));
813
814 if (sockaddr->ss_family == AF_INET6)
815 len = sizeof(struct sockaddr_in6);
816 else
817 len = sizeof(struct sockaddr_in);
818 /*
819 * Set SO_REUSEADDR, and disable Nagel Algorithm with TCP_NODELAY.
820 */
821 opt = 1;
822 if (np->np_network_transport == ISCSI_TCP) {
823 ret = kernel_setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
824 (char *)&opt, sizeof(opt));
825 if (ret < 0) {
826 pr_err("kernel_setsockopt() for TCP_NODELAY"
827 " failed: %d\n", ret);
828 goto fail;
829 }
830 }
831
832 ret = kernel_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
833 (char *)&opt, sizeof(opt));
834 if (ret < 0) {
835 pr_err("kernel_setsockopt() for SO_REUSEADDR"
836 " failed\n");
837 goto fail;
838 }
839
840 ret = kernel_bind(sock, (struct sockaddr *)&np->np_sockaddr, len);
841 if (ret < 0) {
842 pr_err("kernel_bind() failed: %d\n", ret);
843 goto fail;
844 }
845
846 ret = kernel_listen(sock, backlog);
847 if (ret != 0) {
848 pr_err("kernel_listen() failed: %d\n", ret);
849 goto fail;
850 }
851
852 return 0;
853
854fail:
855 np->np_socket = NULL;
856 if (sock) {
857 if (np->np_flags & NPF_SCTP_STRUCT_FILE) {
858 kfree(sock->file);
859 sock->file = NULL;
860 }
861
862 sock_release(sock);
863 }
864 return ret;
865}
866
867static int __iscsi_target_login_thread(struct iscsi_np *np)
868{
869 u8 buffer[ISCSI_HDR_LEN], iscsi_opcode, zero_tsih = 0;
870 int err, ret = 0, ip_proto, sock_type, set_sctp_conn_flag, stop;
871 struct iscsi_conn *conn = NULL;
872 struct iscsi_login *login;
873 struct iscsi_portal_group *tpg = NULL;
874 struct socket *new_sock, *sock;
875 struct kvec iov;
876 struct iscsi_login_req *pdu;
877 struct sockaddr_in sock_in;
878 struct sockaddr_in6 sock_in6;
879
880 flush_signals(current);
881 set_sctp_conn_flag = 0;
882 sock = np->np_socket;
883 ip_proto = np->np_ip_proto;
884 sock_type = np->np_sock_type;
885
886 spin_lock_bh(&np->np_thread_lock);
887 if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
888 np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
889 complete(&np->np_restart_comp);
890 } else {
891 np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
892 }
893 spin_unlock_bh(&np->np_thread_lock);
894
895 if (kernel_accept(sock, &new_sock, 0) < 0) {
896 spin_lock_bh(&np->np_thread_lock);
897 if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
898 spin_unlock_bh(&np->np_thread_lock);
899 complete(&np->np_restart_comp);
900 /* Get another socket */
901 return 1;
902 }
903 spin_unlock_bh(&np->np_thread_lock);
904 goto out;
905 }
906 /*
907 * The SCTP stack needs struct socket->file.
908 */
909 if ((np->np_network_transport == ISCSI_SCTP_TCP) ||
910 (np->np_network_transport == ISCSI_SCTP_UDP)) {
911 if (!new_sock->file) {
912 new_sock->file = kzalloc(
913 sizeof(struct file), GFP_KERNEL);
914 if (!new_sock->file) {
915 pr_err("Unable to allocate struct"
916 " file for SCTP\n");
917 sock_release(new_sock);
918 /* Get another socket */
919 return 1;
920 }
921 set_sctp_conn_flag = 1;
922 }
923 }
924
925 iscsi_start_login_thread_timer(np);
926
927 conn = kzalloc(sizeof(struct iscsi_conn), GFP_KERNEL);
928 if (!conn) {
929 pr_err("Could not allocate memory for"
930 " new connection\n");
931 if (set_sctp_conn_flag) {
932 kfree(new_sock->file);
933 new_sock->file = NULL;
934 }
935 sock_release(new_sock);
936 /* Get another socket */
937 return 1;
938 }
939
940 pr_debug("Moving to TARG_CONN_STATE_FREE.\n");
941 conn->conn_state = TARG_CONN_STATE_FREE;
942 conn->sock = new_sock;
943
944 if (set_sctp_conn_flag)
945 conn->conn_flags |= CONNFLAG_SCTP_STRUCT_FILE;
946
947 pr_debug("Moving to TARG_CONN_STATE_XPT_UP.\n");
948 conn->conn_state = TARG_CONN_STATE_XPT_UP;
949
950 /*
951 * Allocate conn->conn_ops early as a failure calling
952 * iscsit_tx_login_rsp() below will call tx_data().
953 */
954 conn->conn_ops = kzalloc(sizeof(struct iscsi_conn_ops), GFP_KERNEL);
955 if (!conn->conn_ops) {
956 pr_err("Unable to allocate memory for"
957 " struct iscsi_conn_ops.\n");
958 goto new_sess_out;
959 }
960 /*
961 * Perform the remaining iSCSI connection initialization items..
962 */
963 if (iscsi_login_init_conn(conn) < 0)
964 goto new_sess_out;
965
966 memset(buffer, 0, ISCSI_HDR_LEN);
967 memset(&iov, 0, sizeof(struct kvec));
968 iov.iov_base = buffer;
969 iov.iov_len = ISCSI_HDR_LEN;
970
971 if (rx_data(conn, &iov, 1, ISCSI_HDR_LEN) <= 0) {
972 pr_err("rx_data() returned an error.\n");
973 goto new_sess_out;
974 }
975
976 iscsi_opcode = (buffer[0] & ISCSI_OPCODE_MASK);
977 if (!(iscsi_opcode & ISCSI_OP_LOGIN)) {
978 pr_err("First opcode is not login request,"
979 " failing login request.\n");
980 goto new_sess_out;
981 }
982
983 pdu = (struct iscsi_login_req *) buffer;
984 pdu->cid = be16_to_cpu(pdu->cid);
985 pdu->tsih = be16_to_cpu(pdu->tsih);
986 pdu->itt = be32_to_cpu(pdu->itt);
987 pdu->cmdsn = be32_to_cpu(pdu->cmdsn);
988 pdu->exp_statsn = be32_to_cpu(pdu->exp_statsn);
989 /*
990 * Used by iscsit_tx_login_rsp() for Login Resonses PDUs
991 * when Status-Class != 0.
992 */
993 conn->login_itt = pdu->itt;
994
995 spin_lock_bh(&np->np_thread_lock);
996 if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
997 spin_unlock_bh(&np->np_thread_lock);
998 pr_err("iSCSI Network Portal on %s:%hu currently not"
999 " active.\n", np->np_ip, np->np_port);
1000 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
1001 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
1002 goto new_sess_out;
1003 }
1004 spin_unlock_bh(&np->np_thread_lock);
1005
1006 if (np->np_sockaddr.ss_family == AF_INET6) {
1007 memset(&sock_in6, 0, sizeof(struct sockaddr_in6));
1008
1009 if (conn->sock->ops->getname(conn->sock,
1010 (struct sockaddr *)&sock_in6, &err, 1) < 0) {
1011 pr_err("sock_ops->getname() failed.\n");
1012 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
1013 ISCSI_LOGIN_STATUS_TARGET_ERROR);
1014 goto new_sess_out;
1015 }
1016#if 0
1017 if (!iscsi_ntop6((const unsigned char *)
1018 &sock_in6.sin6_addr.in6_u,
1019 (char *)&conn->ipv6_login_ip[0],
1020 IPV6_ADDRESS_SPACE)) {
1021 pr_err("iscsi_ntop6() failed\n");
1022 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
1023 ISCSI_LOGIN_STATUS_TARGET_ERROR);
1024 goto new_sess_out;
1025 }
1026#else
1027 pr_debug("Skipping iscsi_ntop6()\n");
1028#endif
1029 } else {
1030 memset(&sock_in, 0, sizeof(struct sockaddr_in));
1031
1032 if (conn->sock->ops->getname(conn->sock,
1033 (struct sockaddr *)&sock_in, &err, 1) < 0) {
1034 pr_err("sock_ops->getname() failed.\n");
1035 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
1036 ISCSI_LOGIN_STATUS_TARGET_ERROR);
1037 goto new_sess_out;
1038 }
1039 sprintf(conn->login_ip, "%pI4", &sock_in.sin_addr.s_addr);
1040 conn->login_port = ntohs(sock_in.sin_port);
1041 }
1042
1043 conn->network_transport = np->np_network_transport;
1044
1045 pr_debug("Received iSCSI login request from %s on %s Network"
1046 " Portal %s:%hu\n", conn->login_ip,
1047 (conn->network_transport == ISCSI_TCP) ? "TCP" : "SCTP",
1048 np->np_ip, np->np_port);
1049
1050 pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n");
1051 conn->conn_state = TARG_CONN_STATE_IN_LOGIN;
1052
1053 if (iscsi_login_check_initiator_version(conn, pdu->max_version,
1054 pdu->min_version) < 0)
1055 goto new_sess_out;
1056
1057 zero_tsih = (pdu->tsih == 0x0000);
1058 if ((zero_tsih)) {
1059 /*
1060 * This is the leading connection of a new session.
1061 * We wait until after authentication to check for
1062 * session reinstatement.
1063 */
1064 if (iscsi_login_zero_tsih_s1(conn, buffer) < 0)
1065 goto new_sess_out;
1066 } else {
1067 /*
1068 * Add a new connection to an existing session.
1069 * We check for a non-existant session in
1070 * iscsi_login_non_zero_tsih_s2() below based
1071 * on ISID/TSIH, but wait until after authentication
1072 * to check for connection reinstatement, etc.
1073 */
1074 if (iscsi_login_non_zero_tsih_s1(conn, buffer) < 0)
1075 goto new_sess_out;
1076 }
1077
1078 /*
1079 * This will process the first login request, and call
1080 * iscsi_target_locate_portal(), and return a valid struct iscsi_login.
1081 */
1082 login = iscsi_target_init_negotiation(np, conn, buffer);
1083 if (!login) {
1084 tpg = conn->tpg;
1085 goto new_sess_out;
1086 }
1087
1088 tpg = conn->tpg;
1089 if (!tpg) {
1090 pr_err("Unable to locate struct iscsi_conn->tpg\n");
1091 goto new_sess_out;
1092 }
1093
1094 if (zero_tsih) {
1095 if (iscsi_login_zero_tsih_s2(conn) < 0) {
1096 iscsi_target_nego_release(login, conn);
1097 goto new_sess_out;
1098 }
1099 } else {
1100 if (iscsi_login_non_zero_tsih_s2(conn, buffer) < 0) {
1101 iscsi_target_nego_release(login, conn);
1102 goto old_sess_out;
1103 }
1104 }
1105
1106 if (iscsi_target_start_negotiation(login, conn) < 0)
1107 goto new_sess_out;
1108
1109 if (!conn->sess) {
1110 pr_err("struct iscsi_conn session pointer is NULL!\n");
1111 goto new_sess_out;
1112 }
1113
1114 iscsi_stop_login_thread_timer(np);
1115
1116 if (signal_pending(current))
1117 goto new_sess_out;
1118
1119 ret = iscsi_post_login_handler(np, conn, zero_tsih);
1120
1121 if (ret < 0)
1122 goto new_sess_out;
1123
1124 iscsit_deaccess_np(np, tpg);
1125 tpg = NULL;
1126 /* Get another socket */
1127 return 1;
1128
1129new_sess_out:
1130 pr_err("iSCSI Login negotiation failed.\n");
1131 iscsit_collect_login_stats(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
1132 ISCSI_LOGIN_STATUS_INIT_ERR);
1133 if (!zero_tsih || !conn->sess)
1134 goto old_sess_out;
1135 if (conn->sess->se_sess)
1136 transport_free_session(conn->sess->se_sess);
1137 if (conn->sess->session_index != 0) {
1138 spin_lock_bh(&sess_idr_lock);
1139 idr_remove(&sess_idr, conn->sess->session_index);
1140 spin_unlock_bh(&sess_idr_lock);
1141 }
1142 if (conn->sess->sess_ops)
1143 kfree(conn->sess->sess_ops);
1144 if (conn->sess)
1145 kfree(conn->sess);
1146old_sess_out:
1147 iscsi_stop_login_thread_timer(np);
1148 /*
1149 * If login negotiation fails check if the Time2Retain timer
1150 * needs to be restarted.
1151 */
1152 if (!zero_tsih && conn->sess) {
1153 spin_lock_bh(&conn->sess->conn_lock);
1154 if (conn->sess->session_state == TARG_SESS_STATE_FAILED) {
1155 struct se_portal_group *se_tpg =
1156 &ISCSI_TPG_C(conn)->tpg_se_tpg;
1157
1158 atomic_set(&conn->sess->session_continuation, 0);
1159 spin_unlock_bh(&conn->sess->conn_lock);
1160 spin_lock_bh(&se_tpg->session_lock);
1161 iscsit_start_time2retain_handler(conn->sess);
1162 spin_unlock_bh(&se_tpg->session_lock);
1163 } else
1164 spin_unlock_bh(&conn->sess->conn_lock);
1165 iscsit_dec_session_usage_count(conn->sess);
1166 }
1167
1168 if (!IS_ERR(conn->conn_rx_hash.tfm))
1169 crypto_free_hash(conn->conn_rx_hash.tfm);
1170 if (!IS_ERR(conn->conn_tx_hash.tfm))
1171 crypto_free_hash(conn->conn_tx_hash.tfm);
1172
1173 if (conn->conn_cpumask)
1174 free_cpumask_var(conn->conn_cpumask);
1175
1176 kfree(conn->conn_ops);
1177
1178 if (conn->param_list) {
1179 iscsi_release_param_list(conn->param_list);
1180 conn->param_list = NULL;
1181 }
1182 if (conn->sock) {
1183 if (conn->conn_flags & CONNFLAG_SCTP_STRUCT_FILE) {
1184 kfree(conn->sock->file);
1185 conn->sock->file = NULL;
1186 }
1187 sock_release(conn->sock);
1188 }
1189 kfree(conn);
1190
1191 if (tpg) {
1192 iscsit_deaccess_np(np, tpg);
1193 tpg = NULL;
1194 }
1195
1196out:
1197 stop = kthread_should_stop();
1198 if (!stop && signal_pending(current)) {
1199 spin_lock_bh(&np->np_thread_lock);
1200 stop = (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN);
1201 spin_unlock_bh(&np->np_thread_lock);
1202 }
1203 /* Wait for another socket.. */
1204 if (!stop)
1205 return 1;
1206
1207 iscsi_stop_login_thread_timer(np);
1208 spin_lock_bh(&np->np_thread_lock);
1209 np->np_thread_state = ISCSI_NP_THREAD_EXIT;
1210 spin_unlock_bh(&np->np_thread_lock);
1211 return 0;
1212}
1213
1214int iscsi_target_login_thread(void *arg)
1215{
1216 struct iscsi_np *np = (struct iscsi_np *)arg;
1217 int ret;
1218
1219 allow_signal(SIGINT);
1220
1221 while (!kthread_should_stop()) {
1222 ret = __iscsi_target_login_thread(np);
1223 /*
1224 * We break and exit here unless another sock_accept() call
1225 * is expected.
1226 */
1227 if (ret != 1)
1228 break;
1229 }
1230
1231 return 0;
1232}
diff --git a/drivers/target/iscsi/iscsi_target_login.h b/drivers/target/iscsi/iscsi_target_login.h
new file mode 100644
index 000000000000..091dcae2532b
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_login.h
@@ -0,0 +1,12 @@
1#ifndef ISCSI_TARGET_LOGIN_H
2#define ISCSI_TARGET_LOGIN_H
3
4extern int iscsi_login_setup_crypto(struct iscsi_conn *);
5extern int iscsi_check_for_session_reinstatement(struct iscsi_conn *);
6extern int iscsi_login_post_auth_non_zero_tsih(struct iscsi_conn *, u16, u32);
7extern int iscsi_target_setup_login_socket(struct iscsi_np *,
8 struct __kernel_sockaddr_storage *);
9extern int iscsi_target_login_thread(void *);
10extern int iscsi_login_disable_FIM_keys(struct iscsi_param_list *, struct iscsi_conn *);
11
12#endif /*** ISCSI_TARGET_LOGIN_H ***/
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
new file mode 100644
index 000000000000..713a4d23557a
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -0,0 +1,1067 @@
1/*******************************************************************************
2 * This file contains main functions related to iSCSI Parameter negotiation.
3 *
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5 *
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7 *
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.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
21#include <linux/ctype.h>
22#include <scsi/iscsi_proto.h>
23#include <target/target_core_base.h>
24#include <target/target_core_tpg.h>
25
26#include "iscsi_target_core.h"
27#include "iscsi_target_parameters.h"
28#include "iscsi_target_login.h"
29#include "iscsi_target_nego.h"
30#include "iscsi_target_tpg.h"
31#include "iscsi_target_util.h"
32#include "iscsi_target.h"
33#include "iscsi_target_auth.h"
34
35#define MAX_LOGIN_PDUS 7
36#define TEXT_LEN 4096
37
38void convert_null_to_semi(char *buf, int len)
39{
40 int i;
41
42 for (i = 0; i < len; i++)
43 if (buf[i] == '\0')
44 buf[i] = ';';
45}
46
47int strlen_semi(char *buf)
48{
49 int i = 0;
50
51 while (buf[i] != '\0') {
52 if (buf[i] == ';')
53 return i;
54 i++;
55 }
56
57 return -1;
58}
59
60int extract_param(
61 const char *in_buf,
62 const char *pattern,
63 unsigned int max_length,
64 char *out_buf,
65 unsigned char *type)
66{
67 char *ptr;
68 int len;
69
70 if (!in_buf || !pattern || !out_buf || !type)
71 return -1;
72
73 ptr = strstr(in_buf, pattern);
74 if (!ptr)
75 return -1;
76
77 ptr = strstr(ptr, "=");
78 if (!ptr)
79 return -1;
80
81 ptr += 1;
82 if (*ptr == '0' && (*(ptr+1) == 'x' || *(ptr+1) == 'X')) {
83 ptr += 2; /* skip 0x */
84 *type = HEX;
85 } else
86 *type = DECIMAL;
87
88 len = strlen_semi(ptr);
89 if (len < 0)
90 return -1;
91
92 if (len > max_length) {
93 pr_err("Length of input: %d exeeds max_length:"
94 " %d\n", len, max_length);
95 return -1;
96 }
97 memcpy(out_buf, ptr, len);
98 out_buf[len] = '\0';
99
100 return 0;
101}
102
103static u32 iscsi_handle_authentication(
104 struct iscsi_conn *conn,
105 char *in_buf,
106 char *out_buf,
107 int in_length,
108 int *out_length,
109 unsigned char *authtype)
110{
111 struct iscsi_session *sess = conn->sess;
112 struct iscsi_node_auth *auth;
113 struct iscsi_node_acl *iscsi_nacl;
114 struct se_node_acl *se_nacl;
115
116 if (!sess->sess_ops->SessionType) {
117 /*
118 * For SessionType=Normal
119 */
120 se_nacl = conn->sess->se_sess->se_node_acl;
121 if (!se_nacl) {
122 pr_err("Unable to locate struct se_node_acl for"
123 " CHAP auth\n");
124 return -1;
125 }
126 iscsi_nacl = container_of(se_nacl, struct iscsi_node_acl,
127 se_node_acl);
128 if (!iscsi_nacl) {
129 pr_err("Unable to locate struct iscsi_node_acl for"
130 " CHAP auth\n");
131 return -1;
132 }
133
134 auth = ISCSI_NODE_AUTH(iscsi_nacl);
135 } else {
136 /*
137 * For SessionType=Discovery
138 */
139 auth = &iscsit_global->discovery_acl.node_auth;
140 }
141
142 if (strstr("CHAP", authtype))
143 strcpy(conn->sess->auth_type, "CHAP");
144 else
145 strcpy(conn->sess->auth_type, NONE);
146
147 if (strstr("None", authtype))
148 return 1;
149#ifdef CANSRP
150 else if (strstr("SRP", authtype))
151 return srp_main_loop(conn, auth, in_buf, out_buf,
152 &in_length, out_length);
153#endif
154 else if (strstr("CHAP", authtype))
155 return chap_main_loop(conn, auth, in_buf, out_buf,
156 &in_length, out_length);
157 else if (strstr("SPKM1", authtype))
158 return 2;
159 else if (strstr("SPKM2", authtype))
160 return 2;
161 else if (strstr("KRB5", authtype))
162 return 2;
163 else
164 return 2;
165}
166
167static void iscsi_remove_failed_auth_entry(struct iscsi_conn *conn)
168{
169 kfree(conn->auth_protocol);
170}
171
172static int iscsi_target_check_login_request(
173 struct iscsi_conn *conn,
174 struct iscsi_login *login)
175{
176 int req_csg, req_nsg, rsp_csg, rsp_nsg;
177 u32 payload_length;
178 struct iscsi_login_req *login_req;
179 struct iscsi_login_rsp *login_rsp;
180
181 login_req = (struct iscsi_login_req *) login->req;
182 login_rsp = (struct iscsi_login_rsp *) login->rsp;
183 payload_length = ntoh24(login_req->dlength);
184
185 switch (login_req->opcode & ISCSI_OPCODE_MASK) {
186 case ISCSI_OP_LOGIN:
187 break;
188 default:
189 pr_err("Received unknown opcode 0x%02x.\n",
190 login_req->opcode & ISCSI_OPCODE_MASK);
191 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
192 ISCSI_LOGIN_STATUS_INIT_ERR);
193 return -1;
194 }
195
196 if ((login_req->flags & ISCSI_FLAG_LOGIN_CONTINUE) &&
197 (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)) {
198 pr_err("Login request has both ISCSI_FLAG_LOGIN_CONTINUE"
199 " and ISCSI_FLAG_LOGIN_TRANSIT set, protocol error.\n");
200 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
201 ISCSI_LOGIN_STATUS_INIT_ERR);
202 return -1;
203 }
204
205 req_csg = (login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2;
206 rsp_csg = (login_rsp->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2;
207 req_nsg = (login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK);
208 rsp_nsg = (login_rsp->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK);
209
210 if (req_csg != login->current_stage) {
211 pr_err("Initiator unexpectedly changed login stage"
212 " from %d to %d, login failed.\n", login->current_stage,
213 req_csg);
214 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
215 ISCSI_LOGIN_STATUS_INIT_ERR);
216 return -1;
217 }
218
219 if ((req_nsg == 2) || (req_csg >= 2) ||
220 ((login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT) &&
221 (req_nsg <= req_csg))) {
222 pr_err("Illegal login_req->flags Combination, CSG: %d,"
223 " NSG: %d, ISCSI_FLAG_LOGIN_TRANSIT: %d.\n", req_csg,
224 req_nsg, (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT));
225 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
226 ISCSI_LOGIN_STATUS_INIT_ERR);
227 return -1;
228 }
229
230 if ((login_req->max_version != login->version_max) ||
231 (login_req->min_version != login->version_min)) {
232 pr_err("Login request changed Version Max/Nin"
233 " unexpectedly to 0x%02x/0x%02x, protocol error\n",
234 login_req->max_version, login_req->min_version);
235 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
236 ISCSI_LOGIN_STATUS_INIT_ERR);
237 return -1;
238 }
239
240 if (memcmp(login_req->isid, login->isid, 6) != 0) {
241 pr_err("Login request changed ISID unexpectedly,"
242 " protocol error.\n");
243 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
244 ISCSI_LOGIN_STATUS_INIT_ERR);
245 return -1;
246 }
247
248 if (login_req->itt != login->init_task_tag) {
249 pr_err("Login request changed ITT unexpectedly to"
250 " 0x%08x, protocol error.\n", login_req->itt);
251 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
252 ISCSI_LOGIN_STATUS_INIT_ERR);
253 return -1;
254 }
255
256 if (payload_length > MAX_KEY_VALUE_PAIRS) {
257 pr_err("Login request payload exceeds default"
258 " MaxRecvDataSegmentLength: %u, protocol error.\n",
259 MAX_KEY_VALUE_PAIRS);
260 return -1;
261 }
262
263 return 0;
264}
265
266static int iscsi_target_check_first_request(
267 struct iscsi_conn *conn,
268 struct iscsi_login *login)
269{
270 struct iscsi_param *param = NULL;
271 struct se_node_acl *se_nacl;
272
273 login->first_request = 0;
274
275 list_for_each_entry(param, &conn->param_list->param_list, p_list) {
276 if (!strncmp(param->name, SESSIONTYPE, 11)) {
277 if (!IS_PSTATE_ACCEPTOR(param)) {
278 pr_err("SessionType key not received"
279 " in first login request.\n");
280 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
281 ISCSI_LOGIN_STATUS_MISSING_FIELDS);
282 return -1;
283 }
284 if (!strncmp(param->value, DISCOVERY, 9))
285 return 0;
286 }
287
288 if (!strncmp(param->name, INITIATORNAME, 13)) {
289 if (!IS_PSTATE_ACCEPTOR(param)) {
290 if (!login->leading_connection)
291 continue;
292
293 pr_err("InitiatorName key not received"
294 " in first login request.\n");
295 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
296 ISCSI_LOGIN_STATUS_MISSING_FIELDS);
297 return -1;
298 }
299
300 /*
301 * For non-leading connections, double check that the
302 * received InitiatorName matches the existing session's
303 * struct iscsi_node_acl.
304 */
305 if (!login->leading_connection) {
306 se_nacl = conn->sess->se_sess->se_node_acl;
307 if (!se_nacl) {
308 pr_err("Unable to locate"
309 " struct se_node_acl\n");
310 iscsit_tx_login_rsp(conn,
311 ISCSI_STATUS_CLS_INITIATOR_ERR,
312 ISCSI_LOGIN_STATUS_TGT_NOT_FOUND);
313 return -1;
314 }
315
316 if (strcmp(param->value,
317 se_nacl->initiatorname)) {
318 pr_err("Incorrect"
319 " InitiatorName: %s for this"
320 " iSCSI Initiator Node.\n",
321 param->value);
322 iscsit_tx_login_rsp(conn,
323 ISCSI_STATUS_CLS_INITIATOR_ERR,
324 ISCSI_LOGIN_STATUS_TGT_NOT_FOUND);
325 return -1;
326 }
327 }
328 }
329 }
330
331 return 0;
332}
333
334static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_login *login)
335{
336 u32 padding = 0;
337 struct iscsi_session *sess = conn->sess;
338 struct iscsi_login_rsp *login_rsp;
339
340 login_rsp = (struct iscsi_login_rsp *) login->rsp;
341
342 login_rsp->opcode = ISCSI_OP_LOGIN_RSP;
343 hton24(login_rsp->dlength, login->rsp_length);
344 memcpy(login_rsp->isid, login->isid, 6);
345 login_rsp->tsih = cpu_to_be16(login->tsih);
346 login_rsp->itt = cpu_to_be32(login->init_task_tag);
347 login_rsp->statsn = cpu_to_be32(conn->stat_sn++);
348 login_rsp->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
349 login_rsp->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
350
351 pr_debug("Sending Login Response, Flags: 0x%02x, ITT: 0x%08x,"
352 " ExpCmdSN; 0x%08x, MaxCmdSN: 0x%08x, StatSN: 0x%08x, Length:"
353 " %u\n", login_rsp->flags, ntohl(login_rsp->itt),
354 ntohl(login_rsp->exp_cmdsn), ntohl(login_rsp->max_cmdsn),
355 ntohl(login_rsp->statsn), login->rsp_length);
356
357 padding = ((-login->rsp_length) & 3);
358
359 if (iscsi_login_tx_data(
360 conn,
361 login->rsp,
362 login->rsp_buf,
363 login->rsp_length + padding) < 0)
364 return -1;
365
366 login->rsp_length = 0;
367 login_rsp->tsih = be16_to_cpu(login_rsp->tsih);
368 login_rsp->itt = be32_to_cpu(login_rsp->itt);
369 login_rsp->statsn = be32_to_cpu(login_rsp->statsn);
370 mutex_lock(&sess->cmdsn_mutex);
371 login_rsp->exp_cmdsn = be32_to_cpu(sess->exp_cmd_sn);
372 login_rsp->max_cmdsn = be32_to_cpu(sess->max_cmd_sn);
373 mutex_unlock(&sess->cmdsn_mutex);
374
375 return 0;
376}
377
378static int iscsi_target_do_rx_login_io(struct iscsi_conn *conn, struct iscsi_login *login)
379{
380 u32 padding = 0, payload_length;
381 struct iscsi_login_req *login_req;
382
383 if (iscsi_login_rx_data(conn, login->req, ISCSI_HDR_LEN) < 0)
384 return -1;
385
386 login_req = (struct iscsi_login_req *) login->req;
387 payload_length = ntoh24(login_req->dlength);
388 login_req->tsih = be16_to_cpu(login_req->tsih);
389 login_req->itt = be32_to_cpu(login_req->itt);
390 login_req->cid = be16_to_cpu(login_req->cid);
391 login_req->cmdsn = be32_to_cpu(login_req->cmdsn);
392 login_req->exp_statsn = be32_to_cpu(login_req->exp_statsn);
393
394 pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x,"
395 " CmdSN: 0x%08x, ExpStatSN: 0x%08x, CID: %hu, Length: %u\n",
396 login_req->flags, login_req->itt, login_req->cmdsn,
397 login_req->exp_statsn, login_req->cid, payload_length);
398
399 if (iscsi_target_check_login_request(conn, login) < 0)
400 return -1;
401
402 padding = ((-payload_length) & 3);
403 memset(login->req_buf, 0, MAX_KEY_VALUE_PAIRS);
404
405 if (iscsi_login_rx_data(
406 conn,
407 login->req_buf,
408 payload_length + padding) < 0)
409 return -1;
410
411 return 0;
412}
413
414static int iscsi_target_do_login_io(struct iscsi_conn *conn, struct iscsi_login *login)
415{
416 if (iscsi_target_do_tx_login_io(conn, login) < 0)
417 return -1;
418
419 if (iscsi_target_do_rx_login_io(conn, login) < 0)
420 return -1;
421
422 return 0;
423}
424
425static int iscsi_target_get_initial_payload(
426 struct iscsi_conn *conn,
427 struct iscsi_login *login)
428{
429 u32 padding = 0, payload_length;
430 struct iscsi_login_req *login_req;
431
432 login_req = (struct iscsi_login_req *) login->req;
433 payload_length = ntoh24(login_req->dlength);
434
435 pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x,"
436 " CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n",
437 login_req->flags, login_req->itt, login_req->cmdsn,
438 login_req->exp_statsn, payload_length);
439
440 if (iscsi_target_check_login_request(conn, login) < 0)
441 return -1;
442
443 padding = ((-payload_length) & 3);
444
445 if (iscsi_login_rx_data(
446 conn,
447 login->req_buf,
448 payload_length + padding) < 0)
449 return -1;
450
451 return 0;
452}
453
454/*
455 * NOTE: We check for existing sessions or connections AFTER the initiator
456 * has been successfully authenticated in order to protect against faked
457 * ISID/TSIH combinations.
458 */
459static int iscsi_target_check_for_existing_instances(
460 struct iscsi_conn *conn,
461 struct iscsi_login *login)
462{
463 if (login->checked_for_existing)
464 return 0;
465
466 login->checked_for_existing = 1;
467
468 if (!login->tsih)
469 return iscsi_check_for_session_reinstatement(conn);
470 else
471 return iscsi_login_post_auth_non_zero_tsih(conn, login->cid,
472 login->initial_exp_statsn);
473}
474
475static int iscsi_target_do_authentication(
476 struct iscsi_conn *conn,
477 struct iscsi_login *login)
478{
479 int authret;
480 u32 payload_length;
481 struct iscsi_param *param;
482 struct iscsi_login_req *login_req;
483 struct iscsi_login_rsp *login_rsp;
484
485 login_req = (struct iscsi_login_req *) login->req;
486 login_rsp = (struct iscsi_login_rsp *) login->rsp;
487 payload_length = ntoh24(login_req->dlength);
488
489 param = iscsi_find_param_from_key(AUTHMETHOD, conn->param_list);
490 if (!param)
491 return -1;
492
493 authret = iscsi_handle_authentication(
494 conn,
495 login->req_buf,
496 login->rsp_buf,
497 payload_length,
498 &login->rsp_length,
499 param->value);
500 switch (authret) {
501 case 0:
502 pr_debug("Received OK response"
503 " from LIO Authentication, continuing.\n");
504 break;
505 case 1:
506 pr_debug("iSCSI security negotiation"
507 " completed sucessfully.\n");
508 login->auth_complete = 1;
509 if ((login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE1) &&
510 (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)) {
511 login_rsp->flags |= (ISCSI_FLAG_LOGIN_NEXT_STAGE1 |
512 ISCSI_FLAG_LOGIN_TRANSIT);
513 login->current_stage = 1;
514 }
515 return iscsi_target_check_for_existing_instances(
516 conn, login);
517 case 2:
518 pr_err("Security negotiation"
519 " failed.\n");
520 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
521 ISCSI_LOGIN_STATUS_AUTH_FAILED);
522 return -1;
523 default:
524 pr_err("Received unknown error %d from LIO"
525 " Authentication\n", authret);
526 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
527 ISCSI_LOGIN_STATUS_TARGET_ERROR);
528 return -1;
529 }
530
531 return 0;
532}
533
534static int iscsi_target_handle_csg_zero(
535 struct iscsi_conn *conn,
536 struct iscsi_login *login)
537{
538 int ret;
539 u32 payload_length;
540 struct iscsi_param *param;
541 struct iscsi_login_req *login_req;
542 struct iscsi_login_rsp *login_rsp;
543
544 login_req = (struct iscsi_login_req *) login->req;
545 login_rsp = (struct iscsi_login_rsp *) login->rsp;
546 payload_length = ntoh24(login_req->dlength);
547
548 param = iscsi_find_param_from_key(AUTHMETHOD, conn->param_list);
549 if (!param)
550 return -1;
551
552 ret = iscsi_decode_text_input(
553 PHASE_SECURITY|PHASE_DECLARATIVE,
554 SENDER_INITIATOR|SENDER_RECEIVER,
555 login->req_buf,
556 payload_length,
557 conn->param_list);
558 if (ret < 0)
559 return -1;
560
561 if (ret > 0) {
562 if (login->auth_complete) {
563 pr_err("Initiator has already been"
564 " successfully authenticated, but is still"
565 " sending %s keys.\n", param->value);
566 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
567 ISCSI_LOGIN_STATUS_INIT_ERR);
568 return -1;
569 }
570
571 goto do_auth;
572 }
573
574 if (login->first_request)
575 if (iscsi_target_check_first_request(conn, login) < 0)
576 return -1;
577
578 ret = iscsi_encode_text_output(
579 PHASE_SECURITY|PHASE_DECLARATIVE,
580 SENDER_TARGET,
581 login->rsp_buf,
582 &login->rsp_length,
583 conn->param_list);
584 if (ret < 0)
585 return -1;
586
587 if (!iscsi_check_negotiated_keys(conn->param_list)) {
588 if (ISCSI_TPG_ATTRIB(ISCSI_TPG_C(conn))->authentication &&
589 !strncmp(param->value, NONE, 4)) {
590 pr_err("Initiator sent AuthMethod=None but"
591 " Target is enforcing iSCSI Authentication,"
592 " login failed.\n");
593 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
594 ISCSI_LOGIN_STATUS_AUTH_FAILED);
595 return -1;
596 }
597
598 if (ISCSI_TPG_ATTRIB(ISCSI_TPG_C(conn))->authentication &&
599 !login->auth_complete)
600 return 0;
601
602 if (strncmp(param->value, NONE, 4) && !login->auth_complete)
603 return 0;
604
605 if ((login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE1) &&
606 (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT)) {
607 login_rsp->flags |= ISCSI_FLAG_LOGIN_NEXT_STAGE1 |
608 ISCSI_FLAG_LOGIN_TRANSIT;
609 login->current_stage = 1;
610 }
611 }
612
613 return 0;
614do_auth:
615 return iscsi_target_do_authentication(conn, login);
616}
617
618static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_login *login)
619{
620 int ret;
621 u32 payload_length;
622 struct iscsi_login_req *login_req;
623 struct iscsi_login_rsp *login_rsp;
624
625 login_req = (struct iscsi_login_req *) login->req;
626 login_rsp = (struct iscsi_login_rsp *) login->rsp;
627 payload_length = ntoh24(login_req->dlength);
628
629 ret = iscsi_decode_text_input(
630 PHASE_OPERATIONAL|PHASE_DECLARATIVE,
631 SENDER_INITIATOR|SENDER_RECEIVER,
632 login->req_buf,
633 payload_length,
634 conn->param_list);
635 if (ret < 0)
636 return -1;
637
638 if (login->first_request)
639 if (iscsi_target_check_first_request(conn, login) < 0)
640 return -1;
641
642 if (iscsi_target_check_for_existing_instances(conn, login) < 0)
643 return -1;
644
645 ret = iscsi_encode_text_output(
646 PHASE_OPERATIONAL|PHASE_DECLARATIVE,
647 SENDER_TARGET,
648 login->rsp_buf,
649 &login->rsp_length,
650 conn->param_list);
651 if (ret < 0)
652 return -1;
653
654 if (!login->auth_complete &&
655 ISCSI_TPG_ATTRIB(ISCSI_TPG_C(conn))->authentication) {
656 pr_err("Initiator is requesting CSG: 1, has not been"
657 " successfully authenticated, and the Target is"
658 " enforcing iSCSI Authentication, login failed.\n");
659 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
660 ISCSI_LOGIN_STATUS_AUTH_FAILED);
661 return -1;
662 }
663
664 if (!iscsi_check_negotiated_keys(conn->param_list))
665 if ((login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE3) &&
666 (login_req->flags & ISCSI_FLAG_LOGIN_TRANSIT))
667 login_rsp->flags |= ISCSI_FLAG_LOGIN_NEXT_STAGE3 |
668 ISCSI_FLAG_LOGIN_TRANSIT;
669
670 return 0;
671}
672
673static int iscsi_target_do_login(struct iscsi_conn *conn, struct iscsi_login *login)
674{
675 int pdu_count = 0;
676 struct iscsi_login_req *login_req;
677 struct iscsi_login_rsp *login_rsp;
678
679 login_req = (struct iscsi_login_req *) login->req;
680 login_rsp = (struct iscsi_login_rsp *) login->rsp;
681
682 while (1) {
683 if (++pdu_count > MAX_LOGIN_PDUS) {
684 pr_err("MAX_LOGIN_PDUS count reached.\n");
685 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
686 ISCSI_LOGIN_STATUS_TARGET_ERROR);
687 return -1;
688 }
689
690 switch ((login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2) {
691 case 0:
692 login_rsp->flags |= (0 & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK);
693 if (iscsi_target_handle_csg_zero(conn, login) < 0)
694 return -1;
695 break;
696 case 1:
697 login_rsp->flags |= ISCSI_FLAG_LOGIN_CURRENT_STAGE1;
698 if (iscsi_target_handle_csg_one(conn, login) < 0)
699 return -1;
700 if (login_rsp->flags & ISCSI_FLAG_LOGIN_TRANSIT) {
701 login->tsih = conn->sess->tsih;
702 if (iscsi_target_do_tx_login_io(conn,
703 login) < 0)
704 return -1;
705 return 0;
706 }
707 break;
708 default:
709 pr_err("Illegal CSG: %d received from"
710 " Initiator, protocol error.\n",
711 (login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK)
712 >> 2);
713 break;
714 }
715
716 if (iscsi_target_do_login_io(conn, login) < 0)
717 return -1;
718
719 if (login_rsp->flags & ISCSI_FLAG_LOGIN_TRANSIT) {
720 login_rsp->flags &= ~ISCSI_FLAG_LOGIN_TRANSIT;
721 login_rsp->flags &= ~ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK;
722 }
723 }
724
725 return 0;
726}
727
728static void iscsi_initiatorname_tolower(
729 char *param_buf)
730{
731 char *c;
732 u32 iqn_size = strlen(param_buf), i;
733
734 for (i = 0; i < iqn_size; i++) {
735 c = (char *)&param_buf[i];
736 if (!isupper(*c))
737 continue;
738
739 *c = tolower(*c);
740 }
741}
742
743/*
744 * Processes the first Login Request..
745 */
746static int iscsi_target_locate_portal(
747 struct iscsi_np *np,
748 struct iscsi_conn *conn,
749 struct iscsi_login *login)
750{
751 char *i_buf = NULL, *s_buf = NULL, *t_buf = NULL;
752 char *tmpbuf, *start = NULL, *end = NULL, *key, *value;
753 struct iscsi_session *sess = conn->sess;
754 struct iscsi_tiqn *tiqn;
755 struct iscsi_login_req *login_req;
756 struct iscsi_targ_login_rsp *login_rsp;
757 u32 payload_length;
758 int sessiontype = 0, ret = 0;
759
760 login_req = (struct iscsi_login_req *) login->req;
761 login_rsp = (struct iscsi_targ_login_rsp *) login->rsp;
762 payload_length = ntoh24(login_req->dlength);
763
764 login->first_request = 1;
765 login->leading_connection = (!login_req->tsih) ? 1 : 0;
766 login->current_stage =
767 (login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2;
768 login->version_min = login_req->min_version;
769 login->version_max = login_req->max_version;
770 memcpy(login->isid, login_req->isid, 6);
771 login->cmd_sn = login_req->cmdsn;
772 login->init_task_tag = login_req->itt;
773 login->initial_exp_statsn = login_req->exp_statsn;
774 login->cid = login_req->cid;
775 login->tsih = login_req->tsih;
776
777 if (iscsi_target_get_initial_payload(conn, login) < 0)
778 return -1;
779
780 tmpbuf = kzalloc(payload_length + 1, GFP_KERNEL);
781 if (!tmpbuf) {
782 pr_err("Unable to allocate memory for tmpbuf.\n");
783 return -1;
784 }
785
786 memcpy(tmpbuf, login->req_buf, payload_length);
787 tmpbuf[payload_length] = '\0';
788 start = tmpbuf;
789 end = (start + payload_length);
790
791 /*
792 * Locate the initial keys expected from the Initiator node in
793 * the first login request in order to progress with the login phase.
794 */
795 while (start < end) {
796 if (iscsi_extract_key_value(start, &key, &value) < 0) {
797 ret = -1;
798 goto out;
799 }
800
801 if (!strncmp(key, "InitiatorName", 13))
802 i_buf = value;
803 else if (!strncmp(key, "SessionType", 11))
804 s_buf = value;
805 else if (!strncmp(key, "TargetName", 10))
806 t_buf = value;
807
808 start += strlen(key) + strlen(value) + 2;
809 }
810
811 /*
812 * See 5.3. Login Phase.
813 */
814 if (!i_buf) {
815 pr_err("InitiatorName key not received"
816 " in first login request.\n");
817 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
818 ISCSI_LOGIN_STATUS_MISSING_FIELDS);
819 ret = -1;
820 goto out;
821 }
822 /*
823 * Convert the incoming InitiatorName to lowercase following
824 * RFC-3720 3.2.6.1. section c) that says that iSCSI IQNs
825 * are NOT case sensitive.
826 */
827 iscsi_initiatorname_tolower(i_buf);
828
829 if (!s_buf) {
830 if (!login->leading_connection)
831 goto get_target;
832
833 pr_err("SessionType key not received"
834 " in first login request.\n");
835 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
836 ISCSI_LOGIN_STATUS_MISSING_FIELDS);
837 ret = -1;
838 goto out;
839 }
840
841 /*
842 * Use default portal group for discovery sessions.
843 */
844 sessiontype = strncmp(s_buf, DISCOVERY, 9);
845 if (!sessiontype) {
846 conn->tpg = iscsit_global->discovery_tpg;
847 if (!login->leading_connection)
848 goto get_target;
849
850 sess->sess_ops->SessionType = 1;
851 /*
852 * Setup crc32c modules from libcrypto
853 */
854 if (iscsi_login_setup_crypto(conn) < 0) {
855 pr_err("iscsi_login_setup_crypto() failed\n");
856 ret = -1;
857 goto out;
858 }
859 /*
860 * Serialize access across the discovery struct iscsi_portal_group to
861 * process login attempt.
862 */
863 if (iscsit_access_np(np, conn->tpg) < 0) {
864 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
865 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
866 ret = -1;
867 goto out;
868 }
869 ret = 0;
870 goto out;
871 }
872
873get_target:
874 if (!t_buf) {
875 pr_err("TargetName key not received"
876 " in first login request while"
877 " SessionType=Normal.\n");
878 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
879 ISCSI_LOGIN_STATUS_MISSING_FIELDS);
880 ret = -1;
881 goto out;
882 }
883
884 /*
885 * Locate Target IQN from Storage Node.
886 */
887 tiqn = iscsit_get_tiqn_for_login(t_buf);
888 if (!tiqn) {
889 pr_err("Unable to locate Target IQN: %s in"
890 " Storage Node\n", t_buf);
891 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
892 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
893 ret = -1;
894 goto out;
895 }
896 pr_debug("Located Storage Object: %s\n", tiqn->tiqn);
897
898 /*
899 * Locate Target Portal Group from Storage Node.
900 */
901 conn->tpg = iscsit_get_tpg_from_np(tiqn, np);
902 if (!conn->tpg) {
903 pr_err("Unable to locate Target Portal Group"
904 " on %s\n", tiqn->tiqn);
905 iscsit_put_tiqn_for_login(tiqn);
906 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
907 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
908 ret = -1;
909 goto out;
910 }
911 pr_debug("Located Portal Group Object: %hu\n", conn->tpg->tpgt);
912 /*
913 * Setup crc32c modules from libcrypto
914 */
915 if (iscsi_login_setup_crypto(conn) < 0) {
916 pr_err("iscsi_login_setup_crypto() failed\n");
917 ret = -1;
918 goto out;
919 }
920 /*
921 * Serialize access across the struct iscsi_portal_group to
922 * process login attempt.
923 */
924 if (iscsit_access_np(np, conn->tpg) < 0) {
925 iscsit_put_tiqn_for_login(tiqn);
926 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
927 ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
928 ret = -1;
929 conn->tpg = NULL;
930 goto out;
931 }
932
933 /*
934 * conn->sess->node_acl will be set when the referenced
935 * struct iscsi_session is located from received ISID+TSIH in
936 * iscsi_login_non_zero_tsih_s2().
937 */
938 if (!login->leading_connection) {
939 ret = 0;
940 goto out;
941 }
942
943 /*
944 * This value is required in iscsi_login_zero_tsih_s2()
945 */
946 sess->sess_ops->SessionType = 0;
947
948 /*
949 * Locate incoming Initiator IQN reference from Storage Node.
950 */
951 sess->se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
952 &conn->tpg->tpg_se_tpg, i_buf);
953 if (!sess->se_sess->se_node_acl) {
954 pr_err("iSCSI Initiator Node: %s is not authorized to"
955 " access iSCSI target portal group: %hu.\n",
956 i_buf, conn->tpg->tpgt);
957 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
958 ISCSI_LOGIN_STATUS_TGT_FORBIDDEN);
959 ret = -1;
960 goto out;
961 }
962
963 ret = 0;
964out:
965 kfree(tmpbuf);
966 return ret;
967}
968
969struct iscsi_login *iscsi_target_init_negotiation(
970 struct iscsi_np *np,
971 struct iscsi_conn *conn,
972 char *login_pdu)
973{
974 struct iscsi_login *login;
975
976 login = kzalloc(sizeof(struct iscsi_login), GFP_KERNEL);
977 if (!login) {
978 pr_err("Unable to allocate memory for struct iscsi_login.\n");
979 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
980 ISCSI_LOGIN_STATUS_NO_RESOURCES);
981 goto out;
982 }
983
984 login->req = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL);
985 if (!login->req) {
986 pr_err("Unable to allocate memory for Login Request.\n");
987 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
988 ISCSI_LOGIN_STATUS_NO_RESOURCES);
989 goto out;
990 }
991 memcpy(login->req, login_pdu, ISCSI_HDR_LEN);
992
993 login->req_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL);
994 if (!login->req_buf) {
995 pr_err("Unable to allocate memory for response buffer.\n");
996 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
997 ISCSI_LOGIN_STATUS_NO_RESOURCES);
998 goto out;
999 }
1000 /*
1001 * SessionType: Discovery
1002 *
1003 * Locates Default Portal
1004 *
1005 * SessionType: Normal
1006 *
1007 * Locates Target Portal from NP -> Target IQN
1008 */
1009 if (iscsi_target_locate_portal(np, conn, login) < 0) {
1010 pr_err("iSCSI Login negotiation failed.\n");
1011 goto out;
1012 }
1013
1014 return login;
1015out:
1016 kfree(login->req);
1017 kfree(login->req_buf);
1018 kfree(login);
1019
1020 return NULL;
1021}
1022
1023int iscsi_target_start_negotiation(
1024 struct iscsi_login *login,
1025 struct iscsi_conn *conn)
1026{
1027 int ret = -1;
1028
1029 login->rsp = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL);
1030 if (!login->rsp) {
1031 pr_err("Unable to allocate memory for"
1032 " Login Response.\n");
1033 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
1034 ISCSI_LOGIN_STATUS_NO_RESOURCES);
1035 ret = -1;
1036 goto out;
1037 }
1038
1039 login->rsp_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL);
1040 if (!login->rsp_buf) {
1041 pr_err("Unable to allocate memory for"
1042 " request buffer.\n");
1043 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
1044 ISCSI_LOGIN_STATUS_NO_RESOURCES);
1045 ret = -1;
1046 goto out;
1047 }
1048
1049 ret = iscsi_target_do_login(conn, login);
1050out:
1051 if (ret != 0)
1052 iscsi_remove_failed_auth_entry(conn);
1053
1054 iscsi_target_nego_release(login, conn);
1055 return ret;
1056}
1057
1058void iscsi_target_nego_release(
1059 struct iscsi_login *login,
1060 struct iscsi_conn *conn)
1061{
1062 kfree(login->req);
1063 kfree(login->rsp);
1064 kfree(login->req_buf);
1065 kfree(login->rsp_buf);
1066 kfree(login);
1067}
diff --git a/drivers/target/iscsi/iscsi_target_nego.h b/drivers/target/iscsi/iscsi_target_nego.h
new file mode 100644
index 000000000000..92e133a5158f
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_nego.h
@@ -0,0 +1,17 @@
1#ifndef ISCSI_TARGET_NEGO_H
2#define ISCSI_TARGET_NEGO_H
3
4#define DECIMAL 0
5#define HEX 1
6
7extern void convert_null_to_semi(char *, int);
8extern int extract_param(const char *, const char *, unsigned int, char *,
9 unsigned char *);
10extern struct iscsi_login *iscsi_target_init_negotiation(
11 struct iscsi_np *, struct iscsi_conn *, char *);
12extern int iscsi_target_start_negotiation(
13 struct iscsi_login *, struct iscsi_conn *);
14extern void iscsi_target_nego_release(
15 struct iscsi_login *, struct iscsi_conn *);
16
17#endif /* ISCSI_TARGET_NEGO_H */
diff --git a/drivers/target/iscsi/iscsi_target_nodeattrib.c b/drivers/target/iscsi/iscsi_target_nodeattrib.c
new file mode 100644
index 000000000000..aeafbe0cd7d1
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_nodeattrib.c
@@ -0,0 +1,263 @@
1/*******************************************************************************
2 * This file contains the main functions related to Initiator Node Attributes.
3 *
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5 *
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7 *
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.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
21#include <target/target_core_base.h>
22#include <target/target_core_transport.h>
23
24#include "iscsi_target_core.h"
25#include "iscsi_target_device.h"
26#include "iscsi_target_tpg.h"
27#include "iscsi_target_util.h"
28#include "iscsi_target_nodeattrib.h"
29
30static inline char *iscsit_na_get_initiatorname(
31 struct iscsi_node_acl *nacl)
32{
33 struct se_node_acl *se_nacl = &nacl->se_node_acl;
34
35 return &se_nacl->initiatorname[0];
36}
37
38void iscsit_set_default_node_attribues(
39 struct iscsi_node_acl *acl)
40{
41 struct iscsi_node_attrib *a = &acl->node_attrib;
42
43 a->dataout_timeout = NA_DATAOUT_TIMEOUT;
44 a->dataout_timeout_retries = NA_DATAOUT_TIMEOUT_RETRIES;
45 a->nopin_timeout = NA_NOPIN_TIMEOUT;
46 a->nopin_response_timeout = NA_NOPIN_RESPONSE_TIMEOUT;
47 a->random_datain_pdu_offsets = NA_RANDOM_DATAIN_PDU_OFFSETS;
48 a->random_datain_seq_offsets = NA_RANDOM_DATAIN_SEQ_OFFSETS;
49 a->random_r2t_offsets = NA_RANDOM_R2T_OFFSETS;
50 a->default_erl = NA_DEFAULT_ERL;
51}
52
53extern int iscsit_na_dataout_timeout(
54 struct iscsi_node_acl *acl,
55 u32 dataout_timeout)
56{
57 struct iscsi_node_attrib *a = &acl->node_attrib;
58
59 if (dataout_timeout > NA_DATAOUT_TIMEOUT_MAX) {
60 pr_err("Requested DataOut Timeout %u larger than"
61 " maximum %u\n", dataout_timeout,
62 NA_DATAOUT_TIMEOUT_MAX);
63 return -EINVAL;
64 } else if (dataout_timeout < NA_DATAOUT_TIMEOUT_MIX) {
65 pr_err("Requested DataOut Timeout %u smaller than"
66 " minimum %u\n", dataout_timeout,
67 NA_DATAOUT_TIMEOUT_MIX);
68 return -EINVAL;
69 }
70
71 a->dataout_timeout = dataout_timeout;
72 pr_debug("Set DataOut Timeout to %u for Initiator Node"
73 " %s\n", a->dataout_timeout, iscsit_na_get_initiatorname(acl));
74
75 return 0;
76}
77
78extern int iscsit_na_dataout_timeout_retries(
79 struct iscsi_node_acl *acl,
80 u32 dataout_timeout_retries)
81{
82 struct iscsi_node_attrib *a = &acl->node_attrib;
83
84 if (dataout_timeout_retries > NA_DATAOUT_TIMEOUT_RETRIES_MAX) {
85 pr_err("Requested DataOut Timeout Retries %u larger"
86 " than maximum %u", dataout_timeout_retries,
87 NA_DATAOUT_TIMEOUT_RETRIES_MAX);
88 return -EINVAL;
89 } else if (dataout_timeout_retries < NA_DATAOUT_TIMEOUT_RETRIES_MIN) {
90 pr_err("Requested DataOut Timeout Retries %u smaller"
91 " than minimum %u", dataout_timeout_retries,
92 NA_DATAOUT_TIMEOUT_RETRIES_MIN);
93 return -EINVAL;
94 }
95
96 a->dataout_timeout_retries = dataout_timeout_retries;
97 pr_debug("Set DataOut Timeout Retries to %u for"
98 " Initiator Node %s\n", a->dataout_timeout_retries,
99 iscsit_na_get_initiatorname(acl));
100
101 return 0;
102}
103
104extern int iscsit_na_nopin_timeout(
105 struct iscsi_node_acl *acl,
106 u32 nopin_timeout)
107{
108 struct iscsi_node_attrib *a = &acl->node_attrib;
109 struct iscsi_session *sess;
110 struct iscsi_conn *conn;
111 struct se_node_acl *se_nacl = &a->nacl->se_node_acl;
112 struct se_session *se_sess;
113 u32 orig_nopin_timeout = a->nopin_timeout;
114
115 if (nopin_timeout > NA_NOPIN_TIMEOUT_MAX) {
116 pr_err("Requested NopIn Timeout %u larger than maximum"
117 " %u\n", nopin_timeout, NA_NOPIN_TIMEOUT_MAX);
118 return -EINVAL;
119 } else if ((nopin_timeout < NA_NOPIN_TIMEOUT_MIN) &&
120 (nopin_timeout != 0)) {
121 pr_err("Requested NopIn Timeout %u smaller than"
122 " minimum %u and not 0\n", nopin_timeout,
123 NA_NOPIN_TIMEOUT_MIN);
124 return -EINVAL;
125 }
126
127 a->nopin_timeout = nopin_timeout;
128 pr_debug("Set NopIn Timeout to %u for Initiator"
129 " Node %s\n", a->nopin_timeout,
130 iscsit_na_get_initiatorname(acl));
131 /*
132 * Reenable disabled nopin_timeout timer for all iSCSI connections.
133 */
134 if (!orig_nopin_timeout) {
135 spin_lock_bh(&se_nacl->nacl_sess_lock);
136 se_sess = se_nacl->nacl_sess;
137 if (se_sess) {
138 sess = (struct iscsi_session *)se_sess->fabric_sess_ptr;
139
140 spin_lock(&sess->conn_lock);
141 list_for_each_entry(conn, &sess->sess_conn_list,
142 conn_list) {
143 if (conn->conn_state !=
144 TARG_CONN_STATE_LOGGED_IN)
145 continue;
146
147 spin_lock(&conn->nopin_timer_lock);
148 __iscsit_start_nopin_timer(conn);
149 spin_unlock(&conn->nopin_timer_lock);
150 }
151 spin_unlock(&sess->conn_lock);
152 }
153 spin_unlock_bh(&se_nacl->nacl_sess_lock);
154 }
155
156 return 0;
157}
158
159extern int iscsit_na_nopin_response_timeout(
160 struct iscsi_node_acl *acl,
161 u32 nopin_response_timeout)
162{
163 struct iscsi_node_attrib *a = &acl->node_attrib;
164
165 if (nopin_response_timeout > NA_NOPIN_RESPONSE_TIMEOUT_MAX) {
166 pr_err("Requested NopIn Response Timeout %u larger"
167 " than maximum %u\n", nopin_response_timeout,
168 NA_NOPIN_RESPONSE_TIMEOUT_MAX);
169 return -EINVAL;
170 } else if (nopin_response_timeout < NA_NOPIN_RESPONSE_TIMEOUT_MIN) {
171 pr_err("Requested NopIn Response Timeout %u smaller"
172 " than minimum %u\n", nopin_response_timeout,
173 NA_NOPIN_RESPONSE_TIMEOUT_MIN);
174 return -EINVAL;
175 }
176
177 a->nopin_response_timeout = nopin_response_timeout;
178 pr_debug("Set NopIn Response Timeout to %u for"
179 " Initiator Node %s\n", a->nopin_timeout,
180 iscsit_na_get_initiatorname(acl));
181
182 return 0;
183}
184
185extern int iscsit_na_random_datain_pdu_offsets(
186 struct iscsi_node_acl *acl,
187 u32 random_datain_pdu_offsets)
188{
189 struct iscsi_node_attrib *a = &acl->node_attrib;
190
191 if (random_datain_pdu_offsets != 0 && random_datain_pdu_offsets != 1) {
192 pr_err("Requested Random DataIN PDU Offsets: %u not"
193 " 0 or 1\n", random_datain_pdu_offsets);
194 return -EINVAL;
195 }
196
197 a->random_datain_pdu_offsets = random_datain_pdu_offsets;
198 pr_debug("Set Random DataIN PDU Offsets to %u for"
199 " Initiator Node %s\n", a->random_datain_pdu_offsets,
200 iscsit_na_get_initiatorname(acl));
201
202 return 0;
203}
204
205extern int iscsit_na_random_datain_seq_offsets(
206 struct iscsi_node_acl *acl,
207 u32 random_datain_seq_offsets)
208{
209 struct iscsi_node_attrib *a = &acl->node_attrib;
210
211 if (random_datain_seq_offsets != 0 && random_datain_seq_offsets != 1) {
212 pr_err("Requested Random DataIN Sequence Offsets: %u"
213 " not 0 or 1\n", random_datain_seq_offsets);
214 return -EINVAL;
215 }
216
217 a->random_datain_seq_offsets = random_datain_seq_offsets;
218 pr_debug("Set Random DataIN Sequence Offsets to %u for"
219 " Initiator Node %s\n", a->random_datain_seq_offsets,
220 iscsit_na_get_initiatorname(acl));
221
222 return 0;
223}
224
225extern int iscsit_na_random_r2t_offsets(
226 struct iscsi_node_acl *acl,
227 u32 random_r2t_offsets)
228{
229 struct iscsi_node_attrib *a = &acl->node_attrib;
230
231 if (random_r2t_offsets != 0 && random_r2t_offsets != 1) {
232 pr_err("Requested Random R2T Offsets: %u not"
233 " 0 or 1\n", random_r2t_offsets);
234 return -EINVAL;
235 }
236
237 a->random_r2t_offsets = random_r2t_offsets;
238 pr_debug("Set Random R2T Offsets to %u for"
239 " Initiator Node %s\n", a->random_r2t_offsets,
240 iscsit_na_get_initiatorname(acl));
241
242 return 0;
243}
244
245extern int iscsit_na_default_erl(
246 struct iscsi_node_acl *acl,
247 u32 default_erl)
248{
249 struct iscsi_node_attrib *a = &acl->node_attrib;
250
251 if (default_erl != 0 && default_erl != 1 && default_erl != 2) {
252 pr_err("Requested default ERL: %u not 0, 1, or 2\n",
253 default_erl);
254 return -EINVAL;
255 }
256
257 a->default_erl = default_erl;
258 pr_debug("Set use ERL0 flag to %u for Initiator"
259 " Node %s\n", a->default_erl,
260 iscsit_na_get_initiatorname(acl));
261
262 return 0;
263}
diff --git a/drivers/target/iscsi/iscsi_target_nodeattrib.h b/drivers/target/iscsi/iscsi_target_nodeattrib.h
new file mode 100644
index 000000000000..c970b326ef23
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_nodeattrib.h
@@ -0,0 +1,14 @@
1#ifndef ISCSI_TARGET_NODEATTRIB_H
2#define ISCSI_TARGET_NODEATTRIB_H
3
4extern void iscsit_set_default_node_attribues(struct iscsi_node_acl *);
5extern int iscsit_na_dataout_timeout(struct iscsi_node_acl *, u32);
6extern int iscsit_na_dataout_timeout_retries(struct iscsi_node_acl *, u32);
7extern int iscsit_na_nopin_timeout(struct iscsi_node_acl *, u32);
8extern int iscsit_na_nopin_response_timeout(struct iscsi_node_acl *, u32);
9extern int iscsit_na_random_datain_pdu_offsets(struct iscsi_node_acl *, u32);
10extern int iscsit_na_random_datain_seq_offsets(struct iscsi_node_acl *, u32);
11extern int iscsit_na_random_r2t_offsets(struct iscsi_node_acl *, u32);
12extern int iscsit_na_default_erl(struct iscsi_node_acl *, u32);
13
14#endif /* ISCSI_TARGET_NODEATTRIB_H */
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c
new file mode 100644
index 000000000000..252e246cf51e
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_parameters.c
@@ -0,0 +1,1905 @@
1/*******************************************************************************
2 * This file contains main functions related to iSCSI Parameter negotiation.
3 *
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5 *
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7 *
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.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
21#include <linux/slab.h>
22
23#include "iscsi_target_core.h"
24#include "iscsi_target_util.h"
25#include "iscsi_target_parameters.h"
26
27int iscsi_login_rx_data(
28 struct iscsi_conn *conn,
29 char *buf,
30 int length)
31{
32 int rx_got;
33 struct kvec iov;
34
35 memset(&iov, 0, sizeof(struct kvec));
36 iov.iov_len = length;
37 iov.iov_base = buf;
38
39 /*
40 * Initial Marker-less Interval.
41 * Add the values regardless of IFMarker/OFMarker, considering
42 * it may not be negoitated yet.
43 */
44 conn->of_marker += length;
45
46 rx_got = rx_data(conn, &iov, 1, length);
47 if (rx_got != length) {
48 pr_err("rx_data returned %d, expecting %d.\n",
49 rx_got, length);
50 return -1;
51 }
52
53 return 0 ;
54}
55
56int iscsi_login_tx_data(
57 struct iscsi_conn *conn,
58 char *pdu_buf,
59 char *text_buf,
60 int text_length)
61{
62 int length, tx_sent;
63 struct kvec iov[2];
64
65 length = (ISCSI_HDR_LEN + text_length);
66
67 memset(&iov[0], 0, 2 * sizeof(struct kvec));
68 iov[0].iov_len = ISCSI_HDR_LEN;
69 iov[0].iov_base = pdu_buf;
70 iov[1].iov_len = text_length;
71 iov[1].iov_base = text_buf;
72
73 /*
74 * Initial Marker-less Interval.
75 * Add the values regardless of IFMarker/OFMarker, considering
76 * it may not be negoitated yet.
77 */
78 conn->if_marker += length;
79
80 tx_sent = tx_data(conn, &iov[0], 2, length);
81 if (tx_sent != length) {
82 pr_err("tx_data returned %d, expecting %d.\n",
83 tx_sent, length);
84 return -1;
85 }
86
87 return 0;
88}
89
90void iscsi_dump_conn_ops(struct iscsi_conn_ops *conn_ops)
91{
92 pr_debug("HeaderDigest: %s\n", (conn_ops->HeaderDigest) ?
93 "CRC32C" : "None");
94 pr_debug("DataDigest: %s\n", (conn_ops->DataDigest) ?
95 "CRC32C" : "None");
96 pr_debug("MaxRecvDataSegmentLength: %u\n",
97 conn_ops->MaxRecvDataSegmentLength);
98 pr_debug("OFMarker: %s\n", (conn_ops->OFMarker) ? "Yes" : "No");
99 pr_debug("IFMarker: %s\n", (conn_ops->IFMarker) ? "Yes" : "No");
100 if (conn_ops->OFMarker)
101 pr_debug("OFMarkInt: %u\n", conn_ops->OFMarkInt);
102 if (conn_ops->IFMarker)
103 pr_debug("IFMarkInt: %u\n", conn_ops->IFMarkInt);
104}
105
106void iscsi_dump_sess_ops(struct iscsi_sess_ops *sess_ops)
107{
108 pr_debug("InitiatorName: %s\n", sess_ops->InitiatorName);
109 pr_debug("InitiatorAlias: %s\n", sess_ops->InitiatorAlias);
110 pr_debug("TargetName: %s\n", sess_ops->TargetName);
111 pr_debug("TargetAlias: %s\n", sess_ops->TargetAlias);
112 pr_debug("TargetPortalGroupTag: %hu\n",
113 sess_ops->TargetPortalGroupTag);
114 pr_debug("MaxConnections: %hu\n", sess_ops->MaxConnections);
115 pr_debug("InitialR2T: %s\n",
116 (sess_ops->InitialR2T) ? "Yes" : "No");
117 pr_debug("ImmediateData: %s\n", (sess_ops->ImmediateData) ?
118 "Yes" : "No");
119 pr_debug("MaxBurstLength: %u\n", sess_ops->MaxBurstLength);
120 pr_debug("FirstBurstLength: %u\n", sess_ops->FirstBurstLength);
121 pr_debug("DefaultTime2Wait: %hu\n", sess_ops->DefaultTime2Wait);
122 pr_debug("DefaultTime2Retain: %hu\n",
123 sess_ops->DefaultTime2Retain);
124 pr_debug("MaxOutstandingR2T: %hu\n",
125 sess_ops->MaxOutstandingR2T);
126 pr_debug("DataPDUInOrder: %s\n",
127 (sess_ops->DataPDUInOrder) ? "Yes" : "No");
128 pr_debug("DataSequenceInOrder: %s\n",
129 (sess_ops->DataSequenceInOrder) ? "Yes" : "No");
130 pr_debug("ErrorRecoveryLevel: %hu\n",
131 sess_ops->ErrorRecoveryLevel);
132 pr_debug("SessionType: %s\n", (sess_ops->SessionType) ?
133 "Discovery" : "Normal");
134}
135
136void iscsi_print_params(struct iscsi_param_list *param_list)
137{
138 struct iscsi_param *param;
139
140 list_for_each_entry(param, &param_list->param_list, p_list)
141 pr_debug("%s: %s\n", param->name, param->value);
142}
143
144static struct iscsi_param *iscsi_set_default_param(struct iscsi_param_list *param_list,
145 char *name, char *value, u8 phase, u8 scope, u8 sender,
146 u16 type_range, u8 use)
147{
148 struct iscsi_param *param = NULL;
149
150 param = kzalloc(sizeof(struct iscsi_param), GFP_KERNEL);
151 if (!param) {
152 pr_err("Unable to allocate memory for parameter.\n");
153 goto out;
154 }
155 INIT_LIST_HEAD(&param->p_list);
156
157 param->name = kzalloc(strlen(name) + 1, GFP_KERNEL);
158 if (!param->name) {
159 pr_err("Unable to allocate memory for parameter name.\n");
160 goto out;
161 }
162
163 param->value = kzalloc(strlen(value) + 1, GFP_KERNEL);
164 if (!param->value) {
165 pr_err("Unable to allocate memory for parameter value.\n");
166 goto out;
167 }
168
169 memcpy(param->name, name, strlen(name));
170 param->name[strlen(name)] = '\0';
171 memcpy(param->value, value, strlen(value));
172 param->value[strlen(value)] = '\0';
173 param->phase = phase;
174 param->scope = scope;
175 param->sender = sender;
176 param->use = use;
177 param->type_range = type_range;
178
179 switch (param->type_range) {
180 case TYPERANGE_BOOL_AND:
181 param->type = TYPE_BOOL_AND;
182 break;
183 case TYPERANGE_BOOL_OR:
184 param->type = TYPE_BOOL_OR;
185 break;
186 case TYPERANGE_0_TO_2:
187 case TYPERANGE_0_TO_3600:
188 case TYPERANGE_0_TO_32767:
189 case TYPERANGE_0_TO_65535:
190 case TYPERANGE_1_TO_65535:
191 case TYPERANGE_2_TO_3600:
192 case TYPERANGE_512_TO_16777215:
193 param->type = TYPE_NUMBER;
194 break;
195 case TYPERANGE_AUTH:
196 case TYPERANGE_DIGEST:
197 param->type = TYPE_VALUE_LIST | TYPE_STRING;
198 break;
199 case TYPERANGE_MARKINT:
200 param->type = TYPE_NUMBER_RANGE;
201 param->type_range |= TYPERANGE_1_TO_65535;
202 break;
203 case TYPERANGE_ISCSINAME:
204 case TYPERANGE_SESSIONTYPE:
205 case TYPERANGE_TARGETADDRESS:
206 case TYPERANGE_UTF8:
207 param->type = TYPE_STRING;
208 break;
209 default:
210 pr_err("Unknown type_range 0x%02x\n",
211 param->type_range);
212 goto out;
213 }
214 list_add_tail(&param->p_list, &param_list->param_list);
215
216 return param;
217out:
218 if (param) {
219 kfree(param->value);
220 kfree(param->name);
221 kfree(param);
222 }
223
224 return NULL;
225}
226
227/* #warning Add extension keys */
228int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr)
229{
230 struct iscsi_param *param = NULL;
231 struct iscsi_param_list *pl;
232
233 pl = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL);
234 if (!pl) {
235 pr_err("Unable to allocate memory for"
236 " struct iscsi_param_list.\n");
237 return -1 ;
238 }
239 INIT_LIST_HEAD(&pl->param_list);
240 INIT_LIST_HEAD(&pl->extra_response_list);
241
242 /*
243 * The format for setting the initial parameter definitions are:
244 *
245 * Parameter name:
246 * Initial value:
247 * Allowable phase:
248 * Scope:
249 * Allowable senders:
250 * Typerange:
251 * Use:
252 */
253 param = iscsi_set_default_param(pl, AUTHMETHOD, INITIAL_AUTHMETHOD,
254 PHASE_SECURITY, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
255 TYPERANGE_AUTH, USE_INITIAL_ONLY);
256 if (!param)
257 goto out;
258
259 param = iscsi_set_default_param(pl, HEADERDIGEST, INITIAL_HEADERDIGEST,
260 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
261 TYPERANGE_DIGEST, USE_INITIAL_ONLY);
262 if (!param)
263 goto out;
264
265 param = iscsi_set_default_param(pl, DATADIGEST, INITIAL_DATADIGEST,
266 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
267 TYPERANGE_DIGEST, USE_INITIAL_ONLY);
268 if (!param)
269 goto out;
270
271 param = iscsi_set_default_param(pl, MAXCONNECTIONS,
272 INITIAL_MAXCONNECTIONS, PHASE_OPERATIONAL,
273 SCOPE_SESSION_WIDE, SENDER_BOTH,
274 TYPERANGE_1_TO_65535, USE_LEADING_ONLY);
275 if (!param)
276 goto out;
277
278 param = iscsi_set_default_param(pl, SENDTARGETS, INITIAL_SENDTARGETS,
279 PHASE_FFP0, SCOPE_SESSION_WIDE, SENDER_INITIATOR,
280 TYPERANGE_UTF8, 0);
281 if (!param)
282 goto out;
283
284 param = iscsi_set_default_param(pl, TARGETNAME, INITIAL_TARGETNAME,
285 PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_BOTH,
286 TYPERANGE_ISCSINAME, USE_ALL);
287 if (!param)
288 goto out;
289
290 param = iscsi_set_default_param(pl, INITIATORNAME,
291 INITIAL_INITIATORNAME, PHASE_DECLARATIVE,
292 SCOPE_SESSION_WIDE, SENDER_INITIATOR,
293 TYPERANGE_ISCSINAME, USE_INITIAL_ONLY);
294 if (!param)
295 goto out;
296
297 param = iscsi_set_default_param(pl, TARGETALIAS, INITIAL_TARGETALIAS,
298 PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_TARGET,
299 TYPERANGE_UTF8, USE_ALL);
300 if (!param)
301 goto out;
302
303 param = iscsi_set_default_param(pl, INITIATORALIAS,
304 INITIAL_INITIATORALIAS, PHASE_DECLARATIVE,
305 SCOPE_SESSION_WIDE, SENDER_INITIATOR, TYPERANGE_UTF8,
306 USE_ALL);
307 if (!param)
308 goto out;
309
310 param = iscsi_set_default_param(pl, TARGETADDRESS,
311 INITIAL_TARGETADDRESS, PHASE_DECLARATIVE,
312 SCOPE_SESSION_WIDE, SENDER_TARGET,
313 TYPERANGE_TARGETADDRESS, USE_ALL);
314 if (!param)
315 goto out;
316
317 param = iscsi_set_default_param(pl, TARGETPORTALGROUPTAG,
318 INITIAL_TARGETPORTALGROUPTAG,
319 PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_TARGET,
320 TYPERANGE_0_TO_65535, USE_INITIAL_ONLY);
321 if (!param)
322 goto out;
323
324 param = iscsi_set_default_param(pl, INITIALR2T, INITIAL_INITIALR2T,
325 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
326 TYPERANGE_BOOL_OR, USE_LEADING_ONLY);
327 if (!param)
328 goto out;
329
330 param = iscsi_set_default_param(pl, IMMEDIATEDATA,
331 INITIAL_IMMEDIATEDATA, PHASE_OPERATIONAL,
332 SCOPE_SESSION_WIDE, SENDER_BOTH, TYPERANGE_BOOL_AND,
333 USE_LEADING_ONLY);
334 if (!param)
335 goto out;
336
337 param = iscsi_set_default_param(pl, MAXRECVDATASEGMENTLENGTH,
338 INITIAL_MAXRECVDATASEGMENTLENGTH,
339 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
340 TYPERANGE_512_TO_16777215, USE_ALL);
341 if (!param)
342 goto out;
343
344 param = iscsi_set_default_param(pl, MAXBURSTLENGTH,
345 INITIAL_MAXBURSTLENGTH, PHASE_OPERATIONAL,
346 SCOPE_SESSION_WIDE, SENDER_BOTH,
347 TYPERANGE_512_TO_16777215, USE_LEADING_ONLY);
348 if (!param)
349 goto out;
350
351 param = iscsi_set_default_param(pl, FIRSTBURSTLENGTH,
352 INITIAL_FIRSTBURSTLENGTH,
353 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
354 TYPERANGE_512_TO_16777215, USE_LEADING_ONLY);
355 if (!param)
356 goto out;
357
358 param = iscsi_set_default_param(pl, DEFAULTTIME2WAIT,
359 INITIAL_DEFAULTTIME2WAIT,
360 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
361 TYPERANGE_0_TO_3600, USE_LEADING_ONLY);
362 if (!param)
363 goto out;
364
365 param = iscsi_set_default_param(pl, DEFAULTTIME2RETAIN,
366 INITIAL_DEFAULTTIME2RETAIN,
367 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
368 TYPERANGE_0_TO_3600, USE_LEADING_ONLY);
369 if (!param)
370 goto out;
371
372 param = iscsi_set_default_param(pl, MAXOUTSTANDINGR2T,
373 INITIAL_MAXOUTSTANDINGR2T,
374 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
375 TYPERANGE_1_TO_65535, USE_LEADING_ONLY);
376 if (!param)
377 goto out;
378
379 param = iscsi_set_default_param(pl, DATAPDUINORDER,
380 INITIAL_DATAPDUINORDER, PHASE_OPERATIONAL,
381 SCOPE_SESSION_WIDE, SENDER_BOTH, TYPERANGE_BOOL_OR,
382 USE_LEADING_ONLY);
383 if (!param)
384 goto out;
385
386 param = iscsi_set_default_param(pl, DATASEQUENCEINORDER,
387 INITIAL_DATASEQUENCEINORDER,
388 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
389 TYPERANGE_BOOL_OR, USE_LEADING_ONLY);
390 if (!param)
391 goto out;
392
393 param = iscsi_set_default_param(pl, ERRORRECOVERYLEVEL,
394 INITIAL_ERRORRECOVERYLEVEL,
395 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
396 TYPERANGE_0_TO_2, USE_LEADING_ONLY);
397 if (!param)
398 goto out;
399
400 param = iscsi_set_default_param(pl, SESSIONTYPE, INITIAL_SESSIONTYPE,
401 PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_INITIATOR,
402 TYPERANGE_SESSIONTYPE, USE_LEADING_ONLY);
403 if (!param)
404 goto out;
405
406 param = iscsi_set_default_param(pl, IFMARKER, INITIAL_IFMARKER,
407 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
408 TYPERANGE_BOOL_AND, USE_INITIAL_ONLY);
409 if (!param)
410 goto out;
411
412 param = iscsi_set_default_param(pl, OFMARKER, INITIAL_OFMARKER,
413 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
414 TYPERANGE_BOOL_AND, USE_INITIAL_ONLY);
415 if (!param)
416 goto out;
417
418 param = iscsi_set_default_param(pl, IFMARKINT, INITIAL_IFMARKINT,
419 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
420 TYPERANGE_MARKINT, USE_INITIAL_ONLY);
421 if (!param)
422 goto out;
423
424 param = iscsi_set_default_param(pl, OFMARKINT, INITIAL_OFMARKINT,
425 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
426 TYPERANGE_MARKINT, USE_INITIAL_ONLY);
427 if (!param)
428 goto out;
429
430 *param_list_ptr = pl;
431 return 0;
432out:
433 iscsi_release_param_list(pl);
434 return -1;
435}
436
437int iscsi_set_keys_to_negotiate(
438 int sessiontype,
439 struct iscsi_param_list *param_list)
440{
441 struct iscsi_param *param;
442
443 list_for_each_entry(param, &param_list->param_list, p_list) {
444 param->state = 0;
445 if (!strcmp(param->name, AUTHMETHOD)) {
446 SET_PSTATE_NEGOTIATE(param);
447 } else if (!strcmp(param->name, HEADERDIGEST)) {
448 SET_PSTATE_NEGOTIATE(param);
449 } else if (!strcmp(param->name, DATADIGEST)) {
450 SET_PSTATE_NEGOTIATE(param);
451 } else if (!strcmp(param->name, MAXCONNECTIONS)) {
452 SET_PSTATE_NEGOTIATE(param);
453 } else if (!strcmp(param->name, TARGETNAME)) {
454 continue;
455 } else if (!strcmp(param->name, INITIATORNAME)) {
456 continue;
457 } else if (!strcmp(param->name, TARGETALIAS)) {
458 if (param->value)
459 SET_PSTATE_NEGOTIATE(param);
460 } else if (!strcmp(param->name, INITIATORALIAS)) {
461 continue;
462 } else if (!strcmp(param->name, TARGETPORTALGROUPTAG)) {
463 SET_PSTATE_NEGOTIATE(param);
464 } else if (!strcmp(param->name, INITIALR2T)) {
465 SET_PSTATE_NEGOTIATE(param);
466 } else if (!strcmp(param->name, IMMEDIATEDATA)) {
467 SET_PSTATE_NEGOTIATE(param);
468 } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
469 SET_PSTATE_NEGOTIATE(param);
470 } else if (!strcmp(param->name, MAXBURSTLENGTH)) {
471 SET_PSTATE_NEGOTIATE(param);
472 } else if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
473 SET_PSTATE_NEGOTIATE(param);
474 } else if (!strcmp(param->name, DEFAULTTIME2WAIT)) {
475 SET_PSTATE_NEGOTIATE(param);
476 } else if (!strcmp(param->name, DEFAULTTIME2RETAIN)) {
477 SET_PSTATE_NEGOTIATE(param);
478 } else if (!strcmp(param->name, MAXOUTSTANDINGR2T)) {
479 SET_PSTATE_NEGOTIATE(param);
480 } else if (!strcmp(param->name, DATAPDUINORDER)) {
481 SET_PSTATE_NEGOTIATE(param);
482 } else if (!strcmp(param->name, DATASEQUENCEINORDER)) {
483 SET_PSTATE_NEGOTIATE(param);
484 } else if (!strcmp(param->name, ERRORRECOVERYLEVEL)) {
485 SET_PSTATE_NEGOTIATE(param);
486 } else if (!strcmp(param->name, SESSIONTYPE)) {
487 SET_PSTATE_NEGOTIATE(param);
488 } else if (!strcmp(param->name, IFMARKER)) {
489 SET_PSTATE_NEGOTIATE(param);
490 } else if (!strcmp(param->name, OFMARKER)) {
491 SET_PSTATE_NEGOTIATE(param);
492 } else if (!strcmp(param->name, IFMARKINT)) {
493 SET_PSTATE_NEGOTIATE(param);
494 } else if (!strcmp(param->name, OFMARKINT)) {
495 SET_PSTATE_NEGOTIATE(param);
496 }
497 }
498
499 return 0;
500}
501
502int iscsi_set_keys_irrelevant_for_discovery(
503 struct iscsi_param_list *param_list)
504{
505 struct iscsi_param *param;
506
507 list_for_each_entry(param, &param_list->param_list, p_list) {
508 if (!strcmp(param->name, MAXCONNECTIONS))
509 param->state &= ~PSTATE_NEGOTIATE;
510 else if (!strcmp(param->name, INITIALR2T))
511 param->state &= ~PSTATE_NEGOTIATE;
512 else if (!strcmp(param->name, IMMEDIATEDATA))
513 param->state &= ~PSTATE_NEGOTIATE;
514 else if (!strcmp(param->name, MAXBURSTLENGTH))
515 param->state &= ~PSTATE_NEGOTIATE;
516 else if (!strcmp(param->name, FIRSTBURSTLENGTH))
517 param->state &= ~PSTATE_NEGOTIATE;
518 else if (!strcmp(param->name, MAXOUTSTANDINGR2T))
519 param->state &= ~PSTATE_NEGOTIATE;
520 else if (!strcmp(param->name, DATAPDUINORDER))
521 param->state &= ~PSTATE_NEGOTIATE;
522 else if (!strcmp(param->name, DATASEQUENCEINORDER))
523 param->state &= ~PSTATE_NEGOTIATE;
524 else if (!strcmp(param->name, ERRORRECOVERYLEVEL))
525 param->state &= ~PSTATE_NEGOTIATE;
526 else if (!strcmp(param->name, DEFAULTTIME2WAIT))
527 param->state &= ~PSTATE_NEGOTIATE;
528 else if (!strcmp(param->name, DEFAULTTIME2RETAIN))
529 param->state &= ~PSTATE_NEGOTIATE;
530 else if (!strcmp(param->name, IFMARKER))
531 param->state &= ~PSTATE_NEGOTIATE;
532 else if (!strcmp(param->name, OFMARKER))
533 param->state &= ~PSTATE_NEGOTIATE;
534 else if (!strcmp(param->name, IFMARKINT))
535 param->state &= ~PSTATE_NEGOTIATE;
536 else if (!strcmp(param->name, OFMARKINT))
537 param->state &= ~PSTATE_NEGOTIATE;
538 }
539
540 return 0;
541}
542
543int iscsi_copy_param_list(
544 struct iscsi_param_list **dst_param_list,
545 struct iscsi_param_list *src_param_list,
546 int leading)
547{
548 struct iscsi_param *new_param = NULL, *param = NULL;
549 struct iscsi_param_list *param_list = NULL;
550
551 param_list = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL);
552 if (!param_list) {
553 pr_err("Unable to allocate memory for"
554 " struct iscsi_param_list.\n");
555 goto err_out;
556 }
557 INIT_LIST_HEAD(&param_list->param_list);
558 INIT_LIST_HEAD(&param_list->extra_response_list);
559
560 list_for_each_entry(param, &src_param_list->param_list, p_list) {
561 if (!leading && (param->scope & SCOPE_SESSION_WIDE)) {
562 if ((strcmp(param->name, "TargetName") != 0) &&
563 (strcmp(param->name, "InitiatorName") != 0) &&
564 (strcmp(param->name, "TargetPortalGroupTag") != 0))
565 continue;
566 }
567
568 new_param = kzalloc(sizeof(struct iscsi_param), GFP_KERNEL);
569 if (!new_param) {
570 pr_err("Unable to allocate memory for"
571 " struct iscsi_param.\n");
572 goto err_out;
573 }
574
575 new_param->set_param = param->set_param;
576 new_param->phase = param->phase;
577 new_param->scope = param->scope;
578 new_param->sender = param->sender;
579 new_param->type = param->type;
580 new_param->use = param->use;
581 new_param->type_range = param->type_range;
582
583 new_param->name = kzalloc(strlen(param->name) + 1, GFP_KERNEL);
584 if (!new_param->name) {
585 pr_err("Unable to allocate memory for"
586 " parameter name.\n");
587 goto err_out;
588 }
589
590 new_param->value = kzalloc(strlen(param->value) + 1,
591 GFP_KERNEL);
592 if (!new_param->value) {
593 pr_err("Unable to allocate memory for"
594 " parameter value.\n");
595 goto err_out;
596 }
597
598 memcpy(new_param->name, param->name, strlen(param->name));
599 new_param->name[strlen(param->name)] = '\0';
600 memcpy(new_param->value, param->value, strlen(param->value));
601 new_param->value[strlen(param->value)] = '\0';
602
603 list_add_tail(&new_param->p_list, &param_list->param_list);
604 }
605
606 if (!list_empty(&param_list->param_list))
607 *dst_param_list = param_list;
608 else {
609 pr_err("No parameters allocated.\n");
610 goto err_out;
611 }
612
613 return 0;
614
615err_out:
616 iscsi_release_param_list(param_list);
617 return -1;
618}
619
620static void iscsi_release_extra_responses(struct iscsi_param_list *param_list)
621{
622 struct iscsi_extra_response *er, *er_tmp;
623
624 list_for_each_entry_safe(er, er_tmp, &param_list->extra_response_list,
625 er_list) {
626 list_del(&er->er_list);
627 kfree(er);
628 }
629}
630
631void iscsi_release_param_list(struct iscsi_param_list *param_list)
632{
633 struct iscsi_param *param, *param_tmp;
634
635 list_for_each_entry_safe(param, param_tmp, &param_list->param_list,
636 p_list) {
637 list_del(&param->p_list);
638
639 kfree(param->name);
640 param->name = NULL;
641 kfree(param->value);
642 param->value = NULL;
643 kfree(param);
644 param = NULL;
645 }
646
647 iscsi_release_extra_responses(param_list);
648
649 kfree(param_list);
650}
651
652struct iscsi_param *iscsi_find_param_from_key(
653 char *key,
654 struct iscsi_param_list *param_list)
655{
656 struct iscsi_param *param;
657
658 if (!key || !param_list) {
659 pr_err("Key or parameter list pointer is NULL.\n");
660 return NULL;
661 }
662
663 list_for_each_entry(param, &param_list->param_list, p_list) {
664 if (!strcmp(key, param->name))
665 return param;
666 }
667
668 pr_err("Unable to locate key \"%s\".\n", key);
669 return NULL;
670}
671
672int iscsi_extract_key_value(char *textbuf, char **key, char **value)
673{
674 *value = strchr(textbuf, '=');
675 if (!*value) {
676 pr_err("Unable to locate \"=\" seperator for key,"
677 " ignoring request.\n");
678 return -1;
679 }
680
681 *key = textbuf;
682 **value = '\0';
683 *value = *value + 1;
684
685 return 0;
686}
687
688int iscsi_update_param_value(struct iscsi_param *param, char *value)
689{
690 kfree(param->value);
691
692 param->value = kzalloc(strlen(value) + 1, GFP_KERNEL);
693 if (!param->value) {
694 pr_err("Unable to allocate memory for value.\n");
695 return -1;
696 }
697
698 memcpy(param->value, value, strlen(value));
699 param->value[strlen(value)] = '\0';
700
701 pr_debug("iSCSI Parameter updated to %s=%s\n",
702 param->name, param->value);
703 return 0;
704}
705
706static int iscsi_add_notunderstood_response(
707 char *key,
708 char *value,
709 struct iscsi_param_list *param_list)
710{
711 struct iscsi_extra_response *extra_response;
712
713 if (strlen(value) > VALUE_MAXLEN) {
714 pr_err("Value for notunderstood key \"%s\" exceeds %d,"
715 " protocol error.\n", key, VALUE_MAXLEN);
716 return -1;
717 }
718
719 extra_response = kzalloc(sizeof(struct iscsi_extra_response), GFP_KERNEL);
720 if (!extra_response) {
721 pr_err("Unable to allocate memory for"
722 " struct iscsi_extra_response.\n");
723 return -1;
724 }
725 INIT_LIST_HEAD(&extra_response->er_list);
726
727 strncpy(extra_response->key, key, strlen(key) + 1);
728 strncpy(extra_response->value, NOTUNDERSTOOD,
729 strlen(NOTUNDERSTOOD) + 1);
730
731 list_add_tail(&extra_response->er_list,
732 &param_list->extra_response_list);
733 return 0;
734}
735
736static int iscsi_check_for_auth_key(char *key)
737{
738 /*
739 * RFC 1994
740 */
741 if (!strcmp(key, "CHAP_A") || !strcmp(key, "CHAP_I") ||
742 !strcmp(key, "CHAP_C") || !strcmp(key, "CHAP_N") ||
743 !strcmp(key, "CHAP_R"))
744 return 1;
745
746 /*
747 * RFC 2945
748 */
749 if (!strcmp(key, "SRP_U") || !strcmp(key, "SRP_N") ||
750 !strcmp(key, "SRP_g") || !strcmp(key, "SRP_s") ||
751 !strcmp(key, "SRP_A") || !strcmp(key, "SRP_B") ||
752 !strcmp(key, "SRP_M") || !strcmp(key, "SRP_HM"))
753 return 1;
754
755 return 0;
756}
757
758static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
759{
760 if (IS_TYPE_BOOL_AND(param)) {
761 if (!strcmp(param->value, NO))
762 SET_PSTATE_REPLY_OPTIONAL(param);
763 } else if (IS_TYPE_BOOL_OR(param)) {
764 if (!strcmp(param->value, YES))
765 SET_PSTATE_REPLY_OPTIONAL(param);
766 /*
767 * Required for gPXE iSCSI boot client
768 */
769 if (!strcmp(param->name, IMMEDIATEDATA))
770 SET_PSTATE_REPLY_OPTIONAL(param);
771 } else if (IS_TYPE_NUMBER(param)) {
772 if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
773 SET_PSTATE_REPLY_OPTIONAL(param);
774 /*
775 * The GlobalSAN iSCSI Initiator for MacOSX does
776 * not respond to MaxBurstLength, FirstBurstLength,
777 * DefaultTime2Wait or DefaultTime2Retain parameter keys.
778 * So, we set them to 'reply optional' here, and assume the
779 * the defaults from iscsi_parameters.h if the initiator
780 * is not RFC compliant and the keys are not negotiated.
781 */
782 if (!strcmp(param->name, MAXBURSTLENGTH))
783 SET_PSTATE_REPLY_OPTIONAL(param);
784 if (!strcmp(param->name, FIRSTBURSTLENGTH))
785 SET_PSTATE_REPLY_OPTIONAL(param);
786 if (!strcmp(param->name, DEFAULTTIME2WAIT))
787 SET_PSTATE_REPLY_OPTIONAL(param);
788 if (!strcmp(param->name, DEFAULTTIME2RETAIN))
789 SET_PSTATE_REPLY_OPTIONAL(param);
790 /*
791 * Required for gPXE iSCSI boot client
792 */
793 if (!strcmp(param->name, MAXCONNECTIONS))
794 SET_PSTATE_REPLY_OPTIONAL(param);
795 } else if (IS_PHASE_DECLARATIVE(param))
796 SET_PSTATE_REPLY_OPTIONAL(param);
797}
798
799static int iscsi_check_boolean_value(struct iscsi_param *param, char *value)
800{
801 if (strcmp(value, YES) && strcmp(value, NO)) {
802 pr_err("Illegal value for \"%s\", must be either"
803 " \"%s\" or \"%s\".\n", param->name, YES, NO);
804 return -1;
805 }
806
807 return 0;
808}
809
810static int iscsi_check_numerical_value(struct iscsi_param *param, char *value_ptr)
811{
812 char *tmpptr;
813 int value = 0;
814
815 value = simple_strtoul(value_ptr, &tmpptr, 0);
816
817/* #warning FIXME: Fix this */
818#if 0
819 if (strspn(endptr, WHITE_SPACE) != strlen(endptr)) {
820 pr_err("Illegal value \"%s\" for \"%s\".\n",
821 value, param->name);
822 return -1;
823 }
824#endif
825 if (IS_TYPERANGE_0_TO_2(param)) {
826 if ((value < 0) || (value > 2)) {
827 pr_err("Illegal value for \"%s\", must be"
828 " between 0 and 2.\n", param->name);
829 return -1;
830 }
831 return 0;
832 }
833 if (IS_TYPERANGE_0_TO_3600(param)) {
834 if ((value < 0) || (value > 3600)) {
835 pr_err("Illegal value for \"%s\", must be"
836 " between 0 and 3600.\n", param->name);
837 return -1;
838 }
839 return 0;
840 }
841 if (IS_TYPERANGE_0_TO_32767(param)) {
842 if ((value < 0) || (value > 32767)) {
843 pr_err("Illegal value for \"%s\", must be"
844 " between 0 and 32767.\n", param->name);
845 return -1;
846 }
847 return 0;
848 }
849 if (IS_TYPERANGE_0_TO_65535(param)) {
850 if ((value < 0) || (value > 65535)) {
851 pr_err("Illegal value for \"%s\", must be"
852 " between 0 and 65535.\n", param->name);
853 return -1;
854 }
855 return 0;
856 }
857 if (IS_TYPERANGE_1_TO_65535(param)) {
858 if ((value < 1) || (value > 65535)) {
859 pr_err("Illegal value for \"%s\", must be"
860 " between 1 and 65535.\n", param->name);
861 return -1;
862 }
863 return 0;
864 }
865 if (IS_TYPERANGE_2_TO_3600(param)) {
866 if ((value < 2) || (value > 3600)) {
867 pr_err("Illegal value for \"%s\", must be"
868 " between 2 and 3600.\n", param->name);
869 return -1;
870 }
871 return 0;
872 }
873 if (IS_TYPERANGE_512_TO_16777215(param)) {
874 if ((value < 512) || (value > 16777215)) {
875 pr_err("Illegal value for \"%s\", must be"
876 " between 512 and 16777215.\n", param->name);
877 return -1;
878 }
879 return 0;
880 }
881
882 return 0;
883}
884
885static int iscsi_check_numerical_range_value(struct iscsi_param *param, char *value)
886{
887 char *left_val_ptr = NULL, *right_val_ptr = NULL;
888 char *tilde_ptr = NULL, *tmp_ptr = NULL;
889 u32 left_val, right_val, local_left_val, local_right_val;
890
891 if (strcmp(param->name, IFMARKINT) &&
892 strcmp(param->name, OFMARKINT)) {
893 pr_err("Only parameters \"%s\" or \"%s\" may contain a"
894 " numerical range value.\n", IFMARKINT, OFMARKINT);
895 return -1;
896 }
897
898 if (IS_PSTATE_PROPOSER(param))
899 return 0;
900
901 tilde_ptr = strchr(value, '~');
902 if (!tilde_ptr) {
903 pr_err("Unable to locate numerical range indicator"
904 " \"~\" for \"%s\".\n", param->name);
905 return -1;
906 }
907 *tilde_ptr = '\0';
908
909 left_val_ptr = value;
910 right_val_ptr = value + strlen(left_val_ptr) + 1;
911
912 if (iscsi_check_numerical_value(param, left_val_ptr) < 0)
913 return -1;
914 if (iscsi_check_numerical_value(param, right_val_ptr) < 0)
915 return -1;
916
917 left_val = simple_strtoul(left_val_ptr, &tmp_ptr, 0);
918 right_val = simple_strtoul(right_val_ptr, &tmp_ptr, 0);
919 *tilde_ptr = '~';
920
921 if (right_val < left_val) {
922 pr_err("Numerical range for parameter \"%s\" contains"
923 " a right value which is less than the left.\n",
924 param->name);
925 return -1;
926 }
927
928 /*
929 * For now, enforce reasonable defaults for [I,O]FMarkInt.
930 */
931 tilde_ptr = strchr(param->value, '~');
932 if (!tilde_ptr) {
933 pr_err("Unable to locate numerical range indicator"
934 " \"~\" for \"%s\".\n", param->name);
935 return -1;
936 }
937 *tilde_ptr = '\0';
938
939 left_val_ptr = param->value;
940 right_val_ptr = param->value + strlen(left_val_ptr) + 1;
941
942 local_left_val = simple_strtoul(left_val_ptr, &tmp_ptr, 0);
943 local_right_val = simple_strtoul(right_val_ptr, &tmp_ptr, 0);
944 *tilde_ptr = '~';
945
946 if (param->set_param) {
947 if ((left_val < local_left_val) ||
948 (right_val < local_left_val)) {
949 pr_err("Passed value range \"%u~%u\" is below"
950 " minimum left value \"%u\" for key \"%s\","
951 " rejecting.\n", left_val, right_val,
952 local_left_val, param->name);
953 return -1;
954 }
955 } else {
956 if ((left_val < local_left_val) &&
957 (right_val < local_left_val)) {
958 pr_err("Received value range \"%u~%u\" is"
959 " below minimum left value \"%u\" for key"
960 " \"%s\", rejecting.\n", left_val, right_val,
961 local_left_val, param->name);
962 SET_PSTATE_REJECT(param);
963 if (iscsi_update_param_value(param, REJECT) < 0)
964 return -1;
965 }
966 }
967
968 return 0;
969}
970
971static int iscsi_check_string_or_list_value(struct iscsi_param *param, char *value)
972{
973 if (IS_PSTATE_PROPOSER(param))
974 return 0;
975
976 if (IS_TYPERANGE_AUTH_PARAM(param)) {
977 if (strcmp(value, KRB5) && strcmp(value, SPKM1) &&
978 strcmp(value, SPKM2) && strcmp(value, SRP) &&
979 strcmp(value, CHAP) && strcmp(value, NONE)) {
980 pr_err("Illegal value for \"%s\", must be"
981 " \"%s\", \"%s\", \"%s\", \"%s\", \"%s\""
982 " or \"%s\".\n", param->name, KRB5,
983 SPKM1, SPKM2, SRP, CHAP, NONE);
984 return -1;
985 }
986 }
987 if (IS_TYPERANGE_DIGEST_PARAM(param)) {
988 if (strcmp(value, CRC32C) && strcmp(value, NONE)) {
989 pr_err("Illegal value for \"%s\", must be"
990 " \"%s\" or \"%s\".\n", param->name,
991 CRC32C, NONE);
992 return -1;
993 }
994 }
995 if (IS_TYPERANGE_SESSIONTYPE(param)) {
996 if (strcmp(value, DISCOVERY) && strcmp(value, NORMAL)) {
997 pr_err("Illegal value for \"%s\", must be"
998 " \"%s\" or \"%s\".\n", param->name,
999 DISCOVERY, NORMAL);
1000 return -1;
1001 }
1002 }
1003
1004 return 0;
1005}
1006
1007/*
1008 * This function is used to pick a value range number, currently just
1009 * returns the lesser of both right values.
1010 */
1011static char *iscsi_get_value_from_number_range(
1012 struct iscsi_param *param,
1013 char *value)
1014{
1015 char *end_ptr, *tilde_ptr1 = NULL, *tilde_ptr2 = NULL;
1016 u32 acceptor_right_value, proposer_right_value;
1017
1018 tilde_ptr1 = strchr(value, '~');
1019 if (!tilde_ptr1)
1020 return NULL;
1021 *tilde_ptr1++ = '\0';
1022 proposer_right_value = simple_strtoul(tilde_ptr1, &end_ptr, 0);
1023
1024 tilde_ptr2 = strchr(param->value, '~');
1025 if (!tilde_ptr2)
1026 return NULL;
1027 *tilde_ptr2++ = '\0';
1028 acceptor_right_value = simple_strtoul(tilde_ptr2, &end_ptr, 0);
1029
1030 return (acceptor_right_value >= proposer_right_value) ?
1031 tilde_ptr1 : tilde_ptr2;
1032}
1033
1034static char *iscsi_check_valuelist_for_support(
1035 struct iscsi_param *param,
1036 char *value)
1037{
1038 char *tmp1 = NULL, *tmp2 = NULL;
1039 char *acceptor_values = NULL, *proposer_values = NULL;
1040
1041 acceptor_values = param->value;
1042 proposer_values = value;
1043
1044 do {
1045 if (!proposer_values)
1046 return NULL;
1047 tmp1 = strchr(proposer_values, ',');
1048 if (tmp1)
1049 *tmp1 = '\0';
1050 acceptor_values = param->value;
1051 do {
1052 if (!acceptor_values) {
1053 if (tmp1)
1054 *tmp1 = ',';
1055 return NULL;
1056 }
1057 tmp2 = strchr(acceptor_values, ',');
1058 if (tmp2)
1059 *tmp2 = '\0';
1060 if (!acceptor_values || !proposer_values) {
1061 if (tmp1)
1062 *tmp1 = ',';
1063 if (tmp2)
1064 *tmp2 = ',';
1065 return NULL;
1066 }
1067 if (!strcmp(acceptor_values, proposer_values)) {
1068 if (tmp2)
1069 *tmp2 = ',';
1070 goto out;
1071 }
1072 if (tmp2)
1073 *tmp2++ = ',';
1074
1075 acceptor_values = tmp2;
1076 if (!acceptor_values)
1077 break;
1078 } while (acceptor_values);
1079 if (tmp1)
1080 *tmp1++ = ',';
1081 proposer_values = tmp1;
1082 } while (proposer_values);
1083
1084out:
1085 return proposer_values;
1086}
1087
1088static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value)
1089{
1090 u8 acceptor_boolean_value = 0, proposer_boolean_value = 0;
1091 char *negoitated_value = NULL;
1092
1093 if (IS_PSTATE_ACCEPTOR(param)) {
1094 pr_err("Received key \"%s\" twice, protocol error.\n",
1095 param->name);
1096 return -1;
1097 }
1098
1099 if (IS_PSTATE_REJECT(param))
1100 return 0;
1101
1102 if (IS_TYPE_BOOL_AND(param)) {
1103 if (!strcmp(value, YES))
1104 proposer_boolean_value = 1;
1105 if (!strcmp(param->value, YES))
1106 acceptor_boolean_value = 1;
1107 if (acceptor_boolean_value && proposer_boolean_value)
1108 do {} while (0);
1109 else {
1110 if (iscsi_update_param_value(param, NO) < 0)
1111 return -1;
1112 if (!proposer_boolean_value)
1113 SET_PSTATE_REPLY_OPTIONAL(param);
1114 }
1115 } else if (IS_TYPE_BOOL_OR(param)) {
1116 if (!strcmp(value, YES))
1117 proposer_boolean_value = 1;
1118 if (!strcmp(param->value, YES))
1119 acceptor_boolean_value = 1;
1120 if (acceptor_boolean_value || proposer_boolean_value) {
1121 if (iscsi_update_param_value(param, YES) < 0)
1122 return -1;
1123 if (proposer_boolean_value)
1124 SET_PSTATE_REPLY_OPTIONAL(param);
1125 }
1126 } else if (IS_TYPE_NUMBER(param)) {
1127 char *tmpptr, buf[10];
1128 u32 acceptor_value = simple_strtoul(param->value, &tmpptr, 0);
1129 u32 proposer_value = simple_strtoul(value, &tmpptr, 0);
1130
1131 memset(buf, 0, 10);
1132
1133 if (!strcmp(param->name, MAXCONNECTIONS) ||
1134 !strcmp(param->name, MAXBURSTLENGTH) ||
1135 !strcmp(param->name, FIRSTBURSTLENGTH) ||
1136 !strcmp(param->name, MAXOUTSTANDINGR2T) ||
1137 !strcmp(param->name, DEFAULTTIME2RETAIN) ||
1138 !strcmp(param->name, ERRORRECOVERYLEVEL)) {
1139 if (proposer_value > acceptor_value) {
1140 sprintf(buf, "%u", acceptor_value);
1141 if (iscsi_update_param_value(param,
1142 &buf[0]) < 0)
1143 return -1;
1144 } else {
1145 if (iscsi_update_param_value(param, value) < 0)
1146 return -1;
1147 }
1148 } else if (!strcmp(param->name, DEFAULTTIME2WAIT)) {
1149 if (acceptor_value > proposer_value) {
1150 sprintf(buf, "%u", acceptor_value);
1151 if (iscsi_update_param_value(param,
1152 &buf[0]) < 0)
1153 return -1;
1154 } else {
1155 if (iscsi_update_param_value(param, value) < 0)
1156 return -1;
1157 }
1158 } else {
1159 if (iscsi_update_param_value(param, value) < 0)
1160 return -1;
1161 }
1162
1163 if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
1164 SET_PSTATE_REPLY_OPTIONAL(param);
1165 } else if (IS_TYPE_NUMBER_RANGE(param)) {
1166 negoitated_value = iscsi_get_value_from_number_range(
1167 param, value);
1168 if (!negoitated_value)
1169 return -1;
1170 if (iscsi_update_param_value(param, negoitated_value) < 0)
1171 return -1;
1172 } else if (IS_TYPE_VALUE_LIST(param)) {
1173 negoitated_value = iscsi_check_valuelist_for_support(
1174 param, value);
1175 if (!negoitated_value) {
1176 pr_err("Proposer's value list \"%s\" contains"
1177 " no valid values from Acceptor's value list"
1178 " \"%s\".\n", value, param->value);
1179 return -1;
1180 }
1181 if (iscsi_update_param_value(param, negoitated_value) < 0)
1182 return -1;
1183 } else if (IS_PHASE_DECLARATIVE(param)) {
1184 if (iscsi_update_param_value(param, value) < 0)
1185 return -1;
1186 SET_PSTATE_REPLY_OPTIONAL(param);
1187 }
1188
1189 return 0;
1190}
1191
1192static int iscsi_check_proposer_state(struct iscsi_param *param, char *value)
1193{
1194 if (IS_PSTATE_RESPONSE_GOT(param)) {
1195 pr_err("Received key \"%s\" twice, protocol error.\n",
1196 param->name);
1197 return -1;
1198 }
1199
1200 if (IS_TYPE_NUMBER_RANGE(param)) {
1201 u32 left_val = 0, right_val = 0, recieved_value = 0;
1202 char *left_val_ptr = NULL, *right_val_ptr = NULL;
1203 char *tilde_ptr = NULL, *tmp_ptr = NULL;
1204
1205 if (!strcmp(value, IRRELEVANT) || !strcmp(value, REJECT)) {
1206 if (iscsi_update_param_value(param, value) < 0)
1207 return -1;
1208 return 0;
1209 }
1210
1211 tilde_ptr = strchr(value, '~');
1212 if (tilde_ptr) {
1213 pr_err("Illegal \"~\" in response for \"%s\".\n",
1214 param->name);
1215 return -1;
1216 }
1217 tilde_ptr = strchr(param->value, '~');
1218 if (!tilde_ptr) {
1219 pr_err("Unable to locate numerical range"
1220 " indicator \"~\" for \"%s\".\n", param->name);
1221 return -1;
1222 }
1223 *tilde_ptr = '\0';
1224
1225 left_val_ptr = param->value;
1226 right_val_ptr = param->value + strlen(left_val_ptr) + 1;
1227 left_val = simple_strtoul(left_val_ptr, &tmp_ptr, 0);
1228 right_val = simple_strtoul(right_val_ptr, &tmp_ptr, 0);
1229 recieved_value = simple_strtoul(value, &tmp_ptr, 0);
1230
1231 *tilde_ptr = '~';
1232
1233 if ((recieved_value < left_val) ||
1234 (recieved_value > right_val)) {
1235 pr_err("Illegal response \"%s=%u\", value must"
1236 " be between %u and %u.\n", param->name,
1237 recieved_value, left_val, right_val);
1238 return -1;
1239 }
1240 } else if (IS_TYPE_VALUE_LIST(param)) {
1241 char *comma_ptr = NULL, *tmp_ptr = NULL;
1242
1243 comma_ptr = strchr(value, ',');
1244 if (comma_ptr) {
1245 pr_err("Illegal \",\" in response for \"%s\".\n",
1246 param->name);
1247 return -1;
1248 }
1249
1250 tmp_ptr = iscsi_check_valuelist_for_support(param, value);
1251 if (!tmp_ptr)
1252 return -1;
1253 }
1254
1255 if (iscsi_update_param_value(param, value) < 0)
1256 return -1;
1257
1258 return 0;
1259}
1260
1261static int iscsi_check_value(struct iscsi_param *param, char *value)
1262{
1263 char *comma_ptr = NULL;
1264
1265 if (!strcmp(value, REJECT)) {
1266 if (!strcmp(param->name, IFMARKINT) ||
1267 !strcmp(param->name, OFMARKINT)) {
1268 /*
1269 * Reject is not fatal for [I,O]FMarkInt, and causes
1270 * [I,O]FMarker to be reset to No. (See iSCSI v20 A.3.2)
1271 */
1272 SET_PSTATE_REJECT(param);
1273 return 0;
1274 }
1275 pr_err("Received %s=%s\n", param->name, value);
1276 return -1;
1277 }
1278 if (!strcmp(value, IRRELEVANT)) {
1279 pr_debug("Received %s=%s\n", param->name, value);
1280 SET_PSTATE_IRRELEVANT(param);
1281 return 0;
1282 }
1283 if (!strcmp(value, NOTUNDERSTOOD)) {
1284 if (!IS_PSTATE_PROPOSER(param)) {
1285 pr_err("Received illegal offer %s=%s\n",
1286 param->name, value);
1287 return -1;
1288 }
1289
1290/* #warning FIXME: Add check for X-ExtensionKey here */
1291 pr_err("Standard iSCSI key \"%s\" cannot be answered"
1292 " with \"%s\", protocol error.\n", param->name, value);
1293 return -1;
1294 }
1295
1296 do {
1297 comma_ptr = NULL;
1298 comma_ptr = strchr(value, ',');
1299
1300 if (comma_ptr && !IS_TYPE_VALUE_LIST(param)) {
1301 pr_err("Detected value seperator \",\", but"
1302 " key \"%s\" does not allow a value list,"
1303 " protocol error.\n", param->name);
1304 return -1;
1305 }
1306 if (comma_ptr)
1307 *comma_ptr = '\0';
1308
1309 if (strlen(value) > VALUE_MAXLEN) {
1310 pr_err("Value for key \"%s\" exceeds %d,"
1311 " protocol error.\n", param->name,
1312 VALUE_MAXLEN);
1313 return -1;
1314 }
1315
1316 if (IS_TYPE_BOOL_AND(param) || IS_TYPE_BOOL_OR(param)) {
1317 if (iscsi_check_boolean_value(param, value) < 0)
1318 return -1;
1319 } else if (IS_TYPE_NUMBER(param)) {
1320 if (iscsi_check_numerical_value(param, value) < 0)
1321 return -1;
1322 } else if (IS_TYPE_NUMBER_RANGE(param)) {
1323 if (iscsi_check_numerical_range_value(param, value) < 0)
1324 return -1;
1325 } else if (IS_TYPE_STRING(param) || IS_TYPE_VALUE_LIST(param)) {
1326 if (iscsi_check_string_or_list_value(param, value) < 0)
1327 return -1;
1328 } else {
1329 pr_err("Huh? 0x%02x\n", param->type);
1330 return -1;
1331 }
1332
1333 if (comma_ptr)
1334 *comma_ptr++ = ',';
1335
1336 value = comma_ptr;
1337 } while (value);
1338
1339 return 0;
1340}
1341
1342static struct iscsi_param *__iscsi_check_key(
1343 char *key,
1344 int sender,
1345 struct iscsi_param_list *param_list)
1346{
1347 struct iscsi_param *param;
1348
1349 if (strlen(key) > KEY_MAXLEN) {
1350 pr_err("Length of key name \"%s\" exceeds %d.\n",
1351 key, KEY_MAXLEN);
1352 return NULL;
1353 }
1354
1355 param = iscsi_find_param_from_key(key, param_list);
1356 if (!param)
1357 return NULL;
1358
1359 if ((sender & SENDER_INITIATOR) && !IS_SENDER_INITIATOR(param)) {
1360 pr_err("Key \"%s\" may not be sent to %s,"
1361 " protocol error.\n", param->name,
1362 (sender & SENDER_RECEIVER) ? "target" : "initiator");
1363 return NULL;
1364 }
1365
1366 if ((sender & SENDER_TARGET) && !IS_SENDER_TARGET(param)) {
1367 pr_err("Key \"%s\" may not be sent to %s,"
1368 " protocol error.\n", param->name,
1369 (sender & SENDER_RECEIVER) ? "initiator" : "target");
1370 return NULL;
1371 }
1372
1373 return param;
1374}
1375
1376static struct iscsi_param *iscsi_check_key(
1377 char *key,
1378 int phase,
1379 int sender,
1380 struct iscsi_param_list *param_list)
1381{
1382 struct iscsi_param *param;
1383 /*
1384 * Key name length must not exceed 63 bytes. (See iSCSI v20 5.1)
1385 */
1386 if (strlen(key) > KEY_MAXLEN) {
1387 pr_err("Length of key name \"%s\" exceeds %d.\n",
1388 key, KEY_MAXLEN);
1389 return NULL;
1390 }
1391
1392 param = iscsi_find_param_from_key(key, param_list);
1393 if (!param)
1394 return NULL;
1395
1396 if ((sender & SENDER_INITIATOR) && !IS_SENDER_INITIATOR(param)) {
1397 pr_err("Key \"%s\" may not be sent to %s,"
1398 " protocol error.\n", param->name,
1399 (sender & SENDER_RECEIVER) ? "target" : "initiator");
1400 return NULL;
1401 }
1402 if ((sender & SENDER_TARGET) && !IS_SENDER_TARGET(param)) {
1403 pr_err("Key \"%s\" may not be sent to %s,"
1404 " protocol error.\n", param->name,
1405 (sender & SENDER_RECEIVER) ? "initiator" : "target");
1406 return NULL;
1407 }
1408
1409 if (IS_PSTATE_ACCEPTOR(param)) {
1410 pr_err("Key \"%s\" received twice, protocol error.\n",
1411 key);
1412 return NULL;
1413 }
1414
1415 if (!phase)
1416 return param;
1417
1418 if (!(param->phase & phase)) {
1419 pr_err("Key \"%s\" may not be negotiated during ",
1420 param->name);
1421 switch (phase) {
1422 case PHASE_SECURITY:
1423 pr_debug("Security phase.\n");
1424 break;
1425 case PHASE_OPERATIONAL:
1426 pr_debug("Operational phase.\n");
1427 default:
1428 pr_debug("Unknown phase.\n");
1429 }
1430 return NULL;
1431 }
1432
1433 return param;
1434}
1435
1436static int iscsi_enforce_integrity_rules(
1437 u8 phase,
1438 struct iscsi_param_list *param_list)
1439{
1440 char *tmpptr;
1441 u8 DataSequenceInOrder = 0;
1442 u8 ErrorRecoveryLevel = 0, SessionType = 0;
1443 u8 IFMarker = 0, OFMarker = 0;
1444 u8 IFMarkInt_Reject = 0, OFMarkInt_Reject = 0;
1445 u32 FirstBurstLength = 0, MaxBurstLength = 0;
1446 struct iscsi_param *param = NULL;
1447
1448 list_for_each_entry(param, &param_list->param_list, p_list) {
1449 if (!(param->phase & phase))
1450 continue;
1451 if (!strcmp(param->name, SESSIONTYPE))
1452 if (!strcmp(param->value, NORMAL))
1453 SessionType = 1;
1454 if (!strcmp(param->name, ERRORRECOVERYLEVEL))
1455 ErrorRecoveryLevel = simple_strtoul(param->value,
1456 &tmpptr, 0);
1457 if (!strcmp(param->name, DATASEQUENCEINORDER))
1458 if (!strcmp(param->value, YES))
1459 DataSequenceInOrder = 1;
1460 if (!strcmp(param->name, MAXBURSTLENGTH))
1461 MaxBurstLength = simple_strtoul(param->value,
1462 &tmpptr, 0);
1463 if (!strcmp(param->name, IFMARKER))
1464 if (!strcmp(param->value, YES))
1465 IFMarker = 1;
1466 if (!strcmp(param->name, OFMARKER))
1467 if (!strcmp(param->value, YES))
1468 OFMarker = 1;
1469 if (!strcmp(param->name, IFMARKINT))
1470 if (!strcmp(param->value, REJECT))
1471 IFMarkInt_Reject = 1;
1472 if (!strcmp(param->name, OFMARKINT))
1473 if (!strcmp(param->value, REJECT))
1474 OFMarkInt_Reject = 1;
1475 }
1476
1477 list_for_each_entry(param, &param_list->param_list, p_list) {
1478 if (!(param->phase & phase))
1479 continue;
1480 if (!SessionType && (!IS_PSTATE_ACCEPTOR(param) &&
1481 (strcmp(param->name, IFMARKER) &&
1482 strcmp(param->name, OFMARKER) &&
1483 strcmp(param->name, IFMARKINT) &&
1484 strcmp(param->name, OFMARKINT))))
1485 continue;
1486 if (!strcmp(param->name, MAXOUTSTANDINGR2T) &&
1487 DataSequenceInOrder && (ErrorRecoveryLevel > 0)) {
1488 if (strcmp(param->value, "1")) {
1489 if (iscsi_update_param_value(param, "1") < 0)
1490 return -1;
1491 pr_debug("Reset \"%s\" to \"%s\".\n",
1492 param->name, param->value);
1493 }
1494 }
1495 if (!strcmp(param->name, MAXCONNECTIONS) && !SessionType) {
1496 if (strcmp(param->value, "1")) {
1497 if (iscsi_update_param_value(param, "1") < 0)
1498 return -1;
1499 pr_debug("Reset \"%s\" to \"%s\".\n",
1500 param->name, param->value);
1501 }
1502 }
1503 if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
1504 FirstBurstLength = simple_strtoul(param->value,
1505 &tmpptr, 0);
1506 if (FirstBurstLength > MaxBurstLength) {
1507 char tmpbuf[10];
1508 memset(tmpbuf, 0, 10);
1509 sprintf(tmpbuf, "%u", MaxBurstLength);
1510 if (iscsi_update_param_value(param, tmpbuf))
1511 return -1;
1512 pr_debug("Reset \"%s\" to \"%s\".\n",
1513 param->name, param->value);
1514 }
1515 }
1516 if (!strcmp(param->name, IFMARKER) && IFMarkInt_Reject) {
1517 if (iscsi_update_param_value(param, NO) < 0)
1518 return -1;
1519 IFMarker = 0;
1520 pr_debug("Reset \"%s\" to \"%s\".\n",
1521 param->name, param->value);
1522 }
1523 if (!strcmp(param->name, OFMARKER) && OFMarkInt_Reject) {
1524 if (iscsi_update_param_value(param, NO) < 0)
1525 return -1;
1526 OFMarker = 0;
1527 pr_debug("Reset \"%s\" to \"%s\".\n",
1528 param->name, param->value);
1529 }
1530 if (!strcmp(param->name, IFMARKINT) && !IFMarker) {
1531 if (!strcmp(param->value, REJECT))
1532 continue;
1533 param->state &= ~PSTATE_NEGOTIATE;
1534 if (iscsi_update_param_value(param, IRRELEVANT) < 0)
1535 return -1;
1536 pr_debug("Reset \"%s\" to \"%s\".\n",
1537 param->name, param->value);
1538 }
1539 if (!strcmp(param->name, OFMARKINT) && !OFMarker) {
1540 if (!strcmp(param->value, REJECT))
1541 continue;
1542 param->state &= ~PSTATE_NEGOTIATE;
1543 if (iscsi_update_param_value(param, IRRELEVANT) < 0)
1544 return -1;
1545 pr_debug("Reset \"%s\" to \"%s\".\n",
1546 param->name, param->value);
1547 }
1548 }
1549
1550 return 0;
1551}
1552
1553int iscsi_decode_text_input(
1554 u8 phase,
1555 u8 sender,
1556 char *textbuf,
1557 u32 length,
1558 struct iscsi_param_list *param_list)
1559{
1560 char *tmpbuf, *start = NULL, *end = NULL;
1561
1562 tmpbuf = kzalloc(length + 1, GFP_KERNEL);
1563 if (!tmpbuf) {
1564 pr_err("Unable to allocate memory for tmpbuf.\n");
1565 return -1;
1566 }
1567
1568 memcpy(tmpbuf, textbuf, length);
1569 tmpbuf[length] = '\0';
1570 start = tmpbuf;
1571 end = (start + length);
1572
1573 while (start < end) {
1574 char *key, *value;
1575 struct iscsi_param *param;
1576
1577 if (iscsi_extract_key_value(start, &key, &value) < 0) {
1578 kfree(tmpbuf);
1579 return -1;
1580 }
1581
1582 pr_debug("Got key: %s=%s\n", key, value);
1583
1584 if (phase & PHASE_SECURITY) {
1585 if (iscsi_check_for_auth_key(key) > 0) {
1586 char *tmpptr = key + strlen(key);
1587 *tmpptr = '=';
1588 kfree(tmpbuf);
1589 return 1;
1590 }
1591 }
1592
1593 param = iscsi_check_key(key, phase, sender, param_list);
1594 if (!param) {
1595 if (iscsi_add_notunderstood_response(key,
1596 value, param_list) < 0) {
1597 kfree(tmpbuf);
1598 return -1;
1599 }
1600 start += strlen(key) + strlen(value) + 2;
1601 continue;
1602 }
1603 if (iscsi_check_value(param, value) < 0) {
1604 kfree(tmpbuf);
1605 return -1;
1606 }
1607
1608 start += strlen(key) + strlen(value) + 2;
1609
1610 if (IS_PSTATE_PROPOSER(param)) {
1611 if (iscsi_check_proposer_state(param, value) < 0) {
1612 kfree(tmpbuf);
1613 return -1;
1614 }
1615 SET_PSTATE_RESPONSE_GOT(param);
1616 } else {
1617 if (iscsi_check_acceptor_state(param, value) < 0) {
1618 kfree(tmpbuf);
1619 return -1;
1620 }
1621 SET_PSTATE_ACCEPTOR(param);
1622 }
1623 }
1624
1625 kfree(tmpbuf);
1626 return 0;
1627}
1628
1629int iscsi_encode_text_output(
1630 u8 phase,
1631 u8 sender,
1632 char *textbuf,
1633 u32 *length,
1634 struct iscsi_param_list *param_list)
1635{
1636 char *output_buf = NULL;
1637 struct iscsi_extra_response *er;
1638 struct iscsi_param *param;
1639
1640 output_buf = textbuf + *length;
1641
1642 if (iscsi_enforce_integrity_rules(phase, param_list) < 0)
1643 return -1;
1644
1645 list_for_each_entry(param, &param_list->param_list, p_list) {
1646 if (!(param->sender & sender))
1647 continue;
1648 if (IS_PSTATE_ACCEPTOR(param) &&
1649 !IS_PSTATE_RESPONSE_SENT(param) &&
1650 !IS_PSTATE_REPLY_OPTIONAL(param) &&
1651 (param->phase & phase)) {
1652 *length += sprintf(output_buf, "%s=%s",
1653 param->name, param->value);
1654 *length += 1;
1655 output_buf = textbuf + *length;
1656 SET_PSTATE_RESPONSE_SENT(param);
1657 pr_debug("Sending key: %s=%s\n",
1658 param->name, param->value);
1659 continue;
1660 }
1661 if (IS_PSTATE_NEGOTIATE(param) &&
1662 !IS_PSTATE_ACCEPTOR(param) &&
1663 !IS_PSTATE_PROPOSER(param) &&
1664 (param->phase & phase)) {
1665 *length += sprintf(output_buf, "%s=%s",
1666 param->name, param->value);
1667 *length += 1;
1668 output_buf = textbuf + *length;
1669 SET_PSTATE_PROPOSER(param);
1670 iscsi_check_proposer_for_optional_reply(param);
1671 pr_debug("Sending key: %s=%s\n",
1672 param->name, param->value);
1673 }
1674 }
1675
1676 list_for_each_entry(er, &param_list->extra_response_list, er_list) {
1677 *length += sprintf(output_buf, "%s=%s", er->key, er->value);
1678 *length += 1;
1679 output_buf = textbuf + *length;
1680 pr_debug("Sending key: %s=%s\n", er->key, er->value);
1681 }
1682 iscsi_release_extra_responses(param_list);
1683
1684 return 0;
1685}
1686
1687int iscsi_check_negotiated_keys(struct iscsi_param_list *param_list)
1688{
1689 int ret = 0;
1690 struct iscsi_param *param;
1691
1692 list_for_each_entry(param, &param_list->param_list, p_list) {
1693 if (IS_PSTATE_NEGOTIATE(param) &&
1694 IS_PSTATE_PROPOSER(param) &&
1695 !IS_PSTATE_RESPONSE_GOT(param) &&
1696 !IS_PSTATE_REPLY_OPTIONAL(param) &&
1697 !IS_PHASE_DECLARATIVE(param)) {
1698 pr_err("No response for proposed key \"%s\".\n",
1699 param->name);
1700 ret = -1;
1701 }
1702 }
1703
1704 return ret;
1705}
1706
1707int iscsi_change_param_value(
1708 char *keyvalue,
1709 struct iscsi_param_list *param_list,
1710 int check_key)
1711{
1712 char *key = NULL, *value = NULL;
1713 struct iscsi_param *param;
1714 int sender = 0;
1715
1716 if (iscsi_extract_key_value(keyvalue, &key, &value) < 0)
1717 return -1;
1718
1719 if (!check_key) {
1720 param = __iscsi_check_key(keyvalue, sender, param_list);
1721 if (!param)
1722 return -1;
1723 } else {
1724 param = iscsi_check_key(keyvalue, 0, sender, param_list);
1725 if (!param)
1726 return -1;
1727
1728 param->set_param = 1;
1729 if (iscsi_check_value(param, value) < 0) {
1730 param->set_param = 0;
1731 return -1;
1732 }
1733 param->set_param = 0;
1734 }
1735
1736 if (iscsi_update_param_value(param, value) < 0)
1737 return -1;
1738
1739 return 0;
1740}
1741
1742void iscsi_set_connection_parameters(
1743 struct iscsi_conn_ops *ops,
1744 struct iscsi_param_list *param_list)
1745{
1746 char *tmpptr;
1747 struct iscsi_param *param;
1748
1749 pr_debug("---------------------------------------------------"
1750 "---------------\n");
1751 list_for_each_entry(param, &param_list->param_list, p_list) {
1752 if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
1753 continue;
1754 if (!strcmp(param->name, AUTHMETHOD)) {
1755 pr_debug("AuthMethod: %s\n",
1756 param->value);
1757 } else if (!strcmp(param->name, HEADERDIGEST)) {
1758 ops->HeaderDigest = !strcmp(param->value, CRC32C);
1759 pr_debug("HeaderDigest: %s\n",
1760 param->value);
1761 } else if (!strcmp(param->name, DATADIGEST)) {
1762 ops->DataDigest = !strcmp(param->value, CRC32C);
1763 pr_debug("DataDigest: %s\n",
1764 param->value);
1765 } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
1766 ops->MaxRecvDataSegmentLength =
1767 simple_strtoul(param->value, &tmpptr, 0);
1768 pr_debug("MaxRecvDataSegmentLength: %s\n",
1769 param->value);
1770 } else if (!strcmp(param->name, OFMARKER)) {
1771 ops->OFMarker = !strcmp(param->value, YES);
1772 pr_debug("OFMarker: %s\n",
1773 param->value);
1774 } else if (!strcmp(param->name, IFMARKER)) {
1775 ops->IFMarker = !strcmp(param->value, YES);
1776 pr_debug("IFMarker: %s\n",
1777 param->value);
1778 } else if (!strcmp(param->name, OFMARKINT)) {
1779 ops->OFMarkInt =
1780 simple_strtoul(param->value, &tmpptr, 0);
1781 pr_debug("OFMarkInt: %s\n",
1782 param->value);
1783 } else if (!strcmp(param->name, IFMARKINT)) {
1784 ops->IFMarkInt =
1785 simple_strtoul(param->value, &tmpptr, 0);
1786 pr_debug("IFMarkInt: %s\n",
1787 param->value);
1788 }
1789 }
1790 pr_debug("----------------------------------------------------"
1791 "--------------\n");
1792}
1793
1794void iscsi_set_session_parameters(
1795 struct iscsi_sess_ops *ops,
1796 struct iscsi_param_list *param_list,
1797 int leading)
1798{
1799 char *tmpptr;
1800 struct iscsi_param *param;
1801
1802 pr_debug("----------------------------------------------------"
1803 "--------------\n");
1804 list_for_each_entry(param, &param_list->param_list, p_list) {
1805 if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
1806 continue;
1807 if (!strcmp(param->name, INITIATORNAME)) {
1808 if (!param->value)
1809 continue;
1810 if (leading)
1811 snprintf(ops->InitiatorName,
1812 sizeof(ops->InitiatorName),
1813 "%s", param->value);
1814 pr_debug("InitiatorName: %s\n",
1815 param->value);
1816 } else if (!strcmp(param->name, INITIATORALIAS)) {
1817 if (!param->value)
1818 continue;
1819 snprintf(ops->InitiatorAlias,
1820 sizeof(ops->InitiatorAlias),
1821 "%s", param->value);
1822 pr_debug("InitiatorAlias: %s\n",
1823 param->value);
1824 } else if (!strcmp(param->name, TARGETNAME)) {
1825 if (!param->value)
1826 continue;
1827 if (leading)
1828 snprintf(ops->TargetName,
1829 sizeof(ops->TargetName),
1830 "%s", param->value);
1831 pr_debug("TargetName: %s\n",
1832 param->value);
1833 } else if (!strcmp(param->name, TARGETALIAS)) {
1834 if (!param->value)
1835 continue;
1836 snprintf(ops->TargetAlias, sizeof(ops->TargetAlias),
1837 "%s", param->value);
1838 pr_debug("TargetAlias: %s\n",
1839 param->value);
1840 } else if (!strcmp(param->name, TARGETPORTALGROUPTAG)) {
1841 ops->TargetPortalGroupTag =
1842 simple_strtoul(param->value, &tmpptr, 0);
1843 pr_debug("TargetPortalGroupTag: %s\n",
1844 param->value);
1845 } else if (!strcmp(param->name, MAXCONNECTIONS)) {
1846 ops->MaxConnections =
1847 simple_strtoul(param->value, &tmpptr, 0);
1848 pr_debug("MaxConnections: %s\n",
1849 param->value);
1850 } else if (!strcmp(param->name, INITIALR2T)) {
1851 ops->InitialR2T = !strcmp(param->value, YES);
1852 pr_debug("InitialR2T: %s\n",
1853 param->value);
1854 } else if (!strcmp(param->name, IMMEDIATEDATA)) {
1855 ops->ImmediateData = !strcmp(param->value, YES);
1856 pr_debug("ImmediateData: %s\n",
1857 param->value);
1858 } else if (!strcmp(param->name, MAXBURSTLENGTH)) {
1859 ops->MaxBurstLength =
1860 simple_strtoul(param->value, &tmpptr, 0);
1861 pr_debug("MaxBurstLength: %s\n",
1862 param->value);
1863 } else if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
1864 ops->FirstBurstLength =
1865 simple_strtoul(param->value, &tmpptr, 0);
1866 pr_debug("FirstBurstLength: %s\n",
1867 param->value);
1868 } else if (!strcmp(param->name, DEFAULTTIME2WAIT)) {
1869 ops->DefaultTime2Wait =
1870 simple_strtoul(param->value, &tmpptr, 0);
1871 pr_debug("DefaultTime2Wait: %s\n",
1872 param->value);
1873 } else if (!strcmp(param->name, DEFAULTTIME2RETAIN)) {
1874 ops->DefaultTime2Retain =
1875 simple_strtoul(param->value, &tmpptr, 0);
1876 pr_debug("DefaultTime2Retain: %s\n",
1877 param->value);
1878 } else if (!strcmp(param->name, MAXOUTSTANDINGR2T)) {
1879 ops->MaxOutstandingR2T =
1880 simple_strtoul(param->value, &tmpptr, 0);
1881 pr_debug("MaxOutstandingR2T: %s\n",
1882 param->value);
1883 } else if (!strcmp(param->name, DATAPDUINORDER)) {
1884 ops->DataPDUInOrder = !strcmp(param->value, YES);
1885 pr_debug("DataPDUInOrder: %s\n",
1886 param->value);
1887 } else if (!strcmp(param->name, DATASEQUENCEINORDER)) {
1888 ops->DataSequenceInOrder = !strcmp(param->value, YES);
1889 pr_debug("DataSequenceInOrder: %s\n",
1890 param->value);
1891 } else if (!strcmp(param->name, ERRORRECOVERYLEVEL)) {
1892 ops->ErrorRecoveryLevel =
1893 simple_strtoul(param->value, &tmpptr, 0);
1894 pr_debug("ErrorRecoveryLevel: %s\n",
1895 param->value);
1896 } else if (!strcmp(param->name, SESSIONTYPE)) {
1897 ops->SessionType = !strcmp(param->value, DISCOVERY);
1898 pr_debug("SessionType: %s\n",
1899 param->value);
1900 }
1901 }
1902 pr_debug("----------------------------------------------------"
1903 "--------------\n");
1904
1905}
diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h
new file mode 100644
index 000000000000..6a37fd6f1285
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_parameters.h
@@ -0,0 +1,269 @@
1#ifndef ISCSI_PARAMETERS_H
2#define ISCSI_PARAMETERS_H
3
4struct iscsi_extra_response {
5 char key[64];
6 char value[32];
7 struct list_head er_list;
8} ____cacheline_aligned;
9
10struct iscsi_param {
11 char *name;
12 char *value;
13 u8 set_param;
14 u8 phase;
15 u8 scope;
16 u8 sender;
17 u8 type;
18 u8 use;
19 u16 type_range;
20 u32 state;
21 struct list_head p_list;
22} ____cacheline_aligned;
23
24extern int iscsi_login_rx_data(struct iscsi_conn *, char *, int);
25extern int iscsi_login_tx_data(struct iscsi_conn *, char *, char *, int);
26extern void iscsi_dump_conn_ops(struct iscsi_conn_ops *);
27extern void iscsi_dump_sess_ops(struct iscsi_sess_ops *);
28extern void iscsi_print_params(struct iscsi_param_list *);
29extern int iscsi_create_default_params(struct iscsi_param_list **);
30extern int iscsi_set_keys_to_negotiate(int, struct iscsi_param_list *);
31extern int iscsi_set_keys_irrelevant_for_discovery(struct iscsi_param_list *);
32extern int iscsi_copy_param_list(struct iscsi_param_list **,
33 struct iscsi_param_list *, int);
34extern int iscsi_change_param_value(char *, struct iscsi_param_list *, int);
35extern void iscsi_release_param_list(struct iscsi_param_list *);
36extern struct iscsi_param *iscsi_find_param_from_key(char *, struct iscsi_param_list *);
37extern int iscsi_extract_key_value(char *, char **, char **);
38extern int iscsi_update_param_value(struct iscsi_param *, char *);
39extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_param_list *);
40extern int iscsi_encode_text_output(u8, u8, char *, u32 *,
41 struct iscsi_param_list *);
42extern int iscsi_check_negotiated_keys(struct iscsi_param_list *);
43extern void iscsi_set_connection_parameters(struct iscsi_conn_ops *,
44 struct iscsi_param_list *);
45extern void iscsi_set_session_parameters(struct iscsi_sess_ops *,
46 struct iscsi_param_list *, int);
47
48#define YES "Yes"
49#define NO "No"
50#define ALL "All"
51#define IRRELEVANT "Irrelevant"
52#define NONE "None"
53#define NOTUNDERSTOOD "NotUnderstood"
54#define REJECT "Reject"
55
56/*
57 * The Parameter Names.
58 */
59#define AUTHMETHOD "AuthMethod"
60#define HEADERDIGEST "HeaderDigest"
61#define DATADIGEST "DataDigest"
62#define MAXCONNECTIONS "MaxConnections"
63#define SENDTARGETS "SendTargets"
64#define TARGETNAME "TargetName"
65#define INITIATORNAME "InitiatorName"
66#define TARGETALIAS "TargetAlias"
67#define INITIATORALIAS "InitiatorAlias"
68#define TARGETADDRESS "TargetAddress"
69#define TARGETPORTALGROUPTAG "TargetPortalGroupTag"
70#define INITIALR2T "InitialR2T"
71#define IMMEDIATEDATA "ImmediateData"
72#define MAXRECVDATASEGMENTLENGTH "MaxRecvDataSegmentLength"
73#define MAXBURSTLENGTH "MaxBurstLength"
74#define FIRSTBURSTLENGTH "FirstBurstLength"
75#define DEFAULTTIME2WAIT "DefaultTime2Wait"
76#define DEFAULTTIME2RETAIN "DefaultTime2Retain"
77#define MAXOUTSTANDINGR2T "MaxOutstandingR2T"
78#define DATAPDUINORDER "DataPDUInOrder"
79#define DATASEQUENCEINORDER "DataSequenceInOrder"
80#define ERRORRECOVERYLEVEL "ErrorRecoveryLevel"
81#define SESSIONTYPE "SessionType"
82#define IFMARKER "IFMarker"
83#define OFMARKER "OFMarker"
84#define IFMARKINT "IFMarkInt"
85#define OFMARKINT "OFMarkInt"
86#define X_EXTENSIONKEY "X-com.sbei.version"
87#define X_EXTENSIONKEY_CISCO_NEW "X-com.cisco.protocol"
88#define X_EXTENSIONKEY_CISCO_OLD "X-com.cisco.iscsi.draft"
89
90/*
91 * For AuthMethod.
92 */
93#define KRB5 "KRB5"
94#define SPKM1 "SPKM1"
95#define SPKM2 "SPKM2"
96#define SRP "SRP"
97#define CHAP "CHAP"
98
99/*
100 * Initial values for Parameter Negotiation.
101 */
102#define INITIAL_AUTHMETHOD CHAP
103#define INITIAL_HEADERDIGEST "CRC32C,None"
104#define INITIAL_DATADIGEST "CRC32C,None"
105#define INITIAL_MAXCONNECTIONS "1"
106#define INITIAL_SENDTARGETS ALL
107#define INITIAL_TARGETNAME "LIO.Target"
108#define INITIAL_INITIATORNAME "LIO.Initiator"
109#define INITIAL_TARGETALIAS "LIO Target"
110#define INITIAL_INITIATORALIAS "LIO Initiator"
111#define INITIAL_TARGETADDRESS "0.0.0.0:0000,0"
112#define INITIAL_TARGETPORTALGROUPTAG "1"
113#define INITIAL_INITIALR2T YES
114#define INITIAL_IMMEDIATEDATA YES
115#define INITIAL_MAXRECVDATASEGMENTLENGTH "8192"
116#define INITIAL_MAXBURSTLENGTH "262144"
117#define INITIAL_FIRSTBURSTLENGTH "65536"
118#define INITIAL_DEFAULTTIME2WAIT "2"
119#define INITIAL_DEFAULTTIME2RETAIN "20"
120#define INITIAL_MAXOUTSTANDINGR2T "1"
121#define INITIAL_DATAPDUINORDER YES
122#define INITIAL_DATASEQUENCEINORDER YES
123#define INITIAL_ERRORRECOVERYLEVEL "0"
124#define INITIAL_SESSIONTYPE NORMAL
125#define INITIAL_IFMARKER NO
126#define INITIAL_OFMARKER NO
127#define INITIAL_IFMARKINT "2048~65535"
128#define INITIAL_OFMARKINT "2048~65535"
129
130/*
131 * For [Header,Data]Digests.
132 */
133#define CRC32C "CRC32C"
134
135/*
136 * For SessionType.
137 */
138#define DISCOVERY "Discovery"
139#define NORMAL "Normal"
140
141/*
142 * struct iscsi_param->use
143 */
144#define USE_LEADING_ONLY 0x01
145#define USE_INITIAL_ONLY 0x02
146#define USE_ALL 0x04
147
148#define IS_USE_LEADING_ONLY(p) ((p)->use & USE_LEADING_ONLY)
149#define IS_USE_INITIAL_ONLY(p) ((p)->use & USE_INITIAL_ONLY)
150#define IS_USE_ALL(p) ((p)->use & USE_ALL)
151
152#define SET_USE_INITIAL_ONLY(p) ((p)->use |= USE_INITIAL_ONLY)
153
154/*
155 * struct iscsi_param->sender
156 */
157#define SENDER_INITIATOR 0x01
158#define SENDER_TARGET 0x02
159#define SENDER_BOTH 0x03
160/* Used in iscsi_check_key() */
161#define SENDER_RECEIVER 0x04
162
163#define IS_SENDER_INITIATOR(p) ((p)->sender & SENDER_INITIATOR)
164#define IS_SENDER_TARGET(p) ((p)->sender & SENDER_TARGET)
165#define IS_SENDER_BOTH(p) ((p)->sender & SENDER_BOTH)
166
167/*
168 * struct iscsi_param->scope
169 */
170#define SCOPE_CONNECTION_ONLY 0x01
171#define SCOPE_SESSION_WIDE 0x02
172
173#define IS_SCOPE_CONNECTION_ONLY(p) ((p)->scope & SCOPE_CONNECTION_ONLY)
174#define IS_SCOPE_SESSION_WIDE(p) ((p)->scope & SCOPE_SESSION_WIDE)
175
176/*
177 * struct iscsi_param->phase
178 */
179#define PHASE_SECURITY 0x01
180#define PHASE_OPERATIONAL 0x02
181#define PHASE_DECLARATIVE 0x04
182#define PHASE_FFP0 0x08
183
184#define IS_PHASE_SECURITY(p) ((p)->phase & PHASE_SECURITY)
185#define IS_PHASE_OPERATIONAL(p) ((p)->phase & PHASE_OPERATIONAL)
186#define IS_PHASE_DECLARATIVE(p) ((p)->phase & PHASE_DECLARATIVE)
187#define IS_PHASE_FFP0(p) ((p)->phase & PHASE_FFP0)
188
189/*
190 * struct iscsi_param->type
191 */
192#define TYPE_BOOL_AND 0x01
193#define TYPE_BOOL_OR 0x02
194#define TYPE_NUMBER 0x04
195#define TYPE_NUMBER_RANGE 0x08
196#define TYPE_STRING 0x10
197#define TYPE_VALUE_LIST 0x20
198
199#define IS_TYPE_BOOL_AND(p) ((p)->type & TYPE_BOOL_AND)
200#define IS_TYPE_BOOL_OR(p) ((p)->type & TYPE_BOOL_OR)
201#define IS_TYPE_NUMBER(p) ((p)->type & TYPE_NUMBER)
202#define IS_TYPE_NUMBER_RANGE(p) ((p)->type & TYPE_NUMBER_RANGE)
203#define IS_TYPE_STRING(p) ((p)->type & TYPE_STRING)
204#define IS_TYPE_VALUE_LIST(p) ((p)->type & TYPE_VALUE_LIST)
205
206/*
207 * struct iscsi_param->type_range
208 */
209#define TYPERANGE_BOOL_AND 0x0001
210#define TYPERANGE_BOOL_OR 0x0002
211#define TYPERANGE_0_TO_2 0x0004
212#define TYPERANGE_0_TO_3600 0x0008
213#define TYPERANGE_0_TO_32767 0x0010
214#define TYPERANGE_0_TO_65535 0x0020
215#define TYPERANGE_1_TO_65535 0x0040
216#define TYPERANGE_2_TO_3600 0x0080
217#define TYPERANGE_512_TO_16777215 0x0100
218#define TYPERANGE_AUTH 0x0200
219#define TYPERANGE_DIGEST 0x0400
220#define TYPERANGE_ISCSINAME 0x0800
221#define TYPERANGE_MARKINT 0x1000
222#define TYPERANGE_SESSIONTYPE 0x2000
223#define TYPERANGE_TARGETADDRESS 0x4000
224#define TYPERANGE_UTF8 0x8000
225
226#define IS_TYPERANGE_0_TO_2(p) ((p)->type_range & TYPERANGE_0_TO_2)
227#define IS_TYPERANGE_0_TO_3600(p) ((p)->type_range & TYPERANGE_0_TO_3600)
228#define IS_TYPERANGE_0_TO_32767(p) ((p)->type_range & TYPERANGE_0_TO_32767)
229#define IS_TYPERANGE_0_TO_65535(p) ((p)->type_range & TYPERANGE_0_TO_65535)
230#define IS_TYPERANGE_1_TO_65535(p) ((p)->type_range & TYPERANGE_1_TO_65535)
231#define IS_TYPERANGE_2_TO_3600(p) ((p)->type_range & TYPERANGE_2_TO_3600)
232#define IS_TYPERANGE_512_TO_16777215(p) ((p)->type_range & \
233 TYPERANGE_512_TO_16777215)
234#define IS_TYPERANGE_AUTH_PARAM(p) ((p)->type_range & TYPERANGE_AUTH)
235#define IS_TYPERANGE_DIGEST_PARAM(p) ((p)->type_range & TYPERANGE_DIGEST)
236#define IS_TYPERANGE_SESSIONTYPE(p) ((p)->type_range & \
237 TYPERANGE_SESSIONTYPE)
238
239/*
240 * struct iscsi_param->state
241 */
242#define PSTATE_ACCEPTOR 0x01
243#define PSTATE_NEGOTIATE 0x02
244#define PSTATE_PROPOSER 0x04
245#define PSTATE_IRRELEVANT 0x08
246#define PSTATE_REJECT 0x10
247#define PSTATE_REPLY_OPTIONAL 0x20
248#define PSTATE_RESPONSE_GOT 0x40
249#define PSTATE_RESPONSE_SENT 0x80
250
251#define IS_PSTATE_ACCEPTOR(p) ((p)->state & PSTATE_ACCEPTOR)
252#define IS_PSTATE_NEGOTIATE(p) ((p)->state & PSTATE_NEGOTIATE)
253#define IS_PSTATE_PROPOSER(p) ((p)->state & PSTATE_PROPOSER)
254#define IS_PSTATE_IRRELEVANT(p) ((p)->state & PSTATE_IRRELEVANT)
255#define IS_PSTATE_REJECT(p) ((p)->state & PSTATE_REJECT)
256#define IS_PSTATE_REPLY_OPTIONAL(p) ((p)->state & PSTATE_REPLY_OPTIONAL)
257#define IS_PSTATE_RESPONSE_GOT(p) ((p)->state & PSTATE_RESPONSE_GOT)
258#define IS_PSTATE_RESPONSE_SENT(p) ((p)->state & PSTATE_RESPONSE_SENT)
259
260#define SET_PSTATE_ACCEPTOR(p) ((p)->state |= PSTATE_ACCEPTOR)
261#define SET_PSTATE_NEGOTIATE(p) ((p)->state |= PSTATE_NEGOTIATE)
262#define SET_PSTATE_PROPOSER(p) ((p)->state |= PSTATE_PROPOSER)
263#define SET_PSTATE_IRRELEVANT(p) ((p)->state |= PSTATE_IRRELEVANT)
264#define SET_PSTATE_REJECT(p) ((p)->state |= PSTATE_REJECT)
265#define SET_PSTATE_REPLY_OPTIONAL(p) ((p)->state |= PSTATE_REPLY_OPTIONAL)
266#define SET_PSTATE_RESPONSE_GOT(p) ((p)->state |= PSTATE_RESPONSE_GOT)
267#define SET_PSTATE_RESPONSE_SENT(p) ((p)->state |= PSTATE_RESPONSE_SENT)
268
269#endif /* ISCSI_PARAMETERS_H */
diff --git a/drivers/target/iscsi/iscsi_target_seq_pdu_list.c b/drivers/target/iscsi/iscsi_target_seq_pdu_list.c
new file mode 100644
index 000000000000..fc694082bfc0
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_seq_pdu_list.c
@@ -0,0 +1,664 @@
1/*******************************************************************************
2 * This file contains main functions related to iSCSI DataSequenceInOrder=No
3 * and DataPDUInOrder=No.
4 *
5 \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
6 *
7 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
8 *
9 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 ******************************************************************************/
21
22#include <linux/slab.h>
23#include <linux/random.h>
24
25#include "iscsi_target_core.h"
26#include "iscsi_target_util.h"
27#include "iscsi_target_seq_pdu_list.h"
28
29#define OFFLOAD_BUF_SIZE 32768
30
31void iscsit_dump_seq_list(struct iscsi_cmd *cmd)
32{
33 int i;
34 struct iscsi_seq *seq;
35
36 pr_debug("Dumping Sequence List for ITT: 0x%08x:\n",
37 cmd->init_task_tag);
38
39 for (i = 0; i < cmd->seq_count; i++) {
40 seq = &cmd->seq_list[i];
41 pr_debug("i: %d, pdu_start: %d, pdu_count: %d,"
42 " offset: %d, xfer_len: %d, seq_send_order: %d,"
43 " seq_no: %d\n", i, seq->pdu_start, seq->pdu_count,
44 seq->offset, seq->xfer_len, seq->seq_send_order,
45 seq->seq_no);
46 }
47}
48
49void iscsit_dump_pdu_list(struct iscsi_cmd *cmd)
50{
51 int i;
52 struct iscsi_pdu *pdu;
53
54 pr_debug("Dumping PDU List for ITT: 0x%08x:\n",
55 cmd->init_task_tag);
56
57 for (i = 0; i < cmd->pdu_count; i++) {
58 pdu = &cmd->pdu_list[i];
59 pr_debug("i: %d, offset: %d, length: %d,"
60 " pdu_send_order: %d, seq_no: %d\n", i, pdu->offset,
61 pdu->length, pdu->pdu_send_order, pdu->seq_no);
62 }
63}
64
65static void iscsit_ordered_seq_lists(
66 struct iscsi_cmd *cmd,
67 u8 type)
68{
69 u32 i, seq_count = 0;
70
71 for (i = 0; i < cmd->seq_count; i++) {
72 if (cmd->seq_list[i].type != SEQTYPE_NORMAL)
73 continue;
74 cmd->seq_list[i].seq_send_order = seq_count++;
75 }
76}
77
78static void iscsit_ordered_pdu_lists(
79 struct iscsi_cmd *cmd,
80 u8 type)
81{
82 u32 i, pdu_send_order = 0, seq_no = 0;
83
84 for (i = 0; i < cmd->pdu_count; i++) {
85redo:
86 if (cmd->pdu_list[i].seq_no == seq_no) {
87 cmd->pdu_list[i].pdu_send_order = pdu_send_order++;
88 continue;
89 }
90 seq_no++;
91 pdu_send_order = 0;
92 goto redo;
93 }
94}
95
96/*
97 * Generate count random values into array.
98 * Use 0x80000000 to mark generates valued in array[].
99 */
100static void iscsit_create_random_array(u32 *array, u32 count)
101{
102 int i, j, k;
103
104 if (count == 1) {
105 array[0] = 0;
106 return;
107 }
108
109 for (i = 0; i < count; i++) {
110redo:
111 get_random_bytes(&j, sizeof(u32));
112 j = (1 + (int) (9999 + 1) - j) % count;
113 for (k = 0; k < i + 1; k++) {
114 j |= 0x80000000;
115 if ((array[k] & 0x80000000) && (array[k] == j))
116 goto redo;
117 }
118 array[i] = j;
119 }
120
121 for (i = 0; i < count; i++)
122 array[i] &= ~0x80000000;
123}
124
125static int iscsit_randomize_pdu_lists(
126 struct iscsi_cmd *cmd,
127 u8 type)
128{
129 int i = 0;
130 u32 *array, pdu_count, seq_count = 0, seq_no = 0, seq_offset = 0;
131
132 for (pdu_count = 0; pdu_count < cmd->pdu_count; pdu_count++) {
133redo:
134 if (cmd->pdu_list[pdu_count].seq_no == seq_no) {
135 seq_count++;
136 continue;
137 }
138 array = kzalloc(seq_count * sizeof(u32), GFP_KERNEL);
139 if (!array) {
140 pr_err("Unable to allocate memory"
141 " for random array.\n");
142 return -1;
143 }
144 iscsit_create_random_array(array, seq_count);
145
146 for (i = 0; i < seq_count; i++)
147 cmd->pdu_list[seq_offset+i].pdu_send_order = array[i];
148
149 kfree(array);
150
151 seq_offset += seq_count;
152 seq_count = 0;
153 seq_no++;
154 goto redo;
155 }
156
157 if (seq_count) {
158 array = kzalloc(seq_count * sizeof(u32), GFP_KERNEL);
159 if (!array) {
160 pr_err("Unable to allocate memory for"
161 " random array.\n");
162 return -1;
163 }
164 iscsit_create_random_array(array, seq_count);
165
166 for (i = 0; i < seq_count; i++)
167 cmd->pdu_list[seq_offset+i].pdu_send_order = array[i];
168
169 kfree(array);
170 }
171
172 return 0;
173}
174
175static int iscsit_randomize_seq_lists(
176 struct iscsi_cmd *cmd,
177 u8 type)
178{
179 int i, j = 0;
180 u32 *array, seq_count = cmd->seq_count;
181
182 if ((type == PDULIST_IMMEDIATE) || (type == PDULIST_UNSOLICITED))
183 seq_count--;
184 else if (type == PDULIST_IMMEDIATE_AND_UNSOLICITED)
185 seq_count -= 2;
186
187 if (!seq_count)
188 return 0;
189
190 array = kzalloc(seq_count * sizeof(u32), GFP_KERNEL);
191 if (!array) {
192 pr_err("Unable to allocate memory for random array.\n");
193 return -1;
194 }
195 iscsit_create_random_array(array, seq_count);
196
197 for (i = 0; i < cmd->seq_count; i++) {
198 if (cmd->seq_list[i].type != SEQTYPE_NORMAL)
199 continue;
200 cmd->seq_list[i].seq_send_order = array[j++];
201 }
202
203 kfree(array);
204 return 0;
205}
206
207static void iscsit_determine_counts_for_list(
208 struct iscsi_cmd *cmd,
209 struct iscsi_build_list *bl,
210 u32 *seq_count,
211 u32 *pdu_count)
212{
213 int check_immediate = 0;
214 u32 burstlength = 0, offset = 0;
215 u32 unsolicited_data_length = 0;
216 struct iscsi_conn *conn = cmd->conn;
217
218 if ((bl->type == PDULIST_IMMEDIATE) ||
219 (bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED))
220 check_immediate = 1;
221
222 if ((bl->type == PDULIST_UNSOLICITED) ||
223 (bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED))
224 unsolicited_data_length = (cmd->data_length >
225 conn->sess->sess_ops->FirstBurstLength) ?
226 conn->sess->sess_ops->FirstBurstLength : cmd->data_length;
227
228 while (offset < cmd->data_length) {
229 *pdu_count += 1;
230
231 if (check_immediate) {
232 check_immediate = 0;
233 offset += bl->immediate_data_length;
234 *seq_count += 1;
235 if (unsolicited_data_length)
236 unsolicited_data_length -=
237 bl->immediate_data_length;
238 continue;
239 }
240 if (unsolicited_data_length > 0) {
241 if ((offset + conn->conn_ops->MaxRecvDataSegmentLength)
242 >= cmd->data_length) {
243 unsolicited_data_length -=
244 (cmd->data_length - offset);
245 offset += (cmd->data_length - offset);
246 continue;
247 }
248 if ((offset + conn->conn_ops->MaxRecvDataSegmentLength)
249 >= conn->sess->sess_ops->FirstBurstLength) {
250 unsolicited_data_length -=
251 (conn->sess->sess_ops->FirstBurstLength -
252 offset);
253 offset += (conn->sess->sess_ops->FirstBurstLength -
254 offset);
255 burstlength = 0;
256 *seq_count += 1;
257 continue;
258 }
259
260 offset += conn->conn_ops->MaxRecvDataSegmentLength;
261 unsolicited_data_length -=
262 conn->conn_ops->MaxRecvDataSegmentLength;
263 continue;
264 }
265 if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >=
266 cmd->data_length) {
267 offset += (cmd->data_length - offset);
268 continue;
269 }
270 if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >=
271 conn->sess->sess_ops->MaxBurstLength) {
272 offset += (conn->sess->sess_ops->MaxBurstLength -
273 burstlength);
274 burstlength = 0;
275 *seq_count += 1;
276 continue;
277 }
278
279 burstlength += conn->conn_ops->MaxRecvDataSegmentLength;
280 offset += conn->conn_ops->MaxRecvDataSegmentLength;
281 }
282}
283
284
285/*
286 * Builds PDU and/or Sequence list, called while DataSequenceInOrder=No
287 * and DataPDUInOrder=No.
288 */
289static int iscsit_build_pdu_and_seq_list(
290 struct iscsi_cmd *cmd,
291 struct iscsi_build_list *bl)
292{
293 int check_immediate = 0, datapduinorder, datasequenceinorder;
294 u32 burstlength = 0, offset = 0, i = 0;
295 u32 pdu_count = 0, seq_no = 0, unsolicited_data_length = 0;
296 struct iscsi_conn *conn = cmd->conn;
297 struct iscsi_pdu *pdu = cmd->pdu_list;
298 struct iscsi_seq *seq = cmd->seq_list;
299
300 datapduinorder = conn->sess->sess_ops->DataPDUInOrder;
301 datasequenceinorder = conn->sess->sess_ops->DataSequenceInOrder;
302
303 if ((bl->type == PDULIST_IMMEDIATE) ||
304 (bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED))
305 check_immediate = 1;
306
307 if ((bl->type == PDULIST_UNSOLICITED) ||
308 (bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED))
309 unsolicited_data_length = (cmd->data_length >
310 conn->sess->sess_ops->FirstBurstLength) ?
311 conn->sess->sess_ops->FirstBurstLength : cmd->data_length;
312
313 while (offset < cmd->data_length) {
314 pdu_count++;
315 if (!datapduinorder) {
316 pdu[i].offset = offset;
317 pdu[i].seq_no = seq_no;
318 }
319 if (!datasequenceinorder && (pdu_count == 1)) {
320 seq[seq_no].pdu_start = i;
321 seq[seq_no].seq_no = seq_no;
322 seq[seq_no].offset = offset;
323 seq[seq_no].orig_offset = offset;
324 }
325
326 if (check_immediate) {
327 check_immediate = 0;
328 if (!datapduinorder) {
329 pdu[i].type = PDUTYPE_IMMEDIATE;
330 pdu[i++].length = bl->immediate_data_length;
331 }
332 if (!datasequenceinorder) {
333 seq[seq_no].type = SEQTYPE_IMMEDIATE;
334 seq[seq_no].pdu_count = 1;
335 seq[seq_no].xfer_len =
336 bl->immediate_data_length;
337 }
338 offset += bl->immediate_data_length;
339 pdu_count = 0;
340 seq_no++;
341 if (unsolicited_data_length)
342 unsolicited_data_length -=
343 bl->immediate_data_length;
344 continue;
345 }
346 if (unsolicited_data_length > 0) {
347 if ((offset +
348 conn->conn_ops->MaxRecvDataSegmentLength) >=
349 cmd->data_length) {
350 if (!datapduinorder) {
351 pdu[i].type = PDUTYPE_UNSOLICITED;
352 pdu[i].length =
353 (cmd->data_length - offset);
354 }
355 if (!datasequenceinorder) {
356 seq[seq_no].type = SEQTYPE_UNSOLICITED;
357 seq[seq_no].pdu_count = pdu_count;
358 seq[seq_no].xfer_len = (burstlength +
359 (cmd->data_length - offset));
360 }
361 unsolicited_data_length -=
362 (cmd->data_length - offset);
363 offset += (cmd->data_length - offset);
364 continue;
365 }
366 if ((offset +
367 conn->conn_ops->MaxRecvDataSegmentLength) >=
368 conn->sess->sess_ops->FirstBurstLength) {
369 if (!datapduinorder) {
370 pdu[i].type = PDUTYPE_UNSOLICITED;
371 pdu[i++].length =
372 (conn->sess->sess_ops->FirstBurstLength -
373 offset);
374 }
375 if (!datasequenceinorder) {
376 seq[seq_no].type = SEQTYPE_UNSOLICITED;
377 seq[seq_no].pdu_count = pdu_count;
378 seq[seq_no].xfer_len = (burstlength +
379 (conn->sess->sess_ops->FirstBurstLength -
380 offset));
381 }
382 unsolicited_data_length -=
383 (conn->sess->sess_ops->FirstBurstLength -
384 offset);
385 offset += (conn->sess->sess_ops->FirstBurstLength -
386 offset);
387 burstlength = 0;
388 pdu_count = 0;
389 seq_no++;
390 continue;
391 }
392
393 if (!datapduinorder) {
394 pdu[i].type = PDUTYPE_UNSOLICITED;
395 pdu[i++].length =
396 conn->conn_ops->MaxRecvDataSegmentLength;
397 }
398 burstlength += conn->conn_ops->MaxRecvDataSegmentLength;
399 offset += conn->conn_ops->MaxRecvDataSegmentLength;
400 unsolicited_data_length -=
401 conn->conn_ops->MaxRecvDataSegmentLength;
402 continue;
403 }
404 if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >=
405 cmd->data_length) {
406 if (!datapduinorder) {
407 pdu[i].type = PDUTYPE_NORMAL;
408 pdu[i].length = (cmd->data_length - offset);
409 }
410 if (!datasequenceinorder) {
411 seq[seq_no].type = SEQTYPE_NORMAL;
412 seq[seq_no].pdu_count = pdu_count;
413 seq[seq_no].xfer_len = (burstlength +
414 (cmd->data_length - offset));
415 }
416 offset += (cmd->data_length - offset);
417 continue;
418 }
419 if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >=
420 conn->sess->sess_ops->MaxBurstLength) {
421 if (!datapduinorder) {
422 pdu[i].type = PDUTYPE_NORMAL;
423 pdu[i++].length =
424 (conn->sess->sess_ops->MaxBurstLength -
425 burstlength);
426 }
427 if (!datasequenceinorder) {
428 seq[seq_no].type = SEQTYPE_NORMAL;
429 seq[seq_no].pdu_count = pdu_count;
430 seq[seq_no].xfer_len = (burstlength +
431 (conn->sess->sess_ops->MaxBurstLength -
432 burstlength));
433 }
434 offset += (conn->sess->sess_ops->MaxBurstLength -
435 burstlength);
436 burstlength = 0;
437 pdu_count = 0;
438 seq_no++;
439 continue;
440 }
441
442 if (!datapduinorder) {
443 pdu[i].type = PDUTYPE_NORMAL;
444 pdu[i++].length =
445 conn->conn_ops->MaxRecvDataSegmentLength;
446 }
447 burstlength += conn->conn_ops->MaxRecvDataSegmentLength;
448 offset += conn->conn_ops->MaxRecvDataSegmentLength;
449 }
450
451 if (!datasequenceinorder) {
452 if (bl->data_direction & ISCSI_PDU_WRITE) {
453 if (bl->randomize & RANDOM_R2T_OFFSETS) {
454 if (iscsit_randomize_seq_lists(cmd, bl->type)
455 < 0)
456 return -1;
457 } else
458 iscsit_ordered_seq_lists(cmd, bl->type);
459 } else if (bl->data_direction & ISCSI_PDU_READ) {
460 if (bl->randomize & RANDOM_DATAIN_SEQ_OFFSETS) {
461 if (iscsit_randomize_seq_lists(cmd, bl->type)
462 < 0)
463 return -1;
464 } else
465 iscsit_ordered_seq_lists(cmd, bl->type);
466 }
467#if 0
468 iscsit_dump_seq_list(cmd);
469#endif
470 }
471 if (!datapduinorder) {
472 if (bl->data_direction & ISCSI_PDU_WRITE) {
473 if (bl->randomize & RANDOM_DATAOUT_PDU_OFFSETS) {
474 if (iscsit_randomize_pdu_lists(cmd, bl->type)
475 < 0)
476 return -1;
477 } else
478 iscsit_ordered_pdu_lists(cmd, bl->type);
479 } else if (bl->data_direction & ISCSI_PDU_READ) {
480 if (bl->randomize & RANDOM_DATAIN_PDU_OFFSETS) {
481 if (iscsit_randomize_pdu_lists(cmd, bl->type)
482 < 0)
483 return -1;
484 } else
485 iscsit_ordered_pdu_lists(cmd, bl->type);
486 }
487#if 0
488 iscsit_dump_pdu_list(cmd);
489#endif
490 }
491
492 return 0;
493}
494
495/*
496 * Only called while DataSequenceInOrder=No or DataPDUInOrder=No.
497 */
498int iscsit_do_build_list(
499 struct iscsi_cmd *cmd,
500 struct iscsi_build_list *bl)
501{
502 u32 pdu_count = 0, seq_count = 1;
503 struct iscsi_conn *conn = cmd->conn;
504 struct iscsi_pdu *pdu = NULL;
505 struct iscsi_seq *seq = NULL;
506
507 iscsit_determine_counts_for_list(cmd, bl, &seq_count, &pdu_count);
508
509 if (!conn->sess->sess_ops->DataSequenceInOrder) {
510 seq = kzalloc(seq_count * sizeof(struct iscsi_seq), GFP_ATOMIC);
511 if (!seq) {
512 pr_err("Unable to allocate struct iscsi_seq list\n");
513 return -1;
514 }
515 cmd->seq_list = seq;
516 cmd->seq_count = seq_count;
517 }
518
519 if (!conn->sess->sess_ops->DataPDUInOrder) {
520 pdu = kzalloc(pdu_count * sizeof(struct iscsi_pdu), GFP_ATOMIC);
521 if (!pdu) {
522 pr_err("Unable to allocate struct iscsi_pdu list.\n");
523 kfree(seq);
524 return -1;
525 }
526 cmd->pdu_list = pdu;
527 cmd->pdu_count = pdu_count;
528 }
529
530 return iscsit_build_pdu_and_seq_list(cmd, bl);
531}
532
533struct iscsi_pdu *iscsit_get_pdu_holder(
534 struct iscsi_cmd *cmd,
535 u32 offset,
536 u32 length)
537{
538 u32 i;
539 struct iscsi_pdu *pdu = NULL;
540
541 if (!cmd->pdu_list) {
542 pr_err("struct iscsi_cmd->pdu_list is NULL!\n");
543 return NULL;
544 }
545
546 pdu = &cmd->pdu_list[0];
547
548 for (i = 0; i < cmd->pdu_count; i++)
549 if ((pdu[i].offset == offset) && (pdu[i].length == length))
550 return &pdu[i];
551
552 pr_err("Unable to locate PDU holder for ITT: 0x%08x, Offset:"
553 " %u, Length: %u\n", cmd->init_task_tag, offset, length);
554 return NULL;
555}
556
557struct iscsi_pdu *iscsit_get_pdu_holder_for_seq(
558 struct iscsi_cmd *cmd,
559 struct iscsi_seq *seq)
560{
561 u32 i;
562 struct iscsi_conn *conn = cmd->conn;
563 struct iscsi_pdu *pdu = NULL;
564
565 if (!cmd->pdu_list) {
566 pr_err("struct iscsi_cmd->pdu_list is NULL!\n");
567 return NULL;
568 }
569
570 if (conn->sess->sess_ops->DataSequenceInOrder) {
571redo:
572 pdu = &cmd->pdu_list[cmd->pdu_start];
573
574 for (i = 0; pdu[i].seq_no != cmd->seq_no; i++) {
575#if 0
576 pr_debug("pdu[i].seq_no: %d, pdu[i].pdu"
577 "_send_order: %d, pdu[i].offset: %d,"
578 " pdu[i].length: %d\n", pdu[i].seq_no,
579 pdu[i].pdu_send_order, pdu[i].offset,
580 pdu[i].length);
581#endif
582 if (pdu[i].pdu_send_order == cmd->pdu_send_order) {
583 cmd->pdu_send_order++;
584 return &pdu[i];
585 }
586 }
587
588 cmd->pdu_start += cmd->pdu_send_order;
589 cmd->pdu_send_order = 0;
590 cmd->seq_no++;
591
592 if (cmd->pdu_start < cmd->pdu_count)
593 goto redo;
594
595 pr_err("Command ITT: 0x%08x unable to locate"
596 " struct iscsi_pdu for cmd->pdu_send_order: %u.\n",
597 cmd->init_task_tag, cmd->pdu_send_order);
598 return NULL;
599 } else {
600 if (!seq) {
601 pr_err("struct iscsi_seq is NULL!\n");
602 return NULL;
603 }
604#if 0
605 pr_debug("seq->pdu_start: %d, seq->pdu_count: %d,"
606 " seq->seq_no: %d\n", seq->pdu_start, seq->pdu_count,
607 seq->seq_no);
608#endif
609 pdu = &cmd->pdu_list[seq->pdu_start];
610
611 if (seq->pdu_send_order == seq->pdu_count) {
612 pr_err("Command ITT: 0x%08x seq->pdu_send"
613 "_order: %u equals seq->pdu_count: %u\n",
614 cmd->init_task_tag, seq->pdu_send_order,
615 seq->pdu_count);
616 return NULL;
617 }
618
619 for (i = 0; i < seq->pdu_count; i++) {
620 if (pdu[i].pdu_send_order == seq->pdu_send_order) {
621 seq->pdu_send_order++;
622 return &pdu[i];
623 }
624 }
625
626 pr_err("Command ITT: 0x%08x unable to locate iscsi"
627 "_pdu_t for seq->pdu_send_order: %u.\n",
628 cmd->init_task_tag, seq->pdu_send_order);
629 return NULL;
630 }
631
632 return NULL;
633}
634
635struct iscsi_seq *iscsit_get_seq_holder(
636 struct iscsi_cmd *cmd,
637 u32 offset,
638 u32 length)
639{
640 u32 i;
641
642 if (!cmd->seq_list) {
643 pr_err("struct iscsi_cmd->seq_list is NULL!\n");
644 return NULL;
645 }
646
647 for (i = 0; i < cmd->seq_count; i++) {
648#if 0
649 pr_debug("seq_list[i].orig_offset: %d, seq_list[i]."
650 "xfer_len: %d, seq_list[i].seq_no %u\n",
651 cmd->seq_list[i].orig_offset, cmd->seq_list[i].xfer_len,
652 cmd->seq_list[i].seq_no);
653#endif
654 if ((cmd->seq_list[i].orig_offset +
655 cmd->seq_list[i].xfer_len) >=
656 (offset + length))
657 return &cmd->seq_list[i];
658 }
659
660 pr_err("Unable to locate Sequence holder for ITT: 0x%08x,"
661 " Offset: %u, Length: %u\n", cmd->init_task_tag, offset,
662 length);
663 return NULL;
664}
diff --git a/drivers/target/iscsi/iscsi_target_seq_pdu_list.h b/drivers/target/iscsi/iscsi_target_seq_pdu_list.h
new file mode 100644
index 000000000000..0d52a10e3069
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_seq_pdu_list.h
@@ -0,0 +1,86 @@
1#ifndef ISCSI_SEQ_AND_PDU_LIST_H
2#define ISCSI_SEQ_AND_PDU_LIST_H
3
4/* struct iscsi_pdu->status */
5#define DATAOUT_PDU_SENT 1
6
7/* struct iscsi_seq->type */
8#define SEQTYPE_IMMEDIATE 1
9#define SEQTYPE_UNSOLICITED 2
10#define SEQTYPE_NORMAL 3
11
12/* struct iscsi_seq->status */
13#define DATAOUT_SEQUENCE_GOT_R2T 1
14#define DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY 2
15#define DATAOUT_SEQUENCE_COMPLETE 3
16
17/* iscsi_determine_counts_for_list() type */
18#define PDULIST_NORMAL 1
19#define PDULIST_IMMEDIATE 2
20#define PDULIST_UNSOLICITED 3
21#define PDULIST_IMMEDIATE_AND_UNSOLICITED 4
22
23/* struct iscsi_pdu->type */
24#define PDUTYPE_IMMEDIATE 1
25#define PDUTYPE_UNSOLICITED 2
26#define PDUTYPE_NORMAL 3
27
28/* struct iscsi_pdu->status */
29#define ISCSI_PDU_NOT_RECEIVED 0
30#define ISCSI_PDU_RECEIVED_OK 1
31#define ISCSI_PDU_CRC_FAILED 2
32#define ISCSI_PDU_TIMED_OUT 3
33
34/* struct iscsi_build_list->randomize */
35#define RANDOM_DATAIN_PDU_OFFSETS 0x01
36#define RANDOM_DATAIN_SEQ_OFFSETS 0x02
37#define RANDOM_DATAOUT_PDU_OFFSETS 0x04
38#define RANDOM_R2T_OFFSETS 0x08
39
40/* struct iscsi_build_list->data_direction */
41#define ISCSI_PDU_READ 0x01
42#define ISCSI_PDU_WRITE 0x02
43
44struct iscsi_build_list {
45 int data_direction;
46 int randomize;
47 int type;
48 int immediate_data_length;
49};
50
51struct iscsi_pdu {
52 int status;
53 int type;
54 u8 flags;
55 u32 data_sn;
56 u32 length;
57 u32 offset;
58 u32 pdu_send_order;
59 u32 seq_no;
60} ____cacheline_aligned;
61
62struct iscsi_seq {
63 int sent;
64 int status;
65 int type;
66 u32 data_sn;
67 u32 first_datasn;
68 u32 last_datasn;
69 u32 next_burst_len;
70 u32 pdu_start;
71 u32 pdu_count;
72 u32 offset;
73 u32 orig_offset;
74 u32 pdu_send_order;
75 u32 r2t_sn;
76 u32 seq_send_order;
77 u32 seq_no;
78 u32 xfer_len;
79} ____cacheline_aligned;
80
81extern int iscsit_do_build_list(struct iscsi_cmd *, struct iscsi_build_list *);
82extern struct iscsi_pdu *iscsit_get_pdu_holder(struct iscsi_cmd *, u32, u32);
83extern struct iscsi_pdu *iscsit_get_pdu_holder_for_seq(struct iscsi_cmd *, struct iscsi_seq *);
84extern struct iscsi_seq *iscsit_get_seq_holder(struct iscsi_cmd *, u32, u32);
85
86#endif /* ISCSI_SEQ_AND_PDU_LIST_H */
diff --git a/drivers/target/iscsi/iscsi_target_stat.c b/drivers/target/iscsi/iscsi_target_stat.c
new file mode 100644
index 000000000000..bbdbe9301b27
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_stat.c
@@ -0,0 +1,950 @@
1/*******************************************************************************
2 * Modern ConfigFS group context specific iSCSI statistics based on original
3 * iscsi_target_mib.c code
4 *
5 * Copyright (c) 2011 Rising Tide Systems
6 *
7 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
8 *
9 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 ******************************************************************************/
21
22#include <linux/configfs.h>
23#include <scsi/iscsi_proto.h>
24#include <target/target_core_base.h>
25#include <target/target_core_transport.h>
26#include <target/configfs_macros.h>
27
28#include "iscsi_target_core.h"
29#include "iscsi_target_parameters.h"
30#include "iscsi_target_device.h"
31#include "iscsi_target_tpg.h"
32#include "iscsi_target_util.h"
33#include "iscsi_target_stat.h"
34
35#ifndef INITIAL_JIFFIES
36#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
37#endif
38
39/* Instance Attributes Table */
40#define ISCSI_INST_NUM_NODES 1
41#define ISCSI_INST_DESCR "Storage Engine Target"
42#define ISCSI_INST_LAST_FAILURE_TYPE 0
43#define ISCSI_DISCONTINUITY_TIME 0
44
45#define ISCSI_NODE_INDEX 1
46
47#define ISPRINT(a) ((a >= ' ') && (a <= '~'))
48
49/****************************************************************************
50 * iSCSI MIB Tables
51 ****************************************************************************/
52/*
53 * Instance Attributes Table
54 */
55CONFIGFS_EATTR_STRUCT(iscsi_stat_instance, iscsi_wwn_stat_grps);
56#define ISCSI_STAT_INSTANCE_ATTR(_name, _mode) \
57static struct iscsi_stat_instance_attribute \
58 iscsi_stat_instance_##_name = \
59 __CONFIGFS_EATTR(_name, _mode, \
60 iscsi_stat_instance_show_attr_##_name, \
61 iscsi_stat_instance_store_attr_##_name);
62
63#define ISCSI_STAT_INSTANCE_ATTR_RO(_name) \
64static struct iscsi_stat_instance_attribute \
65 iscsi_stat_instance_##_name = \
66 __CONFIGFS_EATTR_RO(_name, \
67 iscsi_stat_instance_show_attr_##_name);
68
69static ssize_t iscsi_stat_instance_show_attr_inst(
70 struct iscsi_wwn_stat_grps *igrps, char *page)
71{
72 struct iscsi_tiqn *tiqn = container_of(igrps,
73 struct iscsi_tiqn, tiqn_stat_grps);
74
75 return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
76}
77ISCSI_STAT_INSTANCE_ATTR_RO(inst);
78
79static ssize_t iscsi_stat_instance_show_attr_min_ver(
80 struct iscsi_wwn_stat_grps *igrps, char *page)
81{
82 return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DRAFT20_VERSION);
83}
84ISCSI_STAT_INSTANCE_ATTR_RO(min_ver);
85
86static ssize_t iscsi_stat_instance_show_attr_max_ver(
87 struct iscsi_wwn_stat_grps *igrps, char *page)
88{
89 return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DRAFT20_VERSION);
90}
91ISCSI_STAT_INSTANCE_ATTR_RO(max_ver);
92
93static ssize_t iscsi_stat_instance_show_attr_portals(
94 struct iscsi_wwn_stat_grps *igrps, char *page)
95{
96 struct iscsi_tiqn *tiqn = container_of(igrps,
97 struct iscsi_tiqn, tiqn_stat_grps);
98
99 return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_num_tpg_nps);
100}
101ISCSI_STAT_INSTANCE_ATTR_RO(portals);
102
103static ssize_t iscsi_stat_instance_show_attr_nodes(
104 struct iscsi_wwn_stat_grps *igrps, char *page)
105{
106 return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_INST_NUM_NODES);
107}
108ISCSI_STAT_INSTANCE_ATTR_RO(nodes);
109
110static ssize_t iscsi_stat_instance_show_attr_sessions(
111 struct iscsi_wwn_stat_grps *igrps, char *page)
112{
113 struct iscsi_tiqn *tiqn = container_of(igrps,
114 struct iscsi_tiqn, tiqn_stat_grps);
115
116 return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_nsessions);
117}
118ISCSI_STAT_INSTANCE_ATTR_RO(sessions);
119
120static ssize_t iscsi_stat_instance_show_attr_fail_sess(
121 struct iscsi_wwn_stat_grps *igrps, char *page)
122{
123 struct iscsi_tiqn *tiqn = container_of(igrps,
124 struct iscsi_tiqn, tiqn_stat_grps);
125 struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
126 u32 sess_err_count;
127
128 spin_lock_bh(&sess_err->lock);
129 sess_err_count = (sess_err->digest_errors +
130 sess_err->cxn_timeout_errors +
131 sess_err->pdu_format_errors);
132 spin_unlock_bh(&sess_err->lock);
133
134 return snprintf(page, PAGE_SIZE, "%u\n", sess_err_count);
135}
136ISCSI_STAT_INSTANCE_ATTR_RO(fail_sess);
137
138static ssize_t iscsi_stat_instance_show_attr_fail_type(
139 struct iscsi_wwn_stat_grps *igrps, char *page)
140{
141 struct iscsi_tiqn *tiqn = container_of(igrps,
142 struct iscsi_tiqn, tiqn_stat_grps);
143 struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
144
145 return snprintf(page, PAGE_SIZE, "%u\n",
146 sess_err->last_sess_failure_type);
147}
148ISCSI_STAT_INSTANCE_ATTR_RO(fail_type);
149
150static ssize_t iscsi_stat_instance_show_attr_fail_rem_name(
151 struct iscsi_wwn_stat_grps *igrps, char *page)
152{
153 struct iscsi_tiqn *tiqn = container_of(igrps,
154 struct iscsi_tiqn, tiqn_stat_grps);
155 struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
156
157 return snprintf(page, PAGE_SIZE, "%s\n",
158 sess_err->last_sess_fail_rem_name[0] ?
159 sess_err->last_sess_fail_rem_name : NONE);
160}
161ISCSI_STAT_INSTANCE_ATTR_RO(fail_rem_name);
162
163static ssize_t iscsi_stat_instance_show_attr_disc_time(
164 struct iscsi_wwn_stat_grps *igrps, char *page)
165{
166 return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DISCONTINUITY_TIME);
167}
168ISCSI_STAT_INSTANCE_ATTR_RO(disc_time);
169
170static ssize_t iscsi_stat_instance_show_attr_description(
171 struct iscsi_wwn_stat_grps *igrps, char *page)
172{
173 return snprintf(page, PAGE_SIZE, "%s\n", ISCSI_INST_DESCR);
174}
175ISCSI_STAT_INSTANCE_ATTR_RO(description);
176
177static ssize_t iscsi_stat_instance_show_attr_vendor(
178 struct iscsi_wwn_stat_grps *igrps, char *page)
179{
180 return snprintf(page, PAGE_SIZE, "RisingTide Systems iSCSI-Target\n");
181}
182ISCSI_STAT_INSTANCE_ATTR_RO(vendor);
183
184static ssize_t iscsi_stat_instance_show_attr_version(
185 struct iscsi_wwn_stat_grps *igrps, char *page)
186{
187 return snprintf(page, PAGE_SIZE, "%s\n", ISCSIT_VERSION);
188}
189ISCSI_STAT_INSTANCE_ATTR_RO(version);
190
191CONFIGFS_EATTR_OPS(iscsi_stat_instance, iscsi_wwn_stat_grps,
192 iscsi_instance_group);
193
194static struct configfs_attribute *iscsi_stat_instance_attrs[] = {
195 &iscsi_stat_instance_inst.attr,
196 &iscsi_stat_instance_min_ver.attr,
197 &iscsi_stat_instance_max_ver.attr,
198 &iscsi_stat_instance_portals.attr,
199 &iscsi_stat_instance_nodes.attr,
200 &iscsi_stat_instance_sessions.attr,
201 &iscsi_stat_instance_fail_sess.attr,
202 &iscsi_stat_instance_fail_type.attr,
203 &iscsi_stat_instance_fail_rem_name.attr,
204 &iscsi_stat_instance_disc_time.attr,
205 &iscsi_stat_instance_description.attr,
206 &iscsi_stat_instance_vendor.attr,
207 &iscsi_stat_instance_version.attr,
208 NULL,
209};
210
211static struct configfs_item_operations iscsi_stat_instance_item_ops = {
212 .show_attribute = iscsi_stat_instance_attr_show,
213 .store_attribute = iscsi_stat_instance_attr_store,
214};
215
216struct config_item_type iscsi_stat_instance_cit = {
217 .ct_item_ops = &iscsi_stat_instance_item_ops,
218 .ct_attrs = iscsi_stat_instance_attrs,
219 .ct_owner = THIS_MODULE,
220};
221
222/*
223 * Instance Session Failure Stats Table
224 */
225CONFIGFS_EATTR_STRUCT(iscsi_stat_sess_err, iscsi_wwn_stat_grps);
226#define ISCSI_STAT_SESS_ERR_ATTR(_name, _mode) \
227static struct iscsi_stat_sess_err_attribute \
228 iscsi_stat_sess_err_##_name = \
229 __CONFIGFS_EATTR(_name, _mode, \
230 iscsi_stat_sess_err_show_attr_##_name, \
231 iscsi_stat_sess_err_store_attr_##_name);
232
233#define ISCSI_STAT_SESS_ERR_ATTR_RO(_name) \
234static struct iscsi_stat_sess_err_attribute \
235 iscsi_stat_sess_err_##_name = \
236 __CONFIGFS_EATTR_RO(_name, \
237 iscsi_stat_sess_err_show_attr_##_name);
238
239static ssize_t iscsi_stat_sess_err_show_attr_inst(
240 struct iscsi_wwn_stat_grps *igrps, char *page)
241{
242 struct iscsi_tiqn *tiqn = container_of(igrps,
243 struct iscsi_tiqn, tiqn_stat_grps);
244
245 return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
246}
247ISCSI_STAT_SESS_ERR_ATTR_RO(inst);
248
249static ssize_t iscsi_stat_sess_err_show_attr_digest_errors(
250 struct iscsi_wwn_stat_grps *igrps, char *page)
251{
252 struct iscsi_tiqn *tiqn = container_of(igrps,
253 struct iscsi_tiqn, tiqn_stat_grps);
254 struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
255
256 return snprintf(page, PAGE_SIZE, "%u\n", sess_err->digest_errors);
257}
258ISCSI_STAT_SESS_ERR_ATTR_RO(digest_errors);
259
260static ssize_t iscsi_stat_sess_err_show_attr_cxn_errors(
261 struct iscsi_wwn_stat_grps *igrps, char *page)
262{
263 struct iscsi_tiqn *tiqn = container_of(igrps,
264 struct iscsi_tiqn, tiqn_stat_grps);
265 struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
266
267 return snprintf(page, PAGE_SIZE, "%u\n", sess_err->cxn_timeout_errors);
268}
269ISCSI_STAT_SESS_ERR_ATTR_RO(cxn_errors);
270
271static ssize_t iscsi_stat_sess_err_show_attr_format_errors(
272 struct iscsi_wwn_stat_grps *igrps, char *page)
273{
274 struct iscsi_tiqn *tiqn = container_of(igrps,
275 struct iscsi_tiqn, tiqn_stat_grps);
276 struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats;
277
278 return snprintf(page, PAGE_SIZE, "%u\n", sess_err->pdu_format_errors);
279}
280ISCSI_STAT_SESS_ERR_ATTR_RO(format_errors);
281
282CONFIGFS_EATTR_OPS(iscsi_stat_sess_err, iscsi_wwn_stat_grps,
283 iscsi_sess_err_group);
284
285static struct configfs_attribute *iscsi_stat_sess_err_attrs[] = {
286 &iscsi_stat_sess_err_inst.attr,
287 &iscsi_stat_sess_err_digest_errors.attr,
288 &iscsi_stat_sess_err_cxn_errors.attr,
289 &iscsi_stat_sess_err_format_errors.attr,
290 NULL,
291};
292
293static struct configfs_item_operations iscsi_stat_sess_err_item_ops = {
294 .show_attribute = iscsi_stat_sess_err_attr_show,
295 .store_attribute = iscsi_stat_sess_err_attr_store,
296};
297
298struct config_item_type iscsi_stat_sess_err_cit = {
299 .ct_item_ops = &iscsi_stat_sess_err_item_ops,
300 .ct_attrs = iscsi_stat_sess_err_attrs,
301 .ct_owner = THIS_MODULE,
302};
303
304/*
305 * Target Attributes Table
306 */
307CONFIGFS_EATTR_STRUCT(iscsi_stat_tgt_attr, iscsi_wwn_stat_grps);
308#define ISCSI_STAT_TGT_ATTR(_name, _mode) \
309static struct iscsi_stat_tgt_attr_attribute \
310 iscsi_stat_tgt_attr_##_name = \
311 __CONFIGFS_EATTR(_name, _mode, \
312 iscsi_stat_tgt-attr_show_attr_##_name, \
313 iscsi_stat_tgt_attr_store_attr_##_name);
314
315#define ISCSI_STAT_TGT_ATTR_RO(_name) \
316static struct iscsi_stat_tgt_attr_attribute \
317 iscsi_stat_tgt_attr_##_name = \
318 __CONFIGFS_EATTR_RO(_name, \
319 iscsi_stat_tgt_attr_show_attr_##_name);
320
321static ssize_t iscsi_stat_tgt_attr_show_attr_inst(
322 struct iscsi_wwn_stat_grps *igrps, char *page)
323{
324 struct iscsi_tiqn *tiqn = container_of(igrps,
325 struct iscsi_tiqn, tiqn_stat_grps);
326
327 return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
328}
329ISCSI_STAT_TGT_ATTR_RO(inst);
330
331static ssize_t iscsi_stat_tgt_attr_show_attr_indx(
332 struct iscsi_wwn_stat_grps *igrps, char *page)
333{
334 return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
335}
336ISCSI_STAT_TGT_ATTR_RO(indx);
337
338static ssize_t iscsi_stat_tgt_attr_show_attr_login_fails(
339 struct iscsi_wwn_stat_grps *igrps, char *page)
340{
341 struct iscsi_tiqn *tiqn = container_of(igrps,
342 struct iscsi_tiqn, tiqn_stat_grps);
343 struct iscsi_login_stats *lstat = &tiqn->login_stats;
344 u32 fail_count;
345
346 spin_lock(&lstat->lock);
347 fail_count = (lstat->redirects + lstat->authorize_fails +
348 lstat->authenticate_fails + lstat->negotiate_fails +
349 lstat->other_fails);
350 spin_unlock(&lstat->lock);
351
352 return snprintf(page, PAGE_SIZE, "%u\n", fail_count);
353}
354ISCSI_STAT_TGT_ATTR_RO(login_fails);
355
356static ssize_t iscsi_stat_tgt_attr_show_attr_last_fail_time(
357 struct iscsi_wwn_stat_grps *igrps, char *page)
358{
359 struct iscsi_tiqn *tiqn = container_of(igrps,
360 struct iscsi_tiqn, tiqn_stat_grps);
361 struct iscsi_login_stats *lstat = &tiqn->login_stats;
362 u32 last_fail_time;
363
364 spin_lock(&lstat->lock);
365 last_fail_time = lstat->last_fail_time ?
366 (u32)(((u32)lstat->last_fail_time -
367 INITIAL_JIFFIES) * 100 / HZ) : 0;
368 spin_unlock(&lstat->lock);
369
370 return snprintf(page, PAGE_SIZE, "%u\n", last_fail_time);
371}
372ISCSI_STAT_TGT_ATTR_RO(last_fail_time);
373
374static ssize_t iscsi_stat_tgt_attr_show_attr_last_fail_type(
375 struct iscsi_wwn_stat_grps *igrps, char *page)
376{
377 struct iscsi_tiqn *tiqn = container_of(igrps,
378 struct iscsi_tiqn, tiqn_stat_grps);
379 struct iscsi_login_stats *lstat = &tiqn->login_stats;
380 u32 last_fail_type;
381
382 spin_lock(&lstat->lock);
383 last_fail_type = lstat->last_fail_type;
384 spin_unlock(&lstat->lock);
385
386 return snprintf(page, PAGE_SIZE, "%u\n", last_fail_type);
387}
388ISCSI_STAT_TGT_ATTR_RO(last_fail_type);
389
390static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_name(
391 struct iscsi_wwn_stat_grps *igrps, char *page)
392{
393 struct iscsi_tiqn *tiqn = container_of(igrps,
394 struct iscsi_tiqn, tiqn_stat_grps);
395 struct iscsi_login_stats *lstat = &tiqn->login_stats;
396 unsigned char buf[224];
397
398 spin_lock(&lstat->lock);
399 snprintf(buf, 224, "%s", lstat->last_intr_fail_name[0] ?
400 lstat->last_intr_fail_name : NONE);
401 spin_unlock(&lstat->lock);
402
403 return snprintf(page, PAGE_SIZE, "%s\n", buf);
404}
405ISCSI_STAT_TGT_ATTR_RO(fail_intr_name);
406
407static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr_type(
408 struct iscsi_wwn_stat_grps *igrps, char *page)
409{
410 struct iscsi_tiqn *tiqn = container_of(igrps,
411 struct iscsi_tiqn, tiqn_stat_grps);
412 struct iscsi_login_stats *lstat = &tiqn->login_stats;
413 unsigned char buf[8];
414
415 spin_lock(&lstat->lock);
416 snprintf(buf, 8, "%s", (lstat->last_intr_fail_ip_addr != NULL) ?
417 "ipv6" : "ipv4");
418 spin_unlock(&lstat->lock);
419
420 return snprintf(page, PAGE_SIZE, "%s\n", buf);
421}
422ISCSI_STAT_TGT_ATTR_RO(fail_intr_addr_type);
423
424static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr(
425 struct iscsi_wwn_stat_grps *igrps, char *page)
426{
427 struct iscsi_tiqn *tiqn = container_of(igrps,
428 struct iscsi_tiqn, tiqn_stat_grps);
429 struct iscsi_login_stats *lstat = &tiqn->login_stats;
430 unsigned char buf[32];
431
432 spin_lock(&lstat->lock);
433 if (lstat->last_intr_fail_ip_family == AF_INET6)
434 snprintf(buf, 32, "[%s]", lstat->last_intr_fail_ip_addr);
435 else
436 snprintf(buf, 32, "%s", lstat->last_intr_fail_ip_addr);
437 spin_unlock(&lstat->lock);
438
439 return snprintf(page, PAGE_SIZE, "%s\n", buf);
440}
441ISCSI_STAT_TGT_ATTR_RO(fail_intr_addr);
442
443CONFIGFS_EATTR_OPS(iscsi_stat_tgt_attr, iscsi_wwn_stat_grps,
444 iscsi_tgt_attr_group);
445
446static struct configfs_attribute *iscsi_stat_tgt_attr_attrs[] = {
447 &iscsi_stat_tgt_attr_inst.attr,
448 &iscsi_stat_tgt_attr_indx.attr,
449 &iscsi_stat_tgt_attr_login_fails.attr,
450 &iscsi_stat_tgt_attr_last_fail_time.attr,
451 &iscsi_stat_tgt_attr_last_fail_type.attr,
452 &iscsi_stat_tgt_attr_fail_intr_name.attr,
453 &iscsi_stat_tgt_attr_fail_intr_addr_type.attr,
454 &iscsi_stat_tgt_attr_fail_intr_addr.attr,
455 NULL,
456};
457
458static struct configfs_item_operations iscsi_stat_tgt_attr_item_ops = {
459 .show_attribute = iscsi_stat_tgt_attr_attr_show,
460 .store_attribute = iscsi_stat_tgt_attr_attr_store,
461};
462
463struct config_item_type iscsi_stat_tgt_attr_cit = {
464 .ct_item_ops = &iscsi_stat_tgt_attr_item_ops,
465 .ct_attrs = iscsi_stat_tgt_attr_attrs,
466 .ct_owner = THIS_MODULE,
467};
468
469/*
470 * Target Login Stats Table
471 */
472CONFIGFS_EATTR_STRUCT(iscsi_stat_login, iscsi_wwn_stat_grps);
473#define ISCSI_STAT_LOGIN(_name, _mode) \
474static struct iscsi_stat_login_attribute \
475 iscsi_stat_login_##_name = \
476 __CONFIGFS_EATTR(_name, _mode, \
477 iscsi_stat_login_show_attr_##_name, \
478 iscsi_stat_login_store_attr_##_name);
479
480#define ISCSI_STAT_LOGIN_RO(_name) \
481static struct iscsi_stat_login_attribute \
482 iscsi_stat_login_##_name = \
483 __CONFIGFS_EATTR_RO(_name, \
484 iscsi_stat_login_show_attr_##_name);
485
486static ssize_t iscsi_stat_login_show_attr_inst(
487 struct iscsi_wwn_stat_grps *igrps, char *page)
488{
489 struct iscsi_tiqn *tiqn = container_of(igrps,
490 struct iscsi_tiqn, tiqn_stat_grps);
491
492 return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
493}
494ISCSI_STAT_LOGIN_RO(inst);
495
496static ssize_t iscsi_stat_login_show_attr_indx(
497 struct iscsi_wwn_stat_grps *igrps, char *page)
498{
499 return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
500}
501ISCSI_STAT_LOGIN_RO(indx);
502
503static ssize_t iscsi_stat_login_show_attr_accepts(
504 struct iscsi_wwn_stat_grps *igrps, char *page)
505{
506 struct iscsi_tiqn *tiqn = container_of(igrps,
507 struct iscsi_tiqn, tiqn_stat_grps);
508 struct iscsi_login_stats *lstat = &tiqn->login_stats;
509 ssize_t ret;
510
511 spin_lock(&lstat->lock);
512 ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->accepts);
513 spin_unlock(&lstat->lock);
514
515 return ret;
516}
517ISCSI_STAT_LOGIN_RO(accepts);
518
519static ssize_t iscsi_stat_login_show_attr_other_fails(
520 struct iscsi_wwn_stat_grps *igrps, char *page)
521{
522 struct iscsi_tiqn *tiqn = container_of(igrps,
523 struct iscsi_tiqn, tiqn_stat_grps);
524 struct iscsi_login_stats *lstat = &tiqn->login_stats;
525 ssize_t ret;
526
527 spin_lock(&lstat->lock);
528 ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->other_fails);
529 spin_unlock(&lstat->lock);
530
531 return ret;
532}
533ISCSI_STAT_LOGIN_RO(other_fails);
534
535static ssize_t iscsi_stat_login_show_attr_redirects(
536 struct iscsi_wwn_stat_grps *igrps, char *page)
537{
538 struct iscsi_tiqn *tiqn = container_of(igrps,
539 struct iscsi_tiqn, tiqn_stat_grps);
540 struct iscsi_login_stats *lstat = &tiqn->login_stats;
541 ssize_t ret;
542
543 spin_lock(&lstat->lock);
544 ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->redirects);
545 spin_unlock(&lstat->lock);
546
547 return ret;
548}
549ISCSI_STAT_LOGIN_RO(redirects);
550
551static ssize_t iscsi_stat_login_show_attr_authorize_fails(
552 struct iscsi_wwn_stat_grps *igrps, char *page)
553{
554 struct iscsi_tiqn *tiqn = container_of(igrps,
555 struct iscsi_tiqn, tiqn_stat_grps);
556 struct iscsi_login_stats *lstat = &tiqn->login_stats;
557 ssize_t ret;
558
559 spin_lock(&lstat->lock);
560 ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->authorize_fails);
561 spin_unlock(&lstat->lock);
562
563 return ret;
564}
565ISCSI_STAT_LOGIN_RO(authorize_fails);
566
567static ssize_t iscsi_stat_login_show_attr_authenticate_fails(
568 struct iscsi_wwn_stat_grps *igrps, char *page)
569{
570 struct iscsi_tiqn *tiqn = container_of(igrps,
571 struct iscsi_tiqn, tiqn_stat_grps);
572 struct iscsi_login_stats *lstat = &tiqn->login_stats;
573 ssize_t ret;
574
575 spin_lock(&lstat->lock);
576 ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->authenticate_fails);
577 spin_unlock(&lstat->lock);
578
579 return ret;
580}
581ISCSI_STAT_LOGIN_RO(authenticate_fails);
582
583static ssize_t iscsi_stat_login_show_attr_negotiate_fails(
584 struct iscsi_wwn_stat_grps *igrps, char *page)
585{
586 struct iscsi_tiqn *tiqn = container_of(igrps,
587 struct iscsi_tiqn, tiqn_stat_grps);
588 struct iscsi_login_stats *lstat = &tiqn->login_stats;
589 ssize_t ret;
590
591 spin_lock(&lstat->lock);
592 ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->negotiate_fails);
593 spin_unlock(&lstat->lock);
594
595 return ret;
596}
597ISCSI_STAT_LOGIN_RO(negotiate_fails);
598
599CONFIGFS_EATTR_OPS(iscsi_stat_login, iscsi_wwn_stat_grps,
600 iscsi_login_stats_group);
601
602static struct configfs_attribute *iscsi_stat_login_stats_attrs[] = {
603 &iscsi_stat_login_inst.attr,
604 &iscsi_stat_login_indx.attr,
605 &iscsi_stat_login_accepts.attr,
606 &iscsi_stat_login_other_fails.attr,
607 &iscsi_stat_login_redirects.attr,
608 &iscsi_stat_login_authorize_fails.attr,
609 &iscsi_stat_login_authenticate_fails.attr,
610 &iscsi_stat_login_negotiate_fails.attr,
611 NULL,
612};
613
614static struct configfs_item_operations iscsi_stat_login_stats_item_ops = {
615 .show_attribute = iscsi_stat_login_attr_show,
616 .store_attribute = iscsi_stat_login_attr_store,
617};
618
619struct config_item_type iscsi_stat_login_cit = {
620 .ct_item_ops = &iscsi_stat_login_stats_item_ops,
621 .ct_attrs = iscsi_stat_login_stats_attrs,
622 .ct_owner = THIS_MODULE,
623};
624
625/*
626 * Target Logout Stats Table
627 */
628
629CONFIGFS_EATTR_STRUCT(iscsi_stat_logout, iscsi_wwn_stat_grps);
630#define ISCSI_STAT_LOGOUT(_name, _mode) \
631static struct iscsi_stat_logout_attribute \
632 iscsi_stat_logout_##_name = \
633 __CONFIGFS_EATTR(_name, _mode, \
634 iscsi_stat_logout_show_attr_##_name, \
635 iscsi_stat_logout_store_attr_##_name);
636
637#define ISCSI_STAT_LOGOUT_RO(_name) \
638static struct iscsi_stat_logout_attribute \
639 iscsi_stat_logout_##_name = \
640 __CONFIGFS_EATTR_RO(_name, \
641 iscsi_stat_logout_show_attr_##_name);
642
643static ssize_t iscsi_stat_logout_show_attr_inst(
644 struct iscsi_wwn_stat_grps *igrps, char *page)
645{
646 struct iscsi_tiqn *tiqn = container_of(igrps,
647 struct iscsi_tiqn, tiqn_stat_grps);
648
649 return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
650}
651ISCSI_STAT_LOGOUT_RO(inst);
652
653static ssize_t iscsi_stat_logout_show_attr_indx(
654 struct iscsi_wwn_stat_grps *igrps, char *page)
655{
656 return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX);
657}
658ISCSI_STAT_LOGOUT_RO(indx);
659
660static ssize_t iscsi_stat_logout_show_attr_normal_logouts(
661 struct iscsi_wwn_stat_grps *igrps, char *page)
662{
663 struct iscsi_tiqn *tiqn = container_of(igrps,
664 struct iscsi_tiqn, tiqn_stat_grps);
665 struct iscsi_logout_stats *lstats = &tiqn->logout_stats;
666
667 return snprintf(page, PAGE_SIZE, "%u\n", lstats->normal_logouts);
668}
669ISCSI_STAT_LOGOUT_RO(normal_logouts);
670
671static ssize_t iscsi_stat_logout_show_attr_abnormal_logouts(
672 struct iscsi_wwn_stat_grps *igrps, char *page)
673{
674 struct iscsi_tiqn *tiqn = container_of(igrps,
675 struct iscsi_tiqn, tiqn_stat_grps);
676 struct iscsi_logout_stats *lstats = &tiqn->logout_stats;
677
678 return snprintf(page, PAGE_SIZE, "%u\n", lstats->abnormal_logouts);
679}
680ISCSI_STAT_LOGOUT_RO(abnormal_logouts);
681
682CONFIGFS_EATTR_OPS(iscsi_stat_logout, iscsi_wwn_stat_grps,
683 iscsi_logout_stats_group);
684
685static struct configfs_attribute *iscsi_stat_logout_stats_attrs[] = {
686 &iscsi_stat_logout_inst.attr,
687 &iscsi_stat_logout_indx.attr,
688 &iscsi_stat_logout_normal_logouts.attr,
689 &iscsi_stat_logout_abnormal_logouts.attr,
690 NULL,
691};
692
693static struct configfs_item_operations iscsi_stat_logout_stats_item_ops = {
694 .show_attribute = iscsi_stat_logout_attr_show,
695 .store_attribute = iscsi_stat_logout_attr_store,
696};
697
698struct config_item_type iscsi_stat_logout_cit = {
699 .ct_item_ops = &iscsi_stat_logout_stats_item_ops,
700 .ct_attrs = iscsi_stat_logout_stats_attrs,
701 .ct_owner = THIS_MODULE,
702};
703
704/*
705 * Session Stats Table
706 */
707
708CONFIGFS_EATTR_STRUCT(iscsi_stat_sess, iscsi_node_stat_grps);
709#define ISCSI_STAT_SESS(_name, _mode) \
710static struct iscsi_stat_sess_attribute \
711 iscsi_stat_sess_##_name = \
712 __CONFIGFS_EATTR(_name, _mode, \
713 iscsi_stat_sess_show_attr_##_name, \
714 iscsi_stat_sess_store_attr_##_name);
715
716#define ISCSI_STAT_SESS_RO(_name) \
717static struct iscsi_stat_sess_attribute \
718 iscsi_stat_sess_##_name = \
719 __CONFIGFS_EATTR_RO(_name, \
720 iscsi_stat_sess_show_attr_##_name);
721
722static ssize_t iscsi_stat_sess_show_attr_inst(
723 struct iscsi_node_stat_grps *igrps, char *page)
724{
725 struct iscsi_node_acl *acl = container_of(igrps,
726 struct iscsi_node_acl, node_stat_grps);
727 struct se_wwn *wwn = acl->se_node_acl.se_tpg->se_tpg_wwn;
728 struct iscsi_tiqn *tiqn = container_of(wwn,
729 struct iscsi_tiqn, tiqn_wwn);
730
731 return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index);
732}
733ISCSI_STAT_SESS_RO(inst);
734
735static ssize_t iscsi_stat_sess_show_attr_node(
736 struct iscsi_node_stat_grps *igrps, char *page)
737{
738 struct iscsi_node_acl *acl = container_of(igrps,
739 struct iscsi_node_acl, node_stat_grps);
740 struct se_node_acl *se_nacl = &acl->se_node_acl;
741 struct iscsi_session *sess;
742 struct se_session *se_sess;
743 ssize_t ret = 0;
744
745 spin_lock_bh(&se_nacl->nacl_sess_lock);
746 se_sess = se_nacl->nacl_sess;
747 if (se_sess) {
748 sess = (struct iscsi_session *)se_sess->fabric_sess_ptr;
749 if (sess)
750 ret = snprintf(page, PAGE_SIZE, "%u\n",
751 sess->sess_ops->SessionType ? 0 : ISCSI_NODE_INDEX);
752 }
753 spin_unlock_bh(&se_nacl->nacl_sess_lock);
754
755 return ret;
756}
757ISCSI_STAT_SESS_RO(node);
758
759static ssize_t iscsi_stat_sess_show_attr_indx(
760 struct iscsi_node_stat_grps *igrps, char *page)
761{
762 struct iscsi_node_acl *acl = container_of(igrps,
763 struct iscsi_node_acl, node_stat_grps);
764 struct se_node_acl *se_nacl = &acl->se_node_acl;
765 struct iscsi_session *sess;
766 struct se_session *se_sess;
767 ssize_t ret = 0;
768
769 spin_lock_bh(&se_nacl->nacl_sess_lock);
770 se_sess = se_nacl->nacl_sess;
771 if (se_sess) {
772 sess = (struct iscsi_session *)se_sess->fabric_sess_ptr;
773 if (sess)
774 ret = snprintf(page, PAGE_SIZE, "%u\n",
775 sess->session_index);
776 }
777 spin_unlock_bh(&se_nacl->nacl_sess_lock);
778
779 return ret;
780}
781ISCSI_STAT_SESS_RO(indx);
782
783static ssize_t iscsi_stat_sess_show_attr_cmd_pdus(
784 struct iscsi_node_stat_grps *igrps, char *page)
785{
786 struct iscsi_node_acl *acl = container_of(igrps,
787 struct iscsi_node_acl, node_stat_grps);
788 struct se_node_acl *se_nacl = &acl->se_node_acl;
789 struct iscsi_session *sess;
790 struct se_session *se_sess;
791 ssize_t ret = 0;
792
793 spin_lock_bh(&se_nacl->nacl_sess_lock);
794 se_sess = se_nacl->nacl_sess;
795 if (se_sess) {
796 sess = (struct iscsi_session *)se_sess->fabric_sess_ptr;
797 if (sess)
798 ret = snprintf(page, PAGE_SIZE, "%u\n", sess->cmd_pdus);
799 }
800 spin_unlock_bh(&se_nacl->nacl_sess_lock);
801
802 return ret;
803}
804ISCSI_STAT_SESS_RO(cmd_pdus);
805
806static ssize_t iscsi_stat_sess_show_attr_rsp_pdus(
807 struct iscsi_node_stat_grps *igrps, char *page)
808{
809 struct iscsi_node_acl *acl = container_of(igrps,
810 struct iscsi_node_acl, node_stat_grps);
811 struct se_node_acl *se_nacl = &acl->se_node_acl;
812 struct iscsi_session *sess;
813 struct se_session *se_sess;
814 ssize_t ret = 0;
815
816 spin_lock_bh(&se_nacl->nacl_sess_lock);
817 se_sess = se_nacl->nacl_sess;
818 if (se_sess) {
819 sess = (struct iscsi_session *)se_sess->fabric_sess_ptr;
820 if (sess)
821 ret = snprintf(page, PAGE_SIZE, "%u\n", sess->rsp_pdus);
822 }
823 spin_unlock_bh(&se_nacl->nacl_sess_lock);
824
825 return ret;
826}
827ISCSI_STAT_SESS_RO(rsp_pdus);
828
829static ssize_t iscsi_stat_sess_show_attr_txdata_octs(
830 struct iscsi_node_stat_grps *igrps, char *page)
831{
832 struct iscsi_node_acl *acl = container_of(igrps,
833 struct iscsi_node_acl, node_stat_grps);
834 struct se_node_acl *se_nacl = &acl->se_node_acl;
835 struct iscsi_session *sess;
836 struct se_session *se_sess;
837 ssize_t ret = 0;
838
839 spin_lock_bh(&se_nacl->nacl_sess_lock);
840 se_sess = se_nacl->nacl_sess;
841 if (se_sess) {
842 sess = (struct iscsi_session *)se_sess->fabric_sess_ptr;
843 if (sess)
844 ret = snprintf(page, PAGE_SIZE, "%llu\n",
845 (unsigned long long)sess->tx_data_octets);
846 }
847 spin_unlock_bh(&se_nacl->nacl_sess_lock);
848
849 return ret;
850}
851ISCSI_STAT_SESS_RO(txdata_octs);
852
853static ssize_t iscsi_stat_sess_show_attr_rxdata_octs(
854 struct iscsi_node_stat_grps *igrps, char *page)
855{
856 struct iscsi_node_acl *acl = container_of(igrps,
857 struct iscsi_node_acl, node_stat_grps);
858 struct se_node_acl *se_nacl = &acl->se_node_acl;
859 struct iscsi_session *sess;
860 struct se_session *se_sess;
861 ssize_t ret = 0;
862
863 spin_lock_bh(&se_nacl->nacl_sess_lock);
864 se_sess = se_nacl->nacl_sess;
865 if (se_sess) {
866 sess = (struct iscsi_session *)se_sess->fabric_sess_ptr;
867 if (sess)
868 ret = snprintf(page, PAGE_SIZE, "%llu\n",
869 (unsigned long long)sess->rx_data_octets);
870 }
871 spin_unlock_bh(&se_nacl->nacl_sess_lock);
872
873 return ret;
874}
875ISCSI_STAT_SESS_RO(rxdata_octs);
876
877static ssize_t iscsi_stat_sess_show_attr_conn_digest_errors(
878 struct iscsi_node_stat_grps *igrps, char *page)
879{
880 struct iscsi_node_acl *acl = container_of(igrps,
881 struct iscsi_node_acl, node_stat_grps);
882 struct se_node_acl *se_nacl = &acl->se_node_acl;
883 struct iscsi_session *sess;
884 struct se_session *se_sess;
885 ssize_t ret = 0;
886
887 spin_lock_bh(&se_nacl->nacl_sess_lock);
888 se_sess = se_nacl->nacl_sess;
889 if (se_sess) {
890 sess = (struct iscsi_session *)se_sess->fabric_sess_ptr;
891 if (sess)
892 ret = snprintf(page, PAGE_SIZE, "%u\n",
893 sess->conn_digest_errors);
894 }
895 spin_unlock_bh(&se_nacl->nacl_sess_lock);
896
897 return ret;
898}
899ISCSI_STAT_SESS_RO(conn_digest_errors);
900
901static ssize_t iscsi_stat_sess_show_attr_conn_timeout_errors(
902 struct iscsi_node_stat_grps *igrps, char *page)
903{
904 struct iscsi_node_acl *acl = container_of(igrps,
905 struct iscsi_node_acl, node_stat_grps);
906 struct se_node_acl *se_nacl = &acl->se_node_acl;
907 struct iscsi_session *sess;
908 struct se_session *se_sess;
909 ssize_t ret = 0;
910
911 spin_lock_bh(&se_nacl->nacl_sess_lock);
912 se_sess = se_nacl->nacl_sess;
913 if (se_sess) {
914 sess = (struct iscsi_session *)se_sess->fabric_sess_ptr;
915 if (sess)
916 ret = snprintf(page, PAGE_SIZE, "%u\n",
917 sess->conn_timeout_errors);
918 }
919 spin_unlock_bh(&se_nacl->nacl_sess_lock);
920
921 return ret;
922}
923ISCSI_STAT_SESS_RO(conn_timeout_errors);
924
925CONFIGFS_EATTR_OPS(iscsi_stat_sess, iscsi_node_stat_grps,
926 iscsi_sess_stats_group);
927
928static struct configfs_attribute *iscsi_stat_sess_stats_attrs[] = {
929 &iscsi_stat_sess_inst.attr,
930 &iscsi_stat_sess_node.attr,
931 &iscsi_stat_sess_indx.attr,
932 &iscsi_stat_sess_cmd_pdus.attr,
933 &iscsi_stat_sess_rsp_pdus.attr,
934 &iscsi_stat_sess_txdata_octs.attr,
935 &iscsi_stat_sess_rxdata_octs.attr,
936 &iscsi_stat_sess_conn_digest_errors.attr,
937 &iscsi_stat_sess_conn_timeout_errors.attr,
938 NULL,
939};
940
941static struct configfs_item_operations iscsi_stat_sess_stats_item_ops = {
942 .show_attribute = iscsi_stat_sess_attr_show,
943 .store_attribute = iscsi_stat_sess_attr_store,
944};
945
946struct config_item_type iscsi_stat_sess_cit = {
947 .ct_item_ops = &iscsi_stat_sess_stats_item_ops,
948 .ct_attrs = iscsi_stat_sess_stats_attrs,
949 .ct_owner = THIS_MODULE,
950};
diff --git a/drivers/target/iscsi/iscsi_target_stat.h b/drivers/target/iscsi/iscsi_target_stat.h
new file mode 100644
index 000000000000..3ff76b4faad3
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_stat.h
@@ -0,0 +1,64 @@
1#ifndef ISCSI_TARGET_STAT_H
2#define ISCSI_TARGET_STAT_H
3
4/*
5 * For struct iscsi_tiqn->tiqn_wwn default groups
6 */
7extern struct config_item_type iscsi_stat_instance_cit;
8extern struct config_item_type iscsi_stat_sess_err_cit;
9extern struct config_item_type iscsi_stat_tgt_attr_cit;
10extern struct config_item_type iscsi_stat_login_cit;
11extern struct config_item_type iscsi_stat_logout_cit;
12
13/*
14 * For struct iscsi_session->se_sess default groups
15 */
16extern struct config_item_type iscsi_stat_sess_cit;
17
18/* iSCSI session error types */
19#define ISCSI_SESS_ERR_UNKNOWN 0
20#define ISCSI_SESS_ERR_DIGEST 1
21#define ISCSI_SESS_ERR_CXN_TIMEOUT 2
22#define ISCSI_SESS_ERR_PDU_FORMAT 3
23
24/* iSCSI session error stats */
25struct iscsi_sess_err_stats {
26 spinlock_t lock;
27 u32 digest_errors;
28 u32 cxn_timeout_errors;
29 u32 pdu_format_errors;
30 u32 last_sess_failure_type;
31 char last_sess_fail_rem_name[224];
32} ____cacheline_aligned;
33
34/* iSCSI login failure types (sub oids) */
35#define ISCSI_LOGIN_FAIL_OTHER 2
36#define ISCSI_LOGIN_FAIL_REDIRECT 3
37#define ISCSI_LOGIN_FAIL_AUTHORIZE 4
38#define ISCSI_LOGIN_FAIL_AUTHENTICATE 5
39#define ISCSI_LOGIN_FAIL_NEGOTIATE 6
40
41/* iSCSI login stats */
42struct iscsi_login_stats {
43 spinlock_t lock;
44 u32 accepts;
45 u32 other_fails;
46 u32 redirects;
47 u32 authorize_fails;
48 u32 authenticate_fails;
49 u32 negotiate_fails; /* used for notifications */
50 u64 last_fail_time; /* time stamp (jiffies) */
51 u32 last_fail_type;
52 int last_intr_fail_ip_family;
53 unsigned char last_intr_fail_ip_addr[IPV6_ADDRESS_SPACE];
54 char last_intr_fail_name[224];
55} ____cacheline_aligned;
56
57/* iSCSI logout stats */
58struct iscsi_logout_stats {
59 spinlock_t lock;
60 u32 normal_logouts;
61 u32 abnormal_logouts;
62} ____cacheline_aligned;
63
64#endif /*** ISCSI_TARGET_STAT_H ***/
diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c
new file mode 100644
index 000000000000..db1fe1ec84df
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_tmr.c
@@ -0,0 +1,849 @@
1/*******************************************************************************
2 * This file contains the iSCSI Target specific Task Management functions.
3 *
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5 *
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7 *
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.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
21#include <asm/unaligned.h>
22#include <scsi/iscsi_proto.h>
23#include <target/target_core_base.h>
24#include <target/target_core_transport.h>
25
26#include "iscsi_target_core.h"
27#include "iscsi_target_seq_pdu_list.h"
28#include "iscsi_target_datain_values.h"
29#include "iscsi_target_device.h"
30#include "iscsi_target_erl0.h"
31#include "iscsi_target_erl1.h"
32#include "iscsi_target_erl2.h"
33#include "iscsi_target_tmr.h"
34#include "iscsi_target_tpg.h"
35#include "iscsi_target_util.h"
36#include "iscsi_target.h"
37
38u8 iscsit_tmr_abort_task(
39 struct iscsi_cmd *cmd,
40 unsigned char *buf)
41{
42 struct iscsi_cmd *ref_cmd;
43 struct iscsi_conn *conn = cmd->conn;
44 struct iscsi_tmr_req *tmr_req = cmd->tmr_req;
45 struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
46 struct iscsi_tm *hdr = (struct iscsi_tm *) buf;
47
48 ref_cmd = iscsit_find_cmd_from_itt(conn, hdr->rtt);
49 if (!ref_cmd) {
50 pr_err("Unable to locate RefTaskTag: 0x%08x on CID:"
51 " %hu.\n", hdr->rtt, conn->cid);
52 return ((hdr->refcmdsn >= conn->sess->exp_cmd_sn) &&
53 (hdr->refcmdsn <= conn->sess->max_cmd_sn)) ?
54 ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK;
55 }
56 if (ref_cmd->cmd_sn != hdr->refcmdsn) {
57 pr_err("RefCmdSN 0x%08x does not equal"
58 " task's CmdSN 0x%08x. Rejecting ABORT_TASK.\n",
59 hdr->refcmdsn, ref_cmd->cmd_sn);
60 return ISCSI_TMF_RSP_REJECTED;
61 }
62
63 se_tmr->ref_task_tag = hdr->rtt;
64 se_tmr->ref_cmd = &ref_cmd->se_cmd;
65 tmr_req->ref_cmd_sn = hdr->refcmdsn;
66 tmr_req->exp_data_sn = hdr->exp_datasn;
67
68 return ISCSI_TMF_RSP_COMPLETE;
69}
70
71/*
72 * Called from iscsit_handle_task_mgt_cmd().
73 */
74int iscsit_tmr_task_warm_reset(
75 struct iscsi_conn *conn,
76 struct iscsi_tmr_req *tmr_req,
77 unsigned char *buf)
78{
79 struct iscsi_session *sess = conn->sess;
80 struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);
81#if 0
82 struct iscsi_init_task_mgt_cmnd *hdr =
83 (struct iscsi_init_task_mgt_cmnd *) buf;
84#endif
85 if (!na->tmr_warm_reset) {
86 pr_err("TMR Opcode TARGET_WARM_RESET authorization"
87 " failed for Initiator Node: %s\n",
88 sess->se_sess->se_node_acl->initiatorname);
89 return -1;
90 }
91 /*
92 * Do the real work in transport_generic_do_tmr().
93 */
94 return 0;
95}
96
97int iscsit_tmr_task_cold_reset(
98 struct iscsi_conn *conn,
99 struct iscsi_tmr_req *tmr_req,
100 unsigned char *buf)
101{
102 struct iscsi_session *sess = conn->sess;
103 struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);
104
105 if (!na->tmr_cold_reset) {
106 pr_err("TMR Opcode TARGET_COLD_RESET authorization"
107 " failed for Initiator Node: %s\n",
108 sess->se_sess->se_node_acl->initiatorname);
109 return -1;
110 }
111 /*
112 * Do the real work in transport_generic_do_tmr().
113 */
114 return 0;
115}
116
117u8 iscsit_tmr_task_reassign(
118 struct iscsi_cmd *cmd,
119 unsigned char *buf)
120{
121 struct iscsi_cmd *ref_cmd = NULL;
122 struct iscsi_conn *conn = cmd->conn;
123 struct iscsi_conn_recovery *cr = NULL;
124 struct iscsi_tmr_req *tmr_req = cmd->tmr_req;
125 struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
126 struct iscsi_tm *hdr = (struct iscsi_tm *) buf;
127 int ret;
128
129 pr_debug("Got TASK_REASSIGN TMR ITT: 0x%08x,"
130 " RefTaskTag: 0x%08x, ExpDataSN: 0x%08x, CID: %hu\n",
131 hdr->itt, hdr->rtt, hdr->exp_datasn, conn->cid);
132
133 if (conn->sess->sess_ops->ErrorRecoveryLevel != 2) {
134 pr_err("TMR TASK_REASSIGN not supported in ERL<2,"
135 " ignoring request.\n");
136 return ISCSI_TMF_RSP_NOT_SUPPORTED;
137 }
138
139 ret = iscsit_find_cmd_for_recovery(conn->sess, &ref_cmd, &cr, hdr->rtt);
140 if (ret == -2) {
141 pr_err("Command ITT: 0x%08x is still alligent to CID:"
142 " %hu\n", ref_cmd->init_task_tag, cr->cid);
143 return ISCSI_TMF_RSP_TASK_ALLEGIANT;
144 } else if (ret == -1) {
145 pr_err("Unable to locate RefTaskTag: 0x%08x in"
146 " connection recovery command list.\n", hdr->rtt);
147 return ISCSI_TMF_RSP_NO_TASK;
148 }
149 /*
150 * Temporary check to prevent connection recovery for
151 * connections with a differing MaxRecvDataSegmentLength.
152 */
153 if (cr->maxrecvdatasegmentlength !=
154 conn->conn_ops->MaxRecvDataSegmentLength) {
155 pr_err("Unable to perform connection recovery for"
156 " differing MaxRecvDataSegmentLength, rejecting"
157 " TMR TASK_REASSIGN.\n");
158 return ISCSI_TMF_RSP_REJECTED;
159 }
160
161 se_tmr->ref_task_tag = hdr->rtt;
162 se_tmr->ref_cmd = &ref_cmd->se_cmd;
163 se_tmr->ref_task_lun = get_unaligned_le64(&hdr->lun);
164 tmr_req->ref_cmd_sn = hdr->refcmdsn;
165 tmr_req->exp_data_sn = hdr->exp_datasn;
166 tmr_req->conn_recovery = cr;
167 tmr_req->task_reassign = 1;
168 /*
169 * Command can now be reassigned to a new connection.
170 * The task management response must be sent before the
171 * reassignment actually happens. See iscsi_tmr_post_handler().
172 */
173 return ISCSI_TMF_RSP_COMPLETE;
174}
175
176static void iscsit_task_reassign_remove_cmd(
177 struct iscsi_cmd *cmd,
178 struct iscsi_conn_recovery *cr,
179 struct iscsi_session *sess)
180{
181 int ret;
182
183 spin_lock(&cr->conn_recovery_cmd_lock);
184 ret = iscsit_remove_cmd_from_connection_recovery(cmd, sess);
185 spin_unlock(&cr->conn_recovery_cmd_lock);
186 if (!ret) {
187 pr_debug("iSCSI connection recovery successful for CID:"
188 " %hu on SID: %u\n", cr->cid, sess->sid);
189 iscsit_remove_active_connection_recovery_entry(cr, sess);
190 }
191}
192
193static int iscsit_task_reassign_complete_nop_out(
194 struct iscsi_tmr_req *tmr_req,
195 struct iscsi_conn *conn)
196{
197 struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
198 struct se_cmd *se_cmd = se_tmr->ref_cmd;
199 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
200 struct iscsi_conn_recovery *cr;
201
202 if (!cmd->cr) {
203 pr_err("struct iscsi_conn_recovery pointer for ITT: 0x%08x"
204 " is NULL!\n", cmd->init_task_tag);
205 return -1;
206 }
207 cr = cmd->cr;
208
209 /*
210 * Reset the StatSN so a new one for this commands new connection
211 * will be assigned.
212 * Reset the ExpStatSN as well so we may receive Status SNACKs.
213 */
214 cmd->stat_sn = cmd->exp_stat_sn = 0;
215
216 iscsit_task_reassign_remove_cmd(cmd, cr, conn->sess);
217
218 spin_lock_bh(&conn->cmd_lock);
219 list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
220 spin_unlock_bh(&conn->cmd_lock);
221
222 cmd->i_state = ISTATE_SEND_NOPIN;
223 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
224 return 0;
225}
226
227static int iscsit_task_reassign_complete_write(
228 struct iscsi_cmd *cmd,
229 struct iscsi_tmr_req *tmr_req)
230{
231 int no_build_r2ts = 0;
232 u32 length = 0, offset = 0;
233 struct iscsi_conn *conn = cmd->conn;
234 struct se_cmd *se_cmd = &cmd->se_cmd;
235 /*
236 * The Initiator must not send a R2T SNACK with a Begrun less than
237 * the TMR TASK_REASSIGN's ExpDataSN.
238 */
239 if (!tmr_req->exp_data_sn) {
240 cmd->cmd_flags &= ~ICF_GOT_DATACK_SNACK;
241 cmd->acked_data_sn = 0;
242 } else {
243 cmd->cmd_flags |= ICF_GOT_DATACK_SNACK;
244 cmd->acked_data_sn = (tmr_req->exp_data_sn - 1);
245 }
246
247 /*
248 * The TMR TASK_REASSIGN's ExpDataSN contains the next R2TSN the
249 * Initiator is expecting. The Target controls all WRITE operations
250 * so if we have received all DataOUT we can safety ignore Initiator.
251 */
252 if (cmd->cmd_flags & ICF_GOT_LAST_DATAOUT) {
253 if (!atomic_read(&cmd->transport_sent)) {
254 pr_debug("WRITE ITT: 0x%08x: t_state: %d"
255 " never sent to transport\n",
256 cmd->init_task_tag, cmd->se_cmd.t_state);
257 return transport_generic_handle_data(se_cmd);
258 }
259
260 cmd->i_state = ISTATE_SEND_STATUS;
261 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
262 return 0;
263 }
264
265 /*
266 * Special case to deal with DataSequenceInOrder=No and Non-Immeidate
267 * Unsolicited DataOut.
268 */
269 if (cmd->unsolicited_data) {
270 cmd->unsolicited_data = 0;
271
272 offset = cmd->next_burst_len = cmd->write_data_done;
273
274 if ((conn->sess->sess_ops->FirstBurstLength - offset) >=
275 cmd->data_length) {
276 no_build_r2ts = 1;
277 length = (cmd->data_length - offset);
278 } else
279 length = (conn->sess->sess_ops->FirstBurstLength - offset);
280
281 spin_lock_bh(&cmd->r2t_lock);
282 if (iscsit_add_r2t_to_list(cmd, offset, length, 0, 0) < 0) {
283 spin_unlock_bh(&cmd->r2t_lock);
284 return -1;
285 }
286 cmd->outstanding_r2ts++;
287 spin_unlock_bh(&cmd->r2t_lock);
288
289 if (no_build_r2ts)
290 return 0;
291 }
292 /*
293 * iscsit_build_r2ts_for_cmd() can handle the rest from here.
294 */
295 return iscsit_build_r2ts_for_cmd(cmd, conn, 2);
296}
297
298static int iscsit_task_reassign_complete_read(
299 struct iscsi_cmd *cmd,
300 struct iscsi_tmr_req *tmr_req)
301{
302 struct iscsi_conn *conn = cmd->conn;
303 struct iscsi_datain_req *dr;
304 struct se_cmd *se_cmd = &cmd->se_cmd;
305 /*
306 * The Initiator must not send a Data SNACK with a BegRun less than
307 * the TMR TASK_REASSIGN's ExpDataSN.
308 */
309 if (!tmr_req->exp_data_sn) {
310 cmd->cmd_flags &= ~ICF_GOT_DATACK_SNACK;
311 cmd->acked_data_sn = 0;
312 } else {
313 cmd->cmd_flags |= ICF_GOT_DATACK_SNACK;
314 cmd->acked_data_sn = (tmr_req->exp_data_sn - 1);
315 }
316
317 if (!atomic_read(&cmd->transport_sent)) {
318 pr_debug("READ ITT: 0x%08x: t_state: %d never sent to"
319 " transport\n", cmd->init_task_tag,
320 cmd->se_cmd.t_state);
321 transport_generic_handle_cdb(se_cmd);
322 return 0;
323 }
324
325 if (!atomic_read(&se_cmd->t_transport_complete)) {
326 pr_err("READ ITT: 0x%08x: t_state: %d, never returned"
327 " from transport\n", cmd->init_task_tag,
328 cmd->se_cmd.t_state);
329 return -1;
330 }
331
332 dr = iscsit_allocate_datain_req();
333 if (!dr)
334 return -1;
335 /*
336 * The TMR TASK_REASSIGN's ExpDataSN contains the next DataSN the
337 * Initiator is expecting.
338 */
339 dr->data_sn = dr->begrun = tmr_req->exp_data_sn;
340 dr->runlength = 0;
341 dr->generate_recovery_values = 1;
342 dr->recovery = DATAIN_CONNECTION_RECOVERY;
343
344 iscsit_attach_datain_req(cmd, dr);
345
346 cmd->i_state = ISTATE_SEND_DATAIN;
347 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
348 return 0;
349}
350
351static int iscsit_task_reassign_complete_none(
352 struct iscsi_cmd *cmd,
353 struct iscsi_tmr_req *tmr_req)
354{
355 struct iscsi_conn *conn = cmd->conn;
356
357 cmd->i_state = ISTATE_SEND_STATUS;
358 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
359 return 0;
360}
361
362static int iscsit_task_reassign_complete_scsi_cmnd(
363 struct iscsi_tmr_req *tmr_req,
364 struct iscsi_conn *conn)
365{
366 struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
367 struct se_cmd *se_cmd = se_tmr->ref_cmd;
368 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
369 struct iscsi_conn_recovery *cr;
370
371 if (!cmd->cr) {
372 pr_err("struct iscsi_conn_recovery pointer for ITT: 0x%08x"
373 " is NULL!\n", cmd->init_task_tag);
374 return -1;
375 }
376 cr = cmd->cr;
377
378 /*
379 * Reset the StatSN so a new one for this commands new connection
380 * will be assigned.
381 * Reset the ExpStatSN as well so we may receive Status SNACKs.
382 */
383 cmd->stat_sn = cmd->exp_stat_sn = 0;
384
385 iscsit_task_reassign_remove_cmd(cmd, cr, conn->sess);
386
387 spin_lock_bh(&conn->cmd_lock);
388 list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
389 spin_unlock_bh(&conn->cmd_lock);
390
391 if (se_cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) {
392 cmd->i_state = ISTATE_SEND_STATUS;
393 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
394 return 0;
395 }
396
397 switch (cmd->data_direction) {
398 case DMA_TO_DEVICE:
399 return iscsit_task_reassign_complete_write(cmd, tmr_req);
400 case DMA_FROM_DEVICE:
401 return iscsit_task_reassign_complete_read(cmd, tmr_req);
402 case DMA_NONE:
403 return iscsit_task_reassign_complete_none(cmd, tmr_req);
404 default:
405 pr_err("Unknown cmd->data_direction: 0x%02x\n",
406 cmd->data_direction);
407 return -1;
408 }
409
410 return 0;
411}
412
413static int iscsit_task_reassign_complete(
414 struct iscsi_tmr_req *tmr_req,
415 struct iscsi_conn *conn)
416{
417 struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
418 struct se_cmd *se_cmd;
419 struct iscsi_cmd *cmd;
420 int ret = 0;
421
422 if (!se_tmr->ref_cmd) {
423 pr_err("TMR Request is missing a RefCmd struct iscsi_cmd.\n");
424 return -1;
425 }
426 se_cmd = se_tmr->ref_cmd;
427 cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
428
429 cmd->conn = conn;
430
431 switch (cmd->iscsi_opcode) {
432 case ISCSI_OP_NOOP_OUT:
433 ret = iscsit_task_reassign_complete_nop_out(tmr_req, conn);
434 break;
435 case ISCSI_OP_SCSI_CMD:
436 ret = iscsit_task_reassign_complete_scsi_cmnd(tmr_req, conn);
437 break;
438 default:
439 pr_err("Illegal iSCSI Opcode 0x%02x during"
440 " command realligence\n", cmd->iscsi_opcode);
441 return -1;
442 }
443
444 if (ret != 0)
445 return ret;
446
447 pr_debug("Completed connection realligence for Opcode: 0x%02x,"
448 " ITT: 0x%08x to CID: %hu.\n", cmd->iscsi_opcode,
449 cmd->init_task_tag, conn->cid);
450
451 return 0;
452}
453
454/*
455 * Handles special after-the-fact actions related to TMRs.
456 * Right now the only one that its really needed for is
457 * connection recovery releated TASK_REASSIGN.
458 */
459extern int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
460{
461 struct iscsi_tmr_req *tmr_req = cmd->tmr_req;
462 struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
463
464 if (tmr_req->task_reassign &&
465 (se_tmr->response == ISCSI_TMF_RSP_COMPLETE))
466 return iscsit_task_reassign_complete(tmr_req, conn);
467
468 return 0;
469}
470
471/*
472 * Nothing to do here, but leave it for good measure. :-)
473 */
474int iscsit_task_reassign_prepare_read(
475 struct iscsi_tmr_req *tmr_req,
476 struct iscsi_conn *conn)
477{
478 return 0;
479}
480
481static void iscsit_task_reassign_prepare_unsolicited_dataout(
482 struct iscsi_cmd *cmd,
483 struct iscsi_conn *conn)
484{
485 int i, j;
486 struct iscsi_pdu *pdu = NULL;
487 struct iscsi_seq *seq = NULL;
488
489 if (conn->sess->sess_ops->DataSequenceInOrder) {
490 cmd->data_sn = 0;
491
492 if (cmd->immediate_data)
493 cmd->r2t_offset += (cmd->first_burst_len -
494 cmd->seq_start_offset);
495
496 if (conn->sess->sess_ops->DataPDUInOrder) {
497 cmd->write_data_done -= (cmd->immediate_data) ?
498 (cmd->first_burst_len -
499 cmd->seq_start_offset) :
500 cmd->first_burst_len;
501 cmd->first_burst_len = 0;
502 return;
503 }
504
505 for (i = 0; i < cmd->pdu_count; i++) {
506 pdu = &cmd->pdu_list[i];
507
508 if (pdu->status != ISCSI_PDU_RECEIVED_OK)
509 continue;
510
511 if ((pdu->offset >= cmd->seq_start_offset) &&
512 ((pdu->offset + pdu->length) <=
513 cmd->seq_end_offset)) {
514 cmd->first_burst_len -= pdu->length;
515 cmd->write_data_done -= pdu->length;
516 pdu->status = ISCSI_PDU_NOT_RECEIVED;
517 }
518 }
519 } else {
520 for (i = 0; i < cmd->seq_count; i++) {
521 seq = &cmd->seq_list[i];
522
523 if (seq->type != SEQTYPE_UNSOLICITED)
524 continue;
525
526 cmd->write_data_done -=
527 (seq->offset - seq->orig_offset);
528 cmd->first_burst_len = 0;
529 seq->data_sn = 0;
530 seq->offset = seq->orig_offset;
531 seq->next_burst_len = 0;
532 seq->status = DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY;
533
534 if (conn->sess->sess_ops->DataPDUInOrder)
535 continue;
536
537 for (j = 0; j < seq->pdu_count; j++) {
538 pdu = &cmd->pdu_list[j+seq->pdu_start];
539
540 if (pdu->status != ISCSI_PDU_RECEIVED_OK)
541 continue;
542
543 pdu->status = ISCSI_PDU_NOT_RECEIVED;
544 }
545 }
546 }
547}
548
549int iscsit_task_reassign_prepare_write(
550 struct iscsi_tmr_req *tmr_req,
551 struct iscsi_conn *conn)
552{
553 struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
554 struct se_cmd *se_cmd = se_tmr->ref_cmd;
555 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
556 struct iscsi_pdu *pdu = NULL;
557 struct iscsi_r2t *r2t = NULL, *r2t_tmp;
558 int first_incomplete_r2t = 1, i = 0;
559
560 /*
561 * The command was in the process of receiving Unsolicited DataOUT when
562 * the connection failed.
563 */
564 if (cmd->unsolicited_data)
565 iscsit_task_reassign_prepare_unsolicited_dataout(cmd, conn);
566
567 /*
568 * The Initiator is requesting R2Ts starting from zero, skip
569 * checking acknowledged R2Ts and start checking struct iscsi_r2ts
570 * greater than zero.
571 */
572 if (!tmr_req->exp_data_sn)
573 goto drop_unacknowledged_r2ts;
574
575 /*
576 * We now check that the PDUs in DataOUT sequences below
577 * the TMR TASK_REASSIGN ExpDataSN (R2TSN the Initiator is
578 * expecting next) have all the DataOUT they require to complete
579 * the DataOUT sequence. First scan from R2TSN 0 to TMR
580 * TASK_REASSIGN ExpDataSN-1.
581 *
582 * If we have not received all DataOUT in question, we must
583 * make sure to make the appropriate changes to values in
584 * struct iscsi_cmd (and elsewhere depending on session parameters)
585 * so iscsit_build_r2ts_for_cmd() in iscsit_task_reassign_complete_write()
586 * will resend a new R2T for the DataOUT sequences in question.
587 */
588 spin_lock_bh(&cmd->r2t_lock);
589 if (list_empty(&cmd->cmd_r2t_list)) {
590 spin_unlock_bh(&cmd->r2t_lock);
591 return -1;
592 }
593
594 list_for_each_entry(r2t, &cmd->cmd_r2t_list, r2t_list) {
595
596 if (r2t->r2t_sn >= tmr_req->exp_data_sn)
597 continue;
598 /*
599 * Safely ignore Recovery R2Ts and R2Ts that have completed
600 * DataOUT sequences.
601 */
602 if (r2t->seq_complete)
603 continue;
604
605 if (r2t->recovery_r2t)
606 continue;
607
608 /*
609 * DataSequenceInOrder=Yes:
610 *
611 * Taking into account the iSCSI implementation requirement of
612 * MaxOutstandingR2T=1 while ErrorRecoveryLevel>0 and
613 * DataSequenceInOrder=Yes, we must take into consideration
614 * the following:
615 *
616 * DataSequenceInOrder=No:
617 *
618 * Taking into account that the Initiator controls the (possibly
619 * random) PDU Order in (possibly random) Sequence Order of
620 * DataOUT the target requests with R2Ts, we must take into
621 * consideration the following:
622 *
623 * DataPDUInOrder=Yes for DataSequenceInOrder=[Yes,No]:
624 *
625 * While processing non-complete R2T DataOUT sequence requests
626 * the Target will re-request only the total sequence length
627 * minus current received offset. This is because we must
628 * assume the initiator will continue sending DataOUT from the
629 * last PDU before the connection failed.
630 *
631 * DataPDUInOrder=No for DataSequenceInOrder=[Yes,No]:
632 *
633 * While processing non-complete R2T DataOUT sequence requests
634 * the Target will re-request the entire DataOUT sequence if
635 * any single PDU is missing from the sequence. This is because
636 * we have no logical method to determine the next PDU offset,
637 * and we must assume the Initiator will be sending any random
638 * PDU offset in the current sequence after TASK_REASSIGN
639 * has completed.
640 */
641 if (conn->sess->sess_ops->DataSequenceInOrder) {
642 if (!first_incomplete_r2t) {
643 cmd->r2t_offset -= r2t->xfer_len;
644 goto next;
645 }
646
647 if (conn->sess->sess_ops->DataPDUInOrder) {
648 cmd->data_sn = 0;
649 cmd->r2t_offset -= (r2t->xfer_len -
650 cmd->next_burst_len);
651 first_incomplete_r2t = 0;
652 goto next;
653 }
654
655 cmd->data_sn = 0;
656 cmd->r2t_offset -= r2t->xfer_len;
657
658 for (i = 0; i < cmd->pdu_count; i++) {
659 pdu = &cmd->pdu_list[i];
660
661 if (pdu->status != ISCSI_PDU_RECEIVED_OK)
662 continue;
663
664 if ((pdu->offset >= r2t->offset) &&
665 (pdu->offset < (r2t->offset +
666 r2t->xfer_len))) {
667 cmd->next_burst_len -= pdu->length;
668 cmd->write_data_done -= pdu->length;
669 pdu->status = ISCSI_PDU_NOT_RECEIVED;
670 }
671 }
672
673 first_incomplete_r2t = 0;
674 } else {
675 struct iscsi_seq *seq;
676
677 seq = iscsit_get_seq_holder(cmd, r2t->offset,
678 r2t->xfer_len);
679 if (!seq) {
680 spin_unlock_bh(&cmd->r2t_lock);
681 return -1;
682 }
683
684 cmd->write_data_done -=
685 (seq->offset - seq->orig_offset);
686 seq->data_sn = 0;
687 seq->offset = seq->orig_offset;
688 seq->next_burst_len = 0;
689 seq->status = DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY;
690
691 cmd->seq_send_order--;
692
693 if (conn->sess->sess_ops->DataPDUInOrder)
694 goto next;
695
696 for (i = 0; i < seq->pdu_count; i++) {
697 pdu = &cmd->pdu_list[i+seq->pdu_start];
698
699 if (pdu->status != ISCSI_PDU_RECEIVED_OK)
700 continue;
701
702 pdu->status = ISCSI_PDU_NOT_RECEIVED;
703 }
704 }
705
706next:
707 cmd->outstanding_r2ts--;
708 }
709 spin_unlock_bh(&cmd->r2t_lock);
710
711 /*
712 * We now drop all unacknowledged R2Ts, ie: ExpDataSN from TMR
713 * TASK_REASSIGN to the last R2T in the list.. We are also careful
714 * to check that the Initiator is not requesting R2Ts for DataOUT
715 * sequences it has already completed.
716 *
717 * Free each R2T in question and adjust values in struct iscsi_cmd
718 * accordingly so iscsit_build_r2ts_for_cmd() do the rest of
719 * the work after the TMR TASK_REASSIGN Response is sent.
720 */
721drop_unacknowledged_r2ts:
722
723 cmd->cmd_flags &= ~ICF_SENT_LAST_R2T;
724 cmd->r2t_sn = tmr_req->exp_data_sn;
725
726 spin_lock_bh(&cmd->r2t_lock);
727 list_for_each_entry_safe(r2t, r2t_tmp, &cmd->cmd_r2t_list, r2t_list) {
728 /*
729 * Skip up to the R2T Sequence number provided by the
730 * iSCSI TASK_REASSIGN TMR
731 */
732 if (r2t->r2t_sn < tmr_req->exp_data_sn)
733 continue;
734
735 if (r2t->seq_complete) {
736 pr_err("Initiator is requesting R2Ts from"
737 " R2TSN: 0x%08x, but R2TSN: 0x%08x, Offset: %u,"
738 " Length: %u is already complete."
739 " BAD INITIATOR ERL=2 IMPLEMENTATION!\n",
740 tmr_req->exp_data_sn, r2t->r2t_sn,
741 r2t->offset, r2t->xfer_len);
742 spin_unlock_bh(&cmd->r2t_lock);
743 return -1;
744 }
745
746 if (r2t->recovery_r2t) {
747 iscsit_free_r2t(r2t, cmd);
748 continue;
749 }
750
751 /* DataSequenceInOrder=Yes:
752 *
753 * Taking into account the iSCSI implementation requirement of
754 * MaxOutstandingR2T=1 while ErrorRecoveryLevel>0 and
755 * DataSequenceInOrder=Yes, it's safe to subtract the R2Ts
756 * entire transfer length from the commands R2T offset marker.
757 *
758 * DataSequenceInOrder=No:
759 *
760 * We subtract the difference from struct iscsi_seq between the
761 * current offset and original offset from cmd->write_data_done
762 * for account for DataOUT PDUs already received. Then reset
763 * the current offset to the original and zero out the current
764 * burst length, to make sure we re-request the entire DataOUT
765 * sequence.
766 */
767 if (conn->sess->sess_ops->DataSequenceInOrder)
768 cmd->r2t_offset -= r2t->xfer_len;
769 else
770 cmd->seq_send_order--;
771
772 cmd->outstanding_r2ts--;
773 iscsit_free_r2t(r2t, cmd);
774 }
775 spin_unlock_bh(&cmd->r2t_lock);
776
777 return 0;
778}
779
780/*
781 * Performs sanity checks TMR TASK_REASSIGN's ExpDataSN for
782 * a given struct iscsi_cmd.
783 */
784int iscsit_check_task_reassign_expdatasn(
785 struct iscsi_tmr_req *tmr_req,
786 struct iscsi_conn *conn)
787{
788 struct se_tmr_req *se_tmr = tmr_req->se_tmr_req;
789 struct se_cmd *se_cmd = se_tmr->ref_cmd;
790 struct iscsi_cmd *ref_cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
791
792 if (ref_cmd->iscsi_opcode != ISCSI_OP_SCSI_CMD)
793 return 0;
794
795 if (se_cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION)
796 return 0;
797
798 if (ref_cmd->data_direction == DMA_NONE)
799 return 0;
800
801 /*
802 * For READs the TMR TASK_REASSIGNs ExpDataSN contains the next DataSN
803 * of DataIN the Initiator is expecting.
804 *
805 * Also check that the Initiator is not re-requesting DataIN that has
806 * already been acknowledged with a DataAck SNACK.
807 */
808 if (ref_cmd->data_direction == DMA_FROM_DEVICE) {
809 if (tmr_req->exp_data_sn > ref_cmd->data_sn) {
810 pr_err("Received ExpDataSN: 0x%08x for READ"
811 " in TMR TASK_REASSIGN greater than command's"
812 " DataSN: 0x%08x.\n", tmr_req->exp_data_sn,
813 ref_cmd->data_sn);
814 return -1;
815 }
816 if ((ref_cmd->cmd_flags & ICF_GOT_DATACK_SNACK) &&
817 (tmr_req->exp_data_sn <= ref_cmd->acked_data_sn)) {
818 pr_err("Received ExpDataSN: 0x%08x for READ"
819 " in TMR TASK_REASSIGN for previously"
820 " acknowledged DataIN: 0x%08x,"
821 " protocol error\n", tmr_req->exp_data_sn,
822 ref_cmd->acked_data_sn);
823 return -1;
824 }
825 return iscsit_task_reassign_prepare_read(tmr_req, conn);
826 }
827
828 /*
829 * For WRITEs the TMR TASK_REASSIGNs ExpDataSN contains the next R2TSN
830 * for R2Ts the Initiator is expecting.
831 *
832 * Do the magic in iscsit_task_reassign_prepare_write().
833 */
834 if (ref_cmd->data_direction == DMA_TO_DEVICE) {
835 if (tmr_req->exp_data_sn > ref_cmd->r2t_sn) {
836 pr_err("Received ExpDataSN: 0x%08x for WRITE"
837 " in TMR TASK_REASSIGN greater than command's"
838 " R2TSN: 0x%08x.\n", tmr_req->exp_data_sn,
839 ref_cmd->r2t_sn);
840 return -1;
841 }
842 return iscsit_task_reassign_prepare_write(tmr_req, conn);
843 }
844
845 pr_err("Unknown iSCSI data_direction: 0x%02x\n",
846 ref_cmd->data_direction);
847
848 return -1;
849}
diff --git a/drivers/target/iscsi/iscsi_target_tmr.h b/drivers/target/iscsi/iscsi_target_tmr.h
new file mode 100644
index 000000000000..142e992cb097
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_tmr.h
@@ -0,0 +1,14 @@
1#ifndef ISCSI_TARGET_TMR_H
2#define ISCSI_TARGET_TMR_H
3
4extern u8 iscsit_tmr_abort_task(struct iscsi_cmd *, unsigned char *);
5extern int iscsit_tmr_task_warm_reset(struct iscsi_conn *, struct iscsi_tmr_req *,
6 unsigned char *);
7extern int iscsit_tmr_task_cold_reset(struct iscsi_conn *, struct iscsi_tmr_req *,
8 unsigned char *);
9extern u8 iscsit_tmr_task_reassign(struct iscsi_cmd *, unsigned char *);
10extern int iscsit_tmr_post_handler(struct iscsi_cmd *, struct iscsi_conn *);
11extern int iscsit_check_task_reassign_expdatasn(struct iscsi_tmr_req *,
12 struct iscsi_conn *);
13
14#endif /* ISCSI_TARGET_TMR_H */
diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c
new file mode 100644
index 000000000000..d4cf2cd25c44
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_tpg.c
@@ -0,0 +1,759 @@
1/*******************************************************************************
2 * This file contains iSCSI Target Portal Group related functions.
3 *
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5 *
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7 *
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.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
21#include <target/target_core_base.h>
22#include <target/target_core_transport.h>
23#include <target/target_core_fabric_ops.h>
24#include <target/target_core_configfs.h>
25#include <target/target_core_tpg.h>
26
27#include "iscsi_target_core.h"
28#include "iscsi_target_erl0.h"
29#include "iscsi_target_login.h"
30#include "iscsi_target_nodeattrib.h"
31#include "iscsi_target_tpg.h"
32#include "iscsi_target_util.h"
33#include "iscsi_target.h"
34#include "iscsi_target_parameters.h"
35
36struct iscsi_portal_group *iscsit_alloc_portal_group(struct iscsi_tiqn *tiqn, u16 tpgt)
37{
38 struct iscsi_portal_group *tpg;
39
40 tpg = kzalloc(sizeof(struct iscsi_portal_group), GFP_KERNEL);
41 if (!tpg) {
42 pr_err("Unable to allocate struct iscsi_portal_group\n");
43 return NULL;
44 }
45
46 tpg->tpgt = tpgt;
47 tpg->tpg_state = TPG_STATE_FREE;
48 tpg->tpg_tiqn = tiqn;
49 INIT_LIST_HEAD(&tpg->tpg_gnp_list);
50 INIT_LIST_HEAD(&tpg->tpg_list);
51 mutex_init(&tpg->tpg_access_lock);
52 mutex_init(&tpg->np_login_lock);
53 spin_lock_init(&tpg->tpg_state_lock);
54 spin_lock_init(&tpg->tpg_np_lock);
55
56 return tpg;
57}
58
59static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *);
60
61int iscsit_load_discovery_tpg(void)
62{
63 struct iscsi_param *param;
64 struct iscsi_portal_group *tpg;
65 int ret;
66
67 tpg = iscsit_alloc_portal_group(NULL, 1);
68 if (!tpg) {
69 pr_err("Unable to allocate struct iscsi_portal_group\n");
70 return -1;
71 }
72
73 ret = core_tpg_register(
74 &lio_target_fabric_configfs->tf_ops,
75 NULL, &tpg->tpg_se_tpg, (void *)tpg,
76 TRANSPORT_TPG_TYPE_DISCOVERY);
77 if (ret < 0) {
78 kfree(tpg);
79 return -1;
80 }
81
82 tpg->sid = 1; /* First Assigned LIO Session ID */
83 iscsit_set_default_tpg_attribs(tpg);
84
85 if (iscsi_create_default_params(&tpg->param_list) < 0)
86 goto out;
87 /*
88 * By default we disable authentication for discovery sessions,
89 * this can be changed with:
90 *
91 * /sys/kernel/config/target/iscsi/discovery_auth/enforce_discovery_auth
92 */
93 param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
94 if (!param)
95 goto out;
96
97 if (iscsi_update_param_value(param, "CHAP,None") < 0)
98 goto out;
99
100 tpg->tpg_attrib.authentication = 0;
101
102 spin_lock(&tpg->tpg_state_lock);
103 tpg->tpg_state = TPG_STATE_ACTIVE;
104 spin_unlock(&tpg->tpg_state_lock);
105
106 iscsit_global->discovery_tpg = tpg;
107 pr_debug("CORE[0] - Allocated Discovery TPG\n");
108
109 return 0;
110out:
111 if (tpg->sid == 1)
112 core_tpg_deregister(&tpg->tpg_se_tpg);
113 kfree(tpg);
114 return -1;
115}
116
117void iscsit_release_discovery_tpg(void)
118{
119 struct iscsi_portal_group *tpg = iscsit_global->discovery_tpg;
120
121 if (!tpg)
122 return;
123
124 core_tpg_deregister(&tpg->tpg_se_tpg);
125
126 kfree(tpg);
127 iscsit_global->discovery_tpg = NULL;
128}
129
130struct iscsi_portal_group *iscsit_get_tpg_from_np(
131 struct iscsi_tiqn *tiqn,
132 struct iscsi_np *np)
133{
134 struct iscsi_portal_group *tpg = NULL;
135 struct iscsi_tpg_np *tpg_np;
136
137 spin_lock(&tiqn->tiqn_tpg_lock);
138 list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
139
140 spin_lock(&tpg->tpg_state_lock);
141 if (tpg->tpg_state == TPG_STATE_FREE) {
142 spin_unlock(&tpg->tpg_state_lock);
143 continue;
144 }
145 spin_unlock(&tpg->tpg_state_lock);
146
147 spin_lock(&tpg->tpg_np_lock);
148 list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
149 if (tpg_np->tpg_np == np) {
150 spin_unlock(&tpg->tpg_np_lock);
151 spin_unlock(&tiqn->tiqn_tpg_lock);
152 return tpg;
153 }
154 }
155 spin_unlock(&tpg->tpg_np_lock);
156 }
157 spin_unlock(&tiqn->tiqn_tpg_lock);
158
159 return NULL;
160}
161
162int iscsit_get_tpg(
163 struct iscsi_portal_group *tpg)
164{
165 int ret;
166
167 ret = mutex_lock_interruptible(&tpg->tpg_access_lock);
168 return ((ret != 0) || signal_pending(current)) ? -1 : 0;
169}
170
171void iscsit_put_tpg(struct iscsi_portal_group *tpg)
172{
173 mutex_unlock(&tpg->tpg_access_lock);
174}
175
176static void iscsit_clear_tpg_np_login_thread(
177 struct iscsi_tpg_np *tpg_np,
178 struct iscsi_portal_group *tpg)
179{
180 if (!tpg_np->tpg_np) {
181 pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
182 return;
183 }
184
185 iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg);
186}
187
188void iscsit_clear_tpg_np_login_threads(
189 struct iscsi_portal_group *tpg)
190{
191 struct iscsi_tpg_np *tpg_np;
192
193 spin_lock(&tpg->tpg_np_lock);
194 list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
195 if (!tpg_np->tpg_np) {
196 pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
197 continue;
198 }
199 spin_unlock(&tpg->tpg_np_lock);
200 iscsit_clear_tpg_np_login_thread(tpg_np, tpg);
201 spin_lock(&tpg->tpg_np_lock);
202 }
203 spin_unlock(&tpg->tpg_np_lock);
204}
205
206void iscsit_tpg_dump_params(struct iscsi_portal_group *tpg)
207{
208 iscsi_print_params(tpg->param_list);
209}
210
211static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg)
212{
213 struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
214
215 a->authentication = TA_AUTHENTICATION;
216 a->login_timeout = TA_LOGIN_TIMEOUT;
217 a->netif_timeout = TA_NETIF_TIMEOUT;
218 a->default_cmdsn_depth = TA_DEFAULT_CMDSN_DEPTH;
219 a->generate_node_acls = TA_GENERATE_NODE_ACLS;
220 a->cache_dynamic_acls = TA_CACHE_DYNAMIC_ACLS;
221 a->demo_mode_write_protect = TA_DEMO_MODE_WRITE_PROTECT;
222 a->prod_mode_write_protect = TA_PROD_MODE_WRITE_PROTECT;
223}
224
225int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg)
226{
227 if (tpg->tpg_state != TPG_STATE_FREE) {
228 pr_err("Unable to add iSCSI Target Portal Group: %d"
229 " while not in TPG_STATE_FREE state.\n", tpg->tpgt);
230 return -EEXIST;
231 }
232 iscsit_set_default_tpg_attribs(tpg);
233
234 if (iscsi_create_default_params(&tpg->param_list) < 0)
235 goto err_out;
236
237 ISCSI_TPG_ATTRIB(tpg)->tpg = tpg;
238
239 spin_lock(&tpg->tpg_state_lock);
240 tpg->tpg_state = TPG_STATE_INACTIVE;
241 spin_unlock(&tpg->tpg_state_lock);
242
243 spin_lock(&tiqn->tiqn_tpg_lock);
244 list_add_tail(&tpg->tpg_list, &tiqn->tiqn_tpg_list);
245 tiqn->tiqn_ntpgs++;
246 pr_debug("CORE[%s]_TPG[%hu] - Added iSCSI Target Portal Group\n",
247 tiqn->tiqn, tpg->tpgt);
248 spin_unlock(&tiqn->tiqn_tpg_lock);
249
250 return 0;
251err_out:
252 if (tpg->param_list) {
253 iscsi_release_param_list(tpg->param_list);
254 tpg->param_list = NULL;
255 }
256 kfree(tpg);
257 return -ENOMEM;
258}
259
260int iscsit_tpg_del_portal_group(
261 struct iscsi_tiqn *tiqn,
262 struct iscsi_portal_group *tpg,
263 int force)
264{
265 u8 old_state = tpg->tpg_state;
266
267 spin_lock(&tpg->tpg_state_lock);
268 tpg->tpg_state = TPG_STATE_INACTIVE;
269 spin_unlock(&tpg->tpg_state_lock);
270
271 if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
272 pr_err("Unable to delete iSCSI Target Portal Group:"
273 " %hu while active sessions exist, and force=0\n",
274 tpg->tpgt);
275 tpg->tpg_state = old_state;
276 return -EPERM;
277 }
278
279 core_tpg_clear_object_luns(&tpg->tpg_se_tpg);
280
281 if (tpg->param_list) {
282 iscsi_release_param_list(tpg->param_list);
283 tpg->param_list = NULL;
284 }
285
286 core_tpg_deregister(&tpg->tpg_se_tpg);
287
288 spin_lock(&tpg->tpg_state_lock);
289 tpg->tpg_state = TPG_STATE_FREE;
290 spin_unlock(&tpg->tpg_state_lock);
291
292 spin_lock(&tiqn->tiqn_tpg_lock);
293 tiqn->tiqn_ntpgs--;
294 list_del(&tpg->tpg_list);
295 spin_unlock(&tiqn->tiqn_tpg_lock);
296
297 pr_debug("CORE[%s]_TPG[%hu] - Deleted iSCSI Target Portal Group\n",
298 tiqn->tiqn, tpg->tpgt);
299
300 kfree(tpg);
301 return 0;
302}
303
304int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *tpg)
305{
306 struct iscsi_param *param;
307 struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
308
309 spin_lock(&tpg->tpg_state_lock);
310 if (tpg->tpg_state == TPG_STATE_ACTIVE) {
311 pr_err("iSCSI target portal group: %hu is already"
312 " active, ignoring request.\n", tpg->tpgt);
313 spin_unlock(&tpg->tpg_state_lock);
314 return -EINVAL;
315 }
316 /*
317 * Make sure that AuthMethod does not contain None as an option
318 * unless explictly disabled. Set the default to CHAP if authentication
319 * is enforced (as per default), and remove the NONE option.
320 */
321 param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
322 if (!param) {
323 spin_unlock(&tpg->tpg_state_lock);
324 return -ENOMEM;
325 }
326
327 if (ISCSI_TPG_ATTRIB(tpg)->authentication) {
328 if (!strcmp(param->value, NONE))
329 if (iscsi_update_param_value(param, CHAP) < 0) {
330 spin_unlock(&tpg->tpg_state_lock);
331 return -ENOMEM;
332 }
333 if (iscsit_ta_authentication(tpg, 1) < 0) {
334 spin_unlock(&tpg->tpg_state_lock);
335 return -ENOMEM;
336 }
337 }
338
339 tpg->tpg_state = TPG_STATE_ACTIVE;
340 spin_unlock(&tpg->tpg_state_lock);
341
342 spin_lock(&tiqn->tiqn_tpg_lock);
343 tiqn->tiqn_active_tpgs++;
344 pr_debug("iSCSI_TPG[%hu] - Enabled iSCSI Target Portal Group\n",
345 tpg->tpgt);
346 spin_unlock(&tiqn->tiqn_tpg_lock);
347
348 return 0;
349}
350
351int iscsit_tpg_disable_portal_group(struct iscsi_portal_group *tpg, int force)
352{
353 struct iscsi_tiqn *tiqn;
354 u8 old_state = tpg->tpg_state;
355
356 spin_lock(&tpg->tpg_state_lock);
357 if (tpg->tpg_state == TPG_STATE_INACTIVE) {
358 pr_err("iSCSI Target Portal Group: %hu is already"
359 " inactive, ignoring request.\n", tpg->tpgt);
360 spin_unlock(&tpg->tpg_state_lock);
361 return -EINVAL;
362 }
363 tpg->tpg_state = TPG_STATE_INACTIVE;
364 spin_unlock(&tpg->tpg_state_lock);
365
366 iscsit_clear_tpg_np_login_threads(tpg);
367
368 if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
369 spin_lock(&tpg->tpg_state_lock);
370 tpg->tpg_state = old_state;
371 spin_unlock(&tpg->tpg_state_lock);
372 pr_err("Unable to disable iSCSI Target Portal Group:"
373 " %hu while active sessions exist, and force=0\n",
374 tpg->tpgt);
375 return -EPERM;
376 }
377
378 tiqn = tpg->tpg_tiqn;
379 if (!tiqn || (tpg == iscsit_global->discovery_tpg))
380 return 0;
381
382 spin_lock(&tiqn->tiqn_tpg_lock);
383 tiqn->tiqn_active_tpgs--;
384 pr_debug("iSCSI_TPG[%hu] - Disabled iSCSI Target Portal Group\n",
385 tpg->tpgt);
386 spin_unlock(&tiqn->tiqn_tpg_lock);
387
388 return 0;
389}
390
391struct iscsi_node_attrib *iscsit_tpg_get_node_attrib(
392 struct iscsi_session *sess)
393{
394 struct se_session *se_sess = sess->se_sess;
395 struct se_node_acl *se_nacl = se_sess->se_node_acl;
396 struct iscsi_node_acl *acl = container_of(se_nacl, struct iscsi_node_acl,
397 se_node_acl);
398
399 return &acl->node_attrib;
400}
401
402struct iscsi_tpg_np *iscsit_tpg_locate_child_np(
403 struct iscsi_tpg_np *tpg_np,
404 int network_transport)
405{
406 struct iscsi_tpg_np *tpg_np_child, *tpg_np_child_tmp;
407
408 spin_lock(&tpg_np->tpg_np_parent_lock);
409 list_for_each_entry_safe(tpg_np_child, tpg_np_child_tmp,
410 &tpg_np->tpg_np_parent_list, tpg_np_child_list) {
411 if (tpg_np_child->tpg_np->np_network_transport ==
412 network_transport) {
413 spin_unlock(&tpg_np->tpg_np_parent_lock);
414 return tpg_np_child;
415 }
416 }
417 spin_unlock(&tpg_np->tpg_np_parent_lock);
418
419 return NULL;
420}
421
422struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
423 struct iscsi_portal_group *tpg,
424 struct __kernel_sockaddr_storage *sockaddr,
425 char *ip_str,
426 struct iscsi_tpg_np *tpg_np_parent,
427 int network_transport)
428{
429 struct iscsi_np *np;
430 struct iscsi_tpg_np *tpg_np;
431
432 tpg_np = kzalloc(sizeof(struct iscsi_tpg_np), GFP_KERNEL);
433 if (!tpg_np) {
434 pr_err("Unable to allocate memory for"
435 " struct iscsi_tpg_np.\n");
436 return ERR_PTR(-ENOMEM);
437 }
438
439 np = iscsit_add_np(sockaddr, ip_str, network_transport);
440 if (IS_ERR(np)) {
441 kfree(tpg_np);
442 return ERR_CAST(np);
443 }
444
445 INIT_LIST_HEAD(&tpg_np->tpg_np_list);
446 INIT_LIST_HEAD(&tpg_np->tpg_np_child_list);
447 INIT_LIST_HEAD(&tpg_np->tpg_np_parent_list);
448 spin_lock_init(&tpg_np->tpg_np_parent_lock);
449 tpg_np->tpg_np = np;
450 tpg_np->tpg = tpg;
451
452 spin_lock(&tpg->tpg_np_lock);
453 list_add_tail(&tpg_np->tpg_np_list, &tpg->tpg_gnp_list);
454 tpg->num_tpg_nps++;
455 if (tpg->tpg_tiqn)
456 tpg->tpg_tiqn->tiqn_num_tpg_nps++;
457 spin_unlock(&tpg->tpg_np_lock);
458
459 if (tpg_np_parent) {
460 tpg_np->tpg_np_parent = tpg_np_parent;
461 spin_lock(&tpg_np_parent->tpg_np_parent_lock);
462 list_add_tail(&tpg_np->tpg_np_child_list,
463 &tpg_np_parent->tpg_np_parent_list);
464 spin_unlock(&tpg_np_parent->tpg_np_parent_lock);
465 }
466
467 pr_debug("CORE[%s] - Added Network Portal: %s:%hu,%hu on %s\n",
468 tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt,
469 (np->np_network_transport == ISCSI_TCP) ? "TCP" : "SCTP");
470
471 return tpg_np;
472}
473
474static int iscsit_tpg_release_np(
475 struct iscsi_tpg_np *tpg_np,
476 struct iscsi_portal_group *tpg,
477 struct iscsi_np *np)
478{
479 iscsit_clear_tpg_np_login_thread(tpg_np, tpg);
480
481 pr_debug("CORE[%s] - Removed Network Portal: %s:%hu,%hu on %s\n",
482 tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt,
483 (np->np_network_transport == ISCSI_TCP) ? "TCP" : "SCTP");
484
485 tpg_np->tpg_np = NULL;
486 tpg_np->tpg = NULL;
487 kfree(tpg_np);
488 /*
489 * iscsit_del_np() will shutdown struct iscsi_np when last TPG reference is released.
490 */
491 return iscsit_del_np(np);
492}
493
494int iscsit_tpg_del_network_portal(
495 struct iscsi_portal_group *tpg,
496 struct iscsi_tpg_np *tpg_np)
497{
498 struct iscsi_np *np;
499 struct iscsi_tpg_np *tpg_np_child, *tpg_np_child_tmp;
500 int ret = 0;
501
502 np = tpg_np->tpg_np;
503 if (!np) {
504 pr_err("Unable to locate struct iscsi_np from"
505 " struct iscsi_tpg_np\n");
506 return -EINVAL;
507 }
508
509 if (!tpg_np->tpg_np_parent) {
510 /*
511 * We are the parent tpg network portal. Release all of the
512 * child tpg_np's (eg: the non ISCSI_TCP ones) on our parent
513 * list first.
514 */
515 list_for_each_entry_safe(tpg_np_child, tpg_np_child_tmp,
516 &tpg_np->tpg_np_parent_list,
517 tpg_np_child_list) {
518 ret = iscsit_tpg_del_network_portal(tpg, tpg_np_child);
519 if (ret < 0)
520 pr_err("iscsit_tpg_del_network_portal()"
521 " failed: %d\n", ret);
522 }
523 } else {
524 /*
525 * We are not the parent ISCSI_TCP tpg network portal. Release
526 * our own network portals from the child list.
527 */
528 spin_lock(&tpg_np->tpg_np_parent->tpg_np_parent_lock);
529 list_del(&tpg_np->tpg_np_child_list);
530 spin_unlock(&tpg_np->tpg_np_parent->tpg_np_parent_lock);
531 }
532
533 spin_lock(&tpg->tpg_np_lock);
534 list_del(&tpg_np->tpg_np_list);
535 tpg->num_tpg_nps--;
536 if (tpg->tpg_tiqn)
537 tpg->tpg_tiqn->tiqn_num_tpg_nps--;
538 spin_unlock(&tpg->tpg_np_lock);
539
540 return iscsit_tpg_release_np(tpg_np, tpg, np);
541}
542
543int iscsit_tpg_set_initiator_node_queue_depth(
544 struct iscsi_portal_group *tpg,
545 unsigned char *initiatorname,
546 u32 queue_depth,
547 int force)
548{
549 return core_tpg_set_initiator_node_queue_depth(&tpg->tpg_se_tpg,
550 initiatorname, queue_depth, force);
551}
552
553int iscsit_ta_authentication(struct iscsi_portal_group *tpg, u32 authentication)
554{
555 unsigned char buf1[256], buf2[256], *none = NULL;
556 int len;
557 struct iscsi_param *param;
558 struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
559
560 if ((authentication != 1) && (authentication != 0)) {
561 pr_err("Illegal value for authentication parameter:"
562 " %u, ignoring request.\n", authentication);
563 return -1;
564 }
565
566 memset(buf1, 0, sizeof(buf1));
567 memset(buf2, 0, sizeof(buf2));
568
569 param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
570 if (!param)
571 return -EINVAL;
572
573 if (authentication) {
574 snprintf(buf1, sizeof(buf1), "%s", param->value);
575 none = strstr(buf1, NONE);
576 if (!none)
577 goto out;
578 if (!strncmp(none + 4, ",", 1)) {
579 if (!strcmp(buf1, none))
580 sprintf(buf2, "%s", none+5);
581 else {
582 none--;
583 *none = '\0';
584 len = sprintf(buf2, "%s", buf1);
585 none += 5;
586 sprintf(buf2 + len, "%s", none);
587 }
588 } else {
589 none--;
590 *none = '\0';
591 sprintf(buf2, "%s", buf1);
592 }
593 if (iscsi_update_param_value(param, buf2) < 0)
594 return -EINVAL;
595 } else {
596 snprintf(buf1, sizeof(buf1), "%s", param->value);
597 none = strstr(buf1, NONE);
598 if ((none))
599 goto out;
600 strncat(buf1, ",", strlen(","));
601 strncat(buf1, NONE, strlen(NONE));
602 if (iscsi_update_param_value(param, buf1) < 0)
603 return -EINVAL;
604 }
605
606out:
607 a->authentication = authentication;
608 pr_debug("%s iSCSI Authentication Methods for TPG: %hu.\n",
609 a->authentication ? "Enforcing" : "Disabling", tpg->tpgt);
610
611 return 0;
612}
613
614int iscsit_ta_login_timeout(
615 struct iscsi_portal_group *tpg,
616 u32 login_timeout)
617{
618 struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
619
620 if (login_timeout > TA_LOGIN_TIMEOUT_MAX) {
621 pr_err("Requested Login Timeout %u larger than maximum"
622 " %u\n", login_timeout, TA_LOGIN_TIMEOUT_MAX);
623 return -EINVAL;
624 } else if (login_timeout < TA_LOGIN_TIMEOUT_MIN) {
625 pr_err("Requested Logout Timeout %u smaller than"
626 " minimum %u\n", login_timeout, TA_LOGIN_TIMEOUT_MIN);
627 return -EINVAL;
628 }
629
630 a->login_timeout = login_timeout;
631 pr_debug("Set Logout Timeout to %u for Target Portal Group"
632 " %hu\n", a->login_timeout, tpg->tpgt);
633
634 return 0;
635}
636
637int iscsit_ta_netif_timeout(
638 struct iscsi_portal_group *tpg,
639 u32 netif_timeout)
640{
641 struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
642
643 if (netif_timeout > TA_NETIF_TIMEOUT_MAX) {
644 pr_err("Requested Network Interface Timeout %u larger"
645 " than maximum %u\n", netif_timeout,
646 TA_NETIF_TIMEOUT_MAX);
647 return -EINVAL;
648 } else if (netif_timeout < TA_NETIF_TIMEOUT_MIN) {
649 pr_err("Requested Network Interface Timeout %u smaller"
650 " than minimum %u\n", netif_timeout,
651 TA_NETIF_TIMEOUT_MIN);
652 return -EINVAL;
653 }
654
655 a->netif_timeout = netif_timeout;
656 pr_debug("Set Network Interface Timeout to %u for"
657 " Target Portal Group %hu\n", a->netif_timeout, tpg->tpgt);
658
659 return 0;
660}
661
662int iscsit_ta_generate_node_acls(
663 struct iscsi_portal_group *tpg,
664 u32 flag)
665{
666 struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
667
668 if ((flag != 0) && (flag != 1)) {
669 pr_err("Illegal value %d\n", flag);
670 return -EINVAL;
671 }
672
673 a->generate_node_acls = flag;
674 pr_debug("iSCSI_TPG[%hu] - Generate Initiator Portal Group ACLs: %s\n",
675 tpg->tpgt, (a->generate_node_acls) ? "Enabled" : "Disabled");
676
677 return 0;
678}
679
680int iscsit_ta_default_cmdsn_depth(
681 struct iscsi_portal_group *tpg,
682 u32 tcq_depth)
683{
684 struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
685
686 if (tcq_depth > TA_DEFAULT_CMDSN_DEPTH_MAX) {
687 pr_err("Requested Default Queue Depth: %u larger"
688 " than maximum %u\n", tcq_depth,
689 TA_DEFAULT_CMDSN_DEPTH_MAX);
690 return -EINVAL;
691 } else if (tcq_depth < TA_DEFAULT_CMDSN_DEPTH_MIN) {
692 pr_err("Requested Default Queue Depth: %u smaller"
693 " than minimum %u\n", tcq_depth,
694 TA_DEFAULT_CMDSN_DEPTH_MIN);
695 return -EINVAL;
696 }
697
698 a->default_cmdsn_depth = tcq_depth;
699 pr_debug("iSCSI_TPG[%hu] - Set Default CmdSN TCQ Depth to %u\n",
700 tpg->tpgt, a->default_cmdsn_depth);
701
702 return 0;
703}
704
705int iscsit_ta_cache_dynamic_acls(
706 struct iscsi_portal_group *tpg,
707 u32 flag)
708{
709 struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
710
711 if ((flag != 0) && (flag != 1)) {
712 pr_err("Illegal value %d\n", flag);
713 return -EINVAL;
714 }
715
716 a->cache_dynamic_acls = flag;
717 pr_debug("iSCSI_TPG[%hu] - Cache Dynamic Initiator Portal Group"
718 " ACLs %s\n", tpg->tpgt, (a->cache_dynamic_acls) ?
719 "Enabled" : "Disabled");
720
721 return 0;
722}
723
724int iscsit_ta_demo_mode_write_protect(
725 struct iscsi_portal_group *tpg,
726 u32 flag)
727{
728 struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
729
730 if ((flag != 0) && (flag != 1)) {
731 pr_err("Illegal value %d\n", flag);
732 return -EINVAL;
733 }
734
735 a->demo_mode_write_protect = flag;
736 pr_debug("iSCSI_TPG[%hu] - Demo Mode Write Protect bit: %s\n",
737 tpg->tpgt, (a->demo_mode_write_protect) ? "ON" : "OFF");
738
739 return 0;
740}
741
742int iscsit_ta_prod_mode_write_protect(
743 struct iscsi_portal_group *tpg,
744 u32 flag)
745{
746 struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
747
748 if ((flag != 0) && (flag != 1)) {
749 pr_err("Illegal value %d\n", flag);
750 return -EINVAL;
751 }
752
753 a->prod_mode_write_protect = flag;
754 pr_debug("iSCSI_TPG[%hu] - Production Mode Write Protect bit:"
755 " %s\n", tpg->tpgt, (a->prod_mode_write_protect) ?
756 "ON" : "OFF");
757
758 return 0;
759}
diff --git a/drivers/target/iscsi/iscsi_target_tpg.h b/drivers/target/iscsi/iscsi_target_tpg.h
new file mode 100644
index 000000000000..dda48c141a8c
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_tpg.h
@@ -0,0 +1,41 @@
1#ifndef ISCSI_TARGET_TPG_H
2#define ISCSI_TARGET_TPG_H
3
4extern struct iscsi_portal_group *iscsit_alloc_portal_group(struct iscsi_tiqn *, u16);
5extern int iscsit_load_discovery_tpg(void);
6extern void iscsit_release_discovery_tpg(void);
7extern struct iscsi_portal_group *iscsit_get_tpg_from_np(struct iscsi_tiqn *,
8 struct iscsi_np *);
9extern int iscsit_get_tpg(struct iscsi_portal_group *);
10extern void iscsit_put_tpg(struct iscsi_portal_group *);
11extern void iscsit_clear_tpg_np_login_threads(struct iscsi_portal_group *);
12extern void iscsit_tpg_dump_params(struct iscsi_portal_group *);
13extern int iscsit_tpg_add_portal_group(struct iscsi_tiqn *, struct iscsi_portal_group *);
14extern int iscsit_tpg_del_portal_group(struct iscsi_tiqn *, struct iscsi_portal_group *,
15 int);
16extern int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *);
17extern int iscsit_tpg_disable_portal_group(struct iscsi_portal_group *, int);
18extern struct iscsi_node_acl *iscsit_tpg_add_initiator_node_acl(
19 struct iscsi_portal_group *, const char *, u32);
20extern void iscsit_tpg_del_initiator_node_acl(struct iscsi_portal_group *,
21 struct se_node_acl *);
22extern struct iscsi_node_attrib *iscsit_tpg_get_node_attrib(struct iscsi_session *);
23extern void iscsit_tpg_del_external_nps(struct iscsi_tpg_np *);
24extern struct iscsi_tpg_np *iscsit_tpg_locate_child_np(struct iscsi_tpg_np *, int);
25extern struct iscsi_tpg_np *iscsit_tpg_add_network_portal(struct iscsi_portal_group *,
26 struct __kernel_sockaddr_storage *, char *, struct iscsi_tpg_np *,
27 int);
28extern int iscsit_tpg_del_network_portal(struct iscsi_portal_group *,
29 struct iscsi_tpg_np *);
30extern int iscsit_tpg_set_initiator_node_queue_depth(struct iscsi_portal_group *,
31 unsigned char *, u32, int);
32extern int iscsit_ta_authentication(struct iscsi_portal_group *, u32);
33extern int iscsit_ta_login_timeout(struct iscsi_portal_group *, u32);
34extern int iscsit_ta_netif_timeout(struct iscsi_portal_group *, u32);
35extern int iscsit_ta_generate_node_acls(struct iscsi_portal_group *, u32);
36extern int iscsit_ta_default_cmdsn_depth(struct iscsi_portal_group *, u32);
37extern int iscsit_ta_cache_dynamic_acls(struct iscsi_portal_group *, u32);
38extern int iscsit_ta_demo_mode_write_protect(struct iscsi_portal_group *, u32);
39extern int iscsit_ta_prod_mode_write_protect(struct iscsi_portal_group *, u32);
40
41#endif /* ISCSI_TARGET_TPG_H */
diff --git a/drivers/target/iscsi/iscsi_target_tq.c b/drivers/target/iscsi/iscsi_target_tq.c
new file mode 100644
index 000000000000..0baac5bcebd4
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_tq.c
@@ -0,0 +1,551 @@
1/*******************************************************************************
2 * This file contains the iSCSI Login Thread and Thread Queue functions.
3 *
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5 *
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7 *
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.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
21#include <linux/kthread.h>
22#include <linux/list.h>
23#include <linux/bitmap.h>
24
25#include "iscsi_target_core.h"
26#include "iscsi_target_tq.h"
27#include "iscsi_target.h"
28
29static LIST_HEAD(active_ts_list);
30static LIST_HEAD(inactive_ts_list);
31static DEFINE_SPINLOCK(active_ts_lock);
32static DEFINE_SPINLOCK(inactive_ts_lock);
33static DEFINE_SPINLOCK(ts_bitmap_lock);
34
35static void iscsi_add_ts_to_active_list(struct iscsi_thread_set *ts)
36{
37 spin_lock(&active_ts_lock);
38 list_add_tail(&ts->ts_list, &active_ts_list);
39 iscsit_global->active_ts++;
40 spin_unlock(&active_ts_lock);
41}
42
43extern void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts)
44{
45 spin_lock(&inactive_ts_lock);
46 list_add_tail(&ts->ts_list, &inactive_ts_list);
47 iscsit_global->inactive_ts++;
48 spin_unlock(&inactive_ts_lock);
49}
50
51static void iscsi_del_ts_from_active_list(struct iscsi_thread_set *ts)
52{
53 spin_lock(&active_ts_lock);
54 list_del(&ts->ts_list);
55 iscsit_global->active_ts--;
56 spin_unlock(&active_ts_lock);
57}
58
59static struct iscsi_thread_set *iscsi_get_ts_from_inactive_list(void)
60{
61 struct iscsi_thread_set *ts;
62
63 spin_lock(&inactive_ts_lock);
64 if (list_empty(&inactive_ts_list)) {
65 spin_unlock(&inactive_ts_lock);
66 return NULL;
67 }
68
69 list_for_each_entry(ts, &inactive_ts_list, ts_list)
70 break;
71
72 list_del(&ts->ts_list);
73 iscsit_global->inactive_ts--;
74 spin_unlock(&inactive_ts_lock);
75
76 return ts;
77}
78
79extern int iscsi_allocate_thread_sets(u32 thread_pair_count)
80{
81 int allocated_thread_pair_count = 0, i, thread_id;
82 struct iscsi_thread_set *ts = NULL;
83
84 for (i = 0; i < thread_pair_count; i++) {
85 ts = kzalloc(sizeof(struct iscsi_thread_set), GFP_KERNEL);
86 if (!ts) {
87 pr_err("Unable to allocate memory for"
88 " thread set.\n");
89 return allocated_thread_pair_count;
90 }
91 /*
92 * Locate the next available regision in the thread_set_bitmap
93 */
94 spin_lock(&ts_bitmap_lock);
95 thread_id = bitmap_find_free_region(iscsit_global->ts_bitmap,
96 iscsit_global->ts_bitmap_count, get_order(1));
97 spin_unlock(&ts_bitmap_lock);
98 if (thread_id < 0) {
99 pr_err("bitmap_find_free_region() failed for"
100 " thread_set_bitmap\n");
101 kfree(ts);
102 return allocated_thread_pair_count;
103 }
104
105 ts->thread_id = thread_id;
106 ts->status = ISCSI_THREAD_SET_FREE;
107 INIT_LIST_HEAD(&ts->ts_list);
108 spin_lock_init(&ts->ts_state_lock);
109 init_completion(&ts->rx_post_start_comp);
110 init_completion(&ts->tx_post_start_comp);
111 init_completion(&ts->rx_restart_comp);
112 init_completion(&ts->tx_restart_comp);
113 init_completion(&ts->rx_start_comp);
114 init_completion(&ts->tx_start_comp);
115
116 ts->create_threads = 1;
117 ts->tx_thread = kthread_run(iscsi_target_tx_thread, ts, "%s",
118 ISCSI_TX_THREAD_NAME);
119 if (IS_ERR(ts->tx_thread)) {
120 dump_stack();
121 pr_err("Unable to start iscsi_target_tx_thread\n");
122 break;
123 }
124
125 ts->rx_thread = kthread_run(iscsi_target_rx_thread, ts, "%s",
126 ISCSI_RX_THREAD_NAME);
127 if (IS_ERR(ts->rx_thread)) {
128 kthread_stop(ts->tx_thread);
129 pr_err("Unable to start iscsi_target_rx_thread\n");
130 break;
131 }
132 ts->create_threads = 0;
133
134 iscsi_add_ts_to_inactive_list(ts);
135 allocated_thread_pair_count++;
136 }
137
138 pr_debug("Spawned %d thread set(s) (%d total threads).\n",
139 allocated_thread_pair_count, allocated_thread_pair_count * 2);
140 return allocated_thread_pair_count;
141}
142
143extern void iscsi_deallocate_thread_sets(void)
144{
145 u32 released_count = 0;
146 struct iscsi_thread_set *ts = NULL;
147
148 while ((ts = iscsi_get_ts_from_inactive_list())) {
149
150 spin_lock_bh(&ts->ts_state_lock);
151 ts->status = ISCSI_THREAD_SET_DIE;
152 spin_unlock_bh(&ts->ts_state_lock);
153
154 if (ts->rx_thread) {
155 send_sig(SIGINT, ts->rx_thread, 1);
156 kthread_stop(ts->rx_thread);
157 }
158 if (ts->tx_thread) {
159 send_sig(SIGINT, ts->tx_thread, 1);
160 kthread_stop(ts->tx_thread);
161 }
162 /*
163 * Release this thread_id in the thread_set_bitmap
164 */
165 spin_lock(&ts_bitmap_lock);
166 bitmap_release_region(iscsit_global->ts_bitmap,
167 ts->thread_id, get_order(1));
168 spin_unlock(&ts_bitmap_lock);
169
170 released_count++;
171 kfree(ts);
172 }
173
174 if (released_count)
175 pr_debug("Stopped %d thread set(s) (%d total threads)."
176 "\n", released_count, released_count * 2);
177}
178
179static void iscsi_deallocate_extra_thread_sets(void)
180{
181 u32 orig_count, released_count = 0;
182 struct iscsi_thread_set *ts = NULL;
183
184 orig_count = TARGET_THREAD_SET_COUNT;
185
186 while ((iscsit_global->inactive_ts + 1) > orig_count) {
187 ts = iscsi_get_ts_from_inactive_list();
188 if (!ts)
189 break;
190
191 spin_lock_bh(&ts->ts_state_lock);
192 ts->status = ISCSI_THREAD_SET_DIE;
193 spin_unlock_bh(&ts->ts_state_lock);
194
195 if (ts->rx_thread) {
196 send_sig(SIGINT, ts->rx_thread, 1);
197 kthread_stop(ts->rx_thread);
198 }
199 if (ts->tx_thread) {
200 send_sig(SIGINT, ts->tx_thread, 1);
201 kthread_stop(ts->tx_thread);
202 }
203 /*
204 * Release this thread_id in the thread_set_bitmap
205 */
206 spin_lock(&ts_bitmap_lock);
207 bitmap_release_region(iscsit_global->ts_bitmap,
208 ts->thread_id, get_order(1));
209 spin_unlock(&ts_bitmap_lock);
210
211 released_count++;
212 kfree(ts);
213 }
214
215 if (released_count) {
216 pr_debug("Stopped %d thread set(s) (%d total threads)."
217 "\n", released_count, released_count * 2);
218 }
219}
220
221void iscsi_activate_thread_set(struct iscsi_conn *conn, struct iscsi_thread_set *ts)
222{
223 iscsi_add_ts_to_active_list(ts);
224
225 spin_lock_bh(&ts->ts_state_lock);
226 conn->thread_set = ts;
227 ts->conn = conn;
228 spin_unlock_bh(&ts->ts_state_lock);
229 /*
230 * Start up the RX thread and wait on rx_post_start_comp. The RX
231 * Thread will then do the same for the TX Thread in
232 * iscsi_rx_thread_pre_handler().
233 */
234 complete(&ts->rx_start_comp);
235 wait_for_completion(&ts->rx_post_start_comp);
236}
237
238struct iscsi_thread_set *iscsi_get_thread_set(void)
239{
240 int allocate_ts = 0;
241 struct completion comp;
242 struct iscsi_thread_set *ts = NULL;
243 /*
244 * If no inactive thread set is available on the first call to
245 * iscsi_get_ts_from_inactive_list(), sleep for a second and
246 * try again. If still none are available after two attempts,
247 * allocate a set ourselves.
248 */
249get_set:
250 ts = iscsi_get_ts_from_inactive_list();
251 if (!ts) {
252 if (allocate_ts == 2)
253 iscsi_allocate_thread_sets(1);
254
255 init_completion(&comp);
256 wait_for_completion_timeout(&comp, 1 * HZ);
257
258 allocate_ts++;
259 goto get_set;
260 }
261
262 ts->delay_inactive = 1;
263 ts->signal_sent = 0;
264 ts->thread_count = 2;
265 init_completion(&ts->rx_restart_comp);
266 init_completion(&ts->tx_restart_comp);
267
268 return ts;
269}
270
271void iscsi_set_thread_clear(struct iscsi_conn *conn, u8 thread_clear)
272{
273 struct iscsi_thread_set *ts = NULL;
274
275 if (!conn->thread_set) {
276 pr_err("struct iscsi_conn->thread_set is NULL\n");
277 return;
278 }
279 ts = conn->thread_set;
280
281 spin_lock_bh(&ts->ts_state_lock);
282 ts->thread_clear &= ~thread_clear;
283
284 if ((thread_clear & ISCSI_CLEAR_RX_THREAD) &&
285 (ts->blocked_threads & ISCSI_BLOCK_RX_THREAD))
286 complete(&ts->rx_restart_comp);
287 else if ((thread_clear & ISCSI_CLEAR_TX_THREAD) &&
288 (ts->blocked_threads & ISCSI_BLOCK_TX_THREAD))
289 complete(&ts->tx_restart_comp);
290 spin_unlock_bh(&ts->ts_state_lock);
291}
292
293void iscsi_set_thread_set_signal(struct iscsi_conn *conn, u8 signal_sent)
294{
295 struct iscsi_thread_set *ts = NULL;
296
297 if (!conn->thread_set) {
298 pr_err("struct iscsi_conn->thread_set is NULL\n");
299 return;
300 }
301 ts = conn->thread_set;
302
303 spin_lock_bh(&ts->ts_state_lock);
304 ts->signal_sent |= signal_sent;
305 spin_unlock_bh(&ts->ts_state_lock);
306}
307
308int iscsi_release_thread_set(struct iscsi_conn *conn)
309{
310 int thread_called = 0;
311 struct iscsi_thread_set *ts = NULL;
312
313 if (!conn || !conn->thread_set) {
314 pr_err("connection or thread set pointer is NULL\n");
315 BUG();
316 }
317 ts = conn->thread_set;
318
319 spin_lock_bh(&ts->ts_state_lock);
320 ts->status = ISCSI_THREAD_SET_RESET;
321
322 if (!strncmp(current->comm, ISCSI_RX_THREAD_NAME,
323 strlen(ISCSI_RX_THREAD_NAME)))
324 thread_called = ISCSI_RX_THREAD;
325 else if (!strncmp(current->comm, ISCSI_TX_THREAD_NAME,
326 strlen(ISCSI_TX_THREAD_NAME)))
327 thread_called = ISCSI_TX_THREAD;
328
329 if (ts->rx_thread && (thread_called == ISCSI_TX_THREAD) &&
330 (ts->thread_clear & ISCSI_CLEAR_RX_THREAD)) {
331
332 if (!(ts->signal_sent & ISCSI_SIGNAL_RX_THREAD)) {
333 send_sig(SIGINT, ts->rx_thread, 1);
334 ts->signal_sent |= ISCSI_SIGNAL_RX_THREAD;
335 }
336 ts->blocked_threads |= ISCSI_BLOCK_RX_THREAD;
337 spin_unlock_bh(&ts->ts_state_lock);
338 wait_for_completion(&ts->rx_restart_comp);
339 spin_lock_bh(&ts->ts_state_lock);
340 ts->blocked_threads &= ~ISCSI_BLOCK_RX_THREAD;
341 }
342 if (ts->tx_thread && (thread_called == ISCSI_RX_THREAD) &&
343 (ts->thread_clear & ISCSI_CLEAR_TX_THREAD)) {
344
345 if (!(ts->signal_sent & ISCSI_SIGNAL_TX_THREAD)) {
346 send_sig(SIGINT, ts->tx_thread, 1);
347 ts->signal_sent |= ISCSI_SIGNAL_TX_THREAD;
348 }
349 ts->blocked_threads |= ISCSI_BLOCK_TX_THREAD;
350 spin_unlock_bh(&ts->ts_state_lock);
351 wait_for_completion(&ts->tx_restart_comp);
352 spin_lock_bh(&ts->ts_state_lock);
353 ts->blocked_threads &= ~ISCSI_BLOCK_TX_THREAD;
354 }
355
356 ts->conn = NULL;
357 ts->status = ISCSI_THREAD_SET_FREE;
358 spin_unlock_bh(&ts->ts_state_lock);
359
360 return 0;
361}
362
363int iscsi_thread_set_force_reinstatement(struct iscsi_conn *conn)
364{
365 struct iscsi_thread_set *ts;
366
367 if (!conn->thread_set)
368 return -1;
369 ts = conn->thread_set;
370
371 spin_lock_bh(&ts->ts_state_lock);
372 if (ts->status != ISCSI_THREAD_SET_ACTIVE) {
373 spin_unlock_bh(&ts->ts_state_lock);
374 return -1;
375 }
376
377 if (ts->tx_thread && (!(ts->signal_sent & ISCSI_SIGNAL_TX_THREAD))) {
378 send_sig(SIGINT, ts->tx_thread, 1);
379 ts->signal_sent |= ISCSI_SIGNAL_TX_THREAD;
380 }
381 if (ts->rx_thread && (!(ts->signal_sent & ISCSI_SIGNAL_RX_THREAD))) {
382 send_sig(SIGINT, ts->rx_thread, 1);
383 ts->signal_sent |= ISCSI_SIGNAL_RX_THREAD;
384 }
385 spin_unlock_bh(&ts->ts_state_lock);
386
387 return 0;
388}
389
390static void iscsi_check_to_add_additional_sets(void)
391{
392 int thread_sets_add;
393
394 spin_lock(&inactive_ts_lock);
395 thread_sets_add = iscsit_global->inactive_ts;
396 spin_unlock(&inactive_ts_lock);
397 if (thread_sets_add == 1)
398 iscsi_allocate_thread_sets(1);
399}
400
401static int iscsi_signal_thread_pre_handler(struct iscsi_thread_set *ts)
402{
403 spin_lock_bh(&ts->ts_state_lock);
404 if ((ts->status == ISCSI_THREAD_SET_DIE) || signal_pending(current)) {
405 spin_unlock_bh(&ts->ts_state_lock);
406 return -1;
407 }
408 spin_unlock_bh(&ts->ts_state_lock);
409
410 return 0;
411}
412
413struct iscsi_conn *iscsi_rx_thread_pre_handler(struct iscsi_thread_set *ts)
414{
415 int ret;
416
417 spin_lock_bh(&ts->ts_state_lock);
418 if (ts->create_threads) {
419 spin_unlock_bh(&ts->ts_state_lock);
420 goto sleep;
421 }
422
423 flush_signals(current);
424
425 if (ts->delay_inactive && (--ts->thread_count == 0)) {
426 spin_unlock_bh(&ts->ts_state_lock);
427 iscsi_del_ts_from_active_list(ts);
428
429 if (!iscsit_global->in_shutdown)
430 iscsi_deallocate_extra_thread_sets();
431
432 iscsi_add_ts_to_inactive_list(ts);
433 spin_lock_bh(&ts->ts_state_lock);
434 }
435
436 if ((ts->status == ISCSI_THREAD_SET_RESET) &&
437 (ts->thread_clear & ISCSI_CLEAR_RX_THREAD))
438 complete(&ts->rx_restart_comp);
439
440 ts->thread_clear &= ~ISCSI_CLEAR_RX_THREAD;
441 spin_unlock_bh(&ts->ts_state_lock);
442sleep:
443 ret = wait_for_completion_interruptible(&ts->rx_start_comp);
444 if (ret != 0)
445 return NULL;
446
447 if (iscsi_signal_thread_pre_handler(ts) < 0)
448 return NULL;
449
450 if (!ts->conn) {
451 pr_err("struct iscsi_thread_set->conn is NULL for"
452 " thread_id: %d, going back to sleep\n", ts->thread_id);
453 goto sleep;
454 }
455 iscsi_check_to_add_additional_sets();
456 /*
457 * The RX Thread starts up the TX Thread and sleeps.
458 */
459 ts->thread_clear |= ISCSI_CLEAR_RX_THREAD;
460 complete(&ts->tx_start_comp);
461 wait_for_completion(&ts->tx_post_start_comp);
462
463 return ts->conn;
464}
465
466struct iscsi_conn *iscsi_tx_thread_pre_handler(struct iscsi_thread_set *ts)
467{
468 int ret;
469
470 spin_lock_bh(&ts->ts_state_lock);
471 if (ts->create_threads) {
472 spin_unlock_bh(&ts->ts_state_lock);
473 goto sleep;
474 }
475
476 flush_signals(current);
477
478 if (ts->delay_inactive && (--ts->thread_count == 0)) {
479 spin_unlock_bh(&ts->ts_state_lock);
480 iscsi_del_ts_from_active_list(ts);
481
482 if (!iscsit_global->in_shutdown)
483 iscsi_deallocate_extra_thread_sets();
484
485 iscsi_add_ts_to_inactive_list(ts);
486 spin_lock_bh(&ts->ts_state_lock);
487 }
488 if ((ts->status == ISCSI_THREAD_SET_RESET) &&
489 (ts->thread_clear & ISCSI_CLEAR_TX_THREAD))
490 complete(&ts->tx_restart_comp);
491
492 ts->thread_clear &= ~ISCSI_CLEAR_TX_THREAD;
493 spin_unlock_bh(&ts->ts_state_lock);
494sleep:
495 ret = wait_for_completion_interruptible(&ts->tx_start_comp);
496 if (ret != 0)
497 return NULL;
498
499 if (iscsi_signal_thread_pre_handler(ts) < 0)
500 return NULL;
501
502 if (!ts->conn) {
503 pr_err("struct iscsi_thread_set->conn is NULL for "
504 " thread_id: %d, going back to sleep\n",
505 ts->thread_id);
506 goto sleep;
507 }
508
509 iscsi_check_to_add_additional_sets();
510 /*
511 * From the TX thread, up the tx_post_start_comp that the RX Thread is
512 * sleeping on in iscsi_rx_thread_pre_handler(), then up the
513 * rx_post_start_comp that iscsi_activate_thread_set() is sleeping on.
514 */
515 ts->thread_clear |= ISCSI_CLEAR_TX_THREAD;
516 complete(&ts->tx_post_start_comp);
517 complete(&ts->rx_post_start_comp);
518
519 spin_lock_bh(&ts->ts_state_lock);
520 ts->status = ISCSI_THREAD_SET_ACTIVE;
521 spin_unlock_bh(&ts->ts_state_lock);
522
523 return ts->conn;
524}
525
526int iscsi_thread_set_init(void)
527{
528 int size;
529
530 iscsit_global->ts_bitmap_count = ISCSI_TS_BITMAP_BITS;
531
532 size = BITS_TO_LONGS(iscsit_global->ts_bitmap_count) * sizeof(long);
533 iscsit_global->ts_bitmap = kzalloc(size, GFP_KERNEL);
534 if (!iscsit_global->ts_bitmap) {
535 pr_err("Unable to allocate iscsit_global->ts_bitmap\n");
536 return -ENOMEM;
537 }
538
539 spin_lock_init(&active_ts_lock);
540 spin_lock_init(&inactive_ts_lock);
541 spin_lock_init(&ts_bitmap_lock);
542 INIT_LIST_HEAD(&active_ts_list);
543 INIT_LIST_HEAD(&inactive_ts_list);
544
545 return 0;
546}
547
548void iscsi_thread_set_free(void)
549{
550 kfree(iscsit_global->ts_bitmap);
551}
diff --git a/drivers/target/iscsi/iscsi_target_tq.h b/drivers/target/iscsi/iscsi_target_tq.h
new file mode 100644
index 000000000000..26e6a95ec203
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_tq.h
@@ -0,0 +1,88 @@
1#ifndef ISCSI_THREAD_QUEUE_H
2#define ISCSI_THREAD_QUEUE_H
3
4/*
5 * Defines for thread sets.
6 */
7extern int iscsi_thread_set_force_reinstatement(struct iscsi_conn *);
8extern void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *);
9extern int iscsi_allocate_thread_sets(u32);
10extern void iscsi_deallocate_thread_sets(void);
11extern void iscsi_activate_thread_set(struct iscsi_conn *, struct iscsi_thread_set *);
12extern struct iscsi_thread_set *iscsi_get_thread_set(void);
13extern void iscsi_set_thread_clear(struct iscsi_conn *, u8);
14extern void iscsi_set_thread_set_signal(struct iscsi_conn *, u8);
15extern int iscsi_release_thread_set(struct iscsi_conn *);
16extern struct iscsi_conn *iscsi_rx_thread_pre_handler(struct iscsi_thread_set *);
17extern struct iscsi_conn *iscsi_tx_thread_pre_handler(struct iscsi_thread_set *);
18extern int iscsi_thread_set_init(void);
19extern void iscsi_thread_set_free(void);
20
21extern int iscsi_target_tx_thread(void *);
22extern int iscsi_target_rx_thread(void *);
23
24#define TARGET_THREAD_SET_COUNT 4
25
26#define ISCSI_RX_THREAD 1
27#define ISCSI_TX_THREAD 2
28#define ISCSI_RX_THREAD_NAME "iscsi_trx"
29#define ISCSI_TX_THREAD_NAME "iscsi_ttx"
30#define ISCSI_BLOCK_RX_THREAD 0x1
31#define ISCSI_BLOCK_TX_THREAD 0x2
32#define ISCSI_CLEAR_RX_THREAD 0x1
33#define ISCSI_CLEAR_TX_THREAD 0x2
34#define ISCSI_SIGNAL_RX_THREAD 0x1
35#define ISCSI_SIGNAL_TX_THREAD 0x2
36
37/* struct iscsi_thread_set->status */
38#define ISCSI_THREAD_SET_FREE 1
39#define ISCSI_THREAD_SET_ACTIVE 2
40#define ISCSI_THREAD_SET_DIE 3
41#define ISCSI_THREAD_SET_RESET 4
42#define ISCSI_THREAD_SET_DEALLOCATE_THREADS 5
43
44/* By default allow a maximum of 32K iSCSI connections */
45#define ISCSI_TS_BITMAP_BITS 32768
46
47struct iscsi_thread_set {
48 /* flags used for blocking and restarting sets */
49 int blocked_threads;
50 /* flag for creating threads */
51 int create_threads;
52 /* flag for delaying readding to inactive list */
53 int delay_inactive;
54 /* status for thread set */
55 int status;
56 /* which threads have had signals sent */
57 int signal_sent;
58 /* flag for which threads exited first */
59 int thread_clear;
60 /* Active threads in the thread set */
61 int thread_count;
62 /* Unique thread ID */
63 u32 thread_id;
64 /* pointer to connection if set is active */
65 struct iscsi_conn *conn;
66 /* used for controlling ts state accesses */
67 spinlock_t ts_state_lock;
68 /* Used for rx side post startup */
69 struct completion rx_post_start_comp;
70 /* Used for tx side post startup */
71 struct completion tx_post_start_comp;
72 /* used for restarting thread queue */
73 struct completion rx_restart_comp;
74 /* used for restarting thread queue */
75 struct completion tx_restart_comp;
76 /* used for normal unused blocking */
77 struct completion rx_start_comp;
78 /* used for normal unused blocking */
79 struct completion tx_start_comp;
80 /* OS descriptor for rx thread */
81 struct task_struct *rx_thread;
82 /* OS descriptor for tx thread */
83 struct task_struct *tx_thread;
84 /* struct iscsi_thread_set in list list head*/
85 struct list_head ts_list;
86};
87
88#endif /*** ISCSI_THREAD_QUEUE_H ***/
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
new file mode 100644
index 000000000000..a1acb0167902
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -0,0 +1,1819 @@
1/*******************************************************************************
2 * This file contains the iSCSI Target specific utility functions.
3 *
4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC.
5 *
6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
7 *
8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.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
21#include <linux/list.h>
22#include <scsi/scsi_tcq.h>
23#include <scsi/iscsi_proto.h>
24#include <target/target_core_base.h>
25#include <target/target_core_transport.h>
26#include <target/target_core_tmr.h>
27#include <target/target_core_fabric_ops.h>
28#include <target/target_core_configfs.h>
29
30#include "iscsi_target_core.h"
31#include "iscsi_target_parameters.h"
32#include "iscsi_target_seq_pdu_list.h"
33#include "iscsi_target_datain_values.h"
34#include "iscsi_target_erl0.h"
35#include "iscsi_target_erl1.h"
36#include "iscsi_target_erl2.h"
37#include "iscsi_target_tpg.h"
38#include "iscsi_target_tq.h"
39#include "iscsi_target_util.h"
40#include "iscsi_target.h"
41
42#define PRINT_BUFF(buff, len) \
43{ \
44 int zzz; \
45 \
46 pr_debug("%d:\n", __LINE__); \
47 for (zzz = 0; zzz < len; zzz++) { \
48 if (zzz % 16 == 0) { \
49 if (zzz) \
50 pr_debug("\n"); \
51 pr_debug("%4i: ", zzz); \
52 } \
53 pr_debug("%02x ", (unsigned char) (buff)[zzz]); \
54 } \
55 if ((len + 1) % 16) \
56 pr_debug("\n"); \
57}
58
59extern struct list_head g_tiqn_list;
60extern spinlock_t tiqn_lock;
61
62/*
63 * Called with cmd->r2t_lock held.
64 */
65int iscsit_add_r2t_to_list(
66 struct iscsi_cmd *cmd,
67 u32 offset,
68 u32 xfer_len,
69 int recovery,
70 u32 r2t_sn)
71{
72 struct iscsi_r2t *r2t;
73
74 r2t = kmem_cache_zalloc(lio_r2t_cache, GFP_ATOMIC);
75 if (!r2t) {
76 pr_err("Unable to allocate memory for struct iscsi_r2t.\n");
77 return -1;
78 }
79 INIT_LIST_HEAD(&r2t->r2t_list);
80
81 r2t->recovery_r2t = recovery;
82 r2t->r2t_sn = (!r2t_sn) ? cmd->r2t_sn++ : r2t_sn;
83 r2t->offset = offset;
84 r2t->xfer_len = xfer_len;
85 list_add_tail(&r2t->r2t_list, &cmd->cmd_r2t_list);
86 spin_unlock_bh(&cmd->r2t_lock);
87
88 iscsit_add_cmd_to_immediate_queue(cmd, cmd->conn, ISTATE_SEND_R2T);
89
90 spin_lock_bh(&cmd->r2t_lock);
91 return 0;
92}
93
94struct iscsi_r2t *iscsit_get_r2t_for_eos(
95 struct iscsi_cmd *cmd,
96 u32 offset,
97 u32 length)
98{
99 struct iscsi_r2t *r2t;
100
101 spin_lock_bh(&cmd->r2t_lock);
102 list_for_each_entry(r2t, &cmd->cmd_r2t_list, r2t_list) {
103 if ((r2t->offset <= offset) &&
104 (r2t->offset + r2t->xfer_len) >= (offset + length)) {
105 spin_unlock_bh(&cmd->r2t_lock);
106 return r2t;
107 }
108 }
109 spin_unlock_bh(&cmd->r2t_lock);
110
111 pr_err("Unable to locate R2T for Offset: %u, Length:"
112 " %u\n", offset, length);
113 return NULL;
114}
115
116struct iscsi_r2t *iscsit_get_r2t_from_list(struct iscsi_cmd *cmd)
117{
118 struct iscsi_r2t *r2t;
119
120 spin_lock_bh(&cmd->r2t_lock);
121 list_for_each_entry(r2t, &cmd->cmd_r2t_list, r2t_list) {
122 if (!r2t->sent_r2t) {
123 spin_unlock_bh(&cmd->r2t_lock);
124 return r2t;
125 }
126 }
127 spin_unlock_bh(&cmd->r2t_lock);
128
129 pr_err("Unable to locate next R2T to send for ITT:"
130 " 0x%08x.\n", cmd->init_task_tag);
131 return NULL;
132}
133
134/*
135 * Called with cmd->r2t_lock held.
136 */
137void iscsit_free_r2t(struct iscsi_r2t *r2t, struct iscsi_cmd *cmd)
138{
139 list_del(&r2t->r2t_list);
140 kmem_cache_free(lio_r2t_cache, r2t);
141}
142
143void iscsit_free_r2ts_from_list(struct iscsi_cmd *cmd)
144{
145 struct iscsi_r2t *r2t, *r2t_tmp;
146
147 spin_lock_bh(&cmd->r2t_lock);
148 list_for_each_entry_safe(r2t, r2t_tmp, &cmd->cmd_r2t_list, r2t_list)
149 iscsit_free_r2t(r2t, cmd);
150 spin_unlock_bh(&cmd->r2t_lock);
151}
152
153/*
154 * May be called from software interrupt (timer) context for allocating
155 * iSCSI NopINs.
156 */
157struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, gfp_t gfp_mask)
158{
159 struct iscsi_cmd *cmd;
160
161 cmd = kmem_cache_zalloc(lio_cmd_cache, gfp_mask);
162 if (!cmd) {
163 pr_err("Unable to allocate memory for struct iscsi_cmd.\n");
164 return NULL;
165 }
166
167 cmd->conn = conn;
168 INIT_LIST_HEAD(&cmd->i_list);
169 INIT_LIST_HEAD(&cmd->datain_list);
170 INIT_LIST_HEAD(&cmd->cmd_r2t_list);
171 init_completion(&cmd->reject_comp);
172 spin_lock_init(&cmd->datain_lock);
173 spin_lock_init(&cmd->dataout_timeout_lock);
174 spin_lock_init(&cmd->istate_lock);
175 spin_lock_init(&cmd->error_lock);
176 spin_lock_init(&cmd->r2t_lock);
177
178 return cmd;
179}
180
181/*
182 * Called from iscsi_handle_scsi_cmd()
183 */
184struct iscsi_cmd *iscsit_allocate_se_cmd(
185 struct iscsi_conn *conn,
186 u32 data_length,
187 int data_direction,
188 int iscsi_task_attr)
189{
190 struct iscsi_cmd *cmd;
191 struct se_cmd *se_cmd;
192 int sam_task_attr;
193
194 cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
195 if (!cmd)
196 return NULL;
197
198 cmd->data_direction = data_direction;
199 cmd->data_length = data_length;
200 /*
201 * Figure out the SAM Task Attribute for the incoming SCSI CDB
202 */
203 if ((iscsi_task_attr == ISCSI_ATTR_UNTAGGED) ||
204 (iscsi_task_attr == ISCSI_ATTR_SIMPLE))
205 sam_task_attr = MSG_SIMPLE_TAG;
206 else if (iscsi_task_attr == ISCSI_ATTR_ORDERED)
207 sam_task_attr = MSG_ORDERED_TAG;
208 else if (iscsi_task_attr == ISCSI_ATTR_HEAD_OF_QUEUE)
209 sam_task_attr = MSG_HEAD_TAG;
210 else if (iscsi_task_attr == ISCSI_ATTR_ACA)
211 sam_task_attr = MSG_ACA_TAG;
212 else {
213 pr_debug("Unknown iSCSI Task Attribute: 0x%02x, using"
214 " MSG_SIMPLE_TAG\n", iscsi_task_attr);
215 sam_task_attr = MSG_SIMPLE_TAG;
216 }
217
218 se_cmd = &cmd->se_cmd;
219 /*
220 * Initialize struct se_cmd descriptor from target_core_mod infrastructure
221 */
222 transport_init_se_cmd(se_cmd, &lio_target_fabric_configfs->tf_ops,
223 conn->sess->se_sess, data_length, data_direction,
224 sam_task_attr, &cmd->sense_buffer[0]);
225 return cmd;
226}
227
228struct iscsi_cmd *iscsit_allocate_se_cmd_for_tmr(
229 struct iscsi_conn *conn,
230 u8 function)
231{
232 struct iscsi_cmd *cmd;
233 struct se_cmd *se_cmd;
234 u8 tcm_function;
235
236 cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
237 if (!cmd)
238 return NULL;
239
240 cmd->data_direction = DMA_NONE;
241
242 cmd->tmr_req = kzalloc(sizeof(struct iscsi_tmr_req), GFP_KERNEL);
243 if (!cmd->tmr_req) {
244 pr_err("Unable to allocate memory for"
245 " Task Management command!\n");
246 return NULL;
247 }
248 /*
249 * TASK_REASSIGN for ERL=2 / connection stays inside of
250 * LIO-Target $FABRIC_MOD
251 */
252 if (function == ISCSI_TM_FUNC_TASK_REASSIGN)
253 return cmd;
254
255 se_cmd = &cmd->se_cmd;
256 /*
257 * Initialize struct se_cmd descriptor from target_core_mod infrastructure
258 */
259 transport_init_se_cmd(se_cmd, &lio_target_fabric_configfs->tf_ops,
260 conn->sess->se_sess, 0, DMA_NONE,
261 MSG_SIMPLE_TAG, &cmd->sense_buffer[0]);
262
263 switch (function) {
264 case ISCSI_TM_FUNC_ABORT_TASK:
265 tcm_function = TMR_ABORT_TASK;
266 break;
267 case ISCSI_TM_FUNC_ABORT_TASK_SET:
268 tcm_function = TMR_ABORT_TASK_SET;
269 break;
270 case ISCSI_TM_FUNC_CLEAR_ACA:
271 tcm_function = TMR_CLEAR_ACA;
272 break;
273 case ISCSI_TM_FUNC_CLEAR_TASK_SET:
274 tcm_function = TMR_CLEAR_TASK_SET;
275 break;
276 case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET:
277 tcm_function = TMR_LUN_RESET;
278 break;
279 case ISCSI_TM_FUNC_TARGET_WARM_RESET:
280 tcm_function = TMR_TARGET_WARM_RESET;
281 break;
282 case ISCSI_TM_FUNC_TARGET_COLD_RESET:
283 tcm_function = TMR_TARGET_COLD_RESET;
284 break;
285 default:
286 pr_err("Unknown iSCSI TMR Function:"
287 " 0x%02x\n", function);
288 goto out;
289 }
290
291 se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd,
292 (void *)cmd->tmr_req, tcm_function);
293 if (!se_cmd->se_tmr_req)
294 goto out;
295
296 cmd->tmr_req->se_tmr_req = se_cmd->se_tmr_req;
297
298 return cmd;
299out:
300 iscsit_release_cmd(cmd);
301 if (se_cmd)
302 transport_free_se_cmd(se_cmd);
303 return NULL;
304}
305
306int iscsit_decide_list_to_build(
307 struct iscsi_cmd *cmd,
308 u32 immediate_data_length)
309{
310 struct iscsi_build_list bl;
311 struct iscsi_conn *conn = cmd->conn;
312 struct iscsi_session *sess = conn->sess;
313 struct iscsi_node_attrib *na;
314
315 if (sess->sess_ops->DataSequenceInOrder &&
316 sess->sess_ops->DataPDUInOrder)
317 return 0;
318
319 if (cmd->data_direction == DMA_NONE)
320 return 0;
321
322 na = iscsit_tpg_get_node_attrib(sess);
323 memset(&bl, 0, sizeof(struct iscsi_build_list));
324
325 if (cmd->data_direction == DMA_FROM_DEVICE) {
326 bl.data_direction = ISCSI_PDU_READ;
327 bl.type = PDULIST_NORMAL;
328 if (na->random_datain_pdu_offsets)
329 bl.randomize |= RANDOM_DATAIN_PDU_OFFSETS;
330 if (na->random_datain_seq_offsets)
331 bl.randomize |= RANDOM_DATAIN_SEQ_OFFSETS;
332 } else {
333 bl.data_direction = ISCSI_PDU_WRITE;
334 bl.immediate_data_length = immediate_data_length;
335 if (na->random_r2t_offsets)
336 bl.randomize |= RANDOM_R2T_OFFSETS;
337
338 if (!cmd->immediate_data && !cmd->unsolicited_data)
339 bl.type = PDULIST_NORMAL;
340 else if (cmd->immediate_data && !cmd->unsolicited_data)
341 bl.type = PDULIST_IMMEDIATE;
342 else if (!cmd->immediate_data && cmd->unsolicited_data)
343 bl.type = PDULIST_UNSOLICITED;
344 else if (cmd->immediate_data && cmd->unsolicited_data)
345 bl.type = PDULIST_IMMEDIATE_AND_UNSOLICITED;
346 }
347
348 return iscsit_do_build_list(cmd, &bl);
349}
350
351struct iscsi_seq *iscsit_get_seq_holder_for_datain(
352 struct iscsi_cmd *cmd,
353 u32 seq_send_order)
354{
355 u32 i;
356
357 for (i = 0; i < cmd->seq_count; i++)
358 if (cmd->seq_list[i].seq_send_order == seq_send_order)
359 return &cmd->seq_list[i];
360
361 return NULL;
362}
363
364struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *cmd)
365{
366 u32 i;
367
368 if (!cmd->seq_list) {
369 pr_err("struct iscsi_cmd->seq_list is NULL!\n");
370 return NULL;
371 }
372
373 for (i = 0; i < cmd->seq_count; i++) {
374 if (cmd->seq_list[i].type != SEQTYPE_NORMAL)
375 continue;
376 if (cmd->seq_list[i].seq_send_order == cmd->seq_send_order) {
377 cmd->seq_send_order++;
378 return &cmd->seq_list[i];
379 }
380 }
381
382 return NULL;
383}
384
385struct iscsi_r2t *iscsit_get_holder_for_r2tsn(
386 struct iscsi_cmd *cmd,
387 u32 r2t_sn)
388{
389 struct iscsi_r2t *r2t;
390
391 spin_lock_bh(&cmd->r2t_lock);
392 list_for_each_entry(r2t, &cmd->cmd_r2t_list, r2t_list) {
393 if (r2t->r2t_sn == r2t_sn) {
394 spin_unlock_bh(&cmd->r2t_lock);
395 return r2t;
396 }
397 }
398 spin_unlock_bh(&cmd->r2t_lock);
399
400 return NULL;
401}
402
403static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cmdsn)
404{
405 int ret;
406
407 /*
408 * This is the proper method of checking received CmdSN against
409 * ExpCmdSN and MaxCmdSN values, as well as accounting for out
410 * or order CmdSNs due to multiple connection sessions and/or
411 * CRC failures.
412 */
413 if (iscsi_sna_gt(cmdsn, sess->max_cmd_sn)) {
414 pr_err("Received CmdSN: 0x%08x is greater than"
415 " MaxCmdSN: 0x%08x, protocol error.\n", cmdsn,
416 sess->max_cmd_sn);
417 ret = CMDSN_ERROR_CANNOT_RECOVER;
418
419 } else if (cmdsn == sess->exp_cmd_sn) {
420 sess->exp_cmd_sn++;
421 pr_debug("Received CmdSN matches ExpCmdSN,"
422 " incremented ExpCmdSN to: 0x%08x\n",
423 sess->exp_cmd_sn);
424 ret = CMDSN_NORMAL_OPERATION;
425
426 } else if (iscsi_sna_gt(cmdsn, sess->exp_cmd_sn)) {
427 pr_debug("Received CmdSN: 0x%08x is greater"
428 " than ExpCmdSN: 0x%08x, not acknowledging.\n",
429 cmdsn, sess->exp_cmd_sn);
430 ret = CMDSN_HIGHER_THAN_EXP;
431
432 } else {
433 pr_err("Received CmdSN: 0x%08x is less than"
434 " ExpCmdSN: 0x%08x, ignoring.\n", cmdsn,
435 sess->exp_cmd_sn);
436 ret = CMDSN_LOWER_THAN_EXP;
437 }
438
439 return ret;
440}
441
442/*
443 * Commands may be received out of order if MC/S is in use.
444 * Ensure they are executed in CmdSN order.
445 */
446int iscsit_sequence_cmd(
447 struct iscsi_conn *conn,
448 struct iscsi_cmd *cmd,
449 u32 cmdsn)
450{
451 int ret;
452 int cmdsn_ret;
453
454 mutex_lock(&conn->sess->cmdsn_mutex);
455
456 cmdsn_ret = iscsit_check_received_cmdsn(conn->sess, cmdsn);
457 switch (cmdsn_ret) {
458 case CMDSN_NORMAL_OPERATION:
459 ret = iscsit_execute_cmd(cmd, 0);
460 if ((ret >= 0) && !list_empty(&conn->sess->sess_ooo_cmdsn_list))
461 iscsit_execute_ooo_cmdsns(conn->sess);
462 break;
463 case CMDSN_HIGHER_THAN_EXP:
464 ret = iscsit_handle_ooo_cmdsn(conn->sess, cmd, cmdsn);
465 break;
466 case CMDSN_LOWER_THAN_EXP:
467 cmd->i_state = ISTATE_REMOVE;
468 iscsit_add_cmd_to_immediate_queue(cmd, conn, cmd->i_state);
469 ret = cmdsn_ret;
470 break;
471 default:
472 ret = cmdsn_ret;
473 break;
474 }
475 mutex_unlock(&conn->sess->cmdsn_mutex);
476
477 return ret;
478}
479
480int iscsit_check_unsolicited_dataout(struct iscsi_cmd *cmd, unsigned char *buf)
481{
482 struct iscsi_conn *conn = cmd->conn;
483 struct se_cmd *se_cmd = &cmd->se_cmd;
484 struct iscsi_data *hdr = (struct iscsi_data *) buf;
485 u32 payload_length = ntoh24(hdr->dlength);
486
487 if (conn->sess->sess_ops->InitialR2T) {
488 pr_err("Received unexpected unsolicited data"
489 " while InitialR2T=Yes, protocol error.\n");
490 transport_send_check_condition_and_sense(se_cmd,
491 TCM_UNEXPECTED_UNSOLICITED_DATA, 0);
492 return -1;
493 }
494
495 if ((cmd->first_burst_len + payload_length) >
496 conn->sess->sess_ops->FirstBurstLength) {
497 pr_err("Total %u bytes exceeds FirstBurstLength: %u"
498 " for this Unsolicited DataOut Burst.\n",
499 (cmd->first_burst_len + payload_length),
500 conn->sess->sess_ops->FirstBurstLength);
501 transport_send_check_condition_and_sense(se_cmd,
502 TCM_INCORRECT_AMOUNT_OF_DATA, 0);
503 return -1;
504 }
505
506 if (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))
507 return 0;
508
509 if (((cmd->first_burst_len + payload_length) != cmd->data_length) &&
510 ((cmd->first_burst_len + payload_length) !=
511 conn->sess->sess_ops->FirstBurstLength)) {
512 pr_err("Unsolicited non-immediate data received %u"
513 " does not equal FirstBurstLength: %u, and does"
514 " not equal ExpXferLen %u.\n",
515 (cmd->first_burst_len + payload_length),
516 conn->sess->sess_ops->FirstBurstLength, cmd->data_length);
517 transport_send_check_condition_and_sense(se_cmd,
518 TCM_INCORRECT_AMOUNT_OF_DATA, 0);
519 return -1;
520 }
521 return 0;
522}
523
524struct iscsi_cmd *iscsit_find_cmd_from_itt(
525 struct iscsi_conn *conn,
526 u32 init_task_tag)
527{
528 struct iscsi_cmd *cmd;
529
530 spin_lock_bh(&conn->cmd_lock);
531 list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) {
532 if (cmd->init_task_tag == init_task_tag) {
533 spin_unlock_bh(&conn->cmd_lock);
534 return cmd;
535 }
536 }
537 spin_unlock_bh(&conn->cmd_lock);
538
539 pr_err("Unable to locate ITT: 0x%08x on CID: %hu",
540 init_task_tag, conn->cid);
541 return NULL;
542}
543
544struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(
545 struct iscsi_conn *conn,
546 u32 init_task_tag,
547 u32 length)
548{
549 struct iscsi_cmd *cmd;
550
551 spin_lock_bh(&conn->cmd_lock);
552 list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) {
553 if (cmd->init_task_tag == init_task_tag) {
554 spin_unlock_bh(&conn->cmd_lock);
555 return cmd;
556 }
557 }
558 spin_unlock_bh(&conn->cmd_lock);
559
560 pr_err("Unable to locate ITT: 0x%08x on CID: %hu,"
561 " dumping payload\n", init_task_tag, conn->cid);
562 if (length)
563 iscsit_dump_data_payload(conn, length, 1);
564
565 return NULL;
566}
567
568struct iscsi_cmd *iscsit_find_cmd_from_ttt(
569 struct iscsi_conn *conn,
570 u32 targ_xfer_tag)
571{
572 struct iscsi_cmd *cmd = NULL;
573
574 spin_lock_bh(&conn->cmd_lock);
575 list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) {
576 if (cmd->targ_xfer_tag == targ_xfer_tag) {
577 spin_unlock_bh(&conn->cmd_lock);
578 return cmd;
579 }
580 }
581 spin_unlock_bh(&conn->cmd_lock);
582
583 pr_err("Unable to locate TTT: 0x%08x on CID: %hu\n",
584 targ_xfer_tag, conn->cid);
585 return NULL;
586}
587
588int iscsit_find_cmd_for_recovery(
589 struct iscsi_session *sess,
590 struct iscsi_cmd **cmd_ptr,
591 struct iscsi_conn_recovery **cr_ptr,
592 u32 init_task_tag)
593{
594 struct iscsi_cmd *cmd = NULL;
595 struct iscsi_conn_recovery *cr;
596 /*
597 * Scan through the inactive connection recovery list's command list.
598 * If init_task_tag matches the command is still alligent.
599 */
600 spin_lock(&sess->cr_i_lock);
601 list_for_each_entry(cr, &sess->cr_inactive_list, cr_list) {
602 spin_lock(&cr->conn_recovery_cmd_lock);
603 list_for_each_entry(cmd, &cr->conn_recovery_cmd_list, i_list) {
604 if (cmd->init_task_tag == init_task_tag) {
605 spin_unlock(&cr->conn_recovery_cmd_lock);
606 spin_unlock(&sess->cr_i_lock);
607
608 *cr_ptr = cr;
609 *cmd_ptr = cmd;
610 return -2;
611 }
612 }
613 spin_unlock(&cr->conn_recovery_cmd_lock);
614 }
615 spin_unlock(&sess->cr_i_lock);
616 /*
617 * Scan through the active connection recovery list's command list.
618 * If init_task_tag matches the command is ready to be reassigned.
619 */
620 spin_lock(&sess->cr_a_lock);
621 list_for_each_entry(cr, &sess->cr_active_list, cr_list) {
622 spin_lock(&cr->conn_recovery_cmd_lock);
623 list_for_each_entry(cmd, &cr->conn_recovery_cmd_list, i_list) {
624 if (cmd->init_task_tag == init_task_tag) {
625 spin_unlock(&cr->conn_recovery_cmd_lock);
626 spin_unlock(&sess->cr_a_lock);
627
628 *cr_ptr = cr;
629 *cmd_ptr = cmd;
630 return 0;
631 }
632 }
633 spin_unlock(&cr->conn_recovery_cmd_lock);
634 }
635 spin_unlock(&sess->cr_a_lock);
636
637 return -1;
638}
639
640void iscsit_add_cmd_to_immediate_queue(
641 struct iscsi_cmd *cmd,
642 struct iscsi_conn *conn,
643 u8 state)
644{
645 struct iscsi_queue_req *qr;
646
647 qr = kmem_cache_zalloc(lio_qr_cache, GFP_ATOMIC);
648 if (!qr) {
649 pr_err("Unable to allocate memory for"
650 " struct iscsi_queue_req\n");
651 return;
652 }
653 INIT_LIST_HEAD(&qr->qr_list);
654 qr->cmd = cmd;
655 qr->state = state;
656
657 spin_lock_bh(&conn->immed_queue_lock);
658 list_add_tail(&qr->qr_list, &conn->immed_queue_list);
659 atomic_inc(&cmd->immed_queue_count);
660 atomic_set(&conn->check_immediate_queue, 1);
661 spin_unlock_bh(&conn->immed_queue_lock);
662
663 wake_up_process(conn->thread_set->tx_thread);
664}
665
666struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn)
667{
668 struct iscsi_queue_req *qr;
669
670 spin_lock_bh(&conn->immed_queue_lock);
671 if (list_empty(&conn->immed_queue_list)) {
672 spin_unlock_bh(&conn->immed_queue_lock);
673 return NULL;
674 }
675 list_for_each_entry(qr, &conn->immed_queue_list, qr_list)
676 break;
677
678 list_del(&qr->qr_list);
679 if (qr->cmd)
680 atomic_dec(&qr->cmd->immed_queue_count);
681 spin_unlock_bh(&conn->immed_queue_lock);
682
683 return qr;
684}
685
686static void iscsit_remove_cmd_from_immediate_queue(
687 struct iscsi_cmd *cmd,
688 struct iscsi_conn *conn)
689{
690 struct iscsi_queue_req *qr, *qr_tmp;
691
692 spin_lock_bh(&conn->immed_queue_lock);
693 if (!atomic_read(&cmd->immed_queue_count)) {
694 spin_unlock_bh(&conn->immed_queue_lock);
695 return;
696 }
697
698 list_for_each_entry_safe(qr, qr_tmp, &conn->immed_queue_list, qr_list) {
699 if (qr->cmd != cmd)
700 continue;
701
702 atomic_dec(&qr->cmd->immed_queue_count);
703 list_del(&qr->qr_list);
704 kmem_cache_free(lio_qr_cache, qr);
705 }
706 spin_unlock_bh(&conn->immed_queue_lock);
707
708 if (atomic_read(&cmd->immed_queue_count)) {
709 pr_err("ITT: 0x%08x immed_queue_count: %d\n",
710 cmd->init_task_tag,
711 atomic_read(&cmd->immed_queue_count));
712 }
713}
714
715void iscsit_add_cmd_to_response_queue(
716 struct iscsi_cmd *cmd,
717 struct iscsi_conn *conn,
718 u8 state)
719{
720 struct iscsi_queue_req *qr;
721
722 qr = kmem_cache_zalloc(lio_qr_cache, GFP_ATOMIC);
723 if (!qr) {
724 pr_err("Unable to allocate memory for"
725 " struct iscsi_queue_req\n");
726 return;
727 }
728 INIT_LIST_HEAD(&qr->qr_list);
729 qr->cmd = cmd;
730 qr->state = state;
731
732 spin_lock_bh(&conn->response_queue_lock);
733 list_add_tail(&qr->qr_list, &conn->response_queue_list);
734 atomic_inc(&cmd->response_queue_count);
735 spin_unlock_bh(&conn->response_queue_lock);
736
737 wake_up_process(conn->thread_set->tx_thread);
738}
739
740struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn)
741{
742 struct iscsi_queue_req *qr;
743
744 spin_lock_bh(&conn->response_queue_lock);
745 if (list_empty(&conn->response_queue_list)) {
746 spin_unlock_bh(&conn->response_queue_lock);
747 return NULL;
748 }
749
750 list_for_each_entry(qr, &conn->response_queue_list, qr_list)
751 break;
752
753 list_del(&qr->qr_list);
754 if (qr->cmd)
755 atomic_dec(&qr->cmd->response_queue_count);
756 spin_unlock_bh(&conn->response_queue_lock);
757
758 return qr;
759}
760
761static void iscsit_remove_cmd_from_response_queue(
762 struct iscsi_cmd *cmd,
763 struct iscsi_conn *conn)
764{
765 struct iscsi_queue_req *qr, *qr_tmp;
766
767 spin_lock_bh(&conn->response_queue_lock);
768 if (!atomic_read(&cmd->response_queue_count)) {
769 spin_unlock_bh(&conn->response_queue_lock);
770 return;
771 }
772
773 list_for_each_entry_safe(qr, qr_tmp, &conn->response_queue_list,
774 qr_list) {
775 if (qr->cmd != cmd)
776 continue;
777
778 atomic_dec(&qr->cmd->response_queue_count);
779 list_del(&qr->qr_list);
780 kmem_cache_free(lio_qr_cache, qr);
781 }
782 spin_unlock_bh(&conn->response_queue_lock);
783
784 if (atomic_read(&cmd->response_queue_count)) {
785 pr_err("ITT: 0x%08x response_queue_count: %d\n",
786 cmd->init_task_tag,
787 atomic_read(&cmd->response_queue_count));
788 }
789}
790
791void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn)
792{
793 struct iscsi_queue_req *qr, *qr_tmp;
794
795 spin_lock_bh(&conn->immed_queue_lock);
796 list_for_each_entry_safe(qr, qr_tmp, &conn->immed_queue_list, qr_list) {
797 list_del(&qr->qr_list);
798 if (qr->cmd)
799 atomic_dec(&qr->cmd->immed_queue_count);
800
801 kmem_cache_free(lio_qr_cache, qr);
802 }
803 spin_unlock_bh(&conn->immed_queue_lock);
804
805 spin_lock_bh(&conn->response_queue_lock);
806 list_for_each_entry_safe(qr, qr_tmp, &conn->response_queue_list,
807 qr_list) {
808 list_del(&qr->qr_list);
809 if (qr->cmd)
810 atomic_dec(&qr->cmd->response_queue_count);
811
812 kmem_cache_free(lio_qr_cache, qr);
813 }
814 spin_unlock_bh(&conn->response_queue_lock);
815}
816
817void iscsit_release_cmd(struct iscsi_cmd *cmd)
818{
819 struct iscsi_conn *conn = cmd->conn;
820 int i;
821
822 iscsit_free_r2ts_from_list(cmd);
823 iscsit_free_all_datain_reqs(cmd);
824
825 kfree(cmd->buf_ptr);
826 kfree(cmd->pdu_list);
827 kfree(cmd->seq_list);
828 kfree(cmd->tmr_req);
829 kfree(cmd->iov_data);
830
831 for (i = 0; i < cmd->t_mem_sg_nents; i++)
832 __free_page(sg_page(&cmd->t_mem_sg[i]));
833
834 kfree(cmd->t_mem_sg);
835
836 if (conn) {
837 iscsit_remove_cmd_from_immediate_queue(cmd, conn);
838 iscsit_remove_cmd_from_response_queue(cmd, conn);
839 }
840
841 kmem_cache_free(lio_cmd_cache, cmd);
842}
843
844int iscsit_check_session_usage_count(struct iscsi_session *sess)
845{
846 spin_lock_bh(&sess->session_usage_lock);
847 if (sess->session_usage_count != 0) {
848 sess->session_waiting_on_uc = 1;
849 spin_unlock_bh(&sess->session_usage_lock);
850 if (in_interrupt())
851 return 2;
852
853 wait_for_completion(&sess->session_waiting_on_uc_comp);
854 return 1;
855 }
856 spin_unlock_bh(&sess->session_usage_lock);
857
858 return 0;
859}
860
861void iscsit_dec_session_usage_count(struct iscsi_session *sess)
862{
863 spin_lock_bh(&sess->session_usage_lock);
864 sess->session_usage_count--;
865
866 if (!sess->session_usage_count && sess->session_waiting_on_uc)
867 complete(&sess->session_waiting_on_uc_comp);
868
869 spin_unlock_bh(&sess->session_usage_lock);
870}
871
872void iscsit_inc_session_usage_count(struct iscsi_session *sess)
873{
874 spin_lock_bh(&sess->session_usage_lock);
875 sess->session_usage_count++;
876 spin_unlock_bh(&sess->session_usage_lock);
877}
878
879/*
880 * Used before iscsi_do[rx,tx]_data() to determine iov and [rx,tx]_marker
881 * array counts needed for sync and steering.
882 */
883static int iscsit_determine_sync_and_steering_counts(
884 struct iscsi_conn *conn,
885 struct iscsi_data_count *count)
886{
887 u32 length = count->data_length;
888 u32 marker, markint;
889
890 count->sync_and_steering = 1;
891
892 marker = (count->type == ISCSI_RX_DATA) ?
893 conn->of_marker : conn->if_marker;
894 markint = (count->type == ISCSI_RX_DATA) ?
895 (conn->conn_ops->OFMarkInt * 4) :
896 (conn->conn_ops->IFMarkInt * 4);
897 count->ss_iov_count = count->iov_count;
898
899 while (length > 0) {
900 if (length >= marker) {
901 count->ss_iov_count += 3;
902 count->ss_marker_count += 2;
903
904 length -= marker;
905 marker = markint;
906 } else
907 length = 0;
908 }
909
910 return 0;
911}
912
913/*
914 * Setup conn->if_marker and conn->of_marker values based upon
915 * the initial marker-less interval. (see iSCSI v19 A.2)
916 */
917int iscsit_set_sync_and_steering_values(struct iscsi_conn *conn)
918{
919 int login_ifmarker_count = 0, login_ofmarker_count = 0, next_marker = 0;
920 /*
921 * IFMarkInt and OFMarkInt are negotiated as 32-bit words.
922 */
923 u32 IFMarkInt = (conn->conn_ops->IFMarkInt * 4);
924 u32 OFMarkInt = (conn->conn_ops->OFMarkInt * 4);
925
926 if (conn->conn_ops->OFMarker) {
927 /*
928 * Account for the first Login Command received not
929 * via iscsi_recv_msg().
930 */
931 conn->of_marker += ISCSI_HDR_LEN;
932 if (conn->of_marker <= OFMarkInt) {
933 conn->of_marker = (OFMarkInt - conn->of_marker);
934 } else {
935 login_ofmarker_count = (conn->of_marker / OFMarkInt);
936 next_marker = (OFMarkInt * (login_ofmarker_count + 1)) +
937 (login_ofmarker_count * MARKER_SIZE);
938 conn->of_marker = (next_marker - conn->of_marker);
939 }
940 conn->of_marker_offset = 0;
941 pr_debug("Setting OFMarker value to %u based on Initial"
942 " Markerless Interval.\n", conn->of_marker);
943 }
944
945 if (conn->conn_ops->IFMarker) {
946 if (conn->if_marker <= IFMarkInt) {
947 conn->if_marker = (IFMarkInt - conn->if_marker);
948 } else {
949 login_ifmarker_count = (conn->if_marker / IFMarkInt);
950 next_marker = (IFMarkInt * (login_ifmarker_count + 1)) +
951 (login_ifmarker_count * MARKER_SIZE);
952 conn->if_marker = (next_marker - conn->if_marker);
953 }
954 pr_debug("Setting IFMarker value to %u based on Initial"
955 " Markerless Interval.\n", conn->if_marker);
956 }
957
958 return 0;
959}
960
961struct iscsi_conn *iscsit_get_conn_from_cid(struct iscsi_session *sess, u16 cid)
962{
963 struct iscsi_conn *conn;
964
965 spin_lock_bh(&sess->conn_lock);
966 list_for_each_entry(conn, &sess->sess_conn_list, conn_list) {
967 if ((conn->cid == cid) &&
968 (conn->conn_state == TARG_CONN_STATE_LOGGED_IN)) {
969 iscsit_inc_conn_usage_count(conn);
970 spin_unlock_bh(&sess->conn_lock);
971 return conn;
972 }
973 }
974 spin_unlock_bh(&sess->conn_lock);
975
976 return NULL;
977}
978
979struct iscsi_conn *iscsit_get_conn_from_cid_rcfr(struct iscsi_session *sess, u16 cid)
980{
981 struct iscsi_conn *conn;
982
983 spin_lock_bh(&sess->conn_lock);
984 list_for_each_entry(conn, &sess->sess_conn_list, conn_list) {
985 if (conn->cid == cid) {
986 iscsit_inc_conn_usage_count(conn);
987 spin_lock(&conn->state_lock);
988 atomic_set(&conn->connection_wait_rcfr, 1);
989 spin_unlock(&conn->state_lock);
990 spin_unlock_bh(&sess->conn_lock);
991 return conn;
992 }
993 }
994 spin_unlock_bh(&sess->conn_lock);
995
996 return NULL;
997}
998
999void iscsit_check_conn_usage_count(struct iscsi_conn *conn)
1000{
1001 spin_lock_bh(&conn->conn_usage_lock);
1002 if (conn->conn_usage_count != 0) {
1003 conn->conn_waiting_on_uc = 1;
1004 spin_unlock_bh(&conn->conn_usage_lock);
1005
1006 wait_for_completion(&conn->conn_waiting_on_uc_comp);
1007 return;
1008 }
1009 spin_unlock_bh(&conn->conn_usage_lock);
1010}
1011
1012void iscsit_dec_conn_usage_count(struct iscsi_conn *conn)
1013{
1014 spin_lock_bh(&conn->conn_usage_lock);
1015 conn->conn_usage_count--;
1016
1017 if (!conn->conn_usage_count && conn->conn_waiting_on_uc)
1018 complete(&conn->conn_waiting_on_uc_comp);
1019
1020 spin_unlock_bh(&conn->conn_usage_lock);
1021}
1022
1023void iscsit_inc_conn_usage_count(struct iscsi_conn *conn)
1024{
1025 spin_lock_bh(&conn->conn_usage_lock);
1026 conn->conn_usage_count++;
1027 spin_unlock_bh(&conn->conn_usage_lock);
1028}
1029
1030static int iscsit_add_nopin(struct iscsi_conn *conn, int want_response)
1031{
1032 u8 state;
1033 struct iscsi_cmd *cmd;
1034
1035 cmd = iscsit_allocate_cmd(conn, GFP_ATOMIC);
1036 if (!cmd)
1037 return -1;
1038
1039 cmd->iscsi_opcode = ISCSI_OP_NOOP_IN;
1040 state = (want_response) ? ISTATE_SEND_NOPIN_WANT_RESPONSE :
1041 ISTATE_SEND_NOPIN_NO_RESPONSE;
1042 cmd->init_task_tag = 0xFFFFFFFF;
1043 spin_lock_bh(&conn->sess->ttt_lock);
1044 cmd->targ_xfer_tag = (want_response) ? conn->sess->targ_xfer_tag++ :
1045 0xFFFFFFFF;
1046 if (want_response && (cmd->targ_xfer_tag == 0xFFFFFFFF))
1047 cmd->targ_xfer_tag = conn->sess->targ_xfer_tag++;
1048 spin_unlock_bh(&conn->sess->ttt_lock);
1049
1050 spin_lock_bh(&conn->cmd_lock);
1051 list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
1052 spin_unlock_bh(&conn->cmd_lock);
1053
1054 if (want_response)
1055 iscsit_start_nopin_response_timer(conn);
1056 iscsit_add_cmd_to_immediate_queue(cmd, conn, state);
1057
1058 return 0;
1059}
1060
1061static void iscsit_handle_nopin_response_timeout(unsigned long data)
1062{
1063 struct iscsi_conn *conn = (struct iscsi_conn *) data;
1064
1065 iscsit_inc_conn_usage_count(conn);
1066
1067 spin_lock_bh(&conn->nopin_timer_lock);
1068 if (conn->nopin_response_timer_flags & ISCSI_TF_STOP) {
1069 spin_unlock_bh(&conn->nopin_timer_lock);
1070 iscsit_dec_conn_usage_count(conn);
1071 return;
1072 }
1073
1074 pr_debug("Did not receive response to NOPIN on CID: %hu on"
1075 " SID: %u, failing connection.\n", conn->cid,
1076 conn->sess->sid);
1077 conn->nopin_response_timer_flags &= ~ISCSI_TF_RUNNING;
1078 spin_unlock_bh(&conn->nopin_timer_lock);
1079
1080 {
1081 struct iscsi_portal_group *tpg = conn->sess->tpg;
1082 struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
1083
1084 if (tiqn) {
1085 spin_lock_bh(&tiqn->sess_err_stats.lock);
1086 strcpy(tiqn->sess_err_stats.last_sess_fail_rem_name,
1087 (void *)conn->sess->sess_ops->InitiatorName);
1088 tiqn->sess_err_stats.last_sess_failure_type =
1089 ISCSI_SESS_ERR_CXN_TIMEOUT;
1090 tiqn->sess_err_stats.cxn_timeout_errors++;
1091 conn->sess->conn_timeout_errors++;
1092 spin_unlock_bh(&tiqn->sess_err_stats.lock);
1093 }
1094 }
1095
1096 iscsit_cause_connection_reinstatement(conn, 0);
1097 iscsit_dec_conn_usage_count(conn);
1098}
1099
1100void iscsit_mod_nopin_response_timer(struct iscsi_conn *conn)
1101{
1102 struct iscsi_session *sess = conn->sess;
1103 struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);
1104
1105 spin_lock_bh(&conn->nopin_timer_lock);
1106 if (!(conn->nopin_response_timer_flags & ISCSI_TF_RUNNING)) {
1107 spin_unlock_bh(&conn->nopin_timer_lock);
1108 return;
1109 }
1110
1111 mod_timer(&conn->nopin_response_timer,
1112 (get_jiffies_64() + na->nopin_response_timeout * HZ));
1113 spin_unlock_bh(&conn->nopin_timer_lock);
1114}
1115
1116/*
1117 * Called with conn->nopin_timer_lock held.
1118 */
1119void iscsit_start_nopin_response_timer(struct iscsi_conn *conn)
1120{
1121 struct iscsi_session *sess = conn->sess;
1122 struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);
1123
1124 spin_lock_bh(&conn->nopin_timer_lock);
1125 if (conn->nopin_response_timer_flags & ISCSI_TF_RUNNING) {
1126 spin_unlock_bh(&conn->nopin_timer_lock);
1127 return;
1128 }
1129
1130 init_timer(&conn->nopin_response_timer);
1131 conn->nopin_response_timer.expires =
1132 (get_jiffies_64() + na->nopin_response_timeout * HZ);
1133 conn->nopin_response_timer.data = (unsigned long)conn;
1134 conn->nopin_response_timer.function = iscsit_handle_nopin_response_timeout;
1135 conn->nopin_response_timer_flags &= ~ISCSI_TF_STOP;
1136 conn->nopin_response_timer_flags |= ISCSI_TF_RUNNING;
1137 add_timer(&conn->nopin_response_timer);
1138
1139 pr_debug("Started NOPIN Response Timer on CID: %d to %u"
1140 " seconds\n", conn->cid, na->nopin_response_timeout);
1141 spin_unlock_bh(&conn->nopin_timer_lock);
1142}
1143
1144void iscsit_stop_nopin_response_timer(struct iscsi_conn *conn)
1145{
1146 spin_lock_bh(&conn->nopin_timer_lock);
1147 if (!(conn->nopin_response_timer_flags & ISCSI_TF_RUNNING)) {
1148 spin_unlock_bh(&conn->nopin_timer_lock);
1149 return;
1150 }
1151 conn->nopin_response_timer_flags |= ISCSI_TF_STOP;
1152 spin_unlock_bh(&conn->nopin_timer_lock);
1153
1154 del_timer_sync(&conn->nopin_response_timer);
1155
1156 spin_lock_bh(&conn->nopin_timer_lock);
1157 conn->nopin_response_timer_flags &= ~ISCSI_TF_RUNNING;
1158 spin_unlock_bh(&conn->nopin_timer_lock);
1159}
1160
1161static void iscsit_handle_nopin_timeout(unsigned long data)
1162{
1163 struct iscsi_conn *conn = (struct iscsi_conn *) data;
1164
1165 iscsit_inc_conn_usage_count(conn);
1166
1167 spin_lock_bh(&conn->nopin_timer_lock);
1168 if (conn->nopin_timer_flags & ISCSI_TF_STOP) {
1169 spin_unlock_bh(&conn->nopin_timer_lock);
1170 iscsit_dec_conn_usage_count(conn);
1171 return;
1172 }
1173 conn->nopin_timer_flags &= ~ISCSI_TF_RUNNING;
1174 spin_unlock_bh(&conn->nopin_timer_lock);
1175
1176 iscsit_add_nopin(conn, 1);
1177 iscsit_dec_conn_usage_count(conn);
1178}
1179
1180/*
1181 * Called with conn->nopin_timer_lock held.
1182 */
1183void __iscsit_start_nopin_timer(struct iscsi_conn *conn)
1184{
1185 struct iscsi_session *sess = conn->sess;
1186 struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);
1187 /*
1188 * NOPIN timeout is disabled.
1189 */
1190 if (!na->nopin_timeout)
1191 return;
1192
1193 if (conn->nopin_timer_flags & ISCSI_TF_RUNNING)
1194 return;
1195
1196 init_timer(&conn->nopin_timer);
1197 conn->nopin_timer.expires = (get_jiffies_64() + na->nopin_timeout * HZ);
1198 conn->nopin_timer.data = (unsigned long)conn;
1199 conn->nopin_timer.function = iscsit_handle_nopin_timeout;
1200 conn->nopin_timer_flags &= ~ISCSI_TF_STOP;
1201 conn->nopin_timer_flags |= ISCSI_TF_RUNNING;
1202 add_timer(&conn->nopin_timer);
1203
1204 pr_debug("Started NOPIN Timer on CID: %d at %u second"
1205 " interval\n", conn->cid, na->nopin_timeout);
1206}
1207
1208void iscsit_start_nopin_timer(struct iscsi_conn *conn)
1209{
1210 struct iscsi_session *sess = conn->sess;
1211 struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);
1212 /*
1213 * NOPIN timeout is disabled..
1214 */
1215 if (!na->nopin_timeout)
1216 return;
1217
1218 spin_lock_bh(&conn->nopin_timer_lock);
1219 if (conn->nopin_timer_flags & ISCSI_TF_RUNNING) {
1220 spin_unlock_bh(&conn->nopin_timer_lock);
1221 return;
1222 }
1223
1224 init_timer(&conn->nopin_timer);
1225 conn->nopin_timer.expires = (get_jiffies_64() + na->nopin_timeout * HZ);
1226 conn->nopin_timer.data = (unsigned long)conn;
1227 conn->nopin_timer.function = iscsit_handle_nopin_timeout;
1228 conn->nopin_timer_flags &= ~ISCSI_TF_STOP;
1229 conn->nopin_timer_flags |= ISCSI_TF_RUNNING;
1230 add_timer(&conn->nopin_timer);
1231
1232 pr_debug("Started NOPIN Timer on CID: %d at %u second"
1233 " interval\n", conn->cid, na->nopin_timeout);
1234 spin_unlock_bh(&conn->nopin_timer_lock);
1235}
1236
1237void iscsit_stop_nopin_timer(struct iscsi_conn *conn)
1238{
1239 spin_lock_bh(&conn->nopin_timer_lock);
1240 if (!(conn->nopin_timer_flags & ISCSI_TF_RUNNING)) {
1241 spin_unlock_bh(&conn->nopin_timer_lock);
1242 return;
1243 }
1244 conn->nopin_timer_flags |= ISCSI_TF_STOP;
1245 spin_unlock_bh(&conn->nopin_timer_lock);
1246
1247 del_timer_sync(&conn->nopin_timer);
1248
1249 spin_lock_bh(&conn->nopin_timer_lock);
1250 conn->nopin_timer_flags &= ~ISCSI_TF_RUNNING;
1251 spin_unlock_bh(&conn->nopin_timer_lock);
1252}
1253
1254int iscsit_send_tx_data(
1255 struct iscsi_cmd *cmd,
1256 struct iscsi_conn *conn,
1257 int use_misc)
1258{
1259 int tx_sent, tx_size;
1260 u32 iov_count;
1261 struct kvec *iov;
1262
1263send_data:
1264 tx_size = cmd->tx_size;
1265
1266 if (!use_misc) {
1267 iov = &cmd->iov_data[0];
1268 iov_count = cmd->iov_data_count;
1269 } else {
1270 iov = &cmd->iov_misc[0];
1271 iov_count = cmd->iov_misc_count;
1272 }
1273
1274 tx_sent = tx_data(conn, &iov[0], iov_count, tx_size);
1275 if (tx_size != tx_sent) {
1276 if (tx_sent == -EAGAIN) {
1277 pr_err("tx_data() returned -EAGAIN\n");
1278 goto send_data;
1279 } else
1280 return -1;
1281 }
1282 cmd->tx_size = 0;
1283
1284 return 0;
1285}
1286
1287int iscsit_fe_sendpage_sg(
1288 struct iscsi_cmd *cmd,
1289 struct iscsi_conn *conn)
1290{
1291 struct scatterlist *sg = cmd->first_data_sg;
1292 struct kvec iov;
1293 u32 tx_hdr_size, data_len;
1294 u32 offset = cmd->first_data_sg_off;
1295 int tx_sent;
1296
1297send_hdr:
1298 tx_hdr_size = ISCSI_HDR_LEN;
1299 if (conn->conn_ops->HeaderDigest)
1300 tx_hdr_size += ISCSI_CRC_LEN;
1301
1302 iov.iov_base = cmd->pdu;
1303 iov.iov_len = tx_hdr_size;
1304
1305 tx_sent = tx_data(conn, &iov, 1, tx_hdr_size);
1306 if (tx_hdr_size != tx_sent) {
1307 if (tx_sent == -EAGAIN) {
1308 pr_err("tx_data() returned -EAGAIN\n");
1309 goto send_hdr;
1310 }
1311 return -1;
1312 }
1313
1314 data_len = cmd->tx_size - tx_hdr_size - cmd->padding;
1315 if (conn->conn_ops->DataDigest)
1316 data_len -= ISCSI_CRC_LEN;
1317
1318 /*
1319 * Perform sendpage() for each page in the scatterlist
1320 */
1321 while (data_len) {
1322 u32 space = (sg->length - offset);
1323 u32 sub_len = min_t(u32, data_len, space);
1324send_pg:
1325 tx_sent = conn->sock->ops->sendpage(conn->sock,
1326 sg_page(sg), sg->offset + offset, sub_len, 0);
1327 if (tx_sent != sub_len) {
1328 if (tx_sent == -EAGAIN) {
1329 pr_err("tcp_sendpage() returned"
1330 " -EAGAIN\n");
1331 goto send_pg;
1332 }
1333
1334 pr_err("tcp_sendpage() failure: %d\n",
1335 tx_sent);
1336 return -1;
1337 }
1338
1339 data_len -= sub_len;
1340 offset = 0;
1341 sg = sg_next(sg);
1342 }
1343
1344send_padding:
1345 if (cmd->padding) {
1346 struct kvec *iov_p =
1347 &cmd->iov_data[cmd->iov_data_count-1];
1348
1349 tx_sent = tx_data(conn, iov_p, 1, cmd->padding);
1350 if (cmd->padding != tx_sent) {
1351 if (tx_sent == -EAGAIN) {
1352 pr_err("tx_data() returned -EAGAIN\n");
1353 goto send_padding;
1354 }
1355 return -1;
1356 }
1357 }
1358
1359send_datacrc:
1360 if (conn->conn_ops->DataDigest) {
1361 struct kvec *iov_d =
1362 &cmd->iov_data[cmd->iov_data_count];
1363
1364 tx_sent = tx_data(conn, iov_d, 1, ISCSI_CRC_LEN);
1365 if (ISCSI_CRC_LEN != tx_sent) {
1366 if (tx_sent == -EAGAIN) {
1367 pr_err("tx_data() returned -EAGAIN\n");
1368 goto send_datacrc;
1369 }
1370 return -1;
1371 }
1372 }
1373
1374 return 0;
1375}
1376
1377/*
1378 * This function is used for mainly sending a ISCSI_TARG_LOGIN_RSP PDU
1379 * back to the Initiator when an expection condition occurs with the
1380 * errors set in status_class and status_detail.
1381 *
1382 * Parameters: iSCSI Connection, Status Class, Status Detail.
1383 * Returns: 0 on success, -1 on error.
1384 */
1385int iscsit_tx_login_rsp(struct iscsi_conn *conn, u8 status_class, u8 status_detail)
1386{
1387 u8 iscsi_hdr[ISCSI_HDR_LEN];
1388 int err;
1389 struct kvec iov;
1390 struct iscsi_login_rsp *hdr;
1391
1392 iscsit_collect_login_stats(conn, status_class, status_detail);
1393
1394 memset(&iov, 0, sizeof(struct kvec));
1395 memset(&iscsi_hdr, 0x0, ISCSI_HDR_LEN);
1396
1397 hdr = (struct iscsi_login_rsp *)&iscsi_hdr;
1398 hdr->opcode = ISCSI_OP_LOGIN_RSP;
1399 hdr->status_class = status_class;
1400 hdr->status_detail = status_detail;
1401 hdr->itt = cpu_to_be32(conn->login_itt);
1402
1403 iov.iov_base = &iscsi_hdr;
1404 iov.iov_len = ISCSI_HDR_LEN;
1405
1406 PRINT_BUFF(iscsi_hdr, ISCSI_HDR_LEN);
1407
1408 err = tx_data(conn, &iov, 1, ISCSI_HDR_LEN);
1409 if (err != ISCSI_HDR_LEN) {
1410 pr_err("tx_data returned less than expected\n");
1411 return -1;
1412 }
1413
1414 return 0;
1415}
1416
1417void iscsit_print_session_params(struct iscsi_session *sess)
1418{
1419 struct iscsi_conn *conn;
1420
1421 pr_debug("-----------------------------[Session Params for"
1422 " SID: %u]-----------------------------\n", sess->sid);
1423 spin_lock_bh(&sess->conn_lock);
1424 list_for_each_entry(conn, &sess->sess_conn_list, conn_list)
1425 iscsi_dump_conn_ops(conn->conn_ops);
1426 spin_unlock_bh(&sess->conn_lock);
1427
1428 iscsi_dump_sess_ops(sess->sess_ops);
1429}
1430
1431static int iscsit_do_rx_data(
1432 struct iscsi_conn *conn,
1433 struct iscsi_data_count *count)
1434{
1435 int data = count->data_length, rx_loop = 0, total_rx = 0, iov_len;
1436 u32 rx_marker_val[count->ss_marker_count], rx_marker_iov = 0;
1437 struct kvec iov[count->ss_iov_count], *iov_p;
1438 struct msghdr msg;
1439
1440 if (!conn || !conn->sock || !conn->conn_ops)
1441 return -1;
1442
1443 memset(&msg, 0, sizeof(struct msghdr));
1444
1445 if (count->sync_and_steering) {
1446 int size = 0;
1447 u32 i, orig_iov_count = 0;
1448 u32 orig_iov_len = 0, orig_iov_loc = 0;
1449 u32 iov_count = 0, per_iov_bytes = 0;
1450 u32 *rx_marker, old_rx_marker = 0;
1451 struct kvec *iov_record;
1452
1453 memset(&rx_marker_val, 0,
1454 count->ss_marker_count * sizeof(u32));
1455 memset(&iov, 0, count->ss_iov_count * sizeof(struct kvec));
1456
1457 iov_record = count->iov;
1458 orig_iov_count = count->iov_count;
1459 rx_marker = &conn->of_marker;
1460
1461 i = 0;
1462 size = data;
1463 orig_iov_len = iov_record[orig_iov_loc].iov_len;
1464 while (size > 0) {
1465 pr_debug("rx_data: #1 orig_iov_len %u,"
1466 " orig_iov_loc %u\n", orig_iov_len, orig_iov_loc);
1467 pr_debug("rx_data: #2 rx_marker %u, size"
1468 " %u\n", *rx_marker, size);
1469
1470 if (orig_iov_len >= *rx_marker) {
1471 iov[iov_count].iov_len = *rx_marker;
1472 iov[iov_count++].iov_base =
1473 (iov_record[orig_iov_loc].iov_base +
1474 per_iov_bytes);
1475
1476 iov[iov_count].iov_len = (MARKER_SIZE / 2);
1477 iov[iov_count++].iov_base =
1478 &rx_marker_val[rx_marker_iov++];
1479 iov[iov_count].iov_len = (MARKER_SIZE / 2);
1480 iov[iov_count++].iov_base =
1481 &rx_marker_val[rx_marker_iov++];
1482 old_rx_marker = *rx_marker;
1483
1484 /*
1485 * OFMarkInt is in 32-bit words.
1486 */
1487 *rx_marker = (conn->conn_ops->OFMarkInt * 4);
1488 size -= old_rx_marker;
1489 orig_iov_len -= old_rx_marker;
1490 per_iov_bytes += old_rx_marker;
1491
1492 pr_debug("rx_data: #3 new_rx_marker"
1493 " %u, size %u\n", *rx_marker, size);
1494 } else {
1495 iov[iov_count].iov_len = orig_iov_len;
1496 iov[iov_count++].iov_base =
1497 (iov_record[orig_iov_loc].iov_base +
1498 per_iov_bytes);
1499
1500 per_iov_bytes = 0;
1501 *rx_marker -= orig_iov_len;
1502 size -= orig_iov_len;
1503
1504 if (size)
1505 orig_iov_len =
1506 iov_record[++orig_iov_loc].iov_len;
1507
1508 pr_debug("rx_data: #4 new_rx_marker"
1509 " %u, size %u\n", *rx_marker, size);
1510 }
1511 }
1512 data += (rx_marker_iov * (MARKER_SIZE / 2));
1513
1514 iov_p = &iov[0];
1515 iov_len = iov_count;
1516
1517 if (iov_count > count->ss_iov_count) {
1518 pr_err("iov_count: %d, count->ss_iov_count:"
1519 " %d\n", iov_count, count->ss_iov_count);
1520 return -1;
1521 }
1522 if (rx_marker_iov > count->ss_marker_count) {
1523 pr_err("rx_marker_iov: %d, count->ss_marker"
1524 "_count: %d\n", rx_marker_iov,
1525 count->ss_marker_count);
1526 return -1;
1527 }
1528 } else {
1529 iov_p = count->iov;
1530 iov_len = count->iov_count;
1531 }
1532
1533 while (total_rx < data) {
1534 rx_loop = kernel_recvmsg(conn->sock, &msg, iov_p, iov_len,
1535 (data - total_rx), MSG_WAITALL);
1536 if (rx_loop <= 0) {
1537 pr_debug("rx_loop: %d total_rx: %d\n",
1538 rx_loop, total_rx);
1539 return rx_loop;
1540 }
1541 total_rx += rx_loop;
1542 pr_debug("rx_loop: %d, total_rx: %d, data: %d\n",
1543 rx_loop, total_rx, data);
1544 }
1545
1546 if (count->sync_and_steering) {
1547 int j;
1548 for (j = 0; j < rx_marker_iov; j++) {
1549 pr_debug("rx_data: #5 j: %d, offset: %d\n",
1550 j, rx_marker_val[j]);
1551 conn->of_marker_offset = rx_marker_val[j];
1552 }
1553 total_rx -= (rx_marker_iov * (MARKER_SIZE / 2));
1554 }
1555
1556 return total_rx;
1557}
1558
1559static int iscsit_do_tx_data(
1560 struct iscsi_conn *conn,
1561 struct iscsi_data_count *count)
1562{
1563 int data = count->data_length, total_tx = 0, tx_loop = 0, iov_len;
1564 u32 tx_marker_val[count->ss_marker_count], tx_marker_iov = 0;
1565 struct kvec iov[count->ss_iov_count], *iov_p;
1566 struct msghdr msg;
1567
1568 if (!conn || !conn->sock || !conn->conn_ops)
1569 return -1;
1570
1571 if (data <= 0) {
1572 pr_err("Data length is: %d\n", data);
1573 return -1;
1574 }
1575
1576 memset(&msg, 0, sizeof(struct msghdr));
1577
1578 if (count->sync_and_steering) {
1579 int size = 0;
1580 u32 i, orig_iov_count = 0;
1581 u32 orig_iov_len = 0, orig_iov_loc = 0;
1582 u32 iov_count = 0, per_iov_bytes = 0;
1583 u32 *tx_marker, old_tx_marker = 0;
1584 struct kvec *iov_record;
1585
1586 memset(&tx_marker_val, 0,
1587 count->ss_marker_count * sizeof(u32));
1588 memset(&iov, 0, count->ss_iov_count * sizeof(struct kvec));
1589
1590 iov_record = count->iov;
1591 orig_iov_count = count->iov_count;
1592 tx_marker = &conn->if_marker;
1593
1594 i = 0;
1595 size = data;
1596 orig_iov_len = iov_record[orig_iov_loc].iov_len;
1597 while (size > 0) {
1598 pr_debug("tx_data: #1 orig_iov_len %u,"
1599 " orig_iov_loc %u\n", orig_iov_len, orig_iov_loc);
1600 pr_debug("tx_data: #2 tx_marker %u, size"
1601 " %u\n", *tx_marker, size);
1602
1603 if (orig_iov_len >= *tx_marker) {
1604 iov[iov_count].iov_len = *tx_marker;
1605 iov[iov_count++].iov_base =
1606 (iov_record[orig_iov_loc].iov_base +
1607 per_iov_bytes);
1608
1609 tx_marker_val[tx_marker_iov] =
1610 (size - *tx_marker);
1611 iov[iov_count].iov_len = (MARKER_SIZE / 2);
1612 iov[iov_count++].iov_base =
1613 &tx_marker_val[tx_marker_iov++];
1614 iov[iov_count].iov_len = (MARKER_SIZE / 2);
1615 iov[iov_count++].iov_base =
1616 &tx_marker_val[tx_marker_iov++];
1617 old_tx_marker = *tx_marker;
1618
1619 /*
1620 * IFMarkInt is in 32-bit words.
1621 */
1622 *tx_marker = (conn->conn_ops->IFMarkInt * 4);
1623 size -= old_tx_marker;
1624 orig_iov_len -= old_tx_marker;
1625 per_iov_bytes += old_tx_marker;
1626
1627 pr_debug("tx_data: #3 new_tx_marker"
1628 " %u, size %u\n", *tx_marker, size);
1629 pr_debug("tx_data: #4 offset %u\n",
1630 tx_marker_val[tx_marker_iov-1]);
1631 } else {
1632 iov[iov_count].iov_len = orig_iov_len;
1633 iov[iov_count++].iov_base
1634 = (iov_record[orig_iov_loc].iov_base +
1635 per_iov_bytes);
1636
1637 per_iov_bytes = 0;
1638 *tx_marker -= orig_iov_len;
1639 size -= orig_iov_len;
1640
1641 if (size)
1642 orig_iov_len =
1643 iov_record[++orig_iov_loc].iov_len;
1644
1645 pr_debug("tx_data: #5 new_tx_marker"
1646 " %u, size %u\n", *tx_marker, size);
1647 }
1648 }
1649
1650 data += (tx_marker_iov * (MARKER_SIZE / 2));
1651
1652 iov_p = &iov[0];
1653 iov_len = iov_count;
1654
1655 if (iov_count > count->ss_iov_count) {
1656 pr_err("iov_count: %d, count->ss_iov_count:"
1657 " %d\n", iov_count, count->ss_iov_count);
1658 return -1;
1659 }
1660 if (tx_marker_iov > count->ss_marker_count) {
1661 pr_err("tx_marker_iov: %d, count->ss_marker"
1662 "_count: %d\n", tx_marker_iov,
1663 count->ss_marker_count);
1664 return -1;
1665 }
1666 } else {
1667 iov_p = count->iov;
1668 iov_len = count->iov_count;
1669 }
1670
1671 while (total_tx < data) {
1672 tx_loop = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len,
1673 (data - total_tx));
1674 if (tx_loop <= 0) {
1675 pr_debug("tx_loop: %d total_tx %d\n",
1676 tx_loop, total_tx);
1677 return tx_loop;
1678 }
1679 total_tx += tx_loop;
1680 pr_debug("tx_loop: %d, total_tx: %d, data: %d\n",
1681 tx_loop, total_tx, data);
1682 }
1683
1684 if (count->sync_and_steering)
1685 total_tx -= (tx_marker_iov * (MARKER_SIZE / 2));
1686
1687 return total_tx;
1688}
1689
1690int rx_data(
1691 struct iscsi_conn *conn,
1692 struct kvec *iov,
1693 int iov_count,
1694 int data)
1695{
1696 struct iscsi_data_count c;
1697
1698 if (!conn || !conn->sock || !conn->conn_ops)
1699 return -1;
1700
1701 memset(&c, 0, sizeof(struct iscsi_data_count));
1702 c.iov = iov;
1703 c.iov_count = iov_count;
1704 c.data_length = data;
1705 c.type = ISCSI_RX_DATA;
1706
1707 if (conn->conn_ops->OFMarker &&
1708 (conn->conn_state >= TARG_CONN_STATE_LOGGED_IN)) {
1709 if (iscsit_determine_sync_and_steering_counts(conn, &c) < 0)
1710 return -1;
1711 }
1712
1713 return iscsit_do_rx_data(conn, &c);
1714}
1715
1716int tx_data(
1717 struct iscsi_conn *conn,
1718 struct kvec *iov,
1719 int iov_count,
1720 int data)
1721{
1722 struct iscsi_data_count c;
1723
1724 if (!conn || !conn->sock || !conn->conn_ops)
1725 return -1;
1726
1727 memset(&c, 0, sizeof(struct iscsi_data_count));
1728 c.iov = iov;
1729 c.iov_count = iov_count;
1730 c.data_length = data;
1731 c.type = ISCSI_TX_DATA;
1732
1733 if (conn->conn_ops->IFMarker &&
1734 (conn->conn_state >= TARG_CONN_STATE_LOGGED_IN)) {
1735 if (iscsit_determine_sync_and_steering_counts(conn, &c) < 0)
1736 return -1;
1737 }
1738
1739 return iscsit_do_tx_data(conn, &c);
1740}
1741
1742void iscsit_collect_login_stats(
1743 struct iscsi_conn *conn,
1744 u8 status_class,
1745 u8 status_detail)
1746{
1747 struct iscsi_param *intrname = NULL;
1748 struct iscsi_tiqn *tiqn;
1749 struct iscsi_login_stats *ls;
1750
1751 tiqn = iscsit_snmp_get_tiqn(conn);
1752 if (!tiqn)
1753 return;
1754
1755 ls = &tiqn->login_stats;
1756
1757 spin_lock(&ls->lock);
1758 if (!strcmp(conn->login_ip, ls->last_intr_fail_ip_addr) &&
1759 ((get_jiffies_64() - ls->last_fail_time) < 10)) {
1760 /* We already have the failure info for this login */
1761 spin_unlock(&ls->lock);
1762 return;
1763 }
1764
1765 if (status_class == ISCSI_STATUS_CLS_SUCCESS)
1766 ls->accepts++;
1767 else if (status_class == ISCSI_STATUS_CLS_REDIRECT) {
1768 ls->redirects++;
1769 ls->last_fail_type = ISCSI_LOGIN_FAIL_REDIRECT;
1770 } else if ((status_class == ISCSI_STATUS_CLS_INITIATOR_ERR) &&
1771 (status_detail == ISCSI_LOGIN_STATUS_AUTH_FAILED)) {
1772 ls->authenticate_fails++;
1773 ls->last_fail_type = ISCSI_LOGIN_FAIL_AUTHENTICATE;
1774 } else if ((status_class == ISCSI_STATUS_CLS_INITIATOR_ERR) &&
1775 (status_detail == ISCSI_LOGIN_STATUS_TGT_FORBIDDEN)) {
1776 ls->authorize_fails++;
1777 ls->last_fail_type = ISCSI_LOGIN_FAIL_AUTHORIZE;
1778 } else if ((status_class == ISCSI_STATUS_CLS_INITIATOR_ERR) &&
1779 (status_detail == ISCSI_LOGIN_STATUS_INIT_ERR)) {
1780 ls->negotiate_fails++;
1781 ls->last_fail_type = ISCSI_LOGIN_FAIL_NEGOTIATE;
1782 } else {
1783 ls->other_fails++;
1784 ls->last_fail_type = ISCSI_LOGIN_FAIL_OTHER;
1785 }
1786
1787 /* Save initiator name, ip address and time, if it is a failed login */
1788 if (status_class != ISCSI_STATUS_CLS_SUCCESS) {
1789 if (conn->param_list)
1790 intrname = iscsi_find_param_from_key(INITIATORNAME,
1791 conn->param_list);
1792 strcpy(ls->last_intr_fail_name,
1793 (intrname ? intrname->value : "Unknown"));
1794
1795 ls->last_intr_fail_ip_family = conn->sock->sk->sk_family;
1796 snprintf(ls->last_intr_fail_ip_addr, IPV6_ADDRESS_SPACE,
1797 "%s", conn->login_ip);
1798 ls->last_fail_time = get_jiffies_64();
1799 }
1800
1801 spin_unlock(&ls->lock);
1802}
1803
1804struct iscsi_tiqn *iscsit_snmp_get_tiqn(struct iscsi_conn *conn)
1805{
1806 struct iscsi_portal_group *tpg;
1807
1808 if (!conn || !conn->sess)
1809 return NULL;
1810
1811 tpg = conn->sess->tpg;
1812 if (!tpg)
1813 return NULL;
1814
1815 if (!tpg->tpg_tiqn)
1816 return NULL;
1817
1818 return tpg->tpg_tiqn;
1819}
diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h
new file mode 100644
index 000000000000..2cd49d607bda
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_util.h
@@ -0,0 +1,60 @@
1#ifndef ISCSI_TARGET_UTIL_H
2#define ISCSI_TARGET_UTIL_H
3
4#define MARKER_SIZE 8
5
6extern int iscsit_add_r2t_to_list(struct iscsi_cmd *, u32, u32, int, u32);
7extern struct iscsi_r2t *iscsit_get_r2t_for_eos(struct iscsi_cmd *, u32, u32);
8extern struct iscsi_r2t *iscsit_get_r2t_from_list(struct iscsi_cmd *);
9extern void iscsit_free_r2t(struct iscsi_r2t *, struct iscsi_cmd *);
10extern void iscsit_free_r2ts_from_list(struct iscsi_cmd *);
11extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t);
12extern struct iscsi_cmd *iscsit_allocate_se_cmd(struct iscsi_conn *, u32, int, int);
13extern struct iscsi_cmd *iscsit_allocate_se_cmd_for_tmr(struct iscsi_conn *, u8);
14extern int iscsit_decide_list_to_build(struct iscsi_cmd *, u32);
15extern struct iscsi_seq *iscsit_get_seq_holder_for_datain(struct iscsi_cmd *, u32);
16extern struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *);
17extern struct iscsi_r2t *iscsit_get_holder_for_r2tsn(struct iscsi_cmd *, u32);
18int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, u32 cmdsn);
19extern int iscsit_check_unsolicited_dataout(struct iscsi_cmd *, unsigned char *);
20extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, u32);
21extern struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(struct iscsi_conn *,
22 u32, u32);
23extern struct iscsi_cmd *iscsit_find_cmd_from_ttt(struct iscsi_conn *, u32);
24extern int iscsit_find_cmd_for_recovery(struct iscsi_session *, struct iscsi_cmd **,
25 struct iscsi_conn_recovery **, u32);
26extern void iscsit_add_cmd_to_immediate_queue(struct iscsi_cmd *, struct iscsi_conn *, u8);
27extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *);
28extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8);
29extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *);
30extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *);
31extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *);
32extern void iscsit_release_cmd(struct iscsi_cmd *);
33extern int iscsit_check_session_usage_count(struct iscsi_session *);
34extern void iscsit_dec_session_usage_count(struct iscsi_session *);
35extern void iscsit_inc_session_usage_count(struct iscsi_session *);
36extern int iscsit_set_sync_and_steering_values(struct iscsi_conn *);
37extern struct iscsi_conn *iscsit_get_conn_from_cid(struct iscsi_session *, u16);
38extern struct iscsi_conn *iscsit_get_conn_from_cid_rcfr(struct iscsi_session *, u16);
39extern void iscsit_check_conn_usage_count(struct iscsi_conn *);
40extern void iscsit_dec_conn_usage_count(struct iscsi_conn *);
41extern void iscsit_inc_conn_usage_count(struct iscsi_conn *);
42extern void iscsit_mod_nopin_response_timer(struct iscsi_conn *);
43extern void iscsit_start_nopin_response_timer(struct iscsi_conn *);
44extern void iscsit_stop_nopin_response_timer(struct iscsi_conn *);
45extern void __iscsit_start_nopin_timer(struct iscsi_conn *);
46extern void iscsit_start_nopin_timer(struct iscsi_conn *);
47extern void iscsit_stop_nopin_timer(struct iscsi_conn *);
48extern int iscsit_send_tx_data(struct iscsi_cmd *, struct iscsi_conn *, int);
49extern int iscsit_fe_sendpage_sg(struct iscsi_cmd *, struct iscsi_conn *);
50extern int iscsit_tx_login_rsp(struct iscsi_conn *, u8, u8);
51extern void iscsit_print_session_params(struct iscsi_session *);
52extern int iscsit_print_dev_to_proc(char *, char **, off_t, int);
53extern int iscsit_print_sessions_to_proc(char *, char **, off_t, int);
54extern int iscsit_print_tpg_to_proc(char *, char **, off_t, int);
55extern int rx_data(struct iscsi_conn *, struct kvec *, int, int);
56extern int tx_data(struct iscsi_conn *, struct kvec *, int, int);
57extern void iscsit_collect_login_stats(struct iscsi_conn *, u8, u8);
58extern struct iscsi_tiqn *iscsit_snmp_get_tiqn(struct iscsi_conn *);
59
60#endif /*** ISCSI_TARGET_UTIL_H ***/