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