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 
1969110e3cSHerbert Xu #include <crypto/hash.h>
20e48354ceSNicholas Bellinger #include <linux/string.h>
21e48354ceSNicholas Bellinger #include <linux/kthread.h>
22e48354ceSNicholas Bellinger #include <linux/completion.h>
23827509e3SPaul Gortmaker #include <linux/module.h>
245538d294SDavid S. Miller #include <linux/vmalloc.h>
2540401530SAl Viro #include <linux/idr.h>
268dcf07beSBart Van Assche #include <linux/delay.h>
27e48354ceSNicholas Bellinger #include <asm/unaligned.h>
288dcf07beSBart Van Assche #include <net/ipv6.h>
29ba929992SBart Van Assche #include <scsi/scsi_proto.h>
30e48354ceSNicholas Bellinger #include <scsi/iscsi_proto.h>
31d28b1169SAndy Grover #include <scsi/scsi_tcq.h>
32e48354ceSNicholas Bellinger #include <target/target_core_base.h>
33c4795fb2SChristoph Hellwig #include <target/target_core_fabric.h>
34e48354ceSNicholas Bellinger 
3567f091f2SSagi Grimberg #include <target/iscsi/iscsi_target_core.h>
36e48354ceSNicholas Bellinger #include "iscsi_target_parameters.h"
37e48354ceSNicholas Bellinger #include "iscsi_target_seq_pdu_list.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);
235ee7619f2SNicholas Bellinger 	if (ret != 0)
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(
27413a3cf08SAndy Grover 	struct 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;
28169d75574SAndy Grover 	u16 port, port_e;
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);
29369d75574SAndy Grover 		port_e = ntohs(sock_in6_e->sin6_port);
29405b96892SNicholas Bellinger 	} else {
29505b96892SNicholas Bellinger 		sock_in = (struct sockaddr_in *)sockaddr;
29605b96892SNicholas Bellinger 		sock_in_e = (struct sockaddr_in *)&np->np_sockaddr;
29705b96892SNicholas Bellinger 
29805b96892SNicholas Bellinger 		if (sock_in->sin_addr.s_addr == sock_in_e->sin_addr.s_addr)
29905b96892SNicholas Bellinger 			ip_match = true;
30005b96892SNicholas Bellinger 
30105b96892SNicholas Bellinger 		port = ntohs(sock_in->sin_port);
30269d75574SAndy Grover 		port_e = ntohs(sock_in_e->sin_port);
30305b96892SNicholas Bellinger 	}
30405b96892SNicholas Bellinger 
30569d75574SAndy Grover 	if (ip_match && (port_e == port) &&
30605b96892SNicholas Bellinger 	    (np->np_network_transport == network_transport))
30705b96892SNicholas Bellinger 		return true;
30805b96892SNicholas Bellinger 
30905b96892SNicholas Bellinger 	return false;
31005b96892SNicholas Bellinger }
31105b96892SNicholas Bellinger 
312ee291e63SAndy Grover /*
313ee291e63SAndy Grover  * Called with mutex np_lock held
314ee291e63SAndy Grover  */
31505b96892SNicholas Bellinger static struct iscsi_np *iscsit_get_np(
31613a3cf08SAndy Grover 	struct sockaddr_storage *sockaddr,
31705b96892SNicholas Bellinger 	int network_transport)
31805b96892SNicholas Bellinger {
31905b96892SNicholas Bellinger 	struct iscsi_np *np;
32005b96892SNicholas Bellinger 	bool match;
32105b96892SNicholas Bellinger 
322e48354ceSNicholas Bellinger 	list_for_each_entry(np, &g_np_list, np_list) {
323ee291e63SAndy Grover 		spin_lock_bh(&np->np_thread_lock);
324e48354ceSNicholas Bellinger 		if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
325ee291e63SAndy Grover 			spin_unlock_bh(&np->np_thread_lock);
326e48354ceSNicholas Bellinger 			continue;
327e48354ceSNicholas Bellinger 		}
328e48354ceSNicholas Bellinger 
32905b96892SNicholas Bellinger 		match = iscsit_check_np_match(sockaddr, np, network_transport);
3300bcc297eSChristophe Vu-Brugier 		if (match) {
331e48354ceSNicholas Bellinger 			/*
332e48354ceSNicholas Bellinger 			 * Increment the np_exports reference count now to
333e48354ceSNicholas Bellinger 			 * prevent iscsit_del_np() below from being called
334e48354ceSNicholas Bellinger 			 * while iscsi_tpg_add_network_portal() is called.
335e48354ceSNicholas Bellinger 			 */
336e48354ceSNicholas Bellinger 			np->np_exports++;
337ee291e63SAndy Grover 			spin_unlock_bh(&np->np_thread_lock);
338e48354ceSNicholas Bellinger 			return np;
339e48354ceSNicholas Bellinger 		}
340ee291e63SAndy Grover 		spin_unlock_bh(&np->np_thread_lock);
341e48354ceSNicholas Bellinger 	}
342e48354ceSNicholas Bellinger 
343e48354ceSNicholas Bellinger 	return NULL;
344e48354ceSNicholas Bellinger }
345e48354ceSNicholas Bellinger 
346e48354ceSNicholas Bellinger struct iscsi_np *iscsit_add_np(
34713a3cf08SAndy Grover 	struct sockaddr_storage *sockaddr,
348e48354ceSNicholas Bellinger 	int network_transport)
349e48354ceSNicholas Bellinger {
350e48354ceSNicholas Bellinger 	struct iscsi_np *np;
351e48354ceSNicholas Bellinger 	int ret;
352ee291e63SAndy Grover 
353ee291e63SAndy Grover 	mutex_lock(&np_lock);
354ee291e63SAndy Grover 
355e48354ceSNicholas Bellinger 	/*
356e48354ceSNicholas Bellinger 	 * Locate the existing struct iscsi_np if already active..
357e48354ceSNicholas Bellinger 	 */
358e48354ceSNicholas Bellinger 	np = iscsit_get_np(sockaddr, network_transport);
359ee291e63SAndy Grover 	if (np) {
360ee291e63SAndy Grover 		mutex_unlock(&np_lock);
361e48354ceSNicholas Bellinger 		return np;
362ee291e63SAndy Grover 	}
363e48354ceSNicholas Bellinger 
364e48354ceSNicholas Bellinger 	np = kzalloc(sizeof(struct iscsi_np), GFP_KERNEL);
365e48354ceSNicholas Bellinger 	if (!np) {
366e48354ceSNicholas Bellinger 		pr_err("Unable to allocate memory for struct iscsi_np\n");
367ee291e63SAndy Grover 		mutex_unlock(&np_lock);
368e48354ceSNicholas Bellinger 		return ERR_PTR(-ENOMEM);
369e48354ceSNicholas Bellinger 	}
370e48354ceSNicholas Bellinger 
371e48354ceSNicholas Bellinger 	np->np_flags |= NPF_IP_NETWORK;
372e48354ceSNicholas Bellinger 	np->np_network_transport = network_transport;
373e48354ceSNicholas Bellinger 	spin_lock_init(&np->np_thread_lock);
374e48354ceSNicholas Bellinger 	init_completion(&np->np_restart_comp);
375e48354ceSNicholas Bellinger 	INIT_LIST_HEAD(&np->np_list);
376e48354ceSNicholas Bellinger 
377e48354ceSNicholas Bellinger 	ret = iscsi_target_setup_login_socket(np, sockaddr);
378e48354ceSNicholas Bellinger 	if (ret != 0) {
379e48354ceSNicholas Bellinger 		kfree(np);
380ee291e63SAndy Grover 		mutex_unlock(&np_lock);
381e48354ceSNicholas Bellinger 		return ERR_PTR(ret);
382e48354ceSNicholas Bellinger 	}
383e48354ceSNicholas Bellinger 
384e48354ceSNicholas Bellinger 	np->np_thread = kthread_run(iscsi_target_login_thread, np, "iscsi_np");
385e48354ceSNicholas Bellinger 	if (IS_ERR(np->np_thread)) {
386e48354ceSNicholas Bellinger 		pr_err("Unable to create kthread: iscsi_np\n");
387e48354ceSNicholas Bellinger 		ret = PTR_ERR(np->np_thread);
388e48354ceSNicholas Bellinger 		kfree(np);
389ee291e63SAndy Grover 		mutex_unlock(&np_lock);
390e48354ceSNicholas Bellinger 		return ERR_PTR(ret);
391e48354ceSNicholas Bellinger 	}
392e48354ceSNicholas Bellinger 	/*
393e48354ceSNicholas Bellinger 	 * Increment the np_exports reference count now to prevent
394e48354ceSNicholas Bellinger 	 * iscsit_del_np() below from being run while a new call to
395e48354ceSNicholas Bellinger 	 * iscsi_tpg_add_network_portal() for a matching iscsi_np is
396e48354ceSNicholas Bellinger 	 * active.  We don't need to hold np->np_thread_lock at this
397e48354ceSNicholas Bellinger 	 * point because iscsi_np has not been added to g_np_list yet.
398e48354ceSNicholas Bellinger 	 */
399e48354ceSNicholas Bellinger 	np->np_exports = 1;
400ee291e63SAndy Grover 	np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
401e48354ceSNicholas Bellinger 
402e48354ceSNicholas Bellinger 	list_add_tail(&np->np_list, &g_np_list);
403ee291e63SAndy Grover 	mutex_unlock(&np_lock);
404e48354ceSNicholas Bellinger 
40569d75574SAndy Grover 	pr_debug("CORE[0] - Added Network Portal: %pISpc on %s\n",
40669d75574SAndy Grover 		&np->np_sockaddr, np->np_transport->name);
407e48354ceSNicholas Bellinger 
408e48354ceSNicholas Bellinger 	return np;
409e48354ceSNicholas Bellinger }
410e48354ceSNicholas Bellinger 
411e48354ceSNicholas Bellinger int iscsit_reset_np_thread(
412e48354ceSNicholas Bellinger 	struct iscsi_np *np,
413e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np,
414a91eb7d9SNicholas Bellinger 	struct iscsi_portal_group *tpg,
415a91eb7d9SNicholas Bellinger 	bool shutdown)
416e48354ceSNicholas Bellinger {
417e48354ceSNicholas Bellinger 	spin_lock_bh(&np->np_thread_lock);
418e48354ceSNicholas Bellinger 	if (np->np_thread_state == ISCSI_NP_THREAD_INACTIVE) {
419e48354ceSNicholas Bellinger 		spin_unlock_bh(&np->np_thread_lock);
420e48354ceSNicholas Bellinger 		return 0;
421e48354ceSNicholas Bellinger 	}
422e48354ceSNicholas Bellinger 	np->np_thread_state = ISCSI_NP_THREAD_RESET;
423e48354ceSNicholas Bellinger 
424e48354ceSNicholas Bellinger 	if (np->np_thread) {
425e48354ceSNicholas Bellinger 		spin_unlock_bh(&np->np_thread_lock);
426e48354ceSNicholas Bellinger 		send_sig(SIGINT, np->np_thread, 1);
427e48354ceSNicholas Bellinger 		wait_for_completion(&np->np_restart_comp);
428e48354ceSNicholas Bellinger 		spin_lock_bh(&np->np_thread_lock);
429e48354ceSNicholas Bellinger 	}
430e48354ceSNicholas Bellinger 	spin_unlock_bh(&np->np_thread_lock);
431e48354ceSNicholas Bellinger 
432a91eb7d9SNicholas Bellinger 	if (tpg_np && shutdown) {
433a91eb7d9SNicholas Bellinger 		kref_put(&tpg_np->tpg_np_kref, iscsit_login_kref_put);
434a91eb7d9SNicholas Bellinger 
435a91eb7d9SNicholas Bellinger 		wait_for_completion(&tpg_np->tpg_np_comp);
436a91eb7d9SNicholas Bellinger 	}
437a91eb7d9SNicholas Bellinger 
438e48354ceSNicholas Bellinger 	return 0;
439e48354ceSNicholas Bellinger }
440e48354ceSNicholas Bellinger 
441baa4d64bSNicholas Bellinger static void iscsit_free_np(struct iscsi_np *np)
442e48354ceSNicholas Bellinger {
443bf6932f4SAl Viro 	if (np->np_socket)
444e48354ceSNicholas Bellinger 		sock_release(np->np_socket);
445e48354ceSNicholas Bellinger }
446e48354ceSNicholas Bellinger 
447e48354ceSNicholas Bellinger int iscsit_del_np(struct iscsi_np *np)
448e48354ceSNicholas Bellinger {
449e48354ceSNicholas Bellinger 	spin_lock_bh(&np->np_thread_lock);
450e48354ceSNicholas Bellinger 	np->np_exports--;
451e48354ceSNicholas Bellinger 	if (np->np_exports) {
4522363d196SNicholas Bellinger 		np->enabled = true;
453e48354ceSNicholas Bellinger 		spin_unlock_bh(&np->np_thread_lock);
454e48354ceSNicholas Bellinger 		return 0;
455e48354ceSNicholas Bellinger 	}
456e48354ceSNicholas Bellinger 	np->np_thread_state = ISCSI_NP_THREAD_SHUTDOWN;
457e48354ceSNicholas Bellinger 	spin_unlock_bh(&np->np_thread_lock);
458e48354ceSNicholas Bellinger 
459e48354ceSNicholas Bellinger 	if (np->np_thread) {
460e48354ceSNicholas Bellinger 		/*
461e48354ceSNicholas Bellinger 		 * We need to send the signal to wakeup Linux/Net
462e48354ceSNicholas Bellinger 		 * which may be sleeping in sock_accept()..
463e48354ceSNicholas Bellinger 		 */
464e48354ceSNicholas Bellinger 		send_sig(SIGINT, np->np_thread, 1);
465e48354ceSNicholas Bellinger 		kthread_stop(np->np_thread);
466db6077fdSNicholas Bellinger 		np->np_thread = NULL;
467e48354ceSNicholas Bellinger 	}
468baa4d64bSNicholas Bellinger 
469baa4d64bSNicholas Bellinger 	np->np_transport->iscsit_free_np(np);
470e48354ceSNicholas Bellinger 
471ee291e63SAndy Grover 	mutex_lock(&np_lock);
472e48354ceSNicholas Bellinger 	list_del(&np->np_list);
473ee291e63SAndy Grover 	mutex_unlock(&np_lock);
474e48354ceSNicholas Bellinger 
47569d75574SAndy Grover 	pr_debug("CORE[0] - Removed Network Portal: %pISpc on %s\n",
47669d75574SAndy Grover 		&np->np_sockaddr, np->np_transport->name);
477e48354ceSNicholas Bellinger 
478baa4d64bSNicholas Bellinger 	iscsit_put_transport(np->np_transport);
479e48354ceSNicholas Bellinger 	kfree(np);
480e48354ceSNicholas Bellinger 	return 0;
481e48354ceSNicholas Bellinger }
482e48354ceSNicholas Bellinger 
483e8205ccaSVarun Prakash static void iscsit_get_rx_pdu(struct iscsi_conn *);
4842ec5a8c1SNicholas Bellinger 
485d2faaefbSVarun Prakash int iscsit_queue_rsp(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
4862ec5a8c1SNicholas Bellinger {
4872ec5a8c1SNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
4882ec5a8c1SNicholas Bellinger 	return 0;
4892ec5a8c1SNicholas Bellinger }
490d2faaefbSVarun Prakash EXPORT_SYMBOL(iscsit_queue_rsp);
4912ec5a8c1SNicholas Bellinger 
492d2faaefbSVarun Prakash void iscsit_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
493131e6abcSNicholas Bellinger {
494131e6abcSNicholas Bellinger 	bool scsi_cmd = (cmd->iscsi_opcode == ISCSI_OP_SCSI_CMD);
495131e6abcSNicholas Bellinger 
496131e6abcSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
497064cdd2dSNicholas Bellinger 	if (!list_empty(&cmd->i_conn_node) &&
498064cdd2dSNicholas Bellinger 	    !(cmd->se_cmd.transport_state & CMD_T_FABRIC_STOP))
499131e6abcSNicholas Bellinger 		list_del_init(&cmd->i_conn_node);
500131e6abcSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
501131e6abcSNicholas Bellinger 
502131e6abcSNicholas Bellinger 	__iscsit_free_cmd(cmd, scsi_cmd, true);
503131e6abcSNicholas Bellinger }
504d2faaefbSVarun Prakash EXPORT_SYMBOL(iscsit_aborted_task);
505131e6abcSNicholas Bellinger 
5062854bb23SVarun Prakash static void iscsit_do_crypto_hash_buf(struct ahash_request *, const void *,
5072854bb23SVarun Prakash 				      u32, u32, u8 *, u8 *);
5082854bb23SVarun Prakash static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *);
5092854bb23SVarun Prakash 
5102854bb23SVarun Prakash static int
5112854bb23SVarun Prakash iscsit_xmit_nondatain_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
5122854bb23SVarun Prakash 			  const void *data_buf, u32 data_buf_len)
5132854bb23SVarun Prakash {
5142854bb23SVarun Prakash 	struct iscsi_hdr *hdr = (struct iscsi_hdr *)cmd->pdu;
5152854bb23SVarun Prakash 	struct kvec *iov;
5162854bb23SVarun Prakash 	u32 niov = 0, tx_size = ISCSI_HDR_LEN;
5172854bb23SVarun Prakash 	int ret;
5182854bb23SVarun Prakash 
5192854bb23SVarun Prakash 	iov = &cmd->iov_misc[0];
5202854bb23SVarun Prakash 	iov[niov].iov_base	= cmd->pdu;
5212854bb23SVarun Prakash 	iov[niov++].iov_len	= ISCSI_HDR_LEN;
5222854bb23SVarun Prakash 
5232854bb23SVarun Prakash 	if (conn->conn_ops->HeaderDigest) {
5242854bb23SVarun Prakash 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
5252854bb23SVarun Prakash 
5262854bb23SVarun Prakash 		iscsit_do_crypto_hash_buf(conn->conn_tx_hash, hdr,
5272854bb23SVarun Prakash 					  ISCSI_HDR_LEN, 0, NULL,
5282854bb23SVarun Prakash 					  (u8 *)header_digest);
5292854bb23SVarun Prakash 
5302854bb23SVarun Prakash 		iov[0].iov_len += ISCSI_CRC_LEN;
5312854bb23SVarun Prakash 		tx_size += ISCSI_CRC_LEN;
5322854bb23SVarun Prakash 		pr_debug("Attaching CRC32C HeaderDigest"
5332854bb23SVarun Prakash 			 " to opcode 0x%x 0x%08x\n",
5342854bb23SVarun Prakash 			 hdr->opcode, *header_digest);
5352854bb23SVarun Prakash 	}
5362854bb23SVarun Prakash 
5372854bb23SVarun Prakash 	if (data_buf_len) {
5382854bb23SVarun Prakash 		u32 padding = ((-data_buf_len) & 3);
5392854bb23SVarun Prakash 
5402854bb23SVarun Prakash 		iov[niov].iov_base	= (void *)data_buf;
5412854bb23SVarun Prakash 		iov[niov++].iov_len	= data_buf_len;
5422854bb23SVarun Prakash 		tx_size += data_buf_len;
5432854bb23SVarun Prakash 
5442854bb23SVarun Prakash 		if (padding != 0) {
5452854bb23SVarun Prakash 			iov[niov].iov_base = &cmd->pad_bytes;
5462854bb23SVarun Prakash 			iov[niov++].iov_len = padding;
5472854bb23SVarun Prakash 			tx_size += padding;
5482854bb23SVarun Prakash 			pr_debug("Attaching %u additional"
5492854bb23SVarun Prakash 				 " padding bytes.\n", padding);
5502854bb23SVarun Prakash 		}
5512854bb23SVarun Prakash 
5522854bb23SVarun Prakash 		if (conn->conn_ops->DataDigest) {
5532854bb23SVarun Prakash 			iscsit_do_crypto_hash_buf(conn->conn_tx_hash,
5542854bb23SVarun Prakash 						  data_buf, data_buf_len,
5552854bb23SVarun Prakash 						  padding,
5562854bb23SVarun Prakash 						  (u8 *)&cmd->pad_bytes,
5572854bb23SVarun Prakash 						  (u8 *)&cmd->data_crc);
5582854bb23SVarun Prakash 
5592854bb23SVarun Prakash 			iov[niov].iov_base = &cmd->data_crc;
5602854bb23SVarun Prakash 			iov[niov++].iov_len = ISCSI_CRC_LEN;
5612854bb23SVarun Prakash 			tx_size += ISCSI_CRC_LEN;
5622854bb23SVarun Prakash 			pr_debug("Attached DataDigest for %u"
5632854bb23SVarun Prakash 				 " bytes opcode 0x%x, CRC 0x%08x\n",
5642854bb23SVarun Prakash 				 data_buf_len, hdr->opcode, cmd->data_crc);
5652854bb23SVarun Prakash 		}
5662854bb23SVarun Prakash 	}
5672854bb23SVarun Prakash 
5682854bb23SVarun Prakash 	cmd->iov_misc_count = niov;
5692854bb23SVarun Prakash 	cmd->tx_size = tx_size;
5702854bb23SVarun Prakash 
5712854bb23SVarun Prakash 	ret = iscsit_send_tx_data(cmd, conn, 1);
5722854bb23SVarun Prakash 	if (ret < 0) {
5732854bb23SVarun Prakash 		iscsit_tx_thread_wait_for_tcp(conn);
5742854bb23SVarun Prakash 		return ret;
5752854bb23SVarun Prakash 	}
5762854bb23SVarun Prakash 
5772854bb23SVarun Prakash 	return 0;
5782854bb23SVarun Prakash }
5792854bb23SVarun Prakash 
5802854bb23SVarun Prakash static int iscsit_map_iovec(struct iscsi_cmd *, struct kvec *, u32, u32);
5812854bb23SVarun Prakash static void iscsit_unmap_iovec(struct iscsi_cmd *);
5822854bb23SVarun Prakash static u32 iscsit_do_crypto_hash_sg(struct ahash_request *, struct iscsi_cmd *,
5832854bb23SVarun Prakash 				    u32, u32, u32, u8 *);
5842854bb23SVarun Prakash static int
5852854bb23SVarun Prakash iscsit_xmit_datain_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
5862854bb23SVarun Prakash 		       const struct iscsi_datain *datain)
5872854bb23SVarun Prakash {
5882854bb23SVarun Prakash 	struct kvec *iov;
5892854bb23SVarun Prakash 	u32 iov_count = 0, tx_size = 0;
5902854bb23SVarun Prakash 	int ret, iov_ret;
5912854bb23SVarun Prakash 
5922854bb23SVarun Prakash 	iov = &cmd->iov_data[0];
5932854bb23SVarun Prakash 	iov[iov_count].iov_base	= cmd->pdu;
5942854bb23SVarun Prakash 	iov[iov_count++].iov_len = ISCSI_HDR_LEN;
5952854bb23SVarun Prakash 	tx_size += ISCSI_HDR_LEN;
5962854bb23SVarun Prakash 
5972854bb23SVarun Prakash 	if (conn->conn_ops->HeaderDigest) {
5982854bb23SVarun Prakash 		u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
5992854bb23SVarun Prakash 
6002854bb23SVarun Prakash 		iscsit_do_crypto_hash_buf(conn->conn_tx_hash, cmd->pdu,
6012854bb23SVarun Prakash 					  ISCSI_HDR_LEN, 0, NULL,
6022854bb23SVarun Prakash 					  (u8 *)header_digest);
6032854bb23SVarun Prakash 
6042854bb23SVarun Prakash 		iov[0].iov_len += ISCSI_CRC_LEN;
6052854bb23SVarun Prakash 		tx_size += ISCSI_CRC_LEN;
6062854bb23SVarun Prakash 
6072854bb23SVarun Prakash 		pr_debug("Attaching CRC32 HeaderDigest for DataIN PDU 0x%08x\n",
6082854bb23SVarun Prakash 			 *header_digest);
6092854bb23SVarun Prakash 	}
6102854bb23SVarun Prakash 
6112854bb23SVarun Prakash 	iov_ret = iscsit_map_iovec(cmd, &cmd->iov_data[1],
6122854bb23SVarun Prakash 				   datain->offset, datain->length);
6132854bb23SVarun Prakash 	if (iov_ret < 0)
6142854bb23SVarun Prakash 		return -1;
6152854bb23SVarun Prakash 
6162854bb23SVarun Prakash 	iov_count += iov_ret;
6172854bb23SVarun Prakash 	tx_size += datain->length;
6182854bb23SVarun Prakash 
6192854bb23SVarun Prakash 	cmd->padding = ((-datain->length) & 3);
6202854bb23SVarun Prakash 	if (cmd->padding) {
6212854bb23SVarun Prakash 		iov[iov_count].iov_base		= cmd->pad_bytes;
6222854bb23SVarun Prakash 		iov[iov_count++].iov_len	= cmd->padding;
6232854bb23SVarun Prakash 		tx_size += cmd->padding;
6242854bb23SVarun Prakash 
6252854bb23SVarun Prakash 		pr_debug("Attaching %u padding bytes\n", cmd->padding);
6262854bb23SVarun Prakash 	}
6272854bb23SVarun Prakash 
6282854bb23SVarun Prakash 	if (conn->conn_ops->DataDigest) {
6292854bb23SVarun Prakash 		cmd->data_crc = iscsit_do_crypto_hash_sg(conn->conn_tx_hash,
6302854bb23SVarun Prakash 							 cmd, datain->offset,
6312854bb23SVarun Prakash 							 datain->length,
6322854bb23SVarun Prakash 							 cmd->padding,
6332854bb23SVarun Prakash 							 cmd->pad_bytes);
6342854bb23SVarun Prakash 
6352854bb23SVarun Prakash 		iov[iov_count].iov_base	= &cmd->data_crc;
6362854bb23SVarun Prakash 		iov[iov_count++].iov_len = ISCSI_CRC_LEN;
6372854bb23SVarun Prakash 		tx_size += ISCSI_CRC_LEN;
6382854bb23SVarun Prakash 
6392854bb23SVarun Prakash 		pr_debug("Attached CRC32C DataDigest %d bytes, crc 0x%08x\n",
6402854bb23SVarun Prakash 			 datain->length + cmd->padding, cmd->data_crc);
6412854bb23SVarun Prakash 	}
6422854bb23SVarun Prakash 
6432854bb23SVarun Prakash 	cmd->iov_data_count = iov_count;
6442854bb23SVarun Prakash 	cmd->tx_size = tx_size;
6452854bb23SVarun Prakash 
6462854bb23SVarun Prakash 	ret = iscsit_fe_sendpage_sg(cmd, conn);
6472854bb23SVarun Prakash 
6482854bb23SVarun Prakash 	iscsit_unmap_iovec(cmd);
6492854bb23SVarun Prakash 
6502854bb23SVarun Prakash 	if (ret < 0) {
6512854bb23SVarun Prakash 		iscsit_tx_thread_wait_for_tcp(conn);
6522854bb23SVarun Prakash 		return ret;
6532854bb23SVarun Prakash 	}
6542854bb23SVarun Prakash 
6552854bb23SVarun Prakash 	return 0;
6562854bb23SVarun Prakash }
6572854bb23SVarun Prakash 
6582854bb23SVarun Prakash static int iscsit_xmit_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
6592854bb23SVarun Prakash 			   struct iscsi_datain_req *dr, const void *buf,
6602854bb23SVarun Prakash 			   u32 buf_len)
6612854bb23SVarun Prakash {
6622854bb23SVarun Prakash 	if (dr)
6632854bb23SVarun Prakash 		return iscsit_xmit_datain_pdu(conn, cmd, buf);
6642854bb23SVarun Prakash 	else
6652854bb23SVarun Prakash 		return iscsit_xmit_nondatain_pdu(conn, cmd, buf, buf_len);
6662854bb23SVarun Prakash }
6672854bb23SVarun Prakash 
668e70beee7SNicholas Bellinger static enum target_prot_op iscsit_get_sup_prot_ops(struct iscsi_conn *conn)
669e70beee7SNicholas Bellinger {
670e70beee7SNicholas Bellinger 	return TARGET_PROT_NORMAL;
671e70beee7SNicholas Bellinger }
672e70beee7SNicholas Bellinger 
673baa4d64bSNicholas Bellinger static struct iscsit_transport iscsi_target_transport = {
674baa4d64bSNicholas Bellinger 	.name			= "iSCSI/TCP",
675baa4d64bSNicholas Bellinger 	.transport_type		= ISCSI_TCP,
676bd027d85SNicholas Bellinger 	.rdma_shutdown		= false,
677baa4d64bSNicholas Bellinger 	.owner			= NULL,
678baa4d64bSNicholas Bellinger 	.iscsit_setup_np	= iscsit_setup_np,
679baa4d64bSNicholas Bellinger 	.iscsit_accept_np	= iscsit_accept_np,
680baa4d64bSNicholas Bellinger 	.iscsit_free_np		= iscsit_free_np,
681baa4d64bSNicholas Bellinger 	.iscsit_get_login_rx	= iscsit_get_login_rx,
682baa4d64bSNicholas Bellinger 	.iscsit_put_login_tx	= iscsit_put_login_tx,
6833e1c81a9SNicholas Bellinger 	.iscsit_get_dataout	= iscsit_build_r2ts_for_cmd,
6842ec5a8c1SNicholas Bellinger 	.iscsit_immediate_queue	= iscsit_immediate_queue,
6852ec5a8c1SNicholas Bellinger 	.iscsit_response_queue	= iscsit_response_queue,
6862ec5a8c1SNicholas Bellinger 	.iscsit_queue_data_in	= iscsit_queue_rsp,
6872ec5a8c1SNicholas Bellinger 	.iscsit_queue_status	= iscsit_queue_rsp,
688131e6abcSNicholas Bellinger 	.iscsit_aborted_task	= iscsit_aborted_task,
6892854bb23SVarun Prakash 	.iscsit_xmit_pdu	= iscsit_xmit_pdu,
690e8205ccaSVarun Prakash 	.iscsit_get_rx_pdu	= iscsit_get_rx_pdu,
691e70beee7SNicholas Bellinger 	.iscsit_get_sup_prot_ops = iscsit_get_sup_prot_ops,
692baa4d64bSNicholas Bellinger };
693baa4d64bSNicholas Bellinger 
694e48354ceSNicholas Bellinger static int __init iscsi_target_init_module(void)
695e48354ceSNicholas Bellinger {
69688dcd2daSNicholas Bellinger 	int ret = 0, size;
697e48354ceSNicholas Bellinger 
698e48354ceSNicholas Bellinger 	pr_debug("iSCSI-Target "ISCSIT_VERSION"\n");
699e48354ceSNicholas Bellinger 
700e48354ceSNicholas Bellinger 	iscsit_global = kzalloc(sizeof(struct iscsit_global), GFP_KERNEL);
701e48354ceSNicholas Bellinger 	if (!iscsit_global) {
702e48354ceSNicholas Bellinger 		pr_err("Unable to allocate memory for iscsit_global\n");
703e48354ceSNicholas Bellinger 		return -1;
704e48354ceSNicholas Bellinger 	}
70588dcd2daSNicholas Bellinger 	spin_lock_init(&iscsit_global->ts_bitmap_lock);
706e48354ceSNicholas Bellinger 	mutex_init(&auth_id_lock);
707e48354ceSNicholas Bellinger 	spin_lock_init(&sess_idr_lock);
708e48354ceSNicholas Bellinger 	idr_init(&tiqn_idr);
709e48354ceSNicholas Bellinger 	idr_init(&sess_idr);
710e48354ceSNicholas Bellinger 
7119ac8928eSChristoph Hellwig 	ret = target_register_template(&iscsi_ops);
7129ac8928eSChristoph Hellwig 	if (ret)
713e48354ceSNicholas Bellinger 		goto out;
714e48354ceSNicholas Bellinger 
71588dcd2daSNicholas Bellinger 	size = BITS_TO_LONGS(ISCSIT_BITMAP_BITS) * sizeof(long);
71688dcd2daSNicholas Bellinger 	iscsit_global->ts_bitmap = vzalloc(size);
71788dcd2daSNicholas Bellinger 	if (!iscsit_global->ts_bitmap) {
71888dcd2daSNicholas Bellinger 		pr_err("Unable to allocate iscsit_global->ts_bitmap\n");
719e48354ceSNicholas Bellinger 		goto configfs_out;
720e48354ceSNicholas Bellinger 	}
721e48354ceSNicholas Bellinger 
722e48354ceSNicholas Bellinger 	lio_qr_cache = kmem_cache_create("lio_qr_cache",
723e48354ceSNicholas Bellinger 			sizeof(struct iscsi_queue_req),
724e48354ceSNicholas Bellinger 			__alignof__(struct iscsi_queue_req), 0, NULL);
725e48354ceSNicholas Bellinger 	if (!lio_qr_cache) {
726e48354ceSNicholas Bellinger 		pr_err("nable to kmem_cache_create() for"
727e48354ceSNicholas Bellinger 				" lio_qr_cache\n");
72888dcd2daSNicholas Bellinger 		goto bitmap_out;
729e48354ceSNicholas Bellinger 	}
730e48354ceSNicholas Bellinger 
731e48354ceSNicholas Bellinger 	lio_dr_cache = kmem_cache_create("lio_dr_cache",
732e48354ceSNicholas Bellinger 			sizeof(struct iscsi_datain_req),
733e48354ceSNicholas Bellinger 			__alignof__(struct iscsi_datain_req), 0, NULL);
734e48354ceSNicholas Bellinger 	if (!lio_dr_cache) {
735e48354ceSNicholas Bellinger 		pr_err("Unable to kmem_cache_create() for"
736e48354ceSNicholas Bellinger 				" lio_dr_cache\n");
737e48354ceSNicholas Bellinger 		goto qr_out;
738e48354ceSNicholas Bellinger 	}
739e48354ceSNicholas Bellinger 
740e48354ceSNicholas Bellinger 	lio_ooo_cache = kmem_cache_create("lio_ooo_cache",
741e48354ceSNicholas Bellinger 			sizeof(struct iscsi_ooo_cmdsn),
742e48354ceSNicholas Bellinger 			__alignof__(struct iscsi_ooo_cmdsn), 0, NULL);
743e48354ceSNicholas Bellinger 	if (!lio_ooo_cache) {
744e48354ceSNicholas Bellinger 		pr_err("Unable to kmem_cache_create() for"
745e48354ceSNicholas Bellinger 				" lio_ooo_cache\n");
746e48354ceSNicholas Bellinger 		goto dr_out;
747e48354ceSNicholas Bellinger 	}
748e48354ceSNicholas Bellinger 
749e48354ceSNicholas Bellinger 	lio_r2t_cache = kmem_cache_create("lio_r2t_cache",
750e48354ceSNicholas Bellinger 			sizeof(struct iscsi_r2t), __alignof__(struct iscsi_r2t),
751e48354ceSNicholas Bellinger 			0, NULL);
752e48354ceSNicholas Bellinger 	if (!lio_r2t_cache) {
753e48354ceSNicholas Bellinger 		pr_err("Unable to kmem_cache_create() for"
754e48354ceSNicholas Bellinger 				" lio_r2t_cache\n");
755e48354ceSNicholas Bellinger 		goto ooo_out;
756e48354ceSNicholas Bellinger 	}
757e48354ceSNicholas Bellinger 
758baa4d64bSNicholas Bellinger 	iscsit_register_transport(&iscsi_target_transport);
759baa4d64bSNicholas Bellinger 
760e48354ceSNicholas Bellinger 	if (iscsit_load_discovery_tpg() < 0)
761e48354ceSNicholas Bellinger 		goto r2t_out;
762e48354ceSNicholas Bellinger 
763e48354ceSNicholas Bellinger 	return ret;
764e48354ceSNicholas Bellinger r2t_out:
7657f2c53bbSLino Sanfilippo 	iscsit_unregister_transport(&iscsi_target_transport);
766e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_r2t_cache);
767e48354ceSNicholas Bellinger ooo_out:
768e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_ooo_cache);
769e48354ceSNicholas Bellinger dr_out:
770e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_dr_cache);
771e48354ceSNicholas Bellinger qr_out:
772e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_qr_cache);
77388dcd2daSNicholas Bellinger bitmap_out:
77488dcd2daSNicholas Bellinger 	vfree(iscsit_global->ts_bitmap);
775e48354ceSNicholas Bellinger configfs_out:
7769ac8928eSChristoph Hellwig 	/* XXX: this probably wants it to be it's own unwind step.. */
7779ac8928eSChristoph Hellwig 	if (iscsit_global->discovery_tpg)
7789ac8928eSChristoph Hellwig 		iscsit_tpg_disable_portal_group(iscsit_global->discovery_tpg, 1);
7799ac8928eSChristoph Hellwig 	target_unregister_template(&iscsi_ops);
780e48354ceSNicholas Bellinger out:
781e48354ceSNicholas Bellinger 	kfree(iscsit_global);
782e48354ceSNicholas Bellinger 	return -ENOMEM;
783e48354ceSNicholas Bellinger }
784e48354ceSNicholas Bellinger 
785e48354ceSNicholas Bellinger static void __exit iscsi_target_cleanup_module(void)
786e48354ceSNicholas Bellinger {
787e48354ceSNicholas Bellinger 	iscsit_release_discovery_tpg();
788baa4d64bSNicholas Bellinger 	iscsit_unregister_transport(&iscsi_target_transport);
789e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_qr_cache);
790e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_dr_cache);
791e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_ooo_cache);
792e48354ceSNicholas Bellinger 	kmem_cache_destroy(lio_r2t_cache);
793e48354ceSNicholas Bellinger 
7949ac8928eSChristoph Hellwig 	/*
7959ac8928eSChristoph Hellwig 	 * Shutdown discovery sessions and disable discovery TPG
7969ac8928eSChristoph Hellwig 	 */
7979ac8928eSChristoph Hellwig 	if (iscsit_global->discovery_tpg)
7989ac8928eSChristoph Hellwig 		iscsit_tpg_disable_portal_group(iscsit_global->discovery_tpg, 1);
799e48354ceSNicholas Bellinger 
8009ac8928eSChristoph Hellwig 	target_unregister_template(&iscsi_ops);
801e48354ceSNicholas Bellinger 
80288dcd2daSNicholas Bellinger 	vfree(iscsit_global->ts_bitmap);
803e48354ceSNicholas Bellinger 	kfree(iscsit_global);
804e48354ceSNicholas Bellinger }
805e48354ceSNicholas Bellinger 
806d2faaefbSVarun Prakash int iscsit_add_reject(
807ba159914SNicholas Bellinger 	struct iscsi_conn *conn,
808e48354ceSNicholas Bellinger 	u8 reason,
809ba159914SNicholas Bellinger 	unsigned char *buf)
810e48354ceSNicholas Bellinger {
811e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd;
812e48354ceSNicholas Bellinger 
813676687c6SNicholas Bellinger 	cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
814e48354ceSNicholas Bellinger 	if (!cmd)
815e48354ceSNicholas Bellinger 		return -1;
816e48354ceSNicholas Bellinger 
817e48354ceSNicholas Bellinger 	cmd->iscsi_opcode = ISCSI_OP_REJECT;
818ba159914SNicholas Bellinger 	cmd->reject_reason = reason;
819e48354ceSNicholas Bellinger 
8201c3d5794SThomas Meyer 	cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL);
821e48354ceSNicholas Bellinger 	if (!cmd->buf_ptr) {
822e48354ceSNicholas Bellinger 		pr_err("Unable to allocate memory for cmd->buf_ptr\n");
823aafc9d15SNicholas Bellinger 		iscsit_free_cmd(cmd, false);
824e48354ceSNicholas Bellinger 		return -1;
825e48354ceSNicholas Bellinger 	}
826e48354ceSNicholas Bellinger 
827e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
8282fbb471eSAndy Grover 	list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
829e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
830e48354ceSNicholas Bellinger 
831e48354ceSNicholas Bellinger 	cmd->i_state = ISTATE_SEND_REJECT;
832e48354ceSNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
833e48354ceSNicholas Bellinger 
834e48354ceSNicholas Bellinger 	return -1;
835e48354ceSNicholas Bellinger }
836d2faaefbSVarun Prakash EXPORT_SYMBOL(iscsit_add_reject);
837e48354ceSNicholas Bellinger 
838ba159914SNicholas Bellinger static int iscsit_add_reject_from_cmd(
839ba159914SNicholas Bellinger 	struct iscsi_cmd *cmd,
840e48354ceSNicholas Bellinger 	u8 reason,
841ba159914SNicholas Bellinger 	bool add_to_conn,
842ba159914SNicholas Bellinger 	unsigned char *buf)
843e48354ceSNicholas Bellinger {
844e48354ceSNicholas Bellinger 	struct iscsi_conn *conn;
845e48354ceSNicholas Bellinger 
846e48354ceSNicholas Bellinger 	if (!cmd->conn) {
847e48354ceSNicholas Bellinger 		pr_err("cmd->conn is NULL for ITT: 0x%08x\n",
848e48354ceSNicholas Bellinger 				cmd->init_task_tag);
849e48354ceSNicholas Bellinger 		return -1;
850e48354ceSNicholas Bellinger 	}
851e48354ceSNicholas Bellinger 	conn = cmd->conn;
852e48354ceSNicholas Bellinger 
853e48354ceSNicholas Bellinger 	cmd->iscsi_opcode = ISCSI_OP_REJECT;
854ba159914SNicholas Bellinger 	cmd->reject_reason = reason;
855e48354ceSNicholas Bellinger 
8561c3d5794SThomas Meyer 	cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL);
857e48354ceSNicholas Bellinger 	if (!cmd->buf_ptr) {
858e48354ceSNicholas Bellinger 		pr_err("Unable to allocate memory for cmd->buf_ptr\n");
859aafc9d15SNicholas Bellinger 		iscsit_free_cmd(cmd, false);
860e48354ceSNicholas Bellinger 		return -1;
861e48354ceSNicholas Bellinger 	}
862e48354ceSNicholas Bellinger 
863e48354ceSNicholas Bellinger 	if (add_to_conn) {
864e48354ceSNicholas Bellinger 		spin_lock_bh(&conn->cmd_lock);
8652fbb471eSAndy Grover 		list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
866e48354ceSNicholas Bellinger 		spin_unlock_bh(&conn->cmd_lock);
867e48354ceSNicholas Bellinger 	}
868e48354ceSNicholas Bellinger 
869e48354ceSNicholas Bellinger 	cmd->i_state = ISTATE_SEND_REJECT;
870e48354ceSNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
8713e1c81a9SNicholas Bellinger 	/*
8723e1c81a9SNicholas Bellinger 	 * Perform the kref_put now if se_cmd has already been setup by
8733e1c81a9SNicholas Bellinger 	 * scsit_setup_scsi_cmd()
8743e1c81a9SNicholas Bellinger 	 */
8753e1c81a9SNicholas Bellinger 	if (cmd->se_cmd.se_tfo != NULL) {
8763e1c81a9SNicholas Bellinger 		pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n");
877afc16604SBart Van Assche 		target_put_sess_cmd(&cmd->se_cmd);
8783e1c81a9SNicholas Bellinger 	}
879e48354ceSNicholas Bellinger 	return -1;
880e48354ceSNicholas Bellinger }
881ba159914SNicholas Bellinger 
882ba159914SNicholas Bellinger static int iscsit_add_reject_cmd(struct iscsi_cmd *cmd, u8 reason,
883ba159914SNicholas Bellinger 				 unsigned char *buf)
884ba159914SNicholas Bellinger {
885ba159914SNicholas Bellinger 	return iscsit_add_reject_from_cmd(cmd, reason, true, buf);
886ba159914SNicholas Bellinger }
887ba159914SNicholas Bellinger 
888ba159914SNicholas Bellinger int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8 reason, unsigned char *buf)
889ba159914SNicholas Bellinger {
890ba159914SNicholas Bellinger 	return iscsit_add_reject_from_cmd(cmd, reason, false, buf);
891ba159914SNicholas Bellinger }
892d2faaefbSVarun Prakash EXPORT_SYMBOL(iscsit_reject_cmd);
893e48354ceSNicholas Bellinger 
894e48354ceSNicholas Bellinger /*
895e48354ceSNicholas Bellinger  * Map some portion of the allocated scatterlist to an iovec, suitable for
896bfb79eacSAndy Grover  * kernel sockets to copy data in/out.
897e48354ceSNicholas Bellinger  */
898e48354ceSNicholas Bellinger static int iscsit_map_iovec(
899e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd,
900e48354ceSNicholas Bellinger 	struct kvec *iov,
901e48354ceSNicholas Bellinger 	u32 data_offset,
902e48354ceSNicholas Bellinger 	u32 data_length)
903e48354ceSNicholas Bellinger {
904e48354ceSNicholas Bellinger 	u32 i = 0;
905e48354ceSNicholas Bellinger 	struct scatterlist *sg;
906e48354ceSNicholas Bellinger 	unsigned int page_off;
907e48354ceSNicholas Bellinger 
908e48354ceSNicholas Bellinger 	/*
909bfb79eacSAndy Grover 	 * We know each entry in t_data_sg contains a page.
910e48354ceSNicholas Bellinger 	 */
9112b16509cSImran Haider 	u32 ent = data_offset / PAGE_SIZE;
9122b16509cSImran Haider 
9132b16509cSImran Haider 	if (ent >= cmd->se_cmd.t_data_nents) {
9142b16509cSImran Haider 		pr_err("Initial page entry out-of-bounds\n");
9152b16509cSImran Haider 		return -1;
9162b16509cSImran Haider 	}
9172b16509cSImran Haider 
9182b16509cSImran Haider 	sg = &cmd->se_cmd.t_data_sg[ent];
919e48354ceSNicholas Bellinger 	page_off = (data_offset % PAGE_SIZE);
920e48354ceSNicholas Bellinger 
921e48354ceSNicholas Bellinger 	cmd->first_data_sg = sg;
922e48354ceSNicholas Bellinger 	cmd->first_data_sg_off = page_off;
923e48354ceSNicholas Bellinger 
924e48354ceSNicholas Bellinger 	while (data_length) {
925e48354ceSNicholas Bellinger 		u32 cur_len = min_t(u32, data_length, sg->length - page_off);
926e48354ceSNicholas Bellinger 
927e48354ceSNicholas Bellinger 		iov[i].iov_base = kmap(sg_page(sg)) + sg->offset + page_off;
928e48354ceSNicholas Bellinger 		iov[i].iov_len = cur_len;
929e48354ceSNicholas Bellinger 
930e48354ceSNicholas Bellinger 		data_length -= cur_len;
931e48354ceSNicholas Bellinger 		page_off = 0;
932e48354ceSNicholas Bellinger 		sg = sg_next(sg);
933e48354ceSNicholas Bellinger 		i++;
934e48354ceSNicholas Bellinger 	}
935e48354ceSNicholas Bellinger 
936e48354ceSNicholas Bellinger 	cmd->kmapped_nents = i;
937e48354ceSNicholas Bellinger 
938e48354ceSNicholas Bellinger 	return i;
939e48354ceSNicholas Bellinger }
940e48354ceSNicholas Bellinger 
941e48354ceSNicholas Bellinger static void iscsit_unmap_iovec(struct iscsi_cmd *cmd)
942e48354ceSNicholas Bellinger {
943e48354ceSNicholas Bellinger 	u32 i;
944e48354ceSNicholas Bellinger 	struct scatterlist *sg;
945e48354ceSNicholas Bellinger 
946e48354ceSNicholas Bellinger 	sg = cmd->first_data_sg;
947e48354ceSNicholas Bellinger 
948e48354ceSNicholas Bellinger 	for (i = 0; i < cmd->kmapped_nents; i++)
949e48354ceSNicholas Bellinger 		kunmap(sg_page(&sg[i]));
950e48354ceSNicholas Bellinger }
951e48354ceSNicholas Bellinger 
952e48354ceSNicholas Bellinger static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn)
953e48354ceSNicholas Bellinger {
954f56cbbb4SNicholas Bellinger 	LIST_HEAD(ack_list);
955f56cbbb4SNicholas Bellinger 	struct iscsi_cmd *cmd, *cmd_p;
956e48354ceSNicholas Bellinger 
957e48354ceSNicholas Bellinger 	conn->exp_statsn = exp_statsn;
958e48354ceSNicholas Bellinger 
9593e1c81a9SNicholas Bellinger 	if (conn->sess->sess_ops->RDMAExtensions)
9603e1c81a9SNicholas Bellinger 		return;
9613e1c81a9SNicholas Bellinger 
962e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
963f56cbbb4SNicholas Bellinger 	list_for_each_entry_safe(cmd, cmd_p, &conn->conn_cmd_list, i_conn_node) {
964e48354ceSNicholas Bellinger 		spin_lock(&cmd->istate_lock);
965e48354ceSNicholas Bellinger 		if ((cmd->i_state == ISTATE_SENT_STATUS) &&
96664c13330SSteve Hodgson 		    iscsi_sna_lt(cmd->stat_sn, exp_statsn)) {
967e48354ceSNicholas Bellinger 			cmd->i_state = ISTATE_REMOVE;
968e48354ceSNicholas Bellinger 			spin_unlock(&cmd->istate_lock);
969f56cbbb4SNicholas Bellinger 			list_move_tail(&cmd->i_conn_node, &ack_list);
970e48354ceSNicholas Bellinger 			continue;
971e48354ceSNicholas Bellinger 		}
972e48354ceSNicholas Bellinger 		spin_unlock(&cmd->istate_lock);
973e48354ceSNicholas Bellinger 	}
974e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
975f56cbbb4SNicholas Bellinger 
976f56cbbb4SNicholas Bellinger 	list_for_each_entry_safe(cmd, cmd_p, &ack_list, i_conn_node) {
9775159d763SNicholas Bellinger 		list_del_init(&cmd->i_conn_node);
978f56cbbb4SNicholas Bellinger 		iscsit_free_cmd(cmd, false);
979f56cbbb4SNicholas Bellinger 	}
980e48354ceSNicholas Bellinger }
981e48354ceSNicholas Bellinger 
982e48354ceSNicholas Bellinger static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd)
983e48354ceSNicholas Bellinger {
984f80e8ed3SNicholas Bellinger 	u32 iov_count = max(1UL, DIV_ROUND_UP(cmd->se_cmd.data_length, PAGE_SIZE));
985e48354ceSNicholas Bellinger 
986c0427f15SChristoph Hellwig 	iov_count += ISCSI_IOV_DATA_BUFFER;
987e48354ceSNicholas Bellinger 
988e48354ceSNicholas Bellinger 	cmd->iov_data = kzalloc(iov_count * sizeof(struct kvec), GFP_KERNEL);
989e48354ceSNicholas Bellinger 	if (!cmd->iov_data) {
990e48354ceSNicholas Bellinger 		pr_err("Unable to allocate cmd->iov_data\n");
991e48354ceSNicholas Bellinger 		return -ENOMEM;
992e48354ceSNicholas Bellinger 	}
993e48354ceSNicholas Bellinger 
994e48354ceSNicholas Bellinger 	cmd->orig_iov_data_count = iov_count;
995e48354ceSNicholas Bellinger 	return 0;
996e48354ceSNicholas Bellinger }
997e48354ceSNicholas Bellinger 
9983e1c81a9SNicholas Bellinger int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
999e48354ceSNicholas Bellinger 			  unsigned char *buf)
1000e48354ceSNicholas Bellinger {
10013e1c81a9SNicholas Bellinger 	int data_direction, payload_length;
1002e48354ceSNicholas Bellinger 	struct iscsi_scsi_req *hdr;
1003d28b1169SAndy Grover 	int iscsi_task_attr;
1004d28b1169SAndy Grover 	int sam_task_attr;
1005e48354ceSNicholas Bellinger 
100604f3b31bSNicholas Bellinger 	atomic_long_inc(&conn->sess->cmd_pdus);
1007e48354ceSNicholas Bellinger 
1008e48354ceSNicholas Bellinger 	hdr			= (struct iscsi_scsi_req *) buf;
1009e48354ceSNicholas Bellinger 	payload_length		= ntoh24(hdr->dlength);
1010e48354ceSNicholas Bellinger 
1011e48354ceSNicholas Bellinger 	/* FIXME; Add checks for AdditionalHeaderSegment */
1012e48354ceSNicholas Bellinger 
1013e48354ceSNicholas Bellinger 	if (!(hdr->flags & ISCSI_FLAG_CMD_WRITE) &&
1014e48354ceSNicholas Bellinger 	    !(hdr->flags & ISCSI_FLAG_CMD_FINAL)) {
1015e48354ceSNicholas Bellinger 		pr_err("ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL"
1016e48354ceSNicholas Bellinger 				" not set. Bad iSCSI Initiator.\n");
1017ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1018ba159914SNicholas Bellinger 					     ISCSI_REASON_BOOKMARK_INVALID, buf);
1019e48354ceSNicholas Bellinger 	}
1020e48354ceSNicholas Bellinger 
1021e48354ceSNicholas Bellinger 	if (((hdr->flags & ISCSI_FLAG_CMD_READ) ||
1022e48354ceSNicholas Bellinger 	     (hdr->flags & ISCSI_FLAG_CMD_WRITE)) && !hdr->data_length) {
1023e48354ceSNicholas Bellinger 		/*
10244454b66cSNicholas Bellinger 		 * From RFC-3720 Section 10.3.1:
10254454b66cSNicholas Bellinger 		 *
10264454b66cSNicholas Bellinger 		 * "Either or both of R and W MAY be 1 when either the
10274454b66cSNicholas Bellinger 		 *  Expected Data Transfer Length and/or Bidirectional Read
10284454b66cSNicholas Bellinger 		 *  Expected Data Transfer Length are 0"
10294454b66cSNicholas Bellinger 		 *
10304454b66cSNicholas Bellinger 		 * For this case, go ahead and clear the unnecssary bits
10314454b66cSNicholas Bellinger 		 * to avoid any confusion with ->data_direction.
1032e48354ceSNicholas Bellinger 		 */
1033e48354ceSNicholas Bellinger 		hdr->flags &= ~ISCSI_FLAG_CMD_READ;
1034e48354ceSNicholas Bellinger 		hdr->flags &= ~ISCSI_FLAG_CMD_WRITE;
1035e48354ceSNicholas Bellinger 
10364454b66cSNicholas Bellinger 		pr_warn("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE"
1037e48354ceSNicholas Bellinger 			" set when Expected Data Transfer Length is 0 for"
10384454b66cSNicholas Bellinger 			" CDB: 0x%02x, Fixing up flags\n", hdr->cdb[0]);
1039e48354ceSNicholas Bellinger 	}
1040e48354ceSNicholas Bellinger 
1041e48354ceSNicholas Bellinger 	if (!(hdr->flags & ISCSI_FLAG_CMD_READ) &&
1042e48354ceSNicholas Bellinger 	    !(hdr->flags & ISCSI_FLAG_CMD_WRITE) && (hdr->data_length != 0)) {
1043e48354ceSNicholas Bellinger 		pr_err("ISCSI_FLAG_CMD_READ and/or ISCSI_FLAG_CMD_WRITE"
1044e48354ceSNicholas Bellinger 			" MUST be set if Expected Data Transfer Length is not 0."
1045e48354ceSNicholas Bellinger 			" Bad iSCSI Initiator\n");
1046ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1047ba159914SNicholas Bellinger 					     ISCSI_REASON_BOOKMARK_INVALID, buf);
1048e48354ceSNicholas Bellinger 	}
1049e48354ceSNicholas Bellinger 
1050e48354ceSNicholas Bellinger 	if ((hdr->flags & ISCSI_FLAG_CMD_READ) &&
1051e48354ceSNicholas Bellinger 	    (hdr->flags & ISCSI_FLAG_CMD_WRITE)) {
1052e48354ceSNicholas Bellinger 		pr_err("Bidirectional operations not supported!\n");
1053ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1054ba159914SNicholas Bellinger 					     ISCSI_REASON_BOOKMARK_INVALID, buf);
1055e48354ceSNicholas Bellinger 	}
1056e48354ceSNicholas Bellinger 
1057e48354ceSNicholas Bellinger 	if (hdr->opcode & ISCSI_OP_IMMEDIATE) {
1058e48354ceSNicholas Bellinger 		pr_err("Illegally set Immediate Bit in iSCSI Initiator"
1059e48354ceSNicholas Bellinger 				" Scsi Command PDU.\n");
1060ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1061ba159914SNicholas Bellinger 					     ISCSI_REASON_BOOKMARK_INVALID, buf);
1062e48354ceSNicholas Bellinger 	}
1063e48354ceSNicholas Bellinger 
1064e48354ceSNicholas Bellinger 	if (payload_length && !conn->sess->sess_ops->ImmediateData) {
1065e48354ceSNicholas Bellinger 		pr_err("ImmediateData=No but DataSegmentLength=%u,"
1066e48354ceSNicholas Bellinger 			" protocol error.\n", payload_length);
1067ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1068ba159914SNicholas Bellinger 					     ISCSI_REASON_PROTOCOL_ERROR, buf);
1069e48354ceSNicholas Bellinger 	}
1070e48354ceSNicholas Bellinger 
107150e5c87dSChristoph Hellwig 	if ((be32_to_cpu(hdr->data_length) == payload_length) &&
1072e48354ceSNicholas Bellinger 	    (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) {
1073e48354ceSNicholas Bellinger 		pr_err("Expected Data Transfer Length and Length of"
1074e48354ceSNicholas Bellinger 			" Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL"
1075e48354ceSNicholas Bellinger 			" bit is not set protocol error\n");
1076ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1077ba159914SNicholas Bellinger 					     ISCSI_REASON_PROTOCOL_ERROR, buf);
1078e48354ceSNicholas Bellinger 	}
1079e48354ceSNicholas Bellinger 
108050e5c87dSChristoph Hellwig 	if (payload_length > be32_to_cpu(hdr->data_length)) {
1081e48354ceSNicholas Bellinger 		pr_err("DataSegmentLength: %u is greater than"
1082e48354ceSNicholas Bellinger 			" EDTL: %u, protocol error.\n", payload_length,
1083e48354ceSNicholas Bellinger 				hdr->data_length);
1084ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1085ba159914SNicholas Bellinger 					     ISCSI_REASON_PROTOCOL_ERROR, buf);
1086e48354ceSNicholas Bellinger 	}
1087e48354ceSNicholas Bellinger 
108821f5aa7eSNicholas Bellinger 	if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
1089e48354ceSNicholas Bellinger 		pr_err("DataSegmentLength: %u is greater than"
109021f5aa7eSNicholas Bellinger 			" MaxXmitDataSegmentLength: %u, protocol error.\n",
109121f5aa7eSNicholas Bellinger 			payload_length, conn->conn_ops->MaxXmitDataSegmentLength);
1092ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1093ba159914SNicholas Bellinger 					     ISCSI_REASON_PROTOCOL_ERROR, buf);
1094e48354ceSNicholas Bellinger 	}
1095e48354ceSNicholas Bellinger 
1096e48354ceSNicholas Bellinger 	if (payload_length > conn->sess->sess_ops->FirstBurstLength) {
1097e48354ceSNicholas Bellinger 		pr_err("DataSegmentLength: %u is greater than"
1098e48354ceSNicholas Bellinger 			" FirstBurstLength: %u, protocol error.\n",
1099e48354ceSNicholas Bellinger 			payload_length, conn->sess->sess_ops->FirstBurstLength);
1100ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1101ba159914SNicholas Bellinger 					     ISCSI_REASON_BOOKMARK_INVALID, buf);
1102e48354ceSNicholas Bellinger 	}
1103e48354ceSNicholas Bellinger 
1104e48354ceSNicholas Bellinger 	data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE :
1105e48354ceSNicholas Bellinger 			 (hdr->flags & ISCSI_FLAG_CMD_READ) ? DMA_FROM_DEVICE :
1106e48354ceSNicholas Bellinger 			  DMA_NONE;
1107e48354ceSNicholas Bellinger 
1108d28b1169SAndy Grover 	cmd->data_direction = data_direction;
1109d28b1169SAndy Grover 	iscsi_task_attr = hdr->flags & ISCSI_FLAG_CMD_ATTR_MASK;
1110d28b1169SAndy Grover 	/*
1111d28b1169SAndy Grover 	 * Figure out the SAM Task Attribute for the incoming SCSI CDB
1112d28b1169SAndy Grover 	 */
1113d28b1169SAndy Grover 	if ((iscsi_task_attr == ISCSI_ATTR_UNTAGGED) ||
1114d28b1169SAndy Grover 	    (iscsi_task_attr == ISCSI_ATTR_SIMPLE))
111568d81f40SChristoph Hellwig 		sam_task_attr = TCM_SIMPLE_TAG;
1116d28b1169SAndy Grover 	else if (iscsi_task_attr == ISCSI_ATTR_ORDERED)
111768d81f40SChristoph Hellwig 		sam_task_attr = TCM_ORDERED_TAG;
1118d28b1169SAndy Grover 	else if (iscsi_task_attr == ISCSI_ATTR_HEAD_OF_QUEUE)
111968d81f40SChristoph Hellwig 		sam_task_attr = TCM_HEAD_TAG;
1120d28b1169SAndy Grover 	else if (iscsi_task_attr == ISCSI_ATTR_ACA)
112168d81f40SChristoph Hellwig 		sam_task_attr = TCM_ACA_TAG;
1122d28b1169SAndy Grover 	else {
1123d28b1169SAndy Grover 		pr_debug("Unknown iSCSI Task Attribute: 0x%02x, using"
112468d81f40SChristoph Hellwig 			" TCM_SIMPLE_TAG\n", iscsi_task_attr);
112568d81f40SChristoph Hellwig 		sam_task_attr = TCM_SIMPLE_TAG;
1126d28b1169SAndy Grover 	}
1127d28b1169SAndy Grover 
1128e48354ceSNicholas Bellinger 	cmd->iscsi_opcode	= ISCSI_OP_SCSI_CMD;
1129e48354ceSNicholas Bellinger 	cmd->i_state		= ISTATE_NEW_CMD;
1130e48354ceSNicholas Bellinger 	cmd->immediate_cmd	= ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
1131e48354ceSNicholas Bellinger 	cmd->immediate_data	= (payload_length) ? 1 : 0;
1132e48354ceSNicholas Bellinger 	cmd->unsolicited_data	= ((!(hdr->flags & ISCSI_FLAG_CMD_FINAL) &&
1133e48354ceSNicholas Bellinger 				     (hdr->flags & ISCSI_FLAG_CMD_WRITE)) ? 1 : 0);
1134e48354ceSNicholas Bellinger 	if (cmd->unsolicited_data)
1135e48354ceSNicholas Bellinger 		cmd->cmd_flags |= ICF_NON_IMMEDIATE_UNSOLICITED_DATA;
1136e48354ceSNicholas Bellinger 
1137e48354ceSNicholas Bellinger 	conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
11389547308bSAlexei Potashnik 	if (hdr->flags & ISCSI_FLAG_CMD_READ)
1139c1e34b64SSagi Grimberg 		cmd->targ_xfer_tag = session_get_next_ttt(conn->sess);
11409547308bSAlexei Potashnik 	else
1141e48354ceSNicholas Bellinger 		cmd->targ_xfer_tag = 0xFFFFFFFF;
114250e5c87dSChristoph Hellwig 	cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
114350e5c87dSChristoph Hellwig 	cmd->exp_stat_sn	= be32_to_cpu(hdr->exp_statsn);
1144e48354ceSNicholas Bellinger 	cmd->first_burst_len	= payload_length;
1145e48354ceSNicholas Bellinger 
11463e1c81a9SNicholas Bellinger 	if (!conn->sess->sess_ops->RDMAExtensions &&
11473e1c81a9SNicholas Bellinger 	     cmd->data_direction == DMA_FROM_DEVICE) {
1148e48354ceSNicholas Bellinger 		struct iscsi_datain_req *dr;
1149e48354ceSNicholas Bellinger 
1150e48354ceSNicholas Bellinger 		dr = iscsit_allocate_datain_req();
1151e48354ceSNicholas Bellinger 		if (!dr)
1152ba159914SNicholas Bellinger 			return iscsit_add_reject_cmd(cmd,
1153ba159914SNicholas Bellinger 					ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
1154e48354ceSNicholas Bellinger 
1155e48354ceSNicholas Bellinger 		iscsit_attach_datain_req(cmd, dr);
1156e48354ceSNicholas Bellinger 	}
1157e48354ceSNicholas Bellinger 
1158e48354ceSNicholas Bellinger 	/*
1159065ca1e4SAndy Grover 	 * Initialize struct se_cmd descriptor from target_core_mod infrastructure
1160065ca1e4SAndy Grover 	 */
11619ac8928eSChristoph Hellwig 	transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops,
116250e5c87dSChristoph Hellwig 			conn->sess->se_sess, be32_to_cpu(hdr->data_length),
116350e5c87dSChristoph Hellwig 			cmd->data_direction, sam_task_attr,
116450e5c87dSChristoph Hellwig 			cmd->sense_buffer + 2);
1165065ca1e4SAndy Grover 
1166065ca1e4SAndy Grover 	pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x,"
1167065ca1e4SAndy Grover 		" ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
11683e1c81a9SNicholas Bellinger 		hdr->cmdsn, be32_to_cpu(hdr->data_length), payload_length,
11693e1c81a9SNicholas Bellinger 		conn->cid);
11703e1c81a9SNicholas Bellinger 
1171afc16604SBart Van Assche 	target_get_sess_cmd(&cmd->se_cmd, true);
1172065ca1e4SAndy Grover 
1173de103c93SChristoph Hellwig 	cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd,
11744f26998aSAndy Grover 						     scsilun_to_int(&hdr->lun));
1175de103c93SChristoph Hellwig 	if (cmd->sense_reason)
1176e48354ceSNicholas Bellinger 		goto attach_cmd;
1177a12f41f8SAndy Grover 
1178649ee054SBart Van Assche 	/* only used for printks or comparing with ->ref_task_tag */
1179649ee054SBart Van Assche 	cmd->se_cmd.tag = (__force u32)cmd->init_task_tag;
1180de103c93SChristoph Hellwig 	cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb);
1181de103c93SChristoph Hellwig 	if (cmd->sense_reason) {
1182de103c93SChristoph Hellwig 		if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) {
1183ba159914SNicholas Bellinger 			return iscsit_add_reject_cmd(cmd,
1184ba159914SNicholas Bellinger 					ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
1185de103c93SChristoph Hellwig 		}
1186de103c93SChristoph Hellwig 
1187de103c93SChristoph Hellwig 		goto attach_cmd;
1188de103c93SChristoph Hellwig 	}
1189de103c93SChristoph Hellwig 
1190de103c93SChristoph Hellwig 	if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) {
1191ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1192ba159914SNicholas Bellinger 				ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
1193e48354ceSNicholas Bellinger 	}
1194e48354ceSNicholas Bellinger 
1195e48354ceSNicholas Bellinger attach_cmd:
1196e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
11972fbb471eSAndy Grover 	list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
1198e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
1199e48354ceSNicholas Bellinger 	/*
1200e48354ceSNicholas Bellinger 	 * Check if we need to delay processing because of ALUA
1201e48354ceSNicholas Bellinger 	 * Active/NonOptimized primary access state..
1202e48354ceSNicholas Bellinger 	 */
1203e48354ceSNicholas Bellinger 	core_alua_check_nonop_delay(&cmd->se_cmd);
1204bfb79eacSAndy Grover 
12053e1c81a9SNicholas Bellinger 	return 0;
1206de103c93SChristoph Hellwig }
12073e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_setup_scsi_cmd);
1208de103c93SChristoph Hellwig 
12093e1c81a9SNicholas Bellinger void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *cmd)
12103e1c81a9SNicholas Bellinger {
12113e1c81a9SNicholas Bellinger 	iscsit_set_dataout_sequence_values(cmd);
12123e1c81a9SNicholas Bellinger 
12133e1c81a9SNicholas Bellinger 	spin_lock_bh(&cmd->dataout_timeout_lock);
12143e1c81a9SNicholas Bellinger 	iscsit_start_dataout_timer(cmd, cmd->conn);
12153e1c81a9SNicholas Bellinger 	spin_unlock_bh(&cmd->dataout_timeout_lock);
12163e1c81a9SNicholas Bellinger }
12173e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_set_unsoliticed_dataout);
12183e1c81a9SNicholas Bellinger 
12193e1c81a9SNicholas Bellinger int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
12203e1c81a9SNicholas Bellinger 			    struct iscsi_scsi_req *hdr)
12213e1c81a9SNicholas Bellinger {
12223e1c81a9SNicholas Bellinger 	int cmdsn_ret = 0;
1223e48354ceSNicholas Bellinger 	/*
1224e48354ceSNicholas Bellinger 	 * Check the CmdSN against ExpCmdSN/MaxCmdSN here if
1225e48354ceSNicholas Bellinger 	 * the Immediate Bit is not set, and no Immediate
1226e48354ceSNicholas Bellinger 	 * Data is attached.
1227e48354ceSNicholas Bellinger 	 *
1228e48354ceSNicholas Bellinger 	 * A PDU/CmdSN carrying Immediate Data can only
1229e48354ceSNicholas Bellinger 	 * be processed after the DataCRC has passed.
1230e48354ceSNicholas Bellinger 	 * If the DataCRC fails, the CmdSN MUST NOT
1231e48354ceSNicholas Bellinger 	 * be acknowledged. (See below)
1232e48354ceSNicholas Bellinger 	 */
1233e48354ceSNicholas Bellinger 	if (!cmd->immediate_data) {
1234561bf158SNicholas Bellinger 		cmdsn_ret = iscsit_sequence_cmd(conn, cmd,
1235561bf158SNicholas Bellinger 					(unsigned char *)hdr, hdr->cmdsn);
1236561bf158SNicholas Bellinger 		if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
1237561bf158SNicholas Bellinger 			return -1;
1238561bf158SNicholas Bellinger 		else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
1239afc16604SBart Van Assche 			target_put_sess_cmd(&cmd->se_cmd);
12403e1c81a9SNicholas Bellinger 			return 0;
12413e1c81a9SNicholas Bellinger 		}
1242e48354ceSNicholas Bellinger 	}
1243e48354ceSNicholas Bellinger 
124450e5c87dSChristoph Hellwig 	iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
1245e48354ceSNicholas Bellinger 
1246e48354ceSNicholas Bellinger 	/*
1247e48354ceSNicholas Bellinger 	 * If no Immediate Data is attached, it's OK to return now.
1248e48354ceSNicholas Bellinger 	 */
1249e48354ceSNicholas Bellinger 	if (!cmd->immediate_data) {
12503e1c81a9SNicholas Bellinger 		if (!cmd->sense_reason && cmd->unsolicited_data)
12513e1c81a9SNicholas Bellinger 			iscsit_set_unsoliticed_dataout(cmd);
12523e1c81a9SNicholas Bellinger 		if (!cmd->sense_reason)
12533e1c81a9SNicholas Bellinger 			return 0;
1254e48354ceSNicholas Bellinger 
1255afc16604SBart Van Assche 		target_put_sess_cmd(&cmd->se_cmd);
1256e48354ceSNicholas Bellinger 		return 0;
1257e48354ceSNicholas Bellinger 	}
1258e48354ceSNicholas Bellinger 
1259e48354ceSNicholas Bellinger 	/*
12603e1c81a9SNicholas Bellinger 	 * Early CHECK_CONDITIONs with ImmediateData never make it to command
12613e1c81a9SNicholas Bellinger 	 * execution.  These exceptions are processed in CmdSN order using
12623e1c81a9SNicholas Bellinger 	 * iscsit_check_received_cmdsn() in iscsit_get_immediate_data() below.
1263e48354ceSNicholas Bellinger 	 */
1264de103c93SChristoph Hellwig 	if (cmd->sense_reason) {
1265561bf158SNicholas Bellinger 		if (cmd->reject_reason)
1266561bf158SNicholas Bellinger 			return 0;
1267561bf158SNicholas Bellinger 
12683e1c81a9SNicholas Bellinger 		return 1;
1269e48354ceSNicholas Bellinger 	}
1270e48354ceSNicholas Bellinger 	/*
1271e48354ceSNicholas Bellinger 	 * Call directly into transport_generic_new_cmd() to perform
1272e48354ceSNicholas Bellinger 	 * the backend memory allocation.
1273e48354ceSNicholas Bellinger 	 */
1274de103c93SChristoph Hellwig 	cmd->sense_reason = transport_generic_new_cmd(&cmd->se_cmd);
1275561bf158SNicholas Bellinger 	if (cmd->sense_reason)
12763e1c81a9SNicholas Bellinger 		return 1;
1277e48354ceSNicholas Bellinger 
12783e1c81a9SNicholas Bellinger 	return 0;
12793e1c81a9SNicholas Bellinger }
12803e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_process_scsi_cmd);
12813e1c81a9SNicholas Bellinger 
12823e1c81a9SNicholas Bellinger static int
12833e1c81a9SNicholas Bellinger iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
12843e1c81a9SNicholas Bellinger 			  bool dump_payload)
12853e1c81a9SNicholas Bellinger {
12863e1c81a9SNicholas Bellinger 	int cmdsn_ret = 0, immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
12873e1c81a9SNicholas Bellinger 	/*
12883e1c81a9SNicholas Bellinger 	 * Special case for Unsupported SAM WRITE Opcodes and ImmediateData=Yes.
12893e1c81a9SNicholas Bellinger 	 */
12900bcc297eSChristophe Vu-Brugier 	if (dump_payload)
12913e1c81a9SNicholas Bellinger 		goto after_immediate_data;
12923e1c81a9SNicholas Bellinger 
12933e1c81a9SNicholas Bellinger 	immed_ret = iscsit_handle_immediate_data(cmd, hdr,
12943e1c81a9SNicholas Bellinger 					cmd->first_burst_len);
1295e48354ceSNicholas Bellinger after_immediate_data:
1296e48354ceSNicholas Bellinger 	if (immed_ret == IMMEDIATE_DATA_NORMAL_OPERATION) {
1297e48354ceSNicholas Bellinger 		/*
1298e48354ceSNicholas Bellinger 		 * A PDU/CmdSN carrying Immediate Data passed
1299e48354ceSNicholas Bellinger 		 * DataCRC, check against ExpCmdSN/MaxCmdSN if
1300e48354ceSNicholas Bellinger 		 * Immediate Bit is not set.
1301e48354ceSNicholas Bellinger 		 */
1302561bf158SNicholas Bellinger 		cmdsn_ret = iscsit_sequence_cmd(cmd->conn, cmd,
1303561bf158SNicholas Bellinger 					(unsigned char *)hdr, hdr->cmdsn);
13049d86a2beSNicholas Bellinger 		if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
1305561bf158SNicholas Bellinger 			return -1;
1306e48354ceSNicholas Bellinger 
13079d86a2beSNicholas Bellinger 		if (cmd->sense_reason || cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
1308561bf158SNicholas Bellinger 			int rc;
1309561bf158SNicholas Bellinger 
1310561bf158SNicholas Bellinger 			rc = iscsit_dump_data_payload(cmd->conn,
1311561bf158SNicholas Bellinger 						      cmd->first_burst_len, 1);
1312afc16604SBart Van Assche 			target_put_sess_cmd(&cmd->se_cmd);
1313561bf158SNicholas Bellinger 			return rc;
13143e1c81a9SNicholas Bellinger 		} else if (cmd->unsolicited_data)
13153e1c81a9SNicholas Bellinger 			iscsit_set_unsoliticed_dataout(cmd);
1316e48354ceSNicholas Bellinger 
1317e48354ceSNicholas Bellinger 	} else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) {
1318e48354ceSNicholas Bellinger 		/*
1319e48354ceSNicholas Bellinger 		 * Immediate Data failed DataCRC and ERL>=1,
1320e48354ceSNicholas Bellinger 		 * silently drop this PDU and let the initiator
1321e48354ceSNicholas Bellinger 		 * plug the CmdSN gap.
1322e48354ceSNicholas Bellinger 		 *
1323e48354ceSNicholas Bellinger 		 * FIXME: Send Unsolicited NOPIN with reserved
1324e48354ceSNicholas Bellinger 		 * TTT here to help the initiator figure out
1325e48354ceSNicholas Bellinger 		 * the missing CmdSN, although they should be
1326e48354ceSNicholas Bellinger 		 * intelligent enough to determine the missing
1327e48354ceSNicholas Bellinger 		 * CmdSN and issue a retry to plug the sequence.
1328e48354ceSNicholas Bellinger 		 */
1329e48354ceSNicholas Bellinger 		cmd->i_state = ISTATE_REMOVE;
13303e1c81a9SNicholas Bellinger 		iscsit_add_cmd_to_immediate_queue(cmd, cmd->conn, cmd->i_state);
1331e48354ceSNicholas Bellinger 	} else /* immed_ret == IMMEDIATE_DATA_CANNOT_RECOVER */
1332e48354ceSNicholas Bellinger 		return -1;
1333e48354ceSNicholas Bellinger 
1334e48354ceSNicholas Bellinger 	return 0;
1335e48354ceSNicholas Bellinger }
1336e48354ceSNicholas Bellinger 
13373e1c81a9SNicholas Bellinger static int
13383e1c81a9SNicholas Bellinger iscsit_handle_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
13393e1c81a9SNicholas Bellinger 			   unsigned char *buf)
13403e1c81a9SNicholas Bellinger {
13413e1c81a9SNicholas Bellinger 	struct iscsi_scsi_req *hdr = (struct iscsi_scsi_req *)buf;
13423e1c81a9SNicholas Bellinger 	int rc, immed_data;
13433e1c81a9SNicholas Bellinger 	bool dump_payload = false;
13443e1c81a9SNicholas Bellinger 
13453e1c81a9SNicholas Bellinger 	rc = iscsit_setup_scsi_cmd(conn, cmd, buf);
13463e1c81a9SNicholas Bellinger 	if (rc < 0)
1347561bf158SNicholas Bellinger 		return 0;
13483e1c81a9SNicholas Bellinger 	/*
13493e1c81a9SNicholas Bellinger 	 * Allocation iovecs needed for struct socket operations for
13503e1c81a9SNicholas Bellinger 	 * traditional iSCSI block I/O.
13513e1c81a9SNicholas Bellinger 	 */
13523e1c81a9SNicholas Bellinger 	if (iscsit_allocate_iovecs(cmd) < 0) {
1353b815fc12SMike Christie 		return iscsit_reject_cmd(cmd,
1354ba159914SNicholas Bellinger 				ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
13553e1c81a9SNicholas Bellinger 	}
13563e1c81a9SNicholas Bellinger 	immed_data = cmd->immediate_data;
13573e1c81a9SNicholas Bellinger 
13583e1c81a9SNicholas Bellinger 	rc = iscsit_process_scsi_cmd(conn, cmd, hdr);
13593e1c81a9SNicholas Bellinger 	if (rc < 0)
13603e1c81a9SNicholas Bellinger 		return rc;
13613e1c81a9SNicholas Bellinger 	else if (rc > 0)
13623e1c81a9SNicholas Bellinger 		dump_payload = true;
13633e1c81a9SNicholas Bellinger 
13643e1c81a9SNicholas Bellinger 	if (!immed_data)
13653e1c81a9SNicholas Bellinger 		return 0;
13663e1c81a9SNicholas Bellinger 
13673e1c81a9SNicholas Bellinger 	return iscsit_get_immediate_data(cmd, hdr, dump_payload);
13683e1c81a9SNicholas Bellinger }
13693e1c81a9SNicholas Bellinger 
1370e48354ceSNicholas Bellinger static u32 iscsit_do_crypto_hash_sg(
137169110e3cSHerbert Xu 	struct ahash_request *hash,
1372e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd,
1373e48354ceSNicholas Bellinger 	u32 data_offset,
1374e48354ceSNicholas Bellinger 	u32 data_length,
1375e48354ceSNicholas Bellinger 	u32 padding,
1376e48354ceSNicholas Bellinger 	u8 *pad_bytes)
1377e48354ceSNicholas Bellinger {
1378e48354ceSNicholas Bellinger 	u32 data_crc;
1379e48354ceSNicholas Bellinger 	struct scatterlist *sg;
1380e48354ceSNicholas Bellinger 	unsigned int page_off;
1381e48354ceSNicholas Bellinger 
138269110e3cSHerbert Xu 	crypto_ahash_init(hash);
1383e48354ceSNicholas Bellinger 
1384e48354ceSNicholas Bellinger 	sg = cmd->first_data_sg;
1385e48354ceSNicholas Bellinger 	page_off = cmd->first_data_sg_off;
1386e48354ceSNicholas Bellinger 
1387e48354ceSNicholas Bellinger 	while (data_length) {
1388aa75679cSAlexei Potashnik 		u32 cur_len = min_t(u32, data_length, (sg->length - page_off));
1389e48354ceSNicholas Bellinger 
139069110e3cSHerbert Xu 		ahash_request_set_crypt(hash, sg, NULL, cur_len);
139169110e3cSHerbert Xu 		crypto_ahash_update(hash);
1392e48354ceSNicholas Bellinger 
1393e48354ceSNicholas Bellinger 		data_length -= cur_len;
1394e48354ceSNicholas Bellinger 		page_off = 0;
1395aa75679cSAlexei Potashnik 		/* iscsit_map_iovec has already checked for invalid sg pointers */
1396aa75679cSAlexei Potashnik 		sg = sg_next(sg);
1397e48354ceSNicholas Bellinger 	}
1398e48354ceSNicholas Bellinger 
1399e48354ceSNicholas Bellinger 	if (padding) {
1400e48354ceSNicholas Bellinger 		struct scatterlist pad_sg;
1401e48354ceSNicholas Bellinger 
1402e48354ceSNicholas Bellinger 		sg_init_one(&pad_sg, pad_bytes, padding);
140369110e3cSHerbert Xu 		ahash_request_set_crypt(hash, &pad_sg, (u8 *)&data_crc,
140469110e3cSHerbert Xu 					padding);
140569110e3cSHerbert Xu 		crypto_ahash_finup(hash);
140669110e3cSHerbert Xu 	} else {
140769110e3cSHerbert Xu 		ahash_request_set_crypt(hash, NULL, (u8 *)&data_crc, 0);
140869110e3cSHerbert Xu 		crypto_ahash_final(hash);
1409e48354ceSNicholas Bellinger 	}
1410e48354ceSNicholas Bellinger 
1411e48354ceSNicholas Bellinger 	return data_crc;
1412e48354ceSNicholas Bellinger }
1413e48354ceSNicholas Bellinger 
1414e48354ceSNicholas Bellinger static void iscsit_do_crypto_hash_buf(
141569110e3cSHerbert Xu 	struct ahash_request *hash,
141680690fdbSGeert Uytterhoeven 	const void *buf,
1417e48354ceSNicholas Bellinger 	u32 payload_length,
1418e48354ceSNicholas Bellinger 	u32 padding,
1419e48354ceSNicholas Bellinger 	u8 *pad_bytes,
1420e48354ceSNicholas Bellinger 	u8 *data_crc)
1421e48354ceSNicholas Bellinger {
142269110e3cSHerbert Xu 	struct scatterlist sg[2];
1423e48354ceSNicholas Bellinger 
142469110e3cSHerbert Xu 	sg_init_table(sg, ARRAY_SIZE(sg));
142569110e3cSHerbert Xu 	sg_set_buf(sg, buf, payload_length);
142669110e3cSHerbert Xu 	sg_set_buf(sg + 1, pad_bytes, padding);
1427e48354ceSNicholas Bellinger 
142869110e3cSHerbert Xu 	ahash_request_set_crypt(hash, sg, data_crc, payload_length + padding);
1429e48354ceSNicholas Bellinger 
143069110e3cSHerbert Xu 	crypto_ahash_digest(hash);
1431e48354ceSNicholas Bellinger }
1432e48354ceSNicholas Bellinger 
14333e1c81a9SNicholas Bellinger int
14343e1c81a9SNicholas Bellinger iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf,
14353e1c81a9SNicholas Bellinger 			  struct iscsi_cmd **out_cmd)
1436e48354ceSNicholas Bellinger {
14373e1c81a9SNicholas Bellinger 	struct iscsi_data *hdr = (struct iscsi_data *)buf;
1438e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd = NULL;
1439e48354ceSNicholas Bellinger 	struct se_cmd *se_cmd;
14403e1c81a9SNicholas Bellinger 	u32 payload_length = ntoh24(hdr->dlength);
14413e1c81a9SNicholas Bellinger 	int rc;
1442e48354ceSNicholas Bellinger 
1443e48354ceSNicholas Bellinger 	if (!payload_length) {
1444dbcbc95cSNicholas Bellinger 		pr_warn("DataOUT payload is ZERO, ignoring.\n");
1445dbcbc95cSNicholas Bellinger 		return 0;
1446e48354ceSNicholas Bellinger 	}
1447e48354ceSNicholas Bellinger 
1448e48354ceSNicholas Bellinger 	/* iSCSI write */
144904f3b31bSNicholas Bellinger 	atomic_long_add(payload_length, &conn->sess->rx_data_octets);
1450e48354ceSNicholas Bellinger 
145121f5aa7eSNicholas Bellinger 	if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
1452e48354ceSNicholas Bellinger 		pr_err("DataSegmentLength: %u is greater than"
145321f5aa7eSNicholas Bellinger 			" MaxXmitDataSegmentLength: %u\n", payload_length,
145421f5aa7eSNicholas Bellinger 			conn->conn_ops->MaxXmitDataSegmentLength);
1455ba159914SNicholas Bellinger 		return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
1456ba159914SNicholas Bellinger 					 buf);
1457e48354ceSNicholas Bellinger 	}
1458e48354ceSNicholas Bellinger 
1459e48354ceSNicholas Bellinger 	cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt,
1460e48354ceSNicholas Bellinger 			payload_length);
1461e48354ceSNicholas Bellinger 	if (!cmd)
1462e48354ceSNicholas Bellinger 		return 0;
1463e48354ceSNicholas Bellinger 
1464e48354ceSNicholas Bellinger 	pr_debug("Got DataOut ITT: 0x%08x, TTT: 0x%08x,"
1465e48354ceSNicholas Bellinger 		" DataSN: 0x%08x, Offset: %u, Length: %u, CID: %hu\n",
14663e1c81a9SNicholas Bellinger 		hdr->itt, hdr->ttt, hdr->datasn, ntohl(hdr->offset),
1467e48354ceSNicholas Bellinger 		payload_length, conn->cid);
1468e48354ceSNicholas Bellinger 
1469e48354ceSNicholas Bellinger 	if (cmd->cmd_flags & ICF_GOT_LAST_DATAOUT) {
1470e48354ceSNicholas Bellinger 		pr_err("Command ITT: 0x%08x received DataOUT after"
1471e48354ceSNicholas Bellinger 			" last DataOUT received, dumping payload\n",
1472e48354ceSNicholas Bellinger 			cmd->init_task_tag);
1473e48354ceSNicholas Bellinger 		return iscsit_dump_data_payload(conn, payload_length, 1);
1474e48354ceSNicholas Bellinger 	}
1475e48354ceSNicholas Bellinger 
1476e48354ceSNicholas Bellinger 	if (cmd->data_direction != DMA_TO_DEVICE) {
1477e48354ceSNicholas Bellinger 		pr_err("Command ITT: 0x%08x received DataOUT for a"
1478e48354ceSNicholas Bellinger 			" NON-WRITE command.\n", cmd->init_task_tag);
147997c99b47SNicholas Bellinger 		return iscsit_dump_data_payload(conn, payload_length, 1);
1480e48354ceSNicholas Bellinger 	}
1481e48354ceSNicholas Bellinger 	se_cmd = &cmd->se_cmd;
1482e48354ceSNicholas Bellinger 	iscsit_mod_dataout_timer(cmd);
1483e48354ceSNicholas Bellinger 
148450e5c87dSChristoph Hellwig 	if ((be32_to_cpu(hdr->offset) + payload_length) > cmd->se_cmd.data_length) {
1485e48354ceSNicholas Bellinger 		pr_err("DataOut Offset: %u, Length %u greater than"
1486e48354ceSNicholas Bellinger 			" iSCSI Command EDTL %u, protocol error.\n",
1487ebf1d95cSAndy Grover 			hdr->offset, payload_length, cmd->se_cmd.data_length);
1488ba159914SNicholas Bellinger 		return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_INVALID, buf);
1489e48354ceSNicholas Bellinger 	}
1490e48354ceSNicholas Bellinger 
1491e48354ceSNicholas Bellinger 	if (cmd->unsolicited_data) {
1492e48354ceSNicholas Bellinger 		int dump_unsolicited_data = 0;
1493e48354ceSNicholas Bellinger 
1494e48354ceSNicholas Bellinger 		if (conn->sess->sess_ops->InitialR2T) {
1495e48354ceSNicholas Bellinger 			pr_err("Received unexpected unsolicited data"
1496e48354ceSNicholas Bellinger 				" while InitialR2T=Yes, protocol error.\n");
1497e48354ceSNicholas Bellinger 			transport_send_check_condition_and_sense(&cmd->se_cmd,
1498e48354ceSNicholas Bellinger 					TCM_UNEXPECTED_UNSOLICITED_DATA, 0);
1499e48354ceSNicholas Bellinger 			return -1;
1500e48354ceSNicholas Bellinger 		}
1501e48354ceSNicholas Bellinger 		/*
1502e48354ceSNicholas Bellinger 		 * Special case for dealing with Unsolicited DataOUT
1503e48354ceSNicholas Bellinger 		 * and Unsupported SAM WRITE Opcodes and SE resource allocation
1504e48354ceSNicholas Bellinger 		 * failures;
1505e48354ceSNicholas Bellinger 		 */
1506e48354ceSNicholas Bellinger 
1507e48354ceSNicholas Bellinger 		/* Something's amiss if we're not in WRITE_PENDING state... */
1508e48354ceSNicholas Bellinger 		WARN_ON(se_cmd->t_state != TRANSPORT_WRITE_PENDING);
1509de103c93SChristoph Hellwig 		if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE))
1510e48354ceSNicholas Bellinger 			dump_unsolicited_data = 1;
1511e48354ceSNicholas Bellinger 
1512e48354ceSNicholas Bellinger 		if (dump_unsolicited_data) {
1513e48354ceSNicholas Bellinger 			/*
1514e48354ceSNicholas Bellinger 			 * Check if a delayed TASK_ABORTED status needs to
1515e48354ceSNicholas Bellinger 			 * be sent now if the ISCSI_FLAG_CMD_FINAL has been
15165a342521SBart Van Assche 			 * received with the unsolicited data out.
1517e48354ceSNicholas Bellinger 			 */
1518e48354ceSNicholas Bellinger 			if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
1519e48354ceSNicholas Bellinger 				iscsit_stop_dataout_timer(cmd);
1520e48354ceSNicholas Bellinger 
1521e48354ceSNicholas Bellinger 			transport_check_aborted_status(se_cmd,
1522e48354ceSNicholas Bellinger 					(hdr->flags & ISCSI_FLAG_CMD_FINAL));
1523e48354ceSNicholas Bellinger 			return iscsit_dump_data_payload(conn, payload_length, 1);
1524e48354ceSNicholas Bellinger 		}
1525e48354ceSNicholas Bellinger 	} else {
1526e48354ceSNicholas Bellinger 		/*
1527e48354ceSNicholas Bellinger 		 * For the normal solicited data path:
1528e48354ceSNicholas Bellinger 		 *
1529e48354ceSNicholas Bellinger 		 * Check for a delayed TASK_ABORTED status and dump any
1530e48354ceSNicholas Bellinger 		 * incoming data out payload if one exists.  Also, when the
1531e48354ceSNicholas Bellinger 		 * ISCSI_FLAG_CMD_FINAL is set to denote the end of the current
1532e48354ceSNicholas Bellinger 		 * data out sequence, we decrement outstanding_r2ts.  Once
1533e48354ceSNicholas Bellinger 		 * outstanding_r2ts reaches zero, go ahead and send the delayed
1534e48354ceSNicholas Bellinger 		 * TASK_ABORTED status.
1535e48354ceSNicholas Bellinger 		 */
15367d680f3bSChristoph Hellwig 		if (se_cmd->transport_state & CMD_T_ABORTED) {
1537e48354ceSNicholas Bellinger 			if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
1538e48354ceSNicholas Bellinger 				if (--cmd->outstanding_r2ts < 1) {
1539e48354ceSNicholas Bellinger 					iscsit_stop_dataout_timer(cmd);
1540e48354ceSNicholas Bellinger 					transport_check_aborted_status(
1541e48354ceSNicholas Bellinger 							se_cmd, 1);
1542e48354ceSNicholas Bellinger 				}
1543e48354ceSNicholas Bellinger 
1544e48354ceSNicholas Bellinger 			return iscsit_dump_data_payload(conn, payload_length, 1);
1545e48354ceSNicholas Bellinger 		}
1546e48354ceSNicholas Bellinger 	}
1547e48354ceSNicholas Bellinger 	/*
15480d5efb8aSBart Van Assche 	 * Perform DataSN, DataSequenceInOrder, DataPDUInOrder, and
1549e48354ceSNicholas Bellinger 	 * within-command recovery checks before receiving the payload.
1550e48354ceSNicholas Bellinger 	 */
15513e1c81a9SNicholas Bellinger 	rc = iscsit_check_pre_dataout(cmd, buf);
15523e1c81a9SNicholas Bellinger 	if (rc == DATAOUT_WITHIN_COMMAND_RECOVERY)
1553e48354ceSNicholas Bellinger 		return 0;
15543e1c81a9SNicholas Bellinger 	else if (rc == DATAOUT_CANNOT_RECOVER)
1555e48354ceSNicholas Bellinger 		return -1;
1556e48354ceSNicholas Bellinger 
15573e1c81a9SNicholas Bellinger 	*out_cmd = cmd;
15583e1c81a9SNicholas Bellinger 	return 0;
15593e1c81a9SNicholas Bellinger }
15603e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_check_dataout_hdr);
15613e1c81a9SNicholas Bellinger 
15623e1c81a9SNicholas Bellinger static int
15633e1c81a9SNicholas Bellinger iscsit_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
15643e1c81a9SNicholas Bellinger 		   struct iscsi_data *hdr)
15653e1c81a9SNicholas Bellinger {
15663e1c81a9SNicholas Bellinger 	struct kvec *iov;
15673e1c81a9SNicholas Bellinger 	u32 checksum, iov_count = 0, padding = 0, rx_got = 0, rx_size = 0;
15683e1c81a9SNicholas Bellinger 	u32 payload_length = ntoh24(hdr->dlength);
15693e1c81a9SNicholas Bellinger 	int iov_ret, data_crc_failed = 0;
15703e1c81a9SNicholas Bellinger 
1571e48354ceSNicholas Bellinger 	rx_size += payload_length;
1572e48354ceSNicholas Bellinger 	iov = &cmd->iov_data[0];
1573e48354ceSNicholas Bellinger 
157450e5c87dSChristoph Hellwig 	iov_ret = iscsit_map_iovec(cmd, iov, be32_to_cpu(hdr->offset),
157550e5c87dSChristoph Hellwig 				   payload_length);
1576e48354ceSNicholas Bellinger 	if (iov_ret < 0)
1577e48354ceSNicholas Bellinger 		return -1;
1578e48354ceSNicholas Bellinger 
1579e48354ceSNicholas Bellinger 	iov_count += iov_ret;
1580e48354ceSNicholas Bellinger 
1581e48354ceSNicholas Bellinger 	padding = ((-payload_length) & 3);
1582e48354ceSNicholas Bellinger 	if (padding != 0) {
1583e48354ceSNicholas Bellinger 		iov[iov_count].iov_base	= cmd->pad_bytes;
1584e48354ceSNicholas Bellinger 		iov[iov_count++].iov_len = padding;
1585e48354ceSNicholas Bellinger 		rx_size += padding;
1586e48354ceSNicholas Bellinger 		pr_debug("Receiving %u padding bytes.\n", padding);
1587e48354ceSNicholas Bellinger 	}
1588e48354ceSNicholas Bellinger 
1589e48354ceSNicholas Bellinger 	if (conn->conn_ops->DataDigest) {
1590e48354ceSNicholas Bellinger 		iov[iov_count].iov_base = &checksum;
1591e48354ceSNicholas Bellinger 		iov[iov_count++].iov_len = ISCSI_CRC_LEN;
1592e48354ceSNicholas Bellinger 		rx_size += ISCSI_CRC_LEN;
1593e48354ceSNicholas Bellinger 	}
1594e48354ceSNicholas Bellinger 
1595e48354ceSNicholas Bellinger 	rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size);
1596e48354ceSNicholas Bellinger 
1597e48354ceSNicholas Bellinger 	iscsit_unmap_iovec(cmd);
1598e48354ceSNicholas Bellinger 
1599e48354ceSNicholas Bellinger 	if (rx_got != rx_size)
1600e48354ceSNicholas Bellinger 		return -1;
1601e48354ceSNicholas Bellinger 
1602e48354ceSNicholas Bellinger 	if (conn->conn_ops->DataDigest) {
1603e48354ceSNicholas Bellinger 		u32 data_crc;
1604e48354ceSNicholas Bellinger 
160569110e3cSHerbert Xu 		data_crc = iscsit_do_crypto_hash_sg(conn->conn_rx_hash, cmd,
160650e5c87dSChristoph Hellwig 						    be32_to_cpu(hdr->offset),
160750e5c87dSChristoph Hellwig 						    payload_length, padding,
1608e48354ceSNicholas Bellinger 						    cmd->pad_bytes);
1609e48354ceSNicholas Bellinger 
1610e48354ceSNicholas Bellinger 		if (checksum != data_crc) {
1611e48354ceSNicholas Bellinger 			pr_err("ITT: 0x%08x, Offset: %u, Length: %u,"
1612e48354ceSNicholas Bellinger 				" DataSN: 0x%08x, CRC32C DataDigest 0x%08x"
1613e48354ceSNicholas Bellinger 				" does not match computed 0x%08x\n",
1614e48354ceSNicholas Bellinger 				hdr->itt, hdr->offset, payload_length,
1615e48354ceSNicholas Bellinger 				hdr->datasn, checksum, data_crc);
1616e48354ceSNicholas Bellinger 			data_crc_failed = 1;
1617e48354ceSNicholas Bellinger 		} else {
1618e48354ceSNicholas Bellinger 			pr_debug("Got CRC32C DataDigest 0x%08x for"
1619e48354ceSNicholas Bellinger 				" %u bytes of Data Out\n", checksum,
1620e48354ceSNicholas Bellinger 				payload_length);
1621e48354ceSNicholas Bellinger 		}
1622e48354ceSNicholas Bellinger 	}
16233e1c81a9SNicholas Bellinger 
16243e1c81a9SNicholas Bellinger 	return data_crc_failed;
16253e1c81a9SNicholas Bellinger }
16263e1c81a9SNicholas Bellinger 
16273e1c81a9SNicholas Bellinger int
16283e1c81a9SNicholas Bellinger iscsit_check_dataout_payload(struct iscsi_cmd *cmd, struct iscsi_data *hdr,
16293e1c81a9SNicholas Bellinger 			     bool data_crc_failed)
16303e1c81a9SNicholas Bellinger {
16313e1c81a9SNicholas Bellinger 	struct iscsi_conn *conn = cmd->conn;
16323e1c81a9SNicholas Bellinger 	int rc, ooo_cmdsn;
1633e48354ceSNicholas Bellinger 	/*
1634e48354ceSNicholas Bellinger 	 * Increment post receive data and CRC values or perform
1635e48354ceSNicholas Bellinger 	 * within-command recovery.
1636e48354ceSNicholas Bellinger 	 */
16373e1c81a9SNicholas Bellinger 	rc = iscsit_check_post_dataout(cmd, (unsigned char *)hdr, data_crc_failed);
16383e1c81a9SNicholas Bellinger 	if ((rc == DATAOUT_NORMAL) || (rc == DATAOUT_WITHIN_COMMAND_RECOVERY))
1639e48354ceSNicholas Bellinger 		return 0;
16403e1c81a9SNicholas Bellinger 	else if (rc == DATAOUT_SEND_R2T) {
1641e48354ceSNicholas Bellinger 		iscsit_set_dataout_sequence_values(cmd);
16423e1c81a9SNicholas Bellinger 		conn->conn_transport->iscsit_get_dataout(conn, cmd, false);
16433e1c81a9SNicholas Bellinger 	} else if (rc == DATAOUT_SEND_TO_TRANSPORT) {
1644e48354ceSNicholas Bellinger 		/*
1645e48354ceSNicholas Bellinger 		 * Handle extra special case for out of order
1646e48354ceSNicholas Bellinger 		 * Unsolicited Data Out.
1647e48354ceSNicholas Bellinger 		 */
1648e48354ceSNicholas Bellinger 		spin_lock_bh(&cmd->istate_lock);
1649e48354ceSNicholas Bellinger 		ooo_cmdsn = (cmd->cmd_flags & ICF_OOO_CMDSN);
1650e48354ceSNicholas Bellinger 		cmd->cmd_flags |= ICF_GOT_LAST_DATAOUT;
1651e48354ceSNicholas Bellinger 		cmd->i_state = ISTATE_RECEIVED_LAST_DATAOUT;
1652e48354ceSNicholas Bellinger 		spin_unlock_bh(&cmd->istate_lock);
1653e48354ceSNicholas Bellinger 
1654e48354ceSNicholas Bellinger 		iscsit_stop_dataout_timer(cmd);
165567441b68SChristoph Hellwig 		if (ooo_cmdsn)
165667441b68SChristoph Hellwig 			return 0;
165767441b68SChristoph Hellwig 		target_execute_cmd(&cmd->se_cmd);
165867441b68SChristoph Hellwig 		return 0;
1659e48354ceSNicholas Bellinger 	} else /* DATAOUT_CANNOT_RECOVER */
1660e48354ceSNicholas Bellinger 		return -1;
1661e48354ceSNicholas Bellinger 
1662e48354ceSNicholas Bellinger 	return 0;
1663e48354ceSNicholas Bellinger }
16643e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_check_dataout_payload);
1665e48354ceSNicholas Bellinger 
16663e1c81a9SNicholas Bellinger static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
16673e1c81a9SNicholas Bellinger {
1668dbcbc95cSNicholas Bellinger 	struct iscsi_cmd *cmd = NULL;
16693e1c81a9SNicholas Bellinger 	struct iscsi_data *hdr = (struct iscsi_data *)buf;
16703e1c81a9SNicholas Bellinger 	int rc;
16713e1c81a9SNicholas Bellinger 	bool data_crc_failed = false;
16723e1c81a9SNicholas Bellinger 
16733e1c81a9SNicholas Bellinger 	rc = iscsit_check_dataout_hdr(conn, buf, &cmd);
16743e1c81a9SNicholas Bellinger 	if (rc < 0)
1675561bf158SNicholas Bellinger 		return 0;
16763e1c81a9SNicholas Bellinger 	else if (!cmd)
16773e1c81a9SNicholas Bellinger 		return 0;
16783e1c81a9SNicholas Bellinger 
16793e1c81a9SNicholas Bellinger 	rc = iscsit_get_dataout(conn, cmd, hdr);
16803e1c81a9SNicholas Bellinger 	if (rc < 0)
16813e1c81a9SNicholas Bellinger 		return rc;
16823e1c81a9SNicholas Bellinger 	else if (rc > 0)
16833e1c81a9SNicholas Bellinger 		data_crc_failed = true;
16843e1c81a9SNicholas Bellinger 
16853e1c81a9SNicholas Bellinger 	return iscsit_check_dataout_payload(cmd, hdr, data_crc_failed);
16863e1c81a9SNicholas Bellinger }
16873e1c81a9SNicholas Bellinger 
1688778de368SNicholas Bellinger int iscsit_setup_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
1689778de368SNicholas Bellinger 			 struct iscsi_nopout *hdr)
1690e48354ceSNicholas Bellinger {
1691778de368SNicholas Bellinger 	u32 payload_length = ntoh24(hdr->dlength);
1692e48354ceSNicholas Bellinger 
1693a3662605SArshad Hussain 	if (!(hdr->flags & ISCSI_FLAG_CMD_FINAL)) {
1694a3662605SArshad Hussain 		pr_err("NopOUT Flag's, Left Most Bit not set, protocol error.\n");
1695a3662605SArshad Hussain 		if (!cmd)
1696a3662605SArshad Hussain 			return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
1697a3662605SArshad Hussain 						 (unsigned char *)hdr);
1698a3662605SArshad Hussain 
1699a3662605SArshad Hussain 		return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
1700a3662605SArshad Hussain 					 (unsigned char *)hdr);
1701a3662605SArshad Hussain 	}
1702a3662605SArshad Hussain 
170366c7db68SChristoph Hellwig 	if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
1704e48354ceSNicholas Bellinger 		pr_err("NOPOUT ITT is reserved, but Immediate Bit is"
1705e48354ceSNicholas Bellinger 			" not set, protocol error.\n");
170628aaa950SNicholas Bellinger 		if (!cmd)
170728aaa950SNicholas Bellinger 			return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
170828aaa950SNicholas Bellinger 						 (unsigned char *)hdr);
170928aaa950SNicholas Bellinger 
1710ba159914SNicholas Bellinger 		return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
1711ba159914SNicholas Bellinger 					 (unsigned char *)hdr);
1712e48354ceSNicholas Bellinger 	}
1713e48354ceSNicholas Bellinger 
171421f5aa7eSNicholas Bellinger 	if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
1715e48354ceSNicholas Bellinger 		pr_err("NOPOUT Ping Data DataSegmentLength: %u is"
171621f5aa7eSNicholas Bellinger 			" greater than MaxXmitDataSegmentLength: %u, protocol"
1717e48354ceSNicholas Bellinger 			" error.\n", payload_length,
171821f5aa7eSNicholas Bellinger 			conn->conn_ops->MaxXmitDataSegmentLength);
171928aaa950SNicholas Bellinger 		if (!cmd)
172028aaa950SNicholas Bellinger 			return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
172128aaa950SNicholas Bellinger 						 (unsigned char *)hdr);
172228aaa950SNicholas Bellinger 
1723ba159914SNicholas Bellinger 		return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
1724ba159914SNicholas Bellinger 					 (unsigned char *)hdr);
1725e48354ceSNicholas Bellinger 	}
1726e48354ceSNicholas Bellinger 
17273e1c81a9SNicholas Bellinger 	pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%08x,"
1728e48354ceSNicholas Bellinger 		" CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n",
172966c7db68SChristoph Hellwig 		hdr->itt == RESERVED_ITT ? "Response" : "Request",
1730e48354ceSNicholas Bellinger 		hdr->itt, hdr->ttt, hdr->cmdsn, hdr->exp_statsn,
1731e48354ceSNicholas Bellinger 		payload_length);
1732e48354ceSNicholas Bellinger 	/*
1733e48354ceSNicholas Bellinger 	 * This is not a response to a Unsolicited NopIN, which means
1734e48354ceSNicholas Bellinger 	 * it can either be a NOPOUT ping request (with a valid ITT),
1735e48354ceSNicholas Bellinger 	 * or a NOPOUT not requesting a NOPIN (with a reserved ITT).
1736e48354ceSNicholas Bellinger 	 * Either way, make sure we allocate an struct iscsi_cmd, as both
1737e48354ceSNicholas Bellinger 	 * can contain ping data.
1738e48354ceSNicholas Bellinger 	 */
173950e5c87dSChristoph Hellwig 	if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
1740e48354ceSNicholas Bellinger 		cmd->iscsi_opcode	= ISCSI_OP_NOOP_OUT;
1741e48354ceSNicholas Bellinger 		cmd->i_state		= ISTATE_SEND_NOPIN;
1742e48354ceSNicholas Bellinger 		cmd->immediate_cmd	= ((hdr->opcode & ISCSI_OP_IMMEDIATE) ?
1743e48354ceSNicholas Bellinger 						1 : 0);
1744e48354ceSNicholas Bellinger 		conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
1745e48354ceSNicholas Bellinger 		cmd->targ_xfer_tag	= 0xFFFFFFFF;
174650e5c87dSChristoph Hellwig 		cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
174750e5c87dSChristoph Hellwig 		cmd->exp_stat_sn	= be32_to_cpu(hdr->exp_statsn);
1748e48354ceSNicholas Bellinger 		cmd->data_direction	= DMA_NONE;
1749e48354ceSNicholas Bellinger 	}
1750e48354ceSNicholas Bellinger 
1751778de368SNicholas Bellinger 	return 0;
1752778de368SNicholas Bellinger }
1753778de368SNicholas Bellinger EXPORT_SYMBOL(iscsit_setup_nop_out);
1754778de368SNicholas Bellinger 
1755778de368SNicholas Bellinger int iscsit_process_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
1756778de368SNicholas Bellinger 			   struct iscsi_nopout *hdr)
1757778de368SNicholas Bellinger {
1758778de368SNicholas Bellinger 	struct iscsi_cmd *cmd_p = NULL;
1759778de368SNicholas Bellinger 	int cmdsn_ret = 0;
1760778de368SNicholas Bellinger 	/*
1761778de368SNicholas Bellinger 	 * Initiator is expecting a NopIN ping reply..
1762778de368SNicholas Bellinger 	 */
1763778de368SNicholas Bellinger 	if (hdr->itt != RESERVED_ITT) {
17647cbfcc95SNicholas Bellinger 		if (!cmd)
17657cbfcc95SNicholas Bellinger 			return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
17667cbfcc95SNicholas Bellinger 						(unsigned char *)hdr);
1767778de368SNicholas Bellinger 
1768778de368SNicholas Bellinger 		spin_lock_bh(&conn->cmd_lock);
1769778de368SNicholas Bellinger 		list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
1770778de368SNicholas Bellinger 		spin_unlock_bh(&conn->cmd_lock);
1771778de368SNicholas Bellinger 
1772778de368SNicholas Bellinger 		iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
1773778de368SNicholas Bellinger 
1774778de368SNicholas Bellinger 		if (hdr->opcode & ISCSI_OP_IMMEDIATE) {
1775778de368SNicholas Bellinger 			iscsit_add_cmd_to_response_queue(cmd, conn,
1776778de368SNicholas Bellinger 							 cmd->i_state);
1777778de368SNicholas Bellinger 			return 0;
1778778de368SNicholas Bellinger 		}
1779778de368SNicholas Bellinger 
1780561bf158SNicholas Bellinger 		cmdsn_ret = iscsit_sequence_cmd(conn, cmd,
1781561bf158SNicholas Bellinger 				(unsigned char *)hdr, hdr->cmdsn);
1782778de368SNicholas Bellinger                 if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
1783778de368SNicholas Bellinger 			return 0;
1784778de368SNicholas Bellinger 		if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
1785ba159914SNicholas Bellinger 			return -1;
1786778de368SNicholas Bellinger 
1787778de368SNicholas Bellinger 		return 0;
1788778de368SNicholas Bellinger 	}
1789778de368SNicholas Bellinger 	/*
1790778de368SNicholas Bellinger 	 * This was a response to a unsolicited NOPIN ping.
1791778de368SNicholas Bellinger 	 */
1792778de368SNicholas Bellinger 	if (hdr->ttt != cpu_to_be32(0xFFFFFFFF)) {
1793778de368SNicholas Bellinger 		cmd_p = iscsit_find_cmd_from_ttt(conn, be32_to_cpu(hdr->ttt));
1794778de368SNicholas Bellinger 		if (!cmd_p)
1795778de368SNicholas Bellinger 			return -EINVAL;
1796778de368SNicholas Bellinger 
1797778de368SNicholas Bellinger 		iscsit_stop_nopin_response_timer(conn);
1798778de368SNicholas Bellinger 
1799778de368SNicholas Bellinger 		cmd_p->i_state = ISTATE_REMOVE;
1800778de368SNicholas Bellinger 		iscsit_add_cmd_to_immediate_queue(cmd_p, conn, cmd_p->i_state);
1801778de368SNicholas Bellinger 
1802778de368SNicholas Bellinger 		iscsit_start_nopin_timer(conn);
1803778de368SNicholas Bellinger 		return 0;
1804778de368SNicholas Bellinger 	}
1805778de368SNicholas Bellinger 	/*
1806778de368SNicholas Bellinger 	 * Otherwise, initiator is not expecting a NOPIN is response.
1807778de368SNicholas Bellinger 	 * Just ignore for now.
1808778de368SNicholas Bellinger 	 */
18091a40f0a3SVarun Prakash 
18101a40f0a3SVarun Prakash 	if (cmd)
18111a40f0a3SVarun Prakash 		iscsit_free_cmd(cmd, false);
18121a40f0a3SVarun Prakash 
1813778de368SNicholas Bellinger         return 0;
1814778de368SNicholas Bellinger }
1815778de368SNicholas Bellinger EXPORT_SYMBOL(iscsit_process_nop_out);
1816778de368SNicholas Bellinger 
1817778de368SNicholas Bellinger static int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
1818778de368SNicholas Bellinger 				 unsigned char *buf)
1819778de368SNicholas Bellinger {
1820778de368SNicholas Bellinger 	unsigned char *ping_data = NULL;
1821778de368SNicholas Bellinger 	struct iscsi_nopout *hdr = (struct iscsi_nopout *)buf;
1822778de368SNicholas Bellinger 	struct kvec *iov = NULL;
1823778de368SNicholas Bellinger 	u32 payload_length = ntoh24(hdr->dlength);
1824778de368SNicholas Bellinger 	int ret;
1825778de368SNicholas Bellinger 
1826778de368SNicholas Bellinger 	ret = iscsit_setup_nop_out(conn, cmd, hdr);
1827778de368SNicholas Bellinger 	if (ret < 0)
1828561bf158SNicholas Bellinger 		return 0;
1829778de368SNicholas Bellinger 	/*
1830778de368SNicholas Bellinger 	 * Handle NOP-OUT payload for traditional iSCSI sockets
1831778de368SNicholas Bellinger 	 */
183250e5c87dSChristoph Hellwig 	if (payload_length && hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
1833778de368SNicholas Bellinger 		u32 checksum, data_crc, padding = 0;
1834778de368SNicholas Bellinger 		int niov = 0, rx_got, rx_size = payload_length;
1835778de368SNicholas Bellinger 
1836e48354ceSNicholas Bellinger 		ping_data = kzalloc(payload_length + 1, GFP_KERNEL);
1837e48354ceSNicholas Bellinger 		if (!ping_data) {
1838e48354ceSNicholas Bellinger 			pr_err("Unable to allocate memory for"
1839e48354ceSNicholas Bellinger 				" NOPOUT ping data.\n");
1840e48354ceSNicholas Bellinger 			ret = -1;
1841e48354ceSNicholas Bellinger 			goto out;
1842e48354ceSNicholas Bellinger 		}
1843e48354ceSNicholas Bellinger 
1844e48354ceSNicholas Bellinger 		iov = &cmd->iov_misc[0];
1845e48354ceSNicholas Bellinger 		iov[niov].iov_base	= ping_data;
1846e48354ceSNicholas Bellinger 		iov[niov++].iov_len	= payload_length;
1847e48354ceSNicholas Bellinger 
1848e48354ceSNicholas Bellinger 		padding = ((-payload_length) & 3);
1849e48354ceSNicholas Bellinger 		if (padding != 0) {
1850e48354ceSNicholas Bellinger 			pr_debug("Receiving %u additional bytes"
1851e48354ceSNicholas Bellinger 				" for padding.\n", padding);
1852e48354ceSNicholas Bellinger 			iov[niov].iov_base	= &cmd->pad_bytes;
1853e48354ceSNicholas Bellinger 			iov[niov++].iov_len	= padding;
1854e48354ceSNicholas Bellinger 			rx_size += padding;
1855e48354ceSNicholas Bellinger 		}
1856e48354ceSNicholas Bellinger 		if (conn->conn_ops->DataDigest) {
1857e48354ceSNicholas Bellinger 			iov[niov].iov_base	= &checksum;
1858e48354ceSNicholas Bellinger 			iov[niov++].iov_len	= ISCSI_CRC_LEN;
1859e48354ceSNicholas Bellinger 			rx_size += ISCSI_CRC_LEN;
1860e48354ceSNicholas Bellinger 		}
1861e48354ceSNicholas Bellinger 
1862e48354ceSNicholas Bellinger 		rx_got = rx_data(conn, &cmd->iov_misc[0], niov, rx_size);
1863e48354ceSNicholas Bellinger 		if (rx_got != rx_size) {
1864e48354ceSNicholas Bellinger 			ret = -1;
1865e48354ceSNicholas Bellinger 			goto out;
1866e48354ceSNicholas Bellinger 		}
1867e48354ceSNicholas Bellinger 
1868e48354ceSNicholas Bellinger 		if (conn->conn_ops->DataDigest) {
186969110e3cSHerbert Xu 			iscsit_do_crypto_hash_buf(conn->conn_rx_hash,
1870e48354ceSNicholas Bellinger 					ping_data, payload_length,
1871e48354ceSNicholas Bellinger 					padding, cmd->pad_bytes,
1872e48354ceSNicholas Bellinger 					(u8 *)&data_crc);
1873e48354ceSNicholas Bellinger 
1874e48354ceSNicholas Bellinger 			if (checksum != data_crc) {
1875e48354ceSNicholas Bellinger 				pr_err("Ping data CRC32C DataDigest"
1876e48354ceSNicholas Bellinger 				" 0x%08x does not match computed 0x%08x\n",
1877e48354ceSNicholas Bellinger 					checksum, data_crc);
1878e48354ceSNicholas Bellinger 				if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
1879e48354ceSNicholas Bellinger 					pr_err("Unable to recover from"
1880e48354ceSNicholas Bellinger 					" NOPOUT Ping DataCRC failure while in"
1881e48354ceSNicholas Bellinger 						" ERL=0.\n");
1882e48354ceSNicholas Bellinger 					ret = -1;
1883e48354ceSNicholas Bellinger 					goto out;
1884e48354ceSNicholas Bellinger 				} else {
1885e48354ceSNicholas Bellinger 					/*
1886e48354ceSNicholas Bellinger 					 * Silently drop this PDU and let the
1887e48354ceSNicholas Bellinger 					 * initiator plug the CmdSN gap.
1888e48354ceSNicholas Bellinger 					 */
1889e48354ceSNicholas Bellinger 					pr_debug("Dropping NOPOUT"
1890e48354ceSNicholas Bellinger 					" Command CmdSN: 0x%08x due to"
1891e48354ceSNicholas Bellinger 					" DataCRC error.\n", hdr->cmdsn);
1892e48354ceSNicholas Bellinger 					ret = 0;
1893e48354ceSNicholas Bellinger 					goto out;
1894e48354ceSNicholas Bellinger 				}
1895e48354ceSNicholas Bellinger 			} else {
1896e48354ceSNicholas Bellinger 				pr_debug("Got CRC32C DataDigest"
1897e48354ceSNicholas Bellinger 				" 0x%08x for %u bytes of ping data.\n",
1898e48354ceSNicholas Bellinger 					checksum, payload_length);
1899e48354ceSNicholas Bellinger 			}
1900e48354ceSNicholas Bellinger 		}
1901e48354ceSNicholas Bellinger 
1902e48354ceSNicholas Bellinger 		ping_data[payload_length] = '\0';
1903e48354ceSNicholas Bellinger 		/*
1904e48354ceSNicholas Bellinger 		 * Attach ping data to struct iscsi_cmd->buf_ptr.
1905e48354ceSNicholas Bellinger 		 */
19068359cf43SJörn Engel 		cmd->buf_ptr = ping_data;
1907e48354ceSNicholas Bellinger 		cmd->buf_ptr_size = payload_length;
1908e48354ceSNicholas Bellinger 
1909e48354ceSNicholas Bellinger 		pr_debug("Got %u bytes of NOPOUT ping"
1910e48354ceSNicholas Bellinger 			" data.\n", payload_length);
1911e48354ceSNicholas Bellinger 		pr_debug("Ping Data: \"%s\"\n", ping_data);
1912e48354ceSNicholas Bellinger 	}
1913e48354ceSNicholas Bellinger 
1914778de368SNicholas Bellinger 	return iscsit_process_nop_out(conn, cmd, hdr);
1915e48354ceSNicholas Bellinger out:
1916e48354ceSNicholas Bellinger 	if (cmd)
1917aafc9d15SNicholas Bellinger 		iscsit_free_cmd(cmd, false);
1918778de368SNicholas Bellinger 
1919e48354ceSNicholas Bellinger 	kfree(ping_data);
1920e48354ceSNicholas Bellinger 	return ret;
1921e48354ceSNicholas Bellinger }
1922e48354ceSNicholas Bellinger 
1923e381fe9eSBart Van Assche static enum tcm_tmreq_table iscsit_convert_tmf(u8 iscsi_tmf)
1924e381fe9eSBart Van Assche {
1925e381fe9eSBart Van Assche 	switch (iscsi_tmf) {
1926e381fe9eSBart Van Assche 	case ISCSI_TM_FUNC_ABORT_TASK:
1927e381fe9eSBart Van Assche 		return TMR_ABORT_TASK;
1928e381fe9eSBart Van Assche 	case ISCSI_TM_FUNC_ABORT_TASK_SET:
1929e381fe9eSBart Van Assche 		return TMR_ABORT_TASK_SET;
1930e381fe9eSBart Van Assche 	case ISCSI_TM_FUNC_CLEAR_ACA:
1931e381fe9eSBart Van Assche 		return TMR_CLEAR_ACA;
1932e381fe9eSBart Van Assche 	case ISCSI_TM_FUNC_CLEAR_TASK_SET:
1933e381fe9eSBart Van Assche 		return TMR_CLEAR_TASK_SET;
1934e381fe9eSBart Van Assche 	case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET:
1935e381fe9eSBart Van Assche 		return TMR_LUN_RESET;
1936e381fe9eSBart Van Assche 	case ISCSI_TM_FUNC_TARGET_WARM_RESET:
1937e381fe9eSBart Van Assche 		return TMR_TARGET_WARM_RESET;
1938e381fe9eSBart Van Assche 	case ISCSI_TM_FUNC_TARGET_COLD_RESET:
1939e381fe9eSBart Van Assche 		return TMR_TARGET_COLD_RESET;
1940e381fe9eSBart Van Assche 	default:
1941e381fe9eSBart Van Assche 		return TMR_UNKNOWN;
1942e381fe9eSBart Van Assche 	}
1943e381fe9eSBart Van Assche }
1944e381fe9eSBart Van Assche 
19453e1c81a9SNicholas Bellinger int
19463e1c81a9SNicholas Bellinger iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
1947e48354ceSNicholas Bellinger 			   unsigned char *buf)
1948e48354ceSNicholas Bellinger {
1949e48354ceSNicholas Bellinger 	struct se_tmr_req *se_tmr;
1950e48354ceSNicholas Bellinger 	struct iscsi_tmr_req *tmr_req;
1951e48354ceSNicholas Bellinger 	struct iscsi_tm *hdr;
1952186a9647SNicholas Bellinger 	int out_of_order_cmdsn = 0, ret;
1953186a9647SNicholas Bellinger 	bool sess_ref = false;
195459b6986dSBart Van Assche 	u8 function, tcm_function = TMR_UNKNOWN;
1955e48354ceSNicholas Bellinger 
1956e48354ceSNicholas Bellinger 	hdr			= (struct iscsi_tm *) buf;
1957e48354ceSNicholas Bellinger 	hdr->flags &= ~ISCSI_FLAG_CMD_FINAL;
1958e48354ceSNicholas Bellinger 	function = hdr->flags;
1959e48354ceSNicholas Bellinger 
1960e48354ceSNicholas Bellinger 	pr_debug("Got Task Management Request ITT: 0x%08x, CmdSN:"
1961e48354ceSNicholas Bellinger 		" 0x%08x, Function: 0x%02x, RefTaskTag: 0x%08x, RefCmdSN:"
1962e48354ceSNicholas Bellinger 		" 0x%08x, CID: %hu\n", hdr->itt, hdr->cmdsn, function,
1963e48354ceSNicholas Bellinger 		hdr->rtt, hdr->refcmdsn, conn->cid);
1964e48354ceSNicholas Bellinger 
1965e48354ceSNicholas Bellinger 	if ((function != ISCSI_TM_FUNC_ABORT_TASK) &&
1966e48354ceSNicholas Bellinger 	    ((function != ISCSI_TM_FUNC_TASK_REASSIGN) &&
196766c7db68SChristoph Hellwig 	     hdr->rtt != RESERVED_ITT)) {
1968e48354ceSNicholas Bellinger 		pr_err("RefTaskTag should be set to 0xFFFFFFFF.\n");
196966c7db68SChristoph Hellwig 		hdr->rtt = RESERVED_ITT;
1970e48354ceSNicholas Bellinger 	}
1971e48354ceSNicholas Bellinger 
1972e48354ceSNicholas Bellinger 	if ((function == ISCSI_TM_FUNC_TASK_REASSIGN) &&
1973e48354ceSNicholas Bellinger 			!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
1974e48354ceSNicholas Bellinger 		pr_err("Task Management Request TASK_REASSIGN not"
1975e48354ceSNicholas Bellinger 			" issued as immediate command, bad iSCSI Initiator"
1976e48354ceSNicholas Bellinger 				"implementation\n");
1977ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1978ba159914SNicholas Bellinger 					     ISCSI_REASON_PROTOCOL_ERROR, buf);
1979e48354ceSNicholas Bellinger 	}
1980e48354ceSNicholas Bellinger 	if ((function != ISCSI_TM_FUNC_ABORT_TASK) &&
198150e5c87dSChristoph Hellwig 	    be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG)
198250e5c87dSChristoph Hellwig 		hdr->refcmdsn = cpu_to_be32(ISCSI_RESERVED_TAG);
1983e48354ceSNicholas Bellinger 
1984d28b1169SAndy Grover 	cmd->data_direction = DMA_NONE;
1985d28b1169SAndy Grover 
1986d28b1169SAndy Grover 	cmd->tmr_req = kzalloc(sizeof(struct iscsi_tmr_req), GFP_KERNEL);
1987d28b1169SAndy Grover 	if (!cmd->tmr_req) {
1988d28b1169SAndy Grover 		pr_err("Unable to allocate memory for"
1989d28b1169SAndy Grover 			" Task Management command!\n");
1990ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
1991d28b1169SAndy Grover 					     ISCSI_REASON_BOOKMARK_NO_RESOURCES,
1992ba159914SNicholas Bellinger 					     buf);
1993d28b1169SAndy Grover 	}
1994d28b1169SAndy Grover 
1995d28b1169SAndy Grover 	/*
1996d28b1169SAndy Grover 	 * TASK_REASSIGN for ERL=2 / connection stays inside of
1997d28b1169SAndy Grover 	 * LIO-Target $FABRIC_MOD
1998d28b1169SAndy Grover 	 */
1999d28b1169SAndy Grover 	if (function != ISCSI_TM_FUNC_TASK_REASSIGN) {
20009ac8928eSChristoph Hellwig 		transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops,
2001d28b1169SAndy Grover 				      conn->sess->se_sess, 0, DMA_NONE,
200268d81f40SChristoph Hellwig 				      TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
2003d28b1169SAndy Grover 
2004afc16604SBart Van Assche 		target_get_sess_cmd(&cmd->se_cmd, true);
2005186a9647SNicholas Bellinger 		sess_ref = true;
2006e381fe9eSBart Van Assche 		tcm_function = iscsit_convert_tmf(function);
2007e381fe9eSBart Van Assche 		if (tcm_function == TMR_UNKNOWN) {
2008d28b1169SAndy Grover 			pr_err("Unknown iSCSI TMR Function:"
2009d28b1169SAndy Grover 			       " 0x%02x\n", function);
2010ba159914SNicholas Bellinger 			return iscsit_add_reject_cmd(cmd,
2011ba159914SNicholas Bellinger 				ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
2012d28b1169SAndy Grover 		}
201359b6986dSBart Van Assche 	}
201459b6986dSBart Van Assche 	ret = core_tmr_alloc_req(&cmd->se_cmd, cmd->tmr_req, tcm_function,
201559b6986dSBart Van Assche 				 GFP_KERNEL);
2016d28b1169SAndy Grover 	if (ret < 0)
2017ba159914SNicholas Bellinger 		return iscsit_add_reject_cmd(cmd,
2018ba159914SNicholas Bellinger 				ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
2019d28b1169SAndy Grover 
2020d28b1169SAndy Grover 	cmd->tmr_req->se_tmr_req = cmd->se_cmd.se_tmr_req;
2021d28b1169SAndy Grover 
2022e48354ceSNicholas Bellinger 	cmd->iscsi_opcode	= ISCSI_OP_SCSI_TMFUNC;
2023e48354ceSNicholas Bellinger 	cmd->i_state		= ISTATE_SEND_TASKMGTRSP;
2024e48354ceSNicholas Bellinger 	cmd->immediate_cmd	= ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
2025e48354ceSNicholas Bellinger 	cmd->init_task_tag	= hdr->itt;
2026e48354ceSNicholas Bellinger 	cmd->targ_xfer_tag	= 0xFFFFFFFF;
202750e5c87dSChristoph Hellwig 	cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
202850e5c87dSChristoph Hellwig 	cmd->exp_stat_sn	= be32_to_cpu(hdr->exp_statsn);
2029e48354ceSNicholas Bellinger 	se_tmr			= cmd->se_cmd.se_tmr_req;
2030e48354ceSNicholas Bellinger 	tmr_req			= cmd->tmr_req;
2031e48354ceSNicholas Bellinger 	/*
2032e48354ceSNicholas Bellinger 	 * Locate the struct se_lun for all TMRs not related to ERL=2 TASK_REASSIGN
2033e48354ceSNicholas Bellinger 	 */
2034e48354ceSNicholas Bellinger 	if (function != ISCSI_TM_FUNC_TASK_REASSIGN) {
20354f26998aSAndy Grover 		ret = transport_lookup_tmr_lun(&cmd->se_cmd,
20364f26998aSAndy Grover 					       scsilun_to_int(&hdr->lun));
2037e48354ceSNicholas Bellinger 		if (ret < 0) {
2038e48354ceSNicholas Bellinger 			se_tmr->response = ISCSI_TMF_RSP_NO_LUN;
2039e48354ceSNicholas Bellinger 			goto attach;
2040e48354ceSNicholas Bellinger 		}
2041e48354ceSNicholas Bellinger 	}
2042e48354ceSNicholas Bellinger 
2043e48354ceSNicholas Bellinger 	switch (function) {
2044e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_ABORT_TASK:
2045e48354ceSNicholas Bellinger 		se_tmr->response = iscsit_tmr_abort_task(cmd, buf);
2046de103c93SChristoph Hellwig 		if (se_tmr->response)
2047e48354ceSNicholas Bellinger 			goto attach;
2048e48354ceSNicholas Bellinger 		break;
2049e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_ABORT_TASK_SET:
2050e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_CLEAR_ACA:
2051e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_CLEAR_TASK_SET:
2052e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET:
2053e48354ceSNicholas Bellinger 		break;
2054e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_TARGET_WARM_RESET:
2055e48354ceSNicholas Bellinger 		if (iscsit_tmr_task_warm_reset(conn, tmr_req, buf) < 0) {
2056e48354ceSNicholas Bellinger 			se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED;
2057e48354ceSNicholas Bellinger 			goto attach;
2058e48354ceSNicholas Bellinger 		}
2059e48354ceSNicholas Bellinger 		break;
2060e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_TARGET_COLD_RESET:
2061e48354ceSNicholas Bellinger 		if (iscsit_tmr_task_cold_reset(conn, tmr_req, buf) < 0) {
2062e48354ceSNicholas Bellinger 			se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED;
2063e48354ceSNicholas Bellinger 			goto attach;
2064e48354ceSNicholas Bellinger 		}
2065e48354ceSNicholas Bellinger 		break;
2066e48354ceSNicholas Bellinger 	case ISCSI_TM_FUNC_TASK_REASSIGN:
2067e48354ceSNicholas Bellinger 		se_tmr->response = iscsit_tmr_task_reassign(cmd, buf);
2068e48354ceSNicholas Bellinger 		/*
2069e48354ceSNicholas Bellinger 		 * Perform sanity checks on the ExpDataSN only if the
2070e48354ceSNicholas Bellinger 		 * TASK_REASSIGN was successful.
2071e48354ceSNicholas Bellinger 		 */
2072de103c93SChristoph Hellwig 		if (se_tmr->response)
2073e48354ceSNicholas Bellinger 			break;
2074e48354ceSNicholas Bellinger 
2075e48354ceSNicholas Bellinger 		if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0)
2076ba159914SNicholas Bellinger 			return iscsit_add_reject_cmd(cmd,
2077ba159914SNicholas Bellinger 					ISCSI_REASON_BOOKMARK_INVALID, buf);
2078e48354ceSNicholas Bellinger 		break;
2079e48354ceSNicholas Bellinger 	default:
2080e48354ceSNicholas Bellinger 		pr_err("Unknown TMR function: 0x%02x, protocol"
2081e48354ceSNicholas Bellinger 			" error.\n", function);
2082e48354ceSNicholas Bellinger 		se_tmr->response = ISCSI_TMF_RSP_NOT_SUPPORTED;
2083e48354ceSNicholas Bellinger 		goto attach;
2084e48354ceSNicholas Bellinger 	}
2085e48354ceSNicholas Bellinger 
2086e48354ceSNicholas Bellinger 	if ((function != ISCSI_TM_FUNC_TASK_REASSIGN) &&
2087e48354ceSNicholas Bellinger 	    (se_tmr->response == ISCSI_TMF_RSP_COMPLETE))
2088e48354ceSNicholas Bellinger 		se_tmr->call_transport = 1;
2089e48354ceSNicholas Bellinger attach:
2090e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
20912fbb471eSAndy Grover 	list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
2092e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
2093e48354ceSNicholas Bellinger 
2094e48354ceSNicholas Bellinger 	if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
2095561bf158SNicholas Bellinger 		int cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn);
2096e48354ceSNicholas Bellinger 		if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP)
2097e48354ceSNicholas Bellinger 			out_of_order_cmdsn = 1;
20985a4c8666SNicholas Bellinger 		else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
2099e48354ceSNicholas Bellinger 			return 0;
21005a4c8666SNicholas Bellinger 		else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
2101ba159914SNicholas Bellinger 			return -1;
2102e48354ceSNicholas Bellinger 	}
210350e5c87dSChristoph Hellwig 	iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
2104e48354ceSNicholas Bellinger 
21055a4c8666SNicholas Bellinger 	if (out_of_order_cmdsn || !(hdr->opcode & ISCSI_OP_IMMEDIATE))
2106e48354ceSNicholas Bellinger 		return 0;
2107e48354ceSNicholas Bellinger 	/*
2108e48354ceSNicholas Bellinger 	 * Found the referenced task, send to transport for processing.
2109e48354ceSNicholas Bellinger 	 */
2110e48354ceSNicholas Bellinger 	if (se_tmr->call_transport)
2111e48354ceSNicholas Bellinger 		return transport_generic_handle_tmr(&cmd->se_cmd);
2112e48354ceSNicholas Bellinger 
2113e48354ceSNicholas Bellinger 	/*
2114e48354ceSNicholas Bellinger 	 * Could not find the referenced LUN, task, or Task Management
2115e48354ceSNicholas Bellinger 	 * command not authorized or supported.  Change state and
2116e48354ceSNicholas Bellinger 	 * let the tx_thread send the response.
2117e48354ceSNicholas Bellinger 	 *
2118e48354ceSNicholas Bellinger 	 * For connection recovery, this is also the default action for
2119e48354ceSNicholas Bellinger 	 * TMR TASK_REASSIGN.
2120e48354ceSNicholas Bellinger 	 */
2121186a9647SNicholas Bellinger 	if (sess_ref) {
2122186a9647SNicholas Bellinger 		pr_debug("Handle TMR, using sess_ref=true check\n");
2123afc16604SBart Van Assche 		target_put_sess_cmd(&cmd->se_cmd);
2124186a9647SNicholas Bellinger 	}
2125186a9647SNicholas Bellinger 
2126e48354ceSNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2127e48354ceSNicholas Bellinger 	return 0;
2128e48354ceSNicholas Bellinger }
21293e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_handle_task_mgt_cmd);
2130e48354ceSNicholas Bellinger 
2131e48354ceSNicholas Bellinger /* #warning FIXME: Support Text Command parameters besides SendTargets */
213264534aa7SNicholas Bellinger int
213364534aa7SNicholas Bellinger iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
213464534aa7SNicholas Bellinger 		      struct iscsi_text *hdr)
2135e48354ceSNicholas Bellinger {
213664534aa7SNicholas Bellinger 	u32 payload_length = ntoh24(hdr->dlength);
2137e48354ceSNicholas Bellinger 
213821f5aa7eSNicholas Bellinger 	if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
2139e48354ceSNicholas Bellinger 		pr_err("Unable to accept text parameter length: %u"
214021f5aa7eSNicholas Bellinger 			"greater than MaxXmitDataSegmentLength %u.\n",
214121f5aa7eSNicholas Bellinger 		       payload_length, conn->conn_ops->MaxXmitDataSegmentLength);
2142ba159914SNicholas Bellinger 		return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
2143ba159914SNicholas Bellinger 					 (unsigned char *)hdr);
2144e48354ceSNicholas Bellinger 	}
2145e48354ceSNicholas Bellinger 
2146122f8afcSNicholas Bellinger 	if (!(hdr->flags & ISCSI_FLAG_CMD_FINAL) ||
2147122f8afcSNicholas Bellinger 	     (hdr->flags & ISCSI_FLAG_TEXT_CONTINUE)) {
2148122f8afcSNicholas Bellinger 		pr_err("Multi sequence text commands currently not supported\n");
2149122f8afcSNicholas Bellinger 		return iscsit_reject_cmd(cmd, ISCSI_REASON_CMD_NOT_SUPPORTED,
2150122f8afcSNicholas Bellinger 					(unsigned char *)hdr);
2151122f8afcSNicholas Bellinger 	}
2152122f8afcSNicholas Bellinger 
2153e48354ceSNicholas Bellinger 	pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x,"
2154e48354ceSNicholas Bellinger 		" ExpStatSN: 0x%08x, Length: %u\n", hdr->itt, hdr->cmdsn,
2155e48354ceSNicholas Bellinger 		hdr->exp_statsn, payload_length);
2156e48354ceSNicholas Bellinger 
215764534aa7SNicholas Bellinger 	cmd->iscsi_opcode	= ISCSI_OP_TEXT;
215864534aa7SNicholas Bellinger 	cmd->i_state		= ISTATE_SEND_TEXTRSP;
215964534aa7SNicholas Bellinger 	cmd->immediate_cmd	= ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
216064534aa7SNicholas Bellinger 	conn->sess->init_task_tag = cmd->init_task_tag  = hdr->itt;
216164534aa7SNicholas Bellinger 	cmd->targ_xfer_tag	= 0xFFFFFFFF;
216264534aa7SNicholas Bellinger 	cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
216364534aa7SNicholas Bellinger 	cmd->exp_stat_sn	= be32_to_cpu(hdr->exp_statsn);
216464534aa7SNicholas Bellinger 	cmd->data_direction	= DMA_NONE;
2165e4f4e801SSagi Grimberg 	cmd->text_in_ptr	= NULL;
216664534aa7SNicholas Bellinger 
216764534aa7SNicholas Bellinger 	return 0;
216864534aa7SNicholas Bellinger }
216964534aa7SNicholas Bellinger EXPORT_SYMBOL(iscsit_setup_text_cmd);
217064534aa7SNicholas Bellinger 
217164534aa7SNicholas Bellinger int
217264534aa7SNicholas Bellinger iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
217364534aa7SNicholas Bellinger 			struct iscsi_text *hdr)
217464534aa7SNicholas Bellinger {
21759864ca9dSNicholas Bellinger 	unsigned char *text_in = cmd->text_in_ptr, *text_ptr;
217664534aa7SNicholas Bellinger 	int cmdsn_ret;
217764534aa7SNicholas Bellinger 
21789864ca9dSNicholas Bellinger 	if (!text_in) {
2179e4f4e801SSagi Grimberg 		cmd->targ_xfer_tag = be32_to_cpu(hdr->ttt);
2180e4f4e801SSagi Grimberg 		if (cmd->targ_xfer_tag == 0xFFFFFFFF) {
21819864ca9dSNicholas Bellinger 			pr_err("Unable to locate text_in buffer for sendtargets"
21829864ca9dSNicholas Bellinger 			       " discovery\n");
21839864ca9dSNicholas Bellinger 			goto reject;
21849864ca9dSNicholas Bellinger 		}
2185e4f4e801SSagi Grimberg 		goto empty_sendtargets;
2186e4f4e801SSagi Grimberg 	}
21879864ca9dSNicholas Bellinger 	if (strncmp("SendTargets", text_in, 11) != 0) {
21889864ca9dSNicholas Bellinger 		pr_err("Received Text Data that is not"
21899864ca9dSNicholas Bellinger 			" SendTargets, cannot continue.\n");
21909864ca9dSNicholas Bellinger 		goto reject;
21919864ca9dSNicholas Bellinger 	}
21929864ca9dSNicholas Bellinger 	text_ptr = strchr(text_in, '=');
21939864ca9dSNicholas Bellinger 	if (!text_ptr) {
21949864ca9dSNicholas Bellinger 		pr_err("No \"=\" separator found in Text Data,"
21959864ca9dSNicholas Bellinger 			"  cannot continue.\n");
21969864ca9dSNicholas Bellinger 		goto reject;
21979864ca9dSNicholas Bellinger 	}
21989864ca9dSNicholas Bellinger 	if (!strncmp("=All", text_ptr, 4)) {
21998060b8ddSAndy Grover 		cmd->cmd_flags |= ICF_SENDTARGETS_ALL;
22006665889cSNicholas Bellinger 	} else if (!strncmp("=iqn.", text_ptr, 5) ||
22016665889cSNicholas Bellinger 		   !strncmp("=eui.", text_ptr, 5)) {
22028060b8ddSAndy Grover 		cmd->cmd_flags |= ICF_SENDTARGETS_SINGLE;
22039864ca9dSNicholas Bellinger 	} else {
22049864ca9dSNicholas Bellinger 		pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr);
22059864ca9dSNicholas Bellinger 		goto reject;
22069864ca9dSNicholas Bellinger 	}
22079864ca9dSNicholas Bellinger 
220864534aa7SNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
220964534aa7SNicholas Bellinger 	list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
221064534aa7SNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
221164534aa7SNicholas Bellinger 
2212e4f4e801SSagi Grimberg empty_sendtargets:
221364534aa7SNicholas Bellinger 	iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
221464534aa7SNicholas Bellinger 
221564534aa7SNicholas Bellinger 	if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
2216561bf158SNicholas Bellinger 		cmdsn_ret = iscsit_sequence_cmd(conn, cmd,
2217561bf158SNicholas Bellinger 				(unsigned char *)hdr, hdr->cmdsn);
221864534aa7SNicholas Bellinger 		if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
2219ba159914SNicholas Bellinger 			return -1;
2220ba159914SNicholas Bellinger 
222164534aa7SNicholas Bellinger 		return 0;
222264534aa7SNicholas Bellinger 	}
222364534aa7SNicholas Bellinger 
222464534aa7SNicholas Bellinger 	return iscsit_execute_cmd(cmd, 0);
22259864ca9dSNicholas Bellinger 
22269864ca9dSNicholas Bellinger reject:
2227ba159914SNicholas Bellinger 	return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
2228ba159914SNicholas Bellinger 				 (unsigned char *)hdr);
222964534aa7SNicholas Bellinger }
223064534aa7SNicholas Bellinger EXPORT_SYMBOL(iscsit_process_text_cmd);
223164534aa7SNicholas Bellinger 
223264534aa7SNicholas Bellinger static int
223364534aa7SNicholas Bellinger iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
223464534aa7SNicholas Bellinger 		       unsigned char *buf)
223564534aa7SNicholas Bellinger {
223664534aa7SNicholas Bellinger 	struct iscsi_text *hdr = (struct iscsi_text *)buf;
223764534aa7SNicholas Bellinger 	char *text_in = NULL;
223864534aa7SNicholas Bellinger 	u32 payload_length = ntoh24(hdr->dlength);
223964534aa7SNicholas Bellinger 	int rx_size, rc;
224064534aa7SNicholas Bellinger 
224164534aa7SNicholas Bellinger 	rc = iscsit_setup_text_cmd(conn, cmd, hdr);
224264534aa7SNicholas Bellinger 	if (rc < 0)
2243561bf158SNicholas Bellinger 		return 0;
224464534aa7SNicholas Bellinger 
224564534aa7SNicholas Bellinger 	rx_size = payload_length;
224664534aa7SNicholas Bellinger 	if (payload_length) {
224764534aa7SNicholas Bellinger 		u32 checksum = 0, data_crc = 0;
224864534aa7SNicholas Bellinger 		u32 padding = 0, pad_bytes = 0;
224964534aa7SNicholas Bellinger 		int niov = 0, rx_got;
225064534aa7SNicholas Bellinger 		struct kvec iov[3];
225164534aa7SNicholas Bellinger 
225264534aa7SNicholas Bellinger 		text_in = kzalloc(payload_length, GFP_KERNEL);
2253e48354ceSNicholas Bellinger 		if (!text_in) {
2254e48354ceSNicholas Bellinger 			pr_err("Unable to allocate memory for"
2255e48354ceSNicholas Bellinger 				" incoming text parameters\n");
225664534aa7SNicholas Bellinger 			goto reject;
2257e48354ceSNicholas Bellinger 		}
22589864ca9dSNicholas Bellinger 		cmd->text_in_ptr = text_in;
2259e48354ceSNicholas Bellinger 
2260e48354ceSNicholas Bellinger 		memset(iov, 0, 3 * sizeof(struct kvec));
2261e48354ceSNicholas Bellinger 		iov[niov].iov_base	= text_in;
226264534aa7SNicholas Bellinger 		iov[niov++].iov_len	= payload_length;
2263e48354ceSNicholas Bellinger 
2264e48354ceSNicholas Bellinger 		padding = ((-payload_length) & 3);
2265e48354ceSNicholas Bellinger 		if (padding != 0) {
226676f1928eSNicholas Bellinger 			iov[niov].iov_base = &pad_bytes;
2267e48354ceSNicholas Bellinger 			iov[niov++].iov_len  = padding;
2268e48354ceSNicholas Bellinger 			rx_size += padding;
2269e48354ceSNicholas Bellinger 			pr_debug("Receiving %u additional bytes"
2270e48354ceSNicholas Bellinger 					" for padding.\n", padding);
2271e48354ceSNicholas Bellinger 		}
2272e48354ceSNicholas Bellinger 		if (conn->conn_ops->DataDigest) {
2273e48354ceSNicholas Bellinger 			iov[niov].iov_base	= &checksum;
2274e48354ceSNicholas Bellinger 			iov[niov++].iov_len	= ISCSI_CRC_LEN;
2275e48354ceSNicholas Bellinger 			rx_size += ISCSI_CRC_LEN;
2276e48354ceSNicholas Bellinger 		}
2277e48354ceSNicholas Bellinger 
2278e48354ceSNicholas Bellinger 		rx_got = rx_data(conn, &iov[0], niov, rx_size);
227964534aa7SNicholas Bellinger 		if (rx_got != rx_size)
228064534aa7SNicholas Bellinger 			goto reject;
2281e48354ceSNicholas Bellinger 
2282e48354ceSNicholas Bellinger 		if (conn->conn_ops->DataDigest) {
228369110e3cSHerbert Xu 			iscsit_do_crypto_hash_buf(conn->conn_rx_hash,
228464534aa7SNicholas Bellinger 					text_in, payload_length,
228576f1928eSNicholas Bellinger 					padding, (u8 *)&pad_bytes,
2286e48354ceSNicholas Bellinger 					(u8 *)&data_crc);
2287e48354ceSNicholas Bellinger 
2288e48354ceSNicholas Bellinger 			if (checksum != data_crc) {
2289e48354ceSNicholas Bellinger 				pr_err("Text data CRC32C DataDigest"
2290e48354ceSNicholas Bellinger 					" 0x%08x does not match computed"
2291e48354ceSNicholas Bellinger 					" 0x%08x\n", checksum, data_crc);
2292e48354ceSNicholas Bellinger 				if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
2293e48354ceSNicholas Bellinger 					pr_err("Unable to recover from"
2294e48354ceSNicholas Bellinger 					" Text Data digest failure while in"
2295e48354ceSNicholas Bellinger 						" ERL=0.\n");
229664534aa7SNicholas Bellinger 					goto reject;
2297e48354ceSNicholas Bellinger 				} else {
2298e48354ceSNicholas Bellinger 					/*
2299e48354ceSNicholas Bellinger 					 * Silently drop this PDU and let the
2300e48354ceSNicholas Bellinger 					 * initiator plug the CmdSN gap.
2301e48354ceSNicholas Bellinger 					 */
2302e48354ceSNicholas Bellinger 					pr_debug("Dropping Text"
2303e48354ceSNicholas Bellinger 					" Command CmdSN: 0x%08x due to"
2304e48354ceSNicholas Bellinger 					" DataCRC error.\n", hdr->cmdsn);
2305e48354ceSNicholas Bellinger 					kfree(text_in);
2306e48354ceSNicholas Bellinger 					return 0;
2307e48354ceSNicholas Bellinger 				}
2308e48354ceSNicholas Bellinger 			} else {
2309e48354ceSNicholas Bellinger 				pr_debug("Got CRC32C DataDigest"
2310e48354ceSNicholas Bellinger 					" 0x%08x for %u bytes of text data.\n",
231164534aa7SNicholas Bellinger 						checksum, payload_length);
2312e48354ceSNicholas Bellinger 			}
2313e48354ceSNicholas Bellinger 		}
231464534aa7SNicholas Bellinger 		text_in[payload_length - 1] = '\0';
2315e48354ceSNicholas Bellinger 		pr_debug("Successfully read %d bytes of text"
231664534aa7SNicholas Bellinger 				" data.\n", payload_length);
2317e48354ceSNicholas Bellinger 	}
2318e48354ceSNicholas Bellinger 
231964534aa7SNicholas Bellinger 	return iscsit_process_text_cmd(conn, cmd, hdr);
2320e48354ceSNicholas Bellinger 
232164534aa7SNicholas Bellinger reject:
23229864ca9dSNicholas Bellinger 	kfree(cmd->text_in_ptr);
23239864ca9dSNicholas Bellinger 	cmd->text_in_ptr = NULL;
2324ba159914SNicholas Bellinger 	return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf);
2325e48354ceSNicholas Bellinger }
2326e48354ceSNicholas Bellinger 
2327e48354ceSNicholas Bellinger int iscsit_logout_closesession(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
2328e48354ceSNicholas Bellinger {
2329e48354ceSNicholas Bellinger 	struct iscsi_conn *conn_p;
2330e48354ceSNicholas Bellinger 	struct iscsi_session *sess = conn->sess;
2331e48354ceSNicholas Bellinger 
2332e48354ceSNicholas Bellinger 	pr_debug("Received logout request CLOSESESSION on CID: %hu"
2333e48354ceSNicholas Bellinger 		" for SID: %u.\n", conn->cid, conn->sess->sid);
2334e48354ceSNicholas Bellinger 
2335e48354ceSNicholas Bellinger 	atomic_set(&sess->session_logout, 1);
2336e48354ceSNicholas Bellinger 	atomic_set(&conn->conn_logout_remove, 1);
2337e48354ceSNicholas Bellinger 	conn->conn_logout_reason = ISCSI_LOGOUT_REASON_CLOSE_SESSION;
2338e48354ceSNicholas Bellinger 
2339e48354ceSNicholas Bellinger 	iscsit_inc_conn_usage_count(conn);
2340e48354ceSNicholas Bellinger 	iscsit_inc_session_usage_count(sess);
2341e48354ceSNicholas Bellinger 
2342e48354ceSNicholas Bellinger 	spin_lock_bh(&sess->conn_lock);
2343e48354ceSNicholas Bellinger 	list_for_each_entry(conn_p, &sess->sess_conn_list, conn_list) {
2344e48354ceSNicholas Bellinger 		if (conn_p->conn_state != TARG_CONN_STATE_LOGGED_IN)
2345e48354ceSNicholas Bellinger 			continue;
2346e48354ceSNicholas Bellinger 
2347e48354ceSNicholas Bellinger 		pr_debug("Moving to TARG_CONN_STATE_IN_LOGOUT.\n");
2348e48354ceSNicholas Bellinger 		conn_p->conn_state = TARG_CONN_STATE_IN_LOGOUT;
2349e48354ceSNicholas Bellinger 	}
2350e48354ceSNicholas Bellinger 	spin_unlock_bh(&sess->conn_lock);
2351e48354ceSNicholas Bellinger 
2352e48354ceSNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2353e48354ceSNicholas Bellinger 
2354e48354ceSNicholas Bellinger 	return 0;
2355e48354ceSNicholas Bellinger }
2356e48354ceSNicholas Bellinger 
2357e48354ceSNicholas Bellinger int iscsit_logout_closeconnection(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
2358e48354ceSNicholas Bellinger {
2359e48354ceSNicholas Bellinger 	struct iscsi_conn *l_conn;
2360e48354ceSNicholas Bellinger 	struct iscsi_session *sess = conn->sess;
2361e48354ceSNicholas Bellinger 
2362e48354ceSNicholas Bellinger 	pr_debug("Received logout request CLOSECONNECTION for CID:"
2363e48354ceSNicholas Bellinger 		" %hu on CID: %hu.\n", cmd->logout_cid, conn->cid);
2364e48354ceSNicholas Bellinger 
2365e48354ceSNicholas Bellinger 	/*
2366e48354ceSNicholas Bellinger 	 * A Logout Request with a CLOSECONNECTION reason code for a CID
2367e48354ceSNicholas Bellinger 	 * can arrive on a connection with a differing CID.
2368e48354ceSNicholas Bellinger 	 */
2369e48354ceSNicholas Bellinger 	if (conn->cid == cmd->logout_cid) {
2370e48354ceSNicholas Bellinger 		spin_lock_bh(&conn->state_lock);
2371e48354ceSNicholas Bellinger 		pr_debug("Moving to TARG_CONN_STATE_IN_LOGOUT.\n");
2372e48354ceSNicholas Bellinger 		conn->conn_state = TARG_CONN_STATE_IN_LOGOUT;
2373e48354ceSNicholas Bellinger 
2374e48354ceSNicholas Bellinger 		atomic_set(&conn->conn_logout_remove, 1);
2375e48354ceSNicholas Bellinger 		conn->conn_logout_reason = ISCSI_LOGOUT_REASON_CLOSE_CONNECTION;
2376e48354ceSNicholas Bellinger 		iscsit_inc_conn_usage_count(conn);
2377e48354ceSNicholas Bellinger 
2378e48354ceSNicholas Bellinger 		spin_unlock_bh(&conn->state_lock);
2379e48354ceSNicholas Bellinger 	} else {
2380e48354ceSNicholas Bellinger 		/*
2381e48354ceSNicholas Bellinger 		 * Handle all different cid CLOSECONNECTION requests in
2382e48354ceSNicholas Bellinger 		 * iscsit_logout_post_handler_diffcid() as to give enough
2383e48354ceSNicholas Bellinger 		 * time for any non immediate command's CmdSN to be
2384e48354ceSNicholas Bellinger 		 * acknowledged on the connection in question.
2385e48354ceSNicholas Bellinger 		 *
2386e48354ceSNicholas Bellinger 		 * Here we simply make sure the CID is still around.
2387e48354ceSNicholas Bellinger 		 */
2388e48354ceSNicholas Bellinger 		l_conn = iscsit_get_conn_from_cid(sess,
2389e48354ceSNicholas Bellinger 				cmd->logout_cid);
2390e48354ceSNicholas Bellinger 		if (!l_conn) {
2391e48354ceSNicholas Bellinger 			cmd->logout_response = ISCSI_LOGOUT_CID_NOT_FOUND;
2392e48354ceSNicholas Bellinger 			iscsit_add_cmd_to_response_queue(cmd, conn,
2393e48354ceSNicholas Bellinger 					cmd->i_state);
2394e48354ceSNicholas Bellinger 			return 0;
2395e48354ceSNicholas Bellinger 		}
2396e48354ceSNicholas Bellinger 
2397e48354ceSNicholas Bellinger 		iscsit_dec_conn_usage_count(l_conn);
2398e48354ceSNicholas Bellinger 	}
2399e48354ceSNicholas Bellinger 
2400e48354ceSNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2401e48354ceSNicholas Bellinger 
2402e48354ceSNicholas Bellinger 	return 0;
2403e48354ceSNicholas Bellinger }
2404e48354ceSNicholas Bellinger 
2405e48354ceSNicholas Bellinger int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
2406e48354ceSNicholas Bellinger {
2407e48354ceSNicholas Bellinger 	struct iscsi_session *sess = conn->sess;
2408e48354ceSNicholas Bellinger 
2409e48354ceSNicholas Bellinger 	pr_debug("Received explicit REMOVECONNFORRECOVERY logout for"
2410e48354ceSNicholas Bellinger 		" CID: %hu on CID: %hu.\n", cmd->logout_cid, conn->cid);
2411e48354ceSNicholas Bellinger 
2412e48354ceSNicholas Bellinger 	if (sess->sess_ops->ErrorRecoveryLevel != 2) {
2413e48354ceSNicholas Bellinger 		pr_err("Received Logout Request REMOVECONNFORRECOVERY"
2414e48354ceSNicholas Bellinger 			" while ERL!=2.\n");
2415e48354ceSNicholas Bellinger 		cmd->logout_response = ISCSI_LOGOUT_RECOVERY_UNSUPPORTED;
2416e48354ceSNicholas Bellinger 		iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2417e48354ceSNicholas Bellinger 		return 0;
2418e48354ceSNicholas Bellinger 	}
2419e48354ceSNicholas Bellinger 
2420e48354ceSNicholas Bellinger 	if (conn->cid == cmd->logout_cid) {
2421e48354ceSNicholas Bellinger 		pr_err("Received Logout Request REMOVECONNFORRECOVERY"
2422e48354ceSNicholas Bellinger 			" with CID: %hu on CID: %hu, implementation error.\n",
2423e48354ceSNicholas Bellinger 				cmd->logout_cid, conn->cid);
2424e48354ceSNicholas Bellinger 		cmd->logout_response = ISCSI_LOGOUT_CLEANUP_FAILED;
2425e48354ceSNicholas Bellinger 		iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2426e48354ceSNicholas Bellinger 		return 0;
2427e48354ceSNicholas Bellinger 	}
2428e48354ceSNicholas Bellinger 
2429e48354ceSNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
2430e48354ceSNicholas Bellinger 
2431e48354ceSNicholas Bellinger 	return 0;
2432e48354ceSNicholas Bellinger }
2433e48354ceSNicholas Bellinger 
24343e1c81a9SNicholas Bellinger int
24353e1c81a9SNicholas Bellinger iscsit_handle_logout_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
2436e48354ceSNicholas Bellinger 			unsigned char *buf)
2437e48354ceSNicholas Bellinger {
2438e48354ceSNicholas Bellinger 	int cmdsn_ret, logout_remove = 0;
2439e48354ceSNicholas Bellinger 	u8 reason_code = 0;
2440e48354ceSNicholas Bellinger 	struct iscsi_logout *hdr;
2441e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn = iscsit_snmp_get_tiqn(conn);
2442e48354ceSNicholas Bellinger 
2443e48354ceSNicholas Bellinger 	hdr			= (struct iscsi_logout *) buf;
2444e48354ceSNicholas Bellinger 	reason_code		= (hdr->flags & 0x7f);
2445e48354ceSNicholas Bellinger 
2446e48354ceSNicholas Bellinger 	if (tiqn) {
2447e48354ceSNicholas Bellinger 		spin_lock(&tiqn->logout_stats.lock);
2448e48354ceSNicholas Bellinger 		if (reason_code == ISCSI_LOGOUT_REASON_CLOSE_SESSION)
2449e48354ceSNicholas Bellinger 			tiqn->logout_stats.normal_logouts++;
2450e48354ceSNicholas Bellinger 		else
2451e48354ceSNicholas Bellinger 			tiqn->logout_stats.abnormal_logouts++;
2452e48354ceSNicholas Bellinger 		spin_unlock(&tiqn->logout_stats.lock);
2453e48354ceSNicholas Bellinger 	}
2454e48354ceSNicholas Bellinger 
2455e48354ceSNicholas Bellinger 	pr_debug("Got Logout Request ITT: 0x%08x CmdSN: 0x%08x"
2456e48354ceSNicholas Bellinger 		" ExpStatSN: 0x%08x Reason: 0x%02x CID: %hu on CID: %hu\n",
2457e48354ceSNicholas Bellinger 		hdr->itt, hdr->cmdsn, hdr->exp_statsn, reason_code,
2458e48354ceSNicholas Bellinger 		hdr->cid, conn->cid);
2459e48354ceSNicholas Bellinger 
2460e48354ceSNicholas Bellinger 	if (conn->conn_state != TARG_CONN_STATE_LOGGED_IN) {
2461e48354ceSNicholas Bellinger 		pr_err("Received logout request on connection that"
2462e48354ceSNicholas Bellinger 			" is not in logged in state, ignoring request.\n");
2463aafc9d15SNicholas Bellinger 		iscsit_free_cmd(cmd, false);
2464e48354ceSNicholas Bellinger 		return 0;
2465e48354ceSNicholas Bellinger 	}
2466e48354ceSNicholas Bellinger 
2467e48354ceSNicholas Bellinger 	cmd->iscsi_opcode       = ISCSI_OP_LOGOUT;
2468e48354ceSNicholas Bellinger 	cmd->i_state            = ISTATE_SEND_LOGOUTRSP;
2469e48354ceSNicholas Bellinger 	cmd->immediate_cmd      = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
2470e48354ceSNicholas Bellinger 	conn->sess->init_task_tag = cmd->init_task_tag  = hdr->itt;
2471e48354ceSNicholas Bellinger 	cmd->targ_xfer_tag      = 0xFFFFFFFF;
247250e5c87dSChristoph Hellwig 	cmd->cmd_sn             = be32_to_cpu(hdr->cmdsn);
247350e5c87dSChristoph Hellwig 	cmd->exp_stat_sn        = be32_to_cpu(hdr->exp_statsn);
247450e5c87dSChristoph Hellwig 	cmd->logout_cid         = be16_to_cpu(hdr->cid);
2475e48354ceSNicholas Bellinger 	cmd->logout_reason      = reason_code;
2476e48354ceSNicholas Bellinger 	cmd->data_direction     = DMA_NONE;
2477e48354ceSNicholas Bellinger 
2478e48354ceSNicholas Bellinger 	/*
2479e48354ceSNicholas Bellinger 	 * We need to sleep in these cases (by returning 1) until the Logout
2480e48354ceSNicholas Bellinger 	 * Response gets sent in the tx thread.
2481e48354ceSNicholas Bellinger 	 */
2482e48354ceSNicholas Bellinger 	if ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_SESSION) ||
2483e48354ceSNicholas Bellinger 	   ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_CONNECTION) &&
248450e5c87dSChristoph Hellwig 	    be16_to_cpu(hdr->cid) == conn->cid))
2485e48354ceSNicholas Bellinger 		logout_remove = 1;
2486e48354ceSNicholas Bellinger 
2487e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
24882fbb471eSAndy Grover 	list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
2489e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
2490e48354ceSNicholas Bellinger 
2491e48354ceSNicholas Bellinger 	if (reason_code != ISCSI_LOGOUT_REASON_RECOVERY)
249250e5c87dSChristoph Hellwig 		iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
2493e48354ceSNicholas Bellinger 
2494e48354ceSNicholas Bellinger 	/*
2495e48354ceSNicholas Bellinger 	 * Immediate commands are executed, well, immediately.
2496e48354ceSNicholas Bellinger 	 * Non-Immediate Logout Commands are executed in CmdSN order.
2497e48354ceSNicholas Bellinger 	 */
2498c6037cc5SAndy Grover 	if (cmd->immediate_cmd) {
2499e48354ceSNicholas Bellinger 		int ret = iscsit_execute_cmd(cmd, 0);
2500e48354ceSNicholas Bellinger 
2501e48354ceSNicholas Bellinger 		if (ret < 0)
2502e48354ceSNicholas Bellinger 			return ret;
2503e48354ceSNicholas Bellinger 	} else {
2504561bf158SNicholas Bellinger 		cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn);
2505ba159914SNicholas Bellinger 		if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
2506e48354ceSNicholas Bellinger 			logout_remove = 0;
2507ba159914SNicholas Bellinger 		else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
2508ba159914SNicholas Bellinger 			return -1;
2509e48354ceSNicholas Bellinger 	}
2510e48354ceSNicholas Bellinger 
2511e48354ceSNicholas Bellinger 	return logout_remove;
2512e48354ceSNicholas Bellinger }
25133e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_handle_logout_cmd);
2514e48354ceSNicholas Bellinger 
2515d2faaefbSVarun Prakash int iscsit_handle_snack(
2516e48354ceSNicholas Bellinger 	struct iscsi_conn *conn,
2517e48354ceSNicholas Bellinger 	unsigned char *buf)
2518e48354ceSNicholas Bellinger {
2519e48354ceSNicholas Bellinger 	struct iscsi_snack *hdr;
2520e48354ceSNicholas Bellinger 
2521e48354ceSNicholas Bellinger 	hdr			= (struct iscsi_snack *) buf;
2522e48354ceSNicholas Bellinger 	hdr->flags		&= ~ISCSI_FLAG_CMD_FINAL;
2523e48354ceSNicholas Bellinger 
2524e48354ceSNicholas Bellinger 	pr_debug("Got ISCSI_INIT_SNACK, ITT: 0x%08x, ExpStatSN:"
2525e48354ceSNicholas Bellinger 		" 0x%08x, Type: 0x%02x, BegRun: 0x%08x, RunLength: 0x%08x,"
2526e48354ceSNicholas Bellinger 		" CID: %hu\n", hdr->itt, hdr->exp_statsn, hdr->flags,
2527e48354ceSNicholas Bellinger 			hdr->begrun, hdr->runlength, conn->cid);
2528e48354ceSNicholas Bellinger 
2529e48354ceSNicholas Bellinger 	if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
2530e48354ceSNicholas Bellinger 		pr_err("Initiator sent SNACK request while in"
2531e48354ceSNicholas Bellinger 			" ErrorRecoveryLevel=0.\n");
2532ba159914SNicholas Bellinger 		return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
2533ba159914SNicholas Bellinger 					 buf);
2534e48354ceSNicholas Bellinger 	}
2535e48354ceSNicholas Bellinger 	/*
2536e48354ceSNicholas Bellinger 	 * SNACK_DATA and SNACK_R2T are both 0,  so check which function to
2537e48354ceSNicholas Bellinger 	 * call from inside iscsi_send_recovery_datain_or_r2t().
2538e48354ceSNicholas Bellinger 	 */
2539e48354ceSNicholas Bellinger 	switch (hdr->flags & ISCSI_FLAG_SNACK_TYPE_MASK) {
2540e48354ceSNicholas Bellinger 	case 0:
2541e48354ceSNicholas Bellinger 		return iscsit_handle_recovery_datain_or_r2t(conn, buf,
254250e5c87dSChristoph Hellwig 			hdr->itt,
254350e5c87dSChristoph Hellwig 			be32_to_cpu(hdr->ttt),
254450e5c87dSChristoph Hellwig 			be32_to_cpu(hdr->begrun),
254550e5c87dSChristoph Hellwig 			be32_to_cpu(hdr->runlength));
2546e48354ceSNicholas Bellinger 	case ISCSI_FLAG_SNACK_TYPE_STATUS:
254750e5c87dSChristoph Hellwig 		return iscsit_handle_status_snack(conn, hdr->itt,
254850e5c87dSChristoph Hellwig 			be32_to_cpu(hdr->ttt),
254950e5c87dSChristoph Hellwig 			be32_to_cpu(hdr->begrun), be32_to_cpu(hdr->runlength));
2550e48354ceSNicholas Bellinger 	case ISCSI_FLAG_SNACK_TYPE_DATA_ACK:
255150e5c87dSChristoph Hellwig 		return iscsit_handle_data_ack(conn, be32_to_cpu(hdr->ttt),
255250e5c87dSChristoph Hellwig 			be32_to_cpu(hdr->begrun),
255350e5c87dSChristoph Hellwig 			be32_to_cpu(hdr->runlength));
2554e48354ceSNicholas Bellinger 	case ISCSI_FLAG_SNACK_TYPE_RDATA:
2555e48354ceSNicholas Bellinger 		/* FIXME: Support R-Data SNACK */
2556e48354ceSNicholas Bellinger 		pr_err("R-Data SNACK Not Supported.\n");
2557ba159914SNicholas Bellinger 		return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
2558ba159914SNicholas Bellinger 					 buf);
2559e48354ceSNicholas Bellinger 	default:
2560e48354ceSNicholas Bellinger 		pr_err("Unknown SNACK type 0x%02x, protocol"
2561e48354ceSNicholas Bellinger 			" error.\n", hdr->flags & 0x0f);
2562ba159914SNicholas Bellinger 		return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
2563ba159914SNicholas Bellinger 					 buf);
2564e48354ceSNicholas Bellinger 	}
2565e48354ceSNicholas Bellinger 
2566e48354ceSNicholas Bellinger 	return 0;
2567e48354ceSNicholas Bellinger }
2568d2faaefbSVarun Prakash EXPORT_SYMBOL(iscsit_handle_snack);
2569e48354ceSNicholas Bellinger 
2570e48354ceSNicholas Bellinger static void iscsit_rx_thread_wait_for_tcp(struct iscsi_conn *conn)
2571e48354ceSNicholas Bellinger {
2572e48354ceSNicholas Bellinger 	if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) ||
2573e48354ceSNicholas Bellinger 	    (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) {
2574e48354ceSNicholas Bellinger 		wait_for_completion_interruptible_timeout(
2575e48354ceSNicholas Bellinger 					&conn->rx_half_close_comp,
2576e48354ceSNicholas Bellinger 					ISCSI_RX_THREAD_TCP_TIMEOUT * HZ);
2577e48354ceSNicholas Bellinger 	}
2578e48354ceSNicholas Bellinger }
2579e48354ceSNicholas Bellinger 
2580e48354ceSNicholas Bellinger static int iscsit_handle_immediate_data(
2581e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd,
25823e1c81a9SNicholas Bellinger 	struct iscsi_scsi_req *hdr,
2583e48354ceSNicholas Bellinger 	u32 length)
2584e48354ceSNicholas Bellinger {
2585e48354ceSNicholas Bellinger 	int iov_ret, rx_got = 0, rx_size = 0;
2586e48354ceSNicholas Bellinger 	u32 checksum, iov_count = 0, padding = 0;
2587e48354ceSNicholas Bellinger 	struct iscsi_conn *conn = cmd->conn;
2588e48354ceSNicholas Bellinger 	struct kvec *iov;
2589e48354ceSNicholas Bellinger 
2590e48354ceSNicholas Bellinger 	iov_ret = iscsit_map_iovec(cmd, cmd->iov_data, cmd->write_data_done, length);
2591e48354ceSNicholas Bellinger 	if (iov_ret < 0)
2592e48354ceSNicholas Bellinger 		return IMMEDIATE_DATA_CANNOT_RECOVER;
2593e48354ceSNicholas Bellinger 
2594e48354ceSNicholas Bellinger 	rx_size = length;
2595e48354ceSNicholas Bellinger 	iov_count = iov_ret;
2596e48354ceSNicholas Bellinger 	iov = &cmd->iov_data[0];
2597e48354ceSNicholas Bellinger 
2598e48354ceSNicholas Bellinger 	padding = ((-length) & 3);
2599e48354ceSNicholas Bellinger 	if (padding != 0) {
2600e48354ceSNicholas Bellinger 		iov[iov_count].iov_base	= cmd->pad_bytes;
2601e48354ceSNicholas Bellinger 		iov[iov_count++].iov_len = padding;
2602e48354ceSNicholas Bellinger 		rx_size += padding;
2603e48354ceSNicholas Bellinger 	}
2604e48354ceSNicholas Bellinger 
2605e48354ceSNicholas Bellinger 	if (conn->conn_ops->DataDigest) {
2606e48354ceSNicholas Bellinger 		iov[iov_count].iov_base		= &checksum;
2607e48354ceSNicholas Bellinger 		iov[iov_count++].iov_len	= ISCSI_CRC_LEN;
2608e48354ceSNicholas Bellinger 		rx_size += ISCSI_CRC_LEN;
2609e48354ceSNicholas Bellinger 	}
2610e48354ceSNicholas Bellinger 
2611e48354ceSNicholas Bellinger 	rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size);
2612e48354ceSNicholas Bellinger 
2613e48354ceSNicholas Bellinger 	iscsit_unmap_iovec(cmd);
2614e48354ceSNicholas Bellinger 
2615e48354ceSNicholas Bellinger 	if (rx_got != rx_size) {
2616e48354ceSNicholas Bellinger 		iscsit_rx_thread_wait_for_tcp(conn);
2617e48354ceSNicholas Bellinger 		return IMMEDIATE_DATA_CANNOT_RECOVER;
2618e48354ceSNicholas Bellinger 	}
2619e48354ceSNicholas Bellinger 
2620e48354ceSNicholas Bellinger 	if (conn->conn_ops->DataDigest) {
2621e48354ceSNicholas Bellinger 		u32 data_crc;
2622e48354ceSNicholas Bellinger 
262369110e3cSHerbert Xu 		data_crc = iscsit_do_crypto_hash_sg(conn->conn_rx_hash, cmd,
2624e48354ceSNicholas Bellinger 						    cmd->write_data_done, length, padding,
2625e48354ceSNicholas Bellinger 						    cmd->pad_bytes);
2626e48354ceSNicholas Bellinger 
2627e48354ceSNicholas Bellinger 		if (checksum != data_crc) {
2628e48354ceSNicholas Bellinger 			pr_err("ImmediateData CRC32C DataDigest 0x%08x"
2629e48354ceSNicholas Bellinger 				" does not match computed 0x%08x\n", checksum,
2630e48354ceSNicholas Bellinger 				data_crc);
2631e48354ceSNicholas Bellinger 
2632e48354ceSNicholas Bellinger 			if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
2633e48354ceSNicholas Bellinger 				pr_err("Unable to recover from"
2634e48354ceSNicholas Bellinger 					" Immediate Data digest failure while"
2635e48354ceSNicholas Bellinger 					" in ERL=0.\n");
2636ba159914SNicholas Bellinger 				iscsit_reject_cmd(cmd,
2637e48354ceSNicholas Bellinger 						ISCSI_REASON_DATA_DIGEST_ERROR,
2638ba159914SNicholas Bellinger 						(unsigned char *)hdr);
2639e48354ceSNicholas Bellinger 				return IMMEDIATE_DATA_CANNOT_RECOVER;
2640e48354ceSNicholas Bellinger 			} else {
2641ba159914SNicholas Bellinger 				iscsit_reject_cmd(cmd,
2642e48354ceSNicholas Bellinger 						ISCSI_REASON_DATA_DIGEST_ERROR,
2643ba159914SNicholas Bellinger 						(unsigned char *)hdr);
2644e48354ceSNicholas Bellinger 				return IMMEDIATE_DATA_ERL1_CRC_FAILURE;
2645e48354ceSNicholas Bellinger 			}
2646e48354ceSNicholas Bellinger 		} else {
2647e48354ceSNicholas Bellinger 			pr_debug("Got CRC32C DataDigest 0x%08x for"
2648e48354ceSNicholas Bellinger 				" %u bytes of Immediate Data\n", checksum,
2649e48354ceSNicholas Bellinger 				length);
2650e48354ceSNicholas Bellinger 		}
2651e48354ceSNicholas Bellinger 	}
2652e48354ceSNicholas Bellinger 
2653e48354ceSNicholas Bellinger 	cmd->write_data_done += length;
2654e48354ceSNicholas Bellinger 
2655ebf1d95cSAndy Grover 	if (cmd->write_data_done == cmd->se_cmd.data_length) {
2656e48354ceSNicholas Bellinger 		spin_lock_bh(&cmd->istate_lock);
2657e48354ceSNicholas Bellinger 		cmd->cmd_flags |= ICF_GOT_LAST_DATAOUT;
2658e48354ceSNicholas Bellinger 		cmd->i_state = ISTATE_RECEIVED_LAST_DATAOUT;
2659e48354ceSNicholas Bellinger 		spin_unlock_bh(&cmd->istate_lock);
2660e48354ceSNicholas Bellinger 	}
2661e48354ceSNicholas Bellinger 
2662e48354ceSNicholas Bellinger 	return IMMEDIATE_DATA_NORMAL_OPERATION;
2663e48354ceSNicholas Bellinger }
2664e48354ceSNicholas Bellinger 
2665e48354ceSNicholas Bellinger /*
2666e48354ceSNicholas Bellinger  *	Called with sess->conn_lock held.
2667e48354ceSNicholas Bellinger  */
2668e48354ceSNicholas Bellinger /* #warning iscsi_build_conn_drop_async_message() only sends out on connections
2669e48354ceSNicholas Bellinger 	with active network interface */
2670e48354ceSNicholas Bellinger static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn)
2671e48354ceSNicholas Bellinger {
2672e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd;
2673e48354ceSNicholas Bellinger 	struct iscsi_conn *conn_p;
2674d444edc6SNicholas Bellinger 	bool found = false;
2675e48354ceSNicholas Bellinger 
2676e48354ceSNicholas Bellinger 	/*
2677e48354ceSNicholas Bellinger 	 * Only send a Asynchronous Message on connections whos network
2678e48354ceSNicholas Bellinger 	 * interface is still functional.
2679e48354ceSNicholas Bellinger 	 */
2680e48354ceSNicholas Bellinger 	list_for_each_entry(conn_p, &conn->sess->sess_conn_list, conn_list) {
2681e48354ceSNicholas Bellinger 		if (conn_p->conn_state == TARG_CONN_STATE_LOGGED_IN) {
2682e48354ceSNicholas Bellinger 			iscsit_inc_conn_usage_count(conn_p);
2683d444edc6SNicholas Bellinger 			found = true;
2684e48354ceSNicholas Bellinger 			break;
2685e48354ceSNicholas Bellinger 		}
2686e48354ceSNicholas Bellinger 	}
2687e48354ceSNicholas Bellinger 
2688d444edc6SNicholas Bellinger 	if (!found)
2689e48354ceSNicholas Bellinger 		return;
2690e48354ceSNicholas Bellinger 
2691676687c6SNicholas Bellinger 	cmd = iscsit_allocate_cmd(conn_p, TASK_RUNNING);
2692e48354ceSNicholas Bellinger 	if (!cmd) {
2693e48354ceSNicholas Bellinger 		iscsit_dec_conn_usage_count(conn_p);
2694e48354ceSNicholas Bellinger 		return;
2695e48354ceSNicholas Bellinger 	}
2696e48354ceSNicholas Bellinger 
2697e48354ceSNicholas Bellinger 	cmd->logout_cid = conn->cid;
2698e48354ceSNicholas Bellinger 	cmd->iscsi_opcode = ISCSI_OP_ASYNC_EVENT;
2699e48354ceSNicholas Bellinger 	cmd->i_state = ISTATE_SEND_ASYNCMSG;
2700e48354ceSNicholas Bellinger 
2701e48354ceSNicholas Bellinger 	spin_lock_bh(&conn_p->cmd_lock);
27022fbb471eSAndy Grover 	list_add_tail(&cmd->i_conn_node, &conn_p->conn_cmd_list);
2703e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn_p->cmd_lock);
2704e48354ceSNicholas Bellinger 
2705e48354ceSNicholas Bellinger 	iscsit_add_cmd_to_response_queue(cmd, conn_p, cmd->i_state);
2706e48354ceSNicholas Bellinger 	iscsit_dec_conn_usage_count(conn_p);
2707e48354ceSNicholas Bellinger }
2708e48354ceSNicholas Bellinger 
2709e48354ceSNicholas Bellinger static int iscsit_send_conn_drop_async_message(
2710e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd,
2711e48354ceSNicholas Bellinger 	struct iscsi_conn *conn)
2712e48354ceSNicholas Bellinger {
2713e48354ceSNicholas Bellinger 	struct iscsi_async *hdr;
2714e48354ceSNicholas Bellinger 
2715e48354ceSNicholas Bellinger 	cmd->iscsi_opcode = ISCSI_OP_ASYNC_EVENT;
2716e48354ceSNicholas Bellinger 
2717e48354ceSNicholas Bellinger 	hdr			= (struct iscsi_async *) cmd->pdu;
2718e48354ceSNicholas Bellinger 	hdr->opcode		= ISCSI_OP_ASYNC_EVENT;
2719e48354ceSNicholas Bellinger 	hdr->flags		= ISCSI_FLAG_CMD_FINAL;
272066c7db68SChristoph Hellwig 	cmd->init_task_tag	= RESERVED_ITT;
2721e48354ceSNicholas Bellinger 	cmd->targ_xfer_tag	= 0xFFFFFFFF;
2722e48354ceSNicholas Bellinger 	put_unaligned_be64(0xFFFFFFFFFFFFFFFFULL, &hdr->rsvd4[0]);
2723e48354ceSNicholas Bellinger 	cmd->stat_sn		= conn->stat_sn++;
2724e48354ceSNicholas Bellinger 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
2725e48354ceSNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
2726109e2381SRoland Dreier 	hdr->max_cmdsn		= cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
2727e48354ceSNicholas Bellinger 	hdr->async_event	= ISCSI_ASYNC_MSG_DROPPING_CONNECTION;
2728e48354ceSNicholas Bellinger 	hdr->param1		= cpu_to_be16(cmd->logout_cid);
2729e48354ceSNicholas Bellinger 	hdr->param2		= cpu_to_be16(conn->sess->sess_ops->DefaultTime2Wait);
2730e48354ceSNicholas Bellinger 	hdr->param3		= cpu_to_be16(conn->sess->sess_ops->DefaultTime2Retain);
2731e48354ceSNicholas Bellinger 
2732e48354ceSNicholas Bellinger 	pr_debug("Sending Connection Dropped Async Message StatSN:"
2733e48354ceSNicholas Bellinger 		" 0x%08x, for CID: %hu on CID: %hu\n", cmd->stat_sn,
2734e48354ceSNicholas Bellinger 			cmd->logout_cid, conn->cid);
27352854bb23SVarun Prakash 
27362854bb23SVarun Prakash 	return conn->conn_transport->iscsit_xmit_pdu(conn, cmd, NULL, NULL, 0);
2737e48354ceSNicholas Bellinger }
2738e48354ceSNicholas Bellinger 
27396f3c0e69SAndy Grover static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn)
27406f3c0e69SAndy Grover {
27416f3c0e69SAndy Grover 	if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) ||
27426f3c0e69SAndy Grover 	    (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) {
27436f3c0e69SAndy Grover 		wait_for_completion_interruptible_timeout(
27446f3c0e69SAndy Grover 					&conn->tx_half_close_comp,
27456f3c0e69SAndy Grover 					ISCSI_TX_THREAD_TCP_TIMEOUT * HZ);
27466f3c0e69SAndy Grover 	}
27476f3c0e69SAndy Grover }
27486f3c0e69SAndy Grover 
2749d2faaefbSVarun Prakash void
27502ec5a8c1SNicholas Bellinger iscsit_build_datain_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
27512ec5a8c1SNicholas Bellinger 			struct iscsi_datain *datain, struct iscsi_data_rsp *hdr,
27522ec5a8c1SNicholas Bellinger 			bool set_statsn)
2753e48354ceSNicholas Bellinger {
27542ec5a8c1SNicholas Bellinger 	hdr->opcode		= ISCSI_OP_SCSI_DATA_IN;
27552ec5a8c1SNicholas Bellinger 	hdr->flags		= datain->flags;
27562ec5a8c1SNicholas Bellinger 	if (hdr->flags & ISCSI_FLAG_DATA_STATUS) {
27572ec5a8c1SNicholas Bellinger 		if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) {
27582ec5a8c1SNicholas Bellinger 			hdr->flags |= ISCSI_FLAG_DATA_OVERFLOW;
27592ec5a8c1SNicholas Bellinger 			hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
27602ec5a8c1SNicholas Bellinger 		} else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) {
27612ec5a8c1SNicholas Bellinger 			hdr->flags |= ISCSI_FLAG_DATA_UNDERFLOW;
27622ec5a8c1SNicholas Bellinger 			hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
27632ec5a8c1SNicholas Bellinger 		}
27642ec5a8c1SNicholas Bellinger 	}
27652ec5a8c1SNicholas Bellinger 	hton24(hdr->dlength, datain->length);
27662ec5a8c1SNicholas Bellinger 	if (hdr->flags & ISCSI_FLAG_DATA_ACK)
27672ec5a8c1SNicholas Bellinger 		int_to_scsilun(cmd->se_cmd.orig_fe_lun,
27682ec5a8c1SNicholas Bellinger 				(struct scsi_lun *)&hdr->lun);
27692ec5a8c1SNicholas Bellinger 	else
27702ec5a8c1SNicholas Bellinger 		put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);
27712ec5a8c1SNicholas Bellinger 
27722ec5a8c1SNicholas Bellinger 	hdr->itt		= cmd->init_task_tag;
27732ec5a8c1SNicholas Bellinger 
27742ec5a8c1SNicholas Bellinger 	if (hdr->flags & ISCSI_FLAG_DATA_ACK)
27752ec5a8c1SNicholas Bellinger 		hdr->ttt		= cpu_to_be32(cmd->targ_xfer_tag);
27762ec5a8c1SNicholas Bellinger 	else
27772ec5a8c1SNicholas Bellinger 		hdr->ttt		= cpu_to_be32(0xFFFFFFFF);
27782ec5a8c1SNicholas Bellinger 	if (set_statsn)
27792ec5a8c1SNicholas Bellinger 		hdr->statsn		= cpu_to_be32(cmd->stat_sn);
27802ec5a8c1SNicholas Bellinger 	else
27812ec5a8c1SNicholas Bellinger 		hdr->statsn		= cpu_to_be32(0xFFFFFFFF);
27822ec5a8c1SNicholas Bellinger 
27832ec5a8c1SNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
2784109e2381SRoland Dreier 	hdr->max_cmdsn		= cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
27852ec5a8c1SNicholas Bellinger 	hdr->datasn		= cpu_to_be32(datain->data_sn);
27862ec5a8c1SNicholas Bellinger 	hdr->offset		= cpu_to_be32(datain->offset);
27872ec5a8c1SNicholas Bellinger 
27882ec5a8c1SNicholas Bellinger 	pr_debug("Built DataIN ITT: 0x%08x, StatSN: 0x%08x,"
27892ec5a8c1SNicholas Bellinger 		" DataSN: 0x%08x, Offset: %u, Length: %u, CID: %hu\n",
27902ec5a8c1SNicholas Bellinger 		cmd->init_task_tag, ntohl(hdr->statsn), ntohl(hdr->datasn),
27912ec5a8c1SNicholas Bellinger 		ntohl(hdr->offset), datain->length, conn->cid);
27922ec5a8c1SNicholas Bellinger }
2793d2faaefbSVarun Prakash EXPORT_SYMBOL(iscsit_build_datain_pdu);
27942ec5a8c1SNicholas Bellinger 
27952ec5a8c1SNicholas Bellinger static int iscsit_send_datain(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
27962ec5a8c1SNicholas Bellinger {
27972ec5a8c1SNicholas Bellinger 	struct iscsi_data_rsp *hdr = (struct iscsi_data_rsp *)&cmd->pdu[0];
2798e48354ceSNicholas Bellinger 	struct iscsi_datain datain;
2799e48354ceSNicholas Bellinger 	struct iscsi_datain_req *dr;
28002854bb23SVarun Prakash 	int eodr = 0, ret;
28012ec5a8c1SNicholas Bellinger 	bool set_statsn = false;
2802e48354ceSNicholas Bellinger 
2803e48354ceSNicholas Bellinger 	memset(&datain, 0, sizeof(struct iscsi_datain));
2804e48354ceSNicholas Bellinger 	dr = iscsit_get_datain_values(cmd, &datain);
2805e48354ceSNicholas Bellinger 	if (!dr) {
2806e48354ceSNicholas Bellinger 		pr_err("iscsit_get_datain_values failed for ITT: 0x%08x\n",
2807e48354ceSNicholas Bellinger 				cmd->init_task_tag);
2808e48354ceSNicholas Bellinger 		return -1;
2809e48354ceSNicholas Bellinger 	}
2810e48354ceSNicholas Bellinger 	/*
2811e48354ceSNicholas Bellinger 	 * Be paranoid and double check the logic for now.
2812e48354ceSNicholas Bellinger 	 */
2813ebf1d95cSAndy Grover 	if ((datain.offset + datain.length) > cmd->se_cmd.data_length) {
2814e48354ceSNicholas Bellinger 		pr_err("Command ITT: 0x%08x, datain.offset: %u and"
2815e48354ceSNicholas Bellinger 			" datain.length: %u exceeds cmd->data_length: %u\n",
2816e48354ceSNicholas Bellinger 			cmd->init_task_tag, datain.offset, datain.length,
2817ebf1d95cSAndy Grover 			cmd->se_cmd.data_length);
2818e48354ceSNicholas Bellinger 		return -1;
2819e48354ceSNicholas Bellinger 	}
2820e48354ceSNicholas Bellinger 
282104f3b31bSNicholas Bellinger 	atomic_long_add(datain.length, &conn->sess->tx_data_octets);
2822e48354ceSNicholas Bellinger 	/*
2823e48354ceSNicholas Bellinger 	 * Special case for successfully execution w/ both DATAIN
2824e48354ceSNicholas Bellinger 	 * and Sense Data.
2825e48354ceSNicholas Bellinger 	 */
2826e48354ceSNicholas Bellinger 	if ((datain.flags & ISCSI_FLAG_DATA_STATUS) &&
2827e48354ceSNicholas Bellinger 	    (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE))
2828e48354ceSNicholas Bellinger 		datain.flags &= ~ISCSI_FLAG_DATA_STATUS;
2829e48354ceSNicholas Bellinger 	else {
2830e48354ceSNicholas Bellinger 		if ((dr->dr_complete == DATAIN_COMPLETE_NORMAL) ||
2831e48354ceSNicholas Bellinger 		    (dr->dr_complete == DATAIN_COMPLETE_CONNECTION_RECOVERY)) {
2832e48354ceSNicholas Bellinger 			iscsit_increment_maxcmdsn(cmd, conn->sess);
2833e48354ceSNicholas Bellinger 			cmd->stat_sn = conn->stat_sn++;
28342ec5a8c1SNicholas Bellinger 			set_statsn = true;
2835e48354ceSNicholas Bellinger 		} else if (dr->dr_complete ==
2836e48354ceSNicholas Bellinger 			   DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY)
28372ec5a8c1SNicholas Bellinger 			set_statsn = true;
2838e48354ceSNicholas Bellinger 	}
2839e48354ceSNicholas Bellinger 
28402ec5a8c1SNicholas Bellinger 	iscsit_build_datain_pdu(cmd, conn, &datain, hdr, set_statsn);
2841e48354ceSNicholas Bellinger 
28422854bb23SVarun Prakash 	ret = conn->conn_transport->iscsit_xmit_pdu(conn, cmd, dr, &datain, 0);
28432854bb23SVarun Prakash 	if (ret < 0)
28446f3c0e69SAndy Grover 		return ret;
28456f3c0e69SAndy Grover 
2846e48354ceSNicholas Bellinger 	if (dr->dr_complete) {
28476f3c0e69SAndy Grover 		eodr = (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ?
2848e48354ceSNicholas Bellinger 				2 : 1;
2849e48354ceSNicholas Bellinger 		iscsit_free_datain_req(cmd, dr);
2850e48354ceSNicholas Bellinger 	}
2851e48354ceSNicholas Bellinger 
28526f3c0e69SAndy Grover 	return eodr;
2853e48354ceSNicholas Bellinger }
2854e48354ceSNicholas Bellinger 
28552ec5a8c1SNicholas Bellinger int
28562ec5a8c1SNicholas Bellinger iscsit_build_logout_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
28572ec5a8c1SNicholas Bellinger 			struct iscsi_logout_rsp *hdr)
2858e48354ceSNicholas Bellinger {
2859e48354ceSNicholas Bellinger 	struct iscsi_conn *logout_conn = NULL;
2860e48354ceSNicholas Bellinger 	struct iscsi_conn_recovery *cr = NULL;
2861e48354ceSNicholas Bellinger 	struct iscsi_session *sess = conn->sess;
2862e48354ceSNicholas Bellinger 	/*
2863e48354ceSNicholas Bellinger 	 * The actual shutting down of Sessions and/or Connections
2864e48354ceSNicholas Bellinger 	 * for CLOSESESSION and CLOSECONNECTION Logout Requests
2865e48354ceSNicholas Bellinger 	 * is done in scsi_logout_post_handler().
2866e48354ceSNicholas Bellinger 	 */
2867e48354ceSNicholas Bellinger 	switch (cmd->logout_reason) {
2868e48354ceSNicholas Bellinger 	case ISCSI_LOGOUT_REASON_CLOSE_SESSION:
2869e48354ceSNicholas Bellinger 		pr_debug("iSCSI session logout successful, setting"
2870e48354ceSNicholas Bellinger 			" logout response to ISCSI_LOGOUT_SUCCESS.\n");
2871e48354ceSNicholas Bellinger 		cmd->logout_response = ISCSI_LOGOUT_SUCCESS;
2872e48354ceSNicholas Bellinger 		break;
2873e48354ceSNicholas Bellinger 	case ISCSI_LOGOUT_REASON_CLOSE_CONNECTION:
2874e48354ceSNicholas Bellinger 		if (cmd->logout_response == ISCSI_LOGOUT_CID_NOT_FOUND)
2875e48354ceSNicholas Bellinger 			break;
2876e48354ceSNicholas Bellinger 		/*
2877e48354ceSNicholas Bellinger 		 * For CLOSECONNECTION logout requests carrying
2878e48354ceSNicholas Bellinger 		 * a matching logout CID -> local CID, the reference
2879e48354ceSNicholas Bellinger 		 * for the local CID will have been incremented in
2880e48354ceSNicholas Bellinger 		 * iscsi_logout_closeconnection().
2881e48354ceSNicholas Bellinger 		 *
2882e48354ceSNicholas Bellinger 		 * For CLOSECONNECTION logout requests carrying
2883e48354ceSNicholas Bellinger 		 * a different CID than the connection it arrived
2884e48354ceSNicholas Bellinger 		 * on, the connection responding to cmd->logout_cid
2885e48354ceSNicholas Bellinger 		 * is stopped in iscsit_logout_post_handler_diffcid().
2886e48354ceSNicholas Bellinger 		 */
2887e48354ceSNicholas Bellinger 
2888e48354ceSNicholas Bellinger 		pr_debug("iSCSI CID: %hu logout on CID: %hu"
2889e48354ceSNicholas Bellinger 			" successful.\n", cmd->logout_cid, conn->cid);
2890e48354ceSNicholas Bellinger 		cmd->logout_response = ISCSI_LOGOUT_SUCCESS;
2891e48354ceSNicholas Bellinger 		break;
2892e48354ceSNicholas Bellinger 	case ISCSI_LOGOUT_REASON_RECOVERY:
2893e48354ceSNicholas Bellinger 		if ((cmd->logout_response == ISCSI_LOGOUT_RECOVERY_UNSUPPORTED) ||
2894e48354ceSNicholas Bellinger 		    (cmd->logout_response == ISCSI_LOGOUT_CLEANUP_FAILED))
2895e48354ceSNicholas Bellinger 			break;
2896e48354ceSNicholas Bellinger 		/*
2897e48354ceSNicholas Bellinger 		 * If the connection is still active from our point of view
2898e48354ceSNicholas Bellinger 		 * force connection recovery to occur.
2899e48354ceSNicholas Bellinger 		 */
2900e48354ceSNicholas Bellinger 		logout_conn = iscsit_get_conn_from_cid_rcfr(sess,
2901e48354ceSNicholas Bellinger 				cmd->logout_cid);
2902ee1b1b9cSAndy Grover 		if (logout_conn) {
2903e48354ceSNicholas Bellinger 			iscsit_connection_reinstatement_rcfr(logout_conn);
2904e48354ceSNicholas Bellinger 			iscsit_dec_conn_usage_count(logout_conn);
2905e48354ceSNicholas Bellinger 		}
2906e48354ceSNicholas Bellinger 
2907e48354ceSNicholas Bellinger 		cr = iscsit_get_inactive_connection_recovery_entry(
2908e48354ceSNicholas Bellinger 				conn->sess, cmd->logout_cid);
2909e48354ceSNicholas Bellinger 		if (!cr) {
2910e48354ceSNicholas Bellinger 			pr_err("Unable to locate CID: %hu for"
2911e48354ceSNicholas Bellinger 			" REMOVECONNFORRECOVERY Logout Request.\n",
2912e48354ceSNicholas Bellinger 				cmd->logout_cid);
2913e48354ceSNicholas Bellinger 			cmd->logout_response = ISCSI_LOGOUT_CID_NOT_FOUND;
2914e48354ceSNicholas Bellinger 			break;
2915e48354ceSNicholas Bellinger 		}
2916e48354ceSNicholas Bellinger 
2917e48354ceSNicholas Bellinger 		iscsit_discard_cr_cmds_by_expstatsn(cr, cmd->exp_stat_sn);
2918e48354ceSNicholas Bellinger 
2919e48354ceSNicholas Bellinger 		pr_debug("iSCSI REMOVECONNFORRECOVERY logout"
2920e48354ceSNicholas Bellinger 			" for recovery for CID: %hu on CID: %hu successful.\n",
2921e48354ceSNicholas Bellinger 				cmd->logout_cid, conn->cid);
2922e48354ceSNicholas Bellinger 		cmd->logout_response = ISCSI_LOGOUT_SUCCESS;
2923e48354ceSNicholas Bellinger 		break;
2924e48354ceSNicholas Bellinger 	default:
2925e48354ceSNicholas Bellinger 		pr_err("Unknown cmd->logout_reason: 0x%02x\n",
2926e48354ceSNicholas Bellinger 				cmd->logout_reason);
2927e48354ceSNicholas Bellinger 		return -1;
2928e48354ceSNicholas Bellinger 	}
2929e48354ceSNicholas Bellinger 
2930e48354ceSNicholas Bellinger 	hdr->opcode		= ISCSI_OP_LOGOUT_RSP;
2931e48354ceSNicholas Bellinger 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
2932e48354ceSNicholas Bellinger 	hdr->response		= cmd->logout_response;
293366c7db68SChristoph Hellwig 	hdr->itt		= cmd->init_task_tag;
2934e48354ceSNicholas Bellinger 	cmd->stat_sn		= conn->stat_sn++;
2935e48354ceSNicholas Bellinger 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
2936e48354ceSNicholas Bellinger 
2937e48354ceSNicholas Bellinger 	iscsit_increment_maxcmdsn(cmd, conn->sess);
2938e48354ceSNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
2939109e2381SRoland Dreier 	hdr->max_cmdsn		= cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
2940e48354ceSNicholas Bellinger 
29412ec5a8c1SNicholas Bellinger 	pr_debug("Built Logout Response ITT: 0x%08x StatSN:"
29422ec5a8c1SNicholas Bellinger 		" 0x%08x Response: 0x%02x CID: %hu on CID: %hu\n",
29432ec5a8c1SNicholas Bellinger 		cmd->init_task_tag, cmd->stat_sn, hdr->response,
29442ec5a8c1SNicholas Bellinger 		cmd->logout_cid, conn->cid);
29452ec5a8c1SNicholas Bellinger 
29462ec5a8c1SNicholas Bellinger 	return 0;
29472ec5a8c1SNicholas Bellinger }
29482ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_logout_rsp);
29492ec5a8c1SNicholas Bellinger 
29502ec5a8c1SNicholas Bellinger static int
29512ec5a8c1SNicholas Bellinger iscsit_send_logout(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
29522ec5a8c1SNicholas Bellinger {
29532854bb23SVarun Prakash 	int rc;
29542ec5a8c1SNicholas Bellinger 
29552ec5a8c1SNicholas Bellinger 	rc = iscsit_build_logout_rsp(cmd, conn,
29562ec5a8c1SNicholas Bellinger 			(struct iscsi_logout_rsp *)&cmd->pdu[0]);
29572ec5a8c1SNicholas Bellinger 	if (rc < 0)
29582ec5a8c1SNicholas Bellinger 		return rc;
29592ec5a8c1SNicholas Bellinger 
29602854bb23SVarun Prakash 	return conn->conn_transport->iscsit_xmit_pdu(conn, cmd, NULL, NULL, 0);
2961e48354ceSNicholas Bellinger }
2962e48354ceSNicholas Bellinger 
29632ec5a8c1SNicholas Bellinger void
29642ec5a8c1SNicholas Bellinger iscsit_build_nopin_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
29652ec5a8c1SNicholas Bellinger 		       struct iscsi_nopin *hdr, bool nopout_response)
29662ec5a8c1SNicholas Bellinger {
29672ec5a8c1SNicholas Bellinger 	hdr->opcode		= ISCSI_OP_NOOP_IN;
29682ec5a8c1SNicholas Bellinger 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
29692ec5a8c1SNicholas Bellinger         hton24(hdr->dlength, cmd->buf_ptr_size);
29702ec5a8c1SNicholas Bellinger 	if (nopout_response)
29712ec5a8c1SNicholas Bellinger 		put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);
29722ec5a8c1SNicholas Bellinger 	hdr->itt		= cmd->init_task_tag;
29732ec5a8c1SNicholas Bellinger 	hdr->ttt		= cpu_to_be32(cmd->targ_xfer_tag);
29742ec5a8c1SNicholas Bellinger 	cmd->stat_sn		= (nopout_response) ? conn->stat_sn++ :
29752ec5a8c1SNicholas Bellinger 				  conn->stat_sn;
29762ec5a8c1SNicholas Bellinger 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
29772ec5a8c1SNicholas Bellinger 
29782ec5a8c1SNicholas Bellinger 	if (nopout_response)
29792ec5a8c1SNicholas Bellinger 		iscsit_increment_maxcmdsn(cmd, conn->sess);
29802ec5a8c1SNicholas Bellinger 
29812ec5a8c1SNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
2982109e2381SRoland Dreier 	hdr->max_cmdsn		= cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
29832ec5a8c1SNicholas Bellinger 
29842ec5a8c1SNicholas Bellinger 	pr_debug("Built NOPIN %s Response ITT: 0x%08x, TTT: 0x%08x,"
29852ec5a8c1SNicholas Bellinger 		" StatSN: 0x%08x, Length %u\n", (nopout_response) ?
29863fc6a642SColin Ian King 		"Solicited" : "Unsolicited", cmd->init_task_tag,
29872ec5a8c1SNicholas Bellinger 		cmd->targ_xfer_tag, cmd->stat_sn, cmd->buf_ptr_size);
29882ec5a8c1SNicholas Bellinger }
29892ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_nopin_rsp);
29902ec5a8c1SNicholas Bellinger 
2991e48354ceSNicholas Bellinger /*
2992e48354ceSNicholas Bellinger  *	Unsolicited NOPIN, either requesting a response or not.
2993e48354ceSNicholas Bellinger  */
2994e48354ceSNicholas Bellinger static int iscsit_send_unsolicited_nopin(
2995e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd,
2996e48354ceSNicholas Bellinger 	struct iscsi_conn *conn,
2997e48354ceSNicholas Bellinger 	int want_response)
2998e48354ceSNicholas Bellinger {
29992ec5a8c1SNicholas Bellinger 	struct iscsi_nopin *hdr = (struct iscsi_nopin *)&cmd->pdu[0];
30002854bb23SVarun Prakash 	int ret;
3001e48354ceSNicholas Bellinger 
30022ec5a8c1SNicholas Bellinger 	iscsit_build_nopin_rsp(cmd, conn, hdr, false);
3003e48354ceSNicholas Bellinger 
3004e48354ceSNicholas Bellinger 	pr_debug("Sending Unsolicited NOPIN TTT: 0x%08x StatSN:"
3005e48354ceSNicholas Bellinger 		" 0x%08x CID: %hu\n", hdr->ttt, cmd->stat_sn, conn->cid);
3006e48354ceSNicholas Bellinger 
30072854bb23SVarun Prakash 	ret = conn->conn_transport->iscsit_xmit_pdu(conn, cmd, NULL, NULL, 0);
30082854bb23SVarun Prakash 	if (ret < 0)
30096f3c0e69SAndy Grover 		return ret;
30106f3c0e69SAndy Grover 
30116f3c0e69SAndy Grover 	spin_lock_bh(&cmd->istate_lock);
30126f3c0e69SAndy Grover 	cmd->i_state = want_response ?
30136f3c0e69SAndy Grover 		ISTATE_SENT_NOPIN_WANT_RESPONSE : ISTATE_SENT_STATUS;
30146f3c0e69SAndy Grover 	spin_unlock_bh(&cmd->istate_lock);
30156f3c0e69SAndy Grover 
3016e48354ceSNicholas Bellinger 	return 0;
3017e48354ceSNicholas Bellinger }
3018e48354ceSNicholas Bellinger 
30192ec5a8c1SNicholas Bellinger static int
30202ec5a8c1SNicholas Bellinger iscsit_send_nopin(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
3021e48354ceSNicholas Bellinger {
30222ec5a8c1SNicholas Bellinger 	struct iscsi_nopin *hdr = (struct iscsi_nopin *)&cmd->pdu[0];
30232ec5a8c1SNicholas Bellinger 
30242ec5a8c1SNicholas Bellinger 	iscsit_build_nopin_rsp(cmd, conn, hdr, true);
3025e48354ceSNicholas Bellinger 
3026e48354ceSNicholas Bellinger 	/*
3027e48354ceSNicholas Bellinger 	 * NOPOUT Ping Data is attached to struct iscsi_cmd->buf_ptr.
3028e48354ceSNicholas Bellinger 	 * NOPOUT DataSegmentLength is at struct iscsi_cmd->buf_ptr_size.
3029e48354ceSNicholas Bellinger 	 */
30302854bb23SVarun Prakash 	pr_debug("Echoing back %u bytes of ping data.\n", cmd->buf_ptr_size);
3031e48354ceSNicholas Bellinger 
30322854bb23SVarun Prakash 	return conn->conn_transport->iscsit_xmit_pdu(conn, cmd, NULL,
30332854bb23SVarun Prakash 						     cmd->buf_ptr,
30342854bb23SVarun Prakash 						     cmd->buf_ptr_size);
3035e48354ceSNicholas Bellinger }
3036e48354ceSNicholas Bellinger 
30376f3c0e69SAndy Grover static int iscsit_send_r2t(
3038e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd,
3039e48354ceSNicholas Bellinger 	struct iscsi_conn *conn)
3040e48354ceSNicholas Bellinger {
3041e48354ceSNicholas Bellinger 	struct iscsi_r2t *r2t;
3042e48354ceSNicholas Bellinger 	struct iscsi_r2t_rsp *hdr;
30436f3c0e69SAndy Grover 	int ret;
3044e48354ceSNicholas Bellinger 
3045e48354ceSNicholas Bellinger 	r2t = iscsit_get_r2t_from_list(cmd);
3046e48354ceSNicholas Bellinger 	if (!r2t)
3047e48354ceSNicholas Bellinger 		return -1;
3048e48354ceSNicholas Bellinger 
3049e48354ceSNicholas Bellinger 	hdr			= (struct iscsi_r2t_rsp *) cmd->pdu;
3050e48354ceSNicholas Bellinger 	memset(hdr, 0, ISCSI_HDR_LEN);
3051e48354ceSNicholas Bellinger 	hdr->opcode		= ISCSI_OP_R2T;
3052e48354ceSNicholas Bellinger 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
3053e48354ceSNicholas Bellinger 	int_to_scsilun(cmd->se_cmd.orig_fe_lun,
3054e48354ceSNicholas Bellinger 			(struct scsi_lun *)&hdr->lun);
305566c7db68SChristoph Hellwig 	hdr->itt		= cmd->init_task_tag;
30568567270dSVarun Prakash 	if (conn->conn_transport->iscsit_get_r2t_ttt)
30578567270dSVarun Prakash 		conn->conn_transport->iscsit_get_r2t_ttt(conn, cmd, r2t);
30588567270dSVarun Prakash 	else
3059c1e34b64SSagi Grimberg 		r2t->targ_xfer_tag = session_get_next_ttt(conn->sess);
3060e48354ceSNicholas Bellinger 	hdr->ttt		= cpu_to_be32(r2t->targ_xfer_tag);
3061e48354ceSNicholas Bellinger 	hdr->statsn		= cpu_to_be32(conn->stat_sn);
3062e48354ceSNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
3063109e2381SRoland Dreier 	hdr->max_cmdsn		= cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
3064e48354ceSNicholas Bellinger 	hdr->r2tsn		= cpu_to_be32(r2t->r2t_sn);
3065e48354ceSNicholas Bellinger 	hdr->data_offset	= cpu_to_be32(r2t->offset);
3066e48354ceSNicholas Bellinger 	hdr->data_length	= cpu_to_be32(r2t->xfer_len);
3067e48354ceSNicholas Bellinger 
3068e48354ceSNicholas Bellinger 	pr_debug("Built %sR2T, ITT: 0x%08x, TTT: 0x%08x, StatSN:"
3069e48354ceSNicholas Bellinger 		" 0x%08x, R2TSN: 0x%08x, Offset: %u, DDTL: %u, CID: %hu\n",
3070e48354ceSNicholas Bellinger 		(!r2t->recovery_r2t) ? "" : "Recovery ", cmd->init_task_tag,
3071e48354ceSNicholas Bellinger 		r2t->targ_xfer_tag, ntohl(hdr->statsn), r2t->r2t_sn,
3072e48354ceSNicholas Bellinger 			r2t->offset, r2t->xfer_len, conn->cid);
3073e48354ceSNicholas Bellinger 
3074e48354ceSNicholas Bellinger 	spin_lock_bh(&cmd->r2t_lock);
3075e48354ceSNicholas Bellinger 	r2t->sent_r2t = 1;
3076e48354ceSNicholas Bellinger 	spin_unlock_bh(&cmd->r2t_lock);
3077e48354ceSNicholas Bellinger 
30782854bb23SVarun Prakash 	ret = conn->conn_transport->iscsit_xmit_pdu(conn, cmd, NULL, NULL, 0);
30796f3c0e69SAndy Grover 	if (ret < 0) {
30806f3c0e69SAndy Grover 		return ret;
30816f3c0e69SAndy Grover 	}
30826f3c0e69SAndy Grover 
30836f3c0e69SAndy Grover 	spin_lock_bh(&cmd->dataout_timeout_lock);
30846f3c0e69SAndy Grover 	iscsit_start_dataout_timer(cmd, conn);
30856f3c0e69SAndy Grover 	spin_unlock_bh(&cmd->dataout_timeout_lock);
30866f3c0e69SAndy Grover 
3087e48354ceSNicholas Bellinger 	return 0;
3088e48354ceSNicholas Bellinger }
3089e48354ceSNicholas Bellinger 
3090e48354ceSNicholas Bellinger /*
30918b1e1244SAndy Grover  *	@recovery: If called from iscsi_task_reassign_complete_write() for
3092e48354ceSNicholas Bellinger  *		connection recovery.
3093e48354ceSNicholas Bellinger  */
3094e48354ceSNicholas Bellinger int iscsit_build_r2ts_for_cmd(
3095e48354ceSNicholas Bellinger 	struct iscsi_conn *conn,
30963e1c81a9SNicholas Bellinger 	struct iscsi_cmd *cmd,
30978b1e1244SAndy Grover 	bool recovery)
3098e48354ceSNicholas Bellinger {
3099e48354ceSNicholas Bellinger 	int first_r2t = 1;
3100e48354ceSNicholas Bellinger 	u32 offset = 0, xfer_len = 0;
3101e48354ceSNicholas Bellinger 
3102e48354ceSNicholas Bellinger 	spin_lock_bh(&cmd->r2t_lock);
3103e48354ceSNicholas Bellinger 	if (cmd->cmd_flags & ICF_SENT_LAST_R2T) {
3104e48354ceSNicholas Bellinger 		spin_unlock_bh(&cmd->r2t_lock);
3105e48354ceSNicholas Bellinger 		return 0;
3106e48354ceSNicholas Bellinger 	}
3107e48354ceSNicholas Bellinger 
31088b1e1244SAndy Grover 	if (conn->sess->sess_ops->DataSequenceInOrder &&
31098b1e1244SAndy Grover 	    !recovery)
3110c6037cc5SAndy Grover 		cmd->r2t_offset = max(cmd->r2t_offset, cmd->write_data_done);
3111e48354ceSNicholas Bellinger 
3112e48354ceSNicholas Bellinger 	while (cmd->outstanding_r2ts < conn->sess->sess_ops->MaxOutstandingR2T) {
3113e48354ceSNicholas Bellinger 		if (conn->sess->sess_ops->DataSequenceInOrder) {
3114e48354ceSNicholas Bellinger 			offset = cmd->r2t_offset;
3115e48354ceSNicholas Bellinger 
31168b1e1244SAndy Grover 			if (first_r2t && recovery) {
31178b1e1244SAndy Grover 				int new_data_end = offset +
31188b1e1244SAndy Grover 					conn->sess->sess_ops->MaxBurstLength -
31198b1e1244SAndy Grover 					cmd->next_burst_len;
31208b1e1244SAndy Grover 
3121ebf1d95cSAndy Grover 				if (new_data_end > cmd->se_cmd.data_length)
3122ebf1d95cSAndy Grover 					xfer_len = cmd->se_cmd.data_length - offset;
31238b1e1244SAndy Grover 				else
31248b1e1244SAndy Grover 					xfer_len =
31258b1e1244SAndy Grover 						conn->sess->sess_ops->MaxBurstLength -
31268b1e1244SAndy Grover 						cmd->next_burst_len;
3127e48354ceSNicholas Bellinger 			} else {
31288b1e1244SAndy Grover 				int new_data_end = offset +
3129e48354ceSNicholas Bellinger 					conn->sess->sess_ops->MaxBurstLength;
31308b1e1244SAndy Grover 
3131ebf1d95cSAndy Grover 				if (new_data_end > cmd->se_cmd.data_length)
3132ebf1d95cSAndy Grover 					xfer_len = cmd->se_cmd.data_length - offset;
31338b1e1244SAndy Grover 				else
31348b1e1244SAndy Grover 					xfer_len = conn->sess->sess_ops->MaxBurstLength;
3135e48354ceSNicholas Bellinger 			}
3136e48354ceSNicholas Bellinger 			cmd->r2t_offset += xfer_len;
3137e48354ceSNicholas Bellinger 
3138ebf1d95cSAndy Grover 			if (cmd->r2t_offset == cmd->se_cmd.data_length)
3139e48354ceSNicholas Bellinger 				cmd->cmd_flags |= ICF_SENT_LAST_R2T;
3140e48354ceSNicholas Bellinger 		} else {
3141e48354ceSNicholas Bellinger 			struct iscsi_seq *seq;
3142e48354ceSNicholas Bellinger 
3143e48354ceSNicholas Bellinger 			seq = iscsit_get_seq_holder_for_r2t(cmd);
3144e48354ceSNicholas Bellinger 			if (!seq) {
3145e48354ceSNicholas Bellinger 				spin_unlock_bh(&cmd->r2t_lock);
3146e48354ceSNicholas Bellinger 				return -1;
3147e48354ceSNicholas Bellinger 			}
3148e48354ceSNicholas Bellinger 
3149e48354ceSNicholas Bellinger 			offset = seq->offset;
3150e48354ceSNicholas Bellinger 			xfer_len = seq->xfer_len;
3151e48354ceSNicholas Bellinger 
3152e48354ceSNicholas Bellinger 			if (cmd->seq_send_order == cmd->seq_count)
3153e48354ceSNicholas Bellinger 				cmd->cmd_flags |= ICF_SENT_LAST_R2T;
3154e48354ceSNicholas Bellinger 		}
3155e48354ceSNicholas Bellinger 		cmd->outstanding_r2ts++;
3156e48354ceSNicholas Bellinger 		first_r2t = 0;
3157e48354ceSNicholas Bellinger 
3158e48354ceSNicholas Bellinger 		if (iscsit_add_r2t_to_list(cmd, offset, xfer_len, 0, 0) < 0) {
3159e48354ceSNicholas Bellinger 			spin_unlock_bh(&cmd->r2t_lock);
3160e48354ceSNicholas Bellinger 			return -1;
3161e48354ceSNicholas Bellinger 		}
3162e48354ceSNicholas Bellinger 
3163e48354ceSNicholas Bellinger 		if (cmd->cmd_flags & ICF_SENT_LAST_R2T)
3164e48354ceSNicholas Bellinger 			break;
3165e48354ceSNicholas Bellinger 	}
3166e48354ceSNicholas Bellinger 	spin_unlock_bh(&cmd->r2t_lock);
3167e48354ceSNicholas Bellinger 
3168e48354ceSNicholas Bellinger 	return 0;
3169e48354ceSNicholas Bellinger }
3170d2faaefbSVarun Prakash EXPORT_SYMBOL(iscsit_build_r2ts_for_cmd);
3171e48354ceSNicholas Bellinger 
31722ec5a8c1SNicholas Bellinger void iscsit_build_rsp_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
31732ec5a8c1SNicholas Bellinger 			bool inc_stat_sn, struct iscsi_scsi_rsp *hdr)
3174e48354ceSNicholas Bellinger {
31752ec5a8c1SNicholas Bellinger 	if (inc_stat_sn)
3176e48354ceSNicholas Bellinger 		cmd->stat_sn = conn->stat_sn++;
3177e48354ceSNicholas Bellinger 
317804f3b31bSNicholas Bellinger 	atomic_long_inc(&conn->sess->rsp_pdus);
3179e48354ceSNicholas Bellinger 
3180e48354ceSNicholas Bellinger 	memset(hdr, 0, ISCSI_HDR_LEN);
3181e48354ceSNicholas Bellinger 	hdr->opcode		= ISCSI_OP_SCSI_CMD_RSP;
3182e48354ceSNicholas Bellinger 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
3183e48354ceSNicholas Bellinger 	if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) {
3184e48354ceSNicholas Bellinger 		hdr->flags |= ISCSI_FLAG_CMD_OVERFLOW;
31857e46cf02SNicholas Bellinger 		hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
3186e48354ceSNicholas Bellinger 	} else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) {
3187e48354ceSNicholas Bellinger 		hdr->flags |= ISCSI_FLAG_CMD_UNDERFLOW;
31887e46cf02SNicholas Bellinger 		hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
3189e48354ceSNicholas Bellinger 	}
3190e48354ceSNicholas Bellinger 	hdr->response		= cmd->iscsi_response;
3191e48354ceSNicholas Bellinger 	hdr->cmd_status		= cmd->se_cmd.scsi_status;
319266c7db68SChristoph Hellwig 	hdr->itt		= cmd->init_task_tag;
3193e48354ceSNicholas Bellinger 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
3194e48354ceSNicholas Bellinger 
3195e48354ceSNicholas Bellinger 	iscsit_increment_maxcmdsn(cmd, conn->sess);
3196e48354ceSNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
3197109e2381SRoland Dreier 	hdr->max_cmdsn		= cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
3198e48354ceSNicholas Bellinger 
31992ec5a8c1SNicholas Bellinger 	pr_debug("Built SCSI Response, ITT: 0x%08x, StatSN: 0x%08x,"
32002ec5a8c1SNicholas Bellinger 		" Response: 0x%02x, SAM Status: 0x%02x, CID: %hu\n",
32012ec5a8c1SNicholas Bellinger 		cmd->init_task_tag, cmd->stat_sn, cmd->se_cmd.scsi_status,
32022ec5a8c1SNicholas Bellinger 		cmd->se_cmd.scsi_status, conn->cid);
32032ec5a8c1SNicholas Bellinger }
32042ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_rsp_pdu);
32052ec5a8c1SNicholas Bellinger 
32062ec5a8c1SNicholas Bellinger static int iscsit_send_response(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
32072ec5a8c1SNicholas Bellinger {
32082ec5a8c1SNicholas Bellinger 	struct iscsi_scsi_rsp *hdr = (struct iscsi_scsi_rsp *)&cmd->pdu[0];
32092ec5a8c1SNicholas Bellinger 	bool inc_stat_sn = (cmd->i_state == ISTATE_SEND_STATUS);
32102854bb23SVarun Prakash 	void *data_buf = NULL;
32112854bb23SVarun Prakash 	u32 padding = 0, data_buf_len = 0;
32122ec5a8c1SNicholas Bellinger 
32132ec5a8c1SNicholas Bellinger 	iscsit_build_rsp_pdu(cmd, conn, inc_stat_sn, hdr);
32142ec5a8c1SNicholas Bellinger 
3215e48354ceSNicholas Bellinger 	/*
3216e48354ceSNicholas Bellinger 	 * Attach SENSE DATA payload to iSCSI Response PDU
3217e48354ceSNicholas Bellinger 	 */
3218e48354ceSNicholas Bellinger 	if (cmd->se_cmd.sense_buffer &&
3219e48354ceSNicholas Bellinger 	   ((cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||
3220e48354ceSNicholas Bellinger 	    (cmd->se_cmd.se_cmd_flags & SCF_EMULATED_TASK_SENSE))) {
32219c58b7ddSRoland Dreier 		put_unaligned_be16(cmd->se_cmd.scsi_sense_length, cmd->sense_buffer);
32229c58b7ddSRoland Dreier 		cmd->se_cmd.scsi_sense_length += sizeof (__be16);
32239c58b7ddSRoland Dreier 
3224e48354ceSNicholas Bellinger 		padding		= -(cmd->se_cmd.scsi_sense_length) & 3;
322550e5c87dSChristoph Hellwig 		hton24(hdr->dlength, (u32)cmd->se_cmd.scsi_sense_length);
32262854bb23SVarun Prakash 		data_buf = cmd->sense_buffer;
32272854bb23SVarun Prakash 		data_buf_len = cmd->se_cmd.scsi_sense_length + padding;
3228e48354ceSNicholas Bellinger 
3229e48354ceSNicholas Bellinger 		if (padding) {
32309c58b7ddSRoland Dreier 			memset(cmd->sense_buffer +
3231e48354ceSNicholas Bellinger 				cmd->se_cmd.scsi_sense_length, 0, padding);
3232e48354ceSNicholas Bellinger 			pr_debug("Adding %u bytes of padding to"
3233e48354ceSNicholas Bellinger 				" SENSE.\n", padding);
3234e48354ceSNicholas Bellinger 		}
3235e48354ceSNicholas Bellinger 
3236e48354ceSNicholas Bellinger 		pr_debug("Attaching SENSE DATA: %u bytes to iSCSI"
3237e48354ceSNicholas Bellinger 				" Response PDU\n",
3238e48354ceSNicholas Bellinger 				cmd->se_cmd.scsi_sense_length);
3239e48354ceSNicholas Bellinger 	}
3240e48354ceSNicholas Bellinger 
32412854bb23SVarun Prakash 	return conn->conn_transport->iscsit_xmit_pdu(conn, cmd, NULL, data_buf,
32422854bb23SVarun Prakash 						     data_buf_len);
3243e48354ceSNicholas Bellinger }
3244e48354ceSNicholas Bellinger 
3245e48354ceSNicholas Bellinger static u8 iscsit_convert_tcm_tmr_rsp(struct se_tmr_req *se_tmr)
3246e48354ceSNicholas Bellinger {
3247e48354ceSNicholas Bellinger 	switch (se_tmr->response) {
3248e48354ceSNicholas Bellinger 	case TMR_FUNCTION_COMPLETE:
3249e48354ceSNicholas Bellinger 		return ISCSI_TMF_RSP_COMPLETE;
3250e48354ceSNicholas Bellinger 	case TMR_TASK_DOES_NOT_EXIST:
3251e48354ceSNicholas Bellinger 		return ISCSI_TMF_RSP_NO_TASK;
3252e48354ceSNicholas Bellinger 	case TMR_LUN_DOES_NOT_EXIST:
3253e48354ceSNicholas Bellinger 		return ISCSI_TMF_RSP_NO_LUN;
3254e48354ceSNicholas Bellinger 	case TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED:
3255e48354ceSNicholas Bellinger 		return ISCSI_TMF_RSP_NOT_SUPPORTED;
3256e48354ceSNicholas Bellinger 	case TMR_FUNCTION_REJECTED:
3257e48354ceSNicholas Bellinger 	default:
3258e48354ceSNicholas Bellinger 		return ISCSI_TMF_RSP_REJECTED;
3259e48354ceSNicholas Bellinger 	}
3260e48354ceSNicholas Bellinger }
3261e48354ceSNicholas Bellinger 
32622ec5a8c1SNicholas Bellinger void
32632ec5a8c1SNicholas Bellinger iscsit_build_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
32642ec5a8c1SNicholas Bellinger 			  struct iscsi_tm_rsp *hdr)
3265e48354ceSNicholas Bellinger {
3266e48354ceSNicholas Bellinger 	struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
3267e48354ceSNicholas Bellinger 
3268e48354ceSNicholas Bellinger 	hdr->opcode		= ISCSI_OP_SCSI_TMFUNC_RSP;
32697ae0b103SNicholas Bellinger 	hdr->flags		= ISCSI_FLAG_CMD_FINAL;
3270e48354ceSNicholas Bellinger 	hdr->response		= iscsit_convert_tcm_tmr_rsp(se_tmr);
327166c7db68SChristoph Hellwig 	hdr->itt		= cmd->init_task_tag;
3272e48354ceSNicholas Bellinger 	cmd->stat_sn		= conn->stat_sn++;
3273e48354ceSNicholas Bellinger 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
3274e48354ceSNicholas Bellinger 
3275e48354ceSNicholas Bellinger 	iscsit_increment_maxcmdsn(cmd, conn->sess);
3276e48354ceSNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
3277109e2381SRoland Dreier 	hdr->max_cmdsn		= cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
3278e48354ceSNicholas Bellinger 
32792ec5a8c1SNicholas Bellinger 	pr_debug("Built Task Management Response ITT: 0x%08x,"
32802ec5a8c1SNicholas Bellinger 		" StatSN: 0x%08x, Response: 0x%02x, CID: %hu\n",
32812ec5a8c1SNicholas Bellinger 		cmd->init_task_tag, cmd->stat_sn, hdr->response, conn->cid);
32822ec5a8c1SNicholas Bellinger }
32832ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_task_mgt_rsp);
32842ec5a8c1SNicholas Bellinger 
32852ec5a8c1SNicholas Bellinger static int
32862ec5a8c1SNicholas Bellinger iscsit_send_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
32872ec5a8c1SNicholas Bellinger {
32882ec5a8c1SNicholas Bellinger 	struct iscsi_tm_rsp *hdr = (struct iscsi_tm_rsp *)&cmd->pdu[0];
32892ec5a8c1SNicholas Bellinger 
32902ec5a8c1SNicholas Bellinger 	iscsit_build_task_mgt_rsp(cmd, conn, hdr);
32912ec5a8c1SNicholas Bellinger 
32922854bb23SVarun Prakash 	return conn->conn_transport->iscsit_xmit_pdu(conn, cmd, NULL, NULL, 0);
3293e48354ceSNicholas Bellinger }
3294e48354ceSNicholas Bellinger 
32952f9bc894SNicholas Bellinger static bool iscsit_check_inaddr_any(struct iscsi_np *np)
32962f9bc894SNicholas Bellinger {
32972f9bc894SNicholas Bellinger 	bool ret = false;
32982f9bc894SNicholas Bellinger 
32992f9bc894SNicholas Bellinger 	if (np->np_sockaddr.ss_family == AF_INET6) {
33002f9bc894SNicholas Bellinger 		const struct sockaddr_in6 sin6 = {
33012f9bc894SNicholas Bellinger 			.sin6_addr = IN6ADDR_ANY_INIT };
33022f9bc894SNicholas Bellinger 		struct sockaddr_in6 *sock_in6 =
33032f9bc894SNicholas Bellinger 			 (struct sockaddr_in6 *)&np->np_sockaddr;
33042f9bc894SNicholas Bellinger 
33052f9bc894SNicholas Bellinger 		if (!memcmp(sock_in6->sin6_addr.s6_addr,
33062f9bc894SNicholas Bellinger 				sin6.sin6_addr.s6_addr, 16))
33072f9bc894SNicholas Bellinger 			ret = true;
33082f9bc894SNicholas Bellinger 	} else {
33092f9bc894SNicholas Bellinger 		struct sockaddr_in * sock_in =
33102f9bc894SNicholas Bellinger 			(struct sockaddr_in *)&np->np_sockaddr;
33112f9bc894SNicholas Bellinger 
3312cea0b4ceSChristoph Hellwig 		if (sock_in->sin_addr.s_addr == htonl(INADDR_ANY))
33132f9bc894SNicholas Bellinger 			ret = true;
33142f9bc894SNicholas Bellinger 	}
33152f9bc894SNicholas Bellinger 
33162f9bc894SNicholas Bellinger 	return ret;
33172f9bc894SNicholas Bellinger }
33182f9bc894SNicholas Bellinger 
33198b1e1244SAndy Grover #define SENDTARGETS_BUF_LIMIT 32768U
33208b1e1244SAndy Grover 
332122c7aaa5SSagi Grimberg static int
332222c7aaa5SSagi Grimberg iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
3323e4f4e801SSagi Grimberg 				  enum iscsit_transport_type network_transport,
3324e4f4e801SSagi Grimberg 				  int skip_bytes, bool *completed)
3325e48354ceSNicholas Bellinger {
3326e48354ceSNicholas Bellinger 	char *payload = NULL;
3327e48354ceSNicholas Bellinger 	struct iscsi_conn *conn = cmd->conn;
3328e48354ceSNicholas Bellinger 	struct iscsi_portal_group *tpg;
3329e48354ceSNicholas Bellinger 	struct iscsi_tiqn *tiqn;
3330e48354ceSNicholas Bellinger 	struct iscsi_tpg_np *tpg_np;
3331e48354ceSNicholas Bellinger 	int buffer_len, end_of_buf = 0, len = 0, payload_len = 0;
33322dd1d53fSThomas Glanzmann 	int target_name_printed;
33338b1e1244SAndy Grover 	unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */
33346665889cSNicholas Bellinger 	unsigned char *text_in = cmd->text_in_ptr, *text_ptr = NULL;
3335a6415cddSDavid Disseldorp 	bool active;
3336e48354ceSNicholas Bellinger 
3337be7dcfb6SSagi Grimberg 	buffer_len = min(conn->conn_ops->MaxRecvDataSegmentLength,
33388b1e1244SAndy Grover 			 SENDTARGETS_BUF_LIMIT);
3339e48354ceSNicholas Bellinger 
3340e48354ceSNicholas Bellinger 	payload = kzalloc(buffer_len, GFP_KERNEL);
3341e48354ceSNicholas Bellinger 	if (!payload) {
3342e48354ceSNicholas Bellinger 		pr_err("Unable to allocate memory for sendtargets"
3343e48354ceSNicholas Bellinger 				" response.\n");
3344e48354ceSNicholas Bellinger 		return -ENOMEM;
3345e48354ceSNicholas Bellinger 	}
33466665889cSNicholas Bellinger 	/*
33478060b8ddSAndy Grover 	 * Locate pointer to iqn./eui. string for ICF_SENDTARGETS_SINGLE
33486665889cSNicholas Bellinger 	 * explicit case..
33496665889cSNicholas Bellinger 	 */
33508060b8ddSAndy Grover 	if (cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) {
33516665889cSNicholas Bellinger 		text_ptr = strchr(text_in, '=');
33526665889cSNicholas Bellinger 		if (!text_ptr) {
33536665889cSNicholas Bellinger 			pr_err("Unable to locate '=' string in text_in:"
33546665889cSNicholas Bellinger 			       " %s\n", text_in);
33554f45d320SDan Carpenter 			kfree(payload);
33566665889cSNicholas Bellinger 			return -EINVAL;
33576665889cSNicholas Bellinger 		}
33586665889cSNicholas Bellinger 		/*
33596665889cSNicholas Bellinger 		 * Skip over '=' character..
33606665889cSNicholas Bellinger 		 */
33616665889cSNicholas Bellinger 		text_ptr += 1;
33626665889cSNicholas Bellinger 	}
3363e48354ceSNicholas Bellinger 
3364e48354ceSNicholas Bellinger 	spin_lock(&tiqn_lock);
3365e48354ceSNicholas Bellinger 	list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) {
33668060b8ddSAndy Grover 		if ((cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) &&
33676665889cSNicholas Bellinger 		     strcmp(tiqn->tiqn, text_ptr)) {
33686665889cSNicholas Bellinger 			continue;
33696665889cSNicholas Bellinger 		}
33706665889cSNicholas Bellinger 
33712dd1d53fSThomas Glanzmann 		target_name_printed = 0;
3372e48354ceSNicholas Bellinger 
3373e48354ceSNicholas Bellinger 		spin_lock(&tiqn->tiqn_tpg_lock);
3374e48354ceSNicholas Bellinger 		list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
3375e48354ceSNicholas Bellinger 
33762dd1d53fSThomas Glanzmann 			/* If demo_mode_discovery=0 and generate_node_acls=0
33772dd1d53fSThomas Glanzmann 			 * (demo mode dislabed) do not return
33782dd1d53fSThomas Glanzmann 			 * TargetName+TargetAddress unless a NodeACL exists.
33792dd1d53fSThomas Glanzmann 			 */
33802dd1d53fSThomas Glanzmann 
33812dd1d53fSThomas Glanzmann 			if ((tpg->tpg_attrib.generate_node_acls == 0) &&
33822dd1d53fSThomas Glanzmann 			    (tpg->tpg_attrib.demo_mode_discovery == 0) &&
338321aaa23bSNicholas Bellinger 			    (!target_tpg_has_node_acl(&tpg->tpg_se_tpg,
33842dd1d53fSThomas Glanzmann 				cmd->conn->sess->sess_ops->InitiatorName))) {
33852dd1d53fSThomas Glanzmann 				continue;
33862dd1d53fSThomas Glanzmann 			}
33872dd1d53fSThomas Glanzmann 
3388e48354ceSNicholas Bellinger 			spin_lock(&tpg->tpg_state_lock);
3389a6415cddSDavid Disseldorp 			active = (tpg->tpg_state == TPG_STATE_ACTIVE);
3390e48354ceSNicholas Bellinger 			spin_unlock(&tpg->tpg_state_lock);
3391a6415cddSDavid Disseldorp 
3392a6415cddSDavid Disseldorp 			if (!active && tpg->tpg_attrib.tpg_enabled_sendtargets)
3393e48354ceSNicholas Bellinger 				continue;
3394e48354ceSNicholas Bellinger 
3395e48354ceSNicholas Bellinger 			spin_lock(&tpg->tpg_np_lock);
3396e48354ceSNicholas Bellinger 			list_for_each_entry(tpg_np, &tpg->tpg_gnp_list,
3397e48354ceSNicholas Bellinger 						tpg_np_list) {
33982f9bc894SNicholas Bellinger 				struct iscsi_np *np = tpg_np->tpg_np;
33992f9bc894SNicholas Bellinger 				bool inaddr_any = iscsit_check_inaddr_any(np);
340013a3cf08SAndy Grover 				struct sockaddr_storage *sockaddr;
34012f9bc894SNicholas Bellinger 
340222c7aaa5SSagi Grimberg 				if (np->np_network_transport != network_transport)
340322c7aaa5SSagi Grimberg 					continue;
340422c7aaa5SSagi Grimberg 
34052dd1d53fSThomas Glanzmann 				if (!target_name_printed) {
34062dd1d53fSThomas Glanzmann 					len = sprintf(buf, "TargetName=%s",
34072dd1d53fSThomas Glanzmann 						      tiqn->tiqn);
34082dd1d53fSThomas Glanzmann 					len += 1;
34092dd1d53fSThomas Glanzmann 
34102dd1d53fSThomas Glanzmann 					if ((len + payload_len) > buffer_len) {
34112dd1d53fSThomas Glanzmann 						spin_unlock(&tpg->tpg_np_lock);
34122dd1d53fSThomas Glanzmann 						spin_unlock(&tiqn->tiqn_tpg_lock);
34132dd1d53fSThomas Glanzmann 						end_of_buf = 1;
34142dd1d53fSThomas Glanzmann 						goto eob;
34152dd1d53fSThomas Glanzmann 					}
3416e4f4e801SSagi Grimberg 
3417e4f4e801SSagi Grimberg 					if (skip_bytes && len <= skip_bytes) {
3418e4f4e801SSagi Grimberg 						skip_bytes -= len;
3419e4f4e801SSagi Grimberg 					} else {
34202dd1d53fSThomas Glanzmann 						memcpy(payload + payload_len, buf, len);
34212dd1d53fSThomas Glanzmann 						payload_len += len;
34222dd1d53fSThomas Glanzmann 						target_name_printed = 1;
3423e4f4e801SSagi Grimberg 						if (len > skip_bytes)
3424e4f4e801SSagi Grimberg 							skip_bytes = 0;
3425e4f4e801SSagi Grimberg 					}
34262dd1d53fSThomas Glanzmann 				}
34272dd1d53fSThomas Glanzmann 
342869d75574SAndy Grover 				if (inaddr_any)
342969d75574SAndy Grover 					sockaddr = &conn->local_sockaddr;
34301997e625SAndy Grover 				else
343169d75574SAndy Grover 					sockaddr = &np->np_sockaddr;
34321997e625SAndy Grover 
343376c28f1fSAndy Grover 				len = sprintf(buf, "TargetAddress="
343476c28f1fSAndy Grover 					      "%pISpc,%hu",
343569d75574SAndy Grover 					      sockaddr,
3436e48354ceSNicholas Bellinger 					      tpg->tpgt);
3437e48354ceSNicholas Bellinger 				len += 1;
3438e48354ceSNicholas Bellinger 
3439e48354ceSNicholas Bellinger 				if ((len + payload_len) > buffer_len) {
3440e48354ceSNicholas Bellinger 					spin_unlock(&tpg->tpg_np_lock);
3441e48354ceSNicholas Bellinger 					spin_unlock(&tiqn->tiqn_tpg_lock);
3442e48354ceSNicholas Bellinger 					end_of_buf = 1;
3443e48354ceSNicholas Bellinger 					goto eob;
3444e48354ceSNicholas Bellinger 				}
3445e4f4e801SSagi Grimberg 
3446e4f4e801SSagi Grimberg 				if (skip_bytes && len <= skip_bytes) {
3447e4f4e801SSagi Grimberg 					skip_bytes -= len;
3448e4f4e801SSagi Grimberg 				} else {
34498359cf43SJörn Engel 					memcpy(payload + payload_len, buf, len);
3450e48354ceSNicholas Bellinger 					payload_len += len;
3451e4f4e801SSagi Grimberg 					if (len > skip_bytes)
3452e4f4e801SSagi Grimberg 						skip_bytes = 0;
3453e4f4e801SSagi Grimberg 				}
3454e48354ceSNicholas Bellinger 			}
3455e48354ceSNicholas Bellinger 			spin_unlock(&tpg->tpg_np_lock);
3456e48354ceSNicholas Bellinger 		}
3457e48354ceSNicholas Bellinger 		spin_unlock(&tiqn->tiqn_tpg_lock);
3458e48354ceSNicholas Bellinger eob:
3459e4f4e801SSagi Grimberg 		if (end_of_buf) {
3460e4f4e801SSagi Grimberg 			*completed = false;
3461e48354ceSNicholas Bellinger 			break;
3462e4f4e801SSagi Grimberg 		}
34636665889cSNicholas Bellinger 
34648060b8ddSAndy Grover 		if (cmd->cmd_flags & ICF_SENDTARGETS_SINGLE)
34656665889cSNicholas Bellinger 			break;
3466e48354ceSNicholas Bellinger 	}
3467e48354ceSNicholas Bellinger 	spin_unlock(&tiqn_lock);
3468e48354ceSNicholas Bellinger 
3469e48354ceSNicholas Bellinger 	cmd->buf_ptr = payload;
3470e48354ceSNicholas Bellinger 
3471e48354ceSNicholas Bellinger 	return payload_len;
3472e48354ceSNicholas Bellinger }
3473e48354ceSNicholas Bellinger 
3474889c8a68SNicholas Bellinger int
3475889c8a68SNicholas Bellinger iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
347622c7aaa5SSagi Grimberg 		      struct iscsi_text_rsp *hdr,
347722c7aaa5SSagi Grimberg 		      enum iscsit_transport_type network_transport)
3478e48354ceSNicholas Bellinger {
3479889c8a68SNicholas Bellinger 	int text_length, padding;
3480e4f4e801SSagi Grimberg 	bool completed = true;
3481e48354ceSNicholas Bellinger 
3482e4f4e801SSagi Grimberg 	text_length = iscsit_build_sendtargets_response(cmd, network_transport,
3483e4f4e801SSagi Grimberg 							cmd->read_data_done,
3484e4f4e801SSagi Grimberg 							&completed);
3485e48354ceSNicholas Bellinger 	if (text_length < 0)
3486e48354ceSNicholas Bellinger 		return text_length;
3487e48354ceSNicholas Bellinger 
3488e4f4e801SSagi Grimberg 	if (completed) {
3489e48354ceSNicholas Bellinger 		hdr->flags |= ISCSI_FLAG_CMD_FINAL;
3490e4f4e801SSagi Grimberg 	} else {
3491e4f4e801SSagi Grimberg 		hdr->flags |= ISCSI_FLAG_TEXT_CONTINUE;
3492e4f4e801SSagi Grimberg 		cmd->read_data_done += text_length;
3493e4f4e801SSagi Grimberg 		if (cmd->targ_xfer_tag == 0xFFFFFFFF)
3494e4f4e801SSagi Grimberg 			cmd->targ_xfer_tag = session_get_next_ttt(conn->sess);
3495e4f4e801SSagi Grimberg 	}
3496e4f4e801SSagi Grimberg 	hdr->opcode = ISCSI_OP_TEXT_RSP;
3497889c8a68SNicholas Bellinger 	padding = ((-text_length) & 3);
3498e48354ceSNicholas Bellinger 	hton24(hdr->dlength, text_length);
349966c7db68SChristoph Hellwig 	hdr->itt = cmd->init_task_tag;
3500e48354ceSNicholas Bellinger 	hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
3501e48354ceSNicholas Bellinger 	cmd->stat_sn = conn->stat_sn++;
3502e48354ceSNicholas Bellinger 	hdr->statsn = cpu_to_be32(cmd->stat_sn);
3503e48354ceSNicholas Bellinger 
3504e48354ceSNicholas Bellinger 	iscsit_increment_maxcmdsn(cmd, conn->sess);
3505e4f4e801SSagi Grimberg 	/*
3506e4f4e801SSagi Grimberg 	 * Reset maxcmdsn_inc in multi-part text payload exchanges to
3507e4f4e801SSagi Grimberg 	 * correctly increment MaxCmdSN for each response answering a
3508e4f4e801SSagi Grimberg 	 * non immediate text request with a valid CmdSN.
3509e4f4e801SSagi Grimberg 	 */
3510e4f4e801SSagi Grimberg 	cmd->maxcmdsn_inc = 0;
3511e48354ceSNicholas Bellinger 	hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
3512109e2381SRoland Dreier 	hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
3513e48354ceSNicholas Bellinger 
3514e4f4e801SSagi Grimberg 	pr_debug("Built Text Response: ITT: 0x%08x, TTT: 0x%08x, StatSN: 0x%08x,"
3515e4f4e801SSagi Grimberg 		" Length: %u, CID: %hu F: %d C: %d\n", cmd->init_task_tag,
3516e4f4e801SSagi Grimberg 		cmd->targ_xfer_tag, cmd->stat_sn, text_length, conn->cid,
3517e4f4e801SSagi Grimberg 		!!(hdr->flags & ISCSI_FLAG_CMD_FINAL),
3518e4f4e801SSagi Grimberg 		!!(hdr->flags & ISCSI_FLAG_TEXT_CONTINUE));
3519e48354ceSNicholas Bellinger 
3520889c8a68SNicholas Bellinger 	return text_length + padding;
3521889c8a68SNicholas Bellinger }
3522889c8a68SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_text_rsp);
3523889c8a68SNicholas Bellinger 
3524889c8a68SNicholas Bellinger static int iscsit_send_text_rsp(
3525889c8a68SNicholas Bellinger 	struct iscsi_cmd *cmd,
3526889c8a68SNicholas Bellinger 	struct iscsi_conn *conn)
3527889c8a68SNicholas Bellinger {
3528889c8a68SNicholas Bellinger 	struct iscsi_text_rsp *hdr = (struct iscsi_text_rsp *)cmd->pdu;
35292854bb23SVarun Prakash 	int text_length;
3530889c8a68SNicholas Bellinger 
3531864e504aSVarun Prakash 	text_length = iscsit_build_text_rsp(cmd, conn, hdr,
3532864e504aSVarun Prakash 				conn->conn_transport->transport_type);
35332854bb23SVarun Prakash 	if (text_length < 0)
35342854bb23SVarun Prakash 		return text_length;
3535889c8a68SNicholas Bellinger 
35362854bb23SVarun Prakash 	return conn->conn_transport->iscsit_xmit_pdu(conn, cmd, NULL,
35372854bb23SVarun Prakash 						     cmd->buf_ptr,
35382854bb23SVarun Prakash 						     text_length);
3539e48354ceSNicholas Bellinger }
3540e48354ceSNicholas Bellinger 
35412ec5a8c1SNicholas Bellinger void
35422ec5a8c1SNicholas Bellinger iscsit_build_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
35432ec5a8c1SNicholas Bellinger 		    struct iscsi_reject *hdr)
3544e48354ceSNicholas Bellinger {
3545e48354ceSNicholas Bellinger 	hdr->opcode		= ISCSI_OP_REJECT;
3546ba159914SNicholas Bellinger 	hdr->reason		= cmd->reject_reason;
3547e48354ceSNicholas Bellinger 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
3548e48354ceSNicholas Bellinger 	hton24(hdr->dlength, ISCSI_HDR_LEN);
354950e5c87dSChristoph Hellwig 	hdr->ffffffff		= cpu_to_be32(0xffffffff);
3550e48354ceSNicholas Bellinger 	cmd->stat_sn		= conn->stat_sn++;
3551e48354ceSNicholas Bellinger 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
3552e48354ceSNicholas Bellinger 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
3553109e2381SRoland Dreier 	hdr->max_cmdsn		= cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
3554e48354ceSNicholas Bellinger 
35552ec5a8c1SNicholas Bellinger }
35562ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_reject);
3557e48354ceSNicholas Bellinger 
35582ec5a8c1SNicholas Bellinger static int iscsit_send_reject(
35592ec5a8c1SNicholas Bellinger 	struct iscsi_cmd *cmd,
35602ec5a8c1SNicholas Bellinger 	struct iscsi_conn *conn)
35612ec5a8c1SNicholas Bellinger {
3562bfbdb31dSNicholas Bellinger 	struct iscsi_reject *hdr = (struct iscsi_reject *)&cmd->pdu[0];
35632ec5a8c1SNicholas Bellinger 
3564bfbdb31dSNicholas Bellinger 	iscsit_build_reject(cmd, conn, hdr);
35652ec5a8c1SNicholas Bellinger 
3566e48354ceSNicholas Bellinger 	pr_debug("Built Reject PDU StatSN: 0x%08x, Reason: 0x%02x,"
3567e48354ceSNicholas Bellinger 		" CID: %hu\n", ntohl(hdr->statsn), hdr->reason, conn->cid);
3568e48354ceSNicholas Bellinger 
35692854bb23SVarun Prakash 	return conn->conn_transport->iscsit_xmit_pdu(conn, cmd, NULL,
35702854bb23SVarun Prakash 						     cmd->buf_ptr,
35712854bb23SVarun Prakash 						     ISCSI_HDR_LEN);
3572e48354ceSNicholas Bellinger }
3573e48354ceSNicholas Bellinger 
3574e48354ceSNicholas Bellinger void iscsit_thread_get_cpumask(struct iscsi_conn *conn)
3575e48354ceSNicholas Bellinger {
3576e48354ceSNicholas Bellinger 	int ord, cpu;
3577e48354ceSNicholas Bellinger 	/*
357888dcd2daSNicholas Bellinger 	 * bitmap_id is assigned from iscsit_global->ts_bitmap from
357988dcd2daSNicholas Bellinger 	 * within iscsit_start_kthreads()
3580e48354ceSNicholas Bellinger 	 *
358188dcd2daSNicholas Bellinger 	 * Here we use bitmap_id to determine which CPU that this
358288dcd2daSNicholas Bellinger 	 * iSCSI connection's RX/TX threads will be scheduled to
3583e48354ceSNicholas Bellinger 	 * execute upon.
3584e48354ceSNicholas Bellinger 	 */
358588dcd2daSNicholas Bellinger 	ord = conn->bitmap_id % cpumask_weight(cpu_online_mask);
3586e48354ceSNicholas Bellinger 	for_each_online_cpu(cpu) {
3587e48354ceSNicholas Bellinger 		if (ord-- == 0) {
3588e48354ceSNicholas Bellinger 			cpumask_set_cpu(cpu, conn->conn_cpumask);
3589e48354ceSNicholas Bellinger 			return;
3590e48354ceSNicholas Bellinger 		}
3591e48354ceSNicholas Bellinger 	}
3592e48354ceSNicholas Bellinger 	/*
3593e48354ceSNicholas Bellinger 	 * This should never be reached..
3594e48354ceSNicholas Bellinger 	 */
3595e48354ceSNicholas Bellinger 	dump_stack();
3596e48354ceSNicholas Bellinger 	cpumask_setall(conn->conn_cpumask);
3597e48354ceSNicholas Bellinger }
3598e48354ceSNicholas Bellinger 
3599d2faaefbSVarun Prakash int
36002ec5a8c1SNicholas Bellinger iscsit_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state)
3601e48354ceSNicholas Bellinger {
36022ec5a8c1SNicholas Bellinger 	int ret;
36032ec5a8c1SNicholas Bellinger 
36042ec5a8c1SNicholas Bellinger 	switch (state) {
36052ec5a8c1SNicholas Bellinger 	case ISTATE_SEND_R2T:
36062ec5a8c1SNicholas Bellinger 		ret = iscsit_send_r2t(cmd, conn);
36072ec5a8c1SNicholas Bellinger 		if (ret < 0)
36082ec5a8c1SNicholas Bellinger 			goto err;
36092ec5a8c1SNicholas Bellinger 		break;
36102ec5a8c1SNicholas Bellinger 	case ISTATE_REMOVE:
36112ec5a8c1SNicholas Bellinger 		spin_lock_bh(&conn->cmd_lock);
36125159d763SNicholas Bellinger 		list_del_init(&cmd->i_conn_node);
36132ec5a8c1SNicholas Bellinger 		spin_unlock_bh(&conn->cmd_lock);
36142ec5a8c1SNicholas Bellinger 
3615aafc9d15SNicholas Bellinger 		iscsit_free_cmd(cmd, false);
36162ec5a8c1SNicholas Bellinger 		break;
36172ec5a8c1SNicholas Bellinger 	case ISTATE_SEND_NOPIN_WANT_RESPONSE:
36182ec5a8c1SNicholas Bellinger 		iscsit_mod_nopin_response_timer(conn);
36192ec5a8c1SNicholas Bellinger 		ret = iscsit_send_unsolicited_nopin(cmd, conn, 1);
36202ec5a8c1SNicholas Bellinger 		if (ret < 0)
36212ec5a8c1SNicholas Bellinger 			goto err;
36222ec5a8c1SNicholas Bellinger 		break;
36232ec5a8c1SNicholas Bellinger 	case ISTATE_SEND_NOPIN_NO_RESPONSE:
36242ec5a8c1SNicholas Bellinger 		ret = iscsit_send_unsolicited_nopin(cmd, conn, 0);
36252ec5a8c1SNicholas Bellinger 		if (ret < 0)
36262ec5a8c1SNicholas Bellinger 			goto err;
36272ec5a8c1SNicholas Bellinger 		break;
36282ec5a8c1SNicholas Bellinger 	default:
36292ec5a8c1SNicholas Bellinger 		pr_err("Unknown Opcode: 0x%02x ITT:"
36302ec5a8c1SNicholas Bellinger 		       " 0x%08x, i_state: %d on CID: %hu\n",
36312ec5a8c1SNicholas Bellinger 		       cmd->iscsi_opcode, cmd->init_task_tag, state,
36322ec5a8c1SNicholas Bellinger 		       conn->cid);
36332ec5a8c1SNicholas Bellinger 		goto err;
36342ec5a8c1SNicholas Bellinger 	}
36352ec5a8c1SNicholas Bellinger 
36362ec5a8c1SNicholas Bellinger 	return 0;
36372ec5a8c1SNicholas Bellinger 
36382ec5a8c1SNicholas Bellinger err:
36392ec5a8c1SNicholas Bellinger 	return -1;
36402ec5a8c1SNicholas Bellinger }
3641d2faaefbSVarun Prakash EXPORT_SYMBOL(iscsit_immediate_queue);
36422ec5a8c1SNicholas Bellinger 
36432ec5a8c1SNicholas Bellinger static int
36442ec5a8c1SNicholas Bellinger iscsit_handle_immediate_queue(struct iscsi_conn *conn)
36452ec5a8c1SNicholas Bellinger {
36462ec5a8c1SNicholas Bellinger 	struct iscsit_transport *t = conn->conn_transport;
36476f3c0e69SAndy Grover 	struct iscsi_queue_req *qr;
36486f3c0e69SAndy Grover 	struct iscsi_cmd *cmd;
3649e48354ceSNicholas Bellinger 	u8 state;
36506f3c0e69SAndy Grover 	int ret;
3651e48354ceSNicholas Bellinger 
3652c6037cc5SAndy Grover 	while ((qr = iscsit_get_cmd_from_immediate_queue(conn))) {
3653e48354ceSNicholas Bellinger 		atomic_set(&conn->check_immediate_queue, 0);
3654e48354ceSNicholas Bellinger 		cmd = qr->cmd;
3655e48354ceSNicholas Bellinger 		state = qr->state;
3656e48354ceSNicholas Bellinger 		kmem_cache_free(lio_qr_cache, qr);
3657e48354ceSNicholas Bellinger 
36582ec5a8c1SNicholas Bellinger 		ret = t->iscsit_immediate_queue(conn, cmd, state);
36596f3c0e69SAndy Grover 		if (ret < 0)
36602ec5a8c1SNicholas Bellinger 			return ret;
3661e48354ceSNicholas Bellinger 	}
3662e48354ceSNicholas Bellinger 
36636f3c0e69SAndy Grover 	return 0;
3664e48354ceSNicholas Bellinger }
36656f3c0e69SAndy Grover 
3666d2faaefbSVarun Prakash int
36672ec5a8c1SNicholas Bellinger iscsit_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state)
36686f3c0e69SAndy Grover {
36696f3c0e69SAndy Grover 	int ret;
3670e48354ceSNicholas Bellinger 
3671e48354ceSNicholas Bellinger check_rsp_state:
3672e48354ceSNicholas Bellinger 	switch (state) {
3673e48354ceSNicholas Bellinger 	case ISTATE_SEND_DATAIN:
36742ec5a8c1SNicholas Bellinger 		ret = iscsit_send_datain(cmd, conn);
36756f3c0e69SAndy Grover 		if (ret < 0)
36766f3c0e69SAndy Grover 			goto err;
36776f3c0e69SAndy Grover 		else if (!ret)
36786f3c0e69SAndy Grover 			/* more drs */
36796f3c0e69SAndy Grover 			goto check_rsp_state;
36806f3c0e69SAndy Grover 		else if (ret == 1) {
36816f3c0e69SAndy Grover 			/* all done */
36826f3c0e69SAndy Grover 			spin_lock_bh(&cmd->istate_lock);
36836f3c0e69SAndy Grover 			cmd->i_state = ISTATE_SENT_STATUS;
3684e48354ceSNicholas Bellinger 			spin_unlock_bh(&cmd->istate_lock);
3685fd3a9025SNicholas Bellinger 
3686fd3a9025SNicholas Bellinger 			if (atomic_read(&conn->check_immediate_queue))
3687fd3a9025SNicholas Bellinger 				return 1;
3688fd3a9025SNicholas Bellinger 
36892ec5a8c1SNicholas Bellinger 			return 0;
36906f3c0e69SAndy Grover 		} else if (ret == 2) {
36916f3c0e69SAndy Grover 			/* Still must send status,
36926f3c0e69SAndy Grover 			   SCF_TRANSPORT_TASK_SENSE was set */
36936f3c0e69SAndy Grover 			spin_lock_bh(&cmd->istate_lock);
36946f3c0e69SAndy Grover 			cmd->i_state = ISTATE_SEND_STATUS;
36956f3c0e69SAndy Grover 			spin_unlock_bh(&cmd->istate_lock);
36966f3c0e69SAndy Grover 			state = ISTATE_SEND_STATUS;
36976f3c0e69SAndy Grover 			goto check_rsp_state;
36986f3c0e69SAndy Grover 		}
36996f3c0e69SAndy Grover 
3700e48354ceSNicholas Bellinger 		break;
3701e48354ceSNicholas Bellinger 	case ISTATE_SEND_STATUS:
3702e48354ceSNicholas Bellinger 	case ISTATE_SEND_STATUS_RECOVERY:
37032ec5a8c1SNicholas Bellinger 		ret = iscsit_send_response(cmd, conn);
3704e48354ceSNicholas Bellinger 		break;
3705e48354ceSNicholas Bellinger 	case ISTATE_SEND_LOGOUTRSP:
37062ec5a8c1SNicholas Bellinger 		ret = iscsit_send_logout(cmd, conn);
3707e48354ceSNicholas Bellinger 		break;
3708e48354ceSNicholas Bellinger 	case ISTATE_SEND_ASYNCMSG:
3709e48354ceSNicholas Bellinger 		ret = iscsit_send_conn_drop_async_message(
3710e48354ceSNicholas Bellinger 			cmd, conn);
3711e48354ceSNicholas Bellinger 		break;
3712e48354ceSNicholas Bellinger 	case ISTATE_SEND_NOPIN:
37132ec5a8c1SNicholas Bellinger 		ret = iscsit_send_nopin(cmd, conn);
3714e48354ceSNicholas Bellinger 		break;
3715e48354ceSNicholas Bellinger 	case ISTATE_SEND_REJECT:
3716e48354ceSNicholas Bellinger 		ret = iscsit_send_reject(cmd, conn);
3717e48354ceSNicholas Bellinger 		break;
3718e48354ceSNicholas Bellinger 	case ISTATE_SEND_TASKMGTRSP:
3719e48354ceSNicholas Bellinger 		ret = iscsit_send_task_mgt_rsp(cmd, conn);
3720e48354ceSNicholas Bellinger 		if (ret != 0)
3721e48354ceSNicholas Bellinger 			break;
3722e48354ceSNicholas Bellinger 		ret = iscsit_tmr_post_handler(cmd, conn);
3723e48354ceSNicholas Bellinger 		if (ret != 0)
3724e48354ceSNicholas Bellinger 			iscsit_fall_back_to_erl0(conn->sess);
3725e48354ceSNicholas Bellinger 		break;
3726e48354ceSNicholas Bellinger 	case ISTATE_SEND_TEXTRSP:
3727e48354ceSNicholas Bellinger 		ret = iscsit_send_text_rsp(cmd, conn);
3728e48354ceSNicholas Bellinger 		break;
3729e48354ceSNicholas Bellinger 	default:
3730e48354ceSNicholas Bellinger 		pr_err("Unknown Opcode: 0x%02x ITT:"
3731e48354ceSNicholas Bellinger 		       " 0x%08x, i_state: %d on CID: %hu\n",
3732e48354ceSNicholas Bellinger 		       cmd->iscsi_opcode, cmd->init_task_tag,
3733e48354ceSNicholas Bellinger 		       state, conn->cid);
37346f3c0e69SAndy Grover 		goto err;
3735e48354ceSNicholas Bellinger 	}
3736c6037cc5SAndy Grover 	if (ret < 0)
37376f3c0e69SAndy Grover 		goto err;
3738e48354ceSNicholas Bellinger 
3739e48354ceSNicholas Bellinger 	switch (state) {
37406f3c0e69SAndy Grover 	case ISTATE_SEND_LOGOUTRSP:
37416f3c0e69SAndy Grover 		if (!iscsit_logout_post_handler(cmd, conn))
374288dcd2daSNicholas Bellinger 			return -ECONNRESET;
37436f3c0e69SAndy Grover 		/* fall through */
3744e48354ceSNicholas Bellinger 	case ISTATE_SEND_STATUS:
3745e48354ceSNicholas Bellinger 	case ISTATE_SEND_ASYNCMSG:
3746e48354ceSNicholas Bellinger 	case ISTATE_SEND_NOPIN:
3747e48354ceSNicholas Bellinger 	case ISTATE_SEND_STATUS_RECOVERY:
3748e48354ceSNicholas Bellinger 	case ISTATE_SEND_TEXTRSP:
37496f3c0e69SAndy Grover 	case ISTATE_SEND_TASKMGTRSP:
3750ba159914SNicholas Bellinger 	case ISTATE_SEND_REJECT:
37516f3c0e69SAndy Grover 		spin_lock_bh(&cmd->istate_lock);
37526f3c0e69SAndy Grover 		cmd->i_state = ISTATE_SENT_STATUS;
37536f3c0e69SAndy Grover 		spin_unlock_bh(&cmd->istate_lock);
3754e48354ceSNicholas Bellinger 		break;
3755e48354ceSNicholas Bellinger 	default:
3756e48354ceSNicholas Bellinger 		pr_err("Unknown Opcode: 0x%02x ITT:"
3757e48354ceSNicholas Bellinger 		       " 0x%08x, i_state: %d on CID: %hu\n",
3758e48354ceSNicholas Bellinger 		       cmd->iscsi_opcode, cmd->init_task_tag,
3759e48354ceSNicholas Bellinger 		       cmd->i_state, conn->cid);
37606f3c0e69SAndy Grover 		goto err;
3761e48354ceSNicholas Bellinger 	}
3762e48354ceSNicholas Bellinger 
3763e48354ceSNicholas Bellinger 	if (atomic_read(&conn->check_immediate_queue))
3764fd3a9025SNicholas Bellinger 		return 1;
37656f3c0e69SAndy Grover 
37666f3c0e69SAndy Grover 	return 0;
37676f3c0e69SAndy Grover 
37686f3c0e69SAndy Grover err:
37696f3c0e69SAndy Grover 	return -1;
37706f3c0e69SAndy Grover }
3771d2faaefbSVarun Prakash EXPORT_SYMBOL(iscsit_response_queue);
37726f3c0e69SAndy Grover 
37732ec5a8c1SNicholas Bellinger static int iscsit_handle_response_queue(struct iscsi_conn *conn)
37742ec5a8c1SNicholas Bellinger {
37752ec5a8c1SNicholas Bellinger 	struct iscsit_transport *t = conn->conn_transport;
37762ec5a8c1SNicholas Bellinger 	struct iscsi_queue_req *qr;
37772ec5a8c1SNicholas Bellinger 	struct iscsi_cmd *cmd;
37782ec5a8c1SNicholas Bellinger 	u8 state;
37792ec5a8c1SNicholas Bellinger 	int ret;
37802ec5a8c1SNicholas Bellinger 
37812ec5a8c1SNicholas Bellinger 	while ((qr = iscsit_get_cmd_from_response_queue(conn))) {
37822ec5a8c1SNicholas Bellinger 		cmd = qr->cmd;
37832ec5a8c1SNicholas Bellinger 		state = qr->state;
37842ec5a8c1SNicholas Bellinger 		kmem_cache_free(lio_qr_cache, qr);
37852ec5a8c1SNicholas Bellinger 
37862ec5a8c1SNicholas Bellinger 		ret = t->iscsit_response_queue(conn, cmd, state);
37872ec5a8c1SNicholas Bellinger 		if (ret == 1 || ret < 0)
37882ec5a8c1SNicholas Bellinger 			return ret;
37892ec5a8c1SNicholas Bellinger 	}
37902ec5a8c1SNicholas Bellinger 
37912ec5a8c1SNicholas Bellinger 	return 0;
37922ec5a8c1SNicholas Bellinger }
37932ec5a8c1SNicholas Bellinger 
37946f3c0e69SAndy Grover int iscsi_target_tx_thread(void *arg)
37956f3c0e69SAndy Grover {
37966f3c0e69SAndy Grover 	int ret = 0;
379788dcd2daSNicholas Bellinger 	struct iscsi_conn *conn = arg;
37986f3c0e69SAndy Grover 	/*
37996f3c0e69SAndy Grover 	 * Allow ourselves to be interrupted by SIGINT so that a
38006f3c0e69SAndy Grover 	 * connection recovery / failure event can be triggered externally.
38016f3c0e69SAndy Grover 	 */
38026f3c0e69SAndy Grover 	allow_signal(SIGINT);
38036f3c0e69SAndy Grover 
38046f3c0e69SAndy Grover 	while (!kthread_should_stop()) {
38056f3c0e69SAndy Grover 		/*
38066f3c0e69SAndy Grover 		 * Ensure that both TX and RX per connection kthreads
38076f3c0e69SAndy Grover 		 * are scheduled to run on the same CPU.
38086f3c0e69SAndy Grover 		 */
38096f3c0e69SAndy Grover 		iscsit_thread_check_cpumask(conn, current, 1);
38106f3c0e69SAndy Grover 
3811d5627acbSRoland Dreier 		wait_event_interruptible(conn->queues_wq,
381288dcd2daSNicholas Bellinger 					 !iscsit_conn_all_queues_empty(conn));
38136f3c0e69SAndy Grover 
381488dcd2daSNicholas Bellinger 		if (signal_pending(current))
38156f3c0e69SAndy Grover 			goto transport_err;
38166f3c0e69SAndy Grover 
3817fd3a9025SNicholas Bellinger get_immediate:
38182ec5a8c1SNicholas Bellinger 		ret = iscsit_handle_immediate_queue(conn);
38196f3c0e69SAndy Grover 		if (ret < 0)
38206f3c0e69SAndy Grover 			goto transport_err;
38216f3c0e69SAndy Grover 
38222ec5a8c1SNicholas Bellinger 		ret = iscsit_handle_response_queue(conn);
3823fd3a9025SNicholas Bellinger 		if (ret == 1)
3824fd3a9025SNicholas Bellinger 			goto get_immediate;
382588dcd2daSNicholas Bellinger 		else if (ret == -ECONNRESET)
382688dcd2daSNicholas Bellinger 			goto out;
38276f3c0e69SAndy Grover 		else if (ret < 0)
38286f3c0e69SAndy Grover 			goto transport_err;
3829e48354ceSNicholas Bellinger 	}
3830e48354ceSNicholas Bellinger 
3831e48354ceSNicholas Bellinger transport_err:
3832e5419865SNicholas Bellinger 	/*
3833e5419865SNicholas Bellinger 	 * Avoid the normal connection failure code-path if this connection
3834e5419865SNicholas Bellinger 	 * is still within LOGIN mode, and iscsi_np process context is
3835e5419865SNicholas Bellinger 	 * responsible for cleaning up the early connection failure.
3836e5419865SNicholas Bellinger 	 */
3837e5419865SNicholas Bellinger 	if (conn->conn_state != TARG_CONN_STATE_IN_LOGIN)
3838e48354ceSNicholas Bellinger 		iscsit_take_action_for_connection_exit(conn);
3839e48354ceSNicholas Bellinger out:
3840e48354ceSNicholas Bellinger 	return 0;
3841e48354ceSNicholas Bellinger }
3842e48354ceSNicholas Bellinger 
38433e1c81a9SNicholas Bellinger static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf)
38443e1c81a9SNicholas Bellinger {
38453e1c81a9SNicholas Bellinger 	struct iscsi_hdr *hdr = (struct iscsi_hdr *)buf;
38463e1c81a9SNicholas Bellinger 	struct iscsi_cmd *cmd;
38473e1c81a9SNicholas Bellinger 	int ret = 0;
38483e1c81a9SNicholas Bellinger 
38493e1c81a9SNicholas Bellinger 	switch (hdr->opcode & ISCSI_OPCODE_MASK) {
38503e1c81a9SNicholas Bellinger 	case ISCSI_OP_SCSI_CMD:
3851676687c6SNicholas Bellinger 		cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
38523e1c81a9SNicholas Bellinger 		if (!cmd)
3853ba159914SNicholas Bellinger 			goto reject;
38543e1c81a9SNicholas Bellinger 
38553e1c81a9SNicholas Bellinger 		ret = iscsit_handle_scsi_cmd(conn, cmd, buf);
38563e1c81a9SNicholas Bellinger 		break;
38573e1c81a9SNicholas Bellinger 	case ISCSI_OP_SCSI_DATA_OUT:
38583e1c81a9SNicholas Bellinger 		ret = iscsit_handle_data_out(conn, buf);
38593e1c81a9SNicholas Bellinger 		break;
38603e1c81a9SNicholas Bellinger 	case ISCSI_OP_NOOP_OUT:
38613e1c81a9SNicholas Bellinger 		cmd = NULL;
38623e1c81a9SNicholas Bellinger 		if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
3863676687c6SNicholas Bellinger 			cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
38643e1c81a9SNicholas Bellinger 			if (!cmd)
3865ba159914SNicholas Bellinger 				goto reject;
38663e1c81a9SNicholas Bellinger 		}
38673e1c81a9SNicholas Bellinger 		ret = iscsit_handle_nop_out(conn, cmd, buf);
38683e1c81a9SNicholas Bellinger 		break;
38693e1c81a9SNicholas Bellinger 	case ISCSI_OP_SCSI_TMFUNC:
3870676687c6SNicholas Bellinger 		cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
38713e1c81a9SNicholas Bellinger 		if (!cmd)
3872ba159914SNicholas Bellinger 			goto reject;
38733e1c81a9SNicholas Bellinger 
38743e1c81a9SNicholas Bellinger 		ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf);
38753e1c81a9SNicholas Bellinger 		break;
38763e1c81a9SNicholas Bellinger 	case ISCSI_OP_TEXT:
3877e4f4e801SSagi Grimberg 		if (hdr->ttt != cpu_to_be32(0xFFFFFFFF)) {
3878e4f4e801SSagi Grimberg 			cmd = iscsit_find_cmd_from_itt(conn, hdr->itt);
3879e4f4e801SSagi Grimberg 			if (!cmd)
3880e4f4e801SSagi Grimberg 				goto reject;
3881e4f4e801SSagi Grimberg 		} else {
3882676687c6SNicholas Bellinger 			cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
388364534aa7SNicholas Bellinger 			if (!cmd)
3884ba159914SNicholas Bellinger 				goto reject;
3885e4f4e801SSagi Grimberg 		}
388664534aa7SNicholas Bellinger 
388764534aa7SNicholas Bellinger 		ret = iscsit_handle_text_cmd(conn, cmd, buf);
38883e1c81a9SNicholas Bellinger 		break;
38893e1c81a9SNicholas Bellinger 	case ISCSI_OP_LOGOUT:
3890676687c6SNicholas Bellinger 		cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
38913e1c81a9SNicholas Bellinger 		if (!cmd)
3892ba159914SNicholas Bellinger 			goto reject;
38933e1c81a9SNicholas Bellinger 
38943e1c81a9SNicholas Bellinger 		ret = iscsit_handle_logout_cmd(conn, cmd, buf);
38953e1c81a9SNicholas Bellinger 		if (ret > 0)
38963e1c81a9SNicholas Bellinger 			wait_for_completion_timeout(&conn->conn_logout_comp,
38973e1c81a9SNicholas Bellinger 					SECONDS_FOR_LOGOUT_COMP * HZ);
38983e1c81a9SNicholas Bellinger 		break;
38993e1c81a9SNicholas Bellinger 	case ISCSI_OP_SNACK:
39003e1c81a9SNicholas Bellinger 		ret = iscsit_handle_snack(conn, buf);
39013e1c81a9SNicholas Bellinger 		break;
39023e1c81a9SNicholas Bellinger 	default:
39033e1c81a9SNicholas Bellinger 		pr_err("Got unknown iSCSI OpCode: 0x%02x\n", hdr->opcode);
39043e1c81a9SNicholas Bellinger 		if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
39053e1c81a9SNicholas Bellinger 			pr_err("Cannot recover from unknown"
39063e1c81a9SNicholas Bellinger 			" opcode while ERL=0, closing iSCSI connection.\n");
39073e1c81a9SNicholas Bellinger 			return -1;
39083e1c81a9SNicholas Bellinger 		}
3909c04a6091SChristophe Vu-Brugier 		pr_err("Unable to recover from unknown opcode while OFMarker=No,"
3910c04a6091SChristophe Vu-Brugier 		       " closing iSCSI connection.\n");
3911c04a6091SChristophe Vu-Brugier 		ret = -1;
39123e1c81a9SNicholas Bellinger 		break;
39133e1c81a9SNicholas Bellinger 	}
39143e1c81a9SNicholas Bellinger 
39153e1c81a9SNicholas Bellinger 	return ret;
3916ba159914SNicholas Bellinger reject:
3917ba159914SNicholas Bellinger 	return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
39183e1c81a9SNicholas Bellinger }
39193e1c81a9SNicholas Bellinger 
3920ca82c2bdSNicholas Bellinger static bool iscsi_target_check_conn_state(struct iscsi_conn *conn)
3921ca82c2bdSNicholas Bellinger {
3922ca82c2bdSNicholas Bellinger 	bool ret;
3923ca82c2bdSNicholas Bellinger 
3924ca82c2bdSNicholas Bellinger 	spin_lock_bh(&conn->state_lock);
3925ca82c2bdSNicholas Bellinger 	ret = (conn->conn_state != TARG_CONN_STATE_LOGGED_IN);
3926ca82c2bdSNicholas Bellinger 	spin_unlock_bh(&conn->state_lock);
3927ca82c2bdSNicholas Bellinger 
3928ca82c2bdSNicholas Bellinger 	return ret;
3929ca82c2bdSNicholas Bellinger }
3930ca82c2bdSNicholas Bellinger 
3931e8205ccaSVarun Prakash static void iscsit_get_rx_pdu(struct iscsi_conn *conn)
3932e48354ceSNicholas Bellinger {
3933e8205ccaSVarun Prakash 	int ret;
3934e48354ceSNicholas Bellinger 	u8 buffer[ISCSI_HDR_LEN], opcode;
3935e48354ceSNicholas Bellinger 	u32 checksum = 0, digest = 0;
3936e48354ceSNicholas Bellinger 	struct kvec iov;
39373e1c81a9SNicholas Bellinger 
3938e48354ceSNicholas Bellinger 	while (!kthread_should_stop()) {
3939e48354ceSNicholas Bellinger 		/*
3940e48354ceSNicholas Bellinger 		 * Ensure that both TX and RX per connection kthreads
3941e48354ceSNicholas Bellinger 		 * are scheduled to run on the same CPU.
3942e48354ceSNicholas Bellinger 		 */
3943e48354ceSNicholas Bellinger 		iscsit_thread_check_cpumask(conn, current, 0);
3944e48354ceSNicholas Bellinger 
3945e48354ceSNicholas Bellinger 		memset(buffer, 0, ISCSI_HDR_LEN);
3946e48354ceSNicholas Bellinger 		memset(&iov, 0, sizeof(struct kvec));
3947e48354ceSNicholas Bellinger 
3948e48354ceSNicholas Bellinger 		iov.iov_base	= buffer;
3949e48354ceSNicholas Bellinger 		iov.iov_len	= ISCSI_HDR_LEN;
3950e48354ceSNicholas Bellinger 
3951e48354ceSNicholas Bellinger 		ret = rx_data(conn, &iov, 1, ISCSI_HDR_LEN);
3952e48354ceSNicholas Bellinger 		if (ret != ISCSI_HDR_LEN) {
3953e48354ceSNicholas Bellinger 			iscsit_rx_thread_wait_for_tcp(conn);
3954e8205ccaSVarun Prakash 			return;
3955e48354ceSNicholas Bellinger 		}
3956e48354ceSNicholas Bellinger 
3957e48354ceSNicholas Bellinger 		if (conn->conn_ops->HeaderDigest) {
3958e48354ceSNicholas Bellinger 			iov.iov_base	= &digest;
3959e48354ceSNicholas Bellinger 			iov.iov_len	= ISCSI_CRC_LEN;
3960e48354ceSNicholas Bellinger 
3961e48354ceSNicholas Bellinger 			ret = rx_data(conn, &iov, 1, ISCSI_CRC_LEN);
3962e48354ceSNicholas Bellinger 			if (ret != ISCSI_CRC_LEN) {
3963e48354ceSNicholas Bellinger 				iscsit_rx_thread_wait_for_tcp(conn);
3964e8205ccaSVarun Prakash 				return;
3965e48354ceSNicholas Bellinger 			}
3966e48354ceSNicholas Bellinger 
396769110e3cSHerbert Xu 			iscsit_do_crypto_hash_buf(conn->conn_rx_hash,
3968e48354ceSNicholas Bellinger 					buffer, ISCSI_HDR_LEN,
3969e48354ceSNicholas Bellinger 					0, NULL, (u8 *)&checksum);
3970e48354ceSNicholas Bellinger 
3971e48354ceSNicholas Bellinger 			if (digest != checksum) {
3972e48354ceSNicholas Bellinger 				pr_err("HeaderDigest CRC32C failed,"
3973e48354ceSNicholas Bellinger 					" received 0x%08x, computed 0x%08x\n",
3974e48354ceSNicholas Bellinger 					digest, checksum);
3975e48354ceSNicholas Bellinger 				/*
3976e48354ceSNicholas Bellinger 				 * Set the PDU to 0xff so it will intentionally
3977e48354ceSNicholas Bellinger 				 * hit default in the switch below.
3978e48354ceSNicholas Bellinger 				 */
3979e48354ceSNicholas Bellinger 				memset(buffer, 0xff, ISCSI_HDR_LEN);
398004f3b31bSNicholas Bellinger 				atomic_long_inc(&conn->sess->conn_digest_errors);
3981e48354ceSNicholas Bellinger 			} else {
3982e48354ceSNicholas Bellinger 				pr_debug("Got HeaderDigest CRC32C"
3983e48354ceSNicholas Bellinger 						" 0x%08x\n", checksum);
3984e48354ceSNicholas Bellinger 			}
3985e48354ceSNicholas Bellinger 		}
3986e48354ceSNicholas Bellinger 
3987e48354ceSNicholas Bellinger 		if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT)
3988e8205ccaSVarun Prakash 			return;
3989e48354ceSNicholas Bellinger 
3990e48354ceSNicholas Bellinger 		opcode = buffer[0] & ISCSI_OPCODE_MASK;
3991e48354ceSNicholas Bellinger 
3992e48354ceSNicholas Bellinger 		if (conn->sess->sess_ops->SessionType &&
3993e48354ceSNicholas Bellinger 		   ((!(opcode & ISCSI_OP_TEXT)) ||
3994e48354ceSNicholas Bellinger 		    (!(opcode & ISCSI_OP_LOGOUT)))) {
3995e48354ceSNicholas Bellinger 			pr_err("Received illegal iSCSI Opcode: 0x%02x"
3996e48354ceSNicholas Bellinger 			" while in Discovery Session, rejecting.\n", opcode);
3997ba159914SNicholas Bellinger 			iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
3998ba159914SNicholas Bellinger 					  buffer);
3999e8205ccaSVarun Prakash 			return;
4000e48354ceSNicholas Bellinger 		}
4001e48354ceSNicholas Bellinger 
40023e1c81a9SNicholas Bellinger 		ret = iscsi_target_rx_opcode(conn, buffer);
40033e1c81a9SNicholas Bellinger 		if (ret < 0)
4004e8205ccaSVarun Prakash 			return;
4005e8205ccaSVarun Prakash 	}
4006e48354ceSNicholas Bellinger }
4007e48354ceSNicholas Bellinger 
4008e8205ccaSVarun Prakash int iscsi_target_rx_thread(void *arg)
4009e8205ccaSVarun Prakash {
4010e8205ccaSVarun Prakash 	int rc;
4011e8205ccaSVarun Prakash 	struct iscsi_conn *conn = arg;
4012e8205ccaSVarun Prakash 
4013e8205ccaSVarun Prakash 	/*
4014e8205ccaSVarun Prakash 	 * Allow ourselves to be interrupted by SIGINT so that a
4015e8205ccaSVarun Prakash 	 * connection recovery / failure event can be triggered externally.
4016e8205ccaSVarun Prakash 	 */
4017e8205ccaSVarun Prakash 	allow_signal(SIGINT);
4018e8205ccaSVarun Prakash 	/*
4019e8205ccaSVarun Prakash 	 * Wait for iscsi_post_login_handler() to complete before allowing
4020e8205ccaSVarun Prakash 	 * incoming iscsi/tcp socket I/O, and/or failing the connection.
4021e8205ccaSVarun Prakash 	 */
4022e8205ccaSVarun Prakash 	rc = wait_for_completion_interruptible(&conn->rx_login_comp);
4023e8205ccaSVarun Prakash 	if (rc < 0 || iscsi_target_check_conn_state(conn))
4024e8205ccaSVarun Prakash 		return 0;
4025e8205ccaSVarun Prakash 
4026e8205ccaSVarun Prakash 	if (!conn->conn_transport->iscsit_get_rx_pdu)
4027e8205ccaSVarun Prakash 		return 0;
4028e8205ccaSVarun Prakash 
4029e8205ccaSVarun Prakash 	conn->conn_transport->iscsit_get_rx_pdu(conn);
4030e8205ccaSVarun Prakash 
4031e48354ceSNicholas Bellinger 	if (!signal_pending(current))
4032e48354ceSNicholas Bellinger 		atomic_set(&conn->transport_failed, 1);
4033e48354ceSNicholas Bellinger 	iscsit_take_action_for_connection_exit(conn);
4034e48354ceSNicholas Bellinger 	return 0;
4035e48354ceSNicholas Bellinger }
4036e48354ceSNicholas Bellinger 
4037e48354ceSNicholas Bellinger static void iscsit_release_commands_from_conn(struct iscsi_conn *conn)
4038e48354ceSNicholas Bellinger {
4039064cdd2dSNicholas Bellinger 	LIST_HEAD(tmp_list);
4040e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd = NULL, *cmd_tmp = NULL;
4041e48354ceSNicholas Bellinger 	struct iscsi_session *sess = conn->sess;
4042e48354ceSNicholas Bellinger 	/*
4043e48354ceSNicholas Bellinger 	 * We expect this function to only ever be called from either RX or TX
4044e48354ceSNicholas Bellinger 	 * thread context via iscsit_close_connection() once the other context
4045e48354ceSNicholas Bellinger 	 * has been reset -> returned sleeping pre-handler state.
4046e48354ceSNicholas Bellinger 	 */
4047e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
4048064cdd2dSNicholas Bellinger 	list_splice_init(&conn->conn_cmd_list, &tmp_list);
4049e48354ceSNicholas Bellinger 
4050064cdd2dSNicholas Bellinger 	list_for_each_entry(cmd, &tmp_list, i_conn_node) {
4051064cdd2dSNicholas Bellinger 		struct se_cmd *se_cmd = &cmd->se_cmd;
4052e48354ceSNicholas Bellinger 
4053064cdd2dSNicholas Bellinger 		if (se_cmd->se_tfo != NULL) {
4054064cdd2dSNicholas Bellinger 			spin_lock(&se_cmd->t_state_lock);
4055064cdd2dSNicholas Bellinger 			se_cmd->transport_state |= CMD_T_FABRIC_STOP;
4056064cdd2dSNicholas Bellinger 			spin_unlock(&se_cmd->t_state_lock);
4057064cdd2dSNicholas Bellinger 		}
4058e48354ceSNicholas Bellinger 	}
4059e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
4060064cdd2dSNicholas Bellinger 
4061064cdd2dSNicholas Bellinger 	list_for_each_entry_safe(cmd, cmd_tmp, &tmp_list, i_conn_node) {
4062064cdd2dSNicholas Bellinger 		list_del_init(&cmd->i_conn_node);
4063064cdd2dSNicholas Bellinger 
4064064cdd2dSNicholas Bellinger 		iscsit_increment_maxcmdsn(cmd, sess);
4065064cdd2dSNicholas Bellinger 		iscsit_free_cmd(cmd, true);
4066064cdd2dSNicholas Bellinger 
4067064cdd2dSNicholas Bellinger 	}
4068e48354ceSNicholas Bellinger }
4069e48354ceSNicholas Bellinger 
4070e48354ceSNicholas Bellinger static void iscsit_stop_timers_for_cmds(
4071e48354ceSNicholas Bellinger 	struct iscsi_conn *conn)
4072e48354ceSNicholas Bellinger {
4073e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd;
4074e48354ceSNicholas Bellinger 
4075e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->cmd_lock);
40762fbb471eSAndy Grover 	list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) {
4077e48354ceSNicholas Bellinger 		if (cmd->data_direction == DMA_TO_DEVICE)
4078e48354ceSNicholas Bellinger 			iscsit_stop_dataout_timer(cmd);
4079e48354ceSNicholas Bellinger 	}
4080e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->cmd_lock);
4081e48354ceSNicholas Bellinger }
4082e48354ceSNicholas Bellinger 
4083e48354ceSNicholas Bellinger int iscsit_close_connection(
4084e48354ceSNicholas Bellinger 	struct iscsi_conn *conn)
4085e48354ceSNicholas Bellinger {
4086e48354ceSNicholas Bellinger 	int conn_logout = (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT);
4087e48354ceSNicholas Bellinger 	struct iscsi_session	*sess = conn->sess;
4088e48354ceSNicholas Bellinger 
4089e48354ceSNicholas Bellinger 	pr_debug("Closing iSCSI connection CID %hu on SID:"
4090e48354ceSNicholas Bellinger 		" %u\n", conn->cid, sess->sid);
4091e48354ceSNicholas Bellinger 	/*
4092b4869ee9SVarun Prakash 	 * Always up conn_logout_comp for the traditional TCP and HW_OFFLOAD
4093b4869ee9SVarun Prakash 	 * case just in case the RX Thread in iscsi_target_rx_opcode() is
4094b4869ee9SVarun Prakash 	 * sleeping and the logout response never got sent because the
4095b4869ee9SVarun Prakash 	 * connection failed.
4096f068fbc8SNicholas Bellinger 	 *
4097f068fbc8SNicholas Bellinger 	 * However for iser-target, isert_wait4logout() is using conn_logout_comp
4098f068fbc8SNicholas Bellinger 	 * to signal logout response TX interrupt completion.  Go ahead and skip
4099f068fbc8SNicholas Bellinger 	 * this for iser since isert_rx_opcode() does not wait on logout failure,
4100f068fbc8SNicholas Bellinger 	 * and to avoid iscsi_conn pointer dereference in iser-target code.
4101e48354ceSNicholas Bellinger 	 */
4102bd027d85SNicholas Bellinger 	if (!conn->conn_transport->rdma_shutdown)
4103e48354ceSNicholas Bellinger 		complete(&conn->conn_logout_comp);
4104e48354ceSNicholas Bellinger 
410588dcd2daSNicholas Bellinger 	if (!strcmp(current->comm, ISCSI_RX_THREAD_NAME)) {
410688dcd2daSNicholas Bellinger 		if (conn->tx_thread &&
410788dcd2daSNicholas Bellinger 		    cmpxchg(&conn->tx_thread_active, true, false)) {
410888dcd2daSNicholas Bellinger 			send_sig(SIGINT, conn->tx_thread, 1);
410988dcd2daSNicholas Bellinger 			kthread_stop(conn->tx_thread);
411088dcd2daSNicholas Bellinger 		}
411188dcd2daSNicholas Bellinger 	} else if (!strcmp(current->comm, ISCSI_TX_THREAD_NAME)) {
411288dcd2daSNicholas Bellinger 		if (conn->rx_thread &&
411388dcd2daSNicholas Bellinger 		    cmpxchg(&conn->rx_thread_active, true, false)) {
411488dcd2daSNicholas Bellinger 			send_sig(SIGINT, conn->rx_thread, 1);
411588dcd2daSNicholas Bellinger 			kthread_stop(conn->rx_thread);
411688dcd2daSNicholas Bellinger 		}
411788dcd2daSNicholas Bellinger 	}
411888dcd2daSNicholas Bellinger 
411988dcd2daSNicholas Bellinger 	spin_lock(&iscsit_global->ts_bitmap_lock);
412088dcd2daSNicholas Bellinger 	bitmap_release_region(iscsit_global->ts_bitmap, conn->bitmap_id,
412188dcd2daSNicholas Bellinger 			      get_order(1));
412288dcd2daSNicholas Bellinger 	spin_unlock(&iscsit_global->ts_bitmap_lock);
4123e48354ceSNicholas Bellinger 
4124e48354ceSNicholas Bellinger 	iscsit_stop_timers_for_cmds(conn);
4125e48354ceSNicholas Bellinger 	iscsit_stop_nopin_response_timer(conn);
4126e48354ceSNicholas Bellinger 	iscsit_stop_nopin_timer(conn);
4127defd8848SNicholas Bellinger 
4128defd8848SNicholas Bellinger 	if (conn->conn_transport->iscsit_wait_conn)
4129defd8848SNicholas Bellinger 		conn->conn_transport->iscsit_wait_conn(conn);
4130defd8848SNicholas Bellinger 
4131e48354ceSNicholas Bellinger 	/*
4132e48354ceSNicholas Bellinger 	 * During Connection recovery drop unacknowledged out of order
4133e48354ceSNicholas Bellinger 	 * commands for this connection, and prepare the other commands
413453c561dcSBart Van Assche 	 * for reallegiance.
4135e48354ceSNicholas Bellinger 	 *
4136e48354ceSNicholas Bellinger 	 * During normal operation clear the out of order commands (but
4137e48354ceSNicholas Bellinger 	 * do not free the struct iscsi_ooo_cmdsn's) and release all
4138e48354ceSNicholas Bellinger 	 * struct iscsi_cmds.
4139e48354ceSNicholas Bellinger 	 */
4140e48354ceSNicholas Bellinger 	if (atomic_read(&conn->connection_recovery)) {
4141e48354ceSNicholas Bellinger 		iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(conn);
414253c561dcSBart Van Assche 		iscsit_prepare_cmds_for_reallegiance(conn);
4143e48354ceSNicholas Bellinger 	} else {
4144e48354ceSNicholas Bellinger 		iscsit_clear_ooo_cmdsns_for_conn(conn);
4145e48354ceSNicholas Bellinger 		iscsit_release_commands_from_conn(conn);
4146e48354ceSNicholas Bellinger 	}
4147bbc05048SNicholas Bellinger 	iscsit_free_queue_reqs_for_conn(conn);
4148e48354ceSNicholas Bellinger 
4149e48354ceSNicholas Bellinger 	/*
4150e48354ceSNicholas Bellinger 	 * Handle decrementing session or connection usage count if
4151e48354ceSNicholas Bellinger 	 * a logout response was not able to be sent because the
4152e48354ceSNicholas Bellinger 	 * connection failed.  Fall back to Session Recovery here.
4153e48354ceSNicholas Bellinger 	 */
4154e48354ceSNicholas Bellinger 	if (atomic_read(&conn->conn_logout_remove)) {
4155e48354ceSNicholas Bellinger 		if (conn->conn_logout_reason == ISCSI_LOGOUT_REASON_CLOSE_SESSION) {
4156e48354ceSNicholas Bellinger 			iscsit_dec_conn_usage_count(conn);
4157e48354ceSNicholas Bellinger 			iscsit_dec_session_usage_count(sess);
4158e48354ceSNicholas Bellinger 		}
4159e48354ceSNicholas Bellinger 		if (conn->conn_logout_reason == ISCSI_LOGOUT_REASON_CLOSE_CONNECTION)
4160e48354ceSNicholas Bellinger 			iscsit_dec_conn_usage_count(conn);
4161e48354ceSNicholas Bellinger 
4162e48354ceSNicholas Bellinger 		atomic_set(&conn->conn_logout_remove, 0);
4163e48354ceSNicholas Bellinger 		atomic_set(&sess->session_reinstatement, 0);
4164e48354ceSNicholas Bellinger 		atomic_set(&sess->session_fall_back_to_erl0, 1);
4165e48354ceSNicholas Bellinger 	}
4166e48354ceSNicholas Bellinger 
4167e48354ceSNicholas Bellinger 	spin_lock_bh(&sess->conn_lock);
4168e48354ceSNicholas Bellinger 	list_del(&conn->conn_list);
4169e48354ceSNicholas Bellinger 
4170e48354ceSNicholas Bellinger 	/*
4171e48354ceSNicholas Bellinger 	 * Attempt to let the Initiator know this connection failed by
4172e48354ceSNicholas Bellinger 	 * sending an Connection Dropped Async Message on another
4173e48354ceSNicholas Bellinger 	 * active connection.
4174e48354ceSNicholas Bellinger 	 */
4175e48354ceSNicholas Bellinger 	if (atomic_read(&conn->connection_recovery))
4176e48354ceSNicholas Bellinger 		iscsit_build_conn_drop_async_message(conn);
4177e48354ceSNicholas Bellinger 
4178e48354ceSNicholas Bellinger 	spin_unlock_bh(&sess->conn_lock);
4179e48354ceSNicholas Bellinger 
4180e48354ceSNicholas Bellinger 	/*
4181e48354ceSNicholas Bellinger 	 * If connection reinstatement is being performed on this connection,
4182e48354ceSNicholas Bellinger 	 * up the connection reinstatement semaphore that is being blocked on
4183e48354ceSNicholas Bellinger 	 * in iscsit_cause_connection_reinstatement().
4184e48354ceSNicholas Bellinger 	 */
4185e48354ceSNicholas Bellinger 	spin_lock_bh(&conn->state_lock);
4186e48354ceSNicholas Bellinger 	if (atomic_read(&conn->sleep_on_conn_wait_comp)) {
4187e48354ceSNicholas Bellinger 		spin_unlock_bh(&conn->state_lock);
4188e48354ceSNicholas Bellinger 		complete(&conn->conn_wait_comp);
4189e48354ceSNicholas Bellinger 		wait_for_completion(&conn->conn_post_wait_comp);
4190e48354ceSNicholas Bellinger 		spin_lock_bh(&conn->state_lock);
4191e48354ceSNicholas Bellinger 	}
4192e48354ceSNicholas Bellinger 
4193e48354ceSNicholas Bellinger 	/*
4194e48354ceSNicholas Bellinger 	 * If connection reinstatement is being performed on this connection
4195e48354ceSNicholas Bellinger 	 * by receiving a REMOVECONNFORRECOVERY logout request, up the
4196e48354ceSNicholas Bellinger 	 * connection wait rcfr semaphore that is being blocked on
4197e48354ceSNicholas Bellinger 	 * an iscsit_connection_reinstatement_rcfr().
4198e48354ceSNicholas Bellinger 	 */
4199e48354ceSNicholas Bellinger 	if (atomic_read(&conn->connection_wait_rcfr)) {
4200e48354ceSNicholas Bellinger 		spin_unlock_bh(&conn->state_lock);
4201e48354ceSNicholas Bellinger 		complete(&conn->conn_wait_rcfr_comp);
4202e48354ceSNicholas Bellinger 		wait_for_completion(&conn->conn_post_wait_comp);
4203e48354ceSNicholas Bellinger 		spin_lock_bh(&conn->state_lock);
4204e48354ceSNicholas Bellinger 	}
4205e48354ceSNicholas Bellinger 	atomic_set(&conn->connection_reinstatement, 1);
4206e48354ceSNicholas Bellinger 	spin_unlock_bh(&conn->state_lock);
4207e48354ceSNicholas Bellinger 
4208e48354ceSNicholas Bellinger 	/*
4209e48354ceSNicholas Bellinger 	 * If any other processes are accessing this connection pointer we
4210e48354ceSNicholas Bellinger 	 * must wait until they have completed.
4211e48354ceSNicholas Bellinger 	 */
4212e48354ceSNicholas Bellinger 	iscsit_check_conn_usage_count(conn);
4213e48354ceSNicholas Bellinger 
421469110e3cSHerbert Xu 	ahash_request_free(conn->conn_tx_hash);
421569110e3cSHerbert Xu 	if (conn->conn_rx_hash) {
421669110e3cSHerbert Xu 		struct crypto_ahash *tfm;
421769110e3cSHerbert Xu 
421869110e3cSHerbert Xu 		tfm = crypto_ahash_reqtfm(conn->conn_rx_hash);
421969110e3cSHerbert Xu 		ahash_request_free(conn->conn_rx_hash);
422069110e3cSHerbert Xu 		crypto_free_ahash(tfm);
422169110e3cSHerbert Xu 	}
4222e48354ceSNicholas Bellinger 
4223e48354ceSNicholas Bellinger 	free_cpumask_var(conn->conn_cpumask);
4224e48354ceSNicholas Bellinger 
4225e48354ceSNicholas Bellinger 	kfree(conn->conn_ops);
4226e48354ceSNicholas Bellinger 	conn->conn_ops = NULL;
4227e48354ceSNicholas Bellinger 
4228bf6932f4SAl Viro 	if (conn->sock)
4229e48354ceSNicholas Bellinger 		sock_release(conn->sock);
4230baa4d64bSNicholas Bellinger 
4231baa4d64bSNicholas Bellinger 	if (conn->conn_transport->iscsit_free_conn)
4232baa4d64bSNicholas Bellinger 		conn->conn_transport->iscsit_free_conn(conn);
4233baa4d64bSNicholas Bellinger 
4234baa4d64bSNicholas Bellinger 	iscsit_put_transport(conn->conn_transport);
4235baa4d64bSNicholas Bellinger 
4236e48354ceSNicholas Bellinger 	pr_debug("Moving to TARG_CONN_STATE_FREE.\n");
4237e48354ceSNicholas Bellinger 	conn->conn_state = TARG_CONN_STATE_FREE;
4238e48354ceSNicholas Bellinger 	kfree(conn);
4239e48354ceSNicholas Bellinger 
4240e48354ceSNicholas Bellinger 	spin_lock_bh(&sess->conn_lock);
4241e48354ceSNicholas Bellinger 	atomic_dec(&sess->nconn);
4242e48354ceSNicholas Bellinger 	pr_debug("Decremented iSCSI connection count to %hu from node:"
4243e48354ceSNicholas Bellinger 		" %s\n", atomic_read(&sess->nconn),
4244e48354ceSNicholas Bellinger 		sess->sess_ops->InitiatorName);
4245e48354ceSNicholas Bellinger 	/*
4246e48354ceSNicholas Bellinger 	 * Make sure that if one connection fails in an non ERL=2 iSCSI
4247e48354ceSNicholas Bellinger 	 * Session that they all fail.
4248e48354ceSNicholas Bellinger 	 */
4249e48354ceSNicholas Bellinger 	if ((sess->sess_ops->ErrorRecoveryLevel != 2) && !conn_logout &&
4250e48354ceSNicholas Bellinger 	     !atomic_read(&sess->session_logout))
4251e48354ceSNicholas Bellinger 		atomic_set(&sess->session_fall_back_to_erl0, 1);
4252e48354ceSNicholas Bellinger 
4253e48354ceSNicholas Bellinger 	/*
4254e48354ceSNicholas Bellinger 	 * If this was not the last connection in the session, and we are
4255e48354ceSNicholas Bellinger 	 * performing session reinstatement or falling back to ERL=0, call
4256e48354ceSNicholas Bellinger 	 * iscsit_stop_session() without sleeping to shutdown the other
4257e48354ceSNicholas Bellinger 	 * active connections.
4258e48354ceSNicholas Bellinger 	 */
4259e48354ceSNicholas Bellinger 	if (atomic_read(&sess->nconn)) {
4260e48354ceSNicholas Bellinger 		if (!atomic_read(&sess->session_reinstatement) &&
4261e48354ceSNicholas Bellinger 		    !atomic_read(&sess->session_fall_back_to_erl0)) {
4262e48354ceSNicholas Bellinger 			spin_unlock_bh(&sess->conn_lock);
4263e48354ceSNicholas Bellinger 			return 0;
4264e48354ceSNicholas Bellinger 		}
4265e48354ceSNicholas Bellinger 		if (!atomic_read(&sess->session_stop_active)) {
4266e48354ceSNicholas Bellinger 			atomic_set(&sess->session_stop_active, 1);
4267e48354ceSNicholas Bellinger 			spin_unlock_bh(&sess->conn_lock);
4268e48354ceSNicholas Bellinger 			iscsit_stop_session(sess, 0, 0);
4269e48354ceSNicholas Bellinger 			return 0;
4270e48354ceSNicholas Bellinger 		}
4271e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
4272e48354ceSNicholas Bellinger 		return 0;
4273e48354ceSNicholas Bellinger 	}
4274e48354ceSNicholas Bellinger 
4275e48354ceSNicholas Bellinger 	/*
4276e48354ceSNicholas Bellinger 	 * If this was the last connection in the session and one of the
4277e48354ceSNicholas Bellinger 	 * following is occurring:
4278e48354ceSNicholas Bellinger 	 *
4279e48354ceSNicholas Bellinger 	 * Session Reinstatement is not being performed, and are falling back
4280e48354ceSNicholas Bellinger 	 * to ERL=0 call iscsit_close_session().
4281e48354ceSNicholas Bellinger 	 *
4282e48354ceSNicholas Bellinger 	 * Session Logout was requested.  iscsit_close_session() will be called
4283e48354ceSNicholas Bellinger 	 * elsewhere.
4284e48354ceSNicholas Bellinger 	 *
4285e48354ceSNicholas Bellinger 	 * Session Continuation is not being performed, start the Time2Retain
4286e48354ceSNicholas Bellinger 	 * handler and check if sleep_on_sess_wait_sem is active.
4287e48354ceSNicholas Bellinger 	 */
4288e48354ceSNicholas Bellinger 	if (!atomic_read(&sess->session_reinstatement) &&
4289e48354ceSNicholas Bellinger 	     atomic_read(&sess->session_fall_back_to_erl0)) {
4290e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
429144f33d0fSChristoph Hellwig 		iscsit_close_session(sess);
4292e48354ceSNicholas Bellinger 
4293e48354ceSNicholas Bellinger 		return 0;
4294e48354ceSNicholas Bellinger 	} else if (atomic_read(&sess->session_logout)) {
4295e48354ceSNicholas Bellinger 		pr_debug("Moving to TARG_SESS_STATE_FREE.\n");
4296e48354ceSNicholas Bellinger 		sess->session_state = TARG_SESS_STATE_FREE;
4297e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
4298e48354ceSNicholas Bellinger 
4299e48354ceSNicholas Bellinger 		if (atomic_read(&sess->sleep_on_sess_wait_comp))
4300e48354ceSNicholas Bellinger 			complete(&sess->session_wait_comp);
4301e48354ceSNicholas Bellinger 
4302e48354ceSNicholas Bellinger 		return 0;
4303e48354ceSNicholas Bellinger 	} else {
4304e48354ceSNicholas Bellinger 		pr_debug("Moving to TARG_SESS_STATE_FAILED.\n");
4305e48354ceSNicholas Bellinger 		sess->session_state = TARG_SESS_STATE_FAILED;
4306e48354ceSNicholas Bellinger 
4307e48354ceSNicholas Bellinger 		if (!atomic_read(&sess->session_continuation)) {
4308e48354ceSNicholas Bellinger 			spin_unlock_bh(&sess->conn_lock);
4309e48354ceSNicholas Bellinger 			iscsit_start_time2retain_handler(sess);
4310e48354ceSNicholas Bellinger 		} else
4311e48354ceSNicholas Bellinger 			spin_unlock_bh(&sess->conn_lock);
4312e48354ceSNicholas Bellinger 
4313e48354ceSNicholas Bellinger 		if (atomic_read(&sess->sleep_on_sess_wait_comp))
4314e48354ceSNicholas Bellinger 			complete(&sess->session_wait_comp);
4315e48354ceSNicholas Bellinger 
4316e48354ceSNicholas Bellinger 		return 0;
4317e48354ceSNicholas Bellinger 	}
4318e48354ceSNicholas Bellinger }
4319e48354ceSNicholas Bellinger 
432044f33d0fSChristoph Hellwig /*
432144f33d0fSChristoph Hellwig  * If the iSCSI Session for the iSCSI Initiator Node exists,
432244f33d0fSChristoph Hellwig  * forcefully shutdown the iSCSI NEXUS.
432344f33d0fSChristoph Hellwig  */
4324e48354ceSNicholas Bellinger int iscsit_close_session(struct iscsi_session *sess)
4325e48354ceSNicholas Bellinger {
432660bfcf8eSAndy Grover 	struct iscsi_portal_group *tpg = sess->tpg;
4327e48354ceSNicholas Bellinger 	struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
4328e48354ceSNicholas Bellinger 
4329e48354ceSNicholas Bellinger 	if (atomic_read(&sess->nconn)) {
4330e48354ceSNicholas Bellinger 		pr_err("%d connection(s) still exist for iSCSI session"
4331e48354ceSNicholas Bellinger 			" to %s\n", atomic_read(&sess->nconn),
4332e48354ceSNicholas Bellinger 			sess->sess_ops->InitiatorName);
4333e48354ceSNicholas Bellinger 		BUG();
4334e48354ceSNicholas Bellinger 	}
4335e48354ceSNicholas Bellinger 
4336e48354ceSNicholas Bellinger 	spin_lock_bh(&se_tpg->session_lock);
4337e48354ceSNicholas Bellinger 	atomic_set(&sess->session_logout, 1);
4338e48354ceSNicholas Bellinger 	atomic_set(&sess->session_reinstatement, 1);
4339e48354ceSNicholas Bellinger 	iscsit_stop_time2retain_timer(sess);
4340e48354ceSNicholas Bellinger 	spin_unlock_bh(&se_tpg->session_lock);
4341e48354ceSNicholas Bellinger 
4342e48354ceSNicholas Bellinger 	/*
4343e48354ceSNicholas Bellinger 	 * transport_deregister_session_configfs() will clear the
4344e48354ceSNicholas Bellinger 	 * struct se_node_acl->nacl_sess pointer now as a iscsi_np process context
4345e48354ceSNicholas Bellinger 	 * can be setting it again with __transport_register_session() in
4346e48354ceSNicholas Bellinger 	 * iscsi_post_login_handler() again after the iscsit_stop_session()
4347e48354ceSNicholas Bellinger 	 * completes in iscsi_np context.
4348e48354ceSNicholas Bellinger 	 */
4349e48354ceSNicholas Bellinger 	transport_deregister_session_configfs(sess->se_sess);
4350e48354ceSNicholas Bellinger 
4351e48354ceSNicholas Bellinger 	/*
4352e48354ceSNicholas Bellinger 	 * If any other processes are accessing this session pointer we must
4353e48354ceSNicholas Bellinger 	 * wait until they have completed.  If we are in an interrupt (the
4354e48354ceSNicholas Bellinger 	 * time2retain handler) and contain and active session usage count we
4355e48354ceSNicholas Bellinger 	 * restart the timer and exit.
4356e48354ceSNicholas Bellinger 	 */
4357e48354ceSNicholas Bellinger 	if (!in_interrupt()) {
4358e48354ceSNicholas Bellinger 		if (iscsit_check_session_usage_count(sess) == 1)
4359e48354ceSNicholas Bellinger 			iscsit_stop_session(sess, 1, 1);
4360e48354ceSNicholas Bellinger 	} else {
4361e48354ceSNicholas Bellinger 		if (iscsit_check_session_usage_count(sess) == 2) {
4362e48354ceSNicholas Bellinger 			atomic_set(&sess->session_logout, 0);
4363e48354ceSNicholas Bellinger 			iscsit_start_time2retain_handler(sess);
4364e48354ceSNicholas Bellinger 			return 0;
4365e48354ceSNicholas Bellinger 		}
4366e48354ceSNicholas Bellinger 	}
4367e48354ceSNicholas Bellinger 
4368e48354ceSNicholas Bellinger 	transport_deregister_session(sess->se_sess);
4369e48354ceSNicholas Bellinger 
4370e48354ceSNicholas Bellinger 	if (sess->sess_ops->ErrorRecoveryLevel == 2)
4371e48354ceSNicholas Bellinger 		iscsit_free_connection_recovery_entires(sess);
4372e48354ceSNicholas Bellinger 
4373e48354ceSNicholas Bellinger 	iscsit_free_all_ooo_cmdsns(sess);
4374e48354ceSNicholas Bellinger 
4375e48354ceSNicholas Bellinger 	spin_lock_bh(&se_tpg->session_lock);
4376e48354ceSNicholas Bellinger 	pr_debug("Moving to TARG_SESS_STATE_FREE.\n");
4377e48354ceSNicholas Bellinger 	sess->session_state = TARG_SESS_STATE_FREE;
4378e48354ceSNicholas Bellinger 	pr_debug("Released iSCSI session from node: %s\n",
4379e48354ceSNicholas Bellinger 			sess->sess_ops->InitiatorName);
4380e48354ceSNicholas Bellinger 	tpg->nsessions--;
4381e48354ceSNicholas Bellinger 	if (tpg->tpg_tiqn)
4382e48354ceSNicholas Bellinger 		tpg->tpg_tiqn->tiqn_nsessions--;
4383e48354ceSNicholas Bellinger 
4384e48354ceSNicholas Bellinger 	pr_debug("Decremented number of active iSCSI Sessions on"
4385e48354ceSNicholas Bellinger 		" iSCSI TPG: %hu to %u\n", tpg->tpgt, tpg->nsessions);
4386e48354ceSNicholas Bellinger 
4387e48354ceSNicholas Bellinger 	spin_lock(&sess_idr_lock);
4388e48354ceSNicholas Bellinger 	idr_remove(&sess_idr, sess->session_index);
4389e48354ceSNicholas Bellinger 	spin_unlock(&sess_idr_lock);
4390e48354ceSNicholas Bellinger 
4391e48354ceSNicholas Bellinger 	kfree(sess->sess_ops);
4392e48354ceSNicholas Bellinger 	sess->sess_ops = NULL;
4393e48354ceSNicholas Bellinger 	spin_unlock_bh(&se_tpg->session_lock);
4394e48354ceSNicholas Bellinger 
4395e48354ceSNicholas Bellinger 	kfree(sess);
4396e48354ceSNicholas Bellinger 	return 0;
4397e48354ceSNicholas Bellinger }
4398e48354ceSNicholas Bellinger 
4399e48354ceSNicholas Bellinger static void iscsit_logout_post_handler_closesession(
4400e48354ceSNicholas Bellinger 	struct iscsi_conn *conn)
4401e48354ceSNicholas Bellinger {
4402e48354ceSNicholas Bellinger 	struct iscsi_session *sess = conn->sess;
4403007d038bSNicholas Bellinger 	int sleep = 1;
4404007d038bSNicholas Bellinger 	/*
4405007d038bSNicholas Bellinger 	 * Traditional iscsi/tcp will invoke this logic from TX thread
4406007d038bSNicholas Bellinger 	 * context during session logout, so clear tx_thread_active and
4407007d038bSNicholas Bellinger 	 * sleep if iscsit_close_connection() has not already occured.
4408007d038bSNicholas Bellinger 	 *
4409007d038bSNicholas Bellinger 	 * Since iser-target invokes this logic from it's own workqueue,
4410007d038bSNicholas Bellinger 	 * always sleep waiting for RX/TX thread shutdown to complete
4411007d038bSNicholas Bellinger 	 * within iscsit_close_connection().
4412007d038bSNicholas Bellinger 	 */
4413bd027d85SNicholas Bellinger 	if (!conn->conn_transport->rdma_shutdown)
4414007d038bSNicholas Bellinger 		sleep = cmpxchg(&conn->tx_thread_active, true, false);
4415e48354ceSNicholas Bellinger 
4416e48354ceSNicholas Bellinger 	atomic_set(&conn->conn_logout_remove, 0);
4417e48354ceSNicholas Bellinger 	complete(&conn->conn_logout_comp);
4418e48354ceSNicholas Bellinger 
4419e48354ceSNicholas Bellinger 	iscsit_dec_conn_usage_count(conn);
442088dcd2daSNicholas Bellinger 	iscsit_stop_session(sess, sleep, sleep);
4421e48354ceSNicholas Bellinger 	iscsit_dec_session_usage_count(sess);
442244f33d0fSChristoph Hellwig 	iscsit_close_session(sess);
4423e48354ceSNicholas Bellinger }
4424e48354ceSNicholas Bellinger 
4425e48354ceSNicholas Bellinger static void iscsit_logout_post_handler_samecid(
4426e48354ceSNicholas Bellinger 	struct iscsi_conn *conn)
4427e48354ceSNicholas Bellinger {
4428007d038bSNicholas Bellinger 	int sleep = 1;
4429007d038bSNicholas Bellinger 
4430bd027d85SNicholas Bellinger 	if (!conn->conn_transport->rdma_shutdown)
4431007d038bSNicholas Bellinger 		sleep = cmpxchg(&conn->tx_thread_active, true, false);
4432e48354ceSNicholas Bellinger 
4433e48354ceSNicholas Bellinger 	atomic_set(&conn->conn_logout_remove, 0);
4434e48354ceSNicholas Bellinger 	complete(&conn->conn_logout_comp);
4435e48354ceSNicholas Bellinger 
443688dcd2daSNicholas Bellinger 	iscsit_cause_connection_reinstatement(conn, sleep);
4437e48354ceSNicholas Bellinger 	iscsit_dec_conn_usage_count(conn);
4438e48354ceSNicholas Bellinger }
4439e48354ceSNicholas Bellinger 
4440e48354ceSNicholas Bellinger static void iscsit_logout_post_handler_diffcid(
4441e48354ceSNicholas Bellinger 	struct iscsi_conn *conn,
4442e48354ceSNicholas Bellinger 	u16 cid)
4443e48354ceSNicholas Bellinger {
4444e48354ceSNicholas Bellinger 	struct iscsi_conn *l_conn;
4445e48354ceSNicholas Bellinger 	struct iscsi_session *sess = conn->sess;
4446b53b0d99SNicholas Bellinger 	bool conn_found = false;
4447e48354ceSNicholas Bellinger 
4448e48354ceSNicholas Bellinger 	if (!sess)
4449e48354ceSNicholas Bellinger 		return;
4450e48354ceSNicholas Bellinger 
4451e48354ceSNicholas Bellinger 	spin_lock_bh(&sess->conn_lock);
4452e48354ceSNicholas Bellinger 	list_for_each_entry(l_conn, &sess->sess_conn_list, conn_list) {
4453e48354ceSNicholas Bellinger 		if (l_conn->cid == cid) {
4454e48354ceSNicholas Bellinger 			iscsit_inc_conn_usage_count(l_conn);
4455b53b0d99SNicholas Bellinger 			conn_found = true;
4456e48354ceSNicholas Bellinger 			break;
4457e48354ceSNicholas Bellinger 		}
4458e48354ceSNicholas Bellinger 	}
4459e48354ceSNicholas Bellinger 	spin_unlock_bh(&sess->conn_lock);
4460e48354ceSNicholas Bellinger 
4461b53b0d99SNicholas Bellinger 	if (!conn_found)
4462e48354ceSNicholas Bellinger 		return;
4463e48354ceSNicholas Bellinger 
4464e48354ceSNicholas Bellinger 	if (l_conn->sock)
4465e48354ceSNicholas Bellinger 		l_conn->sock->ops->shutdown(l_conn->sock, RCV_SHUTDOWN);
4466e48354ceSNicholas Bellinger 
4467e48354ceSNicholas Bellinger 	spin_lock_bh(&l_conn->state_lock);
4468e48354ceSNicholas Bellinger 	pr_debug("Moving to TARG_CONN_STATE_IN_LOGOUT.\n");
4469e48354ceSNicholas Bellinger 	l_conn->conn_state = TARG_CONN_STATE_IN_LOGOUT;
4470e48354ceSNicholas Bellinger 	spin_unlock_bh(&l_conn->state_lock);
4471e48354ceSNicholas Bellinger 
4472e48354ceSNicholas Bellinger 	iscsit_cause_connection_reinstatement(l_conn, 1);
4473e48354ceSNicholas Bellinger 	iscsit_dec_conn_usage_count(l_conn);
4474e48354ceSNicholas Bellinger }
4475e48354ceSNicholas Bellinger 
4476e48354ceSNicholas Bellinger /*
4477e48354ceSNicholas Bellinger  *	Return of 0 causes the TX thread to restart.
4478e48354ceSNicholas Bellinger  */
44792ec5a8c1SNicholas Bellinger int iscsit_logout_post_handler(
4480e48354ceSNicholas Bellinger 	struct iscsi_cmd *cmd,
4481e48354ceSNicholas Bellinger 	struct iscsi_conn *conn)
4482e48354ceSNicholas Bellinger {
4483e48354ceSNicholas Bellinger 	int ret = 0;
4484e48354ceSNicholas Bellinger 
4485e48354ceSNicholas Bellinger 	switch (cmd->logout_reason) {
4486e48354ceSNicholas Bellinger 	case ISCSI_LOGOUT_REASON_CLOSE_SESSION:
4487e48354ceSNicholas Bellinger 		switch (cmd->logout_response) {
4488e48354ceSNicholas Bellinger 		case ISCSI_LOGOUT_SUCCESS:
4489e48354ceSNicholas Bellinger 		case ISCSI_LOGOUT_CLEANUP_FAILED:
4490e48354ceSNicholas Bellinger 		default:
4491e48354ceSNicholas Bellinger 			iscsit_logout_post_handler_closesession(conn);
4492e48354ceSNicholas Bellinger 			break;
4493e48354ceSNicholas Bellinger 		}
4494e48354ceSNicholas Bellinger 		ret = 0;
4495e48354ceSNicholas Bellinger 		break;
4496e48354ceSNicholas Bellinger 	case ISCSI_LOGOUT_REASON_CLOSE_CONNECTION:
4497e48354ceSNicholas Bellinger 		if (conn->cid == cmd->logout_cid) {
4498e48354ceSNicholas Bellinger 			switch (cmd->logout_response) {
4499e48354ceSNicholas Bellinger 			case ISCSI_LOGOUT_SUCCESS:
4500e48354ceSNicholas Bellinger 			case ISCSI_LOGOUT_CLEANUP_FAILED:
4501e48354ceSNicholas Bellinger 			default:
4502e48354ceSNicholas Bellinger 				iscsit_logout_post_handler_samecid(conn);
4503e48354ceSNicholas Bellinger 				break;
4504e48354ceSNicholas Bellinger 			}
4505e48354ceSNicholas Bellinger 			ret = 0;
4506e48354ceSNicholas Bellinger 		} else {
4507e48354ceSNicholas Bellinger 			switch (cmd->logout_response) {
4508e48354ceSNicholas Bellinger 			case ISCSI_LOGOUT_SUCCESS:
4509e48354ceSNicholas Bellinger 				iscsit_logout_post_handler_diffcid(conn,
4510e48354ceSNicholas Bellinger 					cmd->logout_cid);
4511e48354ceSNicholas Bellinger 				break;
4512e48354ceSNicholas Bellinger 			case ISCSI_LOGOUT_CID_NOT_FOUND:
4513e48354ceSNicholas Bellinger 			case ISCSI_LOGOUT_CLEANUP_FAILED:
4514e48354ceSNicholas Bellinger 			default:
4515e48354ceSNicholas Bellinger 				break;
4516e48354ceSNicholas Bellinger 			}
4517e48354ceSNicholas Bellinger 			ret = 1;
4518e48354ceSNicholas Bellinger 		}
4519e48354ceSNicholas Bellinger 		break;
4520e48354ceSNicholas Bellinger 	case ISCSI_LOGOUT_REASON_RECOVERY:
4521e48354ceSNicholas Bellinger 		switch (cmd->logout_response) {
4522e48354ceSNicholas Bellinger 		case ISCSI_LOGOUT_SUCCESS:
4523e48354ceSNicholas Bellinger 		case ISCSI_LOGOUT_CID_NOT_FOUND:
4524e48354ceSNicholas Bellinger 		case ISCSI_LOGOUT_RECOVERY_UNSUPPORTED:
4525e48354ceSNicholas Bellinger 		case ISCSI_LOGOUT_CLEANUP_FAILED:
4526e48354ceSNicholas Bellinger 		default:
4527e48354ceSNicholas Bellinger 			break;
4528e48354ceSNicholas Bellinger 		}
4529e48354ceSNicholas Bellinger 		ret = 1;
4530e48354ceSNicholas Bellinger 		break;
4531e48354ceSNicholas Bellinger 	default:
4532e48354ceSNicholas Bellinger 		break;
4533e48354ceSNicholas Bellinger 
4534e48354ceSNicholas Bellinger 	}
4535e48354ceSNicholas Bellinger 	return ret;
4536e48354ceSNicholas Bellinger }
45372ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_logout_post_handler);
4538e48354ceSNicholas Bellinger 
4539e48354ceSNicholas Bellinger void iscsit_fail_session(struct iscsi_session *sess)
4540e48354ceSNicholas Bellinger {
4541e48354ceSNicholas Bellinger 	struct iscsi_conn *conn;
4542e48354ceSNicholas Bellinger 
4543e48354ceSNicholas Bellinger 	spin_lock_bh(&sess->conn_lock);
4544e48354ceSNicholas Bellinger 	list_for_each_entry(conn, &sess->sess_conn_list, conn_list) {
4545e48354ceSNicholas Bellinger 		pr_debug("Moving to TARG_CONN_STATE_CLEANUP_WAIT.\n");
4546e48354ceSNicholas Bellinger 		conn->conn_state = TARG_CONN_STATE_CLEANUP_WAIT;
4547e48354ceSNicholas Bellinger 	}
4548e48354ceSNicholas Bellinger 	spin_unlock_bh(&sess->conn_lock);
4549e48354ceSNicholas Bellinger 
4550e48354ceSNicholas Bellinger 	pr_debug("Moving to TARG_SESS_STATE_FAILED.\n");
4551e48354ceSNicholas Bellinger 	sess->session_state = TARG_SESS_STATE_FAILED;
4552e48354ceSNicholas Bellinger }
4553e48354ceSNicholas Bellinger 
4554e48354ceSNicholas Bellinger int iscsit_free_session(struct iscsi_session *sess)
4555e48354ceSNicholas Bellinger {
4556e48354ceSNicholas Bellinger 	u16 conn_count = atomic_read(&sess->nconn);
4557e48354ceSNicholas Bellinger 	struct iscsi_conn *conn, *conn_tmp = NULL;
4558e48354ceSNicholas Bellinger 	int is_last;
4559e48354ceSNicholas Bellinger 
4560e48354ceSNicholas Bellinger 	spin_lock_bh(&sess->conn_lock);
4561e48354ceSNicholas Bellinger 	atomic_set(&sess->sleep_on_sess_wait_comp, 1);
4562e48354ceSNicholas Bellinger 
4563e48354ceSNicholas Bellinger 	list_for_each_entry_safe(conn, conn_tmp, &sess->sess_conn_list,
4564e48354ceSNicholas Bellinger 			conn_list) {
4565e48354ceSNicholas Bellinger 		if (conn_count == 0)
4566e48354ceSNicholas Bellinger 			break;
4567e48354ceSNicholas Bellinger 
4568e48354ceSNicholas Bellinger 		if (list_is_last(&conn->conn_list, &sess->sess_conn_list)) {
4569e48354ceSNicholas Bellinger 			is_last = 1;
4570e48354ceSNicholas Bellinger 		} else {
4571e48354ceSNicholas Bellinger 			iscsit_inc_conn_usage_count(conn_tmp);
4572e48354ceSNicholas Bellinger 			is_last = 0;
4573e48354ceSNicholas Bellinger 		}
4574e48354ceSNicholas Bellinger 		iscsit_inc_conn_usage_count(conn);
4575e48354ceSNicholas Bellinger 
4576e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
4577e48354ceSNicholas Bellinger 		iscsit_cause_connection_reinstatement(conn, 1);
4578e48354ceSNicholas Bellinger 		spin_lock_bh(&sess->conn_lock);
4579e48354ceSNicholas Bellinger 
4580e48354ceSNicholas Bellinger 		iscsit_dec_conn_usage_count(conn);
4581e48354ceSNicholas Bellinger 		if (is_last == 0)
4582e48354ceSNicholas Bellinger 			iscsit_dec_conn_usage_count(conn_tmp);
4583e48354ceSNicholas Bellinger 
4584e48354ceSNicholas Bellinger 		conn_count--;
4585e48354ceSNicholas Bellinger 	}
4586e48354ceSNicholas Bellinger 
4587e48354ceSNicholas Bellinger 	if (atomic_read(&sess->nconn)) {
4588e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
4589e48354ceSNicholas Bellinger 		wait_for_completion(&sess->session_wait_comp);
4590e48354ceSNicholas Bellinger 	} else
4591e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
4592e48354ceSNicholas Bellinger 
459344f33d0fSChristoph Hellwig 	iscsit_close_session(sess);
4594e48354ceSNicholas Bellinger 	return 0;
4595e48354ceSNicholas Bellinger }
4596e48354ceSNicholas Bellinger 
4597e48354ceSNicholas Bellinger void iscsit_stop_session(
4598e48354ceSNicholas Bellinger 	struct iscsi_session *sess,
4599e48354ceSNicholas Bellinger 	int session_sleep,
4600e48354ceSNicholas Bellinger 	int connection_sleep)
4601e48354ceSNicholas Bellinger {
4602e48354ceSNicholas Bellinger 	u16 conn_count = atomic_read(&sess->nconn);
4603e48354ceSNicholas Bellinger 	struct iscsi_conn *conn, *conn_tmp = NULL;
4604e48354ceSNicholas Bellinger 	int is_last;
4605e48354ceSNicholas Bellinger 
4606e48354ceSNicholas Bellinger 	spin_lock_bh(&sess->conn_lock);
4607e48354ceSNicholas Bellinger 	if (session_sleep)
4608e48354ceSNicholas Bellinger 		atomic_set(&sess->sleep_on_sess_wait_comp, 1);
4609e48354ceSNicholas Bellinger 
4610e48354ceSNicholas Bellinger 	if (connection_sleep) {
4611e48354ceSNicholas Bellinger 		list_for_each_entry_safe(conn, conn_tmp, &sess->sess_conn_list,
4612e48354ceSNicholas Bellinger 				conn_list) {
4613e48354ceSNicholas Bellinger 			if (conn_count == 0)
4614e48354ceSNicholas Bellinger 				break;
4615e48354ceSNicholas Bellinger 
4616e48354ceSNicholas Bellinger 			if (list_is_last(&conn->conn_list, &sess->sess_conn_list)) {
4617e48354ceSNicholas Bellinger 				is_last = 1;
4618e48354ceSNicholas Bellinger 			} else {
4619e48354ceSNicholas Bellinger 				iscsit_inc_conn_usage_count(conn_tmp);
4620e48354ceSNicholas Bellinger 				is_last = 0;
4621e48354ceSNicholas Bellinger 			}
4622e48354ceSNicholas Bellinger 			iscsit_inc_conn_usage_count(conn);
4623e48354ceSNicholas Bellinger 
4624e48354ceSNicholas Bellinger 			spin_unlock_bh(&sess->conn_lock);
4625e48354ceSNicholas Bellinger 			iscsit_cause_connection_reinstatement(conn, 1);
4626e48354ceSNicholas Bellinger 			spin_lock_bh(&sess->conn_lock);
4627e48354ceSNicholas Bellinger 
4628e48354ceSNicholas Bellinger 			iscsit_dec_conn_usage_count(conn);
4629e48354ceSNicholas Bellinger 			if (is_last == 0)
4630e48354ceSNicholas Bellinger 				iscsit_dec_conn_usage_count(conn_tmp);
4631e48354ceSNicholas Bellinger 			conn_count--;
4632e48354ceSNicholas Bellinger 		}
4633e48354ceSNicholas Bellinger 	} else {
4634e48354ceSNicholas Bellinger 		list_for_each_entry(conn, &sess->sess_conn_list, conn_list)
4635e48354ceSNicholas Bellinger 			iscsit_cause_connection_reinstatement(conn, 0);
4636e48354ceSNicholas Bellinger 	}
4637e48354ceSNicholas Bellinger 
4638e48354ceSNicholas Bellinger 	if (session_sleep && atomic_read(&sess->nconn)) {
4639e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
4640e48354ceSNicholas Bellinger 		wait_for_completion(&sess->session_wait_comp);
4641e48354ceSNicholas Bellinger 	} else
4642e48354ceSNicholas Bellinger 		spin_unlock_bh(&sess->conn_lock);
4643e48354ceSNicholas Bellinger }
4644e48354ceSNicholas Bellinger 
4645e48354ceSNicholas Bellinger int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force)
4646e48354ceSNicholas Bellinger {
4647e48354ceSNicholas Bellinger 	struct iscsi_session *sess;
4648e48354ceSNicholas Bellinger 	struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
4649e48354ceSNicholas Bellinger 	struct se_session *se_sess, *se_sess_tmp;
4650417c20a9SNicholas Bellinger 	LIST_HEAD(free_list);
4651e48354ceSNicholas Bellinger 	int session_count = 0;
4652e48354ceSNicholas Bellinger 
4653e48354ceSNicholas Bellinger 	spin_lock_bh(&se_tpg->session_lock);
4654e48354ceSNicholas Bellinger 	if (tpg->nsessions && !force) {
4655e48354ceSNicholas Bellinger 		spin_unlock_bh(&se_tpg->session_lock);
4656e48354ceSNicholas Bellinger 		return -1;
4657e48354ceSNicholas Bellinger 	}
4658e48354ceSNicholas Bellinger 
4659e48354ceSNicholas Bellinger 	list_for_each_entry_safe(se_sess, se_sess_tmp, &se_tpg->tpg_sess_list,
4660e48354ceSNicholas Bellinger 			sess_list) {
4661e48354ceSNicholas Bellinger 		sess = (struct iscsi_session *)se_sess->fabric_sess_ptr;
4662e48354ceSNicholas Bellinger 
4663e48354ceSNicholas Bellinger 		spin_lock(&sess->conn_lock);
4664e48354ceSNicholas Bellinger 		if (atomic_read(&sess->session_fall_back_to_erl0) ||
4665e48354ceSNicholas Bellinger 		    atomic_read(&sess->session_logout) ||
4666e48354ceSNicholas Bellinger 		    (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)) {
4667e48354ceSNicholas Bellinger 			spin_unlock(&sess->conn_lock);
4668e48354ceSNicholas Bellinger 			continue;
4669e48354ceSNicholas Bellinger 		}
4670e48354ceSNicholas Bellinger 		atomic_set(&sess->session_reinstatement, 1);
4671e48354ceSNicholas Bellinger 		spin_unlock(&sess->conn_lock);
4672e48354ceSNicholas Bellinger 
4673417c20a9SNicholas Bellinger 		list_move_tail(&se_sess->sess_list, &free_list);
4674e48354ceSNicholas Bellinger 	}
4675e48354ceSNicholas Bellinger 	spin_unlock_bh(&se_tpg->session_lock);
4676e48354ceSNicholas Bellinger 
4677417c20a9SNicholas Bellinger 	list_for_each_entry_safe(se_sess, se_sess_tmp, &free_list, sess_list) {
4678417c20a9SNicholas Bellinger 		sess = (struct iscsi_session *)se_sess->fabric_sess_ptr;
4679417c20a9SNicholas Bellinger 
4680417c20a9SNicholas Bellinger 		iscsit_free_session(sess);
4681417c20a9SNicholas Bellinger 		session_count++;
4682417c20a9SNicholas Bellinger 	}
4683417c20a9SNicholas Bellinger 
4684e48354ceSNicholas Bellinger 	pr_debug("Released %d iSCSI Session(s) from Target Portal"
4685e48354ceSNicholas Bellinger 			" Group: %hu\n", session_count, tpg->tpgt);
4686e48354ceSNicholas Bellinger 	return 0;
4687e48354ceSNicholas Bellinger }
4688e48354ceSNicholas Bellinger 
4689e48354ceSNicholas Bellinger MODULE_DESCRIPTION("iSCSI-Target Driver for mainline target infrastructure");
4690e48354ceSNicholas Bellinger MODULE_VERSION("4.1.x");
4691e48354ceSNicholas Bellinger MODULE_AUTHOR("nab@Linux-iSCSI.org");
4692e48354ceSNicholas Bellinger MODULE_LICENSE("GPL");
4693e48354ceSNicholas Bellinger 
4694e48354ceSNicholas Bellinger module_init(iscsi_target_init_module);
4695e48354ceSNicholas Bellinger module_exit(iscsi_target_cleanup_module);
4696