~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to drivers/target/iscsi/iscsi_target_tpg.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************************
 
2
 * This file contains iSCSI Target Portal Group related functions.
 
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
#include <target/target_core_fabric_ops.h>
 
24
#include <target/target_core_configfs.h>
 
25
#include <target/target_core_tpg.h>
 
26
 
 
27
#include "iscsi_target_core.h"
 
28
#include "iscsi_target_erl0.h"
 
29
#include "iscsi_target_login.h"
 
30
#include "iscsi_target_nodeattrib.h"
 
31
#include "iscsi_target_tpg.h"
 
32
#include "iscsi_target_util.h"
 
33
#include "iscsi_target.h"
 
34
#include "iscsi_target_parameters.h"
 
35
 
 
36
struct iscsi_portal_group *iscsit_alloc_portal_group(struct iscsi_tiqn *tiqn, u16 tpgt)
 
37
{
 
38
        struct iscsi_portal_group *tpg;
 
39
 
 
40
        tpg = kzalloc(sizeof(struct iscsi_portal_group), GFP_KERNEL);
 
41
        if (!tpg) {
 
42
                pr_err("Unable to allocate struct iscsi_portal_group\n");
 
43
                return NULL;
 
44
        }
 
45
 
 
46
        tpg->tpgt = tpgt;
 
47
        tpg->tpg_state = TPG_STATE_FREE;
 
48
        tpg->tpg_tiqn = tiqn;
 
49
        INIT_LIST_HEAD(&tpg->tpg_gnp_list);
 
50
        INIT_LIST_HEAD(&tpg->tpg_list);
 
51
        mutex_init(&tpg->tpg_access_lock);
 
52
        mutex_init(&tpg->np_login_lock);
 
53
        spin_lock_init(&tpg->tpg_state_lock);
 
54
        spin_lock_init(&tpg->tpg_np_lock);
 
55
 
 
56
        return tpg;
 
57
}
 
58
 
 
59
static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *);
 
60
 
 
61
int iscsit_load_discovery_tpg(void)
 
62
{
 
63
        struct iscsi_param *param;
 
64
        struct iscsi_portal_group *tpg;
 
65
        int ret;
 
66
 
 
67
        tpg = iscsit_alloc_portal_group(NULL, 1);
 
68
        if (!tpg) {
 
69
                pr_err("Unable to allocate struct iscsi_portal_group\n");
 
70
                return -1;
 
71
        }
 
72
 
 
73
        ret = core_tpg_register(
 
74
                        &lio_target_fabric_configfs->tf_ops,
 
75
                        NULL, &tpg->tpg_se_tpg, (void *)tpg,
 
76
                        TRANSPORT_TPG_TYPE_DISCOVERY);
 
77
        if (ret < 0) {
 
78
                kfree(tpg);
 
79
                return -1;
 
80
        }
 
81
 
 
82
        tpg->sid = 1; /* First Assigned LIO Session ID */
 
83
        iscsit_set_default_tpg_attribs(tpg);
 
84
 
 
85
        if (iscsi_create_default_params(&tpg->param_list) < 0)
 
86
                goto out;
 
87
        /*
 
88
         * By default we disable authentication for discovery sessions,
 
89
         * this can be changed with:
 
90
         *
 
91
         * /sys/kernel/config/target/iscsi/discovery_auth/enforce_discovery_auth
 
92
         */
 
93
        param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
 
94
        if (!param)
 
95
                goto out;
 
96
 
 
97
        if (iscsi_update_param_value(param, "CHAP,None") < 0)
 
98
                goto out;
 
99
 
 
100
        tpg->tpg_attrib.authentication = 0;
 
101
 
 
102
        spin_lock(&tpg->tpg_state_lock);
 
103
        tpg->tpg_state  = TPG_STATE_ACTIVE;
 
104
        spin_unlock(&tpg->tpg_state_lock);
 
105
 
 
106
        iscsit_global->discovery_tpg = tpg;
 
107
        pr_debug("CORE[0] - Allocated Discovery TPG\n");
 
108
 
 
109
        return 0;
 
110
out:
 
111
        if (tpg->sid == 1)
 
112
                core_tpg_deregister(&tpg->tpg_se_tpg);
 
113
        kfree(tpg);
 
114
        return -1;
 
115
}
 
