aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2011-04-26 04:22:15 -0400
committerJiri Kosina <jkosina@suse.cz>2011-04-26 04:22:59 -0400
commit07f9479a40cc778bc1462ada11f95b01360ae4ff (patch)
tree0676cf38df3844004bb3ebfd99dfa67a4a8998f5 /drivers/target
parent9d5e6bdb3013acfb311ab407eeca0b6a6a3dedbf (diff)
parentcd2e49e90f1cae7726c9a2c54488d881d7f1cd1c (diff)
Merge branch 'master' into for-next
Fast-forwarded to current state of Linus' tree as there are patches to be applied for files that didn't exist on the old branch.
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/Kconfig2
-rw-r--r--drivers/target/Makefile7
-rw-r--r--drivers/target/loopback/Kconfig11
-rw-r--r--drivers/target/loopback/Makefile1
-rw-r--r--drivers/target/loopback/tcm_loop.c1579
-rw-r--r--drivers/target/loopback/tcm_loop.h77
-rw-r--r--drivers/target/target_core_alua.c10
-rw-r--r--drivers/target/target_core_configfs.c117
-rw-r--r--drivers/target/target_core_device.c42
-rw-r--r--drivers/target/target_core_fabric_configfs.c209
-rw-r--r--drivers/target/target_core_fabric_lib.c3
-rw-r--r--drivers/target/target_core_file.c30
-rw-r--r--drivers/target/target_core_hba.c15
-rw-r--r--drivers/target/target_core_iblock.c35
-rw-r--r--drivers/target/target_core_pr.c6
-rw-r--r--drivers/target/target_core_pscsi.c22
-rw-r--r--drivers/target/target_core_rd.c15
-rw-r--r--drivers/target/target_core_rd.h2
-rw-r--r--drivers/target/target_core_stat.c1810
-rw-r--r--drivers/target/target_core_stat.h8
-rw-r--r--drivers/target/target_core_transport.c51
-rw-r--r--drivers/target/target_core_ua.c4
22 files changed, 3904 insertions, 152 deletions
diff --git a/drivers/target/Kconfig b/drivers/target/Kconfig
index 2fac3be209ac..9ef2dbbfa62b 100644
--- a/drivers/target/Kconfig
+++ b/drivers/target/Kconfig
@@ -29,4 +29,6 @@ config TCM_PSCSI
29 Say Y here to enable the TCM/pSCSI subsystem plugin for non-buffered 29 Say Y here to enable the TCM/pSCSI subsystem plugin for non-buffered
30 passthrough access to Linux/SCSI device 30 passthrough access to Linux/SCSI device
31 31
32source "drivers/target/loopback/Kconfig"
33
32endif 34endif
diff --git a/drivers/target/Makefile b/drivers/target/Makefile
index 973bb190ef57..1178bbfc68fe 100644
--- a/drivers/target/Makefile
+++ b/drivers/target/Makefile
@@ -1,4 +1,3 @@
1EXTRA_CFLAGS += -I$(srctree)/drivers/target/ -I$(srctree)/drivers/scsi/
2 1
3target_core_mod-y := target_core_configfs.o \ 2target_core_mod-y := target_core_configfs.o \
4 target_core_device.o \ 3 target_core_device.o \
@@ -13,7 +12,8 @@ target_core_mod-y := target_core_configfs.o \
13 target_core_transport.o \ 12 target_core_transport.o \
14 target_core_cdb.o \ 13 target_core_cdb.o \
15 target_core_ua.o \ 14 target_core_ua.o \
16 target_core_rd.o 15 target_core_rd.o \
16 target_core_stat.o
17 17
18obj-$(CONFIG_TARGET_CORE) += target_core_mod.o 18obj-$(CONFIG_TARGET_CORE) += target_core_mod.o
19 19
@@ -21,3 +21,6 @@ obj-$(CONFIG_TARGET_CORE) += target_core_mod.o
21obj-$(CONFIG_TCM_IBLOCK) += target_core_iblock.o 21obj-$(CONFIG_TCM_IBLOCK) += target_core_iblock.o
22obj-$(CONFIG_TCM_FILEIO) += target_core_file.o 22obj-$(CONFIG_TCM_FILEIO) += target_core_file.o
23obj-$(CONFIG_TCM_PSCSI) += target_core_pscsi.o 23obj-$(CONFIG_TCM_PSCSI) += target_core_pscsi.o
24
25# Fabric modules
26obj-$(CONFIG_LOOPBACK_TARGET) += loopback/
diff --git a/drivers/target/loopback/Kconfig b/drivers/target/loopback/Kconfig
new file mode 100644
index 000000000000..57dcbc2d711b
--- /dev/null
+++ b/drivers/target/loopback/Kconfig
@@ -0,0 +1,11 @@
1config LOOPBACK_TARGET
2 tristate "TCM Virtual SAS target and Linux/SCSI LDD fabric loopback module"
3 help
4 Say Y here to enable the TCM Virtual SAS target and Linux/SCSI LLD
5 fabric loopback module.
6
7config LOOPBACK_TARGET_CDB_DEBUG
8 bool "TCM loopback fabric module CDB debug code"
9 depends on LOOPBACK_TARGET
10 help
11 Say Y here to enable the TCM loopback fabric module CDB debug code
diff --git a/drivers/target/loopback/Makefile b/drivers/target/loopback/Makefile
new file mode 100644
index 000000000000..6abebdf95659
--- /dev/null
+++ b/drivers/target/loopback/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_LOOPBACK_TARGET) += tcm_loop.o
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
new file mode 100644
index 000000000000..aed4e464d31c
--- /dev/null
+++ b/drivers/target/loopback/tcm_loop.c
@@ -0,0 +1,1579 @@
1/*******************************************************************************
2 *
3 * This file contains the Linux/SCSI LLD virtual SCSI initiator driver
4 * for emulated SAS initiator ports
5 *
6 * © Copyright 2011 RisingTide Systems LLC.
7 *
8 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
9 *
10 * Author: Nicholas A. Bellinger <nab@risingtidesystems.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 ****************************************************************************/
22
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/init.h>
26#include <linux/slab.h>
27#include <linux/types.h>
28#include <linux/configfs.h>
29#include <scsi/scsi.h>
30#include <scsi/scsi_tcq.h>
31#include <scsi/scsi_host.h>
32#include <scsi/scsi_device.h>
33#include <scsi/scsi_cmnd.h>
34#include <scsi/libsas.h> /* For TASK_ATTR_* */
35
36#include <target/target_core_base.h>
37#include <target/target_core_transport.h>
38#include <target/target_core_fabric_ops.h>
39#include <target/target_core_fabric_configfs.h>
40#include <target/target_core_fabric_lib.h>
41#include <target/target_core_configfs.h>
42#include <target/target_core_device.h>
43#include <target/target_core_tpg.h>
44#include <target/target_core_tmr.h>
45
46#include "tcm_loop.h"
47
48#define to_tcm_loop_hba(hba) container_of(hba, struct tcm_loop_hba, dev)
49
50/* Local pointer to allocated TCM configfs fabric module */
51static struct target_fabric_configfs *tcm_loop_fabric_configfs;
52
53static struct kmem_cache *tcm_loop_cmd_cache;
54
55static int tcm_loop_hba_no_cnt;
56
57/*
58 * Allocate a tcm_loop cmd descriptor from target_core_mod code
59 *
60 * Can be called from interrupt context in tcm_loop_queuecommand() below
61 */
62static struct se_cmd *tcm_loop_allocate_core_cmd(
63 struct tcm_loop_hba *tl_hba,
64 struct se_portal_group *se_tpg,
65 struct scsi_cmnd *sc)
66{
67 struct se_cmd *se_cmd;
68 struct se_session *se_sess;
69 struct tcm_loop_nexus *tl_nexus = tl_hba->tl_nexus;
70 struct tcm_loop_cmd *tl_cmd;
71 int sam_task_attr;
72
73 if (!tl_nexus) {
74 scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus"
75 " does not exist\n");
76 set_host_byte(sc, DID_ERROR);
77 return NULL;
78 }
79 se_sess = tl_nexus->se_sess;
80
81 tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_ATOMIC);
82 if (!tl_cmd) {
83 printk(KERN_ERR "Unable to allocate struct tcm_loop_cmd\n");
84 set_host_byte(sc, DID_ERROR);
85 return NULL;
86 }
87 se_cmd = &tl_cmd->tl_se_cmd;
88 /*
89 * Save the pointer to struct scsi_cmnd *sc
90 */
91 tl_cmd->sc = sc;
92 /*
93 * Locate the SAM Task Attr from struct scsi_cmnd *
94 */
95 if (sc->device->tagged_supported) {
96 switch (sc->tag) {
97 case HEAD_OF_QUEUE_TAG:
98 sam_task_attr = TASK_ATTR_HOQ;
99 break;
100 case ORDERED_QUEUE_TAG:
101 sam_task_attr = TASK_ATTR_ORDERED;
102 break;
103 default:
104 sam_task_attr = TASK_ATTR_SIMPLE;
105 break;
106 }
107 } else
108 sam_task_attr = TASK_ATTR_SIMPLE;
109
110 /*
111 * Initialize struct se_cmd descriptor from target_core_mod infrastructure
112 */
113 transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess,
114 scsi_bufflen(sc), sc->sc_data_direction, sam_task_attr,
115 &tl_cmd->tl_sense_buf[0]);
116
117 /*
118 * Signal BIDI usage with T_TASK(cmd)->t_tasks_bidi
119 */
120 if (scsi_bidi_cmnd(sc))
121 T_TASK(se_cmd)->t_tasks_bidi = 1;
122 /*
123 * Locate the struct se_lun pointer and attach it to struct se_cmd
124 */
125 if (transport_get_lun_for_cmd(se_cmd, NULL, tl_cmd->sc->device->lun) < 0) {
126 kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
127 set_host_byte(sc, DID_NO_CONNECT);
128 return NULL;
129 }
130
131 transport_device_setup_cmd(se_cmd);
132 return se_cmd;
133}
134
135/*
136 * Called by struct target_core_fabric_ops->new_cmd_map()
137 *
138 * Always called in process context. A non zero return value
139 * here will signal to handle an exception based on the return code.
140 */
141static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd)
142{
143 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
144 struct tcm_loop_cmd, tl_se_cmd);
145 struct scsi_cmnd *sc = tl_cmd->sc;
146 void *mem_ptr, *mem_bidi_ptr = NULL;
147 u32 sg_no_bidi = 0;
148 int ret;
149 /*
150 * Allocate the necessary tasks to complete the received CDB+data
151 */
152 ret = transport_generic_allocate_tasks(se_cmd, tl_cmd->sc->cmnd);
153 if (ret == -1) {
154 /* Out of Resources */
155 return PYX_TRANSPORT_LU_COMM_FAILURE;
156 } else if (ret == -2) {
157 /*
158 * Handle case for SAM_STAT_RESERVATION_CONFLICT
159 */
160 if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
161 return PYX_TRANSPORT_RESERVATION_CONFLICT;
162 /*
163 * Otherwise, return SAM_STAT_CHECK_CONDITION and return
164 * sense data.
165 */
166 return PYX_TRANSPORT_USE_SENSE_REASON;
167 }
168 /*
169 * Setup the struct scatterlist memory from the received
170 * struct scsi_cmnd.
171 */
172 if (scsi_sg_count(sc)) {
173 se_cmd->se_cmd_flags |= SCF_PASSTHROUGH_SG_TO_MEM;
174 mem_ptr = (void *)scsi_sglist(sc);
175 /*
176 * For BIDI commands, pass in the extra READ buffer
177 * to transport_generic_map_mem_to_cmd() below..
178 */
179 if (T_TASK(se_cmd)->t_tasks_bidi) {
180 struct scsi_data_buffer *sdb = scsi_in(sc);
181
182 mem_bidi_ptr = (void *)sdb->table.sgl;
183 sg_no_bidi = sdb->table.nents;
184 }
185 } else {
186 /*
187 * Used for DMA_NONE
188 */
189 mem_ptr = NULL;
190 }
191 /*
192 * Map the SG memory into struct se_mem->page linked list using the same
193 * physical memory at sg->page_link.
194 */
195 ret = transport_generic_map_mem_to_cmd(se_cmd, mem_ptr,
196 scsi_sg_count(sc), mem_bidi_ptr, sg_no_bidi);
197 if (ret < 0)
198 return PYX_TRANSPORT_LU_COMM_FAILURE;
199
200 return 0;
201}
202
203/*
204 * Called from struct target_core_fabric_ops->check_stop_free()
205 */
206static void tcm_loop_check_stop_free(struct se_cmd *se_cmd)
207{
208 /*
209 * Do not release struct se_cmd's containing a valid TMR
210 * pointer. These will be released directly in tcm_loop_device_reset()
211 * with transport_generic_free_cmd().
212 */
213 if (se_cmd->se_tmr_req)
214 return;
215 /*
216 * Release the struct se_cmd, which will make a callback to release
217 * struct tcm_loop_cmd * in tcm_loop_deallocate_core_cmd()
218 */
219 transport_generic_free_cmd(se_cmd, 0, 1, 0);
220}
221
222/*
223 * Called from struct target_core_fabric_ops->release_cmd_to_pool()
224 */
225static void tcm_loop_deallocate_core_cmd(struct se_cmd *se_cmd)
226{
227 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
228 struct tcm_loop_cmd, tl_se_cmd);
229
230 kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
231}
232
233static int tcm_loop_proc_info(struct Scsi_Host *host, char *buffer,
234 char **start, off_t offset,
235 int length, int inout)
236{
237 return sprintf(buffer, "tcm_loop_proc_info()\n");
238}
239
240static int tcm_loop_driver_probe(struct device *);
241static int tcm_loop_driver_remove(struct device *);
242
243static int pseudo_lld_bus_match(struct device *dev,
244 struct device_driver *dev_driver)
245{
246 return 1;
247}
248
249static struct bus_type tcm_loop_lld_bus = {
250 .name = "tcm_loop_bus",
251 .match = pseudo_lld_bus_match,
252 .probe = tcm_loop_driver_probe,
253 .remove = tcm_loop_driver_remove,
254};
255
256static struct device_driver tcm_loop_driverfs = {
257 .name = "tcm_loop",
258 .bus = &tcm_loop_lld_bus,
259};
260/*
261 * Used with root_device_register() in tcm_loop_alloc_core_bus() below
262 */
263struct device *tcm_loop_primary;
264
265/*
266 * Copied from drivers/scsi/libfc/fc_fcp.c:fc_change_queue_depth() and
267 * drivers/scsi/libiscsi.c:iscsi_change_queue_depth()
268 */
269static int tcm_loop_change_queue_depth(
270 struct scsi_device *sdev,
271 int depth,
272 int reason)
273{
274 switch (reason) {
275 case SCSI_QDEPTH_DEFAULT:
276 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
277 break;
278 case SCSI_QDEPTH_QFULL:
279 scsi_track_queue_full(sdev, depth);
280 break;
281 case SCSI_QDEPTH_RAMP_UP:
282 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
283 break;
284 default:
285 return -EOPNOTSUPP;
286 }
287 return sdev->queue_depth;
288}
289
290/*
291 * Main entry point from struct scsi_host_template for incoming SCSI CDB+Data
292 * from Linux/SCSI subsystem for SCSI low level device drivers (LLDs)
293 */
294static int tcm_loop_queuecommand(
295 struct Scsi_Host *sh,
296 struct scsi_cmnd *sc)
297{
298 struct se_cmd *se_cmd;
299 struct se_portal_group *se_tpg;
300 struct tcm_loop_hba *tl_hba;
301 struct tcm_loop_tpg *tl_tpg;
302
303 TL_CDB_DEBUG("tcm_loop_queuecommand() %d:%d:%d:%d got CDB: 0x%02x"
304 " scsi_buf_len: %u\n", sc->device->host->host_no,
305 sc->device->id, sc->device->channel, sc->device->lun,
306 sc->cmnd[0], scsi_bufflen(sc));
307 /*
308 * Locate the tcm_loop_hba_t pointer
309 */
310 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
311 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
312 se_tpg = &tl_tpg->tl_se_tpg;
313 /*
314 * Determine the SAM Task Attribute and allocate tl_cmd and
315 * tl_cmd->tl_se_cmd from TCM infrastructure
316 */
317 se_cmd = tcm_loop_allocate_core_cmd(tl_hba, se_tpg, sc);
318 if (!se_cmd) {
319 sc->scsi_done(sc);
320 return 0;
321 }
322 /*
323 * Queue up the newly allocated to be processed in TCM thread context.
324 */
325 transport_generic_handle_cdb_map(se_cmd);
326 return 0;
327}
328
329/*
330 * Called from SCSI EH process context to issue a LUN_RESET TMR
331 * to struct scsi_device
332 */
333static int tcm_loop_device_reset(struct scsi_cmnd *sc)
334{
335 struct se_cmd *se_cmd = NULL;
336 struct se_portal_group *se_tpg;
337 struct se_session *se_sess;
338 struct tcm_loop_cmd *tl_cmd = NULL;
339 struct tcm_loop_hba *tl_hba;
340 struct tcm_loop_nexus *tl_nexus;
341 struct tcm_loop_tmr *tl_tmr = NULL;
342 struct tcm_loop_tpg *tl_tpg;
343 int ret = FAILED;
344 /*
345 * Locate the tcm_loop_hba_t pointer
346 */
347 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
348 /*
349 * Locate the tl_nexus and se_sess pointers
350 */
351 tl_nexus = tl_hba->tl_nexus;
352 if (!tl_nexus) {
353 printk(KERN_ERR "Unable to perform device reset without"
354 " active I_T Nexus\n");
355 return FAILED;
356 }
357 se_sess = tl_nexus->se_sess;
358 /*
359 * Locate the tl_tpg and se_tpg pointers from TargetID in sc->device->id
360 */
361 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
362 se_tpg = &tl_tpg->tl_se_tpg;
363
364 tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL);
365 if (!tl_cmd) {
366 printk(KERN_ERR "Unable to allocate memory for tl_cmd\n");
367 return FAILED;
368 }
369
370 tl_tmr = kzalloc(sizeof(struct tcm_loop_tmr), GFP_KERNEL);
371 if (!tl_tmr) {
372 printk(KERN_ERR "Unable to allocate memory for tl_tmr\n");
373 goto release;
374 }
375 init_waitqueue_head(&tl_tmr->tl_tmr_wait);
376
377 se_cmd = &tl_cmd->tl_se_cmd;
378 /*
379 * Initialize struct se_cmd descriptor from target_core_mod infrastructure
380 */
381 transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, 0,
382 DMA_NONE, TASK_ATTR_SIMPLE,
383 &tl_cmd->tl_sense_buf[0]);
384 /*
385 * Allocate the LUN_RESET TMR
386 */
387 se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd, (void *)tl_tmr,
388 TMR_LUN_RESET);
389 if (!se_cmd->se_tmr_req)
390 goto release;
391 /*
392 * Locate the underlying TCM struct se_lun from sc->device->lun
393 */
394 if (transport_get_lun_for_tmr(se_cmd, sc->device->lun) < 0)
395 goto release;
396 /*
397 * Queue the TMR to TCM Core and sleep waiting for tcm_loop_queue_tm_rsp()
398 * to wake us up.
399 */
400 transport_generic_handle_tmr(se_cmd);
401 wait_event(tl_tmr->tl_tmr_wait, atomic_read(&tl_tmr->tmr_complete));
402 /*
403 * The TMR LUN_RESET has completed, check the response status and
404 * then release allocations.
405 */
406 ret = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ?
407 SUCCESS : FAILED;
408release:
409 if (se_cmd)
410 transport_generic_free_cmd(se_cmd, 1, 1, 0);
411 else
412 kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
413 kfree(tl_tmr);
414 return ret;
415}
416
417static int tcm_loop_slave_alloc(struct scsi_device *sd)
418{
419 set_bit(QUEUE_FLAG_BIDI, &sd->request_queue->queue_flags);
420 return 0;
421}
422
423static int tcm_loop_slave_configure(struct scsi_device *sd)
424{
425 return 0;
426}
427
428static struct scsi_host_template tcm_loop_driver_template = {
429 .proc_info = tcm_loop_proc_info,
430 .proc_name = "tcm_loopback",
431 .name = "TCM_Loopback",
432 .queuecommand = tcm_loop_queuecommand,
433 .change_queue_depth = tcm_loop_change_queue_depth,
434 .eh_device_reset_handler = tcm_loop_device_reset,
435 .can_queue = TL_SCSI_CAN_QUEUE,
436 .this_id = -1,
437 .sg_tablesize = TL_SCSI_SG_TABLESIZE,
438 .cmd_per_lun = TL_SCSI_CMD_PER_LUN,
439 .max_sectors = TL_SCSI_MAX_SECTORS,
440 .use_clustering = DISABLE_CLUSTERING,
441 .slave_alloc = tcm_loop_slave_alloc,
442 .slave_configure = tcm_loop_slave_configure,
443 .module = THIS_MODULE,
444};
445
446static int tcm_loop_driver_probe(struct device *dev)
447{
448 struct tcm_loop_hba *tl_hba;
449 struct Scsi_Host *sh;
450 int error;
451
452 tl_hba = to_tcm_loop_hba(dev);
453
454 sh = scsi_host_alloc(&tcm_loop_driver_template,
455 sizeof(struct tcm_loop_hba));
456 if (!sh) {
457 printk(KERN_ERR "Unable to allocate struct scsi_host\n");
458 return -ENODEV;
459 }
460 tl_hba->sh = sh;
461
462 /*
463 * Assign the struct tcm_loop_hba pointer to struct Scsi_Host->hostdata
464 */
465 *((struct tcm_loop_hba **)sh->hostdata) = tl_hba;
466 /*
467 * Setup single ID, Channel and LUN for now..
468 */
469 sh->max_id = 2;
470 sh->max_lun = 0;
471 sh->max_channel = 0;
472 sh->max_cmd_len = TL_SCSI_MAX_CMD_LEN;
473
474 error = scsi_add_host(sh, &tl_hba->dev);
475 if (error) {
476 printk(KERN_ERR "%s: scsi_add_host failed\n", __func__);
477 scsi_host_put(sh);
478 return -ENODEV;
479 }
480 return 0;
481}
482
483static int tcm_loop_driver_remove(struct device *dev)
484{
485 struct tcm_loop_hba *tl_hba;
486 struct Scsi_Host *sh;
487
488 tl_hba = to_tcm_loop_hba(dev);
489 sh = tl_hba->sh;
490
491 scsi_remove_host(sh);
492 scsi_host_put(sh);
493 return 0;
494}
495
496static void tcm_loop_release_adapter(struct device *dev)
497{
498 struct tcm_loop_hba *tl_hba = to_tcm_loop_hba(dev);
499
500 kfree(tl_hba);
501}
502
503/*
504 * Called from tcm_loop_make_scsi_hba() in tcm_loop_configfs.c
505 */
506static int tcm_loop_setup_hba_bus(struct tcm_loop_hba *tl_hba, int tcm_loop_host_id)
507{
508 int ret;
509
510 tl_hba->dev.bus = &tcm_loop_lld_bus;
511 tl_hba->dev.parent = tcm_loop_primary;
512 tl_hba->dev.release = &tcm_loop_release_adapter;
513 dev_set_name(&tl_hba->dev, "tcm_loop_adapter_%d", tcm_loop_host_id);
514
515 ret = device_register(&tl_hba->dev);
516 if (ret) {
517 printk(KERN_ERR "device_register() failed for"
518 " tl_hba->dev: %d\n", ret);
519 return -ENODEV;
520 }
521
522 return 0;
523}
524
525/*
526 * Called from tcm_loop_fabric_init() in tcl_loop_fabric.c to load the emulated
527 * tcm_loop SCSI bus.
528 */
529static int tcm_loop_alloc_core_bus(void)
530{
531 int ret;
532
533 tcm_loop_primary = root_device_register("tcm_loop_0");
534 if (IS_ERR(tcm_loop_primary)) {
535 printk(KERN_ERR "Unable to allocate tcm_loop_primary\n");
536 return PTR_ERR(tcm_loop_primary);
537 }
538
539 ret = bus_register(&tcm_loop_lld_bus);
540 if (ret) {
541 printk(KERN_ERR "bus_register() failed for tcm_loop_lld_bus\n");
542 goto dev_unreg;
543 }
544
545 ret = driver_register(&tcm_loop_driverfs);
546 if (ret) {
547 printk(KERN_ERR "driver_register() failed for"
548 "tcm_loop_driverfs\n");
549 goto bus_unreg;
550 }
551
552 printk(KERN_INFO "Initialized TCM Loop Core Bus\n");
553 return ret;
554
555bus_unreg:
556 bus_unregister(&tcm_loop_lld_bus);
557dev_unreg:
558 root_device_unregister(tcm_loop_primary);
559 return ret;
560}
561
562static void tcm_loop_release_core_bus(void)
563{
564 driver_unregister(&tcm_loop_driverfs);
565 bus_unregister(&tcm_loop_lld_bus);
566 root_device_unregister(tcm_loop_primary);
567
568 printk(KERN_INFO "Releasing TCM Loop Core BUS\n");
569}
570
571static char *tcm_loop_get_fabric_name(void)
572{
573 return "loopback";
574}
575
576static u8 tcm_loop_get_fabric_proto_ident(struct se_portal_group *se_tpg)
577{
578 struct tcm_loop_tpg *tl_tpg =
579 (struct tcm_loop_tpg *)se_tpg->se_tpg_fabric_ptr;
580 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
581 /*
582 * tl_proto_id is set at tcm_loop_configfs.c:tcm_loop_make_scsi_hba()
583 * time based on the protocol dependent prefix of the passed configfs group.
584 *
585 * Based upon tl_proto_id, TCM_Loop emulates the requested fabric
586 * ProtocolID using target_core_fabric_lib.c symbols.
587 */
588 switch (tl_hba->tl_proto_id) {
589 case SCSI_PROTOCOL_SAS:
590 return sas_get_fabric_proto_ident(se_tpg);
591 case SCSI_PROTOCOL_FCP:
592 return fc_get_fabric_proto_ident(se_tpg);
593 case SCSI_PROTOCOL_ISCSI:
594 return iscsi_get_fabric_proto_ident(se_tpg);
595 default:
596 printk(KERN_ERR "Unknown tl_proto_id: 0x%02x, using"
597 " SAS emulation\n", tl_hba->tl_proto_id);
598 break;
599 }
600
601 return sas_get_fabric_proto_ident(se_tpg);
602}
603
604static char *tcm_loop_get_endpoint_wwn(struct se_portal_group *se_tpg)
605{
606 struct tcm_loop_tpg *tl_tpg =
607 (struct tcm_loop_tpg *)se_tpg->se_tpg_fabric_ptr;
608 /*
609 * Return the passed NAA identifier for the SAS Target Port
610 */
611 return &tl_tpg->tl_hba->tl_wwn_address[0];
612}
613
614static u16 tcm_loop_get_tag(struct se_portal_group *se_tpg)
615{
616 struct tcm_loop_tpg *tl_tpg =
617 (struct tcm_loop_tpg *)se_tpg->se_tpg_fabric_ptr;
618 /*
619 * This Tag is used when forming SCSI Name identifier in EVPD=1 0x83
620 * to represent the SCSI Target Port.
621 */
622 return tl_tpg->tl_tpgt;
623}
624
625static u32 tcm_loop_get_default_depth(struct se_portal_group *se_tpg)
626{
627 return 1;
628}
629
630static u32 tcm_loop_get_pr_transport_id(
631 struct se_portal_group *se_tpg,
632 struct se_node_acl *se_nacl,
633 struct t10_pr_registration *pr_reg,
634 int *format_code,
635 unsigned char *buf)
636{
637 struct tcm_loop_tpg *tl_tpg =
638 (struct tcm_loop_tpg *)se_tpg->se_tpg_fabric_ptr;
639 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
640
641 switch (tl_hba->tl_proto_id) {
642 case SCSI_PROTOCOL_SAS:
643 return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
644 format_code, buf);
645 case SCSI_PROTOCOL_FCP:
646 return fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
647 format_code, buf);
648 case SCSI_PROTOCOL_ISCSI:
649 return iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
650 format_code, buf);
651 default:
652 printk(KERN_ERR "Unknown tl_proto_id: 0x%02x, using"
653 " SAS emulation\n", tl_hba->tl_proto_id);
654 break;
655 }
656
657 return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
658 format_code, buf);
659}
660
661static u32 tcm_loop_get_pr_transport_id_len(
662 struct se_portal_group *se_tpg,
663 struct se_node_acl *se_nacl,
664 struct t10_pr_registration *pr_reg,
665 int *format_code)
666{
667 struct tcm_loop_tpg *tl_tpg =
668 (struct tcm_loop_tpg *)se_tpg->se_tpg_fabric_ptr;
669 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
670
671 switch (tl_hba->tl_proto_id) {
672 case SCSI_PROTOCOL_SAS:
673 return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
674 format_code);
675 case SCSI_PROTOCOL_FCP:
676 return fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
677 format_code);
678 case SCSI_PROTOCOL_ISCSI:
679 return iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
680 format_code);
681 default:
682 printk(KERN_ERR "Unknown tl_proto_id: 0x%02x, using"
683 " SAS emulation\n", tl_hba->tl_proto_id);
684 break;
685 }
686
687 return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
688 format_code);
689}
690
691/*
692 * Used for handling SCSI fabric dependent TransportIDs in SPC-3 and above
693 * Persistent Reservation SPEC_I_PT=1 and PROUT REGISTER_AND_MOVE operations.
694 */
695static char *tcm_loop_parse_pr_out_transport_id(
696 struct se_portal_group *se_tpg,
697 const char *buf,
698 u32 *out_tid_len,
699 char **port_nexus_ptr)
700{
701 struct tcm_loop_tpg *tl_tpg =
702 (struct tcm_loop_tpg *)se_tpg->se_tpg_fabric_ptr;
703 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
704
705 switch (tl_hba->tl_proto_id) {
706 case SCSI_PROTOCOL_SAS:
707 return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
708 port_nexus_ptr);
709 case SCSI_PROTOCOL_FCP:
710 return fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
711 port_nexus_ptr);
712 case SCSI_PROTOCOL_ISCSI:
713 return iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
714 port_nexus_ptr);
715 default:
716 printk(KERN_ERR "Unknown tl_proto_id: 0x%02x, using"
717 " SAS emulation\n", tl_hba->tl_proto_id);
718 break;
719 }
720
721 return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
722 port_nexus_ptr);
723}
724
725/*
726 * Returning (1) here allows for target_core_mod struct se_node_acl to be generated
727 * based upon the incoming fabric dependent SCSI Initiator Port
728 */
729static int tcm_loop_check_demo_mode(struct se_portal_group *se_tpg)
730{
731 return 1;
732}
733
734static int tcm_loop_check_demo_mode_cache(struct se_portal_group *se_tpg)
735{
736 return 0;
737}
738
739/*
740 * Allow I_T Nexus full READ-WRITE access without explict Initiator Node ACLs for
741 * local virtual Linux/SCSI LLD passthrough into VM hypervisor guest
742 */
743static int tcm_loop_check_demo_mode_write_protect(struct se_portal_group *se_tpg)
744{
745 return 0;
746}
747
748/*
749 * Because TCM_Loop does not use explict ACLs and MappedLUNs, this will
750 * never be called for TCM_Loop by target_core_fabric_configfs.c code.
751 * It has been added here as a nop for target_fabric_tf_ops_check()
752 */
753static int tcm_loop_check_prod_mode_write_protect(struct se_portal_group *se_tpg)
754{
755 return 0;
756}
757
758static struct se_node_acl *tcm_loop_tpg_alloc_fabric_acl(
759 struct se_portal_group *se_tpg)
760{
761 struct tcm_loop_nacl *tl_nacl;
762
763 tl_nacl = kzalloc(sizeof(struct tcm_loop_nacl), GFP_KERNEL);
764 if (!tl_nacl) {
765 printk(KERN_ERR "Unable to allocate struct tcm_loop_nacl\n");
766 return NULL;
767 }
768
769 return &tl_nacl->se_node_acl;
770}
771
772static void tcm_loop_tpg_release_fabric_acl(
773 struct se_portal_group *se_tpg,
774 struct se_node_acl *se_nacl)
775{
776 struct tcm_loop_nacl *tl_nacl = container_of(se_nacl,
777 struct tcm_loop_nacl, se_node_acl);
778
779 kfree(tl_nacl);
780}
781
782static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg)
783{
784 return 1;
785}
786
787static void tcm_loop_new_cmd_failure(struct se_cmd *se_cmd)
788{
789 /*
790 * Since TCM_loop is already passing struct scatterlist data from
791 * struct scsi_cmnd, no more Linux/SCSI failure dependent state need
792 * to be handled here.
793 */
794 return;
795}
796
797static int tcm_loop_is_state_remove(struct se_cmd *se_cmd)
798{
799 /*
800 * Assume struct scsi_cmnd is not in remove state..
801 */
802 return 0;
803}
804
805static int tcm_loop_sess_logged_in(struct se_session *se_sess)
806{
807 /*
808 * Assume that TL Nexus is always active
809 */
810 return 1;
811}
812
813static u32 tcm_loop_sess_get_index(struct se_session *se_sess)
814{
815 return 1;
816}
817
818static void tcm_loop_set_default_node_attributes(struct se_node_acl *se_acl)
819{
820 return;
821}
822
823static u32 tcm_loop_get_task_tag(struct se_cmd *se_cmd)
824{
825 return 1;
826}
827
828static int tcm_loop_get_cmd_state(struct se_cmd *se_cmd)
829{
830 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
831 struct tcm_loop_cmd, tl_se_cmd);
832
833 return tl_cmd->sc_cmd_state;
834}
835
836static int tcm_loop_shutdown_session(struct se_session *se_sess)
837{
838 return 0;
839}
840
841static void tcm_loop_close_session(struct se_session *se_sess)
842{
843 return;
844};
845
846static void tcm_loop_stop_session(
847 struct se_session *se_sess,
848 int sess_sleep,
849 int conn_sleep)
850{
851 return;
852}
853
854static void tcm_loop_fall_back_to_erl0(struct se_session *se_sess)
855{
856 return;
857}
858
859static int tcm_loop_write_pending(struct se_cmd *se_cmd)
860{
861 /*
862 * Since Linux/SCSI has already sent down a struct scsi_cmnd
863 * sc->sc_data_direction of DMA_TO_DEVICE with struct scatterlist array
864 * memory, and memory has already been mapped to struct se_cmd->t_mem_list
865 * format with transport_generic_map_mem_to_cmd().
866 *
867 * We now tell TCM to add this WRITE CDB directly into the TCM storage
868 * object execution queue.
869 */
870 transport_generic_process_write(se_cmd);
871 return 0;
872}
873
874static int tcm_loop_write_pending_status(struct se_cmd *se_cmd)
875{
876 return 0;
877}
878
879static int tcm_loop_queue_data_in(struct se_cmd *se_cmd)
880{
881 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
882 struct tcm_loop_cmd, tl_se_cmd);
883 struct scsi_cmnd *sc = tl_cmd->sc;
884
885 TL_CDB_DEBUG("tcm_loop_queue_data_in() called for scsi_cmnd: %p"
886 " cdb: 0x%02x\n", sc, sc->cmnd[0]);
887
888 sc->result = SAM_STAT_GOOD;
889 set_host_byte(sc, DID_OK);
890 sc->scsi_done(sc);
891 return 0;
892}
893
894static int tcm_loop_queue_status(struct se_cmd *se_cmd)
895{
896 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
897 struct tcm_loop_cmd, tl_se_cmd);
898 struct scsi_cmnd *sc = tl_cmd->sc;
899
900 TL_CDB_DEBUG("tcm_loop_queue_status() called for scsi_cmnd: %p"
901 " cdb: 0x%02x\n", sc, sc->cmnd[0]);
902
903 if (se_cmd->sense_buffer &&
904 ((se_cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||
905 (se_cmd->se_cmd_flags & SCF_EMULATED_TASK_SENSE))) {
906
907 memcpy((void *)sc->sense_buffer, (void *)se_cmd->sense_buffer,
908 SCSI_SENSE_BUFFERSIZE);
909 sc->result = SAM_STAT_CHECK_CONDITION;
910 set_driver_byte(sc, DRIVER_SENSE);
911 } else
912 sc->result = se_cmd->scsi_status;
913
914 set_host_byte(sc, DID_OK);
915 sc->scsi_done(sc);
916 return 0;
917}
918
919static int tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd)
920{
921 struct se_tmr_req *se_tmr = se_cmd->se_tmr_req;
922 struct tcm_loop_tmr *tl_tmr = se_tmr->fabric_tmr_ptr;
923 /*
924 * The SCSI EH thread will be sleeping on se_tmr->tl_tmr_wait, go ahead
925 * and wake up the wait_queue_head_t in tcm_loop_device_reset()
926 */
927 atomic_set(&tl_tmr->tmr_complete, 1);
928 wake_up(&tl_tmr->tl_tmr_wait);
929 return 0;
930}
931
932static u16 tcm_loop_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
933{
934 return 0;
935}
936
937static u16 tcm_loop_get_fabric_sense_len(void)
938{
939 return 0;
940}
941
942static u64 tcm_loop_pack_lun(unsigned int lun)
943{
944 u64 result;
945
946 /* LSB of lun into byte 1 big-endian */
947 result = ((lun & 0xff) << 8);
948 /* use flat space addressing method */
949 result |= 0x40 | ((lun >> 8) & 0x3f);
950
951 return cpu_to_le64(result);
952}
953
954static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba)
955{
956 switch (tl_hba->tl_proto_id) {
957 case SCSI_PROTOCOL_SAS:
958 return "SAS";
959 case SCSI_PROTOCOL_FCP:
960 return "FCP";
961 case SCSI_PROTOCOL_ISCSI:
962 return "iSCSI";
963 default:
964 break;
965 }
966
967 return "Unknown";
968}
969
970/* Start items for tcm_loop_port_cit */
971
972static int tcm_loop_port_link(
973 struct se_portal_group *se_tpg,
974 struct se_lun *lun)
975{
976 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
977 struct tcm_loop_tpg, tl_se_tpg);
978 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
979
980 atomic_inc(&tl_tpg->tl_tpg_port_count);
981 smp_mb__after_atomic_inc();
982 /*
983 * Add Linux/SCSI struct scsi_device by HCTL
984 */
985 scsi_add_device(tl_hba->sh, 0, tl_tpg->tl_tpgt, lun->unpacked_lun);
986
987 printk(KERN_INFO "TCM_Loop_ConfigFS: Port Link Successful\n");
988 return 0;
989}
990
991static void tcm_loop_port_unlink(
992 struct se_portal_group *se_tpg,
993 struct se_lun *se_lun)
994{
995 struct scsi_device *sd;
996 struct tcm_loop_hba *tl_hba;
997 struct tcm_loop_tpg *tl_tpg;
998
999 tl_tpg = container_of(se_tpg, struct tcm_loop_tpg, tl_se_tpg);
1000 tl_hba = tl_tpg->tl_hba;
1001
1002 sd = scsi_device_lookup(tl_hba->sh, 0, tl_tpg->tl_tpgt,
1003 se_lun->unpacked_lun);
1004 if (!sd) {
1005 printk(KERN_ERR "Unable to locate struct scsi_device for %d:%d:"
1006 "%d\n", 0, tl_tpg->tl_tpgt, se_lun->unpacked_lun);
1007 return;
1008 }
1009 /*
1010 * Remove Linux/SCSI struct scsi_device by HCTL
1011 */
1012 scsi_remove_device(sd);
1013 scsi_device_put(sd);
1014
1015 atomic_dec(&tl_tpg->tl_tpg_port_count);
1016 smp_mb__after_atomic_dec();
1017
1018 printk(KERN_INFO "TCM_Loop_ConfigFS: Port Unlink Successful\n");
1019}
1020
1021/* End items for tcm_loop_port_cit */
1022
1023/* Start items for tcm_loop_nexus_cit */
1024
1025static int tcm_loop_make_nexus(
1026 struct tcm_loop_tpg *tl_tpg,
1027 const char *name)
1028{
1029 struct se_portal_group *se_tpg;
1030 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
1031 struct tcm_loop_nexus *tl_nexus;
1032
1033 if (tl_tpg->tl_hba->tl_nexus) {
1034 printk(KERN_INFO "tl_tpg->tl_hba->tl_nexus already exists\n");
1035 return -EEXIST;
1036 }
1037 se_tpg = &tl_tpg->tl_se_tpg;
1038
1039 tl_nexus = kzalloc(sizeof(struct tcm_loop_nexus), GFP_KERNEL);
1040 if (!tl_nexus) {
1041 printk(KERN_ERR "Unable to allocate struct tcm_loop_nexus\n");
1042 return -ENOMEM;
1043 }
1044 /*
1045 * Initialize the struct se_session pointer
1046 */
1047 tl_nexus->se_sess = transport_init_session();
1048 if (!tl_nexus->se_sess)
1049 goto out;
1050 /*
1051 * Since we are running in 'demo mode' this call with generate a
1052 * struct se_node_acl for the tcm_loop struct se_portal_group with the SCSI
1053 * Initiator port name of the passed configfs group 'name'.
1054 */
1055 tl_nexus->se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
1056 se_tpg, (unsigned char *)name);
1057 if (!tl_nexus->se_sess->se_node_acl) {
1058 transport_free_session(tl_nexus->se_sess);
1059 goto out;
1060 }
1061 /*
1062 * Now, register the SAS I_T Nexus as active with the call to
1063 * transport_register_session()
1064 */
1065 __transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl,
1066 tl_nexus->se_sess, (void *)tl_nexus);
1067 tl_tpg->tl_hba->tl_nexus = tl_nexus;
1068 printk(KERN_INFO "TCM_Loop_ConfigFS: Established I_T Nexus to emulated"
1069 " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba),
1070 name);
1071 return 0;
1072
1073out:
1074 kfree(tl_nexus);
1075 return -ENOMEM;
1076}
1077
1078static int tcm_loop_drop_nexus(
1079 struct tcm_loop_tpg *tpg)
1080{
1081 struct se_session *se_sess;
1082 struct tcm_loop_nexus *tl_nexus;
1083 struct tcm_loop_hba *tl_hba = tpg->tl_hba;
1084
1085 tl_nexus = tpg->tl_hba->tl_nexus;
1086 if (!tl_nexus)
1087 return -ENODEV;
1088
1089 se_sess = tl_nexus->se_sess;
1090 if (!se_sess)
1091 return -ENODEV;
1092
1093 if (atomic_read(&tpg->tl_tpg_port_count)) {
1094 printk(KERN_ERR "Unable to remove TCM_Loop I_T Nexus with"
1095 " active TPG port count: %d\n",
1096 atomic_read(&tpg->tl_tpg_port_count));
1097 return -EPERM;
1098 }
1099
1100 printk(KERN_INFO "TCM_Loop_ConfigFS: Removing I_T Nexus to emulated"
1101 " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba),
1102 tl_nexus->se_sess->se_node_acl->initiatorname);
1103 /*
1104 * Release the SCSI I_T Nexus to the emulated SAS Target Port
1105 */
1106 transport_deregister_session(tl_nexus->se_sess);
1107 tpg->tl_hba->tl_nexus = NULL;
1108 kfree(tl_nexus);
1109 return 0;
1110}
1111
1112/* End items for tcm_loop_nexus_cit */
1113
1114static ssize_t tcm_loop_tpg_show_nexus(
1115 struct se_portal_group *se_tpg,
1116 char *page)
1117{
1118 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
1119 struct tcm_loop_tpg, tl_se_tpg);
1120 struct tcm_loop_nexus *tl_nexus;
1121 ssize_t ret;
1122
1123 tl_nexus = tl_tpg->tl_hba->tl_nexus;
1124 if (!tl_nexus)
1125 return -ENODEV;
1126
1127 ret = snprintf(page, PAGE_SIZE, "%s\n",
1128 tl_nexus->se_sess->se_node_acl->initiatorname);
1129
1130 return ret;
1131}
1132
1133static ssize_t tcm_loop_tpg_store_nexus(
1134 struct se_portal_group *se_tpg,
1135 const char *page,
1136 size_t count)
1137{
1138 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
1139 struct tcm_loop_tpg, tl_se_tpg);
1140 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
1141 unsigned char i_port[TL_WWN_ADDR_LEN], *ptr, *port_ptr;
1142 int ret;
1143 /*
1144 * Shutdown the active I_T nexus if 'NULL' is passed..
1145 */
1146 if (!strncmp(page, "NULL", 4)) {
1147 ret = tcm_loop_drop_nexus(tl_tpg);
1148 return (!ret) ? count : ret;
1149 }
1150 /*
1151 * Otherwise make sure the passed virtual Initiator port WWN matches
1152 * the fabric protocol_id set in tcm_loop_make_scsi_hba(), and call
1153 * tcm_loop_make_nexus()
1154 */
1155 if (strlen(page) > TL_WWN_ADDR_LEN) {
1156 printk(KERN_ERR "Emulated NAA Sas Address: %s, exceeds"
1157 " max: %d\n", page, TL_WWN_ADDR_LEN);
1158 return -EINVAL;
1159 }
1160 snprintf(&i_port[0], TL_WWN_ADDR_LEN, "%s", page);
1161
1162 ptr = strstr(i_port, "naa.");
1163 if (ptr) {
1164 if (tl_hba->tl_proto_id != SCSI_PROTOCOL_SAS) {
1165 printk(KERN_ERR "Passed SAS Initiator Port %s does not"
1166 " match target port protoid: %s\n", i_port,
1167 tcm_loop_dump_proto_id(tl_hba));
1168 return -EINVAL;
1169 }
1170 port_ptr = &i_port[0];
1171 goto check_newline;
1172 }
1173 ptr = strstr(i_port, "fc.");
1174 if (ptr) {
1175 if (tl_hba->tl_proto_id != SCSI_PROTOCOL_FCP) {
1176 printk(KERN_ERR "Passed FCP Initiator Port %s does not"
1177 " match target port protoid: %s\n", i_port,
1178 tcm_loop_dump_proto_id(tl_hba));
1179 return -EINVAL;
1180 }
1181 port_ptr = &i_port[3]; /* Skip over "fc." */
1182 goto check_newline;
1183 }
1184 ptr = strstr(i_port, "iqn.");
1185 if (ptr) {
1186 if (tl_hba->tl_proto_id != SCSI_PROTOCOL_ISCSI) {
1187 printk(KERN_ERR "Passed iSCSI Initiator Port %s does not"
1188 " match target port protoid: %s\n", i_port,
1189 tcm_loop_dump_proto_id(tl_hba));
1190 return -EINVAL;
1191 }
1192 port_ptr = &i_port[0];
1193 goto check_newline;
1194 }
1195 printk(KERN_ERR "Unable to locate prefix for emulated Initiator Port:"
1196 " %s\n", i_port);
1197 return -EINVAL;
1198 /*
1199 * Clear any trailing newline for the NAA WWN
1200 */
1201check_newline:
1202 if (i_port[strlen(i_port)-1] == '\n')
1203 i_port[strlen(i_port)-1] = '\0';
1204
1205 ret = tcm_loop_make_nexus(tl_tpg, port_ptr);
1206 if (ret < 0)
1207 return ret;
1208
1209 return count;
1210}
1211
1212TF_TPG_BASE_ATTR(tcm_loop, nexus, S_IRUGO | S_IWUSR);
1213
1214static struct configfs_attribute *tcm_loop_tpg_attrs[] = {
1215 &tcm_loop_tpg_nexus.attr,
1216 NULL,
1217};
1218
1219/* Start items for tcm_loop_naa_cit */
1220
1221struct se_portal_group *tcm_loop_make_naa_tpg(
1222 struct se_wwn *wwn,
1223 struct config_group *group,
1224 const char *name)
1225{
1226 struct tcm_loop_hba *tl_hba = container_of(wwn,
1227 struct tcm_loop_hba, tl_hba_wwn);
1228 struct tcm_loop_tpg *tl_tpg;
1229 char *tpgt_str, *end_ptr;
1230 int ret;
1231 unsigned short int tpgt;
1232
1233 tpgt_str = strstr(name, "tpgt_");
1234 if (!tpgt_str) {
1235 printk(KERN_ERR "Unable to locate \"tpgt_#\" directory"
1236 " group\n");
1237 return ERR_PTR(-EINVAL);
1238 }
1239 tpgt_str += 5; /* Skip ahead of "tpgt_" */
1240 tpgt = (unsigned short int) simple_strtoul(tpgt_str, &end_ptr, 0);
1241
1242 if (tpgt > TL_TPGS_PER_HBA) {
1243 printk(KERN_ERR "Passed tpgt: %hu exceeds TL_TPGS_PER_HBA:"
1244 " %u\n", tpgt, TL_TPGS_PER_HBA);
1245 return ERR_PTR(-EINVAL);
1246 }
1247 tl_tpg = &tl_hba->tl_hba_tpgs[tpgt];
1248 tl_tpg->tl_hba = tl_hba;
1249 tl_tpg->tl_tpgt = tpgt;
1250 /*
1251 * Register the tl_tpg as a emulated SAS TCM Target Endpoint
1252 */
1253 ret = core_tpg_register(&tcm_loop_fabric_configfs->tf_ops,
1254 wwn, &tl_tpg->tl_se_tpg, (void *)tl_tpg,
1255 TRANSPORT_TPG_TYPE_NORMAL);
1256 if (ret < 0)
1257 return ERR_PTR(-ENOMEM);
1258
1259 printk(KERN_INFO "TCM_Loop_ConfigFS: Allocated Emulated %s"
1260 " Target Port %s,t,0x%04x\n", tcm_loop_dump_proto_id(tl_hba),
1261 config_item_name(&wwn->wwn_group.cg_item), tpgt);
1262
1263 return &tl_tpg->tl_se_tpg;
1264}
1265
1266void tcm_loop_drop_naa_tpg(
1267 struct se_portal_group *se_tpg)
1268{
1269 struct se_wwn *wwn = se_tpg->se_tpg_wwn;
1270 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
1271 struct tcm_loop_tpg, tl_se_tpg);
1272 struct tcm_loop_hba *tl_hba;
1273 unsigned short tpgt;
1274
1275 tl_hba = tl_tpg->tl_hba;
1276 tpgt = tl_tpg->tl_tpgt;
1277 /*
1278 * Release the I_T Nexus for the Virtual SAS link if present
1279 */
1280 tcm_loop_drop_nexus(tl_tpg);
1281 /*
1282 * Deregister the tl_tpg as a emulated SAS TCM Target Endpoint
1283 */
1284 core_tpg_deregister(se_tpg);
1285
1286 printk(KERN_INFO "TCM_Loop_ConfigFS: Deallocated Emulated %s"
1287 " Target Port %s,t,0x%04x\n", tcm_loop_dump_proto_id(tl_hba),
1288 config_item_name(&wwn->wwn_group.cg_item), tpgt);
1289}
1290
1291/* End items for tcm_loop_naa_cit */
1292
1293/* Start items for tcm_loop_cit */
1294
1295struct se_wwn *tcm_loop_make_scsi_hba(
1296 struct target_fabric_configfs *tf,
1297 struct config_group *group,
1298 const char *name)
1299{
1300 struct tcm_loop_hba *tl_hba;
1301 struct Scsi_Host *sh;
1302 char *ptr;
1303 int ret, off = 0;
1304
1305 tl_hba = kzalloc(sizeof(struct tcm_loop_hba), GFP_KERNEL);
1306 if (!tl_hba) {
1307 printk(KERN_ERR "Unable to allocate struct tcm_loop_hba\n");
1308 return ERR_PTR(-ENOMEM);
1309 }
1310 /*
1311 * Determine the emulated Protocol Identifier and Target Port Name
1312 * based on the incoming configfs directory name.
1313 */
1314 ptr = strstr(name, "naa.");
1315 if (ptr) {
1316 tl_hba->tl_proto_id = SCSI_PROTOCOL_SAS;
1317 goto check_len;
1318 }
1319 ptr = strstr(name, "fc.");
1320 if (ptr) {
1321 tl_hba->tl_proto_id = SCSI_PROTOCOL_FCP;
1322 off = 3; /* Skip over "fc." */
1323 goto check_len;
1324 }
1325 ptr = strstr(name, "iqn.");
1326 if (ptr) {
1327 tl_hba->tl_proto_id = SCSI_PROTOCOL_ISCSI;
1328 goto check_len;
1329 }
1330
1331 printk(KERN_ERR "Unable to locate prefix for emulated Target Port:"
1332 " %s\n", name);
1333 return ERR_PTR(-EINVAL);
1334
1335check_len:
1336 if (strlen(name) > TL_WWN_ADDR_LEN) {
1337 printk(KERN_ERR "Emulated NAA %s Address: %s, exceeds"
1338 " max: %d\n", name, tcm_loop_dump_proto_id(tl_hba),
1339 TL_WWN_ADDR_LEN);
1340 kfree(tl_hba);
1341 return ERR_PTR(-EINVAL);
1342 }
1343 snprintf(&tl_hba->tl_wwn_address[0], TL_WWN_ADDR_LEN, "%s", &name[off]);
1344
1345 /*
1346 * Call device_register(tl_hba->dev) to register the emulated
1347 * Linux/SCSI LLD of type struct Scsi_Host at tl_hba->sh after
1348 * device_register() callbacks in tcm_loop_driver_probe()
1349 */
1350 ret = tcm_loop_setup_hba_bus(tl_hba, tcm_loop_hba_no_cnt);
1351 if (ret)
1352 goto out;
1353
1354 sh = tl_hba->sh;
1355 tcm_loop_hba_no_cnt++;
1356 printk(KERN_INFO "TCM_Loop_ConfigFS: Allocated emulated Target"
1357 " %s Address: %s at Linux/SCSI Host ID: %d\n",
1358 tcm_loop_dump_proto_id(tl_hba), name, sh->host_no);
1359
1360 return &tl_hba->tl_hba_wwn;
1361out:
1362 kfree(tl_hba);
1363 return ERR_PTR(ret);
1364}
1365
1366void tcm_loop_drop_scsi_hba(
1367 struct se_wwn *wwn)
1368{
1369 struct tcm_loop_hba *tl_hba = container_of(wwn,
1370 struct tcm_loop_hba, tl_hba_wwn);
1371 int host_no = tl_hba->sh->host_no;
1372 /*
1373 * Call device_unregister() on the original tl_hba->dev.
1374 * tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will
1375 * release *tl_hba;
1376 */
1377 device_unregister(&tl_hba->dev);
1378
1379 printk(KERN_INFO "TCM_Loop_ConfigFS: Deallocated emulated Target"
1380 " SAS Address: %s at Linux/SCSI Host ID: %d\n",
1381 config_item_name(&wwn->wwn_group.cg_item), host_no);
1382}
1383
1384/* Start items for tcm_loop_cit */
1385static ssize_t tcm_loop_wwn_show_attr_version(
1386 struct target_fabric_configfs *tf,
1387 char *page)
1388{
1389 return sprintf(page, "TCM Loopback Fabric module %s\n", TCM_LOOP_VERSION);
1390}
1391
1392TF_WWN_ATTR_RO(tcm_loop, version);
1393
1394static struct configfs_attribute *tcm_loop_wwn_attrs[] = {
1395 &tcm_loop_wwn_version.attr,
1396 NULL,
1397};
1398
1399/* End items for tcm_loop_cit */
1400
1401static int tcm_loop_register_configfs(void)
1402{
1403 struct target_fabric_configfs *fabric;
1404 struct config_group *tf_cg;
1405 int ret;
1406 /*
1407 * Set the TCM Loop HBA counter to zero
1408 */
1409 tcm_loop_hba_no_cnt = 0;
1410 /*
1411 * Register the top level struct config_item_type with TCM core
1412 */
1413 fabric = target_fabric_configfs_init(THIS_MODULE, "loopback");
1414 if (!fabric) {
1415 printk(KERN_ERR "tcm_loop_register_configfs() failed!\n");
1416 return -1;
1417 }
1418 /*
1419 * Setup the fabric API of function pointers used by target_core_mod
1420 */
1421 fabric->tf_ops.get_fabric_name = &tcm_loop_get_fabric_name;
1422 fabric->tf_ops.get_fabric_proto_ident = &tcm_loop_get_fabric_proto_ident;
1423 fabric->tf_ops.tpg_get_wwn = &tcm_loop_get_endpoint_wwn;
1424 fabric->tf_ops.tpg_get_tag = &tcm_loop_get_tag;
1425 fabric->tf_ops.tpg_get_default_depth = &tcm_loop_get_default_depth;
1426 fabric->tf_ops.tpg_get_pr_transport_id = &tcm_loop_get_pr_transport_id;
1427 fabric->tf_ops.tpg_get_pr_transport_id_len =
1428 &tcm_loop_get_pr_transport_id_len;
1429 fabric->tf_ops.tpg_parse_pr_out_transport_id =
1430 &tcm_loop_parse_pr_out_transport_id;
1431 fabric->tf_ops.tpg_check_demo_mode = &tcm_loop_check_demo_mode;
1432 fabric->tf_ops.tpg_check_demo_mode_cache =
1433 &tcm_loop_check_demo_mode_cache;
1434 fabric->tf_ops.tpg_check_demo_mode_write_protect =
1435 &tcm_loop_check_demo_mode_write_protect;
1436 fabric->tf_ops.tpg_check_prod_mode_write_protect =
1437 &tcm_loop_check_prod_mode_write_protect;
1438 /*
1439 * The TCM loopback fabric module runs in demo-mode to a local
1440 * virtual SCSI device, so fabric dependent initator ACLs are
1441 * not required.
1442 */
1443 fabric->tf_ops.tpg_alloc_fabric_acl = &tcm_loop_tpg_alloc_fabric_acl;
1444 fabric->tf_ops.tpg_release_fabric_acl =
1445 &tcm_loop_tpg_release_fabric_acl;
1446 fabric->tf_ops.tpg_get_inst_index = &tcm_loop_get_inst_index;
1447 /*
1448 * Since tcm_loop is mapping physical memory from Linux/SCSI
1449 * struct scatterlist arrays for each struct scsi_cmnd I/O,
1450 * we do not need TCM to allocate a iovec array for
1451 * virtual memory address mappings
1452 */
1453 fabric->tf_ops.alloc_cmd_iovecs = NULL;
1454 /*
1455 * Used for setting up remaining TCM resources in process context
1456 */
1457 fabric->tf_ops.new_cmd_map = &tcm_loop_new_cmd_map;
1458 fabric->tf_ops.check_stop_free = &tcm_loop_check_stop_free;
1459 fabric->tf_ops.release_cmd_to_pool = &tcm_loop_deallocate_core_cmd;
1460 fabric->tf_ops.release_cmd_direct = &tcm_loop_deallocate_core_cmd;
1461 fabric->tf_ops.shutdown_session = &tcm_loop_shutdown_session;
1462 fabric->tf_ops.close_session = &tcm_loop_close_session;
1463 fabric->tf_ops.stop_session = &tcm_loop_stop_session;
1464 fabric->tf_ops.fall_back_to_erl0 = &tcm_loop_fall_back_to_erl0;
1465 fabric->tf_ops.sess_logged_in = &tcm_loop_sess_logged_in;
1466 fabric->tf_ops.sess_get_index = &tcm_loop_sess_get_index;
1467 fabric->tf_ops.sess_get_initiator_sid = NULL;
1468 fabric->tf_ops.write_pending = &tcm_loop_write_pending;
1469 fabric->tf_ops.write_pending_status = &tcm_loop_write_pending_status;
1470 /*
1471 * Not used for TCM loopback
1472 */
1473 fabric->tf_ops.set_default_node_attributes =
1474 &tcm_loop_set_default_node_attributes;
1475 fabric->tf_ops.get_task_tag = &tcm_loop_get_task_tag;
1476 fabric->tf_ops.get_cmd_state = &tcm_loop_get_cmd_state;
1477 fabric->tf_ops.new_cmd_failure = &tcm_loop_new_cmd_failure;
1478 fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in;
1479 fabric->tf_ops.queue_status = &tcm_loop_queue_status;
1480 fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp;
1481 fabric->tf_ops.set_fabric_sense_len = &tcm_loop_set_fabric_sense_len;
1482 fabric->tf_ops.get_fabric_sense_len = &tcm_loop_get_fabric_sense_len;
1483 fabric->tf_ops.is_state_remove = &tcm_loop_is_state_remove;
1484 fabric->tf_ops.pack_lun = &tcm_loop_pack_lun;
1485
1486 tf_cg = &fabric->tf_group;
1487 /*
1488 * Setup function pointers for generic logic in target_core_fabric_configfs.c
1489 */
1490 fabric->tf_ops.fabric_make_wwn = &tcm_loop_make_scsi_hba;
1491 fabric->tf_ops.fabric_drop_wwn = &tcm_loop_drop_scsi_hba;
1492 fabric->tf_ops.fabric_make_tpg = &tcm_loop_make_naa_tpg;
1493 fabric->tf_ops.fabric_drop_tpg = &tcm_loop_drop_naa_tpg;
1494 /*
1495 * fabric_post_link() and fabric_pre_unlink() are used for
1496 * registration and release of TCM Loop Virtual SCSI LUNs.
1497 */
1498 fabric->tf_ops.fabric_post_link = &tcm_loop_port_link;
1499 fabric->tf_ops.fabric_pre_unlink = &tcm_loop_port_unlink;
1500 fabric->tf_ops.fabric_make_np = NULL;
1501 fabric->tf_ops.fabric_drop_np = NULL;
1502 /*
1503 * Setup default attribute lists for various fabric->tf_cit_tmpl
1504 */
1505 TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = tcm_loop_wwn_attrs;
1506 TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = tcm_loop_tpg_attrs;
1507 TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL;
1508 TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL;
1509 TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL;
1510 /*
1511 * Once fabric->tf_ops has been setup, now register the fabric for
1512 * use within TCM
1513 */
1514 ret = target_fabric_configfs_register(fabric);
1515 if (ret < 0) {
1516 printk(KERN_ERR "target_fabric_configfs_register() for"
1517 " TCM_Loop failed!\n");
1518 target_fabric_configfs_free(fabric);
1519 return -1;
1520 }
1521 /*
1522 * Setup our local pointer to *fabric.
1523 */
1524 tcm_loop_fabric_configfs = fabric;
1525 printk(KERN_INFO "TCM_LOOP[0] - Set fabric ->"
1526 " tcm_loop_fabric_configfs\n");
1527 return 0;
1528}
1529
1530static void tcm_loop_deregister_configfs(void)
1531{
1532 if (!tcm_loop_fabric_configfs)
1533 return;
1534
1535 target_fabric_configfs_deregister(tcm_loop_fabric_configfs);
1536 tcm_loop_fabric_configfs = NULL;
1537 printk(KERN_INFO "TCM_LOOP[0] - Cleared"
1538 " tcm_loop_fabric_configfs\n");
1539}
1540
1541static int __init tcm_loop_fabric_init(void)
1542{
1543 int ret;
1544
1545 tcm_loop_cmd_cache = kmem_cache_create("tcm_loop_cmd_cache",
1546 sizeof(struct tcm_loop_cmd),
1547 __alignof__(struct tcm_loop_cmd),
1548 0, NULL);
1549 if (!tcm_loop_cmd_cache) {
1550 printk(KERN_ERR "kmem_cache_create() for"
1551 " tcm_loop_cmd_cache failed\n");
1552 return -ENOMEM;
1553 }
1554
1555 ret = tcm_loop_alloc_core_bus();
1556 if (ret)
1557 return ret;
1558
1559 ret = tcm_loop_register_configfs();
1560 if (ret) {
1561 tcm_loop_release_core_bus();
1562 return ret;
1563 }
1564
1565 return 0;
1566}
1567
1568static void __exit tcm_loop_fabric_exit(void)
1569{
1570 tcm_loop_deregister_configfs();
1571 tcm_loop_release_core_bus();
1572 kmem_cache_destroy(tcm_loop_cmd_cache);
1573}
1574
1575MODULE_DESCRIPTION("TCM loopback virtual Linux/SCSI fabric module");
1576MODULE_AUTHOR("Nicholas A. Bellinger <nab@risingtidesystems.com>");
1577MODULE_LICENSE("GPL");
1578module_init(tcm_loop_fabric_init);
1579module_exit(tcm_loop_fabric_exit);
diff --git a/drivers/target/loopback/tcm_loop.h b/drivers/target/loopback/tcm_loop.h
new file mode 100644
index 000000000000..7e9f7ab45548
--- /dev/null
+++ b/drivers/target/loopback/tcm_loop.h
@@ -0,0 +1,77 @@
1#define TCM_LOOP_VERSION "v2.1-rc1"
2#define TL_WWN_ADDR_LEN 256
3#define TL_TPGS_PER_HBA 32
4/*
5 * Defaults for struct scsi_host_template tcm_loop_driver_template
6 *
7 * We use large can_queue and cmd_per_lun here and let TCM enforce
8 * the underlying se_device_t->queue_depth.
9 */
10#define TL_SCSI_CAN_QUEUE 1024
11#define TL_SCSI_CMD_PER_LUN 1024
12#define TL_SCSI_MAX_SECTORS 1024
13#define TL_SCSI_SG_TABLESIZE 256
14/*
15 * Used in tcm_loop_driver_probe() for struct Scsi_Host->max_cmd_len
16 */
17#define TL_SCSI_MAX_CMD_LEN 32
18
19#ifdef CONFIG_LOOPBACK_TARGET_CDB_DEBUG
20# define TL_CDB_DEBUG(x...) printk(KERN_INFO x)
21#else
22# define TL_CDB_DEBUG(x...)
23#endif
24
25struct tcm_loop_cmd {
26 /* State of Linux/SCSI CDB+Data descriptor */
27 u32 sc_cmd_state;
28 /* Pointer to the CDB+Data descriptor from Linux/SCSI subsystem */
29 struct scsi_cmnd *sc;
30 struct list_head *tl_cmd_list;
31 /* The TCM I/O descriptor that is accessed via container_of() */
32 struct se_cmd tl_se_cmd;
33 /* Sense buffer that will be mapped into outgoing status */
34 unsigned char tl_sense_buf[TRANSPORT_SENSE_BUFFER];
35};
36
37struct tcm_loop_tmr {
38 atomic_t tmr_complete;
39 wait_queue_head_t tl_tmr_wait;
40};
41
42struct tcm_loop_nexus {
43 int it_nexus_active;
44 /*
45 * Pointer to Linux/SCSI HBA from linux/include/scsi_host.h
46 */
47 struct scsi_host *sh;
48 /*
49 * Pointer to TCM session for I_T Nexus
50 */
51 struct se_session *se_sess;
52};
53
54struct tcm_loop_nacl {
55 struct se_node_acl se_node_acl;
56};
57
58struct tcm_loop_tpg {
59 unsigned short tl_tpgt;
60 atomic_t tl_tpg_port_count;
61 struct se_portal_group tl_se_tpg;
62 struct tcm_loop_hba *tl_hba;
63};
64
65struct tcm_loop_hba {
66 u8 tl_proto_id;
67 unsigned char tl_wwn_address[TL_WWN_ADDR_LEN];
68 struct se_hba_s *se_hba;
69 struct se_lun *tl_hba_lun;
70 struct se_port *tl_hba_lun_sep;
71 struct se_device_s *se_dev_hba_ptr;
72 struct tcm_loop_nexus *tl_nexus;
73 struct device dev;
74 struct Scsi_Host *sh;
75 struct tcm_loop_tpg tl_hba_tpgs[TL_TPGS_PER_HBA];
76 struct se_wwn tl_hba_wwn;
77};
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index e7dddafe73f6..47abb42d9c36 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -496,8 +496,8 @@ static int core_alua_state_check(
496 nonop_delay_msecs = tg_pt_gp->tg_pt_gp_nonop_delay_msecs; 496 nonop_delay_msecs = tg_pt_gp->tg_pt_gp_nonop_delay_msecs;
497 spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 497 spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
498 /* 498 /*
499 * Process ALUA_ACCESS_STATE_ACTIVE_OPTMIZED in a seperate conditional 499 * Process ALUA_ACCESS_STATE_ACTIVE_OPTMIZED in a separate conditional
500 * statement so the complier knows explictly to check this case first. 500 * statement so the compiler knows explicitly to check this case first.
501 * For the Optimized ALUA access state case, we want to process the 501 * For the Optimized ALUA access state case, we want to process the
502 * incoming fabric cmd ASAP.. 502 * incoming fabric cmd ASAP..
503 */ 503 */
@@ -1157,7 +1157,7 @@ void core_alua_free_lu_gp(struct t10_alua_lu_gp *lu_gp)
1157 spin_unlock(&lu_gp->lu_gp_lock); 1157 spin_unlock(&lu_gp->lu_gp_lock);
1158 /* 1158 /*
1159 * 1159 *
1160 * lu_gp_mem is assoicated with a single 1160 * lu_gp_mem is associated with a single
1161 * struct se_device->dev_alua_lu_gp_mem, and is released when 1161 * struct se_device->dev_alua_lu_gp_mem, and is released when
1162 * struct se_device is released via core_alua_free_lu_gp_mem(). 1162 * struct se_device is released via core_alua_free_lu_gp_mem().
1163 * 1163 *
@@ -1429,7 +1429,7 @@ void core_alua_free_tg_pt_gp(
1429 } 1429 }
1430 spin_unlock(&tg_pt_gp->tg_pt_gp_lock); 1430 spin_unlock(&tg_pt_gp->tg_pt_gp_lock);
1431 /* 1431 /*
1432 * tg_pt_gp_mem is assoicated with a single 1432 * tg_pt_gp_mem is associated with a single
1433 * se_port->sep_alua_tg_pt_gp_mem, and is released via 1433 * se_port->sep_alua_tg_pt_gp_mem, and is released via
1434 * core_alua_free_tg_pt_gp_mem(). 1434 * core_alua_free_tg_pt_gp_mem().
1435 * 1435 *
@@ -1963,7 +1963,7 @@ int core_setup_alua(struct se_device *dev, int force_pt)
1963 printk(KERN_INFO "%s: Enabling ALUA Emulation for SPC-3" 1963 printk(KERN_INFO "%s: Enabling ALUA Emulation for SPC-3"
1964 " device\n", TRANSPORT(dev)->name); 1964 " device\n", TRANSPORT(dev)->name);
1965 /* 1965 /*
1966 * Assoicate this struct se_device with the default ALUA 1966 * Associate this struct se_device with the default ALUA
1967 * LUN Group. 1967 * LUN Group.
1968 */ 1968 */
1969 lu_gp_mem = core_alua_allocate_lu_gp_mem(dev); 1969 lu_gp_mem = core_alua_allocate_lu_gp_mem(dev);
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index caf8dc18ee0a..a5f44a6e6e1d 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -3,8 +3,8 @@
3 * 3 *
4 * This file contains ConfigFS logic for the Generic Target Engine project. 4 * This file contains ConfigFS logic for the Generic Target Engine project.
5 * 5 *
6 * Copyright (c) 2008-2010 Rising Tide Systems 6 * Copyright (c) 2008-2011 Rising Tide Systems
7 * Copyright (c) 2008-2010 Linux-iSCSI.org 7 * Copyright (c) 2008-2011 Linux-iSCSI.org
8 * 8 *
9 * Nicholas A. Bellinger <nab@kernel.org> 9 * Nicholas A. Bellinger <nab@kernel.org>
10 * 10 *
@@ -50,6 +50,7 @@
50#include "target_core_hba.h" 50#include "target_core_hba.h"
51#include "target_core_pr.h" 51#include "target_core_pr.h"
52#include "target_core_rd.h" 52#include "target_core_rd.h"
53#include "target_core_stat.h"
53 54
54static struct list_head g_tf_list; 55static struct list_head g_tf_list;
55static struct mutex g_tf_lock; 56static struct mutex g_tf_lock;
@@ -1451,8 +1452,8 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
1451 size_t count) 1452 size_t count)
1452{ 1453{
1453 struct se_device *dev; 1454 struct se_device *dev;
1454 unsigned char *i_fabric, *t_fabric, *i_port = NULL, *t_port = NULL; 1455 unsigned char *i_fabric = NULL, *i_port = NULL, *isid = NULL;
1455 unsigned char *isid = NULL; 1456 unsigned char *t_fabric = NULL, *t_port = NULL;
1456 char *orig, *ptr, *arg_p, *opts; 1457 char *orig, *ptr, *arg_p, *opts;
1457 substring_t args[MAX_OPT_ARGS]; 1458 substring_t args[MAX_OPT_ARGS];
1458 unsigned long long tmp_ll; 1459 unsigned long long tmp_ll;
@@ -1488,9 +1489,17 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
1488 switch (token) { 1489 switch (token) {
1489 case Opt_initiator_fabric: 1490 case Opt_initiator_fabric:
1490 i_fabric = match_strdup(&args[0]); 1491 i_fabric = match_strdup(&args[0]);
1492 if (!i_fabric) {
1493 ret = -ENOMEM;
1494 goto out;
1495 }
1491 break; 1496 break;
1492 case Opt_initiator_node: 1497 case Opt_initiator_node:
1493 i_port = match_strdup(&args[0]); 1498 i_port = match_strdup(&args[0]);
1499 if (!i_port) {
1500 ret = -ENOMEM;
1501 goto out;
1502 }
1494 if (strlen(i_port) > PR_APTPL_MAX_IPORT_LEN) { 1503 if (strlen(i_port) > PR_APTPL_MAX_IPORT_LEN) {
1495 printk(KERN_ERR "APTPL metadata initiator_node=" 1504 printk(KERN_ERR "APTPL metadata initiator_node="
1496 " exceeds PR_APTPL_MAX_IPORT_LEN: %d\n", 1505 " exceeds PR_APTPL_MAX_IPORT_LEN: %d\n",
@@ -1501,6 +1510,10 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
1501 break; 1510 break;
1502 case Opt_initiator_sid: 1511 case Opt_initiator_sid:
1503 isid = match_strdup(&args[0]); 1512 isid = match_strdup(&args[0]);
1513 if (!isid) {
1514 ret = -ENOMEM;
1515 goto out;
1516 }
1504 if (strlen(isid) > PR_REG_ISID_LEN) { 1517 if (strlen(isid) > PR_REG_ISID_LEN) {
1505 printk(KERN_ERR "APTPL metadata initiator_isid" 1518 printk(KERN_ERR "APTPL metadata initiator_isid"
1506 "= exceeds PR_REG_ISID_LEN: %d\n", 1519 "= exceeds PR_REG_ISID_LEN: %d\n",
@@ -1511,6 +1524,10 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
1511 break; 1524 break;
1512 case Opt_sa_res_key: 1525 case Opt_sa_res_key:
1513 arg_p = match_strdup(&args[0]); 1526 arg_p = match_strdup(&args[0]);
1527 if (!arg_p) {
1528 ret = -ENOMEM;
1529 goto out;
1530 }
1514 ret = strict_strtoull(arg_p, 0, &tmp_ll); 1531 ret = strict_strtoull(arg_p, 0, &tmp_ll);
1515 if (ret < 0) { 1532 if (ret < 0) {
1516 printk(KERN_ERR "strict_strtoull() failed for" 1533 printk(KERN_ERR "strict_strtoull() failed for"
@@ -1547,9 +1564,17 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
1547 */ 1564 */
1548 case Opt_target_fabric: 1565 case Opt_target_fabric:
1549 t_fabric = match_strdup(&args[0]); 1566 t_fabric = match_strdup(&args[0]);
1567 if (!t_fabric) {
1568 ret = -ENOMEM;
1569 goto out;
1570 }
1550 break; 1571 break;
1551 case Opt_target_node: 1572 case Opt_target_node:
1552 t_port = match_strdup(&args[0]); 1573 t_port = match_strdup(&args[0]);
1574 if (!t_port) {
1575 ret = -ENOMEM;
1576 goto out;
1577 }
1553 if (strlen(t_port) > PR_APTPL_MAX_TPORT_LEN) { 1578 if (strlen(t_port) > PR_APTPL_MAX_TPORT_LEN) {
1554 printk(KERN_ERR "APTPL metadata target_node=" 1579 printk(KERN_ERR "APTPL metadata target_node="
1555 " exceeds PR_APTPL_MAX_TPORT_LEN: %d\n", 1580 " exceeds PR_APTPL_MAX_TPORT_LEN: %d\n",
@@ -1592,6 +1617,11 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata(
1592 i_port, isid, mapped_lun, t_port, tpgt, target_lun, 1617 i_port, isid, mapped_lun, t_port, tpgt, target_lun,
1593 res_holder, all_tg_pt, type); 1618 res_holder, all_tg_pt, type);
1594out: 1619out:
1620 kfree(i_fabric);
1621 kfree(i_port);
1622 kfree(isid);
1623 kfree(t_fabric);
1624 kfree(t_port);
1595 kfree(orig); 1625 kfree(orig);
1596 return (ret == 0) ? count : ret; 1626 return (ret == 0) ? count : ret;
1597} 1627}
@@ -1798,7 +1828,9 @@ static ssize_t target_core_store_dev_enable(
1798 return -EINVAL; 1828 return -EINVAL;
1799 1829
1800 dev = t->create_virtdevice(hba, se_dev, se_dev->se_dev_su_ptr); 1830 dev = t->create_virtdevice(hba, se_dev, se_dev->se_dev_su_ptr);
1801 if (!(dev) || IS_ERR(dev)) 1831 if (IS_ERR(dev))
1832 return PTR_ERR(dev);
1833 else if (!dev)
1802 return -EINVAL; 1834 return -EINVAL;
1803 1835
1804 se_dev->se_dev_ptr = dev; 1836 se_dev->se_dev_ptr = dev;
@@ -2678,6 +2710,34 @@ static struct config_item_type target_core_alua_cit = {
2678 2710
2679/* End functions for struct config_item_type target_core_alua_cit */ 2711/* End functions for struct config_item_type target_core_alua_cit */
2680 2712
2713/* Start functions for struct config_item_type target_core_stat_cit */
2714
2715static struct config_group *target_core_stat_mkdir(
2716 struct config_group *group,
2717 const char *name)
2718{
2719 return ERR_PTR(-ENOSYS);
2720}
2721
2722static void target_core_stat_rmdir(
2723 struct config_group *group,
2724 struct config_item *item)
2725{
2726 return;
2727}
2728
2729static struct configfs_group_operations target_core_stat_group_ops = {
2730 .make_group = &target_core_stat_mkdir,
2731 .drop_item = &target_core_stat_rmdir,
2732};
2733
2734static struct config_item_type target_core_stat_cit = {
2735 .ct_group_ops = &target_core_stat_group_ops,
2736 .ct_owner = THIS_MODULE,
2737};
2738
2739/* End functions for struct config_item_type target_core_stat_cit */
2740
2681/* Start functions for struct config_item_type target_core_hba_cit */ 2741/* Start functions for struct config_item_type target_core_hba_cit */
2682 2742
2683static struct config_group *target_core_make_subdev( 2743static struct config_group *target_core_make_subdev(
@@ -2690,10 +2750,12 @@ static struct config_group *target_core_make_subdev(
2690 struct config_item *hba_ci = &group->cg_item; 2750 struct config_item *hba_ci = &group->cg_item;
2691 struct se_hba *hba = item_to_hba(hba_ci); 2751 struct se_hba *hba = item_to_hba(hba_ci);
2692 struct config_group *dev_cg = NULL, *tg_pt_gp_cg = NULL; 2752 struct config_group *dev_cg = NULL, *tg_pt_gp_cg = NULL;
2753 struct config_group *dev_stat_grp = NULL;
2754 int errno = -ENOMEM, ret;
2693 2755
2694 if (mutex_lock_interruptible(&hba->hba_access_mutex)) 2756 ret = mutex_lock_interruptible(&hba->hba_access_mutex);
2695 return NULL; 2757 if (ret)
2696 2758 return ERR_PTR(ret);
2697 /* 2759 /*
2698 * Locate the struct se_subsystem_api from parent's struct se_hba. 2760 * Locate the struct se_subsystem_api from parent's struct se_hba.
2699 */ 2761 */
@@ -2723,7 +2785,7 @@ static struct config_group *target_core_make_subdev(
2723 se_dev->se_dev_hba = hba; 2785 se_dev->se_dev_hba = hba;
2724 dev_cg = &se_dev->se_dev_group; 2786 dev_cg = &se_dev->se_dev_group;
2725 2787
2726 dev_cg->default_groups = kzalloc(sizeof(struct config_group) * 6, 2788 dev_cg->default_groups = kzalloc(sizeof(struct config_group) * 7,
2727 GFP_KERNEL); 2789 GFP_KERNEL);
2728 if (!(dev_cg->default_groups)) 2790 if (!(dev_cg->default_groups))
2729 goto out; 2791 goto out;
@@ -2755,13 +2817,17 @@ static struct config_group *target_core_make_subdev(
2755 &target_core_dev_wwn_cit); 2817 &target_core_dev_wwn_cit);
2756 config_group_init_type_name(&se_dev->t10_alua.alua_tg_pt_gps_group, 2818 config_group_init_type_name(&se_dev->t10_alua.alua_tg_pt_gps_group,
2757 "alua", &target_core_alua_tg_pt_gps_cit); 2819 "alua", &target_core_alua_tg_pt_gps_cit);
2820 config_group_init_type_name(&se_dev->dev_stat_grps.stat_group,
2821 "statistics", &target_core_stat_cit);
2822
2758 dev_cg->default_groups[0] = &se_dev->se_dev_attrib.da_group; 2823 dev_cg->default_groups[0] = &se_dev->se_dev_attrib.da_group;
2759 dev_cg->default_groups[1] = &se_dev->se_dev_pr_group; 2824 dev_cg->default_groups[1] = &se_dev->se_dev_pr_group;
2760 dev_cg->default_groups[2] = &se_dev->t10_wwn.t10_wwn_group; 2825 dev_cg->default_groups[2] = &se_dev->t10_wwn.t10_wwn_group;
2761 dev_cg->default_groups[3] = &se_dev->t10_alua.alua_tg_pt_gps_group; 2826 dev_cg->default_groups[3] = &se_dev->t10_alua.alua_tg_pt_gps_group;
2762 dev_cg->default_groups[4] = NULL; 2827 dev_cg->default_groups[4] = &se_dev->dev_stat_grps.stat_group;
2828 dev_cg->default_groups[5] = NULL;
2763 /* 2829 /*
2764 * Add core/$HBA/$DEV/alua/tg_pt_gps/default_tg_pt_gp 2830 * Add core/$HBA/$DEV/alua/default_tg_pt_gp
2765 */ 2831 */
2766 tg_pt_gp = core_alua_allocate_tg_pt_gp(se_dev, "default_tg_pt_gp", 1); 2832 tg_pt_gp = core_alua_allocate_tg_pt_gp(se_dev, "default_tg_pt_gp", 1);
2767 if (!(tg_pt_gp)) 2833 if (!(tg_pt_gp))
@@ -2781,6 +2847,17 @@ static struct config_group *target_core_make_subdev(
2781 tg_pt_gp_cg->default_groups[0] = &tg_pt_gp->tg_pt_gp_group; 2847 tg_pt_gp_cg->default_groups[0] = &tg_pt_gp->tg_pt_gp_group;
2782 tg_pt_gp_cg->default_groups[1] = NULL; 2848 tg_pt_gp_cg->default_groups[1] = NULL;
2783 T10_ALUA(se_dev)->default_tg_pt_gp = tg_pt_gp; 2849 T10_ALUA(se_dev)->default_tg_pt_gp = tg_pt_gp;
2850 /*
2851 * Add core/$HBA/$DEV/statistics/ default groups
2852 */
2853 dev_stat_grp = &DEV_STAT_GRP(se_dev)->stat_group;
2854 dev_stat_grp->default_groups = kzalloc(sizeof(struct config_group) * 4,
2855 GFP_KERNEL);
2856 if (!dev_stat_grp->default_groups) {
2857 printk(KERN_ERR "Unable to allocate dev_stat_grp->default_groups\n");
2858 goto out;
2859 }
2860 target_stat_setup_dev_default_groups(se_dev);
2784 2861
2785 printk(KERN_INFO "Target_Core_ConfigFS: Allocated struct se_subsystem_dev:" 2862 printk(KERN_INFO "Target_Core_ConfigFS: Allocated struct se_subsystem_dev:"
2786 " %p se_dev_su_ptr: %p\n", se_dev, se_dev->se_dev_su_ptr); 2863 " %p se_dev_su_ptr: %p\n", se_dev, se_dev->se_dev_su_ptr);
@@ -2792,6 +2869,8 @@ out:
2792 core_alua_free_tg_pt_gp(T10_ALUA(se_dev)->default_tg_pt_gp); 2869 core_alua_free_tg_pt_gp(T10_ALUA(se_dev)->default_tg_pt_gp);
2793 T10_ALUA(se_dev)->default_tg_pt_gp = NULL; 2870 T10_ALUA(se_dev)->default_tg_pt_gp = NULL;
2794 } 2871 }
2872 if (dev_stat_grp)
2873 kfree(dev_stat_grp->default_groups);
2795 if (tg_pt_gp_cg) 2874 if (tg_pt_gp_cg)
2796 kfree(tg_pt_gp_cg->default_groups); 2875 kfree(tg_pt_gp_cg->default_groups);
2797 if (dev_cg) 2876 if (dev_cg)
@@ -2801,7 +2880,7 @@ out:
2801 kfree(se_dev); 2880 kfree(se_dev);
2802unlock: 2881unlock:
2803 mutex_unlock(&hba->hba_access_mutex); 2882 mutex_unlock(&hba->hba_access_mutex);
2804 return NULL; 2883 return ERR_PTR(errno);
2805} 2884}
2806 2885
2807static void target_core_drop_subdev( 2886static void target_core_drop_subdev(
@@ -2813,7 +2892,7 @@ static void target_core_drop_subdev(
2813 struct se_hba *hba; 2892 struct se_hba *hba;
2814 struct se_subsystem_api *t; 2893 struct se_subsystem_api *t;
2815 struct config_item *df_item; 2894 struct config_item *df_item;
2816 struct config_group *dev_cg, *tg_pt_gp_cg; 2895 struct config_group *dev_cg, *tg_pt_gp_cg, *dev_stat_grp;
2817 int i; 2896 int i;
2818 2897
2819 hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item); 2898 hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item);
@@ -2825,6 +2904,14 @@ static void target_core_drop_subdev(
2825 list_del(&se_dev->g_se_dev_list); 2904 list_del(&se_dev->g_se_dev_list);
2826 spin_unlock(&se_global->g_device_lock); 2905 spin_unlock(&se_global->g_device_lock);
2827 2906
2907 dev_stat_grp = &DEV_STAT_GRP(se_dev)->stat_group;
2908 for (i = 0; dev_stat_grp->default_groups[i]; i++) {
2909 df_item = &dev_stat_grp->default_groups[i]->cg_item;
2910 dev_stat_grp->default_groups[i] = NULL;
2911 config_item_put(df_item);
2912 }
2913 kfree(dev_stat_grp->default_groups);
2914
2828 tg_pt_gp_cg = &T10_ALUA(se_dev)->alua_tg_pt_gps_group; 2915 tg_pt_gp_cg = &T10_ALUA(se_dev)->alua_tg_pt_gps_group;
2829 for (i = 0; tg_pt_gp_cg->default_groups[i]; i++) { 2916 for (i = 0; tg_pt_gp_cg->default_groups[i]; i++) {
2830 df_item = &tg_pt_gp_cg->default_groups[i]->cg_item; 2917 df_item = &tg_pt_gp_cg->default_groups[i]->cg_item;
@@ -3044,7 +3131,7 @@ static struct config_item_type target_core_cit = {
3044 3131
3045/* Stop functions for struct config_item_type target_core_hba_cit */ 3132/* Stop functions for struct config_item_type target_core_hba_cit */
3046 3133
3047static int target_core_init_configfs(void) 3134static int __init target_core_init_configfs(void)
3048{ 3135{
3049 struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL; 3136 struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL;
3050 struct config_group *lu_gp_cg = NULL; 3137 struct config_group *lu_gp_cg = NULL;
@@ -3176,7 +3263,7 @@ out_global:
3176 return -1; 3263 return -1;
3177} 3264}
3178 3265
3179static void target_core_exit_configfs(void) 3266static void __exit target_core_exit_configfs(void)
3180{ 3267{
3181 struct configfs_subsystem *subsys; 3268 struct configfs_subsystem *subsys;
3182 struct config_group *hba_cg, *alua_cg, *lu_gp_cg; 3269 struct config_group *hba_cg, *alua_cg, *lu_gp_cg;
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 350ed401544e..d25e20829012 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -371,7 +371,7 @@ int core_update_device_list_for_node(
371 if (!(enable)) { 371 if (!(enable)) {
372 /* 372 /*
373 * deve->se_lun_acl will be NULL for demo-mode created LUNs 373 * deve->se_lun_acl will be NULL for demo-mode created LUNs
374 * that have not been explictly concerted to MappedLUNs -> 374 * that have not been explicitly concerted to MappedLUNs ->
375 * struct se_lun_acl, but we remove deve->alua_port_list from 375 * struct se_lun_acl, but we remove deve->alua_port_list from
376 * port->sep_alua_list. This also means that active UAs and 376 * port->sep_alua_list. This also means that active UAs and
377 * NodeACL context specific PR metadata for demo-mode 377 * NodeACL context specific PR metadata for demo-mode
@@ -589,6 +589,7 @@ static void core_export_port(
589 * Called with struct se_device->se_port_lock spinlock held. 589 * Called with struct se_device->se_port_lock spinlock held.
590 */ 590 */
591static void core_release_port(struct se_device *dev, struct se_port *port) 591static void core_release_port(struct se_device *dev, struct se_port *port)
592 __releases(&dev->se_port_lock) __acquires(&dev->se_port_lock)
592{ 593{
593 /* 594 /*
594 * Wait for any port reference for PR ALL_TG_PT=1 operation 595 * Wait for any port reference for PR ALL_TG_PT=1 operation
@@ -779,49 +780,14 @@ void se_release_vpd_for_dev(struct se_device *dev)
779 return; 780 return;
780} 781}
781 782
782/*
783 * Called with struct se_hba->device_lock held.
784 */
785void se_clear_dev_ports(struct se_device *dev)
786{
787 struct se_hba *hba = dev->se_hba;
788 struct se_lun *lun;
789 struct se_portal_group *tpg;
790 struct se_port *sep, *sep_tmp;
791
792 spin_lock(&dev->se_port_lock);
793 list_for_each_entry_safe(sep, sep_tmp, &dev->dev_sep_list, sep_list) {
794 spin_unlock(&dev->se_port_lock);
795 spin_unlock(&hba->device_lock);
796
797 lun = sep->sep_lun;
798 tpg = sep->sep_tpg;
799 spin_lock(&lun->lun_sep_lock);
800 if (lun->lun_se_dev == NULL) {
801 spin_unlock(&lun->lun_sep_lock);
802 continue;
803 }
804 spin_unlock(&lun->lun_sep_lock);
805
806 core_dev_del_lun(tpg, lun->unpacked_lun);
807
808 spin_lock(&hba->device_lock);
809 spin_lock(&dev->se_port_lock);
810 }
811 spin_unlock(&dev->se_port_lock);
812
813 return;
814}
815
816/* se_free_virtual_device(): 783/* se_free_virtual_device():
817 * 784 *
818 * Used for IBLOCK, RAMDISK, and FILEIO Transport Drivers. 785 * Used for IBLOCK, RAMDISK, and FILEIO Transport Drivers.
819 */ 786 */
820int se_free_virtual_device(struct se_device *dev, struct se_hba *hba) 787int se_free_virtual_device(struct se_device *dev, struct se_hba *hba)
821{ 788{
822 spin_lock(&hba->device_lock); 789 if (!list_empty(&dev->dev_sep_list))
823 se_clear_dev_ports(dev); 790 dump_stack();
824 spin_unlock(&hba->device_lock);
825 791
826 core_alua_free_lu_gp_mem(dev); 792 core_alua_free_lu_gp_mem(dev);
827 se_release_device_for_hba(dev); 793 se_release_device_for_hba(dev);
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c
index b65d1c8e7740..07ab5a3bb8e8 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -4,10 +4,10 @@
4 * This file contains generic fabric module configfs infrastructure for 4 * This file contains generic fabric module configfs infrastructure for
5 * TCM v4.x code 5 * TCM v4.x code
6 * 6 *
7 * Copyright (c) 2010 Rising Tide Systems 7 * Copyright (c) 2010,2011 Rising Tide Systems
8 * Copyright (c) 2010 Linux-iSCSI.org 8 * Copyright (c) 2010,2011 Linux-iSCSI.org
9 * 9 *
10 * Copyright (c) 2010 Nicholas A. Bellinger <nab@linux-iscsi.org> 10 * Copyright (c) Nicholas A. Bellinger <nab@linux-iscsi.org>
11* 11*
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License as published by
@@ -48,6 +48,7 @@
48#include "target_core_alua.h" 48#include "target_core_alua.h"
49#include "target_core_hba.h" 49#include "target_core_hba.h"
50#include "target_core_pr.h" 50#include "target_core_pr.h"
51#include "target_core_stat.h"
51 52
52#define TF_CIT_SETUP(_name, _item_ops, _group_ops, _attrs) \ 53#define TF_CIT_SETUP(_name, _item_ops, _group_ops, _attrs) \
53static void target_fabric_setup_##_name##_cit(struct target_fabric_configfs *tf) \ 54static void target_fabric_setup_##_name##_cit(struct target_fabric_configfs *tf) \
@@ -241,6 +242,32 @@ TF_CIT_SETUP(tpg_mappedlun, &target_fabric_mappedlun_item_ops, NULL,
241 242
242/* End of tfc_tpg_mappedlun_cit */ 243/* End of tfc_tpg_mappedlun_cit */
243 244
245/* Start of tfc_tpg_mappedlun_port_cit */
246
247static struct config_group *target_core_mappedlun_stat_mkdir(
248 struct config_group *group,
249 const char *name)
250{
251 return ERR_PTR(-ENOSYS);
252}
253
254static void target_core_mappedlun_stat_rmdir(
255 struct config_group *group,
256 struct config_item *item)
257{
258 return;
259}
260
261static struct configfs_group_operations target_fabric_mappedlun_stat_group_ops = {
262 .make_group = target_core_mappedlun_stat_mkdir,
263 .drop_item = target_core_mappedlun_stat_rmdir,
264};
265
266TF_CIT_SETUP(tpg_mappedlun_stat, NULL, &target_fabric_mappedlun_stat_group_ops,
267 NULL);
268
269/* End of tfc_tpg_mappedlun_port_cit */
270
244/* Start of tfc_tpg_nacl_attrib_cit */ 271/* Start of tfc_tpg_nacl_attrib_cit */
245 272
246CONFIGFS_EATTR_OPS(target_fabric_nacl_attrib, se_node_acl, acl_attrib_group); 273CONFIGFS_EATTR_OPS(target_fabric_nacl_attrib, se_node_acl, acl_attrib_group);
@@ -294,6 +321,7 @@ static struct config_group *target_fabric_make_mappedlun(
294 struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; 321 struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
295 struct se_lun_acl *lacl; 322 struct se_lun_acl *lacl;
296 struct config_item *acl_ci; 323 struct config_item *acl_ci;
324 struct config_group *lacl_cg = NULL, *ml_stat_grp = NULL;
297 char *buf; 325 char *buf;
298 unsigned long mapped_lun; 326 unsigned long mapped_lun;
299 int ret = 0; 327 int ret = 0;
@@ -330,15 +358,42 @@ static struct config_group *target_fabric_make_mappedlun(
330 358
331 lacl = core_dev_init_initiator_node_lun_acl(se_tpg, mapped_lun, 359 lacl = core_dev_init_initiator_node_lun_acl(se_tpg, mapped_lun,
332 config_item_name(acl_ci), &ret); 360 config_item_name(acl_ci), &ret);
333 if (!(lacl)) 361 if (!(lacl)) {
362 ret = -EINVAL;
334 goto out; 363 goto out;
364 }
365
366 lacl_cg = &lacl->se_lun_group;
367 lacl_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
368 GFP_KERNEL);
369 if (!lacl_cg->default_groups) {
370 printk(KERN_ERR "Unable to allocate lacl_cg->default_groups\n");
371 ret = -ENOMEM;
372 goto out;
373 }
335 374
336 config_group_init_type_name(&lacl->se_lun_group, name, 375 config_group_init_type_name(&lacl->se_lun_group, name,
337 &TF_CIT_TMPL(tf)->tfc_tpg_mappedlun_cit); 376 &TF_CIT_TMPL(tf)->tfc_tpg_mappedlun_cit);
377 config_group_init_type_name(&lacl->ml_stat_grps.stat_group,
378 "statistics", &TF_CIT_TMPL(tf)->tfc_tpg_mappedlun_stat_cit);
379 lacl_cg->default_groups[0] = &lacl->ml_stat_grps.stat_group;
380 lacl_cg->default_groups[1] = NULL;
381
382 ml_stat_grp = &ML_STAT_GRPS(lacl)->stat_group;
383 ml_stat_grp->default_groups = kzalloc(sizeof(struct config_group) * 3,
384 GFP_KERNEL);
385 if (!ml_stat_grp->default_groups) {
386 printk(KERN_ERR "Unable to allocate ml_stat_grp->default_groups\n");
387 ret = -ENOMEM;
388 goto out;
389 }
390 target_stat_setup_mappedlun_default_groups(lacl);
338 391
339 kfree(buf); 392 kfree(buf);
340 return &lacl->se_lun_group; 393 return &lacl->se_lun_group;
341out: 394out:
395 if (lacl_cg)
396 kfree(lacl_cg->default_groups);
342 kfree(buf); 397 kfree(buf);
343 return ERR_PTR(ret); 398 return ERR_PTR(ret);
344} 399}
@@ -347,6 +402,28 @@ static void target_fabric_drop_mappedlun(
347 struct config_group *group, 402 struct config_group *group,
348 struct config_item *item) 403 struct config_item *item)
349{ 404{
405 struct se_lun_acl *lacl = container_of(to_config_group(item),
406 struct se_lun_acl, se_lun_group);
407 struct config_item *df_item;
408 struct config_group *lacl_cg = NULL, *ml_stat_grp = NULL;
409 int i;
410
411 ml_stat_grp = &ML_STAT_GRPS(lacl)->stat_group;
412 for (i = 0; ml_stat_grp->default_groups[i]; i++) {
413 df_item = &ml_stat_grp->default_groups[i]->cg_item;
414 ml_stat_grp->default_groups[i] = NULL;
415 config_item_put(df_item);
416 }
417 kfree(ml_stat_grp->default_groups);
418
419 lacl_cg = &lacl->se_lun_group;
420 for (i = 0; lacl_cg->default_groups[i]; i++) {
421 df_item = &lacl_cg->default_groups[i]->cg_item;
422 lacl_cg->default_groups[i] = NULL;
423 config_item_put(df_item);
424 }
425 kfree(lacl_cg->default_groups);
426
350 config_item_put(item); 427 config_item_put(item);
351} 428}
352 429
@@ -376,6 +453,15 @@ TF_CIT_SETUP(tpg_nacl_base, &target_fabric_nacl_base_item_ops,
376 453
377/* End of tfc_tpg_nacl_base_cit */ 454/* End of tfc_tpg_nacl_base_cit */
378 455
456/* Start of tfc_node_fabric_stats_cit */
457/*
458 * This is used as a placeholder for struct se_node_acl->acl_fabric_stat_group
459 * to allow fabrics access to ->acl_fabric_stat_group->default_groups[]
460 */
461TF_CIT_SETUP(tpg_nacl_stat, NULL, NULL, NULL);
462
463/* End of tfc_wwn_fabric_stats_cit */
464
379/* Start of tfc_tpg_nacl_cit */ 465/* Start of tfc_tpg_nacl_cit */
380 466
381static struct config_group *target_fabric_make_nodeacl( 467static struct config_group *target_fabric_make_nodeacl(
@@ -402,7 +488,8 @@ static struct config_group *target_fabric_make_nodeacl(
402 nacl_cg->default_groups[0] = &se_nacl->acl_attrib_group; 488 nacl_cg->default_groups[0] = &se_nacl->acl_attrib_group;
403 nacl_cg->default_groups[1] = &se_nacl->acl_auth_group; 489 nacl_cg->default_groups[1] = &se_nacl->acl_auth_group;
404 nacl_cg->default_groups[2] = &se_nacl->acl_param_group; 490 nacl_cg->default_groups[2] = &se_nacl->acl_param_group;
405 nacl_cg->default_groups[3] = NULL; 491 nacl_cg->default_groups[3] = &se_nacl->acl_fabric_stat_group;
492 nacl_cg->default_groups[4] = NULL;
406 493
407 config_group_init_type_name(&se_nacl->acl_group, name, 494 config_group_init_type_name(&se_nacl->acl_group, name,
408 &TF_CIT_TMPL(tf)->tfc_tpg_nacl_base_cit); 495 &TF_CIT_TMPL(tf)->tfc_tpg_nacl_base_cit);
@@ -412,6 +499,9 @@ static struct config_group *target_fabric_make_nodeacl(
412 &TF_CIT_TMPL(tf)->tfc_tpg_nacl_auth_cit); 499 &TF_CIT_TMPL(tf)->tfc_tpg_nacl_auth_cit);
413 config_group_init_type_name(&se_nacl->acl_param_group, "param", 500 config_group_init_type_name(&se_nacl->acl_param_group, "param",
414 &TF_CIT_TMPL(tf)->tfc_tpg_nacl_param_cit); 501 &TF_CIT_TMPL(tf)->tfc_tpg_nacl_param_cit);
502 config_group_init_type_name(&se_nacl->acl_fabric_stat_group,
503 "fabric_statistics",
504 &TF_CIT_TMPL(tf)->tfc_tpg_nacl_stat_cit);
415 505
416 return &se_nacl->acl_group; 506 return &se_nacl->acl_group;
417} 507}
@@ -758,6 +848,31 @@ TF_CIT_SETUP(tpg_port, &target_fabric_port_item_ops, NULL, target_fabric_port_at
758 848
759/* End of tfc_tpg_port_cit */ 849/* End of tfc_tpg_port_cit */
760 850
851/* Start of tfc_tpg_port_stat_cit */
852
853static struct config_group *target_core_port_stat_mkdir(
854 struct config_group *group,
855 const char *name)
856{
857 return ERR_PTR(-ENOSYS);
858}
859
860static void target_core_port_stat_rmdir(
861 struct config_group *group,
862 struct config_item *item)
863{
864 return;
865}
866
867static struct configfs_group_operations target_fabric_port_stat_group_ops = {
868 .make_group = target_core_port_stat_mkdir,
869 .drop_item = target_core_port_stat_rmdir,
870};
871
872TF_CIT_SETUP(tpg_port_stat, NULL, &target_fabric_port_stat_group_ops, NULL);
873
874/* End of tfc_tpg_port_stat_cit */
875
761/* Start of tfc_tpg_lun_cit */ 876/* Start of tfc_tpg_lun_cit */
762 877
763static struct config_group *target_fabric_make_lun( 878static struct config_group *target_fabric_make_lun(
@@ -768,7 +883,9 @@ static struct config_group *target_fabric_make_lun(
768 struct se_portal_group *se_tpg = container_of(group, 883 struct se_portal_group *se_tpg = container_of(group,
769 struct se_portal_group, tpg_lun_group); 884 struct se_portal_group, tpg_lun_group);
770 struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; 885 struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
886 struct config_group *lun_cg = NULL, *port_stat_grp = NULL;
771 unsigned long unpacked_lun; 887 unsigned long unpacked_lun;
888 int errno;
772 889
773 if (strstr(name, "lun_") != name) { 890 if (strstr(name, "lun_") != name) {
774 printk(KERN_ERR "Unable to locate \'_\" in" 891 printk(KERN_ERR "Unable to locate \'_\" in"
@@ -782,16 +899,64 @@ static struct config_group *target_fabric_make_lun(
782 if (!(lun)) 899 if (!(lun))
783 return ERR_PTR(-EINVAL); 900 return ERR_PTR(-EINVAL);
784 901
902 lun_cg = &lun->lun_group;
903 lun_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
904 GFP_KERNEL);
905 if (!lun_cg->default_groups) {
906 printk(KERN_ERR "Unable to allocate lun_cg->default_groups\n");
907 return ERR_PTR(-ENOMEM);
908 }
909
785 config_group_init_type_name(&lun->lun_group, name, 910 config_group_init_type_name(&lun->lun_group, name,
786 &TF_CIT_TMPL(tf)->tfc_tpg_port_cit); 911 &TF_CIT_TMPL(tf)->tfc_tpg_port_cit);
912 config_group_init_type_name(&lun->port_stat_grps.stat_group,
913 "statistics", &TF_CIT_TMPL(tf)->tfc_tpg_port_stat_cit);
914 lun_cg->default_groups[0] = &lun->port_stat_grps.stat_group;
915 lun_cg->default_groups[1] = NULL;
916
917 port_stat_grp = &PORT_STAT_GRP(lun)->stat_group;
918 port_stat_grp->default_groups = kzalloc(sizeof(struct config_group) * 3,
919 GFP_KERNEL);
920 if (!port_stat_grp->default_groups) {
921 printk(KERN_ERR "Unable to allocate port_stat_grp->default_groups\n");
922 errno = -ENOMEM;
923 goto out;
924 }
925 target_stat_setup_port_default_groups(lun);
787 926
788 return &lun->lun_group; 927 return &lun->lun_group;
928out:
929 if (lun_cg)
930 kfree(lun_cg->default_groups);
931 return ERR_PTR(errno);
789} 932}
790 933
791static void target_fabric_drop_lun( 934static void target_fabric_drop_lun(
792 struct config_group *group, 935 struct config_group *group,
793 struct config_item *item) 936 struct config_item *item)
794{ 937{
938 struct se_lun *lun = container_of(to_config_group(item),
939 struct se_lun, lun_group);
940 struct config_item *df_item;
941 struct config_group *lun_cg, *port_stat_grp;
942 int i;
943
944 port_stat_grp = &PORT_STAT_GRP(lun)->stat_group;
945 for (i = 0; port_stat_grp->default_groups[i]; i++) {
946 df_item = &port_stat_grp->default_groups[i]->cg_item;
947 port_stat_grp->default_groups[i] = NULL;
948 config_item_put(df_item);
949 }
950 kfree(port_stat_grp->default_groups);
951
952 lun_cg = &lun->lun_group;
953 for (i = 0; lun_cg->default_groups[i]; i++) {
954 df_item = &lun_cg->default_groups[i]->cg_item;
955 lun_cg->default_groups[i] = NULL;
956 config_item_put(df_item);
957 }
958 kfree(lun_cg->default_groups);
959
795 config_item_put(item); 960 config_item_put(item);
796} 961}
797 962
@@ -946,6 +1111,15 @@ TF_CIT_SETUP(tpg, &target_fabric_tpg_item_ops, &target_fabric_tpg_group_ops,
946 1111
947/* End of tfc_tpg_cit */ 1112/* End of tfc_tpg_cit */
948 1113
1114/* Start of tfc_wwn_fabric_stats_cit */
1115/*
1116 * This is used as a placeholder for struct se_wwn->fabric_stat_group
1117 * to allow fabrics access to ->fabric_stat_group->default_groups[]
1118 */
1119TF_CIT_SETUP(wwn_fabric_stats, NULL, NULL, NULL);
1120
1121/* End of tfc_wwn_fabric_stats_cit */
1122
949/* Start of tfc_wwn_cit */ 1123/* Start of tfc_wwn_cit */
950 1124
951static struct config_group *target_fabric_make_wwn( 1125static struct config_group *target_fabric_make_wwn(
@@ -966,8 +1140,17 @@ static struct config_group *target_fabric_make_wwn(
966 return ERR_PTR(-EINVAL); 1140 return ERR_PTR(-EINVAL);
967 1141
968 wwn->wwn_tf = tf; 1142 wwn->wwn_tf = tf;
1143 /*
1144 * Setup default groups from pre-allocated wwn->wwn_default_groups
1145 */
1146 wwn->wwn_group.default_groups = wwn->wwn_default_groups;
1147 wwn->wwn_group.default_groups[0] = &wwn->fabric_stat_group;
1148 wwn->wwn_group.default_groups[1] = NULL;
1149
969 config_group_init_type_name(&wwn->wwn_group, name, 1150 config_group_init_type_name(&wwn->wwn_group, name,
970 &TF_CIT_TMPL(tf)->tfc_tpg_cit); 1151 &TF_CIT_TMPL(tf)->tfc_tpg_cit);
1152 config_group_init_type_name(&wwn->fabric_stat_group, "fabric_statistics",
1153 &TF_CIT_TMPL(tf)->tfc_wwn_fabric_stats_cit);
971 1154
972 return &wwn->wwn_group; 1155 return &wwn->wwn_group;
973} 1156}
@@ -976,6 +1159,18 @@ static void target_fabric_drop_wwn(
976 struct config_group *group, 1159 struct config_group *group,
977 struct config_item *item) 1160 struct config_item *item)
978{ 1161{
1162 struct se_wwn *wwn = container_of(to_config_group(item),
1163 struct se_wwn, wwn_group);
1164 struct config_item *df_item;
1165 struct config_group *cg = &wwn->wwn_group;
1166 int i;
1167
1168 for (i = 0; cg->default_groups[i]; i++) {
1169 df_item = &cg->default_groups[i]->cg_item;
1170 cg->default_groups[i] = NULL;
1171 config_item_put(df_item);
1172 }
1173
979 config_item_put(item); 1174 config_item_put(item);
980} 1175}
981 1176
@@ -1015,9 +1210,11 @@ int target_fabric_setup_cits(struct target_fabric_configfs *tf)
1015{ 1210{
1016 target_fabric_setup_discovery_cit(tf); 1211 target_fabric_setup_discovery_cit(tf);
1017 target_fabric_setup_wwn_cit(tf); 1212 target_fabric_setup_wwn_cit(tf);
1213 target_fabric_setup_wwn_fabric_stats_cit(tf);
1018 target_fabric_setup_tpg_cit(tf); 1214 target_fabric_setup_tpg_cit(tf);
1019 target_fabric_setup_tpg_base_cit(tf); 1215 target_fabric_setup_tpg_base_cit(tf);
1020 target_fabric_setup_tpg_port_cit(tf); 1216 target_fabric_setup_tpg_port_cit(tf);
1217 target_fabric_setup_tpg_port_stat_cit(tf);
1021 target_fabric_setup_tpg_lun_cit(tf); 1218 target_fabric_setup_tpg_lun_cit(tf);
1022 target_fabric_setup_tpg_np_cit(tf); 1219 target_fabric_setup_tpg_np_cit(tf);
1023 target_fabric_setup_tpg_np_base_cit(tf); 1220 target_fabric_setup_tpg_np_base_cit(tf);
@@ -1028,7 +1225,9 @@ int target_fabric_setup_cits(struct target_fabric_configfs *tf)
1028 target_fabric_setup_tpg_nacl_attrib_cit(tf); 1225 target_fabric_setup_tpg_nacl_attrib_cit(tf);
1029 target_fabric_setup_tpg_nacl_auth_cit(tf); 1226 target_fabric_setup_tpg_nacl_auth_cit(tf);
1030 target_fabric_setup_tpg_nacl_param_cit(tf); 1227 target_fabric_setup_tpg_nacl_param_cit(tf);
1228 target_fabric_setup_tpg_nacl_stat_cit(tf);
1031 target_fabric_setup_tpg_mappedlun_cit(tf); 1229 target_fabric_setup_tpg_mappedlun_cit(tf);
1230 target_fabric_setup_tpg_mappedlun_stat_cit(tf);
1032 1231
1033 return 0; 1232 return 0;
1034} 1233}
diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
index a3c695adabec..1e193f324895 100644
--- a/drivers/target/target_core_fabric_lib.c
+++ b/drivers/target/target_core_fabric_lib.c
@@ -34,6 +34,7 @@
34#include <target/target_core_base.h> 34#include <target/target_core_base.h>
35#include <target/target_core_device.h> 35#include <target/target_core_device.h>
36#include <target/target_core_transport.h> 36#include <target/target_core_transport.h>
37#include <target/target_core_fabric_lib.h>
37#include <target/target_core_fabric_ops.h> 38#include <target/target_core_fabric_ops.h>
38#include <target/target_core_configfs.h> 39#include <target/target_core_configfs.h>
39 40
@@ -432,7 +433,7 @@ char *iscsi_parse_pr_out_transport_id(
432 /* 433 /*
433 * Go ahead and do the lower case conversion of the received 434 * Go ahead and do the lower case conversion of the received
434 * 12 ASCII characters representing the ISID in the TransportID 435 * 12 ASCII characters representing the ISID in the TransportID
435 * for comparision against the running iSCSI session's ISID from 436 * for comparison against the running iSCSI session's ISID from
436 * iscsi_target.c:lio_sess_get_initiator_sid() 437 * iscsi_target.c:lio_sess_get_initiator_sid()
437 */ 438 */
438 for (i = 0; i < 12; i++) { 439 for (i = 0; i < 12; i++) {
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index 190ca8ac2498..150c4305f385 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -134,7 +134,7 @@ static struct se_device *fd_create_virtdevice(
134 mm_segment_t old_fs; 134 mm_segment_t old_fs;
135 struct file *file; 135 struct file *file;
136 struct inode *inode = NULL; 136 struct inode *inode = NULL;
137 int dev_flags = 0, flags; 137 int dev_flags = 0, flags, ret = -EINVAL;
138 138
139 memset(&dev_limits, 0, sizeof(struct se_dev_limits)); 139 memset(&dev_limits, 0, sizeof(struct se_dev_limits));
140 140
@@ -146,6 +146,7 @@ static struct se_device *fd_create_virtdevice(
146 if (IS_ERR(dev_p)) { 146 if (IS_ERR(dev_p)) {
147 printk(KERN_ERR "getname(%s) failed: %lu\n", 147 printk(KERN_ERR "getname(%s) failed: %lu\n",
148 fd_dev->fd_dev_name, IS_ERR(dev_p)); 148 fd_dev->fd_dev_name, IS_ERR(dev_p));
149 ret = PTR_ERR(dev_p);
149 goto fail; 150 goto fail;
150 } 151 }
151#if 0 152#if 0
@@ -158,15 +159,19 @@ static struct se_device *fd_create_virtdevice(
158#endif 159#endif
159/* flags |= O_DIRECT; */ 160/* flags |= O_DIRECT; */
160 /* 161 /*
161 * If fd_buffered_io=1 has not been set explictly (the default), 162 * If fd_buffered_io=1 has not been set explicitly (the default),
162 * use O_SYNC to force FILEIO writes to disk. 163 * use O_SYNC to force FILEIO writes to disk.
163 */ 164 */
164 if (!(fd_dev->fbd_flags & FDBD_USE_BUFFERED_IO)) 165 if (!(fd_dev->fbd_flags & FDBD_USE_BUFFERED_IO))
165 flags |= O_SYNC; 166 flags |= O_SYNC;
166 167
167 file = filp_open(dev_p, flags, 0600); 168 file = filp_open(dev_p, flags, 0600);
168 169 if (IS_ERR(file)) {
169 if (IS_ERR(file) || !file || !file->f_dentry) { 170 printk(KERN_ERR "filp_open(%s) failed\n", dev_p);
171 ret = PTR_ERR(file);
172 goto fail;
173 }
174 if (!file || !file->f_dentry) {
170 printk(KERN_ERR "filp_open(%s) failed\n", dev_p); 175 printk(KERN_ERR "filp_open(%s) failed\n", dev_p);
171 goto fail; 176 goto fail;
172 } 177 }
@@ -241,7 +246,7 @@ fail:
241 fd_dev->fd_file = NULL; 246 fd_dev->fd_file = NULL;
242 } 247 }
243 putname(dev_p); 248 putname(dev_p);
244 return NULL; 249 return ERR_PTR(ret);
245} 250}
246 251
247/* fd_free_device(): (Part of se_subsystem_api_t template) 252/* fd_free_device(): (Part of se_subsystem_api_t template)
@@ -509,7 +514,7 @@ enum {
509static match_table_t tokens = { 514static match_table_t tokens = {
510 {Opt_fd_dev_name, "fd_dev_name=%s"}, 515 {Opt_fd_dev_name, "fd_dev_name=%s"},
511 {Opt_fd_dev_size, "fd_dev_size=%s"}, 516 {Opt_fd_dev_size, "fd_dev_size=%s"},
512 {Opt_fd_buffered_io, "fd_buffered_id=%d"}, 517 {Opt_fd_buffered_io, "fd_buffered_io=%d"},
513 {Opt_err, NULL} 518 {Opt_err, NULL}
514}; 519};
515 520
@@ -536,15 +541,26 @@ static ssize_t fd_set_configfs_dev_params(
536 token = match_token(ptr, tokens, args); 541 token = match_token(ptr, tokens, args);
537 switch (token) { 542 switch (token) {
538 case Opt_fd_dev_name: 543 case Opt_fd_dev_name:
544 arg_p = match_strdup(&args[0]);
545 if (!arg_p) {
546 ret = -ENOMEM;
547 break;
548 }
539 snprintf(fd_dev->fd_dev_name, FD_MAX_DEV_NAME, 549 snprintf(fd_dev->fd_dev_name, FD_MAX_DEV_NAME,
540 "%s", match_strdup(&args[0])); 550 "%s", arg_p);
551 kfree(arg_p);
541 printk(KERN_INFO "FILEIO: Referencing Path: %s\n", 552 printk(KERN_INFO "FILEIO: Referencing Path: %s\n",
542 fd_dev->fd_dev_name); 553 fd_dev->fd_dev_name);
543 fd_dev->fbd_flags |= FBDF_HAS_PATH; 554 fd_dev->fbd_flags |= FBDF_HAS_PATH;
544 break; 555 break;
545 case Opt_fd_dev_size: 556 case Opt_fd_dev_size:
546 arg_p = match_strdup(&args[0]); 557 arg_p = match_strdup(&args[0]);
558 if (!arg_p) {
559 ret = -ENOMEM;
560 break;
561 }
547 ret = strict_strtoull(arg_p, 0, &fd_dev->fd_dev_size); 562 ret = strict_strtoull(arg_p, 0, &fd_dev->fd_dev_size);
563 kfree(arg_p);
548 if (ret < 0) { 564 if (ret < 0) {
549 printk(KERN_ERR "strict_strtoull() failed for" 565 printk(KERN_ERR "strict_strtoull() failed for"
550 " fd_dev_size=\n"); 566 " fd_dev_size=\n");
diff --git a/drivers/target/target_core_hba.c b/drivers/target/target_core_hba.c
index 6ec51cbc018e..0b8f8da89019 100644
--- a/drivers/target/target_core_hba.c
+++ b/drivers/target/target_core_hba.c
@@ -151,19 +151,8 @@ out_free_hba:
151int 151int
152core_delete_hba(struct se_hba *hba) 152core_delete_hba(struct se_hba *hba)
153{ 153{
154 struct se_device *dev, *dev_tmp; 154 if (!list_empty(&hba->hba_dev_list))
155 155 dump_stack();
156 spin_lock(&hba->device_lock);
157 list_for_each_entry_safe(dev, dev_tmp, &hba->hba_dev_list, dev_list) {
158
159 se_clear_dev_ports(dev);
160 spin_unlock(&hba->device_lock);
161
162 se_release_device_for_hba(dev);
163
164 spin_lock(&hba->device_lock);
165 }
166 spin_unlock(&hba->device_lock);
167 156
168 hba->transport->detach_hba(hba); 157 hba->transport->detach_hba(hba);
169 158
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 3df570db0e4f..86639004af9e 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -129,10 +129,11 @@ static struct se_device *iblock_create_virtdevice(
129 struct request_queue *q; 129 struct request_queue *q;
130 struct queue_limits *limits; 130 struct queue_limits *limits;
131 u32 dev_flags = 0; 131 u32 dev_flags = 0;
132 int ret = -EINVAL;
132 133
133 if (!(ib_dev)) { 134 if (!(ib_dev)) {
134 printk(KERN_ERR "Unable to locate struct iblock_dev parameter\n"); 135 printk(KERN_ERR "Unable to locate struct iblock_dev parameter\n");
135 return 0; 136 return ERR_PTR(ret);
136 } 137 }
137 memset(&dev_limits, 0, sizeof(struct se_dev_limits)); 138 memset(&dev_limits, 0, sizeof(struct se_dev_limits));
138 /* 139 /*
@@ -141,7 +142,7 @@ static struct se_device *iblock_create_virtdevice(
141 ib_dev->ibd_bio_set = bioset_create(32, 64); 142 ib_dev->ibd_bio_set = bioset_create(32, 64);
142 if (!(ib_dev->ibd_bio_set)) { 143 if (!(ib_dev->ibd_bio_set)) {
143 printk(KERN_ERR "IBLOCK: Unable to create bioset()\n"); 144 printk(KERN_ERR "IBLOCK: Unable to create bioset()\n");
144 return 0; 145 return ERR_PTR(-ENOMEM);
145 } 146 }
146 printk(KERN_INFO "IBLOCK: Created bio_set()\n"); 147 printk(KERN_INFO "IBLOCK: Created bio_set()\n");
147 /* 148 /*
@@ -153,8 +154,10 @@ static struct se_device *iblock_create_virtdevice(
153 154
154 bd = blkdev_get_by_path(ib_dev->ibd_udev_path, 155 bd = blkdev_get_by_path(ib_dev->ibd_udev_path,
155 FMODE_WRITE|FMODE_READ|FMODE_EXCL, ib_dev); 156 FMODE_WRITE|FMODE_READ|FMODE_EXCL, ib_dev);
156 if (IS_ERR(bd)) 157 if (IS_ERR(bd)) {
158 ret = PTR_ERR(bd);
157 goto failed; 159 goto failed;
160 }
158 /* 161 /*
159 * Setup the local scope queue_limits from struct request_queue->limits 162 * Setup the local scope queue_limits from struct request_queue->limits
160 * to pass into transport_add_device_to_core_hba() as struct se_dev_limits. 163 * to pass into transport_add_device_to_core_hba() as struct se_dev_limits.
@@ -184,9 +187,7 @@ static struct se_device *iblock_create_virtdevice(
184 * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM 187 * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
185 * in ATA and we need to set TPE=1 188 * in ATA and we need to set TPE=1
186 */ 189 */
187 if (blk_queue_discard(bdev_get_queue(bd))) { 190 if (blk_queue_discard(q)) {
188 struct request_queue *q = bdev_get_queue(bd);
189
190 DEV_ATTRIB(dev)->max_unmap_lba_count = 191 DEV_ATTRIB(dev)->max_unmap_lba_count =
191 q->limits.max_discard_sectors; 192 q->limits.max_discard_sectors;
192 /* 193 /*
@@ -212,7 +213,7 @@ failed:
212 ib_dev->ibd_bd = NULL; 213 ib_dev->ibd_bd = NULL;
213 ib_dev->ibd_major = 0; 214 ib_dev->ibd_major = 0;
214 ib_dev->ibd_minor = 0; 215 ib_dev->ibd_minor = 0;
215 return NULL; 216 return ERR_PTR(ret);
216} 217}
217 218
218static void iblock_free_device(void *p) 219static void iblock_free_device(void *p)
@@ -391,9 +392,8 @@ static int iblock_do_task(struct se_task *task)
391{ 392{
392 struct se_device *dev = task->task_se_cmd->se_dev; 393 struct se_device *dev = task->task_se_cmd->se_dev;
393 struct iblock_req *req = IBLOCK_REQ(task); 394 struct iblock_req *req = IBLOCK_REQ(task);
394 struct iblock_dev *ibd = (struct iblock_dev *)req->ib_dev;
395 struct request_queue *q = bdev_get_queue(ibd->ibd_bd);
396 struct bio *bio = req->ib_bio, *nbio = NULL; 395 struct bio *bio = req->ib_bio, *nbio = NULL;
396 struct blk_plug plug;
397 int rw; 397 int rw;
398 398
399 if (task->task_data_direction == DMA_TO_DEVICE) { 399 if (task->task_data_direction == DMA_TO_DEVICE) {
@@ -411,6 +411,7 @@ static int iblock_do_task(struct se_task *task)
411 rw = READ; 411 rw = READ;
412 } 412 }
413 413
414 blk_start_plug(&plug);
414 while (bio) { 415 while (bio) {
415 nbio = bio->bi_next; 416 nbio = bio->bi_next;
416 bio->bi_next = NULL; 417 bio->bi_next = NULL;
@@ -420,9 +421,8 @@ static int iblock_do_task(struct se_task *task)
420 submit_bio(rw, bio); 421 submit_bio(rw, bio);
421 bio = nbio; 422 bio = nbio;
422 } 423 }
424 blk_finish_plug(&plug);
423 425
424 if (q->unplug_fn)
425 q->unplug_fn(q);
426 return PYX_TRANSPORT_SENT_TO_TRANSPORT; 426 return PYX_TRANSPORT_SENT_TO_TRANSPORT;
427} 427}
428 428
@@ -468,7 +468,7 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba,
468 const char *page, ssize_t count) 468 const char *page, ssize_t count)
469{ 469{
470 struct iblock_dev *ib_dev = se_dev->se_dev_su_ptr; 470 struct iblock_dev *ib_dev = se_dev->se_dev_su_ptr;
471 char *orig, *ptr, *opts; 471 char *orig, *ptr, *arg_p, *opts;
472 substring_t args[MAX_OPT_ARGS]; 472 substring_t args[MAX_OPT_ARGS];
473 int ret = 0, arg, token; 473 int ret = 0, arg, token;
474 474
@@ -491,9 +491,14 @@ static ssize_t iblock_set_configfs_dev_params(struct se_hba *hba,
491 ret = -EEXIST; 491 ret = -EEXIST;
492 goto out; 492 goto out;
493 } 493 }
494 494 arg_p = match_strdup(&args[0]);
495 ret = snprintf(ib_dev->ibd_udev_path, SE_UDEV_PATH_LEN, 495 if (!arg_p) {
496 "%s", match_strdup(&args[0])); 496 ret = -ENOMEM;
497 break;
498 }
499 snprintf(ib_dev->ibd_udev_path, SE_UDEV_PATH_LEN,
500 "%s", arg_p);
501 kfree(arg_p);
497 printk(KERN_INFO "IBLOCK: Referencing UDEV path: %s\n", 502 printk(KERN_INFO "IBLOCK: Referencing UDEV path: %s\n",
498 ib_dev->ibd_udev_path); 503 ib_dev->ibd_udev_path);
499 ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH; 504 ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH;
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index 2521f75362c3..a79f518ca6e2 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -478,7 +478,7 @@ static int core_scsi3_pr_seq_non_holder(
478 break; 478 break;
479 } 479 }
480 /* 480 /*
481 * Case where the CDB is explictly allowed in the above switch 481 * Case where the CDB is explicitly allowed in the above switch
482 * statement. 482 * statement.
483 */ 483 */
484 if (!(ret) && !(other_cdb)) { 484 if (!(ret) && !(other_cdb)) {
@@ -3735,7 +3735,7 @@ static int core_scsi3_emulate_pr_out(struct se_cmd *cmd, unsigned char *cdb)
3735 return PYX_TRANSPORT_LU_COMM_FAILURE; 3735 return PYX_TRANSPORT_LU_COMM_FAILURE;
3736 3736
3737 if (cmd->data_length < 24) { 3737 if (cmd->data_length < 24) {
3738 printk(KERN_WARNING "SPC-PR: Recieved PR OUT parameter list" 3738 printk(KERN_WARNING "SPC-PR: Received PR OUT parameter list"
3739 " length too small: %u\n", cmd->data_length); 3739 " length too small: %u\n", cmd->data_length);
3740 return PYX_TRANSPORT_INVALID_PARAMETER_LIST; 3740 return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
3741 } 3741 }
@@ -3778,7 +3778,7 @@ static int core_scsi3_emulate_pr_out(struct se_cmd *cmd, unsigned char *cdb)
3778 */ 3778 */
3779 if (!(spec_i_pt) && ((cdb[1] & 0x1f) != PRO_REGISTER_AND_MOVE) && 3779 if (!(spec_i_pt) && ((cdb[1] & 0x1f) != PRO_REGISTER_AND_MOVE) &&
3780 (cmd->data_length != 24)) { 3780 (cmd->data_length != 24)) {
3781 printk(KERN_WARNING "SPC-PR: Recieved PR OUT illegal parameter" 3781 printk(KERN_WARNING "SPC-PR: Received PR OUT illegal parameter"
3782 " list length: %u\n", cmd->data_length); 3782 " list length: %u\n", cmd->data_length);
3783 return PYX_TRANSPORT_INVALID_PARAMETER_LIST; 3783 return PYX_TRANSPORT_INVALID_PARAMETER_LIST;
3784 } 3784 }
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index 5a9d2ba4b609..7ff6a35f26ac 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -441,6 +441,7 @@ static struct se_device *pscsi_create_type_disk(
441 struct pscsi_dev_virt *pdv, 441 struct pscsi_dev_virt *pdv,
442 struct se_subsystem_dev *se_dev, 442 struct se_subsystem_dev *se_dev,
443 struct se_hba *hba) 443 struct se_hba *hba)
444 __releases(sh->host_lock)
444{ 445{
445 struct se_device *dev; 446 struct se_device *dev;
446 struct pscsi_hba_virt *phv = (struct pscsi_hba_virt *)pdv->pdv_se_hba->hba_ptr; 447 struct pscsi_hba_virt *phv = (struct pscsi_hba_virt *)pdv->pdv_se_hba->hba_ptr;
@@ -488,6 +489,7 @@ static struct se_device *pscsi_create_type_rom(
488 struct pscsi_dev_virt *pdv, 489 struct pscsi_dev_virt *pdv,
489 struct se_subsystem_dev *se_dev, 490 struct se_subsystem_dev *se_dev,
490 struct se_hba *hba) 491 struct se_hba *hba)
492 __releases(sh->host_lock)
491{ 493{
492 struct se_device *dev; 494 struct se_device *dev;
493 struct pscsi_hba_virt *phv = (struct pscsi_hba_virt *)pdv->pdv_se_hba->hba_ptr; 495 struct pscsi_hba_virt *phv = (struct pscsi_hba_virt *)pdv->pdv_se_hba->hba_ptr;
@@ -522,6 +524,7 @@ static struct se_device *pscsi_create_type_other(
522 struct pscsi_dev_virt *pdv, 524 struct pscsi_dev_virt *pdv,
523 struct se_subsystem_dev *se_dev, 525 struct se_subsystem_dev *se_dev,
524 struct se_hba *hba) 526 struct se_hba *hba)
527 __releases(sh->host_lock)
525{ 528{
526 struct se_device *dev; 529 struct se_device *dev;
527 struct pscsi_hba_virt *phv = (struct pscsi_hba_virt *)pdv->pdv_se_hba->hba_ptr; 530 struct pscsi_hba_virt *phv = (struct pscsi_hba_virt *)pdv->pdv_se_hba->hba_ptr;
@@ -555,7 +558,7 @@ static struct se_device *pscsi_create_virtdevice(
555 if (!(pdv)) { 558 if (!(pdv)) {
556 printk(KERN_ERR "Unable to locate struct pscsi_dev_virt" 559 printk(KERN_ERR "Unable to locate struct pscsi_dev_virt"
557 " parameter\n"); 560 " parameter\n");
558 return NULL; 561 return ERR_PTR(-EINVAL);
559 } 562 }
560 /* 563 /*
561 * If not running in PHV_LLD_SCSI_HOST_NO mode, locate the 564 * If not running in PHV_LLD_SCSI_HOST_NO mode, locate the
@@ -565,7 +568,7 @@ static struct se_device *pscsi_create_virtdevice(
565 if (phv->phv_mode == PHV_LLD_SCSI_HOST_NO) { 568 if (phv->phv_mode == PHV_LLD_SCSI_HOST_NO) {
566 printk(KERN_ERR "pSCSI: Unable to locate struct" 569 printk(KERN_ERR "pSCSI: Unable to locate struct"
567 " Scsi_Host for PHV_LLD_SCSI_HOST_NO\n"); 570 " Scsi_Host for PHV_LLD_SCSI_HOST_NO\n");
568 return NULL; 571 return ERR_PTR(-ENODEV);
569 } 572 }
570 /* 573 /*
571 * For the newer PHV_VIRUTAL_HOST_ID struct scsi_device 574 * For the newer PHV_VIRUTAL_HOST_ID struct scsi_device
@@ -574,7 +577,7 @@ static struct se_device *pscsi_create_virtdevice(
574 if (!(se_dev->su_dev_flags & SDF_USING_UDEV_PATH)) { 577 if (!(se_dev->su_dev_flags & SDF_USING_UDEV_PATH)) {
575 printk(KERN_ERR "pSCSI: udev_path attribute has not" 578 printk(KERN_ERR "pSCSI: udev_path attribute has not"
576 " been set before ENABLE=1\n"); 579 " been set before ENABLE=1\n");
577 return NULL; 580 return ERR_PTR(-EINVAL);
578 } 581 }
579 /* 582 /*
580 * If no scsi_host_id= was passed for PHV_VIRUTAL_HOST_ID, 583 * If no scsi_host_id= was passed for PHV_VIRUTAL_HOST_ID,
@@ -587,12 +590,12 @@ static struct se_device *pscsi_create_virtdevice(
587 printk(KERN_ERR "pSCSI: Unable to set hba_mode" 590 printk(KERN_ERR "pSCSI: Unable to set hba_mode"
588 " with active devices\n"); 591 " with active devices\n");
589 spin_unlock(&hba->device_lock); 592 spin_unlock(&hba->device_lock);
590 return NULL; 593 return ERR_PTR(-EEXIST);
591 } 594 }
592 spin_unlock(&hba->device_lock); 595 spin_unlock(&hba->device_lock);
593 596
594 if (pscsi_pmode_enable_hba(hba, 1) != 1) 597 if (pscsi_pmode_enable_hba(hba, 1) != 1)
595 return NULL; 598 return ERR_PTR(-ENODEV);
596 599
597 legacy_mode_enable = 1; 600 legacy_mode_enable = 1;
598 hba->hba_flags |= HBA_FLAGS_PSCSI_MODE; 601 hba->hba_flags |= HBA_FLAGS_PSCSI_MODE;
@@ -602,14 +605,14 @@ static struct se_device *pscsi_create_virtdevice(
602 if (!(sh)) { 605 if (!(sh)) {
603 printk(KERN_ERR "pSCSI: Unable to locate" 606 printk(KERN_ERR "pSCSI: Unable to locate"
604 " pdv_host_id: %d\n", pdv->pdv_host_id); 607 " pdv_host_id: %d\n", pdv->pdv_host_id);
605 return NULL; 608 return ERR_PTR(-ENODEV);
606 } 609 }
607 } 610 }
608 } else { 611 } else {
609 if (phv->phv_mode == PHV_VIRUTAL_HOST_ID) { 612 if (phv->phv_mode == PHV_VIRUTAL_HOST_ID) {
610 printk(KERN_ERR "pSCSI: PHV_VIRUTAL_HOST_ID set while" 613 printk(KERN_ERR "pSCSI: PHV_VIRUTAL_HOST_ID set while"
611 " struct Scsi_Host exists\n"); 614 " struct Scsi_Host exists\n");
612 return NULL; 615 return ERR_PTR(-EEXIST);
613 } 616 }
614 } 617 }
615 618
@@ -644,7 +647,7 @@ static struct se_device *pscsi_create_virtdevice(
644 hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE; 647 hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE;
645 } 648 }
646 pdv->pdv_sd = NULL; 649 pdv->pdv_sd = NULL;
647 return NULL; 650 return ERR_PTR(-ENODEV);
648 } 651 }
649 return dev; 652 return dev;
650 } 653 }
@@ -660,7 +663,7 @@ static struct se_device *pscsi_create_virtdevice(
660 hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE; 663 hba->hba_flags &= ~HBA_FLAGS_PSCSI_MODE;
661 } 664 }
662 665
663 return NULL; 666 return ERR_PTR(-ENODEV);
664} 667}
665 668
666/* pscsi_free_device(): (Part of se_subsystem_api_t template) 669/* pscsi_free_device(): (Part of se_subsystem_api_t template)
@@ -816,6 +819,7 @@ pscsi_alloc_task(struct se_cmd *cmd)
816 if (!(pt->pscsi_cdb)) { 819 if (!(pt->pscsi_cdb)) {
817 printk(KERN_ERR "pSCSI: Unable to allocate extended" 820 printk(KERN_ERR "pSCSI: Unable to allocate extended"
818 " pt->pscsi_cdb\n"); 821 " pt->pscsi_cdb\n");
822 kfree(pt);
819 return NULL; 823 return NULL;
820 } 824 }
821 } else 825 } else
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index 8dc6d74c1d40..7837dd365a9d 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -150,7 +150,7 @@ static int rd_build_device_space(struct rd_dev *rd_dev)
150 if (rd_dev->rd_page_count <= 0) { 150 if (rd_dev->rd_page_count <= 0) {
151 printk(KERN_ERR "Illegal page count: %u for Ramdisk device\n", 151 printk(KERN_ERR "Illegal page count: %u for Ramdisk device\n",
152 rd_dev->rd_page_count); 152 rd_dev->rd_page_count);
153 return -1; 153 return -EINVAL;
154 } 154 }
155 total_sg_needed = rd_dev->rd_page_count; 155 total_sg_needed = rd_dev->rd_page_count;
156 156
@@ -160,7 +160,7 @@ static int rd_build_device_space(struct rd_dev *rd_dev)
160 if (!(sg_table)) { 160 if (!(sg_table)) {
161 printk(KERN_ERR "Unable to allocate memory for Ramdisk" 161 printk(KERN_ERR "Unable to allocate memory for Ramdisk"
162 " scatterlist tables\n"); 162 " scatterlist tables\n");
163 return -1; 163 return -ENOMEM;
164 } 164 }
165 165
166 rd_dev->sg_table_array = sg_table; 166 rd_dev->sg_table_array = sg_table;
@@ -175,7 +175,7 @@ static int rd_build_device_space(struct rd_dev *rd_dev)
175 if (!(sg)) { 175 if (!(sg)) {
176 printk(KERN_ERR "Unable to allocate scatterlist array" 176 printk(KERN_ERR "Unable to allocate scatterlist array"
177 " for struct rd_dev\n"); 177 " for struct rd_dev\n");
178 return -1; 178 return -ENOMEM;
179 } 179 }
180 180
181 sg_init_table((struct scatterlist *)&sg[0], sg_per_table); 181 sg_init_table((struct scatterlist *)&sg[0], sg_per_table);
@@ -191,7 +191,7 @@ static int rd_build_device_space(struct rd_dev *rd_dev)
191 if (!(pg)) { 191 if (!(pg)) {
192 printk(KERN_ERR "Unable to allocate scatterlist" 192 printk(KERN_ERR "Unable to allocate scatterlist"
193 " pages for struct rd_dev_sg_table\n"); 193 " pages for struct rd_dev_sg_table\n");
194 return -1; 194 return -ENOMEM;
195 } 195 }
196 sg_assign_page(&sg[j], pg); 196 sg_assign_page(&sg[j], pg);
197 sg[j].length = PAGE_SIZE; 197 sg[j].length = PAGE_SIZE;
@@ -253,12 +253,13 @@ static struct se_device *rd_create_virtdevice(
253 struct se_dev_limits dev_limits; 253 struct se_dev_limits dev_limits;
254 struct rd_dev *rd_dev = p; 254 struct rd_dev *rd_dev = p;
255 struct rd_host *rd_host = hba->hba_ptr; 255 struct rd_host *rd_host = hba->hba_ptr;
256 int dev_flags = 0; 256 int dev_flags = 0, ret;
257 char prod[16], rev[4]; 257 char prod[16], rev[4];
258 258
259 memset(&dev_limits, 0, sizeof(struct se_dev_limits)); 259 memset(&dev_limits, 0, sizeof(struct se_dev_limits));
260 260
261 if (rd_build_device_space(rd_dev) < 0) 261 ret = rd_build_device_space(rd_dev);
262 if (ret < 0)
262 goto fail; 263 goto fail;
263 264
264 snprintf(prod, 16, "RAMDISK-%s", (rd_dev->rd_direct) ? "DR" : "MCP"); 265 snprintf(prod, 16, "RAMDISK-%s", (rd_dev->rd_direct) ? "DR" : "MCP");
@@ -292,7 +293,7 @@ static struct se_device *rd_create_virtdevice(
292 293
293fail: 294fail:
294 rd_release_device_space(rd_dev); 295 rd_release_device_space(rd_dev);
295 return NULL; 296 return ERR_PTR(ret);
296} 297}
297 298
298static struct se_device *rd_DIRECT_create_virtdevice( 299static struct se_device *rd_DIRECT_create_virtdevice(
diff --git a/drivers/target/target_core_rd.h b/drivers/target/target_core_rd.h
index 13badfbaf9c0..3ea19e29d8ec 100644
--- a/drivers/target/target_core_rd.h
+++ b/drivers/target/target_core_rd.h
@@ -14,8 +14,6 @@
14#define RD_BLOCKSIZE 512 14#define RD_BLOCKSIZE 512
15#define RD_MAX_SECTORS 1024 15#define RD_MAX_SECTORS 1024
16 16
17extern struct kmem_cache *se_mem_cache;
18
19/* Used in target_core_init_configfs() for virtual LUN 0 access */ 17/* Used in target_core_init_configfs() for virtual LUN 0 access */
20int __init rd_module_init(void); 18int __init rd_module_init(void);
21void rd_module_exit(void); 19void rd_module_exit(void);
diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c
new file mode 100644
index 000000000000..5e3a067a7475
--- /dev/null
+++ b/drivers/target/target_core_stat.c
@@ -0,0 +1,1810 @@
1/*******************************************************************************
2 * Filename: target_core_stat.c
3 *
4 * Copyright (c) 2011 Rising Tide Systems
5 * Copyright (c) 2011 Linux-iSCSI.org
6 *
7 * Modern ConfigFS group context specific statistics based on original
8 * target_core_mib.c code
9 *
10 * Copyright (c) 2006-2007 SBE, Inc. All Rights Reserved.
11 *
12 * Nicholas A. Bellinger <nab@linux-iscsi.org>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 *
28 ******************************************************************************/
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/delay.h>
33#include <linux/timer.h>
34#include <linux/string.h>
35#include <linux/version.h>
36#include <generated/utsrelease.h>
37#include <linux/utsname.h>
38#include <linux/proc_fs.h>
39#include <linux/seq_file.h>
40#include <linux/blkdev.h>
41#include <linux/configfs.h>
42#include <scsi/scsi.h>
43#include <scsi/scsi_device.h>
44#include <scsi/scsi_host.h>
45
46#include <target/target_core_base.h>
47#include <target/target_core_transport.h>
48#include <target/target_core_fabric_ops.h>
49#include <target/target_core_configfs.h>
50#include <target/configfs_macros.h>
51
52#include "target_core_hba.h"
53
54#ifndef INITIAL_JIFFIES
55#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
56#endif
57
58#define NONE "None"
59#define ISPRINT(a) ((a >= ' ') && (a <= '~'))
60
61#define SCSI_LU_INDEX 1
62#define LU_COUNT 1
63
64/*
65 * SCSI Device Table
66 */
67
68CONFIGFS_EATTR_STRUCT(target_stat_scsi_dev, se_dev_stat_grps);
69#define DEV_STAT_SCSI_DEV_ATTR(_name, _mode) \
70static struct target_stat_scsi_dev_attribute \
71 target_stat_scsi_dev_##_name = \
72 __CONFIGFS_EATTR(_name, _mode, \
73 target_stat_scsi_dev_show_attr_##_name, \
74 target_stat_scsi_dev_store_attr_##_name);
75
76#define DEV_STAT_SCSI_DEV_ATTR_RO(_name) \
77static struct target_stat_scsi_dev_attribute \
78 target_stat_scsi_dev_##_name = \
79 __CONFIGFS_EATTR_RO(_name, \
80 target_stat_scsi_dev_show_attr_##_name);
81
82static ssize_t target_stat_scsi_dev_show_attr_inst(
83 struct se_dev_stat_grps *sgrps, char *page)
84{
85 struct se_subsystem_dev *se_subdev = container_of(sgrps,
86 struct se_subsystem_dev, dev_stat_grps);
87 struct se_hba *hba = se_subdev->se_dev_hba;
88 struct se_device *dev = se_subdev->se_dev_ptr;
89
90 if (!dev)
91 return -ENODEV;
92
93 return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
94}
95DEV_STAT_SCSI_DEV_ATTR_RO(inst);
96
97static ssize_t target_stat_scsi_dev_show_attr_indx(
98 struct se_dev_stat_grps *sgrps, char *page)
99{
100 struct se_subsystem_dev *se_subdev = container_of(sgrps,
101 struct se_subsystem_dev, dev_stat_grps);
102 struct se_device *dev = se_subdev->se_dev_ptr;
103
104 if (!dev)
105 return -ENODEV;
106
107 return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
108}
109DEV_STAT_SCSI_DEV_ATTR_RO(indx);
110
111static ssize_t target_stat_scsi_dev_show_attr_role(
112 struct se_dev_stat_grps *sgrps, char *page)
113{
114 struct se_subsystem_dev *se_subdev = container_of(sgrps,
115 struct se_subsystem_dev, dev_stat_grps);
116 struct se_device *dev = se_subdev->se_dev_ptr;
117
118 if (!dev)
119 return -ENODEV;
120
121 return snprintf(page, PAGE_SIZE, "Target\n");
122}
123DEV_STAT_SCSI_DEV_ATTR_RO(role);
124
125static ssize_t target_stat_scsi_dev_show_attr_ports(
126 struct se_dev_stat_grps *sgrps, char *page)
127{
128 struct se_subsystem_dev *se_subdev = container_of(sgrps,
129 struct se_subsystem_dev, dev_stat_grps);
130 struct se_device *dev = se_subdev->se_dev_ptr;
131
132 if (!dev)
133 return -ENODEV;
134
135 return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_port_count);
136}
137DEV_STAT_SCSI_DEV_ATTR_RO(ports);
138
139CONFIGFS_EATTR_OPS(target_stat_scsi_dev, se_dev_stat_grps, scsi_dev_group);
140
141static struct configfs_attribute *target_stat_scsi_dev_attrs[] = {
142 &target_stat_scsi_dev_inst.attr,
143 &target_stat_scsi_dev_indx.attr,
144 &target_stat_scsi_dev_role.attr,
145 &target_stat_scsi_dev_ports.attr,
146 NULL,
147};
148
149static struct configfs_item_operations target_stat_scsi_dev_attrib_ops = {
150 .show_attribute = target_stat_scsi_dev_attr_show,
151 .store_attribute = target_stat_scsi_dev_attr_store,
152};
153
154static struct config_item_type target_stat_scsi_dev_cit = {
155 .ct_item_ops = &target_stat_scsi_dev_attrib_ops,
156 .ct_attrs = target_stat_scsi_dev_attrs,
157 .ct_owner = THIS_MODULE,
158};
159
160/*
161 * SCSI Target Device Table
162 */
163
164CONFIGFS_EATTR_STRUCT(target_stat_scsi_tgt_dev, se_dev_stat_grps);
165#define DEV_STAT_SCSI_TGT_DEV_ATTR(_name, _mode) \
166static struct target_stat_scsi_tgt_dev_attribute \
167 target_stat_scsi_tgt_dev_##_name = \
168 __CONFIGFS_EATTR(_name, _mode, \
169 target_stat_scsi_tgt_dev_show_attr_##_name, \
170 target_stat_scsi_tgt_dev_store_attr_##_name);
171
172#define DEV_STAT_SCSI_TGT_DEV_ATTR_RO(_name) \
173static struct target_stat_scsi_tgt_dev_attribute \
174 target_stat_scsi_tgt_dev_##_name = \
175 __CONFIGFS_EATTR_RO(_name, \
176 target_stat_scsi_tgt_dev_show_attr_##_name);
177
178static ssize_t target_stat_scsi_tgt_dev_show_attr_inst(
179 struct se_dev_stat_grps *sgrps, char *page)
180{
181 struct se_subsystem_dev *se_subdev = container_of(sgrps,
182 struct se_subsystem_dev, dev_stat_grps);
183 struct se_hba *hba = se_subdev->se_dev_hba;
184 struct se_device *dev = se_subdev->se_dev_ptr;
185
186 if (!dev)
187 return -ENODEV;
188
189 return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
190}
191DEV_STAT_SCSI_TGT_DEV_ATTR_RO(inst);
192
193static ssize_t target_stat_scsi_tgt_dev_show_attr_indx(
194 struct se_dev_stat_grps *sgrps, char *page)
195{
196 struct se_subsystem_dev *se_subdev = container_of(sgrps,
197 struct se_subsystem_dev, dev_stat_grps);
198 struct se_device *dev = se_subdev->se_dev_ptr;
199
200 if (!dev)
201 return -ENODEV;
202
203 return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
204}
205DEV_STAT_SCSI_TGT_DEV_ATTR_RO(indx);
206
207static ssize_t target_stat_scsi_tgt_dev_show_attr_num_lus(
208 struct se_dev_stat_grps *sgrps, char *page)
209{
210 struct se_subsystem_dev *se_subdev = container_of(sgrps,
211 struct se_subsystem_dev, dev_stat_grps);
212 struct se_device *dev = se_subdev->se_dev_ptr;
213
214 if (!dev)
215 return -ENODEV;
216
217 return snprintf(page, PAGE_SIZE, "%u\n", LU_COUNT);
218}
219DEV_STAT_SCSI_TGT_DEV_ATTR_RO(num_lus);
220
221static ssize_t target_stat_scsi_tgt_dev_show_attr_status(
222 struct se_dev_stat_grps *sgrps, char *page)
223{
224 struct se_subsystem_dev *se_subdev = container_of(sgrps,
225 struct se_subsystem_dev, dev_stat_grps);
226 struct se_device *dev = se_subdev->se_dev_ptr;
227 char status[16];
228
229 if (!dev)
230 return -ENODEV;
231
232 switch (dev->dev_status) {
233 case TRANSPORT_DEVICE_ACTIVATED:
234 strcpy(status, "activated");
235 break;
236 case TRANSPORT_DEVICE_DEACTIVATED:
237 strcpy(status, "deactivated");
238 break;
239 case TRANSPORT_DEVICE_SHUTDOWN:
240 strcpy(status, "shutdown");
241 break;
242 case TRANSPORT_DEVICE_OFFLINE_ACTIVATED:
243 case TRANSPORT_DEVICE_OFFLINE_DEACTIVATED:
244 strcpy(status, "offline");
245 break;
246 default:
247 sprintf(status, "unknown(%d)", dev->dev_status);
248 break;
249 }
250
251 return snprintf(page, PAGE_SIZE, "%s\n", status);
252}
253DEV_STAT_SCSI_TGT_DEV_ATTR_RO(status);
254
255static ssize_t target_stat_scsi_tgt_dev_show_attr_non_access_lus(
256 struct se_dev_stat_grps *sgrps, char *page)
257{
258 struct se_subsystem_dev *se_subdev = container_of(sgrps,
259 struct se_subsystem_dev, dev_stat_grps);
260 struct se_device *dev = se_subdev->se_dev_ptr;
261 int non_accessible_lus;
262
263 if (!dev)
264 return -ENODEV;
265
266 switch (dev->dev_status) {
267 case TRANSPORT_DEVICE_ACTIVATED:
268 non_accessible_lus = 0;
269 break;
270 case TRANSPORT_DEVICE_DEACTIVATED:
271 case TRANSPORT_DEVICE_SHUTDOWN:
272 case TRANSPORT_DEVICE_OFFLINE_ACTIVATED:
273 case TRANSPORT_DEVICE_OFFLINE_DEACTIVATED:
274 default:
275 non_accessible_lus = 1;
276 break;
277 }
278
279 return snprintf(page, PAGE_SIZE, "%u\n", non_accessible_lus);
280}
281DEV_STAT_SCSI_TGT_DEV_ATTR_RO(non_access_lus);
282
283static ssize_t target_stat_scsi_tgt_dev_show_attr_resets(
284 struct se_dev_stat_grps *sgrps, char *page)
285{
286 struct se_subsystem_dev *se_subdev = container_of(sgrps,
287 struct se_subsystem_dev, dev_stat_grps);
288 struct se_device *dev = se_subdev->se_dev_ptr;
289
290 if (!dev)
291 return -ENODEV;
292
293 return snprintf(page, PAGE_SIZE, "%u\n", dev->num_resets);
294}
295DEV_STAT_SCSI_TGT_DEV_ATTR_RO(resets);
296
297
298CONFIGFS_EATTR_OPS(target_stat_scsi_tgt_dev, se_dev_stat_grps, scsi_tgt_dev_group);
299
300static struct configfs_attribute *target_stat_scsi_tgt_dev_attrs[] = {
301 &target_stat_scsi_tgt_dev_inst.attr,
302 &target_stat_scsi_tgt_dev_indx.attr,
303 &target_stat_scsi_tgt_dev_num_lus.attr,
304 &target_stat_scsi_tgt_dev_status.attr,
305 &target_stat_scsi_tgt_dev_non_access_lus.attr,
306 &target_stat_scsi_tgt_dev_resets.attr,
307 NULL,
308};
309
310static struct configfs_item_operations target_stat_scsi_tgt_dev_attrib_ops = {
311 .show_attribute = target_stat_scsi_tgt_dev_attr_show,
312 .store_attribute = target_stat_scsi_tgt_dev_attr_store,
313};
314
315static struct config_item_type target_stat_scsi_tgt_dev_cit = {
316 .ct_item_ops = &target_stat_scsi_tgt_dev_attrib_ops,
317 .ct_attrs = target_stat_scsi_tgt_dev_attrs,
318 .ct_owner = THIS_MODULE,
319};
320
321/*
322 * SCSI Logical Unit Table
323 */
324
325CONFIGFS_EATTR_STRUCT(target_stat_scsi_lu, se_dev_stat_grps);
326#define DEV_STAT_SCSI_LU_ATTR(_name, _mode) \
327static struct target_stat_scsi_lu_attribute target_stat_scsi_lu_##_name = \
328 __CONFIGFS_EATTR(_name, _mode, \
329 target_stat_scsi_lu_show_attr_##_name, \
330 target_stat_scsi_lu_store_attr_##_name);
331
332#define DEV_STAT_SCSI_LU_ATTR_RO(_name) \
333static struct target_stat_scsi_lu_attribute target_stat_scsi_lu_##_name = \
334 __CONFIGFS_EATTR_RO(_name, \
335 target_stat_scsi_lu_show_attr_##_name);
336
337static ssize_t target_stat_scsi_lu_show_attr_inst(
338 struct se_dev_stat_grps *sgrps, char *page)
339{
340 struct se_subsystem_dev *se_subdev = container_of(sgrps,
341 struct se_subsystem_dev, dev_stat_grps);
342 struct se_hba *hba = se_subdev->se_dev_hba;
343 struct se_device *dev = se_subdev->se_dev_ptr;
344
345 if (!dev)
346 return -ENODEV;
347
348 return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
349}
350DEV_STAT_SCSI_LU_ATTR_RO(inst);
351
352static ssize_t target_stat_scsi_lu_show_attr_dev(
353 struct se_dev_stat_grps *sgrps, char *page)
354{
355 struct se_subsystem_dev *se_subdev = container_of(sgrps,
356 struct se_subsystem_dev, dev_stat_grps);
357 struct se_device *dev = se_subdev->se_dev_ptr;
358
359 if (!dev)
360 return -ENODEV;
361
362 return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
363}
364DEV_STAT_SCSI_LU_ATTR_RO(dev);
365
366static ssize_t target_stat_scsi_lu_show_attr_indx(
367 struct se_dev_stat_grps *sgrps, char *page)
368{
369 struct se_subsystem_dev *se_subdev = container_of(sgrps,
370 struct se_subsystem_dev, dev_stat_grps);
371 struct se_device *dev = se_subdev->se_dev_ptr;
372
373 if (!dev)
374 return -ENODEV;
375
376 return snprintf(page, PAGE_SIZE, "%u\n", SCSI_LU_INDEX);
377}
378DEV_STAT_SCSI_LU_ATTR_RO(indx);
379
380static ssize_t target_stat_scsi_lu_show_attr_lun(
381 struct se_dev_stat_grps *sgrps, char *page)
382{
383 struct se_subsystem_dev *se_subdev = container_of(sgrps,
384 struct se_subsystem_dev, dev_stat_grps);
385 struct se_device *dev = se_subdev->se_dev_ptr;
386
387 if (!dev)
388 return -ENODEV;
389 /* FIXME: scsiLuDefaultLun */
390 return snprintf(page, PAGE_SIZE, "%llu\n", (unsigned long long)0);
391}
392DEV_STAT_SCSI_LU_ATTR_RO(lun);
393
394static ssize_t target_stat_scsi_lu_show_attr_lu_name(
395 struct se_dev_stat_grps *sgrps, char *page)
396{
397 struct se_subsystem_dev *se_subdev = container_of(sgrps,
398 struct se_subsystem_dev, dev_stat_grps);
399 struct se_device *dev = se_subdev->se_dev_ptr;
400
401 if (!dev)
402 return -ENODEV;
403 /* scsiLuWwnName */
404 return snprintf(page, PAGE_SIZE, "%s\n",
405 (strlen(DEV_T10_WWN(dev)->unit_serial)) ?
406 (char *)&DEV_T10_WWN(dev)->unit_serial[0] : "None");
407}
408DEV_STAT_SCSI_LU_ATTR_RO(lu_name);
409
410static ssize_t target_stat_scsi_lu_show_attr_vend(
411 struct se_dev_stat_grps *sgrps, char *page)
412{
413 struct se_subsystem_dev *se_subdev = container_of(sgrps,
414 struct se_subsystem_dev, dev_stat_grps);
415 struct se_device *dev = se_subdev->se_dev_ptr;
416 int j;
417 char str[28];
418
419 if (!dev)
420 return -ENODEV;
421 /* scsiLuVendorId */
422 memcpy(&str[0], (void *)DEV_T10_WWN(dev), 28);
423 for (j = 0; j < 8; j++)
424 str[j] = ISPRINT(DEV_T10_WWN(dev)->vendor[j]) ?
425 DEV_T10_WWN(dev)->vendor[j] : 0x20;
426 str[8] = 0;
427 return snprintf(page, PAGE_SIZE, "%s\n", str);
428}
429DEV_STAT_SCSI_LU_ATTR_RO(vend);
430
431static ssize_t target_stat_scsi_lu_show_attr_prod(
432 struct se_dev_stat_grps *sgrps, char *page)
433{
434 struct se_subsystem_dev *se_subdev = container_of(sgrps,
435 struct se_subsystem_dev, dev_stat_grps);
436 struct se_device *dev = se_subdev->se_dev_ptr;
437 int j;
438 char str[28];
439
440 if (!dev)
441 return -ENODEV;
442
443 /* scsiLuProductId */
444 memcpy(&str[0], (void *)DEV_T10_WWN(dev), 28);
445 for (j = 0; j < 16; j++)
446 str[j] = ISPRINT(DEV_T10_WWN(dev)->model[j]) ?
447 DEV_T10_WWN(dev)->model[j] : 0x20;
448 str[16] = 0;
449 return snprintf(page, PAGE_SIZE, "%s\n", str);
450}
451DEV_STAT_SCSI_LU_ATTR_RO(prod);
452
453static ssize_t target_stat_scsi_lu_show_attr_rev(
454 struct se_dev_stat_grps *sgrps, char *page)
455{
456 struct se_subsystem_dev *se_subdev = container_of(sgrps,
457 struct se_subsystem_dev, dev_stat_grps);
458 struct se_device *dev = se_subdev->se_dev_ptr;
459 int j;
460 char str[28];
461
462 if (!dev)
463 return -ENODEV;
464
465 /* scsiLuRevisionId */
466 memcpy(&str[0], (void *)DEV_T10_WWN(dev), 28);
467 for (j = 0; j < 4; j++)
468 str[j] = ISPRINT(DEV_T10_WWN(dev)->revision[j]) ?
469 DEV_T10_WWN(dev)->revision[j] : 0x20;
470 str[4] = 0;
471 return snprintf(page, PAGE_SIZE, "%s\n", str);
472}
473DEV_STAT_SCSI_LU_ATTR_RO(rev);
474
475static ssize_t target_stat_scsi_lu_show_attr_dev_type(
476 struct se_dev_stat_grps *sgrps, char *page)
477{
478 struct se_subsystem_dev *se_subdev = container_of(sgrps,
479 struct se_subsystem_dev, dev_stat_grps);
480 struct se_device *dev = se_subdev->se_dev_ptr;
481
482 if (!dev)
483 return -ENODEV;
484
485 /* scsiLuPeripheralType */
486 return snprintf(page, PAGE_SIZE, "%u\n",
487 TRANSPORT(dev)->get_device_type(dev));
488}
489DEV_STAT_SCSI_LU_ATTR_RO(dev_type);
490
491static ssize_t target_stat_scsi_lu_show_attr_status(
492 struct se_dev_stat_grps *sgrps, char *page)
493{
494 struct se_subsystem_dev *se_subdev = container_of(sgrps,
495 struct se_subsystem_dev, dev_stat_grps);
496 struct se_device *dev = se_subdev->se_dev_ptr;
497
498 if (!dev)
499 return -ENODEV;
500
501 /* scsiLuStatus */
502 return snprintf(page, PAGE_SIZE, "%s\n",
503 (dev->dev_status == TRANSPORT_DEVICE_ACTIVATED) ?
504 "available" : "notavailable");
505}
506DEV_STAT_SCSI_LU_ATTR_RO(status);
507
508static ssize_t target_stat_scsi_lu_show_attr_state_bit(
509 struct se_dev_stat_grps *sgrps, char *page)
510{
511 struct se_subsystem_dev *se_subdev = container_of(sgrps,
512 struct se_subsystem_dev, dev_stat_grps);
513 struct se_device *dev = se_subdev->se_dev_ptr;
514
515 if (!dev)
516 return -ENODEV;
517
518 /* scsiLuState */
519 return snprintf(page, PAGE_SIZE, "exposed\n");
520}
521DEV_STAT_SCSI_LU_ATTR_RO(state_bit);
522
523static ssize_t target_stat_scsi_lu_show_attr_num_cmds(
524 struct se_dev_stat_grps *sgrps, char *page)
525{
526 struct se_subsystem_dev *se_subdev = container_of(sgrps,
527 struct se_subsystem_dev, dev_stat_grps);
528 struct se_device *dev = se_subdev->se_dev_ptr;
529
530 if (!dev)
531 return -ENODEV;
532
533 /* scsiLuNumCommands */
534 return snprintf(page, PAGE_SIZE, "%llu\n",
535 (unsigned long long)dev->num_cmds);
536}
537DEV_STAT_SCSI_LU_ATTR_RO(num_cmds);
538
539static ssize_t target_stat_scsi_lu_show_attr_read_mbytes(
540 struct se_dev_stat_grps *sgrps, char *page)
541{
542 struct se_subsystem_dev *se_subdev = container_of(sgrps,
543 struct se_subsystem_dev, dev_stat_grps);
544 struct se_device *dev = se_subdev->se_dev_ptr;
545
546 if (!dev)
547 return -ENODEV;
548
549 /* scsiLuReadMegaBytes */
550 return snprintf(page, PAGE_SIZE, "%u\n", (u32)(dev->read_bytes >> 20));
551}
552DEV_STAT_SCSI_LU_ATTR_RO(read_mbytes);
553
554static ssize_t target_stat_scsi_lu_show_attr_write_mbytes(
555 struct se_dev_stat_grps *sgrps, char *page)
556{
557 struct se_subsystem_dev *se_subdev = container_of(sgrps,
558 struct se_subsystem_dev, dev_stat_grps);
559 struct se_device *dev = se_subdev->se_dev_ptr;
560
561 if (!dev)
562 return -ENODEV;
563
564 /* scsiLuWrittenMegaBytes */
565 return snprintf(page, PAGE_SIZE, "%u\n", (u32)(dev->write_bytes >> 20));
566}
567DEV_STAT_SCSI_LU_ATTR_RO(write_mbytes);
568
569static ssize_t target_stat_scsi_lu_show_attr_resets(
570 struct se_dev_stat_grps *sgrps, char *page)
571{
572 struct se_subsystem_dev *se_subdev = container_of(sgrps,
573 struct se_subsystem_dev, dev_stat_grps);
574 struct se_device *dev = se_subdev->se_dev_ptr;
575
576 if (!dev)
577 return -ENODEV;
578
579 /* scsiLuInResets */
580 return snprintf(page, PAGE_SIZE, "%u\n", dev->num_resets);
581}
582DEV_STAT_SCSI_LU_ATTR_RO(resets);
583
584static ssize_t target_stat_scsi_lu_show_attr_full_stat(
585 struct se_dev_stat_grps *sgrps, char *page)
586{
587 struct se_subsystem_dev *se_subdev = container_of(sgrps,
588 struct se_subsystem_dev, dev_stat_grps);
589 struct se_device *dev = se_subdev->se_dev_ptr;
590
591 if (!dev)
592 return -ENODEV;
593
594 /* FIXME: scsiLuOutTaskSetFullStatus */
595 return snprintf(page, PAGE_SIZE, "%u\n", 0);
596}
597DEV_STAT_SCSI_LU_ATTR_RO(full_stat);
598
599static ssize_t target_stat_scsi_lu_show_attr_hs_num_cmds(
600 struct se_dev_stat_grps *sgrps, char *page)
601{
602 struct se_subsystem_dev *se_subdev = container_of(sgrps,
603 struct se_subsystem_dev, dev_stat_grps);
604 struct se_device *dev = se_subdev->se_dev_ptr;
605
606 if (!dev)
607 return -ENODEV;
608
609 /* FIXME: scsiLuHSInCommands */
610 return snprintf(page, PAGE_SIZE, "%u\n", 0);
611}
612DEV_STAT_SCSI_LU_ATTR_RO(hs_num_cmds);
613
614static ssize_t target_stat_scsi_lu_show_attr_creation_time(
615 struct se_dev_stat_grps *sgrps, char *page)
616{
617 struct se_subsystem_dev *se_subdev = container_of(sgrps,
618 struct se_subsystem_dev, dev_stat_grps);
619 struct se_device *dev = se_subdev->se_dev_ptr;
620
621 if (!dev)
622 return -ENODEV;
623
624 /* scsiLuCreationTime */
625 return snprintf(page, PAGE_SIZE, "%u\n", (u32)(((u32)dev->creation_time -
626 INITIAL_JIFFIES) * 100 / HZ));
627}
628DEV_STAT_SCSI_LU_ATTR_RO(creation_time);
629
630CONFIGFS_EATTR_OPS(target_stat_scsi_lu, se_dev_stat_grps, scsi_lu_group);
631
632static struct configfs_attribute *target_stat_scsi_lu_attrs[] = {
633 &target_stat_scsi_lu_inst.attr,
634 &target_stat_scsi_lu_dev.attr,
635 &target_stat_scsi_lu_indx.attr,
636 &target_stat_scsi_lu_lun.attr,
637 &target_stat_scsi_lu_lu_name.attr,
638 &target_stat_scsi_lu_vend.attr,
639 &target_stat_scsi_lu_prod.attr,
640 &target_stat_scsi_lu_rev.attr,
641 &target_stat_scsi_lu_dev_type.attr,
642 &target_stat_scsi_lu_status.attr,
643 &target_stat_scsi_lu_state_bit.attr,
644 &target_stat_scsi_lu_num_cmds.attr,
645 &target_stat_scsi_lu_read_mbytes.attr,
646 &target_stat_scsi_lu_write_mbytes.attr,
647 &target_stat_scsi_lu_resets.attr,
648 &target_stat_scsi_lu_full_stat.attr,
649 &target_stat_scsi_lu_hs_num_cmds.attr,
650 &target_stat_scsi_lu_creation_time.attr,
651 NULL,
652};
653
654static struct configfs_item_operations target_stat_scsi_lu_attrib_ops = {
655 .show_attribute = target_stat_scsi_lu_attr_show,
656 .store_attribute = target_stat_scsi_lu_attr_store,
657};
658
659static struct config_item_type target_stat_scsi_lu_cit = {
660 .ct_item_ops = &target_stat_scsi_lu_attrib_ops,
661 .ct_attrs = target_stat_scsi_lu_attrs,
662 .ct_owner = THIS_MODULE,
663};
664
665/*
666 * Called from target_core_configfs.c:target_core_make_subdev() to setup
667 * the target statistics groups + configfs CITs located in target_core_stat.c
668 */
669void target_stat_setup_dev_default_groups(struct se_subsystem_dev *se_subdev)
670{
671 struct config_group *dev_stat_grp = &DEV_STAT_GRP(se_subdev)->stat_group;
672
673 config_group_init_type_name(&DEV_STAT_GRP(se_subdev)->scsi_dev_group,
674 "scsi_dev", &target_stat_scsi_dev_cit);
675 config_group_init_type_name(&DEV_STAT_GRP(se_subdev)->scsi_tgt_dev_group,
676 "scsi_tgt_dev", &target_stat_scsi_tgt_dev_cit);
677 config_group_init_type_name(&DEV_STAT_GRP(se_subdev)->scsi_lu_group,
678 "scsi_lu", &target_stat_scsi_lu_cit);
679
680 dev_stat_grp->default_groups[0] = &DEV_STAT_GRP(se_subdev)->scsi_dev_group;
681 dev_stat_grp->default_groups[1] = &DEV_STAT_GRP(se_subdev)->scsi_tgt_dev_group;
682 dev_stat_grp->default_groups[2] = &DEV_STAT_GRP(se_subdev)->scsi_lu_group;
683 dev_stat_grp->default_groups[3] = NULL;
684}
685
686/*
687 * SCSI Port Table
688 */
689
690CONFIGFS_EATTR_STRUCT(target_stat_scsi_port, se_port_stat_grps);
691#define DEV_STAT_SCSI_PORT_ATTR(_name, _mode) \
692static struct target_stat_scsi_port_attribute \
693 target_stat_scsi_port_##_name = \
694 __CONFIGFS_EATTR(_name, _mode, \
695 target_stat_scsi_port_show_attr_##_name, \
696 target_stat_scsi_port_store_attr_##_name);
697
698#define DEV_STAT_SCSI_PORT_ATTR_RO(_name) \
699static struct target_stat_scsi_port_attribute \
700 target_stat_scsi_port_##_name = \
701 __CONFIGFS_EATTR_RO(_name, \
702 target_stat_scsi_port_show_attr_##_name);
703
704static ssize_t target_stat_scsi_port_show_attr_inst(
705 struct se_port_stat_grps *pgrps, char *page)
706{
707 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
708 struct se_port *sep;
709 struct se_device *dev = lun->lun_se_dev;
710 struct se_hba *hba;
711 ssize_t ret;
712
713 spin_lock(&lun->lun_sep_lock);
714 sep = lun->lun_sep;
715 if (!sep) {
716 spin_unlock(&lun->lun_sep_lock);
717 return -ENODEV;
718 }
719 hba = dev->se_hba;
720 ret = snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
721 spin_unlock(&lun->lun_sep_lock);
722 return ret;
723}
724DEV_STAT_SCSI_PORT_ATTR_RO(inst);
725
726static ssize_t target_stat_scsi_port_show_attr_dev(
727 struct se_port_stat_grps *pgrps, char *page)
728{
729 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
730 struct se_port *sep;
731 struct se_device *dev = lun->lun_se_dev;
732 ssize_t ret;
733
734 spin_lock(&lun->lun_sep_lock);
735 sep = lun->lun_sep;
736 if (!sep) {
737 spin_unlock(&lun->lun_sep_lock);
738 return -ENODEV;
739 }
740 ret = snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
741 spin_unlock(&lun->lun_sep_lock);
742 return ret;
743}
744DEV_STAT_SCSI_PORT_ATTR_RO(dev);
745
746static ssize_t target_stat_scsi_port_show_attr_indx(
747 struct se_port_stat_grps *pgrps, char *page)
748{
749 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
750 struct se_port *sep;
751 ssize_t ret;
752
753 spin_lock(&lun->lun_sep_lock);
754 sep = lun->lun_sep;
755 if (!sep) {
756 spin_unlock(&lun->lun_sep_lock);
757 return -ENODEV;
758 }
759 ret = snprintf(page, PAGE_SIZE, "%u\n", sep->sep_index);
760 spin_unlock(&lun->lun_sep_lock);
761 return ret;
762}
763DEV_STAT_SCSI_PORT_ATTR_RO(indx);
764
765static ssize_t target_stat_scsi_port_show_attr_role(
766 struct se_port_stat_grps *pgrps, char *page)
767{
768 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
769 struct se_device *dev = lun->lun_se_dev;
770 struct se_port *sep;
771 ssize_t ret;
772
773 if (!dev)
774 return -ENODEV;
775
776 spin_lock(&lun->lun_sep_lock);
777 sep = lun->lun_sep;
778 if (!sep) {
779 spin_unlock(&lun->lun_sep_lock);
780 return -ENODEV;
781 }
782 ret = snprintf(page, PAGE_SIZE, "%s%u\n", "Device", dev->dev_index);
783 spin_unlock(&lun->lun_sep_lock);
784 return ret;
785}
786DEV_STAT_SCSI_PORT_ATTR_RO(role);
787
788static ssize_t target_stat_scsi_port_show_attr_busy_count(
789 struct se_port_stat_grps *pgrps, char *page)
790{
791 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
792 struct se_port *sep;
793 ssize_t ret;
794
795 spin_lock(&lun->lun_sep_lock);
796 sep = lun->lun_sep;
797 if (!sep) {
798 spin_unlock(&lun->lun_sep_lock);
799 return -ENODEV;
800 }
801 /* FIXME: scsiPortBusyStatuses */
802 ret = snprintf(page, PAGE_SIZE, "%u\n", 0);
803 spin_unlock(&lun->lun_sep_lock);
804 return ret;
805}
806DEV_STAT_SCSI_PORT_ATTR_RO(busy_count);
807
808CONFIGFS_EATTR_OPS(target_stat_scsi_port, se_port_stat_grps, scsi_port_group);
809
810static struct configfs_attribute *target_stat_scsi_port_attrs[] = {
811 &target_stat_scsi_port_inst.attr,
812 &target_stat_scsi_port_dev.attr,
813 &target_stat_scsi_port_indx.attr,
814 &target_stat_scsi_port_role.attr,
815 &target_stat_scsi_port_busy_count.attr,
816 NULL,
817};
818
819static struct configfs_item_operations target_stat_scsi_port_attrib_ops = {
820 .show_attribute = target_stat_scsi_port_attr_show,
821 .store_attribute = target_stat_scsi_port_attr_store,
822};
823
824static struct config_item_type target_stat_scsi_port_cit = {
825 .ct_item_ops = &target_stat_scsi_port_attrib_ops,
826 .ct_attrs = target_stat_scsi_port_attrs,
827 .ct_owner = THIS_MODULE,
828};
829
830/*
831 * SCSI Target Port Table
832 */
833CONFIGFS_EATTR_STRUCT(target_stat_scsi_tgt_port, se_port_stat_grps);
834#define DEV_STAT_SCSI_TGT_PORT_ATTR(_name, _mode) \
835static struct target_stat_scsi_tgt_port_attribute \
836 target_stat_scsi_tgt_port_##_name = \
837 __CONFIGFS_EATTR(_name, _mode, \
838 target_stat_scsi_tgt_port_show_attr_##_name, \
839 target_stat_scsi_tgt_port_store_attr_##_name);
840
841#define DEV_STAT_SCSI_TGT_PORT_ATTR_RO(_name) \
842static struct target_stat_scsi_tgt_port_attribute \
843 target_stat_scsi_tgt_port_##_name = \
844 __CONFIGFS_EATTR_RO(_name, \
845 target_stat_scsi_tgt_port_show_attr_##_name);
846
847static ssize_t target_stat_scsi_tgt_port_show_attr_inst(
848 struct se_port_stat_grps *pgrps, char *page)
849{
850 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
851 struct se_device *dev = lun->lun_se_dev;
852 struct se_port *sep;
853 struct se_hba *hba;
854 ssize_t ret;
855
856 spin_lock(&lun->lun_sep_lock);
857 sep = lun->lun_sep;
858 if (!sep) {
859 spin_unlock(&lun->lun_sep_lock);
860 return -ENODEV;
861 }
862 hba = dev->se_hba;
863 ret = snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
864 spin_unlock(&lun->lun_sep_lock);
865 return ret;
866}
867DEV_STAT_SCSI_TGT_PORT_ATTR_RO(inst);
868
869static ssize_t target_stat_scsi_tgt_port_show_attr_dev(
870 struct se_port_stat_grps *pgrps, char *page)
871{
872 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
873 struct se_device *dev = lun->lun_se_dev;
874 struct se_port *sep;
875 ssize_t ret;
876
877 spin_lock(&lun->lun_sep_lock);
878 sep = lun->lun_sep;
879 if (!sep) {
880 spin_unlock(&lun->lun_sep_lock);
881 return -ENODEV;
882 }
883 ret = snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
884 spin_unlock(&lun->lun_sep_lock);
885 return ret;
886}
887DEV_STAT_SCSI_TGT_PORT_ATTR_RO(dev);
888
889static ssize_t target_stat_scsi_tgt_port_show_attr_indx(
890 struct se_port_stat_grps *pgrps, char *page)
891{
892 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
893 struct se_port *sep;
894 ssize_t ret;
895
896 spin_lock(&lun->lun_sep_lock);
897 sep = lun->lun_sep;
898 if (!sep) {
899 spin_unlock(&lun->lun_sep_lock);
900 return -ENODEV;
901 }
902 ret = snprintf(page, PAGE_SIZE, "%u\n", sep->sep_index);
903 spin_unlock(&lun->lun_sep_lock);
904 return ret;
905}
906DEV_STAT_SCSI_TGT_PORT_ATTR_RO(indx);
907
908static ssize_t target_stat_scsi_tgt_port_show_attr_name(
909 struct se_port_stat_grps *pgrps, char *page)
910{
911 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
912 struct se_port *sep;
913 struct se_portal_group *tpg;
914 ssize_t ret;
915
916 spin_lock(&lun->lun_sep_lock);
917 sep = lun->lun_sep;
918 if (!sep) {
919 spin_unlock(&lun->lun_sep_lock);
920 return -ENODEV;
921 }
922 tpg = sep->sep_tpg;
923
924 ret = snprintf(page, PAGE_SIZE, "%sPort#%u\n",
925 TPG_TFO(tpg)->get_fabric_name(), sep->sep_index);
926 spin_unlock(&lun->lun_sep_lock);
927 return ret;
928}
929DEV_STAT_SCSI_TGT_PORT_ATTR_RO(name);
930
931static ssize_t target_stat_scsi_tgt_port_show_attr_port_index(
932 struct se_port_stat_grps *pgrps, char *page)
933{
934 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
935 struct se_port *sep;
936 struct se_portal_group *tpg;
937 ssize_t ret;
938
939 spin_lock(&lun->lun_sep_lock);
940 sep = lun->lun_sep;
941 if (!sep) {
942 spin_unlock(&lun->lun_sep_lock);
943 return -ENODEV;
944 }
945 tpg = sep->sep_tpg;
946
947 ret = snprintf(page, PAGE_SIZE, "%s%s%d\n",
948 TPG_TFO(tpg)->tpg_get_wwn(tpg), "+t+",
949 TPG_TFO(tpg)->tpg_get_tag(tpg));
950 spin_unlock(&lun->lun_sep_lock);
951 return ret;
952}
953DEV_STAT_SCSI_TGT_PORT_ATTR_RO(port_index);
954
955static ssize_t target_stat_scsi_tgt_port_show_attr_in_cmds(
956 struct se_port_stat_grps *pgrps, char *page)
957{
958 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
959 struct se_port *sep;
960 struct se_portal_group *tpg;
961 ssize_t ret;
962
963 spin_lock(&lun->lun_sep_lock);
964 sep = lun->lun_sep;
965 if (!sep) {
966 spin_unlock(&lun->lun_sep_lock);
967 return -ENODEV;
968 }
969 tpg = sep->sep_tpg;
970
971 ret = snprintf(page, PAGE_SIZE, "%llu\n", sep->sep_stats.cmd_pdus);
972 spin_unlock(&lun->lun_sep_lock);
973 return ret;
974}
975DEV_STAT_SCSI_TGT_PORT_ATTR_RO(in_cmds);
976
977static ssize_t target_stat_scsi_tgt_port_show_attr_write_mbytes(
978 struct se_port_stat_grps *pgrps, char *page)
979{
980 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
981 struct se_port *sep;
982 struct se_portal_group *tpg;
983 ssize_t ret;
984
985 spin_lock(&lun->lun_sep_lock);
986 sep = lun->lun_sep;
987 if (!sep) {
988 spin_unlock(&lun->lun_sep_lock);
989 return -ENODEV;
990 }
991 tpg = sep->sep_tpg;
992
993 ret = snprintf(page, PAGE_SIZE, "%u\n",
994 (u32)(sep->sep_stats.rx_data_octets >> 20));
995 spin_unlock(&lun->lun_sep_lock);
996 return ret;
997}
998DEV_STAT_SCSI_TGT_PORT_ATTR_RO(write_mbytes);
999
1000static ssize_t target_stat_scsi_tgt_port_show_attr_read_mbytes(
1001 struct se_port_stat_grps *pgrps, char *page)
1002{
1003 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
1004 struct se_port *sep;
1005 struct se_portal_group *tpg;
1006 ssize_t ret;
1007
1008 spin_lock(&lun->lun_sep_lock);
1009 sep = lun->lun_sep;
1010 if (!sep) {
1011 spin_unlock(&lun->lun_sep_lock);
1012 return -ENODEV;
1013 }
1014 tpg = sep->sep_tpg;
1015
1016 ret = snprintf(page, PAGE_SIZE, "%u\n",
1017 (u32)(sep->sep_stats.tx_data_octets >> 20));
1018 spin_unlock(&lun->lun_sep_lock);
1019 return ret;
1020}
1021DEV_STAT_SCSI_TGT_PORT_ATTR_RO(read_mbytes);
1022
1023static ssize_t target_stat_scsi_tgt_port_show_attr_hs_in_cmds(
1024 struct se_port_stat_grps *pgrps, char *page)
1025{
1026 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
1027 struct se_port *sep;
1028 struct se_portal_group *tpg;
1029 ssize_t ret;
1030
1031 spin_lock(&lun->lun_sep_lock);
1032 sep = lun->lun_sep;
1033 if (!sep) {
1034 spin_unlock(&lun->lun_sep_lock);
1035 return -ENODEV;
1036 }
1037 tpg = sep->sep_tpg;
1038
1039 /* FIXME: scsiTgtPortHsInCommands */
1040 ret = snprintf(page, PAGE_SIZE, "%u\n", 0);
1041 spin_unlock(&lun->lun_sep_lock);
1042 return ret;
1043}
1044DEV_STAT_SCSI_TGT_PORT_ATTR_RO(hs_in_cmds);
1045
1046CONFIGFS_EATTR_OPS(target_stat_scsi_tgt_port, se_port_stat_grps,
1047 scsi_tgt_port_group);
1048
1049static struct configfs_attribute *target_stat_scsi_tgt_port_attrs[] = {
1050 &target_stat_scsi_tgt_port_inst.attr,
1051 &target_stat_scsi_tgt_port_dev.attr,
1052 &target_stat_scsi_tgt_port_indx.attr,
1053 &target_stat_scsi_tgt_port_name.attr,
1054 &target_stat_scsi_tgt_port_port_index.attr,
1055 &target_stat_scsi_tgt_port_in_cmds.attr,
1056 &target_stat_scsi_tgt_port_write_mbytes.attr,
1057 &target_stat_scsi_tgt_port_read_mbytes.attr,
1058 &target_stat_scsi_tgt_port_hs_in_cmds.attr,
1059 NULL,
1060};
1061
1062static struct configfs_item_operations target_stat_scsi_tgt_port_attrib_ops = {
1063 .show_attribute = target_stat_scsi_tgt_port_attr_show,
1064 .store_attribute = target_stat_scsi_tgt_port_attr_store,
1065};
1066
1067static struct config_item_type target_stat_scsi_tgt_port_cit = {
1068 .ct_item_ops = &target_stat_scsi_tgt_port_attrib_ops,
1069 .ct_attrs = target_stat_scsi_tgt_port_attrs,
1070 .ct_owner = THIS_MODULE,
1071};
1072
1073/*
1074 * SCSI Transport Table
1075o */
1076
1077CONFIGFS_EATTR_STRUCT(target_stat_scsi_transport, se_port_stat_grps);
1078#define DEV_STAT_SCSI_TRANSPORT_ATTR(_name, _mode) \
1079static struct target_stat_scsi_transport_attribute \
1080 target_stat_scsi_transport_##_name = \
1081 __CONFIGFS_EATTR(_name, _mode, \
1082 target_stat_scsi_transport_show_attr_##_name, \
1083 target_stat_scsi_transport_store_attr_##_name);
1084
1085#define DEV_STAT_SCSI_TRANSPORT_ATTR_RO(_name) \
1086static struct target_stat_scsi_transport_attribute \
1087 target_stat_scsi_transport_##_name = \
1088 __CONFIGFS_EATTR_RO(_name, \
1089 target_stat_scsi_transport_show_attr_##_name);
1090
1091static ssize_t target_stat_scsi_transport_show_attr_inst(
1092 struct se_port_stat_grps *pgrps, char *page)
1093{
1094 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
1095 struct se_device *dev = lun->lun_se_dev;
1096 struct se_port *sep;
1097 struct se_hba *hba;
1098 ssize_t ret;
1099
1100 spin_lock(&lun->lun_sep_lock);
1101 sep = lun->lun_sep;
1102 if (!sep) {
1103 spin_unlock(&lun->lun_sep_lock);
1104 return -ENODEV;
1105 }
1106
1107 hba = dev->se_hba;
1108 ret = snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
1109 spin_unlock(&lun->lun_sep_lock);
1110 return ret;
1111}
1112DEV_STAT_SCSI_TRANSPORT_ATTR_RO(inst);
1113
1114static ssize_t target_stat_scsi_transport_show_attr_device(
1115 struct se_port_stat_grps *pgrps, char *page)
1116{
1117 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
1118 struct se_port *sep;
1119 struct se_portal_group *tpg;
1120 ssize_t ret;
1121
1122 spin_lock(&lun->lun_sep_lock);
1123 sep = lun->lun_sep;
1124 if (!sep) {
1125 spin_unlock(&lun->lun_sep_lock);
1126 return -ENODEV;
1127 }
1128 tpg = sep->sep_tpg;
1129 /* scsiTransportType */
1130 ret = snprintf(page, PAGE_SIZE, "scsiTransport%s\n",
1131 TPG_TFO(tpg)->get_fabric_name());
1132 spin_unlock(&lun->lun_sep_lock);
1133 return ret;
1134}
1135DEV_STAT_SCSI_TRANSPORT_ATTR_RO(device);
1136
1137static ssize_t target_stat_scsi_transport_show_attr_indx(
1138 struct se_port_stat_grps *pgrps, char *page)
1139{
1140 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
1141 struct se_port *sep;
1142 struct se_portal_group *tpg;
1143 ssize_t ret;
1144
1145 spin_lock(&lun->lun_sep_lock);
1146 sep = lun->lun_sep;
1147 if (!sep) {
1148 spin_unlock(&lun->lun_sep_lock);
1149 return -ENODEV;
1150 }
1151 tpg = sep->sep_tpg;
1152 ret = snprintf(page, PAGE_SIZE, "%u\n",
1153 TPG_TFO(tpg)->tpg_get_inst_index(tpg));
1154 spin_unlock(&lun->lun_sep_lock);
1155 return ret;
1156}
1157DEV_STAT_SCSI_TRANSPORT_ATTR_RO(indx);
1158
1159static ssize_t target_stat_scsi_transport_show_attr_dev_name(
1160 struct se_port_stat_grps *pgrps, char *page)
1161{
1162 struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
1163 struct se_device *dev = lun->lun_se_dev;
1164 struct se_port *sep;
1165 struct se_portal_group *tpg;
1166 struct t10_wwn *wwn;
1167 ssize_t ret;
1168
1169 spin_lock(&lun->lun_sep_lock);
1170 sep = lun->lun_sep;
1171 if (!sep) {
1172 spin_unlock(&lun->lun_sep_lock);
1173 return -ENODEV;
1174 }
1175 tpg = sep->sep_tpg;
1176 wwn = DEV_T10_WWN(dev);
1177 /* scsiTransportDevName */
1178 ret = snprintf(page, PAGE_SIZE, "%s+%s\n",
1179 TPG_TFO(tpg)->tpg_get_wwn(tpg),
1180 (strlen(wwn->unit_serial)) ? wwn->unit_serial :
1181 wwn->vendor);
1182 spin_unlock(&lun->lun_sep_lock);
1183 return ret;
1184}
1185DEV_STAT_SCSI_TRANSPORT_ATTR_RO(dev_name);
1186
1187CONFIGFS_EATTR_OPS(target_stat_scsi_transport, se_port_stat_grps,
1188 scsi_transport_group);
1189
1190static struct configfs_attribute *target_stat_scsi_transport_attrs[] = {
1191 &target_stat_scsi_transport_inst.attr,
1192 &target_stat_scsi_transport_device.attr,
1193 &target_stat_scsi_transport_indx.attr,
1194 &target_stat_scsi_transport_dev_name.attr,
1195 NULL,
1196};
1197
1198static struct configfs_item_operations target_stat_scsi_transport_attrib_ops = {
1199 .show_attribute = target_stat_scsi_transport_attr_show,
1200 .store_attribute = target_stat_scsi_transport_attr_store,
1201};
1202
1203static struct config_item_type target_stat_scsi_transport_cit = {
1204 .ct_item_ops = &target_stat_scsi_transport_attrib_ops,
1205 .ct_attrs = target_stat_scsi_transport_attrs,
1206 .ct_owner = THIS_MODULE,
1207};
1208
1209/*
1210 * Called from target_core_fabric_configfs.c:target_fabric_make_lun() to setup
1211 * the target port statistics groups + configfs CITs located in target_core_stat.c
1212 */
1213void target_stat_setup_port_default_groups(struct se_lun *lun)
1214{
1215 struct config_group *port_stat_grp = &PORT_STAT_GRP(lun)->stat_group;
1216
1217 config_group_init_type_name(&PORT_STAT_GRP(lun)->scsi_port_group,
1218 "scsi_port", &target_stat_scsi_port_cit);
1219 config_group_init_type_name(&PORT_STAT_GRP(lun)->scsi_tgt_port_group,
1220 "scsi_tgt_port", &target_stat_scsi_tgt_port_cit);
1221 config_group_init_type_name(&PORT_STAT_GRP(lun)->scsi_transport_group,
1222 "scsi_transport", &target_stat_scsi_transport_cit);
1223
1224 port_stat_grp->default_groups[0] = &PORT_STAT_GRP(lun)->scsi_port_group;
1225 port_stat_grp->default_groups[1] = &PORT_STAT_GRP(lun)->scsi_tgt_port_group;
1226 port_stat_grp->default_groups[2] = &PORT_STAT_GRP(lun)->scsi_transport_group;
1227 port_stat_grp->default_groups[3] = NULL;
1228}
1229
1230/*
1231 * SCSI Authorized Initiator Table
1232 */
1233
1234CONFIGFS_EATTR_STRUCT(target_stat_scsi_auth_intr, se_ml_stat_grps);
1235#define DEV_STAT_SCSI_AUTH_INTR_ATTR(_name, _mode) \
1236static struct target_stat_scsi_auth_intr_attribute \
1237 target_stat_scsi_auth_intr_##_name = \
1238 __CONFIGFS_EATTR(_name, _mode, \
1239 target_stat_scsi_auth_intr_show_attr_##_name, \
1240 target_stat_scsi_auth_intr_store_attr_##_name);
1241
1242#define DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(_name) \
1243static struct target_stat_scsi_auth_intr_attribute \
1244 target_stat_scsi_auth_intr_##_name = \
1245 __CONFIGFS_EATTR_RO(_name, \
1246 target_stat_scsi_auth_intr_show_attr_##_name);
1247
1248static ssize_t target_stat_scsi_auth_intr_show_attr_inst(
1249 struct se_ml_stat_grps *lgrps, char *page)
1250{
1251 struct se_lun_acl *lacl = container_of(lgrps,
1252 struct se_lun_acl, ml_stat_grps);
1253 struct se_node_acl *nacl = lacl->se_lun_nacl;
1254 struct se_dev_entry *deve;
1255 struct se_portal_group *tpg;
1256 ssize_t ret;
1257
1258 spin_lock_irq(&nacl->device_list_lock);
1259 deve = &nacl->device_list[lacl->mapped_lun];
1260 if (!deve->se_lun || !deve->se_lun_acl) {
1261 spin_unlock_irq(&nacl->device_list_lock);
1262 return -ENODEV;
1263 }
1264 tpg = nacl->se_tpg;
1265 /* scsiInstIndex */
1266 ret = snprintf(page, PAGE_SIZE, "%u\n",
1267 TPG_TFO(tpg)->tpg_get_inst_index(tpg));
1268 spin_unlock_irq(&nacl->device_list_lock);
1269 return ret;
1270}
1271DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(inst);
1272
1273static ssize_t target_stat_scsi_auth_intr_show_attr_dev(
1274 struct se_ml_stat_grps *lgrps, char *page)
1275{
1276 struct se_lun_acl *lacl = container_of(lgrps,
1277 struct se_lun_acl, ml_stat_grps);
1278 struct se_node_acl *nacl = lacl->se_lun_nacl;
1279 struct se_dev_entry *deve;
1280 struct se_lun *lun;
1281 struct se_portal_group *tpg;
1282 ssize_t ret;
1283
1284 spin_lock_irq(&nacl->device_list_lock);
1285 deve = &nacl->device_list[lacl->mapped_lun];
1286 if (!deve->se_lun || !deve->se_lun_acl) {
1287 spin_unlock_irq(&nacl->device_list_lock);
1288 return -ENODEV;
1289 }
1290 tpg = nacl->se_tpg;
1291 lun = deve->se_lun;
1292 /* scsiDeviceIndex */
1293 ret = snprintf(page, PAGE_SIZE, "%u\n", lun->lun_se_dev->dev_index);
1294 spin_unlock_irq(&nacl->device_list_lock);
1295 return ret;
1296}
1297DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(dev);
1298
1299static ssize_t target_stat_scsi_auth_intr_show_attr_port(
1300 struct se_ml_stat_grps *lgrps, char *page)
1301{
1302 struct se_lun_acl *lacl = container_of(lgrps,
1303 struct se_lun_acl, ml_stat_grps);
1304 struct se_node_acl *nacl = lacl->se_lun_nacl;
1305 struct se_dev_entry *deve;
1306 struct se_portal_group *tpg;
1307 ssize_t ret;
1308
1309 spin_lock_irq(&nacl->device_list_lock);
1310 deve = &nacl->device_list[lacl->mapped_lun];
1311 if (!deve->se_lun || !deve->se_lun_acl) {
1312 spin_unlock_irq(&nacl->device_list_lock);
1313 return -ENODEV;
1314 }
1315 tpg = nacl->se_tpg;
1316 /* scsiAuthIntrTgtPortIndex */
1317 ret = snprintf(page, PAGE_SIZE, "%u\n", TPG_TFO(tpg)->tpg_get_tag(tpg));
1318 spin_unlock_irq(&nacl->device_list_lock);
1319 return ret;
1320}
1321DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(port);
1322
1323static ssize_t target_stat_scsi_auth_intr_show_attr_indx(
1324 struct se_ml_stat_grps *lgrps, char *page)
1325{
1326 struct se_lun_acl *lacl = container_of(lgrps,
1327 struct se_lun_acl, ml_stat_grps);
1328 struct se_node_acl *nacl = lacl->se_lun_nacl;
1329 struct se_dev_entry *deve;
1330 ssize_t ret;
1331
1332 spin_lock_irq(&nacl->device_list_lock);
1333 deve = &nacl->device_list[lacl->mapped_lun];
1334 if (!deve->se_lun || !deve->se_lun_acl) {
1335 spin_unlock_irq(&nacl->device_list_lock);
1336 return -ENODEV;
1337 }
1338 /* scsiAuthIntrIndex */
1339 ret = snprintf(page, PAGE_SIZE, "%u\n", nacl->acl_index);
1340 spin_unlock_irq(&nacl->device_list_lock);
1341 return ret;
1342}
1343DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(indx);
1344
1345static ssize_t target_stat_scsi_auth_intr_show_attr_dev_or_port(
1346 struct se_ml_stat_grps *lgrps, char *page)
1347{
1348 struct se_lun_acl *lacl = container_of(lgrps,
1349 struct se_lun_acl, ml_stat_grps);
1350 struct se_node_acl *nacl = lacl->se_lun_nacl;
1351 struct se_dev_entry *deve;
1352 ssize_t ret;
1353
1354 spin_lock_irq(&nacl->device_list_lock);
1355 deve = &nacl->device_list[lacl->mapped_lun];
1356 if (!deve->se_lun || !deve->se_lun_acl) {
1357 spin_unlock_irq(&nacl->device_list_lock);
1358 return -ENODEV;
1359 }
1360 /* scsiAuthIntrDevOrPort */
1361 ret = snprintf(page, PAGE_SIZE, "%u\n", 1);
1362 spin_unlock_irq(&nacl->device_list_lock);
1363 return ret;
1364}
1365DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(dev_or_port);
1366
1367static ssize_t target_stat_scsi_auth_intr_show_attr_intr_name(
1368 struct se_ml_stat_grps *lgrps, char *page)
1369{
1370 struct se_lun_acl *lacl = container_of(lgrps,
1371 struct se_lun_acl, ml_stat_grps);
1372 struct se_node_acl *nacl = lacl->se_lun_nacl;
1373 struct se_dev_entry *deve;
1374 ssize_t ret;
1375
1376 spin_lock_irq(&nacl->device_list_lock);
1377 deve = &nacl->device_list[lacl->mapped_lun];
1378 if (!deve->se_lun || !deve->se_lun_acl) {
1379 spin_unlock_irq(&nacl->device_list_lock);
1380 return -ENODEV;
1381 }
1382 /* scsiAuthIntrName */
1383 ret = snprintf(page, PAGE_SIZE, "%s\n", nacl->initiatorname);
1384 spin_unlock_irq(&nacl->device_list_lock);
1385 return ret;
1386}
1387DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(intr_name);
1388
1389static ssize_t target_stat_scsi_auth_intr_show_attr_map_indx(
1390 struct se_ml_stat_grps *lgrps, char *page)
1391{
1392 struct se_lun_acl *lacl = container_of(lgrps,
1393 struct se_lun_acl, ml_stat_grps);
1394 struct se_node_acl *nacl = lacl->se_lun_nacl;
1395 struct se_dev_entry *deve;
1396 ssize_t ret;
1397
1398 spin_lock_irq(&nacl->device_list_lock);
1399 deve = &nacl->device_list[lacl->mapped_lun];
1400 if (!deve->se_lun || !deve->se_lun_acl) {
1401 spin_unlock_irq(&nacl->device_list_lock);
1402 return -ENODEV;
1403 }
1404 /* FIXME: scsiAuthIntrLunMapIndex */
1405 ret = snprintf(page, PAGE_SIZE, "%u\n", 0);
1406 spin_unlock_irq(&nacl->device_list_lock);
1407 return ret;
1408}
1409DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(map_indx);
1410
1411static ssize_t target_stat_scsi_auth_intr_show_attr_att_count(
1412 struct se_ml_stat_grps *lgrps, char *page)
1413{
1414 struct se_lun_acl *lacl = container_of(lgrps,
1415 struct se_lun_acl, ml_stat_grps);
1416 struct se_node_acl *nacl = lacl->se_lun_nacl;
1417 struct se_dev_entry *deve;
1418 ssize_t ret;
1419
1420 spin_lock_irq(&nacl->device_list_lock);
1421 deve = &nacl->device_list[lacl->mapped_lun];
1422 if (!deve->se_lun || !deve->se_lun_acl) {
1423 spin_unlock_irq(&nacl->device_list_lock);
1424 return -ENODEV;
1425 }
1426 /* scsiAuthIntrAttachedTimes */
1427 ret = snprintf(page, PAGE_SIZE, "%u\n", deve->attach_count);
1428 spin_unlock_irq(&nacl->device_list_lock);
1429 return ret;
1430}
1431DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(att_count);
1432
1433static ssize_t target_stat_scsi_auth_intr_show_attr_num_cmds(
1434 struct se_ml_stat_grps *lgrps, char *page)
1435{
1436 struct se_lun_acl *lacl = container_of(lgrps,
1437 struct se_lun_acl, ml_stat_grps);
1438 struct se_node_acl *nacl = lacl->se_lun_nacl;
1439 struct se_dev_entry *deve;
1440 ssize_t ret;
1441
1442 spin_lock_irq(&nacl->device_list_lock);
1443 deve = &nacl->device_list[lacl->mapped_lun];
1444 if (!deve->se_lun || !deve->se_lun_acl) {
1445 spin_unlock_irq(&nacl->device_list_lock);
1446 return -ENODEV;
1447 }
1448 /* scsiAuthIntrOutCommands */
1449 ret = snprintf(page, PAGE_SIZE, "%u\n", deve->total_cmds);
1450 spin_unlock_irq(&nacl->device_list_lock);
1451 return ret;
1452}
1453DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(num_cmds);
1454
1455static ssize_t target_stat_scsi_auth_intr_show_attr_read_mbytes(
1456 struct se_ml_stat_grps *lgrps, char *page)
1457{
1458 struct se_lun_acl *lacl = container_of(lgrps,
1459 struct se_lun_acl, ml_stat_grps);
1460 struct se_node_acl *nacl = lacl->se_lun_nacl;
1461 struct se_dev_entry *deve;
1462 ssize_t ret;
1463
1464 spin_lock_irq(&nacl->device_list_lock);
1465 deve = &nacl->device_list[lacl->mapped_lun];
1466 if (!deve->se_lun || !deve->se_lun_acl) {
1467 spin_unlock_irq(&nacl->device_list_lock);
1468 return -ENODEV;
1469 }
1470 /* scsiAuthIntrReadMegaBytes */
1471 ret = snprintf(page, PAGE_SIZE, "%u\n", (u32)(deve->read_bytes >> 20));
1472 spin_unlock_irq(&nacl->device_list_lock);
1473 return ret;
1474}
1475DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(read_mbytes);
1476
1477static ssize_t target_stat_scsi_auth_intr_show_attr_write_mbytes(
1478 struct se_ml_stat_grps *lgrps, char *page)
1479{
1480 struct se_lun_acl *lacl = container_of(lgrps,
1481 struct se_lun_acl, ml_stat_grps);
1482 struct se_node_acl *nacl = lacl->se_lun_nacl;
1483 struct se_dev_entry *deve;
1484 ssize_t ret;
1485
1486 spin_lock_irq(&nacl->device_list_lock);
1487 deve = &nacl->device_list[lacl->mapped_lun];
1488 if (!deve->se_lun || !deve->se_lun_acl) {
1489 spin_unlock_irq(&nacl->device_list_lock);
1490 return -ENODEV;
1491 }
1492 /* scsiAuthIntrWrittenMegaBytes */
1493 ret = snprintf(page, PAGE_SIZE, "%u\n", (u32)(deve->write_bytes >> 20));
1494 spin_unlock_irq(&nacl->device_list_lock);
1495 return ret;
1496}
1497DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(write_mbytes);
1498
1499static ssize_t target_stat_scsi_auth_intr_show_attr_hs_num_cmds(
1500 struct se_ml_stat_grps *lgrps, char *page)
1501{
1502 struct se_lun_acl *lacl = container_of(lgrps,
1503 struct se_lun_acl, ml_stat_grps);
1504 struct se_node_acl *nacl = lacl->se_lun_nacl;
1505 struct se_dev_entry *deve;
1506 ssize_t ret;
1507
1508 spin_lock_irq(&nacl->device_list_lock);
1509 deve = &nacl->device_list[lacl->mapped_lun];
1510 if (!deve->se_lun || !deve->se_lun_acl) {
1511 spin_unlock_irq(&nacl->device_list_lock);
1512 return -ENODEV;
1513 }
1514 /* FIXME: scsiAuthIntrHSOutCommands */
1515 ret = snprintf(page, PAGE_SIZE, "%u\n", 0);
1516 spin_unlock_irq(&nacl->device_list_lock);
1517 return ret;
1518}
1519DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(hs_num_cmds);
1520
1521static ssize_t target_stat_scsi_auth_intr_show_attr_creation_time(
1522 struct se_ml_stat_grps *lgrps, char *page)
1523{
1524 struct se_lun_acl *lacl = container_of(lgrps,
1525 struct se_lun_acl, ml_stat_grps);
1526 struct se_node_acl *nacl = lacl->se_lun_nacl;
1527 struct se_dev_entry *deve;
1528 ssize_t ret;
1529
1530 spin_lock_irq(&nacl->device_list_lock);
1531 deve = &nacl->device_list[lacl->mapped_lun];
1532 if (!deve->se_lun || !deve->se_lun_acl) {
1533 spin_unlock_irq(&nacl->device_list_lock);
1534 return -ENODEV;
1535 }
1536 /* scsiAuthIntrLastCreation */
1537 ret = snprintf(page, PAGE_SIZE, "%u\n", (u32)(((u32)deve->creation_time -
1538 INITIAL_JIFFIES) * 100 / HZ));
1539 spin_unlock_irq(&nacl->device_list_lock);
1540 return ret;
1541}
1542DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(creation_time);
1543
1544static ssize_t target_stat_scsi_auth_intr_show_attr_row_status(
1545 struct se_ml_stat_grps *lgrps, char *page)
1546{
1547 struct se_lun_acl *lacl = container_of(lgrps,
1548 struct se_lun_acl, ml_stat_grps);
1549 struct se_node_acl *nacl = lacl->se_lun_nacl;
1550 struct se_dev_entry *deve;
1551 ssize_t ret;
1552
1553 spin_lock_irq(&nacl->device_list_lock);
1554 deve = &nacl->device_list[lacl->mapped_lun];
1555 if (!deve->se_lun || !deve->se_lun_acl) {
1556 spin_unlock_irq(&nacl->device_list_lock);
1557 return -ENODEV;
1558 }
1559 /* FIXME: scsiAuthIntrRowStatus */
1560 ret = snprintf(page, PAGE_SIZE, "Ready\n");
1561 spin_unlock_irq(&nacl->device_list_lock);
1562 return ret;
1563}
1564DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(row_status);
1565
1566CONFIGFS_EATTR_OPS(target_stat_scsi_auth_intr, se_ml_stat_grps,
1567 scsi_auth_intr_group);
1568
1569static struct configfs_attribute *target_stat_scsi_auth_intr_attrs[] = {
1570 &target_stat_scsi_auth_intr_inst.attr,
1571 &target_stat_scsi_auth_intr_dev.attr,
1572 &target_stat_scsi_auth_intr_port.attr,
1573 &target_stat_scsi_auth_intr_indx.attr,
1574 &target_stat_scsi_auth_intr_dev_or_port.attr,
1575 &target_stat_scsi_auth_intr_intr_name.attr,
1576 &target_stat_scsi_auth_intr_map_indx.attr,
1577 &target_stat_scsi_auth_intr_att_count.attr,
1578 &target_stat_scsi_auth_intr_num_cmds.attr,
1579 &target_stat_scsi_auth_intr_read_mbytes.attr,
1580 &target_stat_scsi_auth_intr_write_mbytes.attr,
1581 &target_stat_scsi_auth_intr_hs_num_cmds.attr,
1582 &target_stat_scsi_auth_intr_creation_time.attr,
1583 &target_stat_scsi_auth_intr_row_status.attr,
1584 NULL,
1585};
1586
1587static struct configfs_item_operations target_stat_scsi_auth_intr_attrib_ops = {
1588 .show_attribute = target_stat_scsi_auth_intr_attr_show,
1589 .store_attribute = target_stat_scsi_auth_intr_attr_store,
1590};
1591
1592static struct config_item_type target_stat_scsi_auth_intr_cit = {
1593 .ct_item_ops = &target_stat_scsi_auth_intr_attrib_ops,
1594 .ct_attrs = target_stat_scsi_auth_intr_attrs,
1595 .ct_owner = THIS_MODULE,
1596};
1597
1598/*
1599 * SCSI Attached Initiator Port Table
1600 */
1601
1602CONFIGFS_EATTR_STRUCT(target_stat_scsi_att_intr_port, se_ml_stat_grps);
1603#define DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR(_name, _mode) \
1604static struct target_stat_scsi_att_intr_port_attribute \
1605 target_stat_scsi_att_intr_port_##_name = \
1606 __CONFIGFS_EATTR(_name, _mode, \
1607 target_stat_scsi_att_intr_port_show_attr_##_name, \
1608 target_stat_scsi_att_intr_port_store_attr_##_name);
1609
1610#define DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(_name) \
1611static struct target_stat_scsi_att_intr_port_attribute \
1612 target_stat_scsi_att_intr_port_##_name = \
1613 __CONFIGFS_EATTR_RO(_name, \
1614 target_stat_scsi_att_intr_port_show_attr_##_name);
1615
1616static ssize_t target_stat_scsi_att_intr_port_show_attr_inst(
1617 struct se_ml_stat_grps *lgrps, char *page)
1618{
1619 struct se_lun_acl *lacl = container_of(lgrps,
1620 struct se_lun_acl, ml_stat_grps);
1621 struct se_node_acl *nacl = lacl->se_lun_nacl;
1622 struct se_dev_entry *deve;
1623 struct se_portal_group *tpg;
1624 ssize_t ret;
1625
1626 spin_lock_irq(&nacl->device_list_lock);
1627 deve = &nacl->device_list[lacl->mapped_lun];
1628 if (!deve->se_lun || !deve->se_lun_acl) {
1629 spin_unlock_irq(&nacl->device_list_lock);
1630 return -ENODEV;
1631 }
1632 tpg = nacl->se_tpg;
1633 /* scsiInstIndex */
1634 ret = snprintf(page, PAGE_SIZE, "%u\n",
1635 TPG_TFO(tpg)->tpg_get_inst_index(tpg));
1636 spin_unlock_irq(&nacl->device_list_lock);
1637 return ret;
1638}
1639DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(inst);
1640
1641static ssize_t target_stat_scsi_att_intr_port_show_attr_dev(
1642 struct se_ml_stat_grps *lgrps, char *page)
1643{
1644 struct se_lun_acl *lacl = container_of(lgrps,
1645 struct se_lun_acl, ml_stat_grps);
1646 struct se_node_acl *nacl = lacl->se_lun_nacl;
1647 struct se_dev_entry *deve;
1648 struct se_lun *lun;
1649 struct se_portal_group *tpg;
1650 ssize_t ret;
1651
1652 spin_lock_irq(&nacl->device_list_lock);
1653 deve = &nacl->device_list[lacl->mapped_lun];
1654 if (!deve->se_lun || !deve->se_lun_acl) {
1655 spin_unlock_irq(&nacl->device_list_lock);
1656 return -ENODEV;
1657 }
1658 tpg = nacl->se_tpg;
1659 lun = deve->se_lun;
1660 /* scsiDeviceIndex */
1661 ret = snprintf(page, PAGE_SIZE, "%u\n", lun->lun_se_dev->dev_index);
1662 spin_unlock_irq(&nacl->device_list_lock);
1663 return ret;
1664}
1665DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(dev);
1666
1667static ssize_t target_stat_scsi_att_intr_port_show_attr_port(
1668 struct se_ml_stat_grps *lgrps, char *page)
1669{
1670 struct se_lun_acl *lacl = container_of(lgrps,
1671 struct se_lun_acl, ml_stat_grps);
1672 struct se_node_acl *nacl = lacl->se_lun_nacl;
1673 struct se_dev_entry *deve;
1674 struct se_portal_group *tpg;
1675 ssize_t ret;
1676
1677 spin_lock_irq(&nacl->device_list_lock);
1678 deve = &nacl->device_list[lacl->mapped_lun];
1679 if (!deve->se_lun || !deve->se_lun_acl) {
1680 spin_unlock_irq(&nacl->device_list_lock);
1681 return -ENODEV;
1682 }
1683 tpg = nacl->se_tpg;
1684 /* scsiPortIndex */
1685 ret = snprintf(page, PAGE_SIZE, "%u\n", TPG_TFO(tpg)->tpg_get_tag(tpg));
1686 spin_unlock_irq(&nacl->device_list_lock);
1687 return ret;
1688}
1689DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(port);
1690
1691static ssize_t target_stat_scsi_att_intr_port_show_attr_indx(
1692 struct se_ml_stat_grps *lgrps, char *page)
1693{
1694 struct se_lun_acl *lacl = container_of(lgrps,
1695 struct se_lun_acl, ml_stat_grps);
1696 struct se_node_acl *nacl = lacl->se_lun_nacl;
1697 struct se_session *se_sess;
1698 struct se_portal_group *tpg;
1699 ssize_t ret;
1700
1701 spin_lock_irq(&nacl->nacl_sess_lock);
1702 se_sess = nacl->nacl_sess;
1703 if (!se_sess) {
1704 spin_unlock_irq(&nacl->nacl_sess_lock);
1705 return -ENODEV;
1706 }
1707
1708 tpg = nacl->se_tpg;
1709 /* scsiAttIntrPortIndex */
1710 ret = snprintf(page, PAGE_SIZE, "%u\n",
1711 TPG_TFO(tpg)->sess_get_index(se_sess));
1712 spin_unlock_irq(&nacl->nacl_sess_lock);
1713 return ret;
1714}
1715DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(indx);
1716
1717static ssize_t target_stat_scsi_att_intr_port_show_attr_port_auth_indx(
1718 struct se_ml_stat_grps *lgrps, char *page)
1719{
1720 struct se_lun_acl *lacl = container_of(lgrps,
1721 struct se_lun_acl, ml_stat_grps);
1722 struct se_node_acl *nacl = lacl->se_lun_nacl;
1723 struct se_dev_entry *deve;
1724 ssize_t ret;
1725
1726 spin_lock_irq(&nacl->device_list_lock);
1727 deve = &nacl->device_list[lacl->mapped_lun];
1728 if (!deve->se_lun || !deve->se_lun_acl) {
1729 spin_unlock_irq(&nacl->device_list_lock);
1730 return -ENODEV;
1731 }
1732 /* scsiAttIntrPortAuthIntrIdx */
1733 ret = snprintf(page, PAGE_SIZE, "%u\n", nacl->acl_index);
1734 spin_unlock_irq(&nacl->device_list_lock);
1735 return ret;
1736}
1737DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(port_auth_indx);
1738
1739static ssize_t target_stat_scsi_att_intr_port_show_attr_port_ident(
1740 struct se_ml_stat_grps *lgrps, char *page)
1741{
1742 struct se_lun_acl *lacl = container_of(lgrps,
1743 struct se_lun_acl, ml_stat_grps);
1744 struct se_node_acl *nacl = lacl->se_lun_nacl;
1745 struct se_session *se_sess;
1746 struct se_portal_group *tpg;
1747 ssize_t ret;
1748 unsigned char buf[64];
1749
1750 spin_lock_irq(&nacl->nacl_sess_lock);
1751 se_sess = nacl->nacl_sess;
1752 if (!se_sess) {
1753 spin_unlock_irq(&nacl->nacl_sess_lock);
1754 return -ENODEV;
1755 }
1756
1757 tpg = nacl->se_tpg;
1758 /* scsiAttIntrPortName+scsiAttIntrPortIdentifier */
1759 memset(buf, 0, 64);
1760 if (TPG_TFO(tpg)->sess_get_initiator_sid != NULL)
1761 TPG_TFO(tpg)->sess_get_initiator_sid(se_sess,
1762 (unsigned char *)&buf[0], 64);
1763
1764 ret = snprintf(page, PAGE_SIZE, "%s+i+%s\n", nacl->initiatorname, buf);
1765 spin_unlock_irq(&nacl->nacl_sess_lock);
1766 return ret;
1767}
1768DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(port_ident);
1769
1770CONFIGFS_EATTR_OPS(target_stat_scsi_att_intr_port, se_ml_stat_grps,
1771 scsi_att_intr_port_group);
1772
1773static struct configfs_attribute *target_stat_scsi_ath_intr_port_attrs[] = {
1774 &target_stat_scsi_att_intr_port_inst.attr,
1775 &target_stat_scsi_att_intr_port_dev.attr,
1776 &target_stat_scsi_att_intr_port_port.attr,
1777 &target_stat_scsi_att_intr_port_indx.attr,
1778 &target_stat_scsi_att_intr_port_port_auth_indx.attr,
1779 &target_stat_scsi_att_intr_port_port_ident.attr,
1780 NULL,
1781};
1782
1783static struct configfs_item_operations target_stat_scsi_att_intr_port_attrib_ops = {
1784 .show_attribute = target_stat_scsi_att_intr_port_attr_show,
1785 .store_attribute = target_stat_scsi_att_intr_port_attr_store,
1786};
1787
1788static struct config_item_type target_stat_scsi_att_intr_port_cit = {
1789 .ct_item_ops = &target_stat_scsi_att_intr_port_attrib_ops,
1790 .ct_attrs = target_stat_scsi_ath_intr_port_attrs,
1791 .ct_owner = THIS_MODULE,
1792};
1793
1794/*
1795 * Called from target_core_fabric_configfs.c:target_fabric_make_mappedlun() to setup
1796 * the target MappedLUN statistics groups + configfs CITs located in target_core_stat.c
1797 */
1798void target_stat_setup_mappedlun_default_groups(struct se_lun_acl *lacl)
1799{
1800 struct config_group *ml_stat_grp = &ML_STAT_GRPS(lacl)->stat_group;
1801
1802 config_group_init_type_name(&ML_STAT_GRPS(lacl)->scsi_auth_intr_group,
1803 "scsi_auth_intr", &target_stat_scsi_auth_intr_cit);
1804 config_group_init_type_name(&ML_STAT_GRPS(lacl)->scsi_att_intr_port_group,
1805 "scsi_att_intr_port", &target_stat_scsi_att_intr_port_cit);
1806
1807 ml_stat_grp->default_groups[0] = &ML_STAT_GRPS(lacl)->scsi_auth_intr_group;
1808 ml_stat_grp->default_groups[1] = &ML_STAT_GRPS(lacl)->scsi_att_intr_port_group;
1809 ml_stat_grp->default_groups[2] = NULL;
1810}
diff --git a/drivers/target/target_core_stat.h b/drivers/target/target_core_stat.h
new file mode 100644
index 000000000000..86c252f9ea47
--- /dev/null
+++ b/drivers/target/target_core_stat.h
@@ -0,0 +1,8 @@
1#ifndef TARGET_CORE_STAT_H
2#define TARGET_CORE_STAT_H
3
4extern void target_stat_setup_dev_default_groups(struct se_subsystem_dev *);
5extern void target_stat_setup_port_default_groups(struct se_lun *);
6extern void target_stat_setup_mappedlun_default_groups(struct se_lun_acl *);
7
8#endif /*** TARGET_CORE_STAT_H ***/
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 39ac190080e2..b9d3501bdd91 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -227,8 +227,6 @@ static void transport_remove_cmd_from_queue(struct se_cmd *cmd,
227static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq); 227static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq);
228static void transport_stop_all_task_timers(struct se_cmd *cmd); 228static void transport_stop_all_task_timers(struct se_cmd *cmd);
229 229
230int transport_emulate_control_cdb(struct se_task *task);
231
232int init_se_global(void) 230int init_se_global(void)
233{ 231{
234 struct se_global *global; 232 struct se_global *global;
@@ -721,7 +719,7 @@ static int transport_cmd_check_stop(
721 cmd->se_lun = NULL; 719 cmd->se_lun = NULL;
722 /* 720 /*
723 * Some fabric modules like tcm_loop can release 721 * Some fabric modules like tcm_loop can release
724 * their internally allocated I/O refrence now and 722 * their internally allocated I/O reference now and
725 * struct se_cmd now. 723 * struct se_cmd now.
726 */ 724 */
727 if (CMD_TFO(cmd)->check_stop_free != NULL) { 725 if (CMD_TFO(cmd)->check_stop_free != NULL) {
@@ -1622,7 +1620,7 @@ struct se_device *transport_add_device_to_core_hba(
1622 const char *inquiry_prod, 1620 const char *inquiry_prod,
1623 const char *inquiry_rev) 1621 const char *inquiry_rev)
1624{ 1622{
1625 int ret = 0, force_pt; 1623 int force_pt;
1626 struct se_device *dev; 1624 struct se_device *dev;
1627 1625
1628 dev = kzalloc(sizeof(struct se_device), GFP_KERNEL); 1626 dev = kzalloc(sizeof(struct se_device), GFP_KERNEL);
@@ -1739,9 +1737,8 @@ struct se_device *transport_add_device_to_core_hba(
1739 } 1737 }
1740 scsi_dump_inquiry(dev); 1738 scsi_dump_inquiry(dev);
1741 1739
1740 return dev;
1742out: 1741out:
1743 if (!ret)
1744 return dev;
1745 kthread_stop(dev->process_thread); 1742 kthread_stop(dev->process_thread);
1746 1743
1747 spin_lock(&hba->device_lock); 1744 spin_lock(&hba->device_lock);
@@ -2032,7 +2029,7 @@ int transport_generic_handle_data(
2032 * If the received CDB has aleady been ABORTED by the generic 2029 * If the received CDB has aleady been ABORTED by the generic
2033 * target engine, we now call transport_check_aborted_status() 2030 * target engine, we now call transport_check_aborted_status()
2034 * to queue any delated TASK_ABORTED status for the received CDB to the 2031 * to queue any delated TASK_ABORTED status for the received CDB to the
2035 * fabric module as we are expecting no futher incoming DATA OUT 2032 * fabric module as we are expecting no further incoming DATA OUT
2036 * sequences at this point. 2033 * sequences at this point.
2037 */ 2034 */
2038 if (transport_check_aborted_status(cmd, 1) != 0) 2035 if (transport_check_aborted_status(cmd, 1) != 0)
@@ -2504,7 +2501,7 @@ static inline int transport_execute_task_attr(struct se_cmd *cmd)
2504 if (SE_DEV(cmd)->dev_task_attr_type != SAM_TASK_ATTR_EMULATED) 2501 if (SE_DEV(cmd)->dev_task_attr_type != SAM_TASK_ATTR_EMULATED)
2505 return 1; 2502 return 1;
2506 /* 2503 /*
2507 * Check for the existance of HEAD_OF_QUEUE, and if true return 1 2504 * Check for the existence of HEAD_OF_QUEUE, and if true return 1
2508 * to allow the passed struct se_cmd list of tasks to the front of the list. 2505 * to allow the passed struct se_cmd list of tasks to the front of the list.
2509 */ 2506 */
2510 if (cmd->sam_task_attr == TASK_ATTR_HOQ) { 2507 if (cmd->sam_task_attr == TASK_ATTR_HOQ) {
@@ -2550,7 +2547,7 @@ static inline int transport_execute_task_attr(struct se_cmd *cmd)
2550 if (atomic_read(&SE_DEV(cmd)->dev_ordered_sync) != 0) { 2547 if (atomic_read(&SE_DEV(cmd)->dev_ordered_sync) != 0) {
2551 /* 2548 /*
2552 * Otherwise, add cmd w/ tasks to delayed cmd queue that 2549 * Otherwise, add cmd w/ tasks to delayed cmd queue that
2553 * will be drained upon competion of HEAD_OF_QUEUE task. 2550 * will be drained upon completion of HEAD_OF_QUEUE task.
2554 */ 2551 */
2555 spin_lock(&SE_DEV(cmd)->delayed_cmd_lock); 2552 spin_lock(&SE_DEV(cmd)->delayed_cmd_lock);
2556 cmd->se_cmd_flags |= SCF_DELAYED_CMD_FROM_SAM_ATTR; 2553 cmd->se_cmd_flags |= SCF_DELAYED_CMD_FROM_SAM_ATTR;
@@ -2592,7 +2589,7 @@ static int transport_execute_tasks(struct se_cmd *cmd)
2592 } 2589 }
2593 /* 2590 /*
2594 * Call transport_cmd_check_stop() to see if a fabric exception 2591 * Call transport_cmd_check_stop() to see if a fabric exception
2595 * has occured that prevents execution. 2592 * has occurred that prevents execution.
2596 */ 2593 */
2597 if (!(transport_cmd_check_stop(cmd, 0, TRANSPORT_PROCESSING))) { 2594 if (!(transport_cmd_check_stop(cmd, 0, TRANSPORT_PROCESSING))) {
2598 /* 2595 /*
@@ -3112,7 +3109,7 @@ static int transport_generic_cmd_sequencer(
3112 if (ret != 0) { 3109 if (ret != 0) {
3113 cmd->transport_wait_for_tasks = &transport_nop_wait_for_tasks; 3110 cmd->transport_wait_for_tasks = &transport_nop_wait_for_tasks;
3114 /* 3111 /*
3115 * Set SCSI additional sense code (ASC) to 'LUN Not Accessable'; 3112 * Set SCSI additional sense code (ASC) to 'LUN Not Accessible';
3116 * The ALUA additional sense code qualifier (ASCQ) is determined 3113 * The ALUA additional sense code qualifier (ASCQ) is determined
3117 * by the ALUA primary or secondary access state.. 3114 * by the ALUA primary or secondary access state..
3118 */ 3115 */
@@ -3870,7 +3867,7 @@ static void transport_generic_complete_ok(struct se_cmd *cmd)
3870 } 3867 }
3871 } 3868 }
3872 /* 3869 /*
3873 * Check for a callback, used by amoungst other things 3870 * Check for a callback, used by amongst other things
3874 * XDWRITE_READ_10 emulation. 3871 * XDWRITE_READ_10 emulation.
3875 */ 3872 */
3876 if (cmd->transport_complete_callback) 3873 if (cmd->transport_complete_callback)
@@ -4359,11 +4356,9 @@ transport_generic_get_mem(struct se_cmd *cmd, u32 length, u32 dma_size)
4359 printk(KERN_ERR "Unable to allocate struct se_mem\n"); 4356 printk(KERN_ERR "Unable to allocate struct se_mem\n");
4360 goto out; 4357 goto out;
4361 } 4358 }
4362 INIT_LIST_HEAD(&se_mem->se_list);
4363 se_mem->se_len = (length > dma_size) ? dma_size : length;
4364 4359
4365/* #warning FIXME Allocate contigous pages for struct se_mem elements */ 4360/* #warning FIXME Allocate contigous pages for struct se_mem elements */
4366 se_mem->se_page = (struct page *) alloc_pages(GFP_KERNEL, 0); 4361 se_mem->se_page = alloc_pages(GFP_KERNEL, 0);
4367 if (!(se_mem->se_page)) { 4362 if (!(se_mem->se_page)) {
4368 printk(KERN_ERR "alloc_pages() failed\n"); 4363 printk(KERN_ERR "alloc_pages() failed\n");
4369 goto out; 4364 goto out;
@@ -4374,6 +4369,8 @@ transport_generic_get_mem(struct se_cmd *cmd, u32 length, u32 dma_size)
4374 printk(KERN_ERR "kmap_atomic() failed\n"); 4369 printk(KERN_ERR "kmap_atomic() failed\n");
4375 goto out; 4370 goto out;
4376 } 4371 }
4372 INIT_LIST_HEAD(&se_mem->se_list);
4373 se_mem->se_len = (length > dma_size) ? dma_size : length;
4377 memset(buf, 0, se_mem->se_len); 4374 memset(buf, 0, se_mem->se_len);
4378 kunmap_atomic(buf, KM_IRQ0); 4375 kunmap_atomic(buf, KM_IRQ0);
4379 4376
@@ -4392,10 +4389,13 @@ transport_generic_get_mem(struct se_cmd *cmd, u32 length, u32 dma_size)
4392 4389
4393 return 0; 4390 return 0;
4394out: 4391out:
4392 if (se_mem)
4393 __free_pages(se_mem->se_page, 0);
4394 kmem_cache_free(se_mem_cache, se_mem);
4395 return -1; 4395 return -1;
4396} 4396}
4397 4397
4398extern u32 transport_calc_sg_num( 4398u32 transport_calc_sg_num(
4399 struct se_task *task, 4399 struct se_task *task,
4400 struct se_mem *in_se_mem, 4400 struct se_mem *in_se_mem,
4401 u32 task_offset) 4401 u32 task_offset)
@@ -5834,31 +5834,26 @@ int transport_generic_do_tmr(struct se_cmd *cmd)
5834 int ret; 5834 int ret;
5835 5835
5836 switch (tmr->function) { 5836 switch (tmr->function) {
5837 case ABORT_TASK: 5837 case TMR_ABORT_TASK:
5838 ref_cmd = tmr->ref_cmd; 5838 ref_cmd = tmr->ref_cmd;
5839 tmr->response = TMR_FUNCTION_REJECTED; 5839 tmr->response = TMR_FUNCTION_REJECTED;
5840 break; 5840 break;
5841 case ABORT_TASK_SET: 5841 case TMR_ABORT_TASK_SET:
5842 case CLEAR_ACA: 5842 case TMR_CLEAR_ACA:
5843 case CLEAR_TASK_SET: 5843 case TMR_CLEAR_TASK_SET:
5844 tmr->response = TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED; 5844 tmr->response = TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;
5845 break; 5845 break;
5846 case LUN_RESET: 5846 case TMR_LUN_RESET:
5847 ret = core_tmr_lun_reset(dev, tmr, NULL, NULL); 5847 ret = core_tmr_lun_reset(dev, tmr, NULL, NULL);
5848 tmr->response = (!ret) ? TMR_FUNCTION_COMPLETE : 5848 tmr->response = (!ret) ? TMR_FUNCTION_COMPLETE :
5849 TMR_FUNCTION_REJECTED; 5849 TMR_FUNCTION_REJECTED;
5850 break; 5850 break;
5851#if 0 5851 case TMR_TARGET_WARM_RESET:
5852 case TARGET_WARM_RESET:
5853 transport_generic_host_reset(dev->se_hba);
5854 tmr->response = TMR_FUNCTION_REJECTED; 5852 tmr->response = TMR_FUNCTION_REJECTED;
5855 break; 5853 break;
5856 case TARGET_COLD_RESET: 5854 case TMR_TARGET_COLD_RESET:
5857 transport_generic_host_reset(dev->se_hba);
5858 transport_generic_cold_reset(dev->se_hba);
5859 tmr->response = TMR_FUNCTION_REJECTED; 5855 tmr->response = TMR_FUNCTION_REJECTED;
5860 break; 5856 break;
5861#endif
5862 default: 5857 default:
5863 printk(KERN_ERR "Uknown TMR function: 0x%02x.\n", 5858 printk(KERN_ERR "Uknown TMR function: 0x%02x.\n",
5864 tmr->function); 5859 tmr->function);
diff --git a/drivers/target/target_core_ua.c b/drivers/target/target_core_ua.c
index a2ef346087e8..df355176a377 100644
--- a/drivers/target/target_core_ua.c
+++ b/drivers/target/target_core_ua.c
@@ -247,7 +247,7 @@ void core_scsi3_ua_for_check_condition(
247 } 247 }
248 /* 248 /*
249 * Otherwise for the default 00b, release the UNIT ATTENTION 249 * Otherwise for the default 00b, release the UNIT ATTENTION
250 * condition. Return the ASC/ASCQ of the higest priority UA 250 * condition. Return the ASC/ASCQ of the highest priority UA
251 * (head of the list) in the outgoing CHECK_CONDITION + sense. 251 * (head of the list) in the outgoing CHECK_CONDITION + sense.
252 */ 252 */
253 if (head) { 253 if (head) {
@@ -304,7 +304,7 @@ int core_scsi3_ua_clear_for_request_sense(
304 * matching struct se_lun. 304 * matching struct se_lun.
305 * 305 *
306 * Once the returning ASC/ASCQ values are set, we go ahead and 306 * Once the returning ASC/ASCQ values are set, we go ahead and
307 * release all of the Unit Attention conditions for the assoicated 307 * release all of the Unit Attention conditions for the associated
308 * struct se_lun. 308 * struct se_lun.
309 */ 309 */
310 spin_lock(&deve->ua_lock); 310 spin_lock(&deve->ua_lock);