linux/drivers/vhost/tcm_vhost.c
<<
>>
Prefs
   1/*******************************************************************************
   2 * Vhost kernel TCM fabric driver for virtio SCSI initiators
   3 *
   4 * (C) Copyright 2010-2012 RisingTide Systems LLC.
   5 * (C) Copyright 2010-2012 IBM Corp.
   6 *
   7 * Licensed to the Linux Foundation under the General Public License (GPL) version 2.
   8 *
   9 * Authors: Nicholas A. Bellinger <nab@risingtidesystems.com>
  10 *          Stefan Hajnoczi <stefanha@linux.vnet.ibm.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
  24#include <linux/module.h>
  25#include <linux/moduleparam.h>
  26#include <generated/utsrelease.h>
  27#include <linux/utsname.h>
  28#include <linux/init.h>
  29#include <linux/slab.h>
  30#include <linux/kthread.h>
  31#include <linux/types.h>
  32#include <linux/string.h>
  33#include <linux/configfs.h>
  34#include <linux/ctype.h>
  35#include <linux/compat.h>
  36#include <linux/eventfd.h>
  37#include <linux/vhost.h>
  38#include <linux/fs.h>
  39#include <linux/miscdevice.h>
  40#include <asm/unaligned.h>
  41#include <scsi/scsi.h>
  42#include <scsi/scsi_tcq.h>
  43#include <target/target_core_base.h>
  44#include <target/target_core_fabric.h>
  45#include <target/target_core_fabric_configfs.h>
  46#include <target/target_core_configfs.h>
  47#include <target/configfs_macros.h>
  48#include <linux/vhost.h>
  49#include <linux/virtio_net.h> /* TODO vhost.h currently depends on this */
  50#include <linux/virtio_scsi.h>
  51
  52#include "vhost.c"
  53#include "vhost.h"
  54#include "tcm_vhost.h"
  55
  56enum {
  57        VHOST_SCSI_VQ_CTL = 0,
  58        VHOST_SCSI_VQ_EVT = 1,
  59        VHOST_SCSI_VQ_IO = 2,
  60};
  61
  62struct vhost_scsi {
  63        struct tcm_vhost_tpg *vs_tpg;   /* Protected by vhost_scsi->dev.mutex */
  64        struct vhost_dev dev;
  65        struct vhost_virtqueue vqs[3];
  66
  67        struct vhost_work vs_completion_work; /* cmd completion work item */
  68        struct list_head vs_completion_list;  /* cmd completion queue */
  69        spinlock_t vs_completion_lock;        /* protects s_completion_list */
  70};
  71
  72/* Local pointer to allocated TCM configfs fabric module */
  73static struct target_fabric_configfs *tcm_vhost_fabric_configfs;
  74
  75static struct workqueue_struct *tcm_vhost_workqueue;
  76
  77/* Global spinlock to protect tcm_vhost TPG list for vhost IOCTL access */
  78static DEFINE_MUTEX(tcm_vhost_mutex);
  79static LIST_HEAD(tcm_vhost_list);
  80
  81static int tcm_vhost_check_true(struct se_portal_group *se_tpg)
  82{
  83        return 1;
  84}
  85
  86static int tcm_vhost_check_false(struct se_portal_group *se_tpg)
  87{
  88        return 0;
  89}
  90
  91static char *tcm_vhost_get_fabric_name(void)
  92{
  93        return "vhost";
  94}
  95
  96static u8 tcm_vhost_get_fabric_proto_ident(struct se_portal_group *se_tpg)
  97{
  98        struct tcm_vhost_tpg *tpg = container_of(se_tpg,
  99                                struct tcm_vhost_tpg, se_tpg);
 100        struct tcm_vhost_tport *tport = tpg->tport;
 101
 102        switch (tport->tport_proto_id) {
 103        case SCSI_PROTOCOL_SAS:
 104                return sas_get_fabric_proto_ident(se_tpg);
 105        case SCSI_PROTOCOL_FCP:
 106                return fc_get_fabric_proto_ident(se_tpg);
 107        case SCSI_PROTOCOL_ISCSI:
 108                return iscsi_get_fabric_proto_ident(se_tpg);
 109        default:
 110                pr_err("Unknown tport_proto_id: 0x%02x, using"
 111                        " SAS emulation\n", tport->tport_proto_id);
 112                break;
 113        }
 114
 115        return sas_get_fabric_proto_ident(se_tpg);
 116}
 117
 118static char *tcm_vhost_get_fabric_wwn(struct se_portal_group *se_tpg)
 119{
 120        struct tcm_vhost_tpg *tpg = container_of(se_tpg,
 121                                struct tcm_vhost_tpg, se_tpg);
 122        struct tcm_vhost_tport *tport = tpg->tport;
 123
 124        return &tport->tport_name[0];
 125}
 126
 127static u16 tcm_vhost_get_tag(struct se_portal_group *se_tpg)
 128{
 129        struct tcm_vhost_tpg *tpg = container_of(se_tpg,
 130                                struct tcm_vhost_tpg, se_tpg);
 131        return tpg->tport_tpgt;
 132}
 133
 134static u32 tcm_vhost_get_default_depth(struct se_portal_group *se_tpg)
 135{
 136        return 1;
 137}
 138
 139static u32 tcm_vhost_get_pr_transport_id(struct se_portal_group *se_tpg,
 140        struct se_node_acl *se_nacl,
 141        struct t10_pr_registration *pr_reg,
 142        int *format_code,
 143        unsigned char *buf)
 144{
 145        struct tcm_vhost_tpg *tpg = container_of(se_tpg,
 146                                struct tcm_vhost_tpg, se_tpg);
 147        struct tcm_vhost_tport *tport = tpg->tport;
 148
 149        switch (tport->tport_proto_id) {
 150        case SCSI_PROTOCOL_SAS:
 151                return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
 152                                        format_code, buf);
 153        case SCSI_PROTOCOL_FCP:
 154                return fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
 155                                        format_code, buf);
 156        case SCSI_PROTOCOL_ISCSI:
 157                return iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
 158                                        format_code, buf);
 159        default:
 160                pr_err("Unknown tport_proto_id: 0x%02x, using"
 161                        " SAS emulation\n", tport->tport_proto_id);
 162                break;
 163        }
 164
 165        return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
 166                        format_code, buf);
 167}
 168
 169static u32 tcm_vhost_get_pr_transport_id_len(struct se_portal_group *se_tpg,
 170        struct se_node_acl *se_nacl,
 171        struct t10_pr_registration *pr_reg,
 172        int *format_code)
 173{
 174        struct tcm_vhost_tpg *tpg = container_of(se_tpg,
 175                                struct tcm_vhost_tpg, se_tpg);
 176        struct tcm_vhost_tport *tport = tpg->tport;
 177
 178        switch (tport->tport_proto_id) {
 179        case SCSI_PROTOCOL_SAS:
 180                return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
 181                                        format_code);
 182        case SCSI_PROTOCOL_FCP:
 183                return fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
 184                                        format_code);
 185        case SCSI_PROTOCOL_ISCSI:
 186                return iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
 187                                        format_code);
 188        default:
 189                pr_err("Unknown tport_proto_id: 0x%02x, using"
 190                        " SAS emulation\n", tport->tport_proto_id);
 191                break;
 192        }
 193
 194        return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
 195                        format_code);
 196}
 197
 198static char *tcm_vhost_parse_pr_out_transport_id(struct se_portal_group *se_tpg,
 199        const char *buf,
 200        u32 *out_tid_len,
 201        char **port_nexus_ptr)
 202{
 203        struct tcm_vhost_tpg *tpg = container_of(se_tpg,
 204                                struct tcm_vhost_tpg, se_tpg);
 205        struct tcm_vhost_tport *tport = tpg->tport;
 206
 207        switch (tport->tport_proto_id) {
 208        case SCSI_PROTOCOL_SAS:
 209                return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
 210                                        port_nexus_ptr);
 211        case SCSI_PROTOCOL_FCP:
 212                return fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
 213                                        port_nexus_ptr);
 214        case SCSI_PROTOCOL_ISCSI:
 215                return iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
 216                                        port_nexus_ptr);
 217        default:
 218                pr_err("Unknown tport_proto_id: 0x%02x, using"
 219                        " SAS emulation\n", tport->tport_proto_id);
 220                break;
 221        }
 222
 223        return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
 224                        port_nexus_ptr);
 225}
 226
 227static struct se_node_acl *tcm_vhost_alloc_fabric_acl(
 228        struct se_portal_group *se_tpg)
 229{
 230        struct tcm_vhost_nacl *nacl;
 231
 232        nacl = kzalloc(sizeof(struct tcm_vhost_nacl), GFP_KERNEL);
 233        if (!nacl) {
 234                pr_err("Unable to alocate struct tcm_vhost_nacl\n");
 235                return NULL;
 236        }
 237
 238        return &nacl->se_node_acl;
 239}
 240
 241static void tcm_vhost_release_fabric_acl(struct se_portal_group *se_tpg,
 242        struct se_node_acl *se_nacl)
 243{
 244        struct tcm_vhost_nacl *nacl = container_of(se_nacl,
 245                        struct tcm_vhost_nacl, se_node_acl);
 246        kfree(nacl);
 247}
 248
 249static u32 tcm_vhost_tpg_get_inst_index(struct se_portal_group *se_tpg)
 250{
 251        return 1;
 252}
 253
 254static void tcm_vhost_release_cmd(struct se_cmd *se_cmd)
 255{
 256        return;
 257}
 258
 259static int tcm_vhost_shutdown_session(struct se_session *se_sess)
 260{
 261        return 0;
 262}
 263
 264static void tcm_vhost_close_session(struct se_session *se_sess)
 265{
 266        return;
 267}
 268
 269static u32 tcm_vhost_sess_get_index(struct se_session *se_sess)
 270{
 271        return 0;
 272}
 273
 274static int tcm_vhost_write_pending(struct se_cmd *se_cmd)
 275{
 276        /* Go ahead and process the write immediately */
 277        target_execute_cmd(se_cmd);
 278        return 0;
 279}
 280
 281static int tcm_vhost_write_pending_status(struct se_cmd *se_cmd)
 282{
 283        return 0;
 284}
 285
 286static void tcm_vhost_set_default_node_attrs(struct se_node_acl *nacl)
 287{
 288        return;
 289}
 290
 291static u32 tcm_vhost_get_task_tag(struct se_cmd *se_cmd)
 292{
 293        return 0;
 294}
 295
 296static int tcm_vhost_get_cmd_state(struct se_cmd *se_cmd)
 297{
 298        return 0;
 299}
 300
 301static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *tv_cmd)
 302{
 303        struct vhost_scsi *vs = tv_cmd->tvc_vhost;
 304
 305        spin_lock_bh(&vs->vs_completion_lock);
 306        list_add_tail(&tv_cmd->tvc_completion_list, &vs->vs_completion_list);
 307        spin_unlock_bh(&vs->vs_completion_lock);
 308
 309        vhost_work_queue(&vs->dev, &vs->vs_completion_work);
 310}
 311
 312static int tcm_vhost_queue_data_in(struct se_cmd *se_cmd)
 313{
 314        struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd,
 315                                struct tcm_vhost_cmd, tvc_se_cmd);
 316        vhost_scsi_complete_cmd(tv_cmd);
 317        return 0;
 318}
 319
 320static int tcm_vhost_queue_status(struct se_cmd *se_cmd)
 321{
 322        struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd,
 323                                struct tcm_vhost_cmd, tvc_se_cmd);
 324        vhost_scsi_complete_cmd(tv_cmd);
 325        return 0;
 326}
 327
 328static int tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd)
 329{
 330        return 0;
 331}
 332
 333static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd)
 334{
 335        struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
 336
 337        /* TODO locking against target/backend threads? */
 338        transport_generic_free_cmd(se_cmd, 1);
 339
 340        if (tv_cmd->tvc_sgl_count) {
 341                u32 i;
 342                for (i = 0; i < tv_cmd->tvc_sgl_count; i++)
 343                        put_page(sg_page(&tv_cmd->tvc_sgl[i]));
 344
 345                kfree(tv_cmd->tvc_sgl);
 346        }
 347
 348        kfree(tv_cmd);
 349}
 350
 351/* Dequeue a command from the completion list */
 352static struct tcm_vhost_cmd *vhost_scsi_get_cmd_from_completion(
 353        struct vhost_scsi *vs)
 354{
 355        struct tcm_vhost_cmd *tv_cmd = NULL;
 356
 357        spin_lock_bh(&vs->vs_completion_lock);
 358        if (list_empty(&vs->vs_completion_list)) {
 359                spin_unlock_bh(&vs->vs_completion_lock);
 360                return NULL;
 361        }
 362
 363        list_for_each_entry(tv_cmd, &vs->vs_completion_list,
 364                            tvc_completion_list) {
 365                list_del(&tv_cmd->tvc_completion_list);
 366                break;
 367        }
 368        spin_unlock_bh(&vs->vs_completion_lock);
 369        return tv_cmd;
 370}
 371
 372/* Fill in status and signal that we are done processing this command
 373 *
 374 * This is scheduled in the vhost work queue so we are called with the owner
 375 * process mm and can access the vring.
 376 */
 377static void vhost_scsi_complete_cmd_work(struct vhost_work *work)
 378{
 379        struct vhost_scsi *vs = container_of(work, struct vhost_scsi,
 380                                        vs_completion_work);
 381        struct tcm_vhost_cmd *tv_cmd;
 382
 383        while ((tv_cmd = vhost_scsi_get_cmd_from_completion(vs))) {
 384                struct virtio_scsi_cmd_resp v_rsp;
 385                struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
 386                int ret;
 387
 388                pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__,
 389                        tv_cmd, se_cmd->residual_count, se_cmd->scsi_status);
 390
 391                memset(&v_rsp, 0, sizeof(v_rsp));
 392                v_rsp.resid = se_cmd->residual_count;
 393                /* TODO is status_qualifier field needed? */
 394                v_rsp.status = se_cmd->scsi_status;
 395                v_rsp.sense_len = se_cmd->scsi_sense_length;
 396                memcpy(v_rsp.sense, tv_cmd->tvc_sense_buf,
 397                       v_rsp.sense_len);
 398                ret = copy_to_user(tv_cmd->tvc_resp, &v_rsp, sizeof(v_rsp));
 399                if (likely(ret == 0))
 400                        vhost_add_used(&vs->vqs[2], tv_cmd->tvc_vq_desc, 0);
 401                else
 402                        pr_err("Faulted on virtio_scsi_cmd_resp\n");
 403
 404                vhost_scsi_free_cmd(tv_cmd);
 405        }
 406
 407        vhost_signal(&vs->dev, &vs->vqs[2]);
 408}
 409
 410static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd(
 411        struct tcm_vhost_tpg *tv_tpg,
 412        struct virtio_scsi_cmd_req *v_req,
 413        u32 exp_data_len,
 414        int data_direction)
 415{
 416        struct tcm_vhost_cmd *tv_cmd;
 417        struct tcm_vhost_nexus *tv_nexus;
 418        struct se_session *se_sess;
 419
 420        tv_nexus = tv_tpg->tpg_nexus;
 421        if (!tv_nexus) {
 422                pr_err("Unable to locate active struct tcm_vhost_nexus\n");
 423                return ERR_PTR(-EIO);
 424        }
 425        se_sess = tv_nexus->tvn_se_sess;
 426
 427        tv_cmd = kzalloc(sizeof(struct tcm_vhost_cmd), GFP_ATOMIC);
 428        if (!tv_cmd) {
 429                pr_err("Unable to allocate struct tcm_vhost_cmd\n");
 430                return ERR_PTR(-ENOMEM);
 431        }
 432        INIT_LIST_HEAD(&tv_cmd->tvc_completion_list);
 433        tv_cmd->tvc_tag = v_req->tag;
 434        tv_cmd->tvc_task_attr = v_req->task_attr;
 435        tv_cmd->tvc_exp_data_len = exp_data_len;
 436        tv_cmd->tvc_data_direction = data_direction;
 437        tv_cmd->tvc_nexus = tv_nexus;
 438
 439        return tv_cmd;
 440}
 441
 442/*
 443 * Map a user memory range into a scatterlist
 444 *
 445 * Returns the number of scatterlist entries used or -errno on error.
 446 */
 447static int vhost_scsi_map_to_sgl(struct scatterlist *sgl,
 448        unsigned int sgl_count, void __user *ptr, size_t len, int write)
 449{
 450        struct scatterlist *sg = sgl;
 451        unsigned int npages = 0;
 452        int ret;
 453
 454        while (len > 0) {
 455                struct page *page;
 456                unsigned int offset = (uintptr_t)ptr & ~PAGE_MASK;
 457                unsigned int nbytes = min_t(unsigned int,
 458                                PAGE_SIZE - offset, len);
 459
 460                if (npages == sgl_count) {
 461                        ret = -ENOBUFS;
 462                        goto err;
 463                }
 464
 465                ret = get_user_pages_fast((unsigned long)ptr, 1, write, &page);
 466                BUG_ON(ret == 0); /* we should either get our page or fail */
 467                if (ret < 0)
 468                        goto err;
 469
 470                sg_set_page(sg, page, nbytes, offset);
 471                ptr += nbytes;
 472                len -= nbytes;
 473                sg++;
 474                npages++;
 475        }
 476        return npages;
 477
 478err:
 479        /* Put pages that we hold */
 480        for (sg = sgl; sg != &sgl[npages]; sg++)
 481                put_page(sg_page(sg));
 482        return ret;
 483}
 484
 485static int vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *tv_cmd,
 486        struct iovec *iov, unsigned int niov, int write)
 487{
 488        int ret;
 489        unsigned int i;
 490        u32 sgl_count;
 491        struct scatterlist *sg;
 492
 493        /*
 494         * Find out how long sglist needs to be
 495         */
 496        sgl_count = 0;
 497        for (i = 0; i < niov; i++) {
 498                sgl_count += (((uintptr_t)iov[i].iov_base + iov[i].iov_len +
 499                                PAGE_SIZE - 1) >> PAGE_SHIFT) -
 500                                ((uintptr_t)iov[i].iov_base >> PAGE_SHIFT);
 501        }
 502        /* TODO overflow checking */
 503
 504        sg = kmalloc(sizeof(tv_cmd->tvc_sgl[0]) * sgl_count, GFP_ATOMIC);
 505        if (!sg)
 506                return -ENOMEM;
 507        pr_debug("%s sg %p sgl_count %u is_err %d\n", __func__,
 508               sg, sgl_count, !sg);
 509        sg_init_table(sg, sgl_count);
 510
 511        tv_cmd->tvc_sgl = sg;
 512        tv_cmd->tvc_sgl_count = sgl_count;
 513
 514        pr_debug("Mapping %u iovecs for %u pages\n", niov, sgl_count);
 515        for (i = 0; i < niov; i++) {
 516                ret = vhost_scsi_map_to_sgl(sg, sgl_count, iov[i].iov_base,
 517                                        iov[i].iov_len, write);
 518                if (ret < 0) {
 519                        for (i = 0; i < tv_cmd->tvc_sgl_count; i++)
 520                                put_page(sg_page(&tv_cmd->tvc_sgl[i]));
 521                        kfree(tv_cmd->tvc_sgl);
 522                        tv_cmd->tvc_sgl = NULL;
 523                        tv_cmd->tvc_sgl_count = 0;
 524                        return ret;
 525                }
 526
 527                sg += ret;
 528                sgl_count -= ret;
 529        }
 530        return 0;
 531}
 532
 533static void tcm_vhost_submission_work(struct work_struct *work)
 534{
 535        struct tcm_vhost_cmd *tv_cmd =
 536                container_of(work, struct tcm_vhost_cmd, work);
 537        struct tcm_vhost_nexus *tv_nexus;
 538        struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
 539        struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL;
 540        int rc, sg_no_bidi = 0;
 541
 542        if (tv_cmd->tvc_sgl_count) {
 543                sg_ptr = tv_cmd->tvc_sgl;
 544                /*
 545                 * For BIDI commands, pass in the extra READ buffer
 546                 * to transport_generic_map_mem_to_cmd() below..
 547                 */
 548/* FIXME: Fix BIDI operation in tcm_vhost_submission_work() */
 549#if 0
 550                if (se_cmd->se_cmd_flags & SCF_BIDI) {
 551                        sg_bidi_ptr = NULL;
 552                        sg_no_bidi = 0;
 553                }
 554#endif
 555        } else {
 556                sg_ptr = NULL;
 557        }
 558        tv_nexus = tv_cmd->tvc_nexus;
 559
 560        rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess,
 561                        tv_cmd->tvc_cdb, &tv_cmd->tvc_sense_buf[0],
 562                        tv_cmd->tvc_lun, tv_cmd->tvc_exp_data_len,
 563                        tv_cmd->tvc_task_attr, tv_cmd->tvc_data_direction,
 564                        0, sg_ptr, tv_cmd->tvc_sgl_count,
 565                        sg_bidi_ptr, sg_no_bidi);
 566        if (rc < 0) {
 567                transport_send_check_condition_and_sense(se_cmd,
 568                                TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
 569                transport_generic_free_cmd(se_cmd, 0);
 570        }
 571}
 572
 573static void vhost_scsi_handle_vq(struct vhost_scsi *vs)
 574{
 575        struct vhost_virtqueue *vq = &vs->vqs[2];
 576        struct virtio_scsi_cmd_req v_req;
 577        struct tcm_vhost_tpg *tv_tpg;
 578        struct tcm_vhost_cmd *tv_cmd;
 579        u32 exp_data_len, data_first, data_num, data_direction;
 580        unsigned out, in, i;
 581        int head, ret;
 582
 583        /* Must use ioctl VHOST_SCSI_SET_ENDPOINT */
 584        tv_tpg = vs->vs_tpg;
 585        if (unlikely(!tv_tpg)) {
 586                pr_err("%s endpoint not set\n", __func__);
 587                return;
 588        }
 589
 590        mutex_lock(&vq->mutex);
 591        vhost_disable_notify(&vs->dev, vq);
 592
 593        for (;;) {
 594                head = vhost_get_vq_desc(&vs->dev, vq, vq->iov,
 595                                        ARRAY_SIZE(vq->iov), &out, &in,
 596                                        NULL, NULL);
 597                pr_debug("vhost_get_vq_desc: head: %d, out: %u in: %u\n",
 598                                        head, out, in);
 599                /* On error, stop handling until the next kick. */
 600                if (unlikely(head < 0))
 601                        break;
 602                /* Nothing new?  Wait for eventfd to tell us they refilled. */
 603                if (head == vq->num) {
 604                        if (unlikely(vhost_enable_notify(&vs->dev, vq))) {
 605                                vhost_disable_notify(&vs->dev, vq);
 606                                continue;
 607                        }
 608                        break;
 609                }
 610
 611/* FIXME: BIDI operation */
 612                if (out == 1 && in == 1) {
 613                        data_direction = DMA_NONE;
 614                        data_first = 0;
 615                        data_num = 0;
 616                } else if (out == 1 && in > 1) {
 617                        data_direction = DMA_FROM_DEVICE;
 618                        data_first = out + 1;
 619                        data_num = in - 1;
 620                } else if (out > 1 && in == 1) {
 621                        data_direction = DMA_TO_DEVICE;
 622                        data_first = 1;
 623                        data_num = out - 1;
 624                } else {
 625                        vq_err(vq, "Invalid buffer layout out: %u in: %u\n",
 626                                        out, in);
 627                        break;
 628                }
 629
 630                /*
 631                 * Check for a sane resp buffer so we can report errors to
 632                 * the guest.
 633                 */
 634                if (unlikely(vq->iov[out].iov_len !=
 635                                        sizeof(struct virtio_scsi_cmd_resp))) {
 636                        vq_err(vq, "Expecting virtio_scsi_cmd_resp, got %zu"
 637                                " bytes\n", vq->iov[out].iov_len);
 638                        break;
 639                }
 640
 641                if (unlikely(vq->iov[0].iov_len != sizeof(v_req))) {
 642                        vq_err(vq, "Expecting virtio_scsi_cmd_req, got %zu"
 643                                " bytes\n", vq->iov[0].iov_len);
 644                        break;
 645                }
 646                pr_debug("Calling __copy_from_user: vq->iov[0].iov_base: %p,"
 647                        " len: %zu\n", vq->iov[0].iov_base, sizeof(v_req));
 648                ret = __copy_from_user(&v_req, vq->iov[0].iov_base,
 649                                sizeof(v_req));
 650                if (unlikely(ret)) {
 651                        vq_err(vq, "Faulted on virtio_scsi_cmd_req\n");
 652                        break;
 653                }
 654
 655                exp_data_len = 0;
 656                for (i = 0; i < data_num; i++)
 657                        exp_data_len += vq->iov[data_first + i].iov_len;
 658
 659                tv_cmd = vhost_scsi_allocate_cmd(tv_tpg, &v_req,
 660                                        exp_data_len, data_direction);
 661                if (IS_ERR(tv_cmd)) {
 662                        vq_err(vq, "vhost_scsi_allocate_cmd failed %ld\n",
 663                                        PTR_ERR(tv_cmd));
 664                        break;
 665                }
 666                pr_debug("Allocated tv_cmd: %p exp_data_len: %d, data_direction"
 667                        ": %d\n", tv_cmd, exp_data_len, data_direction);
 668
 669                tv_cmd->tvc_vhost = vs;
 670
 671                if (unlikely(vq->iov[out].iov_len !=
 672                                sizeof(struct virtio_scsi_cmd_resp))) {
 673                        vq_err(vq, "Expecting virtio_scsi_cmd_resp, got %zu"
 674                                " bytes, out: %d, in: %d\n",
 675                                vq->iov[out].iov_len, out, in);
 676                        break;
 677                }
 678
 679                tv_cmd->tvc_resp = vq->iov[out].iov_base;
 680
 681                /*
 682                 * Copy in the recieved CDB descriptor into tv_cmd->tvc_cdb
 683                 * that will be used by tcm_vhost_new_cmd_map() and down into
 684                 * target_setup_cmd_from_cdb()
 685                 */
 686                memcpy(tv_cmd->tvc_cdb, v_req.cdb, TCM_VHOST_MAX_CDB_SIZE);
 687                /*
 688                 * Check that the recieved CDB size does not exceeded our
 689                 * hardcoded max for tcm_vhost
 690                 */
 691                /* TODO what if cdb was too small for varlen cdb header? */
 692                if (unlikely(scsi_command_size(tv_cmd->tvc_cdb) >
 693                                        TCM_VHOST_MAX_CDB_SIZE)) {
 694                        vq_err(vq, "Received SCSI CDB with command_size: %d that"
 695                                " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n",
 696                                scsi_command_size(tv_cmd->tvc_cdb),
 697                                TCM_VHOST_MAX_CDB_SIZE);
 698                        break; /* TODO */
 699                }
 700                tv_cmd->tvc_lun = ((v_req.lun[2] << 8) | v_req.lun[3]) & 0x3FFF;
 701
 702                pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n",
 703                        tv_cmd->tvc_cdb[0], tv_cmd->tvc_lun);
 704
 705                if (data_direction != DMA_NONE) {
 706                        ret = vhost_scsi_map_iov_to_sgl(tv_cmd,
 707                                        &vq->iov[data_first], data_num,
 708                                        data_direction == DMA_TO_DEVICE);
 709                        if (unlikely(ret)) {
 710                                vq_err(vq, "Failed to map iov to sgl\n");
 711                                break; /* TODO */
 712                        }
 713                }
 714
 715                /*
 716                 * Save the descriptor from vhost_get_vq_desc() to be used to
 717                 * complete the virtio-scsi request in TCM callback context via
 718                 * tcm_vhost_queue_data_in() and tcm_vhost_queue_status()
 719                 */
 720                tv_cmd->tvc_vq_desc = head;
 721                /*
 722                 * Dispatch tv_cmd descriptor for cmwq execution in process
 723                 * context provided by tcm_vhost_workqueue.  This also ensures
 724                 * tv_cmd is executed on the same kworker CPU as this vhost
 725                 * thread to gain positive L2 cache locality effects..
 726                 */
 727                INIT_WORK(&tv_cmd->work, tcm_vhost_submission_work);
 728                queue_work(tcm_vhost_workqueue, &tv_cmd->work);
 729        }
 730
 731        mutex_unlock(&vq->mutex);
 732}
 733
 734static void vhost_scsi_ctl_handle_kick(struct vhost_work *work)
 735{
 736        pr_debug("%s: The handling func for control queue.\n", __func__);
 737}
 738
 739static void vhost_scsi_evt_handle_kick(struct vhost_work *work)
 740{
 741        pr_debug("%s: The handling func for event queue.\n", __func__);
 742}
 743
 744static void vhost_scsi_handle_kick(struct vhost_work *work)
 745{
 746        struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue,
 747                                                poll.work);
 748        struct vhost_scsi *vs = container_of(vq->dev, struct vhost_scsi, dev);
 749
 750        vhost_scsi_handle_vq(vs);
 751}
 752
 753/*
 754 * Called from vhost_scsi_ioctl() context to walk the list of available
 755 * tcm_vhost_tpg with an active struct tcm_vhost_nexus
 756 */
 757static int vhost_scsi_set_endpoint(
 758        struct vhost_scsi *vs,
 759        struct vhost_scsi_target *t)
 760{
 761        struct tcm_vhost_tport *tv_tport;
 762        struct tcm_vhost_tpg *tv_tpg;
 763        int index;
 764
 765        mutex_lock(&vs->dev.mutex);
 766        /* Verify that ring has been setup correctly. */
 767        for (index = 0; index < vs->dev.nvqs; ++index) {
 768                /* Verify that ring has been setup correctly. */
 769                if (!vhost_vq_access_ok(&vs->vqs[index])) {
 770                        mutex_unlock(&vs->dev.mutex);
 771                        return -EFAULT;
 772                }
 773        }
 774        mutex_unlock(&vs->dev.mutex);
 775
 776        mutex_lock(&tcm_vhost_mutex);
 777        list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) {
 778                mutex_lock(&tv_tpg->tv_tpg_mutex);
 779                if (!tv_tpg->tpg_nexus) {
 780                        mutex_unlock(&tv_tpg->tv_tpg_mutex);
 781                        continue;
 782                }
 783                if (tv_tpg->tv_tpg_vhost_count != 0) {
 784                        mutex_unlock(&tv_tpg->tv_tpg_mutex);
 785                        continue;
 786                }
 787                tv_tport = tv_tpg->tport;
 788
 789                if (!strcmp(tv_tport->tport_name, t->vhost_wwpn) &&
 790                    (tv_tpg->tport_tpgt == t->vhost_tpgt)) {
 791                        tv_tpg->tv_tpg_vhost_count++;
 792                        mutex_unlock(&tv_tpg->tv_tpg_mutex);
 793                        mutex_unlock(&tcm_vhost_mutex);
 794
 795                        mutex_lock(&vs->dev.mutex);
 796                        if (vs->vs_tpg) {
 797                                mutex_unlock(&vs->dev.mutex);
 798                                mutex_lock(&tv_tpg->tv_tpg_mutex);
 799                                tv_tpg->tv_tpg_vhost_count--;
 800                                mutex_unlock(&tv_tpg->tv_tpg_mutex);
 801                                return -EEXIST;
 802                        }
 803
 804                        vs->vs_tpg = tv_tpg;
 805                        smp_mb__after_atomic_inc();
 806                        mutex_unlock(&vs->dev.mutex);
 807                        return 0;
 808                }
 809                mutex_unlock(&tv_tpg->tv_tpg_mutex);
 810        }
 811        mutex_unlock(&tcm_vhost_mutex);
 812        return -EINVAL;
 813}
 814
 815static int vhost_scsi_clear_endpoint(
 816        struct vhost_scsi *vs,
 817        struct vhost_scsi_target *t)
 818{
 819        struct tcm_vhost_tport *tv_tport;
 820        struct tcm_vhost_tpg *tv_tpg;
 821        int index, ret;
 822
 823        mutex_lock(&vs->dev.mutex);
 824        /* Verify that ring has been setup correctly. */
 825        for (index = 0; index < vs->dev.nvqs; ++index) {
 826                if (!vhost_vq_access_ok(&vs->vqs[index])) {
 827                        ret = -EFAULT;
 828                        goto err;
 829                }
 830        }
 831
 832        if (!vs->vs_tpg) {
 833                ret = -ENODEV;
 834                goto err;
 835        }
 836        tv_tpg = vs->vs_tpg;
 837        tv_tport = tv_tpg->tport;
 838
 839        if (strcmp(tv_tport->tport_name, t->vhost_wwpn) ||
 840            (tv_tpg->tport_tpgt != t->vhost_tpgt)) {
 841                pr_warn("tv_tport->tport_name: %s, tv_tpg->tport_tpgt: %hu"
 842                        " does not match t->vhost_wwpn: %s, t->vhost_tpgt: %hu\n",
 843                        tv_tport->tport_name, tv_tpg->tport_tpgt,
 844                        t->vhost_wwpn, t->vhost_tpgt);
 845                ret = -EINVAL;
 846                goto err;
 847        }
 848        tv_tpg->tv_tpg_vhost_count--;
 849        vs->vs_tpg = NULL;
 850        mutex_unlock(&vs->dev.mutex);
 851
 852        return 0;
 853
 854err:
 855        mutex_unlock(&vs->dev.mutex);
 856        return ret;
 857}
 858
 859static int vhost_scsi_open(struct inode *inode, struct file *f)
 860{
 861        struct vhost_scsi *s;
 862        int r;
 863
 864        s = kzalloc(sizeof(*s), GFP_KERNEL);
 865        if (!s)
 866                return -ENOMEM;
 867
 868        vhost_work_init(&s->vs_completion_work, vhost_scsi_complete_cmd_work);
 869        INIT_LIST_HEAD(&s->vs_completion_list);
 870        spin_lock_init(&s->vs_completion_lock);
 871
 872        s->vqs[VHOST_SCSI_VQ_CTL].handle_kick = vhost_scsi_ctl_handle_kick;
 873        s->vqs[VHOST_SCSI_VQ_EVT].handle_kick = vhost_scsi_evt_handle_kick;
 874        s->vqs[VHOST_SCSI_VQ_IO].handle_kick = vhost_scsi_handle_kick;
 875        r = vhost_dev_init(&s->dev, s->vqs, 3);
 876        if (r < 0) {
 877                kfree(s);
 878                return r;
 879        }
 880
 881        f->private_data = s;
 882        return 0;
 883}
 884
 885static int vhost_scsi_release(struct inode *inode, struct file *f)
 886{
 887        struct vhost_scsi *s = f->private_data;
 888
 889        if (s->vs_tpg && s->vs_tpg->tport) {
 890                struct vhost_scsi_target backend;
 891
 892                memcpy(backend.vhost_wwpn, s->vs_tpg->tport->tport_name,
 893                                sizeof(backend.vhost_wwpn));
 894                backend.vhost_tpgt = s->vs_tpg->tport_tpgt;
 895                vhost_scsi_clear_endpoint(s, &backend);
 896        }
 897
 898        vhost_dev_cleanup(&s->dev, false);
 899        kfree(s);
 900        return 0;
 901}
 902
 903static void vhost_scsi_flush_vq(struct vhost_scsi *vs, int index)
 904{
 905        vhost_poll_flush(&vs->dev.vqs[index].poll);
 906}
 907
 908static void vhost_scsi_flush(struct vhost_scsi *vs)
 909{
 910        vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_CTL);
 911        vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_EVT);
 912        vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_IO);
 913}
 914
 915static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
 916{
 917        if (features & ~VHOST_FEATURES)
 918                return -EOPNOTSUPP;
 919
 920        mutex_lock(&vs->dev.mutex);
 921        if ((features & (1 << VHOST_F_LOG_ALL)) &&
 922            !vhost_log_access_ok(&vs->dev)) {
 923                mutex_unlock(&vs->dev.mutex);
 924                return -EFAULT;
 925        }
 926        vs->dev.acked_features = features;
 927        smp_wmb();
 928        vhost_scsi_flush(vs);
 929        mutex_unlock(&vs->dev.mutex);
 930        return 0;
 931}
 932
 933static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl,
 934                                unsigned long arg)
 935{
 936        struct vhost_scsi *vs = f->private_data;
 937        struct vhost_scsi_target backend;
 938        void __user *argp = (void __user *)arg;
 939        u64 __user *featurep = argp;
 940        u64 features;
 941        int r, abi_version = VHOST_SCSI_ABI_VERSION;
 942
 943        switch (ioctl) {
 944        case VHOST_SCSI_SET_ENDPOINT:
 945                if (copy_from_user(&backend, argp, sizeof backend))
 946                        return -EFAULT;
 947                if (backend.reserved != 0)
 948                        return -EOPNOTSUPP;
 949
 950                return vhost_scsi_set_endpoint(vs, &backend);
 951        case VHOST_SCSI_CLEAR_ENDPOINT:
 952                if (copy_from_user(&backend, argp, sizeof backend))
 953                        return -EFAULT;
 954                if (backend.reserved != 0)
 955                        return -EOPNOTSUPP;
 956
 957                return vhost_scsi_clear_endpoint(vs, &backend);
 958        case VHOST_SCSI_GET_ABI_VERSION:
 959                if (copy_to_user(argp, &abi_version, sizeof abi_version))
 960                        return -EFAULT;
 961                return 0;
 962        case VHOST_GET_FEATURES:
 963                features = VHOST_FEATURES;
 964                if (copy_to_user(featurep, &features, sizeof features))
 965                        return -EFAULT;
 966                return 0;
 967        case VHOST_SET_FEATURES:
 968                if (copy_from_user(&features, featurep, sizeof features))
 969                        return -EFAULT;
 970                return vhost_scsi_set_features(vs, features);
 971        default:
 972                mutex_lock(&vs->dev.mutex);
 973                r = vhost_dev_ioctl(&vs->dev, ioctl, arg);
 974                mutex_unlock(&vs->dev.mutex);
 975                return r;
 976        }
 977}
 978
 979#ifdef CONFIG_COMPAT
 980static long vhost_scsi_compat_ioctl(struct file *f, unsigned int ioctl,
 981                                unsigned long arg)
 982{
 983        return vhost_scsi_ioctl(f, ioctl, (unsigned long)compat_ptr(arg));
 984}
 985#endif
 986
 987static const struct file_operations vhost_scsi_fops = {
 988        .owner          = THIS_MODULE,
 989        .release        = vhost_scsi_release,
 990        .unlocked_ioctl = vhost_scsi_ioctl,
 991#ifdef CONFIG_COMPAT
 992        .compat_ioctl   = vhost_scsi_compat_ioctl,
 993#endif
 994        .open           = vhost_scsi_open,
 995        .llseek         = noop_llseek,
 996};
 997
 998static struct miscdevice vhost_scsi_misc = {
 999        MISC_DYNAMIC_MINOR,
1000        "vhost-scsi",
1001        &vhost_scsi_fops,
1002};
1003
1004static int __init vhost_scsi_register(void)
1005{
1006        return misc_register(&vhost_scsi_misc);
1007}
1008
1009static int vhost_scsi_deregister(void)
1010{
1011        return misc_deregister(&vhost_scsi_misc);
1012}
1013
1014static char *tcm_vhost_dump_proto_id(struct tcm_vhost_tport *tport)
1015{
1016        switch (tport->tport_proto_id) {
1017        case SCSI_PROTOCOL_SAS:
1018                return "SAS";
1019        case SCSI_PROTOCOL_FCP:
1020                return "FCP";
1021        case SCSI_PROTOCOL_ISCSI:
1022                return "iSCSI";
1023        default:
1024                break;
1025        }
1026
1027        return "Unknown";
1028}
1029
1030static int tcm_vhost_port_link(struct se_portal_group *se_tpg,
1031        struct se_lun *lun)
1032{
1033        struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg,
1034                                struct tcm_vhost_tpg, se_tpg);
1035
1036        mutex_lock(&tv_tpg->tv_tpg_mutex);
1037        tv_tpg->tv_tpg_port_count++;
1038        mutex_unlock(&tv_tpg->tv_tpg_mutex);
1039
1040        return 0;
1041}
1042
1043static void tcm_vhost_port_unlink(struct se_portal_group *se_tpg,
1044        struct se_lun *se_lun)
1045{
1046        struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg,
1047                                struct tcm_vhost_tpg, se_tpg);
1048
1049        mutex_lock(&tv_tpg->tv_tpg_mutex);
1050        tv_tpg->tv_tpg_port_count--;
1051        mutex_unlock(&tv_tpg->tv_tpg_mutex);
1052}
1053
1054static struct se_node_acl *tcm_vhost_make_nodeacl(
1055        struct se_portal_group *se_tpg,
1056        struct config_group *group,
1057        const char *name)
1058{
1059        struct se_node_acl *se_nacl, *se_nacl_new;
1060        struct tcm_vhost_nacl *nacl;
1061        u64 wwpn = 0;
1062        u32 nexus_depth;
1063
1064        /* tcm_vhost_parse_wwn(name, &wwpn, 1) < 0)
1065                return ERR_PTR(-EINVAL); */
1066        se_nacl_new = tcm_vhost_alloc_fabric_acl(se_tpg);
1067        if (!se_nacl_new)
1068                return ERR_PTR(-ENOMEM);
1069
1070        nexus_depth = 1;
1071        /*
1072         * se_nacl_new may be released by core_tpg_add_initiator_node_acl()
1073         * when converting a NodeACL from demo mode -> explict
1074         */
1075        se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new,
1076                                name, nexus_depth);
1077        if (IS_ERR(se_nacl)) {
1078                tcm_vhost_release_fabric_acl(se_tpg, se_nacl_new);
1079                return se_nacl;
1080        }
1081        /*
1082         * Locate our struct tcm_vhost_nacl and set the FC Nport WWPN
1083         */
1084        nacl = container_of(se_nacl, struct tcm_vhost_nacl, se_node_acl);
1085        nacl->iport_wwpn = wwpn;
1086
1087        return se_nacl;
1088}
1089
1090static void tcm_vhost_drop_nodeacl(struct se_node_acl *se_acl)
1091{
1092        struct tcm_vhost_nacl *nacl = container_of(se_acl,
1093                                struct tcm_vhost_nacl, se_node_acl);
1094        core_tpg_del_initiator_node_acl(se_acl->se_tpg, se_acl, 1);
1095        kfree(nacl);
1096}
1097
1098static int tcm_vhost_make_nexus(struct tcm_vhost_tpg *tv_tpg,
1099        const char *name)
1100{
1101        struct se_portal_group *se_tpg;
1102        struct tcm_vhost_nexus *tv_nexus;
1103
1104        mutex_lock(&tv_tpg->tv_tpg_mutex);
1105        if (tv_tpg->tpg_nexus) {
1106                mutex_unlock(&tv_tpg->tv_tpg_mutex);
1107                pr_debug("tv_tpg->tpg_nexus already exists\n");
1108                return -EEXIST;
1109        }
1110        se_tpg = &tv_tpg->se_tpg;
1111
1112        tv_nexus = kzalloc(sizeof(struct tcm_vhost_nexus), GFP_KERNEL);
1113        if (!tv_nexus) {
1114                mutex_unlock(&tv_tpg->tv_tpg_mutex);
1115                pr_err("Unable to allocate struct tcm_vhost_nexus\n");
1116                return -ENOMEM;
1117        }
1118        /*
1119         *  Initialize the struct se_session pointer
1120         */
1121        tv_nexus->tvn_se_sess = transport_init_session();
1122        if (IS_ERR(tv_nexus->tvn_se_sess)) {
1123                mutex_unlock(&tv_tpg->tv_tpg_mutex);
1124                kfree(tv_nexus);
1125                return -ENOMEM;
1126        }
1127        /*
1128         * Since we are running in 'demo mode' this call with generate a
1129         * struct se_node_acl for the tcm_vhost struct se_portal_group with
1130         * the SCSI Initiator port name of the passed configfs group 'name'.
1131         */
1132        tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
1133                                se_tpg, (unsigned char *)name);
1134        if (!tv_nexus->tvn_se_sess->se_node_acl) {
1135                mutex_unlock(&tv_tpg->tv_tpg_mutex);
1136                pr_debug("core_tpg_check_initiator_node_acl() failed"
1137                                " for %s\n", name);
1138                transport_free_session(tv_nexus->tvn_se_sess);
1139                kfree(tv_nexus);
1140                return -ENOMEM;
1141        }
1142        /*
1143         * Now register the TCM vhost virtual I_T Nexus as active with the
1144         * call to __transport_register_session()
1145         */
1146        __transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl,
1147                        tv_nexus->tvn_se_sess, tv_nexus);
1148        tv_tpg->tpg_nexus = tv_nexus;
1149
1150        mutex_unlock(&tv_tpg->tv_tpg_mutex);
1151        return 0;
1152}
1153
1154static int tcm_vhost_drop_nexus(struct tcm_vhost_tpg *tpg)
1155{
1156        struct se_session *se_sess;
1157        struct tcm_vhost_nexus *tv_nexus;
1158
1159        mutex_lock(&tpg->tv_tpg_mutex);
1160        tv_nexus = tpg->tpg_nexus;
1161        if (!tv_nexus) {
1162                mutex_unlock(&tpg->tv_tpg_mutex);
1163                return -ENODEV;
1164        }
1165
1166        se_sess = tv_nexus->tvn_se_sess;
1167        if (!se_sess) {
1168                mutex_unlock(&tpg->tv_tpg_mutex);
1169                return -ENODEV;
1170        }
1171
1172        if (tpg->tv_tpg_port_count != 0) {
1173                mutex_unlock(&tpg->tv_tpg_mutex);
1174                pr_err("Unable to remove TCM_vhost I_T Nexus with"
1175                        " active TPG port count: %d\n",
1176                        tpg->tv_tpg_port_count);
1177                return -EBUSY;
1178        }
1179
1180        if (tpg->tv_tpg_vhost_count != 0) {
1181                mutex_unlock(&tpg->tv_tpg_mutex);
1182                pr_err("Unable to remove TCM_vhost I_T Nexus with"
1183                        " active TPG vhost count: %d\n",
1184                        tpg->tv_tpg_vhost_count);
1185                return -EBUSY;
1186        }
1187
1188        pr_debug("TCM_vhost_ConfigFS: Removing I_T Nexus to emulated"
1189                " %s Initiator Port: %s\n", tcm_vhost_dump_proto_id(tpg->tport),
1190                tv_nexus->tvn_se_sess->se_node_acl->initiatorname);
1191        /*
1192         * Release the SCSI I_T Nexus to the emulated vhost Target Port
1193         */
1194        transport_deregister_session(tv_nexus->tvn_se_sess);
1195        tpg->tpg_nexus = NULL;
1196        mutex_unlock(&tpg->tv_tpg_mutex);
1197
1198        kfree(tv_nexus);
1199        return 0;
1200}
1201
1202static ssize_t tcm_vhost_tpg_show_nexus(struct se_portal_group *se_tpg,
1203        char *page)
1204{
1205        struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg,
1206                                struct tcm_vhost_tpg, se_tpg);
1207        struct tcm_vhost_nexus *tv_nexus;
1208        ssize_t ret;
1209
1210        mutex_lock(&tv_tpg->tv_tpg_mutex);
1211        tv_nexus = tv_tpg->tpg_nexus;
1212        if (!tv_nexus) {
1213                mutex_unlock(&tv_tpg->tv_tpg_mutex);
1214                return -ENODEV;
1215        }
1216        ret = snprintf(page, PAGE_SIZE, "%s\n",
1217                        tv_nexus->tvn_se_sess->se_node_acl->initiatorname);
1218        mutex_unlock(&tv_tpg->tv_tpg_mutex);
1219
1220        return ret;
1221}
1222
1223static ssize_t tcm_vhost_tpg_store_nexus(struct se_portal_group *se_tpg,
1224        const char *page,
1225        size_t count)
1226{
1227        struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg,
1228                                struct tcm_vhost_tpg, se_tpg);
1229        struct tcm_vhost_tport *tport_wwn = tv_tpg->tport;
1230        unsigned char i_port[TCM_VHOST_NAMELEN], *ptr, *port_ptr;
1231        int ret;
1232        /*
1233         * Shutdown the active I_T nexus if 'NULL' is passed..
1234         */
1235        if (!strncmp(page, "NULL", 4)) {
1236                ret = tcm_vhost_drop_nexus(tv_tpg);
1237                return (!ret) ? count : ret;
1238        }
1239        /*
1240         * Otherwise make sure the passed virtual Initiator port WWN matches
1241         * the fabric protocol_id set in tcm_vhost_make_tport(), and call
1242         * tcm_vhost_make_nexus().
1243         */
1244        if (strlen(page) >= TCM_VHOST_NAMELEN) {
1245                pr_err("Emulated NAA Sas Address: %s, exceeds"
1246                                " max: %d\n", page, TCM_VHOST_NAMELEN);
1247                return -EINVAL;
1248        }
1249        snprintf(&i_port[0], TCM_VHOST_NAMELEN, "%s", page);
1250
1251        ptr = strstr(i_port, "naa.");
1252        if (ptr) {
1253                if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_SAS) {
1254                        pr_err("Passed SAS Initiator Port %s does not"
1255                                " match target port protoid: %s\n", i_port,
1256                                tcm_vhost_dump_proto_id(tport_wwn));
1257                        return -EINVAL;
1258                }
1259                port_ptr = &i_port[0];
1260                goto check_newline;
1261        }
1262        ptr = strstr(i_port, "fc.");
1263        if (ptr) {
1264                if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_FCP) {
1265                        pr_err("Passed FCP Initiator Port %s does not"
1266                                " match target port protoid: %s\n", i_port,
1267                                tcm_vhost_dump_proto_id(tport_wwn));
1268                        return -EINVAL;
1269                }
1270                port_ptr = &i_port[3]; /* Skip over "fc." */
1271                goto check_newline;
1272        }
1273        ptr = strstr(i_port, "iqn.");
1274        if (ptr) {
1275                if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_ISCSI) {
1276                        pr_err("Passed iSCSI Initiator Port %s does not"
1277                                " match target port protoid: %s\n", i_port,
1278                                tcm_vhost_dump_proto_id(tport_wwn));
1279                        return -EINVAL;
1280                }
1281                port_ptr = &i_port[0];
1282                goto check_newline;
1283        }
1284        pr_err("Unable to locate prefix for emulated Initiator Port:"
1285                        " %s\n", i_port);
1286        return -EINVAL;
1287        /*
1288         * Clear any trailing newline for the NAA WWN
1289         */
1290check_newline:
1291        if (i_port[strlen(i_port)-1] == '\n')
1292                i_port[strlen(i_port)-1] = '\0';
1293
1294        ret = tcm_vhost_make_nexus(tv_tpg, port_ptr);
1295        if (ret < 0)
1296                return ret;
1297
1298        return count;
1299}
1300
1301TF_TPG_BASE_ATTR(tcm_vhost, nexus, S_IRUGO | S_IWUSR);
1302
1303static struct configfs_attribute *tcm_vhost_tpg_attrs[] = {
1304        &tcm_vhost_tpg_nexus.attr,
1305        NULL,
1306};
1307
1308static struct se_portal_group *tcm_vhost_make_tpg(struct se_wwn *wwn,
1309        struct config_group *group,
1310        const char *name)
1311{
1312        struct tcm_vhost_tport *tport = container_of(wwn,
1313                        struct tcm_vhost_tport, tport_wwn);
1314
1315        struct tcm_vhost_tpg *tpg;
1316        unsigned long tpgt;
1317        int ret;
1318
1319        if (strstr(name, "tpgt_") != name)
1320                return ERR_PTR(-EINVAL);
1321        if (kstrtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX)
1322                return ERR_PTR(-EINVAL);
1323
1324        tpg = kzalloc(sizeof(struct tcm_vhost_tpg), GFP_KERNEL);
1325        if (!tpg) {
1326                pr_err("Unable to allocate struct tcm_vhost_tpg");
1327                return ERR_PTR(-ENOMEM);
1328        }
1329        mutex_init(&tpg->tv_tpg_mutex);
1330        INIT_LIST_HEAD(&tpg->tv_tpg_list);
1331        tpg->tport = tport;
1332        tpg->tport_tpgt = tpgt;
1333
1334        ret = core_tpg_register(&tcm_vhost_fabric_configfs->tf_ops, wwn,
1335                                &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL);
1336        if (ret < 0) {
1337                kfree(tpg);
1338                return NULL;
1339        }
1340        mutex_lock(&tcm_vhost_mutex);
1341        list_add_tail(&tpg->tv_tpg_list, &tcm_vhost_list);
1342        mutex_unlock(&tcm_vhost_mutex);
1343
1344        return &tpg->se_tpg;
1345}
1346
1347static void tcm_vhost_drop_tpg(struct se_portal_group *se_tpg)
1348{
1349        struct tcm_vhost_tpg *tpg = container_of(se_tpg,
1350                                struct tcm_vhost_tpg, se_tpg);
1351
1352        mutex_lock(&tcm_vhost_mutex);
1353        list_del(&tpg->tv_tpg_list);
1354        mutex_unlock(&tcm_vhost_mutex);
1355        /*
1356         * Release the virtual I_T Nexus for this vhost TPG
1357         */
1358        tcm_vhost_drop_nexus(tpg);
1359        /*
1360         * Deregister the se_tpg from TCM..
1361         */
1362        core_tpg_deregister(se_tpg);
1363        kfree(tpg);
1364}
1365
1366static struct se_wwn *tcm_vhost_make_tport(struct target_fabric_configfs *tf,
1367        struct config_group *group,
1368        const char *name)
1369{
1370        struct tcm_vhost_tport *tport;
1371        char *ptr;
1372        u64 wwpn = 0;
1373        int off = 0;
1374
1375        /* if (tcm_vhost_parse_wwn(name, &wwpn, 1) < 0)
1376                return ERR_PTR(-EINVAL); */
1377
1378        tport = kzalloc(sizeof(struct tcm_vhost_tport), GFP_KERNEL);
1379        if (!tport) {
1380                pr_err("Unable to allocate struct tcm_vhost_tport");
1381                return ERR_PTR(-ENOMEM);
1382        }
1383        tport->tport_wwpn = wwpn;
1384        /*
1385         * Determine the emulated Protocol Identifier and Target Port Name
1386         * based on the incoming configfs directory name.
1387         */
1388        ptr = strstr(name, "naa.");
1389        if (ptr) {
1390                tport->tport_proto_id = SCSI_PROTOCOL_SAS;
1391                goto check_len;
1392        }
1393        ptr = strstr(name, "fc.");
1394        if (ptr) {
1395                tport->tport_proto_id = SCSI_PROTOCOL_FCP;
1396                off = 3; /* Skip over "fc." */
1397                goto check_len;
1398        }
1399        ptr = strstr(name, "iqn.");
1400        if (ptr) {
1401                tport->tport_proto_id = SCSI_PROTOCOL_ISCSI;
1402                goto check_len;
1403        }
1404
1405        pr_err("Unable to locate prefix for emulated Target Port:"
1406                        " %s\n", name);
1407        kfree(tport);
1408        return ERR_PTR(-EINVAL);
1409
1410check_len:
1411        if (strlen(name) >= TCM_VHOST_NAMELEN) {
1412                pr_err("Emulated %s Address: %s, exceeds"
1413                        " max: %d\n", name, tcm_vhost_dump_proto_id(tport),
1414                        TCM_VHOST_NAMELEN);
1415                kfree(tport);
1416                return ERR_PTR(-EINVAL);
1417        }
1418        snprintf(&tport->tport_name[0], TCM_VHOST_NAMELEN, "%s", &name[off]);
1419
1420        pr_debug("TCM_VHost_ConfigFS: Allocated emulated Target"
1421                " %s Address: %s\n", tcm_vhost_dump_proto_id(tport), name);
1422
1423        return &tport->tport_wwn;
1424}
1425
1426static void tcm_vhost_drop_tport(struct se_wwn *wwn)
1427{
1428        struct tcm_vhost_tport *tport = container_of(wwn,
1429                                struct tcm_vhost_tport, tport_wwn);
1430
1431        pr_debug("TCM_VHost_ConfigFS: Deallocating emulated Target"
1432                " %s Address: %s\n", tcm_vhost_dump_proto_id(tport),
1433                tport->tport_name);
1434
1435        kfree(tport);
1436}
1437
1438static ssize_t tcm_vhost_wwn_show_attr_version(
1439        struct target_fabric_configfs *tf,
1440        char *page)
1441{
1442        return sprintf(page, "TCM_VHOST fabric module %s on %s/%s"
1443                "on "UTS_RELEASE"\n", TCM_VHOST_VERSION, utsname()->sysname,
1444                utsname()->machine);
1445}
1446
1447TF_WWN_ATTR_RO(tcm_vhost, version);
1448
1449static struct configfs_attribute *tcm_vhost_wwn_attrs[] = {
1450        &tcm_vhost_wwn_version.attr,
1451        NULL,
1452};
1453
1454static struct target_core_fabric_ops tcm_vhost_ops = {
1455        .get_fabric_name                = tcm_vhost_get_fabric_name,
1456        .get_fabric_proto_ident         = tcm_vhost_get_fabric_proto_ident,
1457        .tpg_get_wwn                    = tcm_vhost_get_fabric_wwn,
1458        .tpg_get_tag                    = tcm_vhost_get_tag,
1459        .tpg_get_default_depth          = tcm_vhost_get_default_depth,
1460        .tpg_get_pr_transport_id        = tcm_vhost_get_pr_transport_id,
1461        .tpg_get_pr_transport_id_len    = tcm_vhost_get_pr_transport_id_len,
1462        .tpg_parse_pr_out_transport_id  = tcm_vhost_parse_pr_out_transport_id,
1463        .tpg_check_demo_mode            = tcm_vhost_check_true,
1464        .tpg_check_demo_mode_cache      = tcm_vhost_check_true,
1465        .tpg_check_demo_mode_write_protect = tcm_vhost_check_false,
1466        .tpg_check_prod_mode_write_protect = tcm_vhost_check_false,
1467        .tpg_alloc_fabric_acl           = tcm_vhost_alloc_fabric_acl,
1468        .tpg_release_fabric_acl         = tcm_vhost_release_fabric_acl,
1469        .tpg_get_inst_index             = tcm_vhost_tpg_get_inst_index,
1470        .release_cmd                    = tcm_vhost_release_cmd,
1471        .shutdown_session               = tcm_vhost_shutdown_session,
1472        .close_session                  = tcm_vhost_close_session,
1473        .sess_get_index                 = tcm_vhost_sess_get_index,
1474        .sess_get_initiator_sid         = NULL,
1475        .write_pending                  = tcm_vhost_write_pending,
1476        .write_pending_status           = tcm_vhost_write_pending_status,
1477        .set_default_node_attributes    = tcm_vhost_set_default_node_attrs,
1478        .get_task_tag                   = tcm_vhost_get_task_tag,
1479        .get_cmd_state                  = tcm_vhost_get_cmd_state,
1480        .queue_data_in                  = tcm_vhost_queue_data_in,
1481        .queue_status                   = tcm_vhost_queue_status,
1482        .queue_tm_rsp                   = tcm_vhost_queue_tm_rsp,
1483        /*
1484         * Setup callers for generic logic in target_core_fabric_configfs.c
1485         */
1486        .fabric_make_wwn                = tcm_vhost_make_tport,
1487        .fabric_drop_wwn                = tcm_vhost_drop_tport,
1488        .fabric_make_tpg                = tcm_vhost_make_tpg,
1489        .fabric_drop_tpg                = tcm_vhost_drop_tpg,
1490        .fabric_post_link               = tcm_vhost_port_link,
1491        .fabric_pre_unlink              = tcm_vhost_port_unlink,
1492        .fabric_make_np                 = NULL,
1493        .fabric_drop_np                 = NULL,
1494        .fabric_make_nodeacl            = tcm_vhost_make_nodeacl,
1495        .fabric_drop_nodeacl            = tcm_vhost_drop_nodeacl,
1496};
1497
1498static int tcm_vhost_register_configfs(void)
1499{
1500        struct target_fabric_configfs *fabric;
1501        int ret;
1502
1503        pr_debug("TCM_VHOST fabric module %s on %s/%s"
1504                " on "UTS_RELEASE"\n", TCM_VHOST_VERSION, utsname()->sysname,
1505                utsname()->machine);
1506        /*
1507         * Register the top level struct config_item_type with TCM core
1508         */
1509        fabric = target_fabric_configfs_init(THIS_MODULE, "vhost");
1510        if (IS_ERR(fabric)) {
1511                pr_err("target_fabric_configfs_init() failed\n");
1512                return PTR_ERR(fabric);
1513        }
1514        /*
1515         * Setup fabric->tf_ops from our local tcm_vhost_ops
1516         */
1517        fabric->tf_ops = tcm_vhost_ops;
1518        /*
1519         * Setup default attribute lists for various fabric->tf_cit_tmpl
1520         */
1521        TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = tcm_vhost_wwn_attrs;
1522        TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = tcm_vhost_tpg_attrs;
1523        TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL;
1524        TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL;
1525        TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL;
1526        TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL;
1527        TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL;
1528        TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL;
1529        TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL;
1530        /*
1531         * Register the fabric for use within TCM
1532         */
1533        ret = target_fabric_configfs_register(fabric);
1534        if (ret < 0) {
1535                pr_err("target_fabric_configfs_register() failed"
1536                                " for TCM_VHOST\n");
1537                return ret;
1538        }
1539        /*
1540         * Setup our local pointer to *fabric
1541         */
1542        tcm_vhost_fabric_configfs = fabric;
1543        pr_debug("TCM_VHOST[0] - Set fabric -> tcm_vhost_fabric_configfs\n");
1544        return 0;
1545};
1546
1547static void tcm_vhost_deregister_configfs(void)
1548{
1549        if (!tcm_vhost_fabric_configfs)
1550                return;
1551
1552        target_fabric_configfs_deregister(tcm_vhost_fabric_configfs);
1553        tcm_vhost_fabric_configfs = NULL;
1554        pr_debug("TCM_VHOST[0] - Cleared tcm_vhost_fabric_configfs\n");
1555};
1556
1557static int __init tcm_vhost_init(void)
1558{
1559        int ret = -ENOMEM;
1560        /*
1561         * Use our own dedicated workqueue for submitting I/O into
1562         * target core to avoid contention within system_wq.
1563         */
1564        tcm_vhost_workqueue = alloc_workqueue("tcm_vhost", 0, 0);
1565        if (!tcm_vhost_workqueue)
1566                goto out;
1567
1568        ret = vhost_scsi_register();
1569        if (ret < 0)
1570                goto out_destroy_workqueue;
1571
1572        ret = tcm_vhost_register_configfs();
1573        if (ret < 0)
1574                goto out_vhost_scsi_deregister;
1575
1576        return 0;
1577
1578out_vhost_scsi_deregister:
1579        vhost_scsi_deregister();
1580out_destroy_workqueue:
1581        destroy_workqueue(tcm_vhost_workqueue);
1582out:
1583        return ret;
1584};
1585
1586static void tcm_vhost_exit(void)
1587{
1588        tcm_vhost_deregister_configfs();
1589        vhost_scsi_deregister();
1590        destroy_workqueue(tcm_vhost_workqueue);
1591};
1592
1593MODULE_DESCRIPTION("TCM_VHOST series fabric driver");
1594MODULE_LICENSE("GPL");
1595module_init(tcm_vhost_init);
1596module_exit(tcm_vhost_exit);
1597
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.