18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/******************************************************************************* 38c2ecf20Sopenharmony_ci * This file contains the main functions related to Initiator Node Attributes. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * (c) Copyright 2007-2013 Datera, Inc. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Author: Nicholas A. Bellinger <nab@linux-iscsi.org> 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci ******************************************************************************/ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <target/target_core_base.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <target/iscsi/iscsi_target_core.h> 148c2ecf20Sopenharmony_ci#include "iscsi_target_device.h" 158c2ecf20Sopenharmony_ci#include "iscsi_target_tpg.h" 168c2ecf20Sopenharmony_ci#include "iscsi_target_util.h" 178c2ecf20Sopenharmony_ci#include "iscsi_target_nodeattrib.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistatic inline char *iscsit_na_get_initiatorname( 208c2ecf20Sopenharmony_ci struct iscsi_node_acl *nacl) 218c2ecf20Sopenharmony_ci{ 228c2ecf20Sopenharmony_ci struct se_node_acl *se_nacl = &nacl->se_node_acl; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci return &se_nacl->initiatorname[0]; 258c2ecf20Sopenharmony_ci} 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_civoid iscsit_set_default_node_attribues( 288c2ecf20Sopenharmony_ci struct iscsi_node_acl *acl, 298c2ecf20Sopenharmony_ci struct iscsi_portal_group *tpg) 308c2ecf20Sopenharmony_ci{ 318c2ecf20Sopenharmony_ci struct iscsi_node_attrib *a = &acl->node_attrib; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci a->dataout_timeout = NA_DATAOUT_TIMEOUT; 348c2ecf20Sopenharmony_ci a->dataout_timeout_retries = NA_DATAOUT_TIMEOUT_RETRIES; 358c2ecf20Sopenharmony_ci a->nopin_timeout = NA_NOPIN_TIMEOUT; 368c2ecf20Sopenharmony_ci a->nopin_response_timeout = NA_NOPIN_RESPONSE_TIMEOUT; 378c2ecf20Sopenharmony_ci a->random_datain_pdu_offsets = NA_RANDOM_DATAIN_PDU_OFFSETS; 388c2ecf20Sopenharmony_ci a->random_datain_seq_offsets = NA_RANDOM_DATAIN_SEQ_OFFSETS; 398c2ecf20Sopenharmony_ci a->random_r2t_offsets = NA_RANDOM_R2T_OFFSETS; 408c2ecf20Sopenharmony_ci a->default_erl = tpg->tpg_attrib.default_erl; 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ciint iscsit_na_dataout_timeout( 448c2ecf20Sopenharmony_ci struct iscsi_node_acl *acl, 458c2ecf20Sopenharmony_ci u32 dataout_timeout) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci struct iscsi_node_attrib *a = &acl->node_attrib; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci if (dataout_timeout > NA_DATAOUT_TIMEOUT_MAX) { 508c2ecf20Sopenharmony_ci pr_err("Requested DataOut Timeout %u larger than" 518c2ecf20Sopenharmony_ci " maximum %u\n", dataout_timeout, 528c2ecf20Sopenharmony_ci NA_DATAOUT_TIMEOUT_MAX); 538c2ecf20Sopenharmony_ci return -EINVAL; 548c2ecf20Sopenharmony_ci } else if (dataout_timeout < NA_DATAOUT_TIMEOUT_MIX) { 558c2ecf20Sopenharmony_ci pr_err("Requested DataOut Timeout %u smaller than" 568c2ecf20Sopenharmony_ci " minimum %u\n", dataout_timeout, 578c2ecf20Sopenharmony_ci NA_DATAOUT_TIMEOUT_MIX); 588c2ecf20Sopenharmony_ci return -EINVAL; 598c2ecf20Sopenharmony_ci } 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci a->dataout_timeout = dataout_timeout; 628c2ecf20Sopenharmony_ci pr_debug("Set DataOut Timeout to %u for Initiator Node" 638c2ecf20Sopenharmony_ci " %s\n", a->dataout_timeout, iscsit_na_get_initiatorname(acl)); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci return 0; 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ciint iscsit_na_dataout_timeout_retries( 698c2ecf20Sopenharmony_ci struct iscsi_node_acl *acl, 708c2ecf20Sopenharmony_ci u32 dataout_timeout_retries) 718c2ecf20Sopenharmony_ci{ 728c2ecf20Sopenharmony_ci struct iscsi_node_attrib *a = &acl->node_attrib; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci if (dataout_timeout_retries > NA_DATAOUT_TIMEOUT_RETRIES_MAX) { 758c2ecf20Sopenharmony_ci pr_err("Requested DataOut Timeout Retries %u larger" 768c2ecf20Sopenharmony_ci " than maximum %u", dataout_timeout_retries, 778c2ecf20Sopenharmony_ci NA_DATAOUT_TIMEOUT_RETRIES_MAX); 788c2ecf20Sopenharmony_ci return -EINVAL; 798c2ecf20Sopenharmony_ci } else if (dataout_timeout_retries < NA_DATAOUT_TIMEOUT_RETRIES_MIN) { 808c2ecf20Sopenharmony_ci pr_err("Requested DataOut Timeout Retries %u smaller" 818c2ecf20Sopenharmony_ci " than minimum %u", dataout_timeout_retries, 828c2ecf20Sopenharmony_ci NA_DATAOUT_TIMEOUT_RETRIES_MIN); 838c2ecf20Sopenharmony_ci return -EINVAL; 848c2ecf20Sopenharmony_ci } 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci a->dataout_timeout_retries = dataout_timeout_retries; 878c2ecf20Sopenharmony_ci pr_debug("Set DataOut Timeout Retries to %u for" 888c2ecf20Sopenharmony_ci " Initiator Node %s\n", a->dataout_timeout_retries, 898c2ecf20Sopenharmony_ci iscsit_na_get_initiatorname(acl)); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci return 0; 928c2ecf20Sopenharmony_ci} 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ciint iscsit_na_nopin_timeout( 958c2ecf20Sopenharmony_ci struct iscsi_node_acl *acl, 968c2ecf20Sopenharmony_ci u32 nopin_timeout) 978c2ecf20Sopenharmony_ci{ 988c2ecf20Sopenharmony_ci struct iscsi_node_attrib *a = &acl->node_attrib; 998c2ecf20Sopenharmony_ci struct iscsi_session *sess; 1008c2ecf20Sopenharmony_ci struct iscsi_conn *conn; 1018c2ecf20Sopenharmony_ci struct se_node_acl *se_nacl = &a->nacl->se_node_acl; 1028c2ecf20Sopenharmony_ci struct se_session *se_sess; 1038c2ecf20Sopenharmony_ci u32 orig_nopin_timeout = a->nopin_timeout; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci if (nopin_timeout > NA_NOPIN_TIMEOUT_MAX) { 1068c2ecf20Sopenharmony_ci pr_err("Requested NopIn Timeout %u larger than maximum" 1078c2ecf20Sopenharmony_ci " %u\n", nopin_timeout, NA_NOPIN_TIMEOUT_MAX); 1088c2ecf20Sopenharmony_ci return -EINVAL; 1098c2ecf20Sopenharmony_ci } else if ((nopin_timeout < NA_NOPIN_TIMEOUT_MIN) && 1108c2ecf20Sopenharmony_ci (nopin_timeout != 0)) { 1118c2ecf20Sopenharmony_ci pr_err("Requested NopIn Timeout %u smaller than" 1128c2ecf20Sopenharmony_ci " minimum %u and not 0\n", nopin_timeout, 1138c2ecf20Sopenharmony_ci NA_NOPIN_TIMEOUT_MIN); 1148c2ecf20Sopenharmony_ci return -EINVAL; 1158c2ecf20Sopenharmony_ci } 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci a->nopin_timeout = nopin_timeout; 1188c2ecf20Sopenharmony_ci pr_debug("Set NopIn Timeout to %u for Initiator" 1198c2ecf20Sopenharmony_ci " Node %s\n", a->nopin_timeout, 1208c2ecf20Sopenharmony_ci iscsit_na_get_initiatorname(acl)); 1218c2ecf20Sopenharmony_ci /* 1228c2ecf20Sopenharmony_ci * Reenable disabled nopin_timeout timer for all iSCSI connections. 1238c2ecf20Sopenharmony_ci */ 1248c2ecf20Sopenharmony_ci if (!orig_nopin_timeout) { 1258c2ecf20Sopenharmony_ci spin_lock_bh(&se_nacl->nacl_sess_lock); 1268c2ecf20Sopenharmony_ci se_sess = se_nacl->nacl_sess; 1278c2ecf20Sopenharmony_ci if (se_sess) { 1288c2ecf20Sopenharmony_ci sess = se_sess->fabric_sess_ptr; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci spin_lock(&sess->conn_lock); 1318c2ecf20Sopenharmony_ci list_for_each_entry(conn, &sess->sess_conn_list, 1328c2ecf20Sopenharmony_ci conn_list) { 1338c2ecf20Sopenharmony_ci if (conn->conn_state != 1348c2ecf20Sopenharmony_ci TARG_CONN_STATE_LOGGED_IN) 1358c2ecf20Sopenharmony_ci continue; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci spin_lock(&conn->nopin_timer_lock); 1388c2ecf20Sopenharmony_ci __iscsit_start_nopin_timer(conn); 1398c2ecf20Sopenharmony_ci spin_unlock(&conn->nopin_timer_lock); 1408c2ecf20Sopenharmony_ci } 1418c2ecf20Sopenharmony_ci spin_unlock(&sess->conn_lock); 1428c2ecf20Sopenharmony_ci } 1438c2ecf20Sopenharmony_ci spin_unlock_bh(&se_nacl->nacl_sess_lock); 1448c2ecf20Sopenharmony_ci } 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci return 0; 1478c2ecf20Sopenharmony_ci} 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ciint iscsit_na_nopin_response_timeout( 1508c2ecf20Sopenharmony_ci struct iscsi_node_acl *acl, 1518c2ecf20Sopenharmony_ci u32 nopin_response_timeout) 1528c2ecf20Sopenharmony_ci{ 1538c2ecf20Sopenharmony_ci struct iscsi_node_attrib *a = &acl->node_attrib; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci if (nopin_response_timeout > NA_NOPIN_RESPONSE_TIMEOUT_MAX) { 1568c2ecf20Sopenharmony_ci pr_err("Requested NopIn Response Timeout %u larger" 1578c2ecf20Sopenharmony_ci " than maximum %u\n", nopin_response_timeout, 1588c2ecf20Sopenharmony_ci NA_NOPIN_RESPONSE_TIMEOUT_MAX); 1598c2ecf20Sopenharmony_ci return -EINVAL; 1608c2ecf20Sopenharmony_ci } else if (nopin_response_timeout < NA_NOPIN_RESPONSE_TIMEOUT_MIN) { 1618c2ecf20Sopenharmony_ci pr_err("Requested NopIn Response Timeout %u smaller" 1628c2ecf20Sopenharmony_ci " than minimum %u\n", nopin_response_timeout, 1638c2ecf20Sopenharmony_ci NA_NOPIN_RESPONSE_TIMEOUT_MIN); 1648c2ecf20Sopenharmony_ci return -EINVAL; 1658c2ecf20Sopenharmony_ci } 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci a->nopin_response_timeout = nopin_response_timeout; 1688c2ecf20Sopenharmony_ci pr_debug("Set NopIn Response Timeout to %u for" 1698c2ecf20Sopenharmony_ci " Initiator Node %s\n", a->nopin_timeout, 1708c2ecf20Sopenharmony_ci iscsit_na_get_initiatorname(acl)); 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci return 0; 1738c2ecf20Sopenharmony_ci} 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ciint iscsit_na_random_datain_pdu_offsets( 1768c2ecf20Sopenharmony_ci struct iscsi_node_acl *acl, 1778c2ecf20Sopenharmony_ci u32 random_datain_pdu_offsets) 1788c2ecf20Sopenharmony_ci{ 1798c2ecf20Sopenharmony_ci struct iscsi_node_attrib *a = &acl->node_attrib; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci if (random_datain_pdu_offsets != 0 && random_datain_pdu_offsets != 1) { 1828c2ecf20Sopenharmony_ci pr_err("Requested Random DataIN PDU Offsets: %u not" 1838c2ecf20Sopenharmony_ci " 0 or 1\n", random_datain_pdu_offsets); 1848c2ecf20Sopenharmony_ci return -EINVAL; 1858c2ecf20Sopenharmony_ci } 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci a->random_datain_pdu_offsets = random_datain_pdu_offsets; 1888c2ecf20Sopenharmony_ci pr_debug("Set Random DataIN PDU Offsets to %u for" 1898c2ecf20Sopenharmony_ci " Initiator Node %s\n", a->random_datain_pdu_offsets, 1908c2ecf20Sopenharmony_ci iscsit_na_get_initiatorname(acl)); 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci return 0; 1938c2ecf20Sopenharmony_ci} 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ciint iscsit_na_random_datain_seq_offsets( 1968c2ecf20Sopenharmony_ci struct iscsi_node_acl *acl, 1978c2ecf20Sopenharmony_ci u32 random_datain_seq_offsets) 1988c2ecf20Sopenharmony_ci{ 1998c2ecf20Sopenharmony_ci struct iscsi_node_attrib *a = &acl->node_attrib; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci if (random_datain_seq_offsets != 0 && random_datain_seq_offsets != 1) { 2028c2ecf20Sopenharmony_ci pr_err("Requested Random DataIN Sequence Offsets: %u" 2038c2ecf20Sopenharmony_ci " not 0 or 1\n", random_datain_seq_offsets); 2048c2ecf20Sopenharmony_ci return -EINVAL; 2058c2ecf20Sopenharmony_ci } 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci a->random_datain_seq_offsets = random_datain_seq_offsets; 2088c2ecf20Sopenharmony_ci pr_debug("Set Random DataIN Sequence Offsets to %u for" 2098c2ecf20Sopenharmony_ci " Initiator Node %s\n", a->random_datain_seq_offsets, 2108c2ecf20Sopenharmony_ci iscsit_na_get_initiatorname(acl)); 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci return 0; 2138c2ecf20Sopenharmony_ci} 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ciint iscsit_na_random_r2t_offsets( 2168c2ecf20Sopenharmony_ci struct iscsi_node_acl *acl, 2178c2ecf20Sopenharmony_ci u32 random_r2t_offsets) 2188c2ecf20Sopenharmony_ci{ 2198c2ecf20Sopenharmony_ci struct iscsi_node_attrib *a = &acl->node_attrib; 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci if (random_r2t_offsets != 0 && random_r2t_offsets != 1) { 2228c2ecf20Sopenharmony_ci pr_err("Requested Random R2T Offsets: %u not" 2238c2ecf20Sopenharmony_ci " 0 or 1\n", random_r2t_offsets); 2248c2ecf20Sopenharmony_ci return -EINVAL; 2258c2ecf20Sopenharmony_ci } 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci a->random_r2t_offsets = random_r2t_offsets; 2288c2ecf20Sopenharmony_ci pr_debug("Set Random R2T Offsets to %u for" 2298c2ecf20Sopenharmony_ci " Initiator Node %s\n", a->random_r2t_offsets, 2308c2ecf20Sopenharmony_ci iscsit_na_get_initiatorname(acl)); 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci return 0; 2338c2ecf20Sopenharmony_ci} 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ciint iscsit_na_default_erl( 2368c2ecf20Sopenharmony_ci struct iscsi_node_acl *acl, 2378c2ecf20Sopenharmony_ci u32 default_erl) 2388c2ecf20Sopenharmony_ci{ 2398c2ecf20Sopenharmony_ci struct iscsi_node_attrib *a = &acl->node_attrib; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci if (default_erl != 0 && default_erl != 1 && default_erl != 2) { 2428c2ecf20Sopenharmony_ci pr_err("Requested default ERL: %u not 0, 1, or 2\n", 2438c2ecf20Sopenharmony_ci default_erl); 2448c2ecf20Sopenharmony_ci return -EINVAL; 2458c2ecf20Sopenharmony_ci } 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci a->default_erl = default_erl; 2488c2ecf20Sopenharmony_ci pr_debug("Set use ERL0 flag to %u for Initiator" 2498c2ecf20Sopenharmony_ci " Node %s\n", a->default_erl, 2508c2ecf20Sopenharmony_ci iscsit_na_get_initiatorname(acl)); 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci return 0; 2538c2ecf20Sopenharmony_ci} 254