~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/target/loopback/tcm_loop.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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/scsi_tcq.h>
 
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 */
 
51
static struct target_fabric_configfs *tcm_loop_fabric_configfs;
 
52
 
 
53
static struct kmem_cache *tcm_loop_cmd_cache;
 
54
 
 
55
static 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
 */
 
62
static 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 = MSG_HEAD_TAG;
 
99
                        break;
 
100
                case ORDERED_QUEUE_TAG:
 
101
                        sam_task_attr = MSG_ORDERED_TAG;
 
102
                        break;
 
103
                default:
 
104
                        sam_task_attr = MSG_SIMPLE_TAG;
 
105
                        break;
 
106
                }
 
107
        } else
 
108
                sam_task_attr = MSG_SIMPLE_TAG;
 
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
 */
 
141
static 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
 */
 
206
static 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
 */
 
225
static 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
 
 
233
static 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
 
 
240
static int tcm_loop_driver_probe(struct device *);
 
241
static int tcm_loop_driver_remove(struct device *);
 
242
 
 
243
static int pseudo_lld_bus_match(struct device *dev,
 
244
                                struct device_driver *dev_driver)
 
245
{
 
246
        return 1;
 
247
}
 
248
 
 
249
static 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
 
 
256
static 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
 */
 
263
struct 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
 */
 
269
static 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
 */
 
294
static 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
 */
 
333
static 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, MSG_SIMPLE_TAG,
 
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 (IS_ERR(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;
 
408
release:
 
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
 
 
417
static 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
 
 
423
static int tcm_loop_slave_configure(struct scsi_device *sd)
 
424
{
 
425
        return 0;
 
426
}
 
427
 
 
428
static 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
 
 
446
static 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
 
 
483
static 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
 
 
496
static 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
 */
 
506
static 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
 */
 
529
static 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
 
 
555
bus_unreg:
 
556
        bus_unregister(&tcm_loop_lld_bus);
 
557
dev_unreg:
 
558
        root_device_unregister(tcm_loop_primary);
 
559
        return ret;
 
560
}
 
561
 
 
562
static 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
 
 
571
static char *tcm_loop_get_fabric_name(void)
 
572
{
 
573
        return "loopback";
 
574
}
 
575
 
 
576
static 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
 
 
604
static 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
 
 
614
static 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
 
 
625
static u32 tcm_loop_get_default_depth(struct se_portal_group *se_tpg)
 
626
{
 
627
        return 1;
 
628
}
 
629
 
 
630
static 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
 
 
661
static 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
 */
 
695
static 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
 */
 
729
static int tcm_loop_check_demo_mode(struct se_portal_group *se_tpg)
 
730
{
 
731
        return 1;
 
732
}
 
733
 
 
734
static 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
 */
 
743
static 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
 */
 
753
static int tcm_loop_check_prod_mode_write_protect(struct se_portal_group *se_tpg)
 
754
{
 
755
        return 0;
 
756
}
 
757
 
 
758
static 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
 
 
772
static 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
 
 
782
static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg)
 
783
{
 
784
        return 1;
 
785
}
 
786
 
 
787
static 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
 
 
797
static 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
 
 
805
static 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
 
 
813
static u32 tcm_loop_sess_get_index(struct se_session *se_sess)
 
814
{
 
815
        return 1;
 
816
}
 
817
 
 
818
static void tcm_loop_set_default_node_attributes(struct se_node_acl *se_acl)
 
819
{
 
820
        return;
 
821
}
 
822
 
 
823
static u32 tcm_loop_get_task_tag(struct se_cmd *se_cmd)
 
824
{
 
825
        return 1;
 
826
}
 
827
 
 
828
static 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
 
 
836
static int tcm_loop_shutdown_session(struct se_session *se_sess)
 
837
{
 
838
        return 0;
 
839
}
 
840
 
 
841
static void tcm_loop_close_session(struct se_session *se_sess)
 
842
{
 
843
        return;
 
844
};
 
845
 
 
846
static void tcm_loop_stop_session(
 
847
        struct se_session *se_sess,
 
848
        int sess_sleep,
 
849
        int conn_sleep)
 
850
{
 
851
        return;
 
852
}
 
853
 
 
854
static void tcm_loop_fall_back_to_erl0(struct se_session *se_sess)
 
855
{
 
856
        return;
 
857
}
 
858
 
 
859
static 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
 
 
874
static int tcm_loop_write_pending_status(struct se_cmd *se_cmd)
 
875
{
 
876
        return 0;
 
877
}
 
878
 
 
879
static 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
 
 
894
static 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
 
 
919
static 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
 
 
932
static u16 tcm_loop_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
 
933
{
 
934
        return 0;
 
935
}
 
