1 /******************************************************************************* 2 * This file contains the main functions related to Initiator Node Attributes. 3 * 4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC. 5 * 6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2. 7 * 8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 ******************************************************************************/ 20 21 #include <target/target_core_base.h> 22 #include <target/target_core_transport.h> 23 24 #include "iscsi_target_core.h" 25 #include "iscsi_target_device.h" 26 #include "iscsi_target_tpg.h" 27 #include "iscsi_target_util.h" 28 #include "iscsi_target_nodeattrib.h" 29 30 static inline char *iscsit_na_get_initiatorname( 31 struct iscsi_node_acl *nacl) 32 { 33 struct se_node_acl *se_nacl = &nacl->se_node_acl; 34 35 return &se_nacl->initiatorname[0]; 36 } 37 38 void iscsit_set_default_node_attribues( 39 struct iscsi_node_acl *acl) 40 { 41 struct iscsi_node_attrib *a = &acl->node_attrib; 42 43 a->dataout_timeout = NA_DATAOUT_TIMEOUT; 44 a->dataout_timeout_retries = NA_DATAOUT_TIMEOUT_RETRIES; 45 a->nopin_timeout = NA_NOPIN_TIMEOUT; 46 a->nopin_response_timeout = NA_NOPIN_RESPONSE_TIMEOUT; 47 a->random_datain_pdu_offsets = NA_RANDOM_DATAIN_PDU_OFFSETS; 48 a->random_datain_seq_offsets = NA_RANDOM_DATAIN_SEQ_OFFSETS; 49 a->random_r2t_offsets = NA_RANDOM_R2T_OFFSETS; 50 a->default_erl = NA_DEFAULT_ERL; 51 } 52 53 extern int iscsit_na_dataout_timeout( 54 struct iscsi_node_acl *acl, 55 u32 dataout_timeout) 56 { 57 struct iscsi_node_attrib *a = &acl->node_attrib; 58 59 if (dataout_timeout > NA_DATAOUT_TIMEOUT_MAX) { 60 pr_err("Requested DataOut Timeout %u larger than" 61 " maximum %u\n", dataout_timeout, 62 NA_DATAOUT_TIMEOUT_MAX); 63 return -EINVAL; 64 } else if (dataout_timeout < NA_DATAOUT_TIMEOUT_MIX) { 65 pr_err("Requested DataOut Timeout %u smaller than" 66 " minimum %u\n", dataout_timeout, 67 NA_DATAOUT_TIMEOUT_MIX); 68 return -EINVAL; 69 } 70 71 a->dataout_timeout = dataout_timeout; 72 pr_debug("Set DataOut Timeout to %u for Initiator Node" 73 " %s\n", a->dataout_timeout, iscsit_na_get_initiatorname(acl)); 74 75 return 0; 76 } 77 78 extern int iscsit_na_dataout_timeout_retries( 79 struct iscsi_node_acl *acl, 80 u32 dataout_timeout_retries) 81 { 82 struct iscsi_node_attrib *a = &acl->node_attrib; 83 84 if (dataout_timeout_retries > NA_DATAOUT_TIMEOUT_RETRIES_MAX) { 85 pr_err("Requested DataOut Timeout Retries %u larger" 86 " than maximum %u", dataout_timeout_retries, 87 NA_DATAOUT_TIMEOUT_RETRIES_MAX); 88 return -EINVAL; 89 } else if (dataout_timeout_retries < NA_DATAOUT_TIMEOUT_RETRIES_MIN) { 90 pr_err("Requested DataOut Timeout Retries %u smaller" 91 " than minimum %u", dataout_timeout_retries, 92 NA_DATAOUT_TIMEOUT_RETRIES_MIN); 93 return -EINVAL; 94 } 95 96 a->dataout_timeout_retries = dataout_timeout_retries; 97 pr_debug("Set DataOut Timeout Retries to %u for" 98 " Initiator Node %s\n", a->dataout_timeout_retries, 99 iscsit_na_get_initiatorname(acl)); 100 101 return 0; 102 } 103 104 extern int iscsit_na_nopin_timeout( 105 struct iscsi_node_acl *acl, 106 u32 nopin_timeout) 107 { 108 struct iscsi_node_attrib *a = &acl->node_attrib; 109 struct iscsi_session *sess; 110 struct iscsi_conn *conn; 111 struct se_node_acl *se_nacl = &a->nacl->se_node_acl; 112 struct se_session *se_sess; 113 u32 orig_nopin_timeout = a->nopin_timeout; 114 115 if (nopin_timeout > NA_NOPIN_TIMEOUT_MAX) { 116 pr_err("Requested NopIn Timeout %u larger than maximum" 117 " %u\n", nopin_timeout, NA_NOPIN_TIMEOUT_MAX); 118 return -EINVAL; 119 } else if ((nopin_timeout < NA_NOPIN_TIMEOUT_MIN) && 120 (nopin_timeout != 0)) { 121 pr_err("Requested NopIn Timeout %u smaller than" 122 " minimum %u and not 0\n", nopin_timeout, 123 NA_NOPIN_TIMEOUT_MIN); 124 return -EINVAL; 125 } 126 127 a->nopin_timeout = nopin_timeout; 128 pr_debug("Set NopIn Timeout to %u for Initiator" 129 " Node %s\n", a->nopin_timeout, 130 iscsit_na_get_initiatorname(acl)); 131 /* 132 * Reenable disabled nopin_timeout timer for all iSCSI connections. 133 */ 134 if (!orig_nopin_timeout) { 135 spin_lock_bh(&se_nacl->nacl_sess_lock); 136 se_sess = se_nacl->nacl_sess; 137 if (se_sess) { 138 sess = (struct iscsi_session *)se_sess->fabric_sess_ptr; 139 140 spin_lock(&sess->conn_lock); 141 list_for_each_entry(conn, &sess->sess_conn_list, 142 conn_list) { 143 if (conn->conn_state != 144 TARG_CONN_STATE_LOGGED_IN) 145 continue; 146 147 spin_lock(&conn->nopin_timer_lock); 148 __iscsit_start_nopin_timer(conn); 149 spin_unlock(&conn->nopin_timer_lock); 150 } 151 spin_unlock(&sess->conn_lock); 152 } 153 spin_unlock_bh(&se_nacl->nacl_sess_lock); 154 } 155 156 return 0; 157 } 158 159 extern int iscsit_na_nopin_response_timeout( 160 struct iscsi_node_acl *acl, 161 u32 nopin_response_timeout) 162 { 163 struct iscsi_node_attrib *a = &acl->node_attrib; 164 165 if (nopin_response_timeout > NA_NOPIN_RESPONSE_TIMEOUT_MAX) { 166 pr_err("Requested NopIn Response Timeout %u larger" 167 " than maximum %u\n", nopin_response_timeout, 168 NA_NOPIN_RESPONSE_TIMEOUT_MAX); 169 return -EINVAL; 170 } else if (nopin_response_timeout < NA_NOPIN_RESPONSE_TIMEOUT_MIN) { 171 pr_err("Requested NopIn Response Timeout %u smaller" 172 " than minimum %u\n", nopin_response_timeout, 173 NA_NOPIN_RESPONSE_TIMEOUT_MIN); 174 return -EINVAL; 175 } 176 177 a->nopin_response_timeout = nopin_response_timeout; 178 pr_debug("Set NopIn Response Timeout to %u for" 179 " Initiator Node %s\n", a->nopin_timeout, 180 iscsit_na_get_initiatorname(acl)); 181 182 return 0; 183 } 184 185 extern int iscsit_na_random_datain_pdu_offsets( 186 struct iscsi_node_acl *acl, 187 u32 random_datain_pdu_offsets) 188 { 189 struct iscsi_node_attrib *a = &acl->node_attrib; 190 191 if (random_datain_pdu_offsets != 0 && random_datain_pdu_offsets != 1) { 192 pr_err("Requested Random DataIN PDU Offsets: %u not" 193 " 0 or 1\n", random_datain_pdu_offsets); 194 return -EINVAL; 195 } 196 197 a->random_datain_pdu_offsets = random_datain_pdu_offsets; 198 pr_debug("Set Random DataIN PDU Offsets to %u for" 199 " Initiator Node %s\n", a->random_datain_pdu_offsets, 200 iscsit_na_get_initiatorname(acl)); 201 202 return 0; 203 } 204 205 extern int iscsit_na_random_datain_seq_offsets( 206 struct iscsi_node_acl *acl, 207 u32 random_datain_seq_offsets) 208 { 209 struct iscsi_node_attrib *a = &acl->node_attrib; 210 211 if (random_datain_seq_offsets != 0 && random_datain_seq_offsets != 1) { 212 pr_err("Requested Random DataIN Sequence Offsets: %u" 213 " not 0 or 1\n", random_datain_seq_offsets); 214 return -EINVAL; 215 } 216 217 a->random_datain_seq_offsets = random_datain_seq_offsets; 218 pr_debug("Set Random DataIN Sequence Offsets to %u for" 219 " Initiator Node %s\n", a->random_datain_seq_offsets, 220 iscsit_na_get_initiatorname(acl)); 221 222 return 0; 223 } 224 225 extern int iscsit_na_random_r2t_offsets( 226 struct iscsi_node_acl *acl, 227 u32 random_r2t_offsets) 228 { 229 struct iscsi_node_attrib *a = &acl->node_attrib; 230 231 if (random_r2t_offsets != 0 && random_r2t_offsets != 1) { 232 pr_err("Requested Random R2T Offsets: %u not" 233 " 0 or 1\n", random_r2t_offsets); 234 return -EINVAL; 235 } 236 237 a->random_r2t_offsets = random_r2t_offsets; 238 pr_debug("Set Random R2T Offsets to %u for" 239 " Initiator Node %s\n", a->random_r2t_offsets, 240 iscsit_na_get_initiatorname(acl)); 241 242 return 0; 243 } 244 245 extern int iscsit_na_default_erl( 246 struct iscsi_node_acl *acl, 247 u32 default_erl) 248 { 249 struct iscsi_node_attrib *a = &acl->node_attrib; 250 251 if (default_erl != 0 && default_erl != 1 && default_erl != 2) { 252 pr_err("Requested default ERL: %u not 0, 1, or 2\n", 253 default_erl); 254 return -EINVAL; 255 } 256 257 a->default_erl = default_erl; 258 pr_debug("Set use ERL0 flag to %u for Initiator" 259 " Node %s\n", a->default_erl, 260 iscsit_na_get_initiatorname(acl)); 261 262 return 0; 263 } 264