/*
 * vhost_scsi host device
 *
 * Copyright IBM, Corp. 2011
 *
 * Authors:
 *  Stefan Hajnoczi   <stefanha@linux.vnet.ibm.com>
 *
 * Changes for QEMU mainline + tcm_vhost kernel upstream:
 *  Nicholas Bellinger <nab@risingtidesystems.com>
 *
 * This work is licensed under the terms of the GNU LGPL, version 2 or later.
 * See the COPYING.LIB file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include <linux/vhost.h>
#include <sys/ioctl.h>
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "monitor/monitor.h"
#include "migration/blocker.h"
#include "hw/virtio/vhost-scsi.h"
#include "hw/virtio/vhost.h"
#include "hw/virtio/virtio-scsi.h"
#include "hw/virtio/virtio-bus.h"
#include "hw/fw-path-provider.h"
#include "hw/qdev-properties.h"
#include "qemu/cutils.h"
#include "sysemu/sysemu.h"

/* Features supported by host kernel. */
static const int kernel_feature_bits[] = {
    VIRTIO_F_NOTIFY_ON_EMPTY,
    VIRTIO_RING_F_INDIRECT_DESC,
    VIRTIO_RING_F_EVENT_IDX,
    VIRTIO_SCSI_F_HOTPLUG,
    VIRTIO_F_RING_RESET,
    VHOST_INVALID_FEATURE_BIT
};

static int vhost_scsi_set_endpoint(VHostSCSI *s)
{
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
    const VhostOps *vhost_ops = vsc->dev.vhost_ops;
    struct vhost_scsi_target backend;
    int ret;

    memset(&backend, 0, sizeof(backend));
    pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn);
    ret = vhost_ops->vhost_scsi_set_endpoint(&vsc->dev, &backend);
    if (ret < 0) {
        return -errno;
    }
    return 0;
}

static void vhost_scsi_clear_endpoint(VHostSCSI *s)
{
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
    struct vhost_scsi_target backend;
    const VhostOps *vhost_ops = vsc->dev.vhost_ops;

    memset(&backend, 0, sizeof(backend));
    pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn);
    vhost_ops->vhost_scsi_clear_endpoint(&vsc->dev, &backend);
}

static int vhost_scsi_start(VHostSCSI *s)
{
    int ret, abi_version;
    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
    const VhostOps *vhost_ops = vsc->dev.vhost_ops;
    Error *local_err = NULL;

    ret = vhost_ops->vhost_scsi_get_abi_version(&vsc->dev, &abi_version);
    if (ret < 0) {
        return -errno;
    }
    if (abi_version > VHOST_SCSI_ABI_VERSION) {
        error_report("vhost-scsi: The running tcm_vhost kernel abi_version:"
                     " %d is greater than vhost_scsi userspace supports: %d,"
                     " please upgrade your version of QEMU", abi_version,
                     VHOST_SCSI_ABI_VERSION);
        return -ENOSYS;
    }

    ret = vhost_scsi_common_start(vsc, &local_err);
    if (ret < 0) {
        error_reportf_err(local_err, "Error starting vhost-scsi: ");
        return ret;
    }

    ret = vhost_scsi_set_endpoint(s);
    if (ret < 0) {
        error_report("Error setting vhost-scsi endpoint");
        vhost_scsi_common_stop(vsc);
    }

    return ret;
}

static void vhost_scsi_stop(VHostSCSI *s)
{
    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);

    vhost_scsi_clear_endpoint(s);
    vhost_scsi_common_stop(vsc);
}

static void vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val)
{
    VHostSCSI *s = VHOST_SCSI(vdev);
    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
    bool start = (val & VIRTIO_CONFIG_S_DRIVER_OK);

    if (!vdev->vm_running) {
        start = false;
    }

    if (vhost_dev_is_started(&vsc->dev) == start) {
        return;
    }

    if (start) {
        int ret;

        ret = vhost_scsi_start(s);
        if (ret < 0) {
            error_report("unable to start vhost-scsi: %s", strerror(-ret));
            exit(1);
        }
    } else {
        vhost_scsi_stop(s);
    }
}

static void vhost_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
}

static int vhost_scsi_pre_save(void *opaque)
{
    VHostSCSICommon *vsc = opaque;

    /* At this point, backend must be stopped, otherwise
     * it might keep writing to memory. */
    assert(!vhost_dev_is_started(&vsc->dev));

    return 0;
}