116
 
 
117
void iscsit_release_discovery_tpg(void)
 
118
{
 
119
        struct iscsi_portal_group *tpg = iscsit_global->discovery_tpg;
 
120
 
 
121
        if (!tpg)
 
122
                return;
 
123
 
 
124
        core_tpg_deregister(&tpg->tpg_se_tpg);
 
125
 
 
126
        kfree(tpg);
 
127
        iscsit_global->discovery_tpg = NULL;
 
128
}
 
129
 
 
130
struct iscsi_portal_group *iscsit_get_tpg_from_np(
 
131
        struct iscsi_tiqn *tiqn,
 
132
        struct iscsi_np *np)
 
133
{
 
134
        struct iscsi_portal_group *tpg = NULL;
 
135
        struct iscsi_tpg_np *tpg_np;
 
136
 
 
137
        spin_lock(&tiqn->tiqn_tpg_lock);
 
138
        list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
 
139
 
 
140
                spin_lock(&tpg->tpg_state_lock);
 
141
                if (tpg->tpg_state == TPG_STATE_FREE) {
 
142
                        spin_unlock(&tpg->tpg_state_lock);
 
143
                        continue;
 
144
                }
 
145
                spin_unlock(&tpg->tpg_state_lock);
 
146
 
 
147
                spin_lock(&tpg->tpg_np_lock);
 
148
                list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
 
149
                        if (tpg_np->tpg_np == np) {
 
150
                                spin_unlock(&tpg->tpg_np_lock);
 
151
                                spin_unlock(&tiqn->tiqn_tpg_lock);
 
152
                                return tpg;
 
153
                        }
 
154
                }
 
155
                spin_unlock(&tpg->tpg_np_lock);
 
156
        }
 
157
        spin_unlock(&tiqn->tiqn_tpg_lock);
 
158
 
 
159
        return NULL;
 
160
}
 
161
 
 
162
int iscsit_get_tpg(
 
163
        struct iscsi_portal_group *tpg)
 
164
{
 
165
        int ret;
 
166
 
 
167
        ret = mutex_lock_interruptible(&tpg->tpg_access_lock);
 
168
        return ((ret != 0) || signal_pending(current)) ? -1 : 0;
 
169
}
 
170
 
 
171
void iscsit_put_tpg(struct iscsi_portal_group *tpg)
 
172
{
 
173
        mutex_unlock(&tpg->tpg_access_lock);
 
174
}
 
175
 
 
176
static void iscsit_clear_tpg_np_login_thread(
 
177
        struct iscsi_tpg_np *tpg_np,
 
178
        struct iscsi_portal_group *tpg)
 
179
{
 
180
        if (!tpg_np->tpg_np) {
 
181
                pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
 
182
                return;
 
183
        }
 
184
 
 
185
        iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg);
 
186
}
 
187
 
 
188
void iscsit_clear_tpg_np_login_threads(
 
189
        struct iscsi_portal_group *tpg)
 
190
{
 
191
        struct iscsi_tpg_np *tpg_np;
 
192
 
 
193
        spin_lock(&tpg->tpg_np_lock);
 
194
        list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, tpg_np_list) {
 
195
                if (!tpg_np->tpg_np) {
 
196
                        pr_err("struct iscsi_tpg_np->tpg_np is NULL!\n");
 
197
                        continue;
 
198
                }
 
199
                spin_unlock(&tpg->tpg_np_lock);
 
200
                iscsit_clear_tpg_np_login_thread(tpg_np, tpg);
 
201
                spin_lock(&tpg->tpg_np_lock);
 
202
        }
 
203
        spin_unlock(&tpg->tpg_np_lock);
 
204
}
 
205
 
 
206
void iscsit_tpg_dump_params(struct iscsi_portal_group *tpg)
 
207
{
 
208
        iscsi_print_params(tpg->param_list);
 
209
}
 
210
 
 
211
static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg)
 