936
 
 
937
static u16 tcm_loop_get_fabric_sense_len(void)
 
938
{
 
939
        return 0;
 
940
}
 
941
 
 
942
static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba)
 
943
{
 
944
        switch (tl_hba->tl_proto_id) {
 
945
        case SCSI_PROTOCOL_SAS:
 
946
                return "SAS";
 
947
        case SCSI_PROTOCOL_FCP:
 
948
                return "FCP";
 
949
        case SCSI_PROTOCOL_ISCSI:
 
950
                return "iSCSI";
 
951
        default:
 
952
                break;
 
953
        }
 
954
 
 
955
        return "Unknown";
 
956
}
 
957
 
 
958
/* Start items for tcm_loop_port_cit */
 
959
 
 
960
static int tcm_loop_port_link(
 
961
        struct se_portal_group *se_tpg,
 
962
        struct se_lun *lun)
 
963
{
 
964
        struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
 
965
                                struct tcm_loop_tpg, tl_se_tpg);
 
966
        struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
 
967
 
 
968
        atomic_inc(&tl_tpg->tl_tpg_port_count);
 
969
        smp_mb__after_atomic_inc();
 
970
        /*
 
971
         * Add Linux/SCSI struct scsi_device by HCTL
 
972
         */
 
973
        scsi_add_device(tl_hba->sh, 0, tl_tpg->tl_tpgt, lun->unpacked_lun);
 
974
 
 
975
        printk(KERN_INFO "TCM_Loop_ConfigFS: Port Link Successful\n");
 
976
        return 0;
 
977
}
 
978
 
 
979
static void tcm_loop_port_unlink(
 
980
        struct se_portal_group *se_tpg,
 
981
        struct se_lun *se_lun)
 
982
{
 
983
        struct scsi_device *sd;
 
984
        struct tcm_loop_hba *tl_hba;
 
985
        struct tcm_loop_tpg *tl_tpg;
 
986
 
 
987
        tl_tpg = container_of(se_tpg, struct tcm_loop_tpg, tl_se_tpg);
 
988
        tl_hba = tl_tpg->tl_hba;
 
989
 
 
990
        sd = scsi_device_lookup(tl_hba->sh, 0, tl_tpg->tl_tpgt,
 
991
                                se_lun->unpacked_lun);
 
992
        if (!sd) {
 
993
                printk(KERN_ERR "Unable to locate struct scsi_device for %d:%d:"
 
994
                        "%d\n", 0, tl_tpg->tl_tpgt, se_lun->unpacked_lun);
 
995
                return;
 
996
        }
 
997
        /*
 
998
         * Remove Linux/SCSI struct scsi_device by HCTL
 
999
         */
 
1000
        scsi_remove_device(sd);
 
1001
        scsi_device_put(sd);
 
1002
 
 
1003
        atomic_dec(&tl_tpg->tl_tpg_port_count);
 
1004
        smp_mb__after_atomic_dec();
 
1005
 
 
1006
        printk(KERN_INFO "TCM_Loop_ConfigFS: Port Unlink Successful\n");
 
1007
}
 
1008
 
 
1009
/* End items for tcm_loop_port_cit */
 
1010
 
 
1011
/* Start items for tcm_loop_nexus_cit */
 
1012
 
 
1013
static int tcm_loop_make_nexus(
 
1014
        struct tcm_loop_tpg *tl_tpg,
 
1015
        const char *name)
 
1016
{
 
1017
        struct se_portal_group *se_tpg;
 
1018
        struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
 
1019
        struct tcm_loop_nexus *tl_nexus;
 
1020
        int ret = -ENOMEM;
 
1021
 
 
1022
        if (tl_tpg->tl_hba->tl_nexus) {
 
1023
                printk(KERN_INFO "tl_tpg->tl_hba->tl_nexus already exists\n");
 
1024
                return -EEXIST;
 
1025
        }
 
1026
        se_tpg = &tl_tpg->tl_se_tpg;
 
1027
 
 
1028
        tl_nexus = kzalloc(sizeof(struct tcm_loop_nexus), GFP_KERNEL);
 
1029
        if (!tl_nexus) {
 
1030
                printk(KERN_ERR "Unable to allocate struct tcm_loop_nexus\n");
 
1031
                return -ENOMEM;
 
1032
        }
 
1033
        /*
 
1034
         * Initialize the struct se_session pointer
 
1035
         */
 
1036
        tl_nexus->se_sess = transport_init_session();
 
1037
        if (IS_ERR(tl_nexus->se_sess)) {
 
1038
                ret = PTR_ERR(tl_nexus->se_sess);
 
1039
                goto out;
 
1040
        }
 
1041
        /*
 
1042
         * Since we are running in 'demo mode' this call with generate a
 
1043
         * struct se_node_acl for the tcm_loop struct se_portal_group with the SCSI
 
1044
         * Initiator port name of the passed configfs group 'name'.
 
1045
         */
 
1046
        tl_nexus->se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
 
1047
                                se_tpg, (unsigned char *)name);
 
