1e48354ceSNicholas Bellinger /******************************************************************************* 2e48354ceSNicholas Bellinger * This file contains main functions related to the iSCSI Target Core Driver. 3e48354ceSNicholas Bellinger * 4e48354ceSNicholas Bellinger * \u00a9 Copyright 2007-2011 RisingTide Systems LLC. 5e48354ceSNicholas Bellinger * 6e48354ceSNicholas Bellinger * Licensed to the Linux Foundation under the General Public License (GPL) version 2. 7e48354ceSNicholas Bellinger * 8e48354ceSNicholas Bellinger * Author: Nicholas A. Bellinger <nab@linux-iscsi.org> 9e48354ceSNicholas Bellinger * 10e48354ceSNicholas Bellinger * This program is free software; you can redistribute it and/or modify 11e48354ceSNicholas Bellinger * it under the terms of the GNU General Public License as published by 12e48354ceSNicholas Bellinger * the Free Software Foundation; either version 2 of the License, or 13e48354ceSNicholas Bellinger * (at your option) any later version. 14e48354ceSNicholas Bellinger * 15e48354ceSNicholas Bellinger * This program is distributed in the hope that it will be useful, 16e48354ceSNicholas Bellinger * but WITHOUT ANY WARRANTY; without even the implied warranty of 17e48354ceSNicholas Bellinger * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18e48354ceSNicholas Bellinger * GNU General Public License for more details. 19e48354ceSNicholas Bellinger ******************************************************************************/ 20e48354ceSNicholas Bellinger 21e48354ceSNicholas Bellinger #include <linux/string.h> 22e48354ceSNicholas Bellinger #include <linux/kthread.h> 23e48354ceSNicholas Bellinger #include <linux/crypto.h> 24e48354ceSNicholas Bellinger #include <linux/completion.h> 25827509e3SPaul Gortmaker #include <linux/module.h> 2640401530SAl Viro #include <linux/idr.h> 27e48354ceSNicholas Bellinger #include <asm/unaligned.h> 28e48354ceSNicholas Bellinger #include <scsi/scsi_device.h> 29e48354ceSNicholas Bellinger #include <scsi/iscsi_proto.h> 30d28b1169SAndy Grover #include <scsi/scsi_tcq.h> 31e48354ceSNicholas Bellinger #include <target/target_core_base.h> 32c4795fb2SChristoph Hellwig #include <target/target_core_fabric.h> 33d28b1169SAndy Grover #include <target/target_core_configfs.h> 34e48354ceSNicholas Bellinger 35e48354ceSNicholas Bellinger #include "iscsi_target_core.h" 36e48354ceSNicholas Bellinger #include "iscsi_target_parameters.h" 37e48354ceSNicholas Bellinger #include "iscsi_target_seq_pdu_list.h" 38e48354ceSNicholas Bellinger #include "iscsi_target_tq.h" 39e48354ceSNicholas Bellinger #include "iscsi_target_configfs.h" 40e48354ceSNicholas Bellinger #include "iscsi_target_datain_values.h" 41e48354ceSNicholas Bellinger #include "iscsi_target_erl0.h" 42e48354ceSNicholas Bellinger #include "iscsi_target_erl1.h" 43e48354ceSNicholas Bellinger #include "iscsi_target_erl2.h" 44e48354ceSNicholas Bellinger #include "iscsi_target_login.h" 45e48354ceSNicholas Bellinger #include "iscsi_target_tmr.h" 46e48354ceSNicholas Bellinger #include "iscsi_target_tpg.h" 47e48354ceSNicholas Bellinger #include "iscsi_target_util.h" 48e48354ceSNicholas Bellinger #include "iscsi_target.h" 49e48354ceSNicholas Bellinger #include "iscsi_target_device.h" 50e48354ceSNicholas Bellinger #include "iscsi_target_stat.h" 51e48354ceSNicholas Bellinger 52baa4d64bSNicholas Bellinger #include <target/iscsi/iscsi_transport.h> 53baa4d64bSNicholas Bellinger 54e48354ceSNicholas Bellinger static LIST_HEAD(g_tiqn_list); 55e48354ceSNicholas Bellinger static LIST_HEAD(g_np_list); 56e48354ceSNicholas Bellinger static DEFINE_SPINLOCK(tiqn_lock); 57e48354ceSNicholas Bellinger static DEFINE_SPINLOCK(np_lock); 58e48354ceSNicholas Bellinger 59e48354ceSNicholas Bellinger static struct idr tiqn_idr; 60e48354ceSNicholas Bellinger struct idr sess_idr; 61e48354ceSNicholas Bellinger struct mutex auth_id_lock; 62e48354ceSNicholas Bellinger spinlock_t sess_idr_lock; 63e48354ceSNicholas Bellinger 64e48354ceSNicholas Bellinger struct iscsit_global *iscsit_global; 65e48354ceSNicholas Bellinger 66e48354ceSNicholas Bellinger struct kmem_cache *lio_cmd_cache; 67e48354ceSNicholas Bellinger struct kmem_cache *lio_qr_cache; 68e48354ceSNicholas Bellinger struct kmem_cache *lio_dr_cache; 69e48354ceSNicholas Bellinger struct kmem_cache *lio_ooo_cache; 70e48354ceSNicholas Bellinger struct kmem_cache *lio_r2t_cache; 71e48354ceSNicholas Bellinger 72e48354ceSNicholas Bellinger static int iscsit_handle_immediate_data(struct iscsi_cmd *, 732ec5a8c1SNicholas Bellinger struct iscsi_scsi_req *, u32); 74e48354ceSNicholas Bellinger 75e48354ceSNicholas Bellinger struct iscsi_tiqn *iscsit_get_tiqn_for_login(unsigned char *buf) 76e48354ceSNicholas Bellinger { 77e48354ceSNicholas Bellinger struct iscsi_tiqn *tiqn = NULL; 78e48354ceSNicholas Bellinger 79e48354ceSNicholas Bellinger spin_lock(&tiqn_lock); 80e48354ceSNicholas Bellinger list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) { 81e48354ceSNicholas Bellinger if (!strcmp(tiqn->tiqn, buf)) { 82e48354ceSNicholas Bellinger 83e48354ceSNicholas Bellinger spin_lock(&tiqn->tiqn_state_lock); 84e48354ceSNicholas Bellinger if (tiqn->tiqn_state == TIQN_STATE_ACTIVE) { 85e48354ceSNicholas Bellinger tiqn->tiqn_access_count++; 86e48354ceSNicholas Bellinger spin_unlock(&tiqn->tiqn_state_lock); 87e48354ceSNicholas Bellinger spin_unlock(&tiqn_lock); 88e48354ceSNicholas Bellinger return tiqn; 89e48354ceSNicholas Bellinger } 90e48354ceSNicholas Bellinger spin_unlock(&tiqn->tiqn_state_lock); 91e48354ceSNicholas Bellinger } 92e48354ceSNicholas Bellinger } 93e48354ceSNicholas Bellinger spin_unlock(&tiqn_lock); 94e48354ceSNicholas Bellinger 95e48354ceSNicholas Bellinger return NULL; 96e48354ceSNicholas Bellinger } 97e48354ceSNicholas Bellinger 98e48354ceSNicholas Bellinger static int iscsit_set_tiqn_shutdown(struct iscsi_tiqn *tiqn) 99e48354ceSNicholas Bellinger { 100e48354ceSNicholas Bellinger spin_lock(&tiqn->tiqn_state_lock); 101e48354ceSNicholas Bellinger if (tiqn->tiqn_state == TIQN_STATE_ACTIVE) { 102e48354ceSNicholas Bellinger tiqn->tiqn_state = TIQN_STATE_SHUTDOWN; 103e48354ceSNicholas Bellinger spin_unlock(&tiqn->tiqn_state_lock); 104e48354ceSNicholas Bellinger return 0; 105e48354ceSNicholas Bellinger } 106e48354ceSNicholas Bellinger spin_unlock(&tiqn->tiqn_state_lock); 107e48354ceSNicholas Bellinger 108e48354ceSNicholas Bellinger return -1; 109e48354ceSNicholas Bellinger } 110e48354ceSNicholas Bellinger 111e48354ceSNicholas Bellinger void iscsit_put_tiqn_for_login(struct iscsi_tiqn *tiqn) 112e48354ceSNicholas Bellinger { 113e48354ceSNicholas Bellinger spin_lock(&tiqn->tiqn_state_lock); 114e48354ceSNicholas Bellinger tiqn->tiqn_access_count--; 115e48354ceSNicholas Bellinger spin_unlock(&tiqn->tiqn_state_lock); 116e48354ceSNicholas Bellinger } 117e48354ceSNicholas Bellinger 118e48354ceSNicholas Bellinger /* 119e48354ceSNicholas Bellinger * Note that IQN formatting is expected to be done in userspace, and 120e48354ceSNicholas Bellinger * no explict IQN format checks are done here. 121e48354ceSNicholas Bellinger */ 122e48354ceSNicholas Bellinger struct iscsi_tiqn *iscsit_add_tiqn(unsigned char *buf) 123e48354ceSNicholas Bellinger { 124e48354ceSNicholas Bellinger struct iscsi_tiqn *tiqn = NULL; 125e48354ceSNicholas Bellinger int ret; 126e48354ceSNicholas Bellinger 1278f50c7f5SDan Carpenter if (strlen(buf) >= ISCSI_IQN_LEN) { 128e48354ceSNicholas Bellinger pr_err("Target IQN exceeds %d bytes\n", 129e48354ceSNicholas Bellinger ISCSI_IQN_LEN); 130e48354ceSNicholas Bellinger return ERR_PTR(-EINVAL); 131e48354ceSNicholas Bellinger } 132e48354ceSNicholas Bellinger 133e48354ceSNicholas Bellinger tiqn = kzalloc(sizeof(struct iscsi_tiqn), GFP_KERNEL); 134e48354ceSNicholas Bellinger if (!tiqn) { 135e48354ceSNicholas Bellinger pr_err("Unable to allocate struct iscsi_tiqn\n"); 136e48354ceSNicholas Bellinger return ERR_PTR(-ENOMEM); 137e48354ceSNicholas Bellinger } 138e48354ceSNicholas Bellinger 139e48354ceSNicholas Bellinger sprintf(tiqn->tiqn, "%s", buf); 140e48354ceSNicholas Bellinger INIT_LIST_HEAD(&tiqn->tiqn_list); 141e48354ceSNicholas Bellinger INIT_LIST_HEAD(&tiqn->tiqn_tpg_list); 142e48354ceSNicholas Bellinger spin_lock_init(&tiqn->tiqn_state_lock); 143e48354ceSNicholas Bellinger spin_lock_init(&tiqn->tiqn_tpg_lock); 144e48354ceSNicholas Bellinger spin_lock_init(&tiqn->sess_err_stats.lock); 145e48354ceSNicholas Bellinger spin_lock_init(&tiqn->login_stats.lock); 146e48354ceSNicholas Bellinger spin_lock_init(&tiqn->logout_stats.lock); 147e48354ceSNicholas Bellinger 148e48354ceSNicholas Bellinger tiqn->tiqn_state = TIQN_STATE_ACTIVE; 149e48354ceSNicholas Bellinger 150c9365bd0STejun Heo idr_preload(GFP_KERNEL); 151e48354ceSNicholas Bellinger spin_lock(&tiqn_lock); 152c9365bd0STejun Heo 153c9365bd0STejun Heo ret = idr_alloc(&tiqn_idr, NULL, 0, 0, GFP_NOWAIT); 154e48354ceSNicholas Bellinger if (ret < 0) { 155c9365bd0STejun Heo pr_err("idr_alloc() failed for tiqn->tiqn_index\n"); 156e48354ceSNicholas Bellinger spin_unlock(&tiqn_lock); 157c9365bd0STejun Heo idr_preload_end(); 158e48354ceSNicholas Bellinger kfree(tiqn); 159e48354ceSNicholas Bellinger return ERR_PTR(ret); 160e48354ceSNicholas Bellinger } 161c9365bd0STejun Heo tiqn->tiqn_index = ret; 162e48354ceSNicholas Bellinger list_add_tail(&tiqn->tiqn_list, &g_tiqn_list); 163c9365bd0STejun Heo 164e48354ceSNicholas Bellinger spin_unlock(&tiqn_lock); 165c9365bd0STejun Heo idr_preload_end(); 166e48354ceSNicholas Bellinger 167e48354ceSNicholas Bellinger pr_debug("CORE[0] - Added iSCSI Target IQN: %s\n", tiqn->tiqn); 168e48354ceSNicholas Bellinger 169e48354ceSNicholas Bellinger return tiqn; 170e48354ceSNicholas Bellinger 171e48354ceSNicholas Bellinger } 172e48354ceSNicholas Bellinger 173e48354ceSNicholas Bellinger static void iscsit_wait_for_tiqn(struct iscsi_tiqn *tiqn) 174e48354ceSNicholas Bellinger { 175e48354ceSNicholas Bellinger /* 176e48354ceSNicholas Bellinger * Wait for accesses to said struct iscsi_tiqn to end. 177e48354ceSNicholas Bellinger */ 178e48354ceSNicholas Bellinger spin_lock(&tiqn->tiqn_state_lock); 179e48354ceSNicholas Bellinger while (tiqn->tiqn_access_count != 0) { 180e48354ceSNicholas Bellinger spin_unlock(&tiqn->tiqn_state_lock); 181e48354ceSNicholas Bellinger msleep(10); 182e48354ceSNicholas Bellinger spin_lock(&tiqn->tiqn_state_lock); 183e48354ceSNicholas Bellinger } 184e48354ceSNicholas Bellinger spin_unlock(&tiqn->tiqn_state_lock); 185e48354ceSNicholas Bellinger } 186e48354ceSNicholas Bellinger 187e48354ceSNicholas Bellinger void iscsit_del_tiqn(struct iscsi_tiqn *tiqn) 188e48354ceSNicholas Bellinger { 189e48354ceSNicholas Bellinger /* 190e48354ceSNicholas Bellinger * iscsit_set_tiqn_shutdown sets tiqn->tiqn_state = TIQN_STATE_SHUTDOWN 191e48354ceSNicholas Bellinger * while holding tiqn->tiqn_state_lock. This means that all subsequent 192e48354ceSNicholas Bellinger * attempts to access this struct iscsi_tiqn will fail from both transport 193e48354ceSNicholas Bellinger * fabric and control code paths. 194e48354ceSNicholas Bellinger */ 195e48354ceSNicholas Bellinger if (iscsit_set_tiqn_shutdown(tiqn) < 0) { 196e48354ceSNicholas Bellinger pr_err("iscsit_set_tiqn_shutdown() failed\n"); 197e48354ceSNicholas Bellinger return; 198e48354ceSNicholas Bellinger } 199e48354ceSNicholas Bellinger 200e48354ceSNicholas Bellinger iscsit_wait_for_tiqn(tiqn); 201e48354ceSNicholas Bellinger 202e48354ceSNicholas Bellinger spin_lock(&tiqn_lock); 203e48354ceSNicholas Bellinger list_del(&tiqn->tiqn_list); 204e48354ceSNicholas Bellinger idr_remove(&tiqn_idr, tiqn->tiqn_index); 205e48354ceSNicholas Bellinger spin_unlock(&tiqn_lock); 206e48354ceSNicholas Bellinger 207e48354ceSNicholas Bellinger pr_debug("CORE[0] - Deleted iSCSI Target IQN: %s\n", 208e48354ceSNicholas Bellinger tiqn->tiqn); 209e48354ceSNicholas Bellinger kfree(tiqn); 210e48354ceSNicholas Bellinger } 211e48354ceSNicholas Bellinger 212e48354ceSNicholas Bellinger int iscsit_access_np(struct iscsi_np *np, struct iscsi_portal_group *tpg) 213e48354ceSNicholas Bellinger { 214e48354ceSNicholas Bellinger int ret; 215e48354ceSNicholas Bellinger /* 216e48354ceSNicholas Bellinger * Determine if the network portal is accepting storage traffic. 217e48354ceSNicholas Bellinger */ 218e48354ceSNicholas Bellinger spin_lock_bh(&np->np_thread_lock); 219e48354ceSNicholas Bellinger if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) { 220e48354ceSNicholas Bellinger spin_unlock_bh(&np->np_thread_lock); 221e48354ceSNicholas Bellinger return -1; 222e48354ceSNicholas Bellinger } 223e48354ceSNicholas Bellinger if (np->np_login_tpg) { 224e48354ceSNicholas Bellinger pr_err("np->np_login_tpg() is not NULL!\n"); 225e48354ceSNicholas Bellinger spin_unlock_bh(&np->np_thread_lock); 226e48354ceSNicholas Bellinger return -1; 227e48354ceSNicholas Bellinger } 228e48354ceSNicholas Bellinger spin_unlock_bh(&np->np_thread_lock); 229e48354ceSNicholas Bellinger /* 230e48354ceSNicholas Bellinger * Determine if the portal group is accepting storage traffic. 231e48354ceSNicholas Bellinger */ 232e48354ceSNicholas Bellinger spin_lock_bh(&tpg->tpg_state_lock); 233e48354ceSNicholas Bellinger if (tpg->tpg_state != TPG_STATE_ACTIVE) { 234e48354ceSNicholas Bellinger spin_unlock_bh(&tpg->tpg_state_lock); 235e48354ceSNicholas Bellinger return -1; 236e48354ceSNicholas Bellinger } 237e48354ceSNicholas Bellinger spin_unlock_bh(&tpg->tpg_state_lock); 238e48354ceSNicholas Bellinger 239e48354ceSNicholas Bellinger /* 240e48354ceSNicholas Bellinger * Here we serialize access across the TIQN+TPG Tuple. 241e48354ceSNicholas Bellinger */ 242e48354ceSNicholas Bellinger ret = mutex_lock_interruptible(&tpg->np_login_lock); 243e48354ceSNicholas Bellinger if ((ret != 0) || signal_pending(current)) 244e48354ceSNicholas Bellinger return -1; 245e48354ceSNicholas Bellinger 246e48354ceSNicholas Bellinger spin_lock_bh(&np->np_thread_lock); 247e48354ceSNicholas Bellinger np->np_login_tpg = tpg; 248e48354ceSNicholas Bellinger spin_unlock_bh(&np->np_thread_lock); 249e48354ceSNicholas Bellinger 250e48354ceSNicholas Bellinger return 0; 251e48354ceSNicholas Bellinger } 252e48354ceSNicholas Bellinger 253e48354ceSNicholas Bellinger int iscsit_deaccess_np(struct iscsi_np *np, struct iscsi_portal_group *tpg) 254e48354ceSNicholas Bellinger { 255e48354ceSNicholas Bellinger struct iscsi_tiqn *tiqn = tpg->tpg_tiqn; 256e48354ceSNicholas Bellinger 257e48354ceSNicholas Bellinger spin_lock_bh(&np->np_thread_lock); 258e48354ceSNicholas Bellinger np->np_login_tpg = NULL; 259e48354ceSNicholas Bellinger spin_unlock_bh(&np->np_thread_lock); 260e48354ceSNicholas Bellinger 261e48354ceSNicholas Bellinger mutex_unlock(&tpg->np_login_lock); 262e48354ceSNicholas Bellinger 263e48354ceSNicholas Bellinger if (tiqn) 264e48354ceSNicholas Bellinger iscsit_put_tiqn_for_login(tiqn); 265e48354ceSNicholas Bellinger 266e48354ceSNicholas Bellinger return 0; 267e48354ceSNicholas Bellinger } 268e48354ceSNicholas Bellinger 26905b96892SNicholas Bellinger bool iscsit_check_np_match( 270e48354ceSNicholas Bellinger struct __kernel_sockaddr_storage *sockaddr, 27105b96892SNicholas Bellinger struct iscsi_np *np, 272e48354ceSNicholas Bellinger int network_transport) 273e48354ceSNicholas Bellinger { 274e48354ceSNicholas Bellinger struct sockaddr_in *sock_in, *sock_in_e; 275e48354ceSNicholas Bellinger struct sockaddr_in6 *sock_in6, *sock_in6_e; 27605b96892SNicholas Bellinger bool ip_match = false; 277e48354ceSNicholas Bellinger u16 port; 278e48354ceSNicholas Bellinger 27905b96892SNicholas Bellinger if (sockaddr->ss_family == AF_INET6) { 28005b96892SNicholas Bellinger sock_in6 = (struct sockaddr_in6 *)sockaddr; 28105b96892SNicholas Bellinger sock_in6_e = (struct sockaddr_in6 *)&np->np_sockaddr; 28205b96892SNicholas Bellinger 28305b96892SNicholas Bellinger if (!memcmp(&sock_in6->sin6_addr.in6_u, 28405b96892SNicholas Bellinger &sock_in6_e->sin6_addr.in6_u, 28505b96892SNicholas Bellinger sizeof(struct in6_addr))) 28605b96892SNicholas Bellinger ip_match = true; 28705b96892SNicholas Bellinger 28805b96892SNicholas Bellinger port = ntohs(sock_in6->sin6_port); 28905b96892SNicholas Bellinger } else { 29005b96892SNicholas Bellinger sock_in = (struct sockaddr_in *)sockaddr; 29105b96892SNicholas Bellinger sock_in_e = (struct sockaddr_in *)&np->np_sockaddr; 29205b96892SNicholas Bellinger 29305b96892SNicholas Bellinger if (sock_in->sin_addr.s_addr == sock_in_e->sin_addr.s_addr) 29405b96892SNicholas Bellinger ip_match = true; 29505b96892SNicholas Bellinger 29605b96892SNicholas Bellinger port = ntohs(sock_in->sin_port); 29705b96892SNicholas Bellinger } 29805b96892SNicholas Bellinger 29905b96892SNicholas Bellinger if ((ip_match == true) && (np->np_port == port) && 30005b96892SNicholas Bellinger (np->np_network_transport == network_transport)) 30105b96892SNicholas Bellinger return true; 30205b96892SNicholas Bellinger 30305b96892SNicholas Bellinger return false; 30405b96892SNicholas Bellinger } 30505b96892SNicholas Bellinger 30605b96892SNicholas Bellinger static struct iscsi_np *iscsit_get_np( 30705b96892SNicholas Bellinger struct __kernel_sockaddr_storage *sockaddr, 30805b96892SNicholas Bellinger int network_transport) 30905b96892SNicholas Bellinger { 31005b96892SNicholas Bellinger struct iscsi_np *np; 31105b96892SNicholas Bellinger bool match; 31205b96892SNicholas Bellinger 313e48354ceSNicholas Bellinger spin_lock_bh(&np_lock); 314e48354ceSNicholas Bellinger list_for_each_entry(np, &g_np_list, np_list) { 315e48354ceSNicholas Bellinger spin_lock(&np->np_thread_lock); 316e48354ceSNicholas Bellinger if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) { 317e48354ceSNicholas Bellinger spin_unlock(&np->np_thread_lock); 318e48354ceSNicholas Bellinger continue; 319e48354ceSNicholas Bellinger } 320e48354ceSNicholas Bellinger 32105b96892SNicholas Bellinger match = iscsit_check_np_match(sockaddr, np, network_transport); 32205b96892SNicholas Bellinger if (match == true) { 323e48354ceSNicholas Bellinger /* 324e48354ceSNicholas Bellinger * Increment the np_exports reference count now to 325e48354ceSNicholas Bellinger * prevent iscsit_del_np() below from being called 326e48354ceSNicholas Bellinger * while iscsi_tpg_add_network_portal() is called. 327e48354ceSNicholas Bellinger */ 328e48354ceSNicholas Bellinger np->np_exports++; 329e48354ceSNicholas Bellinger spin_unlock(&np->np_thread_lock); 330e48354ceSNicholas Bellinger spin_unlock_bh(&np_lock); 331e48354ceSNicholas Bellinger return np; 332e48354ceSNicholas Bellinger } 333e48354ceSNicholas Bellinger spin_unlock(&np->np_thread_lock); 334e48354ceSNicholas Bellinger } 335e48354ceSNicholas Bellinger spin_unlock_bh(&np_lock); 336e48354ceSNicholas Bellinger 337e48354ceSNicholas Bellinger return NULL; 338e48354ceSNicholas Bellinger } 339e48354ceSNicholas Bellinger 340e48354ceSNicholas Bellinger struct iscsi_np *iscsit_add_np( 341e48354ceSNicholas Bellinger struct __kernel_sockaddr_storage *sockaddr, 342e48354ceSNicholas Bellinger char *ip_str, 343e48354ceSNicholas Bellinger int network_transport) 344e48354ceSNicholas Bellinger { 345e48354ceSNicholas Bellinger struct sockaddr_in *sock_in; 346e48354ceSNicholas Bellinger struct sockaddr_in6 *sock_in6; 347e48354ceSNicholas Bellinger struct iscsi_np *np; 348e48354ceSNicholas Bellinger int ret; 349e48354ceSNicholas Bellinger /* 350e48354ceSNicholas Bellinger * Locate the existing struct iscsi_np if already active.. 351e48354ceSNicholas Bellinger */ 352e48354ceSNicholas Bellinger np = iscsit_get_np(sockaddr, network_transport); 353e48354ceSNicholas Bellinger if (np) 354e48354ceSNicholas Bellinger return np; 355e48354ceSNicholas Bellinger 356e48354ceSNicholas Bellinger np = kzalloc(sizeof(struct iscsi_np), GFP_KERNEL); 357e48354ceSNicholas Bellinger if (!np) { 358e48354ceSNicholas Bellinger pr_err("Unable to allocate memory for struct iscsi_np\n"); 359e48354ceSNicholas Bellinger return ERR_PTR(-ENOMEM); 360e48354ceSNicholas Bellinger } 361e48354ceSNicholas Bellinger 362e48354ceSNicholas Bellinger np->np_flags |= NPF_IP_NETWORK; 363e48354ceSNicholas Bellinger if (sockaddr->ss_family == AF_INET6) { 364e48354ceSNicholas Bellinger sock_in6 = (struct sockaddr_in6 *)sockaddr; 365e48354ceSNicholas Bellinger snprintf(np->np_ip, IPV6_ADDRESS_SPACE, "%s", ip_str); 366e48354ceSNicholas Bellinger np->np_port = ntohs(sock_in6->sin6_port); 367e48354ceSNicholas Bellinger } else { 368e48354ceSNicholas Bellinger sock_in = (struct sockaddr_in *)sockaddr; 369e48354ceSNicholas Bellinger sprintf(np->np_ip, "%s", ip_str); 370e48354ceSNicholas Bellinger np->np_port = ntohs(sock_in->sin_port); 371e48354ceSNicholas Bellinger } 372e48354ceSNicholas Bellinger 373e48354ceSNicholas Bellinger np->np_network_transport = network_transport; 374e48354ceSNicholas Bellinger spin_lock_init(&np->np_thread_lock); 375e48354ceSNicholas Bellinger init_completion(&np->np_restart_comp); 376e48354ceSNicholas Bellinger INIT_LIST_HEAD(&np->np_list); 377e48354ceSNicholas Bellinger 378e48354ceSNicholas Bellinger ret = iscsi_target_setup_login_socket(np, sockaddr); 379e48354ceSNicholas Bellinger if (ret != 0) { 380e48354ceSNicholas Bellinger kfree(np); 381e48354ceSNicholas Bellinger return ERR_PTR(ret); 382e48354ceSNicholas Bellinger } 383e48354ceSNicholas Bellinger 384e48354ceSNicholas Bellinger np->np_thread = kthread_run(iscsi_target_login_thread, np, "iscsi_np"); 385e48354ceSNicholas Bellinger if (IS_ERR(np->np_thread)) { 386e48354ceSNicholas Bellinger pr_err("Unable to create kthread: iscsi_np\n"); 387e48354ceSNicholas Bellinger ret = PTR_ERR(np->np_thread); 388e48354ceSNicholas Bellinger kfree(np); 389e48354ceSNicholas Bellinger return ERR_PTR(ret); 390e48354ceSNicholas Bellinger } 391e48354ceSNicholas Bellinger /* 392e48354ceSNicholas Bellinger * Increment the np_exports reference count now to prevent 393e48354ceSNicholas Bellinger * iscsit_del_np() below from being run while a new call to 394e48354ceSNicholas Bellinger * iscsi_tpg_add_network_portal() for a matching iscsi_np is 395e48354ceSNicholas Bellinger * active. We don't need to hold np->np_thread_lock at this 396e48354ceSNicholas Bellinger * point because iscsi_np has not been added to g_np_list yet. 397e48354ceSNicholas Bellinger */ 398e48354ceSNicholas Bellinger np->np_exports = 1; 399e48354ceSNicholas Bellinger 400e48354ceSNicholas Bellinger spin_lock_bh(&np_lock); 401e48354ceSNicholas Bellinger list_add_tail(&np->np_list, &g_np_list); 402e48354ceSNicholas Bellinger spin_unlock_bh(&np_lock); 403e48354ceSNicholas Bellinger 404e48354ceSNicholas Bellinger pr_debug("CORE[0] - Added Network Portal: %s:%hu on %s\n", 405baa4d64bSNicholas Bellinger np->np_ip, np->np_port, np->np_transport->name); 406e48354ceSNicholas Bellinger 407e48354ceSNicholas Bellinger return np; 408e48354ceSNicholas Bellinger } 409e48354ceSNicholas Bellinger 410e48354ceSNicholas Bellinger int iscsit_reset_np_thread( 411e48354ceSNicholas Bellinger struct iscsi_np *np, 412e48354ceSNicholas Bellinger struct iscsi_tpg_np *tpg_np, 413e48354ceSNicholas Bellinger struct iscsi_portal_group *tpg) 414e48354ceSNicholas Bellinger { 415e48354ceSNicholas Bellinger spin_lock_bh(&np->np_thread_lock); 416e48354ceSNicholas Bellinger if (tpg && tpg_np) { 417e48354ceSNicholas Bellinger /* 418e48354ceSNicholas Bellinger * The reset operation need only be performed when the 419e48354ceSNicholas Bellinger * passed struct iscsi_portal_group has a login in progress 420e48354ceSNicholas Bellinger * to one of the network portals. 421e48354ceSNicholas Bellinger */ 422e48354ceSNicholas Bellinger if (tpg_np->tpg_np->np_login_tpg != tpg) { 423e48354ceSNicholas Bellinger spin_unlock_bh(&np->np_thread_lock); 424e48354ceSNicholas Bellinger return 0; 425e48354ceSNicholas Bellinger } 426e48354ceSNicholas Bellinger } 427e48354ceSNicholas Bellinger if (np->np_thread_state == ISCSI_NP_THREAD_INACTIVE) { 428e48354ceSNicholas Bellinger spin_unlock_bh(&np->np_thread_lock); 429e48354ceSNicholas Bellinger return 0; 430e48354ceSNicholas Bellinger } 431e48354ceSNicholas Bellinger np->np_thread_state = ISCSI_NP_THREAD_RESET; 432e48354ceSNicholas Bellinger 433e48354ceSNicholas Bellinger if (np->np_thread) { 434e48354ceSNicholas Bellinger spin_unlock_bh(&np->np_thread_lock); 435e48354ceSNicholas Bellinger send_sig(SIGINT, np->np_thread, 1); 436e48354ceSNicholas Bellinger wait_for_completion(&np->np_restart_comp); 437e48354ceSNicholas Bellinger spin_lock_bh(&np->np_thread_lock); 438e48354ceSNicholas Bellinger } 439e48354ceSNicholas Bellinger spin_unlock_bh(&np->np_thread_lock); 440e48354ceSNicholas Bellinger 441e48354ceSNicholas Bellinger return 0; 442e48354ceSNicholas Bellinger } 443e48354ceSNicholas Bellinger 444baa4d64bSNicholas Bellinger static void iscsit_free_np(struct iscsi_np *np) 445e48354ceSNicholas Bellinger { 446bf6932f4SAl Viro if (np->np_socket) 447e48354ceSNicholas Bellinger sock_release(np->np_socket); 448e48354ceSNicholas Bellinger } 449e48354ceSNicholas Bellinger 450e48354ceSNicholas Bellinger int iscsit_del_np(struct iscsi_np *np) 451e48354ceSNicholas Bellinger { 452e48354ceSNicholas Bellinger spin_lock_bh(&np->np_thread_lock); 453e48354ceSNicholas Bellinger np->np_exports--; 454e48354ceSNicholas Bellinger if (np->np_exports) { 455e48354ceSNicholas Bellinger spin_unlock_bh(&np->np_thread_lock); 456e48354ceSNicholas Bellinger return 0; 457e48354ceSNicholas Bellinger } 458e48354ceSNicholas Bellinger np->np_thread_state = ISCSI_NP_THREAD_SHUTDOWN; 459e48354ceSNicholas Bellinger spin_unlock_bh(&np->np_thread_lock); 460e48354ceSNicholas Bellinger 461e48354ceSNicholas Bellinger if (np->np_thread) { 462e48354ceSNicholas Bellinger /* 463e48354ceSNicholas Bellinger * We need to send the signal to wakeup Linux/Net 464e48354ceSNicholas Bellinger * which may be sleeping in sock_accept().. 465e48354ceSNicholas Bellinger */ 466e48354ceSNicholas Bellinger send_sig(SIGINT, np->np_thread, 1); 467e48354ceSNicholas Bellinger kthread_stop(np->np_thread); 468e48354ceSNicholas Bellinger } 469baa4d64bSNicholas Bellinger 470baa4d64bSNicholas Bellinger np->np_transport->iscsit_free_np(np); 471e48354ceSNicholas Bellinger 472e48354ceSNicholas Bellinger spin_lock_bh(&np_lock); 473e48354ceSNicholas Bellinger list_del(&np->np_list); 474e48354ceSNicholas Bellinger spin_unlock_bh(&np_lock); 475e48354ceSNicholas Bellinger 476e48354ceSNicholas Bellinger pr_debug("CORE[0] - Removed Network Portal: %s:%hu on %s\n", 477baa4d64bSNicholas Bellinger np->np_ip, np->np_port, np->np_transport->name); 478e48354ceSNicholas Bellinger 479baa4d64bSNicholas Bellinger iscsit_put_transport(np->np_transport); 480e48354ceSNicholas Bellinger kfree(np); 481e48354ceSNicholas Bellinger return 0; 482e48354ceSNicholas Bellinger } 483e48354ceSNicholas Bellinger 4842ec5a8c1SNicholas Bellinger static int iscsit_immediate_queue(struct iscsi_conn *, struct iscsi_cmd *, int); 4852ec5a8c1SNicholas Bellinger static int iscsit_response_queue(struct iscsi_conn *, struct iscsi_cmd *, int); 4862ec5a8c1SNicholas Bellinger 4872ec5a8c1SNicholas Bellinger static int iscsit_queue_rsp(struct iscsi_conn *conn, struct iscsi_cmd *cmd) 4882ec5a8c1SNicholas Bellinger { 4892ec5a8c1SNicholas Bellinger iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); 4902ec5a8c1SNicholas Bellinger return 0; 4912ec5a8c1SNicholas Bellinger } 4922ec5a8c1SNicholas Bellinger 493baa4d64bSNicholas Bellinger static struct iscsit_transport iscsi_target_transport = { 494baa4d64bSNicholas Bellinger .name = "iSCSI/TCP", 495baa4d64bSNicholas Bellinger .transport_type = ISCSI_TCP, 496baa4d64bSNicholas Bellinger .owner = NULL, 497baa4d64bSNicholas Bellinger .iscsit_setup_np = iscsit_setup_np, 498baa4d64bSNicholas Bellinger .iscsit_accept_np = iscsit_accept_np, 499baa4d64bSNicholas Bellinger .iscsit_free_np = iscsit_free_np, 500cdb72665SNicholas Bellinger .iscsit_alloc_cmd = iscsit_alloc_cmd, 501baa4d64bSNicholas Bellinger .iscsit_get_login_rx = iscsit_get_login_rx, 502baa4d64bSNicholas Bellinger .iscsit_put_login_tx = iscsit_put_login_tx, 5033e1c81a9SNicholas Bellinger .iscsit_get_dataout = iscsit_build_r2ts_for_cmd, 5042ec5a8c1SNicholas Bellinger .iscsit_immediate_queue = iscsit_immediate_queue, 5052ec5a8c1SNicholas Bellinger .iscsit_response_queue = iscsit_response_queue, 5062ec5a8c1SNicholas Bellinger .iscsit_queue_data_in = iscsit_queue_rsp, 5072ec5a8c1SNicholas Bellinger .iscsit_queue_status = iscsit_queue_rsp, 508baa4d64bSNicholas Bellinger }; 509baa4d64bSNicholas Bellinger 510e48354ceSNicholas Bellinger static int __init iscsi_target_init_module(void) 511e48354ceSNicholas Bellinger { 512e48354ceSNicholas Bellinger int ret = 0; 513e48354ceSNicholas Bellinger 514e48354ceSNicholas Bellinger pr_debug("iSCSI-Target "ISCSIT_VERSION"\n"); 515e48354ceSNicholas Bellinger 516e48354ceSNicholas Bellinger iscsit_global = kzalloc(sizeof(struct iscsit_global), GFP_KERNEL); 517e48354ceSNicholas Bellinger if (!iscsit_global) { 518e48354ceSNicholas Bellinger pr_err("Unable to allocate memory for iscsit_global\n"); 519e48354ceSNicholas Bellinger return -1; 520e48354ceSNicholas Bellinger } 521e48354ceSNicholas Bellinger mutex_init(&auth_id_lock); 522e48354ceSNicholas Bellinger spin_lock_init(&sess_idr_lock); 523e48354ceSNicholas Bellinger idr_init(&tiqn_idr); 524e48354ceSNicholas Bellinger idr_init(&sess_idr); 525e48354ceSNicholas Bellinger 526e48354ceSNicholas Bellinger ret = iscsi_target_register_configfs(); 527e48354ceSNicholas Bellinger if (ret < 0) 528e48354ceSNicholas Bellinger goto out; 529e48354ceSNicholas Bellinger 530e48354ceSNicholas Bellinger ret = iscsi_thread_set_init(); 531e48354ceSNicholas Bellinger if (ret < 0) 532e48354ceSNicholas Bellinger goto configfs_out; 533e48354ceSNicholas Bellinger 534e48354ceSNicholas Bellinger if (iscsi_allocate_thread_sets(TARGET_THREAD_SET_COUNT) != 535e48354ceSNicholas Bellinger TARGET_THREAD_SET_COUNT) { 536e48354ceSNicholas Bellinger pr_err("iscsi_allocate_thread_sets() returned" 537e48354ceSNicholas Bellinger " unexpected value!\n"); 538e48354ceSNicholas Bellinger goto ts_out1; 539e48354ceSNicholas Bellinger } 540e48354ceSNicholas Bellinger 541e48354ceSNicholas Bellinger lio_cmd_cache = kmem_cache_create("lio_cmd_cache", 542e48354ceSNicholas Bellinger sizeof(struct iscsi_cmd), __alignof__(struct iscsi_cmd), 543e48354ceSNicholas Bellinger 0, NULL); 544e48354ceSNicholas Bellinger if (!lio_cmd_cache) { 545e48354ceSNicholas Bellinger pr_err("Unable to kmem_cache_create() for" 546e48354ceSNicholas Bellinger " lio_cmd_cache\n"); 547e48354ceSNicholas Bellinger goto ts_out2; 548e48354ceSNicholas Bellinger } 549e48354ceSNicholas Bellinger 550e48354ceSNicholas Bellinger lio_qr_cache = kmem_cache_create("lio_qr_cache", 551e48354ceSNicholas Bellinger sizeof(struct iscsi_queue_req), 552e48354ceSNicholas Bellinger __alignof__(struct iscsi_queue_req), 0, NULL); 553e48354ceSNicholas Bellinger if (!lio_qr_cache) { 554e48354ceSNicholas Bellinger pr_err("nable to kmem_cache_create() for" 555e48354ceSNicholas Bellinger " lio_qr_cache\n"); 556e48354ceSNicholas Bellinger goto cmd_out; 557e48354ceSNicholas Bellinger } 558e48354ceSNicholas Bellinger 559e48354ceSNicholas Bellinger lio_dr_cache = kmem_cache_create("lio_dr_cache", 560e48354ceSNicholas Bellinger sizeof(struct iscsi_datain_req), 561e48354ceSNicholas Bellinger __alignof__(struct iscsi_datain_req), 0, NULL); 562e48354ceSNicholas Bellinger if (!lio_dr_cache) { 563e48354ceSNicholas Bellinger pr_err("Unable to kmem_cache_create() for" 564e48354ceSNicholas Bellinger " lio_dr_cache\n"); 565e48354ceSNicholas Bellinger goto qr_out; 566e48354ceSNicholas Bellinger } 567e48354ceSNicholas Bellinger 568e48354ceSNicholas Bellinger lio_ooo_cache = kmem_cache_create("lio_ooo_cache", 569e48354ceSNicholas Bellinger sizeof(struct iscsi_ooo_cmdsn), 570e48354ceSNicholas Bellinger __alignof__(struct iscsi_ooo_cmdsn), 0, NULL); 571e48354ceSNicholas Bellinger if (!lio_ooo_cache) { 572e48354ceSNicholas Bellinger pr_err("Unable to kmem_cache_create() for" 573e48354ceSNicholas Bellinger " lio_ooo_cache\n"); 574e48354ceSNicholas Bellinger goto dr_out; 575e48354ceSNicholas Bellinger } 576e48354ceSNicholas Bellinger 577e48354ceSNicholas Bellinger lio_r2t_cache = kmem_cache_create("lio_r2t_cache", 578e48354ceSNicholas Bellinger sizeof(struct iscsi_r2t), __alignof__(struct iscsi_r2t), 579e48354ceSNicholas Bellinger 0, NULL); 580e48354ceSNicholas Bellinger if (!lio_r2t_cache) { 581e48354ceSNicholas Bellinger pr_err("Unable to kmem_cache_create() for" 582e48354ceSNicholas Bellinger " lio_r2t_cache\n"); 583e48354ceSNicholas Bellinger goto ooo_out; 584e48354ceSNicholas Bellinger } 585e48354ceSNicholas Bellinger 586baa4d64bSNicholas Bellinger iscsit_register_transport(&iscsi_target_transport); 587baa4d64bSNicholas Bellinger 588e48354ceSNicholas Bellinger if (iscsit_load_discovery_tpg() < 0) 589e48354ceSNicholas Bellinger goto r2t_out; 590e48354ceSNicholas Bellinger 591e48354ceSNicholas Bellinger return ret; 592e48354ceSNicholas Bellinger r2t_out: 593e48354ceSNicholas Bellinger kmem_cache_destroy(lio_r2t_cache); 594e48354ceSNicholas Bellinger ooo_out: 595e48354ceSNicholas Bellinger kmem_cache_destroy(lio_ooo_cache); 596e48354ceSNicholas Bellinger dr_out: 597e48354ceSNicholas Bellinger kmem_cache_destroy(lio_dr_cache); 598e48354ceSNicholas Bellinger qr_out: 599e48354ceSNicholas Bellinger kmem_cache_destroy(lio_qr_cache); 600e48354ceSNicholas Bellinger cmd_out: 601e48354ceSNicholas Bellinger kmem_cache_destroy(lio_cmd_cache); 602e48354ceSNicholas Bellinger ts_out2: 603e48354ceSNicholas Bellinger iscsi_deallocate_thread_sets(); 604e48354ceSNicholas Bellinger ts_out1: 605e48354ceSNicholas Bellinger iscsi_thread_set_free(); 606e48354ceSNicholas Bellinger configfs_out: 607e48354ceSNicholas Bellinger iscsi_target_deregister_configfs(); 608e48354ceSNicholas Bellinger out: 609e48354ceSNicholas Bellinger kfree(iscsit_global); 610e48354ceSNicholas Bellinger return -ENOMEM; 611e48354ceSNicholas Bellinger } 612e48354ceSNicholas Bellinger 613e48354ceSNicholas Bellinger static void __exit iscsi_target_cleanup_module(void) 614e48354ceSNicholas Bellinger { 615e48354ceSNicholas Bellinger iscsi_deallocate_thread_sets(); 616e48354ceSNicholas Bellinger iscsi_thread_set_free(); 617e48354ceSNicholas Bellinger iscsit_release_discovery_tpg(); 618baa4d64bSNicholas Bellinger iscsit_unregister_transport(&iscsi_target_transport); 619e48354ceSNicholas Bellinger kmem_cache_destroy(lio_cmd_cache); 620e48354ceSNicholas Bellinger kmem_cache_destroy(lio_qr_cache); 621e48354ceSNicholas Bellinger kmem_cache_destroy(lio_dr_cache); 622e48354ceSNicholas Bellinger kmem_cache_destroy(lio_ooo_cache); 623e48354ceSNicholas Bellinger kmem_cache_destroy(lio_r2t_cache); 624e48354ceSNicholas Bellinger 625e48354ceSNicholas Bellinger iscsi_target_deregister_configfs(); 626e48354ceSNicholas Bellinger 627e48354ceSNicholas Bellinger kfree(iscsit_global); 628e48354ceSNicholas Bellinger } 629e48354ceSNicholas Bellinger 6308b1e1244SAndy Grover static int iscsit_add_reject( 631ba159914SNicholas Bellinger struct iscsi_conn *conn, 632e48354ceSNicholas Bellinger u8 reason, 633ba159914SNicholas Bellinger unsigned char *buf) 634e48354ceSNicholas Bellinger { 635e48354ceSNicholas Bellinger struct iscsi_cmd *cmd; 636e48354ceSNicholas Bellinger 637e48354ceSNicholas Bellinger cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); 638e48354ceSNicholas Bellinger if (!cmd) 639e48354ceSNicholas Bellinger return -1; 640e48354ceSNicholas Bellinger 641e48354ceSNicholas Bellinger cmd->iscsi_opcode = ISCSI_OP_REJECT; 642ba159914SNicholas Bellinger cmd->reject_reason = reason; 643e48354ceSNicholas Bellinger 6441c3d5794SThomas Meyer cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); 645e48354ceSNicholas Bellinger if (!cmd->buf_ptr) { 646e48354ceSNicholas Bellinger pr_err("Unable to allocate memory for cmd->buf_ptr\n"); 647aafc9d15SNicholas Bellinger iscsit_free_cmd(cmd, false); 648e48354ceSNicholas Bellinger return -1; 649e48354ceSNicholas Bellinger } 650e48354ceSNicholas Bellinger 651e48354ceSNicholas Bellinger spin_lock_bh(&conn->cmd_lock); 6522fbb471eSAndy Grover list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); 653e48354ceSNicholas Bellinger spin_unlock_bh(&conn->cmd_lock); 654e48354ceSNicholas Bellinger 655e48354ceSNicholas Bellinger cmd->i_state = ISTATE_SEND_REJECT; 656e48354ceSNicholas Bellinger iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); 657e48354ceSNicholas Bellinger 658e48354ceSNicholas Bellinger return -1; 659e48354ceSNicholas Bellinger } 660e48354ceSNicholas Bellinger 661ba159914SNicholas Bellinger static int iscsit_add_reject_from_cmd( 662ba159914SNicholas Bellinger struct iscsi_cmd *cmd, 663e48354ceSNicholas Bellinger u8 reason, 664ba159914SNicholas Bellinger bool add_to_conn, 665ba159914SNicholas Bellinger unsigned char *buf) 666e48354ceSNicholas Bellinger { 667e48354ceSNicholas Bellinger struct iscsi_conn *conn; 668e48354ceSNicholas Bellinger 669e48354ceSNicholas Bellinger if (!cmd->conn) { 670e48354ceSNicholas Bellinger pr_err("cmd->conn is NULL for ITT: 0x%08x\n", 671e48354ceSNicholas Bellinger cmd->init_task_tag); 672e48354ceSNicholas Bellinger return -1; 673e48354ceSNicholas Bellinger } 674e48354ceSNicholas Bellinger conn = cmd->conn; 675e48354ceSNicholas Bellinger 676e48354ceSNicholas Bellinger cmd->iscsi_opcode = ISCSI_OP_REJECT; 677ba159914SNicholas Bellinger cmd->reject_reason = reason; 678e48354ceSNicholas Bellinger 6791c3d5794SThomas Meyer cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); 680e48354ceSNicholas Bellinger if (!cmd->buf_ptr) { 681e48354ceSNicholas Bellinger pr_err("Unable to allocate memory for cmd->buf_ptr\n"); 682aafc9d15SNicholas Bellinger iscsit_free_cmd(cmd, false); 683e48354ceSNicholas Bellinger return -1; 684e48354ceSNicholas Bellinger } 685e48354ceSNicholas Bellinger 686e48354ceSNicholas Bellinger if (add_to_conn) { 687e48354ceSNicholas Bellinger spin_lock_bh(&conn->cmd_lock); 6882fbb471eSAndy Grover list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); 689e48354ceSNicholas Bellinger spin_unlock_bh(&conn->cmd_lock); 690e48354ceSNicholas Bellinger } 691e48354ceSNicholas Bellinger 692e48354ceSNicholas Bellinger cmd->i_state = ISTATE_SEND_REJECT; 693e48354ceSNicholas Bellinger iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); 6943e1c81a9SNicholas Bellinger /* 6953e1c81a9SNicholas Bellinger * Perform the kref_put now if se_cmd has already been setup by 6963e1c81a9SNicholas Bellinger * scsit_setup_scsi_cmd() 6973e1c81a9SNicholas Bellinger */ 6983e1c81a9SNicholas Bellinger if (cmd->se_cmd.se_tfo != NULL) { 6993e1c81a9SNicholas Bellinger pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n"); 7003e1c81a9SNicholas Bellinger target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); 7013e1c81a9SNicholas Bellinger } 702e48354ceSNicholas Bellinger return -1; 703e48354ceSNicholas Bellinger } 704ba159914SNicholas Bellinger 705ba159914SNicholas Bellinger static int iscsit_add_reject_cmd(struct iscsi_cmd *cmd, u8 reason, 706ba159914SNicholas Bellinger unsigned char *buf) 707ba159914SNicholas Bellinger { 708ba159914SNicholas Bellinger return iscsit_add_reject_from_cmd(cmd, reason, true, buf); 709ba159914SNicholas Bellinger } 710ba159914SNicholas Bellinger 711ba159914SNicholas Bellinger int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8 reason, unsigned char *buf) 712ba159914SNicholas Bellinger { 713ba159914SNicholas Bellinger return iscsit_add_reject_from_cmd(cmd, reason, false, buf); 714ba159914SNicholas Bellinger } 715e48354ceSNicholas Bellinger 716e48354ceSNicholas Bellinger /* 717e48354ceSNicholas Bellinger * Map some portion of the allocated scatterlist to an iovec, suitable for 718bfb79eacSAndy Grover * kernel sockets to copy data in/out. 719e48354ceSNicholas Bellinger */ 720e48354ceSNicholas Bellinger static int iscsit_map_iovec( 721e48354ceSNicholas Bellinger struct iscsi_cmd *cmd, 722e48354ceSNicholas Bellinger struct kvec *iov, 723e48354ceSNicholas Bellinger u32 data_offset, 724e48354ceSNicholas Bellinger u32 data_length) 725e48354ceSNicholas Bellinger { 726e48354ceSNicholas Bellinger u32 i = 0; 727e48354ceSNicholas Bellinger struct scatterlist *sg; 728e48354ceSNicholas Bellinger unsigned int page_off; 729e48354ceSNicholas Bellinger 730e48354ceSNicholas Bellinger /* 731bfb79eacSAndy Grover * We know each entry in t_data_sg contains a page. 732e48354ceSNicholas Bellinger */ 733bfb79eacSAndy Grover sg = &cmd->se_cmd.t_data_sg[data_offset / PAGE_SIZE]; 734e48354ceSNicholas Bellinger page_off = (data_offset % PAGE_SIZE); 735e48354ceSNicholas Bellinger 736e48354ceSNicholas Bellinger cmd->first_data_sg = sg; 737e48354ceSNicholas Bellinger cmd->first_data_sg_off = page_off; 738e48354ceSNicholas Bellinger 739e48354ceSNicholas Bellinger while (data_length) { 740e48354ceSNicholas Bellinger u32 cur_len = min_t(u32, data_length, sg->length - page_off); 741e48354ceSNicholas Bellinger 742e48354ceSNicholas Bellinger iov[i].iov_base = kmap(sg_page(sg)) + sg->offset + page_off; 743e48354ceSNicholas Bellinger iov[i].iov_len = cur_len; 744e48354ceSNicholas Bellinger 745e48354ceSNicholas Bellinger data_length -= cur_len; 746e48354ceSNicholas Bellinger page_off = 0; 747e48354ceSNicholas Bellinger sg = sg_next(sg); 748e48354ceSNicholas Bellinger i++; 749e48354ceSNicholas Bellinger } 750e48354ceSNicholas Bellinger 751e48354ceSNicholas Bellinger cmd->kmapped_nents = i; 752e48354ceSNicholas Bellinger 753e48354ceSNicholas Bellinger return i; 754e48354ceSNicholas Bellinger } 755e48354ceSNicholas Bellinger 756e48354ceSNicholas Bellinger static void iscsit_unmap_iovec(struct iscsi_cmd *cmd) 757e48354ceSNicholas Bellinger { 758e48354ceSNicholas Bellinger u32 i; 759e48354ceSNicholas Bellinger struct scatterlist *sg; 760e48354ceSNicholas Bellinger 761e48354ceSNicholas Bellinger sg = cmd->first_data_sg; 762e48354ceSNicholas Bellinger 763e48354ceSNicholas Bellinger for (i = 0; i < cmd->kmapped_nents; i++) 764e48354ceSNicholas Bellinger kunmap(sg_page(&sg[i])); 765e48354ceSNicholas Bellinger } 766e48354ceSNicholas Bellinger 767e48354ceSNicholas Bellinger static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) 768e48354ceSNicholas Bellinger { 769e48354ceSNicholas Bellinger struct iscsi_cmd *cmd; 770e48354ceSNicholas Bellinger 771e48354ceSNicholas Bellinger conn->exp_statsn = exp_statsn; 772e48354ceSNicholas Bellinger 7733e1c81a9SNicholas Bellinger if (conn->sess->sess_ops->RDMAExtensions) 7743e1c81a9SNicholas Bellinger return; 7753e1c81a9SNicholas Bellinger 776e48354ceSNicholas Bellinger spin_lock_bh(&conn->cmd_lock); 7772fbb471eSAndy Grover list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { 778e48354ceSNicholas Bellinger spin_lock(&cmd->istate_lock); 779e48354ceSNicholas Bellinger if ((cmd->i_state == ISTATE_SENT_STATUS) && 78064c13330SSteve Hodgson iscsi_sna_lt(cmd->stat_sn, exp_statsn)) { 781e48354ceSNicholas Bellinger cmd->i_state = ISTATE_REMOVE; 782e48354ceSNicholas Bellinger spin_unlock(&cmd->istate_lock); 783e48354ceSNicholas Bellinger iscsit_add_cmd_to_immediate_queue(cmd, conn, 784e48354ceSNicholas Bellinger cmd->i_state); 785e48354ceSNicholas Bellinger continue; 786e48354ceSNicholas Bellinger } 787e48354ceSNicholas Bellinger spin_unlock(&cmd->istate_lock); 788e48354ceSNicholas Bellinger } 789e48354ceSNicholas Bellinger spin_unlock_bh(&conn->cmd_lock); 790e48354ceSNicholas Bellinger } 791e48354ceSNicholas Bellinger 792e48354ceSNicholas Bellinger static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd) 793e48354ceSNicholas Bellinger { 794f80e8ed3SNicholas Bellinger u32 iov_count = max(1UL, DIV_ROUND_UP(cmd->se_cmd.data_length, PAGE_SIZE)); 795e48354ceSNicholas Bellinger 796c0427f15SChristoph Hellwig iov_count += ISCSI_IOV_DATA_BUFFER; 797e48354ceSNicholas Bellinger 798e48354ceSNicholas Bellinger cmd->iov_data = kzalloc(iov_count * sizeof(struct kvec), GFP_KERNEL); 799e48354ceSNicholas Bellinger if (!cmd->iov_data) { 800e48354ceSNicholas Bellinger pr_err("Unable to allocate cmd->iov_data\n"); 801e48354ceSNicholas Bellinger return -ENOMEM; 802e48354ceSNicholas Bellinger } 803e48354ceSNicholas Bellinger 804e48354ceSNicholas Bellinger cmd->orig_iov_data_count = iov_count; 805e48354ceSNicholas Bellinger return 0; 806e48354ceSNicholas Bellinger } 807e48354ceSNicholas Bellinger 8083e1c81a9SNicholas Bellinger int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, 809e48354ceSNicholas Bellinger unsigned char *buf) 810e48354ceSNicholas Bellinger { 8113e1c81a9SNicholas Bellinger int data_direction, payload_length; 812e48354ceSNicholas Bellinger struct iscsi_scsi_req *hdr; 813d28b1169SAndy Grover int iscsi_task_attr; 814d28b1169SAndy Grover int sam_task_attr; 815e48354ceSNicholas Bellinger 816e48354ceSNicholas Bellinger spin_lock_bh(&conn->sess->session_stats_lock); 817e48354ceSNicholas Bellinger conn->sess->cmd_pdus++; 818e48354ceSNicholas Bellinger if (conn->sess->se_sess->se_node_acl) { 819e48354ceSNicholas Bellinger spin_lock(&conn->sess->se_sess->se_node_acl->stats_lock); 820e48354ceSNicholas Bellinger conn->sess->se_sess->se_node_acl->num_cmds++; 821e48354ceSNicholas Bellinger spin_unlock(&conn->sess->se_sess->se_node_acl->stats_lock); 822e48354ceSNicholas Bellinger } 823e48354ceSNicholas Bellinger spin_unlock_bh(&conn->sess->session_stats_lock); 824e48354ceSNicholas Bellinger 825e48354ceSNicholas Bellinger hdr = (struct iscsi_scsi_req *) buf; 826e48354ceSNicholas Bellinger payload_length = ntoh24(hdr->dlength); 827e48354ceSNicholas Bellinger 828e48354ceSNicholas Bellinger /* FIXME; Add checks for AdditionalHeaderSegment */ 829e48354ceSNicholas Bellinger 830e48354ceSNicholas Bellinger if (!(hdr->flags & ISCSI_FLAG_CMD_WRITE) && 831e48354ceSNicholas Bellinger !(hdr->flags & ISCSI_FLAG_CMD_FINAL)) { 832e48354ceSNicholas Bellinger pr_err("ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL" 833e48354ceSNicholas Bellinger " not set. Bad iSCSI Initiator.\n"); 834ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 835ba159914SNicholas Bellinger ISCSI_REASON_BOOKMARK_INVALID, buf); 836e48354ceSNicholas Bellinger } 837e48354ceSNicholas Bellinger 838e48354ceSNicholas Bellinger if (((hdr->flags & ISCSI_FLAG_CMD_READ) || 839e48354ceSNicholas Bellinger (hdr->flags & ISCSI_FLAG_CMD_WRITE)) && !hdr->data_length) { 840e48354ceSNicholas Bellinger /* 841e48354ceSNicholas Bellinger * Vmware ESX v3.0 uses a modified Cisco Initiator (v3.4.2) 842e48354ceSNicholas Bellinger * that adds support for RESERVE/RELEASE. There is a bug 843e48354ceSNicholas Bellinger * add with this new functionality that sets R/W bits when 844e48354ceSNicholas Bellinger * neither CDB carries any READ or WRITE datapayloads. 845e48354ceSNicholas Bellinger */ 846e48354ceSNicholas Bellinger if ((hdr->cdb[0] == 0x16) || (hdr->cdb[0] == 0x17)) { 847e48354ceSNicholas Bellinger hdr->flags &= ~ISCSI_FLAG_CMD_READ; 848e48354ceSNicholas Bellinger hdr->flags &= ~ISCSI_FLAG_CMD_WRITE; 849e48354ceSNicholas Bellinger goto done; 850e48354ceSNicholas Bellinger } 851e48354ceSNicholas Bellinger 852e48354ceSNicholas Bellinger pr_err("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE" 853e48354ceSNicholas Bellinger " set when Expected Data Transfer Length is 0 for" 854e48354ceSNicholas Bellinger " CDB: 0x%02x. Bad iSCSI Initiator.\n", hdr->cdb[0]); 855ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 856ba159914SNicholas Bellinger ISCSI_REASON_BOOKMARK_INVALID, buf); 857e48354ceSNicholas Bellinger } 858e48354ceSNicholas Bellinger done: 859e48354ceSNicholas Bellinger 860e48354ceSNicholas Bellinger if (!(hdr->flags & ISCSI_FLAG_CMD_READ) && 861e48354ceSNicholas Bellinger !(hdr->flags & ISCSI_FLAG_CMD_WRITE) && (hdr->data_length != 0)) { 862e48354ceSNicholas Bellinger pr_err("ISCSI_FLAG_CMD_READ and/or ISCSI_FLAG_CMD_WRITE" 863e48354ceSNicholas Bellinger " MUST be set if Expected Data Transfer Length is not 0." 864e48354ceSNicholas Bellinger " Bad iSCSI Initiator\n"); 865ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 866ba159914SNicholas Bellinger ISCSI_REASON_BOOKMARK_INVALID, buf); 867e48354ceSNicholas Bellinger } 868e48354ceSNicholas Bellinger 869e48354ceSNicholas Bellinger if ((hdr->flags & ISCSI_FLAG_CMD_READ) && 870e48354ceSNicholas Bellinger (hdr->flags & ISCSI_FLAG_CMD_WRITE)) { 871e48354ceSNicholas Bellinger pr_err("Bidirectional operations not supported!\n"); 872ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 873ba159914SNicholas Bellinger ISCSI_REASON_BOOKMARK_INVALID, buf); 874e48354ceSNicholas Bellinger } 875e48354ceSNicholas Bellinger 876e48354ceSNicholas Bellinger if (hdr->opcode & ISCSI_OP_IMMEDIATE) { 877e48354ceSNicholas Bellinger pr_err("Illegally set Immediate Bit in iSCSI Initiator" 878e48354ceSNicholas Bellinger " Scsi Command PDU.\n"); 879ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 880ba159914SNicholas Bellinger ISCSI_REASON_BOOKMARK_INVALID, buf); 881e48354ceSNicholas Bellinger } 882e48354ceSNicholas Bellinger 883e48354ceSNicholas Bellinger if (payload_length && !conn->sess->sess_ops->ImmediateData) { 884e48354ceSNicholas Bellinger pr_err("ImmediateData=No but DataSegmentLength=%u," 885e48354ceSNicholas Bellinger " protocol error.\n", payload_length); 886ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 887ba159914SNicholas Bellinger ISCSI_REASON_PROTOCOL_ERROR, buf); 888e48354ceSNicholas Bellinger } 889e48354ceSNicholas Bellinger 89050e5c87dSChristoph Hellwig if ((be32_to_cpu(hdr->data_length) == payload_length) && 891e48354ceSNicholas Bellinger (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) { 892e48354ceSNicholas Bellinger pr_err("Expected Data Transfer Length and Length of" 893e48354ceSNicholas Bellinger " Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL" 894e48354ceSNicholas Bellinger " bit is not set protocol error\n"); 895ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 896ba159914SNicholas Bellinger ISCSI_REASON_PROTOCOL_ERROR, buf); 897e48354ceSNicholas Bellinger } 898e48354ceSNicholas Bellinger 89950e5c87dSChristoph Hellwig if (payload_length > be32_to_cpu(hdr->data_length)) { 900e48354ceSNicholas Bellinger pr_err("DataSegmentLength: %u is greater than" 901e48354ceSNicholas Bellinger " EDTL: %u, protocol error.\n", payload_length, 902e48354ceSNicholas Bellinger hdr->data_length); 903ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 904ba159914SNicholas Bellinger ISCSI_REASON_PROTOCOL_ERROR, buf); 905e48354ceSNicholas Bellinger } 906e48354ceSNicholas Bellinger 90721f5aa7eSNicholas Bellinger if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { 908e48354ceSNicholas Bellinger pr_err("DataSegmentLength: %u is greater than" 90921f5aa7eSNicholas Bellinger " MaxXmitDataSegmentLength: %u, protocol error.\n", 91021f5aa7eSNicholas Bellinger payload_length, conn->conn_ops->MaxXmitDataSegmentLength); 911ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 912ba159914SNicholas Bellinger ISCSI_REASON_PROTOCOL_ERROR, buf); 913e48354ceSNicholas Bellinger } 914e48354ceSNicholas Bellinger 915e48354ceSNicholas Bellinger if (payload_length > conn->sess->sess_ops->FirstBurstLength) { 916e48354ceSNicholas Bellinger pr_err("DataSegmentLength: %u is greater than" 917e48354ceSNicholas Bellinger " FirstBurstLength: %u, protocol error.\n", 918e48354ceSNicholas Bellinger payload_length, conn->sess->sess_ops->FirstBurstLength); 919ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 920ba159914SNicholas Bellinger ISCSI_REASON_BOOKMARK_INVALID, buf); 921e48354ceSNicholas Bellinger } 922e48354ceSNicholas Bellinger 923e48354ceSNicholas Bellinger data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE : 924e48354ceSNicholas Bellinger (hdr->flags & ISCSI_FLAG_CMD_READ) ? DMA_FROM_DEVICE : 925e48354ceSNicholas Bellinger DMA_NONE; 926e48354ceSNicholas Bellinger 927d28b1169SAndy Grover cmd->data_direction = data_direction; 928d28b1169SAndy Grover iscsi_task_attr = hdr->flags & ISCSI_FLAG_CMD_ATTR_MASK; 929d28b1169SAndy Grover /* 930d28b1169SAndy Grover * Figure out the SAM Task Attribute for the incoming SCSI CDB 931d28b1169SAndy Grover */ 932d28b1169SAndy Grover if ((iscsi_task_attr == ISCSI_ATTR_UNTAGGED) || 933d28b1169SAndy Grover (iscsi_task_attr == ISCSI_ATTR_SIMPLE)) 934d28b1169SAndy Grover sam_task_attr = MSG_SIMPLE_TAG; 935d28b1169SAndy Grover else if (iscsi_task_attr == ISCSI_ATTR_ORDERED) 936d28b1169SAndy Grover sam_task_attr = MSG_ORDERED_TAG; 937d28b1169SAndy Grover else if (iscsi_task_attr == ISCSI_ATTR_HEAD_OF_QUEUE) 938d28b1169SAndy Grover sam_task_attr = MSG_HEAD_TAG; 939d28b1169SAndy Grover else if (iscsi_task_attr == ISCSI_ATTR_ACA) 940d28b1169SAndy Grover sam_task_attr = MSG_ACA_TAG; 941d28b1169SAndy Grover else { 942d28b1169SAndy Grover pr_debug("Unknown iSCSI Task Attribute: 0x%02x, using" 943d28b1169SAndy Grover " MSG_SIMPLE_TAG\n", iscsi_task_attr); 944d28b1169SAndy Grover sam_task_attr = MSG_SIMPLE_TAG; 945d28b1169SAndy Grover } 946d28b1169SAndy Grover 947e48354ceSNicholas Bellinger cmd->iscsi_opcode = ISCSI_OP_SCSI_CMD; 948e48354ceSNicholas Bellinger cmd->i_state = ISTATE_NEW_CMD; 949e48354ceSNicholas Bellinger cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0); 950e48354ceSNicholas Bellinger cmd->immediate_data = (payload_length) ? 1 : 0; 951e48354ceSNicholas Bellinger cmd->unsolicited_data = ((!(hdr->flags & ISCSI_FLAG_CMD_FINAL) && 952e48354ceSNicholas Bellinger (hdr->flags & ISCSI_FLAG_CMD_WRITE)) ? 1 : 0); 953e48354ceSNicholas Bellinger if (cmd->unsolicited_data) 954e48354ceSNicholas Bellinger cmd->cmd_flags |= ICF_NON_IMMEDIATE_UNSOLICITED_DATA; 955e48354ceSNicholas Bellinger 956e48354ceSNicholas Bellinger conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt; 957e48354ceSNicholas Bellinger if (hdr->flags & ISCSI_FLAG_CMD_READ) { 958e48354ceSNicholas Bellinger spin_lock_bh(&conn->sess->ttt_lock); 959e48354ceSNicholas Bellinger cmd->targ_xfer_tag = conn->sess->targ_xfer_tag++; 960e48354ceSNicholas Bellinger if (cmd->targ_xfer_tag == 0xFFFFFFFF) 961e48354ceSNicholas Bellinger cmd->targ_xfer_tag = conn->sess->targ_xfer_tag++; 962e48354ceSNicholas Bellinger spin_unlock_bh(&conn->sess->ttt_lock); 963e48354ceSNicholas Bellinger } else if (hdr->flags & ISCSI_FLAG_CMD_WRITE) 964e48354ceSNicholas Bellinger cmd->targ_xfer_tag = 0xFFFFFFFF; 96550e5c87dSChristoph Hellwig cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); 96650e5c87dSChristoph Hellwig cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); 967e48354ceSNicholas Bellinger cmd->first_burst_len = payload_length; 968e48354ceSNicholas Bellinger 9693e1c81a9SNicholas Bellinger if (!conn->sess->sess_ops->RDMAExtensions && 9703e1c81a9SNicholas Bellinger cmd->data_direction == DMA_FROM_DEVICE) { 971e48354ceSNicholas Bellinger struct iscsi_datain_req *dr; 972e48354ceSNicholas Bellinger 973e48354ceSNicholas Bellinger dr = iscsit_allocate_datain_req(); 974e48354ceSNicholas Bellinger if (!dr) 975ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 976ba159914SNicholas Bellinger ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); 977e48354ceSNicholas Bellinger 978e48354ceSNicholas Bellinger iscsit_attach_datain_req(cmd, dr); 979e48354ceSNicholas Bellinger } 980e48354ceSNicholas Bellinger 981e48354ceSNicholas Bellinger /* 982065ca1e4SAndy Grover * Initialize struct se_cmd descriptor from target_core_mod infrastructure 983065ca1e4SAndy Grover */ 984065ca1e4SAndy Grover transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops, 98550e5c87dSChristoph Hellwig conn->sess->se_sess, be32_to_cpu(hdr->data_length), 98650e5c87dSChristoph Hellwig cmd->data_direction, sam_task_attr, 98750e5c87dSChristoph Hellwig cmd->sense_buffer + 2); 988065ca1e4SAndy Grover 989065ca1e4SAndy Grover pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x," 990065ca1e4SAndy Grover " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, 9913e1c81a9SNicholas Bellinger hdr->cmdsn, be32_to_cpu(hdr->data_length), payload_length, 9923e1c81a9SNicholas Bellinger conn->cid); 9933e1c81a9SNicholas Bellinger 9943e1c81a9SNicholas Bellinger target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true); 995065ca1e4SAndy Grover 996de103c93SChristoph Hellwig cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd, 9974f26998aSAndy Grover scsilun_to_int(&hdr->lun)); 998de103c93SChristoph Hellwig if (cmd->sense_reason) 999e48354ceSNicholas Bellinger goto attach_cmd; 1000a12f41f8SAndy Grover 1001de103c93SChristoph Hellwig cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb); 1002de103c93SChristoph Hellwig if (cmd->sense_reason) { 1003de103c93SChristoph Hellwig if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) { 1004ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 1005ba159914SNicholas Bellinger ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); 1006de103c93SChristoph Hellwig } 1007de103c93SChristoph Hellwig 1008de103c93SChristoph Hellwig goto attach_cmd; 1009de103c93SChristoph Hellwig } 1010de103c93SChristoph Hellwig 1011de103c93SChristoph Hellwig if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) { 1012ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 1013ba159914SNicholas Bellinger ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); 1014e48354ceSNicholas Bellinger } 1015e48354ceSNicholas Bellinger 1016e48354ceSNicholas Bellinger attach_cmd: 1017e48354ceSNicholas Bellinger spin_lock_bh(&conn->cmd_lock); 10182fbb471eSAndy Grover list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); 1019e48354ceSNicholas Bellinger spin_unlock_bh(&conn->cmd_lock); 1020e48354ceSNicholas Bellinger /* 1021e48354ceSNicholas Bellinger * Check if we need to delay processing because of ALUA 1022e48354ceSNicholas Bellinger * Active/NonOptimized primary access state.. 1023e48354ceSNicholas Bellinger */ 1024e48354ceSNicholas Bellinger core_alua_check_nonop_delay(&cmd->se_cmd); 1025bfb79eacSAndy Grover 10263e1c81a9SNicholas Bellinger return 0; 1027de103c93SChristoph Hellwig } 10283e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_setup_scsi_cmd); 1029de103c93SChristoph Hellwig 10303e1c81a9SNicholas Bellinger void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *cmd) 10313e1c81a9SNicholas Bellinger { 10323e1c81a9SNicholas Bellinger iscsit_set_dataout_sequence_values(cmd); 10333e1c81a9SNicholas Bellinger 10343e1c81a9SNicholas Bellinger spin_lock_bh(&cmd->dataout_timeout_lock); 10353e1c81a9SNicholas Bellinger iscsit_start_dataout_timer(cmd, cmd->conn); 10363e1c81a9SNicholas Bellinger spin_unlock_bh(&cmd->dataout_timeout_lock); 10373e1c81a9SNicholas Bellinger } 10383e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_set_unsoliticed_dataout); 10393e1c81a9SNicholas Bellinger 10403e1c81a9SNicholas Bellinger int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, 10413e1c81a9SNicholas Bellinger struct iscsi_scsi_req *hdr) 10423e1c81a9SNicholas Bellinger { 10433e1c81a9SNicholas Bellinger int cmdsn_ret = 0; 1044e48354ceSNicholas Bellinger /* 1045e48354ceSNicholas Bellinger * Check the CmdSN against ExpCmdSN/MaxCmdSN here if 1046e48354ceSNicholas Bellinger * the Immediate Bit is not set, and no Immediate 1047e48354ceSNicholas Bellinger * Data is attached. 1048e48354ceSNicholas Bellinger * 1049e48354ceSNicholas Bellinger * A PDU/CmdSN carrying Immediate Data can only 1050e48354ceSNicholas Bellinger * be processed after the DataCRC has passed. 1051e48354ceSNicholas Bellinger * If the DataCRC fails, the CmdSN MUST NOT 1052e48354ceSNicholas Bellinger * be acknowledged. (See below) 1053e48354ceSNicholas Bellinger */ 1054e48354ceSNicholas Bellinger if (!cmd->immediate_data) { 1055561bf158SNicholas Bellinger cmdsn_ret = iscsit_sequence_cmd(conn, cmd, 1056561bf158SNicholas Bellinger (unsigned char *)hdr, hdr->cmdsn); 1057561bf158SNicholas Bellinger if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) 1058561bf158SNicholas Bellinger return -1; 1059561bf158SNicholas Bellinger else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) { 10603e1c81a9SNicholas Bellinger target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); 10613e1c81a9SNicholas Bellinger return 0; 10623e1c81a9SNicholas Bellinger } 1063e48354ceSNicholas Bellinger } 1064e48354ceSNicholas Bellinger 106550e5c87dSChristoph Hellwig iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); 1066e48354ceSNicholas Bellinger 1067e48354ceSNicholas Bellinger /* 1068e48354ceSNicholas Bellinger * If no Immediate Data is attached, it's OK to return now. 1069e48354ceSNicholas Bellinger */ 1070e48354ceSNicholas Bellinger if (!cmd->immediate_data) { 10713e1c81a9SNicholas Bellinger if (!cmd->sense_reason && cmd->unsolicited_data) 10723e1c81a9SNicholas Bellinger iscsit_set_unsoliticed_dataout(cmd); 10733e1c81a9SNicholas Bellinger if (!cmd->sense_reason) 10743e1c81a9SNicholas Bellinger return 0; 1075e48354ceSNicholas Bellinger 10763e1c81a9SNicholas Bellinger target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); 1077e48354ceSNicholas Bellinger return 0; 1078e48354ceSNicholas Bellinger } 1079e48354ceSNicholas Bellinger 1080e48354ceSNicholas Bellinger /* 10813e1c81a9SNicholas Bellinger * Early CHECK_CONDITIONs with ImmediateData never make it to command 10823e1c81a9SNicholas Bellinger * execution. These exceptions are processed in CmdSN order using 10833e1c81a9SNicholas Bellinger * iscsit_check_received_cmdsn() in iscsit_get_immediate_data() below. 1084e48354ceSNicholas Bellinger */ 1085de103c93SChristoph Hellwig if (cmd->sense_reason) { 1086561bf158SNicholas Bellinger if (cmd->reject_reason) 1087561bf158SNicholas Bellinger return 0; 1088561bf158SNicholas Bellinger 10893e1c81a9SNicholas Bellinger return 1; 1090e48354ceSNicholas Bellinger } 1091e48354ceSNicholas Bellinger /* 1092e48354ceSNicholas Bellinger * Call directly into transport_generic_new_cmd() to perform 1093e48354ceSNicholas Bellinger * the backend memory allocation. 1094e48354ceSNicholas Bellinger */ 1095de103c93SChristoph Hellwig cmd->sense_reason = transport_generic_new_cmd(&cmd->se_cmd); 1096561bf158SNicholas Bellinger if (cmd->sense_reason) 10973e1c81a9SNicholas Bellinger return 1; 1098e48354ceSNicholas Bellinger 10993e1c81a9SNicholas Bellinger return 0; 11003e1c81a9SNicholas Bellinger } 11013e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_process_scsi_cmd); 11023e1c81a9SNicholas Bellinger 11033e1c81a9SNicholas Bellinger static int 11043e1c81a9SNicholas Bellinger iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr, 11053e1c81a9SNicholas Bellinger bool dump_payload) 11063e1c81a9SNicholas Bellinger { 1107561bf158SNicholas Bellinger struct iscsi_conn *conn = cmd->conn; 11083e1c81a9SNicholas Bellinger int cmdsn_ret = 0, immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; 11093e1c81a9SNicholas Bellinger /* 11103e1c81a9SNicholas Bellinger * Special case for Unsupported SAM WRITE Opcodes and ImmediateData=Yes. 11113e1c81a9SNicholas Bellinger */ 11123e1c81a9SNicholas Bellinger if (dump_payload == true) 11133e1c81a9SNicholas Bellinger goto after_immediate_data; 11143e1c81a9SNicholas Bellinger 11153e1c81a9SNicholas Bellinger immed_ret = iscsit_handle_immediate_data(cmd, hdr, 11163e1c81a9SNicholas Bellinger cmd->first_burst_len); 1117e48354ceSNicholas Bellinger after_immediate_data: 1118e48354ceSNicholas Bellinger if (immed_ret == IMMEDIATE_DATA_NORMAL_OPERATION) { 1119e48354ceSNicholas Bellinger /* 1120e48354ceSNicholas Bellinger * A PDU/CmdSN carrying Immediate Data passed 1121e48354ceSNicholas Bellinger * DataCRC, check against ExpCmdSN/MaxCmdSN if 1122e48354ceSNicholas Bellinger * Immediate Bit is not set. 1123e48354ceSNicholas Bellinger */ 1124561bf158SNicholas Bellinger cmdsn_ret = iscsit_sequence_cmd(cmd->conn, cmd, 1125561bf158SNicholas Bellinger (unsigned char *)hdr, hdr->cmdsn); 11269d86a2beSNicholas Bellinger if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) 1127561bf158SNicholas Bellinger return -1; 1128e48354ceSNicholas Bellinger 11299d86a2beSNicholas Bellinger if (cmd->sense_reason || cmdsn_ret == CMDSN_LOWER_THAN_EXP) { 1130561bf158SNicholas Bellinger int rc; 1131561bf158SNicholas Bellinger 1132561bf158SNicholas Bellinger rc = iscsit_dump_data_payload(cmd->conn, 1133561bf158SNicholas Bellinger cmd->first_burst_len, 1); 1134561bf158SNicholas Bellinger target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); 1135561bf158SNicholas Bellinger return rc; 11363e1c81a9SNicholas Bellinger } else if (cmd->unsolicited_data) 11373e1c81a9SNicholas Bellinger iscsit_set_unsoliticed_dataout(cmd); 1138e48354ceSNicholas Bellinger 1139e48354ceSNicholas Bellinger } else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) { 1140e48354ceSNicholas Bellinger /* 1141e48354ceSNicholas Bellinger * Immediate Data failed DataCRC and ERL>=1, 1142e48354ceSNicholas Bellinger * silently drop this PDU and let the initiator 1143e48354ceSNicholas Bellinger * plug the CmdSN gap. 1144e48354ceSNicholas Bellinger * 1145e48354ceSNicholas Bellinger * FIXME: Send Unsolicited NOPIN with reserved 1146e48354ceSNicholas Bellinger * TTT here to help the initiator figure out 1147e48354ceSNicholas Bellinger * the missing CmdSN, although they should be 1148e48354ceSNicholas Bellinger * intelligent enough to determine the missing 1149e48354ceSNicholas Bellinger * CmdSN and issue a retry to plug the sequence. 1150e48354ceSNicholas Bellinger */ 1151e48354ceSNicholas Bellinger cmd->i_state = ISTATE_REMOVE; 11523e1c81a9SNicholas Bellinger iscsit_add_cmd_to_immediate_queue(cmd, cmd->conn, cmd->i_state); 1153e48354ceSNicholas Bellinger } else /* immed_ret == IMMEDIATE_DATA_CANNOT_RECOVER */ 1154e48354ceSNicholas Bellinger return -1; 1155e48354ceSNicholas Bellinger 1156e48354ceSNicholas Bellinger return 0; 1157e48354ceSNicholas Bellinger } 1158e48354ceSNicholas Bellinger 11593e1c81a9SNicholas Bellinger static int 11603e1c81a9SNicholas Bellinger iscsit_handle_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, 11613e1c81a9SNicholas Bellinger unsigned char *buf) 11623e1c81a9SNicholas Bellinger { 11633e1c81a9SNicholas Bellinger struct iscsi_scsi_req *hdr = (struct iscsi_scsi_req *)buf; 11643e1c81a9SNicholas Bellinger int rc, immed_data; 11653e1c81a9SNicholas Bellinger bool dump_payload = false; 11663e1c81a9SNicholas Bellinger 11673e1c81a9SNicholas Bellinger rc = iscsit_setup_scsi_cmd(conn, cmd, buf); 11683e1c81a9SNicholas Bellinger if (rc < 0) 1169561bf158SNicholas Bellinger return 0; 11703e1c81a9SNicholas Bellinger /* 11713e1c81a9SNicholas Bellinger * Allocation iovecs needed for struct socket operations for 11723e1c81a9SNicholas Bellinger * traditional iSCSI block I/O. 11733e1c81a9SNicholas Bellinger */ 11743e1c81a9SNicholas Bellinger if (iscsit_allocate_iovecs(cmd) < 0) { 1175ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 1176ba159914SNicholas Bellinger ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); 11773e1c81a9SNicholas Bellinger } 11783e1c81a9SNicholas Bellinger immed_data = cmd->immediate_data; 11793e1c81a9SNicholas Bellinger 11803e1c81a9SNicholas Bellinger rc = iscsit_process_scsi_cmd(conn, cmd, hdr); 11813e1c81a9SNicholas Bellinger if (rc < 0) 11823e1c81a9SNicholas Bellinger return rc; 11833e1c81a9SNicholas Bellinger else if (rc > 0) 11843e1c81a9SNicholas Bellinger dump_payload = true; 11853e1c81a9SNicholas Bellinger 11863e1c81a9SNicholas Bellinger if (!immed_data) 11873e1c81a9SNicholas Bellinger return 0; 11883e1c81a9SNicholas Bellinger 11893e1c81a9SNicholas Bellinger return iscsit_get_immediate_data(cmd, hdr, dump_payload); 11903e1c81a9SNicholas Bellinger } 11913e1c81a9SNicholas Bellinger 1192e48354ceSNicholas Bellinger static u32 iscsit_do_crypto_hash_sg( 1193e48354ceSNicholas Bellinger struct hash_desc *hash, 1194e48354ceSNicholas Bellinger struct iscsi_cmd *cmd, 1195e48354ceSNicholas Bellinger u32 data_offset, 1196e48354ceSNicholas Bellinger u32 data_length, 1197e48354ceSNicholas Bellinger u32 padding, 1198e48354ceSNicholas Bellinger u8 *pad_bytes) 1199e48354ceSNicholas Bellinger { 1200e48354ceSNicholas Bellinger u32 data_crc; 1201e48354ceSNicholas Bellinger u32 i; 1202e48354ceSNicholas Bellinger struct scatterlist *sg; 1203e48354ceSNicholas Bellinger unsigned int page_off; 1204e48354ceSNicholas Bellinger 1205e48354ceSNicholas Bellinger crypto_hash_init(hash); 1206e48354ceSNicholas Bellinger 1207e48354ceSNicholas Bellinger sg = cmd->first_data_sg; 1208e48354ceSNicholas Bellinger page_off = cmd->first_data_sg_off; 1209e48354ceSNicholas Bellinger 1210e48354ceSNicholas Bellinger i = 0; 1211e48354ceSNicholas Bellinger while (data_length) { 1212e48354ceSNicholas Bellinger u32 cur_len = min_t(u32, data_length, (sg[i].length - page_off)); 1213e48354ceSNicholas Bellinger 1214e48354ceSNicholas Bellinger crypto_hash_update(hash, &sg[i], cur_len); 1215e48354ceSNicholas Bellinger 1216e48354ceSNicholas Bellinger data_length -= cur_len; 1217e48354ceSNicholas Bellinger page_off = 0; 1218e48354ceSNicholas Bellinger i++; 1219e48354ceSNicholas Bellinger } 1220e48354ceSNicholas Bellinger 1221e48354ceSNicholas Bellinger if (padding) { 1222e48354ceSNicholas Bellinger struct scatterlist pad_sg; 1223e48354ceSNicholas Bellinger 1224e48354ceSNicholas Bellinger sg_init_one(&pad_sg, pad_bytes, padding); 1225e48354ceSNicholas Bellinger crypto_hash_update(hash, &pad_sg, padding); 1226e48354ceSNicholas Bellinger } 1227e48354ceSNicholas Bellinger crypto_hash_final(hash, (u8 *) &data_crc); 1228e48354ceSNicholas Bellinger 1229e48354ceSNicholas Bellinger return data_crc; 1230e48354ceSNicholas Bellinger } 1231e48354ceSNicholas Bellinger 1232e48354ceSNicholas Bellinger static void iscsit_do_crypto_hash_buf( 1233e48354ceSNicholas Bellinger struct hash_desc *hash, 123480690fdbSGeert Uytterhoeven const void *buf, 1235e48354ceSNicholas Bellinger u32 payload_length, 1236e48354ceSNicholas Bellinger u32 padding, 1237e48354ceSNicholas Bellinger u8 *pad_bytes, 1238e48354ceSNicholas Bellinger u8 *data_crc) 1239e48354ceSNicholas Bellinger { 1240e48354ceSNicholas Bellinger struct scatterlist sg; 1241e48354ceSNicholas Bellinger 1242e48354ceSNicholas Bellinger crypto_hash_init(hash); 1243e48354ceSNicholas Bellinger 12448359cf43SJörn Engel sg_init_one(&sg, buf, payload_length); 1245e48354ceSNicholas Bellinger crypto_hash_update(hash, &sg, payload_length); 1246e48354ceSNicholas Bellinger 1247e48354ceSNicholas Bellinger if (padding) { 1248e48354ceSNicholas Bellinger sg_init_one(&sg, pad_bytes, padding); 1249e48354ceSNicholas Bellinger crypto_hash_update(hash, &sg, padding); 1250e48354ceSNicholas Bellinger } 1251e48354ceSNicholas Bellinger crypto_hash_final(hash, data_crc); 1252e48354ceSNicholas Bellinger } 1253e48354ceSNicholas Bellinger 12543e1c81a9SNicholas Bellinger int 12553e1c81a9SNicholas Bellinger iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, 12563e1c81a9SNicholas Bellinger struct iscsi_cmd **out_cmd) 1257e48354ceSNicholas Bellinger { 12583e1c81a9SNicholas Bellinger struct iscsi_data *hdr = (struct iscsi_data *)buf; 1259e48354ceSNicholas Bellinger struct iscsi_cmd *cmd = NULL; 1260e48354ceSNicholas Bellinger struct se_cmd *se_cmd; 12613e1c81a9SNicholas Bellinger u32 payload_length = ntoh24(hdr->dlength); 12623e1c81a9SNicholas Bellinger int rc; 1263e48354ceSNicholas Bellinger 1264e48354ceSNicholas Bellinger if (!payload_length) { 1265e48354ceSNicholas Bellinger pr_err("DataOUT payload is ZERO, protocol error.\n"); 1266ba159914SNicholas Bellinger return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, 1267ba159914SNicholas Bellinger buf); 1268e48354ceSNicholas Bellinger } 1269e48354ceSNicholas Bellinger 1270e48354ceSNicholas Bellinger /* iSCSI write */ 1271e48354ceSNicholas Bellinger spin_lock_bh(&conn->sess->session_stats_lock); 1272e48354ceSNicholas Bellinger conn->sess->rx_data_octets += payload_length; 1273e48354ceSNicholas Bellinger if (conn->sess->se_sess->se_node_acl) { 1274e48354ceSNicholas Bellinger spin_lock(&conn->sess->se_sess->se_node_acl->stats_lock); 1275e48354ceSNicholas Bellinger conn->sess->se_sess->se_node_acl->write_bytes += payload_length; 1276e48354ceSNicholas Bellinger spin_unlock(&conn->sess->se_sess->se_node_acl->stats_lock); 1277e48354ceSNicholas Bellinger } 1278e48354ceSNicholas Bellinger spin_unlock_bh(&conn->sess->session_stats_lock); 1279e48354ceSNicholas Bellinger 128021f5aa7eSNicholas Bellinger if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { 1281e48354ceSNicholas Bellinger pr_err("DataSegmentLength: %u is greater than" 128221f5aa7eSNicholas Bellinger " MaxXmitDataSegmentLength: %u\n", payload_length, 128321f5aa7eSNicholas Bellinger conn->conn_ops->MaxXmitDataSegmentLength); 1284ba159914SNicholas Bellinger return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, 1285ba159914SNicholas Bellinger buf); 1286e48354ceSNicholas Bellinger } 1287e48354ceSNicholas Bellinger 1288e48354ceSNicholas Bellinger cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt, 1289e48354ceSNicholas Bellinger payload_length); 1290e48354ceSNicholas Bellinger if (!cmd) 1291e48354ceSNicholas Bellinger return 0; 1292e48354ceSNicholas Bellinger 1293e48354ceSNicholas Bellinger pr_debug("Got DataOut ITT: 0x%08x, TTT: 0x%08x," 1294e48354ceSNicholas Bellinger " DataSN: 0x%08x, Offset: %u, Length: %u, CID: %hu\n", 12953e1c81a9SNicholas Bellinger hdr->itt, hdr->ttt, hdr->datasn, ntohl(hdr->offset), 1296e48354ceSNicholas Bellinger payload_length, conn->cid); 1297e48354ceSNicholas Bellinger 1298e48354ceSNicholas Bellinger if (cmd->cmd_flags & ICF_GOT_LAST_DATAOUT) { 1299e48354ceSNicholas Bellinger pr_err("Command ITT: 0x%08x received DataOUT after" 1300e48354ceSNicholas Bellinger " last DataOUT received, dumping payload\n", 1301e48354ceSNicholas Bellinger cmd->init_task_tag); 1302e48354ceSNicholas Bellinger return iscsit_dump_data_payload(conn, payload_length, 1); 1303e48354ceSNicholas Bellinger } 1304e48354ceSNicholas Bellinger 1305e48354ceSNicholas Bellinger if (cmd->data_direction != DMA_TO_DEVICE) { 1306e48354ceSNicholas Bellinger pr_err("Command ITT: 0x%08x received DataOUT for a" 1307e48354ceSNicholas Bellinger " NON-WRITE command.\n", cmd->init_task_tag); 1308ba159914SNicholas Bellinger return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf); 1309e48354ceSNicholas Bellinger } 1310e48354ceSNicholas Bellinger se_cmd = &cmd->se_cmd; 1311e48354ceSNicholas Bellinger iscsit_mod_dataout_timer(cmd); 1312e48354ceSNicholas Bellinger 131350e5c87dSChristoph Hellwig if ((be32_to_cpu(hdr->offset) + payload_length) > cmd->se_cmd.data_length) { 1314e48354ceSNicholas Bellinger pr_err("DataOut Offset: %u, Length %u greater than" 1315e48354ceSNicholas Bellinger " iSCSI Command EDTL %u, protocol error.\n", 1316ebf1d95cSAndy Grover hdr->offset, payload_length, cmd->se_cmd.data_length); 1317ba159914SNicholas Bellinger return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_INVALID, buf); 1318e48354ceSNicholas Bellinger } 1319e48354ceSNicholas Bellinger 1320e48354ceSNicholas Bellinger if (cmd->unsolicited_data) { 1321e48354ceSNicholas Bellinger int dump_unsolicited_data = 0; 1322e48354ceSNicholas Bellinger 1323e48354ceSNicholas Bellinger if (conn->sess->sess_ops->InitialR2T) { 1324e48354ceSNicholas Bellinger pr_err("Received unexpected unsolicited data" 1325e48354ceSNicholas Bellinger " while InitialR2T=Yes, protocol error.\n"); 1326e48354ceSNicholas Bellinger transport_send_check_condition_and_sense(&cmd->se_cmd, 1327e48354ceSNicholas Bellinger TCM_UNEXPECTED_UNSOLICITED_DATA, 0); 1328e48354ceSNicholas Bellinger return -1; 1329e48354ceSNicholas Bellinger } 1330e48354ceSNicholas Bellinger /* 1331e48354ceSNicholas Bellinger * Special case for dealing with Unsolicited DataOUT 1332e48354ceSNicholas Bellinger * and Unsupported SAM WRITE Opcodes and SE resource allocation 1333e48354ceSNicholas Bellinger * failures; 1334e48354ceSNicholas Bellinger */ 1335e48354ceSNicholas Bellinger 1336e48354ceSNicholas Bellinger /* Something's amiss if we're not in WRITE_PENDING state... */ 1337e48354ceSNicholas Bellinger WARN_ON(se_cmd->t_state != TRANSPORT_WRITE_PENDING); 1338de103c93SChristoph Hellwig if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE)) 1339e48354ceSNicholas Bellinger dump_unsolicited_data = 1; 1340e48354ceSNicholas Bellinger 1341e48354ceSNicholas Bellinger if (dump_unsolicited_data) { 1342e48354ceSNicholas Bellinger /* 1343e48354ceSNicholas Bellinger * Check if a delayed TASK_ABORTED status needs to 1344e48354ceSNicholas Bellinger * be sent now if the ISCSI_FLAG_CMD_FINAL has been 1345e48354ceSNicholas Bellinger * received with the unsolicitied data out. 1346e48354ceSNicholas Bellinger */ 1347e48354ceSNicholas Bellinger if (hdr->flags & ISCSI_FLAG_CMD_FINAL) 1348e48354ceSNicholas Bellinger iscsit_stop_dataout_timer(cmd); 1349e48354ceSNicholas Bellinger 1350e48354ceSNicholas Bellinger transport_check_aborted_status(se_cmd, 1351e48354ceSNicholas Bellinger (hdr->flags & ISCSI_FLAG_CMD_FINAL)); 1352e48354ceSNicholas Bellinger return iscsit_dump_data_payload(conn, payload_length, 1); 1353e48354ceSNicholas Bellinger } 1354e48354ceSNicholas Bellinger } else { 1355e48354ceSNicholas Bellinger /* 1356e48354ceSNicholas Bellinger * For the normal solicited data path: 1357e48354ceSNicholas Bellinger * 1358e48354ceSNicholas Bellinger * Check for a delayed TASK_ABORTED status and dump any 1359e48354ceSNicholas Bellinger * incoming data out payload if one exists. Also, when the 1360e48354ceSNicholas Bellinger * ISCSI_FLAG_CMD_FINAL is set to denote the end of the current 1361e48354ceSNicholas Bellinger * data out sequence, we decrement outstanding_r2ts. Once 1362e48354ceSNicholas Bellinger * outstanding_r2ts reaches zero, go ahead and send the delayed 1363e48354ceSNicholas Bellinger * TASK_ABORTED status. 1364e48354ceSNicholas Bellinger */ 13657d680f3bSChristoph Hellwig if (se_cmd->transport_state & CMD_T_ABORTED) { 1366e48354ceSNicholas Bellinger if (hdr->flags & ISCSI_FLAG_CMD_FINAL) 1367e48354ceSNicholas Bellinger if (--cmd->outstanding_r2ts < 1) { 1368e48354ceSNicholas Bellinger iscsit_stop_dataout_timer(cmd); 1369e48354ceSNicholas Bellinger transport_check_aborted_status( 1370e48354ceSNicholas Bellinger se_cmd, 1); 1371e48354ceSNicholas Bellinger } 1372e48354ceSNicholas Bellinger 1373e48354ceSNicholas Bellinger return iscsit_dump_data_payload(conn, payload_length, 1); 1374e48354ceSNicholas Bellinger } 1375e48354ceSNicholas Bellinger } 1376e48354ceSNicholas Bellinger /* 1377e48354ceSNicholas Bellinger * Preform DataSN, DataSequenceInOrder, DataPDUInOrder, and 1378e48354ceSNicholas Bellinger * within-command recovery checks before receiving the payload. 1379e48354ceSNicholas Bellinger */ 13803e1c81a9SNicholas Bellinger rc = iscsit_check_pre_dataout(cmd, buf); 13813e1c81a9SNicholas Bellinger if (rc == DATAOUT_WITHIN_COMMAND_RECOVERY) 1382e48354ceSNicholas Bellinger return 0; 13833e1c81a9SNicholas Bellinger else if (rc == DATAOUT_CANNOT_RECOVER) 1384e48354ceSNicholas Bellinger return -1; 1385e48354ceSNicholas Bellinger 13863e1c81a9SNicholas Bellinger *out_cmd = cmd; 13873e1c81a9SNicholas Bellinger return 0; 13883e1c81a9SNicholas Bellinger } 13893e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_check_dataout_hdr); 13903e1c81a9SNicholas Bellinger 13913e1c81a9SNicholas Bellinger static int 13923e1c81a9SNicholas Bellinger iscsit_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd, 13933e1c81a9SNicholas Bellinger struct iscsi_data *hdr) 13943e1c81a9SNicholas Bellinger { 13953e1c81a9SNicholas Bellinger struct kvec *iov; 13963e1c81a9SNicholas Bellinger u32 checksum, iov_count = 0, padding = 0, rx_got = 0, rx_size = 0; 13973e1c81a9SNicholas Bellinger u32 payload_length = ntoh24(hdr->dlength); 13983e1c81a9SNicholas Bellinger int iov_ret, data_crc_failed = 0; 13993e1c81a9SNicholas Bellinger 1400e48354ceSNicholas Bellinger rx_size += payload_length; 1401e48354ceSNicholas Bellinger iov = &cmd->iov_data[0]; 1402e48354ceSNicholas Bellinger 140350e5c87dSChristoph Hellwig iov_ret = iscsit_map_iovec(cmd, iov, be32_to_cpu(hdr->offset), 140450e5c87dSChristoph Hellwig payload_length); 1405e48354ceSNicholas Bellinger if (iov_ret < 0) 1406e48354ceSNicholas Bellinger return -1; 1407e48354ceSNicholas Bellinger 1408e48354ceSNicholas Bellinger iov_count += iov_ret; 1409e48354ceSNicholas Bellinger 1410e48354ceSNicholas Bellinger padding = ((-payload_length) & 3); 1411e48354ceSNicholas Bellinger if (padding != 0) { 1412e48354ceSNicholas Bellinger iov[iov_count].iov_base = cmd->pad_bytes; 1413e48354ceSNicholas Bellinger iov[iov_count++].iov_len = padding; 1414e48354ceSNicholas Bellinger rx_size += padding; 1415e48354ceSNicholas Bellinger pr_debug("Receiving %u padding bytes.\n", padding); 1416e48354ceSNicholas Bellinger } 1417e48354ceSNicholas Bellinger 1418e48354ceSNicholas Bellinger if (conn->conn_ops->DataDigest) { 1419e48354ceSNicholas Bellinger iov[iov_count].iov_base = &checksum; 1420e48354ceSNicholas Bellinger iov[iov_count++].iov_len = ISCSI_CRC_LEN; 1421e48354ceSNicholas Bellinger rx_size += ISCSI_CRC_LEN; 1422e48354ceSNicholas Bellinger } 1423e48354ceSNicholas Bellinger 1424e48354ceSNicholas Bellinger rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size); 1425e48354ceSNicholas Bellinger 1426e48354ceSNicholas Bellinger iscsit_unmap_iovec(cmd); 1427e48354ceSNicholas Bellinger 1428e48354ceSNicholas Bellinger if (rx_got != rx_size) 1429e48354ceSNicholas Bellinger return -1; 1430e48354ceSNicholas Bellinger 1431e48354ceSNicholas Bellinger if (conn->conn_ops->DataDigest) { 1432e48354ceSNicholas Bellinger u32 data_crc; 1433e48354ceSNicholas Bellinger 1434e48354ceSNicholas Bellinger data_crc = iscsit_do_crypto_hash_sg(&conn->conn_rx_hash, cmd, 143550e5c87dSChristoph Hellwig be32_to_cpu(hdr->offset), 143650e5c87dSChristoph Hellwig payload_length, padding, 1437e48354ceSNicholas Bellinger cmd->pad_bytes); 1438e48354ceSNicholas Bellinger 1439e48354ceSNicholas Bellinger if (checksum != data_crc) { 1440e48354ceSNicholas Bellinger pr_err("ITT: 0x%08x, Offset: %u, Length: %u," 1441e48354ceSNicholas Bellinger " DataSN: 0x%08x, CRC32C DataDigest 0x%08x" 1442e48354ceSNicholas Bellinger " does not match computed 0x%08x\n", 1443e48354ceSNicholas Bellinger hdr->itt, hdr->offset, payload_length, 1444e48354ceSNicholas Bellinger hdr->datasn, checksum, data_crc); 1445e48354ceSNicholas Bellinger data_crc_failed = 1; 1446e48354ceSNicholas Bellinger } else { 1447e48354ceSNicholas Bellinger pr_debug("Got CRC32C DataDigest 0x%08x for" 1448e48354ceSNicholas Bellinger " %u bytes of Data Out\n", checksum, 1449e48354ceSNicholas Bellinger payload_length); 1450e48354ceSNicholas Bellinger } 1451e48354ceSNicholas Bellinger } 14523e1c81a9SNicholas Bellinger 14533e1c81a9SNicholas Bellinger return data_crc_failed; 14543e1c81a9SNicholas Bellinger } 14553e1c81a9SNicholas Bellinger 14563e1c81a9SNicholas Bellinger int 14573e1c81a9SNicholas Bellinger iscsit_check_dataout_payload(struct iscsi_cmd *cmd, struct iscsi_data *hdr, 14583e1c81a9SNicholas Bellinger bool data_crc_failed) 14593e1c81a9SNicholas Bellinger { 14603e1c81a9SNicholas Bellinger struct iscsi_conn *conn = cmd->conn; 14613e1c81a9SNicholas Bellinger int rc, ooo_cmdsn; 1462e48354ceSNicholas Bellinger /* 1463e48354ceSNicholas Bellinger * Increment post receive data and CRC values or perform 1464e48354ceSNicholas Bellinger * within-command recovery. 1465e48354ceSNicholas Bellinger */ 14663e1c81a9SNicholas Bellinger rc = iscsit_check_post_dataout(cmd, (unsigned char *)hdr, data_crc_failed); 14673e1c81a9SNicholas Bellinger if ((rc == DATAOUT_NORMAL) || (rc == DATAOUT_WITHIN_COMMAND_RECOVERY)) 1468e48354ceSNicholas Bellinger return 0; 14693e1c81a9SNicholas Bellinger else if (rc == DATAOUT_SEND_R2T) { 1470e48354ceSNicholas Bellinger iscsit_set_dataout_sequence_values(cmd); 14713e1c81a9SNicholas Bellinger conn->conn_transport->iscsit_get_dataout(conn, cmd, false); 14723e1c81a9SNicholas Bellinger } else if (rc == DATAOUT_SEND_TO_TRANSPORT) { 1473e48354ceSNicholas Bellinger /* 1474e48354ceSNicholas Bellinger * Handle extra special case for out of order 1475e48354ceSNicholas Bellinger * Unsolicited Data Out. 1476e48354ceSNicholas Bellinger */ 1477e48354ceSNicholas Bellinger spin_lock_bh(&cmd->istate_lock); 1478e48354ceSNicholas Bellinger ooo_cmdsn = (cmd->cmd_flags & ICF_OOO_CMDSN); 1479e48354ceSNicholas Bellinger cmd->cmd_flags |= ICF_GOT_LAST_DATAOUT; 1480e48354ceSNicholas Bellinger cmd->i_state = ISTATE_RECEIVED_LAST_DATAOUT; 1481e48354ceSNicholas Bellinger spin_unlock_bh(&cmd->istate_lock); 1482e48354ceSNicholas Bellinger 1483e48354ceSNicholas Bellinger iscsit_stop_dataout_timer(cmd); 148467441b68SChristoph Hellwig if (ooo_cmdsn) 148567441b68SChristoph Hellwig return 0; 148667441b68SChristoph Hellwig target_execute_cmd(&cmd->se_cmd); 148767441b68SChristoph Hellwig return 0; 1488e48354ceSNicholas Bellinger } else /* DATAOUT_CANNOT_RECOVER */ 1489e48354ceSNicholas Bellinger return -1; 1490e48354ceSNicholas Bellinger 1491e48354ceSNicholas Bellinger return 0; 1492e48354ceSNicholas Bellinger } 14933e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_check_dataout_payload); 1494e48354ceSNicholas Bellinger 14953e1c81a9SNicholas Bellinger static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) 14963e1c81a9SNicholas Bellinger { 14973e1c81a9SNicholas Bellinger struct iscsi_cmd *cmd; 14983e1c81a9SNicholas Bellinger struct iscsi_data *hdr = (struct iscsi_data *)buf; 14993e1c81a9SNicholas Bellinger int rc; 15003e1c81a9SNicholas Bellinger bool data_crc_failed = false; 15013e1c81a9SNicholas Bellinger 15023e1c81a9SNicholas Bellinger rc = iscsit_check_dataout_hdr(conn, buf, &cmd); 15033e1c81a9SNicholas Bellinger if (rc < 0) 1504561bf158SNicholas Bellinger return 0; 15053e1c81a9SNicholas Bellinger else if (!cmd) 15063e1c81a9SNicholas Bellinger return 0; 15073e1c81a9SNicholas Bellinger 15083e1c81a9SNicholas Bellinger rc = iscsit_get_dataout(conn, cmd, hdr); 15093e1c81a9SNicholas Bellinger if (rc < 0) 15103e1c81a9SNicholas Bellinger return rc; 15113e1c81a9SNicholas Bellinger else if (rc > 0) 15123e1c81a9SNicholas Bellinger data_crc_failed = true; 15133e1c81a9SNicholas Bellinger 15143e1c81a9SNicholas Bellinger return iscsit_check_dataout_payload(cmd, hdr, data_crc_failed); 15153e1c81a9SNicholas Bellinger } 15163e1c81a9SNicholas Bellinger 1517778de368SNicholas Bellinger int iscsit_setup_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, 1518778de368SNicholas Bellinger struct iscsi_nopout *hdr) 1519e48354ceSNicholas Bellinger { 1520778de368SNicholas Bellinger u32 payload_length = ntoh24(hdr->dlength); 1521e48354ceSNicholas Bellinger 152266c7db68SChristoph Hellwig if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { 1523e48354ceSNicholas Bellinger pr_err("NOPOUT ITT is reserved, but Immediate Bit is" 1524e48354ceSNicholas Bellinger " not set, protocol error.\n"); 1525ba159914SNicholas Bellinger return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, 1526ba159914SNicholas Bellinger (unsigned char *)hdr); 1527e48354ceSNicholas Bellinger } 1528e48354ceSNicholas Bellinger 152921f5aa7eSNicholas Bellinger if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { 1530e48354ceSNicholas Bellinger pr_err("NOPOUT Ping Data DataSegmentLength: %u is" 153121f5aa7eSNicholas Bellinger " greater than MaxXmitDataSegmentLength: %u, protocol" 1532e48354ceSNicholas Bellinger " error.\n", payload_length, 153321f5aa7eSNicholas Bellinger conn->conn_ops->MaxXmitDataSegmentLength); 1534ba159914SNicholas Bellinger return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, 1535ba159914SNicholas Bellinger (unsigned char *)hdr); 1536e48354ceSNicholas Bellinger } 1537e48354ceSNicholas Bellinger 15383e1c81a9SNicholas Bellinger pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%08x," 1539e48354ceSNicholas Bellinger " CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n", 154066c7db68SChristoph Hellwig hdr->itt == RESERVED_ITT ? "Response" : "Request", 1541e48354ceSNicholas Bellinger hdr->itt, hdr->ttt, hdr->cmdsn, hdr->exp_statsn, 1542e48354ceSNicholas Bellinger payload_length); 1543e48354ceSNicholas Bellinger /* 1544e48354ceSNicholas Bellinger * This is not a response to a Unsolicited NopIN, which means 1545e48354ceSNicholas Bellinger * it can either be a NOPOUT ping request (with a valid ITT), 1546e48354ceSNicholas Bellinger * or a NOPOUT not requesting a NOPIN (with a reserved ITT). 1547e48354ceSNicholas Bellinger * Either way, make sure we allocate an struct iscsi_cmd, as both 1548e48354ceSNicholas Bellinger * can contain ping data. 1549e48354ceSNicholas Bellinger */ 155050e5c87dSChristoph Hellwig if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { 1551e48354ceSNicholas Bellinger cmd->iscsi_opcode = ISCSI_OP_NOOP_OUT; 1552e48354ceSNicholas Bellinger cmd->i_state = ISTATE_SEND_NOPIN; 1553e48354ceSNicholas Bellinger cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1554e48354ceSNicholas Bellinger 1 : 0); 1555e48354ceSNicholas Bellinger conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt; 1556e48354ceSNicholas Bellinger cmd->targ_xfer_tag = 0xFFFFFFFF; 155750e5c87dSChristoph Hellwig cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); 155850e5c87dSChristoph Hellwig cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); 1559e48354ceSNicholas Bellinger cmd->data_direction = DMA_NONE; 1560e48354ceSNicholas Bellinger } 1561e48354ceSNicholas Bellinger 1562778de368SNicholas Bellinger return 0; 1563778de368SNicholas Bellinger } 1564778de368SNicholas Bellinger EXPORT_SYMBOL(iscsit_setup_nop_out); 1565778de368SNicholas Bellinger 1566778de368SNicholas Bellinger int iscsit_process_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, 1567778de368SNicholas Bellinger struct iscsi_nopout *hdr) 1568778de368SNicholas Bellinger { 1569778de368SNicholas Bellinger struct iscsi_cmd *cmd_p = NULL; 1570778de368SNicholas Bellinger int cmdsn_ret = 0; 1571778de368SNicholas Bellinger /* 1572778de368SNicholas Bellinger * Initiator is expecting a NopIN ping reply.. 1573778de368SNicholas Bellinger */ 1574778de368SNicholas Bellinger if (hdr->itt != RESERVED_ITT) { 1575778de368SNicholas Bellinger BUG_ON(!cmd); 1576778de368SNicholas Bellinger 1577778de368SNicholas Bellinger spin_lock_bh(&conn->cmd_lock); 1578778de368SNicholas Bellinger list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); 1579778de368SNicholas Bellinger spin_unlock_bh(&conn->cmd_lock); 1580778de368SNicholas Bellinger 1581778de368SNicholas Bellinger iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); 1582778de368SNicholas Bellinger 1583778de368SNicholas Bellinger if (hdr->opcode & ISCSI_OP_IMMEDIATE) { 1584778de368SNicholas Bellinger iscsit_add_cmd_to_response_queue(cmd, conn, 1585778de368SNicholas Bellinger cmd->i_state); 1586778de368SNicholas Bellinger return 0; 1587778de368SNicholas Bellinger } 1588778de368SNicholas Bellinger 1589561bf158SNicholas Bellinger cmdsn_ret = iscsit_sequence_cmd(conn, cmd, 1590561bf158SNicholas Bellinger (unsigned char *)hdr, hdr->cmdsn); 1591778de368SNicholas Bellinger if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) 1592778de368SNicholas Bellinger return 0; 1593778de368SNicholas Bellinger if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) 1594ba159914SNicholas Bellinger return -1; 1595778de368SNicholas Bellinger 1596778de368SNicholas Bellinger return 0; 1597778de368SNicholas Bellinger } 1598778de368SNicholas Bellinger /* 1599778de368SNicholas Bellinger * This was a response to a unsolicited NOPIN ping. 1600778de368SNicholas Bellinger */ 1601778de368SNicholas Bellinger if (hdr->ttt != cpu_to_be32(0xFFFFFFFF)) { 1602778de368SNicholas Bellinger cmd_p = iscsit_find_cmd_from_ttt(conn, be32_to_cpu(hdr->ttt)); 1603778de368SNicholas Bellinger if (!cmd_p) 1604778de368SNicholas Bellinger return -EINVAL; 1605778de368SNicholas Bellinger 1606778de368SNicholas Bellinger iscsit_stop_nopin_response_timer(conn); 1607778de368SNicholas Bellinger 1608778de368SNicholas Bellinger cmd_p->i_state = ISTATE_REMOVE; 1609778de368SNicholas Bellinger iscsit_add_cmd_to_immediate_queue(cmd_p, conn, cmd_p->i_state); 1610778de368SNicholas Bellinger 1611778de368SNicholas Bellinger iscsit_start_nopin_timer(conn); 1612778de368SNicholas Bellinger return 0; 1613778de368SNicholas Bellinger } 1614778de368SNicholas Bellinger /* 1615778de368SNicholas Bellinger * Otherwise, initiator is not expecting a NOPIN is response. 1616778de368SNicholas Bellinger * Just ignore for now. 1617778de368SNicholas Bellinger */ 1618778de368SNicholas Bellinger return 0; 1619778de368SNicholas Bellinger } 1620778de368SNicholas Bellinger EXPORT_SYMBOL(iscsit_process_nop_out); 1621778de368SNicholas Bellinger 1622778de368SNicholas Bellinger static int iscsit_handle_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd, 1623778de368SNicholas Bellinger unsigned char *buf) 1624778de368SNicholas Bellinger { 1625778de368SNicholas Bellinger unsigned char *ping_data = NULL; 1626778de368SNicholas Bellinger struct iscsi_nopout *hdr = (struct iscsi_nopout *)buf; 1627778de368SNicholas Bellinger struct kvec *iov = NULL; 1628778de368SNicholas Bellinger u32 payload_length = ntoh24(hdr->dlength); 1629778de368SNicholas Bellinger int ret; 1630778de368SNicholas Bellinger 1631778de368SNicholas Bellinger ret = iscsit_setup_nop_out(conn, cmd, hdr); 1632778de368SNicholas Bellinger if (ret < 0) 1633561bf158SNicholas Bellinger return 0; 1634778de368SNicholas Bellinger /* 1635778de368SNicholas Bellinger * Handle NOP-OUT payload for traditional iSCSI sockets 1636778de368SNicholas Bellinger */ 163750e5c87dSChristoph Hellwig if (payload_length && hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { 1638778de368SNicholas Bellinger u32 checksum, data_crc, padding = 0; 1639778de368SNicholas Bellinger int niov = 0, rx_got, rx_size = payload_length; 1640778de368SNicholas Bellinger 1641e48354ceSNicholas Bellinger ping_data = kzalloc(payload_length + 1, GFP_KERNEL); 1642e48354ceSNicholas Bellinger if (!ping_data) { 1643e48354ceSNicholas Bellinger pr_err("Unable to allocate memory for" 1644e48354ceSNicholas Bellinger " NOPOUT ping data.\n"); 1645e48354ceSNicholas Bellinger ret = -1; 1646e48354ceSNicholas Bellinger goto out; 1647e48354ceSNicholas Bellinger } 1648e48354ceSNicholas Bellinger 1649e48354ceSNicholas Bellinger iov = &cmd->iov_misc[0]; 1650e48354ceSNicholas Bellinger iov[niov].iov_base = ping_data; 1651e48354ceSNicholas Bellinger iov[niov++].iov_len = payload_length; 1652e48354ceSNicholas Bellinger 1653e48354ceSNicholas Bellinger padding = ((-payload_length) & 3); 1654e48354ceSNicholas Bellinger if (padding != 0) { 1655e48354ceSNicholas Bellinger pr_debug("Receiving %u additional bytes" 1656e48354ceSNicholas Bellinger " for padding.\n", padding); 1657e48354ceSNicholas Bellinger iov[niov].iov_base = &cmd->pad_bytes; 1658e48354ceSNicholas Bellinger iov[niov++].iov_len = padding; 1659e48354ceSNicholas Bellinger rx_size += padding; 1660e48354ceSNicholas Bellinger } 1661e48354ceSNicholas Bellinger if (conn->conn_ops->DataDigest) { 1662e48354ceSNicholas Bellinger iov[niov].iov_base = &checksum; 1663e48354ceSNicholas Bellinger iov[niov++].iov_len = ISCSI_CRC_LEN; 1664e48354ceSNicholas Bellinger rx_size += ISCSI_CRC_LEN; 1665e48354ceSNicholas Bellinger } 1666e48354ceSNicholas Bellinger 1667e48354ceSNicholas Bellinger rx_got = rx_data(conn, &cmd->iov_misc[0], niov, rx_size); 1668e48354ceSNicholas Bellinger if (rx_got != rx_size) { 1669e48354ceSNicholas Bellinger ret = -1; 1670e48354ceSNicholas Bellinger goto out; 1671e48354ceSNicholas Bellinger } 1672e48354ceSNicholas Bellinger 1673e48354ceSNicholas Bellinger if (conn->conn_ops->DataDigest) { 1674e48354ceSNicholas Bellinger iscsit_do_crypto_hash_buf(&conn->conn_rx_hash, 1675e48354ceSNicholas Bellinger ping_data, payload_length, 1676e48354ceSNicholas Bellinger padding, cmd->pad_bytes, 1677e48354ceSNicholas Bellinger (u8 *)&data_crc); 1678e48354ceSNicholas Bellinger 1679e48354ceSNicholas Bellinger if (checksum != data_crc) { 1680e48354ceSNicholas Bellinger pr_err("Ping data CRC32C DataDigest" 1681e48354ceSNicholas Bellinger " 0x%08x does not match computed 0x%08x\n", 1682e48354ceSNicholas Bellinger checksum, data_crc); 1683e48354ceSNicholas Bellinger if (!conn->sess->sess_ops->ErrorRecoveryLevel) { 1684e48354ceSNicholas Bellinger pr_err("Unable to recover from" 1685e48354ceSNicholas Bellinger " NOPOUT Ping DataCRC failure while in" 1686e48354ceSNicholas Bellinger " ERL=0.\n"); 1687e48354ceSNicholas Bellinger ret = -1; 1688e48354ceSNicholas Bellinger goto out; 1689e48354ceSNicholas Bellinger } else { 1690e48354ceSNicholas Bellinger /* 1691e48354ceSNicholas Bellinger * Silently drop this PDU and let the 1692e48354ceSNicholas Bellinger * initiator plug the CmdSN gap. 1693e48354ceSNicholas Bellinger */ 1694e48354ceSNicholas Bellinger pr_debug("Dropping NOPOUT" 1695e48354ceSNicholas Bellinger " Command CmdSN: 0x%08x due to" 1696e48354ceSNicholas Bellinger " DataCRC error.\n", hdr->cmdsn); 1697e48354ceSNicholas Bellinger ret = 0; 1698e48354ceSNicholas Bellinger goto out; 1699e48354ceSNicholas Bellinger } 1700e48354ceSNicholas Bellinger } else { 1701e48354ceSNicholas Bellinger pr_debug("Got CRC32C DataDigest" 1702e48354ceSNicholas Bellinger " 0x%08x for %u bytes of ping data.\n", 1703e48354ceSNicholas Bellinger checksum, payload_length); 1704e48354ceSNicholas Bellinger } 1705e48354ceSNicholas Bellinger } 1706e48354ceSNicholas Bellinger 1707e48354ceSNicholas Bellinger ping_data[payload_length] = '\0'; 1708e48354ceSNicholas Bellinger /* 1709e48354ceSNicholas Bellinger * Attach ping data to struct iscsi_cmd->buf_ptr. 1710e48354ceSNicholas Bellinger */ 17118359cf43SJörn Engel cmd->buf_ptr = ping_data; 1712e48354ceSNicholas Bellinger cmd->buf_ptr_size = payload_length; 1713e48354ceSNicholas Bellinger 1714e48354ceSNicholas Bellinger pr_debug("Got %u bytes of NOPOUT ping" 1715e48354ceSNicholas Bellinger " data.\n", payload_length); 1716e48354ceSNicholas Bellinger pr_debug("Ping Data: \"%s\"\n", ping_data); 1717e48354ceSNicholas Bellinger } 1718e48354ceSNicholas Bellinger 1719778de368SNicholas Bellinger return iscsit_process_nop_out(conn, cmd, hdr); 1720e48354ceSNicholas Bellinger out: 1721e48354ceSNicholas Bellinger if (cmd) 1722aafc9d15SNicholas Bellinger iscsit_free_cmd(cmd, false); 1723778de368SNicholas Bellinger 1724e48354ceSNicholas Bellinger kfree(ping_data); 1725e48354ceSNicholas Bellinger return ret; 1726e48354ceSNicholas Bellinger } 1727e48354ceSNicholas Bellinger 17283e1c81a9SNicholas Bellinger int 17293e1c81a9SNicholas Bellinger iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, 1730e48354ceSNicholas Bellinger unsigned char *buf) 1731e48354ceSNicholas Bellinger { 1732e48354ceSNicholas Bellinger struct se_tmr_req *se_tmr; 1733e48354ceSNicholas Bellinger struct iscsi_tmr_req *tmr_req; 1734e48354ceSNicholas Bellinger struct iscsi_tm *hdr; 1735186a9647SNicholas Bellinger int out_of_order_cmdsn = 0, ret; 1736186a9647SNicholas Bellinger bool sess_ref = false; 1737e48354ceSNicholas Bellinger u8 function; 1738e48354ceSNicholas Bellinger 1739e48354ceSNicholas Bellinger hdr = (struct iscsi_tm *) buf; 1740e48354ceSNicholas Bellinger hdr->flags &= ~ISCSI_FLAG_CMD_FINAL; 1741e48354ceSNicholas Bellinger function = hdr->flags; 1742e48354ceSNicholas Bellinger 1743e48354ceSNicholas Bellinger pr_debug("Got Task Management Request ITT: 0x%08x, CmdSN:" 1744e48354ceSNicholas Bellinger " 0x%08x, Function: 0x%02x, RefTaskTag: 0x%08x, RefCmdSN:" 1745e48354ceSNicholas Bellinger " 0x%08x, CID: %hu\n", hdr->itt, hdr->cmdsn, function, 1746e48354ceSNicholas Bellinger hdr->rtt, hdr->refcmdsn, conn->cid); 1747e48354ceSNicholas Bellinger 1748e48354ceSNicholas Bellinger if ((function != ISCSI_TM_FUNC_ABORT_TASK) && 1749e48354ceSNicholas Bellinger ((function != ISCSI_TM_FUNC_TASK_REASSIGN) && 175066c7db68SChristoph Hellwig hdr->rtt != RESERVED_ITT)) { 1751e48354ceSNicholas Bellinger pr_err("RefTaskTag should be set to 0xFFFFFFFF.\n"); 175266c7db68SChristoph Hellwig hdr->rtt = RESERVED_ITT; 1753e48354ceSNicholas Bellinger } 1754e48354ceSNicholas Bellinger 1755e48354ceSNicholas Bellinger if ((function == ISCSI_TM_FUNC_TASK_REASSIGN) && 1756e48354ceSNicholas Bellinger !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { 1757e48354ceSNicholas Bellinger pr_err("Task Management Request TASK_REASSIGN not" 1758e48354ceSNicholas Bellinger " issued as immediate command, bad iSCSI Initiator" 1759e48354ceSNicholas Bellinger "implementation\n"); 1760ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 1761ba159914SNicholas Bellinger ISCSI_REASON_PROTOCOL_ERROR, buf); 1762e48354ceSNicholas Bellinger } 1763e48354ceSNicholas Bellinger if ((function != ISCSI_TM_FUNC_ABORT_TASK) && 176450e5c87dSChristoph Hellwig be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG) 176550e5c87dSChristoph Hellwig hdr->refcmdsn = cpu_to_be32(ISCSI_RESERVED_TAG); 1766e48354ceSNicholas Bellinger 1767d28b1169SAndy Grover cmd->data_direction = DMA_NONE; 1768d28b1169SAndy Grover 1769d28b1169SAndy Grover cmd->tmr_req = kzalloc(sizeof(struct iscsi_tmr_req), GFP_KERNEL); 1770d28b1169SAndy Grover if (!cmd->tmr_req) { 1771d28b1169SAndy Grover pr_err("Unable to allocate memory for" 1772d28b1169SAndy Grover " Task Management command!\n"); 1773ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 1774d28b1169SAndy Grover ISCSI_REASON_BOOKMARK_NO_RESOURCES, 1775ba159914SNicholas Bellinger buf); 1776d28b1169SAndy Grover } 1777d28b1169SAndy Grover 1778d28b1169SAndy Grover /* 1779d28b1169SAndy Grover * TASK_REASSIGN for ERL=2 / connection stays inside of 1780d28b1169SAndy Grover * LIO-Target $FABRIC_MOD 1781d28b1169SAndy Grover */ 1782d28b1169SAndy Grover if (function != ISCSI_TM_FUNC_TASK_REASSIGN) { 1783d28b1169SAndy Grover 1784d28b1169SAndy Grover u8 tcm_function; 1785d28b1169SAndy Grover int ret; 1786d28b1169SAndy Grover 1787d28b1169SAndy Grover transport_init_se_cmd(&cmd->se_cmd, 1788d28b1169SAndy Grover &lio_target_fabric_configfs->tf_ops, 1789d28b1169SAndy Grover conn->sess->se_sess, 0, DMA_NONE, 17909c58b7ddSRoland Dreier MSG_SIMPLE_TAG, cmd->sense_buffer + 2); 1791d28b1169SAndy Grover 1792186a9647SNicholas Bellinger target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true); 1793186a9647SNicholas Bellinger sess_ref = true; 1794186a9647SNicholas Bellinger 1795d28b1169SAndy Grover switch (function) { 1796d28b1169SAndy Grover case ISCSI_TM_FUNC_ABORT_TASK: 1797d28b1169SAndy Grover tcm_function = TMR_ABORT_TASK; 1798d28b1169SAndy Grover break; 1799d28b1169SAndy Grover case ISCSI_TM_FUNC_ABORT_TASK_SET: 1800d28b1169SAndy Grover tcm_function = TMR_ABORT_TASK_SET; 1801d28b1169SAndy Grover break; 1802d28b1169SAndy Grover case ISCSI_TM_FUNC_CLEAR_ACA: 1803d28b1169SAndy Grover tcm_function = TMR_CLEAR_ACA; 1804d28b1169SAndy Grover break; 1805d28b1169SAndy Grover case ISCSI_TM_FUNC_CLEAR_TASK_SET: 1806d28b1169SAndy Grover tcm_function = TMR_CLEAR_TASK_SET; 1807d28b1169SAndy Grover break; 1808d28b1169SAndy Grover case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET: 1809d28b1169SAndy Grover tcm_function = TMR_LUN_RESET; 1810d28b1169SAndy Grover break; 1811d28b1169SAndy Grover case ISCSI_TM_FUNC_TARGET_WARM_RESET: 1812d28b1169SAndy Grover tcm_function = TMR_TARGET_WARM_RESET; 1813d28b1169SAndy Grover break; 1814d28b1169SAndy Grover case ISCSI_TM_FUNC_TARGET_COLD_RESET: 1815d28b1169SAndy Grover tcm_function = TMR_TARGET_COLD_RESET; 1816d28b1169SAndy Grover break; 1817d28b1169SAndy Grover default: 1818d28b1169SAndy Grover pr_err("Unknown iSCSI TMR Function:" 1819d28b1169SAndy Grover " 0x%02x\n", function); 1820ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 1821ba159914SNicholas Bellinger ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); 1822d28b1169SAndy Grover } 1823d28b1169SAndy Grover 1824d28b1169SAndy Grover ret = core_tmr_alloc_req(&cmd->se_cmd, cmd->tmr_req, 1825d28b1169SAndy Grover tcm_function, GFP_KERNEL); 1826d28b1169SAndy Grover if (ret < 0) 1827ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 1828ba159914SNicholas Bellinger ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); 1829d28b1169SAndy Grover 1830d28b1169SAndy Grover cmd->tmr_req->se_tmr_req = cmd->se_cmd.se_tmr_req; 1831d28b1169SAndy Grover } 1832d28b1169SAndy Grover 1833e48354ceSNicholas Bellinger cmd->iscsi_opcode = ISCSI_OP_SCSI_TMFUNC; 1834e48354ceSNicholas Bellinger cmd->i_state = ISTATE_SEND_TASKMGTRSP; 1835e48354ceSNicholas Bellinger cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0); 1836e48354ceSNicholas Bellinger cmd->init_task_tag = hdr->itt; 1837e48354ceSNicholas Bellinger cmd->targ_xfer_tag = 0xFFFFFFFF; 183850e5c87dSChristoph Hellwig cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); 183950e5c87dSChristoph Hellwig cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); 1840e48354ceSNicholas Bellinger se_tmr = cmd->se_cmd.se_tmr_req; 1841e48354ceSNicholas Bellinger tmr_req = cmd->tmr_req; 1842e48354ceSNicholas Bellinger /* 1843e48354ceSNicholas Bellinger * Locate the struct se_lun for all TMRs not related to ERL=2 TASK_REASSIGN 1844e48354ceSNicholas Bellinger */ 1845e48354ceSNicholas Bellinger if (function != ISCSI_TM_FUNC_TASK_REASSIGN) { 18464f26998aSAndy Grover ret = transport_lookup_tmr_lun(&cmd->se_cmd, 18474f26998aSAndy Grover scsilun_to_int(&hdr->lun)); 1848e48354ceSNicholas Bellinger if (ret < 0) { 1849e48354ceSNicholas Bellinger se_tmr->response = ISCSI_TMF_RSP_NO_LUN; 1850e48354ceSNicholas Bellinger goto attach; 1851e48354ceSNicholas Bellinger } 1852e48354ceSNicholas Bellinger } 1853e48354ceSNicholas Bellinger 1854e48354ceSNicholas Bellinger switch (function) { 1855e48354ceSNicholas Bellinger case ISCSI_TM_FUNC_ABORT_TASK: 1856e48354ceSNicholas Bellinger se_tmr->response = iscsit_tmr_abort_task(cmd, buf); 1857de103c93SChristoph Hellwig if (se_tmr->response) 1858e48354ceSNicholas Bellinger goto attach; 1859e48354ceSNicholas Bellinger break; 1860e48354ceSNicholas Bellinger case ISCSI_TM_FUNC_ABORT_TASK_SET: 1861e48354ceSNicholas Bellinger case ISCSI_TM_FUNC_CLEAR_ACA: 1862e48354ceSNicholas Bellinger case ISCSI_TM_FUNC_CLEAR_TASK_SET: 1863e48354ceSNicholas Bellinger case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET: 1864e48354ceSNicholas Bellinger break; 1865e48354ceSNicholas Bellinger case ISCSI_TM_FUNC_TARGET_WARM_RESET: 1866e48354ceSNicholas Bellinger if (iscsit_tmr_task_warm_reset(conn, tmr_req, buf) < 0) { 1867e48354ceSNicholas Bellinger se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED; 1868e48354ceSNicholas Bellinger goto attach; 1869e48354ceSNicholas Bellinger } 1870e48354ceSNicholas Bellinger break; 1871e48354ceSNicholas Bellinger case ISCSI_TM_FUNC_TARGET_COLD_RESET: 1872e48354ceSNicholas Bellinger if (iscsit_tmr_task_cold_reset(conn, tmr_req, buf) < 0) { 1873e48354ceSNicholas Bellinger se_tmr->response = ISCSI_TMF_RSP_AUTH_FAILED; 1874e48354ceSNicholas Bellinger goto attach; 1875e48354ceSNicholas Bellinger } 1876e48354ceSNicholas Bellinger break; 1877e48354ceSNicholas Bellinger case ISCSI_TM_FUNC_TASK_REASSIGN: 1878e48354ceSNicholas Bellinger se_tmr->response = iscsit_tmr_task_reassign(cmd, buf); 1879e48354ceSNicholas Bellinger /* 1880e48354ceSNicholas Bellinger * Perform sanity checks on the ExpDataSN only if the 1881e48354ceSNicholas Bellinger * TASK_REASSIGN was successful. 1882e48354ceSNicholas Bellinger */ 1883de103c93SChristoph Hellwig if (se_tmr->response) 1884e48354ceSNicholas Bellinger break; 1885e48354ceSNicholas Bellinger 1886e48354ceSNicholas Bellinger if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0) 1887ba159914SNicholas Bellinger return iscsit_add_reject_cmd(cmd, 1888ba159914SNicholas Bellinger ISCSI_REASON_BOOKMARK_INVALID, buf); 1889e48354ceSNicholas Bellinger break; 1890e48354ceSNicholas Bellinger default: 1891e48354ceSNicholas Bellinger pr_err("Unknown TMR function: 0x%02x, protocol" 1892e48354ceSNicholas Bellinger " error.\n", function); 1893e48354ceSNicholas Bellinger se_tmr->response = ISCSI_TMF_RSP_NOT_SUPPORTED; 1894e48354ceSNicholas Bellinger goto attach; 1895e48354ceSNicholas Bellinger } 1896e48354ceSNicholas Bellinger 1897e48354ceSNicholas Bellinger if ((function != ISCSI_TM_FUNC_TASK_REASSIGN) && 1898e48354ceSNicholas Bellinger (se_tmr->response == ISCSI_TMF_RSP_COMPLETE)) 1899e48354ceSNicholas Bellinger se_tmr->call_transport = 1; 1900e48354ceSNicholas Bellinger attach: 1901e48354ceSNicholas Bellinger spin_lock_bh(&conn->cmd_lock); 19022fbb471eSAndy Grover list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); 1903e48354ceSNicholas Bellinger spin_unlock_bh(&conn->cmd_lock); 1904e48354ceSNicholas Bellinger 1905e48354ceSNicholas Bellinger if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { 1906561bf158SNicholas Bellinger int cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn); 1907e48354ceSNicholas Bellinger if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP) 1908e48354ceSNicholas Bellinger out_of_order_cmdsn = 1; 19095a4c8666SNicholas Bellinger else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) 1910e48354ceSNicholas Bellinger return 0; 19115a4c8666SNicholas Bellinger else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) 1912ba159914SNicholas Bellinger return -1; 1913e48354ceSNicholas Bellinger } 191450e5c87dSChristoph Hellwig iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); 1915e48354ceSNicholas Bellinger 19165a4c8666SNicholas Bellinger if (out_of_order_cmdsn || !(hdr->opcode & ISCSI_OP_IMMEDIATE)) 1917e48354ceSNicholas Bellinger return 0; 1918e48354ceSNicholas Bellinger /* 1919e48354ceSNicholas Bellinger * Found the referenced task, send to transport for processing. 1920e48354ceSNicholas Bellinger */ 1921e48354ceSNicholas Bellinger if (se_tmr->call_transport) 1922e48354ceSNicholas Bellinger return transport_generic_handle_tmr(&cmd->se_cmd); 1923e48354ceSNicholas Bellinger 1924e48354ceSNicholas Bellinger /* 1925e48354ceSNicholas Bellinger * Could not find the referenced LUN, task, or Task Management 1926e48354ceSNicholas Bellinger * command not authorized or supported. Change state and 1927e48354ceSNicholas Bellinger * let the tx_thread send the response. 1928e48354ceSNicholas Bellinger * 1929e48354ceSNicholas Bellinger * For connection recovery, this is also the default action for 1930e48354ceSNicholas Bellinger * TMR TASK_REASSIGN. 1931e48354ceSNicholas Bellinger */ 1932186a9647SNicholas Bellinger if (sess_ref) { 1933186a9647SNicholas Bellinger pr_debug("Handle TMR, using sess_ref=true check\n"); 1934186a9647SNicholas Bellinger target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); 1935186a9647SNicholas Bellinger } 1936186a9647SNicholas Bellinger 1937e48354ceSNicholas Bellinger iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); 1938e48354ceSNicholas Bellinger return 0; 1939e48354ceSNicholas Bellinger } 19403e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_handle_task_mgt_cmd); 1941e48354ceSNicholas Bellinger 1942e48354ceSNicholas Bellinger /* #warning FIXME: Support Text Command parameters besides SendTargets */ 194364534aa7SNicholas Bellinger int 194464534aa7SNicholas Bellinger iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, 194564534aa7SNicholas Bellinger struct iscsi_text *hdr) 1946e48354ceSNicholas Bellinger { 194764534aa7SNicholas Bellinger u32 payload_length = ntoh24(hdr->dlength); 1948e48354ceSNicholas Bellinger 194921f5aa7eSNicholas Bellinger if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { 1950e48354ceSNicholas Bellinger pr_err("Unable to accept text parameter length: %u" 195121f5aa7eSNicholas Bellinger "greater than MaxXmitDataSegmentLength %u.\n", 195221f5aa7eSNicholas Bellinger payload_length, conn->conn_ops->MaxXmitDataSegmentLength); 1953ba159914SNicholas Bellinger return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, 1954ba159914SNicholas Bellinger (unsigned char *)hdr); 1955e48354ceSNicholas Bellinger } 1956e48354ceSNicholas Bellinger 1957e48354ceSNicholas Bellinger pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x," 1958e48354ceSNicholas Bellinger " ExpStatSN: 0x%08x, Length: %u\n", hdr->itt, hdr->cmdsn, 1959e48354ceSNicholas Bellinger hdr->exp_statsn, payload_length); 1960e48354ceSNicholas Bellinger 196164534aa7SNicholas Bellinger cmd->iscsi_opcode = ISCSI_OP_TEXT; 196264534aa7SNicholas Bellinger cmd->i_state = ISTATE_SEND_TEXTRSP; 196364534aa7SNicholas Bellinger cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0); 196464534aa7SNicholas Bellinger conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt; 196564534aa7SNicholas Bellinger cmd->targ_xfer_tag = 0xFFFFFFFF; 196664534aa7SNicholas Bellinger cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); 196764534aa7SNicholas Bellinger cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); 196864534aa7SNicholas Bellinger cmd->data_direction = DMA_NONE; 196964534aa7SNicholas Bellinger 197064534aa7SNicholas Bellinger return 0; 197164534aa7SNicholas Bellinger } 197264534aa7SNicholas Bellinger EXPORT_SYMBOL(iscsit_setup_text_cmd); 197364534aa7SNicholas Bellinger 197464534aa7SNicholas Bellinger int 197564534aa7SNicholas Bellinger iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, 197664534aa7SNicholas Bellinger struct iscsi_text *hdr) 197764534aa7SNicholas Bellinger { 19789864ca9dSNicholas Bellinger unsigned char *text_in = cmd->text_in_ptr, *text_ptr; 197964534aa7SNicholas Bellinger int cmdsn_ret; 198064534aa7SNicholas Bellinger 19819864ca9dSNicholas Bellinger if (!text_in) { 19829864ca9dSNicholas Bellinger pr_err("Unable to locate text_in buffer for sendtargets" 19839864ca9dSNicholas Bellinger " discovery\n"); 19849864ca9dSNicholas Bellinger goto reject; 19859864ca9dSNicholas Bellinger } 19869864ca9dSNicholas Bellinger if (strncmp("SendTargets", text_in, 11) != 0) { 19879864ca9dSNicholas Bellinger pr_err("Received Text Data that is not" 19889864ca9dSNicholas Bellinger " SendTargets, cannot continue.\n"); 19899864ca9dSNicholas Bellinger goto reject; 19909864ca9dSNicholas Bellinger } 19919864ca9dSNicholas Bellinger text_ptr = strchr(text_in, '='); 19929864ca9dSNicholas Bellinger if (!text_ptr) { 19939864ca9dSNicholas Bellinger pr_err("No \"=\" separator found in Text Data," 19949864ca9dSNicholas Bellinger " cannot continue.\n"); 19959864ca9dSNicholas Bellinger goto reject; 19969864ca9dSNicholas Bellinger } 19979864ca9dSNicholas Bellinger if (!strncmp("=All", text_ptr, 4)) { 19989864ca9dSNicholas Bellinger cmd->cmd_flags |= IFC_SENDTARGETS_ALL; 19996665889cSNicholas Bellinger } else if (!strncmp("=iqn.", text_ptr, 5) || 20006665889cSNicholas Bellinger !strncmp("=eui.", text_ptr, 5)) { 20016665889cSNicholas Bellinger cmd->cmd_flags |= IFC_SENDTARGETS_SINGLE; 20029864ca9dSNicholas Bellinger } else { 20039864ca9dSNicholas Bellinger pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr); 20049864ca9dSNicholas Bellinger goto reject; 20059864ca9dSNicholas Bellinger } 20069864ca9dSNicholas Bellinger 200764534aa7SNicholas Bellinger spin_lock_bh(&conn->cmd_lock); 200864534aa7SNicholas Bellinger list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); 200964534aa7SNicholas Bellinger spin_unlock_bh(&conn->cmd_lock); 201064534aa7SNicholas Bellinger 201164534aa7SNicholas Bellinger iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); 201264534aa7SNicholas Bellinger 201364534aa7SNicholas Bellinger if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) { 2014561bf158SNicholas Bellinger cmdsn_ret = iscsit_sequence_cmd(conn, cmd, 2015561bf158SNicholas Bellinger (unsigned char *)hdr, hdr->cmdsn); 201664534aa7SNicholas Bellinger if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) 2017ba159914SNicholas Bellinger return -1; 2018ba159914SNicholas Bellinger 201964534aa7SNicholas Bellinger return 0; 202064534aa7SNicholas Bellinger } 202164534aa7SNicholas Bellinger 202264534aa7SNicholas Bellinger return iscsit_execute_cmd(cmd, 0); 20239864ca9dSNicholas Bellinger 20249864ca9dSNicholas Bellinger reject: 2025ba159914SNicholas Bellinger return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, 2026ba159914SNicholas Bellinger (unsigned char *)hdr); 202764534aa7SNicholas Bellinger } 202864534aa7SNicholas Bellinger EXPORT_SYMBOL(iscsit_process_text_cmd); 202964534aa7SNicholas Bellinger 203064534aa7SNicholas Bellinger static int 203164534aa7SNicholas Bellinger iscsit_handle_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, 203264534aa7SNicholas Bellinger unsigned char *buf) 203364534aa7SNicholas Bellinger { 203464534aa7SNicholas Bellinger struct iscsi_text *hdr = (struct iscsi_text *)buf; 203564534aa7SNicholas Bellinger char *text_in = NULL; 203664534aa7SNicholas Bellinger u32 payload_length = ntoh24(hdr->dlength); 203764534aa7SNicholas Bellinger int rx_size, rc; 203864534aa7SNicholas Bellinger 203964534aa7SNicholas Bellinger rc = iscsit_setup_text_cmd(conn, cmd, hdr); 204064534aa7SNicholas Bellinger if (rc < 0) 2041561bf158SNicholas Bellinger return 0; 204264534aa7SNicholas Bellinger 204364534aa7SNicholas Bellinger rx_size = payload_length; 204464534aa7SNicholas Bellinger if (payload_length) { 204564534aa7SNicholas Bellinger u32 checksum = 0, data_crc = 0; 204664534aa7SNicholas Bellinger u32 padding = 0, pad_bytes = 0; 204764534aa7SNicholas Bellinger int niov = 0, rx_got; 204864534aa7SNicholas Bellinger struct kvec iov[3]; 204964534aa7SNicholas Bellinger 205064534aa7SNicholas Bellinger text_in = kzalloc(payload_length, GFP_KERNEL); 2051e48354ceSNicholas Bellinger if (!text_in) { 2052e48354ceSNicholas Bellinger pr_err("Unable to allocate memory for" 2053e48354ceSNicholas Bellinger " incoming text parameters\n"); 205464534aa7SNicholas Bellinger goto reject; 2055e48354ceSNicholas Bellinger } 20569864ca9dSNicholas Bellinger cmd->text_in_ptr = text_in; 2057e48354ceSNicholas Bellinger 2058e48354ceSNicholas Bellinger memset(iov, 0, 3 * sizeof(struct kvec)); 2059e48354ceSNicholas Bellinger iov[niov].iov_base = text_in; 206064534aa7SNicholas Bellinger iov[niov++].iov_len = payload_length; 2061e48354ceSNicholas Bellinger 2062e48354ceSNicholas Bellinger padding = ((-payload_length) & 3); 2063e48354ceSNicholas Bellinger if (padding != 0) { 206476f1928eSNicholas Bellinger iov[niov].iov_base = &pad_bytes; 2065e48354ceSNicholas Bellinger iov[niov++].iov_len = padding; 2066e48354ceSNicholas Bellinger rx_size += padding; 2067e48354ceSNicholas Bellinger pr_debug("Receiving %u additional bytes" 2068e48354ceSNicholas Bellinger " for padding.\n", padding); 2069e48354ceSNicholas Bellinger } 2070e48354ceSNicholas Bellinger if (conn->conn_ops->DataDigest) { 2071e48354ceSNicholas Bellinger iov[niov].iov_base = &checksum; 2072e48354ceSNicholas Bellinger iov[niov++].iov_len = ISCSI_CRC_LEN; 2073e48354ceSNicholas Bellinger rx_size += ISCSI_CRC_LEN; 2074e48354ceSNicholas Bellinger } 2075e48354ceSNicholas Bellinger 2076e48354ceSNicholas Bellinger rx_got = rx_data(conn, &iov[0], niov, rx_size); 207764534aa7SNicholas Bellinger if (rx_got != rx_size) 207864534aa7SNicholas Bellinger goto reject; 2079e48354ceSNicholas Bellinger 2080e48354ceSNicholas Bellinger if (conn->conn_ops->DataDigest) { 2081e48354ceSNicholas Bellinger iscsit_do_crypto_hash_buf(&conn->conn_rx_hash, 208264534aa7SNicholas Bellinger text_in, payload_length, 208376f1928eSNicholas Bellinger padding, (u8 *)&pad_bytes, 2084e48354ceSNicholas Bellinger (u8 *)&data_crc); 2085e48354ceSNicholas Bellinger 2086e48354ceSNicholas Bellinger if (checksum != data_crc) { 2087e48354ceSNicholas Bellinger pr_err("Text data CRC32C DataDigest" 2088e48354ceSNicholas Bellinger " 0x%08x does not match computed" 2089e48354ceSNicholas Bellinger " 0x%08x\n", checksum, data_crc); 2090e48354ceSNicholas Bellinger if (!conn->sess->sess_ops->ErrorRecoveryLevel) { 2091e48354ceSNicholas Bellinger pr_err("Unable to recover from" 2092e48354ceSNicholas Bellinger " Text Data digest failure while in" 2093e48354ceSNicholas Bellinger " ERL=0.\n"); 209464534aa7SNicholas Bellinger goto reject; 2095e48354ceSNicholas Bellinger } else { 2096e48354ceSNicholas Bellinger /* 2097e48354ceSNicholas Bellinger * Silently drop this PDU and let the 2098e48354ceSNicholas Bellinger * initiator plug the CmdSN gap. 2099e48354ceSNicholas Bellinger */ 2100e48354ceSNicholas Bellinger pr_debug("Dropping Text" 2101e48354ceSNicholas Bellinger " Command CmdSN: 0x%08x due to" 2102e48354ceSNicholas Bellinger " DataCRC error.\n", hdr->cmdsn); 2103e48354ceSNicholas Bellinger kfree(text_in); 2104e48354ceSNicholas Bellinger return 0; 2105e48354ceSNicholas Bellinger } 2106e48354ceSNicholas Bellinger } else { 2107e48354ceSNicholas Bellinger pr_debug("Got CRC32C DataDigest" 2108e48354ceSNicholas Bellinger " 0x%08x for %u bytes of text data.\n", 210964534aa7SNicholas Bellinger checksum, payload_length); 2110e48354ceSNicholas Bellinger } 2111e48354ceSNicholas Bellinger } 211264534aa7SNicholas Bellinger text_in[payload_length - 1] = '\0'; 2113e48354ceSNicholas Bellinger pr_debug("Successfully read %d bytes of text" 211464534aa7SNicholas Bellinger " data.\n", payload_length); 2115e48354ceSNicholas Bellinger } 2116e48354ceSNicholas Bellinger 211764534aa7SNicholas Bellinger return iscsit_process_text_cmd(conn, cmd, hdr); 2118e48354ceSNicholas Bellinger 211964534aa7SNicholas Bellinger reject: 21209864ca9dSNicholas Bellinger kfree(cmd->text_in_ptr); 21219864ca9dSNicholas Bellinger cmd->text_in_ptr = NULL; 2122ba159914SNicholas Bellinger return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf); 2123e48354ceSNicholas Bellinger } 212464534aa7SNicholas Bellinger EXPORT_SYMBOL(iscsit_handle_text_cmd); 2125e48354ceSNicholas Bellinger 2126e48354ceSNicholas Bellinger int iscsit_logout_closesession(struct iscsi_cmd *cmd, struct iscsi_conn *conn) 2127e48354ceSNicholas Bellinger { 2128e48354ceSNicholas Bellinger struct iscsi_conn *conn_p; 2129e48354ceSNicholas Bellinger struct iscsi_session *sess = conn->sess; 2130e48354ceSNicholas Bellinger 2131e48354ceSNicholas Bellinger pr_debug("Received logout request CLOSESESSION on CID: %hu" 2132e48354ceSNicholas Bellinger " for SID: %u.\n", conn->cid, conn->sess->sid); 2133e48354ceSNicholas Bellinger 2134e48354ceSNicholas Bellinger atomic_set(&sess->session_logout, 1); 2135e48354ceSNicholas Bellinger atomic_set(&conn->conn_logout_remove, 1); 2136e48354ceSNicholas Bellinger conn->conn_logout_reason = ISCSI_LOGOUT_REASON_CLOSE_SESSION; 2137e48354ceSNicholas Bellinger 2138e48354ceSNicholas Bellinger iscsit_inc_conn_usage_count(conn); 2139e48354ceSNicholas Bellinger iscsit_inc_session_usage_count(sess); 2140e48354ceSNicholas Bellinger 2141e48354ceSNicholas Bellinger spin_lock_bh(&sess->conn_lock); 2142e48354ceSNicholas Bellinger list_for_each_entry(conn_p, &sess->sess_conn_list, conn_list) { 2143e48354ceSNicholas Bellinger if (conn_p->conn_state != TARG_CONN_STATE_LOGGED_IN) 2144e48354ceSNicholas Bellinger continue; 2145e48354ceSNicholas Bellinger 2146e48354ceSNicholas Bellinger pr_debug("Moving to TARG_CONN_STATE_IN_LOGOUT.\n"); 2147e48354ceSNicholas Bellinger conn_p->conn_state = TARG_CONN_STATE_IN_LOGOUT; 2148e48354ceSNicholas Bellinger } 2149e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 2150e48354ceSNicholas Bellinger 2151e48354ceSNicholas Bellinger iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); 2152e48354ceSNicholas Bellinger 2153e48354ceSNicholas Bellinger return 0; 2154e48354ceSNicholas Bellinger } 2155e48354ceSNicholas Bellinger 2156e48354ceSNicholas Bellinger int iscsit_logout_closeconnection(struct iscsi_cmd *cmd, struct iscsi_conn *conn) 2157e48354ceSNicholas Bellinger { 2158e48354ceSNicholas Bellinger struct iscsi_conn *l_conn; 2159e48354ceSNicholas Bellinger struct iscsi_session *sess = conn->sess; 2160e48354ceSNicholas Bellinger 2161e48354ceSNicholas Bellinger pr_debug("Received logout request CLOSECONNECTION for CID:" 2162e48354ceSNicholas Bellinger " %hu on CID: %hu.\n", cmd->logout_cid, conn->cid); 2163e48354ceSNicholas Bellinger 2164e48354ceSNicholas Bellinger /* 2165e48354ceSNicholas Bellinger * A Logout Request with a CLOSECONNECTION reason code for a CID 2166e48354ceSNicholas Bellinger * can arrive on a connection with a differing CID. 2167e48354ceSNicholas Bellinger */ 2168e48354ceSNicholas Bellinger if (conn->cid == cmd->logout_cid) { 2169e48354ceSNicholas Bellinger spin_lock_bh(&conn->state_lock); 2170e48354ceSNicholas Bellinger pr_debug("Moving to TARG_CONN_STATE_IN_LOGOUT.\n"); 2171e48354ceSNicholas Bellinger conn->conn_state = TARG_CONN_STATE_IN_LOGOUT; 2172e48354ceSNicholas Bellinger 2173e48354ceSNicholas Bellinger atomic_set(&conn->conn_logout_remove, 1); 2174e48354ceSNicholas Bellinger conn->conn_logout_reason = ISCSI_LOGOUT_REASON_CLOSE_CONNECTION; 2175e48354ceSNicholas Bellinger iscsit_inc_conn_usage_count(conn); 2176e48354ceSNicholas Bellinger 2177e48354ceSNicholas Bellinger spin_unlock_bh(&conn->state_lock); 2178e48354ceSNicholas Bellinger } else { 2179e48354ceSNicholas Bellinger /* 2180e48354ceSNicholas Bellinger * Handle all different cid CLOSECONNECTION requests in 2181e48354ceSNicholas Bellinger * iscsit_logout_post_handler_diffcid() as to give enough 2182e48354ceSNicholas Bellinger * time for any non immediate command's CmdSN to be 2183e48354ceSNicholas Bellinger * acknowledged on the connection in question. 2184e48354ceSNicholas Bellinger * 2185e48354ceSNicholas Bellinger * Here we simply make sure the CID is still around. 2186e48354ceSNicholas Bellinger */ 2187e48354ceSNicholas Bellinger l_conn = iscsit_get_conn_from_cid(sess, 2188e48354ceSNicholas Bellinger cmd->logout_cid); 2189e48354ceSNicholas Bellinger if (!l_conn) { 2190e48354ceSNicholas Bellinger cmd->logout_response = ISCSI_LOGOUT_CID_NOT_FOUND; 2191e48354ceSNicholas Bellinger iscsit_add_cmd_to_response_queue(cmd, conn, 2192e48354ceSNicholas Bellinger cmd->i_state); 2193e48354ceSNicholas Bellinger return 0; 2194e48354ceSNicholas Bellinger } 2195e48354ceSNicholas Bellinger 2196e48354ceSNicholas Bellinger iscsit_dec_conn_usage_count(l_conn); 2197e48354ceSNicholas Bellinger } 2198e48354ceSNicholas Bellinger 2199e48354ceSNicholas Bellinger iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); 2200e48354ceSNicholas Bellinger 2201e48354ceSNicholas Bellinger return 0; 2202e48354ceSNicholas Bellinger } 2203e48354ceSNicholas Bellinger 2204e48354ceSNicholas Bellinger int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *cmd, struct iscsi_conn *conn) 2205e48354ceSNicholas Bellinger { 2206e48354ceSNicholas Bellinger struct iscsi_session *sess = conn->sess; 2207e48354ceSNicholas Bellinger 2208e48354ceSNicholas Bellinger pr_debug("Received explicit REMOVECONNFORRECOVERY logout for" 2209e48354ceSNicholas Bellinger " CID: %hu on CID: %hu.\n", cmd->logout_cid, conn->cid); 2210e48354ceSNicholas Bellinger 2211e48354ceSNicholas Bellinger if (sess->sess_ops->ErrorRecoveryLevel != 2) { 2212e48354ceSNicholas Bellinger pr_err("Received Logout Request REMOVECONNFORRECOVERY" 2213e48354ceSNicholas Bellinger " while ERL!=2.\n"); 2214e48354ceSNicholas Bellinger cmd->logout_response = ISCSI_LOGOUT_RECOVERY_UNSUPPORTED; 2215e48354ceSNicholas Bellinger iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); 2216e48354ceSNicholas Bellinger return 0; 2217e48354ceSNicholas Bellinger } 2218e48354ceSNicholas Bellinger 2219e48354ceSNicholas Bellinger if (conn->cid == cmd->logout_cid) { 2220e48354ceSNicholas Bellinger pr_err("Received Logout Request REMOVECONNFORRECOVERY" 2221e48354ceSNicholas Bellinger " with CID: %hu on CID: %hu, implementation error.\n", 2222e48354ceSNicholas Bellinger cmd->logout_cid, conn->cid); 2223e48354ceSNicholas Bellinger cmd->logout_response = ISCSI_LOGOUT_CLEANUP_FAILED; 2224e48354ceSNicholas Bellinger iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); 2225e48354ceSNicholas Bellinger return 0; 2226e48354ceSNicholas Bellinger } 2227e48354ceSNicholas Bellinger 2228e48354ceSNicholas Bellinger iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); 2229e48354ceSNicholas Bellinger 2230e48354ceSNicholas Bellinger return 0; 2231e48354ceSNicholas Bellinger } 2232e48354ceSNicholas Bellinger 22333e1c81a9SNicholas Bellinger int 22343e1c81a9SNicholas Bellinger iscsit_handle_logout_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, 2235e48354ceSNicholas Bellinger unsigned char *buf) 2236e48354ceSNicholas Bellinger { 2237e48354ceSNicholas Bellinger int cmdsn_ret, logout_remove = 0; 2238e48354ceSNicholas Bellinger u8 reason_code = 0; 2239e48354ceSNicholas Bellinger struct iscsi_logout *hdr; 2240e48354ceSNicholas Bellinger struct iscsi_tiqn *tiqn = iscsit_snmp_get_tiqn(conn); 2241e48354ceSNicholas Bellinger 2242e48354ceSNicholas Bellinger hdr = (struct iscsi_logout *) buf; 2243e48354ceSNicholas Bellinger reason_code = (hdr->flags & 0x7f); 2244e48354ceSNicholas Bellinger 2245e48354ceSNicholas Bellinger if (tiqn) { 2246e48354ceSNicholas Bellinger spin_lock(&tiqn->logout_stats.lock); 2247e48354ceSNicholas Bellinger if (reason_code == ISCSI_LOGOUT_REASON_CLOSE_SESSION) 2248e48354ceSNicholas Bellinger tiqn->logout_stats.normal_logouts++; 2249e48354ceSNicholas Bellinger else 2250e48354ceSNicholas Bellinger tiqn->logout_stats.abnormal_logouts++; 2251e48354ceSNicholas Bellinger spin_unlock(&tiqn->logout_stats.lock); 2252e48354ceSNicholas Bellinger } 2253e48354ceSNicholas Bellinger 2254e48354ceSNicholas Bellinger pr_debug("Got Logout Request ITT: 0x%08x CmdSN: 0x%08x" 2255e48354ceSNicholas Bellinger " ExpStatSN: 0x%08x Reason: 0x%02x CID: %hu on CID: %hu\n", 2256e48354ceSNicholas Bellinger hdr->itt, hdr->cmdsn, hdr->exp_statsn, reason_code, 2257e48354ceSNicholas Bellinger hdr->cid, conn->cid); 2258e48354ceSNicholas Bellinger 2259e48354ceSNicholas Bellinger if (conn->conn_state != TARG_CONN_STATE_LOGGED_IN) { 2260e48354ceSNicholas Bellinger pr_err("Received logout request on connection that" 2261e48354ceSNicholas Bellinger " is not in logged in state, ignoring request.\n"); 2262aafc9d15SNicholas Bellinger iscsit_free_cmd(cmd, false); 2263e48354ceSNicholas Bellinger return 0; 2264e48354ceSNicholas Bellinger } 2265e48354ceSNicholas Bellinger 2266e48354ceSNicholas Bellinger cmd->iscsi_opcode = ISCSI_OP_LOGOUT; 2267e48354ceSNicholas Bellinger cmd->i_state = ISTATE_SEND_LOGOUTRSP; 2268e48354ceSNicholas Bellinger cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0); 2269e48354ceSNicholas Bellinger conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt; 2270e48354ceSNicholas Bellinger cmd->targ_xfer_tag = 0xFFFFFFFF; 227150e5c87dSChristoph Hellwig cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); 227250e5c87dSChristoph Hellwig cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); 227350e5c87dSChristoph Hellwig cmd->logout_cid = be16_to_cpu(hdr->cid); 2274e48354ceSNicholas Bellinger cmd->logout_reason = reason_code; 2275e48354ceSNicholas Bellinger cmd->data_direction = DMA_NONE; 2276e48354ceSNicholas Bellinger 2277e48354ceSNicholas Bellinger /* 2278e48354ceSNicholas Bellinger * We need to sleep in these cases (by returning 1) until the Logout 2279e48354ceSNicholas Bellinger * Response gets sent in the tx thread. 2280e48354ceSNicholas Bellinger */ 2281e48354ceSNicholas Bellinger if ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_SESSION) || 2282e48354ceSNicholas Bellinger ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_CONNECTION) && 228350e5c87dSChristoph Hellwig be16_to_cpu(hdr->cid) == conn->cid)) 2284e48354ceSNicholas Bellinger logout_remove = 1; 2285e48354ceSNicholas Bellinger 2286e48354ceSNicholas Bellinger spin_lock_bh(&conn->cmd_lock); 22872fbb471eSAndy Grover list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list); 2288e48354ceSNicholas Bellinger spin_unlock_bh(&conn->cmd_lock); 2289e48354ceSNicholas Bellinger 2290e48354ceSNicholas Bellinger if (reason_code != ISCSI_LOGOUT_REASON_RECOVERY) 229150e5c87dSChristoph Hellwig iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn)); 2292e48354ceSNicholas Bellinger 2293e48354ceSNicholas Bellinger /* 2294e48354ceSNicholas Bellinger * Immediate commands are executed, well, immediately. 2295e48354ceSNicholas Bellinger * Non-Immediate Logout Commands are executed in CmdSN order. 2296e48354ceSNicholas Bellinger */ 2297c6037cc5SAndy Grover if (cmd->immediate_cmd) { 2298e48354ceSNicholas Bellinger int ret = iscsit_execute_cmd(cmd, 0); 2299e48354ceSNicholas Bellinger 2300e48354ceSNicholas Bellinger if (ret < 0) 2301e48354ceSNicholas Bellinger return ret; 2302e48354ceSNicholas Bellinger } else { 2303561bf158SNicholas Bellinger cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn); 2304ba159914SNicholas Bellinger if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) 2305e48354ceSNicholas Bellinger logout_remove = 0; 2306ba159914SNicholas Bellinger else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) 2307ba159914SNicholas Bellinger return -1; 2308e48354ceSNicholas Bellinger } 2309e48354ceSNicholas Bellinger 2310e48354ceSNicholas Bellinger return logout_remove; 2311e48354ceSNicholas Bellinger } 23123e1c81a9SNicholas Bellinger EXPORT_SYMBOL(iscsit_handle_logout_cmd); 2313e48354ceSNicholas Bellinger 2314e48354ceSNicholas Bellinger static int iscsit_handle_snack( 2315e48354ceSNicholas Bellinger struct iscsi_conn *conn, 2316e48354ceSNicholas Bellinger unsigned char *buf) 2317e48354ceSNicholas Bellinger { 2318e48354ceSNicholas Bellinger struct iscsi_snack *hdr; 2319e48354ceSNicholas Bellinger 2320e48354ceSNicholas Bellinger hdr = (struct iscsi_snack *) buf; 2321e48354ceSNicholas Bellinger hdr->flags &= ~ISCSI_FLAG_CMD_FINAL; 2322e48354ceSNicholas Bellinger 2323e48354ceSNicholas Bellinger pr_debug("Got ISCSI_INIT_SNACK, ITT: 0x%08x, ExpStatSN:" 2324e48354ceSNicholas Bellinger " 0x%08x, Type: 0x%02x, BegRun: 0x%08x, RunLength: 0x%08x," 2325e48354ceSNicholas Bellinger " CID: %hu\n", hdr->itt, hdr->exp_statsn, hdr->flags, 2326e48354ceSNicholas Bellinger hdr->begrun, hdr->runlength, conn->cid); 2327e48354ceSNicholas Bellinger 2328e48354ceSNicholas Bellinger if (!conn->sess->sess_ops->ErrorRecoveryLevel) { 2329e48354ceSNicholas Bellinger pr_err("Initiator sent SNACK request while in" 2330e48354ceSNicholas Bellinger " ErrorRecoveryLevel=0.\n"); 2331ba159914SNicholas Bellinger return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, 2332ba159914SNicholas Bellinger buf); 2333e48354ceSNicholas Bellinger } 2334e48354ceSNicholas Bellinger /* 2335e48354ceSNicholas Bellinger * SNACK_DATA and SNACK_R2T are both 0, so check which function to 2336e48354ceSNicholas Bellinger * call from inside iscsi_send_recovery_datain_or_r2t(). 2337e48354ceSNicholas Bellinger */ 2338e48354ceSNicholas Bellinger switch (hdr->flags & ISCSI_FLAG_SNACK_TYPE_MASK) { 2339e48354ceSNicholas Bellinger case 0: 2340e48354ceSNicholas Bellinger return iscsit_handle_recovery_datain_or_r2t(conn, buf, 234150e5c87dSChristoph Hellwig hdr->itt, 234250e5c87dSChristoph Hellwig be32_to_cpu(hdr->ttt), 234350e5c87dSChristoph Hellwig be32_to_cpu(hdr->begrun), 234450e5c87dSChristoph Hellwig be32_to_cpu(hdr->runlength)); 2345e48354ceSNicholas Bellinger case ISCSI_FLAG_SNACK_TYPE_STATUS: 234650e5c87dSChristoph Hellwig return iscsit_handle_status_snack(conn, hdr->itt, 234750e5c87dSChristoph Hellwig be32_to_cpu(hdr->ttt), 234850e5c87dSChristoph Hellwig be32_to_cpu(hdr->begrun), be32_to_cpu(hdr->runlength)); 2349e48354ceSNicholas Bellinger case ISCSI_FLAG_SNACK_TYPE_DATA_ACK: 235050e5c87dSChristoph Hellwig return iscsit_handle_data_ack(conn, be32_to_cpu(hdr->ttt), 235150e5c87dSChristoph Hellwig be32_to_cpu(hdr->begrun), 235250e5c87dSChristoph Hellwig be32_to_cpu(hdr->runlength)); 2353e48354ceSNicholas Bellinger case ISCSI_FLAG_SNACK_TYPE_RDATA: 2354e48354ceSNicholas Bellinger /* FIXME: Support R-Data SNACK */ 2355e48354ceSNicholas Bellinger pr_err("R-Data SNACK Not Supported.\n"); 2356ba159914SNicholas Bellinger return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, 2357ba159914SNicholas Bellinger buf); 2358e48354ceSNicholas Bellinger default: 2359e48354ceSNicholas Bellinger pr_err("Unknown SNACK type 0x%02x, protocol" 2360e48354ceSNicholas Bellinger " error.\n", hdr->flags & 0x0f); 2361ba159914SNicholas Bellinger return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, 2362ba159914SNicholas Bellinger buf); 2363e48354ceSNicholas Bellinger } 2364e48354ceSNicholas Bellinger 2365e48354ceSNicholas Bellinger return 0; 2366e48354ceSNicholas Bellinger } 2367e48354ceSNicholas Bellinger 2368e48354ceSNicholas Bellinger static void iscsit_rx_thread_wait_for_tcp(struct iscsi_conn *conn) 2369e48354ceSNicholas Bellinger { 2370e48354ceSNicholas Bellinger if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) || 2371e48354ceSNicholas Bellinger (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) { 2372e48354ceSNicholas Bellinger wait_for_completion_interruptible_timeout( 2373e48354ceSNicholas Bellinger &conn->rx_half_close_comp, 2374e48354ceSNicholas Bellinger ISCSI_RX_THREAD_TCP_TIMEOUT * HZ); 2375e48354ceSNicholas Bellinger } 2376e48354ceSNicholas Bellinger } 2377e48354ceSNicholas Bellinger 2378e48354ceSNicholas Bellinger static int iscsit_handle_immediate_data( 2379e48354ceSNicholas Bellinger struct iscsi_cmd *cmd, 23803e1c81a9SNicholas Bellinger struct iscsi_scsi_req *hdr, 2381e48354ceSNicholas Bellinger u32 length) 2382e48354ceSNicholas Bellinger { 2383e48354ceSNicholas Bellinger int iov_ret, rx_got = 0, rx_size = 0; 2384e48354ceSNicholas Bellinger u32 checksum, iov_count = 0, padding = 0; 2385e48354ceSNicholas Bellinger struct iscsi_conn *conn = cmd->conn; 2386e48354ceSNicholas Bellinger struct kvec *iov; 2387e48354ceSNicholas Bellinger 2388e48354ceSNicholas Bellinger iov_ret = iscsit_map_iovec(cmd, cmd->iov_data, cmd->write_data_done, length); 2389e48354ceSNicholas Bellinger if (iov_ret < 0) 2390e48354ceSNicholas Bellinger return IMMEDIATE_DATA_CANNOT_RECOVER; 2391e48354ceSNicholas Bellinger 2392e48354ceSNicholas Bellinger rx_size = length; 2393e48354ceSNicholas Bellinger iov_count = iov_ret; 2394e48354ceSNicholas Bellinger iov = &cmd->iov_data[0]; 2395e48354ceSNicholas Bellinger 2396e48354ceSNicholas Bellinger padding = ((-length) & 3); 2397e48354ceSNicholas Bellinger if (padding != 0) { 2398e48354ceSNicholas Bellinger iov[iov_count].iov_base = cmd->pad_bytes; 2399e48354ceSNicholas Bellinger iov[iov_count++].iov_len = padding; 2400e48354ceSNicholas Bellinger rx_size += padding; 2401e48354ceSNicholas Bellinger } 2402e48354ceSNicholas Bellinger 2403e48354ceSNicholas Bellinger if (conn->conn_ops->DataDigest) { 2404e48354ceSNicholas Bellinger iov[iov_count].iov_base = &checksum; 2405e48354ceSNicholas Bellinger iov[iov_count++].iov_len = ISCSI_CRC_LEN; 2406e48354ceSNicholas Bellinger rx_size += ISCSI_CRC_LEN; 2407e48354ceSNicholas Bellinger } 2408e48354ceSNicholas Bellinger 2409e48354ceSNicholas Bellinger rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size); 2410e48354ceSNicholas Bellinger 2411e48354ceSNicholas Bellinger iscsit_unmap_iovec(cmd); 2412e48354ceSNicholas Bellinger 2413e48354ceSNicholas Bellinger if (rx_got != rx_size) { 2414e48354ceSNicholas Bellinger iscsit_rx_thread_wait_for_tcp(conn); 2415e48354ceSNicholas Bellinger return IMMEDIATE_DATA_CANNOT_RECOVER; 2416e48354ceSNicholas Bellinger } 2417e48354ceSNicholas Bellinger 2418e48354ceSNicholas Bellinger if (conn->conn_ops->DataDigest) { 2419e48354ceSNicholas Bellinger u32 data_crc; 2420e48354ceSNicholas Bellinger 2421e48354ceSNicholas Bellinger data_crc = iscsit_do_crypto_hash_sg(&conn->conn_rx_hash, cmd, 2422e48354ceSNicholas Bellinger cmd->write_data_done, length, padding, 2423e48354ceSNicholas Bellinger cmd->pad_bytes); 2424e48354ceSNicholas Bellinger 2425e48354ceSNicholas Bellinger if (checksum != data_crc) { 2426e48354ceSNicholas Bellinger pr_err("ImmediateData CRC32C DataDigest 0x%08x" 2427e48354ceSNicholas Bellinger " does not match computed 0x%08x\n", checksum, 2428e48354ceSNicholas Bellinger data_crc); 2429e48354ceSNicholas Bellinger 2430e48354ceSNicholas Bellinger if (!conn->sess->sess_ops->ErrorRecoveryLevel) { 2431e48354ceSNicholas Bellinger pr_err("Unable to recover from" 2432e48354ceSNicholas Bellinger " Immediate Data digest failure while" 2433e48354ceSNicholas Bellinger " in ERL=0.\n"); 2434ba159914SNicholas Bellinger iscsit_reject_cmd(cmd, 2435e48354ceSNicholas Bellinger ISCSI_REASON_DATA_DIGEST_ERROR, 2436ba159914SNicholas Bellinger (unsigned char *)hdr); 2437e48354ceSNicholas Bellinger return IMMEDIATE_DATA_CANNOT_RECOVER; 2438e48354ceSNicholas Bellinger } else { 2439ba159914SNicholas Bellinger iscsit_reject_cmd(cmd, 2440e48354ceSNicholas Bellinger ISCSI_REASON_DATA_DIGEST_ERROR, 2441ba159914SNicholas Bellinger (unsigned char *)hdr); 2442e48354ceSNicholas Bellinger return IMMEDIATE_DATA_ERL1_CRC_FAILURE; 2443e48354ceSNicholas Bellinger } 2444e48354ceSNicholas Bellinger } else { 2445e48354ceSNicholas Bellinger pr_debug("Got CRC32C DataDigest 0x%08x for" 2446e48354ceSNicholas Bellinger " %u bytes of Immediate Data\n", checksum, 2447e48354ceSNicholas Bellinger length); 2448e48354ceSNicholas Bellinger } 2449e48354ceSNicholas Bellinger } 2450e48354ceSNicholas Bellinger 2451e48354ceSNicholas Bellinger cmd->write_data_done += length; 2452e48354ceSNicholas Bellinger 2453ebf1d95cSAndy Grover if (cmd->write_data_done == cmd->se_cmd.data_length) { 2454e48354ceSNicholas Bellinger spin_lock_bh(&cmd->istate_lock); 2455e48354ceSNicholas Bellinger cmd->cmd_flags |= ICF_GOT_LAST_DATAOUT; 2456e48354ceSNicholas Bellinger cmd->i_state = ISTATE_RECEIVED_LAST_DATAOUT; 2457e48354ceSNicholas Bellinger spin_unlock_bh(&cmd->istate_lock); 2458e48354ceSNicholas Bellinger } 2459e48354ceSNicholas Bellinger 2460e48354ceSNicholas Bellinger return IMMEDIATE_DATA_NORMAL_OPERATION; 2461e48354ceSNicholas Bellinger } 2462e48354ceSNicholas Bellinger 2463e48354ceSNicholas Bellinger /* 2464e48354ceSNicholas Bellinger * Called with sess->conn_lock held. 2465e48354ceSNicholas Bellinger */ 2466e48354ceSNicholas Bellinger /* #warning iscsi_build_conn_drop_async_message() only sends out on connections 2467e48354ceSNicholas Bellinger with active network interface */ 2468e48354ceSNicholas Bellinger static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn) 2469e48354ceSNicholas Bellinger { 2470e48354ceSNicholas Bellinger struct iscsi_cmd *cmd; 2471e48354ceSNicholas Bellinger struct iscsi_conn *conn_p; 2472e48354ceSNicholas Bellinger 2473e48354ceSNicholas Bellinger /* 2474e48354ceSNicholas Bellinger * Only send a Asynchronous Message on connections whos network 2475e48354ceSNicholas Bellinger * interface is still functional. 2476e48354ceSNicholas Bellinger */ 2477e48354ceSNicholas Bellinger list_for_each_entry(conn_p, &conn->sess->sess_conn_list, conn_list) { 2478e48354ceSNicholas Bellinger if (conn_p->conn_state == TARG_CONN_STATE_LOGGED_IN) { 2479e48354ceSNicholas Bellinger iscsit_inc_conn_usage_count(conn_p); 2480e48354ceSNicholas Bellinger break; 2481e48354ceSNicholas Bellinger } 2482e48354ceSNicholas Bellinger } 2483e48354ceSNicholas Bellinger 2484e48354ceSNicholas Bellinger if (!conn_p) 2485e48354ceSNicholas Bellinger return; 2486e48354ceSNicholas Bellinger 24873c989d76SWei Yongjun cmd = iscsit_allocate_cmd(conn_p, GFP_ATOMIC); 2488e48354ceSNicholas Bellinger if (!cmd) { 2489e48354ceSNicholas Bellinger iscsit_dec_conn_usage_count(conn_p); 2490e48354ceSNicholas Bellinger return; 2491e48354ceSNicholas Bellinger } 2492e48354ceSNicholas Bellinger 2493e48354ceSNicholas Bellinger cmd->logout_cid = conn->cid; 2494e48354ceSNicholas Bellinger cmd->iscsi_opcode = ISCSI_OP_ASYNC_EVENT; 2495e48354ceSNicholas Bellinger cmd->i_state = ISTATE_SEND_ASYNCMSG; 2496e48354ceSNicholas Bellinger 2497e48354ceSNicholas Bellinger spin_lock_bh(&conn_p->cmd_lock); 24982fbb471eSAndy Grover list_add_tail(&cmd->i_conn_node, &conn_p->conn_cmd_list); 2499e48354ceSNicholas Bellinger spin_unlock_bh(&conn_p->cmd_lock); 2500e48354ceSNicholas Bellinger 2501e48354ceSNicholas Bellinger iscsit_add_cmd_to_response_queue(cmd, conn_p, cmd->i_state); 2502e48354ceSNicholas Bellinger iscsit_dec_conn_usage_count(conn_p); 2503e48354ceSNicholas Bellinger } 2504e48354ceSNicholas Bellinger 2505e48354ceSNicholas Bellinger static int iscsit_send_conn_drop_async_message( 2506e48354ceSNicholas Bellinger struct iscsi_cmd *cmd, 2507e48354ceSNicholas Bellinger struct iscsi_conn *conn) 2508e48354ceSNicholas Bellinger { 2509e48354ceSNicholas Bellinger struct iscsi_async *hdr; 2510e48354ceSNicholas Bellinger 2511e48354ceSNicholas Bellinger cmd->tx_size = ISCSI_HDR_LEN; 2512e48354ceSNicholas Bellinger cmd->iscsi_opcode = ISCSI_OP_ASYNC_EVENT; 2513e48354ceSNicholas Bellinger 2514e48354ceSNicholas Bellinger hdr = (struct iscsi_async *) cmd->pdu; 2515e48354ceSNicholas Bellinger hdr->opcode = ISCSI_OP_ASYNC_EVENT; 2516e48354ceSNicholas Bellinger hdr->flags = ISCSI_FLAG_CMD_FINAL; 251766c7db68SChristoph Hellwig cmd->init_task_tag = RESERVED_ITT; 2518e48354ceSNicholas Bellinger cmd->targ_xfer_tag = 0xFFFFFFFF; 2519e48354ceSNicholas Bellinger put_unaligned_be64(0xFFFFFFFFFFFFFFFFULL, &hdr->rsvd4[0]); 2520e48354ceSNicholas Bellinger cmd->stat_sn = conn->stat_sn++; 2521e48354ceSNicholas Bellinger hdr->statsn = cpu_to_be32(cmd->stat_sn); 2522e48354ceSNicholas Bellinger hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); 2523e48354ceSNicholas Bellinger hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); 2524e48354ceSNicholas Bellinger hdr->async_event = ISCSI_ASYNC_MSG_DROPPING_CONNECTION; 2525e48354ceSNicholas Bellinger hdr->param1 = cpu_to_be16(cmd->logout_cid); 2526e48354ceSNicholas Bellinger hdr->param2 = cpu_to_be16(conn->sess->sess_ops->DefaultTime2Wait); 2527e48354ceSNicholas Bellinger hdr->param3 = cpu_to_be16(conn->sess->sess_ops->DefaultTime2Retain); 2528e48354ceSNicholas Bellinger 2529e48354ceSNicholas Bellinger if (conn->conn_ops->HeaderDigest) { 2530e48354ceSNicholas Bellinger u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 2531e48354ceSNicholas Bellinger 253280690fdbSGeert Uytterhoeven iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr, 253380690fdbSGeert Uytterhoeven ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); 2534e48354ceSNicholas Bellinger 2535e48354ceSNicholas Bellinger cmd->tx_size += ISCSI_CRC_LEN; 2536e48354ceSNicholas Bellinger pr_debug("Attaching CRC32C HeaderDigest to" 2537e48354ceSNicholas Bellinger " Async Message 0x%08x\n", *header_digest); 2538e48354ceSNicholas Bellinger } 2539e48354ceSNicholas Bellinger 2540e48354ceSNicholas Bellinger cmd->iov_misc[0].iov_base = cmd->pdu; 2541e48354ceSNicholas Bellinger cmd->iov_misc[0].iov_len = cmd->tx_size; 2542e48354ceSNicholas Bellinger cmd->iov_misc_count = 1; 2543e48354ceSNicholas Bellinger 2544e48354ceSNicholas Bellinger pr_debug("Sending Connection Dropped Async Message StatSN:" 2545e48354ceSNicholas Bellinger " 0x%08x, for CID: %hu on CID: %hu\n", cmd->stat_sn, 2546e48354ceSNicholas Bellinger cmd->logout_cid, conn->cid); 2547e48354ceSNicholas Bellinger return 0; 2548e48354ceSNicholas Bellinger } 2549e48354ceSNicholas Bellinger 25506f3c0e69SAndy Grover static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn) 25516f3c0e69SAndy Grover { 25526f3c0e69SAndy Grover if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) || 25536f3c0e69SAndy Grover (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) { 25546f3c0e69SAndy Grover wait_for_completion_interruptible_timeout( 25556f3c0e69SAndy Grover &conn->tx_half_close_comp, 25566f3c0e69SAndy Grover ISCSI_TX_THREAD_TCP_TIMEOUT * HZ); 25576f3c0e69SAndy Grover } 25586f3c0e69SAndy Grover } 25596f3c0e69SAndy Grover 25602ec5a8c1SNicholas Bellinger static void 25612ec5a8c1SNicholas Bellinger iscsit_build_datain_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn, 25622ec5a8c1SNicholas Bellinger struct iscsi_datain *datain, struct iscsi_data_rsp *hdr, 25632ec5a8c1SNicholas Bellinger bool set_statsn) 2564e48354ceSNicholas Bellinger { 25652ec5a8c1SNicholas Bellinger hdr->opcode = ISCSI_OP_SCSI_DATA_IN; 25662ec5a8c1SNicholas Bellinger hdr->flags = datain->flags; 25672ec5a8c1SNicholas Bellinger if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { 25682ec5a8c1SNicholas Bellinger if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { 25692ec5a8c1SNicholas Bellinger hdr->flags |= ISCSI_FLAG_DATA_OVERFLOW; 25702ec5a8c1SNicholas Bellinger hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); 25712ec5a8c1SNicholas Bellinger } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { 25722ec5a8c1SNicholas Bellinger hdr->flags |= ISCSI_FLAG_DATA_UNDERFLOW; 25732ec5a8c1SNicholas Bellinger hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); 25742ec5a8c1SNicholas Bellinger } 25752ec5a8c1SNicholas Bellinger } 25762ec5a8c1SNicholas Bellinger hton24(hdr->dlength, datain->length); 25772ec5a8c1SNicholas Bellinger if (hdr->flags & ISCSI_FLAG_DATA_ACK) 25782ec5a8c1SNicholas Bellinger int_to_scsilun(cmd->se_cmd.orig_fe_lun, 25792ec5a8c1SNicholas Bellinger (struct scsi_lun *)&hdr->lun); 25802ec5a8c1SNicholas Bellinger else 25812ec5a8c1SNicholas Bellinger put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun); 25822ec5a8c1SNicholas Bellinger 25832ec5a8c1SNicholas Bellinger hdr->itt = cmd->init_task_tag; 25842ec5a8c1SNicholas Bellinger 25852ec5a8c1SNicholas Bellinger if (hdr->flags & ISCSI_FLAG_DATA_ACK) 25862ec5a8c1SNicholas Bellinger hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag); 25872ec5a8c1SNicholas Bellinger else 25882ec5a8c1SNicholas Bellinger hdr->ttt = cpu_to_be32(0xFFFFFFFF); 25892ec5a8c1SNicholas Bellinger if (set_statsn) 25902ec5a8c1SNicholas Bellinger hdr->statsn = cpu_to_be32(cmd->stat_sn); 25912ec5a8c1SNicholas Bellinger else 25922ec5a8c1SNicholas Bellinger hdr->statsn = cpu_to_be32(0xFFFFFFFF); 25932ec5a8c1SNicholas Bellinger 25942ec5a8c1SNicholas Bellinger hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); 25952ec5a8c1SNicholas Bellinger hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); 25962ec5a8c1SNicholas Bellinger hdr->datasn = cpu_to_be32(datain->data_sn); 25972ec5a8c1SNicholas Bellinger hdr->offset = cpu_to_be32(datain->offset); 25982ec5a8c1SNicholas Bellinger 25992ec5a8c1SNicholas Bellinger pr_debug("Built DataIN ITT: 0x%08x, StatSN: 0x%08x," 26002ec5a8c1SNicholas Bellinger " DataSN: 0x%08x, Offset: %u, Length: %u, CID: %hu\n", 26012ec5a8c1SNicholas Bellinger cmd->init_task_tag, ntohl(hdr->statsn), ntohl(hdr->datasn), 26022ec5a8c1SNicholas Bellinger ntohl(hdr->offset), datain->length, conn->cid); 26032ec5a8c1SNicholas Bellinger } 26042ec5a8c1SNicholas Bellinger 26052ec5a8c1SNicholas Bellinger static int iscsit_send_datain(struct iscsi_cmd *cmd, struct iscsi_conn *conn) 26062ec5a8c1SNicholas Bellinger { 26072ec5a8c1SNicholas Bellinger struct iscsi_data_rsp *hdr = (struct iscsi_data_rsp *)&cmd->pdu[0]; 2608e48354ceSNicholas Bellinger struct iscsi_datain datain; 2609e48354ceSNicholas Bellinger struct iscsi_datain_req *dr; 2610e48354ceSNicholas Bellinger struct kvec *iov; 26112ec5a8c1SNicholas Bellinger u32 iov_count = 0, tx_size = 0; 26122ec5a8c1SNicholas Bellinger int eodr = 0, ret, iov_ret; 26132ec5a8c1SNicholas Bellinger bool set_statsn = false; 2614e48354ceSNicholas Bellinger 2615e48354ceSNicholas Bellinger memset(&datain, 0, sizeof(struct iscsi_datain)); 2616e48354ceSNicholas Bellinger dr = iscsit_get_datain_values(cmd, &datain); 2617e48354ceSNicholas Bellinger if (!dr) { 2618e48354ceSNicholas Bellinger pr_err("iscsit_get_datain_values failed for ITT: 0x%08x\n", 2619e48354ceSNicholas Bellinger cmd->init_task_tag); 2620e48354ceSNicholas Bellinger return -1; 2621e48354ceSNicholas Bellinger } 2622e48354ceSNicholas Bellinger /* 2623e48354ceSNicholas Bellinger * Be paranoid and double check the logic for now. 2624e48354ceSNicholas Bellinger */ 2625ebf1d95cSAndy Grover if ((datain.offset + datain.length) > cmd->se_cmd.data_length) { 2626e48354ceSNicholas Bellinger pr_err("Command ITT: 0x%08x, datain.offset: %u and" 2627e48354ceSNicholas Bellinger " datain.length: %u exceeds cmd->data_length: %u\n", 2628e48354ceSNicholas Bellinger cmd->init_task_tag, datain.offset, datain.length, 2629ebf1d95cSAndy Grover cmd->se_cmd.data_length); 2630e48354ceSNicholas Bellinger return -1; 2631e48354ceSNicholas Bellinger } 2632e48354ceSNicholas Bellinger 2633e48354ceSNicholas Bellinger spin_lock_bh(&conn->sess->session_stats_lock); 2634e48354ceSNicholas Bellinger conn->sess->tx_data_octets += datain.length; 2635e48354ceSNicholas Bellinger if (conn->sess->se_sess->se_node_acl) { 2636e48354ceSNicholas Bellinger spin_lock(&conn->sess->se_sess->se_node_acl->stats_lock); 2637e48354ceSNicholas Bellinger conn->sess->se_sess->se_node_acl->read_bytes += datain.length; 2638e48354ceSNicholas Bellinger spin_unlock(&conn->sess->se_sess->se_node_acl->stats_lock); 2639e48354ceSNicholas Bellinger } 2640e48354ceSNicholas Bellinger spin_unlock_bh(&conn->sess->session_stats_lock); 2641e48354ceSNicholas Bellinger /* 2642e48354ceSNicholas Bellinger * Special case for successfully execution w/ both DATAIN 2643e48354ceSNicholas Bellinger * and Sense Data. 2644e48354ceSNicholas Bellinger */ 2645e48354ceSNicholas Bellinger if ((datain.flags & ISCSI_FLAG_DATA_STATUS) && 2646e48354ceSNicholas Bellinger (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)) 2647e48354ceSNicholas Bellinger datain.flags &= ~ISCSI_FLAG_DATA_STATUS; 2648e48354ceSNicholas Bellinger else { 2649e48354ceSNicholas Bellinger if ((dr->dr_complete == DATAIN_COMPLETE_NORMAL) || 2650e48354ceSNicholas Bellinger (dr->dr_complete == DATAIN_COMPLETE_CONNECTION_RECOVERY)) { 2651e48354ceSNicholas Bellinger iscsit_increment_maxcmdsn(cmd, conn->sess); 2652e48354ceSNicholas Bellinger cmd->stat_sn = conn->stat_sn++; 26532ec5a8c1SNicholas Bellinger set_statsn = true; 2654e48354ceSNicholas Bellinger } else if (dr->dr_complete == 2655e48354ceSNicholas Bellinger DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY) 26562ec5a8c1SNicholas Bellinger set_statsn = true; 2657e48354ceSNicholas Bellinger } 2658e48354ceSNicholas Bellinger 26592ec5a8c1SNicholas Bellinger iscsit_build_datain_pdu(cmd, conn, &datain, hdr, set_statsn); 2660e48354ceSNicholas Bellinger 2661e48354ceSNicholas Bellinger iov = &cmd->iov_data[0]; 2662e48354ceSNicholas Bellinger iov[iov_count].iov_base = cmd->pdu; 2663e48354ceSNicholas Bellinger iov[iov_count++].iov_len = ISCSI_HDR_LEN; 2664e48354ceSNicholas Bellinger tx_size += ISCSI_HDR_LEN; 2665e48354ceSNicholas Bellinger 2666e48354ceSNicholas Bellinger if (conn->conn_ops->HeaderDigest) { 2667e48354ceSNicholas Bellinger u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 2668e48354ceSNicholas Bellinger 266980690fdbSGeert Uytterhoeven iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, cmd->pdu, 267080690fdbSGeert Uytterhoeven ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); 2671e48354ceSNicholas Bellinger 2672e48354ceSNicholas Bellinger iov[0].iov_len += ISCSI_CRC_LEN; 2673e48354ceSNicholas Bellinger tx_size += ISCSI_CRC_LEN; 2674e48354ceSNicholas Bellinger 2675e48354ceSNicholas Bellinger pr_debug("Attaching CRC32 HeaderDigest" 2676e48354ceSNicholas Bellinger " for DataIN PDU 0x%08x\n", *header_digest); 2677e48354ceSNicholas Bellinger } 2678e48354ceSNicholas Bellinger 26792ec5a8c1SNicholas Bellinger iov_ret = iscsit_map_iovec(cmd, &cmd->iov_data[1], 26802ec5a8c1SNicholas Bellinger datain.offset, datain.length); 2681e48354ceSNicholas Bellinger if (iov_ret < 0) 2682e48354ceSNicholas Bellinger return -1; 2683e48354ceSNicholas Bellinger 2684e48354ceSNicholas Bellinger iov_count += iov_ret; 2685e48354ceSNicholas Bellinger tx_size += datain.length; 2686e48354ceSNicholas Bellinger 2687e48354ceSNicholas Bellinger cmd->padding = ((-datain.length) & 3); 2688e48354ceSNicholas Bellinger if (cmd->padding) { 2689e48354ceSNicholas Bellinger iov[iov_count].iov_base = cmd->pad_bytes; 2690e48354ceSNicholas Bellinger iov[iov_count++].iov_len = cmd->padding; 2691e48354ceSNicholas Bellinger tx_size += cmd->padding; 2692e48354ceSNicholas Bellinger 2693e48354ceSNicholas Bellinger pr_debug("Attaching %u padding bytes\n", 2694e48354ceSNicholas Bellinger cmd->padding); 2695e48354ceSNicholas Bellinger } 2696e48354ceSNicholas Bellinger if (conn->conn_ops->DataDigest) { 2697e48354ceSNicholas Bellinger cmd->data_crc = iscsit_do_crypto_hash_sg(&conn->conn_tx_hash, cmd, 2698e48354ceSNicholas Bellinger datain.offset, datain.length, cmd->padding, cmd->pad_bytes); 2699e48354ceSNicholas Bellinger 2700e48354ceSNicholas Bellinger iov[iov_count].iov_base = &cmd->data_crc; 2701e48354ceSNicholas Bellinger iov[iov_count++].iov_len = ISCSI_CRC_LEN; 2702e48354ceSNicholas Bellinger tx_size += ISCSI_CRC_LEN; 2703e48354ceSNicholas Bellinger 2704e48354ceSNicholas Bellinger pr_debug("Attached CRC32C DataDigest %d bytes, crc" 2705e48354ceSNicholas Bellinger " 0x%08x\n", datain.length+cmd->padding, cmd->data_crc); 2706e48354ceSNicholas Bellinger } 2707e48354ceSNicholas Bellinger 2708e48354ceSNicholas Bellinger cmd->iov_data_count = iov_count; 2709e48354ceSNicholas Bellinger cmd->tx_size = tx_size; 2710e48354ceSNicholas Bellinger 27116f3c0e69SAndy Grover /* sendpage is preferred but can't insert markers */ 27126f3c0e69SAndy Grover if (!conn->conn_ops->IFMarker) 27136f3c0e69SAndy Grover ret = iscsit_fe_sendpage_sg(cmd, conn); 27146f3c0e69SAndy Grover else 27156f3c0e69SAndy Grover ret = iscsit_send_tx_data(cmd, conn, 0); 27166f3c0e69SAndy Grover 27176f3c0e69SAndy Grover iscsit_unmap_iovec(cmd); 27186f3c0e69SAndy Grover 27196f3c0e69SAndy Grover if (ret < 0) { 27206f3c0e69SAndy Grover iscsit_tx_thread_wait_for_tcp(conn); 27216f3c0e69SAndy Grover return ret; 27226f3c0e69SAndy Grover } 27236f3c0e69SAndy Grover 2724e48354ceSNicholas Bellinger if (dr->dr_complete) { 27256f3c0e69SAndy Grover eodr = (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ? 2726e48354ceSNicholas Bellinger 2 : 1; 2727e48354ceSNicholas Bellinger iscsit_free_datain_req(cmd, dr); 2728e48354ceSNicholas Bellinger } 2729e48354ceSNicholas Bellinger 27306f3c0e69SAndy Grover return eodr; 2731e48354ceSNicholas Bellinger } 2732e48354ceSNicholas Bellinger 27332ec5a8c1SNicholas Bellinger int 27342ec5a8c1SNicholas Bellinger iscsit_build_logout_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, 27352ec5a8c1SNicholas Bellinger struct iscsi_logout_rsp *hdr) 2736e48354ceSNicholas Bellinger { 2737e48354ceSNicholas Bellinger struct iscsi_conn *logout_conn = NULL; 2738e48354ceSNicholas Bellinger struct iscsi_conn_recovery *cr = NULL; 2739e48354ceSNicholas Bellinger struct iscsi_session *sess = conn->sess; 2740e48354ceSNicholas Bellinger /* 2741e48354ceSNicholas Bellinger * The actual shutting down of Sessions and/or Connections 2742e48354ceSNicholas Bellinger * for CLOSESESSION and CLOSECONNECTION Logout Requests 2743e48354ceSNicholas Bellinger * is done in scsi_logout_post_handler(). 2744e48354ceSNicholas Bellinger */ 2745e48354ceSNicholas Bellinger switch (cmd->logout_reason) { 2746e48354ceSNicholas Bellinger case ISCSI_LOGOUT_REASON_CLOSE_SESSION: 2747e48354ceSNicholas Bellinger pr_debug("iSCSI session logout successful, setting" 2748e48354ceSNicholas Bellinger " logout response to ISCSI_LOGOUT_SUCCESS.\n"); 2749e48354ceSNicholas Bellinger cmd->logout_response = ISCSI_LOGOUT_SUCCESS; 2750e48354ceSNicholas Bellinger break; 2751e48354ceSNicholas Bellinger case ISCSI_LOGOUT_REASON_CLOSE_CONNECTION: 2752e48354ceSNicholas Bellinger if (cmd->logout_response == ISCSI_LOGOUT_CID_NOT_FOUND) 2753e48354ceSNicholas Bellinger break; 2754e48354ceSNicholas Bellinger /* 2755e48354ceSNicholas Bellinger * For CLOSECONNECTION logout requests carrying 2756e48354ceSNicholas Bellinger * a matching logout CID -> local CID, the reference 2757e48354ceSNicholas Bellinger * for the local CID will have been incremented in 2758e48354ceSNicholas Bellinger * iscsi_logout_closeconnection(). 2759e48354ceSNicholas Bellinger * 2760e48354ceSNicholas Bellinger * For CLOSECONNECTION logout requests carrying 2761e48354ceSNicholas Bellinger * a different CID than the connection it arrived 2762e48354ceSNicholas Bellinger * on, the connection responding to cmd->logout_cid 2763e48354ceSNicholas Bellinger * is stopped in iscsit_logout_post_handler_diffcid(). 2764e48354ceSNicholas Bellinger */ 2765e48354ceSNicholas Bellinger 2766e48354ceSNicholas Bellinger pr_debug("iSCSI CID: %hu logout on CID: %hu" 2767e48354ceSNicholas Bellinger " successful.\n", cmd->logout_cid, conn->cid); 2768e48354ceSNicholas Bellinger cmd->logout_response = ISCSI_LOGOUT_SUCCESS; 2769e48354ceSNicholas Bellinger break; 2770e48354ceSNicholas Bellinger case ISCSI_LOGOUT_REASON_RECOVERY: 2771e48354ceSNicholas Bellinger if ((cmd->logout_response == ISCSI_LOGOUT_RECOVERY_UNSUPPORTED) || 2772e48354ceSNicholas Bellinger (cmd->logout_response == ISCSI_LOGOUT_CLEANUP_FAILED)) 2773e48354ceSNicholas Bellinger break; 2774e48354ceSNicholas Bellinger /* 2775e48354ceSNicholas Bellinger * If the connection is still active from our point of view 2776e48354ceSNicholas Bellinger * force connection recovery to occur. 2777e48354ceSNicholas Bellinger */ 2778e48354ceSNicholas Bellinger logout_conn = iscsit_get_conn_from_cid_rcfr(sess, 2779e48354ceSNicholas Bellinger cmd->logout_cid); 2780ee1b1b9cSAndy Grover if (logout_conn) { 2781e48354ceSNicholas Bellinger iscsit_connection_reinstatement_rcfr(logout_conn); 2782e48354ceSNicholas Bellinger iscsit_dec_conn_usage_count(logout_conn); 2783e48354ceSNicholas Bellinger } 2784e48354ceSNicholas Bellinger 2785e48354ceSNicholas Bellinger cr = iscsit_get_inactive_connection_recovery_entry( 2786e48354ceSNicholas Bellinger conn->sess, cmd->logout_cid); 2787e48354ceSNicholas Bellinger if (!cr) { 2788e48354ceSNicholas Bellinger pr_err("Unable to locate CID: %hu for" 2789e48354ceSNicholas Bellinger " REMOVECONNFORRECOVERY Logout Request.\n", 2790e48354ceSNicholas Bellinger cmd->logout_cid); 2791e48354ceSNicholas Bellinger cmd->logout_response = ISCSI_LOGOUT_CID_NOT_FOUND; 2792e48354ceSNicholas Bellinger break; 2793e48354ceSNicholas Bellinger } 2794e48354ceSNicholas Bellinger 2795e48354ceSNicholas Bellinger iscsit_discard_cr_cmds_by_expstatsn(cr, cmd->exp_stat_sn); 2796e48354ceSNicholas Bellinger 2797e48354ceSNicholas Bellinger pr_debug("iSCSI REMOVECONNFORRECOVERY logout" 2798e48354ceSNicholas Bellinger " for recovery for CID: %hu on CID: %hu successful.\n", 2799e48354ceSNicholas Bellinger cmd->logout_cid, conn->cid); 2800e48354ceSNicholas Bellinger cmd->logout_response = ISCSI_LOGOUT_SUCCESS; 2801e48354ceSNicholas Bellinger break; 2802e48354ceSNicholas Bellinger default: 2803e48354ceSNicholas Bellinger pr_err("Unknown cmd->logout_reason: 0x%02x\n", 2804e48354ceSNicholas Bellinger cmd->logout_reason); 2805e48354ceSNicholas Bellinger return -1; 2806e48354ceSNicholas Bellinger } 2807e48354ceSNicholas Bellinger 2808e48354ceSNicholas Bellinger hdr->opcode = ISCSI_OP_LOGOUT_RSP; 2809e48354ceSNicholas Bellinger hdr->flags |= ISCSI_FLAG_CMD_FINAL; 2810e48354ceSNicholas Bellinger hdr->response = cmd->logout_response; 281166c7db68SChristoph Hellwig hdr->itt = cmd->init_task_tag; 2812e48354ceSNicholas Bellinger cmd->stat_sn = conn->stat_sn++; 2813e48354ceSNicholas Bellinger hdr->statsn = cpu_to_be32(cmd->stat_sn); 2814e48354ceSNicholas Bellinger 2815e48354ceSNicholas Bellinger iscsit_increment_maxcmdsn(cmd, conn->sess); 2816e48354ceSNicholas Bellinger hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); 2817e48354ceSNicholas Bellinger hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); 2818e48354ceSNicholas Bellinger 28192ec5a8c1SNicholas Bellinger pr_debug("Built Logout Response ITT: 0x%08x StatSN:" 28202ec5a8c1SNicholas Bellinger " 0x%08x Response: 0x%02x CID: %hu on CID: %hu\n", 28212ec5a8c1SNicholas Bellinger cmd->init_task_tag, cmd->stat_sn, hdr->response, 28222ec5a8c1SNicholas Bellinger cmd->logout_cid, conn->cid); 28232ec5a8c1SNicholas Bellinger 28242ec5a8c1SNicholas Bellinger return 0; 28252ec5a8c1SNicholas Bellinger } 28262ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_logout_rsp); 28272ec5a8c1SNicholas Bellinger 28282ec5a8c1SNicholas Bellinger static int 28292ec5a8c1SNicholas Bellinger iscsit_send_logout(struct iscsi_cmd *cmd, struct iscsi_conn *conn) 28302ec5a8c1SNicholas Bellinger { 28312ec5a8c1SNicholas Bellinger struct kvec *iov; 28322ec5a8c1SNicholas Bellinger int niov = 0, tx_size, rc; 28332ec5a8c1SNicholas Bellinger 28342ec5a8c1SNicholas Bellinger rc = iscsit_build_logout_rsp(cmd, conn, 28352ec5a8c1SNicholas Bellinger (struct iscsi_logout_rsp *)&cmd->pdu[0]); 28362ec5a8c1SNicholas Bellinger if (rc < 0) 28372ec5a8c1SNicholas Bellinger return rc; 28382ec5a8c1SNicholas Bellinger 28392ec5a8c1SNicholas Bellinger tx_size = ISCSI_HDR_LEN; 2840e48354ceSNicholas Bellinger iov = &cmd->iov_misc[0]; 2841e48354ceSNicholas Bellinger iov[niov].iov_base = cmd->pdu; 2842e48354ceSNicholas Bellinger iov[niov++].iov_len = ISCSI_HDR_LEN; 2843e48354ceSNicholas Bellinger 2844e48354ceSNicholas Bellinger if (conn->conn_ops->HeaderDigest) { 2845e48354ceSNicholas Bellinger u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 2846e48354ceSNicholas Bellinger 284780690fdbSGeert Uytterhoeven iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, &cmd->pdu[0], 284880690fdbSGeert Uytterhoeven ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); 2849e48354ceSNicholas Bellinger 2850e48354ceSNicholas Bellinger iov[0].iov_len += ISCSI_CRC_LEN; 2851e48354ceSNicholas Bellinger tx_size += ISCSI_CRC_LEN; 2852e48354ceSNicholas Bellinger pr_debug("Attaching CRC32C HeaderDigest to" 2853e48354ceSNicholas Bellinger " Logout Response 0x%08x\n", *header_digest); 2854e48354ceSNicholas Bellinger } 2855e48354ceSNicholas Bellinger cmd->iov_misc_count = niov; 2856e48354ceSNicholas Bellinger cmd->tx_size = tx_size; 2857e48354ceSNicholas Bellinger 2858e48354ceSNicholas Bellinger return 0; 2859e48354ceSNicholas Bellinger } 2860e48354ceSNicholas Bellinger 28612ec5a8c1SNicholas Bellinger void 28622ec5a8c1SNicholas Bellinger iscsit_build_nopin_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, 28632ec5a8c1SNicholas Bellinger struct iscsi_nopin *hdr, bool nopout_response) 28642ec5a8c1SNicholas Bellinger { 28652ec5a8c1SNicholas Bellinger hdr->opcode = ISCSI_OP_NOOP_IN; 28662ec5a8c1SNicholas Bellinger hdr->flags |= ISCSI_FLAG_CMD_FINAL; 28672ec5a8c1SNicholas Bellinger hton24(hdr->dlength, cmd->buf_ptr_size); 28682ec5a8c1SNicholas Bellinger if (nopout_response) 28692ec5a8c1SNicholas Bellinger put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun); 28702ec5a8c1SNicholas Bellinger hdr->itt = cmd->init_task_tag; 28712ec5a8c1SNicholas Bellinger hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag); 28722ec5a8c1SNicholas Bellinger cmd->stat_sn = (nopout_response) ? conn->stat_sn++ : 28732ec5a8c1SNicholas Bellinger conn->stat_sn; 28742ec5a8c1SNicholas Bellinger hdr->statsn = cpu_to_be32(cmd->stat_sn); 28752ec5a8c1SNicholas Bellinger 28762ec5a8c1SNicholas Bellinger if (nopout_response) 28772ec5a8c1SNicholas Bellinger iscsit_increment_maxcmdsn(cmd, conn->sess); 28782ec5a8c1SNicholas Bellinger 28792ec5a8c1SNicholas Bellinger hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); 28802ec5a8c1SNicholas Bellinger hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); 28812ec5a8c1SNicholas Bellinger 28822ec5a8c1SNicholas Bellinger pr_debug("Built NOPIN %s Response ITT: 0x%08x, TTT: 0x%08x," 28832ec5a8c1SNicholas Bellinger " StatSN: 0x%08x, Length %u\n", (nopout_response) ? 28842ec5a8c1SNicholas Bellinger "Solicitied" : "Unsolicitied", cmd->init_task_tag, 28852ec5a8c1SNicholas Bellinger cmd->targ_xfer_tag, cmd->stat_sn, cmd->buf_ptr_size); 28862ec5a8c1SNicholas Bellinger } 28872ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_nopin_rsp); 28882ec5a8c1SNicholas Bellinger 2889e48354ceSNicholas Bellinger /* 2890e48354ceSNicholas Bellinger * Unsolicited NOPIN, either requesting a response or not. 2891e48354ceSNicholas Bellinger */ 2892e48354ceSNicholas Bellinger static int iscsit_send_unsolicited_nopin( 2893e48354ceSNicholas Bellinger struct iscsi_cmd *cmd, 2894e48354ceSNicholas Bellinger struct iscsi_conn *conn, 2895e48354ceSNicholas Bellinger int want_response) 2896e48354ceSNicholas Bellinger { 28972ec5a8c1SNicholas Bellinger struct iscsi_nopin *hdr = (struct iscsi_nopin *)&cmd->pdu[0]; 28982ec5a8c1SNicholas Bellinger int tx_size = ISCSI_HDR_LEN, ret; 2899e48354ceSNicholas Bellinger 29002ec5a8c1SNicholas Bellinger iscsit_build_nopin_rsp(cmd, conn, hdr, false); 2901e48354ceSNicholas Bellinger 2902e48354ceSNicholas Bellinger if (conn->conn_ops->HeaderDigest) { 2903e48354ceSNicholas Bellinger u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 2904e48354ceSNicholas Bellinger 290580690fdbSGeert Uytterhoeven iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr, 290680690fdbSGeert Uytterhoeven ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); 2907e48354ceSNicholas Bellinger 2908e48354ceSNicholas Bellinger tx_size += ISCSI_CRC_LEN; 2909e48354ceSNicholas Bellinger pr_debug("Attaching CRC32C HeaderDigest to" 2910e48354ceSNicholas Bellinger " NopIN 0x%08x\n", *header_digest); 2911e48354ceSNicholas Bellinger } 2912e48354ceSNicholas Bellinger 2913e48354ceSNicholas Bellinger cmd->iov_misc[0].iov_base = cmd->pdu; 2914e48354ceSNicholas Bellinger cmd->iov_misc[0].iov_len = tx_size; 2915e48354ceSNicholas Bellinger cmd->iov_misc_count = 1; 2916e48354ceSNicholas Bellinger cmd->tx_size = tx_size; 2917e48354ceSNicholas Bellinger 2918e48354ceSNicholas Bellinger pr_debug("Sending Unsolicited NOPIN TTT: 0x%08x StatSN:" 2919e48354ceSNicholas Bellinger " 0x%08x CID: %hu\n", hdr->ttt, cmd->stat_sn, conn->cid); 2920e48354ceSNicholas Bellinger 29216f3c0e69SAndy Grover ret = iscsit_send_tx_data(cmd, conn, 1); 29226f3c0e69SAndy Grover if (ret < 0) { 29236f3c0e69SAndy Grover iscsit_tx_thread_wait_for_tcp(conn); 29246f3c0e69SAndy Grover return ret; 29256f3c0e69SAndy Grover } 29266f3c0e69SAndy Grover 29276f3c0e69SAndy Grover spin_lock_bh(&cmd->istate_lock); 29286f3c0e69SAndy Grover cmd->i_state = want_response ? 29296f3c0e69SAndy Grover ISTATE_SENT_NOPIN_WANT_RESPONSE : ISTATE_SENT_STATUS; 29306f3c0e69SAndy Grover spin_unlock_bh(&cmd->istate_lock); 29316f3c0e69SAndy Grover 2932e48354ceSNicholas Bellinger return 0; 2933e48354ceSNicholas Bellinger } 2934e48354ceSNicholas Bellinger 29352ec5a8c1SNicholas Bellinger static int 29362ec5a8c1SNicholas Bellinger iscsit_send_nopin(struct iscsi_cmd *cmd, struct iscsi_conn *conn) 2937e48354ceSNicholas Bellinger { 29382ec5a8c1SNicholas Bellinger struct iscsi_nopin *hdr = (struct iscsi_nopin *)&cmd->pdu[0]; 2939e48354ceSNicholas Bellinger struct kvec *iov; 29402ec5a8c1SNicholas Bellinger u32 padding = 0; 29412ec5a8c1SNicholas Bellinger int niov = 0, tx_size; 29422ec5a8c1SNicholas Bellinger 29432ec5a8c1SNicholas Bellinger iscsit_build_nopin_rsp(cmd, conn, hdr, true); 2944e48354ceSNicholas Bellinger 2945e48354ceSNicholas Bellinger tx_size = ISCSI_HDR_LEN; 2946e48354ceSNicholas Bellinger iov = &cmd->iov_misc[0]; 2947e48354ceSNicholas Bellinger iov[niov].iov_base = cmd->pdu; 2948e48354ceSNicholas Bellinger iov[niov++].iov_len = ISCSI_HDR_LEN; 2949e48354ceSNicholas Bellinger 2950e48354ceSNicholas Bellinger if (conn->conn_ops->HeaderDigest) { 2951e48354ceSNicholas Bellinger u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 2952e48354ceSNicholas Bellinger 295380690fdbSGeert Uytterhoeven iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr, 295480690fdbSGeert Uytterhoeven ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); 2955e48354ceSNicholas Bellinger 2956e48354ceSNicholas Bellinger iov[0].iov_len += ISCSI_CRC_LEN; 2957e48354ceSNicholas Bellinger tx_size += ISCSI_CRC_LEN; 2958e48354ceSNicholas Bellinger pr_debug("Attaching CRC32C HeaderDigest" 2959e48354ceSNicholas Bellinger " to NopIn 0x%08x\n", *header_digest); 2960e48354ceSNicholas Bellinger } 2961e48354ceSNicholas Bellinger 2962e48354ceSNicholas Bellinger /* 2963e48354ceSNicholas Bellinger * NOPOUT Ping Data is attached to struct iscsi_cmd->buf_ptr. 2964e48354ceSNicholas Bellinger * NOPOUT DataSegmentLength is at struct iscsi_cmd->buf_ptr_size. 2965e48354ceSNicholas Bellinger */ 2966e48354ceSNicholas Bellinger if (cmd->buf_ptr_size) { 2967e48354ceSNicholas Bellinger iov[niov].iov_base = cmd->buf_ptr; 2968e48354ceSNicholas Bellinger iov[niov++].iov_len = cmd->buf_ptr_size; 2969e48354ceSNicholas Bellinger tx_size += cmd->buf_ptr_size; 2970e48354ceSNicholas Bellinger 2971e48354ceSNicholas Bellinger pr_debug("Echoing back %u bytes of ping" 2972e48354ceSNicholas Bellinger " data.\n", cmd->buf_ptr_size); 2973e48354ceSNicholas Bellinger 2974e48354ceSNicholas Bellinger padding = ((-cmd->buf_ptr_size) & 3); 2975e48354ceSNicholas Bellinger if (padding != 0) { 2976e48354ceSNicholas Bellinger iov[niov].iov_base = &cmd->pad_bytes; 2977e48354ceSNicholas Bellinger iov[niov++].iov_len = padding; 2978e48354ceSNicholas Bellinger tx_size += padding; 2979e48354ceSNicholas Bellinger pr_debug("Attaching %u additional" 2980e48354ceSNicholas Bellinger " padding bytes.\n", padding); 2981e48354ceSNicholas Bellinger } 2982e48354ceSNicholas Bellinger if (conn->conn_ops->DataDigest) { 2983e48354ceSNicholas Bellinger iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, 2984e48354ceSNicholas Bellinger cmd->buf_ptr, cmd->buf_ptr_size, 2985e48354ceSNicholas Bellinger padding, (u8 *)&cmd->pad_bytes, 2986e48354ceSNicholas Bellinger (u8 *)&cmd->data_crc); 2987e48354ceSNicholas Bellinger 2988e48354ceSNicholas Bellinger iov[niov].iov_base = &cmd->data_crc; 2989e48354ceSNicholas Bellinger iov[niov++].iov_len = ISCSI_CRC_LEN; 2990e48354ceSNicholas Bellinger tx_size += ISCSI_CRC_LEN; 2991e48354ceSNicholas Bellinger pr_debug("Attached DataDigest for %u" 2992e48354ceSNicholas Bellinger " bytes of ping data, CRC 0x%08x\n", 2993e48354ceSNicholas Bellinger cmd->buf_ptr_size, cmd->data_crc); 2994e48354ceSNicholas Bellinger } 2995e48354ceSNicholas Bellinger } 2996e48354ceSNicholas Bellinger 2997e48354ceSNicholas Bellinger cmd->iov_misc_count = niov; 2998e48354ceSNicholas Bellinger cmd->tx_size = tx_size; 2999e48354ceSNicholas Bellinger 3000e48354ceSNicholas Bellinger return 0; 3001e48354ceSNicholas Bellinger } 3002e48354ceSNicholas Bellinger 30036f3c0e69SAndy Grover static int iscsit_send_r2t( 3004e48354ceSNicholas Bellinger struct iscsi_cmd *cmd, 3005e48354ceSNicholas Bellinger struct iscsi_conn *conn) 3006e48354ceSNicholas Bellinger { 3007e48354ceSNicholas Bellinger int tx_size = 0; 3008e48354ceSNicholas Bellinger struct iscsi_r2t *r2t; 3009e48354ceSNicholas Bellinger struct iscsi_r2t_rsp *hdr; 30106f3c0e69SAndy Grover int ret; 3011e48354ceSNicholas Bellinger 3012e48354ceSNicholas Bellinger r2t = iscsit_get_r2t_from_list(cmd); 3013e48354ceSNicholas Bellinger if (!r2t) 3014e48354ceSNicholas Bellinger return -1; 3015e48354ceSNicholas Bellinger 3016e48354ceSNicholas Bellinger hdr = (struct iscsi_r2t_rsp *) cmd->pdu; 3017e48354ceSNicholas Bellinger memset(hdr, 0, ISCSI_HDR_LEN); 3018e48354ceSNicholas Bellinger hdr->opcode = ISCSI_OP_R2T; 3019e48354ceSNicholas Bellinger hdr->flags |= ISCSI_FLAG_CMD_FINAL; 3020e48354ceSNicholas Bellinger int_to_scsilun(cmd->se_cmd.orig_fe_lun, 3021e48354ceSNicholas Bellinger (struct scsi_lun *)&hdr->lun); 302266c7db68SChristoph Hellwig hdr->itt = cmd->init_task_tag; 3023e48354ceSNicholas Bellinger spin_lock_bh(&conn->sess->ttt_lock); 3024e48354ceSNicholas Bellinger r2t->targ_xfer_tag = conn->sess->targ_xfer_tag++; 3025e48354ceSNicholas Bellinger if (r2t->targ_xfer_tag == 0xFFFFFFFF) 3026e48354ceSNicholas Bellinger r2t->targ_xfer_tag = conn->sess->targ_xfer_tag++; 3027e48354ceSNicholas Bellinger spin_unlock_bh(&conn->sess->ttt_lock); 3028e48354ceSNicholas Bellinger hdr->ttt = cpu_to_be32(r2t->targ_xfer_tag); 3029e48354ceSNicholas Bellinger hdr->statsn = cpu_to_be32(conn->stat_sn); 3030e48354ceSNicholas Bellinger hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); 3031e48354ceSNicholas Bellinger hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); 3032e48354ceSNicholas Bellinger hdr->r2tsn = cpu_to_be32(r2t->r2t_sn); 3033e48354ceSNicholas Bellinger hdr->data_offset = cpu_to_be32(r2t->offset); 3034e48354ceSNicholas Bellinger hdr->data_length = cpu_to_be32(r2t->xfer_len); 3035e48354ceSNicholas Bellinger 3036e48354ceSNicholas Bellinger cmd->iov_misc[0].iov_base = cmd->pdu; 3037e48354ceSNicholas Bellinger cmd->iov_misc[0].iov_len = ISCSI_HDR_LEN; 3038e48354ceSNicholas Bellinger tx_size += ISCSI_HDR_LEN; 3039e48354ceSNicholas Bellinger 3040e48354ceSNicholas Bellinger if (conn->conn_ops->HeaderDigest) { 3041e48354ceSNicholas Bellinger u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 3042e48354ceSNicholas Bellinger 304380690fdbSGeert Uytterhoeven iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr, 304480690fdbSGeert Uytterhoeven ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); 3045e48354ceSNicholas Bellinger 3046e48354ceSNicholas Bellinger cmd->iov_misc[0].iov_len += ISCSI_CRC_LEN; 3047e48354ceSNicholas Bellinger tx_size += ISCSI_CRC_LEN; 3048e48354ceSNicholas Bellinger pr_debug("Attaching CRC32 HeaderDigest for R2T" 3049e48354ceSNicholas Bellinger " PDU 0x%08x\n", *header_digest); 3050e48354ceSNicholas Bellinger } 3051e48354ceSNicholas Bellinger 3052e48354ceSNicholas Bellinger pr_debug("Built %sR2T, ITT: 0x%08x, TTT: 0x%08x, StatSN:" 3053e48354ceSNicholas Bellinger " 0x%08x, R2TSN: 0x%08x, Offset: %u, DDTL: %u, CID: %hu\n", 3054e48354ceSNicholas Bellinger (!r2t->recovery_r2t) ? "" : "Recovery ", cmd->init_task_tag, 3055e48354ceSNicholas Bellinger r2t->targ_xfer_tag, ntohl(hdr->statsn), r2t->r2t_sn, 3056e48354ceSNicholas Bellinger r2t->offset, r2t->xfer_len, conn->cid); 3057e48354ceSNicholas Bellinger 3058e48354ceSNicholas Bellinger cmd->iov_misc_count = 1; 3059e48354ceSNicholas Bellinger cmd->tx_size = tx_size; 3060e48354ceSNicholas Bellinger 3061e48354ceSNicholas Bellinger spin_lock_bh(&cmd->r2t_lock); 3062e48354ceSNicholas Bellinger r2t->sent_r2t = 1; 3063e48354ceSNicholas Bellinger spin_unlock_bh(&cmd->r2t_lock); 3064e48354ceSNicholas Bellinger 30656f3c0e69SAndy Grover ret = iscsit_send_tx_data(cmd, conn, 1); 30666f3c0e69SAndy Grover if (ret < 0) { 30676f3c0e69SAndy Grover iscsit_tx_thread_wait_for_tcp(conn); 30686f3c0e69SAndy Grover return ret; 30696f3c0e69SAndy Grover } 30706f3c0e69SAndy Grover 30716f3c0e69SAndy Grover spin_lock_bh(&cmd->dataout_timeout_lock); 30726f3c0e69SAndy Grover iscsit_start_dataout_timer(cmd, conn); 30736f3c0e69SAndy Grover spin_unlock_bh(&cmd->dataout_timeout_lock); 30746f3c0e69SAndy Grover 3075e48354ceSNicholas Bellinger return 0; 3076e48354ceSNicholas Bellinger } 3077e48354ceSNicholas Bellinger 3078e48354ceSNicholas Bellinger /* 30798b1e1244SAndy Grover * @recovery: If called from iscsi_task_reassign_complete_write() for 3080e48354ceSNicholas Bellinger * connection recovery. 3081e48354ceSNicholas Bellinger */ 3082e48354ceSNicholas Bellinger int iscsit_build_r2ts_for_cmd( 3083e48354ceSNicholas Bellinger struct iscsi_conn *conn, 30843e1c81a9SNicholas Bellinger struct iscsi_cmd *cmd, 30858b1e1244SAndy Grover bool recovery) 3086e48354ceSNicholas Bellinger { 3087e48354ceSNicholas Bellinger int first_r2t = 1; 3088e48354ceSNicholas Bellinger u32 offset = 0, xfer_len = 0; 3089e48354ceSNicholas Bellinger 3090e48354ceSNicholas Bellinger spin_lock_bh(&cmd->r2t_lock); 3091e48354ceSNicholas Bellinger if (cmd->cmd_flags & ICF_SENT_LAST_R2T) { 3092e48354ceSNicholas Bellinger spin_unlock_bh(&cmd->r2t_lock); 3093e48354ceSNicholas Bellinger return 0; 3094e48354ceSNicholas Bellinger } 3095e48354ceSNicholas Bellinger 30968b1e1244SAndy Grover if (conn->sess->sess_ops->DataSequenceInOrder && 30978b1e1244SAndy Grover !recovery) 3098c6037cc5SAndy Grover cmd->r2t_offset = max(cmd->r2t_offset, cmd->write_data_done); 3099e48354ceSNicholas Bellinger 3100e48354ceSNicholas Bellinger while (cmd->outstanding_r2ts < conn->sess->sess_ops->MaxOutstandingR2T) { 3101e48354ceSNicholas Bellinger if (conn->sess->sess_ops->DataSequenceInOrder) { 3102e48354ceSNicholas Bellinger offset = cmd->r2t_offset; 3103e48354ceSNicholas Bellinger 31048b1e1244SAndy Grover if (first_r2t && recovery) { 31058b1e1244SAndy Grover int new_data_end = offset + 31068b1e1244SAndy Grover conn->sess->sess_ops->MaxBurstLength - 31078b1e1244SAndy Grover cmd->next_burst_len; 31088b1e1244SAndy Grover 3109ebf1d95cSAndy Grover if (new_data_end > cmd->se_cmd.data_length) 3110ebf1d95cSAndy Grover xfer_len = cmd->se_cmd.data_length - offset; 31118b1e1244SAndy Grover else 31128b1e1244SAndy Grover xfer_len = 31138b1e1244SAndy Grover conn->sess->sess_ops->MaxBurstLength - 31148b1e1244SAndy Grover cmd->next_burst_len; 3115e48354ceSNicholas Bellinger } else { 31168b1e1244SAndy Grover int new_data_end = offset + 3117e48354ceSNicholas Bellinger conn->sess->sess_ops->MaxBurstLength; 31188b1e1244SAndy Grover 3119ebf1d95cSAndy Grover if (new_data_end > cmd->se_cmd.data_length) 3120ebf1d95cSAndy Grover xfer_len = cmd->se_cmd.data_length - offset; 31218b1e1244SAndy Grover else 31228b1e1244SAndy Grover xfer_len = conn->sess->sess_ops->MaxBurstLength; 3123e48354ceSNicholas Bellinger } 3124e48354ceSNicholas Bellinger cmd->r2t_offset += xfer_len; 3125e48354ceSNicholas Bellinger 3126ebf1d95cSAndy Grover if (cmd->r2t_offset == cmd->se_cmd.data_length) 3127e48354ceSNicholas Bellinger cmd->cmd_flags |= ICF_SENT_LAST_R2T; 3128e48354ceSNicholas Bellinger } else { 3129e48354ceSNicholas Bellinger struct iscsi_seq *seq; 3130e48354ceSNicholas Bellinger 3131e48354ceSNicholas Bellinger seq = iscsit_get_seq_holder_for_r2t(cmd); 3132e48354ceSNicholas Bellinger if (!seq) { 3133e48354ceSNicholas Bellinger spin_unlock_bh(&cmd->r2t_lock); 3134e48354ceSNicholas Bellinger return -1; 3135e48354ceSNicholas Bellinger } 3136e48354ceSNicholas Bellinger 3137e48354ceSNicholas Bellinger offset = seq->offset; 3138e48354ceSNicholas Bellinger xfer_len = seq->xfer_len; 3139e48354ceSNicholas Bellinger 3140e48354ceSNicholas Bellinger if (cmd->seq_send_order == cmd->seq_count) 3141e48354ceSNicholas Bellinger cmd->cmd_flags |= ICF_SENT_LAST_R2T; 3142e48354ceSNicholas Bellinger } 3143e48354ceSNicholas Bellinger cmd->outstanding_r2ts++; 3144e48354ceSNicholas Bellinger first_r2t = 0; 3145e48354ceSNicholas Bellinger 3146e48354ceSNicholas Bellinger if (iscsit_add_r2t_to_list(cmd, offset, xfer_len, 0, 0) < 0) { 3147e48354ceSNicholas Bellinger spin_unlock_bh(&cmd->r2t_lock); 3148e48354ceSNicholas Bellinger return -1; 3149e48354ceSNicholas Bellinger } 3150e48354ceSNicholas Bellinger 3151e48354ceSNicholas Bellinger if (cmd->cmd_flags & ICF_SENT_LAST_R2T) 3152e48354ceSNicholas Bellinger break; 3153e48354ceSNicholas Bellinger } 3154e48354ceSNicholas Bellinger spin_unlock_bh(&cmd->r2t_lock); 3155e48354ceSNicholas Bellinger 3156e48354ceSNicholas Bellinger return 0; 3157e48354ceSNicholas Bellinger } 3158e48354ceSNicholas Bellinger 31592ec5a8c1SNicholas Bellinger void iscsit_build_rsp_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn, 31602ec5a8c1SNicholas Bellinger bool inc_stat_sn, struct iscsi_scsi_rsp *hdr) 3161e48354ceSNicholas Bellinger { 31622ec5a8c1SNicholas Bellinger if (inc_stat_sn) 3163e48354ceSNicholas Bellinger cmd->stat_sn = conn->stat_sn++; 3164e48354ceSNicholas Bellinger 3165e48354ceSNicholas Bellinger spin_lock_bh(&conn->sess->session_stats_lock); 3166e48354ceSNicholas Bellinger conn->sess->rsp_pdus++; 3167e48354ceSNicholas Bellinger spin_unlock_bh(&conn->sess->session_stats_lock); 3168e48354ceSNicholas Bellinger 3169e48354ceSNicholas Bellinger memset(hdr, 0, ISCSI_HDR_LEN); 3170e48354ceSNicholas Bellinger hdr->opcode = ISCSI_OP_SCSI_CMD_RSP; 3171e48354ceSNicholas Bellinger hdr->flags |= ISCSI_FLAG_CMD_FINAL; 3172e48354ceSNicholas Bellinger if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { 3173e48354ceSNicholas Bellinger hdr->flags |= ISCSI_FLAG_CMD_OVERFLOW; 31747e46cf02SNicholas Bellinger hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); 3175e48354ceSNicholas Bellinger } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { 3176e48354ceSNicholas Bellinger hdr->flags |= ISCSI_FLAG_CMD_UNDERFLOW; 31777e46cf02SNicholas Bellinger hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); 3178e48354ceSNicholas Bellinger } 3179e48354ceSNicholas Bellinger hdr->response = cmd->iscsi_response; 3180e48354ceSNicholas Bellinger hdr->cmd_status = cmd->se_cmd.scsi_status; 318166c7db68SChristoph Hellwig hdr->itt = cmd->init_task_tag; 3182e48354ceSNicholas Bellinger hdr->statsn = cpu_to_be32(cmd->stat_sn); 3183e48354ceSNicholas Bellinger 3184e48354ceSNicholas Bellinger iscsit_increment_maxcmdsn(cmd, conn->sess); 3185e48354ceSNicholas Bellinger hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); 3186e48354ceSNicholas Bellinger hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); 3187e48354ceSNicholas Bellinger 31882ec5a8c1SNicholas Bellinger pr_debug("Built SCSI Response, ITT: 0x%08x, StatSN: 0x%08x," 31892ec5a8c1SNicholas Bellinger " Response: 0x%02x, SAM Status: 0x%02x, CID: %hu\n", 31902ec5a8c1SNicholas Bellinger cmd->init_task_tag, cmd->stat_sn, cmd->se_cmd.scsi_status, 31912ec5a8c1SNicholas Bellinger cmd->se_cmd.scsi_status, conn->cid); 31922ec5a8c1SNicholas Bellinger } 31932ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_rsp_pdu); 31942ec5a8c1SNicholas Bellinger 31952ec5a8c1SNicholas Bellinger static int iscsit_send_response(struct iscsi_cmd *cmd, struct iscsi_conn *conn) 31962ec5a8c1SNicholas Bellinger { 31972ec5a8c1SNicholas Bellinger struct iscsi_scsi_rsp *hdr = (struct iscsi_scsi_rsp *)&cmd->pdu[0]; 31982ec5a8c1SNicholas Bellinger struct kvec *iov; 31992ec5a8c1SNicholas Bellinger u32 padding = 0, tx_size = 0; 32002ec5a8c1SNicholas Bellinger int iov_count = 0; 32012ec5a8c1SNicholas Bellinger bool inc_stat_sn = (cmd->i_state == ISTATE_SEND_STATUS); 32022ec5a8c1SNicholas Bellinger 32032ec5a8c1SNicholas Bellinger iscsit_build_rsp_pdu(cmd, conn, inc_stat_sn, hdr); 32042ec5a8c1SNicholas Bellinger 3205e48354ceSNicholas Bellinger iov = &cmd->iov_misc[0]; 3206e48354ceSNicholas Bellinger iov[iov_count].iov_base = cmd->pdu; 3207e48354ceSNicholas Bellinger iov[iov_count++].iov_len = ISCSI_HDR_LEN; 3208e48354ceSNicholas Bellinger tx_size += ISCSI_HDR_LEN; 3209e48354ceSNicholas Bellinger 3210e48354ceSNicholas Bellinger /* 3211e48354ceSNicholas Bellinger * Attach SENSE DATA payload to iSCSI Response PDU 3212e48354ceSNicholas Bellinger */ 3213e48354ceSNicholas Bellinger if (cmd->se_cmd.sense_buffer && 3214e48354ceSNicholas Bellinger ((cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) || 3215e48354ceSNicholas Bellinger (cmd->se_cmd.se_cmd_flags & SCF_EMULATED_TASK_SENSE))) { 32169c58b7ddSRoland Dreier put_unaligned_be16(cmd->se_cmd.scsi_sense_length, cmd->sense_buffer); 32179c58b7ddSRoland Dreier cmd->se_cmd.scsi_sense_length += sizeof (__be16); 32189c58b7ddSRoland Dreier 3219e48354ceSNicholas Bellinger padding = -(cmd->se_cmd.scsi_sense_length) & 3; 322050e5c87dSChristoph Hellwig hton24(hdr->dlength, (u32)cmd->se_cmd.scsi_sense_length); 32219c58b7ddSRoland Dreier iov[iov_count].iov_base = cmd->sense_buffer; 3222e48354ceSNicholas Bellinger iov[iov_count++].iov_len = 3223e48354ceSNicholas Bellinger (cmd->se_cmd.scsi_sense_length + padding); 3224e48354ceSNicholas Bellinger tx_size += cmd->se_cmd.scsi_sense_length; 3225e48354ceSNicholas Bellinger 3226e48354ceSNicholas Bellinger if (padding) { 32279c58b7ddSRoland Dreier memset(cmd->sense_buffer + 3228e48354ceSNicholas Bellinger cmd->se_cmd.scsi_sense_length, 0, padding); 3229e48354ceSNicholas Bellinger tx_size += padding; 3230e48354ceSNicholas Bellinger pr_debug("Adding %u bytes of padding to" 3231e48354ceSNicholas Bellinger " SENSE.\n", padding); 3232e48354ceSNicholas Bellinger } 3233e48354ceSNicholas Bellinger 3234e48354ceSNicholas Bellinger if (conn->conn_ops->DataDigest) { 3235e48354ceSNicholas Bellinger iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, 32369c58b7ddSRoland Dreier cmd->sense_buffer, 3237e48354ceSNicholas Bellinger (cmd->se_cmd.scsi_sense_length + padding), 3238e48354ceSNicholas Bellinger 0, NULL, (u8 *)&cmd->data_crc); 3239e48354ceSNicholas Bellinger 3240e48354ceSNicholas Bellinger iov[iov_count].iov_base = &cmd->data_crc; 3241e48354ceSNicholas Bellinger iov[iov_count++].iov_len = ISCSI_CRC_LEN; 3242e48354ceSNicholas Bellinger tx_size += ISCSI_CRC_LEN; 3243e48354ceSNicholas Bellinger 3244e48354ceSNicholas Bellinger pr_debug("Attaching CRC32 DataDigest for" 3245e48354ceSNicholas Bellinger " SENSE, %u bytes CRC 0x%08x\n", 3246e48354ceSNicholas Bellinger (cmd->se_cmd.scsi_sense_length + padding), 3247e48354ceSNicholas Bellinger cmd->data_crc); 3248e48354ceSNicholas Bellinger } 3249e48354ceSNicholas Bellinger 3250e48354ceSNicholas Bellinger pr_debug("Attaching SENSE DATA: %u bytes to iSCSI" 3251e48354ceSNicholas Bellinger " Response PDU\n", 3252e48354ceSNicholas Bellinger cmd->se_cmd.scsi_sense_length); 3253e48354ceSNicholas Bellinger } 3254e48354ceSNicholas Bellinger 3255e48354ceSNicholas Bellinger if (conn->conn_ops->HeaderDigest) { 3256e48354ceSNicholas Bellinger u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 3257e48354ceSNicholas Bellinger 325880690fdbSGeert Uytterhoeven iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, cmd->pdu, 325980690fdbSGeert Uytterhoeven ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); 3260e48354ceSNicholas Bellinger 3261e48354ceSNicholas Bellinger iov[0].iov_len += ISCSI_CRC_LEN; 3262e48354ceSNicholas Bellinger tx_size += ISCSI_CRC_LEN; 3263e48354ceSNicholas Bellinger pr_debug("Attaching CRC32 HeaderDigest for Response" 3264e48354ceSNicholas Bellinger " PDU 0x%08x\n", *header_digest); 3265e48354ceSNicholas Bellinger } 3266e48354ceSNicholas Bellinger 3267e48354ceSNicholas Bellinger cmd->iov_misc_count = iov_count; 3268e48354ceSNicholas Bellinger cmd->tx_size = tx_size; 3269e48354ceSNicholas Bellinger 3270e48354ceSNicholas Bellinger return 0; 3271e48354ceSNicholas Bellinger } 3272e48354ceSNicholas Bellinger 3273e48354ceSNicholas Bellinger static u8 iscsit_convert_tcm_tmr_rsp(struct se_tmr_req *se_tmr) 3274e48354ceSNicholas Bellinger { 3275e48354ceSNicholas Bellinger switch (se_tmr->response) { 3276e48354ceSNicholas Bellinger case TMR_FUNCTION_COMPLETE: 3277e48354ceSNicholas Bellinger return ISCSI_TMF_RSP_COMPLETE; 3278e48354ceSNicholas Bellinger case TMR_TASK_DOES_NOT_EXIST: 3279e48354ceSNicholas Bellinger return ISCSI_TMF_RSP_NO_TASK; 3280e48354ceSNicholas Bellinger case TMR_LUN_DOES_NOT_EXIST: 3281e48354ceSNicholas Bellinger return ISCSI_TMF_RSP_NO_LUN; 3282e48354ceSNicholas Bellinger case TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED: 3283e48354ceSNicholas Bellinger return ISCSI_TMF_RSP_NOT_SUPPORTED; 3284e48354ceSNicholas Bellinger case TMR_FUNCTION_REJECTED: 3285e48354ceSNicholas Bellinger default: 3286e48354ceSNicholas Bellinger return ISCSI_TMF_RSP_REJECTED; 3287e48354ceSNicholas Bellinger } 3288e48354ceSNicholas Bellinger } 3289e48354ceSNicholas Bellinger 32902ec5a8c1SNicholas Bellinger void 32912ec5a8c1SNicholas Bellinger iscsit_build_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, 32922ec5a8c1SNicholas Bellinger struct iscsi_tm_rsp *hdr) 3293e48354ceSNicholas Bellinger { 3294e48354ceSNicholas Bellinger struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req; 3295e48354ceSNicholas Bellinger 3296e48354ceSNicholas Bellinger hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; 32977ae0b103SNicholas Bellinger hdr->flags = ISCSI_FLAG_CMD_FINAL; 3298e48354ceSNicholas Bellinger hdr->response = iscsit_convert_tcm_tmr_rsp(se_tmr); 329966c7db68SChristoph Hellwig hdr->itt = cmd->init_task_tag; 3300e48354ceSNicholas Bellinger cmd->stat_sn = conn->stat_sn++; 3301e48354ceSNicholas Bellinger hdr->statsn = cpu_to_be32(cmd->stat_sn); 3302e48354ceSNicholas Bellinger 3303e48354ceSNicholas Bellinger iscsit_increment_maxcmdsn(cmd, conn->sess); 3304e48354ceSNicholas Bellinger hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); 3305e48354ceSNicholas Bellinger hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); 3306e48354ceSNicholas Bellinger 33072ec5a8c1SNicholas Bellinger pr_debug("Built Task Management Response ITT: 0x%08x," 33082ec5a8c1SNicholas Bellinger " StatSN: 0x%08x, Response: 0x%02x, CID: %hu\n", 33092ec5a8c1SNicholas Bellinger cmd->init_task_tag, cmd->stat_sn, hdr->response, conn->cid); 33102ec5a8c1SNicholas Bellinger } 33112ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_task_mgt_rsp); 33122ec5a8c1SNicholas Bellinger 33132ec5a8c1SNicholas Bellinger static int 33142ec5a8c1SNicholas Bellinger iscsit_send_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn) 33152ec5a8c1SNicholas Bellinger { 33162ec5a8c1SNicholas Bellinger struct iscsi_tm_rsp *hdr = (struct iscsi_tm_rsp *)&cmd->pdu[0]; 33172ec5a8c1SNicholas Bellinger u32 tx_size = 0; 33182ec5a8c1SNicholas Bellinger 33192ec5a8c1SNicholas Bellinger iscsit_build_task_mgt_rsp(cmd, conn, hdr); 33202ec5a8c1SNicholas Bellinger 3321e48354ceSNicholas Bellinger cmd->iov_misc[0].iov_base = cmd->pdu; 3322e48354ceSNicholas Bellinger cmd->iov_misc[0].iov_len = ISCSI_HDR_LEN; 3323e48354ceSNicholas Bellinger tx_size += ISCSI_HDR_LEN; 3324e48354ceSNicholas Bellinger 3325e48354ceSNicholas Bellinger if (conn->conn_ops->HeaderDigest) { 3326e48354ceSNicholas Bellinger u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 3327e48354ceSNicholas Bellinger 332880690fdbSGeert Uytterhoeven iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr, 332980690fdbSGeert Uytterhoeven ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); 3330e48354ceSNicholas Bellinger 3331e48354ceSNicholas Bellinger cmd->iov_misc[0].iov_len += ISCSI_CRC_LEN; 3332e48354ceSNicholas Bellinger tx_size += ISCSI_CRC_LEN; 3333e48354ceSNicholas Bellinger pr_debug("Attaching CRC32 HeaderDigest for Task" 3334e48354ceSNicholas Bellinger " Mgmt Response PDU 0x%08x\n", *header_digest); 3335e48354ceSNicholas Bellinger } 3336e48354ceSNicholas Bellinger 3337e48354ceSNicholas Bellinger cmd->iov_misc_count = 1; 3338e48354ceSNicholas Bellinger cmd->tx_size = tx_size; 3339e48354ceSNicholas Bellinger 3340e48354ceSNicholas Bellinger return 0; 3341e48354ceSNicholas Bellinger } 3342e48354ceSNicholas Bellinger 33432f9bc894SNicholas Bellinger static bool iscsit_check_inaddr_any(struct iscsi_np *np) 33442f9bc894SNicholas Bellinger { 33452f9bc894SNicholas Bellinger bool ret = false; 33462f9bc894SNicholas Bellinger 33472f9bc894SNicholas Bellinger if (np->np_sockaddr.ss_family == AF_INET6) { 33482f9bc894SNicholas Bellinger const struct sockaddr_in6 sin6 = { 33492f9bc894SNicholas Bellinger .sin6_addr = IN6ADDR_ANY_INIT }; 33502f9bc894SNicholas Bellinger struct sockaddr_in6 *sock_in6 = 33512f9bc894SNicholas Bellinger (struct sockaddr_in6 *)&np->np_sockaddr; 33522f9bc894SNicholas Bellinger 33532f9bc894SNicholas Bellinger if (!memcmp(sock_in6->sin6_addr.s6_addr, 33542f9bc894SNicholas Bellinger sin6.sin6_addr.s6_addr, 16)) 33552f9bc894SNicholas Bellinger ret = true; 33562f9bc894SNicholas Bellinger } else { 33572f9bc894SNicholas Bellinger struct sockaddr_in * sock_in = 33582f9bc894SNicholas Bellinger (struct sockaddr_in *)&np->np_sockaddr; 33592f9bc894SNicholas Bellinger 3360cea0b4ceSChristoph Hellwig if (sock_in->sin_addr.s_addr == htonl(INADDR_ANY)) 33612f9bc894SNicholas Bellinger ret = true; 33622f9bc894SNicholas Bellinger } 33632f9bc894SNicholas Bellinger 33642f9bc894SNicholas Bellinger return ret; 33652f9bc894SNicholas Bellinger } 33662f9bc894SNicholas Bellinger 33678b1e1244SAndy Grover #define SENDTARGETS_BUF_LIMIT 32768U 33688b1e1244SAndy Grover 3369e48354ceSNicholas Bellinger static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) 3370e48354ceSNicholas Bellinger { 3371e48354ceSNicholas Bellinger char *payload = NULL; 3372e48354ceSNicholas Bellinger struct iscsi_conn *conn = cmd->conn; 3373e48354ceSNicholas Bellinger struct iscsi_portal_group *tpg; 3374e48354ceSNicholas Bellinger struct iscsi_tiqn *tiqn; 3375e48354ceSNicholas Bellinger struct iscsi_tpg_np *tpg_np; 3376e48354ceSNicholas Bellinger int buffer_len, end_of_buf = 0, len = 0, payload_len = 0; 33778b1e1244SAndy Grover unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */ 33786665889cSNicholas Bellinger unsigned char *text_in = cmd->text_in_ptr, *text_ptr = NULL; 3379e48354ceSNicholas Bellinger 33808b1e1244SAndy Grover buffer_len = max(conn->conn_ops->MaxRecvDataSegmentLength, 33818b1e1244SAndy Grover SENDTARGETS_BUF_LIMIT); 3382e48354ceSNicholas Bellinger 3383e48354ceSNicholas Bellinger payload = kzalloc(buffer_len, GFP_KERNEL); 3384e48354ceSNicholas Bellinger if (!payload) { 3385e48354ceSNicholas Bellinger pr_err("Unable to allocate memory for sendtargets" 3386e48354ceSNicholas Bellinger " response.\n"); 3387e48354ceSNicholas Bellinger return -ENOMEM; 3388e48354ceSNicholas Bellinger } 33896665889cSNicholas Bellinger /* 33906665889cSNicholas Bellinger * Locate pointer to iqn./eui. string for IFC_SENDTARGETS_SINGLE 33916665889cSNicholas Bellinger * explicit case.. 33926665889cSNicholas Bellinger */ 33936665889cSNicholas Bellinger if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) { 33946665889cSNicholas Bellinger text_ptr = strchr(text_in, '='); 33956665889cSNicholas Bellinger if (!text_ptr) { 33966665889cSNicholas Bellinger pr_err("Unable to locate '=' string in text_in:" 33976665889cSNicholas Bellinger " %s\n", text_in); 33984f45d320SDan Carpenter kfree(payload); 33996665889cSNicholas Bellinger return -EINVAL; 34006665889cSNicholas Bellinger } 34016665889cSNicholas Bellinger /* 34026665889cSNicholas Bellinger * Skip over '=' character.. 34036665889cSNicholas Bellinger */ 34046665889cSNicholas Bellinger text_ptr += 1; 34056665889cSNicholas Bellinger } 3406e48354ceSNicholas Bellinger 3407e48354ceSNicholas Bellinger spin_lock(&tiqn_lock); 3408e48354ceSNicholas Bellinger list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) { 34096665889cSNicholas Bellinger if ((cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) && 34106665889cSNicholas Bellinger strcmp(tiqn->tiqn, text_ptr)) { 34116665889cSNicholas Bellinger continue; 34126665889cSNicholas Bellinger } 34136665889cSNicholas Bellinger 3414e48354ceSNicholas Bellinger len = sprintf(buf, "TargetName=%s", tiqn->tiqn); 3415e48354ceSNicholas Bellinger len += 1; 3416e48354ceSNicholas Bellinger 3417e48354ceSNicholas Bellinger if ((len + payload_len) > buffer_len) { 3418e48354ceSNicholas Bellinger end_of_buf = 1; 3419e48354ceSNicholas Bellinger goto eob; 3420e48354ceSNicholas Bellinger } 34218359cf43SJörn Engel memcpy(payload + payload_len, buf, len); 3422e48354ceSNicholas Bellinger payload_len += len; 3423e48354ceSNicholas Bellinger 3424e48354ceSNicholas Bellinger spin_lock(&tiqn->tiqn_tpg_lock); 3425e48354ceSNicholas Bellinger list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) { 3426e48354ceSNicholas Bellinger 3427e48354ceSNicholas Bellinger spin_lock(&tpg->tpg_state_lock); 3428e48354ceSNicholas Bellinger if ((tpg->tpg_state == TPG_STATE_FREE) || 3429e48354ceSNicholas Bellinger (tpg->tpg_state == TPG_STATE_INACTIVE)) { 3430e48354ceSNicholas Bellinger spin_unlock(&tpg->tpg_state_lock); 3431e48354ceSNicholas Bellinger continue; 3432e48354ceSNicholas Bellinger } 3433e48354ceSNicholas Bellinger spin_unlock(&tpg->tpg_state_lock); 3434e48354ceSNicholas Bellinger 3435e48354ceSNicholas Bellinger spin_lock(&tpg->tpg_np_lock); 3436e48354ceSNicholas Bellinger list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, 3437e48354ceSNicholas Bellinger tpg_np_list) { 34382f9bc894SNicholas Bellinger struct iscsi_np *np = tpg_np->tpg_np; 34392f9bc894SNicholas Bellinger bool inaddr_any = iscsit_check_inaddr_any(np); 34402f9bc894SNicholas Bellinger 3441e48354ceSNicholas Bellinger len = sprintf(buf, "TargetAddress=" 3442e48354ceSNicholas Bellinger "%s%s%s:%hu,%hu", 34432f9bc894SNicholas Bellinger (np->np_sockaddr.ss_family == AF_INET6) ? 34442f9bc894SNicholas Bellinger "[" : "", (inaddr_any == false) ? 34452f9bc894SNicholas Bellinger np->np_ip : conn->local_ip, 34462f9bc894SNicholas Bellinger (np->np_sockaddr.ss_family == AF_INET6) ? 34472f9bc894SNicholas Bellinger "]" : "", (inaddr_any == false) ? 34482f9bc894SNicholas Bellinger np->np_port : conn->local_port, 3449e48354ceSNicholas Bellinger tpg->tpgt); 3450e48354ceSNicholas Bellinger len += 1; 3451e48354ceSNicholas Bellinger 3452e48354ceSNicholas Bellinger if ((len + payload_len) > buffer_len) { 3453e48354ceSNicholas Bellinger spin_unlock(&tpg->tpg_np_lock); 3454e48354ceSNicholas Bellinger spin_unlock(&tiqn->tiqn_tpg_lock); 3455e48354ceSNicholas Bellinger end_of_buf = 1; 3456e48354ceSNicholas Bellinger goto eob; 3457e48354ceSNicholas Bellinger } 34588359cf43SJörn Engel memcpy(payload + payload_len, buf, len); 3459e48354ceSNicholas Bellinger payload_len += len; 3460e48354ceSNicholas Bellinger } 3461e48354ceSNicholas Bellinger spin_unlock(&tpg->tpg_np_lock); 3462e48354ceSNicholas Bellinger } 3463e48354ceSNicholas Bellinger spin_unlock(&tiqn->tiqn_tpg_lock); 3464e48354ceSNicholas Bellinger eob: 3465e48354ceSNicholas Bellinger if (end_of_buf) 3466e48354ceSNicholas Bellinger break; 34676665889cSNicholas Bellinger 34686665889cSNicholas Bellinger if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) 34696665889cSNicholas Bellinger break; 3470e48354ceSNicholas Bellinger } 3471e48354ceSNicholas Bellinger spin_unlock(&tiqn_lock); 3472e48354ceSNicholas Bellinger 3473e48354ceSNicholas Bellinger cmd->buf_ptr = payload; 3474e48354ceSNicholas Bellinger 3475e48354ceSNicholas Bellinger return payload_len; 3476e48354ceSNicholas Bellinger } 3477e48354ceSNicholas Bellinger 3478889c8a68SNicholas Bellinger int 3479889c8a68SNicholas Bellinger iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, 3480889c8a68SNicholas Bellinger struct iscsi_text_rsp *hdr) 3481e48354ceSNicholas Bellinger { 3482889c8a68SNicholas Bellinger int text_length, padding; 3483e48354ceSNicholas Bellinger 3484e48354ceSNicholas Bellinger text_length = iscsit_build_sendtargets_response(cmd); 3485e48354ceSNicholas Bellinger if (text_length < 0) 3486e48354ceSNicholas Bellinger return text_length; 3487e48354ceSNicholas Bellinger 3488e48354ceSNicholas Bellinger hdr->opcode = ISCSI_OP_TEXT_RSP; 3489e48354ceSNicholas Bellinger hdr->flags |= ISCSI_FLAG_CMD_FINAL; 3490889c8a68SNicholas Bellinger padding = ((-text_length) & 3); 3491e48354ceSNicholas Bellinger hton24(hdr->dlength, text_length); 349266c7db68SChristoph Hellwig hdr->itt = cmd->init_task_tag; 3493e48354ceSNicholas Bellinger hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag); 3494e48354ceSNicholas Bellinger cmd->stat_sn = conn->stat_sn++; 3495e48354ceSNicholas Bellinger hdr->statsn = cpu_to_be32(cmd->stat_sn); 3496e48354ceSNicholas Bellinger 3497e48354ceSNicholas Bellinger iscsit_increment_maxcmdsn(cmd, conn->sess); 3498e48354ceSNicholas Bellinger hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); 3499e48354ceSNicholas Bellinger hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); 3500e48354ceSNicholas Bellinger 3501889c8a68SNicholas Bellinger pr_debug("Built Text Response: ITT: 0x%08x, StatSN: 0x%08x," 3502889c8a68SNicholas Bellinger " Length: %u, CID: %hu\n", cmd->init_task_tag, cmd->stat_sn, 3503889c8a68SNicholas Bellinger text_length, conn->cid); 3504e48354ceSNicholas Bellinger 3505889c8a68SNicholas Bellinger return text_length + padding; 3506889c8a68SNicholas Bellinger } 3507889c8a68SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_text_rsp); 3508889c8a68SNicholas Bellinger 3509889c8a68SNicholas Bellinger /* 3510889c8a68SNicholas Bellinger * FIXME: Add support for F_BIT and C_BIT when the length is longer than 3511889c8a68SNicholas Bellinger * MaxRecvDataSegmentLength. 3512889c8a68SNicholas Bellinger */ 3513889c8a68SNicholas Bellinger static int iscsit_send_text_rsp( 3514889c8a68SNicholas Bellinger struct iscsi_cmd *cmd, 3515889c8a68SNicholas Bellinger struct iscsi_conn *conn) 3516889c8a68SNicholas Bellinger { 3517889c8a68SNicholas Bellinger struct iscsi_text_rsp *hdr = (struct iscsi_text_rsp *)cmd->pdu; 3518889c8a68SNicholas Bellinger struct kvec *iov; 3519889c8a68SNicholas Bellinger u32 tx_size = 0; 3520889c8a68SNicholas Bellinger int text_length, iov_count = 0, rc; 3521889c8a68SNicholas Bellinger 3522889c8a68SNicholas Bellinger rc = iscsit_build_text_rsp(cmd, conn, hdr); 3523889c8a68SNicholas Bellinger if (rc < 0) 3524889c8a68SNicholas Bellinger return rc; 3525889c8a68SNicholas Bellinger 3526889c8a68SNicholas Bellinger text_length = rc; 3527889c8a68SNicholas Bellinger iov = &cmd->iov_misc[0]; 3528e48354ceSNicholas Bellinger iov[iov_count].iov_base = cmd->pdu; 3529e48354ceSNicholas Bellinger iov[iov_count++].iov_len = ISCSI_HDR_LEN; 3530e48354ceSNicholas Bellinger iov[iov_count].iov_base = cmd->buf_ptr; 3531889c8a68SNicholas Bellinger iov[iov_count++].iov_len = text_length; 3532e48354ceSNicholas Bellinger 3533889c8a68SNicholas Bellinger tx_size += (ISCSI_HDR_LEN + text_length); 3534e48354ceSNicholas Bellinger 3535e48354ceSNicholas Bellinger if (conn->conn_ops->HeaderDigest) { 3536e48354ceSNicholas Bellinger u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 3537e48354ceSNicholas Bellinger 353880690fdbSGeert Uytterhoeven iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr, 353980690fdbSGeert Uytterhoeven ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); 3540e48354ceSNicholas Bellinger 3541e48354ceSNicholas Bellinger iov[0].iov_len += ISCSI_CRC_LEN; 3542e48354ceSNicholas Bellinger tx_size += ISCSI_CRC_LEN; 3543e48354ceSNicholas Bellinger pr_debug("Attaching CRC32 HeaderDigest for" 3544e48354ceSNicholas Bellinger " Text Response PDU 0x%08x\n", *header_digest); 3545e48354ceSNicholas Bellinger } 3546e48354ceSNicholas Bellinger 3547e48354ceSNicholas Bellinger if (conn->conn_ops->DataDigest) { 3548e48354ceSNicholas Bellinger iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, 3549889c8a68SNicholas Bellinger cmd->buf_ptr, text_length, 3550e48354ceSNicholas Bellinger 0, NULL, (u8 *)&cmd->data_crc); 3551e48354ceSNicholas Bellinger 3552e48354ceSNicholas Bellinger iov[iov_count].iov_base = &cmd->data_crc; 3553e48354ceSNicholas Bellinger iov[iov_count++].iov_len = ISCSI_CRC_LEN; 3554e48354ceSNicholas Bellinger tx_size += ISCSI_CRC_LEN; 3555e48354ceSNicholas Bellinger 3556e48354ceSNicholas Bellinger pr_debug("Attaching DataDigest for %u bytes of text" 3557889c8a68SNicholas Bellinger " data, CRC 0x%08x\n", text_length, 3558e48354ceSNicholas Bellinger cmd->data_crc); 3559e48354ceSNicholas Bellinger } 3560e48354ceSNicholas Bellinger 3561e48354ceSNicholas Bellinger cmd->iov_misc_count = iov_count; 3562e48354ceSNicholas Bellinger cmd->tx_size = tx_size; 3563e48354ceSNicholas Bellinger 3564e48354ceSNicholas Bellinger return 0; 3565e48354ceSNicholas Bellinger } 3566e48354ceSNicholas Bellinger 35672ec5a8c1SNicholas Bellinger void 35682ec5a8c1SNicholas Bellinger iscsit_build_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn, 35692ec5a8c1SNicholas Bellinger struct iscsi_reject *hdr) 3570e48354ceSNicholas Bellinger { 3571e48354ceSNicholas Bellinger hdr->opcode = ISCSI_OP_REJECT; 3572ba159914SNicholas Bellinger hdr->reason = cmd->reject_reason; 3573e48354ceSNicholas Bellinger hdr->flags |= ISCSI_FLAG_CMD_FINAL; 3574e48354ceSNicholas Bellinger hton24(hdr->dlength, ISCSI_HDR_LEN); 357550e5c87dSChristoph Hellwig hdr->ffffffff = cpu_to_be32(0xffffffff); 3576e48354ceSNicholas Bellinger cmd->stat_sn = conn->stat_sn++; 3577e48354ceSNicholas Bellinger hdr->statsn = cpu_to_be32(cmd->stat_sn); 3578e48354ceSNicholas Bellinger hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); 3579e48354ceSNicholas Bellinger hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); 3580e48354ceSNicholas Bellinger 35812ec5a8c1SNicholas Bellinger } 35822ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_build_reject); 3583e48354ceSNicholas Bellinger 35842ec5a8c1SNicholas Bellinger static int iscsit_send_reject( 35852ec5a8c1SNicholas Bellinger struct iscsi_cmd *cmd, 35862ec5a8c1SNicholas Bellinger struct iscsi_conn *conn) 35872ec5a8c1SNicholas Bellinger { 3588bfbdb31dSNicholas Bellinger struct iscsi_reject *hdr = (struct iscsi_reject *)&cmd->pdu[0]; 35892ec5a8c1SNicholas Bellinger struct kvec *iov; 3590bfbdb31dSNicholas Bellinger u32 iov_count = 0, tx_size; 35912ec5a8c1SNicholas Bellinger 3592bfbdb31dSNicholas Bellinger iscsit_build_reject(cmd, conn, hdr); 35932ec5a8c1SNicholas Bellinger 35942ec5a8c1SNicholas Bellinger iov = &cmd->iov_misc[0]; 3595e48354ceSNicholas Bellinger iov[iov_count].iov_base = cmd->pdu; 3596e48354ceSNicholas Bellinger iov[iov_count++].iov_len = ISCSI_HDR_LEN; 3597e48354ceSNicholas Bellinger iov[iov_count].iov_base = cmd->buf_ptr; 3598e48354ceSNicholas Bellinger iov[iov_count++].iov_len = ISCSI_HDR_LEN; 3599e48354ceSNicholas Bellinger 3600e48354ceSNicholas Bellinger tx_size = (ISCSI_HDR_LEN + ISCSI_HDR_LEN); 3601e48354ceSNicholas Bellinger 3602e48354ceSNicholas Bellinger if (conn->conn_ops->HeaderDigest) { 3603e48354ceSNicholas Bellinger u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 3604e48354ceSNicholas Bellinger 360580690fdbSGeert Uytterhoeven iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, hdr, 360680690fdbSGeert Uytterhoeven ISCSI_HDR_LEN, 0, NULL, (u8 *)header_digest); 3607e48354ceSNicholas Bellinger 3608e48354ceSNicholas Bellinger iov[0].iov_len += ISCSI_CRC_LEN; 3609e48354ceSNicholas Bellinger tx_size += ISCSI_CRC_LEN; 3610e48354ceSNicholas Bellinger pr_debug("Attaching CRC32 HeaderDigest for" 3611e48354ceSNicholas Bellinger " REJECT PDU 0x%08x\n", *header_digest); 3612e48354ceSNicholas Bellinger } 3613e48354ceSNicholas Bellinger 3614e48354ceSNicholas Bellinger if (conn->conn_ops->DataDigest) { 361580690fdbSGeert Uytterhoeven iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, cmd->buf_ptr, 361680690fdbSGeert Uytterhoeven ISCSI_HDR_LEN, 0, NULL, (u8 *)&cmd->data_crc); 3617e48354ceSNicholas Bellinger 3618e48354ceSNicholas Bellinger iov[iov_count].iov_base = &cmd->data_crc; 3619e48354ceSNicholas Bellinger iov[iov_count++].iov_len = ISCSI_CRC_LEN; 3620e48354ceSNicholas Bellinger tx_size += ISCSI_CRC_LEN; 3621e48354ceSNicholas Bellinger pr_debug("Attaching CRC32 DataDigest for REJECT" 3622e48354ceSNicholas Bellinger " PDU 0x%08x\n", cmd->data_crc); 3623e48354ceSNicholas Bellinger } 3624e48354ceSNicholas Bellinger 3625e48354ceSNicholas Bellinger cmd->iov_misc_count = iov_count; 3626e48354ceSNicholas Bellinger cmd->tx_size = tx_size; 3627e48354ceSNicholas Bellinger 3628e48354ceSNicholas Bellinger pr_debug("Built Reject PDU StatSN: 0x%08x, Reason: 0x%02x," 3629e48354ceSNicholas Bellinger " CID: %hu\n", ntohl(hdr->statsn), hdr->reason, conn->cid); 3630e48354ceSNicholas Bellinger 3631e48354ceSNicholas Bellinger return 0; 3632e48354ceSNicholas Bellinger } 3633e48354ceSNicholas Bellinger 3634e48354ceSNicholas Bellinger void iscsit_thread_get_cpumask(struct iscsi_conn *conn) 3635e48354ceSNicholas Bellinger { 3636e48354ceSNicholas Bellinger struct iscsi_thread_set *ts = conn->thread_set; 3637e48354ceSNicholas Bellinger int ord, cpu; 3638e48354ceSNicholas Bellinger /* 3639e48354ceSNicholas Bellinger * thread_id is assigned from iscsit_global->ts_bitmap from 3640e48354ceSNicholas Bellinger * within iscsi_thread_set.c:iscsi_allocate_thread_sets() 3641e48354ceSNicholas Bellinger * 3642e48354ceSNicholas Bellinger * Here we use thread_id to determine which CPU that this 3643e48354ceSNicholas Bellinger * iSCSI connection's iscsi_thread_set will be scheduled to 3644e48354ceSNicholas Bellinger * execute upon. 3645e48354ceSNicholas Bellinger */ 3646e48354ceSNicholas Bellinger ord = ts->thread_id % cpumask_weight(cpu_online_mask); 3647e48354ceSNicholas Bellinger for_each_online_cpu(cpu) { 3648e48354ceSNicholas Bellinger if (ord-- == 0) { 3649e48354ceSNicholas Bellinger cpumask_set_cpu(cpu, conn->conn_cpumask); 3650e48354ceSNicholas Bellinger return; 3651e48354ceSNicholas Bellinger } 3652e48354ceSNicholas Bellinger } 3653e48354ceSNicholas Bellinger /* 3654e48354ceSNicholas Bellinger * This should never be reached.. 3655e48354ceSNicholas Bellinger */ 3656e48354ceSNicholas Bellinger dump_stack(); 3657e48354ceSNicholas Bellinger cpumask_setall(conn->conn_cpumask); 3658e48354ceSNicholas Bellinger } 3659e48354ceSNicholas Bellinger 3660e48354ceSNicholas Bellinger static inline void iscsit_thread_check_cpumask( 3661e48354ceSNicholas Bellinger struct iscsi_conn *conn, 3662e48354ceSNicholas Bellinger struct task_struct *p, 3663e48354ceSNicholas Bellinger int mode) 3664e48354ceSNicholas Bellinger { 3665e48354ceSNicholas Bellinger char buf[128]; 3666e48354ceSNicholas Bellinger /* 3667e48354ceSNicholas Bellinger * mode == 1 signals iscsi_target_tx_thread() usage. 3668e48354ceSNicholas Bellinger * mode == 0 signals iscsi_target_rx_thread() usage. 3669e48354ceSNicholas Bellinger */ 3670e48354ceSNicholas Bellinger if (mode == 1) { 3671e48354ceSNicholas Bellinger if (!conn->conn_tx_reset_cpumask) 3672e48354ceSNicholas Bellinger return; 3673e48354ceSNicholas Bellinger conn->conn_tx_reset_cpumask = 0; 3674e48354ceSNicholas Bellinger } else { 3675e48354ceSNicholas Bellinger if (!conn->conn_rx_reset_cpumask) 3676e48354ceSNicholas Bellinger return; 3677e48354ceSNicholas Bellinger conn->conn_rx_reset_cpumask = 0; 3678e48354ceSNicholas Bellinger } 3679e48354ceSNicholas Bellinger /* 3680e48354ceSNicholas Bellinger * Update the CPU mask for this single kthread so that 3681e48354ceSNicholas Bellinger * both TX and RX kthreads are scheduled to run on the 3682e48354ceSNicholas Bellinger * same CPU. 3683e48354ceSNicholas Bellinger */ 3684e48354ceSNicholas Bellinger memset(buf, 0, 128); 3685e48354ceSNicholas Bellinger cpumask_scnprintf(buf, 128, conn->conn_cpumask); 3686e48354ceSNicholas Bellinger set_cpus_allowed_ptr(p, conn->conn_cpumask); 3687e48354ceSNicholas Bellinger } 3688e48354ceSNicholas Bellinger 36892ec5a8c1SNicholas Bellinger static int 36902ec5a8c1SNicholas Bellinger iscsit_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) 3691e48354ceSNicholas Bellinger { 36922ec5a8c1SNicholas Bellinger int ret; 36932ec5a8c1SNicholas Bellinger 36942ec5a8c1SNicholas Bellinger switch (state) { 36952ec5a8c1SNicholas Bellinger case ISTATE_SEND_R2T: 36962ec5a8c1SNicholas Bellinger ret = iscsit_send_r2t(cmd, conn); 36972ec5a8c1SNicholas Bellinger if (ret < 0) 36982ec5a8c1SNicholas Bellinger goto err; 36992ec5a8c1SNicholas Bellinger break; 37002ec5a8c1SNicholas Bellinger case ISTATE_REMOVE: 37012ec5a8c1SNicholas Bellinger spin_lock_bh(&conn->cmd_lock); 37022ec5a8c1SNicholas Bellinger list_del(&cmd->i_conn_node); 37032ec5a8c1SNicholas Bellinger spin_unlock_bh(&conn->cmd_lock); 37042ec5a8c1SNicholas Bellinger 3705aafc9d15SNicholas Bellinger iscsit_free_cmd(cmd, false); 37062ec5a8c1SNicholas Bellinger break; 37072ec5a8c1SNicholas Bellinger case ISTATE_SEND_NOPIN_WANT_RESPONSE: 37082ec5a8c1SNicholas Bellinger iscsit_mod_nopin_response_timer(conn); 37092ec5a8c1SNicholas Bellinger ret = iscsit_send_unsolicited_nopin(cmd, conn, 1); 37102ec5a8c1SNicholas Bellinger if (ret < 0) 37112ec5a8c1SNicholas Bellinger goto err; 37122ec5a8c1SNicholas Bellinger break; 37132ec5a8c1SNicholas Bellinger case ISTATE_SEND_NOPIN_NO_RESPONSE: 37142ec5a8c1SNicholas Bellinger ret = iscsit_send_unsolicited_nopin(cmd, conn, 0); 37152ec5a8c1SNicholas Bellinger if (ret < 0) 37162ec5a8c1SNicholas Bellinger goto err; 37172ec5a8c1SNicholas Bellinger break; 37182ec5a8c1SNicholas Bellinger default: 37192ec5a8c1SNicholas Bellinger pr_err("Unknown Opcode: 0x%02x ITT:" 37202ec5a8c1SNicholas Bellinger " 0x%08x, i_state: %d on CID: %hu\n", 37212ec5a8c1SNicholas Bellinger cmd->iscsi_opcode, cmd->init_task_tag, state, 37222ec5a8c1SNicholas Bellinger conn->cid); 37232ec5a8c1SNicholas Bellinger goto err; 37242ec5a8c1SNicholas Bellinger } 37252ec5a8c1SNicholas Bellinger 37262ec5a8c1SNicholas Bellinger return 0; 37272ec5a8c1SNicholas Bellinger 37282ec5a8c1SNicholas Bellinger err: 37292ec5a8c1SNicholas Bellinger return -1; 37302ec5a8c1SNicholas Bellinger } 37312ec5a8c1SNicholas Bellinger 37322ec5a8c1SNicholas Bellinger static int 37332ec5a8c1SNicholas Bellinger iscsit_handle_immediate_queue(struct iscsi_conn *conn) 37342ec5a8c1SNicholas Bellinger { 37352ec5a8c1SNicholas Bellinger struct iscsit_transport *t = conn->conn_transport; 37366f3c0e69SAndy Grover struct iscsi_queue_req *qr; 37376f3c0e69SAndy Grover struct iscsi_cmd *cmd; 3738e48354ceSNicholas Bellinger u8 state; 37396f3c0e69SAndy Grover int ret; 3740e48354ceSNicholas Bellinger 3741c6037cc5SAndy Grover while ((qr = iscsit_get_cmd_from_immediate_queue(conn))) { 3742e48354ceSNicholas Bellinger atomic_set(&conn->check_immediate_queue, 0); 3743e48354ceSNicholas Bellinger cmd = qr->cmd; 3744e48354ceSNicholas Bellinger state = qr->state; 3745e48354ceSNicholas Bellinger kmem_cache_free(lio_qr_cache, qr); 3746e48354ceSNicholas Bellinger 37472ec5a8c1SNicholas Bellinger ret = t->iscsit_immediate_queue(conn, cmd, state); 37486f3c0e69SAndy Grover if (ret < 0) 37492ec5a8c1SNicholas Bellinger return ret; 3750e48354ceSNicholas Bellinger } 3751e48354ceSNicholas Bellinger 37526f3c0e69SAndy Grover return 0; 3753e48354ceSNicholas Bellinger } 37546f3c0e69SAndy Grover 37552ec5a8c1SNicholas Bellinger static int 37562ec5a8c1SNicholas Bellinger iscsit_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) 37576f3c0e69SAndy Grover { 37586f3c0e69SAndy Grover int ret; 3759e48354ceSNicholas Bellinger 3760e48354ceSNicholas Bellinger check_rsp_state: 3761e48354ceSNicholas Bellinger switch (state) { 3762e48354ceSNicholas Bellinger case ISTATE_SEND_DATAIN: 37632ec5a8c1SNicholas Bellinger ret = iscsit_send_datain(cmd, conn); 37646f3c0e69SAndy Grover if (ret < 0) 37656f3c0e69SAndy Grover goto err; 37666f3c0e69SAndy Grover else if (!ret) 37676f3c0e69SAndy Grover /* more drs */ 37686f3c0e69SAndy Grover goto check_rsp_state; 37696f3c0e69SAndy Grover else if (ret == 1) { 37706f3c0e69SAndy Grover /* all done */ 37716f3c0e69SAndy Grover spin_lock_bh(&cmd->istate_lock); 37726f3c0e69SAndy Grover cmd->i_state = ISTATE_SENT_STATUS; 3773e48354ceSNicholas Bellinger spin_unlock_bh(&cmd->istate_lock); 3774fd3a9025SNicholas Bellinger 3775fd3a9025SNicholas Bellinger if (atomic_read(&conn->check_immediate_queue)) 3776fd3a9025SNicholas Bellinger return 1; 3777fd3a9025SNicholas Bellinger 37782ec5a8c1SNicholas Bellinger return 0; 37796f3c0e69SAndy Grover } else if (ret == 2) { 37806f3c0e69SAndy Grover /* Still must send status, 37816f3c0e69SAndy Grover SCF_TRANSPORT_TASK_SENSE was set */ 37826f3c0e69SAndy Grover spin_lock_bh(&cmd->istate_lock); 37836f3c0e69SAndy Grover cmd->i_state = ISTATE_SEND_STATUS; 37846f3c0e69SAndy Grover spin_unlock_bh(&cmd->istate_lock); 37856f3c0e69SAndy Grover state = ISTATE_SEND_STATUS; 37866f3c0e69SAndy Grover goto check_rsp_state; 37876f3c0e69SAndy Grover } 37886f3c0e69SAndy Grover 3789e48354ceSNicholas Bellinger break; 3790e48354ceSNicholas Bellinger case ISTATE_SEND_STATUS: 3791e48354ceSNicholas Bellinger case ISTATE_SEND_STATUS_RECOVERY: 37922ec5a8c1SNicholas Bellinger ret = iscsit_send_response(cmd, conn); 3793e48354ceSNicholas Bellinger break; 3794e48354ceSNicholas Bellinger case ISTATE_SEND_LOGOUTRSP: 37952ec5a8c1SNicholas Bellinger ret = iscsit_send_logout(cmd, conn); 3796e48354ceSNicholas Bellinger break; 3797e48354ceSNicholas Bellinger case ISTATE_SEND_ASYNCMSG: 3798e48354ceSNicholas Bellinger ret = iscsit_send_conn_drop_async_message( 3799e48354ceSNicholas Bellinger cmd, conn); 3800e48354ceSNicholas Bellinger break; 3801e48354ceSNicholas Bellinger case ISTATE_SEND_NOPIN: 38022ec5a8c1SNicholas Bellinger ret = iscsit_send_nopin(cmd, conn); 3803e48354ceSNicholas Bellinger break; 3804e48354ceSNicholas Bellinger case ISTATE_SEND_REJECT: 3805e48354ceSNicholas Bellinger ret = iscsit_send_reject(cmd, conn); 3806e48354ceSNicholas Bellinger break; 3807e48354ceSNicholas Bellinger case ISTATE_SEND_TASKMGTRSP: 3808e48354ceSNicholas Bellinger ret = iscsit_send_task_mgt_rsp(cmd, conn); 3809e48354ceSNicholas Bellinger if (ret != 0) 3810e48354ceSNicholas Bellinger break; 3811e48354ceSNicholas Bellinger ret = iscsit_tmr_post_handler(cmd, conn); 3812e48354ceSNicholas Bellinger if (ret != 0) 3813e48354ceSNicholas Bellinger iscsit_fall_back_to_erl0(conn->sess); 3814e48354ceSNicholas Bellinger break; 3815e48354ceSNicholas Bellinger case ISTATE_SEND_TEXTRSP: 3816e48354ceSNicholas Bellinger ret = iscsit_send_text_rsp(cmd, conn); 3817e48354ceSNicholas Bellinger break; 3818e48354ceSNicholas Bellinger default: 3819e48354ceSNicholas Bellinger pr_err("Unknown Opcode: 0x%02x ITT:" 3820e48354ceSNicholas Bellinger " 0x%08x, i_state: %d on CID: %hu\n", 3821e48354ceSNicholas Bellinger cmd->iscsi_opcode, cmd->init_task_tag, 3822e48354ceSNicholas Bellinger state, conn->cid); 38236f3c0e69SAndy Grover goto err; 3824e48354ceSNicholas Bellinger } 3825c6037cc5SAndy Grover if (ret < 0) 38266f3c0e69SAndy Grover goto err; 3827e48354ceSNicholas Bellinger 38286f3c0e69SAndy Grover if (iscsit_send_tx_data(cmd, conn, 1) < 0) { 3829e48354ceSNicholas Bellinger iscsit_tx_thread_wait_for_tcp(conn); 3830e48354ceSNicholas Bellinger iscsit_unmap_iovec(cmd); 38316f3c0e69SAndy Grover goto err; 3832e48354ceSNicholas Bellinger } 3833e48354ceSNicholas Bellinger iscsit_unmap_iovec(cmd); 3834e48354ceSNicholas Bellinger 3835e48354ceSNicholas Bellinger switch (state) { 38366f3c0e69SAndy Grover case ISTATE_SEND_LOGOUTRSP: 38376f3c0e69SAndy Grover if (!iscsit_logout_post_handler(cmd, conn)) 38386f3c0e69SAndy Grover goto restart; 38396f3c0e69SAndy Grover /* fall through */ 3840e48354ceSNicholas Bellinger case ISTATE_SEND_STATUS: 3841e48354ceSNicholas Bellinger case ISTATE_SEND_ASYNCMSG: 3842e48354ceSNicholas Bellinger case ISTATE_SEND_NOPIN: 3843e48354ceSNicholas Bellinger case ISTATE_SEND_STATUS_RECOVERY: 3844e48354ceSNicholas Bellinger case ISTATE_SEND_TEXTRSP: 38456f3c0e69SAndy Grover case ISTATE_SEND_TASKMGTRSP: 3846ba159914SNicholas Bellinger case ISTATE_SEND_REJECT: 38476f3c0e69SAndy Grover spin_lock_bh(&cmd->istate_lock); 38486f3c0e69SAndy Grover cmd->i_state = ISTATE_SENT_STATUS; 38496f3c0e69SAndy Grover spin_unlock_bh(&cmd->istate_lock); 3850e48354ceSNicholas Bellinger break; 3851e48354ceSNicholas Bellinger default: 3852e48354ceSNicholas Bellinger pr_err("Unknown Opcode: 0x%02x ITT:" 3853e48354ceSNicholas Bellinger " 0x%08x, i_state: %d on CID: %hu\n", 3854e48354ceSNicholas Bellinger cmd->iscsi_opcode, cmd->init_task_tag, 3855e48354ceSNicholas Bellinger cmd->i_state, conn->cid); 38566f3c0e69SAndy Grover goto err; 3857e48354ceSNicholas Bellinger } 3858e48354ceSNicholas Bellinger 3859e48354ceSNicholas Bellinger if (atomic_read(&conn->check_immediate_queue)) 3860fd3a9025SNicholas Bellinger return 1; 38616f3c0e69SAndy Grover 38626f3c0e69SAndy Grover return 0; 38636f3c0e69SAndy Grover 38646f3c0e69SAndy Grover err: 38656f3c0e69SAndy Grover return -1; 38666f3c0e69SAndy Grover restart: 38676f3c0e69SAndy Grover return -EAGAIN; 38686f3c0e69SAndy Grover } 38696f3c0e69SAndy Grover 38702ec5a8c1SNicholas Bellinger static int iscsit_handle_response_queue(struct iscsi_conn *conn) 38712ec5a8c1SNicholas Bellinger { 38722ec5a8c1SNicholas Bellinger struct iscsit_transport *t = conn->conn_transport; 38732ec5a8c1SNicholas Bellinger struct iscsi_queue_req *qr; 38742ec5a8c1SNicholas Bellinger struct iscsi_cmd *cmd; 38752ec5a8c1SNicholas Bellinger u8 state; 38762ec5a8c1SNicholas Bellinger int ret; 38772ec5a8c1SNicholas Bellinger 38782ec5a8c1SNicholas Bellinger while ((qr = iscsit_get_cmd_from_response_queue(conn))) { 38792ec5a8c1SNicholas Bellinger cmd = qr->cmd; 38802ec5a8c1SNicholas Bellinger state = qr->state; 38812ec5a8c1SNicholas Bellinger kmem_cache_free(lio_qr_cache, qr); 38822ec5a8c1SNicholas Bellinger 38832ec5a8c1SNicholas Bellinger ret = t->iscsit_response_queue(conn, cmd, state); 38842ec5a8c1SNicholas Bellinger if (ret == 1 || ret < 0) 38852ec5a8c1SNicholas Bellinger return ret; 38862ec5a8c1SNicholas Bellinger } 38872ec5a8c1SNicholas Bellinger 38882ec5a8c1SNicholas Bellinger return 0; 38892ec5a8c1SNicholas Bellinger } 38902ec5a8c1SNicholas Bellinger 38916f3c0e69SAndy Grover int iscsi_target_tx_thread(void *arg) 38926f3c0e69SAndy Grover { 38936f3c0e69SAndy Grover int ret = 0; 38946f3c0e69SAndy Grover struct iscsi_conn *conn; 38956f3c0e69SAndy Grover struct iscsi_thread_set *ts = arg; 38966f3c0e69SAndy Grover /* 38976f3c0e69SAndy Grover * Allow ourselves to be interrupted by SIGINT so that a 38986f3c0e69SAndy Grover * connection recovery / failure event can be triggered externally. 38996f3c0e69SAndy Grover */ 39006f3c0e69SAndy Grover allow_signal(SIGINT); 39016f3c0e69SAndy Grover 39026f3c0e69SAndy Grover restart: 39036f3c0e69SAndy Grover conn = iscsi_tx_thread_pre_handler(ts); 39046f3c0e69SAndy Grover if (!conn) 39056f3c0e69SAndy Grover goto out; 39066f3c0e69SAndy Grover 39076f3c0e69SAndy Grover ret = 0; 39086f3c0e69SAndy Grover 39096f3c0e69SAndy Grover while (!kthread_should_stop()) { 39106f3c0e69SAndy Grover /* 39116f3c0e69SAndy Grover * Ensure that both TX and RX per connection kthreads 39126f3c0e69SAndy Grover * are scheduled to run on the same CPU. 39136f3c0e69SAndy Grover */ 39146f3c0e69SAndy Grover iscsit_thread_check_cpumask(conn, current, 1); 39156f3c0e69SAndy Grover 3916d5627acbSRoland Dreier wait_event_interruptible(conn->queues_wq, 3917d5627acbSRoland Dreier !iscsit_conn_all_queues_empty(conn) || 3918d5627acbSRoland Dreier ts->status == ISCSI_THREAD_SET_RESET); 39196f3c0e69SAndy Grover 39206f3c0e69SAndy Grover if ((ts->status == ISCSI_THREAD_SET_RESET) || 39216f3c0e69SAndy Grover signal_pending(current)) 39226f3c0e69SAndy Grover goto transport_err; 39236f3c0e69SAndy Grover 3924fd3a9025SNicholas Bellinger get_immediate: 39252ec5a8c1SNicholas Bellinger ret = iscsit_handle_immediate_queue(conn); 39266f3c0e69SAndy Grover if (ret < 0) 39276f3c0e69SAndy Grover goto transport_err; 39286f3c0e69SAndy Grover 39292ec5a8c1SNicholas Bellinger ret = iscsit_handle_response_queue(conn); 3930fd3a9025SNicholas Bellinger if (ret == 1) 3931fd3a9025SNicholas Bellinger goto get_immediate; 3932fd3a9025SNicholas Bellinger else if (ret == -EAGAIN) 39336f3c0e69SAndy Grover goto restart; 39346f3c0e69SAndy Grover else if (ret < 0) 39356f3c0e69SAndy Grover goto transport_err; 3936e48354ceSNicholas Bellinger } 3937e48354ceSNicholas Bellinger 3938e48354ceSNicholas Bellinger transport_err: 3939e48354ceSNicholas Bellinger iscsit_take_action_for_connection_exit(conn); 3940e48354ceSNicholas Bellinger goto restart; 3941e48354ceSNicholas Bellinger out: 3942e48354ceSNicholas Bellinger return 0; 3943e48354ceSNicholas Bellinger } 3944e48354ceSNicholas Bellinger 39453e1c81a9SNicholas Bellinger static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf) 39463e1c81a9SNicholas Bellinger { 39473e1c81a9SNicholas Bellinger struct iscsi_hdr *hdr = (struct iscsi_hdr *)buf; 39483e1c81a9SNicholas Bellinger struct iscsi_cmd *cmd; 39493e1c81a9SNicholas Bellinger int ret = 0; 39503e1c81a9SNicholas Bellinger 39513e1c81a9SNicholas Bellinger switch (hdr->opcode & ISCSI_OPCODE_MASK) { 39523e1c81a9SNicholas Bellinger case ISCSI_OP_SCSI_CMD: 39533e1c81a9SNicholas Bellinger cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); 39543e1c81a9SNicholas Bellinger if (!cmd) 3955ba159914SNicholas Bellinger goto reject; 39563e1c81a9SNicholas Bellinger 39573e1c81a9SNicholas Bellinger ret = iscsit_handle_scsi_cmd(conn, cmd, buf); 39583e1c81a9SNicholas Bellinger break; 39593e1c81a9SNicholas Bellinger case ISCSI_OP_SCSI_DATA_OUT: 39603e1c81a9SNicholas Bellinger ret = iscsit_handle_data_out(conn, buf); 39613e1c81a9SNicholas Bellinger break; 39623e1c81a9SNicholas Bellinger case ISCSI_OP_NOOP_OUT: 39633e1c81a9SNicholas Bellinger cmd = NULL; 39643e1c81a9SNicholas Bellinger if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) { 39653e1c81a9SNicholas Bellinger cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); 39663e1c81a9SNicholas Bellinger if (!cmd) 3967ba159914SNicholas Bellinger goto reject; 39683e1c81a9SNicholas Bellinger } 39693e1c81a9SNicholas Bellinger ret = iscsit_handle_nop_out(conn, cmd, buf); 39703e1c81a9SNicholas Bellinger break; 39713e1c81a9SNicholas Bellinger case ISCSI_OP_SCSI_TMFUNC: 39723e1c81a9SNicholas Bellinger cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); 39733e1c81a9SNicholas Bellinger if (!cmd) 3974ba159914SNicholas Bellinger goto reject; 39753e1c81a9SNicholas Bellinger 39763e1c81a9SNicholas Bellinger ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf); 39773e1c81a9SNicholas Bellinger break; 39783e1c81a9SNicholas Bellinger case ISCSI_OP_TEXT: 397964534aa7SNicholas Bellinger cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); 398064534aa7SNicholas Bellinger if (!cmd) 3981ba159914SNicholas Bellinger goto reject; 398264534aa7SNicholas Bellinger 398364534aa7SNicholas Bellinger ret = iscsit_handle_text_cmd(conn, cmd, buf); 39843e1c81a9SNicholas Bellinger break; 39853e1c81a9SNicholas Bellinger case ISCSI_OP_LOGOUT: 39863e1c81a9SNicholas Bellinger cmd = iscsit_allocate_cmd(conn, GFP_KERNEL); 39873e1c81a9SNicholas Bellinger if (!cmd) 3988ba159914SNicholas Bellinger goto reject; 39893e1c81a9SNicholas Bellinger 39903e1c81a9SNicholas Bellinger ret = iscsit_handle_logout_cmd(conn, cmd, buf); 39913e1c81a9SNicholas Bellinger if (ret > 0) 39923e1c81a9SNicholas Bellinger wait_for_completion_timeout(&conn->conn_logout_comp, 39933e1c81a9SNicholas Bellinger SECONDS_FOR_LOGOUT_COMP * HZ); 39943e1c81a9SNicholas Bellinger break; 39953e1c81a9SNicholas Bellinger case ISCSI_OP_SNACK: 39963e1c81a9SNicholas Bellinger ret = iscsit_handle_snack(conn, buf); 39973e1c81a9SNicholas Bellinger break; 39983e1c81a9SNicholas Bellinger default: 39993e1c81a9SNicholas Bellinger pr_err("Got unknown iSCSI OpCode: 0x%02x\n", hdr->opcode); 40003e1c81a9SNicholas Bellinger if (!conn->sess->sess_ops->ErrorRecoveryLevel) { 40013e1c81a9SNicholas Bellinger pr_err("Cannot recover from unknown" 40023e1c81a9SNicholas Bellinger " opcode while ERL=0, closing iSCSI connection.\n"); 40033e1c81a9SNicholas Bellinger return -1; 40043e1c81a9SNicholas Bellinger } 40053e1c81a9SNicholas Bellinger if (!conn->conn_ops->OFMarker) { 40063e1c81a9SNicholas Bellinger pr_err("Unable to recover from unknown" 40073e1c81a9SNicholas Bellinger " opcode while OFMarker=No, closing iSCSI" 40083e1c81a9SNicholas Bellinger " connection.\n"); 40093e1c81a9SNicholas Bellinger return -1; 40103e1c81a9SNicholas Bellinger } 40113e1c81a9SNicholas Bellinger if (iscsit_recover_from_unknown_opcode(conn) < 0) { 40123e1c81a9SNicholas Bellinger pr_err("Unable to recover from unknown" 40133e1c81a9SNicholas Bellinger " opcode, closing iSCSI connection.\n"); 40143e1c81a9SNicholas Bellinger return -1; 40153e1c81a9SNicholas Bellinger } 40163e1c81a9SNicholas Bellinger break; 40173e1c81a9SNicholas Bellinger } 40183e1c81a9SNicholas Bellinger 40193e1c81a9SNicholas Bellinger return ret; 4020ba159914SNicholas Bellinger reject: 4021ba159914SNicholas Bellinger return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); 40223e1c81a9SNicholas Bellinger } 40233e1c81a9SNicholas Bellinger 4024e48354ceSNicholas Bellinger int iscsi_target_rx_thread(void *arg) 4025e48354ceSNicholas Bellinger { 4026e48354ceSNicholas Bellinger int ret; 4027e48354ceSNicholas Bellinger u8 buffer[ISCSI_HDR_LEN], opcode; 4028e48354ceSNicholas Bellinger u32 checksum = 0, digest = 0; 4029e48354ceSNicholas Bellinger struct iscsi_conn *conn = NULL; 40308359cf43SJörn Engel struct iscsi_thread_set *ts = arg; 4031e48354ceSNicholas Bellinger struct kvec iov; 4032e48354ceSNicholas Bellinger /* 4033e48354ceSNicholas Bellinger * Allow ourselves to be interrupted by SIGINT so that a 4034e48354ceSNicholas Bellinger * connection recovery / failure event can be triggered externally. 4035e48354ceSNicholas Bellinger */ 4036e48354ceSNicholas Bellinger allow_signal(SIGINT); 4037e48354ceSNicholas Bellinger 4038e48354ceSNicholas Bellinger restart: 4039e48354ceSNicholas Bellinger conn = iscsi_rx_thread_pre_handler(ts); 4040e48354ceSNicholas Bellinger if (!conn) 4041e48354ceSNicholas Bellinger goto out; 4042e48354ceSNicholas Bellinger 40433e1c81a9SNicholas Bellinger if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) { 40443e1c81a9SNicholas Bellinger struct completion comp; 40453e1c81a9SNicholas Bellinger int rc; 40463e1c81a9SNicholas Bellinger 40473e1c81a9SNicholas Bellinger init_completion(&comp); 40483e1c81a9SNicholas Bellinger rc = wait_for_completion_interruptible(&comp); 40493e1c81a9SNicholas Bellinger if (rc < 0) 40503e1c81a9SNicholas Bellinger goto transport_err; 40513e1c81a9SNicholas Bellinger 40523e1c81a9SNicholas Bellinger goto out; 40533e1c81a9SNicholas Bellinger } 40543e1c81a9SNicholas Bellinger 4055e48354ceSNicholas Bellinger while (!kthread_should_stop()) { 4056e48354ceSNicholas Bellinger /* 4057e48354ceSNicholas Bellinger * Ensure that both TX and RX per connection kthreads 4058e48354ceSNicholas Bellinger * are scheduled to run on the same CPU. 4059e48354ceSNicholas Bellinger */ 4060e48354ceSNicholas Bellinger iscsit_thread_check_cpumask(conn, current, 0); 4061e48354ceSNicholas Bellinger 4062e48354ceSNicholas Bellinger memset(buffer, 0, ISCSI_HDR_LEN); 4063e48354ceSNicholas Bellinger memset(&iov, 0, sizeof(struct kvec)); 4064e48354ceSNicholas Bellinger 4065e48354ceSNicholas Bellinger iov.iov_base = buffer; 4066e48354ceSNicholas Bellinger iov.iov_len = ISCSI_HDR_LEN; 4067e48354ceSNicholas Bellinger 4068e48354ceSNicholas Bellinger ret = rx_data(conn, &iov, 1, ISCSI_HDR_LEN); 4069e48354ceSNicholas Bellinger if (ret != ISCSI_HDR_LEN) { 4070e48354ceSNicholas Bellinger iscsit_rx_thread_wait_for_tcp(conn); 4071e48354ceSNicholas Bellinger goto transport_err; 4072e48354ceSNicholas Bellinger } 4073e48354ceSNicholas Bellinger 4074e48354ceSNicholas Bellinger if (conn->conn_ops->HeaderDigest) { 4075e48354ceSNicholas Bellinger iov.iov_base = &digest; 4076e48354ceSNicholas Bellinger iov.iov_len = ISCSI_CRC_LEN; 4077e48354ceSNicholas Bellinger 4078e48354ceSNicholas Bellinger ret = rx_data(conn, &iov, 1, ISCSI_CRC_LEN); 4079e48354ceSNicholas Bellinger if (ret != ISCSI_CRC_LEN) { 4080e48354ceSNicholas Bellinger iscsit_rx_thread_wait_for_tcp(conn); 4081e48354ceSNicholas Bellinger goto transport_err; 4082e48354ceSNicholas Bellinger } 4083e48354ceSNicholas Bellinger 4084e48354ceSNicholas Bellinger iscsit_do_crypto_hash_buf(&conn->conn_rx_hash, 4085e48354ceSNicholas Bellinger buffer, ISCSI_HDR_LEN, 4086e48354ceSNicholas Bellinger 0, NULL, (u8 *)&checksum); 4087e48354ceSNicholas Bellinger 4088e48354ceSNicholas Bellinger if (digest != checksum) { 4089e48354ceSNicholas Bellinger pr_err("HeaderDigest CRC32C failed," 4090e48354ceSNicholas Bellinger " received 0x%08x, computed 0x%08x\n", 4091e48354ceSNicholas Bellinger digest, checksum); 4092e48354ceSNicholas Bellinger /* 4093e48354ceSNicholas Bellinger * Set the PDU to 0xff so it will intentionally 4094e48354ceSNicholas Bellinger * hit default in the switch below. 4095e48354ceSNicholas Bellinger */ 4096e48354ceSNicholas Bellinger memset(buffer, 0xff, ISCSI_HDR_LEN); 4097e48354ceSNicholas Bellinger spin_lock_bh(&conn->sess->session_stats_lock); 4098e48354ceSNicholas Bellinger conn->sess->conn_digest_errors++; 4099e48354ceSNicholas Bellinger spin_unlock_bh(&conn->sess->session_stats_lock); 4100e48354ceSNicholas Bellinger } else { 4101e48354ceSNicholas Bellinger pr_debug("Got HeaderDigest CRC32C" 4102e48354ceSNicholas Bellinger " 0x%08x\n", checksum); 4103e48354ceSNicholas Bellinger } 4104e48354ceSNicholas Bellinger } 4105e48354ceSNicholas Bellinger 4106e48354ceSNicholas Bellinger if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) 4107e48354ceSNicholas Bellinger goto transport_err; 4108e48354ceSNicholas Bellinger 4109e48354ceSNicholas Bellinger opcode = buffer[0] & ISCSI_OPCODE_MASK; 4110e48354ceSNicholas Bellinger 4111e48354ceSNicholas Bellinger if (conn->sess->sess_ops->SessionType && 4112e48354ceSNicholas Bellinger ((!(opcode & ISCSI_OP_TEXT)) || 4113e48354ceSNicholas Bellinger (!(opcode & ISCSI_OP_LOGOUT)))) { 4114e48354ceSNicholas Bellinger pr_err("Received illegal iSCSI Opcode: 0x%02x" 4115e48354ceSNicholas Bellinger " while in Discovery Session, rejecting.\n", opcode); 4116ba159914SNicholas Bellinger iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, 4117ba159914SNicholas Bellinger buffer); 4118e48354ceSNicholas Bellinger goto transport_err; 4119e48354ceSNicholas Bellinger } 4120e48354ceSNicholas Bellinger 41213e1c81a9SNicholas Bellinger ret = iscsi_target_rx_opcode(conn, buffer); 41223e1c81a9SNicholas Bellinger if (ret < 0) 4123e48354ceSNicholas Bellinger goto transport_err; 4124e48354ceSNicholas Bellinger } 4125e48354ceSNicholas Bellinger 4126e48354ceSNicholas Bellinger transport_err: 4127e48354ceSNicholas Bellinger if (!signal_pending(current)) 4128e48354ceSNicholas Bellinger atomic_set(&conn->transport_failed, 1); 4129e48354ceSNicholas Bellinger iscsit_take_action_for_connection_exit(conn); 4130e48354ceSNicholas Bellinger goto restart; 4131e48354ceSNicholas Bellinger out: 4132e48354ceSNicholas Bellinger return 0; 4133e48354ceSNicholas Bellinger } 4134e48354ceSNicholas Bellinger 4135e48354ceSNicholas Bellinger static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) 4136e48354ceSNicholas Bellinger { 4137e48354ceSNicholas Bellinger struct iscsi_cmd *cmd = NULL, *cmd_tmp = NULL; 4138e48354ceSNicholas Bellinger struct iscsi_session *sess = conn->sess; 4139e48354ceSNicholas Bellinger /* 4140e48354ceSNicholas Bellinger * We expect this function to only ever be called from either RX or TX 4141e48354ceSNicholas Bellinger * thread context via iscsit_close_connection() once the other context 4142e48354ceSNicholas Bellinger * has been reset -> returned sleeping pre-handler state. 4143e48354ceSNicholas Bellinger */ 4144e48354ceSNicholas Bellinger spin_lock_bh(&conn->cmd_lock); 41452fbb471eSAndy Grover list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) { 4146e48354ceSNicholas Bellinger 41472fbb471eSAndy Grover list_del(&cmd->i_conn_node); 4148e48354ceSNicholas Bellinger spin_unlock_bh(&conn->cmd_lock); 4149e48354ceSNicholas Bellinger 4150e48354ceSNicholas Bellinger iscsit_increment_maxcmdsn(cmd, sess); 4151e48354ceSNicholas Bellinger 4152aafc9d15SNicholas Bellinger iscsit_free_cmd(cmd, true); 4153e48354ceSNicholas Bellinger 4154e48354ceSNicholas Bellinger spin_lock_bh(&conn->cmd_lock); 4155e48354ceSNicholas Bellinger } 4156e48354ceSNicholas Bellinger spin_unlock_bh(&conn->cmd_lock); 4157e48354ceSNicholas Bellinger } 4158e48354ceSNicholas Bellinger 4159e48354ceSNicholas Bellinger static void iscsit_stop_timers_for_cmds( 4160e48354ceSNicholas Bellinger struct iscsi_conn *conn) 4161e48354ceSNicholas Bellinger { 4162e48354ceSNicholas Bellinger struct iscsi_cmd *cmd; 4163e48354ceSNicholas Bellinger 4164e48354ceSNicholas Bellinger spin_lock_bh(&conn->cmd_lock); 41652fbb471eSAndy Grover list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { 4166e48354ceSNicholas Bellinger if (cmd->data_direction == DMA_TO_DEVICE) 4167e48354ceSNicholas Bellinger iscsit_stop_dataout_timer(cmd); 4168e48354ceSNicholas Bellinger } 4169e48354ceSNicholas Bellinger spin_unlock_bh(&conn->cmd_lock); 4170e48354ceSNicholas Bellinger } 4171e48354ceSNicholas Bellinger 4172e48354ceSNicholas Bellinger int iscsit_close_connection( 4173e48354ceSNicholas Bellinger struct iscsi_conn *conn) 4174e48354ceSNicholas Bellinger { 4175e48354ceSNicholas Bellinger int conn_logout = (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT); 4176e48354ceSNicholas Bellinger struct iscsi_session *sess = conn->sess; 4177e48354ceSNicholas Bellinger 4178e48354ceSNicholas Bellinger pr_debug("Closing iSCSI connection CID %hu on SID:" 4179e48354ceSNicholas Bellinger " %u\n", conn->cid, sess->sid); 4180e48354ceSNicholas Bellinger /* 4181e48354ceSNicholas Bellinger * Always up conn_logout_comp just in case the RX Thread is sleeping 4182e48354ceSNicholas Bellinger * and the logout response never got sent because the connection 4183e48354ceSNicholas Bellinger * failed. 4184e48354ceSNicholas Bellinger */ 4185e48354ceSNicholas Bellinger complete(&conn->conn_logout_comp); 4186e48354ceSNicholas Bellinger 4187e48354ceSNicholas Bellinger iscsi_release_thread_set(conn); 4188e48354ceSNicholas Bellinger 4189e48354ceSNicholas Bellinger iscsit_stop_timers_for_cmds(conn); 4190e48354ceSNicholas Bellinger iscsit_stop_nopin_response_timer(conn); 4191e48354ceSNicholas Bellinger iscsit_stop_nopin_timer(conn); 4192e48354ceSNicholas Bellinger iscsit_free_queue_reqs_for_conn(conn); 4193e48354ceSNicholas Bellinger 4194e48354ceSNicholas Bellinger /* 4195e48354ceSNicholas Bellinger * During Connection recovery drop unacknowledged out of order 4196e48354ceSNicholas Bellinger * commands for this connection, and prepare the other commands 4197e48354ceSNicholas Bellinger * for realligence. 4198e48354ceSNicholas Bellinger * 4199e48354ceSNicholas Bellinger * During normal operation clear the out of order commands (but 4200e48354ceSNicholas Bellinger * do not free the struct iscsi_ooo_cmdsn's) and release all 4201e48354ceSNicholas Bellinger * struct iscsi_cmds. 4202e48354ceSNicholas Bellinger */ 4203e48354ceSNicholas Bellinger if (atomic_read(&conn->connection_recovery)) { 4204e48354ceSNicholas Bellinger iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(conn); 4205e48354ceSNicholas Bellinger iscsit_prepare_cmds_for_realligance(conn); 4206e48354ceSNicholas Bellinger } else { 4207e48354ceSNicholas Bellinger iscsit_clear_ooo_cmdsns_for_conn(conn); 4208e48354ceSNicholas Bellinger iscsit_release_commands_from_conn(conn); 4209e48354ceSNicholas Bellinger } 4210e48354ceSNicholas Bellinger 4211e48354ceSNicholas Bellinger /* 4212e48354ceSNicholas Bellinger * Handle decrementing session or connection usage count if 4213e48354ceSNicholas Bellinger * a logout response was not able to be sent because the 4214e48354ceSNicholas Bellinger * connection failed. Fall back to Session Recovery here. 4215e48354ceSNicholas Bellinger */ 4216e48354ceSNicholas Bellinger if (atomic_read(&conn->conn_logout_remove)) { 4217e48354ceSNicholas Bellinger if (conn->conn_logout_reason == ISCSI_LOGOUT_REASON_CLOSE_SESSION) { 4218e48354ceSNicholas Bellinger iscsit_dec_conn_usage_count(conn); 4219e48354ceSNicholas Bellinger iscsit_dec_session_usage_count(sess); 4220e48354ceSNicholas Bellinger } 4221e48354ceSNicholas Bellinger if (conn->conn_logout_reason == ISCSI_LOGOUT_REASON_CLOSE_CONNECTION) 4222e48354ceSNicholas Bellinger iscsit_dec_conn_usage_count(conn); 4223e48354ceSNicholas Bellinger 4224e48354ceSNicholas Bellinger atomic_set(&conn->conn_logout_remove, 0); 4225e48354ceSNicholas Bellinger atomic_set(&sess->session_reinstatement, 0); 4226e48354ceSNicholas Bellinger atomic_set(&sess->session_fall_back_to_erl0, 1); 4227e48354ceSNicholas Bellinger } 4228e48354ceSNicholas Bellinger 4229e48354ceSNicholas Bellinger spin_lock_bh(&sess->conn_lock); 4230e48354ceSNicholas Bellinger list_del(&conn->conn_list); 4231e48354ceSNicholas Bellinger 4232e48354ceSNicholas Bellinger /* 4233e48354ceSNicholas Bellinger * Attempt to let the Initiator know this connection failed by 4234e48354ceSNicholas Bellinger * sending an Connection Dropped Async Message on another 4235e48354ceSNicholas Bellinger * active connection. 4236e48354ceSNicholas Bellinger */ 4237e48354ceSNicholas Bellinger if (atomic_read(&conn->connection_recovery)) 4238e48354ceSNicholas Bellinger iscsit_build_conn_drop_async_message(conn); 4239e48354ceSNicholas Bellinger 4240e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4241e48354ceSNicholas Bellinger 4242e48354ceSNicholas Bellinger /* 4243e48354ceSNicholas Bellinger * If connection reinstatement is being performed on this connection, 4244e48354ceSNicholas Bellinger * up the connection reinstatement semaphore that is being blocked on 4245e48354ceSNicholas Bellinger * in iscsit_cause_connection_reinstatement(). 4246e48354ceSNicholas Bellinger */ 4247e48354ceSNicholas Bellinger spin_lock_bh(&conn->state_lock); 4248e48354ceSNicholas Bellinger if (atomic_read(&conn->sleep_on_conn_wait_comp)) { 4249e48354ceSNicholas Bellinger spin_unlock_bh(&conn->state_lock); 4250e48354ceSNicholas Bellinger complete(&conn->conn_wait_comp); 4251e48354ceSNicholas Bellinger wait_for_completion(&conn->conn_post_wait_comp); 4252e48354ceSNicholas Bellinger spin_lock_bh(&conn->state_lock); 4253e48354ceSNicholas Bellinger } 4254e48354ceSNicholas Bellinger 4255e48354ceSNicholas Bellinger /* 4256e48354ceSNicholas Bellinger * If connection reinstatement is being performed on this connection 4257e48354ceSNicholas Bellinger * by receiving a REMOVECONNFORRECOVERY logout request, up the 4258e48354ceSNicholas Bellinger * connection wait rcfr semaphore that is being blocked on 4259e48354ceSNicholas Bellinger * an iscsit_connection_reinstatement_rcfr(). 4260e48354ceSNicholas Bellinger */ 4261e48354ceSNicholas Bellinger if (atomic_read(&conn->connection_wait_rcfr)) { 4262e48354ceSNicholas Bellinger spin_unlock_bh(&conn->state_lock); 4263e48354ceSNicholas Bellinger complete(&conn->conn_wait_rcfr_comp); 4264e48354ceSNicholas Bellinger wait_for_completion(&conn->conn_post_wait_comp); 4265e48354ceSNicholas Bellinger spin_lock_bh(&conn->state_lock); 4266e48354ceSNicholas Bellinger } 4267e48354ceSNicholas Bellinger atomic_set(&conn->connection_reinstatement, 1); 4268e48354ceSNicholas Bellinger spin_unlock_bh(&conn->state_lock); 4269e48354ceSNicholas Bellinger 4270e48354ceSNicholas Bellinger /* 4271e48354ceSNicholas Bellinger * If any other processes are accessing this connection pointer we 4272e48354ceSNicholas Bellinger * must wait until they have completed. 4273e48354ceSNicholas Bellinger */ 4274e48354ceSNicholas Bellinger iscsit_check_conn_usage_count(conn); 4275e48354ceSNicholas Bellinger 4276e48354ceSNicholas Bellinger if (conn->conn_rx_hash.tfm) 4277e48354ceSNicholas Bellinger crypto_free_hash(conn->conn_rx_hash.tfm); 4278e48354ceSNicholas Bellinger if (conn->conn_tx_hash.tfm) 4279e48354ceSNicholas Bellinger crypto_free_hash(conn->conn_tx_hash.tfm); 4280e48354ceSNicholas Bellinger 4281e48354ceSNicholas Bellinger if (conn->conn_cpumask) 4282e48354ceSNicholas Bellinger free_cpumask_var(conn->conn_cpumask); 4283e48354ceSNicholas Bellinger 4284e48354ceSNicholas Bellinger kfree(conn->conn_ops); 4285e48354ceSNicholas Bellinger conn->conn_ops = NULL; 4286e48354ceSNicholas Bellinger 4287bf6932f4SAl Viro if (conn->sock) 4288e48354ceSNicholas Bellinger sock_release(conn->sock); 4289baa4d64bSNicholas Bellinger 4290baa4d64bSNicholas Bellinger if (conn->conn_transport->iscsit_free_conn) 4291baa4d64bSNicholas Bellinger conn->conn_transport->iscsit_free_conn(conn); 4292baa4d64bSNicholas Bellinger 4293baa4d64bSNicholas Bellinger iscsit_put_transport(conn->conn_transport); 4294baa4d64bSNicholas Bellinger 4295e48354ceSNicholas Bellinger conn->thread_set = NULL; 4296e48354ceSNicholas Bellinger 4297e48354ceSNicholas Bellinger pr_debug("Moving to TARG_CONN_STATE_FREE.\n"); 4298e48354ceSNicholas Bellinger conn->conn_state = TARG_CONN_STATE_FREE; 4299e48354ceSNicholas Bellinger kfree(conn); 4300e48354ceSNicholas Bellinger 4301e48354ceSNicholas Bellinger spin_lock_bh(&sess->conn_lock); 4302e48354ceSNicholas Bellinger atomic_dec(&sess->nconn); 4303e48354ceSNicholas Bellinger pr_debug("Decremented iSCSI connection count to %hu from node:" 4304e48354ceSNicholas Bellinger " %s\n", atomic_read(&sess->nconn), 4305e48354ceSNicholas Bellinger sess->sess_ops->InitiatorName); 4306e48354ceSNicholas Bellinger /* 4307e48354ceSNicholas Bellinger * Make sure that if one connection fails in an non ERL=2 iSCSI 4308e48354ceSNicholas Bellinger * Session that they all fail. 4309e48354ceSNicholas Bellinger */ 4310e48354ceSNicholas Bellinger if ((sess->sess_ops->ErrorRecoveryLevel != 2) && !conn_logout && 4311e48354ceSNicholas Bellinger !atomic_read(&sess->session_logout)) 4312e48354ceSNicholas Bellinger atomic_set(&sess->session_fall_back_to_erl0, 1); 4313e48354ceSNicholas Bellinger 4314e48354ceSNicholas Bellinger /* 4315e48354ceSNicholas Bellinger * If this was not the last connection in the session, and we are 4316e48354ceSNicholas Bellinger * performing session reinstatement or falling back to ERL=0, call 4317e48354ceSNicholas Bellinger * iscsit_stop_session() without sleeping to shutdown the other 4318e48354ceSNicholas Bellinger * active connections. 4319e48354ceSNicholas Bellinger */ 4320e48354ceSNicholas Bellinger if (atomic_read(&sess->nconn)) { 4321e48354ceSNicholas Bellinger if (!atomic_read(&sess->session_reinstatement) && 4322e48354ceSNicholas Bellinger !atomic_read(&sess->session_fall_back_to_erl0)) { 4323e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4324e48354ceSNicholas Bellinger return 0; 4325e48354ceSNicholas Bellinger } 4326e48354ceSNicholas Bellinger if (!atomic_read(&sess->session_stop_active)) { 4327e48354ceSNicholas Bellinger atomic_set(&sess->session_stop_active, 1); 4328e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4329e48354ceSNicholas Bellinger iscsit_stop_session(sess, 0, 0); 4330e48354ceSNicholas Bellinger return 0; 4331e48354ceSNicholas Bellinger } 4332e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4333e48354ceSNicholas Bellinger return 0; 4334e48354ceSNicholas Bellinger } 4335e48354ceSNicholas Bellinger 4336e48354ceSNicholas Bellinger /* 4337e48354ceSNicholas Bellinger * If this was the last connection in the session and one of the 4338e48354ceSNicholas Bellinger * following is occurring: 4339e48354ceSNicholas Bellinger * 4340e48354ceSNicholas Bellinger * Session Reinstatement is not being performed, and are falling back 4341e48354ceSNicholas Bellinger * to ERL=0 call iscsit_close_session(). 4342e48354ceSNicholas Bellinger * 4343e48354ceSNicholas Bellinger * Session Logout was requested. iscsit_close_session() will be called 4344e48354ceSNicholas Bellinger * elsewhere. 4345e48354ceSNicholas Bellinger * 4346e48354ceSNicholas Bellinger * Session Continuation is not being performed, start the Time2Retain 4347e48354ceSNicholas Bellinger * handler and check if sleep_on_sess_wait_sem is active. 4348e48354ceSNicholas Bellinger */ 4349e48354ceSNicholas Bellinger if (!atomic_read(&sess->session_reinstatement) && 4350e48354ceSNicholas Bellinger atomic_read(&sess->session_fall_back_to_erl0)) { 4351e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 435299367f01SNicholas Bellinger target_put_session(sess->se_sess); 4353e48354ceSNicholas Bellinger 4354e48354ceSNicholas Bellinger return 0; 4355e48354ceSNicholas Bellinger } else if (atomic_read(&sess->session_logout)) { 4356e48354ceSNicholas Bellinger pr_debug("Moving to TARG_SESS_STATE_FREE.\n"); 4357e48354ceSNicholas Bellinger sess->session_state = TARG_SESS_STATE_FREE; 4358e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4359e48354ceSNicholas Bellinger 4360e48354ceSNicholas Bellinger if (atomic_read(&sess->sleep_on_sess_wait_comp)) 4361e48354ceSNicholas Bellinger complete(&sess->session_wait_comp); 4362e48354ceSNicholas Bellinger 4363e48354ceSNicholas Bellinger return 0; 4364e48354ceSNicholas Bellinger } else { 4365e48354ceSNicholas Bellinger pr_debug("Moving to TARG_SESS_STATE_FAILED.\n"); 4366e48354ceSNicholas Bellinger sess->session_state = TARG_SESS_STATE_FAILED; 4367e48354ceSNicholas Bellinger 4368e48354ceSNicholas Bellinger if (!atomic_read(&sess->session_continuation)) { 4369e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4370e48354ceSNicholas Bellinger iscsit_start_time2retain_handler(sess); 4371e48354ceSNicholas Bellinger } else 4372e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4373e48354ceSNicholas Bellinger 4374e48354ceSNicholas Bellinger if (atomic_read(&sess->sleep_on_sess_wait_comp)) 4375e48354ceSNicholas Bellinger complete(&sess->session_wait_comp); 4376e48354ceSNicholas Bellinger 4377e48354ceSNicholas Bellinger return 0; 4378e48354ceSNicholas Bellinger } 4379e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4380e48354ceSNicholas Bellinger 4381e48354ceSNicholas Bellinger return 0; 4382e48354ceSNicholas Bellinger } 4383e48354ceSNicholas Bellinger 4384e48354ceSNicholas Bellinger int iscsit_close_session(struct iscsi_session *sess) 4385e48354ceSNicholas Bellinger { 4386e48354ceSNicholas Bellinger struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess); 4387e48354ceSNicholas Bellinger struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; 4388e48354ceSNicholas Bellinger 4389e48354ceSNicholas Bellinger if (atomic_read(&sess->nconn)) { 4390e48354ceSNicholas Bellinger pr_err("%d connection(s) still exist for iSCSI session" 4391e48354ceSNicholas Bellinger " to %s\n", atomic_read(&sess->nconn), 4392e48354ceSNicholas Bellinger sess->sess_ops->InitiatorName); 4393e48354ceSNicholas Bellinger BUG(); 4394e48354ceSNicholas Bellinger } 4395e48354ceSNicholas Bellinger 4396e48354ceSNicholas Bellinger spin_lock_bh(&se_tpg->session_lock); 4397e48354ceSNicholas Bellinger atomic_set(&sess->session_logout, 1); 4398e48354ceSNicholas Bellinger atomic_set(&sess->session_reinstatement, 1); 4399e48354ceSNicholas Bellinger iscsit_stop_time2retain_timer(sess); 4400e48354ceSNicholas Bellinger spin_unlock_bh(&se_tpg->session_lock); 4401e48354ceSNicholas Bellinger 4402e48354ceSNicholas Bellinger /* 4403e48354ceSNicholas Bellinger * transport_deregister_session_configfs() will clear the 4404e48354ceSNicholas Bellinger * struct se_node_acl->nacl_sess pointer now as a iscsi_np process context 4405e48354ceSNicholas Bellinger * can be setting it again with __transport_register_session() in 4406e48354ceSNicholas Bellinger * iscsi_post_login_handler() again after the iscsit_stop_session() 4407e48354ceSNicholas Bellinger * completes in iscsi_np context. 4408e48354ceSNicholas Bellinger */ 4409e48354ceSNicholas Bellinger transport_deregister_session_configfs(sess->se_sess); 4410e48354ceSNicholas Bellinger 4411e48354ceSNicholas Bellinger /* 4412e48354ceSNicholas Bellinger * If any other processes are accessing this session pointer we must 4413e48354ceSNicholas Bellinger * wait until they have completed. If we are in an interrupt (the 4414e48354ceSNicholas Bellinger * time2retain handler) and contain and active session usage count we 4415e48354ceSNicholas Bellinger * restart the timer and exit. 4416e48354ceSNicholas Bellinger */ 4417e48354ceSNicholas Bellinger if (!in_interrupt()) { 4418e48354ceSNicholas Bellinger if (iscsit_check_session_usage_count(sess) == 1) 4419e48354ceSNicholas Bellinger iscsit_stop_session(sess, 1, 1); 4420e48354ceSNicholas Bellinger } else { 4421e48354ceSNicholas Bellinger if (iscsit_check_session_usage_count(sess) == 2) { 4422e48354ceSNicholas Bellinger atomic_set(&sess->session_logout, 0); 4423e48354ceSNicholas Bellinger iscsit_start_time2retain_handler(sess); 4424e48354ceSNicholas Bellinger return 0; 4425e48354ceSNicholas Bellinger } 4426e48354ceSNicholas Bellinger } 4427e48354ceSNicholas Bellinger 4428e48354ceSNicholas Bellinger transport_deregister_session(sess->se_sess); 4429e48354ceSNicholas Bellinger 4430e48354ceSNicholas Bellinger if (sess->sess_ops->ErrorRecoveryLevel == 2) 4431e48354ceSNicholas Bellinger iscsit_free_connection_recovery_entires(sess); 4432e48354ceSNicholas Bellinger 4433e48354ceSNicholas Bellinger iscsit_free_all_ooo_cmdsns(sess); 4434e48354ceSNicholas Bellinger 4435e48354ceSNicholas Bellinger spin_lock_bh(&se_tpg->session_lock); 4436e48354ceSNicholas Bellinger pr_debug("Moving to TARG_SESS_STATE_FREE.\n"); 4437e48354ceSNicholas Bellinger sess->session_state = TARG_SESS_STATE_FREE; 4438e48354ceSNicholas Bellinger pr_debug("Released iSCSI session from node: %s\n", 4439e48354ceSNicholas Bellinger sess->sess_ops->InitiatorName); 4440e48354ceSNicholas Bellinger tpg->nsessions--; 4441e48354ceSNicholas Bellinger if (tpg->tpg_tiqn) 4442e48354ceSNicholas Bellinger tpg->tpg_tiqn->tiqn_nsessions--; 4443e48354ceSNicholas Bellinger 4444e48354ceSNicholas Bellinger pr_debug("Decremented number of active iSCSI Sessions on" 4445e48354ceSNicholas Bellinger " iSCSI TPG: %hu to %u\n", tpg->tpgt, tpg->nsessions); 4446e48354ceSNicholas Bellinger 4447e48354ceSNicholas Bellinger spin_lock(&sess_idr_lock); 4448e48354ceSNicholas Bellinger idr_remove(&sess_idr, sess->session_index); 4449e48354ceSNicholas Bellinger spin_unlock(&sess_idr_lock); 4450e48354ceSNicholas Bellinger 4451e48354ceSNicholas Bellinger kfree(sess->sess_ops); 4452e48354ceSNicholas Bellinger sess->sess_ops = NULL; 4453e48354ceSNicholas Bellinger spin_unlock_bh(&se_tpg->session_lock); 4454e48354ceSNicholas Bellinger 4455e48354ceSNicholas Bellinger kfree(sess); 4456e48354ceSNicholas Bellinger return 0; 4457e48354ceSNicholas Bellinger } 4458e48354ceSNicholas Bellinger 4459e48354ceSNicholas Bellinger static void iscsit_logout_post_handler_closesession( 4460e48354ceSNicholas Bellinger struct iscsi_conn *conn) 4461e48354ceSNicholas Bellinger { 4462e48354ceSNicholas Bellinger struct iscsi_session *sess = conn->sess; 4463e48354ceSNicholas Bellinger 4464e48354ceSNicholas Bellinger iscsi_set_thread_clear(conn, ISCSI_CLEAR_TX_THREAD); 4465e48354ceSNicholas Bellinger iscsi_set_thread_set_signal(conn, ISCSI_SIGNAL_TX_THREAD); 4466e48354ceSNicholas Bellinger 4467e48354ceSNicholas Bellinger atomic_set(&conn->conn_logout_remove, 0); 4468e48354ceSNicholas Bellinger complete(&conn->conn_logout_comp); 4469e48354ceSNicholas Bellinger 4470e48354ceSNicholas Bellinger iscsit_dec_conn_usage_count(conn); 4471e48354ceSNicholas Bellinger iscsit_stop_session(sess, 1, 1); 4472e48354ceSNicholas Bellinger iscsit_dec_session_usage_count(sess); 447399367f01SNicholas Bellinger target_put_session(sess->se_sess); 4474e48354ceSNicholas Bellinger } 4475e48354ceSNicholas Bellinger 4476e48354ceSNicholas Bellinger static void iscsit_logout_post_handler_samecid( 4477e48354ceSNicholas Bellinger struct iscsi_conn *conn) 4478e48354ceSNicholas Bellinger { 4479e48354ceSNicholas Bellinger iscsi_set_thread_clear(conn, ISCSI_CLEAR_TX_THREAD); 4480e48354ceSNicholas Bellinger iscsi_set_thread_set_signal(conn, ISCSI_SIGNAL_TX_THREAD); 4481e48354ceSNicholas Bellinger 4482e48354ceSNicholas Bellinger atomic_set(&conn->conn_logout_remove, 0); 4483e48354ceSNicholas Bellinger complete(&conn->conn_logout_comp); 4484e48354ceSNicholas Bellinger 4485e48354ceSNicholas Bellinger iscsit_cause_connection_reinstatement(conn, 1); 4486e48354ceSNicholas Bellinger iscsit_dec_conn_usage_count(conn); 4487e48354ceSNicholas Bellinger } 4488e48354ceSNicholas Bellinger 4489e48354ceSNicholas Bellinger static void iscsit_logout_post_handler_diffcid( 4490e48354ceSNicholas Bellinger struct iscsi_conn *conn, 4491e48354ceSNicholas Bellinger u16 cid) 4492e48354ceSNicholas Bellinger { 4493e48354ceSNicholas Bellinger struct iscsi_conn *l_conn; 4494e48354ceSNicholas Bellinger struct iscsi_session *sess = conn->sess; 4495e48354ceSNicholas Bellinger 4496e48354ceSNicholas Bellinger if (!sess) 4497e48354ceSNicholas Bellinger return; 4498e48354ceSNicholas Bellinger 4499e48354ceSNicholas Bellinger spin_lock_bh(&sess->conn_lock); 4500e48354ceSNicholas Bellinger list_for_each_entry(l_conn, &sess->sess_conn_list, conn_list) { 4501e48354ceSNicholas Bellinger if (l_conn->cid == cid) { 4502e48354ceSNicholas Bellinger iscsit_inc_conn_usage_count(l_conn); 4503e48354ceSNicholas Bellinger break; 4504e48354ceSNicholas Bellinger } 4505e48354ceSNicholas Bellinger } 4506e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4507e48354ceSNicholas Bellinger 4508e48354ceSNicholas Bellinger if (!l_conn) 4509e48354ceSNicholas Bellinger return; 4510e48354ceSNicholas Bellinger 4511e48354ceSNicholas Bellinger if (l_conn->sock) 4512e48354ceSNicholas Bellinger l_conn->sock->ops->shutdown(l_conn->sock, RCV_SHUTDOWN); 4513e48354ceSNicholas Bellinger 4514e48354ceSNicholas Bellinger spin_lock_bh(&l_conn->state_lock); 4515e48354ceSNicholas Bellinger pr_debug("Moving to TARG_CONN_STATE_IN_LOGOUT.\n"); 4516e48354ceSNicholas Bellinger l_conn->conn_state = TARG_CONN_STATE_IN_LOGOUT; 4517e48354ceSNicholas Bellinger spin_unlock_bh(&l_conn->state_lock); 4518e48354ceSNicholas Bellinger 4519e48354ceSNicholas Bellinger iscsit_cause_connection_reinstatement(l_conn, 1); 4520e48354ceSNicholas Bellinger iscsit_dec_conn_usage_count(l_conn); 4521e48354ceSNicholas Bellinger } 4522e48354ceSNicholas Bellinger 4523e48354ceSNicholas Bellinger /* 4524e48354ceSNicholas Bellinger * Return of 0 causes the TX thread to restart. 4525e48354ceSNicholas Bellinger */ 45262ec5a8c1SNicholas Bellinger int iscsit_logout_post_handler( 4527e48354ceSNicholas Bellinger struct iscsi_cmd *cmd, 4528e48354ceSNicholas Bellinger struct iscsi_conn *conn) 4529e48354ceSNicholas Bellinger { 4530e48354ceSNicholas Bellinger int ret = 0; 4531e48354ceSNicholas Bellinger 4532e48354ceSNicholas Bellinger switch (cmd->logout_reason) { 4533e48354ceSNicholas Bellinger case ISCSI_LOGOUT_REASON_CLOSE_SESSION: 4534e48354ceSNicholas Bellinger switch (cmd->logout_response) { 4535e48354ceSNicholas Bellinger case ISCSI_LOGOUT_SUCCESS: 4536e48354ceSNicholas Bellinger case ISCSI_LOGOUT_CLEANUP_FAILED: 4537e48354ceSNicholas Bellinger default: 4538e48354ceSNicholas Bellinger iscsit_logout_post_handler_closesession(conn); 4539e48354ceSNicholas Bellinger break; 4540e48354ceSNicholas Bellinger } 4541e48354ceSNicholas Bellinger ret = 0; 4542e48354ceSNicholas Bellinger break; 4543e48354ceSNicholas Bellinger case ISCSI_LOGOUT_REASON_CLOSE_CONNECTION: 4544e48354ceSNicholas Bellinger if (conn->cid == cmd->logout_cid) { 4545e48354ceSNicholas Bellinger switch (cmd->logout_response) { 4546e48354ceSNicholas Bellinger case ISCSI_LOGOUT_SUCCESS: 4547e48354ceSNicholas Bellinger case ISCSI_LOGOUT_CLEANUP_FAILED: 4548e48354ceSNicholas Bellinger default: 4549e48354ceSNicholas Bellinger iscsit_logout_post_handler_samecid(conn); 4550e48354ceSNicholas Bellinger break; 4551e48354ceSNicholas Bellinger } 4552e48354ceSNicholas Bellinger ret = 0; 4553e48354ceSNicholas Bellinger } else { 4554e48354ceSNicholas Bellinger switch (cmd->logout_response) { 4555e48354ceSNicholas Bellinger case ISCSI_LOGOUT_SUCCESS: 4556e48354ceSNicholas Bellinger iscsit_logout_post_handler_diffcid(conn, 4557e48354ceSNicholas Bellinger cmd->logout_cid); 4558e48354ceSNicholas Bellinger break; 4559e48354ceSNicholas Bellinger case ISCSI_LOGOUT_CID_NOT_FOUND: 4560e48354ceSNicholas Bellinger case ISCSI_LOGOUT_CLEANUP_FAILED: 4561e48354ceSNicholas Bellinger default: 4562e48354ceSNicholas Bellinger break; 4563e48354ceSNicholas Bellinger } 4564e48354ceSNicholas Bellinger ret = 1; 4565e48354ceSNicholas Bellinger } 4566e48354ceSNicholas Bellinger break; 4567e48354ceSNicholas Bellinger case ISCSI_LOGOUT_REASON_RECOVERY: 4568e48354ceSNicholas Bellinger switch (cmd->logout_response) { 4569e48354ceSNicholas Bellinger case ISCSI_LOGOUT_SUCCESS: 4570e48354ceSNicholas Bellinger case ISCSI_LOGOUT_CID_NOT_FOUND: 4571e48354ceSNicholas Bellinger case ISCSI_LOGOUT_RECOVERY_UNSUPPORTED: 4572e48354ceSNicholas Bellinger case ISCSI_LOGOUT_CLEANUP_FAILED: 4573e48354ceSNicholas Bellinger default: 4574e48354ceSNicholas Bellinger break; 4575e48354ceSNicholas Bellinger } 4576e48354ceSNicholas Bellinger ret = 1; 4577e48354ceSNicholas Bellinger break; 4578e48354ceSNicholas Bellinger default: 4579e48354ceSNicholas Bellinger break; 4580e48354ceSNicholas Bellinger 4581e48354ceSNicholas Bellinger } 4582e48354ceSNicholas Bellinger return ret; 4583e48354ceSNicholas Bellinger } 45842ec5a8c1SNicholas Bellinger EXPORT_SYMBOL(iscsit_logout_post_handler); 4585e48354ceSNicholas Bellinger 4586e48354ceSNicholas Bellinger void iscsit_fail_session(struct iscsi_session *sess) 4587e48354ceSNicholas Bellinger { 4588e48354ceSNicholas Bellinger struct iscsi_conn *conn; 4589e48354ceSNicholas Bellinger 4590e48354ceSNicholas Bellinger spin_lock_bh(&sess->conn_lock); 4591e48354ceSNicholas Bellinger list_for_each_entry(conn, &sess->sess_conn_list, conn_list) { 4592e48354ceSNicholas Bellinger pr_debug("Moving to TARG_CONN_STATE_CLEANUP_WAIT.\n"); 4593e48354ceSNicholas Bellinger conn->conn_state = TARG_CONN_STATE_CLEANUP_WAIT; 4594e48354ceSNicholas Bellinger } 4595e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4596e48354ceSNicholas Bellinger 4597e48354ceSNicholas Bellinger pr_debug("Moving to TARG_SESS_STATE_FAILED.\n"); 4598e48354ceSNicholas Bellinger sess->session_state = TARG_SESS_STATE_FAILED; 4599e48354ceSNicholas Bellinger } 4600e48354ceSNicholas Bellinger 4601e48354ceSNicholas Bellinger int iscsit_free_session(struct iscsi_session *sess) 4602e48354ceSNicholas Bellinger { 4603e48354ceSNicholas Bellinger u16 conn_count = atomic_read(&sess->nconn); 4604e48354ceSNicholas Bellinger struct iscsi_conn *conn, *conn_tmp = NULL; 4605e48354ceSNicholas Bellinger int is_last; 4606e48354ceSNicholas Bellinger 4607e48354ceSNicholas Bellinger spin_lock_bh(&sess->conn_lock); 4608e48354ceSNicholas Bellinger atomic_set(&sess->sleep_on_sess_wait_comp, 1); 4609e48354ceSNicholas Bellinger 4610e48354ceSNicholas Bellinger list_for_each_entry_safe(conn, conn_tmp, &sess->sess_conn_list, 4611e48354ceSNicholas Bellinger conn_list) { 4612e48354ceSNicholas Bellinger if (conn_count == 0) 4613e48354ceSNicholas Bellinger break; 4614e48354ceSNicholas Bellinger 4615e48354ceSNicholas Bellinger if (list_is_last(&conn->conn_list, &sess->sess_conn_list)) { 4616e48354ceSNicholas Bellinger is_last = 1; 4617e48354ceSNicholas Bellinger } else { 4618e48354ceSNicholas Bellinger iscsit_inc_conn_usage_count(conn_tmp); 4619e48354ceSNicholas Bellinger is_last = 0; 4620e48354ceSNicholas Bellinger } 4621e48354ceSNicholas Bellinger iscsit_inc_conn_usage_count(conn); 4622e48354ceSNicholas Bellinger 4623e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4624e48354ceSNicholas Bellinger iscsit_cause_connection_reinstatement(conn, 1); 4625e48354ceSNicholas Bellinger spin_lock_bh(&sess->conn_lock); 4626e48354ceSNicholas Bellinger 4627e48354ceSNicholas Bellinger iscsit_dec_conn_usage_count(conn); 4628e48354ceSNicholas Bellinger if (is_last == 0) 4629e48354ceSNicholas Bellinger iscsit_dec_conn_usage_count(conn_tmp); 4630e48354ceSNicholas Bellinger 4631e48354ceSNicholas Bellinger conn_count--; 4632e48354ceSNicholas Bellinger } 4633e48354ceSNicholas Bellinger 4634e48354ceSNicholas Bellinger if (atomic_read(&sess->nconn)) { 4635e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4636e48354ceSNicholas Bellinger wait_for_completion(&sess->session_wait_comp); 4637e48354ceSNicholas Bellinger } else 4638e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4639e48354ceSNicholas Bellinger 464099367f01SNicholas Bellinger target_put_session(sess->se_sess); 4641e48354ceSNicholas Bellinger return 0; 4642e48354ceSNicholas Bellinger } 4643e48354ceSNicholas Bellinger 4644e48354ceSNicholas Bellinger void iscsit_stop_session( 4645e48354ceSNicholas Bellinger struct iscsi_session *sess, 4646e48354ceSNicholas Bellinger int session_sleep, 4647e48354ceSNicholas Bellinger int connection_sleep) 4648e48354ceSNicholas Bellinger { 4649e48354ceSNicholas Bellinger u16 conn_count = atomic_read(&sess->nconn); 4650e48354ceSNicholas Bellinger struct iscsi_conn *conn, *conn_tmp = NULL; 4651e48354ceSNicholas Bellinger int is_last; 4652e48354ceSNicholas Bellinger 4653e48354ceSNicholas Bellinger spin_lock_bh(&sess->conn_lock); 4654e48354ceSNicholas Bellinger if (session_sleep) 4655e48354ceSNicholas Bellinger atomic_set(&sess->sleep_on_sess_wait_comp, 1); 4656e48354ceSNicholas Bellinger 4657e48354ceSNicholas Bellinger if (connection_sleep) { 4658e48354ceSNicholas Bellinger list_for_each_entry_safe(conn, conn_tmp, &sess->sess_conn_list, 4659e48354ceSNicholas Bellinger conn_list) { 4660e48354ceSNicholas Bellinger if (conn_count == 0) 4661e48354ceSNicholas Bellinger break; 4662e48354ceSNicholas Bellinger 4663e48354ceSNicholas Bellinger if (list_is_last(&conn->conn_list, &sess->sess_conn_list)) { 4664e48354ceSNicholas Bellinger is_last = 1; 4665e48354ceSNicholas Bellinger } else { 4666e48354ceSNicholas Bellinger iscsit_inc_conn_usage_count(conn_tmp); 4667e48354ceSNicholas Bellinger is_last = 0; 4668e48354ceSNicholas Bellinger } 4669e48354ceSNicholas Bellinger iscsit_inc_conn_usage_count(conn); 4670e48354ceSNicholas Bellinger 4671e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4672e48354ceSNicholas Bellinger iscsit_cause_connection_reinstatement(conn, 1); 4673e48354ceSNicholas Bellinger spin_lock_bh(&sess->conn_lock); 4674e48354ceSNicholas Bellinger 4675e48354ceSNicholas Bellinger iscsit_dec_conn_usage_count(conn); 4676e48354ceSNicholas Bellinger if (is_last == 0) 4677e48354ceSNicholas Bellinger iscsit_dec_conn_usage_count(conn_tmp); 4678e48354ceSNicholas Bellinger conn_count--; 4679e48354ceSNicholas Bellinger } 4680e48354ceSNicholas Bellinger } else { 4681e48354ceSNicholas Bellinger list_for_each_entry(conn, &sess->sess_conn_list, conn_list) 4682e48354ceSNicholas Bellinger iscsit_cause_connection_reinstatement(conn, 0); 4683e48354ceSNicholas Bellinger } 4684e48354ceSNicholas Bellinger 4685e48354ceSNicholas Bellinger if (session_sleep && atomic_read(&sess->nconn)) { 4686e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4687e48354ceSNicholas Bellinger wait_for_completion(&sess->session_wait_comp); 4688e48354ceSNicholas Bellinger } else 4689e48354ceSNicholas Bellinger spin_unlock_bh(&sess->conn_lock); 4690e48354ceSNicholas Bellinger } 4691e48354ceSNicholas Bellinger 4692e48354ceSNicholas Bellinger int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force) 4693e48354ceSNicholas Bellinger { 4694e48354ceSNicholas Bellinger struct iscsi_session *sess; 4695e48354ceSNicholas Bellinger struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; 4696e48354ceSNicholas Bellinger struct se_session *se_sess, *se_sess_tmp; 4697e48354ceSNicholas Bellinger int session_count = 0; 4698e48354ceSNicholas Bellinger 4699e48354ceSNicholas Bellinger spin_lock_bh(&se_tpg->session_lock); 4700e48354ceSNicholas Bellinger if (tpg->nsessions && !force) { 4701e48354ceSNicholas Bellinger spin_unlock_bh(&se_tpg->session_lock); 4702e48354ceSNicholas Bellinger return -1; 4703e48354ceSNicholas Bellinger } 4704e48354ceSNicholas Bellinger 4705e48354ceSNicholas Bellinger list_for_each_entry_safe(se_sess, se_sess_tmp, &se_tpg->tpg_sess_list, 4706e48354ceSNicholas Bellinger sess_list) { 4707e48354ceSNicholas Bellinger sess = (struct iscsi_session *)se_sess->fabric_sess_ptr; 4708e48354ceSNicholas Bellinger 4709e48354ceSNicholas Bellinger spin_lock(&sess->conn_lock); 4710e48354ceSNicholas Bellinger if (atomic_read(&sess->session_fall_back_to_erl0) || 4711e48354ceSNicholas Bellinger atomic_read(&sess->session_logout) || 4712e48354ceSNicholas Bellinger (sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)) { 4713e48354ceSNicholas Bellinger spin_unlock(&sess->conn_lock); 4714e48354ceSNicholas Bellinger continue; 4715e48354ceSNicholas Bellinger } 4716e48354ceSNicholas Bellinger atomic_set(&sess->session_reinstatement, 1); 4717e48354ceSNicholas Bellinger spin_unlock(&sess->conn_lock); 4718e48354ceSNicholas Bellinger spin_unlock_bh(&se_tpg->session_lock); 4719e48354ceSNicholas Bellinger 4720e48354ceSNicholas Bellinger iscsit_free_session(sess); 4721e48354ceSNicholas Bellinger spin_lock_bh(&se_tpg->session_lock); 4722e48354ceSNicholas Bellinger 4723e48354ceSNicholas Bellinger session_count++; 4724e48354ceSNicholas Bellinger } 4725e48354ceSNicholas Bellinger spin_unlock_bh(&se_tpg->session_lock); 4726e48354ceSNicholas Bellinger 4727e48354ceSNicholas Bellinger pr_debug("Released %d iSCSI Session(s) from Target Portal" 4728e48354ceSNicholas Bellinger " Group: %hu\n", session_count, tpg->tpgt); 4729e48354ceSNicholas Bellinger return 0; 4730e48354ceSNicholas Bellinger } 4731e48354ceSNicholas Bellinger 4732e48354ceSNicholas Bellinger MODULE_DESCRIPTION("iSCSI-Target Driver for mainline target infrastructure"); 4733e48354ceSNicholas Bellinger MODULE_VERSION("4.1.x"); 4734e48354ceSNicholas Bellinger MODULE_AUTHOR("nab@Linux-iSCSI.org"); 4735e48354ceSNicholas Bellinger MODULE_LICENSE("GPL"); 4736e48354ceSNicholas Bellinger 4737e48354ceSNicholas Bellinger module_init(iscsi_target_init_module); 4738e48354ceSNicholas Bellinger module_exit(iscsi_target_cleanup_module); 4739