212
{
 
213
        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 
214
 
 
215
        a->authentication = TA_AUTHENTICATION;
 
216
        a->login_timeout = TA_LOGIN_TIMEOUT;
 
217
        a->netif_timeout = TA_NETIF_TIMEOUT;
 
218
        a->default_cmdsn_depth = TA_DEFAULT_CMDSN_DEPTH;
 
219
        a->generate_node_acls = TA_GENERATE_NODE_ACLS;
 
220
        a->cache_dynamic_acls = TA_CACHE_DYNAMIC_ACLS;
 
221
        a->demo_mode_write_protect = TA_DEMO_MODE_WRITE_PROTECT;
 
222
        a->prod_mode_write_protect = TA_PROD_MODE_WRITE_PROTECT;
 
223
}
 
224
 
 
225
int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg)
 
226
{
 
227
        if (tpg->tpg_state != TPG_STATE_FREE) {
 
228
                pr_err("Unable to add iSCSI Target Portal Group: %d"
 
229
                        " while not in TPG_STATE_FREE state.\n", tpg->tpgt);
 
230
                return -EEXIST;
 
231
        }
 
232
        iscsit_set_default_tpg_attribs(tpg);
 
233
 
 
234
        if (iscsi_create_default_params(&tpg->param_list) < 0)
 
235
                goto err_out;
 
236
 
 
237
        ISCSI_TPG_ATTRIB(tpg)->tpg = tpg;
 
238
 
 
239
        spin_lock(&tpg->tpg_state_lock);
 
240
        tpg->tpg_state  = TPG_STATE_INACTIVE;
 
241
        spin_unlock(&tpg->tpg_state_lock);
 
242
 
 
243
        spin_lock(&tiqn->tiqn_tpg_lock);
 
244
        list_add_tail(&tpg->tpg_list, &tiqn->tiqn_tpg_list);
 
245
        tiqn->tiqn_ntpgs++;
 
246
        pr_debug("CORE[%s]_TPG[%hu] - Added iSCSI Target Portal Group\n",
 
247
                        tiqn->tiqn, tpg->tpgt);
 
248
        spin_unlock(&tiqn->tiqn_tpg_lock);
 
249
 
 
250
        return 0;
 
251
err_out:
 
252
        if (tpg->param_list) {
 
253
                iscsi_release_param_list(tpg->param_list);
 
254
                tpg->param_list = NULL;
 
255
        }
 
256
        kfree(tpg);
 
257
        return -ENOMEM;
 
258
}
 
259
 
 
260
int iscsit_tpg_del_portal_group(
 
261
        struct iscsi_tiqn *tiqn,
 
262
        struct iscsi_portal_group *tpg,
 
263
        int force)
 
264
{
 
265
        u8 old_state = tpg->tpg_state;
 
266
 
 
267
        spin_lock(&tpg->tpg_state_lock);
 
268
        tpg->tpg_state = TPG_STATE_INACTIVE;
 
269
        spin_unlock(&tpg->tpg_state_lock);
 
270
 
 
271
        if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
 
272
                pr_err("Unable to delete iSCSI Target Portal Group:"
 
273
                        " %hu while active sessions exist, and force=0\n",
 
274
                        tpg->tpgt);
 
275
                tpg->tpg_state = old_state;
 
276
                return -EPERM;
 
277
        }
 
278
 
 
279
        core_tpg_clear_object_luns(&tpg->tpg_se_tpg);
 
280
 
 
281
        if (tpg->param_list) {
 
282
                iscsi_release_param_list(tpg->param_list);
 
283
                tpg->param_list = NULL;
 
284
        }
 
285
 
 
286
        core_tpg_deregister(&tpg->tpg_se_tpg);
 
287
 
 
288
        spin_lock(&tpg->tpg_state_lock);
 
289
        tpg->tpg_state = TPG_STATE_FREE;
 
290
        spin_unlock(&tpg->tpg_state_lock);
 
291
 
 
292
        spin_lock(&tiqn->tiqn_tpg_lock);
 
293
        tiqn->tiqn_ntpgs--;
 
294
        list_del(&tpg->tpg_list);
 
295
        spin_unlock(&tiqn->tiqn_tpg_lock);
 
296
 
 
297
        pr_debug("CORE[%s]_TPG[%hu] - Deleted iSCSI Target Portal Group\n",
 
298
                        tiqn->tiqn, tpg->tpgt);
 
299
 
 
300
        kfree(tpg);
 
301
        return 0;
 
302
}
 
303
 
 
304
int iscsit_tpg_enable_portal_group(struct iscsi_portal_group *tpg)
 