1048
        if (!tl_nexus->se_sess->se_node_acl) {
 
1049
                transport_free_session(tl_nexus->se_sess);
 
1050
                goto out;
 
1051
        }
 
1052
        /*
 
1053
         * Now, register the SAS I_T Nexus as active with the call to
 
1054
         * transport_register_session()
 
1055
         */
 
1056
        __transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl,
 
1057
                        tl_nexus->se_sess, (void *)tl_nexus);
 
1058
        tl_tpg->tl_hba->tl_nexus = tl_nexus;
 
1059
        printk(KERN_INFO "TCM_Loop_ConfigFS: Established I_T Nexus to emulated"
 
1060
                " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba),
 
1061
                name);
 
1062
        return 0;
 
1063
 
 
1064
out:
 
1065
        kfree(tl_nexus);
 
1066
        return ret;
 
1067
}
 
1068
 
 
1069
static int tcm_loop_drop_nexus(
 
1070
        struct tcm_loop_tpg *tpg)
 
1071
{
 
1072
        struct se_session *se_sess;
 
1073
        struct tcm_loop_nexus *tl_nexus;
 
1074
        struct tcm_loop_hba *tl_hba = tpg->tl_hba;
 
1075
 
 
1076
        tl_nexus = tpg->tl_hba->tl_nexus;
 
1077
        if (!tl_nexus)
 
1078
                return -ENODEV;
 
1079
 
 
1080
        se_sess = tl_nexus->se_sess;
 
1081
        if (!se_sess)
 
1082
                return -ENODEV;
 
1083
 
 
1084
        if (atomic_read(&tpg->tl_tpg_port_count)) {
 
1085
                printk(KERN_ERR "Unable to remove TCM_Loop I_T Nexus with"
 
1086
                        " active TPG port count: %d\n",
 
1087
                        atomic_read(&tpg->tl_tpg_port_count));
 
1088
                return -EPERM;
 
1089
        }
 
1090
 
 
1091
        printk(KERN_INFO "TCM_Loop_ConfigFS: Removing I_T Nexus to emulated"
 
1092
                " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba),
 
1093
                tl_nexus->se_sess->se_node_acl->initiatorname);
 
1094
        /*
 
1095
         * Release the SCSI I_T Nexus to the emulated SAS Target Port
 
1096
         */
 
1097
        transport_deregister_session(tl_nexus->se_sess);
 
1098
        tpg->tl_hba->tl_nexus = NULL;
 
1099
        kfree(tl_nexus);
 
1100
        return 0;
 
1101
}
 
1102
 
 
1103
/* End items for tcm_loop_nexus_cit */
 
1104
 
 
1105
static ssize_t tcm_loop_tpg_show_nexus(
 
1106
        struct se_portal_group *se_tpg,
 
1107
        char *page)
 
1108
{
 
1109
        struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
 
1110
                        struct tcm_loop_tpg, tl_se_tpg);
 
1111
        struct tcm_loop_nexus *tl_nexus;
 
1112
        ssize_t ret;
 
1113
 
 
1114
        tl_nexus = tl_tpg->tl_hba->tl_nexus;
 
1115
        if (!tl_nexus)
 
1116
                return -ENODEV;
 
1117
 
 
1118
        ret = snprintf(page, PAGE_SIZE, "%s\n",
 
1119
                tl_nexus->se_sess->se_node_acl->initiatorname);
 
1120
 
 
1121
        return ret;
 
1122
}
 
1123
 
 
1124
static ssize_t tcm_loop_tpg_store_nexus(
 
1125
        struct se_portal_group *se_tpg,
 
1126
        const char *page,
 
1127
        size_t count)
 
1128
{
 
1129
        struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
 
1130
                        struct tcm_loop_tpg, tl_se_tpg);
 
1131
        struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
 
1132
        unsigned char i_port[TL_WWN_ADDR_LEN], *ptr, *port_ptr;
 
1133
        int ret;
 
1134
        /*
 
1135
         * Shutdown the active I_T nexus if 'NULL' is passed..
 
1136
         */
 
1137
        if (!strncmp(page, "NULL", 4)) {
 
1138
                ret = tcm_loop_drop_nexus(tl_tpg);
 
1139
                return (!ret) ? count : ret;
 
1140
        }
 
1141
        /*
 
1142
         * Otherwise make sure the passed virtual Initiator port WWN matches
 
1143
         * the fabric protocol_id set in tcm_loop_make_scsi_hba(), and call
 
1144
         * tcm_loop_make_nexus()
 
1145
         */
 
