aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2011-03-18 18:39:17 -0400
committerJames Bottomley <James.Bottomley@suse.de>2011-03-23 14:10:33 -0400
commit3703b2c5d041a68095cdd22380c23ce27d449ad7 (patch)
tree6d0a977357652e26b07c4b1ab0a871988b91faaa /drivers/target
parent5fa8b573134108a333a317378998a9f1299c4dd6 (diff)
[SCSI] tcm_loop: Add multi-fabric Linux/SCSI LLD fabric module
This patch adds the TCM_Loop Linux/SCSI LLD fabric module for accessing TCM device backstores as locally accessable SCSI LUNs in virtual SAS, FC, and iSCSI Target ports using the generic fabric TransportID and Target Port WWN naming handlers from TCM's target_core_fabric_lib.c The TCM_Loop module uses the generic fabric configfs infratructure provided by target_core_fabric_configfs.c and adds a module dependent attribute for the creation/release of the virtual I_T Nexus connected the TCM_Loop Target and Initiator Ports. TCM_Loop can also be used with scsi-generic and BSG drivers so that STGT userspace fabric modules, QEMU-KVM and other hypervisor SCSI passthrough support can access TCM device backstore and control CDB emulation. For more information please see: http://linux-iscsi.org/wiki/Tcm_loop [jejb: fixed up checkpatch stuff] Signed-off-by: Nicholas A. Bellinger <nab@linux-iscsi.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/Kconfig2
-rw-r--r--drivers/target/Makefile3
-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
6 files changed, 1673 insertions, 0 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 4f3cb788f06a..1178bbfc68fe 100644
--- a/drivers/target/Makefile
+++ b/drivers/target/Makefile
@@ -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};