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