1146
        if (strlen(page) >= TL_WWN_ADDR_LEN) {
 
1147
                printk(KERN_ERR "Emulated NAA Sas Address: %s, exceeds"
 
1148
                                " max: %d\n", page, TL_WWN_ADDR_LEN);
 
1149
                return -EINVAL;
 
1150
        }
 
1151
        snprintf(&i_port[0], TL_WWN_ADDR_LEN, "%s", page);
 
1152
 
 
1153
        ptr = strstr(i_port, "naa.");
 
1154
        if (ptr) {
 
1155
                if (tl_hba->tl_proto_id != SCSI_PROTOCOL_SAS) {
 
1156
                        printk(KERN_ERR "Passed SAS Initiator Port %s does not"
 
1157
                                " match target port protoid: %s\n", i_port,
 
1158
                                tcm_loop_dump_proto_id(tl_hba));
 
1159
                        return -EINVAL;
 
1160
                }
 
1161
                port_ptr = &i_port[0];
 
1162
                goto check_newline;
 
1163
        }
 
1164
        ptr = strstr(i_port, "fc.");
 
1165
        if (ptr) {
 
1166
                if (tl_hba->tl_proto_id != SCSI_PROTOCOL_FCP) {
 
1167
                        printk(KERN_ERR "Passed FCP Initiator Port %s does not"
 
1168
                                " match target port protoid: %s\n", i_port,
 
1169
                                tcm_loop_dump_proto_id(tl_hba));
 
1170
                        return -EINVAL;
 
1171
                }
 
1172
                port_ptr = &i_port[3]; /* Skip over "fc." */
 
1173
                goto check_newline;
 
1174
        }
 
1175
        ptr = strstr(i_port, "iqn.");
 
1176
        if (ptr) {
 
1177
                if (tl_hba->tl_proto_id != SCSI_PROTOCOL_ISCSI) {
 
1178
                        printk(KERN_ERR "Passed iSCSI Initiator Port %s does not"
 
1179
                                " match target port protoid: %s\n", i_port,
 
1180
                                tcm_loop_dump_proto_id(tl_hba));
 
1181
                        return -EINVAL;
 
1182
                }
 
1183
                port_ptr = &i_port[0];
 
1184
                goto check_newline;
 
1185
        }
 
1186
        printk(KERN_ERR "Unable to locate prefix for emulated Initiator Port:"
 
1187
                        " %s\n", i_port);
 
1188
        return -EINVAL;
 
1189
        /*
 
1190
         * Clear any trailing newline for the NAA WWN
 
1191
         */
 
1192
check_newline:
 
1193
        if (i_port[strlen(i_port)-1] == '\n')
 
1194
                i_port[strlen(i_port)-1] = '\0';
 
1195
 
 
1196
        ret = tcm_loop_make_nexus(tl_tpg, port_ptr);
 
1197
        if (ret < 0)
 
1198
                return ret;
 
1199
 
 
1200
        return count;
 
1201
}
 
1202
 
 
1203
TF_TPG_BASE_ATTR(tcm_loop, nexus, S_IRUGO | S_IWUSR);
 
1204
 
 
1205
static struct configfs_attribute *tcm_loop_tpg_attrs[] = {
 
1206
        &tcm_loop_tpg_nexus.attr,
 
1207
        NULL,
 
1208
};
 
1209
 
 
1210
/* Start items for tcm_loop_naa_cit */
 
1211
 
 
1212
struct se_portal_group *tcm_loop_make_naa_tpg(
 
1213
        struct se_wwn *wwn,
 
1214
        struct config_group *group,
 
1215
        const char *name)
 