305
{
 
306
        struct iscsi_param *param;
 
307
        struct iscsi_tiqn *tiqn = tpg->tpg_tiqn;
 
308
 
 
309
        spin_lock(&tpg->tpg_state_lock);
 
310
        if (tpg->tpg_state == TPG_STATE_ACTIVE) {
 
311
                pr_err("iSCSI target portal group: %hu is already"
 
312
                        " active, ignoring request.\n", tpg->tpgt);
 
313
                spin_unlock(&tpg->tpg_state_lock);
 
314
                return -EINVAL;
 
315
        }
 
316
        /*
 
317
         * Make sure that AuthMethod does not contain None as an option
 
318
         * unless explictly disabled.  Set the default to CHAP if authentication
 
319
         * is enforced (as per default), and remove the NONE option.
 
320
         */
 
321
        param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
 
322
        if (!param) {
 
323
                spin_unlock(&tpg->tpg_state_lock);
 
324
                return -ENOMEM;
 
325
        }
 
326
 
 
327
        if (ISCSI_TPG_ATTRIB(tpg)->authentication) {
 
328
                if (!strcmp(param->value, NONE))
 
329
                        if (iscsi_update_param_value(param, CHAP) < 0) {
 
330
                                spin_unlock(&tpg->tpg_state_lock);
 
331
                                return -ENOMEM;
 
332
                        }
 
333
                if (iscsit_ta_authentication(tpg, 1) < 0) {
 
334
                        spin_unlock(&tpg->tpg_state_lock);
 
335
                        return -ENOMEM;
 
336
                }
 
337
        }
 
338
 
 
339
        tpg->tpg_state = TPG_STATE_ACTIVE;
 
340
        spin_unlock(&tpg->tpg_state_lock);
 
341
 
 
342
        spin_lock(&tiqn->tiqn_tpg_lock);
 
343
        tiqn->tiqn_active_tpgs++;
 
344
        pr_debug("iSCSI_TPG[%hu] - Enabled iSCSI Target Portal Group\n",
 
345
                        tpg->tpgt);
 
346
        spin_unlock(&tiqn->tiqn_tpg_lock);
 
347
 
 
348
        return 0;
 
349
}
 
350
 
 
351
int iscsit_tpg_disable_portal_group(struct iscsi_portal_group *tpg, int force)
 
352
{
 
353
        struct iscsi_tiqn *tiqn;
 
354
        u8 old_state = tpg->tpg_state;
 
355
 
 
356
        spin_lock(&tpg->tpg_state_lock);
 
357
        if (tpg->tpg_state == TPG_STATE_INACTIVE) {
 
358
                pr_err("iSCSI Target Portal Group: %hu is already"
 
359
                        " inactive, ignoring request.\n", tpg->tpgt);
 
360
                spin_unlock(&tpg->tpg_state_lock);
 
361
                return -EINVAL;
 
362
        }
 
363
        tpg->tpg_state = TPG_STATE_INACTIVE;
 
364
        spin_unlock(&tpg->tpg_state_lock);
 
365
 
 
366
        iscsit_clear_tpg_np_login_threads(tpg);
 
367
 
 
368
        if (iscsit_release_sessions_for_tpg(tpg, force) < 0) {
 
369
                spin_lock(&tpg->tpg_state_lock);
 
370
                tpg->tpg_state = old_state;
 
371
                spin_unlock(&tpg->tpg_state_lock);
 
372
                pr_err("Unable to disable iSCSI Target Portal Group:"
 
373
                        " %hu while active sessions exist, and force=0\n",
 
374
                        tpg->tpgt);
 
375
                return -EPERM;
 
376
        }
 
377
 
 
378
        tiqn = tpg->tpg_tiqn;
 
379
        if (!tiqn || (tpg == iscsit_global->discovery_tpg))
 
380
                return 0;
 
381
 
 
382
        spin_lock(&tiqn->tiqn_tpg_lock);
 
383
        tiqn->tiqn_active_tpgs--;
 
384
        pr_debug("iSCSI_TPG[%hu] - Disabled iSCSI Target Portal Group\n",
 
385
                        tpg->tpgt);
 
386
        spin_unlock(&tiqn->tiqn_tpg_lock);
 
387
 
 
388
        return 0;
 
389
}
 
390
 
 
391
struct iscsi_node_attrib *iscsit_tpg_get_node_attrib(
 
392
        struct iscsi_session *sess)
 
