Merge remote-tracking branch 'regulator/fix/da9063' into regulator-linus
[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 {
38         struct iscsi_node_attrib *a = &acl->node_attrib;
39
40         a->dataout_timeout = NA_DATAOUT_TIMEOUT;
41         a->dataout_timeout_retries = NA_DATAOUT_TIMEOUT_RETRIES;
42         a->nopin_timeout = NA_NOPIN_TIMEOUT;
43         a->nopin_response_timeout = NA_NOPIN_RESPONSE_TIMEOUT;
44         a->random_datain_pdu_offsets = NA_RANDOM_DATAIN_PDU_OFFSETS;
45         a->random_datain_seq_offsets = NA_RANDOM_DATAIN_SEQ_OFFSETS;
46         a->random_r2t_offsets = NA_RANDOM_R2T_OFFSETS;
47         a->default_erl = NA_DEFAULT_ERL;
48 }
49
50 int iscsit_na_dataout_timeout(
51         struct iscsi_node_acl *acl,
52         u32 dataout_timeout)
53 {
54         struct iscsi_node_attrib *a = &acl->node_attrib;
55
56         if (dataout_timeout > NA_DATAOUT_TIMEOUT_MAX) {
57                 pr_err("Requested DataOut Timeout %u larger than"
58                         " maximum %u\n", dataout_timeout,
59                         NA_DATAOUT_TIMEOUT_MAX);
60                 return -EINVAL;
61         } else if (dataout_timeout < NA_DATAOUT_TIMEOUT_MIX) {
62                 pr_err("Requested DataOut Timeout %u smaller than"
63                         " minimum %u\n", dataout_timeout,
64                         NA_DATAOUT_TIMEOUT_MIX);
65                 return -EINVAL;
66         }
67
68         a->dataout_timeout = dataout_timeout;
69         pr_debug("Set DataOut Timeout to %u for Initiator Node"
70                 " %s\n", a->dataout_timeout, iscsit_na_get_initiatorname(acl));
71
72         return 0;
73 }
74
75 int iscsit_na_dataout_timeout_retries(
76         struct iscsi_node_acl *acl,
77         u32 dataout_timeout_retries)
78 {
79         struct iscsi_node_attrib *a = &acl->node_attrib;
80
81         if (dataout_timeout_retries > NA_DATAOUT_TIMEOUT_RETRIES_MAX) {
82                 pr_err("Requested DataOut Timeout Retries %u larger"
83                         " than maximum %u", dataout_timeout_retries,
84                                 NA_DATAOUT_TIMEOUT_RETRIES_MAX);
85                 return -EINVAL;
86         } else if (dataout_timeout_retries < NA_DATAOUT_TIMEOUT_RETRIES_MIN) {
87                 pr_err("Requested DataOut Timeout Retries %u smaller"
88                         " than minimum %u", dataout_timeout_retries,
89                                 NA_DATAOUT_TIMEOUT_RETRIES_MIN);
90                 return -EINVAL;
91         }
92
93         a->dataout_timeout_retries = dataout_timeout_retries;
94         pr_debug("Set DataOut Timeout Retries to %u for"
95                 " Initiator Node %s\n", a->dataout_timeout_retries,
96                 iscsit_na_get_initiatorname(acl));
97
98         return 0;
99 }
100
101 int iscsit_na_nopin_timeout(
102         struct iscsi_node_acl *acl,
103         u32 nopin_timeout)
104 {
105         struct iscsi_node_attrib *a = &acl->node_attrib;
106         struct iscsi_session *sess;
107         struct iscsi_conn *conn;
108         struct se_node_acl *se_nacl = &a->nacl->se_node_acl;
109         struct se_session *se_sess;
110         u32 orig_nopin_timeout = a->nopin_timeout;
111
112         if (nopin_timeout > NA_NOPIN_TIMEOUT_MAX) {
113                 pr_err("Requested NopIn Timeout %u larger than maximum"
114                         " %u\n", nopin_timeout, NA_NOPIN_TIMEOUT_MAX);
115                 return -EINVAL;
116         } else if ((nopin_timeout < NA_NOPIN_TIMEOUT_MIN) &&
117                    (nopin_timeout != 0)) {
118                 pr_err("Requested NopIn Timeout %u smaller than"
119                         " minimum %u and not 0\n", nopin_timeout,
120                         NA_NOPIN_TIMEOUT_MIN);
121                 return -EINVAL;
122         }
123
124         a->nopin_timeout = nopin_timeout;
125         pr_debug("Set NopIn Timeout to %u for Initiator"
126                 " Node %s\n", a->nopin_timeout,
127                 iscsit_na_get_initiatorname(acl));
128         /*
129          * Reenable disabled nopin_timeout timer for all iSCSI connections.
130          */
131         if (!orig_nopin_timeout) {
132                 spin_lock_bh(&se_nacl->nacl_sess_lock);
133                 se_sess = se_nacl->nacl_sess;
134                 if (se_sess) {
135                         sess = se_sess->fabric_sess_ptr;
136
137                         spin_lock(&sess->conn_lock);
138                         list_for_each_entry(conn, &sess->sess_conn_list,
139                                         conn_list) {
140                                 if (conn->conn_state !=
141                                                 TARG_CONN_STATE_LOGGED_IN)
142                                         continue;
143
144                                 spin_lock(&conn->nopin_timer_lock);
145                                 __iscsit_start_nopin_timer(conn);
146                                 spin_unlock(&conn->nopin_timer_lock);
147                         }
148                         spin_unlock(&sess->conn_lock);
149                 }
150                 spin_unlock_bh(&se_nacl->nacl_sess_lock);
151         }
152
153         return 0;
154 }
155
156 int iscsit_na_nopin_response_timeout(
157         struct iscsi_node_acl *acl,
158         u32 nopin_response_timeout)
159 {
160         struct iscsi_node_attrib *a = &acl->node_attrib;
161
162         if (nopin_response_timeout > NA_NOPIN_RESPONSE_TIMEOUT_MAX) {
163                 pr_err("Requested NopIn Response Timeout %u larger"
164                         " than maximum %u\n", nopin_response_timeout,
165                                 NA_NOPIN_RESPONSE_TIMEOUT_MAX);
166                 return -EINVAL;
167         } else if (nopin_response_timeout < NA_NOPIN_RESPONSE_TIMEOUT_MIN) {
168                 pr_err("Requested NopIn Response Timeout %u smaller"
169                         " than minimum %u\n", nopin_response_timeout,
170                                 NA_NOPIN_RESPONSE_TIMEOUT_MIN);
171                 return -EINVAL;
172         }
173
174         a->nopin_response_timeout = nopin_response_timeout;
175         pr_debug("Set NopIn Response Timeout to %u for"
176                 " Initiator Node %s\n", a->nopin_timeout,
177                 iscsit_na_get_initiatorname(acl));
178
179         return 0;
180 }
181
182 int iscsit_na_random_datain_pdu_offsets(
183         struct iscsi_node_acl *acl,
184         u32 random_datain_pdu_offsets)
185 {
186         struct iscsi_node_attrib *a = &acl->node_attrib;
187
188         if (random_datain_pdu_offsets != 0 && random_datain_pdu_offsets != 1) {
189                 pr_err("Requested Random DataIN PDU Offsets: %u not"
190                         " 0 or 1\n", random_datain_pdu_offsets);
191                 return -EINVAL;
192         }
193
194         a->random_datain_pdu_offsets = random_datain_pdu_offsets;
195         pr_debug("Set Random DataIN PDU Offsets to %u for"
196                 " Initiator Node %s\n", a->random_datain_pdu_offsets,
197                 iscsit_na_get_initiatorname(acl));
198
199         return 0;
200 }
201
202 int iscsit_na_random_datain_seq_offsets(
203         struct iscsi_node_acl *acl,
204         u32 random_datain_seq_offsets)
205 {
206         struct iscsi_node_attrib *a = &acl->node_attrib;
207
208         if (random_datain_seq_offsets != 0 && random_datain_seq_offsets != 1) {
209                 pr_err("Requested Random DataIN Sequence Offsets: %u"
210                         " not 0 or 1\n", random_datain_seq_offsets);
211                 return -EINVAL;
212         }
213
214         a->random_datain_seq_offsets = random_datain_seq_offsets;
215         pr_debug("Set Random DataIN Sequence Offsets to %u for"
216                 " Initiator Node %s\n", a->random_datain_seq_offsets,
217                 iscsit_na_get_initiatorname(acl));
218
219         return 0;
220 }
221
222 int iscsit_na_random_r2t_offsets(
223         struct iscsi_node_acl *acl,
224         u32 random_r2t_offsets)
225 {
226         struct iscsi_node_attrib *a = &acl->node_attrib;
227
228         if (random_r2t_offsets != 0 && random_r2t_offsets != 1) {
229                 pr_err("Requested Random R2T Offsets: %u not"
230                         " 0 or 1\n", random_r2t_offsets);
231                 return -EINVAL;
232         }
233
234         a->random_r2t_offsets = random_r2t_offsets;
235         pr_debug("Set Random R2T Offsets to %u for"
236                 " Initiator Node %s\n", a->random_r2t_offsets,
237                 iscsit_na_get_initiatorname(acl));
238
239         return 0;
240 }
241
242 int iscsit_na_default_erl(
243         struct iscsi_node_acl *acl,
244         u32 default_erl)
245 {
246         struct iscsi_node_attrib *a = &acl->node_attrib;
247
248         if (default_erl != 0 && default_erl != 1 && default_erl != 2) {
249                 pr_err("Requested default ERL: %u not 0, 1, or 2\n",
250                                 default_erl);
251                 return -EINVAL;
252         }
253
254         a->default_erl = default_erl;
255         pr_debug("Set use ERL0 flag to %u for Initiator"
256                 " Node %s\n", a->default_erl,
257                 iscsit_na_get_initiatorname(acl));
258
259         return 0;
260 }