1216
{
 
1217
        struct tcm_loop_hba *tl_hba = container_of(wwn,
 
1218
                        struct tcm_loop_hba, tl_hba_wwn);
 
1219
        struct tcm_loop_tpg *tl_tpg;
 
1220
        char *tpgt_str, *end_ptr;
 
1221
        int ret;
 
1222
        unsigned short int tpgt;
 
1223
 
 
1224
        tpgt_str = strstr(name, "tpgt_");
 
1225
        if (!tpgt_str) {
 
1226
                printk(KERN_ERR "Unable to locate \"tpgt_#\" directory"
 
1227
                                " group\n");
 
1228
                return ERR_PTR(-EINVAL);
 
1229
        }
 
1230
        tpgt_str += 5; /* Skip ahead of "tpgt_" */
 
1231
        tpgt = (unsigned short int) simple_strtoul(tpgt_str, &end_ptr, 0);
 
1232
 
 
1233
        if (tpgt > TL_TPGS_PER_HBA) {
 
1234
                printk(KERN_ERR "Passed tpgt: %hu exceeds TL_TPGS_PER_HBA:"
 
1235
                                " %u\n", tpgt, TL_TPGS_PER_HBA);
 
1236
                return ERR_PTR(-EINVAL);
 
1237
        }
 
1238
        tl_tpg = &tl_hba->tl_hba_tpgs[tpgt];
 
1239
        tl_tpg->tl_hba = tl_hba;
 
1240
        tl_tpg->tl_tpgt = tpgt;
 
1241
        /*
 
1242
         * Register the tl_tpg as a emulated SAS TCM Target Endpoint
 
1243
         */
 
1244
        ret = core_tpg_register(&tcm_loop_fabric_configfs->tf_ops,
 
1245
                        wwn, &tl_tpg->tl_se_tpg, (void *)tl_tpg,
 
1246
                        TRANSPORT_TPG_TYPE_NORMAL);
 
1247
        if (ret < 0)
 
1248
                return ERR_PTR(-ENOMEM);
 
1249
 
 
1250
        printk(KERN_INFO "TCM_Loop_ConfigFS: Allocated Emulated %s"
 
1251
                " Target Port %s,t,0x%04x\n", tcm_loop_dump_proto_id(tl_hba),
 
1252
                config_item_name(&wwn->wwn_group.cg_item), tpgt);
 
1253
 
 
1254
        return &tl_tpg->tl_se_tpg;
 
1255
}
 
1256
 
 
1257
void tcm_loop_drop_naa_tpg(
 
1258
        struct se_portal_group *se_tpg)
 
1259
{
 
1260
        struct se_wwn *wwn = se_tpg->se_tpg_wwn;
 
1261
        struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
 
1262
                                struct tcm_loop_tpg, tl_se_tpg);
 
1263
        struct tcm_loop_hba *tl_hba;
 
1264
        unsigned short tpgt;
 
1265
 
 
1266
        tl_hba = tl_tpg->tl_hba;
 
1267
        tpgt = tl_tpg->tl_tpgt;
 
1268
        /*
 
1269
         * Release the I_T Nexus for the Virtual SAS link if present
 
1270
         */
 
1271
        tcm_loop_drop_nexus(tl_tpg);
 
1272
        /*
 
1273
         * Deregister the tl_tpg as a emulated SAS TCM Target Endpoint
 
1274
         */
 
1275
        core_tpg_deregister(se_tpg);
 
1276
 
 
1277
        printk(KERN_INFO "TCM_Loop_ConfigFS: Deallocated Emulated %s"
 
1278
                " Target Port %s,t,0x%04x\n", tcm_loop_dump_proto_id(tl_hba),
 
1279
                config_item_name(&wwn->wwn_group.cg_item), tpgt);
 
1280
}
 
1281
 
 
1282
/* End items for tcm_loop_naa_cit */
 
1283
 
 
1284
/* Start items for tcm_loop_cit */
 
1285
 
 
1286
struct se_wwn *tcm_loop_make_scsi_hba(
 
1287
        struct target_fabric_configfs *tf,
 
1288
        struct config_group *group,
 
1289
        const char *name)
 