393
{
 
394
        struct se_session *se_sess = sess->se_sess;
 
395
        struct se_node_acl *se_nacl = se_sess->se_node_acl;
 
396
        struct iscsi_node_acl *acl = container_of(se_nacl, struct iscsi_node_acl,
 
397
                                        se_node_acl);
 
398
 
 
399
        return &acl->node_attrib;
 
400
}
 
401
 
 
402
struct iscsi_tpg_np *iscsit_tpg_locate_child_np(
 
403
        struct iscsi_tpg_np *tpg_np,
 
404
        int network_transport)
 
405
{
 
406
        struct iscsi_tpg_np *tpg_np_child, *tpg_np_child_tmp;
 
407
 
 
408
        spin_lock(&tpg_np->tpg_np_parent_lock);
 
409
        list_for_each_entry_safe(tpg_np_child, tpg_np_child_tmp,
 
410
                        &tpg_np->tpg_np_parent_list, tpg_np_child_list) {
 
411
                if (tpg_np_child->tpg_np->np_network_transport ==
 
412
                                network_transport) {
 
413
                        spin_unlock(&tpg_np->tpg_np_parent_lock);
 
414
                        return tpg_np_child;
 
415
                }
 
416
        }
 
417
        spin_unlock(&tpg_np->tpg_np_parent_lock);
 
418
 
 
419
        return NULL;
 
420
}
 
421
 
 
422
struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
 
423
        struct iscsi_portal_group *tpg,
 
424
        struct __kernel_sockaddr_storage *sockaddr,
 
425
        char *ip_str,
 
426
        struct iscsi_tpg_np *tpg_np_parent,
 
427
        int network_transport)
 
428
{
 
429
        struct iscsi_np *np;
 
430
        struct iscsi_tpg_np *tpg_np;
 
431
 
 
432
        tpg_np = kzalloc(sizeof(struct iscsi_tpg_np), GFP_KERNEL);
 
433
        if (!tpg_np) {
 
434
                pr_err("Unable to allocate memory for"
 
435
                                " struct iscsi_tpg_np.\n");
 
436
                return ERR_PTR(-ENOMEM);
 
437
        }
 
438
 
 
439
        np = iscsit_add_np(sockaddr, ip_str, network_transport);
 
440
        if (IS_ERR(np)) {
 
441
                kfree(tpg_np);
 
442
                return ERR_CAST(np);
 
443
        }
 
444
 
 
445
        INIT_LIST_HEAD(&tpg_np->tpg_np_list);
 
446
        INIT_LIST_HEAD(&tpg_np->tpg_np_child_list);
 
447
        INIT_LIST_HEAD(&tpg_np->tpg_np_parent_list);
 
448
        spin_lock_init(&tpg_np->tpg_np_parent_lock);
 
449
        tpg_np->tpg_np          = np;
 
450
        tpg_np->tpg             = tpg;
 
451
 
 
452
        spin_lock(&tpg->tpg_np_lock);
 
453
        list_add_tail(&tpg_np->tpg_np_list, &tpg->tpg_gnp_list);
 
454
        tpg->num_tpg_nps++;
 
455
        if (tpg->tpg_tiqn)
 
456
                tpg->tpg_tiqn->tiqn_num_tpg_nps++;
 
457
        spin_unlock(&tpg->tpg_np_lock);
 
458
 
 
459
        if (tpg_np_parent) {
 
460
                tpg_np->tpg_np_parent = tpg_np_parent;
 
461
                spin_lock(&tpg_np_parent->tpg_np_parent_lock);
 
462
                list_add_tail(&tpg_np->tpg_np_child_list,
 
463
                        &tpg_np_parent->tpg_np_parent_list);
 
464
                spin_unlock(&tpg_np_parent->tpg_np_parent_lock);
 
465
        }
 
466
 
 
467
        pr_debug("CORE[%s] - Added Network Portal: %s:%hu,%hu on %s\n",
 
468
                tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt,
 
469
                (np->np_network_transport == ISCSI_TCP) ? "TCP" : "SCTP");
 
470
 
 
471
        return tpg_np;
 
472
}
 
