1e48354ceSNicholas Bellinger /*******************************************************************************
2e48354ceSNicholas Bellinger  * This file contains main functions related to the iSCSI Target Core Driver.
3e48354ceSNicholas Bellinger  *
44c76251eSNicholas Bellinger  * (c) Copyright 2007-2013 Datera, Inc.
5e48354ceSNicholas Bellinger  *
6e48354ceSNicholas Bellinger  * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
7e48354ceSNicholas Bellinger  *
8e48354ceSNicholas Bellinger  * This program is free software; you can redistribute it and/or modify
9e48354ceSNicholas Bellinger  * it under the terms of the GNU General Public License as published by
10e48354ceSNicholas Bellinger  * the Free Software Foundation; either version 2 of the License, or
11e48354ceSNicholas Bellinger  * (at your option) any later version.
12e48354ceSNicholas Bellinger  *
13e48354ceSNicholas Bellinger  * This program is distributed in the hope that it will be useful,
14e48354ceSNicholas Bellinger  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15e48354ceSNicholas Bellinger  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16e48354ceSNicholas Bellinger  * GNU General Public License for more details.
17e48354ceSNicholas Bellinger  ******************************************************************************/
18e48354ceSNicholas Bellinger 
19e48354ceSNicholas Bellinger #include <linux/string.h>
20e48354ceSNicholas Bellinger #include <linux/kthread.h>
21e48354ceSNicholas Bellinger #include <linux/crypto.h>
22e48354ceSNicholas Bellinger #include <linux/completion.h>
23827509e3SPaul Gortmaker #include <linux/module.h>
2440401530SAl Viro #include <linux/idr.h>
25e48354ceSNicholas Bellinger #include <asm/unaligned.h>
26e48354ceSNicholas Bellinger #include <scsi/scsi_device.h>
27e48354ceSNicholas Bellinger #include <scsi/iscsi_proto.h>
28d28b1169SAndy Grover #include <scsi/scsi_tcq.h>
29e48354ceSNicholas Bellinger #include <target/target_core_base.h>
30c4795fb2SChristoph Hellwig #include <target/target_core_fabric.h>
31d28b1169SAndy Grover #include <target/target_core_configfs.h>
32e48354ceSNicholas Bellinger 
3367f091f2SSagi Grimberg #include <target/iscsi/iscsi_target_core.h>
34e48354ceSNicholas Bellinger #include "iscsi_target_parameters.h"
35e48354ceSNicholas Bellinger #include "iscsi_target_seq_pdu_list.h"
36e48354ceSNicholas Bellinger #include "iscsi_target_tq.h"
37e48354ceSNicholas Bellinger #include "iscsi_target_configfs.h"
38e48354ceSNicholas Bellinger #include "iscsi_target_datain_values.h"
39e48354ceSNicholas Bellinger #include "iscsi_target_erl0.h"
40e48354ceSNicholas Bellinger #include "iscsi_target_erl1.h"
41e48354ceSNicholas Bellinger #include "iscsi_target_erl2.h"
42e48354ceSNicholas Bellinger #include "iscsi_target_login.h"
43e48354ceSNicholas Bellinger #include "iscsi_target_tmr.h"
44e48354ceSNicholas Bellinger #include "iscsi_target_tpg.h"
45e48354ceSNicholas Bellinger #include "iscsi_target_util.h"
46e48354ceSNicholas Bellinger #include "iscsi_target.h"
47e48354ceSNicholas Bellinger #include "iscsi_target_device.h"
4867f091f2SSagi Grimberg #include <target/iscsi/iscsi_target_stat.h>
49e48354ceSNicholas Bellinger 
50baa4d64bSNicholas Bellinger #include <target/iscsi/iscsi_transport.h>
51baa4d64bSNicholas Bellinger 
52e48354ceSNicholas Bellinger static LIST_HEAD(g_tiqn_list);
53e48354ceSNicholas Bellinger static LIST_HEAD(g_np_list);
54e48354ceSNicholas Bellinger static DEFINE_SPINLOCK(tiqn_lock);
55ee291e63SAndy Grover static DEFINE_MUTEX(np_lock);
56e48354ceSNicholas Bellinger 
57e48354ceSNicholas Bellinger static struct idr tiqn_idr;
58e48354ceSNicholas Bellinger struct idr sess_idr;
59e48354ceSNicholas Bellinger struct mutex auth_id_lock;
60e48354ceSNicholas Bellinger spinlock_t sess_idr_lock;
61e48354ceSNicholas Bellinger 
62e48354ceSNicholas Bellinger struct iscsit_global *iscsit_global;
63e48354ceSNicholas Bellinger 
64e48354ceSNicholas Bellinger struct kmem_cache *lio_qr_cache;
65e48354ceSNicholas Bellinger struct kmem_cache *lio_dr_cache;
66e48354ceSNicholas Bellinger struct kmem_cache *lio_ooo_cache;
67e48354ceSNicholas Bellinger struct kmem_cache *lio_r2t_cache;
68e48354ceSNicholas Bellinger 
69e48354ceSNicholas Bellinger static int iscsit_handle_immediate_data(struct iscsi_cmd *,
702ec5a8c1SNicholas Bellinger 			struct iscsi_scsi_req *, u32);
71e48354ceSNicholas Bellinger 
72e48354ceSNicholas Bellinger struct iscsi_tiqn *iscsit_get_tiqn_for_login(unsigned char *buf)
73e48354ceSNicholas Bellinger {
74e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn = NULL;
75e48354ceSNicholas Bellinger 
76e48354ceSNicholas Bellinger 	spin_lock(&tiqn_lock);
77e48354ceSNicholas Bellinger 	list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) {
78e48354ceSNicholas Bellinger 		if (!strcmp(tiqn->tiqn, buf)) {
79e48354ceSNicholas Bellinger 
80e48354ceSNicholas Bellinger 			spin_lock(&tiqn->tiqn_state_lock);
81e48354ceSNicholas Bellinger 			if (tiqn->tiqn_state == TIQN_STATE_ACTIVE) {
82e48354ceSNicholas Bellinger 				tiqn->tiqn_access_count++;
83e48354ceSNicholas Bellinger 				spin_unlock(&tiqn->tiqn_state_lock);
84e48354ceSNicholas Bellinger 				spin_unlock(&tiqn_lock);
85e48354ceSNicholas Bellinger 				return tiqn;
86e48354ceSNicholas Bellinger 			}
87e48354ceSNicholas Bellinger 			spin_unlock(&tiqn->tiqn_state_lock);
88e48354ceSNicholas Bellinger 		}
89e48354ceSNicholas Bellinger 	}
90e48354ceSNicholas Bellinger 	spin_unlock(&tiqn_lock);
91e48354ceSNicholas Bellinger 
92e48354ceSNicholas Bellinger 	return NULL;
93e48354ceSNicholas Bellinger }
94e48354ceSNicholas Bellinger 
95e48354ceSNicholas Bellinger static int iscsit_set_tiqn_shutdown(struct iscsi_tiqn *tiqn)
96e48354ceSNicholas Bellinger {
97e48354ceSNicholas Bellinger 	spin_lock(&tiqn->tiqn_state_lock);
98e48354ceSNicholas Bellinger 	if (tiqn->tiqn_state == TIQN_STATE_ACTIVE) {
99e48354ceSNicholas Bellinger 		tiqn->tiqn_state = TIQN_STATE_SHUTDOWN;
100e48354ceSNicholas Bellinger 		spin_unlock(&tiqn->tiqn_state_lock);
101e48354ceSNicholas Bellinger 		return 0;
102e48354ceSNicholas Bellinger 	}
103e48354ceSNicholas Bellinger 	spin_unlock(&tiqn->tiqn_state_lock);
104e48354ceSNicholas Bellinger 
105e48354ceSNicholas Bellinger 	return -1;
106e48354ceSNicholas Bellinger }
107e48354ceSNicholas Bellinger 
108e48354ceSNicholas Bellinger void iscsit_put_tiqn_for_login(struct iscsi_tiqn *tiqn)
109e48354ceSNicholas Bellinger {
110e48354ceSNicholas Bellinger 	spin_lock(&tiqn->tiqn_state_lock);
111e48354ceSNicholas Bellinger 	tiqn->tiqn_access_count--;
112e48354ceSNicholas Bellinger 	spin_unlock(&tiqn->tiqn_state_lock);
113e48354ceSNicholas Bellinger }
114e48354ceSNicholas Bellinger 
115e48354ceSNicholas Bellinger /*
116e48354ceSNicholas Bellinger  * Note that IQN formatting is expected to be done in userspace, and
117e48354ceSNicholas Bellinger  * no explict IQN format checks are done here.
118e48354ceSNicholas Bellinger  */
119e48354ceSNicholas Bellinger struct iscsi_tiqn *iscsit_add_tiqn(unsigned char *buf)
120e48354ceSNicholas Bellinger {
121e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn = NULL;
122e48354ceSNicholas Bellinger 	int ret;
123e48354ceSNicholas Bellinger 
1248f50c7f5SDan Carpenter 	if (strlen(buf) >= ISCSI_IQN_LEN) {
125e48354ceSNicholas Bellinger 		pr_err("Target IQN exceeds %d bytes\n",
126e48354ceSNicholas Bellinger 				ISCSI_IQN_LEN);
127e48354ceSNicholas Bellinger 		return ERR_PTR(-EINVAL);
128e48354ceSNicholas Bellinger 	}
129e48354ceSNicholas Bellinger 
130e48354ceSNicholas Bellinger 	tiqn = kzalloc(sizeof(struct iscsi_tiqn), GFP_KERNEL);
131e48354ceSNicholas Bellinger 	if (!tiqn) {
132e48354ceSNicholas Bellinger 		pr_err("Unable to allocate struct iscsi_tiqn\n");
133e48354ceSNicholas Bellinger 		return ERR_PTR(-ENOMEM);
134e48354ceSNicholas Bellinger 	}
135e48354ceSNicholas Bellinger 
136e48354ceSNicholas Bellinger 	sprintf(tiqn->tiqn, "%s", buf);
137e48354ceSNicholas Bellinger 	INIT_LIST_HEAD(&tiqn->tiqn_list);
138e48354ceSNicholas Bellinger 	INIT_LIST_HEAD(&tiqn->tiqn_tpg_list);
139e48354ceSNicholas Bellinger 	spin_lock_init(&tiqn->tiqn_state_lock);
140e48354ceSNicholas Bellinger 	spin_lock_init(&tiqn->tiqn_tpg_lock);
141e48354ceSNicholas Bellinger 	spin_lock_init(&tiqn->sess_err_stats.lock);
142e48354ceSNicholas Bellinger 	spin_lock_init(&tiqn->login_stats.lock);
143e48354ceSNicholas Bellinger 	spin_lock_init(&tiqn->logout_stats.lock);
144e48354ceSNicholas Bellinger 
145e48354ceSNicholas Bellinger 	tiqn->tiqn_state = TIQN_STATE_ACTIVE;
146e48354ceSNicholas Bellinger 
147c9365bd0STejun Heo 	idr_preload(GFP_KERNEL);
148e48354ceSNicholas Bellinger 	spin_lock(&tiqn_lock);
149c9365bd0STejun Heo 
150c9365bd0STejun Heo 	ret = idr_alloc(&tiqn_idr, NULL, 0, 0, GFP_NOWAIT);
151e48354ceSNicholas Bellinger 	if (ret < 0) {
152c9365bd0STejun Heo 		pr_err("idr_alloc() failed for tiqn->tiqn_index\n");
153e48354ceSNicholas Bellinger 		spin_unlock(&tiqn_lock);
154c9365bd0STejun Heo 		idr_preload_end();
155e48354ceSNicholas Bellinger 		kfree(tiqn);
156e48354ceSNicholas Bellinger 		return ERR_PTR(ret);
157e48354ceSNicholas Bellinger 	}
158c9365bd0STejun Heo 	tiqn->tiqn_index = ret;
159e48354ceSNicholas Bellinger 	list_add_tail(&tiqn->tiqn_list, &g_tiqn_list);
160c9365bd0STejun Heo 
161e48354ceSNicholas Bellinger 	spin_unlock(&tiqn_lock);
162c9365bd0STejun Heo 	idr_preload_end();
163e48354ceSNicholas Bellinger 
164e48354ceSNicholas Bellinger 	pr_debug("CORE[0] - Added iSCSI Target IQN: %s\n", tiqn->tiqn);
165e48354ceSNicholas Bellinger 
166e48354ceSNicholas Bellinger 	return tiqn;
167e48354ceSNicholas Bellinger 
168e48354ceSNicholas Bellinger }
169e48354ceSNicholas Bellinger 
170e48354ceSNicholas Bellinger static void iscsit_wait_for_tiqn(struct iscsi_tiqn *tiqn)
171e48354ceSNicholas Bellinger {
172e48354ceSNicholas Bellinger 	/*
173e48354ceSNicholas Bellinger 	 * Wait for accesses to said struct iscsi_tiqn to end.
174e48354ceSNicholas Bellinger 	 */
175e48354ceSNicholas Bellinger 	spin_lock(&tiqn->tiqn_state_lock);
176e48354ceSNicholas Bellinger 	while (tiqn->tiqn_access_count != 0) {
177e48354ceSNicholas Bellinger 		spin_unlock(&tiqn->tiqn_state_lock);
178e48354ceSNicholas Bellinger 		msleep(10);
179e48354ceSNicholas Bellinger 		spin_lock(&tiqn->tiqn_state_lock);
180e48354ceSNicholas Bellinger 	}
181e48354ceSNicholas Bellinger 	spin_unlock(&tiqn->tiqn_state_lock);
182e48354ceSNicholas Bellinger }
183e48354ceSNicholas Bellinger 
184e48354ceSNicholas Bellinger void iscsit_del_tiqn(struct iscsi_tiqn *tiqn)
185e48354ceSNicholas Bellinger {
186e48354ceSNicholas Bellinger 	/*
187e48354ceSNicholas Bellinger 	 * iscsit_set_tiqn_shutdown sets tiqn->tiqn_state = TIQN_STATE_SHUTDOWN
188e48354ceSNicholas Bellinger 	 * while holding tiqn->tiqn_state_lock.  This means that all subsequent
189e48354ceSNicholas Bellinger 	 * attempts to access this struct iscsi_tiqn will fail from both transport
190e48354ceSNicholas Bellinger 	 * fabric and control code paths.
191e48354ceSNicholas Bellinger 	 */
192e48354ceSNicholas Bellinger 	if (iscsit_set_tiqn_shutdown(tiqn) < 0) {
193e48354ceSNicholas Bellinger 		pr_err("iscsit_set_tiqn_shutdown() failed\n");
194e48354ceSNicholas Bellinger 		return;
195e48354ceSNicholas Bellinger 	}
196e48354ceSNicholas Bellinger 
197e48354ceSNicholas Bellinger 	iscsit_wait_for_tiqn(tiqn);
198e48354ceSNicholas Bellinger 
199e48354ceSNicholas Bellinger 	spin_lock(&tiqn_lock);
200e48354ceSNicholas Bellinger 	list_del(&tiqn->tiqn_list);
201e48354ceSNicholas Bellinger 	idr_remove(&tiqn_idr, tiqn->tiqn_index);
202e48354ceSNicholas Bellinger 	spin_unlock(&tiqn_lock);
203e48354ceSNicholas Bellinger 
204e48354ceSNicholas Bellinger 	pr_debug("CORE[0] - Deleted iSCSI Target IQN: %s\n",
205e48354ceSNicholas Bellinger 			tiqn->tiqn);
206e48354ceSNicholas Bellinger 	kfree(tiqn);
207e48354ceSNicholas Bellinger }
208e48354ceSNicholas Bellinger 
209e48354ceSNicholas Bellinger int iscsit_access_np(struct iscsi_np *np, struct iscsi_portal_group *tpg)
210e48354ceSNicholas Bellinger {
211e48354ceSNicholas Bellinger 	int ret;
212e48354ceSNicholas Bellinger 	/*
213e48354ceSNicholas Bellinger 	 * Determine if the network portal is accepting storage traffic.
214e48354ceSNicholas Bellinger 	 */
215e48354ceSNicholas Bellinger 	spin_lock_bh(&np->np_thread_lock);
216e48354ceSNicholas Bellinger 	if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
217e48354ceSNicholas Bellinger 		spin_unlock_bh(&np->np_thread_lock);
218e48354ceSNicholas Bellinger 		return -1;
219e48354ceSNicholas Bellinger 	}
220e48354ceSNicholas Bellinger 	spin_unlock_bh(&np->np_thread_lock);
221e48354ceSNicholas Bellinger 	/*
222e48354ceSNicholas Bellinger 	 * Determine if the portal group is accepting storage traffic.
223e48354ceSNicholas Bellinger 	 */
224e48354ceSNicholas Bellinger 	spin_lock_bh(&tpg->tpg_state_lock);
225e48354ceSNicholas Bellinger 	if (tpg->tpg_state != TPG_STATE_ACTIVE) {
226e48354ceSNicholas Bellinger 		spin_unlock_bh(&tpg->tpg_state_lock);
227e48354ceSNicholas Bellinger 		return -1;
228e48354ceSNicholas Bellinger 	}
229e48354ceSNicholas Bellinger 	spin_unlock_bh(&tpg->tpg_state_lock);
230e48354ceSNicholas Bellinger 
231e48354ceSNicholas Bellinger 	/*
232e48354ceSNicholas Bellinger 	 * Here we serialize access across the TIQN+TPG Tuple.
233e48354ceSNicholas Bellinger 	 */
234a91eb7d9SNicholas Bellinger 	ret = down_interruptible(&tpg->np_login_sem);
235e48354ceSNicholas Bellinger 	if ((ret != 0) || signal_pending(current))
236e48354ceSNicholas Bellinger 		return -1;
237e48354ceSNicholas Bellinger 
238a91eb7d9SNicholas Bellinger 	spin_lock_bh(&tpg->tpg_state_lock);
239a91eb7d9SNicholas Bellinger 	if (tpg->tpg_state != TPG_STATE_ACTIVE) {
240a91eb7d9SNicholas Bellinger 		spin_unlock_bh(&tpg->tpg_state_lock);
241a91eb7d9SNicholas Bellinger 		up(&tpg->np_login_sem);
242a91eb7d9SNicholas Bellinger 		return -1;
243a91eb7d9SNicholas Bellinger 	}
244a91eb7d9SNicholas Bellinger 	spin_unlock_bh(&tpg->tpg_state_lock);
245e48354ceSNicholas Bellinger 
246e48354ceSNicholas Bellinger 	return 0;
247e48354ceSNicholas Bellinger }
248e48354ceSNicholas Bellinger 
249a91eb7d9SNicholas Bellinger void iscsit_login_kref_put(struct kref *kref)
250a91eb7d9SNicholas Bellinger {
251a91eb7d9SNicholas Bellinger 	struct iscsi_tpg_np *tpg_np = container_of(kref,
252a91eb7d9SNicholas Bellinger 				struct iscsi_tpg_np, tpg_np_kref);
253a91eb7d9SNicholas Bellinger 
254a91eb7d9SNicholas Bellinger 	complete(&tpg_np->tpg_np_comp);
255a91eb7d9SNicholas Bellinger }
256a91eb7d9SNicholas Bellinger 
257a91eb7d9SNicholas Bellinger int iscsit_deaccess_np(struct iscsi_np *np, struct iscsi_portal_group *tpg,
258a91eb7d9SNicholas Bellinger 		       struct iscsi_tpg_np *tpg_np)
259e48354ceSNicholas Bellinger {
260e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
261e48354ceSNicholas Bellinger 
262a91eb7d9SNicholas Bellinger 	up(&tpg->np_login_sem);
263e48354ceSNicholas Bellinger 
264a91eb7d9SNicholas Bellinger 	if (tpg_np)
265a91eb7d9SNicholas Bellinger 		kref_put(&tpg_np->tpg_np_kref, iscsit_login_kref_put);
266e48354ceSNicholas Bellinger 
267e48354ceSNicholas Bellinger 	if (tiqn)
268e48354ceSNicholas Bellinger 		iscsit_put_tiqn_for_login(tiqn);
269e48354ceSNicholas Bellinger 
270e48354ceSNicholas Bellinger 	return 0;
271e48354ceSNicholas Bellinger }
272e48354ceSNicholas Bellinger 
27305b96892SNicholas Bellinger bool iscsit_check_np_match(
274e48354ceSNicholas Bellinger 	struct __kernel_sockaddr_storage *sockaddr,
27505b96892SNicholas Bellinger 	struct iscsi_np *np,
276e48354ceSNicholas Bellinger 	int network_transport)
277e48354ceSNicholas Bellinger {
278e48354ceSNicholas Bellinger 	struct sockaddr_in *sock_in, *sock_in_e;
279e48354ceSNicholas Bellinger 	struct sockaddr_in6 *sock_in6, *sock_in6_e;
28005b96892SNicholas Bellinger 	bool ip_match = false;
281e48354ceSNicholas Bellinger 	u16 port;
282e48354ceSNicholas Bellinger 
28305b96892SNicholas Bellinger 	if (sockaddr->ss_family == AF_INET6) {
28405b96892SNicholas Bellinger 		sock_in6 = (struct sockaddr_in6 *)sockaddr;
28505b96892SNicholas Bellinger 		sock_in6_e = (struct sockaddr_in6 *)&np->np_sockaddr;
28605b96892SNicholas Bellinger 
28705b96892SNicholas Bellinger 		if (!memcmp(&sock_in6->sin6_addr.in6_u,
28805b96892SNicholas Bellinger 			    &sock_in6_e->sin6_addr.in6_u,
28905b96892SNicholas Bellinger 			    sizeof(struct in6_addr)))
29005b96892SNicholas Bellinger 			ip_match = true;
29105b96892SNicholas Bellinger 
29205b96892SNicholas Bellinger 		port = ntohs(sock_in6->sin6_port);
29305b96892SNicholas Bellinger 	} else {
29405b96892SNicholas Bellinger 		sock_in = (struct sockaddr_in *)sockaddr;
29505b96892SNicholas Bellinger 		sock_in_e = (struct sockaddr_in *)&np->np_sockaddr;
29605b96892SNicholas Bellinger 
29705b96892SNicholas Bellinger 		if (sock_in->sin_addr.s_addr == sock_in_e->sin_addr.s_addr)
29805b96892SNicholas Bellinger 			ip_match = true;
29905b96892SNicholas Bellinger 
30005b96892SNicholas Bellinger 		port = ntohs(sock_in->sin_port);
30105b96892SNicholas Bellinger 	}
30205b96892SNicholas Bellinger 
3030bcc297eSChristophe Vu-Brugier 	if (ip_match && (np->np_port == port) &&
30405b96892SNicholas Bellinger 	    (np->np_network_transport == network_transport))
30505b96892SNicholas Bellinger 		return true;
30605b96892SNicholas Bellinger 
30705b96892SNicholas Bellinger 	return false;
30805b96892SNicholas Bellinger }
30905b96892SNicholas Bellinger 
310ee291e63SAndy Grover /*
311ee291e63SAndy Grover  * Called with mutex np_lock held
312ee291e63SAndy Grover  */
31305b96892SNicholas Bellinger static struct iscsi_np *iscsit_get_np(
31405b96892SNicholas Bellinger 	struct __kernel_sockaddr_storage *sockaddr,
31505b96892SNicholas Bellinger 	int network_transport)
31605b96892SNicholas Bellinger {
31705b96892SNicholas Bellinger 	struct iscsi_np *np;
31805b96892SNicholas Bellinger 	bool match;
31905b96892SNicholas Bellinger 
320e48354ceSNicholas Bellinger 	list_for_each_entry(np, &g_np_list, np_list) {
321ee291e63SAndy Grover 		spin_lock_bh(&np->np_thread_lock);
322e48354ceSNicholas Bellinger 		if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
323ee291e63SAndy Grover 			spin_unlock_bh(&np->np_thread_lock);
324e48354ceSNicholas Bellinger 			continue;
325e48354ceSNicholas Bellinger 		}
326e48354ceSNicholas Bellinger 
32705b96892SNicholas Bellinger 		match = iscsit_check_np_match(sockaddr, np, network_transport);
3280bcc297eSChristophe Vu-Brugier 		if (match) {
329e48354ceSNicholas Bellinger 			/*
330e48354ceSNicholas Bellinger 			 * Increment the np_exports reference count now to
331e48354ceSNicholas Bellinger 			 * prevent iscsit_del_np() below from being called
332e48354ceSNicholas Bellinger 			 * while iscsi_tpg_add_network_portal() is called.
333e48354ceSNicholas Bellinger 			 */
334e48354ceSNicholas Bellinger 			np->np_exports++;
335ee291e63SAndy Grover 			spin_unlock_bh(&np->np_thread_lock);
336e48354ceSNicholas Bellinger 			return np;
337e48354ceSNicholas Bellinger 		}
338ee291e63SAndy Grover 		spin_unlock_bh(&np->np_thread_lock);
339e48354ceSNicholas Bellinger 	}
340e48354ceSNicholas Bellinger 
341e48354ceSNicholas Bellinger 	return NULL;
342e48354ceSNicholas Bellinger }
343e48354ceSNicholas Bellinger 
344e48354ceSNicholas Bellinger struct iscsi_np *iscsit_add_np(
345e48354ceSNicholas Bellinger 	struct __kernel_sockaddr_storage *sockaddr,
346e48354ceSNicholas Bellinger 	char *ip_str,
347e48354ceSNicholas Bellinger 	int network_transport)
348e48354ceSNicholas Bellinger {
349e48354ceSNicholas Bellinger 	struct sockaddr_in *sock_in;
350e48354ceSNicholas Bellinger 	struct sockaddr_in6 *sock_in6;
351e48354ceSNicholas Bellinger 	struct iscsi_np *np;
352e48354ceSNicholas Bellinger 	int ret;
353ee291e63SAndy Grover 
354ee291e63SAndy Grover 	mutex_lock(&np_lock);
355ee291e63SAndy Grover 
356e48354ceSNicholas Bellinger 	/*
357e48354ceSNicholas Bellinger 	 * Locate the existing struct iscsi_np if already active..
358e48354ceSNicholas Bellinger 	 */
359e48354ceSNicholas Bellinger 	np = iscsit_get_np(sockaddr, network_transport);
360ee291e63SAndy Grover 	if (np) {
361ee291e63SAndy Grover 		mutex_unlock(&np_lock);
362e48354ceSNicholas Bellinger 		return np;
363ee291e63SAndy Grover 	}
364e48354ceSNicholas Bellinger 
365e48354ceSNicholas Bellinger 	np = kzalloc(sizeof(struct iscsi_np), GFP_KERNEL);
366e48354ceSNicholas Bellinger 	if (!np) {
367e48354ceSNicholas Bellinger 		pr_err("Unable to allocate memory for struct iscsi_np\n");
368ee291e63SAndy Grover 		mutex_unlock(&np_lock);
369e48354ceSNicholas Bellinger 		return ERR_PTR(-ENOMEM);
370e48354ceSNicholas Bellinger 	}
371e48354ceSNicholas Bellinger 
372e48354ceSNicholas Bellinger 	np->np_flags |= NPF_IP_NETWORK;
373e48354ceSNicholas Bellinger 	if (sockaddr->ss_family == AF_INET6) {
374e48354ceSNicholas Bellinger 		sock_in6 = (struct sockaddr_in6 *)sockaddr;
375e48354ceSNicholas Bellinger 		snprintf(np->np_ip, IPV6_ADDRESS_SPACE, "%s", ip_str);
376e48354ceSNicholas Bellinger 		np->np_port = ntohs(sock_in6->sin6_port);
377e48354ceSNicholas Bellinger 	} else {
378e48354ceSNicholas Bellinger 		sock_in = (struct sockaddr_in *)sockaddr;
379e48354ceSNicholas Bellinger 		sprintf(np->np_ip, "%s", ip_str);
380e48354ceSNicholas Bellinger 		np->np_port = ntohs(sock_in->sin_port);
381e48354ceSNicholas Bellinger 	}
382e48354ceSNicholas Bellinger 
383e48354ceSNicholas Bellinger 	np->np_network_transport = network_transport;
384e48354ceSNicholas Bellinger 	spin_lock_init(&np->np_thread_lock);
385e48354ceSNicholas Bellinger 	init_completion(&np->np_restart_comp);
386e48354ceSNicholas Bellinger 	INIT_LIST_HEAD(&np->np_list);
387e48354ceSNicholas Bellinger 
388e48354ceSNicholas Bellinger 	ret = iscsi_target_setup_login_socket(np, sockaddr);
389e48354ceSNicholas Bellinger 	if (ret != 0) {
390e48354ceSNicholas Bellinger 		kfree(np);
391ee291e63SAndy Grover 		mutex_unlock(&np_lock);
392e48354ceSNicholas Bellinger 		return ERR_PTR(ret);
393e48354ceSNicholas Bellinger 	}
394e48354ceSNicholas Bellinger 
395e48354ceSNicholas Bellinger 	np->np_thread = kthread_run(iscsi_target_login_thread, np, "iscsi_np");
396e48354ceSNicholas Bellinger 	if (IS_ERR(np->np_thread)) {
397e48354ceSNicholas Bellinger 		pr_err("Unable to create kthread: iscsi_np\n");
398e48354ceSNicholas Bellinger 		ret = PTR_ERR(np->np_thread);
399e48354ceSNicholas Bellinger 		kfree(np);
400ee291e63SAndy Grover 		mutex_unlock(&np_lock);
401e48354ceSNicholas Bellinger 		return ERR_PTR(ret);
402e48354ceSNicholas Bellinger 	}
403e48354ceSNicholas Bellinger 	/*
404e48354ceSNicholas Bellinger 	 * Increment the np_exports reference count now to prevent
405e48354ceSNicholas Bellinger 	 * iscsit_del_np() below from being run while a new call to
406e48354ceSNicholas Bellinger 	 * iscsi_tpg_add_network_portal() for a matching iscsi_np is
407e48354ceSNicholas Bellinger 	 * active.  We don't need to hold np->np_thread_lock at this
408e48354ceSNicholas Bellinger 	 * point because iscsi_np has not been added to g_np_list yet.
409e48354ceSNicholas Bellinger 	 */
410e48354ceSNicholas Bellinger 	np->np_exports = 1;
411ee291e63SAndy Grover 	np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
412e48354ceSNicholas Bellinger 
413e48354ceSNicholas Bellinger 	list_add_tail(&np->np_list, &g_np_list);
414ee291e63SAndy Grover 	mutex_unlock(&np_lock);
415e48354ceSNicholas Bellinger 
416e48354ceSNicholas Bellinger 	pr_debug("CORE[0] - Added Network Portal: %s:%hu on %s\n",
417baa4d64bSNicholas Bellinger 		np->np_ip, np->np_port, np->np_transport->name);
418e48354ceSNicholas Bellinger 
419e48354ceSNicholas Bellinger 	return np;
420e48354ceSNicholas Bellinger }
421e48354ceSNicholas Bellinger 
422e48354ceSNicholas Bellinger int iscsit_reset_np_thread(
423e48354ceSNicholas Bellinger 	struct iscsi_np *np,
424e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np,
425a91eb7d9SNicholas Bellinger 	struct iscsi_portal_group *tpg,
426a91eb7d9SNicholas Bellinger 	bool shutdown)
427e48354ceSNicholas Bellinger {
428e48354ceSNicholas Bellinger 	spin_lock_bh(&np->np_thread_lock);
429e48354ceSNicholas Bellinger 	if (np->np_thread_state == ISCSI_NP_THREAD_INACTIVE) {
430e48354ceSNicholas Bellinger 		spin_unlock_bh(&np->np_thread_lock);
431e48354ceSNicholas Bellinger 		return 0;
432e48354ceSNicholas Bellinger 	}
433e48354ceSNicholas Bellinger 	np->np_thread_state = ISCSI_NP_THREAD_RESET;
434e48354ceSNicholas Bellinger 
435e48354ceSNicholas Bellinger 	if (np->np_thread) {
436e48354ceSNicholas Bellinger 		spin_unlock_bh(&np->np_thread_lock);
437e48354ceSNicholas Bellinger 		send_sig(SIGINT, np->np_thread, 1);
438e48354ceSNicholas Bellinger 		wait_for_completion(&np->np_restart_comp);
439e48354ceSNicholas Bellinger 		spin_lock_bh(&np->np_thread_lock);
440e48354ceSNicholas Bellinger 	}
441e48354ceSNicholas Bellinger 	spin_unlock_bh(&np->np_thread_lock);
442e48354ceSNicholas Bellinger 
443a91eb7d9SNicholas Bellinger 	if (tpg_np && shutdown) {
444a91eb7d9SNicholas Bellinger 		kref_put(&tpg_np->tpg_np_kref, iscsit_login_kref_put);
445a91eb7d9SNicholas Bellinger 
446a91eb7d9SNicholas Bellinger 		wait_for_completion(&tpg_np->tpg_np_comp);
447a91eb7d9SNicholas Bellinger 	}
448a91eb7d9SNicholas Bellinger 
449e48354ceSNicholas Bellinger 	return 0;
450e48354ceSNicholas Bellinger }
451e48354ceSNicholas Bellinger 
452baa4d64bSNicholas Bellinger static void iscsit_free_np(struct iscsi_np *np)
453e48354ceSNicholas Bellinger {
454bf6932f4SAl Viro 	if (np->np_socket)
455e48354ceSNicholas Bellinger 		sock_release(np->np_socket);
456e48354ceSNicholas Bellinger }
457e48354ceSNicholas Bellinger 
458e48354ceSNicholas Bellinger int iscsit_del_np(struct iscsi_np *np)
459e48354ceSNicholas Bellinger {
460e48354ceSNicholas Bellinger 	spin_lock_bh(&np->np_thread_lock);
461e48354ceSNicholas Bellinger 	np->np_exports--;
462e48354ceSNicholas Bellinger 	if (np->np_exports) {
4632363d196SNicholas Bellinger 		np->enabled = true;
464e48354ceSNicholas Bellinger 		spin_unlock_bh(&np->np_thread_lock);
465e48354ceSNicholas Bellinger 		return 0;
466e48354ceSNicholas Bellinger 	}
467e48354ceSNicholas Bellinger 	np->np_thread_state = ISCSI_NP_THREAD_SHUTDOWN;
468e48354ceSNicholas Bellinger 	spin_unlock_bh(&np->np_thread_lock);
469e48354ceSNicholas Bellinger 
470e48354ceSNicholas Bellinger 	if (np->np_thread) {
471e48354ceSNicholas Bellinger 		/*
472e48354ceSNicholas Bellinger 		 * We need to send the signal to wakeup Linux/Net
473e48354ceSNicholas Bellinger 		 * which may be sleeping in sock_accept()..
474e48354ceSNicholas Bellinger 		 */
475e48354ceSNicholas Bellinger 		send_sig(SIGINT, np->np_thread, 1);
476e48354ceSNicholas Bellinger 		kthread_stop(np->np_thread);
477db6077fdSNicholas Bellinger 		np->np_thread = NULL;
478e48354ceSNicholas Bellinger 	}
479baa4d64bSNicholas Bellinger 
480baa4d64bSNicholas Bellinger 	np->np_transport->iscsit_free_np(np);
481e48354ceSNicholas Bellinger 
482ee291e63SAndy Grover 	mutex_lock(&np_lock);
483e48354ceSNicholas Bellinger 	list_del(&np->np_list);
484ee291e63SAndy Grover 	mutex_unlock(&np_lock);
485e48354ceSNicholas Bellinger 
486e48354ceSNicholas Bellinger 	pr_debug("CORE[0] - Removed Network Portal: %s:%hu on %s\n",
487baa4d64bSNicholas Bellinger 		np->np_ip, np->np_port, np->np_transport->name);
488e48354ceSNicholas Bellinger 
489baa4d64bSNicholas Bellinger 	iscsit_put_transport(np->np_transport);
490e48354ceSNicholas Bellinger 	kfree(np);
491e48354ceSNicholas Bellinger 	return 0;
492e48354ceSNicholas Bellinger }
493e48354ceSNicholas Bellinger 
4942ec5a8c1SNicholas Bellinger static int iscsit_immediate_queue(struct iscsi_conn *, struct iscsi_cmd *, int);
4952ec5a8c1SNicholas Bellinger static int iscsit_response_queue(struct iscsi_conn *, struct iscsi_cmd *, int);
4962ec5a8c1SNicholas Bellinger 
4972ec5a8c1SNicholas Bellinger static int iscsit_queue_rsp(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
4982ec5a8c1SNicholas Bellinger {
4992ec5a8c1SNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
5002ec5a8c1SNicholas Bellinger 	return 0;
5012ec5a8c1SNicholas Bellinger }
5022ec5a8c1SNicholas Bellinger 
503131e6abcSNicholas Bellinger static void iscsit_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
504131e6abcSNicholas Bellinger {
505131e6abcSNicholas Bellinger 	bool scsi_cmd = (cmd->iscsi_opcode == ISCSI_OP_SCSI_CMD);
506131e6abcSNicholas Bellinger 
507131e6abcSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
508131e6abcSNicholas Bellinger 	if (!list_empty(&cmd->i_conn_node))
509131e6abcSNicholas Bellinger 		list_del_init(&cmd->i_conn_node);
510131e6abcSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
511131e6abcSNicholas Bellinger 
512131e6abcSNicholas Bellinger 	__iscsit_free_cmd(cmd, scsi_cmd, true);
513131e6abcSNicholas Bellinger }
514131e6abcSNicholas Bellinger 
515e70beee7SNicholas Bellinger static enum target_prot_op iscsit_get_sup_prot_ops(struct iscsi_conn *conn)
516e70beee7SNicholas Bellinger {
517e70beee7SNicholas Bellinger 	return TARGET_PROT_NORMAL;
518e70beee7SNicholas Bellinger }
519e70beee7SNicholas Bellinger 
520baa4d64bSNicholas Bellinger static struct iscsit_transport iscsi_target_transport = {
521baa4d64bSNicholas Bellinger 	.name			= "iSCSI/TCP",
522baa4d64bSNicholas Bellinger 	.transport_type		= ISCSI_TCP,
523baa4d64bSNicholas Bellinger 	.owner			= NULL,
524baa4d64bSNicholas Bellinger 	.iscsit_setup_np	= iscsit_setup_np,
525baa4d64bSNicholas Bellinger 	.iscsit_accept_np	= iscsit_accept_np,
526baa4d64bSNicholas Bellinger 	.iscsit_free_np		= iscsit_free_np,
527baa4d64bSNicholas Bellinger 	.iscsit_get_login_rx	= iscsit_get_login_rx,
528baa4d64bSNicholas Bellinger 	.iscsit_put_login_tx	= iscsit_put_login_tx,
5293e1c81a9SNicholas Bellinger 	.iscsit_get_dataout	= iscsit_build_r2ts_for_cmd,
5302ec5a8c1SNicholas Bellinger 	.iscsit_immediate_queue	= iscsit_immediate_queue,
5312ec5a8c1SNicholas Bellinger 	.iscsit_response_queue	= iscsit_response_queue,
5322ec5a8c1SNicholas Bellinger 	.iscsit_queue_data_in	= iscsit_queue_rsp,
5332ec5a8c1SNicholas Bellinger 	.iscsit_queue_status	= iscsit_queue_rsp,
534131e6abcSNicholas Bellinger 	.iscsit_aborted_task	= iscsit_aborted_task,
535e70beee7SNicholas Bellinger 	.iscsit_get_sup_prot_ops = iscsit_get_sup_prot_ops,
536baa4d64bSNicholas Bellinger };
537baa4d64bSNicholas Bellinger 
538e48354ceSNicholas Bellinger static int __init iscsi_target_init_module(void)
539e48354ceSNicholas Bellinger {
540e48354ceSNicholas Bellinger 	int ret = 0;
541e48354ceSNicholas Bellinger 
542e48354ceSNicholas Bellinger 	pr_debug("iSCSI-Target "ISCSIT_VERSION"\n");
543e48354ceSNicholas Bellinger 
544e48354ceSNicholas Bellinger 	iscsit_global = kzalloc(sizeof(struct iscsit_global), GFP_KERNEL);
545e48354ceSNicholas Bellinger 	if (!iscsit_global) {
546e48354ceSNicholas Bellinger 		pr_err("Unable to allocate memory for iscsit_global\n");
547e48354ceSNicholas Bellinger 		return -1;
548e48354ceSNicholas Bellinger 	}
549e48354ceSNicholas Bellinger 	mutex_init(&auth_id_lock);
550e48354ceSNicholas Bellinger 	spin_lock_init(&sess_idr_lock);
551e48354ceSNicholas Bellinger 	idr_init(&tiqn_idr);
552e48354ceSNicholas Bellinger 	idr_init(&sess_idr);
553e48354ceSNicholas Bellinger 
554e48354ceSNicholas Bellinger 	ret = iscsi_target_register_configfs();
555e48354ceSNicholas Bellinger 	if (ret < 0)
556e48354ceSNicholas Bellinger 		goto out;
557e48354ceSNicholas Bellinger 
558e48354ceSNicholas Bellinger 	ret = iscsi_thread_set_init();
559e48354ceSNicholas Bellinger 	if (ret < 0)
560e48354ceSNicholas Bellinger 		goto configfs_out;
561e48354ceSNicholas Bellinger 
562e48354ceSNicholas Bellinger 	if (iscsi_allocate_thread_sets(TARGET_THREAD_SET_COUNT) !=
563e48354ceSNicholas Bellinger 			TARGET_THREAD_SET_COUNT) {
564e48354ceSNicholas Bellinger 		pr_err("iscsi_allocate_thread_sets() returned"
565e48354ceSNicholas Bellinger 			" unexpected value!\n");
566e48354ceSNicholas Bellinger 		goto ts_out1;
567e48354ceSNicholas Bellinger 	}
568e48354ceSNicholas Bellinger 
569e48354ceSNicholas Bellinger 	lio_qr_cache = kmem_cache_create("lio_qr_cache",
570e48354ceSNicholas Bellinger 			sizeof(struct iscsi_queue_req),
571e48354ceSNicholas Bellinger 			__alignof__(struct iscsi_queue_req), 0, NULL);
572e48354ceSNicholas Bellinger 	if (!lio_qr_cache) {
573e48354ceSNicholas Bellinger 		pr_err("nable to kmem_cache_create() for"
574e48354ceSNicholas Bellinger 				" lio_qr_cache\n");
575d703ce2fSNicholas Bellinger 		goto ts_out2;
576e48354ceSNicholas Bellinger 	}
577e48354ceSNicholas Bellinger 
578e48354ceSNicholas Bellinger 	lio_dr_cache = kmem_cache_create("lio_dr_cache",
579e48354ceSNicholas Bellinger 			sizeof(struct iscsi_datain_req),
580e48354ceSNicholas Bellinger 			__alignof__(struct iscsi_datain_req), 0, NULL);
581e48354ceSNicholas Bellinger 	if (!lio_dr_cache) {
582e48354ceSNicholas Bellinger 		pr_err("Unable to kmem_cache_create() for"
583e48354ceSNicholas Bellinger 				" lio_dr_cache\n");
584e48354ceSNicholas Bellinger 		goto qr_out;
585e48354ceSNicholas Bellinger 	}
586e48354ceSNicholas Bellinger 
587e48354ceSNicholas Bellinger 	lio_ooo_cache = kmem_cache_create("lio_ooo_cache",
588e48354ceSNicholas Bellinger 			sizeof(struct iscsi_ooo_cmdsn),
589e48354ceSNicholas Bellinger 			__alignof__(struct iscsi_ooo_cmdsn), 0, NULL);
590e48354ceSNicholas Bellinger 	if (!lio_ooo_cache) {
591e48354ceSNicholas Bellinger 		pr_err("Unable to kmem_cache_create() for"
592e48354ceSNicholas Bellinger 				" lio_ooo_cache\n");
593e48354ceSNicholas Bellinger 		goto dr_out;
594e48354ceSNicholas Bellinger 	}
595e48354ceSNicholas Bellinger 
596e48354ceSNicholas Bellinger 	lio_r2t_cache = kmem_cache_create("lio_r2t_cache",
597e48354ceSNicholas Bellinger 			sizeof(struct iscsi_r2t), __alignof__(struct iscsi_r2t),
598e48354ceSNicholas Bellinger 			0, NULL);
599e48354ceSNicholas Bellinger 	if (!lio_r2t_cache) {
600e48354ceSNicholas Bellinger 		pr_err("Unable to kmem_cache_create() for"
601e48354ceSNicholas Bellinger 				" lio_r2t_cache\n");
602e48354ceSNicholas Bellinger 		goto ooo_out;
603e48354ceSNicholas Bellinger 	}
604e48354ceSNicholas Bellinger 
605baa4d64bSNicholas Bellinger 	iscsit_register_transport(&iscsi_target_transport);
606baa4d64bSNicholas Bellinger 
607e48354ceSNicholas Bellinger 	if (iscsit_load_discovery_tpg() < 0)
608e48354ceSNicholas Bellinger 		goto r2t_out;
609e48354ceSNicholas Bellinger 
610e48354ceSNicholas Bellinger 	return ret;
611e48354ceSNicholas Bellinger r2t_out:
6127f2c53bbSLino Sanfilippo 	iscsit_unregister_transport(&iscsi_target_transport);
613e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_r2t_cache);
614e48354ceSNicholas Bellinger ooo_out:
615e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_ooo_cache);
616e48354ceSNicholas Bellinger dr_out:
617e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_dr_cache);
618e48354ceSNicholas Bellinger qr_out:
619e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_qr_cache);
620e48354ceSNicholas Bellinger ts_out2:
621e48354ceSNicholas Bellinger 	iscsi_deallocate_thread_sets();
622e48354ceSNicholas Bellinger ts_out1:
623e48354ceSNicholas Bellinger 	iscsi_thread_set_free();
624e48354ceSNicholas Bellinger configfs_out:
625e48354ceSNicholas Bellinger 	iscsi_target_deregister_configfs();
626e48354ceSNicholas Bellinger out:
627e48354ceSNicholas Bellinger 	kfree(iscsit_global);
628e48354ceSNicholas Bellinger 	return -ENOMEM;
629e48354ceSNicholas Bellinger }
630e48354ceSNicholas Bellinger 
631e48354ceSNicholas Bellinger static void __exit iscsi_target_cleanup_module(void)
632e48354ceSNicholas Bellinger {
633e48354ceSNicholas Bellinger 	iscsi_deallocate_thread_sets();
634e48354ceSNicholas Bellinger 	iscsi_thread_set_free();
635e48354ceSNicholas Bellinger 	iscsit_release_discovery_tpg();
636baa4d64bSNicholas Bellinger 	iscsit_unregister_transport(&iscsi_target_transport);
637e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_qr_cache);
638e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_dr_cache);
639e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_ooo_cache);
640e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_r2t_cache);
641e48354ceSNicholas Bellinger 
642e48354ceSNicholas Bellinger 	iscsi_target_deregister_configfs();
643e48354ceSNicholas Bellinger 
644e48354ceSNicholas Bellinger 	kfree(iscsit_global);
645e48354ceSNicholas Bellinger }
646e48354ceSNicholas Bellinger 
6478b1e1244SAndy Grover static int iscsit_add_reject(
648ba159914SNicholas Bellinger 	struct iscsi_conn *conn,
649e48354ceSNicholas Bellinger 	u8 reason,
650ba159914SNicholas Bellinger 	unsigned char *buf)
651e48354ceSNicholas Bellinger {
652e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd;
653e48354ceSNicholas Bellinger 
654676687c6SNicholas Bellinger 	cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
655e48354ceSNicholas Bellinger 	if (!cmd)
656e48354ceSNicholas Bellinger 		return -1;
657e48354ceSNicholas Bellinger 
658e48354ceSNicholas Bellinger 	cmd->iscsi_opcode = ISCSI_OP_REJECT;
659ba159914SNicholas Bellinger 	cmd->reject_reason = reason;
660e48354ceSNicholas Bellinger 
6611c3d5794SThomas Meyer 	cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL);
662e48354ceSNicholas Bellinger 	if (!cmd->buf_ptr) {
663e48354ceSNicholas Bellinger 		pr_err("Unable to allocate memory for cmd->buf_ptr\n");
664aafc9d15SNicholas Bellinger 		iscsit_free_cmd(cmd, false);
665e48354ceSNicholas Bellinger 		return -1;
666e48354ceSNicholas Bellinger 	}
667e48354ceSNicholas Bellinger 
668e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
6692fbb471eSAndy Grover 	list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
670e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
671e48354ceSNicholas Bellinger 
672e48354ceSNicholas Bellinger 	cmd->i_state = ISTATE_SEND_REJECT;
673e48354ceSNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
674e48354ceSNicholas Bellinger 
675e48354ceSNicholas Bellinger 	return -1;
676e48354ceSNicholas Bellinger }
677e48354ceSNicholas Bellinger 
678ba159914SNicholas Bellinger static int iscsit_add_reject_from_cmd(
679ba159914SNicholas Bellinger 	struct iscsi_cmd *cmd,
680e48354ceSNicholas Bellinger 	u8 reason,
681ba159914SNicholas Bellinger 	bool add_to_conn,
682ba159914SNicholas Bellinger 	unsigned char *buf)
683e48354ceSNicholas Bellinger {
684e48354ceSNicholas Bellinger 	struct iscsi_conn *conn;
685e48354ceSNicholas Bellinger 
686e48354ceSNicholas Bellinger 	if (!cmd->conn) {
687e48354ceSNicholas Bellinger 		pr_err("cmd->conn is NULL for ITT: 0x%08x\n",
688e48354ceSNicholas Bellinger 				cmd->init_task_tag);
689e48354ceSNicholas Bellinger 		return -1;
690e48354ceSNicholas Bellinger 	}
691e48354ceSNicholas Bellinger 	conn = cmd->conn;
692e48354ceSNicholas Bellinger 
693e48354ceSNicholas Bellinger 	cmd->iscsi_opcode = ISCSI_OP_REJECT;
694ba159914SNicholas Bellinger 	cmd->reject_reason = reason;
695e48354ceSNicholas Bellinger 
6961c3d5794SThomas Meyer 	cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL);
697e48354ceSNicholas Bellinger 	if (!cmd->buf_ptr) {
698e48354ceSNicholas Bellinger 		pr_err("Unable to allocate memory for cmd->buf_ptr\n");
699aafc9d15SNicholas Bellinger 		iscsit_free_cmd(cmd, false);
700e48354ceSNicholas Bellinger 		return -1;
701e48354ceSNicholas Bellinger 	}
702e48354ceSNicholas Bellinger 
703e48354ceSNicholas Bellinger 	if (add_to_conn) {
704e48354ceSNicholas Bellinger 		spin_lock_bh(&conn->cmd_lock);
7052fbb471eSAndy Grover 		list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
706e48354ceSNicholas Bellinger 		spin_unlock_bh(&conn->cmd_lock);
707e48354ceSNicholas Bellinger 	}
708e48354ceSNicholas Bellinger 
709e48354ceSNicholas Bellinger 	cmd->i_state = ISTATE_SEND_REJECT;
710e48354ceSNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
7113e1c81a9SNicholas Bellinger 	/*
7123e1c81a9SNicholas Bellinger 	 * Perform the kref_put now if se_cmd has already been setup by
7133e1c81a9SNicholas Bellinger 	 * scsit_setup_scsi_cmd()
7143e1c81a9SNicholas Bellinger 	 */
7153e1c81a9SNicholas Bellinger 	if (cmd->se_cmd.se_tfo != NULL) {
7163e1c81a9SNicholas Bellinger 		pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n");
7173e1c81a9SNicholas Bellinger 		target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
7183e1c81a9SNicholas Bellinger 	}
719e48354ceSNicholas Bellinger 	return -1;
720e48354ceSNicholas Bellinger }
721ba159914SNicholas Bellinger 
722ba159914SNicholas Bellinger static int iscsit_add_reject_cmd(struct iscsi_cmd *cmd, u8 reason,
723ba159914SNicholas Bellinger 				 unsigned char *buf)
724ba159914SNicholas Bellinger {
725ba159914SNicholas Bellinger 	return iscsit_add_reject_from_cmd(cmd, reason, true, buf);
726ba159914SNicholas Bellinger }
727ba159914SNicholas Bellinger 
728ba159914SNicholas Bellinger int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8 reason, unsigned char *buf)
729ba159914SNicholas Bellinger {
730ba159914SNicholas Bellinger 	return iscsit_add_reject_from_cmd(cmd, reason, false, buf);
731ba159914SNicholas Bellinger }
732e48354ceSNicholas Bellinger 
733e48354ceSNicholas Bellinger /*
734e48354ceSNicholas Bellinger  * Map some portion of the allocated scatterlist to an iovec, suitable for
735bfb79eacSAndy Grover  * kernel sockets to copy data in/out.
736e48354ceSNicholas Bellinger  */
737e48354ceSNicholas Bellinger static int iscsit_map_iovec(
738e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd,
739e48354ceSNicholas Bellinger 	struct kvec *iov,
740e48354ceSNicholas Bellinger 	u32 data_offset,
741e48354ceSNicholas Bellinger 	u32 data_length)
742e48354ceSNicholas Bellinger {
743e48354ceSNicholas Bellinger 	u32 i = 0;
744e48354ceSNicholas Bellinger 	struct scatterlist *sg;
745e48354ceSNicholas Bellinger 	unsigned int page_off;
746e48354ceSNicholas Bellinger 
747e48354ceSNicholas Bellinger 	/*
748bfb79eacSAndy Grover 	 * We know each entry in t_data_sg contains a page.
749e48354ceSNicholas Bellinger 	 */
750bfb79eacSAndy Grover 	sg = &cmd->se_cmd.t_data_sg[data_offset / PAGE_SIZE];
751e48354ceSNicholas Bellinger 	page_off = (data_offset % PAGE_SIZE);
752e48354ceSNicholas Bellinger 
753e48354ceSNicholas Bellinger 	cmd->first_data_sg = sg;
754e48354ceSNicholas Bellinger 	cmd->first_data_sg_off = page_off;
755e48354ceSNicholas Bellinger 
756e48354ceSNicholas Bellinger 	while (data_length) {
757e48354ceSNicholas Bellinger 		u32 cur_len = min_t(u32, data_length, sg->length - page_off);
758e48354ceSNicholas Bellinger 
759e48354ceSNicholas Bellinger 		iov[i].iov_base = kmap(sg_page(sg)) + sg->offset + page_off;
760e48354ceSNicholas Bellinger 		iov[i].iov_len = cur_len;
761e48354ceSNicholas Bellinger 
762e48354ceSNicholas Bellinger 		data_length -= cur_len;
763e48354ceSNicholas Bellinger 		page_off = 0;
764e48354ceSNicholas Bellinger 		sg = sg_next(sg);
765e48354ceSNicholas Bellinger 		i++;
766e48354ceSNicholas Bellinger 	}
767e48354ceSNicholas Bellinger 
768e48354ceSNicholas Bellinger 	cmd->kmapped_nents = i;
769e48354ceSNicholas Bellinger 
770e48354ceSNicholas Bellinger 	return i;
771e48354ceSNicholas Bellinger }
772e48354ceSNicholas Bellinger 
773e48354ceSNicholas Bellinger static void iscsit_unmap_iovec(struct iscsi_cmd *cmd)
774e48354ceSNicholas Bellinger {
775e48354ceSNicholas Bellinger 	u32 i;
776e48354ceSNicholas Bellinger 	struct scatterlist *sg;
777e48354ceSNicholas Bellinger 
778e48354ceSNicholas Bellinger 	sg = cmd->first_data_sg;
779e48354ceSNicholas Bellinger 
780e48354ceSNicholas Bellinger 	for (i = 0; i < cmd->kmapped_nents; i++)
781e48354ceSNicholas Bellinger 		kunmap(sg_page(&sg[i]));
782e48354ceSNicholas Bellinger }
783e48354ceSNicholas Bellinger 
784e48354ceSNicholas Bellinger static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn)
785e48354ceSNicholas Bellinger {
786f56cbbb4SNicholas Bellinger 	LIST_HEAD(ack_list);
787f56cbbb4SNicholas Bellinger 	struct iscsi_cmd *cmd, *cmd_p;
788e48354ceSNicholas Bellinger 
789e48354ceSNicholas Bellinger 	conn->exp_statsn = exp_statsn;
790e48354ceSNicholas Bellinger 
7913e1c81a9SNicholas Bellinger 	if (conn->sess->sess_ops->RDMAExtensions)
7923e1c81a9SNicholas Bellinger 		return;
7933e1c81a9SNicholas Bellinger 
794e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
795f56cbbb4SNicholas Bellinger 	list_for_each_entry_safe(cmd, cmd_p, &conn->conn_cmd_list, i_conn_node) {
796e48354ceSNicholas Bellinger 		spin_lock(&cmd->istate_lock);
797e48354ceSNicholas Bellinger 		if ((cmd->i_state == ISTATE_SENT_STATUS) &&
79864c13330SSteve Hodgson 		    iscsi_sna_lt(cmd->stat_sn, exp_statsn)) {
799e48354ceSNicholas Bellinger 			cmd->i_state = ISTATE_REMOVE;
800e48354ceSNicholas Bellinger 			spin_unlock(&cmd->istate_lock);
801f56cbbb4SNicholas Bellinger 			list_move_tail(&cmd->i_conn_node, &ack_list);
802e48354ceSNicholas Bellinger 			continue;
803e48354ceSNicholas Bellinger 		}
804e48354ceSNicholas Bellinger 		spin_unlock(&cmd->istate_lock);
805e48354ceSNicholas Bellinger 	}
806e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
807f56cbbb4SNicholas Bellinger 
808f56cbbb4SNicholas Bellinger 	list_for_each_entry_safe(cmd, cmd_p, &ack_list, i_conn_node) {
8095159d763SNicholas Bellinger 		list_del_init(&cmd->i_conn_node);
810f56cbbb4SNicholas Bellinger 		iscsit_free_cmd(cmd, false);
811f56cbbb4SNicholas Bellinger 	}
812e48354ceSNicholas Bellinger }
813e48354ceSNicholas Bellinger 
814e48354ceSNicholas Bellinger static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd)
815e48354ceSNicholas Bellinger {
816f80e8ed3SNicholas Bellinger 	u32 iov_count = max(1UL, DIV_ROUND_UP(cmd->se_cmd.data_length, PAGE_SIZE));
817e48354ceSNicholas Bellinger 
818c0427f15SChristoph Hellwig 	iov_count += ISCSI_IOV_DATA_BUFFER;
819e48354ceSNicholas Bellinger 
820e48354ceSNicholas Bellinger 	cmd->iov_data = kzalloc(iov_count * sizeof(struct kvec), GFP_KERNEL);
821e48354ceSNicholas Bellinger 	if (!cmd->iov_data) {
822e48354ceSNicholas Bellinger 		pr_err("Unable to allocate cmd->iov_data\n");
823e48354ceSNicholas Bellinger 		return -ENOMEM;
824e48354ceSNicholas Bellinger 	}
825e48354ceSNicholas Bellinger 
826e48354ceSNicholas Bellinger 	cmd->orig_iov_data_count = iov_count;
827e48354ceSNicholas Bellinger 	return 0;
828e48354ceSNicholas Bellinger }
829e48354ceSNicholas Bellinger 
8303e1c81a9SNicholas Bellinger int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
831e48354ceSNicholas Bellinger 			  unsigned char *buf)
832e48354ceSNicholas Bellinger {
8333e1c81a9SNicholas Bellinger 	int data_direction, payload_length;
834e48354ceSNicholas Bellinger 	struct iscsi_scsi_req *hdr;
835d28b1169SAndy Grover 	int iscsi_task_attr;
836d28b1169SAndy Grover 	int sam_task_attr;
837e48354ceSNicholas Bellinger 
83804f3b31bSNicholas Bellinger 	atomic_long_inc(&conn->sess->cmd_pdus);
839e48354ceSNicholas Bellinger 
840e48354ceSNicholas Bellinger 	hdr			= (struct iscsi_scsi_req *) buf;
841e48354ceSNicholas Bellinger 	payload_length		= ntoh24(hdr->dlength);
842e48354ceSNicholas Bellinger 
843e48354ceSNicholas Bellinger 	/* FIXME; Add checks for AdditionalHeaderSegment */
844e48354ceSNicholas Bellinger 
845e48354ceSNicholas Bellinger 	if (!(hdr->flags & ISCSI_FLAG_CMD_WRITE) &&
846e48354ceSNicholas Bellinger 	    !(hdr->flags & ISCSI_FLAG_CMD_FINAL)) {
847e48354ceSNicholas Bellinger 		pr_err("ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL"
848e48354ceSNicholas Bellinger 				" not set. Bad iSCSI Initiator.\n");
849ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
850ba159914SNicholas Bellinger 					     ISCSI_REASON_BOOKMARK_INVALID, buf);
851e48354ceSNicholas Bellinger 	}
852e48354ceSNicholas Bellinger 
853e48354ceSNicholas Bellinger 	if (((hdr->flags & ISCSI_FLAG_CMD_READ) ||
854e48354ceSNicholas Bellinger 	     (hdr->flags & ISCSI_FLAG_CMD_WRITE)) && !hdr->data_length) {
855e48354ceSNicholas Bellinger 		/*
8564454b66cSNicholas Bellinger 		 * From RFC-3720 Section 10.3.1:
8574454b66cSNicholas Bellinger 		 *
8584454b66cSNicholas Bellinger 		 * "Either or both of R and W MAY be 1 when either the
8594454b66cSNicholas Bellinger 		 *  Expected Data Transfer Length and/or Bidirectional Read
8604454b66cSNicholas Bellinger 		 *  Expected Data Transfer Length are 0"
8614454b66cSNicholas Bellinger 		 *
8624454b66cSNicholas Bellinger 		 * For this case, go ahead and clear the unnecssary bits
8634454b66cSNicholas Bellinger 		 * to avoid any confusion with ->data_direction.
864e48354ceSNicholas Bellinger 		 */
865e48354ceSNicholas Bellinger 		hdr->flags &= ~ISCSI_FLAG_CMD_READ;
866e48354ceSNicholas Bellinger 		hdr->flags &= ~ISCSI_FLAG_CMD_WRITE;
867e48354ceSNicholas Bellinger 
8684454b66cSNicholas Bellinger 		pr_warn("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE"
869e48354ceSNicholas Bellinger 			" set when Expected Data Transfer Length is 0 for"
8704454b66cSNicholas Bellinger 			" CDB: 0x%02x, Fixing up flags\n", hdr->cdb[0]);
871e48354ceSNicholas Bellinger 	}
872e48354ceSNicholas Bellinger 
873e48354ceSNicholas Bellinger 	if (!(hdr->flags & ISCSI_FLAG_CMD_READ) &&
874e48354ceSNicholas Bellinger 	    !(hdr->flags & ISCSI_FLAG_CMD_WRITE) && (hdr->data_length != 0)) {
875e48354ceSNicholas Bellinger 		pr_err("ISCSI_FLAG_CMD_READ and/or ISCSI_FLAG_CMD_WRITE"
876e48354ceSNicholas Bellinger 			" MUST be set if Expected Data Transfer Length is not 0."
877e48354ceSNicholas Bellinger 			" Bad iSCSI Initiator\n");
878ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
879ba159914SNicholas Bellinger 					     ISCSI_REASON_BOOKMARK_INVALID, buf);
880e48354ceSNicholas Bellinger 	}
881e48354ceSNicholas Bellinger 
882e48354ceSNicholas Bellinger 	if ((hdr->flags & ISCSI_FLAG_CMD_READ) &&
883e48354ceSNicholas Bellinger 	    (hdr->flags & ISCSI_FLAG_CMD_WRITE)) {
884e48354ceSNicholas Bellinger 		pr_err("Bidirectional operations not supported!\n");
885ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
886ba159914SNicholas Bellinger 					     ISCSI_REASON_BOOKMARK_INVALID, buf);
887e48354ceSNicholas Bellinger 	}
888e48354ceSNicholas Bellinger 
889e48354ceSNicholas Bellinger 	if (hdr->opcode & ISCSI_OP_IMMEDIATE) {
890e48354ceSNicholas Bellinger 		pr_err("Illegally set Immediate Bit in iSCSI Initiator"
891e48354ceSNicholas Bellinger 				" Scsi Command PDU.\n");
892ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
893ba159914SNicholas Bellinger 					     ISCSI_REASON_BOOKMARK_INVALID, buf);
894e48354ceSNicholas Bellinger 	}
895e48354ceSNicholas Bellinger 
896e48354ceSNicholas Bellinger 	if (payload_length && !conn->sess->sess_ops->ImmediateData) {
897e48354ceSNicholas Bellinger 		pr_err("ImmediateData=No but DataSegmentLength=%u,"
898e48354ceSNicholas Bellinger 			" protocol error.\n", payload_length);
899ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
900ba159914SNicholas Bellinger 					     ISCSI_REASON_PROTOCOL_ERROR, buf);
901e48354ceSNicholas Bellinger 	}
902e48354ceSNicholas Bellinger 
90350e5c87dSChristoph Hellwig 	if ((be32_to_cpu(hdr->data_length) == payload_length) &&
904e48354ceSNicholas Bellinger 	    (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) {
905e48354ceSNicholas Bellinger 		pr_err("Expected Data Transfer Length and Length of"
906e48354ceSNicholas Bellinger 			" Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL"
907e48354ceSNicholas Bellinger 			" bit is not set protocol error\n");
908ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
909ba159914SNicholas Bellinger 					     ISCSI_REASON_PROTOCOL_ERROR, buf);
910e48354ceSNicholas Bellinger 	}
911e48354ceSNicholas Bellinger 
91250e5c87dSChristoph Hellwig 	if (payload_length > be32_to_cpu(hdr->data_length)) {
913e48354ceSNicholas Bellinger 		pr_err("DataSegmentLength: %u is greater than"
914e48354ceSNicholas Bellinger 			" EDTL: %u, protocol error.\n", payload_length,
915e48354ceSNicholas Bellinger 				hdr->data_length);
916ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
917ba159914SNicholas Bellinger 					     ISCSI_REASON_PROTOCOL_ERROR, buf);
918e48354ceSNicholas Bellinger 	}
919e48354ceSNicholas Bellinger 
92021f5aa7eSNicholas Bellinger 	if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
921e48354ceSNicholas Bellinger 		pr_err("DataSegmentLength: %u is greater than"
92221f5aa7eSNicholas Bellinger 			" MaxXmitDataSegmentLength: %u, protocol error.\n",
92321f5aa7eSNicholas Bellinger 			payload_length, conn->conn_ops->MaxXmitDataSegmentLength);
924ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
925ba159914SNicholas Bellinger 					     ISCSI_REASON_PROTOCOL_ERROR, buf);
926e48354ceSNicholas Bellinger 	}
927e48354ceSNicholas Bellinger 
928e48354ceSNicholas Bellinger 	if (payload_length > conn->sess->sess_ops->FirstBurstLength) {
929e48354ceSNicholas Bellinger 		pr_err("DataSegmentLength: %u is greater than"
930e48354ceSNicholas Bellinger 			" FirstBurstLength: %u, protocol error.\n",
931e48354ceSNicholas Bellinger 			payload_length, conn->sess->sess_ops->FirstBurstLength);
932ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
933ba159914SNicholas Bellinger 					     ISCSI_REASON_BOOKMARK_INVALID, buf);
934e48354ceSNicholas Bellinger 	}
935e48354ceSNicholas Bellinger 
936e48354ceSNicholas Bellinger 	data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE :
937e48354ceSNicholas Bellinger 			 (hdr->flags & ISCSI_FLAG_CMD_READ) ? DMA_FROM_DEVICE :
938e48354ceSNicholas Bellinger 			  DMA_NONE;
939e48354ceSNicholas Bellinger 
940d28b1169SAndy Grover 	cmd->data_direction = data_direction;
941d28b1169SAndy Grover 	iscsi_task_attr = hdr->flags & ISCSI_FLAG_CMD_ATTR_MASK;
942d28b1169SAndy Grover 	/*
943d28b1169SAndy Grover 	 * Figure out the SAM Task Attribute for the incoming SCSI CDB
944d28b1169SAndy Grover 	 */
945d28b1169SAndy Grover 	if ((iscsi_task_attr == ISCSI_ATTR_UNTAGGED) ||
946d28b1169SAndy Grover 	    (iscsi_task_attr == ISCSI_ATTR_SIMPLE))
94768d81f40SChristoph Hellwig 		sam_task_attr = TCM_SIMPLE_TAG;
948d28b1169SAndy Grover 	else if (iscsi_task_attr == ISCSI_ATTR_ORDERED)
94968d81f40SChristoph Hellwig 		sam_task_attr = TCM_ORDERED_TAG;
950d28b1169SAndy Grover 	else if (iscsi_task_attr == ISCSI_ATTR_HEAD_OF_QUEUE)
95168d81f40SChristoph Hellwig 		sam_task_attr = TCM_HEAD_TAG;
952d28b1169SAndy Grover 	else if (iscsi_task_attr == ISCSI_ATTR_ACA)
95368d81f40SChristoph Hellwig 		sam_task_attr = TCM_ACA_TAG;
954d28b1169SAndy Grover 	else {
955d28b1169SAndy Grover 		pr_debug("Unknown iSCSI Task Attribute: 0x%02x, using"
95668d81f40SChristoph Hellwig 			" TCM_SIMPLE_TAG\n", iscsi_task_attr);
95768d81f40SChristoph Hellwig 		sam_task_attr = TCM_SIMPLE_TAG;
958d28b1169SAndy Grover 	}
959d28b1169SAndy Grover 
960e48354ceSNicholas Bellinger 	cmd->iscsi_opcode	= ISCSI_OP_SCSI_CMD;
961e48354ceSNicholas Bellinger 	cmd->i_state		= ISTATE_NEW_CMD;
962e48354ceSNicholas Bellinger 	cmd->immediate_cmd	= ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
963e48354ceSNicholas Bellinger 	cmd->immediate_data	= (payload_length) ? 1 : 0;
964e48354ceSNicholas Bellinger 	cmd->unsolicited_data	= ((!(hdr->flags & ISCSI_FLAG_CMD_FINAL) &&
965e48354ceSNicholas Bellinger 				     (hdr->flags & ISCSI_FLAG_CMD_WRITE)) ? 1 : 0);
966e48354ceSNicholas Bellinger 	if (cmd->unsolicited_data)
967e48354ceSNicholas Bellinger 		cmd->cmd_flags |= ICF_NON_IMMEDIATE_UNSOLICITED_DATA;
968e48354ceSNicholas Bellinger 
969e48354ceSNicholas Bellinger 	conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
970e48354ceSNicholas Bellinger 	if (hdr->flags & ISCSI_FLAG_CMD_READ) {
971c1e34b64SSagi Grimberg 		cmd->targ_xfer_tag = session_get_next_ttt(conn->sess);
972e48354ceSNicholas Bellinger 	} else if (hdr->flags & ISCSI_FLAG_CMD_WRITE)
973e48354ceSNicholas Bellinger 		cmd->targ_xfer_tag = 0xFFFFFFFF;
97450e5c87dSChristoph Hellwig 	cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
97550e5c87dSChristoph Hellwig 	cmd->exp_stat_sn	= be32_to_cpu(hdr->exp_statsn);
976e48354ceSNicholas Bellinger 	cmd->first_burst_len	= payload_length;
977e48354ceSNicholas Bellinger 
9783e1c81a9SNicholas Bellinger 	if (!conn->sess->sess_ops->RDMAExtensions &&
9793e1c81a9SNicholas Bellinger 	     cmd->data_direction == DMA_FROM_DEVICE) {
980e48354ceSNicholas Bellinger 		struct iscsi_datain_req *dr;
981e48354ceSNicholas Bellinger 
982e48354ceSNicholas Bellinger 		dr = iscsit_allocate_datain_req();
983e48354ceSNicholas Bellinger 		if (!dr)
984ba159914SNicholas Bellinger 			return iscsit_add_reject_cmd(cmd,
985ba159914SNicholas Bellinger 					ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
986e48354ceSNicholas Bellinger 
987e48354ceSNicholas Bellinger 		iscsit_attach_datain_req(cmd, dr);
988e48354ceSNicholas Bellinger 	}
989e48354ceSNicholas Bellinger 
990e48354ceSNicholas Bellinger 	/*
991065ca1e4SAndy Grover 	 * Initialize struct se_cmd descriptor from target_core_mod infrastructure
992065ca1e4SAndy Grover 	 */
993065ca1e4SAndy Grover 	transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops,
99450e5c87dSChristoph Hellwig 			conn->sess->se_sess, be32_to_cpu(hdr->data_length),
99550e5c87dSChristoph Hellwig 			cmd->data_direction, sam_task_attr,
99650e5c87dSChristoph Hellwig 			cmd->sense_buffer + 2);
997065ca1e4SAndy Grover 
998065ca1e4SAndy Grover 	pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x,"
999065ca1e4SAndy Grover 		" ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
10003e1c81a9SNicholas Bellinger 		hdr->cmdsn, be32_to_cpu(hdr->data_length), payload_length,
10013e1c81a9SNicholas Bellinger 		conn->cid);
10023e1c81a9SNicholas Bellinger 
10033e1c81a9SNicholas Bellinger 	target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true);
1004065ca1e4SAndy Grover 
1005de103c93SChristoph Hellwig 	cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd,
10064f26998aSAndy Grover 						     scsilun_to_int(&hdr->lun));
1007de103c93SChristoph Hellwig 	if (cmd->sense_reason)
1008e48354ceSNicholas Bellinger 		goto attach_cmd;
1009a12f41f8SAndy Grover 
1010de103c93SChristoph Hellwig 	cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb);
1011de103c93SChristoph Hellwig 	if (cmd->sense_reason) {
1012de103c93SChristoph Hellwig 		if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) {
1013ba159914SNicholas Bellinger 			return iscsit_add_reject_cmd(cmd,
1014ba159914SNicholas Bellinger 					ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
1015de103c93SChristoph Hellwig 		}
1016de103c93SChristoph Hellwig 
1017de103c93SChristoph Hellwig 		goto attach_cmd;
1018de103c93SChristoph Hellwig 	}
1019de103c93SChristoph Hellwig 
1020de103c93SChristoph Hellwig 	if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) {
1021ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1022ba159914SNicholas Bellinger 				ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
1023e48354ceSNicholas Bellinger 	}
1024e48354ceSNicholas Bellinger 
1025e48354ceSNicholas Bellinger attach_cmd:
1026e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
10272fbb471eSAndy Grover 	list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
1028e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
1029e48354ceSNicholas Bellinger 	/*
1030e48354ceSNicholas Bellinger 	 * Check if we need to delay processing because of ALUA
1031e48354ceSNicholas Bellinger 	 * Active/NonOptimized primary access state..
1032e48354ceSNicholas Bellinger 	 */
1033e48354ceSNicholas Bellinger 	core_alua_check_nonop_delay(&cmd->se_cmd);
1034bfb79eacSAndy Grover 
10353e1c81a9SNicholas Bellinger 	return 0;
1036de103c93SChristoph Hellwig }
10373e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_setup_scsi_cmd);
1038de103c93SChristoph Hellwig 
10393e1c81a9SNicholas Bellinger void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *cmd)
10403e1c81a9SNicholas Bellinger {
10413e1c81a9SNicholas Bellinger 	iscsit_set_dataout_sequence_values(cmd);
10423e1c81a9SNicholas Bellinger 
10433e1c81a9SNicholas Bellinger 	spin_lock_bh(&cmd->dataout_timeout_lock);
10443e1c81a9SNicholas Bellinger 	iscsit_start_dataout_timer(cmd, cmd->conn);
10453e1c81a9SNicholas Bellinger 	spin_unlock_bh(&cmd->dataout_timeout_lock);
10463e1c81a9SNicholas Bellinger }
10473e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_set_unsoliticed_dataout);
10483e1c81a9SNicholas Bellinger 
10493e1c81a9SNicholas Bellinger int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
10503e1c81a9SNicholas Bellinger 			    struct iscsi_scsi_req *hdr)
10513e1c81a9SNicholas Bellinger {
10523e1c81a9SNicholas Bellinger 	int cmdsn_ret = 0;
1053e48354ceSNicholas Bellinger 	/*
1054e48354ceSNicholas Bellinger 	 * Check the CmdSN against ExpCmdSN/MaxCmdSN here if
1055e48354ceSNicholas Bellinger 	 * the Immediate Bit is not set, and no Immediate
1056e48354ceSNicholas Bellinger 	 * Data is attached.
1057e48354ceSNicholas Bellinger 	 *
1058e48354ceSNicholas Bellinger 	 * A PDU/CmdSN carrying Immediate Data can only
1059e48354ceSNicholas Bellinger 	 * be processed after the DataCRC has passed.
1060e48354ceSNicholas Bellinger 	 * If the DataCRC fails, the CmdSN MUST NOT
1061e48354ceSNicholas Bellinger 	 * be acknowledged. (See below)
1062e48354ceSNicholas Bellinger 	 */
1063e48354ceSNicholas Bellinger 	if (!cmd->immediate_data) {
1064561bf158SNicholas Bellinger 		cmdsn_ret = iscsit_sequence_cmd(conn, cmd,
1065561bf158SNicholas Bellinger 					(unsigned char *)hdr, hdr->cmdsn);
1066561bf158SNicholas Bellinger 		if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
1067561bf158SNicholas Bellinger 			return -1;
1068561bf158SNicholas Bellinger 		else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
10693e1c81a9SNicholas Bellinger 			target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
10703e1c81a9SNicholas Bellinger 			return 0;
10713e1c81a9SNicholas Bellinger 		}
1072e48354ceSNicholas Bellinger 	}
1073e48354ceSNicholas Bellinger 
107450e5c87dSChristoph Hellwig 	iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
1075e48354ceSNicholas Bellinger 
1076e48354ceSNicholas Bellinger 	/*
1077e48354ceSNicholas Bellinger 	 * If no Immediate Data is attached, it's OK to return now.
1078e48354ceSNicholas Bellinger 	 */
1079e48354ceSNicholas Bellinger 	if (!cmd->immediate_data) {
10803e1c81a9SNicholas Bellinger 		if (!cmd->sense_reason && cmd->unsolicited_data)
10813e1c81a9SNicholas Bellinger 			iscsit_set_unsoliticed_dataout(cmd);
10823e1c81a9SNicholas Bellinger 		if (!cmd->sense_reason)
10833e1c81a9SNicholas Bellinger 			return 0;
1084e48354ceSNicholas Bellinger 
10853e1c81a9SNicholas Bellinger 		target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
1086e48354ceSNicholas Bellinger 		return 0;
1087e48354ceSNicholas Bellinger 	}
1088e48354ceSNicholas Bellinger 
1089e48354ceSNicholas Bellinger 	/*
10903e1c81a9SNicholas Bellinger 	 * Early CHECK_CONDITIONs with ImmediateData never make it to command
10913e1c81a9SNicholas Bellinger 	 * execution.  These exceptions are processed in CmdSN order using
10923e1c81a9SNicholas Bellinger 	 * iscsit_check_received_cmdsn() in iscsit_get_immediate_data() below.
1093e48354ceSNicholas Bellinger 	 */
1094de103c93SChristoph Hellwig 	if (cmd->sense_reason) {
1095561bf158SNicholas Bellinger 		if (cmd->reject_reason)
1096561bf158SNicholas Bellinger 			return 0;
1097561bf158SNicholas Bellinger 
10983e1c81a9SNicholas Bellinger 		return 1;
1099e48354ceSNicholas Bellinger 	}
1100e48354ceSNicholas Bellinger 	/*
1101e48354ceSNicholas Bellinger 	 * Call directly into transport_generic_new_cmd() to perform
1102e48354ceSNicholas Bellinger 	 * the backend memory allocation.
1103e48354ceSNicholas Bellinger 	 */
1104de103c93SChristoph Hellwig 	cmd->sense_reason = transport_generic_new_cmd(&cmd->se_cmd);
1105561bf158SNicholas Bellinger 	if (cmd->sense_reason)
11063e1c81a9SNicholas Bellinger 		return 1;
1107e48354ceSNicholas Bellinger 
11083e1c81a9SNicholas Bellinger 	return 0;
11093e1c81a9SNicholas Bellinger }
11103e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_process_scsi_cmd);
11113e1c81a9SNicholas Bellinger 
11123e1c81a9SNicholas Bellinger static int
11133e1c81a9SNicholas Bellinger iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
11143e1c81a9SNicholas Bellinger 			  bool dump_payload)
11153e1c81a9SNicholas Bellinger {
1116561bf158SNicholas Bellinger 	struct iscsi_conn *conn = cmd->conn;
11173e1c81a9SNicholas Bellinger 	int cmdsn_ret = 0, immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
11183e1c81a9SNicholas Bellinger 	/*
11193e1c81a9SNicholas Bellinger 	 * Special case for Unsupported SAM WRITE Opcodes and ImmediateData=Yes.
11203e1c81a9SNicholas Bellinger 	 */
11210bcc297eSChristophe Vu-Brugier 	if (dump_payload)
11223e1c81a9SNicholas Bellinger 		goto after_immediate_data;
11233e1c81a9SNicholas Bellinger 
11243e1c81a9SNicholas Bellinger 	immed_ret = iscsit_handle_immediate_data(cmd, hdr,
11253e1c81a9SNicholas Bellinger 					cmd->first_burst_len);
1126e48354ceSNicholas Bellinger after_immediate_data:
1127e48354ceSNicholas Bellinger 	if (immed_ret == IMMEDIATE_DATA_NORMAL_OPERATION) {
1128e48354ceSNicholas Bellinger 		/*
1129e48354ceSNicholas Bellinger 		 * A PDU/CmdSN carrying Immediate Data passed
1130e48354ceSNicholas Bellinger 		 * DataCRC, check against ExpCmdSN/MaxCmdSN if
1131e48354ceSNicholas Bellinger 		 * Immediate Bit is not set.
1132e48354ceSNicholas Bellinger 		 */
1133561bf158SNicholas Bellinger 		cmdsn_ret = iscsit_sequence_cmd(cmd->conn, cmd,
1134561bf158SNicholas Bellinger 					(unsigned char *)hdr, hdr->cmdsn);
11359d86a2beSNicholas Bellinger 		if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
1136561bf158SNicholas Bellinger 			return -1;
1137e48354ceSNicholas Bellinger 
11389d86a2beSNicholas Bellinger 		if (cmd->sense_reason || cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
1139561bf158SNicholas Bellinger 			int rc;
1140561bf158SNicholas Bellinger 
1141561bf158SNicholas Bellinger 			rc = iscsit_dump_data_payload(cmd->conn,
1142561bf158SNicholas Bellinger 						      cmd->first_burst_len, 1);
1143561bf158SNicholas Bellinger 			target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
1144561bf158SNicholas Bellinger 			return rc;
11453e1c81a9SNicholas Bellinger 		} else if (cmd->unsolicited_data)
11463e1c81a9SNicholas Bellinger 			iscsit_set_unsoliticed_dataout(cmd);
1147e48354ceSNicholas Bellinger 
1148e48354ceSNicholas Bellinger 	} else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) {
1149e48354ceSNicholas Bellinger 		/*
1150e48354ceSNicholas Bellinger 		 * Immediate Data failed DataCRC and ERL>=1,
1151e48354ceSNicholas Bellinger 		 * silently drop this PDU and let the initiator
1152e48354ceSNicholas Bellinger 		 * plug the CmdSN gap.
1153e48354ceSNicholas Bellinger 		 *
1154e48354ceSNicholas Bellinger 		 * FIXME: Send Unsolicited NOPIN with reserved
1155e48354ceSNicholas Bellinger 		 * TTT here to help the initiator figure out
1156e48354ceSNicholas Bellinger 		 * the missing CmdSN, although they should be
1157e48354ceSNicholas Bellinger 		 * intelligent enough to determine the missing
1158e48354ceSNicholas Bellinger 		 * CmdSN and issue a retry to plug the sequence.
1159e48354ceSNicholas Bellinger 		 */
1160e48354ceSNicholas Bellinger 		cmd->i_state = ISTATE_REMOVE;
11613e1c81a9SNicholas Bellinger 		iscsit_add_cmd_to_immediate_queue(cmd, cmd->conn, cmd->i_state);
1162e48354ceSNicholas Bellinger 	} else /* immed_ret == IMMEDIATE_DATA_CANNOT_RECOVER */
1163e48354ceSNicholas Bellinger 		return -1;
1164e48354ceSNicholas Bellinger 
1165e48354ceSNicholas Bellinger 	return 0;
1166e48354ceSNicholas Bellinger }
1167e48354ceSNicholas Bellinger 
11683e1c81a9SNicholas Bellinger static int
11693e1c81a9SNicholas Bellinger iscsit_handle_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
11703e1c81a9SNicholas Bellinger 			   unsigned char *buf)
11713e1c81a9SNicholas Bellinger {
11723e1c81a9SNicholas Bellinger 	struct iscsi_scsi_req *hdr = (struct iscsi_scsi_req *)buf;
11733e1c81a9SNicholas Bellinger 	int rc, immed_data;
11743e1c81a9SNicholas Bellinger 	bool dump_payload = false;
11753e1c81a9SNicholas Bellinger 
11763e1c81a9SNicholas Bellinger 	rc = iscsit_setup_scsi_cmd(conn, cmd, buf);
11773e1c81a9SNicholas Bellinger 	if (rc < 0)
1178561bf158SNicholas Bellinger 		return 0;
11793e1c81a9SNicholas Bellinger 	/*
11803e1c81a9SNicholas Bellinger 	 * Allocation iovecs needed for struct socket operations for
11813e1c81a9SNicholas Bellinger 	 * traditional iSCSI block I/O.
11823e1c81a9SNicholas Bellinger 	 */
11833e1c81a9SNicholas Bellinger 	if (iscsit_allocate_iovecs(cmd) < 0) {
1184b815fc12SMike Christie 		return iscsit_reject_cmd(cmd,
1185ba159914SNicholas Bellinger 				ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
11863e1c81a9SNicholas Bellinger 	}
11873e1c81a9SNicholas Bellinger 	immed_data = cmd->immediate_data;
11883e1c81a9SNicholas Bellinger 
11893e1c81a9SNicholas Bellinger 	rc = iscsit_process_scsi_cmd(conn, cmd, hdr);
11903e1c81a9SNicholas Bellinger 	if (rc < 0)
11913e1c81a9SNicholas Bellinger 		return rc;
11923e1c81a9SNicholas Bellinger 	else if (rc > 0)
11933e1c81a9SNicholas Bellinger 		dump_payload = true;
11943e1c81a9SNicholas Bellinger 
11953e1c81a9SNicholas Bellinger 	if (!immed_data)
11963e1c81a9SNicholas Bellinger 		return 0;
11973e1c81a9SNicholas Bellinger 
11983e1c81a9SNicholas Bellinger 	return iscsit_get_immediate_data(cmd, hdr, dump_payload);
11993e1c81a9SNicholas Bellinger }
12003e1c81a9SNicholas Bellinger 
1201e48354ceSNicholas Bellinger static u32 iscsit_do_crypto_hash_sg(
1202e48354ceSNicholas Bellinger 	struct hash_desc *hash,
1203e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd,
1204e48354ceSNicholas Bellinger 	u32 data_offset,
1205e48354ceSNicholas Bellinger 	u32 data_length,
1206e48354ceSNicholas Bellinger 	u32 padding,
1207e48354ceSNicholas Bellinger 	u8 *pad_bytes)
1208e48354ceSNicholas Bellinger {
1209e48354ceSNicholas Bellinger 	u32 data_crc;
1210e48354ceSNicholas Bellinger 	u32 i;
1211e48354ceSNicholas Bellinger 	struct scatterlist *sg;
1212e48354ceSNicholas Bellinger 	unsigned int page_off;
1213e48354ceSNicholas Bellinger 
1214e48354ceSNicholas Bellinger 	crypto_hash_init(hash);
1215e48354ceSNicholas Bellinger 
1216e48354ceSNicholas Bellinger 	sg = cmd->first_data_sg;
1217e48354ceSNicholas Bellinger 	page_off = cmd->first_data_sg_off;
1218e48354ceSNicholas Bellinger 
1219e48354ceSNicholas Bellinger 	i = 0;
1220e48354ceSNicholas Bellinger 	while (data_length) {
1221e48354ceSNicholas Bellinger 		u32 cur_len = min_t(u32, data_length, (sg[i].length - page_off));
1222e48354ceSNicholas Bellinger 
1223e48354ceSNicholas Bellinger 		crypto_hash_update(hash, &sg[i], cur_len);
1224e48354ceSNicholas Bellinger 
1225e48354ceSNicholas Bellinger 		data_length -= cur_len;
1226e48354ceSNicholas Bellinger 		page_off = 0;
1227e48354ceSNicholas Bellinger 		i++;
1228e48354ceSNicholas Bellinger 	}
1229e48354ceSNicholas Bellinger 
1230e48354ceSNicholas Bellinger 	if (padding) {
1231e48354ceSNicholas Bellinger 		struct scatterlist pad_sg;
1232e48354ceSNicholas Bellinger 
1233e48354ceSNicholas Bellinger 		sg_init_one(&pad_sg, pad_bytes, padding);
1234e48354ceSNicholas Bellinger 		crypto_hash_update(hash, &pad_sg, padding);
1235e48354ceSNicholas Bellinger 	}
1236e48354ceSNicholas Bellinger 	crypto_hash_final(hash, (u8 *) &data_crc);
1237e48354ceSNicholas Bellinger 
1238e48354ceSNicholas Bellinger 	return data_crc;
1239e48354ceSNicholas Bellinger }
1240e48354ceSNicholas Bellinger 
1241e48354ceSNicholas Bellinger static void iscsit_do_crypto_hash_buf(
1242e48354ceSNicholas Bellinger 	struct hash_desc *hash,
124380690fdbSGeert Uytterhoeven 	const void *buf,
1244e48354ceSNicholas Bellinger 	u32 payload_length,
1245e48354ceSNicholas Bellinger 	u32 padding,
1246e48354ceSNicholas Bellinger 	u8 *pad_bytes,
1247e48354ceSNicholas Bellinger 	u8 *data_crc)
1248e48354ceSNicholas Bellinger {
1249e48354ceSNicholas Bellinger 	struct scatterlist sg;
1250e48354ceSNicholas Bellinger 
1251e48354ceSNicholas Bellinger 	crypto_hash_init(hash);
1252e48354ceSNicholas Bellinger 
12538359cf43SJörn Engel 	sg_init_one(&sg, buf, payload_length);
1254e48354ceSNicholas Bellinger 	crypto_hash_update(hash, &sg, payload_length);
1255e48354ceSNicholas Bellinger 
1256e48354ceSNicholas Bellinger 	if (padding) {
1257e48354ceSNicholas Bellinger 		sg_init_one(&sg, pad_bytes, padding);
1258e48354ceSNicholas Bellinger 		crypto_hash_update(hash, &sg, padding);
1259e48354ceSNicholas Bellinger 	}
1260e48354ceSNicholas Bellinger 	crypto_hash_final(hash, data_crc);
1261e48354ceSNicholas Bellinger }
1262e48354ceSNicholas Bellinger 
12633e1c81a9SNicholas Bellinger int
12643e1c81a9SNicholas Bellinger iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf,
12653e1c81a9SNicholas Bellinger 			  struct iscsi_cmd **out_cmd)
1266e48354ceSNicholas Bellinger {
12673e1c81a9SNicholas Bellinger 	struct iscsi_data *hdr = (struct iscsi_data *)buf;
1268e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd = NULL;
1269e48354ceSNicholas Bellinger 	struct se_cmd *se_cmd;
12703e1c81a9SNicholas Bellinger 	u32 payload_length = ntoh24(hdr->dlength);
12713e1c81a9SNicholas Bellinger 	int rc;
1272e48354ceSNicholas Bellinger 
1273e48354ceSNicholas Bellinger 	if (!payload_length) {
1274dbcbc95cSNicholas Bellinger 		pr_warn("DataOUT payload is ZERO, ignoring.\n");
1275dbcbc95cSNicholas Bellinger 		return 0;
1276e48354ceSNicholas Bellinger 	}
1277e48354ceSNicholas Bellinger 
1278e48354ceSNicholas Bellinger 	/* iSCSI write */
127904f3b31bSNicholas Bellinger 	atomic_long_add(payload_length, &conn->sess->rx_data_octets);
1280e48354ceSNicholas Bellinger 
128121f5aa7eSNicholas Bellinger 	if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
1282e48354ceSNicholas Bellinger 		pr_err("DataSegmentLength: %u is greater than"
128321f5aa7eSNicholas Bellinger 			" MaxXmitDataSegmentLength: %u\n", payload_length,
128421f5aa7eSNicholas Bellinger 			conn->conn_ops->MaxXmitDataSegmentLength);
1285ba159914SNicholas Bellinger 		return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
1286ba159914SNicholas Bellinger 					 buf);
1287e48354ceSNicholas Bellinger 	}
1288e48354ceSNicholas Bellinger 
1289e48354ceSNicholas Bellinger 	cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt,
1290e48354ceSNicholas Bellinger 			payload_length);
1291e48354ceSNicholas Bellinger 	if (!cmd)
1292e48354ceSNicholas Bellinger 		return 0;
1293e48354ceSNicholas Bellinger 
1294e48354ceSNicholas Bellinger 	pr_debug("Got DataOut ITT: 0x%08x, TTT: 0x%08x,"
1295e48354ceSNicholas Bellinger 		" DataSN: 0x%08x, Offset: %u, Length: %u, CID: %hu\n",
12963e1c81a9SNicholas Bellinger 		hdr->itt, hdr->ttt, hdr->datasn, ntohl(hdr->offset),
1297e48354ceSNicholas Bellinger 		payload_length, conn->cid);
1298e48354ceSNicholas Bellinger 
1299e48354ceSNicholas Bellinger 	if (cmd->cmd_flags & ICF_GOT_LAST_DATAOUT) {
1300e48354ceSNicholas Bellinger 		pr_err("Command ITT: 0x%08x received DataOUT after"
1301e48354ceSNicholas Bellinger 			" last DataOUT received, dumping payload\n",
1302e48354ceSNicholas Bellinger 			cmd->init_task_tag);
1303e48354ceSNicholas Bellinger 		return iscsit_dump_data_payload(conn, payload_length, 1);
1304e48354ceSNicholas Bellinger 	}
1305e48354ceSNicholas Bellinger 
1306e48354ceSNicholas Bellinger 	if (cmd->data_direction != DMA_TO_DEVICE) {
1307e48354ceSNicholas Bellinger 		pr_err("Command ITT: 0x%08x received DataOUT for a"
1308e48354ceSNicholas Bellinger 			" NON-WRITE command.\n", cmd->init_task_tag);
130997c99b47SNicholas Bellinger 		return iscsit_dump_data_payload(conn, payload_length, 1);
1310e48354ceSNicholas Bellinger 	}
1311e48354ceSNicholas Bellinger 	se_cmd = &cmd->se_cmd;
1312e48354ceSNicholas Bellinger 	iscsit_mod_dataout_timer(cmd);
1313e48354ceSNicholas Bellinger 
131450e5c87dSChristoph Hellwig 	if ((be32_to_cpu(hdr->offset) + payload_length) > cmd->se_cmd.data_length) {
1315e48354ceSNicholas Bellinger 		pr_err("DataOut Offset: %u, Length %u greater than"
1316e48354ceSNicholas Bellinger 			" iSCSI Command EDTL %u, protocol error.\n",
1317ebf1d95cSAndy Grover 			hdr->offset, payload_length, cmd->se_cmd.data_length);
1318ba159914SNicholas Bellinger 		return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_INVALID, buf);
1319e48354ceSNicholas Bellinger 	}
1320e48354ceSNicholas Bellinger 
1321e48354ceSNicholas Bellinger 	if (cmd->unsolicited_data) {
1322e48354ceSNicholas Bellinger 		int dump_unsolicited_data = 0;
1323e48354ceSNicholas Bellinger 
1324e48354ceSNicholas Bellinger 		if (conn->sess->sess_ops->InitialR2T) {
1325e48354ceSNicholas Bellinger 			pr_err("Received unexpected unsolicited data"
1326e48354ceSNicholas Bellinger 				" while InitialR2T=Yes, protocol error.\n");
1327e48354ceSNicholas Bellinger 			transport_send_check_condition_and_sense(&cmd->se_cmd,
1328e48354ceSNicholas Bellinger 					TCM_UNEXPECTED_UNSOLICITED_DATA, 0);
1329e48354ceSNicholas Bellinger 			return -1;
1330e48354ceSNicholas Bellinger 		}
1331e48354ceSNicholas Bellinger 		/*
1332e48354ceSNicholas Bellinger 		 * Special case for dealing with Unsolicited DataOUT
1333e48354ceSNicholas Bellinger 		 * and Unsupported SAM WRITE Opcodes and SE resource allocation
1334e48354ceSNicholas Bellinger 		 * failures;
1335e48354ceSNicholas Bellinger 		 */
1336e48354ceSNicholas Bellinger 
1337e48354ceSNicholas Bellinger 		/* Something's amiss if we're not in WRITE_PENDING state... */
1338e48354ceSNicholas Bellinger 		WARN_ON(se_cmd->t_state != TRANSPORT_WRITE_PENDING);
1339de103c93SChristoph Hellwig 		if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE))
1340e48354ceSNicholas Bellinger 			dump_unsolicited_data = 1;
1341e48354ceSNicholas Bellinger 
1342e48354ceSNicholas Bellinger 		if (dump_unsolicited_data) {
1343e48354ceSNicholas Bellinger 			/*
1344e48354ceSNicholas Bellinger 			 * Check if a delayed TASK_ABORTED status needs to
1345e48354ceSNicholas Bellinger 			 * be sent now if the ISCSI_FLAG_CMD_FINAL has been
1346e48354ceSNicholas Bellinger 			 * received with the unsolicitied data out.
1347e48354ceSNicholas Bellinger 			 */
1348e48354ceSNicholas Bellinger 			if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
1349e48354ceSNicholas Bellinger 				iscsit_stop_dataout_timer(cmd);
1350e48354ceSNicholas Bellinger 
1351e48354ceSNicholas Bellinger 			transport_check_aborted_status(se_cmd,
1352e48354ceSNicholas Bellinger 					(hdr->flags & ISCSI_FLAG_CMD_FINAL));
1353e48354ceSNicholas Bellinger 			return iscsit_dump_data_payload(conn, payload_length, 1);
1354e48354ceSNicholas Bellinger 		}
1355e48354ceSNicholas Bellinger 	} else {
1356e48354ceSNicholas Bellinger 		/*
1357e48354ceSNicholas Bellinger 		 * For the normal solicited data path:
1358e48354ceSNicholas Bellinger 		 *
1359e48354ceSNicholas Bellinger 		 * Check for a delayed TASK_ABORTED status and dump any
1360e48354ceSNicholas Bellinger 		 * incoming data out payload if one exists.  Also, when the
1361e48354ceSNicholas Bellinger 		 * ISCSI_FLAG_CMD_FINAL is set to denote the end of the current
1362e48354ceSNicholas Bellinger 		 * data out sequence, we decrement outstanding_r2ts.  Once
1363e48354ceSNicholas Bellinger 		 * outstanding_r2ts reaches zero, go ahead and send the delayed
1364e48354ceSNicholas Bellinger 		 * TASK_ABORTED status.
1365e48354ceSNicholas Bellinger 		 */
13667d680f3bSChristoph Hellwig 		if (se_cmd->transport_state & CMD_T_ABORTED) {
1367e48354ceSNicholas Bellinger 			if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
1368e48354ceSNicholas Bellinger 				if (--cmd->outstanding_r2ts < 1) {
1369e48354ceSNicholas Bellinger 					iscsit_stop_dataout_timer(cmd);
1370e48354ceSNicholas Bellinger 					transport_check_aborted_status(
1371e48354ceSNicholas Bellinger 							se_cmd, 1);
1372e48354ceSNicholas Bellinger 				}
1373e48354ceSNicholas Bellinger 
1374e48354ceSNicholas Bellinger 			return iscsit_dump_data_payload(conn, payload_length, 1);
1375e48354ceSNicholas Bellinger 		}
1376e48354ceSNicholas Bellinger 	}
1377e48354ceSNicholas Bellinger 	/*
1378e48354ceSNicholas Bellinger 	 * Preform DataSN, DataSequenceInOrder, DataPDUInOrder, and
1379e48354ceSNicholas Bellinger 	 * within-command recovery checks before receiving the payload.
1380e48354ceSNicholas Bellinger 	 */
13813e1c81a9SNicholas Bellinger 	rc = iscsit_check_pre_dataout(cmd, buf);
13823e1c81a9SNicholas Bellinger 	if (rc == DATAOUT_WITHIN_COMMAND_RECOVERY)
1383e48354ceSNicholas Bellinger 		return 0;
13843e1c81a9SNicholas Bellinger 	else if (rc == DATAOUT_CANNOT_RECOVER)
1385e48354ceSNicholas Bellinger 		return -1;
1386e48354ceSNicholas Bellinger 
13873e1c81a9SNicholas Bellinger 	*out_cmd = cmd;
13883e1c81a9SNicholas Bellinger 	return 0;
13893e1c81a9SNicholas Bellinger }
13903e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_check_dataout_hdr);
13913e1c81a9SNicholas Bellinger 
13923e1c81a9SNicholas Bellinger static int
13933e1c81a9SNicholas Bellinger iscsit_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
13943e1c81a9SNicholas Bellinger 		   struct iscsi_data *hdr)
13953e1c81a9SNicholas Bellinger {
13963e1c81a9SNicholas Bellinger 	struct kvec *iov;
13973e1c81a9SNicholas Bellinger 	u32 checksum, iov_count = 0, padding = 0, rx_got = 0, rx_size = 0;
13983e1c81a9SNicholas Bellinger 	u32 payload_length = ntoh24(hdr->dlength);
13993e1c81a9SNicholas Bellinger 	int iov_ret, data_crc_failed = 0;
14003e1c81a9SNicholas Bellinger 
1401e48354ceSNicholas Bellinger 	rx_size += payload_length;
1402e48354ceSNicholas Bellinger 	iov = &cmd->iov_data[0];
1403e48354ceSNicholas Bellinger 
140450e5c87dSChristoph Hellwig 	iov_ret = iscsit_map_iovec(cmd, iov, be32_to_cpu(hdr->offset),
140550e5c87dSChristoph Hellwig 				   payload_length);
1406e48354ceSNicholas Bellinger 	if (iov_ret < 0)
1407e48354ceSNicholas Bellinger 		return -1;
1408e48354ceSNicholas Bellinger 
1409e48354ceSNicholas Bellinger 	iov_count += iov_ret;
1410e48354ceSNicholas Bellinger 
1411e48354ceSNicholas Bellinger 	padding = ((-payload_length) & 3);
1412e48354ceSNicholas Bellinger 	if (padding != 0) {
1413e48354ceSNicholas Bellinger 		iov[iov_count].iov_base	= cmd->pad_bytes;
1414e48354ceSNicholas Bellinger 		iov[iov_count++].iov_len = padding;
1415e48354ceSNicholas Bellinger 		rx_size += padding;
1416e48354ceSNicholas Bellinger 		pr_debug("Receiving %u padding bytes.\n", padding);
1417e48354ceSNicholas Bellinger 	}
1418e48354ceSNicholas Bellinger 
1419e48354ceSNicholas Bellinger 	if (conn->conn_ops->DataDigest) {
1420e48354ceSNicholas Bellinger 		iov[iov_count].iov_base = &checksum;
1421e48354ceSNicholas Bellinger 		iov[iov_count++].iov_len = ISCSI_CRC_LEN;
1422e48354ceSNicholas Bellinger 		rx_size += ISCSI_CRC_LEN;
1423e48354ceSNicholas Bellinger 	}
1424e48354ceSNicholas Bellinger 
1425e48354ceSNicholas Bellinger 	rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size);
1426e48354ceSNicholas Bellinger 
1427e48354ceSNicholas Bellinger 	iscsit_unmap_iovec(cmd);
1428e48354ceSNicholas Bellinger 
1429e48354ceSNicholas Bellinger 	if (rx_got != rx_size)
1430e48354ceSNicholas Bellinger 		return -1;
1431e48354ceSNicholas Bellinger 
1432e48354ceSNicholas Bellinger 	if (conn->conn_ops->DataDigest) {
1433e48354ceSNicholas Bellinger 		u32 data_crc;
1434e48354ceSNicholas Bellinger 
1435e48354ceSNicholas Bellinger 		data_crc = iscsit_do_crypto_hash_sg(&conn->conn_rx_hash, cmd,
143650e5c87dSChristoph Hellwig 						    be32_to_cpu(hdr->offset),
143750e5c87dSChristoph Hellwig 						    payload_length, padding,
1438e48354ceSNicholas Bellinger 						    cmd->pad_bytes);
1439e48354ceSNicholas Bellinger 
1440e48354ceSNicholas Bellinger 		if (checksum != data_crc) {
1441e48354ceSNicholas Bellinger 			pr_err("ITT: 0x%08x, Offset: %u, Length: %u,"
1442e48354ceSNicholas Bellinger 				" DataSN: 0x%08x, CRC32C DataDigest 0x%08x"
1443e48354ceSNicholas Bellinger 				" does not match computed 0x%08x\n",
1444e48354ceSNicholas Bellinger 				hdr->itt, hdr->offset, payload_length,
1445e48354ceSNicholas Bellinger 				hdr->datasn, checksum, data_crc);
1446e48354ceSNicholas Bellinger 			data_crc_failed = 1;
1447e48354ceSNicholas Bellinger 		} else {
1448e48354ceSNicholas Bellinger 			pr_debug("Got CRC32C DataDigest 0x%08x for"
1449e48354ceSNicholas Bellinger 				" %u bytes of Data Out\n", checksum,
1450e48354ceSNicholas Bellinger 				payload_length);
1451e48354ceSNicholas Bellinger 		}
1452e48354ceSNicholas Bellinger 	}
14533e1c81a9SNicholas Bellinger 
14543e1c81a9SNicholas Bellinger 	return data_crc_failed;
14553e1c81a9SNicholas Bellinger }
14563e1c81a9SNicholas Bellinger 
14573e1c81a9SNicholas Bellinger int
14583e1c81a9SNicholas Bellinger iscsit_check_dataout_payload(struct iscsi_cmd *cmd, struct iscsi_data *hdr,
14593e1c81a9SNicholas Bellinger 			     bool data_crc_failed)
14603e1c81a9SNicholas Bellinger {
14613e1c81a9SNicholas Bellinger 	struct iscsi_conn *conn = cmd->conn;
14623e1c81a9SNicholas Bellinger 	int rc, ooo_cmdsn;
1463e48354ceSNicholas Bellinger 	/*
1464e48354ceSNicholas Bellinger 	 * Increment post receive data and CRC values or perform
1465e48354ceSNicholas Bellinger 	 * within-command recovery.
1466e48354ceSNicholas Bellinger 	 */
14673e1c81a9SNicholas Bellinger 	rc = iscsit_check_post_dataout(cmd, (unsigned char *)hdr, data_crc_failed);
14683e1c81a9SNicholas Bellinger 	if ((rc == DATAOUT_NORMAL) || (rc == DATAOUT_WITHIN_COMMAND_RECOVERY))
1469e48354ceSNicholas Bellinger 		return 0;
14703e1c81a9SNicholas Bellinger 	else if (rc == DATAOUT_SEND_R2T) {
1471e48354ceSNicholas Bellinger 		iscsit_set_dataout_sequence_values(cmd);
14723e1c81a9SNicholas Bellinger 		conn->conn_transport->iscsit_get_dataout(conn, cmd, false);
14733e1c81a9SNicholas Bellinger 	} else if (rc == DATAOUT_SEND_TO_TRANSPORT) {
1474e48354ceSNicholas Bellinger 		/*
1475e48354ceSNicholas Bellinger 		 * Handle extra special case for out of order
1476e48354ceSNicholas Bellinger 		 * Unsolicited Data Out.
1477e48354ceSNicholas Bellinger 		 */
1478e48354ceSNicholas Bellinger 		spin_lock_bh(&cmd->istate_lock);
1479e48354ceSNicholas Bellinger 		ooo_cmdsn = (cmd->cmd_flags & ICF_OOO_CMDSN);
1480e48354ceSNicholas Bellinger 		cmd->cmd_flags |= ICF_GOT_LAST_DATAOUT;
1481e48354ceSNicholas Bellinger 		cmd->i_state = ISTATE_RECEIVED_LAST_DATAOUT;
1482e48354ceSNicholas Bellinger 		spin_unlock_bh(&cmd->istate_lock);
1483e48354ceSNicholas Bellinger 
1484e48354ceSNicholas Bellinger 		iscsit_stop_dataout_timer(cmd);
148567441b68SChristoph Hellwig 		if (ooo_cmdsn)
148667441b68SChristoph Hellwig 			return 0;
148767441b68SChristoph Hellwig 		target_execute_cmd(&cmd->se_cmd);
148867441b68SChristoph Hellwig 		return 0;
1489e48354ceSNicholas Bellinger 	} else /* DATAOUT_CANNOT_RECOVER */
1490e48354ceSNicholas Bellinger 		return -1;
1491e48354ceSNicholas Bellinger 
1492e48354ceSNicholas Bellinger 	return 0;
1493e48354ceSNicholas Bellinger }
14943e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_check_dataout_payload);
1495e48354ceSNicholas Bellinger 
14963e1c81a9SNicholas Bellinger static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
14973e1c81a9SNicholas Bellinger {
1498dbcbc95cSNicholas Bellinger 	struct iscsi_cmd *cmd = NULL;
14993e1c81a9SNicholas Bellinger 	struct iscsi_data *hdr = (struct iscsi_data *)buf;
15003e1c81a9SNicholas Bellinger 	int rc;
15013e1c81a9SNicholas Bellinger 	bool data_crc_failed = false;
15023e1c81a9SNicholas Bellinger 
15033e1c81a9SNicholas Bellinger 	rc = iscsit_check_dataout_hdr(conn, buf, &cmd);
15043e1c81a9SNicholas Bellinger 	if (rc < 0)
1505561bf158SNicholas Bellinger 		return 0;
15063e1c81a9SNicholas Bellinger 	else if (!cmd)
15073e1c81a9SNicholas Bellinger 		return 0;
15083e1c81a9SNicholas Bellinger 
15093e1c81a9SNicholas Bellinger 	rc = iscsit_get_dataout(conn, cmd, hdr);
15103e1c81a9SNicholas Bellinger 	if (rc < 0)
15113e1c81a9SNicholas Bellinger 		return rc;
15123e1c81a9SNicholas Bellinger 	else if (rc > 0)
15133e1c81a9SNicholas Bellinger 		data_crc_failed = true;
15143e1c81a9SNicholas Bellinger 
15153e1c81a9SNicholas Bellinger 	return iscsit_check_dataout_payload(cmd, hdr, data_crc_failed);
15163e1c81a9SNicholas Bellinger }
15173e1c81a9SNicholas Bellinger 
1518778de368SNicholas Bellinger int iscsit_setup_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
1519778de368SNicholas Bellinger 			 struct iscsi_nopout *hdr)
1520e48354ceSNicholas Bellinger {
1521778de368SNicholas Bellinger 	u32 payload_length = ntoh24(hdr->dlength);
1522e48354ceSNicholas Bellinger 
1523a3662605SArshad Hussain 	if (!(hdr->flags & ISCSI_FLAG_CMD_FINAL)) {
1524a3662605SArshad Hussain 		pr_err("NopOUT Flag's, Left Most Bit not set, protocol error.\n");
1525a3662605SArshad Hussain 		if (!cmd)
1526a3662605SArshad Hussain 			return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
1527a3662605SArshad Hussain 						 (unsigned char *)hdr);
1528a3662605SArshad Hussain 
1529a3662605SArshad Hussain 		return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
1530a3662605SArshad Hussain 					 (unsigned char *)hdr);
1531a3662605SArshad Hussain 	}
1532a3662605SArshad Hussain 
153366c7db68SChristoph Hellwig 	if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
1534e48354ceSNicholas Bellinger 		pr_err("NOPOUT ITT is reserved, but Immediate Bit is"
1535e48354ceSNicholas Bellinger 			" not set, protocol error.\n");
153628aaa950SNicholas Bellinger 		if (!cmd)
153728aaa950SNicholas Bellinger 			return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
153828aaa950SNicholas Bellinger 						 (unsigned char *)hdr);
153928aaa950SNicholas Bellinger 
1540ba159914SNicholas Bellinger 		return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
1541ba159914SNicholas Bellinger 					 (unsigned char *)hdr);
1542e48354ceSNicholas Bellinger 	}
1543e48354ceSNicholas Bellinger 
154421f5aa7eSNicholas Bellinger 	if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
1545e48354ceSNicholas Bellinger 		pr_err("NOPOUT Ping Data DataSegmentLength: %u is"
154621f5aa7eSNicholas Bellinger 			" greater than MaxXmitDataSegmentLength: %u, protocol"
1547e48354ceSNicholas Bellinger 			" error.\n", payload_length,
154821f5aa7eSNicholas Bellinger 			conn->conn_ops->MaxXmitDataSegmentLength);
154928aaa950SNicholas Bellinger 		if (!cmd)
155028aaa950SNicholas Bellinger 			return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
155128aaa950SNicholas Bellinger 						 (unsigned char *)hdr);
155228aaa950SNicholas Bellinger 
1553ba159914SNicholas Bellinger 		return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
1554ba159914SNicholas Bellinger 					 (unsigned char *)hdr);
1555e48354ceSNicholas Bellinger 	}
1556e48354ceSNicholas Bellinger 
15573e1c81a9SNicholas Bellinger 	pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%08x,"
1558e48354ceSNicholas Bellinger 		" CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n",
155966c7db68SChristoph Hellwig 		hdr->itt == RESERVED_ITT ? "Response" : "Request",
1560e48354ceSNicholas Bellinger 		hdr->itt, hdr->ttt, hdr->cmdsn, hdr->exp_statsn,
1561e48354ceSNicholas Bellinger 		payload_length);
1562e48354ceSNicholas Bellinger 	/*
1563e48354ceSNicholas Bellinger 	 * This is not a response to a Unsolicited NopIN, which means
1564e48354ceSNicholas Bellinger 	 * it can either be a NOPOUT ping request (with a valid ITT),
1565e48354ceSNicholas Bellinger 	 * or a NOPOUT not requesting a NOPIN (with a reserved ITT).
1566e48354ceSNicholas Bellinger 	 * Either way, make sure we allocate an struct iscsi_cmd, as both
1567e48354ceSNicholas Bellinger 	 * can contain ping data.
1568e48354ceSNicholas Bellinger 	 */
156950e5c87dSChristoph Hellwig 	if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
1570e48354ceSNicholas Bellinger 		cmd->iscsi_opcode	= ISCSI_OP_NOOP_OUT;
1571e48354ceSNicholas Bellinger 		cmd->i_state		= ISTATE_SEND_NOPIN;
1572e48354ceSNicholas Bellinger 		cmd->immediate_cmd	= ((hdr->opcode & ISCSI_OP_IMMEDIATE) ?
1573e48354ceSNicholas Bellinger 						1 : 0);
1574e48354ceSNicholas Bellinger 		conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
1575e48354ceSNicholas Bellinger 		cmd->targ_xfer_tag	= 0xFFFFFFFF;
157650e5c87dSChristoph Hellwig 		cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
157750e5c87dSChristoph Hellwig 		cmd->exp_stat_sn	= be32_to_cpu(hdr->exp_statsn);
1578e48354ceSNicholas Bellinger 		cmd->data_direction	= DMA_NONE;
1579e48354ceSNicholas Bellinger 	}
1580e48354ceSNicholas Bellinger 
1581778de368SNicholas Bellinger 	return 0;
1582778de368SNicholas Bellinger }
1583778de368SNicholas Bellinger EXPORT_SYMBOL(iscsit_setup_nop_out);
1584778de368SNicholas Bellinger 
1585778de368SNicholas Bellinger int iscsit_process_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
1586778de368SNicholas Bellinger 			   struct iscsi_nopout *hdr)
1587778de368SNicholas Bellinger {
1588778de368SNicholas Bellinger 	struct iscsi_cmd *cmd_p = NULL;
1589778de368SNicholas Bellinger 	int cmdsn_ret = 0;
1590778de368SNicholas Bellinger 	/*
1591778de368SNicholas Bellinger 	 * Initiator is expecting a NopIN ping reply..
1592778de368SNicholas Bellinger 	 */
1593778de368SNicholas Bellinger 	if (hdr->itt != RESERVED_ITT) {
15947cbfcc95SNicholas Bellinger 		if (!cmd)
15957cbfcc95SNicholas Bellinger 			return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
15967cbfcc95SNicholas Bellinger 						(unsigned char *)hdr);
1597778de368SNicholas Bellinger 
1598778de368SNicholas Bellinger 		spin_lock_bh(&conn->cmd_lock);
1599778de368SNicholas Bellinger 		list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
1600778de368SNicholas Bellinger 		spin_unlock_bh(&conn->cmd_lock);
1601778de368SNicholas Bellinger 
1602778de368SNicholas Bellinger 		iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
1603778de368SNicholas Bellinger 
1604778de368SNicholas Bellinger 		if (hdr->opcode & ISCSI_OP_IMMEDIATE) {
1605778de368SNicholas Bellinger 			iscsit_add_cmd_to_response_queue(cmd, conn,
1606778de368SNicholas Bellinger 							 cmd->i_state);
1607778de368SNicholas Bellinger 			return 0;
1608778de368SNicholas Bellinger 		}
1609778de368SNicholas Bellinger 
1610561bf158SNicholas Bellinger 		cmdsn_ret = iscsit_sequence_cmd(conn, cmd,
1611561bf158SNicholas Bellinger 				(unsigned char *)hdr, hdr->cmdsn);
1612778de368SNicholas Bellinger                 if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
1613778de368SNicholas Bellinger 			return 0;
1614778de368SNicholas Bellinger 		if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
1615ba159914SNicholas Bellinger 			return -1;
1616778de368SNicholas Bellinger 
1617778de368SNicholas Bellinger 		return 0;
1618778de368SNicholas Bellinger 	}
1619778de368SNicholas Bellinger 	/*
1620778de368SNicholas Bellinger 	 * This was a response to a unsolicited NOPIN ping.
1621778de368SNicholas Bellinger 	 */
1622778de368SNicholas Bellinger 	if (hdr->ttt != cpu_to_be32(0xFFFFFFFF)) {
1623778de368SNicholas Bellinger 		cmd_p = iscsit_find_cmd_from_ttt(conn, be32_to_cpu(hdr->ttt));
1624778de368SNicholas Bellinger 		if (!cmd_p)
1625778de368SNicholas Bellinger 			return -EINVAL;
1626778de368SNicholas Bellinger 
1627778de368SNicholas Bellinger 		iscsit_stop_nopin_response_timer(conn);
1628778de368SNicholas Bellinger 
1629778de368SNicholas Bellinger 		cmd_p->i_state = ISTATE_REMOVE;
1630778de368SNicholas Bellinger 		iscsit_add_cmd_to_immediate_queue(cmd_p, conn, cmd_p->i_state);
1631778de368SNicholas Bellinger 
1632778de368SNicholas Bellinger 		iscsit_start_nopin_timer(conn);
1633778de368SNicholas Bellinger 		return 0;
1634778de368SNicholas Bellinger 	}
1635778de368SNicholas Bellinger 	/*
1636778de368SNicholas Bellinger 	 * Otherwise, initiator is not expecting a NOPIN is response.
1637778de368SNicholas Bellinger 	 * Just ignore for now.
1638778de368SNicholas Bellinger 	 */
1639778de368SNicholas Bellinger         return 0;
1640778de368SNicholas Bellinger }
1641778de368SNicholas Bellinger EXPORT_SYMBOL(iscsit_process_nop_out);
1642778de368SNicholas Bellinger 
1643778de368SNicholas Bellinger static int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
1644778de368SNicholas Bellinger 				 unsigned char *buf)
1645778de368SNicholas Bellinger {
1646778de368SNicholas Bellinger 	unsigned char *ping_data = NULL;
1647778de368SNicholas Bellinger 	struct iscsi_nopout *hdr = (struct iscsi_nopout *)buf;
1648778de368SNicholas Bellinger 	struct kvec *iov = NULL;
1649778de368SNicholas Bellinger 	u32 payload_length = ntoh24(hdr->dlength);
1650778de368SNicholas Bellinger 	int ret;
1651778de368SNicholas Bellinger 
1652778de368SNicholas Bellinger 	ret = iscsit_setup_nop_out(conn, cmd, hdr);
1653778de368SNicholas Bellinger 	if (ret < 0)
1654561bf158SNicholas Bellinger 		return 0;
1655778de368SNicholas Bellinger 	/*
1656778de368SNicholas Bellinger 	 * Handle NOP-OUT payload for traditional iSCSI sockets
1657778de368SNicholas Bellinger 	 */
165850e5c87dSChristoph Hellwig 	if (payload_length && hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
1659778de368SNicholas Bellinger 		u32 checksum, data_crc, padding = 0;
1660778de368SNicholas Bellinger 		int niov = 0, rx_got, rx_size = payload_length;
1661778de368SNicholas Bellinger 
1662e48354ceSNicholas Bellinger 		ping_data = kzalloc(payload_length + 1, GFP_KERNEL);
1663e48354ceSNicholas Bellinger 		if (!ping_data) {
1664e48354ceSNicholas Bellinger 			pr_err("Unable to allocate memory for"
1665e48354ceSNicholas Bellinger 				" NOPOUT ping data.\n");
1666e48354ceSNicholas Bellinger 			ret = -1;
1667e48354ceSNicholas Bellinger 			goto out;
1668e48354ceSNicholas Bellinger 		}
1669e48354ceSNicholas Bellinger 
1670e48354ceSNicholas Bellinger 		iov = &cmd->iov_misc[0];
1671e48354ceSNicholas Bellinger 		iov[niov].iov_base	= ping_data;
1672e48354ceSNicholas Bellinger 		iov[niov++].iov_len	= payload_length;
1673e48354ceSNicholas Bellinger 
1674e48354ceSNicholas Bellinger 		padding = ((-payload_length) & 3);
1675e48354ceSNicholas Bellinger 		if (padding != 0) {
1676e48354ceSNicholas Bellinger 			pr_debug("Receiving %u additional bytes"
1677e48354ceSNicholas Bellinger 				" for padding.\n", padding);
1678e48354ceSNicholas Bellinger 			iov[niov].iov_base	= &cmd->pad_bytes;
1679e48354ceSNicholas Bellinger 			iov[niov++].iov_len	= padding;
1680e48354ceSNicholas Bellinger 			rx_size += padding;
1681e48354ceSNicholas Bellinger 		}
1682e48354ceSNicholas Bellinger 		if (conn->conn_ops->DataDigest) {
1683e48354ceSNicholas Bellinger 			iov[niov].iov_base	= &checksum;
1684e48354ceSNicholas Bellinger 			iov[niov++].iov_len	= ISCSI_CRC_LEN;
1685e48354ceSNicholas Bellinger 			rx_size += ISCSI_CRC_LEN;
1686e48354ceSNicholas Bellinger 		}
1687e48354ceSNicholas Bellinger 
1688e48354ceSNicholas Bellinger 		rx_got = rx_data(conn, &cmd->iov_misc[0], niov, rx_size);
1689e48354ceSNicholas Bellinger 		if (rx_got != rx_size) {
1690e48354ceSNicholas Bellinger 			ret = -1;
1691e48354ceSNicholas Bellinger 			goto out;
1692e48354ceSNicholas Bellinger 		}
1693e48354ceSNicholas Bellinger 
1694e48354ceSNicholas Bellinger 		if (conn->conn_ops->DataDigest) {
1695e48354ceSNicholas Bellinger 			iscsit_do_crypto_hash_buf(&conn->conn_rx_hash,
1696e48354ceSNicholas Bellinger 					ping_data, payload_length,
1697e48354ceSNicholas Bellinger 					padding, cmd->pad_bytes,
1698e48354ceSNicholas Bellinger 					(u8 *)&data_crc);
1699e48354ceSNicholas Bellinger 
1700e48354ceSNicholas Bellinger 			if (checksum != data_crc) {
1701e48354ceSNicholas Bellinger 				pr_err("Ping data CRC32C DataDigest"
1702e48354ceSNicholas Bellinger 				" 0x%08x does not match computed 0x%08x\n",
1703e48354ceSNicholas Bellinger 					checksum, data_crc);
1704e48354ceSNicholas Bellinger 				if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
1705e48354ceSNicholas Bellinger 					pr_err("Unable to recover from"
1706e48354ceSNicholas Bellinger 					" NOPOUT Ping DataCRC failure while in"
1707e48354ceSNicholas Bellinger 						" ERL=0.\n");
1708e48354ceSNicholas Bellinger 					ret = -1;
1709e48354ceSNicholas Bellinger 					goto out;
1710e48354ceSNicholas Bellinger 				} else {
1711e48354ceSNicholas Bellinger 					/*
1712e48354ceSNicholas Bellinger 					 * Silently drop this PDU and let the
1713e48354ceSNicholas Bellinger 					 * initiator plug the CmdSN gap.
1714e48354ceSNicholas Bellinger 					 */
1715e48354ceSNicholas Bellinger 					pr_debug("Dropping NOPOUT"
1716e48354ceSNicholas Bellinger 					" Command CmdSN: 0x%08x due to"
1717e48354ceSNicholas Bellinger 					" DataCRC error.\n", hdr->cmdsn);
1718e48354ceSNicholas Bellinger 					ret = 0;
1719e48354ceSNicholas Bellinger 					goto out;
1720e48354ceSNicholas Bellinger 				}
1721e48354ceSNicholas Bellinger 			} else {
1722e48354ceSNicholas Bellinger 				pr_debug("Got CRC32C DataDigest"
1723e48354ceSNicholas Bellinger 				" 0x%08x for %u bytes of ping data.\n",
1724e48354ceSNicholas Bellinger 					checksum, payload_length);
1725e48354ceSNicholas Bellinger 			}
1726e48354ceSNicholas Bellinger 		}
1727e48354ceSNicholas Bellinger 
1728e48354ceSNicholas Bellinger 		ping_data[payload_length] = '\0';
1729e48354ceSNicholas Bellinger 		/*
1730e48354ceSNicholas Bellinger 		 * Attach ping data to struct iscsi_cmd->buf_ptr.
1731e48354ceSNicholas Bellinger 		 */
17328359cf43SJörn Engel 		cmd->buf_ptr = ping_data;
1733e48354ceSNicholas Bellinger 		cmd->buf_ptr_size = payload_length;
1734e48354ceSNicholas Bellinger 
1735e48354ceSNicholas Bellinger 		pr_debug("Got %u bytes of NOPOUT ping"
1736e48354ceSNicholas Bellinger 			" data.\n", payload_length);
1737e48354ceSNicholas Bellinger 		pr_debug("Ping Data: \"%s\"\n", ping_data);
1738e48354ceSNicholas Bellinger 	}
1739e48354ceSNicholas Bellinger 
1740778de368SNicholas Bellinger 	return iscsit_process_nop_out(conn, cmd, hdr);
1741e48354ceSNicholas Bellinger out:
1742e48354ceSNicholas Bellinger 	if (cmd)
1743aafc9d15SNicholas Bellinger 		iscsit_free_cmd(cmd, false);
1744778de368SNicholas Bellinger 
1745e48354ceSNicholas Bellinger 	kfree(ping_data);
1746e48354ceSNicholas Bellinger 	return ret;
1747e48354ceSNicholas Bellinger }
1748e48354ceSNicholas Bellinger 
17493e1c81a9SNicholas Bellinger int
17503e1c81a9SNicholas Bellinger iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
1751e48354ceSNicholas Bellinger 			   unsigned char *buf)
1752e48354ceSNicholas Bellinger {
1753e48354ceSNicholas Bellinger 	struct se_tmr_req *se_tmr;
1754e48354ceSNicholas Bellinger 	struct iscsi_tmr_req *tmr_req;
1755e48354ceSNicholas Bellinger 	struct iscsi_tm *hdr;
1756186a9647SNicholas Bellinger 	int out_of_order_cmdsn = 0, ret;
1757186a9647SNicholas Bellinger 	bool sess_ref = false;
1758e48354ceSNicholas Bellinger 	u8 function;
1759e48354ceSNicholas Bellinger 
1760e48354ceSNicholas Bellinger 	hdr			= (struct iscsi_tm *) buf;
1761e48354ceSNicholas Bellinger 	hdr->flags &= ~ISCSI_FLAG_CMD_FINAL;
1762e48354ceSNicholas Bellinger 	function = hdr->flags;
1763e48354ceSNicholas Bellinger 
1764e48354ceSNicholas Bellinger 	pr_debug("Got Task Management Request ITT: 0x%08x, CmdSN:"
1765e48354ceSNicholas Bellinger 		" 0x%08x, Function: 0x%02x, RefTaskTag: 0x%08x, RefCmdSN:"
1766e48354ceSNicholas Bellinger 		" 0x%08x, CID: %hu\n", hdr->itt, hdr->cmdsn, function,
1767e48354ceSNicholas Bellinger 		hdr->rtt, hdr->refcmdsn, conn->cid);
1768e48354ceSNicholas Bellinger 
1769e48354ceSNicholas Bellinger 	if ((function != ISCSI_TM_FUNC_ABORT_TASK) &&
1770e48354ceSNicholas Bellinger 	    ((function != ISCSI_TM_FUNC_TASK_REASSIGN) &&
177166c7db68SChristoph Hellwig 	     hdr->rtt != RESERVED_ITT)) {
1772e48354ceSNicholas Bellinger 		pr_err("RefTaskTag should be set to 0xFFFFFFFF.\n");
177366c7db68SChristoph Hellwig 		hdr->rtt = RESERVED_ITT;
1774e48354ceSNicholas Bellinger 	}
1775e48354ceSNicholas Bellinger 
1776e48354ceSNicholas Bellinger 	if ((function == ISCSI_TM_FUNC_TASK_REASSIGN) &&
1777e48354ceSNicholas Bellinger 			!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
1778e48354ceSNicholas Bellinger 		pr_err("Task Management Request TASK_REASSIGN not"
1779e48354ceSNicholas Bellinger 			" issued as immediate command, bad iSCSI Initiator"
1780e48354ceSNicholas Bellinger 				"implementation\n");
1781ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1782ba159914SNicholas Bellinger 					     ISCSI_REASON_PROTOCOL_ERROR, buf);
1783e48354ceSNicholas Bellinger 	}
1784e48354ceSNicholas Bellinger 	if ((function != ISCSI_TM_FUNC_ABORT_TASK) &&
178550e5c87dSChristoph Hellwig 	    be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG)
178650e5c87dSChristoph Hellwig 		hdr->refcmdsn = cpu_to_be32(ISCSI_RESERVED_TAG);
1787e48354ceSNicholas Bellinger 
1788d28b1169SAndy Grover 	cmd->data_direction = DMA_NONE;
1789d28b1169SAndy Grover 
1790d28b1169SAndy Grover 	cmd->tmr_req = kzalloc(sizeof(struct iscsi_tmr_req), GFP_KERNEL);
1791d28b1169SAndy Grover 	if (!cmd->tmr_req) {
1792d28b1169SAndy Grover 		pr_err("Unable to allocate memory for"
1793d28b1169SAndy Grover 			" Task Management command!\n");
1794ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1795d28b1169SAndy Grover 					     ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1796ba159914SNicholas Bellinger 					     buf);
1797d28b1169SAndy Grover 	}
1798d28b1169SAndy Grover 
1799d28b1169SAndy Grover 	/*
1800d28b1169SAndy Grover 	 * TASK_REASSIGN for ERL=2 / connection stays inside of
1801d28b1169SAndy Grover 	 * LIO-Target $FABRIC_MOD
1802d28b1169SAndy Grover 	 */
1803d28b1169SAndy Grover 	if (function != ISCSI_TM_FUNC_TASK_REASSIGN) {
1804d28b1169SAndy Grover 
1805d28b1169SAndy Grover 		u8 tcm_function;
1806d28b1169SAndy Grover 		int ret;
1807d28b1169SAndy Grover 
1808d28b1169SAndy Grover 		transport_init_se_cmd(&cmd->se_cmd,
1809d28b1169SAndy Grover 				      &lio_target_fabric_configfs->tf_ops,
1810d28b1169SAndy Grover 				      conn->sess->se_sess, 0, DMA_NONE,
181168d81f40SChristoph Hellwig 				      TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
1812d28b1169SAndy Grover 
1813186a9647SNicholas Bellinger 		target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true);
1814186a9647SNicholas Bellinger 		sess_ref = true;
1815186a9647SNicholas Bellinger 
1816d28b1169SAndy Grover 		switch (function) {
1817d28b1169SAndy Grover 		case ISCSI_TM_FUNC_ABORT_TASK:
1818d28b1169SAndy Grover 			tcm_function = TMR_ABORT_TASK;
1819d28b1169SAndy Grover 			break;
1820d28b1169SAndy Grover 		case ISCSI_TM_FUNC_ABORT_TASK_SET:
1821d28b1169SAndy Grover 			tcm_function = TMR_ABORT_TASK_SET;
1822d28b1169SAndy Grover 			break;
1823d28b1169SAndy Grover 		case ISCSI_TM_FUNC_CLEAR_ACA:
1824d28b1169SAndy Grover 			tcm_function = TMR_CLEAR_ACA;
1825d28b1169SAndy Grover 			break;
1826d28b1169SAndy Grover 		case ISCSI_TM_FUNC_CLEAR_TASK_SET:
1827d28b1169SAndy Grover 			tcm_function = TMR_CLEAR_TASK_SET;
1828d28b1169SAndy Grover 			break;
1829d28b1169SAndy Grover 		case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET:
1830d28b1169SAndy Grover 			tcm_function = TMR_LUN_RESET;
1831d28b1169SAndy Grover 			break;
1832d28b1169SAndy Grover 		case ISCSI_TM_FUNC_TARGET_WARM_RESET:
1833d28b1169SAndy Grover 			tcm_function = TMR_TARGET_WARM_RESET;
1834d28b1169SAndy Grover 			break;
1835d28b1169SAndy Grover 		case ISCSI_TM_FUNC_TARGET_COLD_RESET:
1836d28b1169SAndy Grover 			tcm_function = TMR_TARGET_COLD_RESET;
1837d28b1169SAndy Grover 			break;
1838d28b1169SAndy Grover 		default:
1839d28b1169SAndy Grover 			pr_err("Unknown iSCSI TMR Function:"
1840d28b1169SAndy Grover 			       " 0x%02x\n", function);
1841ba159914SNicholas Bellinger 			return iscsit_add_reject_cmd(cmd,
1842ba159914SNicholas Bellinger 				ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
1843d28b1169SAndy Grover 		}
1844d28b1169SAndy Grover 
1845d28b1169SAndy Grover 		ret = core_tmr_alloc_req(&cmd->se_cmd, cmd->tmr_req,
1846d28b1169SAndy Grover 					 tcm_function, GFP_KERNEL);
1847d28b1169SAndy Grover 		if (ret < 0)
1848ba159914SNicholas Bellinger 			return iscsit_add_reject_cmd(cmd,
1849ba159914SNicholas Bellinger 				ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
1850d28b1169SAndy Grover 
1851d28b1169SAndy Grover 		cmd->tmr_req->se_tmr_req = cmd->se_cmd.se_tmr_req;
1852d28b1169SAndy Grover 	}
1853d28b1169SAndy Grover 
1854e48354ceSNicholas Bellinger 	cmd->iscsi_opcode	= ISCSI_OP_SCSI_TMFUNC;
1855e48354ceSNicholas Bellinger 	cmd->i_state		= ISTATE_SEND_TASKMGTRSP;
1856e48354ceSNicholas Bellinger 	cmd->immediate_cmd	= ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
1857e48354ceSNicholas Bellinger 	cmd->init_task_tag	= hdr->itt;
1858e48354ceSNicholas Bellinger 	cmd->targ_xfer_tag	= 0xFFFFFFFF;
185950e5c87dSChristoph Hellwig 	cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
186050e5c87dSChristoph Hellwig 	cmd->exp_stat_sn	= be32_to_cpu(hdr->exp_statsn);
1861e48354ceSNicholas Bellinger 	se_tmr			= cmd->se_cmd.se_tmr_req;
1862e48354ceSNicholas Bellinger 	tmr_req			= cmd->tmr_req;
1863e48354ceSNicholas Bellinger 	/*
1864e48354ceSNicholas Bellinger 	 * Locate the struct se_lun for all TMRs not related to ERL=2 TASK_REASSIGN
1865e48354ceSNicholas Bellinger 	 */
1866e48354ceSNicholas Bellinger 	if (function != ISCSI_TM_FUNC_TASK_REASSIGN) {
18674f26998aSAndy Grover 		ret = transport_lookup_tmr_lun(&cmd->se_cmd,
18684f26998aSAndy Grover 					       scsilun_to_int(&hdr->lun));
1869e48354ceSNicholas Bellinger 		if (ret < 0) {
1870e48354ceSNicholas Bellinger 			se_tmr->response = ISCSI_TMF_RSP_NO_LUN;
1871e48354ceSNicholas Bellinger 			goto attach;
1872e48354ceSNicholas Bellinger 		}
1873e48354ceSNicholas Bellinger 	}
1874e48354ceSNicholas Bellinger 
1875e48354ceSNicholas Bellinger 	switch (function) {
1876e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_ABORT_TASK:
1877e48354ceSNicholas Bellinger 		se_tmr->response = iscsit_tmr_abort_task(cmd, buf);
1878de103c93SChristoph Hellwig 		if (se_tmr->response)
1879e48354ceSNicholas Bellinger 			goto attach;
1880e48354ceSNicholas Bellinger 		break;
1881e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_ABORT_TASK_SET:
1882e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_CLEAR_ACA:
1883e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_CLEAR_TASK_SET:
1884e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET:
1885e48354ceSNicholas Bellinger 		break;
1886e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_TARGET_WARM_RESET:
1887e48354ceSNicholas Bellinger 		if (iscsit_tmr_task_warm_reset(conn, tmr_req, buf) < 0) {
1888e48354ceSNicholas Bellinger 			se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED;
1889e48354ceSNicholas Bellinger 			goto attach;
1890e48354ceSNicholas Bellinger 		}
1891e48354ceSNicholas Bellinger 		break;
1892e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_TARGET_COLD_RESET:
1893e48354ceSNicholas Bellinger 		if (iscsit_tmr_task_cold_reset(conn, tmr_req, buf) < 0) {
1894e48354ceSNicholas Bellinger 			se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED;
1895e48354ceSNicholas Bellinger 			goto attach;
1896e48354ceSNicholas Bellinger 		}
1897e48354ceSNicholas Bellinger 		break;
1898e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_TASK_REASSIGN:
1899e48354ceSNicholas Bellinger 		se_tmr->response = iscsit_tmr_task_reassign(cmd, buf);
1900e48354ceSNicholas Bellinger 		/*
1901e48354ceSNicholas Bellinger 		 * Perform sanity checks on the ExpDataSN only if the
1902e48354ceSNicholas Bellinger 		 * TASK_REASSIGN was successful.
1903e48354ceSNicholas Bellinger 		 */
1904de103c93SChristoph Hellwig 		if (se_tmr->response)
1905e48354ceSNicholas Bellinger 			break;
1906e48354ceSNicholas Bellinger 
1907e48354ceSNicholas Bellinger 		if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0)
1908ba159914SNicholas Bellinger 			return iscsit_add_reject_cmd(cmd,
1909ba159914SNicholas Bellinger 					ISCSI_REASON_BOOKMARK_INVALID, buf);
1910e48354ceSNicholas Bellinger 		break;
1911e48354ceSNicholas Bellinger 	default:
1912e48354ceSNicholas Bellinger 		pr_err("Unknown TMR function: 0x%02x, protocol"
1913e48354ceSNicholas Bellinger 			" error.\n", function);
1914e48354ceSNicholas Bellinger 		se_tmr->response = ISCSI_TMF_RSP_NOT_SUPPORTED;
1915e48354ceSNicholas Bellinger 		goto attach;
1916e48354ceSNicholas Bellinger 	}
1917e48354ceSNicholas Bellinger 
1918e48354ceSNicholas Bellinger 	if ((function != ISCSI_TM_FUNC_TASK_REASSIGN) &&
1919e48354ceSNicholas Bellinger 	    (se_tmr->response == ISCSI_TMF_RSP_COMPLETE))
1920e48354ceSNicholas Bellinger 		se_tmr->call_transport = 1;
1921e48354ceSNicholas Bellinger attach:
1922e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
19232fbb471eSAndy Grover 	list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
1924e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
1925e48354ceSNicholas Bellinger 
1926e48354ceSNicholas Bellinger 	if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
1927561bf158SNicholas Bellinger 		int cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn);
1928e48354ceSNicholas Bellinger 		if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP)
1929e48354ceSNicholas Bellinger 			out_of_order_cmdsn = 1;
19305a4c8666SNicholas Bellinger 		else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
1931e48354ceSNicholas Bellinger 			return 0;
19325a4c8666SNicholas Bellinger 		else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
1933ba159914SNicholas Bellinger 			return -1;
1934e48354ceSNicholas Bellinger 	}
193550e5c87dSChristoph Hellwig 	iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
1936e48354ceSNicholas Bellinger 
19375a4c8666SNicholas Bellinger 	if (out_of_order_cmdsn || !(hdr->opcode & ISCSI_OP_IMMEDIATE))
1938e48354ceSNicholas Bellinger 		return 0;
1939e48354ceSNicholas Bellinger 	/*
1940e48354ceSNicholas Bellinger 	 * Found the referenced task, send to transport for processing.
1941e48354ceSNicholas Bellinger 	 */
1942e48354ceSNicholas Bellinger 	if (se_tmr->call_transport)
1943e48354ceSNicholas Bellinger 		return transport_generic_handle_tmr(&cmd->se_cmd);
1944e48354ceSNicholas Bellinger 
1945e48354ceSNicholas Bellinger 	/*
1946e48354ceSNicholas Bellinger 	 * Could not find the referenced LUN, task, or Task Management
1947e48354ceSNicholas Bellinger 	 * command not authorized or supported.  Change state and
1948e48354ceSNicholas Bellinger 	 * let the tx_thread send the response.
1949e48354ceSNicholas Bellinger 	 *
1950e48354ceSNicholas Bellinger 	 * For connection recovery, this is also the default action for
1951e48354ceSNicholas Bellinger 	 * TMR TASK_REASSIGN.
1952e48354ceSNicholas Bellinger 	 */
1953186a9647SNicholas Bellinger 	if (sess_ref) {
1954186a9647SNicholas Bellinger 		pr_debug("Handle TMR, using sess_ref=true check\n");
1955186a9647SNicholas Bellinger 		target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
1956186a9647SNicholas Bellinger 	}
1957186a9647SNicholas Bellinger 
1958e48354ceSNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
1959e48354ceSNicholas Bellinger 	return 0;
1960e48354ceSNicholas Bellinger }
19613e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_handle_task_mgt_cmd);
1962e48354ceSNicholas Bellinger 
1963e48354ceSNicholas Bellinger /* #warning FIXME: Support Text Command parameters besides SendTargets */
196464534aa7SNicholas Bellinger int
196564534aa7SNicholas Bellinger iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
196664534aa7SNicholas Bellinger 		      struct iscsi_text *hdr)
1967e48354ceSNicholas Bellinger {
196864534aa7SNicholas Bellinger 	u32 payload_length = ntoh24(hdr->dlength);
1969e48354ceSNicholas Bellinger 
197021f5aa7eSNicholas Bellinger 	if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
1971e48354ceSNicholas Bellinger 		pr_err("Unable to accept text parameter length: %u"
197221f5aa7eSNicholas Bellinger 			"greater than MaxXmitDataSegmentLength %u.\n",
197321f5aa7eSNicholas Bellinger 		       payload_length, conn->conn_ops->MaxXmitDataSegmentLength);
1974ba159914SNicholas Bellinger 		return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
1975ba159914SNicholas Bellinger 					 (unsigned char *)hdr);
1976e48354ceSNicholas Bellinger 	}
1977e48354ceSNicholas Bellinger 
1978122f8afcSNicholas Bellinger 	if (!(hdr->flags & ISCSI_FLAG_CMD_FINAL) ||
1979122f8afcSNicholas Bellinger 	     (hdr->flags & ISCSI_FLAG_TEXT_CONTINUE)) {
1980122f8afcSNicholas Bellinger 		pr_err("Multi sequence text commands currently not supported\n");
1981122f8afcSNicholas Bellinger 		return iscsit_reject_cmd(cmd, ISCSI_REASON_CMD_NOT_SUPPORTED,
1982122f8afcSNicholas Bellinger 					(unsigned char *)hdr);
1983122f8afcSNicholas Bellinger 	}
1984122f8afcSNicholas Bellinger 
1985e48354ceSNicholas Bellinger 	pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x,"
1986e48354ceSNicholas Bellinger 		" ExpStatSN: 0x%08x, Length: %u\n", hdr->itt, hdr->cmdsn,
1987e48354ceSNicholas Bellinger 		hdr->exp_statsn, payload_length);
1988e48354ceSNicholas Bellinger 
198964534aa7SNicholas Bellinger 	cmd->iscsi_opcode	= ISCSI_OP_TEXT;
199064534aa7SNicholas Bellinger 	cmd->i_state		= ISTATE_SEND_TEXTRSP;
199164534aa7SNicholas Bellinger 	cmd->immediate_cmd	= ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
199264534aa7SNicholas Bellinger 	conn->sess->init_task_tag = cmd->init_task_tag  = hdr->itt;
199364534aa7SNicholas Bellinger 	cmd->targ_xfer_tag	= 0xFFFFFFFF;
199464534aa7SNicholas Bellinger 	cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
199564534aa7SNicholas Bellinger 	cmd->exp_stat_sn	= be32_to_cpu(hdr->exp_statsn);
199664534aa7SNicholas Bellinger 	cmd->data_direction	= DMA_NONE;
1997e4f4e801SSagi Grimberg 	cmd->text_in_ptr	= NULL;
199864534aa7SNicholas Bellinger 
199964534aa7SNicholas Bellinger 	return 0;
200064534aa7SNicholas Bellinger }
200164534aa7SNicholas Bellinger EXPORT_SYMBOL(iscsit_setup_text_cmd);
200264534aa7SNicholas Bellinger 
200364534aa7SNicholas Bellinger int
200464534aa7SNicholas Bellinger iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
200564534aa7SNicholas Bellinger 			struct iscsi_text *hdr)
200664534aa7SNicholas Bellinger {
20079864ca9dSNicholas Bellinger 	unsigned char *text_in = cmd->text_in_ptr, *text_ptr;
200864534aa7SNicholas Bellinger 	int cmdsn_ret;
200964534aa7SNicholas Bellinger 
20109864ca9dSNicholas Bellinger 	if (!text_in) {
2011e4f4e801SSagi Grimberg 		cmd->targ_xfer_tag = be32_to_cpu(hdr->ttt);
2012e4f4e801SSagi Grimberg 		if (cmd->targ_xfer_tag == 0xFFFFFFFF) {
20139864ca9dSNicholas Bellinger 			pr_err("Unable to locate text_in buffer for sendtargets"
20149864ca9dSNicholas Bellinger 			       " discovery\n");
20159864ca9dSNicholas Bellinger 			goto reject;
20169864ca9dSNicholas Bellinger 		}
2017e4f4e801SSagi Grimberg 		goto empty_sendtargets;
2018e4f4e801SSagi Grimberg 	}
20199864ca9dSNicholas Bellinger 	if (strncmp("SendTargets", text_in, 11) != 0) {
20209864ca9dSNicholas Bellinger 		pr_err("Received Text Data that is not"
20219864ca9dSNicholas Bellinger 			" SendTargets, cannot continue.\n");
20229864ca9dSNicholas Bellinger 		goto reject;
20239864ca9dSNicholas Bellinger 	}
20249864ca9dSNicholas Bellinger 	text_ptr = strchr(text_in, '=');
20259864ca9dSNicholas Bellinger 	if (!text_ptr) {
20269864ca9dSNicholas Bellinger 		pr_err("No \"=\" separator found in Text Data,"
20279864ca9dSNicholas Bellinger 			"  cannot continue.\n");
20289864ca9dSNicholas Bellinger 		goto reject;
20299864ca9dSNicholas Bellinger 	}
20309864ca9dSNicholas Bellinger 	if (!strncmp("=All", text_ptr, 4)) {
20318060b8ddSAndy Grover 		cmd->cmd_flags |= ICF_SENDTARGETS_ALL;
20326665889cSNicholas Bellinger 	} else if (!strncmp("=iqn.", text_ptr, 5) ||
20336665889cSNicholas Bellinger 		   !strncmp("=eui.", text_ptr, 5)) {
20348060b8ddSAndy Grover 		cmd->cmd_flags |= ICF_SENDTARGETS_SINGLE;
20359864ca9dSNicholas Bellinger 	} else {
20369864ca9dSNicholas Bellinger 		pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr);
20379864ca9dSNicholas Bellinger 		goto reject;
20389864ca9dSNicholas Bellinger 	}
20399864ca9dSNicholas Bellinger 
204064534aa7SNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
204164534aa7SNicholas Bellinger 	list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
204264534aa7SNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
204364534aa7SNicholas Bellinger 
2044e4f4e801SSagi Grimberg empty_sendtargets:
204564534aa7SNicholas Bellinger 	iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
204664534aa7SNicholas Bellinger 
204764534aa7SNicholas Bellinger 	if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
2048561bf158SNicholas Bellinger 		cmdsn_ret = iscsit_sequence_cmd(conn, cmd,
2049561bf158SNicholas Bellinger 				(unsigned char *)hdr, hdr->cmdsn);
205064534aa7SNicholas Bellinger 		if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
2051ba159914SNicholas Bellinger 			return -1;
2052ba159914SNicholas Bellinger 
205364534aa7SNicholas Bellinger 		return 0;
205464534aa7SNicholas Bellinger 	}
205564534aa7SNicholas Bellinger 
205664534aa7SNicholas Bellinger 	return iscsit_execute_cmd(cmd, 0);
20579864ca9dSNicholas Bellinger 
20589864ca9dSNicholas Bellinger reject:
2059ba159914SNicholas Bellinger 	return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
2060ba159914SNicholas Bellinger 				 (unsigned char *)hdr);
206164534aa7SNicholas Bellinger }
206264534aa7SNicholas Bellinger EXPORT_SYMBOL(iscsit_process_text_cmd);
206364534aa7SNicholas Bellinger 
206464534aa7SNicholas Bellinger static int
206564534aa7SNicholas Bellinger iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
206664534aa7SNicholas Bellinger 		       unsigned char *buf)
206764534aa7SNicholas Bellinger {
206864534aa7SNicholas Bellinger 	struct iscsi_text *hdr = (struct iscsi_text *)buf;
206964534aa7SNicholas Bellinger 	char *text_in = NULL;
207064534aa7SNicholas Bellinger 	u32 payload_length = ntoh24(hdr->dlength);
207164534aa7SNicholas Bellinger 	int rx_size, rc;
207264534aa7SNicholas Bellinger 
207364534aa7SNicholas Bellinger 	rc = iscsit_setup_text_cmd(conn, cmd, hdr);
207464534aa7SNicholas Bellinger 	if (rc < 0)
2075561bf158SNicholas Bellinger 		return 0;
207664534aa7SNicholas Bellinger 
207764534aa7SNicholas Bellinger 	rx_size = payload_length;
207864534aa7SNicholas Bellinger 	if (payload_length) {
207964534aa7SNicholas Bellinger 		u32 checksum = 0, data_crc = 0;
208064534aa7SNicholas Bellinger 		u32 padding = 0, pad_bytes = 0;
208164534aa7SNicholas Bellinger 		int niov = 0, rx_got;
208264534aa7SNicholas Bellinger 		struct kvec iov[3];
208364534aa7SNicholas Bellinger 
208464534aa7SNicholas Bellinger 		text_in = kzalloc(payload_length, GFP_KERNEL);
2085e48354ceSNicholas Bellinger 		if (!text_in) {
2086e48354ceSNicholas Bellinger 			pr_err("Unable to allocate memory for"
2087e48354ceSNicholas Bellinger 				" incoming text parameters\n");
208864534aa7SNicholas Bellinger 			goto reject;
2089e48354ceSNicholas Bellinger 		}
20909864ca9dSNicholas Bellinger 		cmd->text_in_ptr = text_in;
2091e48354ceSNicholas Bellinger 
2092e48354ceSNicholas Bellinger 		memset(iov, 0, 3 * sizeof(struct kvec));
2093e48354ceSNicholas Bellinger 		iov[niov].iov_base	= text_in;
209464534aa7SNicholas Bellinger 		iov[niov++].iov_len	= payload_length;
2095e48354ceSNicholas Bellinger 
2096e48354ceSNicholas Bellinger 		padding = ((-payload_length) & 3);
2097e48354ceSNicholas Bellinger 		if (padding != 0) {
209876f1928eSNicholas Bellinger 			iov[niov].iov_base = &pad_bytes;
2099e48354ceSNicholas Bellinger 			iov[niov++].iov_len  = padding;
2100e48354ceSNicholas Bellinger 			rx_size += padding;
2101e48354ceSNicholas Bellinger 			pr_debug("Receiving %u additional bytes"
2102e48354ceSNicholas Bellinger 					" for padding.\n", padding);
2103e48354ceSNicholas Bellinger 		}
2104e48354ceSNicholas Bellinger 		if (conn->conn_ops->DataDigest) {
2105e48354ceSNicholas Bellinger 			iov[niov].iov_base	= &checksum;
2106e48354ceSNicholas Bellinger 			iov[niov++].iov_len	= ISCSI_CRC_LEN;
2107e48354ceSNicholas Bellinger 			rx_size += ISCSI_CRC_LEN;
2108e48354ceSNicholas Bellinger 		}
2109e48354ceSNicholas Bellinger 
2110e48354ceSNicholas Bellinger 		rx_got = rx_data(conn, &iov[0], niov, rx_size);
211164534aa7SNicholas Bellinger 		if (rx_got != rx_size)
211264534aa7SNicholas Bellinger 			goto reject;
2113e48354ceSNicholas Bellinger 
2114e48354ceSNicholas Bellinger 		if (conn->conn_ops->DataDigest) {
2115e48354ceSNicholas Bellinger 			iscsit_do_crypto_hash_buf(&conn->conn_rx_hash,
211664534aa7SNicholas Bellinger 					text_in, payload_length,
211776f1928eSNicholas Bellinger 					padding, (u8 *)&pad_bytes,
2118e48354ceSNicholas Bellinger 					(u8 *)&data_crc);
2119e48354ceSNicholas Bellinger 
2120e48354ceSNicholas Bellinger 			if (checksum != data_crc) {
2121e48354ceSNicholas Bellinger 				pr_err("Text data CRC32C DataDigest"
2122e48354ceSNicholas Bellinger 					" 0x%08x does not match computed"
2123e48354ceSNicholas Bellinger 					" 0x%08x\n", checksum, data_crc);
2124e48354ceSNicholas Bellinger 				if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
2125e48354ceSNicholas Bellinger 					pr_err("Unable to recover from"
2126e48354ceSNicholas Bellinger 					" Text Data digest failure while in"
2127e48354ceSNicholas Bellinger 						" ERL=0.\n");
212864534aa7SNicholas Bellinger 					goto reject;
2129e48354ceSNicholas Bellinger 				} else {
2130e48354ceSNicholas Bellinger 					/*
2131e48354ceSNicholas Bellinger 					 * Silently drop this PDU and let the
2132e48354ceSNicholas Bellinger 					 * initiator plug the CmdSN gap.
2133e48354ceSNicholas Bellinger 					 */
2134e48354ceSNicholas Bellinger 					pr_debug("Dropping Text"
2135e48354ceSNicholas Bellinger 					" Command CmdSN: 0x%08x due to"
2136e48354ceSNicholas Bellinger 					" DataCRC error.\n", hdr->cmdsn);
2137e48354ceSNicholas Bellinger 					kfree(text_in);
2138e48354ceSNicholas Bellinger 					return 0;
2139e48354ceSNicholas Bellinger 				}
2140e48354ceSNicholas Bellinger 			} else {
2141e48354ceSNicholas Bellinger 				pr_debug("Got CRC32C DataDigest"
2142e48354ceSNicholas Bellinger 					" 0x%08x for %u bytes of text data.\n",
214364534aa7SNicholas Bellinger 						checksum, payload_length);
2144e48354ceSNicholas Bellinger 			}
2145e48354ceSNicholas Bellinger 		}
214664534aa7SNicholas Bellinger 		text_in[payload_length - 1] = '\0';
2147e48354ceSNicholas Bellinger 		pr_debug("Successfully read %d bytes of text"
214864534aa7SNicholas Bellinger 				" data.\n", payload_length);
2149e48354ceSNicholas Bellinger 	}
2150e48354ceSNicholas Bellinger 
215164534aa7SNicholas Bellinger 	return iscsit_process_text_cmd(conn, cmd, hdr);
2152e48354ceSNicholas Bellinger 
215364534aa7SNicholas Bellinger reject:
21549864ca9dSNicholas Bellinger 	kfree(cmd->text_in_ptr);
21559864ca9dSNicholas Bellinger 	cmd->text_in_ptr = NULL;
2156ba159914SNicholas Bellinger 	return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf);
2157e48354ceSNicholas Bellinger }
215864534aa7SNicholas Bellinger EXPORT_SYMBOL(iscsit_handle_text_cmd);
2159e48354ceSNicholas Bellinger 
2160e48354ceSNicholas Bellinger int iscsit_logout_closesession(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
2161e48354ceSNicholas Bellinger {
2162e48354ceSNicholas Bellinger 	struct iscsi_conn *conn_p;
2163e48354ceSNicholas Bellinger 	struct iscsi_session *sess = conn->sess;
2164e48354ceSNicholas Bellinger 
2165e48354ceSNicholas Bellinger 	pr_debug("Received logout request CLOSESESSION on CID: %hu"
2166e48354ceSNicholas Bellinger 		" for SID: %u.\n", conn->cid, conn->sess->sid);
2167e48354ceSNicholas Bellinger 
2168e48354ceSNicholas Bellinger 	atomic_set(&sess->session_logout, 1);
2169e48354ceSNicholas Bellinger 	atomic_set(&conn->conn_logout_remove, 1);
2170e48354ceSNicholas Bellinger 	conn->conn_logout_reason = ISCSI_LOGOUT_REASON_CLOSE_SESSION;
2171e48354ceSNicholas Bellinger 
2172e48354ceSNicholas Bellinger 	iscsit_inc_conn_usage_count(conn);
2173e48354ceSNicholas Bellinger 	iscsit_inc_session_usage_count(sess);
2174e48354ceSNicholas Bellinger 
2175e48354ceSNicholas Bellinger 	spin_lock_bh(&sess->conn_lock);
2176e48354ceSNicholas Bellinger 	list_for_each_entry(conn_p, &sess->sess_conn_list, conn_list) {
2177e48354ceSNicholas Bellinger 		if (conn_p->conn_state != TARG_CONN_STATE_LOGGED_IN)
2178e48354ceSNicholas Bellinger 			continue;
2179e48354ceSNicholas Bellinger 
2180e48354ceSNicholas Bellinger 		pr_debug("Moving to TARG_CONN_STATE_IN_LOGOUT.\n");
2181e48354ceSNicholas Bellinger 		conn_p->conn_state = TARG_CONN_STATE_IN_LOGOUT;
2182e48354ceSNicholas Bellinger 	}
2183e48354ceSNicholas Bellinger 	spin_unlock_bh(&sess->conn_lock);
2184e48354ceSNicholas Bellinger 
2185e48354ceSNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2186e48354ceSNicholas Bellinger 
2187e48354ceSNicholas Bellinger 	return 0;
2188e48354ceSNicholas Bellinger }
2189e48354ceSNicholas Bellinger 
2190e48354ceSNicholas Bellinger int iscsit_logout_closeconnection(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
2191e48354ceSNicholas Bellinger {
2192e48354ceSNicholas Bellinger 	struct iscsi_conn *l_conn;
2193e48354ceSNicholas Bellinger 	struct iscsi_session *sess = conn->sess;
2194e48354ceSNicholas Bellinger 
2195e48354ceSNicholas Bellinger 	pr_debug("Received logout request CLOSECONNECTION for CID:"
2196e48354ceSNicholas Bellinger 		" %hu on CID: %hu.\n", cmd->logout_cid, conn->cid);
2197e48354ceSNicholas Bellinger 
2198e48354ceSNicholas Bellinger 	/*
2199e48354ceSNicholas Bellinger 	 * A Logout Request with a CLOSECONNECTION reason code for a CID
2200e48354ceSNicholas Bellinger 	 * can arrive on a connection with a differing CID.
2201e48354ceSNicholas Bellinger 	 */
2202e48354ceSNicholas Bellinger 	if (conn->cid == cmd->logout_cid) {
2203e48354ceSNicholas Bellinger 		spin_lock_bh(&conn->state_lock);
2204e48354ceSNicholas Bellinger 		pr_debug("Moving to TARG_CONN_STATE_IN_LOGOUT.\n");
2205e48354ceSNicholas Bellinger 		conn->conn_state = TARG_CONN_STATE_IN_LOGOUT;
2206e48354ceSNicholas Bellinger 
2207e48354ceSNicholas Bellinger 		atomic_set(&conn->conn_logout_remove, 1);
2208e48354ceSNicholas Bellinger 		conn->conn_logout_reason = ISCSI_LOGOUT_REASON_CLOSE_CONNECTION;
2209e48354ceSNicholas Bellinger 		iscsit_inc_conn_usage_count(conn);
2210e48354ceSNicholas Bellinger 
2211e48354ceSNicholas Bellinger 		spin_unlock_bh(&conn->state_lock);
2212e48354ceSNicholas Bellinger 	} else {
2213e48354ceSNicholas Bellinger 		/*
2214e48354ceSNicholas Bellinger 		 * Handle all different cid CLOSECONNECTION requests in
2215e48354ceSNicholas Bellinger 		 * iscsit_logout_post_handler_diffcid() as to give enough
2216e48354ceSNicholas Bellinger 		 * time for any non immediate command's CmdSN to be
2217e48354ceSNicholas Bellinger 		 * acknowledged on the connection in question.
2218e48354ceSNicholas Bellinger 		 *
2219e48354ceSNicholas Bellinger 		 * Here we simply make sure the CID is still around.
2220e48354ceSNicholas Bellinger 		 */
2221e48354ceSNicholas Bellinger 		l_conn = iscsit_get_conn_from_cid(sess,
2222e48354ceSNicholas Bellinger 				cmd->logout_cid);
2223e48354ceSNicholas Bellinger 		if (!l_conn) {
2224e48354ceSNicholas Bellinger 			cmd->logout_response = ISCSI_LOGOUT_CID_NOT_FOUND;
2225e48354ceSNicholas Bellinger 			iscsit_add_cmd_to_response_queue(cmd, conn,
2226e48354ceSNicholas Bellinger 					cmd->i_state);
2227e48354ceSNicholas Bellinger 			return 0;
2228e48354ceSNicholas Bellinger 		}
2229e48354ceSNicholas Bellinger 
2230e48354ceSNicholas Bellinger 		iscsit_dec_conn_usage_count(l_conn);
2231e48354ceSNicholas Bellinger 	}
2232e48354ceSNicholas Bellinger 
2233e48354ceSNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2234e48354ceSNicholas Bellinger 
2235e48354ceSNicholas Bellinger 	return 0;
2236e48354ceSNicholas Bellinger }
2237e48354ceSNicholas Bellinger 
2238e48354ceSNicholas Bellinger int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
2239e48354ceSNicholas Bellinger {
2240e48354ceSNicholas Bellinger 	struct iscsi_session *sess = conn->sess;
2241e48354ceSNicholas Bellinger 
2242e48354ceSNicholas Bellinger 	pr_debug("Received explicit REMOVECONNFORRECOVERY logout for"
2243e48354ceSNicholas Bellinger 		" CID: %hu on CID: %hu.\n", cmd->logout_cid, conn->cid);
2244e48354ceSNicholas Bellinger 
2245e48354ceSNicholas Bellinger 	if (sess->sess_ops->ErrorRecoveryLevel != 2) {
2246e48354ceSNicholas Bellinger 		pr_err("Received Logout Request REMOVECONNFORRECOVERY"
2247e48354ceSNicholas Bellinger 			" while ERL!=2.\n");
2248e48354ceSNicholas Bellinger 		cmd->logout_response = ISCSI_LOGOUT_RECOVERY_UNSUPPORTED;
2249e48354ceSNicholas Bellinger 		iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2250e48354ceSNicholas Bellinger 		return 0;
2251e48354ceSNicholas Bellinger 	}
2252e48354ceSNicholas Bellinger 
2253e48354ceSNicholas Bellinger 	if (conn->cid == cmd->logout_cid) {
2254e48354ceSNicholas Bellinger 		pr_err("Received Logout Request REMOVECONNFORRECOVERY"
2255e48354ceSNicholas Bellinger 			" with CID: %hu on CID: %hu, implementation error.\n",
2256e48354ceSNicholas Bellinger 				cmd->logout_cid, conn->cid);
2257e48354ceSNicholas Bellinger 		cmd->logout_response = ISCSI_LOGOUT_CLEANUP_FAILED;
2258e48354ceSNicholas Bellinger 		iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2259e48354ceSNicholas Bellinger 		return 0;
2260e48354ceSNicholas Bellinger 	}
2261e48354ceSNicholas Bellinger 
2262e48354ceSNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2263e48354ceSNicholas Bellinger 
2264e48354ceSNicholas Bellinger 	return 0;
2265e48354ceSNicholas Bellinger }
2266e48354ceSNicholas Bellinger 
22673e1c81a9SNicholas Bellinger int
22683e1c81a9SNicholas Bellinger iscsit_handle_logout_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
2269e48354ceSNicholas Bellinger 			unsigned char *buf)
2270e48354ceSNicholas Bellinger {
2271e48354ceSNicholas Bellinger 	int cmdsn_ret, logout_remove = 0;
2272e48354ceSNicholas Bellinger 	u8 reason_code = 0;
2273e48354ceSNicholas Bellinger 	struct iscsi_logout *hdr;
2274e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn = iscsit_snmp_get_tiqn(conn);
2275e48354ceSNicholas Bellinger 
2276e48354ceSNicholas Bellinger 	hdr			= (struct iscsi_logout *) buf;
2277e48354ceSNicholas Bellinger 	reason_code		= (hdr->flags & 0x7f);
2278e48354ceSNicholas Bellinger 
2279e48354ceSNicholas Bellinger 	if (tiqn) {
2280e48354ceSNicholas Bellinger 		spin_lock(&tiqn->logout_stats.lock);
2281e48354ceSNicholas Bellinger 		if (reason_code == ISCSI_LOGOUT_REASON_CLOSE_SESSION)
2282e48354ceSNicholas Bellinger 			tiqn->logout_stats.normal_logouts++;
2283e48354ceSNicholas Bellinger 		else
2284e48354ceSNicholas Bellinger 			tiqn->logout_stats.abnormal_logouts++;
2285e48354ceSNicholas Bellinger 		spin_unlock(&tiqn->logout_stats.lock);
2286e48354ceSNicholas Bellinger 	}
2287e48354ceSNicholas Bellinger 
2288e48354ceSNicholas Bellinger 	pr_debug("Got Logout Request ITT: 0x%08x CmdSN: 0x%08x"
2289e48354ceSNicholas Bellinger 		" ExpStatSN: 0x%08x Reason: 0x%02x CID: %hu on CID: %hu\n",
2290e48354ceSNicholas Bellinger 		hdr->itt, hdr->cmdsn, hdr->exp_statsn, reason_code,
2291e48354ceSNicholas Bellinger 		hdr->cid, conn->cid);
2292e48354ceSNicholas Bellinger 
2293e48354ceSNicholas Bellinger 	if (conn->conn_state != TARG_CONN_STATE_LOGGED_IN) {
2294e48354ceSNicholas Bellinger 		pr_err("Received logout request on connection that"
2295e48354ceSNicholas Bellinger 			" is not in logged in state, ignoring request.\n");
2296aafc9d15SNicholas Bellinger 		iscsit_free_cmd(cmd, false);
2297e48354ceSNicholas Bellinger 		return 0;
2298e48354ceSNicholas Bellinger 	}
2299e48354ceSNicholas Bellinger 
2300e48354ceSNicholas Bellinger 	cmd->iscsi_opcode       = ISCSI_OP_LOGOUT;
2301e48354ceSNicholas Bellinger 	cmd->i_state            = ISTATE_SEND_LOGOUTRSP;
2302e48354ceSNicholas Bellinger 	cmd->immediate_cmd      = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
2303e48354ceSNicholas Bellinger 	conn->sess->init_task_tag = cmd->init_task_tag  = hdr->itt;
2304e48354ceSNicholas Bellinger 	cmd->targ_xfer_tag      = 0xFFFFFFFF;
230550e5c87dSChristoph Hellwig 	cmd->cmd_sn             = be32_to_cpu(hdr->cmdsn);
230650e5c87dSChristoph Hellwig 	cmd->exp_stat_sn        = be32_to_cpu(hdr->exp_statsn);
230750e5c87dSChristoph Hellwig 	cmd->logout_cid         = be16_to_cpu(hdr->cid);
2308e48354ceSNicholas Bellinger 	cmd->logout_reason      = reason_code;
2309e48354ceSNicholas Bellinger 	cmd->data_direction     = DMA_NONE;
2310e48354ceSNicholas Bellinger 
2311e48354ceSNicholas Bellinger 	/*
2312e48354ceSNicholas Bellinger 	 * We need to sleep in these cases (by returning 1) until the Logout
2313e48354ceSNicholas Bellinger 	 * Response gets sent in the tx thread.
2314e48354ceSNicholas Bellinger 	 */
2315e48354ceSNicholas Bellinger 	if ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_SESSION) ||
2316e48354ceSNicholas Bellinger 	   ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_CONNECTION) &&
231750e5c87dSChristoph Hellwig 	    be16_to_cpu(hdr->cid) == conn->cid))
2318e48354ceSNicholas Bellinger 		logout_remove = 1;
2319e48354ceSNicholas Bellinger 
2320e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
23212fbb471eSAndy Grover 	list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
2322e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
2323e48354ceSNicholas Bellinger 
2324e48354ceSNicholas Bellinger 	if (reason_code != ISCSI_LOGOUT_REASON_RECOVERY)
232550e5c87dSChristoph Hellwig 		iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
2326e48354ceSNicholas Bellinger 
2327e48354ceSNicholas Bellinger 	/*
2328e48354ceSNicholas Bellinger 	 * Immediate commands are executed, well, immediately.
2329e48354ceSNicholas Bellinger 	 * Non-Immediate Logout Commands are executed in CmdSN order.
2330e48354ceSNicholas Bellinger 	 */
2331c6037cc5SAndy Grover 	if (cmd->immediate_cmd) {
2332e48354ceSNicholas Bellinger 		int ret = iscsit_execute_cmd(cmd, 0);
2333e48354ceSNicholas Bellinger 
2334e48354ceSNicholas Bellinger 		if (ret < 0)
2335e48354ceSNicholas Bellinger 			return ret;
2336e48354ceSNicholas Bellinger 	} else {
2337561bf158SNicholas Bellinger 		cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn);
2338ba159914SNicholas Bellinger 		if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
2339e48354ceSNicholas Bellinger 			logout_remove = 0;
2340ba159914SNicholas Bellinger 		else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
2341ba159914SNicholas Bellinger 			return -1;
2342e48354ceSNicholas Bellinger 	}
2343e48354ceSNicholas Bellinger 
2344e48354ceSNicholas Bellinger 	return logout_remove;
2345e48354ceSNicholas Bellinger }
23463e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_handle_logout_cmd);
2347e48354ceSNicholas Bellinger 
2348e48354ceSNicholas Bellinger static int iscsit_handle_snack(
2349e48354ceSNicholas Bellinger 	struct iscsi_conn *conn,
2350e48354ceSNicholas Bellinger 	unsigned char *buf)
2351e48354ceSNicholas Bellinger {
2352e48354ceSNicholas Bellinger 	struct iscsi_snack *hdr;
2353e48354ceSNicholas Bellinger 
2354e48354ceSNicholas Bellinger 	hdr			= (struct iscsi_snack *) buf;
2355e48354ceSNicholas Bellinger 	hdr->flags		&= ~ISCSI_FLAG_CMD_FINAL;
2356e48354ceSNicholas Bellinger 
2357e48354ceSNicholas Bellinger 	pr_debug("Got ISCSI_INIT_SNACK, ITT: 0x%08x, ExpStatSN:"
2358e48354ceSNicholas Bellinger 		" 0x%08x, Type: 0x%02x, BegRun: 0x%08x, RunLength: 0x%08x,"
2359e48354ceSNicholas Bellinger 		" CID: %hu\n", hdr->itt, hdr->exp_statsn, hdr->flags,
2360e48354ceSNicholas Bellinger 			hdr->begrun, hdr->runlength, conn->cid);
2361e48354ceSNicholas Bellinger 
2362e48354ceSNicholas Bellinger 	if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
2363e48354ceSNicholas Bellinger 		pr_err("Initiator sent SNACK request while in"
2364e48354ceSNicholas Bellinger 			" ErrorRecoveryLevel=0.\n");
2365ba159914SNicholas Bellinger 		return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
2366ba159914SNicholas Bellinger 					 buf);
2367e48354ceSNicholas Bellinger 	}
2368e48354ceSNicholas Bellinger 	/*
2369e48354ceSNicholas Bellinger 	 * SNACK_DATA and SNACK_R2T are both 0,  so check which function to
2370e48354ceSNicholas Bellinger 	 * call from inside iscsi_send_recovery_datain_or_r2t().
2371e48354ceSNicholas Bellinger 	 */
2372e48354ceSNicholas Bellinger 	switch (hdr->flags & ISCSI_FLAG_SNACK_TYPE_MASK) {
2373e48354ceSNicholas Bellinger 	case 0:
2374e48354ceSNicholas Bellinger 		return iscsit_handle_recovery_datain_or_r2t(conn, buf,
237550e5c87dSChristoph Hellwig 			hdr->itt,
237650e5c87dSChristoph Hellwig 			be32_to_cpu(hdr->ttt),
237750e5c87dSChristoph Hellwig 			be32_to_cpu(hdr->begrun),
237850e5c87dSChristoph Hellwig 			be32_to_cpu(hdr->runlength));
2379e48354ceSNicholas Bellinger 	case ISCSI_FLAG_SNACK_TYPE_STATUS:
238050e5c87dSChristoph Hellwig 		return iscsit_handle_status_snack(conn, hdr->itt,
238150e5c87dSChristoph Hellwig 			be32_to_cpu(hdr->ttt),
238250e5c87dSChristoph Hellwig 			be32_to_cpu(hdr->begrun), be32_to_cpu(hdr->runlength));
2383e48354ceSNicholas Bellinger 	case ISCSI_FLAG_SNACK_TYPE_DATA_ACK:
238450e5c87dSChristoph Hellwig 		return iscsit_handle_data_ack(conn, be32_to_cpu(hdr->ttt),
238550e5c87dSChristoph Hellwig 			be32_to_cpu(hdr->begrun),
238650e5c87dSChristoph Hellwig 			be32_to_cpu(hdr->runlength));
2387e48354ceSNicholas Bellinger 	case ISCSI_FLAG_SNACK_TYPE_RDATA:
2388e48354ceSNicholas Bellinger 		/* FIXME: Support R-Data SNACK */
2389e48354ceSNicholas Bellinger 		pr_err("R-Data SNACK Not Supported.\n");
2390ba159914SNicholas Bellinger 		return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
2391ba159914SNicholas Bellinger 					 buf);
2392e48354ceSNicholas Bellinger 	default:
2393e48354ceSNicholas Bellinger 		pr_err("Unknown SNACK type 0x%02x, protocol"
2394e48354ceSNicholas Bellinger 			" error.\n", hdr->flags & 0x0f);
2395ba159914SNicholas Bellinger 		return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
2396ba159914SNicholas Bellinger 					 buf);
2397e48354ceSNicholas Bellinger 	}
2398e48354ceSNicholas Bellinger 
2399e48354ceSNicholas Bellinger 	return 0;
2400e48354ceSNicholas Bellinger }
2401e48354ceSNicholas Bellinger 
2402e48354ceSNicholas Bellinger static void iscsit_rx_thread_wait_for_tcp(struct iscsi_conn *conn)
2403e48354ceSNicholas Bellinger {
2404e48354ceSNicholas Bellinger 	if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) ||
2405e48354ceSNicholas Bellinger 	    (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) {
2406e48354ceSNicholas Bellinger 		wait_for_completion_interruptible_timeout(
2407e48354ceSNicholas Bellinger 					&conn->rx_half_close_comp,
2408e48354ceSNicholas Bellinger 					ISCSI_RX_THREAD_TCP_TIMEOUT * HZ);
2409e48354ceSNicholas Bellinger 	}
2410e48354ceSNicholas Bellinger }
2411e48354ceSNicholas Bellinger 
2412e48354ceSNicholas Bellinger static int iscsit_handle_immediate_data(
2413e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd,
24143e1c81a9SNicholas Bellinger 	struct iscsi_scsi_req *hdr,
2415e48354ceSNicholas Bellinger 	u32 length)
2416e48354ceSNicholas Bellinger {
2417e48354ceSNicholas Bellinger 	int iov_ret, rx_got = 0, rx_size = 0;
2418e48354ceSNicholas Bellinger 	u32 checksum, iov_count = 0, padding = 0;
2419e48354ceSNicholas Bellinger 	struct iscsi_conn *conn = cmd->conn;
2420e48354ceSNicholas Bellinger 	struct kvec *iov;
2421e48354ceSNicholas Bellinger 
2422e48354ceSNicholas Bellinger 	iov_ret = iscsit_map_iovec(cmd, cmd->iov_data, cmd->write_data_done, length);
2423e48354ceSNicholas Bellinger 	if (iov_ret < 0)
2424e48354ceSNicholas Bellinger 		return IMMEDIATE_DATA_CANNOT_RECOVER;
2425e48354ceSNicholas Bellinger 
2426e48354ceSNicholas Bellinger 	rx_size = length;
2427e48354ceSNicholas Bellinger 	iov_count = iov_ret;
2428e48354ceSNicholas Bellinger 	iov = &cmd->iov_data[0];
2429e48354ceSNicholas Bellinger 
2430e48354ceSNicholas Bellinger 	padding = ((-length) & 3);
2431e48354ceSNicholas Bellinger 	if (padding != 0) {
2432e48354ceSNicholas Bellinger 		iov[iov_count].iov_base	= cmd->pad_bytes;
2433e48354ceSNicholas Bellinger 		iov[iov_count++].iov_len = padding;
2434e48354ceSNicholas Bellinger 		rx_size += padding;
2435e48354ceSNicholas Bellinger 	}
2436e48354ceSNicholas Bellinger 
2437e48354ceSNicholas Bellinger 	if (conn->conn_ops->DataDigest) {
2438e48354ceSNicholas Bellinger 		iov[iov_count].iov_base		= &checksum;
2439e48354ceSNicholas Bellinger 		iov[iov_count++].iov_len	= ISCSI_CRC_LEN;
2440e48354ceSNicholas Bellinger 		rx_size += ISCSI_CRC_LEN;
2441e48354ceSNicholas Bellinger 	}
2442e48354ceSNicholas Bellinger 
2443e48354ceSNicholas Bellinger 	rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size);
2444e48354ceSNicholas Bellinger 
2445e48354ceSNicholas Bellinger 	iscsit_unmap_iovec(cmd);
2446e48354ceSNicholas Bellinger 
2447e48354ceSNicholas Bellinger 	if (rx_got != rx_size) {
2448e48354ceSNicholas Bellinger 		iscsit_rx_thread_wait_for_tcp(conn);
2449e48354ceSNicholas Bellinger 		return IMMEDIATE_DATA_CANNOT_RECOVER;
2450e48354ceSNicholas Bellinger 	}
2451e48354ceSNicholas Bellinger 
2452e48354ceSNicholas Bellinger 	if (conn->conn_ops->DataDigest) {
2453e48354ceSNicholas Bellinger 		u32 data_crc;
2454e48354ceSNicholas Bellinger 
2455e48354ceSNicholas Bellinger 		data_crc = iscsit_do_crypto_hash_sg(&conn->conn_rx_hash, cmd,
2456e48354ceSNicholas Bellinger 						    cmd->write_data_done, length, padding,
2457e48354ceSNicholas Bellinger 						    cmd->pad_bytes);
2458e48354ceSNicholas Bellinger 
2459e48354ceSNicholas Bellinger 		if (checksum != data_crc) {
2460e48354ceSNicholas Bellinger 			pr_err("ImmediateData CRC32C DataDigest 0x%08x"
2461e48354ceSNicholas Bellinger 				" does not match computed 0x%08x\n", checksum,
2462e48354ceSNicholas Bellinger 				data_crc);
2463e48354ceSNicholas Bellinger 
2464e48354ceSNicholas Bellinger 			if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
2465e48354ceSNicholas Bellinger 				pr_err("Unable to recover from"
2466e48354ceSNicholas Bellinger 					" Immediate Data digest failure while"
2467e48354ceSNicholas Bellinger 					" in ERL=0.\n");
2468ba159914SNicholas Bellinger 				iscsit_reject_cmd(cmd,
2469e48354ceSNicholas Bellinger 						ISCSI_REASON_DATA_DIGEST_ERROR,
2470ba159914SNicholas Bellinger 						(unsigned char *)hdr);
2471e48354ceSNicholas Bellinger 				return IMMEDIATE_DATA_CANNOT_RECOVER;
2472e48354ceSNicholas Bellinger 			} else {
2473ba159914SNicholas Bellinger 				iscsit_reject_cmd(cmd,
2474e48354ceSNicholas Bellinger 						ISCSI_REASON_DATA_DIGEST_ERROR,
2475ba159914SNicholas Bellinger 						(unsigned char *)hdr);
2476e48354ceSNicholas Bellinger 				return IMMEDIATE_DATA_ERL1_CRC_FAILURE;
2477e48354ceSNicholas Bellinger 			}
2478e48354ceSNicholas Bellinger 		} else {
2479e48354ceSNicholas Bellinger 			pr_debug("Got CRC32C DataDigest 0x%08x for"
2480e48354ceSNicholas Bellinger 				" %u bytes of Immediate Data\n", checksum,
2481e48354ceSNicholas Bellinger 				length);
2482e48354ceSNicholas Bellinger 		}
2483e48354ceSNicholas Bellinger 	}
2484e48354ceSNicholas Bellinger 
2485e48354ceSNicholas Bellinger 	cmd->write_data_done += length;
2486e48354ceSNicholas Bellinger 
2487ebf1d95cSAndy Grover 	if (cmd->write_data_done == cmd->se_cmd.data_length) {
2488e48354ceSNicholas Bellinger 		spin_lock_bh(&cmd->istate_lock);
2489e48354ceSNicholas Bellinger 		cmd->cmd_flags |= ICF_GOT_LAST_DATAOUT;
2490e48354ceSNicholas Bellinger 		cmd->i_state = ISTATE_RECEIVED_LAST_DATAOUT;
2491e48354ceSNicholas Bellinger 		spin_unlock_bh(&cmd->istate_lock);
2492e48354ceSNicholas Bellinger 	}
2493e48354ceSNicholas Bellinger 
2494e48354ceSNicholas Bellinger 	return IMMEDIATE_DATA_NORMAL_OPERATION;
2495e48354ceSNicholas Bellinger }
2496e48354ceSNicholas Bellinger 
2497e48354ceSNicholas Bellinger /*
2498e48354ceSNicholas Bellinger  *	Called with sess->conn_lock held.
2499e48354ceSNicholas Bellinger  */
2500e48354ceSNicholas Bellinger /* #warning iscsi_build_conn_drop_async_message() only sends out on connections
2501e48354ceSNicholas Bellinger 	with active network interface */
2502e48354ceSNicholas Bellinger static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn)
2503e48354ceSNicholas Bellinger {
2504e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd;
2505e48354ceSNicholas Bellinger 	struct iscsi_conn *conn_p;
2506d444edc6SNicholas Bellinger 	bool found = false;
2507e48354ceSNicholas Bellinger 
2508e48354ceSNicholas Bellinger 	/*
2509e48354ceSNicholas Bellinger 	 * Only send a Asynchronous Message on connections whos network
2510e48354ceSNicholas Bellinger 	 * interface is still functional.
2511e48354ceSNicholas Bellinger 	 */
2512e48354ceSNicholas Bellinger 	list_for_each_entry(conn_p, &conn->sess->sess_conn_list, conn_list) {
2513e48354ceSNicholas Bellinger 		if (conn_p->conn_state == TARG_CONN_STATE_LOGGED_IN) {
2514e48354ceSNicholas Bellinger 			iscsit_inc_conn_usage_count(conn_p);
2515d444edc6SNicholas Bellinger 			found = true;
2516e48354ceSNicholas Bellinger 			break;
2517e48354ceSNicholas Bellinger 		}
2518e48354ceSNicholas Bellinger 	}
2519e48354ceSNicholas Bellinger 
2520d444edc6SNicholas Bellinger 	if (!found)
2521e48354ceSNicholas Bellinger 		return;
2522e48354ceSNicholas Bellinger 
2523676687c6SNicholas Bellinger 	cmd = iscsit_allocate_cmd(conn_p, TASK_RUNNING);
2524e48354ceSNicholas Bellinger 	if (!cmd) {
2525e48354ceSNicholas Bellinger 		iscsit_dec_conn_usage_count(conn_p);
2526e48354ceSNicholas Bellinger 		return;
2527e48354ceSNicholas Bellinger 	}
2528e48354ceSNicholas Bellinger 
2529e48354ceSNicholas Bellinger 	cmd->logout_cid = conn->cid;
2530e48354ceSNicholas Bellinger 	cmd->iscsi_opcode = ISCSI_OP_ASYNC_EVENT;
2531e48354ceSNicholas Bellinger 	cmd->i_state = ISTATE_SEND_ASYNCMSG;
2532e48354ceSNicholas Bellinger 
2533e48354ceSNicholas Bellinger 	spin_lock_bh(&conn_p->cmd_lock);
25342fbb471eSAndy Grover 	list_add_tail(&cmd->i_conn_node, &conn_p->conn_cmd_list);
2535e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn_p->cmd_lock);
2536e48354ceSNicholas Bellinger 
2537e48354ceSNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, conn_p, cmd->i_state);
2538e48354ceSNicholas Bellinger 	iscsit_dec_conn_usage_count(conn_p);
2539e48354ceSNicholas Bellinger }
2540e48354ceSNicholas Bellinger 
2541e48354ceSNicholas Bellinger static int iscsit_send_conn_drop_async_message(
2542e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd,
2543e48354ceSNicholas Bellinger 	struct iscsi_conn *conn)
2544e48354ceSNicholas Bellinger {
2545e48354ceSNicholas Bellinger 	struct iscsi_async *hdr;
2546e48354ceSNicholas Bellinger 
2547e48354ceSNicholas Bellinger 	cmd->tx_size = ISCSI_HDR_LEN;
2548e48354ceSNicholas Bellinger 	cmd->iscsi_opcode = ISCSI_OP_ASYNC_EVENT;
2549e48354ceSNicholas Bellinger 
2550e48354ceSNicholas Bellinger 	hdr			= (struct iscsi_async *) cmd->pdu;
2551e48354ceSNicholas Bellinger 	hdr->opcode		= ISCSI_OP_ASYNC_EVENT;
2552e48354ceSNicholas Bellinger 	hdr->flags		= ISCSI_FLAG_CMD_FINAL;
255366c7db68SChristoph Hellwig 	cmd->init_task_tag	= RESERVED_ITT;
2554e48354ceSNicholas Bellinger 	cmd->targ_xfer_tag	= 0xFFFFFFFF;
2555e48354ceSNicholas Bellinger 	put_unaligned_be64(0xFFFFFFFFFFFFFFFFULL, &hdr->rsvd4[0]);
2556e48354ceSNicholas Bellinger 	cmd->stat_sn		= conn->stat_sn++;
2557e48354ceSNicholas Bellinger 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
2558e48354ceSNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
2559e48354ceSNicholas Bellinger 	hdr->max_cmdsn		= cpu_to_be32(conn->sess->max_cmd_sn);
2560e48354ceSNicholas Bellinger 	hdr->async_event	= ISCSI_ASYNC_MSG_DROPPING_CONNECTION;
2561e48354ceSNicholas Bellinger 	hdr->param1		= cpu_to_be16(cmd->logout_cid);
2562e48354ceSNicholas Bellinger 	hdr->param2		= cpu_to_be16(conn->sess->sess_ops->DefaultTime2Wait);
2563e48354ceSNicholas Bellinger 	hdr->param3		= cpu_to_be16(conn->sess->sess_ops->DefaultTime2Retain);
2564e48354ceSNicholas Bellinger 
2565e48354ceSNicholas Bellinger 	if (conn->conn_ops->HeaderDigest) {
2566e48354ceSNicholas Bellinger 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
2567e48354ceSNicholas Bellinger 
256880690fdbSGeert Uytterhoeven 		iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr,
256980690fdbSGeert Uytterhoeven 				ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
2570e48354ceSNicholas Bellinger 
2571e48354ceSNicholas Bellinger 		cmd->tx_size += ISCSI_CRC_LEN;
2572e48354ceSNicholas Bellinger 		pr_debug("Attaching CRC32C HeaderDigest to"
2573e48354ceSNicholas Bellinger 			" Async Message 0x%08x\n", *header_digest);
2574e48354ceSNicholas Bellinger 	}
2575e48354ceSNicholas Bellinger 
2576e48354ceSNicholas Bellinger 	cmd->iov_misc[0].iov_base	= cmd->pdu;
2577e48354ceSNicholas Bellinger 	cmd->iov_misc[0].iov_len	= cmd->tx_size;
2578e48354ceSNicholas Bellinger 	cmd->iov_misc_count		= 1;
2579e48354ceSNicholas Bellinger 
2580e48354ceSNicholas Bellinger 	pr_debug("Sending Connection Dropped Async Message StatSN:"
2581e48354ceSNicholas Bellinger 		" 0x%08x, for CID: %hu on CID: %hu\n", cmd->stat_sn,
2582e48354ceSNicholas Bellinger 			cmd->logout_cid, conn->cid);
2583e48354ceSNicholas Bellinger 	return 0;
2584e48354ceSNicholas Bellinger }
2585e48354ceSNicholas Bellinger 
25866f3c0e69SAndy Grover static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn)
25876f3c0e69SAndy Grover {
25886f3c0e69SAndy Grover 	if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) ||
25896f3c0e69SAndy Grover 	    (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) {
25906f3c0e69SAndy Grover 		wait_for_completion_interruptible_timeout(
25916f3c0e69SAndy Grover 					&conn->tx_half_close_comp,
25926f3c0e69SAndy Grover 					ISCSI_TX_THREAD_TCP_TIMEOUT * HZ);
25936f3c0e69SAndy Grover 	}
25946f3c0e69SAndy Grover }
25956f3c0e69SAndy Grover 
25962ec5a8c1SNicholas Bellinger static void
25972ec5a8c1SNicholas Bellinger iscsit_build_datain_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
25982ec5a8c1SNicholas Bellinger 			struct iscsi_datain *datain, struct iscsi_data_rsp *hdr,
25992ec5a8c1SNicholas Bellinger 			bool set_statsn)
2600e48354ceSNicholas Bellinger {
26012ec5a8c1SNicholas Bellinger 	hdr->opcode		= ISCSI_OP_SCSI_DATA_IN;
26022ec5a8c1SNicholas Bellinger 	hdr->flags		= datain->flags;
26032ec5a8c1SNicholas Bellinger 	if (hdr->flags & ISCSI_FLAG_DATA_STATUS) {
26042ec5a8c1SNicholas Bellinger 		if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) {
26052ec5a8c1SNicholas Bellinger 			hdr->flags |= ISCSI_FLAG_DATA_OVERFLOW;
26062ec5a8c1SNicholas Bellinger 			hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
26072ec5a8c1SNicholas Bellinger 		} else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) {
26082ec5a8c1SNicholas Bellinger 			hdr->flags |= ISCSI_FLAG_DATA_UNDERFLOW;
26092ec5a8c1SNicholas Bellinger 			hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
26102ec5a8c1SNicholas Bellinger 		}
26112ec5a8c1SNicholas Bellinger 	}
26122ec5a8c1SNicholas Bellinger 	hton24(hdr->dlength, datain->length);
26132ec5a8c1SNicholas Bellinger 	if (hdr->flags & ISCSI_FLAG_DATA_ACK)
26142ec5a8c1SNicholas Bellinger 		int_to_scsilun(cmd->se_cmd.orig_fe_lun,
26152ec5a8c1SNicholas Bellinger 				(struct scsi_lun *)&hdr->lun);
26162ec5a8c1SNicholas Bellinger 	else
26172ec5a8c1SNicholas Bellinger 		put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);
26182ec5a8c1SNicholas Bellinger 
26192ec5a8c1SNicholas Bellinger 	hdr->itt		= cmd->init_task_tag;
26202ec5a8c1SNicholas Bellinger 
26212ec5a8c1SNicholas Bellinger 	if (hdr->flags & ISCSI_FLAG_DATA_ACK)
26222ec5a8c1SNicholas Bellinger 		hdr->ttt		= cpu_to_be32(cmd->targ_xfer_tag);
26232ec5a8c1SNicholas Bellinger 	else
26242ec5a8c1SNicholas Bellinger 		hdr->ttt		= cpu_to_be32(0xFFFFFFFF);
26252ec5a8c1SNicholas Bellinger 	if (set_statsn)
26262ec5a8c1SNicholas Bellinger 		hdr->statsn		= cpu_to_be32(cmd->stat_sn);
26272ec5a8c1SNicholas Bellinger 	else
26282ec5a8c1SNicholas Bellinger 		hdr->statsn		= cpu_to_be32(0xFFFFFFFF);
26292ec5a8c1SNicholas Bellinger 
26302ec5a8c1SNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
26312ec5a8c1SNicholas Bellinger 	hdr->max_cmdsn		= cpu_to_be32(conn->sess->max_cmd_sn);
26322ec5a8c1SNicholas Bellinger 	hdr->datasn		= cpu_to_be32(datain->data_sn);
26332ec5a8c1SNicholas Bellinger 	hdr->offset		= cpu_to_be32(datain->offset);
26342ec5a8c1SNicholas Bellinger 
26352ec5a8c1SNicholas Bellinger 	pr_debug("Built DataIN ITT: 0x%08x, StatSN: 0x%08x,"
26362ec5a8c1SNicholas Bellinger 		" DataSN: 0x%08x, Offset: %u, Length: %u, CID: %hu\n",
26372ec5a8c1SNicholas Bellinger 		cmd->init_task_tag, ntohl(hdr->statsn), ntohl(hdr->datasn),
26382ec5a8c1SNicholas Bellinger 		ntohl(hdr->offset), datain->length, conn->cid);
26392ec5a8c1SNicholas Bellinger }
26402ec5a8c1SNicholas Bellinger 
26412ec5a8c1SNicholas Bellinger static int iscsit_send_datain(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
26422ec5a8c1SNicholas Bellinger {
26432ec5a8c1SNicholas Bellinger 	struct iscsi_data_rsp *hdr = (struct iscsi_data_rsp *)&cmd->pdu[0];
2644e48354ceSNicholas Bellinger 	struct iscsi_datain datain;
2645e48354ceSNicholas Bellinger 	struct iscsi_datain_req *dr;
2646e48354ceSNicholas Bellinger 	struct kvec *iov;
26472ec5a8c1SNicholas Bellinger 	u32 iov_count = 0, tx_size = 0;
26482ec5a8c1SNicholas Bellinger 	int eodr = 0, ret, iov_ret;
26492ec5a8c1SNicholas Bellinger 	bool set_statsn = false;
2650e48354ceSNicholas Bellinger 
2651e48354ceSNicholas Bellinger 	memset(&datain, 0, sizeof(struct iscsi_datain));
2652e48354ceSNicholas Bellinger 	dr = iscsit_get_datain_values(cmd, &datain);
2653e48354ceSNicholas Bellinger 	if (!dr) {
2654e48354ceSNicholas Bellinger 		pr_err("iscsit_get_datain_values failed for ITT: 0x%08x\n",
2655e48354ceSNicholas Bellinger 				cmd->init_task_tag);
2656e48354ceSNicholas Bellinger 		return -1;
2657e48354ceSNicholas Bellinger 	}
2658e48354ceSNicholas Bellinger 	/*
2659e48354ceSNicholas Bellinger 	 * Be paranoid and double check the logic for now.
2660e48354ceSNicholas Bellinger 	 */
2661ebf1d95cSAndy Grover 	if ((datain.offset + datain.length) > cmd->se_cmd.data_length) {
2662e48354ceSNicholas Bellinger 		pr_err("Command ITT: 0x%08x, datain.offset: %u and"
2663e48354ceSNicholas Bellinger 			" datain.length: %u exceeds cmd->data_length: %u\n",
2664e48354ceSNicholas Bellinger 			cmd->init_task_tag, datain.offset, datain.length,
2665ebf1d95cSAndy Grover 			cmd->se_cmd.data_length);
2666e48354ceSNicholas Bellinger 		return -1;
2667e48354ceSNicholas Bellinger 	}
2668e48354ceSNicholas Bellinger 
266904f3b31bSNicholas Bellinger 	atomic_long_add(datain.length, &conn->sess->tx_data_octets);
2670e48354ceSNicholas Bellinger 	/*
2671e48354ceSNicholas Bellinger 	 * Special case for successfully execution w/ both DATAIN
2672e48354ceSNicholas Bellinger 	 * and Sense Data.
2673e48354ceSNicholas Bellinger 	 */
2674e48354ceSNicholas Bellinger 	if ((datain.flags & ISCSI_FLAG_DATA_STATUS) &&
2675e48354ceSNicholas Bellinger 	    (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE))
2676e48354ceSNicholas Bellinger 		datain.flags &= ~ISCSI_FLAG_DATA_STATUS;
2677e48354ceSNicholas Bellinger 	else {
2678e48354ceSNicholas Bellinger 		if ((dr->dr_complete == DATAIN_COMPLETE_NORMAL) ||
2679e48354ceSNicholas Bellinger 		    (dr->dr_complete == DATAIN_COMPLETE_CONNECTION_RECOVERY)) {
2680e48354ceSNicholas Bellinger 			iscsit_increment_maxcmdsn(cmd, conn->sess);
2681e48354ceSNicholas Bellinger 			cmd->stat_sn = conn->stat_sn++;
26822ec5a8c1SNicholas Bellinger 			set_statsn = true;
2683e48354ceSNicholas Bellinger 		} else if (dr->dr_complete ==
2684e48354ceSNicholas Bellinger 			   DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY)
26852ec5a8c1SNicholas Bellinger 			set_statsn = true;
2686e48354ceSNicholas Bellinger 	}
2687e48354ceSNicholas Bellinger 
26882ec5a8c1SNicholas Bellinger 	iscsit_build_datain_pdu(cmd, conn, &datain, hdr, set_statsn);
2689e48354ceSNicholas Bellinger 
2690e48354ceSNicholas Bellinger 	iov = &cmd->iov_data[0];
2691e48354ceSNicholas Bellinger 	iov[iov_count].iov_base	= cmd->pdu;
2692e48354ceSNicholas Bellinger 	iov[iov_count++].iov_len	= ISCSI_HDR_LEN;
2693e48354ceSNicholas Bellinger 	tx_size += ISCSI_HDR_LEN;
2694e48354ceSNicholas Bellinger 
2695e48354ceSNicholas Bellinger 	if (conn->conn_ops->HeaderDigest) {
2696e48354ceSNicholas Bellinger 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
2697e48354ceSNicholas Bellinger 
269880690fdbSGeert Uytterhoeven 		iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, cmd->pdu,
269980690fdbSGeert Uytterhoeven 				ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
2700e48354ceSNicholas Bellinger 
2701e48354ceSNicholas Bellinger 		iov[0].iov_len += ISCSI_CRC_LEN;
2702e48354ceSNicholas Bellinger 		tx_size += ISCSI_CRC_LEN;
2703e48354ceSNicholas Bellinger 
2704e48354ceSNicholas Bellinger 		pr_debug("Attaching CRC32 HeaderDigest"
2705e48354ceSNicholas Bellinger 			" for DataIN PDU 0x%08x\n", *header_digest);
2706e48354ceSNicholas Bellinger 	}
2707e48354ceSNicholas Bellinger 
27082ec5a8c1SNicholas Bellinger 	iov_ret = iscsit_map_iovec(cmd, &cmd->iov_data[1],
27092ec5a8c1SNicholas Bellinger 				datain.offset, datain.length);
2710e48354ceSNicholas Bellinger 	if (iov_ret < 0)
2711e48354ceSNicholas Bellinger 		return -1;
2712e48354ceSNicholas Bellinger 
2713e48354ceSNicholas Bellinger 	iov_count += iov_ret;
2714e48354ceSNicholas Bellinger 	tx_size += datain.length;
2715e48354ceSNicholas Bellinger 
2716e48354ceSNicholas Bellinger 	cmd->padding = ((-datain.length) & 3);
2717e48354ceSNicholas Bellinger 	if (cmd->padding) {
2718e48354ceSNicholas Bellinger 		iov[iov_count].iov_base		= cmd->pad_bytes;
2719e48354ceSNicholas Bellinger 		iov[iov_count++].iov_len	= cmd->padding;
2720e48354ceSNicholas Bellinger 		tx_size += cmd->padding;
2721e48354ceSNicholas Bellinger 
2722e48354ceSNicholas Bellinger 		pr_debug("Attaching %u padding bytes\n",
2723e48354ceSNicholas Bellinger 				cmd->padding);
2724e48354ceSNicholas Bellinger 	}
2725e48354ceSNicholas Bellinger 	if (conn->conn_ops->DataDigest) {
2726e48354ceSNicholas Bellinger 		cmd->data_crc = iscsit_do_crypto_hash_sg(&conn->conn_tx_hash, cmd,
2727e48354ceSNicholas Bellinger 			 datain.offset, datain.length, cmd->padding, cmd->pad_bytes);
2728e48354ceSNicholas Bellinger 
2729e48354ceSNicholas Bellinger 		iov[iov_count].iov_base	= &cmd->data_crc;
2730e48354ceSNicholas Bellinger 		iov[iov_count++].iov_len = ISCSI_CRC_LEN;
2731e48354ceSNicholas Bellinger 		tx_size += ISCSI_CRC_LEN;
2732e48354ceSNicholas Bellinger 
2733e48354ceSNicholas Bellinger 		pr_debug("Attached CRC32C DataDigest %d bytes, crc"
2734e48354ceSNicholas Bellinger 			" 0x%08x\n", datain.length+cmd->padding, cmd->data_crc);
2735e48354ceSNicholas Bellinger 	}
2736e48354ceSNicholas Bellinger 
2737e48354ceSNicholas Bellinger 	cmd->iov_data_count = iov_count;
2738e48354ceSNicholas Bellinger 	cmd->tx_size = tx_size;
2739e48354ceSNicholas Bellinger 
27406f3c0e69SAndy Grover 	/* sendpage is preferred but can't insert markers */
27416f3c0e69SAndy Grover 	if (!conn->conn_ops->IFMarker)
27426f3c0e69SAndy Grover 		ret = iscsit_fe_sendpage_sg(cmd, conn);
27436f3c0e69SAndy Grover 	else
27446f3c0e69SAndy Grover 		ret = iscsit_send_tx_data(cmd, conn, 0);
27456f3c0e69SAndy Grover 
27466f3c0e69SAndy Grover 	iscsit_unmap_iovec(cmd);
27476f3c0e69SAndy Grover 
27486f3c0e69SAndy Grover 	if (ret < 0) {
27496f3c0e69SAndy Grover 		iscsit_tx_thread_wait_for_tcp(conn);
27506f3c0e69SAndy Grover 		return ret;
27516f3c0e69SAndy Grover 	}
27526f3c0e69SAndy Grover 
2753e48354ceSNicholas Bellinger 	if (dr->dr_complete) {
27546f3c0e69SAndy Grover 		eodr = (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ?
2755e48354ceSNicholas Bellinger 				2 : 1;
2756e48354ceSNicholas Bellinger 		iscsit_free_datain_req(cmd, dr);
2757e48354ceSNicholas Bellinger 	}
2758e48354ceSNicholas Bellinger 
27596f3c0e69SAndy Grover 	return eodr;
2760e48354ceSNicholas Bellinger }
2761e48354ceSNicholas Bellinger 
27622ec5a8c1SNicholas Bellinger int
27632ec5a8c1SNicholas Bellinger iscsit_build_logout_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
27642ec5a8c1SNicholas Bellinger 			struct iscsi_logout_rsp *hdr)
2765e48354ceSNicholas Bellinger {
2766e48354ceSNicholas Bellinger 	struct iscsi_conn *logout_conn = NULL;
2767e48354ceSNicholas Bellinger 	struct iscsi_conn_recovery *cr = NULL;
2768e48354ceSNicholas Bellinger 	struct iscsi_session *sess = conn->sess;
2769e48354ceSNicholas Bellinger 	/*
2770e48354ceSNicholas Bellinger 	 * The actual shutting down of Sessions and/or Connections
2771e48354ceSNicholas Bellinger 	 * for CLOSESESSION and CLOSECONNECTION Logout Requests
2772e48354ceSNicholas Bellinger 	 * is done in scsi_logout_post_handler().
2773e48354ceSNicholas Bellinger 	 */
2774e48354ceSNicholas Bellinger 	switch (cmd->logout_reason) {
2775e48354ceSNicholas Bellinger 	case ISCSI_LOGOUT_REASON_CLOSE_SESSION:
2776e48354ceSNicholas Bellinger 		pr_debug("iSCSI session logout successful, setting"
2777e48354ceSNicholas Bellinger 			" logout response to ISCSI_LOGOUT_SUCCESS.\n");
2778e48354ceSNicholas Bellinger 		cmd->logout_response = ISCSI_LOGOUT_SUCCESS;
2779e48354ceSNicholas Bellinger 		break;
2780e48354ceSNicholas Bellinger 	case ISCSI_LOGOUT_REASON_CLOSE_CONNECTION:
2781e48354ceSNicholas Bellinger 		if (cmd->logout_response == ISCSI_LOGOUT_CID_NOT_FOUND)
2782e48354ceSNicholas Bellinger 			break;
2783e48354ceSNicholas Bellinger 		/*
2784e48354ceSNicholas Bellinger 		 * For CLOSECONNECTION logout requests carrying
2785e48354ceSNicholas Bellinger 		 * a matching logout CID -> local CID, the reference
2786e48354ceSNicholas Bellinger 		 * for the local CID will have been incremented in
2787e48354ceSNicholas Bellinger 		 * iscsi_logout_closeconnection().
2788e48354ceSNicholas Bellinger 		 *
2789e48354ceSNicholas Bellinger 		 * For CLOSECONNECTION logout requests carrying
2790e48354ceSNicholas Bellinger 		 * a different CID than the connection it arrived
2791e48354ceSNicholas Bellinger 		 * on, the connection responding to cmd->logout_cid
2792e48354ceSNicholas Bellinger 		 * is stopped in iscsit_logout_post_handler_diffcid().
2793e48354ceSNicholas Bellinger 		 */
2794e48354ceSNicholas Bellinger 
2795e48354ceSNicholas Bellinger 		pr_debug("iSCSI CID: %hu logout on CID: %hu"
2796e48354ceSNicholas Bellinger 			" successful.\n", cmd->logout_cid, conn->cid);
2797e48354ceSNicholas Bellinger 		cmd->logout_response = ISCSI_LOGOUT_SUCCESS;
2798e48354ceSNicholas Bellinger 		break;
2799e48354ceSNicholas Bellinger 	case ISCSI_LOGOUT_REASON_RECOVERY:
2800e48354ceSNicholas Bellinger 		if ((cmd->logout_response == ISCSI_LOGOUT_RECOVERY_UNSUPPORTED) ||
2801e48354ceSNicholas Bellinger 		    (cmd->logout_response == ISCSI_LOGOUT_CLEANUP_FAILED))
2802e48354ceSNicholas Bellinger 			break;
2803e48354ceSNicholas Bellinger 		/*
2804e48354ceSNicholas Bellinger 		 * If the connection is still active from our point of view
2805e48354ceSNicholas Bellinger 		 * force connection recovery to occur.
2806e48354ceSNicholas Bellinger 		 */
2807e48354ceSNicholas Bellinger 		logout_conn = iscsit_get_conn_from_cid_rcfr(sess,
2808e48354ceSNicholas Bellinger 				cmd->logout_cid);
2809ee1b1b9cSAndy Grover 		if (logout_conn) {
2810e48354ceSNicholas Bellinger 			iscsit_connection_reinstatement_rcfr(logout_conn);
2811e48354ceSNicholas Bellinger 			iscsit_dec_conn_usage_count(logout_conn);
2812e48354ceSNicholas Bellinger 		}
2813e48354ceSNicholas Bellinger 
2814e48354ceSNicholas Bellinger 		cr = iscsit_get_inactive_connection_recovery_entry(
2815e48354ceSNicholas Bellinger 				conn->sess, cmd->logout_cid);
2816e48354ceSNicholas Bellinger 		if (!cr) {
2817e48354ceSNicholas Bellinger 			pr_err("Unable to locate CID: %hu for"
2818e48354ceSNicholas Bellinger 			" REMOVECONNFORRECOVERY Logout Request.\n",
2819e48354ceSNicholas Bellinger 				cmd->logout_cid);
2820e48354ceSNicholas Bellinger 			cmd->logout_response = ISCSI_LOGOUT_CID_NOT_FOUND;
2821e48354ceSNicholas Bellinger 			break;
2822e48354ceSNicholas Bellinger 		}
2823e48354ceSNicholas Bellinger 
2824e48354ceSNicholas Bellinger 		iscsit_discard_cr_cmds_by_expstatsn(cr, cmd->exp_stat_sn);
2825e48354ceSNicholas Bellinger 
2826e48354ceSNicholas Bellinger 		pr_debug("iSCSI REMOVECONNFORRECOVERY logout"
2827e48354ceSNicholas Bellinger 			" for recovery for CID: %hu on CID: %hu successful.\n",
2828e48354ceSNicholas Bellinger 				cmd->logout_cid, conn->cid);
2829e48354ceSNicholas Bellinger 		cmd->logout_response = ISCSI_LOGOUT_SUCCESS;
2830e48354ceSNicholas Bellinger 		break;
2831e48354ceSNicholas Bellinger 	default:
2832e48354ceSNicholas Bellinger 		pr_err("Unknown cmd->logout_reason: 0x%02x\n",
2833e48354ceSNicholas Bellinger 				cmd->logout_reason);
2834e48354ceSNicholas Bellinger 		return -1;
2835e48354ceSNicholas Bellinger 	}
2836e48354ceSNicholas Bellinger 
2837e48354ceSNicholas Bellinger 	hdr->opcode		= ISCSI_OP_LOGOUT_RSP;
2838e48354ceSNicholas Bellinger 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
2839e48354ceSNicholas Bellinger 	hdr->response		= cmd->logout_response;
284066c7db68SChristoph Hellwig 	hdr->itt		= cmd->init_task_tag;
2841e48354ceSNicholas Bellinger 	cmd->stat_sn		= conn->stat_sn++;
2842e48354ceSNicholas Bellinger 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
2843e48354ceSNicholas Bellinger 
2844e48354ceSNicholas Bellinger 	iscsit_increment_maxcmdsn(cmd, conn->sess);
2845e48354ceSNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
2846e48354ceSNicholas Bellinger 	hdr->max_cmdsn		= cpu_to_be32(conn->sess->max_cmd_sn);
2847e48354ceSNicholas Bellinger 
28482ec5a8c1SNicholas Bellinger 	pr_debug("Built Logout Response ITT: 0x%08x StatSN:"
28492ec5a8c1SNicholas Bellinger 		" 0x%08x Response: 0x%02x CID: %hu on CID: %hu\n",
28502ec5a8c1SNicholas Bellinger 		cmd->init_task_tag, cmd->stat_sn, hdr->response,
28512ec5a8c1SNicholas Bellinger 		cmd->logout_cid, conn->cid);
28522ec5a8c1SNicholas Bellinger 
28532ec5a8c1SNicholas Bellinger 	return 0;
28542ec5a8c1SNicholas Bellinger }
28552ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_logout_rsp);
28562ec5a8c1SNicholas Bellinger 
28572ec5a8c1SNicholas Bellinger static int
28582ec5a8c1SNicholas Bellinger iscsit_send_logout(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
28592ec5a8c1SNicholas Bellinger {
28602ec5a8c1SNicholas Bellinger 	struct kvec *iov;
28612ec5a8c1SNicholas Bellinger 	int niov = 0, tx_size, rc;
28622ec5a8c1SNicholas Bellinger 
28632ec5a8c1SNicholas Bellinger 	rc = iscsit_build_logout_rsp(cmd, conn,
28642ec5a8c1SNicholas Bellinger 			(struct iscsi_logout_rsp *)&cmd->pdu[0]);
28652ec5a8c1SNicholas Bellinger 	if (rc < 0)
28662ec5a8c1SNicholas Bellinger 		return rc;
28672ec5a8c1SNicholas Bellinger 
28682ec5a8c1SNicholas Bellinger 	tx_size = ISCSI_HDR_LEN;
2869e48354ceSNicholas Bellinger 	iov = &cmd->iov_misc[0];
2870e48354ceSNicholas Bellinger 	iov[niov].iov_base	= cmd->pdu;
2871e48354ceSNicholas Bellinger 	iov[niov++].iov_len	= ISCSI_HDR_LEN;
2872e48354ceSNicholas Bellinger 
2873e48354ceSNicholas Bellinger 	if (conn->conn_ops->HeaderDigest) {
2874e48354ceSNicholas Bellinger 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
2875e48354ceSNicholas Bellinger 
287680690fdbSGeert Uytterhoeven 		iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, &cmd->pdu[0],
287780690fdbSGeert Uytterhoeven 				ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
2878e48354ceSNicholas Bellinger 
2879e48354ceSNicholas Bellinger 		iov[0].iov_len += ISCSI_CRC_LEN;
2880e48354ceSNicholas Bellinger 		tx_size += ISCSI_CRC_LEN;
2881e48354ceSNicholas Bellinger 		pr_debug("Attaching CRC32C HeaderDigest to"
2882e48354ceSNicholas Bellinger 			" Logout Response 0x%08x\n", *header_digest);
2883e48354ceSNicholas Bellinger 	}
2884e48354ceSNicholas Bellinger 	cmd->iov_misc_count = niov;
2885e48354ceSNicholas Bellinger 	cmd->tx_size = tx_size;
2886e48354ceSNicholas Bellinger 
2887e48354ceSNicholas Bellinger 	return 0;
2888e48354ceSNicholas Bellinger }
2889e48354ceSNicholas Bellinger 
28902ec5a8c1SNicholas Bellinger void
28912ec5a8c1SNicholas Bellinger iscsit_build_nopin_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
28922ec5a8c1SNicholas Bellinger 		       struct iscsi_nopin *hdr, bool nopout_response)
28932ec5a8c1SNicholas Bellinger {
28942ec5a8c1SNicholas Bellinger 	hdr->opcode		= ISCSI_OP_NOOP_IN;
28952ec5a8c1SNicholas Bellinger 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
28962ec5a8c1SNicholas Bellinger         hton24(hdr->dlength, cmd->buf_ptr_size);
28972ec5a8c1SNicholas Bellinger 	if (nopout_response)
28982ec5a8c1SNicholas Bellinger 		put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);
28992ec5a8c1SNicholas Bellinger 	hdr->itt		= cmd->init_task_tag;
29002ec5a8c1SNicholas Bellinger 	hdr->ttt		= cpu_to_be32(cmd->targ_xfer_tag);
29012ec5a8c1SNicholas Bellinger 	cmd->stat_sn		= (nopout_response) ? conn->stat_sn++ :
29022ec5a8c1SNicholas Bellinger 				  conn->stat_sn;
29032ec5a8c1SNicholas Bellinger 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
29042ec5a8c1SNicholas Bellinger 
29052ec5a8c1SNicholas Bellinger 	if (nopout_response)
29062ec5a8c1SNicholas Bellinger 		iscsit_increment_maxcmdsn(cmd, conn->sess);
29072ec5a8c1SNicholas Bellinger 
29082ec5a8c1SNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
29092ec5a8c1SNicholas Bellinger 	hdr->max_cmdsn		= cpu_to_be32(conn->sess->max_cmd_sn);
29102ec5a8c1SNicholas Bellinger 
29112ec5a8c1SNicholas Bellinger 	pr_debug("Built NOPIN %s Response ITT: 0x%08x, TTT: 0x%08x,"
29122ec5a8c1SNicholas Bellinger 		" StatSN: 0x%08x, Length %u\n", (nopout_response) ?
29132ec5a8c1SNicholas Bellinger 		"Solicitied" : "Unsolicitied", cmd->init_task_tag,
29142ec5a8c1SNicholas Bellinger 		cmd->targ_xfer_tag, cmd->stat_sn, cmd->buf_ptr_size);
29152ec5a8c1SNicholas Bellinger }
29162ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_nopin_rsp);
29172ec5a8c1SNicholas Bellinger 
2918e48354ceSNicholas Bellinger /*
2919e48354ceSNicholas Bellinger  *	Unsolicited NOPIN, either requesting a response or not.
2920e48354ceSNicholas Bellinger  */
2921e48354ceSNicholas Bellinger static int iscsit_send_unsolicited_nopin(
2922e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd,
2923e48354ceSNicholas Bellinger 	struct iscsi_conn *conn,
2924e48354ceSNicholas Bellinger 	int want_response)
2925e48354ceSNicholas Bellinger {
29262ec5a8c1SNicholas Bellinger 	struct iscsi_nopin *hdr = (struct iscsi_nopin *)&cmd->pdu[0];
29272ec5a8c1SNicholas Bellinger 	int tx_size = ISCSI_HDR_LEN, ret;
2928e48354ceSNicholas Bellinger 
29292ec5a8c1SNicholas Bellinger 	iscsit_build_nopin_rsp(cmd, conn, hdr, false);
2930e48354ceSNicholas Bellinger 
2931e48354ceSNicholas Bellinger 	if (conn->conn_ops->HeaderDigest) {
2932e48354ceSNicholas Bellinger 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
2933e48354ceSNicholas Bellinger 
293480690fdbSGeert Uytterhoeven 		iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr,
293580690fdbSGeert Uytterhoeven 				ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
2936e48354ceSNicholas Bellinger 
2937e48354ceSNicholas Bellinger 		tx_size += ISCSI_CRC_LEN;
2938e48354ceSNicholas Bellinger 		pr_debug("Attaching CRC32C HeaderDigest to"
2939e48354ceSNicholas Bellinger 			" NopIN 0x%08x\n", *header_digest);
2940e48354ceSNicholas Bellinger 	}
2941e48354ceSNicholas Bellinger 
2942e48354ceSNicholas Bellinger 	cmd->iov_misc[0].iov_base	= cmd->pdu;
2943e48354ceSNicholas Bellinger 	cmd->iov_misc[0].iov_len	= tx_size;
2944e48354ceSNicholas Bellinger 	cmd->iov_misc_count	= 1;
2945e48354ceSNicholas Bellinger 	cmd->tx_size		= tx_size;
2946e48354ceSNicholas Bellinger 
2947e48354ceSNicholas Bellinger 	pr_debug("Sending Unsolicited NOPIN TTT: 0x%08x StatSN:"
2948e48354ceSNicholas Bellinger 		" 0x%08x CID: %hu\n", hdr->ttt, cmd->stat_sn, conn->cid);
2949e48354ceSNicholas Bellinger 
29506f3c0e69SAndy Grover 	ret = iscsit_send_tx_data(cmd, conn, 1);
29516f3c0e69SAndy Grover 	if (ret < 0) {
29526f3c0e69SAndy Grover 		iscsit_tx_thread_wait_for_tcp(conn);
29536f3c0e69SAndy Grover 		return ret;
29546f3c0e69SAndy Grover 	}
29556f3c0e69SAndy Grover 
29566f3c0e69SAndy Grover 	spin_lock_bh(&cmd->istate_lock);
29576f3c0e69SAndy Grover 	cmd->i_state = want_response ?
29586f3c0e69SAndy Grover 		ISTATE_SENT_NOPIN_WANT_RESPONSE : ISTATE_SENT_STATUS;
29596f3c0e69SAndy Grover 	spin_unlock_bh(&cmd->istate_lock);
29606f3c0e69SAndy Grover 
2961e48354ceSNicholas Bellinger 	return 0;
2962e48354ceSNicholas Bellinger }
2963e48354ceSNicholas Bellinger 
29642ec5a8c1SNicholas Bellinger static int
29652ec5a8c1SNicholas Bellinger iscsit_send_nopin(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
2966e48354ceSNicholas Bellinger {
29672ec5a8c1SNicholas Bellinger 	struct iscsi_nopin *hdr = (struct iscsi_nopin *)&cmd->pdu[0];
2968e48354ceSNicholas Bellinger 	struct kvec *iov;
29692ec5a8c1SNicholas Bellinger 	u32 padding = 0;
29702ec5a8c1SNicholas Bellinger 	int niov = 0, tx_size;
29712ec5a8c1SNicholas Bellinger 
29722ec5a8c1SNicholas Bellinger 	iscsit_build_nopin_rsp(cmd, conn, hdr, true);
2973e48354ceSNicholas Bellinger 
2974e48354ceSNicholas Bellinger 	tx_size = ISCSI_HDR_LEN;
2975e48354ceSNicholas Bellinger 	iov = &cmd->iov_misc[0];
2976e48354ceSNicholas Bellinger 	iov[niov].iov_base	= cmd->pdu;
2977e48354ceSNicholas Bellinger 	iov[niov++].iov_len	= ISCSI_HDR_LEN;
2978e48354ceSNicholas Bellinger 
2979e48354ceSNicholas Bellinger 	if (conn->conn_ops->HeaderDigest) {
2980e48354ceSNicholas Bellinger 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
2981e48354ceSNicholas Bellinger 
298280690fdbSGeert Uytterhoeven 		iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr,
298380690fdbSGeert Uytterhoeven 				ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
2984e48354ceSNicholas Bellinger 
2985e48354ceSNicholas Bellinger 		iov[0].iov_len += ISCSI_CRC_LEN;
2986e48354ceSNicholas Bellinger 		tx_size += ISCSI_CRC_LEN;
2987e48354ceSNicholas Bellinger 		pr_debug("Attaching CRC32C HeaderDigest"
2988e48354ceSNicholas Bellinger 			" to NopIn 0x%08x\n", *header_digest);
2989e48354ceSNicholas Bellinger 	}
2990e48354ceSNicholas Bellinger 
2991e48354ceSNicholas Bellinger 	/*
2992e48354ceSNicholas Bellinger 	 * NOPOUT Ping Data is attached to struct iscsi_cmd->buf_ptr.
2993e48354ceSNicholas Bellinger 	 * NOPOUT DataSegmentLength is at struct iscsi_cmd->buf_ptr_size.
2994e48354ceSNicholas Bellinger 	 */
2995e48354ceSNicholas Bellinger 	if (cmd->buf_ptr_size) {
2996e48354ceSNicholas Bellinger 		iov[niov].iov_base	= cmd->buf_ptr;
2997e48354ceSNicholas Bellinger 		iov[niov++].iov_len	= cmd->buf_ptr_size;
2998e48354ceSNicholas Bellinger 		tx_size += cmd->buf_ptr_size;
2999e48354ceSNicholas Bellinger 
3000e48354ceSNicholas Bellinger 		pr_debug("Echoing back %u bytes of ping"
3001e48354ceSNicholas Bellinger 			" data.\n", cmd->buf_ptr_size);
3002e48354ceSNicholas Bellinger 
3003e48354ceSNicholas Bellinger 		padding = ((-cmd->buf_ptr_size) & 3);
3004e48354ceSNicholas Bellinger 		if (padding != 0) {
3005e48354ceSNicholas Bellinger 			iov[niov].iov_base = &cmd->pad_bytes;
3006e48354ceSNicholas Bellinger 			iov[niov++].iov_len = padding;
3007e48354ceSNicholas Bellinger 			tx_size += padding;
3008e48354ceSNicholas Bellinger 			pr_debug("Attaching %u additional"
3009e48354ceSNicholas Bellinger 				" padding bytes.\n", padding);
3010e48354ceSNicholas Bellinger 		}
3011e48354ceSNicholas Bellinger 		if (conn->conn_ops->DataDigest) {
3012e48354ceSNicholas Bellinger 			iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
3013e48354ceSNicholas Bellinger 				cmd->buf_ptr, cmd->buf_ptr_size,
3014e48354ceSNicholas Bellinger 				padding, (u8 *)&cmd->pad_bytes,
3015e48354ceSNicholas Bellinger 				(u8 *)&cmd->data_crc);
3016e48354ceSNicholas Bellinger 
3017e48354ceSNicholas Bellinger 			iov[niov].iov_base = &cmd->data_crc;
3018e48354ceSNicholas Bellinger 			iov[niov++].iov_len = ISCSI_CRC_LEN;
3019e48354ceSNicholas Bellinger 			tx_size += ISCSI_CRC_LEN;
3020e48354ceSNicholas Bellinger 			pr_debug("Attached DataDigest for %u"
3021e48354ceSNicholas Bellinger 				" bytes of ping data, CRC 0x%08x\n",
3022e48354ceSNicholas Bellinger 				cmd->buf_ptr_size, cmd->data_crc);
3023e48354ceSNicholas Bellinger 		}
3024e48354ceSNicholas Bellinger 	}
3025e48354ceSNicholas Bellinger 
3026e48354ceSNicholas Bellinger 	cmd->iov_misc_count = niov;
3027e48354ceSNicholas Bellinger 	cmd->tx_size = tx_size;
3028e48354ceSNicholas Bellinger 
3029e48354ceSNicholas Bellinger 	return 0;
3030e48354ceSNicholas Bellinger }
3031e48354ceSNicholas Bellinger 
30326f3c0e69SAndy Grover static int iscsit_send_r2t(
3033e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd,
3034e48354ceSNicholas Bellinger 	struct iscsi_conn *conn)
3035e48354ceSNicholas Bellinger {
3036e48354ceSNicholas Bellinger 	int tx_size = 0;
3037e48354ceSNicholas Bellinger 	struct iscsi_r2t *r2t;
3038e48354ceSNicholas Bellinger 	struct iscsi_r2t_rsp *hdr;
30396f3c0e69SAndy Grover 	int ret;
3040e48354ceSNicholas Bellinger 
3041e48354ceSNicholas Bellinger 	r2t = iscsit_get_r2t_from_list(cmd);
3042e48354ceSNicholas Bellinger 	if (!r2t)
3043e48354ceSNicholas Bellinger 		return -1;
3044e48354ceSNicholas Bellinger 
3045e48354ceSNicholas Bellinger 	hdr			= (struct iscsi_r2t_rsp *) cmd->pdu;
3046e48354ceSNicholas Bellinger 	memset(hdr, 0, ISCSI_HDR_LEN);
3047e48354ceSNicholas Bellinger 	hdr->opcode		= ISCSI_OP_R2T;
3048e48354ceSNicholas Bellinger 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
3049e48354ceSNicholas Bellinger 	int_to_scsilun(cmd->se_cmd.orig_fe_lun,
3050e48354ceSNicholas Bellinger 			(struct scsi_lun *)&hdr->lun);
305166c7db68SChristoph Hellwig 	hdr->itt		= cmd->init_task_tag;
3052c1e34b64SSagi Grimberg 	r2t->targ_xfer_tag	= session_get_next_ttt(conn->sess);
3053e48354ceSNicholas Bellinger 	hdr->ttt		= cpu_to_be32(r2t->targ_xfer_tag);
3054e48354ceSNicholas Bellinger 	hdr->statsn		= cpu_to_be32(conn->stat_sn);
3055e48354ceSNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
3056e48354ceSNicholas Bellinger 	hdr->max_cmdsn		= cpu_to_be32(conn->sess->max_cmd_sn);
3057e48354ceSNicholas Bellinger 	hdr->r2tsn		= cpu_to_be32(r2t->r2t_sn);
3058e48354ceSNicholas Bellinger 	hdr->data_offset	= cpu_to_be32(r2t->offset);
3059e48354ceSNicholas Bellinger 	hdr->data_length	= cpu_to_be32(r2t->xfer_len);
3060e48354ceSNicholas Bellinger 
3061e48354ceSNicholas Bellinger 	cmd->iov_misc[0].iov_base	= cmd->pdu;
3062e48354ceSNicholas Bellinger 	cmd->iov_misc[0].iov_len	= ISCSI_HDR_LEN;
3063e48354ceSNicholas Bellinger 	tx_size += ISCSI_HDR_LEN;
3064e48354ceSNicholas Bellinger 
3065e48354ceSNicholas Bellinger 	if (conn->conn_ops->HeaderDigest) {
3066e48354ceSNicholas Bellinger 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
3067e48354ceSNicholas Bellinger 
306880690fdbSGeert Uytterhoeven 		iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr,
306980690fdbSGeert Uytterhoeven 				ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
3070e48354ceSNicholas Bellinger 
3071e48354ceSNicholas Bellinger 		cmd->iov_misc[0].iov_len += ISCSI_CRC_LEN;
3072e48354ceSNicholas Bellinger 		tx_size += ISCSI_CRC_LEN;
3073e48354ceSNicholas Bellinger 		pr_debug("Attaching CRC32 HeaderDigest for R2T"
3074e48354ceSNicholas Bellinger 			" PDU 0x%08x\n", *header_digest);
3075e48354ceSNicholas Bellinger 	}
3076e48354ceSNicholas Bellinger 
3077e48354ceSNicholas Bellinger 	pr_debug("Built %sR2T, ITT: 0x%08x, TTT: 0x%08x, StatSN:"
3078e48354ceSNicholas Bellinger 		" 0x%08x, R2TSN: 0x%08x, Offset: %u, DDTL: %u, CID: %hu\n",
3079e48354ceSNicholas Bellinger 		(!r2t->recovery_r2t) ? "" : "Recovery ", cmd->init_task_tag,
3080e48354ceSNicholas Bellinger 		r2t->targ_xfer_tag, ntohl(hdr->statsn), r2t->r2t_sn,
3081e48354ceSNicholas Bellinger 			r2t->offset, r2t->xfer_len, conn->cid);
3082e48354ceSNicholas Bellinger 
3083e48354ceSNicholas Bellinger 	cmd->iov_misc_count = 1;
3084e48354ceSNicholas Bellinger 	cmd->tx_size = tx_size;
3085e48354ceSNicholas Bellinger 
3086e48354ceSNicholas Bellinger 	spin_lock_bh(&cmd->r2t_lock);
3087e48354ceSNicholas Bellinger 	r2t->sent_r2t = 1;
3088e48354ceSNicholas Bellinger 	spin_unlock_bh(&cmd->r2t_lock);
3089e48354ceSNicholas Bellinger 
30906f3c0e69SAndy Grover 	ret = iscsit_send_tx_data(cmd, conn, 1);
30916f3c0e69SAndy Grover 	if (ret < 0) {
30926f3c0e69SAndy Grover 		iscsit_tx_thread_wait_for_tcp(conn);
30936f3c0e69SAndy Grover 		return ret;
30946f3c0e69SAndy Grover 	}
30956f3c0e69SAndy Grover 
30966f3c0e69SAndy Grover 	spin_lock_bh(&cmd->dataout_timeout_lock);
30976f3c0e69SAndy Grover 	iscsit_start_dataout_timer(cmd, conn);
30986f3c0e69SAndy Grover 	spin_unlock_bh(&cmd->dataout_timeout_lock);
30996f3c0e69SAndy Grover 
3100e48354ceSNicholas Bellinger 	return 0;
3101e48354ceSNicholas Bellinger }
3102e48354ceSNicholas Bellinger 
3103e48354ceSNicholas Bellinger /*
31048b1e1244SAndy Grover  *	@recovery: If called from iscsi_task_reassign_complete_write() for
3105e48354ceSNicholas Bellinger  *		connection recovery.
3106e48354ceSNicholas Bellinger  */
3107e48354ceSNicholas Bellinger int iscsit_build_r2ts_for_cmd(
3108e48354ceSNicholas Bellinger 	struct iscsi_conn *conn,
31093e1c81a9SNicholas Bellinger 	struct iscsi_cmd *cmd,
31108b1e1244SAndy Grover 	bool recovery)
3111e48354ceSNicholas Bellinger {
3112e48354ceSNicholas Bellinger 	int first_r2t = 1;
3113e48354ceSNicholas Bellinger 	u32 offset = 0, xfer_len = 0;
3114e48354ceSNicholas Bellinger 
3115e48354ceSNicholas Bellinger 	spin_lock_bh(&cmd->r2t_lock);
3116e48354ceSNicholas Bellinger 	if (cmd->cmd_flags & ICF_SENT_LAST_R2T) {
3117e48354ceSNicholas Bellinger 		spin_unlock_bh(&cmd->r2t_lock);
3118e48354ceSNicholas Bellinger 		return 0;
3119e48354ceSNicholas Bellinger 	}
3120e48354ceSNicholas Bellinger 
31218b1e1244SAndy Grover 	if (conn->sess->sess_ops->DataSequenceInOrder &&
31228b1e1244SAndy Grover 	    !recovery)
3123c6037cc5SAndy Grover 		cmd->r2t_offset = max(cmd->r2t_offset, cmd->write_data_done);
3124e48354ceSNicholas Bellinger 
3125e48354ceSNicholas Bellinger 	while (cmd->outstanding_r2ts < conn->sess->sess_ops->MaxOutstandingR2T) {
3126e48354ceSNicholas Bellinger 		if (conn->sess->sess_ops->DataSequenceInOrder) {
3127e48354ceSNicholas Bellinger 			offset = cmd->r2t_offset;
3128e48354ceSNicholas Bellinger 
31298b1e1244SAndy Grover 			if (first_r2t && recovery) {
31308b1e1244SAndy Grover 				int new_data_end = offset +
31318b1e1244SAndy Grover 					conn->sess->sess_ops->MaxBurstLength -
31328b1e1244SAndy Grover 					cmd->next_burst_len;
31338b1e1244SAndy Grover 
3134ebf1d95cSAndy Grover 				if (new_data_end > cmd->se_cmd.data_length)
3135ebf1d95cSAndy Grover 					xfer_len = cmd->se_cmd.data_length - offset;
31368b1e1244SAndy Grover 				else
31378b1e1244SAndy Grover 					xfer_len =
31388b1e1244SAndy Grover 						conn->sess->sess_ops->MaxBurstLength -
31398b1e1244SAndy Grover 						cmd->next_burst_len;
3140e48354ceSNicholas Bellinger 			} else {
31418b1e1244SAndy Grover 				int new_data_end = offset +
3142e48354ceSNicholas Bellinger 					conn->sess->sess_ops->MaxBurstLength;
31438b1e1244SAndy Grover 
3144ebf1d95cSAndy Grover 				if (new_data_end > cmd->se_cmd.data_length)
3145ebf1d95cSAndy Grover 					xfer_len = cmd->se_cmd.data_length - offset;
31468b1e1244SAndy Grover 				else
31478b1e1244SAndy Grover 					xfer_len = conn->sess->sess_ops->MaxBurstLength;
3148e48354ceSNicholas Bellinger 			}
3149e48354ceSNicholas Bellinger 			cmd->r2t_offset += xfer_len;
3150e48354ceSNicholas Bellinger 
3151ebf1d95cSAndy Grover 			if (cmd->r2t_offset == cmd->se_cmd.data_length)
3152e48354ceSNicholas Bellinger 				cmd->cmd_flags |= ICF_SENT_LAST_R2T;
3153e48354ceSNicholas Bellinger 		} else {
3154e48354ceSNicholas Bellinger 			struct iscsi_seq *seq;
3155e48354ceSNicholas Bellinger 
3156e48354ceSNicholas Bellinger 			seq = iscsit_get_seq_holder_for_r2t(cmd);
3157e48354ceSNicholas Bellinger 			if (!seq) {
3158e48354ceSNicholas Bellinger 				spin_unlock_bh(&cmd->r2t_lock);
3159e48354ceSNicholas Bellinger 				return -1;
3160e48354ceSNicholas Bellinger 			}
3161e48354ceSNicholas Bellinger 
3162e48354ceSNicholas Bellinger 			offset = seq->offset;
3163e48354ceSNicholas Bellinger 			xfer_len = seq->xfer_len;
3164e48354ceSNicholas Bellinger 
3165e48354ceSNicholas Bellinger 			if (cmd->seq_send_order == cmd->seq_count)
3166e48354ceSNicholas Bellinger 				cmd->cmd_flags |= ICF_SENT_LAST_R2T;
3167e48354ceSNicholas Bellinger 		}
3168e48354ceSNicholas Bellinger 		cmd->outstanding_r2ts++;
3169e48354ceSNicholas Bellinger 		first_r2t = 0;
3170e48354ceSNicholas Bellinger 
3171e48354ceSNicholas Bellinger 		if (iscsit_add_r2t_to_list(cmd, offset, xfer_len, 0, 0) < 0) {
3172e48354ceSNicholas Bellinger 			spin_unlock_bh(&cmd->r2t_lock);
3173e48354ceSNicholas Bellinger 			return -1;
3174e48354ceSNicholas Bellinger 		}
3175e48354ceSNicholas Bellinger 
3176e48354ceSNicholas Bellinger 		if (cmd->cmd_flags & ICF_SENT_LAST_R2T)
3177e48354ceSNicholas Bellinger 			break;
3178e48354ceSNicholas Bellinger 	}
3179e48354ceSNicholas Bellinger 	spin_unlock_bh(&cmd->r2t_lock);
3180e48354ceSNicholas Bellinger 
3181e48354ceSNicholas Bellinger 	return 0;
3182e48354ceSNicholas Bellinger }
3183e48354ceSNicholas Bellinger 
31842ec5a8c1SNicholas Bellinger void iscsit_build_rsp_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
31852ec5a8c1SNicholas Bellinger 			bool inc_stat_sn, struct iscsi_scsi_rsp *hdr)
3186e48354ceSNicholas Bellinger {
31872ec5a8c1SNicholas Bellinger 	if (inc_stat_sn)
3188e48354ceSNicholas Bellinger 		cmd->stat_sn = conn->stat_sn++;
3189e48354ceSNicholas Bellinger 
319004f3b31bSNicholas Bellinger 	atomic_long_inc(&conn->sess->rsp_pdus);
3191e48354ceSNicholas Bellinger 
3192e48354ceSNicholas Bellinger 	memset(hdr, 0, ISCSI_HDR_LEN);
3193e48354ceSNicholas Bellinger 	hdr->opcode		= ISCSI_OP_SCSI_CMD_RSP;
3194e48354ceSNicholas Bellinger 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
3195e48354ceSNicholas Bellinger 	if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) {
3196e48354ceSNicholas Bellinger 		hdr->flags |= ISCSI_FLAG_CMD_OVERFLOW;
31977e46cf02SNicholas Bellinger 		hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
3198e48354ceSNicholas Bellinger 	} else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) {
3199e48354ceSNicholas Bellinger 		hdr->flags |= ISCSI_FLAG_CMD_UNDERFLOW;
32007e46cf02SNicholas Bellinger 		hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
3201e48354ceSNicholas Bellinger 	}
3202e48354ceSNicholas Bellinger 	hdr->response		= cmd->iscsi_response;
3203e48354ceSNicholas Bellinger 	hdr->cmd_status		= cmd->se_cmd.scsi_status;
320466c7db68SChristoph Hellwig 	hdr->itt		= cmd->init_task_tag;
3205e48354ceSNicholas Bellinger 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
3206e48354ceSNicholas Bellinger 
3207e48354ceSNicholas Bellinger 	iscsit_increment_maxcmdsn(cmd, conn->sess);
3208e48354ceSNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
3209e48354ceSNicholas Bellinger 	hdr->max_cmdsn		= cpu_to_be32(conn->sess->max_cmd_sn);
3210e48354ceSNicholas Bellinger 
32112ec5a8c1SNicholas Bellinger 	pr_debug("Built SCSI Response, ITT: 0x%08x, StatSN: 0x%08x,"
32122ec5a8c1SNicholas Bellinger 		" Response: 0x%02x, SAM Status: 0x%02x, CID: %hu\n",
32132ec5a8c1SNicholas Bellinger 		cmd->init_task_tag, cmd->stat_sn, cmd->se_cmd.scsi_status,
32142ec5a8c1SNicholas Bellinger 		cmd->se_cmd.scsi_status, conn->cid);
32152ec5a8c1SNicholas Bellinger }
32162ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_rsp_pdu);
32172ec5a8c1SNicholas Bellinger 
32182ec5a8c1SNicholas Bellinger static int iscsit_send_response(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
32192ec5a8c1SNicholas Bellinger {
32202ec5a8c1SNicholas Bellinger 	struct iscsi_scsi_rsp *hdr = (struct iscsi_scsi_rsp *)&cmd->pdu[0];
32212ec5a8c1SNicholas Bellinger 	struct kvec *iov;
32222ec5a8c1SNicholas Bellinger 	u32 padding = 0, tx_size = 0;
32232ec5a8c1SNicholas Bellinger 	int iov_count = 0;
32242ec5a8c1SNicholas Bellinger 	bool inc_stat_sn = (cmd->i_state == ISTATE_SEND_STATUS);
32252ec5a8c1SNicholas Bellinger 
32262ec5a8c1SNicholas Bellinger 	iscsit_build_rsp_pdu(cmd, conn, inc_stat_sn, hdr);
32272ec5a8c1SNicholas Bellinger 
3228e48354ceSNicholas Bellinger 	iov = &cmd->iov_misc[0];
3229e48354ceSNicholas Bellinger 	iov[iov_count].iov_base	= cmd->pdu;
3230e48354ceSNicholas Bellinger 	iov[iov_count++].iov_len = ISCSI_HDR_LEN;
3231e48354ceSNicholas Bellinger 	tx_size += ISCSI_HDR_LEN;
3232e48354ceSNicholas Bellinger 
3233e48354ceSNicholas Bellinger 	/*
3234e48354ceSNicholas Bellinger 	 * Attach SENSE DATA payload to iSCSI Response PDU
3235e48354ceSNicholas Bellinger 	 */
3236e48354ceSNicholas Bellinger 	if (cmd->se_cmd.sense_buffer &&
3237e48354ceSNicholas Bellinger 	   ((cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||
3238e48354ceSNicholas Bellinger 	    (cmd->se_cmd.se_cmd_flags & SCF_EMULATED_TASK_SENSE))) {
32399c58b7ddSRoland Dreier 		put_unaligned_be16(cmd->se_cmd.scsi_sense_length, cmd->sense_buffer);
32409c58b7ddSRoland Dreier 		cmd->se_cmd.scsi_sense_length += sizeof (__be16);
32419c58b7ddSRoland Dreier 
3242e48354ceSNicholas Bellinger 		padding		= -(cmd->se_cmd.scsi_sense_length) & 3;
324350e5c87dSChristoph Hellwig 		hton24(hdr->dlength, (u32)cmd->se_cmd.scsi_sense_length);
32449c58b7ddSRoland Dreier 		iov[iov_count].iov_base	= cmd->sense_buffer;
3245e48354ceSNicholas Bellinger 		iov[iov_count++].iov_len =
3246e48354ceSNicholas Bellinger 				(cmd->se_cmd.scsi_sense_length + padding);
3247e48354ceSNicholas Bellinger 		tx_size += cmd->se_cmd.scsi_sense_length;
3248e48354ceSNicholas Bellinger 
3249e48354ceSNicholas Bellinger 		if (padding) {
32509c58b7ddSRoland Dreier 			memset(cmd->sense_buffer +
3251e48354ceSNicholas Bellinger 				cmd->se_cmd.scsi_sense_length, 0, padding);
3252e48354ceSNicholas Bellinger 			tx_size += padding;
3253e48354ceSNicholas Bellinger 			pr_debug("Adding %u bytes of padding to"
3254e48354ceSNicholas Bellinger 				" SENSE.\n", padding);
3255e48354ceSNicholas Bellinger 		}
3256e48354ceSNicholas Bellinger 
3257e48354ceSNicholas Bellinger 		if (conn->conn_ops->DataDigest) {
3258e48354ceSNicholas Bellinger 			iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
32599c58b7ddSRoland Dreier 				cmd->sense_buffer,
3260e48354ceSNicholas Bellinger 				(cmd->se_cmd.scsi_sense_length + padding),
3261e48354ceSNicholas Bellinger 				0, NULL, (u8 *)&cmd->data_crc);
3262e48354ceSNicholas Bellinger 
3263e48354ceSNicholas Bellinger 			iov[iov_count].iov_base    = &cmd->data_crc;
3264e48354ceSNicholas Bellinger 			iov[iov_count++].iov_len     = ISCSI_CRC_LEN;
3265e48354ceSNicholas Bellinger 			tx_size += ISCSI_CRC_LEN;
3266e48354ceSNicholas Bellinger 
3267e48354ceSNicholas Bellinger 			pr_debug("Attaching CRC32 DataDigest for"
3268e48354ceSNicholas Bellinger 				" SENSE, %u bytes CRC 0x%08x\n",
3269e48354ceSNicholas Bellinger 				(cmd->se_cmd.scsi_sense_length + padding),
3270e48354ceSNicholas Bellinger 				cmd->data_crc);
3271e48354ceSNicholas Bellinger 		}
3272e48354ceSNicholas Bellinger 
3273e48354ceSNicholas Bellinger 		pr_debug("Attaching SENSE DATA: %u bytes to iSCSI"
3274e48354ceSNicholas Bellinger 				" Response PDU\n",
3275e48354ceSNicholas Bellinger 				cmd->se_cmd.scsi_sense_length);
3276e48354ceSNicholas Bellinger 	}
3277e48354ceSNicholas Bellinger 
3278e48354ceSNicholas Bellinger 	if (conn->conn_ops->HeaderDigest) {
3279e48354ceSNicholas Bellinger 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
3280e48354ceSNicholas Bellinger 
328180690fdbSGeert Uytterhoeven 		iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, cmd->pdu,
328280690fdbSGeert Uytterhoeven 				ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
3283e48354ceSNicholas Bellinger 
3284e48354ceSNicholas Bellinger 		iov[0].iov_len += ISCSI_CRC_LEN;
3285e48354ceSNicholas Bellinger 		tx_size += ISCSI_CRC_LEN;
3286e48354ceSNicholas Bellinger 		pr_debug("Attaching CRC32 HeaderDigest for Response"
3287e48354ceSNicholas Bellinger 				" PDU 0x%08x\n", *header_digest);
3288e48354ceSNicholas Bellinger 	}
3289e48354ceSNicholas Bellinger 
3290e48354ceSNicholas Bellinger 	cmd->iov_misc_count = iov_count;
3291e48354ceSNicholas Bellinger 	cmd->tx_size = tx_size;
3292e48354ceSNicholas Bellinger 
3293e48354ceSNicholas Bellinger 	return 0;
3294e48354ceSNicholas Bellinger }
3295e48354ceSNicholas Bellinger 
3296e48354ceSNicholas Bellinger static u8 iscsit_convert_tcm_tmr_rsp(struct se_tmr_req *se_tmr)
3297e48354ceSNicholas Bellinger {
3298e48354ceSNicholas Bellinger 	switch (se_tmr->response) {
3299e48354ceSNicholas Bellinger 	case TMR_FUNCTION_COMPLETE:
3300e48354ceSNicholas Bellinger 		return ISCSI_TMF_RSP_COMPLETE;
3301e48354ceSNicholas Bellinger 	case TMR_TASK_DOES_NOT_EXIST:
3302e48354ceSNicholas Bellinger 		return ISCSI_TMF_RSP_NO_TASK;
3303e48354ceSNicholas Bellinger 	case TMR_LUN_DOES_NOT_EXIST:
3304e48354ceSNicholas Bellinger 		return ISCSI_TMF_RSP_NO_LUN;
3305e48354ceSNicholas Bellinger 	case TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED:
3306e48354ceSNicholas Bellinger 		return ISCSI_TMF_RSP_NOT_SUPPORTED;
3307e48354ceSNicholas Bellinger 	case TMR_FUNCTION_REJECTED:
3308e48354ceSNicholas Bellinger 	default:
3309e48354ceSNicholas Bellinger 		return ISCSI_TMF_RSP_REJECTED;
3310e48354ceSNicholas Bellinger 	}
3311e48354ceSNicholas Bellinger }
3312e48354ceSNicholas Bellinger 
33132ec5a8c1SNicholas Bellinger void
33142ec5a8c1SNicholas Bellinger iscsit_build_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
33152ec5a8c1SNicholas Bellinger 			  struct iscsi_tm_rsp *hdr)
3316e48354ceSNicholas Bellinger {
3317e48354ceSNicholas Bellinger 	struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
3318e48354ceSNicholas Bellinger 
3319e48354ceSNicholas Bellinger 	hdr->opcode		= ISCSI_OP_SCSI_TMFUNC_RSP;
33207ae0b103SNicholas Bellinger 	hdr->flags		= ISCSI_FLAG_CMD_FINAL;
3321e48354ceSNicholas Bellinger 	hdr->response		= iscsit_convert_tcm_tmr_rsp(se_tmr);
332266c7db68SChristoph Hellwig 	hdr->itt		= cmd->init_task_tag;
3323e48354ceSNicholas Bellinger 	cmd->stat_sn		= conn->stat_sn++;
3324e48354ceSNicholas Bellinger 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
3325e48354ceSNicholas Bellinger 
3326e48354ceSNicholas Bellinger 	iscsit_increment_maxcmdsn(cmd, conn->sess);
3327e48354ceSNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
3328e48354ceSNicholas Bellinger 	hdr->max_cmdsn		= cpu_to_be32(conn->sess->max_cmd_sn);
3329e48354ceSNicholas Bellinger 
33302ec5a8c1SNicholas Bellinger 	pr_debug("Built Task Management Response ITT: 0x%08x,"
33312ec5a8c1SNicholas Bellinger 		" StatSN: 0x%08x, Response: 0x%02x, CID: %hu\n",
33322ec5a8c1SNicholas Bellinger 		cmd->init_task_tag, cmd->stat_sn, hdr->response, conn->cid);
33332ec5a8c1SNicholas Bellinger }
33342ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_task_mgt_rsp);
33352ec5a8c1SNicholas Bellinger 
33362ec5a8c1SNicholas Bellinger static int
33372ec5a8c1SNicholas Bellinger iscsit_send_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
33382ec5a8c1SNicholas Bellinger {
33392ec5a8c1SNicholas Bellinger 	struct iscsi_tm_rsp *hdr = (struct iscsi_tm_rsp *)&cmd->pdu[0];
33402ec5a8c1SNicholas Bellinger 	u32 tx_size = 0;
33412ec5a8c1SNicholas Bellinger 
33422ec5a8c1SNicholas Bellinger 	iscsit_build_task_mgt_rsp(cmd, conn, hdr);
33432ec5a8c1SNicholas Bellinger 
3344e48354ceSNicholas Bellinger 	cmd->iov_misc[0].iov_base	= cmd->pdu;
3345e48354ceSNicholas Bellinger 	cmd->iov_misc[0].iov_len	= ISCSI_HDR_LEN;
3346e48354ceSNicholas Bellinger 	tx_size += ISCSI_HDR_LEN;
3347e48354ceSNicholas Bellinger 
3348e48354ceSNicholas Bellinger 	if (conn->conn_ops->HeaderDigest) {
3349e48354ceSNicholas Bellinger 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
3350e48354ceSNicholas Bellinger 
335180690fdbSGeert Uytterhoeven 		iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr,
335280690fdbSGeert Uytterhoeven 				ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
3353e48354ceSNicholas Bellinger 
3354e48354ceSNicholas Bellinger 		cmd->iov_misc[0].iov_len += ISCSI_CRC_LEN;
3355e48354ceSNicholas Bellinger 		tx_size += ISCSI_CRC_LEN;
3356e48354ceSNicholas Bellinger 		pr_debug("Attaching CRC32 HeaderDigest for Task"
3357e48354ceSNicholas Bellinger 			" Mgmt Response PDU 0x%08x\n", *header_digest);
3358e48354ceSNicholas Bellinger 	}
3359e48354ceSNicholas Bellinger 
3360e48354ceSNicholas Bellinger 	cmd->iov_misc_count = 1;
3361e48354ceSNicholas Bellinger 	cmd->tx_size = tx_size;
3362e48354ceSNicholas Bellinger 
3363e48354ceSNicholas Bellinger 	return 0;
3364e48354ceSNicholas Bellinger }
3365e48354ceSNicholas Bellinger 
33662f9bc894SNicholas Bellinger static bool iscsit_check_inaddr_any(struct iscsi_np *np)
33672f9bc894SNicholas Bellinger {
33682f9bc894SNicholas Bellinger 	bool ret = false;
33692f9bc894SNicholas Bellinger 
33702f9bc894SNicholas Bellinger 	if (np->np_sockaddr.ss_family == AF_INET6) {
33712f9bc894SNicholas Bellinger 		const struct sockaddr_in6 sin6 = {
33722f9bc894SNicholas Bellinger 			.sin6_addr = IN6ADDR_ANY_INIT };
33732f9bc894SNicholas Bellinger 		struct sockaddr_in6 *sock_in6 =
33742f9bc894SNicholas Bellinger 			 (struct sockaddr_in6 *)&np->np_sockaddr;
33752f9bc894SNicholas Bellinger 
33762f9bc894SNicholas Bellinger 		if (!memcmp(sock_in6->sin6_addr.s6_addr,
33772f9bc894SNicholas Bellinger 				sin6.sin6_addr.s6_addr, 16))
33782f9bc894SNicholas Bellinger 			ret = true;
33792f9bc894SNicholas Bellinger 	} else {
33802f9bc894SNicholas Bellinger 		struct sockaddr_in * sock_in =
33812f9bc894SNicholas Bellinger 			(struct sockaddr_in *)&np->np_sockaddr;
33822f9bc894SNicholas Bellinger 
3383cea0b4ceSChristoph Hellwig 		if (sock_in->sin_addr.s_addr == htonl(INADDR_ANY))
33842f9bc894SNicholas Bellinger 			ret = true;
33852f9bc894SNicholas Bellinger 	}
33862f9bc894SNicholas Bellinger 
33872f9bc894SNicholas Bellinger 	return ret;
33882f9bc894SNicholas Bellinger }
33892f9bc894SNicholas Bellinger 
33908b1e1244SAndy Grover #define SENDTARGETS_BUF_LIMIT 32768U
33918b1e1244SAndy Grover 
339222c7aaa5SSagi Grimberg static int
339322c7aaa5SSagi Grimberg iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
3394e4f4e801SSagi Grimberg 				  enum iscsit_transport_type network_transport,
3395e4f4e801SSagi Grimberg 				  int skip_bytes, bool *completed)
3396e48354ceSNicholas Bellinger {
3397e48354ceSNicholas Bellinger 	char *payload = NULL;
3398e48354ceSNicholas Bellinger 	struct iscsi_conn *conn = cmd->conn;
3399e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg;
3400e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn;
3401e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np;
3402e48354ceSNicholas Bellinger 	int buffer_len, end_of_buf = 0, len = 0, payload_len = 0;
34032dd1d53fSThomas Glanzmann 	int target_name_printed;
34048b1e1244SAndy Grover 	unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */
34056665889cSNicholas Bellinger 	unsigned char *text_in = cmd->text_in_ptr, *text_ptr = NULL;
3406e48354ceSNicholas Bellinger 
3407be7dcfb6SSagi Grimberg 	buffer_len = min(conn->conn_ops->MaxRecvDataSegmentLength,
34088b1e1244SAndy Grover 			 SENDTARGETS_BUF_LIMIT);
3409e48354ceSNicholas Bellinger 
3410e48354ceSNicholas Bellinger 	payload = kzalloc(buffer_len, GFP_KERNEL);
3411e48354ceSNicholas Bellinger 	if (!payload) {
3412e48354ceSNicholas Bellinger 		pr_err("Unable to allocate memory for sendtargets"
3413e48354ceSNicholas Bellinger 				" response.\n");
3414e48354ceSNicholas Bellinger 		return -ENOMEM;
3415e48354ceSNicholas Bellinger 	}
34166665889cSNicholas Bellinger 	/*
34178060b8ddSAndy Grover 	 * Locate pointer to iqn./eui. string for ICF_SENDTARGETS_SINGLE
34186665889cSNicholas Bellinger 	 * explicit case..
34196665889cSNicholas Bellinger 	 */
34208060b8ddSAndy Grover 	if (cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) {
34216665889cSNicholas Bellinger 		text_ptr = strchr(text_in, '=');
34226665889cSNicholas Bellinger 		if (!text_ptr) {
34236665889cSNicholas Bellinger 			pr_err("Unable to locate '=' string in text_in:"
34246665889cSNicholas Bellinger 			       " %s\n", text_in);
34254f45d320SDan Carpenter 			kfree(payload);
34266665889cSNicholas Bellinger 			return -EINVAL;
34276665889cSNicholas Bellinger 		}
34286665889cSNicholas Bellinger 		/*
34296665889cSNicholas Bellinger 		 * Skip over '=' character..
34306665889cSNicholas Bellinger 		 */
34316665889cSNicholas Bellinger 		text_ptr += 1;
34326665889cSNicholas Bellinger 	}
3433e48354ceSNicholas Bellinger 
3434e48354ceSNicholas Bellinger 	spin_lock(&tiqn_lock);
3435e48354ceSNicholas Bellinger 	list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) {
34368060b8ddSAndy Grover 		if ((cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) &&
34376665889cSNicholas Bellinger 		     strcmp(tiqn->tiqn, text_ptr)) {
34386665889cSNicholas Bellinger 			continue;
34396665889cSNicholas Bellinger 		}
34406665889cSNicholas Bellinger 
34412dd1d53fSThomas Glanzmann 		target_name_printed = 0;
3442e48354ceSNicholas Bellinger 
3443e48354ceSNicholas Bellinger 		spin_lock(&tiqn->tiqn_tpg_lock);
3444e48354ceSNicholas Bellinger 		list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
3445e48354ceSNicholas Bellinger 
34462dd1d53fSThomas Glanzmann 			/* If demo_mode_discovery=0 and generate_node_acls=0
34472dd1d53fSThomas Glanzmann 			 * (demo mode dislabed) do not return
34482dd1d53fSThomas Glanzmann 			 * TargetName+TargetAddress unless a NodeACL exists.
34492dd1d53fSThomas Glanzmann 			 */
34502dd1d53fSThomas Glanzmann 
34512dd1d53fSThomas Glanzmann 			if ((tpg->tpg_attrib.generate_node_acls == 0) &&
34522dd1d53fSThomas Glanzmann 			    (tpg->tpg_attrib.demo_mode_discovery == 0) &&
34532dd1d53fSThomas Glanzmann 			    (!core_tpg_get_initiator_node_acl(&tpg->tpg_se_tpg,
34542dd1d53fSThomas Glanzmann 				cmd->conn->sess->sess_ops->InitiatorName))) {
34552dd1d53fSThomas Glanzmann 				continue;
34562dd1d53fSThomas Glanzmann 			}
34572dd1d53fSThomas Glanzmann 
3458e48354ceSNicholas Bellinger 			spin_lock(&tpg->tpg_state_lock);
3459e48354ceSNicholas Bellinger 			if ((tpg->tpg_state == TPG_STATE_FREE) ||
3460e48354ceSNicholas Bellinger 			    (tpg->tpg_state == TPG_STATE_INACTIVE)) {
3461e48354ceSNicholas Bellinger 				spin_unlock(&tpg->tpg_state_lock);
3462e48354ceSNicholas Bellinger 				continue;
3463e48354ceSNicholas Bellinger 			}
3464e48354ceSNicholas Bellinger 			spin_unlock(&tpg->tpg_state_lock);
3465e48354ceSNicholas Bellinger 
3466e48354ceSNicholas Bellinger 			spin_lock(&tpg->tpg_np_lock);
3467e48354ceSNicholas Bellinger 			list_for_each_entry(tpg_np, &tpg->tpg_gnp_list,
3468e48354ceSNicholas Bellinger 						tpg_np_list) {
34692f9bc894SNicholas Bellinger 				struct iscsi_np *np = tpg_np->tpg_np;
34702f9bc894SNicholas Bellinger 				bool inaddr_any = iscsit_check_inaddr_any(np);
34711997e625SAndy Grover 				char *fmt_str;
34722f9bc894SNicholas Bellinger 
347322c7aaa5SSagi Grimberg 				if (np->np_network_transport != network_transport)
347422c7aaa5SSagi Grimberg 					continue;
347522c7aaa5SSagi Grimberg 
34762dd1d53fSThomas Glanzmann 				if (!target_name_printed) {
34772dd1d53fSThomas Glanzmann 					len = sprintf(buf, "TargetName=%s",
34782dd1d53fSThomas Glanzmann 						      tiqn->tiqn);
34792dd1d53fSThomas Glanzmann 					len += 1;
34802dd1d53fSThomas Glanzmann 
34812dd1d53fSThomas Glanzmann 					if ((len + payload_len) > buffer_len) {
34822dd1d53fSThomas Glanzmann 						spin_unlock(&tpg->tpg_np_lock);
34832dd1d53fSThomas Glanzmann 						spin_unlock(&tiqn->tiqn_tpg_lock);
34842dd1d53fSThomas Glanzmann 						end_of_buf = 1;
34852dd1d53fSThomas Glanzmann 						goto eob;
34862dd1d53fSThomas Glanzmann 					}
3487e4f4e801SSagi Grimberg 
3488e4f4e801SSagi Grimberg 					if (skip_bytes && len <= skip_bytes) {
3489e4f4e801SSagi Grimberg 						skip_bytes -= len;
3490e4f4e801SSagi Grimberg 					} else {
34912dd1d53fSThomas Glanzmann 						memcpy(payload + payload_len, buf, len);
34922dd1d53fSThomas Glanzmann 						payload_len += len;
34932dd1d53fSThomas Glanzmann 						target_name_printed = 1;
3494e4f4e801SSagi Grimberg 						if (len > skip_bytes)
3495e4f4e801SSagi Grimberg 							skip_bytes = 0;
3496e4f4e801SSagi Grimberg 					}
34972dd1d53fSThomas Glanzmann 				}
34982dd1d53fSThomas Glanzmann 
34991997e625SAndy Grover 				if (np->np_sockaddr.ss_family == AF_INET6)
35001997e625SAndy Grover 					fmt_str = "TargetAddress=[%s]:%hu,%hu";
35011997e625SAndy Grover 				else
35021997e625SAndy Grover 					fmt_str = "TargetAddress=%s:%hu,%hu";
35031997e625SAndy Grover 
35041997e625SAndy Grover 				len = sprintf(buf, fmt_str,
35050bcc297eSChristophe Vu-Brugier 					inaddr_any ? conn->local_ip : np->np_ip,
3506f2774f43SSteven Allen 					np->np_port,
3507e48354ceSNicholas Bellinger 					tpg->tpgt);
3508e48354ceSNicholas Bellinger 				len += 1;
3509e48354ceSNicholas Bellinger 
3510e48354ceSNicholas Bellinger 				if ((len + payload_len) > buffer_len) {
3511e48354ceSNicholas Bellinger 					spin_unlock(&tpg->tpg_np_lock);
3512e48354ceSNicholas Bellinger 					spin_unlock(&tiqn->tiqn_tpg_lock);
3513e48354ceSNicholas Bellinger 					end_of_buf = 1;
3514e48354ceSNicholas Bellinger 					goto eob;
3515e48354ceSNicholas Bellinger 				}
3516e4f4e801SSagi Grimberg 
3517e4f4e801SSagi Grimberg 				if (skip_bytes && len <= skip_bytes) {
3518e4f4e801SSagi Grimberg 					skip_bytes -= len;
3519e4f4e801SSagi Grimberg 				} else {
35208359cf43SJörn Engel 					memcpy(payload + payload_len, buf, len);
3521e48354ceSNicholas Bellinger 					payload_len += len;
3522e4f4e801SSagi Grimberg 					if (len > skip_bytes)
3523e4f4e801SSagi Grimberg 						skip_bytes = 0;
3524e4f4e801SSagi Grimberg 				}
3525e48354ceSNicholas Bellinger 			}
3526e48354ceSNicholas Bellinger 			spin_unlock(&tpg->tpg_np_lock);
3527e48354ceSNicholas Bellinger 		}
3528e48354ceSNicholas Bellinger 		spin_unlock(&tiqn->tiqn_tpg_lock);
3529e48354ceSNicholas Bellinger eob:
3530e4f4e801SSagi Grimberg 		if (end_of_buf) {
3531e4f4e801SSagi Grimberg 			*completed = false;
3532e48354ceSNicholas Bellinger 			break;
3533e4f4e801SSagi Grimberg 		}
35346665889cSNicholas Bellinger 
35358060b8ddSAndy Grover 		if (cmd->cmd_flags & ICF_SENDTARGETS_SINGLE)
35366665889cSNicholas Bellinger 			break;
3537e48354ceSNicholas Bellinger 	}
3538e48354ceSNicholas Bellinger 	spin_unlock(&tiqn_lock);
3539e48354ceSNicholas Bellinger 
3540e48354ceSNicholas Bellinger 	cmd->buf_ptr = payload;
3541e48354ceSNicholas Bellinger 
3542e48354ceSNicholas Bellinger 	return payload_len;
3543e48354ceSNicholas Bellinger }
3544e48354ceSNicholas Bellinger 
3545889c8a68SNicholas Bellinger int
3546889c8a68SNicholas Bellinger iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
354722c7aaa5SSagi Grimberg 		      struct iscsi_text_rsp *hdr,
354822c7aaa5SSagi Grimberg 		      enum iscsit_transport_type network_transport)
3549e48354ceSNicholas Bellinger {
3550889c8a68SNicholas Bellinger 	int text_length, padding;
3551e4f4e801SSagi Grimberg 	bool completed = true;
3552e48354ceSNicholas Bellinger 
3553e4f4e801SSagi Grimberg 	text_length = iscsit_build_sendtargets_response(cmd, network_transport,
3554e4f4e801SSagi Grimberg 							cmd->read_data_done,
3555e4f4e801SSagi Grimberg 							&completed);
3556e48354ceSNicholas Bellinger 	if (text_length < 0)
3557e48354ceSNicholas Bellinger 		return text_length;
3558e48354ceSNicholas Bellinger 
3559e4f4e801SSagi Grimberg 	if (completed) {
3560e48354ceSNicholas Bellinger 		hdr->flags |= ISCSI_FLAG_CMD_FINAL;
3561e4f4e801SSagi Grimberg 	} else {
3562e4f4e801SSagi Grimberg 		hdr->flags |= ISCSI_FLAG_TEXT_CONTINUE;
3563e4f4e801SSagi Grimberg 		cmd->read_data_done += text_length;
3564e4f4e801SSagi Grimberg 		if (cmd->targ_xfer_tag == 0xFFFFFFFF)
3565e4f4e801SSagi Grimberg 			cmd->targ_xfer_tag = session_get_next_ttt(conn->sess);
3566e4f4e801SSagi Grimberg 	}
3567e4f4e801SSagi Grimberg 	hdr->opcode = ISCSI_OP_TEXT_RSP;
3568889c8a68SNicholas Bellinger 	padding = ((-text_length) & 3);
3569e48354ceSNicholas Bellinger 	hton24(hdr->dlength, text_length);
357066c7db68SChristoph Hellwig 	hdr->itt = cmd->init_task_tag;
3571e48354ceSNicholas Bellinger 	hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
3572e48354ceSNicholas Bellinger 	cmd->stat_sn = conn->stat_sn++;
3573e48354ceSNicholas Bellinger 	hdr->statsn = cpu_to_be32(cmd->stat_sn);
3574e48354ceSNicholas Bellinger 
3575e48354ceSNicholas Bellinger 	iscsit_increment_maxcmdsn(cmd, conn->sess);
3576e4f4e801SSagi Grimberg 	/*
3577e4f4e801SSagi Grimberg 	 * Reset maxcmdsn_inc in multi-part text payload exchanges to
3578e4f4e801SSagi Grimberg 	 * correctly increment MaxCmdSN for each response answering a
3579e4f4e801SSagi Grimberg 	 * non immediate text request with a valid CmdSN.
3580e4f4e801SSagi Grimberg 	 */
3581e4f4e801SSagi Grimberg 	cmd->maxcmdsn_inc = 0;
3582e48354ceSNicholas Bellinger 	hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
3583e48354ceSNicholas Bellinger 	hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
3584e48354ceSNicholas Bellinger 
3585e4f4e801SSagi Grimberg 	pr_debug("Built Text Response: ITT: 0x%08x, TTT: 0x%08x, StatSN: 0x%08x,"
3586e4f4e801SSagi Grimberg 		" Length: %u, CID: %hu F: %d C: %d\n", cmd->init_task_tag,
3587e4f4e801SSagi Grimberg 		cmd->targ_xfer_tag, cmd->stat_sn, text_length, conn->cid,
3588e4f4e801SSagi Grimberg 		!!(hdr->flags & ISCSI_FLAG_CMD_FINAL),
3589e4f4e801SSagi Grimberg 		!!(hdr->flags & ISCSI_FLAG_TEXT_CONTINUE));
3590e48354ceSNicholas Bellinger 
3591889c8a68SNicholas Bellinger 	return text_length + padding;
3592889c8a68SNicholas Bellinger }
3593889c8a68SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_text_rsp);
3594889c8a68SNicholas Bellinger 
3595889c8a68SNicholas Bellinger static int iscsit_send_text_rsp(
3596889c8a68SNicholas Bellinger 	struct iscsi_cmd *cmd,
3597889c8a68SNicholas Bellinger 	struct iscsi_conn *conn)
3598889c8a68SNicholas Bellinger {
3599889c8a68SNicholas Bellinger 	struct iscsi_text_rsp *hdr = (struct iscsi_text_rsp *)cmd->pdu;
3600889c8a68SNicholas Bellinger 	struct kvec *iov;
3601889c8a68SNicholas Bellinger 	u32 tx_size = 0;
3602889c8a68SNicholas Bellinger 	int text_length, iov_count = 0, rc;
3603889c8a68SNicholas Bellinger 
360422c7aaa5SSagi Grimberg 	rc = iscsit_build_text_rsp(cmd, conn, hdr, ISCSI_TCP);
3605889c8a68SNicholas Bellinger 	if (rc < 0)
3606889c8a68SNicholas Bellinger 		return rc;
3607889c8a68SNicholas Bellinger 
3608889c8a68SNicholas Bellinger 	text_length = rc;
3609889c8a68SNicholas Bellinger 	iov = &cmd->iov_misc[0];
3610e48354ceSNicholas Bellinger 	iov[iov_count].iov_base = cmd->pdu;
3611e48354ceSNicholas Bellinger 	iov[iov_count++].iov_len = ISCSI_HDR_LEN;
3612e48354ceSNicholas Bellinger 	iov[iov_count].iov_base	= cmd->buf_ptr;
3613889c8a68SNicholas Bellinger 	iov[iov_count++].iov_len = text_length;
3614e48354ceSNicholas Bellinger 
3615889c8a68SNicholas Bellinger 	tx_size += (ISCSI_HDR_LEN + text_length);
3616e48354ceSNicholas Bellinger 
3617e48354ceSNicholas Bellinger 	if (conn->conn_ops->HeaderDigest) {
3618e48354ceSNicholas Bellinger 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
3619e48354ceSNicholas Bellinger 
362080690fdbSGeert Uytterhoeven 		iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr,
362180690fdbSGeert Uytterhoeven 				ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
3622e48354ceSNicholas Bellinger 
3623e48354ceSNicholas Bellinger 		iov[0].iov_len += ISCSI_CRC_LEN;
3624e48354ceSNicholas Bellinger 		tx_size += ISCSI_CRC_LEN;
3625e48354ceSNicholas Bellinger 		pr_debug("Attaching CRC32 HeaderDigest for"
3626e48354ceSNicholas Bellinger 			" Text Response PDU 0x%08x\n", *header_digest);
3627e48354ceSNicholas Bellinger 	}
3628e48354ceSNicholas Bellinger 
3629e48354ceSNicholas Bellinger 	if (conn->conn_ops->DataDigest) {
3630e48354ceSNicholas Bellinger 		iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
3631889c8a68SNicholas Bellinger 				cmd->buf_ptr, text_length,
3632e48354ceSNicholas Bellinger 				0, NULL, (u8 *)&cmd->data_crc);
3633e48354ceSNicholas Bellinger 
3634e48354ceSNicholas Bellinger 		iov[iov_count].iov_base	= &cmd->data_crc;
3635e48354ceSNicholas Bellinger 		iov[iov_count++].iov_len = ISCSI_CRC_LEN;
3636e48354ceSNicholas Bellinger 		tx_size	+= ISCSI_CRC_LEN;
3637e48354ceSNicholas Bellinger 
3638e48354ceSNicholas Bellinger 		pr_debug("Attaching DataDigest for %u bytes of text"
3639889c8a68SNicholas Bellinger 			" data, CRC 0x%08x\n", text_length,
3640e48354ceSNicholas Bellinger 			cmd->data_crc);
3641e48354ceSNicholas Bellinger 	}
3642e48354ceSNicholas Bellinger 
3643e48354ceSNicholas Bellinger 	cmd->iov_misc_count = iov_count;
3644e48354ceSNicholas Bellinger 	cmd->tx_size = tx_size;
3645e48354ceSNicholas Bellinger 
3646e48354ceSNicholas Bellinger 	return 0;
3647e48354ceSNicholas Bellinger }
3648e48354ceSNicholas Bellinger 
36492ec5a8c1SNicholas Bellinger void
36502ec5a8c1SNicholas Bellinger iscsit_build_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
36512ec5a8c1SNicholas Bellinger 		    struct iscsi_reject *hdr)
3652e48354ceSNicholas Bellinger {
3653e48354ceSNicholas Bellinger 	hdr->opcode		= ISCSI_OP_REJECT;
3654ba159914SNicholas Bellinger 	hdr->reason		= cmd->reject_reason;
3655e48354ceSNicholas Bellinger 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
3656e48354ceSNicholas Bellinger 	hton24(hdr->dlength, ISCSI_HDR_LEN);
365750e5c87dSChristoph Hellwig 	hdr->ffffffff		= cpu_to_be32(0xffffffff);
3658e48354ceSNicholas Bellinger 	cmd->stat_sn		= conn->stat_sn++;
3659e48354ceSNicholas Bellinger 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
3660e48354ceSNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
3661e48354ceSNicholas Bellinger 	hdr->max_cmdsn		= cpu_to_be32(conn->sess->max_cmd_sn);
3662e48354ceSNicholas Bellinger 
36632ec5a8c1SNicholas Bellinger }
36642ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_reject);
3665e48354ceSNicholas Bellinger 
36662ec5a8c1SNicholas Bellinger static int iscsit_send_reject(
36672ec5a8c1SNicholas Bellinger 	struct iscsi_cmd *cmd,
36682ec5a8c1SNicholas Bellinger 	struct iscsi_conn *conn)
36692ec5a8c1SNicholas Bellinger {
3670bfbdb31dSNicholas Bellinger 	struct iscsi_reject *hdr = (struct iscsi_reject *)&cmd->pdu[0];
36712ec5a8c1SNicholas Bellinger 	struct kvec *iov;
3672bfbdb31dSNicholas Bellinger 	u32 iov_count = 0, tx_size;
36732ec5a8c1SNicholas Bellinger 
3674bfbdb31dSNicholas Bellinger 	iscsit_build_reject(cmd, conn, hdr);
36752ec5a8c1SNicholas Bellinger 
36762ec5a8c1SNicholas Bellinger 	iov = &cmd->iov_misc[0];
3677e48354ceSNicholas Bellinger 	iov[iov_count].iov_base = cmd->pdu;
3678e48354ceSNicholas Bellinger 	iov[iov_count++].iov_len = ISCSI_HDR_LEN;
3679e48354ceSNicholas Bellinger 	iov[iov_count].iov_base = cmd->buf_ptr;
3680e48354ceSNicholas Bellinger 	iov[iov_count++].iov_len = ISCSI_HDR_LEN;
3681e48354ceSNicholas Bellinger 
3682e48354ceSNicholas Bellinger 	tx_size = (ISCSI_HDR_LEN + ISCSI_HDR_LEN);
3683e48354ceSNicholas Bellinger 
3684e48354ceSNicholas Bellinger 	if (conn->conn_ops->HeaderDigest) {
3685e48354ceSNicholas Bellinger 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
3686e48354ceSNicholas Bellinger 
368780690fdbSGeert Uytterhoeven 		iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr,
368880690fdbSGeert Uytterhoeven 				ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest);
3689e48354ceSNicholas Bellinger 
3690e48354ceSNicholas Bellinger 		iov[0].iov_len += ISCSI_CRC_LEN;
3691e48354ceSNicholas Bellinger 		tx_size += ISCSI_CRC_LEN;
3692e48354ceSNicholas Bellinger 		pr_debug("Attaching CRC32 HeaderDigest for"
3693e48354ceSNicholas Bellinger 			" REJECT PDU 0x%08x\n", *header_digest);
3694e48354ceSNicholas Bellinger 	}
3695e48354ceSNicholas Bellinger 
3696e48354ceSNicholas Bellinger 	if (conn->conn_ops->DataDigest) {
369780690fdbSGeert Uytterhoeven 		iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, cmd->buf_ptr,
369880690fdbSGeert Uytterhoeven 				ISCSI_HDR_LEN, 0, NULL, (u8 *)&cmd->data_crc);
3699e48354ceSNicholas Bellinger 
3700e48354ceSNicholas Bellinger 		iov[iov_count].iov_base = &cmd->data_crc;
3701e48354ceSNicholas Bellinger 		iov[iov_count++].iov_len  = ISCSI_CRC_LEN;
3702e48354ceSNicholas Bellinger 		tx_size += ISCSI_CRC_LEN;
3703e48354ceSNicholas Bellinger 		pr_debug("Attaching CRC32 DataDigest for REJECT"
3704e48354ceSNicholas Bellinger 				" PDU 0x%08x\n", cmd->data_crc);
3705e48354ceSNicholas Bellinger 	}
3706e48354ceSNicholas Bellinger 
3707e48354ceSNicholas Bellinger 	cmd->iov_misc_count = iov_count;
3708e48354ceSNicholas Bellinger 	cmd->tx_size = tx_size;
3709e48354ceSNicholas Bellinger 
3710e48354ceSNicholas Bellinger 	pr_debug("Built Reject PDU StatSN: 0x%08x, Reason: 0x%02x,"
3711e48354ceSNicholas Bellinger 		" CID: %hu\n", ntohl(hdr->statsn), hdr->reason, conn->cid);
3712e48354ceSNicholas Bellinger 
3713e48354ceSNicholas Bellinger 	return 0;
3714e48354ceSNicholas Bellinger }
3715e48354ceSNicholas Bellinger 
3716e48354ceSNicholas Bellinger void iscsit_thread_get_cpumask(struct iscsi_conn *conn)
3717e48354ceSNicholas Bellinger {
3718e48354ceSNicholas Bellinger 	struct iscsi_thread_set *ts = conn->thread_set;
3719e48354ceSNicholas Bellinger 	int ord, cpu;
3720e48354ceSNicholas Bellinger 	/*
3721e48354ceSNicholas Bellinger 	 * thread_id is assigned from iscsit_global->ts_bitmap from
3722e48354ceSNicholas Bellinger 	 * within iscsi_thread_set.c:iscsi_allocate_thread_sets()
3723e48354ceSNicholas Bellinger 	 *
3724e48354ceSNicholas Bellinger 	 * Here we use thread_id to determine which CPU that this
3725e48354ceSNicholas Bellinger 	 * iSCSI connection's iscsi_thread_set will be scheduled to
3726e48354ceSNicholas Bellinger 	 * execute upon.
3727e48354ceSNicholas Bellinger 	 */
3728e48354ceSNicholas Bellinger 	ord = ts->thread_id % cpumask_weight(cpu_online_mask);
3729e48354ceSNicholas Bellinger 	for_each_online_cpu(cpu) {
3730e48354ceSNicholas Bellinger 		if (ord-- == 0) {
3731e48354ceSNicholas Bellinger 			cpumask_set_cpu(cpu, conn->conn_cpumask);
3732e48354ceSNicholas Bellinger 			return;
3733e48354ceSNicholas Bellinger 		}
3734e48354ceSNicholas Bellinger 	}
3735e48354ceSNicholas Bellinger 	/*
3736e48354ceSNicholas Bellinger 	 * This should never be reached..
3737e48354ceSNicholas Bellinger 	 */
3738e48354ceSNicholas Bellinger 	dump_stack();
3739e48354ceSNicholas Bellinger 	cpumask_setall(conn->conn_cpumask);
3740e48354ceSNicholas Bellinger }
3741e48354ceSNicholas Bellinger 
3742e48354ceSNicholas Bellinger static inline void iscsit_thread_check_cpumask(
3743e48354ceSNicholas Bellinger 	struct iscsi_conn *conn,
3744e48354ceSNicholas Bellinger 	struct task_struct *p,
3745e48354ceSNicholas Bellinger 	int mode)
3746e48354ceSNicholas Bellinger {
3747e48354ceSNicholas Bellinger 	/*
3748e48354ceSNicholas Bellinger 	 * mode == 1 signals iscsi_target_tx_thread() usage.
3749e48354ceSNicholas Bellinger 	 * mode == 0 signals iscsi_target_rx_thread() usage.
3750e48354ceSNicholas Bellinger 	 */
3751e48354ceSNicholas Bellinger 	if (mode == 1) {
3752e48354ceSNicholas Bellinger 		if (!conn->conn_tx_reset_cpumask)
3753e48354ceSNicholas Bellinger 			return;
3754e48354ceSNicholas Bellinger 		conn->conn_tx_reset_cpumask = 0;
3755e48354ceSNicholas Bellinger 	} else {
3756e48354ceSNicholas Bellinger 		if (!conn->conn_rx_reset_cpumask)
3757e48354ceSNicholas Bellinger 			return;
3758e48354ceSNicholas Bellinger 		conn->conn_rx_reset_cpumask = 0;
3759e48354ceSNicholas Bellinger 	}
3760e48354ceSNicholas Bellinger 	/*
3761e48354ceSNicholas Bellinger 	 * Update the CPU mask for this single kthread so that
3762e48354ceSNicholas Bellinger 	 * both TX and RX kthreads are scheduled to run on the
3763e48354ceSNicholas Bellinger 	 * same CPU.
3764e48354ceSNicholas Bellinger 	 */
3765e48354ceSNicholas Bellinger 	set_cpus_allowed_ptr(p, conn->conn_cpumask);
3766e48354ceSNicholas Bellinger }
3767e48354ceSNicholas Bellinger 
37682ec5a8c1SNicholas Bellinger static int
37692ec5a8c1SNicholas Bellinger iscsit_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state)
3770e48354ceSNicholas Bellinger {
37712ec5a8c1SNicholas Bellinger 	int ret;
37722ec5a8c1SNicholas Bellinger 
37732ec5a8c1SNicholas Bellinger 	switch (state) {
37742ec5a8c1SNicholas Bellinger 	case ISTATE_SEND_R2T:
37752ec5a8c1SNicholas Bellinger 		ret = iscsit_send_r2t(cmd, conn);
37762ec5a8c1SNicholas Bellinger 		if (ret < 0)
37772ec5a8c1SNicholas Bellinger 			goto err;
37782ec5a8c1SNicholas Bellinger 		break;
37792ec5a8c1SNicholas Bellinger 	case ISTATE_REMOVE:
37802ec5a8c1SNicholas Bellinger 		spin_lock_bh(&conn->cmd_lock);
37815159d763SNicholas Bellinger 		list_del_init(&cmd->i_conn_node);
37822ec5a8c1SNicholas Bellinger 		spin_unlock_bh(&conn->cmd_lock);
37832ec5a8c1SNicholas Bellinger 
3784aafc9d15SNicholas Bellinger 		iscsit_free_cmd(cmd, false);
37852ec5a8c1SNicholas Bellinger 		break;
37862ec5a8c1SNicholas Bellinger 	case ISTATE_SEND_NOPIN_WANT_RESPONSE:
37872ec5a8c1SNicholas Bellinger 		iscsit_mod_nopin_response_timer(conn);
37882ec5a8c1SNicholas Bellinger 		ret = iscsit_send_unsolicited_nopin(cmd, conn, 1);
37892ec5a8c1SNicholas Bellinger 		if (ret < 0)
37902ec5a8c1SNicholas Bellinger 			goto err;
37912ec5a8c1SNicholas Bellinger 		break;
37922ec5a8c1SNicholas Bellinger 	case ISTATE_SEND_NOPIN_NO_RESPONSE:
37932ec5a8c1SNicholas Bellinger 		ret = iscsit_send_unsolicited_nopin(cmd, conn, 0);
37942ec5a8c1SNicholas Bellinger 		if (ret < 0)
37952ec5a8c1SNicholas Bellinger 			goto err;
37962ec5a8c1SNicholas Bellinger 		break;
37972ec5a8c1SNicholas Bellinger 	default:
37982ec5a8c1SNicholas Bellinger 		pr_err("Unknown Opcode: 0x%02x ITT:"
37992ec5a8c1SNicholas Bellinger 		       " 0x%08x, i_state: %d on CID: %hu\n",
38002ec5a8c1SNicholas Bellinger 		       cmd->iscsi_opcode, cmd->init_task_tag, state,
38012ec5a8c1SNicholas Bellinger 		       conn->cid);
38022ec5a8c1SNicholas Bellinger 		goto err;
38032ec5a8c1SNicholas Bellinger 	}
38042ec5a8c1SNicholas Bellinger 
38052ec5a8c1SNicholas Bellinger 	return 0;
38062ec5a8c1SNicholas Bellinger 
38072ec5a8c1SNicholas Bellinger err:
38082ec5a8c1SNicholas Bellinger 	return -1;
38092ec5a8c1SNicholas Bellinger }
38102ec5a8c1SNicholas Bellinger 
38112ec5a8c1SNicholas Bellinger static int
38122ec5a8c1SNicholas Bellinger iscsit_handle_immediate_queue(struct iscsi_conn *conn)
38132ec5a8c1SNicholas Bellinger {
38142ec5a8c1SNicholas Bellinger 	struct iscsit_transport *t = conn->conn_transport;
38156f3c0e69SAndy Grover 	struct iscsi_queue_req *qr;
38166f3c0e69SAndy Grover 	struct iscsi_cmd *cmd;
3817e48354ceSNicholas Bellinger 	u8 state;
38186f3c0e69SAndy Grover 	int ret;
3819e48354ceSNicholas Bellinger 
3820c6037cc5SAndy Grover 	while ((qr = iscsit_get_cmd_from_immediate_queue(conn))) {
3821e48354ceSNicholas Bellinger 		atomic_set(&conn->check_immediate_queue, 0);
3822e48354ceSNicholas Bellinger 		cmd = qr->cmd;
3823e48354ceSNicholas Bellinger 		state = qr->state;
3824e48354ceSNicholas Bellinger 		kmem_cache_free(lio_qr_cache, qr);
3825e48354ceSNicholas Bellinger 
38262ec5a8c1SNicholas Bellinger 		ret = t->iscsit_immediate_queue(conn, cmd, state);
38276f3c0e69SAndy Grover 		if (ret < 0)
38282ec5a8c1SNicholas Bellinger 			return ret;
3829e48354ceSNicholas Bellinger 	}
3830e48354ceSNicholas Bellinger 
38316f3c0e69SAndy Grover 	return 0;
3832e48354ceSNicholas Bellinger }
38336f3c0e69SAndy Grover 
38342ec5a8c1SNicholas Bellinger static int
38352ec5a8c1SNicholas Bellinger iscsit_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state)
38366f3c0e69SAndy Grover {
38376f3c0e69SAndy Grover 	int ret;
3838e48354ceSNicholas Bellinger 
3839e48354ceSNicholas Bellinger check_rsp_state:
3840e48354ceSNicholas Bellinger 	switch (state) {
3841e48354ceSNicholas Bellinger 	case ISTATE_SEND_DATAIN:
38422ec5a8c1SNicholas Bellinger 		ret = iscsit_send_datain(cmd, conn);
38436f3c0e69SAndy Grover 		if (ret < 0)
38446f3c0e69SAndy Grover 			goto err;
38456f3c0e69SAndy Grover 		else if (!ret)
38466f3c0e69SAndy Grover 			/* more drs */
38476f3c0e69SAndy Grover 			goto check_rsp_state;
38486f3c0e69SAndy Grover 		else if (ret == 1) {
38496f3c0e69SAndy Grover 			/* all done */
38506f3c0e69SAndy Grover 			spin_lock_bh(&cmd->istate_lock);
38516f3c0e69SAndy Grover 			cmd->i_state = ISTATE_SENT_STATUS;
3852e48354ceSNicholas Bellinger 			spin_unlock_bh(&cmd->istate_lock);
3853fd3a9025SNicholas Bellinger 
3854fd3a9025SNicholas Bellinger 			if (atomic_read(&conn->check_immediate_queue))
3855fd3a9025SNicholas Bellinger 				return 1;
3856fd3a9025SNicholas Bellinger 
38572ec5a8c1SNicholas Bellinger 			return 0;
38586f3c0e69SAndy Grover 		} else if (ret == 2) {
38596f3c0e69SAndy Grover 			/* Still must send status,
38606f3c0e69SAndy Grover 			   SCF_TRANSPORT_TASK_SENSE was set */
38616f3c0e69SAndy Grover 			spin_lock_bh(&cmd->istate_lock);
38626f3c0e69SAndy Grover 			cmd->i_state = ISTATE_SEND_STATUS;
38636f3c0e69SAndy Grover 			spin_unlock_bh(&cmd->istate_lock);
38646f3c0e69SAndy Grover 			state = ISTATE_SEND_STATUS;
38656f3c0e69SAndy Grover 			goto check_rsp_state;
38666f3c0e69SAndy Grover 		}
38676f3c0e69SAndy Grover 
3868e48354ceSNicholas Bellinger 		break;
3869e48354ceSNicholas Bellinger 	case ISTATE_SEND_STATUS:
3870e48354ceSNicholas Bellinger 	case ISTATE_SEND_STATUS_RECOVERY:
38712ec5a8c1SNicholas Bellinger 		ret = iscsit_send_response(cmd, conn);
3872e48354ceSNicholas Bellinger 		break;
3873e48354ceSNicholas Bellinger 	case ISTATE_SEND_LOGOUTRSP:
38742ec5a8c1SNicholas Bellinger 		ret = iscsit_send_logout(cmd, conn);
3875e48354ceSNicholas Bellinger 		break;
3876e48354ceSNicholas Bellinger 	case ISTATE_SEND_ASYNCMSG:
3877e48354ceSNicholas Bellinger 		ret = iscsit_send_conn_drop_async_message(
3878e48354ceSNicholas Bellinger 			cmd, conn);
3879e48354ceSNicholas Bellinger 		break;
3880e48354ceSNicholas Bellinger 	case ISTATE_SEND_NOPIN:
38812ec5a8c1SNicholas Bellinger 		ret = iscsit_send_nopin(cmd, conn);
3882e48354ceSNicholas Bellinger 		break;
3883e48354ceSNicholas Bellinger 	case ISTATE_SEND_REJECT:
3884e48354ceSNicholas Bellinger 		ret = iscsit_send_reject(cmd, conn);
3885e48354ceSNicholas Bellinger 		break;
3886e48354ceSNicholas Bellinger 	case ISTATE_SEND_TASKMGTRSP:
3887e48354ceSNicholas Bellinger 		ret = iscsit_send_task_mgt_rsp(cmd, conn);
3888e48354ceSNicholas Bellinger 		if (ret != 0)
3889e48354ceSNicholas Bellinger 			break;
3890e48354ceSNicholas Bellinger 		ret = iscsit_tmr_post_handler(cmd, conn);
3891e48354ceSNicholas Bellinger 		if (ret != 0)
3892e48354ceSNicholas Bellinger 			iscsit_fall_back_to_erl0(conn->sess);
3893e48354ceSNicholas Bellinger 		break;
3894e48354ceSNicholas Bellinger 	case ISTATE_SEND_TEXTRSP:
3895e48354ceSNicholas Bellinger 		ret = iscsit_send_text_rsp(cmd, conn);
3896e48354ceSNicholas Bellinger 		break;
3897e48354ceSNicholas Bellinger 	default:
3898e48354ceSNicholas Bellinger 		pr_err("Unknown Opcode: 0x%02x ITT:"
3899e48354ceSNicholas Bellinger 		       " 0x%08x, i_state: %d on CID: %hu\n",
3900e48354ceSNicholas Bellinger 		       cmd->iscsi_opcode, cmd->init_task_tag,
3901e48354ceSNicholas Bellinger 		       state, conn->cid);
39026f3c0e69SAndy Grover 		goto err;
3903e48354ceSNicholas Bellinger 	}
3904c6037cc5SAndy Grover 	if (ret < 0)
39056f3c0e69SAndy Grover 		goto err;
3906e48354ceSNicholas Bellinger 
39076f3c0e69SAndy Grover 	if (iscsit_send_tx_data(cmd, conn, 1) < 0) {
3908e48354ceSNicholas Bellinger 		iscsit_tx_thread_wait_for_tcp(conn);
3909e48354ceSNicholas Bellinger 		iscsit_unmap_iovec(cmd);
39106f3c0e69SAndy Grover 		goto err;
3911e48354ceSNicholas Bellinger 	}
3912e48354ceSNicholas Bellinger 	iscsit_unmap_iovec(cmd);
3913e48354ceSNicholas Bellinger 
3914e48354ceSNicholas Bellinger 	switch (state) {
39156f3c0e69SAndy Grover 	case ISTATE_SEND_LOGOUTRSP:
39166f3c0e69SAndy Grover 		if (!iscsit_logout_post_handler(cmd, conn))
39176f3c0e69SAndy Grover 			goto restart;
39186f3c0e69SAndy Grover 		/* fall through */
3919e48354ceSNicholas Bellinger 	case ISTATE_SEND_STATUS:
3920e48354ceSNicholas Bellinger 	case ISTATE_SEND_ASYNCMSG:
3921e48354ceSNicholas Bellinger 	case ISTATE_SEND_NOPIN:
3922e48354ceSNicholas Bellinger 	case ISTATE_SEND_STATUS_RECOVERY:
3923e48354ceSNicholas Bellinger 	case ISTATE_SEND_TEXTRSP:
39246f3c0e69SAndy Grover 	case ISTATE_SEND_TASKMGTRSP:
3925ba159914SNicholas Bellinger 	case ISTATE_SEND_REJECT:
39266f3c0e69SAndy Grover 		spin_lock_bh(&cmd->istate_lock);
39276f3c0e69SAndy Grover 		cmd->i_state = ISTATE_SENT_STATUS;
39286f3c0e69SAndy Grover 		spin_unlock_bh(&cmd->istate_lock);
3929e48354ceSNicholas Bellinger 		break;
3930e48354ceSNicholas Bellinger 	default:
3931e48354ceSNicholas Bellinger 		pr_err("Unknown Opcode: 0x%02x ITT:"
3932e48354ceSNicholas Bellinger 		       " 0x%08x, i_state: %d on CID: %hu\n",
3933e48354ceSNicholas Bellinger 		       cmd->iscsi_opcode, cmd->init_task_tag,
3934e48354ceSNicholas Bellinger 		       cmd->i_state, conn->cid);
39356f3c0e69SAndy Grover 		goto err;
3936e48354ceSNicholas Bellinger 	}
3937e48354ceSNicholas Bellinger 
3938e48354ceSNicholas Bellinger 	if (atomic_read(&conn->check_immediate_queue))
3939fd3a9025SNicholas Bellinger 		return 1;
39406f3c0e69SAndy Grover 
39416f3c0e69SAndy Grover 	return 0;
39426f3c0e69SAndy Grover 
39436f3c0e69SAndy Grover err:
39446f3c0e69SAndy Grover 	return -1;
39456f3c0e69SAndy Grover restart:
39466f3c0e69SAndy Grover 	return -EAGAIN;
39476f3c0e69SAndy Grover }
39486f3c0e69SAndy Grover 
39492ec5a8c1SNicholas Bellinger static int iscsit_handle_response_queue(struct iscsi_conn *conn)
39502ec5a8c1SNicholas Bellinger {
39512ec5a8c1SNicholas Bellinger 	struct iscsit_transport *t = conn->conn_transport;
39522ec5a8c1SNicholas Bellinger 	struct iscsi_queue_req *qr;
39532ec5a8c1SNicholas Bellinger 	struct iscsi_cmd *cmd;
39542ec5a8c1SNicholas Bellinger 	u8 state;
39552ec5a8c1SNicholas Bellinger 	int ret;
39562ec5a8c1SNicholas Bellinger 
39572ec5a8c1SNicholas Bellinger 	while ((qr = iscsit_get_cmd_from_response_queue(conn))) {
39582ec5a8c1SNicholas Bellinger 		cmd = qr->cmd;
39592ec5a8c1SNicholas Bellinger 		state = qr->state;
39602ec5a8c1SNicholas Bellinger 		kmem_cache_free(lio_qr_cache, qr);
39612ec5a8c1SNicholas Bellinger 
39622ec5a8c1SNicholas Bellinger 		ret = t->iscsit_response_queue(conn, cmd, state);
39632ec5a8c1SNicholas Bellinger 		if (ret == 1 || ret < 0)
39642ec5a8c1SNicholas Bellinger 			return ret;
39652ec5a8c1SNicholas Bellinger 	}
39662ec5a8c1SNicholas Bellinger 
39672ec5a8c1SNicholas Bellinger 	return 0;
39682ec5a8c1SNicholas Bellinger }
39692ec5a8c1SNicholas Bellinger 
39706f3c0e69SAndy Grover int iscsi_target_tx_thread(void *arg)
39716f3c0e69SAndy Grover {
39726f3c0e69SAndy Grover 	int ret = 0;
39736f3c0e69SAndy Grover 	struct iscsi_conn *conn;
39746f3c0e69SAndy Grover 	struct iscsi_thread_set *ts = arg;
39756f3c0e69SAndy Grover 	/*
39766f3c0e69SAndy Grover 	 * Allow ourselves to be interrupted by SIGINT so that a
39776f3c0e69SAndy Grover 	 * connection recovery / failure event can be triggered externally.
39786f3c0e69SAndy Grover 	 */
39796f3c0e69SAndy Grover 	allow_signal(SIGINT);
39806f3c0e69SAndy Grover 
39816f3c0e69SAndy Grover restart:
39826f3c0e69SAndy Grover 	conn = iscsi_tx_thread_pre_handler(ts);
39836f3c0e69SAndy Grover 	if (!conn)
39846f3c0e69SAndy Grover 		goto out;
39856f3c0e69SAndy Grover 
39866f3c0e69SAndy Grover 	ret = 0;
39876f3c0e69SAndy Grover 
39886f3c0e69SAndy Grover 	while (!kthread_should_stop()) {
39896f3c0e69SAndy Grover 		/*
39906f3c0e69SAndy Grover 		 * Ensure that both TX and RX per connection kthreads
39916f3c0e69SAndy Grover 		 * are scheduled to run on the same CPU.
39926f3c0e69SAndy Grover 		 */
39936f3c0e69SAndy Grover 		iscsit_thread_check_cpumask(conn, current, 1);
39946f3c0e69SAndy Grover 
3995d5627acbSRoland Dreier 		wait_event_interruptible(conn->queues_wq,
3996d5627acbSRoland Dreier 					 !iscsit_conn_all_queues_empty(conn) ||
3997d5627acbSRoland Dreier 					 ts->status == ISCSI_THREAD_SET_RESET);
39986f3c0e69SAndy Grover 
39996f3c0e69SAndy Grover 		if ((ts->status == ISCSI_THREAD_SET_RESET) ||
40006f3c0e69SAndy Grover 		     signal_pending(current))
40016f3c0e69SAndy Grover 			goto transport_err;
40026f3c0e69SAndy Grover 
4003fd3a9025SNicholas Bellinger get_immediate:
40042ec5a8c1SNicholas Bellinger 		ret = iscsit_handle_immediate_queue(conn);
40056f3c0e69SAndy Grover 		if (ret < 0)
40066f3c0e69SAndy Grover 			goto transport_err;
40076f3c0e69SAndy Grover 
40082ec5a8c1SNicholas Bellinger 		ret = iscsit_handle_response_queue(conn);
4009fd3a9025SNicholas Bellinger 		if (ret == 1)
4010fd3a9025SNicholas Bellinger 			goto get_immediate;
4011fd3a9025SNicholas Bellinger 		else if (ret == -EAGAIN)
40126f3c0e69SAndy Grover 			goto restart;
40136f3c0e69SAndy Grover 		else if (ret < 0)
40146f3c0e69SAndy Grover 			goto transport_err;
4015e48354ceSNicholas Bellinger 	}
4016e48354ceSNicholas Bellinger 
4017e48354ceSNicholas Bellinger transport_err:
4018e48354ceSNicholas Bellinger 	iscsit_take_action_for_connection_exit(conn);
4019e48354ceSNicholas Bellinger 	goto restart;
4020e48354ceSNicholas Bellinger out:
4021e48354ceSNicholas Bellinger 	return 0;
4022e48354ceSNicholas Bellinger }
4023e48354ceSNicholas Bellinger 
40243e1c81a9SNicholas Bellinger static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf)
40253e1c81a9SNicholas Bellinger {
40263e1c81a9SNicholas Bellinger 	struct iscsi_hdr *hdr = (struct iscsi_hdr *)buf;
40273e1c81a9SNicholas Bellinger 	struct iscsi_cmd *cmd;
40283e1c81a9SNicholas Bellinger 	int ret = 0;
40293e1c81a9SNicholas Bellinger 
40303e1c81a9SNicholas Bellinger 	switch (hdr->opcode & ISCSI_OPCODE_MASK) {
40313e1c81a9SNicholas Bellinger 	case ISCSI_OP_SCSI_CMD:
4032676687c6SNicholas Bellinger 		cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
40333e1c81a9SNicholas Bellinger 		if (!cmd)
4034ba159914SNicholas Bellinger 			goto reject;
40353e1c81a9SNicholas Bellinger 
40363e1c81a9SNicholas Bellinger 		ret = iscsit_handle_scsi_cmd(conn, cmd, buf);
40373e1c81a9SNicholas Bellinger 		break;
40383e1c81a9SNicholas Bellinger 	case ISCSI_OP_SCSI_DATA_OUT:
40393e1c81a9SNicholas Bellinger 		ret = iscsit_handle_data_out(conn, buf);
40403e1c81a9SNicholas Bellinger 		break;
40413e1c81a9SNicholas Bellinger 	case ISCSI_OP_NOOP_OUT:
40423e1c81a9SNicholas Bellinger 		cmd = NULL;
40433e1c81a9SNicholas Bellinger 		if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
4044676687c6SNicholas Bellinger 			cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
40453e1c81a9SNicholas Bellinger 			if (!cmd)
4046ba159914SNicholas Bellinger 				goto reject;
40473e1c81a9SNicholas Bellinger 		}
40483e1c81a9SNicholas Bellinger 		ret = iscsit_handle_nop_out(conn, cmd, buf);
40493e1c81a9SNicholas Bellinger 		break;
40503e1c81a9SNicholas Bellinger 	case ISCSI_OP_SCSI_TMFUNC:
4051676687c6SNicholas Bellinger 		cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
40523e1c81a9SNicholas Bellinger 		if (!cmd)
4053ba159914SNicholas Bellinger 			goto reject;
40543e1c81a9SNicholas Bellinger 
40553e1c81a9SNicholas Bellinger 		ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf);
40563e1c81a9SNicholas Bellinger 		break;
40573e1c81a9SNicholas Bellinger 	case ISCSI_OP_TEXT:
4058e4f4e801SSagi Grimberg 		if (hdr->ttt != cpu_to_be32(0xFFFFFFFF)) {
4059e4f4e801SSagi Grimberg 			cmd = iscsit_find_cmd_from_itt(conn, hdr->itt);
4060e4f4e801SSagi Grimberg 			if (!cmd)
4061e4f4e801SSagi Grimberg 				goto reject;
4062e4f4e801SSagi Grimberg 		} else {
4063676687c6SNicholas Bellinger 			cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
406464534aa7SNicholas Bellinger 			if (!cmd)
4065ba159914SNicholas Bellinger 				goto reject;
4066e4f4e801SSagi Grimberg 		}
406764534aa7SNicholas Bellinger 
406864534aa7SNicholas Bellinger 		ret = iscsit_handle_text_cmd(conn, cmd, buf);
40693e1c81a9SNicholas Bellinger 		break;
40703e1c81a9SNicholas Bellinger 	case ISCSI_OP_LOGOUT:
4071676687c6SNicholas Bellinger 		cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
40723e1c81a9SNicholas Bellinger 		if (!cmd)
4073ba159914SNicholas Bellinger 			goto reject;
40743e1c81a9SNicholas Bellinger 
40753e1c81a9SNicholas Bellinger 		ret = iscsit_handle_logout_cmd(conn, cmd, buf);
40763e1c81a9SNicholas Bellinger 		if (ret > 0)
40773e1c81a9SNicholas Bellinger 			wait_for_completion_timeout(&conn->conn_logout_comp,
40783e1c81a9SNicholas Bellinger 					SECONDS_FOR_LOGOUT_COMP * HZ);
40793e1c81a9SNicholas Bellinger 		break;
40803e1c81a9SNicholas Bellinger 	case ISCSI_OP_SNACK:
40813e1c81a9SNicholas Bellinger 		ret = iscsit_handle_snack(conn, buf);
40823e1c81a9SNicholas Bellinger 		break;
40833e1c81a9SNicholas Bellinger 	default:
40843e1c81a9SNicholas Bellinger 		pr_err("Got unknown iSCSI OpCode: 0x%02x\n", hdr->opcode);
40853e1c81a9SNicholas Bellinger 		if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
40863e1c81a9SNicholas Bellinger 			pr_err("Cannot recover from unknown"
40873e1c81a9SNicholas Bellinger 			" opcode while ERL=0, closing iSCSI connection.\n");
40883e1c81a9SNicholas Bellinger 			return -1;
40893e1c81a9SNicholas Bellinger 		}
40903e1c81a9SNicholas Bellinger 		if (!conn->conn_ops->OFMarker) {
40913e1c81a9SNicholas Bellinger 			pr_err("Unable to recover from unknown"
40923e1c81a9SNicholas Bellinger 			" opcode while OFMarker=No, closing iSCSI"
40933e1c81a9SNicholas Bellinger 				" connection.\n");
40943e1c81a9SNicholas Bellinger 			return -1;
40953e1c81a9SNicholas Bellinger 		}
40963e1c81a9SNicholas Bellinger 		if (iscsit_recover_from_unknown_opcode(conn) < 0) {
40973e1c81a9SNicholas Bellinger 			pr_err("Unable to recover from unknown"
40983e1c81a9SNicholas Bellinger 				" opcode, closing iSCSI connection.\n");
40993e1c81a9SNicholas Bellinger 			return -1;
41003e1c81a9SNicholas Bellinger 		}
41013e1c81a9SNicholas Bellinger 		break;
41023e1c81a9SNicholas Bellinger 	}
41033e1c81a9SNicholas Bellinger 
41043e1c81a9SNicholas Bellinger 	return ret;
4105ba159914SNicholas Bellinger reject:
4106ba159914SNicholas Bellinger 	return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
41073e1c81a9SNicholas Bellinger }
41083e1c81a9SNicholas Bellinger 
4109e48354ceSNicholas Bellinger int iscsi_target_rx_thread(void *arg)
4110e48354ceSNicholas Bellinger {
4111e48354ceSNicholas Bellinger 	int ret;
4112e48354ceSNicholas Bellinger 	u8 buffer[ISCSI_HDR_LEN], opcode;
4113e48354ceSNicholas Bellinger 	u32 checksum = 0, digest = 0;
4114e48354ceSNicholas Bellinger 	struct iscsi_conn *conn = NULL;
41158359cf43SJörn Engel 	struct iscsi_thread_set *ts = arg;
4116e48354ceSNicholas Bellinger 	struct kvec iov;
4117e48354ceSNicholas Bellinger 	/*
4118e48354ceSNicholas Bellinger 	 * Allow ourselves to be interrupted by SIGINT so that a
4119e48354ceSNicholas Bellinger 	 * connection recovery / failure event can be triggered externally.
4120e48354ceSNicholas Bellinger 	 */
4121e48354ceSNicholas Bellinger 	allow_signal(SIGINT);
4122e48354ceSNicholas Bellinger 
4123e48354ceSNicholas Bellinger restart:
4124e48354ceSNicholas Bellinger 	conn = iscsi_rx_thread_pre_handler(ts);
4125e48354ceSNicholas Bellinger 	if (!conn)
4126e48354ceSNicholas Bellinger 		goto out;
4127e48354ceSNicholas Bellinger 
41283e1c81a9SNicholas Bellinger 	if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) {
41293e1c81a9SNicholas Bellinger 		struct completion comp;
41303e1c81a9SNicholas Bellinger 		int rc;
41313e1c81a9SNicholas Bellinger 
41323e1c81a9SNicholas Bellinger 		init_completion(&comp);
41333e1c81a9SNicholas Bellinger 		rc = wait_for_completion_interruptible(&comp);
41343e1c81a9SNicholas Bellinger 		if (rc < 0)
41353e1c81a9SNicholas Bellinger 			goto transport_err;
41363e1c81a9SNicholas Bellinger 
41373e1c81a9SNicholas Bellinger 		goto out;
41383e1c81a9SNicholas Bellinger 	}
41393e1c81a9SNicholas Bellinger 
4140e48354ceSNicholas Bellinger 	while (!kthread_should_stop()) {
4141e48354ceSNicholas Bellinger 		/*
4142e48354ceSNicholas Bellinger 		 * Ensure that both TX and RX per connection kthreads
4143e48354ceSNicholas Bellinger 		 * are scheduled to run on the same CPU.
4144e48354ceSNicholas Bellinger 		 */
4145e48354ceSNicholas Bellinger 		iscsit_thread_check_cpumask(conn, current, 0);
4146e48354ceSNicholas Bellinger 
4147e48354ceSNicholas Bellinger 		memset(buffer, 0, ISCSI_HDR_LEN);
4148e48354ceSNicholas Bellinger 		memset(&iov, 0, sizeof(struct kvec));
4149e48354ceSNicholas Bellinger 
4150e48354ceSNicholas Bellinger 		iov.iov_base	= buffer;
4151e48354ceSNicholas Bellinger 		iov.iov_len	= ISCSI_HDR_LEN;
4152e48354ceSNicholas Bellinger 
4153e48354ceSNicholas Bellinger 		ret = rx_data(conn, &iov, 1, ISCSI_HDR_LEN);
4154e48354ceSNicholas Bellinger 		if (ret != ISCSI_HDR_LEN) {
4155e48354ceSNicholas Bellinger 			iscsit_rx_thread_wait_for_tcp(conn);
4156e48354ceSNicholas Bellinger 			goto transport_err;
4157e48354ceSNicholas Bellinger 		}
4158e48354ceSNicholas Bellinger 
4159e48354ceSNicholas Bellinger 		if (conn->conn_ops->HeaderDigest) {
4160e48354ceSNicholas Bellinger 			iov.iov_base	= &digest;
4161e48354ceSNicholas Bellinger 			iov.iov_len	= ISCSI_CRC_LEN;
4162e48354ceSNicholas Bellinger 
4163e48354ceSNicholas Bellinger 			ret = rx_data(conn, &iov, 1, ISCSI_CRC_LEN);
4164e48354ceSNicholas Bellinger 			if (ret != ISCSI_CRC_LEN) {
4165e48354ceSNicholas Bellinger 				iscsit_rx_thread_wait_for_tcp(conn);
4166e48354ceSNicholas Bellinger 				goto transport_err;
4167e48354ceSNicholas Bellinger 			}
4168e48354ceSNicholas Bellinger 
4169e48354ceSNicholas Bellinger 			iscsit_do_crypto_hash_buf(&conn->conn_rx_hash,
4170e48354ceSNicholas Bellinger 					buffer, ISCSI_HDR_LEN,
4171e48354ceSNicholas Bellinger 					0, NULL, (u8 *)&checksum);
4172e48354ceSNicholas Bellinger 
4173e48354ceSNicholas Bellinger 			if (digest != checksum) {
4174e48354ceSNicholas Bellinger 				pr_err("HeaderDigest CRC32C failed,"
4175e48354ceSNicholas Bellinger 					" received 0x%08x, computed 0x%08x\n",
4176e48354ceSNicholas Bellinger 					digest, checksum);
4177e48354ceSNicholas Bellinger 				/*
4178e48354ceSNicholas Bellinger 				 * Set the PDU to 0xff so it will intentionally
4179e48354ceSNicholas Bellinger 				 * hit default in the switch below.
4180e48354ceSNicholas Bellinger 				 */
4181e48354ceSNicholas Bellinger 				memset(buffer, 0xff, ISCSI_HDR_LEN);
418204f3b31bSNicholas Bellinger 				atomic_long_inc(&conn->sess->conn_digest_errors);
4183e48354ceSNicholas Bellinger 			} else {
4184e48354ceSNicholas Bellinger 				pr_debug("Got HeaderDigest CRC32C"
4185e48354ceSNicholas Bellinger 						" 0x%08x\n", checksum);
4186e48354ceSNicholas Bellinger 			}
4187e48354ceSNicholas Bellinger 		}
4188e48354ceSNicholas Bellinger 
4189e48354ceSNicholas Bellinger 		if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT)
4190e48354ceSNicholas Bellinger 			goto transport_err;
4191e48354ceSNicholas Bellinger 
4192e48354ceSNicholas Bellinger 		opcode = buffer[0] & ISCSI_OPCODE_MASK;
4193e48354ceSNicholas Bellinger 
4194e48354ceSNicholas Bellinger 		if (conn->sess->sess_ops->SessionType &&
4195e48354ceSNicholas Bellinger 		   ((!(opcode & ISCSI_OP_TEXT)) ||
4196e48354ceSNicholas Bellinger 		    (!(opcode & ISCSI_OP_LOGOUT)))) {
4197e48354ceSNicholas Bellinger 			pr_err("Received illegal iSCSI Opcode: 0x%02x"
4198e48354ceSNicholas Bellinger 			" while in Discovery Session, rejecting.\n", opcode);
4199ba159914SNicholas Bellinger 			iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
4200ba159914SNicholas Bellinger 					  buffer);
4201e48354ceSNicholas Bellinger 			goto transport_err;
4202e48354ceSNicholas Bellinger 		}
4203e48354ceSNicholas Bellinger 
42043e1c81a9SNicholas Bellinger 		ret = iscsi_target_rx_opcode(conn, buffer);
42053e1c81a9SNicholas Bellinger 		if (ret < 0)
4206e48354ceSNicholas Bellinger 			goto transport_err;
4207e48354ceSNicholas Bellinger 	}
4208e48354ceSNicholas Bellinger 
4209e48354ceSNicholas Bellinger transport_err:
4210e48354ceSNicholas Bellinger 	if (!signal_pending(current))
4211e48354ceSNicholas Bellinger 		atomic_set(&conn->transport_failed, 1);
4212e48354ceSNicholas Bellinger 	iscsit_take_action_for_connection_exit(conn);
4213e48354ceSNicholas Bellinger 	goto restart;
4214e48354ceSNicholas Bellinger out:
4215e48354ceSNicholas Bellinger 	return 0;
4216e48354ceSNicholas Bellinger }
4217e48354ceSNicholas Bellinger 
4218e48354ceSNicholas Bellinger static void iscsit_release_commands_from_conn(struct iscsi_conn *conn)
4219e48354ceSNicholas Bellinger {
4220e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd = NULL, *cmd_tmp = NULL;
4221e48354ceSNicholas Bellinger 	struct iscsi_session *sess = conn->sess;
4222e48354ceSNicholas Bellinger 	/*
4223e48354ceSNicholas Bellinger 	 * We expect this function to only ever be called from either RX or TX
4224e48354ceSNicholas Bellinger 	 * thread context via iscsit_close_connection() once the other context
4225e48354ceSNicholas Bellinger 	 * has been reset -> returned sleeping pre-handler state.
4226e48354ceSNicholas Bellinger 	 */
4227e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
42282fbb471eSAndy Grover 	list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) {
4229e48354ceSNicholas Bellinger 
42305159d763SNicholas Bellinger 		list_del_init(&cmd->i_conn_node);
4231e48354ceSNicholas Bellinger 		spin_unlock_bh(&conn->cmd_lock);
4232e48354ceSNicholas Bellinger 
4233e48354ceSNicholas Bellinger 		iscsit_increment_maxcmdsn(cmd, sess);
4234e48354ceSNicholas Bellinger 
4235aafc9d15SNicholas Bellinger 		iscsit_free_cmd(cmd, true);
4236e48354ceSNicholas Bellinger 
4237e48354ceSNicholas Bellinger 		spin_lock_bh(&conn->cmd_lock);
4238e48354ceSNicholas Bellinger 	}
4239e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
4240e48354ceSNicholas Bellinger }
4241e48354ceSNicholas Bellinger 
4242e48354ceSNicholas Bellinger static void iscsit_stop_timers_for_cmds(
4243e48354ceSNicholas Bellinger 	struct iscsi_conn *conn)
4244e48354ceSNicholas Bellinger {
4245e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd;
4246e48354ceSNicholas Bellinger 
4247e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
42482fbb471eSAndy Grover 	list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) {
4249e48354ceSNicholas Bellinger 		if (cmd->data_direction == DMA_TO_DEVICE)
4250e48354ceSNicholas Bellinger 			iscsit_stop_dataout_timer(cmd);
4251e48354ceSNicholas Bellinger 	}
4252e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
4253e48354ceSNicholas Bellinger }
4254e48354ceSNicholas Bellinger 
4255e48354ceSNicholas Bellinger int iscsit_close_connection(
4256e48354ceSNicholas Bellinger 	struct iscsi_conn *conn)
4257e48354ceSNicholas Bellinger {
4258e48354ceSNicholas Bellinger 	int conn_logout = (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT);
4259e48354ceSNicholas Bellinger 	struct iscsi_session	*sess = conn->sess;
4260e48354ceSNicholas Bellinger 
4261e48354ceSNicholas Bellinger 	pr_debug("Closing iSCSI connection CID %hu on SID:"
4262e48354ceSNicholas Bellinger 		" %u\n", conn->cid, sess->sid);
4263e48354ceSNicholas Bellinger 	/*
4264f068fbc8SNicholas Bellinger 	 * Always up conn_logout_comp for the traditional TCP case just in case
4265f068fbc8SNicholas Bellinger 	 * the RX Thread in iscsi_target_rx_opcode() is sleeping and the logout
4266f068fbc8SNicholas Bellinger 	 * response never got sent because the connection failed.
4267f068fbc8SNicholas Bellinger 	 *
4268f068fbc8SNicholas Bellinger 	 * However for iser-target, isert_wait4logout() is using conn_logout_comp
4269f068fbc8SNicholas Bellinger 	 * to signal logout response TX interrupt completion.  Go ahead and skip
4270f068fbc8SNicholas Bellinger 	 * this for iser since isert_rx_opcode() does not wait on logout failure,
4271f068fbc8SNicholas Bellinger 	 * and to avoid iscsi_conn pointer dereference in iser-target code.
4272e48354ceSNicholas Bellinger 	 */
4273f068fbc8SNicholas Bellinger 	if (conn->conn_transport->transport_type == ISCSI_TCP)
4274e48354ceSNicholas Bellinger 		complete(&conn->conn_logout_comp);
4275e48354ceSNicholas Bellinger 
4276e48354ceSNicholas Bellinger 	iscsi_release_thread_set(conn);
4277e48354ceSNicholas Bellinger 
4278e48354ceSNicholas Bellinger 	iscsit_stop_timers_for_cmds(conn);
4279e48354ceSNicholas Bellinger 	iscsit_stop_nopin_response_timer(conn);
4280e48354ceSNicholas Bellinger 	iscsit_stop_nopin_timer(conn);
4281defd8848SNicholas Bellinger 
4282defd8848SNicholas Bellinger 	if (conn->conn_transport->iscsit_wait_conn)
4283defd8848SNicholas Bellinger 		conn->conn_transport->iscsit_wait_conn(conn);
4284defd8848SNicholas Bellinger 
4285e48354ceSNicholas Bellinger 	/*
4286e48354ceSNicholas Bellinger 	 * During Connection recovery drop unacknowledged out of order
4287e48354ceSNicholas Bellinger 	 * commands for this connection, and prepare the other commands
4288e48354ceSNicholas Bellinger 	 * for realligence.
4289e48354ceSNicholas Bellinger 	 *
4290e48354ceSNicholas Bellinger 	 * During normal operation clear the out of order commands (but
4291e48354ceSNicholas Bellinger 	 * do not free the struct iscsi_ooo_cmdsn's) and release all
4292e48354ceSNicholas Bellinger 	 * struct iscsi_cmds.
4293e48354ceSNicholas Bellinger 	 */
4294e48354ceSNicholas Bellinger 	if (atomic_read(&conn->connection_recovery)) {
4295e48354ceSNicholas Bellinger 		iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(conn);
4296e48354ceSNicholas Bellinger 		iscsit_prepare_cmds_for_realligance(conn);
4297e48354ceSNicholas Bellinger 	} else {
4298e48354ceSNicholas Bellinger 		iscsit_clear_ooo_cmdsns_for_conn(conn);
4299e48354ceSNicholas Bellinger 		iscsit_release_commands_from_conn(conn);
4300e48354ceSNicholas Bellinger 	}
4301bbc05048SNicholas Bellinger 	iscsit_free_queue_reqs_for_conn(conn);
4302e48354ceSNicholas Bellinger 
4303e48354ceSNicholas Bellinger 	/*
4304e48354ceSNicholas Bellinger 	 * Handle decrementing session or connection usage count if
4305e48354ceSNicholas Bellinger 	 * a logout response was not able to be sent because the
4306e48354ceSNicholas Bellinger 	 * connection failed.  Fall back to Session Recovery here.
4307e48354ceSNicholas Bellinger 	 */
4308e48354ceSNicholas Bellinger 	if (atomic_read(&conn->conn_logout_remove)) {
4309e48354ceSNicholas Bellinger 		if (conn->conn_logout_reason == ISCSI_LOGOUT_REASON_CLOSE_SESSION) {
4310e48354ceSNicholas Bellinger 			iscsit_dec_conn_usage_count(conn);
4311e48354ceSNicholas Bellinger 			iscsit_dec_session_usage_count(sess);
4312e48354ceSNicholas Bellinger 		}
4313e48354ceSNicholas Bellinger 		if (conn->conn_logout_reason == ISCSI_LOGOUT_REASON_CLOSE_CONNECTION)
4314e48354ceSNicholas Bellinger 			iscsit_dec_conn_usage_count(conn);
4315e48354ceSNicholas Bellinger 
4316e48354ceSNicholas Bellinger 		atomic_set(&conn->conn_logout_remove, 0);
4317e48354ceSNicholas Bellinger 		atomic_set(&sess->session_reinstatement, 0);
4318e48354ceSNicholas Bellinger 		atomic_set(&sess->session_fall_back_to_erl0, 1);
4319e48354ceSNicholas Bellinger 	}
4320e48354ceSNicholas Bellinger 
4321e48354ceSNicholas Bellinger 	spin_lock_bh(&sess->conn_lock);
4322e48354ceSNicholas Bellinger 	list_del(&conn->conn_list);
4323e48354ceSNicholas Bellinger 
4324e48354ceSNicholas Bellinger 	/*
4325e48354ceSNicholas Bellinger 	 * Attempt to let the Initiator know this connection failed by
4326e48354ceSNicholas Bellinger 	 * sending an Connection Dropped Async Message on another
4327e48354ceSNicholas Bellinger 	 * active connection.
4328e48354ceSNicholas Bellinger 	 */
4329e48354ceSNicholas Bellinger 	if (atomic_read(&conn->connection_recovery))
4330e48354ceSNicholas Bellinger 		iscsit_build_conn_drop_async_message(conn);
4331e48354ceSNicholas Bellinger 
4332e48354ceSNicholas Bellinger 	spin_unlock_bh(&sess->conn_lock);
4333e48354ceSNicholas Bellinger 
4334e48354ceSNicholas Bellinger 	/*
4335e48354ceSNicholas Bellinger 	 * If connection reinstatement is being performed on this connection,
4336e48354ceSNicholas Bellinger 	 * up the connection reinstatement semaphore that is being blocked on
4337e48354ceSNicholas Bellinger 	 * in iscsit_cause_connection_reinstatement().
4338e48354ceSNicholas Bellinger 	 */
4339e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->state_lock);
4340e48354ceSNicholas Bellinger 	if (atomic_read(&conn->sleep_on_conn_wait_comp)) {
4341e48354ceSNicholas Bellinger 		spin_unlock_bh(&conn->state_lock);
4342e48354ceSNicholas Bellinger 		complete(&conn->conn_wait_comp);
4343e48354ceSNicholas Bellinger 		wait_for_completion(&conn->conn_post_wait_comp);
4344e48354ceSNicholas Bellinger 		spin_lock_bh(&conn->state_lock);
4345e48354ceSNicholas Bellinger 	}
4346e48354ceSNicholas Bellinger 
4347e48354ceSNicholas Bellinger 	/*
4348e48354ceSNicholas Bellinger 	 * If connection reinstatement is being performed on this connection
4349e48354ceSNicholas Bellinger 	 * by receiving a REMOVECONNFORRECOVERY logout request, up the
4350e48354ceSNicholas Bellinger 	 * connection wait rcfr semaphore that is being blocked on
4351e48354ceSNicholas Bellinger 	 * an iscsit_connection_reinstatement_rcfr().
4352e48354ceSNicholas Bellinger 	 */
4353e48354ceSNicholas Bellinger 	if (atomic_read(&conn->connection_wait_rcfr)) {
4354e48354ceSNicholas Bellinger 		spin_unlock_bh(&conn->state_lock);
4355e48354ceSNicholas Bellinger 		complete(&conn->conn_wait_rcfr_comp);
4356e48354ceSNicholas Bellinger 		wait_for_completion(&conn->conn_post_wait_comp);
4357e48354ceSNicholas Bellinger 		spin_lock_bh(&conn->state_lock);
4358e48354ceSNicholas Bellinger 	}
4359e48354ceSNicholas Bellinger 	atomic_set(&conn->connection_reinstatement, 1);
4360e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->state_lock);
4361e48354ceSNicholas Bellinger 
4362e48354ceSNicholas Bellinger 	/*
4363e48354ceSNicholas Bellinger 	 * If any other processes are accessing this connection pointer we
4364e48354ceSNicholas Bellinger 	 * must wait until they have completed.
4365e48354ceSNicholas Bellinger 	 */
4366e48354ceSNicholas Bellinger 	iscsit_check_conn_usage_count(conn);
4367e48354ceSNicholas Bellinger 
4368e48354ceSNicholas Bellinger 	if (conn->conn_rx_hash.tfm)
4369e48354ceSNicholas Bellinger 		crypto_free_hash(conn->conn_rx_hash.tfm);
4370e48354ceSNicholas Bellinger 	if (conn->conn_tx_hash.tfm)
4371e48354ceSNicholas Bellinger 		crypto_free_hash(conn->conn_tx_hash.tfm);
4372e48354ceSNicholas Bellinger 
4373e48354ceSNicholas Bellinger 	free_cpumask_var(conn->conn_cpumask);
4374e48354ceSNicholas Bellinger 
4375e48354ceSNicholas Bellinger 	kfree(conn->conn_ops);
4376e48354ceSNicholas Bellinger 	conn->conn_ops = NULL;
4377e48354ceSNicholas Bellinger 
4378bf6932f4SAl Viro 	if (conn->sock)
4379e48354ceSNicholas Bellinger 		sock_release(conn->sock);
4380baa4d64bSNicholas Bellinger 
4381baa4d64bSNicholas Bellinger 	if (conn->conn_transport->iscsit_free_conn)
4382baa4d64bSNicholas Bellinger 		conn->conn_transport->iscsit_free_conn(conn);
4383baa4d64bSNicholas Bellinger 
4384baa4d64bSNicholas Bellinger 	iscsit_put_transport(conn->conn_transport);
4385baa4d64bSNicholas Bellinger 
4386e48354ceSNicholas Bellinger 	conn->thread_set = NULL;
4387e48354ceSNicholas Bellinger 
4388e48354ceSNicholas Bellinger 	pr_debug("Moving to TARG_CONN_STATE_FREE.\n");
4389e48354ceSNicholas Bellinger 	conn->conn_state = TARG_CONN_STATE_FREE;
4390e48354ceSNicholas Bellinger 	kfree(conn);
4391e48354ceSNicholas Bellinger 
4392e48354ceSNicholas Bellinger 	spin_lock_bh(&sess->conn_lock);
4393e48354ceSNicholas Bellinger 	atomic_dec(&sess->nconn);
4394e48354ceSNicholas Bellinger 	pr_debug("Decremented iSCSI connection count to %hu from node:"
4395e48354ceSNicholas Bellinger 		" %s\n", atomic_read(&sess->nconn),
4396e48354ceSNicholas Bellinger 		sess->sess_ops->InitiatorName);
4397e48354ceSNicholas Bellinger 	/*
4398e48354ceSNicholas Bellinger 	 * Make sure that if one connection fails in an non ERL=2 iSCSI
4399e48354ceSNicholas Bellinger 	 * Session that they all fail.
4400e48354ceSNicholas Bellinger 	 */
4401e48354ceSNicholas Bellinger 	if ((sess->sess_ops->ErrorRecoveryLevel != 2) && !conn_logout &&
4402e48354ceSNicholas Bellinger 	     !atomic_read(&sess->session_logout))
4403e48354ceSNicholas Bellinger 		atomic_set(&sess->session_fall_back_to_erl0, 1);
4404e48354ceSNicholas Bellinger 
4405e48354ceSNicholas Bellinger 	/*
4406e48354ceSNicholas Bellinger 	 * If this was not the last connection in the session, and we are
4407e48354ceSNicholas Bellinger 	 * performing session reinstatement or falling back to ERL=0, call
4408e48354ceSNicholas Bellinger 	 * iscsit_stop_session() without sleeping to shutdown the other
4409e48354ceSNicholas Bellinger 	 * active connections.
4410e48354ceSNicholas Bellinger 	 */
4411e48354ceSNicholas Bellinger 	if (atomic_read(&sess->nconn)) {
4412e48354ceSNicholas Bellinger 		if (!atomic_read(&sess->session_reinstatement) &&
4413e48354ceSNicholas Bellinger 		    !atomic_read(&sess->session_fall_back_to_erl0)) {
4414e48354ceSNicholas Bellinger 			spin_unlock_bh(&sess->conn_lock);
4415e48354ceSNicholas Bellinger 			return 0;
4416e48354ceSNicholas Bellinger 		}
4417e48354ceSNicholas Bellinger 		if (!atomic_read(&sess->session_stop_active)) {
4418e48354ceSNicholas Bellinger 			atomic_set(&sess->session_stop_active, 1);
4419e48354ceSNicholas Bellinger 			spin_unlock_bh(&sess->conn_lock);
4420e48354ceSNicholas Bellinger 			iscsit_stop_session(sess, 0, 0);
4421e48354ceSNicholas Bellinger 			return 0;
4422e48354ceSNicholas Bellinger 		}
4423e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
4424e48354ceSNicholas Bellinger 		return 0;
4425e48354ceSNicholas Bellinger 	}
4426e48354ceSNicholas Bellinger 
4427e48354ceSNicholas Bellinger 	/*
4428e48354ceSNicholas Bellinger 	 * If this was the last connection in the session and one of the
4429e48354ceSNicholas Bellinger 	 * following is occurring:
4430e48354ceSNicholas Bellinger 	 *
4431e48354ceSNicholas Bellinger 	 * Session Reinstatement is not being performed, and are falling back
4432e48354ceSNicholas Bellinger 	 * to ERL=0 call iscsit_close_session().
4433e48354ceSNicholas Bellinger 	 *
4434e48354ceSNicholas Bellinger 	 * Session Logout was requested.  iscsit_close_session() will be called
4435e48354ceSNicholas Bellinger 	 * elsewhere.
4436e48354ceSNicholas Bellinger 	 *
4437e48354ceSNicholas Bellinger 	 * Session Continuation is not being performed, start the Time2Retain
4438e48354ceSNicholas Bellinger 	 * handler and check if sleep_on_sess_wait_sem is active.
4439e48354ceSNicholas Bellinger 	 */
4440e48354ceSNicholas Bellinger 	if (!atomic_read(&sess->session_reinstatement) &&
4441e48354ceSNicholas Bellinger 	     atomic_read(&sess->session_fall_back_to_erl0)) {
4442e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
444399367f01SNicholas Bellinger 		target_put_session(sess->se_sess);
4444e48354ceSNicholas Bellinger 
4445e48354ceSNicholas Bellinger 		return 0;
4446e48354ceSNicholas Bellinger 	} else if (atomic_read(&sess->session_logout)) {
4447e48354ceSNicholas Bellinger 		pr_debug("Moving to TARG_SESS_STATE_FREE.\n");
4448e48354ceSNicholas Bellinger 		sess->session_state = TARG_SESS_STATE_FREE;
4449e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
4450e48354ceSNicholas Bellinger 
4451e48354ceSNicholas Bellinger 		if (atomic_read(&sess->sleep_on_sess_wait_comp))
4452e48354ceSNicholas Bellinger 			complete(&sess->session_wait_comp);
4453e48354ceSNicholas Bellinger 
4454e48354ceSNicholas Bellinger 		return 0;
4455e48354ceSNicholas Bellinger 	} else {
4456e48354ceSNicholas Bellinger 		pr_debug("Moving to TARG_SESS_STATE_FAILED.\n");
4457e48354ceSNicholas Bellinger 		sess->session_state = TARG_SESS_STATE_FAILED;
4458e48354ceSNicholas Bellinger 
4459e48354ceSNicholas Bellinger 		if (!atomic_read(&sess->session_continuation)) {
4460e48354ceSNicholas Bellinger 			spin_unlock_bh(&sess->conn_lock);
4461e48354ceSNicholas Bellinger 			iscsit_start_time2retain_handler(sess);
4462e48354ceSNicholas Bellinger 		} else
4463e48354ceSNicholas Bellinger 			spin_unlock_bh(&sess->conn_lock);
4464e48354ceSNicholas Bellinger 
4465e48354ceSNicholas Bellinger 		if (atomic_read(&sess->sleep_on_sess_wait_comp))
4466e48354ceSNicholas Bellinger 			complete(&sess->session_wait_comp);
4467e48354ceSNicholas Bellinger 
4468e48354ceSNicholas Bellinger 		return 0;
4469e48354ceSNicholas Bellinger 	}
4470e48354ceSNicholas Bellinger 	spin_unlock_bh(&sess->conn_lock);
4471e48354ceSNicholas Bellinger 
4472e48354ceSNicholas Bellinger 	return 0;
4473e48354ceSNicholas Bellinger }
4474e48354ceSNicholas Bellinger 
4475e48354ceSNicholas Bellinger int iscsit_close_session(struct iscsi_session *sess)
4476e48354ceSNicholas Bellinger {
447760bfcf8eSAndy Grover 	struct iscsi_portal_group *tpg = sess->tpg;
4478e48354ceSNicholas Bellinger 	struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
4479e48354ceSNicholas Bellinger 
4480e48354ceSNicholas Bellinger 	if (atomic_read(&sess->nconn)) {
4481e48354ceSNicholas Bellinger 		pr_err("%d connection(s) still exist for iSCSI session"
4482e48354ceSNicholas Bellinger 			" to %s\n", atomic_read(&sess->nconn),
4483e48354ceSNicholas Bellinger 			sess->sess_ops->InitiatorName);
4484e48354ceSNicholas Bellinger 		BUG();
4485e48354ceSNicholas Bellinger 	}
4486e48354ceSNicholas Bellinger 
4487e48354ceSNicholas Bellinger 	spin_lock_bh(&se_tpg->session_lock);
4488e48354ceSNicholas Bellinger 	atomic_set(&sess->session_logout, 1);
4489e48354ceSNicholas Bellinger 	atomic_set(&sess->session_reinstatement, 1);
4490e48354ceSNicholas Bellinger 	iscsit_stop_time2retain_timer(sess);
4491e48354ceSNicholas Bellinger 	spin_unlock_bh(&se_tpg->session_lock);
4492e48354ceSNicholas Bellinger 
4493e48354ceSNicholas Bellinger 	/*
4494e48354ceSNicholas Bellinger 	 * transport_deregister_session_configfs() will clear the
4495e48354ceSNicholas Bellinger 	 * struct se_node_acl->nacl_sess pointer now as a iscsi_np process context
4496e48354ceSNicholas Bellinger 	 * can be setting it again with __transport_register_session() in
4497e48354ceSNicholas Bellinger 	 * iscsi_post_login_handler() again after the iscsit_stop_session()
4498e48354ceSNicholas Bellinger 	 * completes in iscsi_np context.
4499e48354ceSNicholas Bellinger 	 */
4500e48354ceSNicholas Bellinger 	transport_deregister_session_configfs(sess->se_sess);
4501e48354ceSNicholas Bellinger 
4502e48354ceSNicholas Bellinger 	/*
4503e48354ceSNicholas Bellinger 	 * If any other processes are accessing this session pointer we must
4504e48354ceSNicholas Bellinger 	 * wait until they have completed.  If we are in an interrupt (the
4505e48354ceSNicholas Bellinger 	 * time2retain handler) and contain and active session usage count we
4506e48354ceSNicholas Bellinger 	 * restart the timer and exit.
4507e48354ceSNicholas Bellinger 	 */
4508e48354ceSNicholas Bellinger 	if (!in_interrupt()) {
4509e48354ceSNicholas Bellinger 		if (iscsit_check_session_usage_count(sess) == 1)
4510e48354ceSNicholas Bellinger 			iscsit_stop_session(sess, 1, 1);
4511e48354ceSNicholas Bellinger 	} else {
4512e48354ceSNicholas Bellinger 		if (iscsit_check_session_usage_count(sess) == 2) {
4513e48354ceSNicholas Bellinger 			atomic_set(&sess->session_logout, 0);
4514e48354ceSNicholas Bellinger 			iscsit_start_time2retain_handler(sess);
4515e48354ceSNicholas Bellinger 			return 0;
4516e48354ceSNicholas Bellinger 		}
4517e48354ceSNicholas Bellinger 	}
4518e48354ceSNicholas Bellinger 
4519e48354ceSNicholas Bellinger 	transport_deregister_session(sess->se_sess);
4520e48354ceSNicholas Bellinger 
4521e48354ceSNicholas Bellinger 	if (sess->sess_ops->ErrorRecoveryLevel == 2)
4522e48354ceSNicholas Bellinger 		iscsit_free_connection_recovery_entires(sess);
4523e48354ceSNicholas Bellinger 
4524e48354ceSNicholas Bellinger 	iscsit_free_all_ooo_cmdsns(sess);
4525e48354ceSNicholas Bellinger 
4526e48354ceSNicholas Bellinger 	spin_lock_bh(&se_tpg->session_lock);
4527e48354ceSNicholas Bellinger 	pr_debug("Moving to TARG_SESS_STATE_FREE.\n");
4528e48354ceSNicholas Bellinger 	sess->session_state = TARG_SESS_STATE_FREE;
4529e48354ceSNicholas Bellinger 	pr_debug("Released iSCSI session from node: %s\n",
4530e48354ceSNicholas Bellinger 			sess->sess_ops->InitiatorName);
4531e48354ceSNicholas Bellinger 	tpg->nsessions--;
4532e48354ceSNicholas Bellinger 	if (tpg->tpg_tiqn)
4533e48354ceSNicholas Bellinger 		tpg->tpg_tiqn->tiqn_nsessions--;
4534e48354ceSNicholas Bellinger 
4535e48354ceSNicholas Bellinger 	pr_debug("Decremented number of active iSCSI Sessions on"
4536e48354ceSNicholas Bellinger 		" iSCSI TPG: %hu to %u\n", tpg->tpgt, tpg->nsessions);
4537e48354ceSNicholas Bellinger 
4538e48354ceSNicholas Bellinger 	spin_lock(&sess_idr_lock);
4539e48354ceSNicholas Bellinger 	idr_remove(&sess_idr, sess->session_index);
4540e48354ceSNicholas Bellinger 	spin_unlock(&sess_idr_lock);
4541e48354ceSNicholas Bellinger 
4542e48354ceSNicholas Bellinger 	kfree(sess->sess_ops);
4543e48354ceSNicholas Bellinger 	sess->sess_ops = NULL;
4544e48354ceSNicholas Bellinger 	spin_unlock_bh(&se_tpg->session_lock);
4545e48354ceSNicholas Bellinger 
4546e48354ceSNicholas Bellinger 	kfree(sess);
4547e48354ceSNicholas Bellinger 	return 0;
4548e48354ceSNicholas Bellinger }
4549e48354ceSNicholas Bellinger 
4550e48354ceSNicholas Bellinger static void iscsit_logout_post_handler_closesession(
4551e48354ceSNicholas Bellinger 	struct iscsi_conn *conn)
4552e48354ceSNicholas Bellinger {
4553e48354ceSNicholas Bellinger 	struct iscsi_session *sess = conn->sess;
4554e48354ceSNicholas Bellinger 
4555e48354ceSNicholas Bellinger 	iscsi_set_thread_clear(conn, ISCSI_CLEAR_TX_THREAD);
4556e48354ceSNicholas Bellinger 	iscsi_set_thread_set_signal(conn, ISCSI_SIGNAL_TX_THREAD);
4557e48354ceSNicholas Bellinger 
4558e48354ceSNicholas Bellinger 	atomic_set(&conn->conn_logout_remove, 0);
4559e48354ceSNicholas Bellinger 	complete(&conn->conn_logout_comp);
4560e48354ceSNicholas Bellinger 
4561e48354ceSNicholas Bellinger 	iscsit_dec_conn_usage_count(conn);
4562e48354ceSNicholas Bellinger 	iscsit_stop_session(sess, 1, 1);
4563e48354ceSNicholas Bellinger 	iscsit_dec_session_usage_count(sess);
456499367f01SNicholas Bellinger 	target_put_session(sess->se_sess);
4565e48354ceSNicholas Bellinger }
4566e48354ceSNicholas Bellinger 
4567e48354ceSNicholas Bellinger static void iscsit_logout_post_handler_samecid(
4568e48354ceSNicholas Bellinger 	struct iscsi_conn *conn)
4569e48354ceSNicholas Bellinger {
4570e48354ceSNicholas Bellinger 	iscsi_set_thread_clear(conn, ISCSI_CLEAR_TX_THREAD);
4571e48354ceSNicholas Bellinger 	iscsi_set_thread_set_signal(conn, ISCSI_SIGNAL_TX_THREAD);
4572e48354ceSNicholas Bellinger 
4573e48354ceSNicholas Bellinger 	atomic_set(&conn->conn_logout_remove, 0);
4574e48354ceSNicholas Bellinger 	complete(&conn->conn_logout_comp);
4575e48354ceSNicholas Bellinger 
4576e48354ceSNicholas Bellinger 	iscsit_cause_connection_reinstatement(conn, 1);
4577e48354ceSNicholas Bellinger 	iscsit_dec_conn_usage_count(conn);
4578e48354ceSNicholas Bellinger }
4579e48354ceSNicholas Bellinger 
4580e48354ceSNicholas Bellinger static void iscsit_logout_post_handler_diffcid(
4581e48354ceSNicholas Bellinger 	struct iscsi_conn *conn,
4582e48354ceSNicholas Bellinger 	u16 cid)
4583e48354ceSNicholas Bellinger {
4584e48354ceSNicholas Bellinger 	struct iscsi_conn *l_conn;
4585e48354ceSNicholas Bellinger 	struct iscsi_session *sess = conn->sess;
4586b53b0d99SNicholas Bellinger 	bool conn_found = false;
4587e48354ceSNicholas Bellinger 
4588e48354ceSNicholas Bellinger 	if (!sess)
4589e48354ceSNicholas Bellinger 		return;
4590e48354ceSNicholas Bellinger 
4591e48354ceSNicholas Bellinger 	spin_lock_bh(&sess->conn_lock);
4592e48354ceSNicholas Bellinger 	list_for_each_entry(l_conn, &sess->sess_conn_list, conn_list) {
4593e48354ceSNicholas Bellinger 		if (l_conn->cid == cid) {
4594e48354ceSNicholas Bellinger 			iscsit_inc_conn_usage_count(l_conn);
4595b53b0d99SNicholas Bellinger 			conn_found = true;
4596e48354ceSNicholas Bellinger 			break;
4597e48354ceSNicholas Bellinger 		}
4598e48354ceSNicholas Bellinger 	}
4599e48354ceSNicholas Bellinger 	spin_unlock_bh(&sess->conn_lock);
4600e48354ceSNicholas Bellinger 
4601b53b0d99SNicholas Bellinger 	if (!conn_found)
4602e48354ceSNicholas Bellinger 		return;
4603e48354ceSNicholas Bellinger 
4604e48354ceSNicholas Bellinger 	if (l_conn->sock)
4605e48354ceSNicholas Bellinger 		l_conn->sock->ops->shutdown(l_conn->sock, RCV_SHUTDOWN);
4606e48354ceSNicholas Bellinger 
4607e48354ceSNicholas Bellinger 	spin_lock_bh(&l_conn->state_lock);
4608e48354ceSNicholas Bellinger 	pr_debug("Moving to TARG_CONN_STATE_IN_LOGOUT.\n");
4609e48354ceSNicholas Bellinger 	l_conn->conn_state = TARG_CONN_STATE_IN_LOGOUT;
4610e48354ceSNicholas Bellinger 	spin_unlock_bh(&l_conn->state_lock);
4611e48354ceSNicholas Bellinger 
4612e48354ceSNicholas Bellinger 	iscsit_cause_connection_reinstatement(l_conn, 1);
4613e48354ceSNicholas Bellinger 	iscsit_dec_conn_usage_count(l_conn);
4614e48354ceSNicholas Bellinger }
4615e48354ceSNicholas Bellinger 
4616e48354ceSNicholas Bellinger /*
4617e48354ceSNicholas Bellinger  *	Return of 0 causes the TX thread to restart.
4618e48354ceSNicholas Bellinger  */
46192ec5a8c1SNicholas Bellinger int iscsit_logout_post_handler(
4620e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd,
4621e48354ceSNicholas Bellinger 	struct iscsi_conn *conn)
4622e48354ceSNicholas Bellinger {
4623e48354ceSNicholas Bellinger 	int ret = 0;
4624e48354ceSNicholas Bellinger 
4625e48354ceSNicholas Bellinger 	switch (cmd->logout_reason) {
4626e48354ceSNicholas Bellinger 	case ISCSI_LOGOUT_REASON_CLOSE_SESSION:
4627e48354ceSNicholas Bellinger 		switch (cmd->logout_response) {
4628e48354ceSNicholas Bellinger 		case ISCSI_LOGOUT_SUCCESS:
4629e48354ceSNicholas Bellinger 		case ISCSI_LOGOUT_CLEANUP_FAILED:
4630e48354ceSNicholas Bellinger 		default:
4631e48354ceSNicholas Bellinger 			iscsit_logout_post_handler_closesession(conn);
4632e48354ceSNicholas Bellinger 			break;
4633e48354ceSNicholas Bellinger 		}
4634e48354ceSNicholas Bellinger 		ret = 0;
4635e48354ceSNicholas Bellinger 		break;
4636e48354ceSNicholas Bellinger 	case ISCSI_LOGOUT_REASON_CLOSE_CONNECTION:
4637e48354ceSNicholas Bellinger 		if (conn->cid == cmd->logout_cid) {
4638e48354ceSNicholas Bellinger 			switch (cmd->logout_response) {
4639e48354ceSNicholas Bellinger 			case ISCSI_LOGOUT_SUCCESS:
4640e48354ceSNicholas Bellinger 			case ISCSI_LOGOUT_CLEANUP_FAILED:
4641e48354ceSNicholas Bellinger 			default:
4642e48354ceSNicholas Bellinger 				iscsit_logout_post_handler_samecid(conn);
4643e48354ceSNicholas Bellinger 				break;
4644e48354ceSNicholas Bellinger 			}
4645e48354ceSNicholas Bellinger 			ret = 0;
4646e48354ceSNicholas Bellinger 		} else {
4647e48354ceSNicholas Bellinger 			switch (cmd->logout_response) {
4648e48354ceSNicholas Bellinger 			case ISCSI_LOGOUT_SUCCESS:
4649e48354ceSNicholas Bellinger 				iscsit_logout_post_handler_diffcid(conn,
4650e48354ceSNicholas Bellinger 					cmd->logout_cid);
4651e48354ceSNicholas Bellinger 				break;
4652e48354ceSNicholas Bellinger 			case ISCSI_LOGOUT_CID_NOT_FOUND:
4653e48354ceSNicholas Bellinger 			case ISCSI_LOGOUT_CLEANUP_FAILED:
4654e48354ceSNicholas Bellinger 			default:
4655e48354ceSNicholas Bellinger 				break;
4656e48354ceSNicholas Bellinger 			}
4657e48354ceSNicholas Bellinger 			ret = 1;
4658e48354ceSNicholas Bellinger 		}
4659e48354ceSNicholas Bellinger 		break;
4660e48354ceSNicholas Bellinger 	case ISCSI_LOGOUT_REASON_RECOVERY:
4661e48354ceSNicholas Bellinger 		switch (cmd->logout_response) {
4662e48354ceSNicholas Bellinger 		case ISCSI_LOGOUT_SUCCESS:
4663e48354ceSNicholas Bellinger 		case ISCSI_LOGOUT_CID_NOT_FOUND:
4664e48354ceSNicholas Bellinger 		case ISCSI_LOGOUT_RECOVERY_UNSUPPORTED:
4665e48354ceSNicholas Bellinger 		case ISCSI_LOGOUT_CLEANUP_FAILED:
4666e48354ceSNicholas Bellinger 		default:
4667e48354ceSNicholas Bellinger 			break;
4668e48354ceSNicholas Bellinger 		}
4669e48354ceSNicholas Bellinger 		ret = 1;
4670e48354ceSNicholas Bellinger 		break;
4671e48354ceSNicholas Bellinger 	default:
4672e48354ceSNicholas Bellinger 		break;
4673e48354ceSNicholas Bellinger 
4674e48354ceSNicholas Bellinger 	}
4675e48354ceSNicholas Bellinger 	return ret;
4676e48354ceSNicholas Bellinger }
46772ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_logout_post_handler);
4678e48354ceSNicholas Bellinger 
4679e48354ceSNicholas Bellinger void iscsit_fail_session(struct iscsi_session *sess)
4680e48354ceSNicholas Bellinger {
4681e48354ceSNicholas Bellinger 	struct iscsi_conn *conn;
4682e48354ceSNicholas Bellinger 
4683e48354ceSNicholas Bellinger 	spin_lock_bh(&sess->conn_lock);
4684e48354ceSNicholas Bellinger 	list_for_each_entry(conn, &sess->sess_conn_list, conn_list) {
4685e48354ceSNicholas Bellinger 		pr_debug("Moving to TARG_CONN_STATE_CLEANUP_WAIT.\n");
4686e48354ceSNicholas Bellinger 		conn->conn_state = TARG_CONN_STATE_CLEANUP_WAIT;
4687e48354ceSNicholas Bellinger 	}
4688e48354ceSNicholas Bellinger 	spin_unlock_bh(&sess->conn_lock);
4689e48354ceSNicholas Bellinger 
4690e48354ceSNicholas Bellinger 	pr_debug("Moving to TARG_SESS_STATE_FAILED.\n");
4691e48354ceSNicholas Bellinger 	sess->session_state = TARG_SESS_STATE_FAILED;
4692e48354ceSNicholas Bellinger }
4693e48354ceSNicholas Bellinger 
4694e48354ceSNicholas Bellinger int iscsit_free_session(struct iscsi_session *sess)
4695e48354ceSNicholas Bellinger {
4696e48354ceSNicholas Bellinger 	u16 conn_count = atomic_read(&sess->nconn);
4697e48354ceSNicholas Bellinger 	struct iscsi_conn *conn, *conn_tmp = NULL;
4698e48354ceSNicholas Bellinger 	int is_last;
4699e48354ceSNicholas Bellinger 
4700e48354ceSNicholas Bellinger 	spin_lock_bh(&sess->conn_lock);
4701e48354ceSNicholas Bellinger 	atomic_set(&sess->sleep_on_sess_wait_comp, 1);
4702e48354ceSNicholas Bellinger 
4703e48354ceSNicholas Bellinger 	list_for_each_entry_safe(conn, conn_tmp, &sess->sess_conn_list,
4704e48354ceSNicholas Bellinger 			conn_list) {
4705e48354ceSNicholas Bellinger 		if (conn_count == 0)
4706e48354ceSNicholas Bellinger 			break;
4707e48354ceSNicholas Bellinger 
4708e48354ceSNicholas Bellinger 		if (list_is_last(&conn->conn_list, &sess->sess_conn_list)) {
4709e48354ceSNicholas Bellinger 			is_last = 1;
4710e48354ceSNicholas Bellinger 		} else {
4711e48354ceSNicholas Bellinger 			iscsit_inc_conn_usage_count(conn_tmp);
4712e48354ceSNicholas Bellinger 			is_last = 0;
4713e48354ceSNicholas Bellinger 		}
4714e48354ceSNicholas Bellinger 		iscsit_inc_conn_usage_count(conn);
4715e48354ceSNicholas Bellinger 
4716e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
4717e48354ceSNicholas Bellinger 		iscsit_cause_connection_reinstatement(conn, 1);
4718e48354ceSNicholas Bellinger 		spin_lock_bh(&sess->conn_lock);
4719e48354ceSNicholas Bellinger 
4720e48354ceSNicholas Bellinger 		iscsit_dec_conn_usage_count(conn);
4721e48354ceSNicholas Bellinger 		if (is_last == 0)
4722e48354ceSNicholas Bellinger 			iscsit_dec_conn_usage_count(conn_tmp);
4723e48354ceSNicholas Bellinger 
4724e48354ceSNicholas Bellinger 		conn_count--;
4725e48354ceSNicholas Bellinger 	}
4726e48354ceSNicholas Bellinger 
4727e48354ceSNicholas Bellinger 	if (atomic_read(&sess->nconn)) {
4728e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
4729e48354ceSNicholas Bellinger 		wait_for_completion(&sess->session_wait_comp);
4730e48354ceSNicholas Bellinger 	} else
4731e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
4732e48354ceSNicholas Bellinger 
473399367f01SNicholas Bellinger 	target_put_session(sess->se_sess);
4734e48354ceSNicholas Bellinger 	return 0;
4735e48354ceSNicholas Bellinger }
4736e48354ceSNicholas Bellinger 
4737e48354ceSNicholas Bellinger void iscsit_stop_session(
4738e48354ceSNicholas Bellinger 	struct iscsi_session *sess,
4739e48354ceSNicholas Bellinger 	int session_sleep,
4740e48354ceSNicholas Bellinger 	int connection_sleep)
4741e48354ceSNicholas Bellinger {
4742e48354ceSNicholas Bellinger 	u16 conn_count = atomic_read(&sess->nconn);
4743e48354ceSNicholas Bellinger 	struct iscsi_conn *conn, *conn_tmp = NULL;
4744e48354ceSNicholas Bellinger 	int is_last;
4745e48354ceSNicholas Bellinger 
4746e48354ceSNicholas Bellinger 	spin_lock_bh(&sess->conn_lock);
4747e48354ceSNicholas Bellinger 	if (session_sleep)
4748e48354ceSNicholas Bellinger 		atomic_set(&sess->sleep_on_sess_wait_comp, 1);
4749e48354ceSNicholas Bellinger 
4750e48354ceSNicholas Bellinger 	if (connection_sleep) {
4751e48354ceSNicholas Bellinger 		list_for_each_entry_safe(conn, conn_tmp, &sess->sess_conn_list,
4752e48354ceSNicholas Bellinger 				conn_list) {
4753e48354ceSNicholas Bellinger 			if (conn_count == 0)
4754e48354ceSNicholas Bellinger 				break;
4755e48354ceSNicholas Bellinger 
4756e48354ceSNicholas Bellinger 			if (list_is_last(&conn->conn_list, &sess->sess_conn_list)) {
4757e48354ceSNicholas Bellinger 				is_last = 1;
4758e48354ceSNicholas Bellinger 			} else {
4759e48354ceSNicholas Bellinger 				iscsit_inc_conn_usage_count(conn_tmp);
4760e48354ceSNicholas Bellinger 				is_last = 0;
4761e48354ceSNicholas Bellinger 			}
4762e48354ceSNicholas Bellinger 			iscsit_inc_conn_usage_count(conn);
4763e48354ceSNicholas Bellinger 
4764e48354ceSNicholas Bellinger 			spin_unlock_bh(&sess->conn_lock);
4765e48354ceSNicholas Bellinger 			iscsit_cause_connection_reinstatement(conn, 1);
4766e48354ceSNicholas Bellinger 			spin_lock_bh(&sess->conn_lock);
4767e48354ceSNicholas Bellinger 
4768e48354ceSNicholas Bellinger 			iscsit_dec_conn_usage_count(conn);
4769e48354ceSNicholas Bellinger 			if (is_last == 0)
4770e48354ceSNicholas Bellinger 				iscsit_dec_conn_usage_count(conn_tmp);
4771e48354ceSNicholas Bellinger 			conn_count--;
4772e48354ceSNicholas Bellinger 		}
4773e48354ceSNicholas Bellinger 	} else {
4774e48354ceSNicholas Bellinger 		list_for_each_entry(conn, &sess->sess_conn_list, conn_list)
4775e48354ceSNicholas Bellinger 			iscsit_cause_connection_reinstatement(conn, 0);
4776e48354ceSNicholas Bellinger 	}
4777e48354ceSNicholas Bellinger 
4778e48354ceSNicholas Bellinger 	if (session_sleep && atomic_read(&sess->nconn)) {
4779e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
4780e48354ceSNicholas Bellinger 		wait_for_completion(&sess->session_wait_comp);
4781e48354ceSNicholas Bellinger 	} else
4782e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
4783e48354ceSNicholas Bellinger }
4784e48354ceSNicholas Bellinger 
4785e48354ceSNicholas Bellinger int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force)
4786e48354ceSNicholas Bellinger {
4787e48354ceSNicholas Bellinger 	struct iscsi_session *sess;
4788e48354ceSNicholas Bellinger 	struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
4789e48354ceSNicholas Bellinger 	struct se_session *se_sess, *se_sess_tmp;
4790e48354ceSNicholas Bellinger 	int session_count = 0;
4791e48354ceSNicholas Bellinger 
4792e48354ceSNicholas Bellinger 	spin_lock_bh(&se_tpg->session_lock);
4793e48354ceSNicholas Bellinger 	if (tpg->nsessions && !force) {
4794e48354ceSNicholas Bellinger 		spin_unlock_bh(&se_tpg->session_lock);
4795e48354ceSNicholas Bellinger 		return -1;
4796e48354ceSNicholas Bellinger 	}
4797e48354ceSNicholas Bellinger 
4798e48354ceSNicholas Bellinger 	list_for_each_entry_safe(se_sess, se_sess_tmp, &se_tpg->tpg_sess_list,
4799e48354ceSNicholas Bellinger 			sess_list) {
4800e48354ceSNicholas Bellinger 		sess = (struct iscsi_session *)se_sess->fabric_sess_ptr;
4801e48354ceSNicholas Bellinger 
4802e48354ceSNicholas Bellinger 		spin_lock(&sess->conn_lock);
4803e48354ceSNicholas Bellinger 		if (atomic_read(&sess->session_fall_back_to_erl0) ||
4804e48354ceSNicholas Bellinger 		    atomic_read(&sess->session_logout) ||
4805e48354ceSNicholas Bellinger 		    (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)) {
4806e48354ceSNicholas Bellinger 			spin_unlock(&sess->conn_lock);
4807e48354ceSNicholas Bellinger 			continue;
4808e48354ceSNicholas Bellinger 		}
4809e48354ceSNicholas Bellinger 		atomic_set(&sess->session_reinstatement, 1);
4810e48354ceSNicholas Bellinger 		spin_unlock(&sess->conn_lock);
4811e48354ceSNicholas Bellinger 		spin_unlock_bh(&se_tpg->session_lock);
4812e48354ceSNicholas Bellinger 
4813e48354ceSNicholas Bellinger 		iscsit_free_session(sess);
4814e48354ceSNicholas Bellinger 		spin_lock_bh(&se_tpg->session_lock);
4815e48354ceSNicholas Bellinger 
4816e48354ceSNicholas Bellinger 		session_count++;
4817e48354ceSNicholas Bellinger 	}
4818e48354ceSNicholas Bellinger 	spin_unlock_bh(&se_tpg->session_lock);
4819e48354ceSNicholas Bellinger 
4820e48354ceSNicholas Bellinger 	pr_debug("Released %d iSCSI Session(s) from Target Portal"
4821e48354ceSNicholas Bellinger 			" Group: %hu\n", session_count, tpg->tpgt);
4822e48354ceSNicholas Bellinger 	return 0;
4823e48354ceSNicholas Bellinger }
4824e48354ceSNicholas Bellinger 
4825e48354ceSNicholas Bellinger MODULE_DESCRIPTION("iSCSI-Target Driver for mainline target infrastructure");
4826e48354ceSNicholas Bellinger MODULE_VERSION("4.1.x");
4827e48354ceSNicholas Bellinger MODULE_AUTHOR("nab@Linux-iSCSI.org");
4828e48354ceSNicholas Bellinger MODULE_LICENSE("GPL");
4829e48354ceSNicholas Bellinger 
4830e48354ceSNicholas Bellinger module_init(iscsi_target_init_module);
4831e48354ceSNicholas Bellinger module_exit(iscsi_target_cleanup_module);
4832