target: Address legacy PYX_TRANSPORT_* return code breakage
[deliverable/linux.git] / drivers / target / loopback / tcm_loop.c
CommitLineData
3703b2c5
NB
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>
3703b2c5
NB
34
35#include <target/target_core_base.h>
36#include <target/target_core_transport.h>
37#include <target/target_core_fabric_ops.h>
38#include <target/target_core_fabric_configfs.h>
39#include <target/target_core_fabric_lib.h>
40#include <target/target_core_configfs.h>
41#include <target/target_core_device.h>
42#include <target/target_core_tpg.h>
43#include <target/target_core_tmr.h>
44
45#include "tcm_loop.h"
46
47#define to_tcm_loop_hba(hba) container_of(hba, struct tcm_loop_hba, dev)
48
49/* Local pointer to allocated TCM configfs fabric module */
50static struct target_fabric_configfs *tcm_loop_fabric_configfs;
51
52static struct kmem_cache *tcm_loop_cmd_cache;
53
54static int tcm_loop_hba_no_cnt;
55
56/*
57 * Allocate a tcm_loop cmd descriptor from target_core_mod code
58 *
59 * Can be called from interrupt context in tcm_loop_queuecommand() below
60 */
61static struct se_cmd *tcm_loop_allocate_core_cmd(
62 struct tcm_loop_hba *tl_hba,
63 struct se_portal_group *se_tpg,
64 struct scsi_cmnd *sc)
65{
66 struct se_cmd *se_cmd;
67 struct se_session *se_sess;
68 struct tcm_loop_nexus *tl_nexus = tl_hba->tl_nexus;
69 struct tcm_loop_cmd *tl_cmd;
70 int sam_task_attr;
71
72 if (!tl_nexus) {
73 scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus"
74 " does not exist\n");
75 set_host_byte(sc, DID_ERROR);
76 return NULL;
77 }
78 se_sess = tl_nexus->se_sess;
79
80 tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_ATOMIC);
81 if (!tl_cmd) {
6708bb27 82 pr_err("Unable to allocate struct tcm_loop_cmd\n");
3703b2c5
NB
83 set_host_byte(sc, DID_ERROR);
84 return NULL;
85 }
86 se_cmd = &tl_cmd->tl_se_cmd;
87 /*
88 * Save the pointer to struct scsi_cmnd *sc
89 */
90 tl_cmd->sc = sc;
91 /*
92 * Locate the SAM Task Attr from struct scsi_cmnd *
93 */
94 if (sc->device->tagged_supported) {
95 switch (sc->tag) {
96 case HEAD_OF_QUEUE_TAG:
61db1802 97 sam_task_attr = MSG_HEAD_TAG;
3703b2c5
NB
98 break;
99 case ORDERED_QUEUE_TAG:
61db1802 100 sam_task_attr = MSG_ORDERED_TAG;
3703b2c5
NB
101 break;
102 default:
61db1802 103 sam_task_attr = MSG_SIMPLE_TAG;
3703b2c5
NB
104 break;
105 }
106 } else
61db1802 107 sam_task_attr = MSG_SIMPLE_TAG;
3703b2c5
NB
108
109 /*
110 * Initialize struct se_cmd descriptor from target_core_mod infrastructure
111 */
112 transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess,
113 scsi_bufflen(sc), sc->sc_data_direction, sam_task_attr,
114 &tl_cmd->tl_sense_buf[0]);
115
116 /*
117 * Signal BIDI usage with T_TASK(cmd)->t_tasks_bidi
118 */
119 if (scsi_bidi_cmnd(sc))
a1d8b49a 120 se_cmd->t_tasks_bidi = 1;
3703b2c5
NB
121 /*
122 * Locate the struct se_lun pointer and attach it to struct se_cmd
123 */
5951146d 124 if (transport_lookup_cmd_lun(se_cmd, tl_cmd->sc->device->lun) < 0) {
3703b2c5
NB
125 kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
126 set_host_byte(sc, DID_NO_CONNECT);
127 return NULL;
128 }
129
3703b2c5
NB
130 return se_cmd;
131}
132
133/*
134 * Called by struct target_core_fabric_ops->new_cmd_map()
135 *
136 * Always called in process context. A non zero return value
137 * here will signal to handle an exception based on the return code.
138 */
139static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd)
140{
141 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
142 struct tcm_loop_cmd, tl_se_cmd);
143 struct scsi_cmnd *sc = tl_cmd->sc;
5951146d
AG
144 struct scatterlist *sgl_bidi = NULL;
145 u32 sgl_bidi_count = 0;
3703b2c5
NB
146 int ret;
147 /*
148 * Allocate the necessary tasks to complete the received CDB+data
149 */
5951146d 150 ret = transport_generic_allocate_tasks(se_cmd, sc->cmnd);
03e98c9e
NB
151 if (ret != 0)
152 return ret;
3703b2c5 153 /*
5951146d
AG
154 * For BIDI commands, pass in the extra READ buffer
155 * to transport_generic_map_mem_to_cmd() below..
3703b2c5 156 */
a1d8b49a 157 if (se_cmd->t_tasks_bidi) {
5951146d 158 struct scsi_data_buffer *sdb = scsi_in(sc);
3703b2c5 159
5951146d
AG
160 sgl_bidi = sdb->table.sgl;
161 sgl_bidi_count = sdb->table.nents;
3703b2c5 162 }
8cd79f24
NB
163 /*
164 * Because some userspace code via scsi-generic do not memset their
165 * associated read buffers, go ahead and do that here for type
166 * SCF_SCSI_CONTROL_SG_IO_CDB. Also note that this is currently
167 * guaranteed to be a single SGL for SCF_SCSI_CONTROL_SG_IO_CDB
168 * by target core in transport_generic_allocate_tasks() ->
169 * transport_generic_cmd_sequencer().
170 */
171 if (se_cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB &&
172 se_cmd->data_direction == DMA_FROM_DEVICE) {
173 struct scatterlist *sg = scsi_sglist(sc);
174 unsigned char *buf = kmap(sg_page(sg)) + sg->offset;
175
176 if (buf != NULL) {
177 memset(buf, 0, sg->length);
178 kunmap(sg_page(sg));
179 }
180 }
5951146d 181
ec98f782 182 /* Tell the core about our preallocated memory */
03e98c9e 183 return transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc),
5951146d 184 scsi_sg_count(sc), sgl_bidi, sgl_bidi_count);
3703b2c5
NB
185}
186
187/*
188 * Called from struct target_core_fabric_ops->check_stop_free()
189 */
88dd9e26 190static int tcm_loop_check_stop_free(struct se_cmd *se_cmd)
3703b2c5
NB
191{
192 /*
193 * Do not release struct se_cmd's containing a valid TMR
194 * pointer. These will be released directly in tcm_loop_device_reset()
195 * with transport_generic_free_cmd().
196 */
197 if (se_cmd->se_tmr_req)
88dd9e26 198 return 0;
3703b2c5
NB
199 /*
200 * Release the struct se_cmd, which will make a callback to release
201 * struct tcm_loop_cmd * in tcm_loop_deallocate_core_cmd()
202 */
82f1c8a4 203 transport_generic_free_cmd(se_cmd, 0);
88dd9e26 204 return 1;
3703b2c5
NB
205}
206
35462975 207static void tcm_loop_release_cmd(struct se_cmd *se_cmd)
3703b2c5
NB
208{
209 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
210 struct tcm_loop_cmd, tl_se_cmd);
211
212 kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
213}
214
215static int tcm_loop_proc_info(struct Scsi_Host *host, char *buffer,
216 char **start, off_t offset,
217 int length, int inout)
218{
219 return sprintf(buffer, "tcm_loop_proc_info()\n");
220}
221
222static int tcm_loop_driver_probe(struct device *);
223static int tcm_loop_driver_remove(struct device *);
224
225static int pseudo_lld_bus_match(struct device *dev,
226 struct device_driver *dev_driver)
227{
228 return 1;
229}
230
231static struct bus_type tcm_loop_lld_bus = {
232 .name = "tcm_loop_bus",
233 .match = pseudo_lld_bus_match,
234 .probe = tcm_loop_driver_probe,
235 .remove = tcm_loop_driver_remove,
236};
237
238static struct device_driver tcm_loop_driverfs = {
239 .name = "tcm_loop",
240 .bus = &tcm_loop_lld_bus,
241};
242/*
243 * Used with root_device_register() in tcm_loop_alloc_core_bus() below
244 */
245struct device *tcm_loop_primary;
246
247/*
248 * Copied from drivers/scsi/libfc/fc_fcp.c:fc_change_queue_depth() and
249 * drivers/scsi/libiscsi.c:iscsi_change_queue_depth()
250 */
251static int tcm_loop_change_queue_depth(
252 struct scsi_device *sdev,
253 int depth,
254 int reason)
255{
256 switch (reason) {
257 case SCSI_QDEPTH_DEFAULT:
258 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
259 break;
260 case SCSI_QDEPTH_QFULL:
261 scsi_track_queue_full(sdev, depth);
262 break;
263 case SCSI_QDEPTH_RAMP_UP:
264 scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
265 break;
266 default:
267 return -EOPNOTSUPP;
268 }
269 return sdev->queue_depth;
270}
271
272/*
273 * Main entry point from struct scsi_host_template for incoming SCSI CDB+Data
274 * from Linux/SCSI subsystem for SCSI low level device drivers (LLDs)
275 */
276static int tcm_loop_queuecommand(
277 struct Scsi_Host *sh,
278 struct scsi_cmnd *sc)
279{
280 struct se_cmd *se_cmd;
281 struct se_portal_group *se_tpg;
282 struct tcm_loop_hba *tl_hba;
283 struct tcm_loop_tpg *tl_tpg;
284
6708bb27 285 pr_debug("tcm_loop_queuecommand() %d:%d:%d:%d got CDB: 0x%02x"
3703b2c5
NB
286 " scsi_buf_len: %u\n", sc->device->host->host_no,
287 sc->device->id, sc->device->channel, sc->device->lun,
288 sc->cmnd[0], scsi_bufflen(sc));
289 /*
290 * Locate the tcm_loop_hba_t pointer
291 */
292 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
293 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
0a020436
NB
294 /*
295 * Ensure that this tl_tpg reference from the incoming sc->device->id
296 * has already been configured via tcm_loop_make_naa_tpg().
297 */
298 if (!tl_tpg->tl_hba) {
299 set_host_byte(sc, DID_NO_CONNECT);
300 sc->scsi_done(sc);
301 return 0;
302 }
3703b2c5
NB
303 se_tpg = &tl_tpg->tl_se_tpg;
304 /*
305 * Determine the SAM Task Attribute and allocate tl_cmd and
306 * tl_cmd->tl_se_cmd from TCM infrastructure
307 */
308 se_cmd = tcm_loop_allocate_core_cmd(tl_hba, se_tpg, sc);
309 if (!se_cmd) {
310 sc->scsi_done(sc);
311 return 0;
312 }
313 /*
314 * Queue up the newly allocated to be processed in TCM thread context.
315 */
316 transport_generic_handle_cdb_map(se_cmd);
317 return 0;
318}
319
320/*
321 * Called from SCSI EH process context to issue a LUN_RESET TMR
322 * to struct scsi_device
323 */
324static int tcm_loop_device_reset(struct scsi_cmnd *sc)
325{
326 struct se_cmd *se_cmd = NULL;
327 struct se_portal_group *se_tpg;
328 struct se_session *se_sess;
329 struct tcm_loop_cmd *tl_cmd = NULL;
330 struct tcm_loop_hba *tl_hba;
331 struct tcm_loop_nexus *tl_nexus;
332 struct tcm_loop_tmr *tl_tmr = NULL;
333 struct tcm_loop_tpg *tl_tpg;
334 int ret = FAILED;
335 /*
336 * Locate the tcm_loop_hba_t pointer
337 */
338 tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
339 /*
340 * Locate the tl_nexus and se_sess pointers
341 */
342 tl_nexus = tl_hba->tl_nexus;
343 if (!tl_nexus) {
6708bb27 344 pr_err("Unable to perform device reset without"
3703b2c5
NB
345 " active I_T Nexus\n");
346 return FAILED;
347 }
348 se_sess = tl_nexus->se_sess;
349 /*
350 * Locate the tl_tpg and se_tpg pointers from TargetID in sc->device->id
351 */
352 tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
353 se_tpg = &tl_tpg->tl_se_tpg;
354
355 tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_KERNEL);
356 if (!tl_cmd) {
6708bb27 357 pr_err("Unable to allocate memory for tl_cmd\n");
3703b2c5
NB
358 return FAILED;
359 }
360
361 tl_tmr = kzalloc(sizeof(struct tcm_loop_tmr), GFP_KERNEL);
362 if (!tl_tmr) {
6708bb27 363 pr_err("Unable to allocate memory for tl_tmr\n");
3703b2c5
NB
364 goto release;
365 }
366 init_waitqueue_head(&tl_tmr->tl_tmr_wait);
367
368 se_cmd = &tl_cmd->tl_se_cmd;
369 /*
370 * Initialize struct se_cmd descriptor from target_core_mod infrastructure
371 */
372 transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, 0,
61db1802 373 DMA_NONE, MSG_SIMPLE_TAG,
3703b2c5
NB
374 &tl_cmd->tl_sense_buf[0]);
375 /*
376 * Allocate the LUN_RESET TMR
377 */
5951146d 378 se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd, tl_tmr,
dd503a5f 379 TMR_LUN_RESET, GFP_KERNEL);
552523dc 380 if (IS_ERR(se_cmd->se_tmr_req))
3703b2c5
NB
381 goto release;
382 /*
383 * Locate the underlying TCM struct se_lun from sc->device->lun
384 */
5951146d 385 if (transport_lookup_tmr_lun(se_cmd, sc->device->lun) < 0)
3703b2c5
NB
386 goto release;
387 /*
388 * Queue the TMR to TCM Core and sleep waiting for tcm_loop_queue_tm_rsp()
389 * to wake us up.
390 */
391 transport_generic_handle_tmr(se_cmd);
392 wait_event(tl_tmr->tl_tmr_wait, atomic_read(&tl_tmr->tmr_complete));
393 /*
394 * The TMR LUN_RESET has completed, check the response status and
395 * then release allocations.
396 */
397 ret = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ?
398 SUCCESS : FAILED;
399release:
400 if (se_cmd)
82f1c8a4 401 transport_generic_free_cmd(se_cmd, 1);
3703b2c5
NB
402 else
403 kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
404 kfree(tl_tmr);
405 return ret;
406}
407
408static int tcm_loop_slave_alloc(struct scsi_device *sd)
409{
410 set_bit(QUEUE_FLAG_BIDI, &sd->request_queue->queue_flags);
411 return 0;
412}
413
414static int tcm_loop_slave_configure(struct scsi_device *sd)
415{
416 return 0;
417}
418
419static struct scsi_host_template tcm_loop_driver_template = {
420 .proc_info = tcm_loop_proc_info,
421 .proc_name = "tcm_loopback",
422 .name = "TCM_Loopback",
423 .queuecommand = tcm_loop_queuecommand,
424 .change_queue_depth = tcm_loop_change_queue_depth,
425 .eh_device_reset_handler = tcm_loop_device_reset,
426 .can_queue = TL_SCSI_CAN_QUEUE,
427 .this_id = -1,
428 .sg_tablesize = TL_SCSI_SG_TABLESIZE,
429 .cmd_per_lun = TL_SCSI_CMD_PER_LUN,
430 .max_sectors = TL_SCSI_MAX_SECTORS,
431 .use_clustering = DISABLE_CLUSTERING,
432 .slave_alloc = tcm_loop_slave_alloc,
433 .slave_configure = tcm_loop_slave_configure,
434 .module = THIS_MODULE,
435};
436
437static int tcm_loop_driver_probe(struct device *dev)
438{
439 struct tcm_loop_hba *tl_hba;
440 struct Scsi_Host *sh;
441 int error;
442
443 tl_hba = to_tcm_loop_hba(dev);
444
445 sh = scsi_host_alloc(&tcm_loop_driver_template,
446 sizeof(struct tcm_loop_hba));
447 if (!sh) {
6708bb27 448 pr_err("Unable to allocate struct scsi_host\n");
3703b2c5
NB
449 return -ENODEV;
450 }
451 tl_hba->sh = sh;
452
453 /*
454 * Assign the struct tcm_loop_hba pointer to struct Scsi_Host->hostdata
455 */
456 *((struct tcm_loop_hba **)sh->hostdata) = tl_hba;
457 /*
458 * Setup single ID, Channel and LUN for now..
459 */
460 sh->max_id = 2;
461 sh->max_lun = 0;
462 sh->max_channel = 0;
463 sh->max_cmd_len = TL_SCSI_MAX_CMD_LEN;
464
465 error = scsi_add_host(sh, &tl_hba->dev);
466 if (error) {
6708bb27 467 pr_err("%s: scsi_add_host failed\n", __func__);
3703b2c5
NB
468 scsi_host_put(sh);
469 return -ENODEV;
470 }
471 return 0;
472}
473
474static int tcm_loop_driver_remove(struct device *dev)
475{
476 struct tcm_loop_hba *tl_hba;
477 struct Scsi_Host *sh;
478
479 tl_hba = to_tcm_loop_hba(dev);
480 sh = tl_hba->sh;
481
482 scsi_remove_host(sh);
483 scsi_host_put(sh);
484 return 0;
485}
486
487static void tcm_loop_release_adapter(struct device *dev)
488{
489 struct tcm_loop_hba *tl_hba = to_tcm_loop_hba(dev);
490
491 kfree(tl_hba);
492}
493
494/*
495 * Called from tcm_loop_make_scsi_hba() in tcm_loop_configfs.c
496 */
497static int tcm_loop_setup_hba_bus(struct tcm_loop_hba *tl_hba, int tcm_loop_host_id)
498{
499 int ret;
500
501 tl_hba->dev.bus = &tcm_loop_lld_bus;
502 tl_hba->dev.parent = tcm_loop_primary;
503 tl_hba->dev.release = &tcm_loop_release_adapter;
504 dev_set_name(&tl_hba->dev, "tcm_loop_adapter_%d", tcm_loop_host_id);
505
506 ret = device_register(&tl_hba->dev);
507 if (ret) {
6708bb27 508 pr_err("device_register() failed for"
3703b2c5
NB
509 " tl_hba->dev: %d\n", ret);
510 return -ENODEV;
511 }
512
513 return 0;
514}
515
516/*
517 * Called from tcm_loop_fabric_init() in tcl_loop_fabric.c to load the emulated
518 * tcm_loop SCSI bus.
519 */
520static int tcm_loop_alloc_core_bus(void)
521{
522 int ret;
523
524 tcm_loop_primary = root_device_register("tcm_loop_0");
525 if (IS_ERR(tcm_loop_primary)) {
6708bb27 526 pr_err("Unable to allocate tcm_loop_primary\n");
3703b2c5
NB
527 return PTR_ERR(tcm_loop_primary);
528 }
529
530 ret = bus_register(&tcm_loop_lld_bus);
531 if (ret) {
6708bb27 532 pr_err("bus_register() failed for tcm_loop_lld_bus\n");
3703b2c5
NB
533 goto dev_unreg;
534 }
535
536 ret = driver_register(&tcm_loop_driverfs);
537 if (ret) {
6708bb27 538 pr_err("driver_register() failed for"
3703b2c5
NB
539 "tcm_loop_driverfs\n");
540 goto bus_unreg;
541 }
542
6708bb27 543 pr_debug("Initialized TCM Loop Core Bus\n");
3703b2c5
NB
544 return ret;
545
546bus_unreg:
547 bus_unregister(&tcm_loop_lld_bus);
548dev_unreg:
549 root_device_unregister(tcm_loop_primary);
550 return ret;
551}
552
553static void tcm_loop_release_core_bus(void)
554{
555 driver_unregister(&tcm_loop_driverfs);
556 bus_unregister(&tcm_loop_lld_bus);
557 root_device_unregister(tcm_loop_primary);
558
6708bb27 559 pr_debug("Releasing TCM Loop Core BUS\n");
3703b2c5
NB
560}
561
562static char *tcm_loop_get_fabric_name(void)
563{
564 return "loopback";
565}
566
567static u8 tcm_loop_get_fabric_proto_ident(struct se_portal_group *se_tpg)
568{
569 struct tcm_loop_tpg *tl_tpg =
570 (struct tcm_loop_tpg *)se_tpg->se_tpg_fabric_ptr;
571 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
572 /*
573 * tl_proto_id is set at tcm_loop_configfs.c:tcm_loop_make_scsi_hba()
574 * time based on the protocol dependent prefix of the passed configfs group.
575 *
576 * Based upon tl_proto_id, TCM_Loop emulates the requested fabric
577 * ProtocolID using target_core_fabric_lib.c symbols.
578 */
579 switch (tl_hba->tl_proto_id) {
580 case SCSI_PROTOCOL_SAS:
581 return sas_get_fabric_proto_ident(se_tpg);
582 case SCSI_PROTOCOL_FCP:
583 return fc_get_fabric_proto_ident(se_tpg);
584 case SCSI_PROTOCOL_ISCSI:
585 return iscsi_get_fabric_proto_ident(se_tpg);
586 default:
6708bb27 587 pr_err("Unknown tl_proto_id: 0x%02x, using"
3703b2c5
NB
588 " SAS emulation\n", tl_hba->tl_proto_id);
589 break;
590 }
591
592 return sas_get_fabric_proto_ident(se_tpg);
593}
594
595static char *tcm_loop_get_endpoint_wwn(struct se_portal_group *se_tpg)
596{
597 struct tcm_loop_tpg *tl_tpg =
598 (struct tcm_loop_tpg *)se_tpg->se_tpg_fabric_ptr;
599 /*
600 * Return the passed NAA identifier for the SAS Target Port
601 */
602 return &tl_tpg->tl_hba->tl_wwn_address[0];
603}
604
605static u16 tcm_loop_get_tag(struct se_portal_group *se_tpg)
606{
607 struct tcm_loop_tpg *tl_tpg =
608 (struct tcm_loop_tpg *)se_tpg->se_tpg_fabric_ptr;
609 /*
610 * This Tag is used when forming SCSI Name identifier in EVPD=1 0x83
611 * to represent the SCSI Target Port.
612 */
613 return tl_tpg->tl_tpgt;
614}
615
616static u32 tcm_loop_get_default_depth(struct se_portal_group *se_tpg)
617{
618 return 1;
619}
620
621static u32 tcm_loop_get_pr_transport_id(
622 struct se_portal_group *se_tpg,
623 struct se_node_acl *se_nacl,
624 struct t10_pr_registration *pr_reg,
625 int *format_code,
626 unsigned char *buf)
627{
628 struct tcm_loop_tpg *tl_tpg =
629 (struct tcm_loop_tpg *)se_tpg->se_tpg_fabric_ptr;
630 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
631
632 switch (tl_hba->tl_proto_id) {
633 case SCSI_PROTOCOL_SAS:
634 return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
635 format_code, buf);
636 case SCSI_PROTOCOL_FCP:
637 return fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
638 format_code, buf);
639 case SCSI_PROTOCOL_ISCSI:
640 return iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
641 format_code, buf);
642 default:
6708bb27 643 pr_err("Unknown tl_proto_id: 0x%02x, using"
3703b2c5
NB
644 " SAS emulation\n", tl_hba->tl_proto_id);
645 break;
646 }
647
648 return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
649 format_code, buf);
650}
651
652static u32 tcm_loop_get_pr_transport_id_len(
653 struct se_portal_group *se_tpg,
654 struct se_node_acl *se_nacl,
655 struct t10_pr_registration *pr_reg,
656 int *format_code)
657{
658 struct tcm_loop_tpg *tl_tpg =
659 (struct tcm_loop_tpg *)se_tpg->se_tpg_fabric_ptr;
660 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
661
662 switch (tl_hba->tl_proto_id) {
663 case SCSI_PROTOCOL_SAS:
664 return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
665 format_code);
666 case SCSI_PROTOCOL_FCP:
667 return fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
668 format_code);
669 case SCSI_PROTOCOL_ISCSI:
670 return iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
671 format_code);
672 default:
6708bb27 673 pr_err("Unknown tl_proto_id: 0x%02x, using"
3703b2c5
NB
674 " SAS emulation\n", tl_hba->tl_proto_id);
675 break;
676 }
677
678 return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
679 format_code);
680}
681
682/*
683 * Used for handling SCSI fabric dependent TransportIDs in SPC-3 and above
684 * Persistent Reservation SPEC_I_PT=1 and PROUT REGISTER_AND_MOVE operations.
685 */
686static char *tcm_loop_parse_pr_out_transport_id(
687 struct se_portal_group *se_tpg,
688 const char *buf,
689 u32 *out_tid_len,
690 char **port_nexus_ptr)
691{
692 struct tcm_loop_tpg *tl_tpg =
693 (struct tcm_loop_tpg *)se_tpg->se_tpg_fabric_ptr;
694 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
695
696 switch (tl_hba->tl_proto_id) {
697 case SCSI_PROTOCOL_SAS:
698 return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
699 port_nexus_ptr);
700 case SCSI_PROTOCOL_FCP:
701 return fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
702 port_nexus_ptr);
703 case SCSI_PROTOCOL_ISCSI:
704 return iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
705 port_nexus_ptr);
706 default:
6708bb27 707 pr_err("Unknown tl_proto_id: 0x%02x, using"
3703b2c5
NB
708 " SAS emulation\n", tl_hba->tl_proto_id);
709 break;
710 }
711
712 return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
713 port_nexus_ptr);
714}
715
716/*
717 * Returning (1) here allows for target_core_mod struct se_node_acl to be generated
718 * based upon the incoming fabric dependent SCSI Initiator Port
719 */
720static int tcm_loop_check_demo_mode(struct se_portal_group *se_tpg)
721{
722 return 1;
723}
724
725static int tcm_loop_check_demo_mode_cache(struct se_portal_group *se_tpg)
726{
727 return 0;
728}
729
730/*
731 * Allow I_T Nexus full READ-WRITE access without explict Initiator Node ACLs for
732 * local virtual Linux/SCSI LLD passthrough into VM hypervisor guest
733 */
734static int tcm_loop_check_demo_mode_write_protect(struct se_portal_group *se_tpg)
735{
736 return 0;
737}
738
739/*
740 * Because TCM_Loop does not use explict ACLs and MappedLUNs, this will
741 * never be called for TCM_Loop by target_core_fabric_configfs.c code.
742 * It has been added here as a nop for target_fabric_tf_ops_check()
743 */
744static int tcm_loop_check_prod_mode_write_protect(struct se_portal_group *se_tpg)
745{
746 return 0;
747}
748
749static struct se_node_acl *tcm_loop_tpg_alloc_fabric_acl(
750 struct se_portal_group *se_tpg)
751{
752 struct tcm_loop_nacl *tl_nacl;
753
754 tl_nacl = kzalloc(sizeof(struct tcm_loop_nacl), GFP_KERNEL);
755 if (!tl_nacl) {
6708bb27 756 pr_err("Unable to allocate struct tcm_loop_nacl\n");
3703b2c5
NB
757 return NULL;
758 }
759
760 return &tl_nacl->se_node_acl;
761}
762
763static void tcm_loop_tpg_release_fabric_acl(
764 struct se_portal_group *se_tpg,
765 struct se_node_acl *se_nacl)
766{
767 struct tcm_loop_nacl *tl_nacl = container_of(se_nacl,
768 struct tcm_loop_nacl, se_node_acl);
769
770 kfree(tl_nacl);
771}
772
773static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg)
774{
775 return 1;
776}
777
3703b2c5
NB
778static int tcm_loop_is_state_remove(struct se_cmd *se_cmd)
779{
780 /*
781 * Assume struct scsi_cmnd is not in remove state..
782 */
783 return 0;
784}
785
786static int tcm_loop_sess_logged_in(struct se_session *se_sess)
787{
788 /*
789 * Assume that TL Nexus is always active
790 */
791 return 1;
792}
793
794static u32 tcm_loop_sess_get_index(struct se_session *se_sess)
795{
796 return 1;
797}
798
799static void tcm_loop_set_default_node_attributes(struct se_node_acl *se_acl)
800{
801 return;
802}
803
804static u32 tcm_loop_get_task_tag(struct se_cmd *se_cmd)
805{
806 return 1;
807}
808
809static int tcm_loop_get_cmd_state(struct se_cmd *se_cmd)
810{
811 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
812 struct tcm_loop_cmd, tl_se_cmd);
813
814 return tl_cmd->sc_cmd_state;
815}
816
817static int tcm_loop_shutdown_session(struct se_session *se_sess)
818{
819 return 0;
820}
821
822static void tcm_loop_close_session(struct se_session *se_sess)
823{
824 return;
825};
826
827static void tcm_loop_stop_session(
828 struct se_session *se_sess,
829 int sess_sleep,
830 int conn_sleep)
831{
832 return;
833}
834
835static void tcm_loop_fall_back_to_erl0(struct se_session *se_sess)
836{
837 return;
838}
839
840static int tcm_loop_write_pending(struct se_cmd *se_cmd)
841{
842 /*
843 * Since Linux/SCSI has already sent down a struct scsi_cmnd
844 * sc->sc_data_direction of DMA_TO_DEVICE with struct scatterlist array
845 * memory, and memory has already been mapped to struct se_cmd->t_mem_list
846 * format with transport_generic_map_mem_to_cmd().
847 *
848 * We now tell TCM to add this WRITE CDB directly into the TCM storage
849 * object execution queue.
850 */
851 transport_generic_process_write(se_cmd);
852 return 0;
853}
854
855static int tcm_loop_write_pending_status(struct se_cmd *se_cmd)
856{
857 return 0;
858}
859
860static int tcm_loop_queue_data_in(struct se_cmd *se_cmd)
861{
862 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
863 struct tcm_loop_cmd, tl_se_cmd);
864 struct scsi_cmnd *sc = tl_cmd->sc;
865
6708bb27 866 pr_debug("tcm_loop_queue_data_in() called for scsi_cmnd: %p"
3703b2c5
NB
867 " cdb: 0x%02x\n", sc, sc->cmnd[0]);
868
869 sc->result = SAM_STAT_GOOD;
870 set_host_byte(sc, DID_OK);
871 sc->scsi_done(sc);
872 return 0;
873}
874
875static int tcm_loop_queue_status(struct se_cmd *se_cmd)
876{
877 struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
878 struct tcm_loop_cmd, tl_se_cmd);
879 struct scsi_cmnd *sc = tl_cmd->sc;
880
6708bb27 881 pr_debug("tcm_loop_queue_status() called for scsi_cmnd: %p"
3703b2c5
NB
882 " cdb: 0x%02x\n", sc, sc->cmnd[0]);
883
884 if (se_cmd->sense_buffer &&
885 ((se_cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||
886 (se_cmd->se_cmd_flags & SCF_EMULATED_TASK_SENSE))) {
887
5951146d 888 memcpy(sc->sense_buffer, se_cmd->sense_buffer,
3703b2c5
NB
889 SCSI_SENSE_BUFFERSIZE);
890 sc->result = SAM_STAT_CHECK_CONDITION;
891 set_driver_byte(sc, DRIVER_SENSE);
892 } else
893 sc->result = se_cmd->scsi_status;
894
895 set_host_byte(sc, DID_OK);
896 sc->scsi_done(sc);
897 return 0;
898}
899
900static int tcm_loop_queue_tm_rsp(struct se_cmd *se_cmd)
901{
902 struct se_tmr_req *se_tmr = se_cmd->se_tmr_req;
903 struct tcm_loop_tmr *tl_tmr = se_tmr->fabric_tmr_ptr;
904 /*
905 * The SCSI EH thread will be sleeping on se_tmr->tl_tmr_wait, go ahead
906 * and wake up the wait_queue_head_t in tcm_loop_device_reset()
907 */
908 atomic_set(&tl_tmr->tmr_complete, 1);
909 wake_up(&tl_tmr->tl_tmr_wait);
910 return 0;
911}
912
913static u16 tcm_loop_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
914{
915 return 0;
916}
917
918static u16 tcm_loop_get_fabric_sense_len(void)
919{
920 return 0;
921}
922
3703b2c5
NB
923static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba)
924{
925 switch (tl_hba->tl_proto_id) {
926 case SCSI_PROTOCOL_SAS:
927 return "SAS";
928 case SCSI_PROTOCOL_FCP:
929 return "FCP";
930 case SCSI_PROTOCOL_ISCSI:
931 return "iSCSI";
932 default:
933 break;
934 }
935
936 return "Unknown";
937}
938
939/* Start items for tcm_loop_port_cit */
940
941static int tcm_loop_port_link(
942 struct se_portal_group *se_tpg,
943 struct se_lun *lun)
944{
945 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
946 struct tcm_loop_tpg, tl_se_tpg);
947 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
948
949 atomic_inc(&tl_tpg->tl_tpg_port_count);
950 smp_mb__after_atomic_inc();
951 /*
952 * Add Linux/SCSI struct scsi_device by HCTL
953 */
954 scsi_add_device(tl_hba->sh, 0, tl_tpg->tl_tpgt, lun->unpacked_lun);
955
6708bb27 956 pr_debug("TCM_Loop_ConfigFS: Port Link Successful\n");
3703b2c5
NB
957 return 0;
958}
959
960static void tcm_loop_port_unlink(
961 struct se_portal_group *se_tpg,
962 struct se_lun *se_lun)
963{
964 struct scsi_device *sd;
965 struct tcm_loop_hba *tl_hba;
966 struct tcm_loop_tpg *tl_tpg;
967
968 tl_tpg = container_of(se_tpg, struct tcm_loop_tpg, tl_se_tpg);
969 tl_hba = tl_tpg->tl_hba;
970
971 sd = scsi_device_lookup(tl_hba->sh, 0, tl_tpg->tl_tpgt,
972 se_lun->unpacked_lun);
973 if (!sd) {
6708bb27 974 pr_err("Unable to locate struct scsi_device for %d:%d:"
3703b2c5
NB
975 "%d\n", 0, tl_tpg->tl_tpgt, se_lun->unpacked_lun);
976 return;
977 }
978 /*
979 * Remove Linux/SCSI struct scsi_device by HCTL
980 */
981 scsi_remove_device(sd);
982 scsi_device_put(sd);
983
984 atomic_dec(&tl_tpg->tl_tpg_port_count);
985 smp_mb__after_atomic_dec();
986
6708bb27 987 pr_debug("TCM_Loop_ConfigFS: Port Unlink Successful\n");
3703b2c5
NB
988}
989
990/* End items for tcm_loop_port_cit */
991
992/* Start items for tcm_loop_nexus_cit */
993
994static int tcm_loop_make_nexus(
995 struct tcm_loop_tpg *tl_tpg,
996 const char *name)
997{
998 struct se_portal_group *se_tpg;
999 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
1000 struct tcm_loop_nexus *tl_nexus;
552523dc 1001 int ret = -ENOMEM;
3703b2c5
NB
1002
1003 if (tl_tpg->tl_hba->tl_nexus) {
6708bb27 1004 pr_debug("tl_tpg->tl_hba->tl_nexus already exists\n");
3703b2c5
NB
1005 return -EEXIST;
1006 }
1007 se_tpg = &tl_tpg->tl_se_tpg;
1008
1009 tl_nexus = kzalloc(sizeof(struct tcm_loop_nexus), GFP_KERNEL);
1010 if (!tl_nexus) {
6708bb27 1011 pr_err("Unable to allocate struct tcm_loop_nexus\n");
3703b2c5
NB
1012 return -ENOMEM;
1013 }
1014 /*
1015 * Initialize the struct se_session pointer
1016 */
1017 tl_nexus->se_sess = transport_init_session();
552523dc
DC
1018 if (IS_ERR(tl_nexus->se_sess)) {
1019 ret = PTR_ERR(tl_nexus->se_sess);
3703b2c5 1020 goto out;
552523dc 1021 }
3703b2c5
NB
1022 /*
1023 * Since we are running in 'demo mode' this call with generate a
1024 * struct se_node_acl for the tcm_loop struct se_portal_group with the SCSI
1025 * Initiator port name of the passed configfs group 'name'.
1026 */
1027 tl_nexus->se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
1028 se_tpg, (unsigned char *)name);
1029 if (!tl_nexus->se_sess->se_node_acl) {
1030 transport_free_session(tl_nexus->se_sess);
1031 goto out;
1032 }
1033 /*
1034 * Now, register the SAS I_T Nexus as active with the call to
1035 * transport_register_session()
1036 */
1037 __transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl,
5951146d 1038 tl_nexus->se_sess, tl_nexus);
3703b2c5 1039 tl_tpg->tl_hba->tl_nexus = tl_nexus;
6708bb27 1040 pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated"
3703b2c5
NB
1041 " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba),
1042 name);
1043 return 0;
1044
1045out:
1046 kfree(tl_nexus);
552523dc 1047 return ret;
3703b2c5
NB
1048}
1049
1050static int tcm_loop_drop_nexus(
1051 struct tcm_loop_tpg *tpg)
1052{
1053 struct se_session *se_sess;
1054 struct tcm_loop_nexus *tl_nexus;
1055 struct tcm_loop_hba *tl_hba = tpg->tl_hba;
1056
1057 tl_nexus = tpg->tl_hba->tl_nexus;
1058 if (!tl_nexus)
1059 return -ENODEV;
1060
1061 se_sess = tl_nexus->se_sess;
1062 if (!se_sess)
1063 return -ENODEV;
1064
1065 if (atomic_read(&tpg->tl_tpg_port_count)) {
6708bb27 1066 pr_err("Unable to remove TCM_Loop I_T Nexus with"
3703b2c5
NB
1067 " active TPG port count: %d\n",
1068 atomic_read(&tpg->tl_tpg_port_count));
1069 return -EPERM;
1070 }
1071
6708bb27 1072 pr_debug("TCM_Loop_ConfigFS: Removing I_T Nexus to emulated"
3703b2c5
NB
1073 " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba),
1074 tl_nexus->se_sess->se_node_acl->initiatorname);
1075 /*
1076 * Release the SCSI I_T Nexus to the emulated SAS Target Port
1077 */
1078 transport_deregister_session(tl_nexus->se_sess);
1079 tpg->tl_hba->tl_nexus = NULL;
1080 kfree(tl_nexus);
1081 return 0;
1082}
1083
1084/* End items for tcm_loop_nexus_cit */
1085
1086static ssize_t tcm_loop_tpg_show_nexus(
1087 struct se_portal_group *se_tpg,
1088 char *page)
1089{
1090 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
1091 struct tcm_loop_tpg, tl_se_tpg);
1092 struct tcm_loop_nexus *tl_nexus;
1093 ssize_t ret;
1094
1095 tl_nexus = tl_tpg->tl_hba->tl_nexus;
1096 if (!tl_nexus)
1097 return -ENODEV;
1098
1099 ret = snprintf(page, PAGE_SIZE, "%s\n",
1100 tl_nexus->se_sess->se_node_acl->initiatorname);
1101
1102 return ret;
1103}
1104
1105static ssize_t tcm_loop_tpg_store_nexus(
1106 struct se_portal_group *se_tpg,
1107 const char *page,
1108 size_t count)
1109{
1110 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
1111 struct tcm_loop_tpg, tl_se_tpg);
1112 struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
1113 unsigned char i_port[TL_WWN_ADDR_LEN], *ptr, *port_ptr;
1114 int ret;
1115 /*
1116 * Shutdown the active I_T nexus if 'NULL' is passed..
1117 */
1118 if (!strncmp(page, "NULL", 4)) {
1119 ret = tcm_loop_drop_nexus(tl_tpg);
1120 return (!ret) ? count : ret;
1121 }
1122 /*
1123 * Otherwise make sure the passed virtual Initiator port WWN matches
1124 * the fabric protocol_id set in tcm_loop_make_scsi_hba(), and call
1125 * tcm_loop_make_nexus()
1126 */
60d645a4 1127 if (strlen(page) >= TL_WWN_ADDR_LEN) {
6708bb27 1128 pr_err("Emulated NAA Sas Address: %s, exceeds"
3703b2c5
NB
1129 " max: %d\n", page, TL_WWN_ADDR_LEN);
1130 return -EINVAL;
1131 }
1132 snprintf(&i_port[0], TL_WWN_ADDR_LEN, "%s", page);
1133
1134 ptr = strstr(i_port, "naa.");
1135 if (ptr) {
1136 if (tl_hba->tl_proto_id != SCSI_PROTOCOL_SAS) {
6708bb27 1137 pr_err("Passed SAS Initiator Port %s does not"
3703b2c5
NB
1138 " match target port protoid: %s\n", i_port,
1139 tcm_loop_dump_proto_id(tl_hba));
1140 return -EINVAL;
1141 }
1142 port_ptr = &i_port[0];
1143 goto check_newline;
1144 }
1145 ptr = strstr(i_port, "fc.");
1146 if (ptr) {
1147 if (tl_hba->tl_proto_id != SCSI_PROTOCOL_FCP) {
6708bb27 1148 pr_err("Passed FCP Initiator Port %s does not"
3703b2c5
NB
1149 " match target port protoid: %s\n", i_port,
1150 tcm_loop_dump_proto_id(tl_hba));
1151 return -EINVAL;
1152 }
1153 port_ptr = &i_port[3]; /* Skip over "fc." */
1154 goto check_newline;
1155 }
1156 ptr = strstr(i_port, "iqn.");
1157 if (ptr) {
1158 if (tl_hba->tl_proto_id != SCSI_PROTOCOL_ISCSI) {
6708bb27 1159 pr_err("Passed iSCSI Initiator Port %s does not"
3703b2c5
NB
1160 " match target port protoid: %s\n", i_port,
1161 tcm_loop_dump_proto_id(tl_hba));
1162 return -EINVAL;
1163 }
1164 port_ptr = &i_port[0];
1165 goto check_newline;
1166 }
6708bb27 1167 pr_err("Unable to locate prefix for emulated Initiator Port:"
3703b2c5
NB
1168 " %s\n", i_port);
1169 return -EINVAL;
1170 /*
1171 * Clear any trailing newline for the NAA WWN
1172 */
1173check_newline:
1174 if (i_port[strlen(i_port)-1] == '\n')
1175 i_port[strlen(i_port)-1] = '\0';
1176
1177 ret = tcm_loop_make_nexus(tl_tpg, port_ptr);
1178 if (ret < 0)
1179 return ret;
1180
1181 return count;
1182}
1183
1184TF_TPG_BASE_ATTR(tcm_loop, nexus, S_IRUGO | S_IWUSR);
1185
1186static struct configfs_attribute *tcm_loop_tpg_attrs[] = {
1187 &tcm_loop_tpg_nexus.attr,
1188 NULL,
1189};
1190
1191/* Start items for tcm_loop_naa_cit */
1192
1193struct se_portal_group *tcm_loop_make_naa_tpg(
1194 struct se_wwn *wwn,
1195 struct config_group *group,
1196 const char *name)
1197{
1198 struct tcm_loop_hba *tl_hba = container_of(wwn,
1199 struct tcm_loop_hba, tl_hba_wwn);
1200 struct tcm_loop_tpg *tl_tpg;
1201 char *tpgt_str, *end_ptr;
1202 int ret;
1203 unsigned short int tpgt;
1204
1205 tpgt_str = strstr(name, "tpgt_");
1206 if (!tpgt_str) {
6708bb27 1207 pr_err("Unable to locate \"tpgt_#\" directory"
3703b2c5
NB
1208 " group\n");
1209 return ERR_PTR(-EINVAL);
1210 }
1211 tpgt_str += 5; /* Skip ahead of "tpgt_" */
1212 tpgt = (unsigned short int) simple_strtoul(tpgt_str, &end_ptr, 0);
1213
12f09ccb 1214 if (tpgt >= TL_TPGS_PER_HBA) {
6708bb27 1215 pr_err("Passed tpgt: %hu exceeds TL_TPGS_PER_HBA:"
3703b2c5
NB
1216 " %u\n", tpgt, TL_TPGS_PER_HBA);
1217 return ERR_PTR(-EINVAL);
1218 }
1219 tl_tpg = &tl_hba->tl_hba_tpgs[tpgt];
1220 tl_tpg->tl_hba = tl_hba;
1221 tl_tpg->tl_tpgt = tpgt;
1222 /*
1223 * Register the tl_tpg as a emulated SAS TCM Target Endpoint
1224 */
1225 ret = core_tpg_register(&tcm_loop_fabric_configfs->tf_ops,
5951146d 1226 wwn, &tl_tpg->tl_se_tpg, tl_tpg,
3703b2c5
NB
1227 TRANSPORT_TPG_TYPE_NORMAL);
1228 if (ret < 0)
1229 return ERR_PTR(-ENOMEM);
1230
6708bb27 1231 pr_debug("TCM_Loop_ConfigFS: Allocated Emulated %s"
3703b2c5
NB
1232 " Target Port %s,t,0x%04x\n", tcm_loop_dump_proto_id(tl_hba),
1233 config_item_name(&wwn->wwn_group.cg_item), tpgt);
1234
1235 return &tl_tpg->tl_se_tpg;
1236}
1237
1238void tcm_loop_drop_naa_tpg(
1239 struct se_portal_group *se_tpg)
1240{
1241 struct se_wwn *wwn = se_tpg->se_tpg_wwn;
1242 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
1243 struct tcm_loop_tpg, tl_se_tpg);
1244 struct tcm_loop_hba *tl_hba;
1245 unsigned short tpgt;
1246
1247 tl_hba = tl_tpg->tl_hba;
1248 tpgt = tl_tpg->tl_tpgt;
1249 /*
1250 * Release the I_T Nexus for the Virtual SAS link if present
1251 */
1252 tcm_loop_drop_nexus(tl_tpg);
1253 /*
1254 * Deregister the tl_tpg as a emulated SAS TCM Target Endpoint
1255 */
1256 core_tpg_deregister(se_tpg);
1257
0a020436
NB
1258 tl_tpg->tl_hba = NULL;
1259 tl_tpg->tl_tpgt = 0;
1260
6708bb27 1261 pr_debug("TCM_Loop_ConfigFS: Deallocated Emulated %s"
3703b2c5
NB
1262 " Target Port %s,t,0x%04x\n", tcm_loop_dump_proto_id(tl_hba),
1263 config_item_name(&wwn->wwn_group.cg_item), tpgt);
1264}
1265
1266/* End items for tcm_loop_naa_cit */
1267
1268/* Start items for tcm_loop_cit */
1269
1270struct se_wwn *tcm_loop_make_scsi_hba(
1271 struct target_fabric_configfs *tf,
1272 struct config_group *group,
1273 const char *name)
1274{
1275 struct tcm_loop_hba *tl_hba;
1276 struct Scsi_Host *sh;
1277 char *ptr;
1278 int ret, off = 0;
1279
1280 tl_hba = kzalloc(sizeof(struct tcm_loop_hba), GFP_KERNEL);
1281 if (!tl_hba) {
6708bb27 1282 pr_err("Unable to allocate struct tcm_loop_hba\n");
3703b2c5
NB
1283 return ERR_PTR(-ENOMEM);
1284 }
1285 /*
1286 * Determine the emulated Protocol Identifier and Target Port Name
1287 * based on the incoming configfs directory name.
1288 */
1289 ptr = strstr(name, "naa.");
1290 if (ptr) {
1291 tl_hba->tl_proto_id = SCSI_PROTOCOL_SAS;
1292 goto check_len;
1293 }
1294 ptr = strstr(name, "fc.");
1295 if (ptr) {
1296 tl_hba->tl_proto_id = SCSI_PROTOCOL_FCP;
1297 off = 3; /* Skip over "fc." */
1298 goto check_len;
1299 }
1300 ptr = strstr(name, "iqn.");
a57b5d36 1301 if (!ptr) {
6708bb27 1302 pr_err("Unable to locate prefix for emulated Target "
a57b5d36
JJ
1303 "Port: %s\n", name);
1304 ret = -EINVAL;
1305 goto out;
3703b2c5 1306 }
a57b5d36 1307 tl_hba->tl_proto_id = SCSI_PROTOCOL_ISCSI;
3703b2c5
NB
1308
1309check_len:
60d645a4 1310 if (strlen(name) >= TL_WWN_ADDR_LEN) {
6708bb27 1311 pr_err("Emulated NAA %s Address: %s, exceeds"
3703b2c5
NB
1312 " max: %d\n", name, tcm_loop_dump_proto_id(tl_hba),
1313 TL_WWN_ADDR_LEN);
a57b5d36
JJ
1314 ret = -EINVAL;
1315 goto out;
3703b2c5
NB
1316 }
1317 snprintf(&tl_hba->tl_wwn_address[0], TL_WWN_ADDR_LEN, "%s", &name[off]);
1318
1319 /*
1320 * Call device_register(tl_hba->dev) to register the emulated
1321 * Linux/SCSI LLD of type struct Scsi_Host at tl_hba->sh after
1322 * device_register() callbacks in tcm_loop_driver_probe()
1323 */
1324 ret = tcm_loop_setup_hba_bus(tl_hba, tcm_loop_hba_no_cnt);
1325 if (ret)
1326 goto out;
1327
1328 sh = tl_hba->sh;
1329 tcm_loop_hba_no_cnt++;
6708bb27 1330 pr_debug("TCM_Loop_ConfigFS: Allocated emulated Target"
3703b2c5
NB
1331 " %s Address: %s at Linux/SCSI Host ID: %d\n",
1332 tcm_loop_dump_proto_id(tl_hba), name, sh->host_no);
1333
1334 return &tl_hba->tl_hba_wwn;
1335out:
1336 kfree(tl_hba);
1337 return ERR_PTR(ret);
1338}
1339
1340void tcm_loop_drop_scsi_hba(
1341 struct se_wwn *wwn)
1342{
1343 struct tcm_loop_hba *tl_hba = container_of(wwn,
1344 struct tcm_loop_hba, tl_hba_wwn);
1345 int host_no = tl_hba->sh->host_no;
1346 /*
1347 * Call device_unregister() on the original tl_hba->dev.
1348 * tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will
1349 * release *tl_hba;
1350 */
1351 device_unregister(&tl_hba->dev);
1352
6708bb27 1353 pr_debug("TCM_Loop_ConfigFS: Deallocated emulated Target"
3703b2c5
NB
1354 " SAS Address: %s at Linux/SCSI Host ID: %d\n",
1355 config_item_name(&wwn->wwn_group.cg_item), host_no);
1356}
1357
1358/* Start items for tcm_loop_cit */
1359static ssize_t tcm_loop_wwn_show_attr_version(
1360 struct target_fabric_configfs *tf,
1361 char *page)
1362{
1363 return sprintf(page, "TCM Loopback Fabric module %s\n", TCM_LOOP_VERSION);
1364}
1365
1366TF_WWN_ATTR_RO(tcm_loop, version);
1367
1368static struct configfs_attribute *tcm_loop_wwn_attrs[] = {
1369 &tcm_loop_wwn_version.attr,
1370 NULL,
1371};
1372
1373/* End items for tcm_loop_cit */
1374
1375static int tcm_loop_register_configfs(void)
1376{
1377 struct target_fabric_configfs *fabric;
1378 struct config_group *tf_cg;
1379 int ret;
1380 /*
1381 * Set the TCM Loop HBA counter to zero
1382 */
1383 tcm_loop_hba_no_cnt = 0;
1384 /*
1385 * Register the top level struct config_item_type with TCM core
1386 */
1387 fabric = target_fabric_configfs_init(THIS_MODULE, "loopback");
e3d6f909 1388 if (IS_ERR(fabric)) {
6708bb27 1389 pr_err("tcm_loop_register_configfs() failed!\n");
e3d6f909 1390 return PTR_ERR(fabric);
3703b2c5
NB
1391 }
1392 /*
1393 * Setup the fabric API of function pointers used by target_core_mod
1394 */
1395 fabric->tf_ops.get_fabric_name = &tcm_loop_get_fabric_name;
1396 fabric->tf_ops.get_fabric_proto_ident = &tcm_loop_get_fabric_proto_ident;
1397 fabric->tf_ops.tpg_get_wwn = &tcm_loop_get_endpoint_wwn;
1398 fabric->tf_ops.tpg_get_tag = &tcm_loop_get_tag;
1399 fabric->tf_ops.tpg_get_default_depth = &tcm_loop_get_default_depth;
1400 fabric->tf_ops.tpg_get_pr_transport_id = &tcm_loop_get_pr_transport_id;
1401 fabric->tf_ops.tpg_get_pr_transport_id_len =
1402 &tcm_loop_get_pr_transport_id_len;
1403 fabric->tf_ops.tpg_parse_pr_out_transport_id =
1404 &tcm_loop_parse_pr_out_transport_id;
1405 fabric->tf_ops.tpg_check_demo_mode = &tcm_loop_check_demo_mode;
1406 fabric->tf_ops.tpg_check_demo_mode_cache =
1407 &tcm_loop_check_demo_mode_cache;
1408 fabric->tf_ops.tpg_check_demo_mode_write_protect =
1409 &tcm_loop_check_demo_mode_write_protect;
1410 fabric->tf_ops.tpg_check_prod_mode_write_protect =
1411 &tcm_loop_check_prod_mode_write_protect;
1412 /*
1413 * The TCM loopback fabric module runs in demo-mode to a local
1414 * virtual SCSI device, so fabric dependent initator ACLs are
1415 * not required.
1416 */
1417 fabric->tf_ops.tpg_alloc_fabric_acl = &tcm_loop_tpg_alloc_fabric_acl;
1418 fabric->tf_ops.tpg_release_fabric_acl =
1419 &tcm_loop_tpg_release_fabric_acl;
1420 fabric->tf_ops.tpg_get_inst_index = &tcm_loop_get_inst_index;
3703b2c5
NB
1421 /*
1422 * Used for setting up remaining TCM resources in process context
1423 */
1424 fabric->tf_ops.new_cmd_map = &tcm_loop_new_cmd_map;
1425 fabric->tf_ops.check_stop_free = &tcm_loop_check_stop_free;
35462975 1426 fabric->tf_ops.release_cmd = &tcm_loop_release_cmd;
3703b2c5
NB
1427 fabric->tf_ops.shutdown_session = &tcm_loop_shutdown_session;
1428 fabric->tf_ops.close_session = &tcm_loop_close_session;
1429 fabric->tf_ops.stop_session = &tcm_loop_stop_session;
1430 fabric->tf_ops.fall_back_to_erl0 = &tcm_loop_fall_back_to_erl0;
1431 fabric->tf_ops.sess_logged_in = &tcm_loop_sess_logged_in;
1432 fabric->tf_ops.sess_get_index = &tcm_loop_sess_get_index;
1433 fabric->tf_ops.sess_get_initiator_sid = NULL;
1434 fabric->tf_ops.write_pending = &tcm_loop_write_pending;
1435 fabric->tf_ops.write_pending_status = &tcm_loop_write_pending_status;
1436 /*
1437 * Not used for TCM loopback
1438 */
1439 fabric->tf_ops.set_default_node_attributes =
1440 &tcm_loop_set_default_node_attributes;
1441 fabric->tf_ops.get_task_tag = &tcm_loop_get_task_tag;
1442 fabric->tf_ops.get_cmd_state = &tcm_loop_get_cmd_state;
3703b2c5
NB
1443 fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in;
1444 fabric->tf_ops.queue_status = &tcm_loop_queue_status;
1445 fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp;
1446 fabric->tf_ops.set_fabric_sense_len = &tcm_loop_set_fabric_sense_len;
1447 fabric->tf_ops.get_fabric_sense_len = &tcm_loop_get_fabric_sense_len;
1448 fabric->tf_ops.is_state_remove = &tcm_loop_is_state_remove;
3703b2c5
NB
1449
1450 tf_cg = &fabric->tf_group;
1451 /*
1452 * Setup function pointers for generic logic in target_core_fabric_configfs.c
1453 */
1454 fabric->tf_ops.fabric_make_wwn = &tcm_loop_make_scsi_hba;
1455 fabric->tf_ops.fabric_drop_wwn = &tcm_loop_drop_scsi_hba;
1456 fabric->tf_ops.fabric_make_tpg = &tcm_loop_make_naa_tpg;
1457 fabric->tf_ops.fabric_drop_tpg = &tcm_loop_drop_naa_tpg;
1458 /*
1459 * fabric_post_link() and fabric_pre_unlink() are used for
1460 * registration and release of TCM Loop Virtual SCSI LUNs.
1461 */
1462 fabric->tf_ops.fabric_post_link = &tcm_loop_port_link;
1463 fabric->tf_ops.fabric_pre_unlink = &tcm_loop_port_unlink;
1464 fabric->tf_ops.fabric_make_np = NULL;
1465 fabric->tf_ops.fabric_drop_np = NULL;
1466 /*
1467 * Setup default attribute lists for various fabric->tf_cit_tmpl
1468 */
1469 TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = tcm_loop_wwn_attrs;
1470 TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = tcm_loop_tpg_attrs;
1471 TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL;
1472 TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL;
1473 TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL;
1474 /*
1475 * Once fabric->tf_ops has been setup, now register the fabric for
1476 * use within TCM
1477 */
1478 ret = target_fabric_configfs_register(fabric);
1479 if (ret < 0) {
6708bb27 1480 pr_err("target_fabric_configfs_register() for"
3703b2c5
NB
1481 " TCM_Loop failed!\n");
1482 target_fabric_configfs_free(fabric);
1483 return -1;
1484 }
1485 /*
1486 * Setup our local pointer to *fabric.
1487 */
1488 tcm_loop_fabric_configfs = fabric;
6708bb27 1489 pr_debug("TCM_LOOP[0] - Set fabric ->"
3703b2c5
NB
1490 " tcm_loop_fabric_configfs\n");
1491 return 0;
1492}
1493
1494static void tcm_loop_deregister_configfs(void)
1495{
1496 if (!tcm_loop_fabric_configfs)
1497 return;
1498
1499 target_fabric_configfs_deregister(tcm_loop_fabric_configfs);
1500 tcm_loop_fabric_configfs = NULL;
6708bb27 1501 pr_debug("TCM_LOOP[0] - Cleared"
3703b2c5
NB
1502 " tcm_loop_fabric_configfs\n");
1503}
1504
1505static int __init tcm_loop_fabric_init(void)
1506{
1507 int ret;
1508
1509 tcm_loop_cmd_cache = kmem_cache_create("tcm_loop_cmd_cache",
1510 sizeof(struct tcm_loop_cmd),
1511 __alignof__(struct tcm_loop_cmd),
1512 0, NULL);
1513 if (!tcm_loop_cmd_cache) {
6708bb27 1514 pr_debug("kmem_cache_create() for"
3703b2c5
NB
1515 " tcm_loop_cmd_cache failed\n");
1516 return -ENOMEM;
1517 }
1518
1519 ret = tcm_loop_alloc_core_bus();
1520 if (ret)
1521 return ret;
1522
1523 ret = tcm_loop_register_configfs();
1524 if (ret) {
1525 tcm_loop_release_core_bus();
1526 return ret;
1527 }
1528
1529 return 0;
1530}
1531
1532static void __exit tcm_loop_fabric_exit(void)
1533{
1534 tcm_loop_deregister_configfs();
1535 tcm_loop_release_core_bus();
1536 kmem_cache_destroy(tcm_loop_cmd_cache);
1537}
1538
1539MODULE_DESCRIPTION("TCM loopback virtual Linux/SCSI fabric module");
1540MODULE_AUTHOR("Nicholas A. Bellinger <nab@risingtidesystems.com>");
1541MODULE_LICENSE("GPL");
1542module_init(tcm_loop_fabric_init);
1543module_exit(tcm_loop_fabric_exit);
This page took 0.202845 seconds and 5 git commands to generate.