473
 
 
474
static int iscsit_tpg_release_np(
 
475
        struct iscsi_tpg_np *tpg_np,
 
476
        struct iscsi_portal_group *tpg,
 
477
        struct iscsi_np *np)
 
478
{
 
479
        iscsit_clear_tpg_np_login_thread(tpg_np, tpg);
 
480
 
 
481
        pr_debug("CORE[%s] - Removed Network Portal: %s:%hu,%hu on %s\n",
 
482
                tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt,
 
483
                (np->np_network_transport == ISCSI_TCP) ? "TCP" : "SCTP");
 
484
 
 
485
        tpg_np->tpg_np = NULL;
 
486
        tpg_np->tpg = NULL;
 
487
        kfree(tpg_np);
 
488
        /*
 
489
         * iscsit_del_np() will shutdown struct iscsi_np when last TPG reference is released.
 
490
         */
 
491
        return iscsit_del_np(np);
 
492
}
 
493
 
 
494
int iscsit_tpg_del_network_portal(
 
495
        struct iscsi_portal_group *tpg,
 
496
        struct iscsi_tpg_np *tpg_np)
 
497
{
 
498
        struct iscsi_np *np;
 
499
        struct iscsi_tpg_np *tpg_np_child, *tpg_np_child_tmp;
 
500
        int ret = 0;
 
501
 
 
502
        np = tpg_np->tpg_np;
 
503
        if (!np) {
 
504
                pr_err("Unable to locate struct iscsi_np from"
 
505
                                " struct iscsi_tpg_np\n");
 
506
                return -EINVAL;
 
507
        }
 
508
 
 
509
        if (!tpg_np->tpg_np_parent) {
 
510
                /*
 
511
                 * We are the parent tpg network portal.  Release all of the
 
512
                 * child tpg_np's (eg: the non ISCSI_TCP ones) on our parent
 
513
                 * list first.
 
514
                 */
 
515
                list_for_each_entry_safe(tpg_np_child, tpg_np_child_tmp,
 
516
                                &tpg_np->tpg_np_parent_list,
 
517
                                tpg_np_child_list) {
 
518
                        ret = iscsit_tpg_del_network_portal(tpg, tpg_np_child);
 
519
                        if (ret < 0)
 
520
                                pr_err("iscsit_tpg_del_network_portal()"
 
521
                                        " failed: %d\n", ret);
 
522
                }
 
523
        } else {
 
524
                /*
 
525
                 * We are not the parent ISCSI_TCP tpg network portal.  Release
 
526
                 * our own network portals from the child list.
 
527
                 */
 
528
                spin_lock(&tpg_np->tpg_np_parent->tpg_np_parent_lock);
 
529
                list_del(&tpg_np->tpg_np_child_list);
 
530
                spin_unlock(&tpg_np->tpg_np_parent->tpg_np_parent_lock);
 
531
        }
 
532
 
 
533
        spin_lock(&tpg->tpg_np_lock);
 
534
        list_del(&tpg_np->tpg_np_list);
 
535
        tpg->num_tpg_nps--;
 
536
        if (tpg->tpg_tiqn)
 
537
                tpg->tpg_tiqn->tiqn_num_tpg_nps--;
 
538
        spin_unlock(&tpg->tpg_np_lock);
 
539
 
 
540
        return iscsit_tpg_release_np(tpg_np, tpg, np);
 
541
}
 
542
 
 
543
int iscsit_tpg_set_initiator_node_queue_depth(
 
544
        struct iscsi_portal_group *tpg,
 
545
        unsigned char *initiatorname,
 
546
        u32 queue_depth,
 
547
        int force)
 
548
{
 
549
        return core_tpg_set_initiator_node_queue_depth(&tpg->tpg_se_tpg,
 
550
                initiatorname, queue_depth, force);
 
551
}
 
552
 
 
553
int iscsit_ta_authentication(struct iscsi_portal_group *tpg, u32 authentication)
 
