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