1290
{
 
1291
        struct tcm_loop_hba *tl_hba;
 
1292
        struct Scsi_Host *sh;
 
1293
        char *ptr;
 
1294
        int ret, off = 0;
 
1295
 
 
1296
        tl_hba = kzalloc(sizeof(struct tcm_loop_hba), GFP_KERNEL);
 
1297
        if (!tl_hba) {
 
1298
                printk(KERN_ERR "Unable to allocate struct tcm_loop_hba\n");
 
1299
                return ERR_PTR(-ENOMEM);
 
1300
        }
 
1301
        /*
 
1302
         * Determine the emulated Protocol Identifier and Target Port Name
 
1303
         * based on the incoming configfs directory name.
 
1304
         */
 
1305
        ptr = strstr(name, "naa.");
 
1306
        if (ptr) {
 
1307
                tl_hba->tl_proto_id = SCSI_PROTOCOL_SAS;
 
1308
                goto check_len;
 
1309
        }
 
1310
        ptr = strstr(name, "fc.");
 
1311
        if (ptr) {
 
1312
                tl_hba->tl_proto_id = SCSI_PROTOCOL_FCP;
 
1313
                off = 3; /* Skip over "fc." */
 
1314
                goto check_len;
 
1315
        }
 
1316
        ptr = strstr(name, "iqn.");
 
1317
        if (ptr) {
 
1318
                tl_hba->tl_proto_id = SCSI_PROTOCOL_ISCSI;
 
1319
                goto check_len;
 
1320
        }
 
1321
 
 
1322
        printk(KERN_ERR "Unable to locate prefix for emulated Target Port:"
 
1323
                        " %s\n", name);
 
1324
        return ERR_PTR(-EINVAL);
 
1325
 
 
1326
check_len:
 
1327
        if (strlen(name) >= TL_WWN_ADDR_LEN) {
 
1328
                printk(KERN_ERR "Emulated NAA %s Address: %s, exceeds"
 
1329
                        " max: %d\n", name, tcm_loop_dump_proto_id(tl_hba),
 
1330
                        TL_WWN_ADDR_LEN);
 
1331
                kfree(tl_hba);
 
1332
                return ERR_PTR(-EINVAL);
 
1333
        }
 
1334
        snprintf(&tl_hba->tl_wwn_address[0], TL_WWN_ADDR_LEN, "%s", &name[off]);
 
1335
 
 
1336
        /*
 
1337
         * Call device_register(tl_hba->dev) to register the emulated
 
1338
         * Linux/SCSI LLD of type struct Scsi_Host at tl_hba->sh after
 
1339
         * device_register() callbacks in tcm_loop_driver_probe()
 
1340
         */
 
1341
        ret = tcm_loop_setup_hba_bus(tl_hba, tcm_loop_hba_no_cnt);
 
1342
        if (ret)
 
1343
                goto out;
 
1344
 
 
1345
        sh = tl_hba->sh;
 
1346
        tcm_loop_hba_no_cnt++;
 
1347
        printk(KERN_INFO "TCM_Loop_ConfigFS: Allocated emulated Target"
 
1348
                " %s Address: %s at Linux/SCSI Host ID: %d\n",
 
1349
                tcm_loop_dump_proto_id(tl_hba), name, sh->host_no);
 
1350
 
 
1351
        return &tl_hba->tl_hba_wwn;
 
1352
out:
 
1353
        kfree(tl_hba);
 
1354
        return ERR_PTR(ret);
 
1355
}
 
1356
 
 
1357
void tcm_loop_drop_scsi_hba(
 
1358
        struct se_wwn *wwn)
 
1359
{
 
1360
        struct tcm_loop_hba *tl_hba = container_of(wwn,
 
1361
                                struct tcm_loop_hba, tl_hba_wwn);
 
1362
        int host_no = tl_hba->sh->host_no;
 
1363
        /*
 
1364
         * Call device_unregister() on the original tl_hba->dev.
 
1365
         * tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will
 
1366
         * release *tl_hba;
 
1367
         */
 
1368
        device_unregister(&tl_hba->dev);
 
1369
 
 
1370
        printk(KERN_INFO "TCM_Loop_ConfigFS: Deallocated emulated Target"
 
1371
                " SAS Address: %s at Linux/SCSI Host ID: %d\n",
 
1372
                config_item_name(&wwn->wwn_group.cg_item), host_no);
 
1373
}
 
1374
 
 
1375
/* Start items for tcm_loop_cit */
 
1376
static ssize_t tcm_loop_wwn_show_attr_version(
 
1377
        struct target_fabric_configfs *tf,
 
1378
        char *page)
 
1379
{
 
1380
        return sprintf(page, "TCM Loopback Fabric module %s\n", TCM_LOOP_VERSION);
 
1381
}
 
1382
 
 
1383
TF_WWN_ATTR_RO(tcm_loop, version);
 
1384
 
 
1385
static struct configfs_attribute *tcm_loop_wwn_attrs[] = {
 
1386
        &tcm_loop_wwn_version.attr,
 
1387
        NULL,
 
1388
};
 
1389
 
 
1390
/* End items for tcm_loop_cit */
 
1391
 
 
1392
static int tcm_loop_register_configfs(void)
 