554
{
 
555
        unsigned char buf1[256], buf2[256], *none = NULL;
 
556
        int len;
 
557
        struct iscsi_param *param;
 
558
        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 
559
 
 
560
        if ((authentication != 1) && (authentication != 0)) {
 
561
                pr_err("Illegal value for authentication parameter:"
 
562
                        " %u, ignoring request.\n", authentication);
 
563
                return -1;
 
564
        }
 
565
 
 
566
        memset(buf1, 0, sizeof(buf1));
 
567
        memset(buf2, 0, sizeof(buf2));
 
568
 
 
569
        param = iscsi_find_param_from_key(AUTHMETHOD, tpg->param_list);
 
570
        if (!param)
 
571
                return -EINVAL;
 
572
 
 
573
        if (authentication) {
 
574
                snprintf(buf1, sizeof(buf1), "%s", param->value);
 
575
                none = strstr(buf1, NONE);
 
576
                if (!none)
 
577
                        goto out;
 
578
                if (!strncmp(none + 4, ",", 1)) {
 
579
                        if (!strcmp(buf1, none))
 
580
                                sprintf(buf2, "%s", none+5);
 
581
                        else {
 
582
                                none--;
 
583
                                *none = '\0';
 
584
                                len = sprintf(buf2, "%s", buf1);
 
585
                                none += 5;
 
586
                                sprintf(buf2 + len, "%s", none);
 
587
                        }
 
588
                } else {
 
589
                        none--;
 
590
                        *none = '\0';
 
591
                        sprintf(buf2, "%s", buf1);
 
592
                }
 
593
                if (iscsi_update_param_value(param, buf2) < 0)
 
594
                        return -EINVAL;
 
595
        } else {
 
596
                snprintf(buf1, sizeof(buf1), "%s", param->value);
 
597
                none = strstr(buf1, NONE);
 
598
                if ((none))
 
599
                        goto out;
 
600
                strncat(buf1, ",", strlen(","));
 
601
                strncat(buf1, NONE, strlen(NONE));
 
602
                if (iscsi_update_param_value(param, buf1) < 0)
 
603
                        return -EINVAL;
 
604
        }
 
605
 
 
606
out:
 
607
        a->authentication = authentication;
 
608
        pr_debug("%s iSCSI Authentication Methods for TPG: %hu.\n",
 
609
                a->authentication ? "Enforcing" : "Disabling", tpg->tpgt);
 
610
 
 
611
        return 0;
 
612
}
 
613
 
 
614
int iscsit_ta_login_timeout(
 
615
        struct iscsi_portal_group *tpg,
 
616
        u32 login_timeout)
 
617
{
 
618
        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 
619
 
 
620
        if (login_timeout > TA_LOGIN_TIMEOUT_MAX) {
 
621
                pr_err("Requested Login Timeout %u larger than maximum"
 
622
                        " %u\n", login_timeout, TA_LOGIN_TIMEOUT_MAX);
 
623
                return -EINVAL;
 
624
        } else if (login_timeout < TA_LOGIN_TIMEOUT_MIN) {
 
625
                pr_err("Requested Logout Timeout %u smaller than"
 
626
                        " minimum %u\n", login_timeout, TA_LOGIN_TIMEOUT_MIN);
 
627
                return -EINVAL;
 
628
        }
 
629
 
 
630
        a->login_timeout = login_timeout;
 
631
        pr_debug("Set Logout Timeout to %u for Target Portal Group"
 
632
                " %hu\n", a->login_timeout, tpg->tpgt);
 
633
 
 
634
        return 0;
 
635
}
 
636
 
 
637
int iscsit_ta_netif_timeout(
 
638
        struct iscsi_portal_group *tpg,
 
639
        u32 netif_timeout)
 
640
{
 
641
        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 
642
 
 
643
        if (netif_timeout > TA_NETIF_TIMEOUT_MAX) {
 
644
                pr_err("Requested Network Interface Timeout %u larger"
 
645
                        " than maximum %u\n", netif_timeout,
 
646
                                TA_NETIF_TIMEOUT_MAX);
 
647
                return -EINVAL;
 
648
        } else if (netif_timeout < TA_NETIF_TIMEOUT_MIN) {
 
649
                pr_err("Requested Network Interface Timeout %u smaller"
 
650
                        " than minimum %u\n", netif_timeout,
 
651
                                TA_NETIF_TIMEOUT_MIN);
 
652
                return -EINVAL;
 
653
        }
 
654
 
 
655
        a->netif_timeout = netif_timeout;
 
656
        pr_debug("Set Network Interface Timeout to %u for"
 
657
                " Target Portal Group %hu\n", a->netif_timeout, tpg->tpgt);
 
658
 
 
659
        return 0;
 
660
}
 