static const VMStateDescription vmstate_virtio_vhost_scsi = {
    .name = "virtio-vhost_scsi",
    .minimum_version_id = 1,
    .version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_VIRTIO_DEVICE,
        VMSTATE_END_OF_LIST()
    },
    .pre_save = vhost_scsi_pre_save,
};

static int vhost_scsi_set_workers(VHostSCSICommon *vsc, bool per_virtqueue)
{
    struct vhost_dev *dev = &vsc->dev;
    struct vhost_vring_worker vq_worker;
    struct vhost_worker_state worker;
    int i, ret;

    /* Use default worker */
    if (!per_virtqueue || dev->nvqs == VHOST_SCSI_VQ_NUM_FIXED + 1) {
        return 0;
    }

    /*
     * ctl/evt share the first worker since it will be rare for them
     * to send cmds while IO is running.
     */
    for (i = VHOST_SCSI_VQ_NUM_FIXED + 1; i < dev->nvqs; i++) {
        memset(&worker, 0, sizeof(worker));

        ret = dev->vhost_ops->vhost_new_worker(dev, &worker);
        if (ret == -ENOTTY) {
            /*
             * worker ioctls are not implemented so just ignore and
             * and continue device setup.
             */
            warn_report("vhost-scsi: Backend supports a single worker. "
                        "Ignoring worker_per_virtqueue=true setting.");
            ret = 0;
            break;
        } else if (ret) {
            break;
        }

        memset(&vq_worker, 0, sizeof(vq_worker));
        vq_worker.worker_id = worker.worker_id;
        vq_worker.index = i;

        ret = dev->vhost_ops->vhost_attach_vring_worker(dev, &vq_worker);
        if (ret == -ENOTTY) {
            /*
             * It's a bug for the kernel to have supported the worker creation
             * ioctl but not attach.
             */
            dev->vhost_ops->vhost_free_worker(dev, &worker);
            break;
        } else if (ret) {
            break;
        }
    }

    return ret;
}

static void vhost_scsi_realize(DeviceState *dev, Error **errp)
{
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(dev);
    Error *err = NULL;
    int vhostfd = -1;
    int ret;
    struct vhost_virtqueue *vqs = NULL;

    if (!vs->conf.wwpn) {
        error_setg(errp, "vhost-scsi: missing wwpn");
        return;
    }

    if (vs->conf.vhostfd) {
        vhostfd = monitor_fd_param(monitor_cur(), vs->conf.vhostfd, errp);
        if (vhostfd == -1) {
            error_prepend(errp, "vhost-scsi: unable to parse vhostfd: ");
            return;
        }
    } else {
        vhostfd = open("/dev/vhost-scsi", O_RDWR);
        if (vhostfd < 0) {
            error_setg(errp, "vhost-scsi: open vhost char device failed: %s",
                       strerror(errno));
            return;
        }
    }

    virtio_scsi_common_realize(dev,
                               vhost_dummy_handle_output,
                               vhost_dummy_handle_output,
                               vhost_dummy_handle_output,
                               &err);
    if (err != NULL) {
        error_propagate(errp, err);
        goto close_fd;
    }

    if (!vsc->migratable) {
        error_setg(&vsc->migration_blocker,
                "vhost-scsi does not support migration in all cases. "
                "When external environment supports it (Orchestrator migrates "
                "target SCSI device state or use shared storage over network), "
                "set 'migratable' property to true to enable migration.");
        if (migrate_add_blocker_normal(&vsc->migration_blocker, errp) < 0) {
            goto free_virtio;
        }
    }

    vsc->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues;
    vqs = g_new0(struct vhost_virtqueue, vsc->dev.nvqs);
    vsc->dev.vqs = vqs;
    vsc->dev.vq_index = 0;
    vsc->dev.backend_features = 0;

    ret = vhost_dev_init(&vsc->dev, (void *)(uintptr_t)vhostfd,
                         VHOST_BACKEND_TYPE_KERNEL, 0, errp);
    if (ret < 0) {
        /*
         * vhost_dev_init calls vhost_dev_cleanup on error, which closes
         * vhostfd, don't double close it.
         */
        vhostfd = -1;
        goto free_vqs;
    }

    ret = vhost_scsi_set_workers(vsc, vs->conf.worker_per_virtqueue);
    if (ret < 0) {
        error_setg(errp, "vhost-scsi: vhost worker setup failed: %s",
                   strerror(-ret));
        goto free_vqs;
    }

    /* At present, channel and lun both are 0 for bootable vhost-scsi disk */
    vsc->channel = 0;
    vsc->lun = 0;
    /* Note: we can also get the minimum tpgt from kernel */
    vsc->target = vs->conf.boot_tpgt;

    return;

 free_vqs:
    g_free(vqs);
    if (!vsc->migratable) {
        migrate_del_blocker(&vsc->migration_blocker);
    }
 free_virtio:
    virtio_scsi_common_unrealize(dev);
 close_fd:
    if (vhostfd >= 0) {
        close(vhostfd);
    }
    return;
}