1393
{
 
1394
        struct target_fabric_configfs *fabric;
 
1395
        struct config_group *tf_cg;
 
1396
        int ret;
 
1397
        /*
 
1398
         * Set the TCM Loop HBA counter to zero
 
1399
         */
 
1400
        tcm_loop_hba_no_cnt = 0;
 
1401
        /*
 
1402
         * Register the top level struct config_item_type with TCM core
 
1403
         */
 
1404
        fabric = target_fabric_configfs_init(THIS_MODULE, "loopback");
 
1405
        if (!fabric) {
 
1406
                printk(KERN_ERR "tcm_loop_register_configfs() failed!\n");
 
1407
                return -1;
 
1408
        }
 
1409
        /*
 
1410
         * Setup the fabric API of function pointers used by target_core_mod
 
1411
         */
 
1412
        fabric->tf_ops.get_fabric_name = &tcm_loop_get_fabric_name;
 
1413
        fabric->tf_ops.get_fabric_proto_ident = &tcm_loop_get_fabric_proto_ident;
 
1414
        fabric->tf_ops.tpg_get_wwn = &tcm_loop_get_endpoint_wwn;
 
1415
        fabric->tf_ops.tpg_get_tag = &tcm_loop_get_tag;
 
1416
        fabric->tf_ops.tpg_get_default_depth = &tcm_loop_get_default_depth;
 
1417
        fabric->tf_ops.tpg_get_pr_transport_id = &tcm_loop_get_pr_transport_id;
 
1418
        fabric->tf_ops.tpg_get_pr_transport_id_len =
 
1419
                                        &tcm_loop_get_pr_transport_id_len;
 
1420
        fabric->tf_ops.tpg_parse_pr_out_transport_id =
 
1421
                                        &tcm_loop_parse_pr_out_transport_id;
 
1422
        fabric->tf_ops.tpg_check_demo_mode = &tcm_loop_check_demo_mode;
 
1423
        fabric->tf_ops.tpg_check_demo_mode_cache =
 
1424
                                        &tcm_loop_check_demo_mode_cache;
 
1425
        fabric->tf_ops.tpg_check_demo_mode_write_protect =
 
1426
                                        &tcm_loop_check_demo_mode_write_protect;
 
1427
        fabric->tf_ops.tpg_check_prod_mode_write_protect =
 
1428
                                        &tcm_loop_check_prod_mode_write_protect;
 
1429
        /*
 
1430
         * The TCM loopback fabric module runs in demo-mode to a local
 
1431
         * virtual SCSI device, so fabric dependent initator ACLs are
 
1432
         * not required.
 
1433
         */
 
1434
        fabric->tf_ops.tpg_alloc_fabric_acl = &tcm_loop_tpg_alloc_fabric_acl;
 
1435
        fabric->tf_ops.tpg_release_fabric_acl =
 
1436
                                        &tcm_loop_tpg_release_fabric_acl;
 
1437
        fabric->tf_ops.tpg_get_inst_index = &tcm_loop_get_inst_index;
 
1438
        /*
 
1439
         * Since tcm_loop is mapping physical memory from Linux/SCSI
 
1440
         * struct scatterlist arrays for each struct scsi_cmnd I/O,
 
1441
         * we do not need TCM to allocate a iovec array for
 
1442
         * virtual memory address mappings
 
1443
         */
 
1444
        fabric->tf_ops.alloc_cmd_iovecs = NULL;
 
1445
        /*
 
1446
         * Used for setting up remaining TCM resources in process context
 
1447
         */
 
1448
        fabric->tf_ops.new_cmd_map = &tcm_loop_new_cmd_map;
 
1449
        fabric->tf_ops.check_stop_free = &tcm_loop_check_stop_free;
 
1450
        fabric->tf_ops.release_cmd_to_pool = &tcm_loop_deallocate_core_cmd;
 
1451
        fabric->tf_ops.release_cmd_direct = &tcm_loop_deallocate_core_cmd;
 
1452
        fabric->tf_ops.shutdown_session = &tcm_loop_shutdown_session;
 
1453
        fabric->tf_ops.close_session = &tcm_loop_close_session;
 
1454
        fabric->tf_ops.stop_session = &tcm_loop_stop_session;
 
1455
        fabric->tf_ops.fall_back_to_erl0 = &tcm_loop_fall_back_to_erl0;
 
1456
        fabric->tf_ops.sess_logged_in = &tcm_loop_sess_logged_in;
 
1457
        fabric->tf_ops.sess_get_index = &tcm_loop_sess_get_index;
 
1458
        fabric->tf_ops.sess_get_initiator_sid = NULL;
 
1459
        fabric->tf_ops.write_pending = &tcm_loop_write_pending;
 
1460
        fabric->tf_ops.write_pending_status = &tcm_loop_write_pending_status;
 
1461
        /*
 
1462
         * Not used for TCM loopback
 
1463
         */
 
1464
        fabric->tf_ops.set_default_node_attributes =
 
1465
                                        &tcm_loop_set_default_node_attributes;
 
1466
        fabric->tf_ops.get_task_tag = &tcm_loop_get_task_tag;
 
1467
        fabric->tf_ops.get_cmd_state = &tcm_loop_get_cmd_state;
 
1468
        fabric->tf_ops.new_cmd_failure = &tcm_loop_new_cmd_failure;
 
1469
        fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in;
 
1470
        fabric->tf_ops.queue_status = &tcm_loop_queue_status;
 
1471
        fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp;
 
1472
        fabric->tf_ops.set_fabric_sense_len = &tcm_loop_set_fabric_sense_len;
 
1473
        fabric->tf_ops.get_fabric_sense_len = &tcm_loop_get_fabric_sense_len;
 
1474
        fabric->tf_ops.is_state_remove = &tcm_loop_is_state_remove;
 
1475
 
 
1476
        tf_cg = &fabric->tf_group;
 
1477
        /*
 
1478
         * Setup function pointers for generic logic in target_core_fabric_configfs.c
 
1479
         */
 
1480
        fabric->tf_ops.fabric_make_wwn = &tcm_loop_make_scsi_hba;
 
1481
        fabric->tf_ops.fabric_drop_wwn = &tcm_loop_drop_scsi_hba;
 
1482
        fabric->tf_ops.fabric_make_tpg = &tcm_loop_make_naa_tpg;
 
1483
        fabric->tf_ops.fabric_drop_tpg = &tcm_loop_drop_naa_tpg;
 
1484
        /*
 
1485
         * fabric_post_link() and fabric_pre_unlink() are used for
 
1486
         * registration and release of TCM Loop Virtual SCSI LUNs.
 
1487
         */
 
1488
        fabric->tf_ops.fabric_post_link = &tcm_loop_port_link;
 
1489
        fabric->tf_ops.fabric_pre_unlink = &tcm_loop_port_unlink;
 
1490
        fabric->tf_ops.fabric_make_np = NULL;
 
1491
        fabric->tf_ops.fabric_drop_np = NULL;
 
1492
        /*
 
1493
         * Setup default attribute lists for various fabric->tf_cit_tmpl
 
1494
         */
 
1495
        TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = tcm_loop_wwn_attrs;
 
1496
        TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = tcm_loop_tpg_attrs;
 
1497
        TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL;
 
1498
        TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL;
 
1499
        TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL;
 
1500
        /*
 
1501
         * Once fabric->tf_ops has been setup, now register the fabric for
 
1502
         * use within TCM
 
1503
         */
 
1504
        ret = target_fabric_configfs_register(fabric);
 
1505
        if (ret < 0) {
 
1506
                printk(KERN_ERR "target_fabric_configfs_register() for"
 
1507
                                " TCM_Loop failed!\n");
 
1508
                target_fabric_configfs_free(fabric);
 
1509
                return -1;
 
1510
        }
 
1511
        /*
 
1512
         * Setup our local pointer to *fabric.
 
1513
         */
 
1514
        tcm_loop_fabric_configfs = fabric;
 
1515
        printk(KERN_INFO "TCM_LOOP[0] - Set fabric ->"
 
1516
                        " tcm_loop_fabric_configfs\n");
 
1517
        return 0;
 
1518
}
 