661
 
 
662
int iscsit_ta_generate_node_acls(
 
663
        struct iscsi_portal_group *tpg,
 
664
        u32 flag)
 
665
{
 
666
        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 
667
 
 
668
        if ((flag != 0) && (flag != 1)) {
 
669
                pr_err("Illegal value %d\n", flag);
 
670
                return -EINVAL;
 
671
        }
 
672
 
 
673
        a->generate_node_acls = flag;
 
674
        pr_debug("iSCSI_TPG[%hu] - Generate Initiator Portal Group ACLs: %s\n",
 
675
                tpg->tpgt, (a->generate_node_acls) ? "Enabled" : "Disabled");
 
676
 
 
677
        return 0;
 
678
}
 
679
 
 
680
int iscsit_ta_default_cmdsn_depth(
 
681
        struct iscsi_portal_group *tpg,
 
682
        u32 tcq_depth)
 
683
{
 
684
        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 
685
 
 
686
        if (tcq_depth > TA_DEFAULT_CMDSN_DEPTH_MAX) {
 
687
                pr_err("Requested Default Queue Depth: %u larger"
 
688
                        " than maximum %u\n", tcq_depth,
 
689
                                TA_DEFAULT_CMDSN_DEPTH_MAX);
 
690
                return -EINVAL;
 
691
        } else if (tcq_depth < TA_DEFAULT_CMDSN_DEPTH_MIN) {
 
692
                pr_err("Requested Default Queue Depth: %u smaller"
 
693
                        " than minimum %u\n", tcq_depth,
 
694
                                TA_DEFAULT_CMDSN_DEPTH_MIN);
 
695
                return -EINVAL;
 
696
        }
 
697
 
 
698
        a->default_cmdsn_depth = tcq_depth;
 
699
        pr_debug("iSCSI_TPG[%hu] - Set Default CmdSN TCQ Depth to %u\n",
 
700
                tpg->tpgt, a->default_cmdsn_depth);
 
701
 
 
702
        return 0;
 
703
}
 
704
 
 
705
int iscsit_ta_cache_dynamic_acls(
 
706
        struct iscsi_portal_group *tpg,
 
707
        u32 flag)
 
708
{
 
709
        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 
710
 
 
711
        if ((flag != 0) && (flag != 1)) {
 
712
                pr_err("Illegal value %d\n", flag);
 
713
                return -EINVAL;
 
714
        }
 
715
 
 
716
        a->cache_dynamic_acls = flag;
 
717
        pr_debug("iSCSI_TPG[%hu] - Cache Dynamic Initiator Portal Group"
 
718
                " ACLs %s\n", tpg->tpgt, (a->cache_dynamic_acls) ?
 
719
                "Enabled" : "Disabled");
 
720
 
 
721
        return 0;
 
722
}
 
723
 
 
724
int iscsit_ta_demo_mode_write_protect(
 
725
        struct iscsi_portal_group *tpg,
 
726
        u32 flag)
 
727
{
 
728
        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 
729
 
 
730
        if ((flag != 0) && (flag != 1)) {
 
731
                pr_err("Illegal value %d\n", flag);
 
732
                return -EINVAL;
 
733
        }
 
734
 
 
735
        a->demo_mode_write_protect = flag;
 
736
        pr_debug("iSCSI_TPG[%hu] - Demo Mode Write Protect bit: %s\n",
 
737
                tpg->tpgt, (a->demo_mode_write_protect) ? "ON" : "OFF");
 
738
 
 
739
        return 0;
 
740
}
 
741
 
 
742
int iscsit_ta_prod_mode_write_protect(
 
743
        struct iscsi_portal_group *tpg,
 
744
        u32 flag)
 
745
{
 
746
        struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
 
747
 
 
748
        if ((flag != 0) && (flag != 1)) {
 
749
                pr_err("Illegal value %d\n", flag);
 
750
                return -EINVAL;
 
751
        }
 
752
 
 
753
        a->prod_mode_write_protect = flag;
 
754
        pr_debug("iSCSI_TPG[%hu] - Production Mode Write Protect bit:"
 
755
                " %s\n", tpg->tpgt, (a->prod_mode_write_protect) ?
 
756
                "ON" : "OFF");
 
757
 
 
758
        return 0;
 
759
}