static void vhost_scsi_unrealize(DeviceState *dev)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(dev);
    struct vhost_virtqueue *vqs = vsc->dev.vqs;

    if (!vsc->migratable) {
        migrate_del_blocker(&vsc->migration_blocker);
    }

    /* This will stop vhost backend. */
    vhost_scsi_set_status(vdev, 0);

    vhost_dev_cleanup(&vsc->dev);
    g_free(vqs);

    virtio_scsi_common_unrealize(dev);
}

static struct vhost_dev *vhost_scsi_get_vhost(VirtIODevice *vdev)
{
    VHostSCSI *s = VHOST_SCSI(vdev);
    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
    return &vsc->dev;
}

static Property vhost_scsi_properties[] = {
    DEFINE_PROP_STRING("vhostfd", VirtIOSCSICommon, conf.vhostfd),
    DEFINE_PROP_STRING("wwpn", VirtIOSCSICommon, conf.wwpn),
    DEFINE_PROP_UINT32("boot_tpgt", VirtIOSCSICommon, conf.boot_tpgt, 0),
    DEFINE_PROP_UINT32("num_queues", VirtIOSCSICommon, conf.num_queues,
                       VIRTIO_SCSI_AUTO_NUM_QUEUES),
    DEFINE_PROP_UINT32("virtqueue_size", VirtIOSCSICommon, conf.virtqueue_size,
                       128),
    DEFINE_PROP_BOOL("seg_max_adjust", VirtIOSCSICommon, conf.seg_max_adjust,
                      true),
    DEFINE_PROP_UINT32("max_sectors", VirtIOSCSICommon, conf.max_sectors,
                       0xFFFF),
    DEFINE_PROP_UINT32("cmd_per_lun", VirtIOSCSICommon, conf.cmd_per_lun, 128),
    DEFINE_PROP_BIT64("t10_pi", VHostSCSICommon, host_features,
                                                 VIRTIO_SCSI_F_T10_PI,
                                                 false),
    DEFINE_PROP_BOOL("migratable", VHostSCSICommon, migratable, false),
    DEFINE_PROP_BOOL("worker_per_virtqueue", VirtIOSCSICommon,
                     conf.worker_per_virtqueue, false),
    DEFINE_PROP_END_OF_LIST(),
};

static void vhost_scsi_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
    FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(klass);

    device_class_set_props(dc, vhost_scsi_properties);
    dc->vmsd = &vmstate_virtio_vhost_scsi;
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
    vdc->realize = vhost_scsi_realize;
    vdc->unrealize = vhost_scsi_unrealize;
    vdc->get_features = vhost_scsi_common_get_features;
    vdc->set_config = vhost_scsi_common_set_config;
    vdc->set_status = vhost_scsi_set_status;
    vdc->get_vhost = vhost_scsi_get_vhost;
    fwc->get_dev_path = vhost_scsi_common_get_fw_dev_path;
}

static void vhost_scsi_instance_init(Object *obj)
{
    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(obj);

    vsc->feature_bits = kernel_feature_bits;

    device_add_bootindex_property(obj, &vsc->bootindex, "bootindex", NULL,
                                  DEVICE(vsc));
}

static const TypeInfo vhost_scsi_info = {
    .name = TYPE_VHOST_SCSI,
    .parent = TYPE_VHOST_SCSI_COMMON,
    .instance_size = sizeof(VHostSCSI),
    .class_init = vhost_scsi_class_init,
    .instance_init = vhost_scsi_instance_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_FW_PATH_PROVIDER },
        { }
    },
};

static void virtio_register_types(void)
{
    type_register_static(&vhost_scsi_info);
}

type_init(virtio_register_types)