1519
 
 
1520
static void tcm_loop_deregister_configfs(void)
 
1521
{
 
1522
        if (!tcm_loop_fabric_configfs)
 
1523
                return;
 
1524
 
 
1525
        target_fabric_configfs_deregister(tcm_loop_fabric_configfs);
 
1526
        tcm_loop_fabric_configfs = NULL;
 
1527
        printk(KERN_INFO "TCM_LOOP[0] - Cleared"
 
1528
                                " tcm_loop_fabric_configfs\n");
 
1529
}
 
1530
 
 
1531
static int __init tcm_loop_fabric_init(void)
 
1532
{
 
1533
        int ret;
 
1534
 
 
1535
        tcm_loop_cmd_cache = kmem_cache_create("tcm_loop_cmd_cache",
 
1536
                                sizeof(struct tcm_loop_cmd),
 
1537
                                __alignof__(struct tcm_loop_cmd),
 
1538
                                0, NULL);
 
1539
        if (!tcm_loop_cmd_cache) {
 
1540
                printk(KERN_ERR "kmem_cache_create() for"
 
1541
                        " tcm_loop_cmd_cache failed\n");
 
1542
                return -ENOMEM;
 
1543
        }
 
1544
 
 
1545
        ret = tcm_loop_alloc_core_bus();
 
1546
        if (ret)
 
1547
                return ret;
 
1548
 
 
1549
        ret = tcm_loop_register_configfs();
 
1550
        if (ret) {
 
1551
                tcm_loop_release_core_bus();
 
1552
                return ret;
 
1553
        }
 
1554
 
 
1555
        return 0;
 
1556
}
 
1557
 
 
1558
static void __exit tcm_loop_fabric_exit(void)
 
1559
{
 
1560
        tcm_loop_deregister_configfs();
 
1561
        tcm_loop_release_core_bus();
 
1562
        kmem_cache_destroy(tcm_loop_cmd_cache);
 
1563
}
 
1564
 
 
1565
MODULE_DESCRIPTION("TCM loopback virtual Linux/SCSI fabric module");
 
1566
MODULE_AUTHOR("Nicholas A. Bellinger <nab@risingtidesystems.com>");
 
1567
MODULE_LICENSE("GPL");
 
1568
module_init(tcm_loop_fabric_init);
 
1569
module_exit(tcm_loop_fabric_exit);