summaryrefslogtreecommitdiffstats
path: root/linux-user/xtensa/target_signal.h
Commit message (Expand)AuthorAgeFilesLines
* linux-user: move generic signal definitions to generic/signal.hLaurent Vivier2018-06-041-0/+2
* linux-user: move get_sp_from_cpustate() to target_cpu.hLaurent Vivier2018-06-041-6/+0Star
* linux-user: define TARGET_ARCH_HAS_SETUP_FRAMELaurent Vivier2018-04-301-4/+0Star
* linux-user: move xtensa signal.c parts to xtensa directoryLaurent Vivier2018-04-301-0/+3
* target/xtensa: add linux-user supportMax Filippov2018-03-161-0/+28
'>78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
/*
 * vhost-scsi-common
 *
 * Copyright (c) 2016 Nutanix Inc. All rights reserved.
 *
 * Author:
 *  Felipe Franciosi <felipe@nutanix.com>
 *
 * This work is largely based on the "vhost-scsi" implementation by:
 *  Stefan Hajnoczi    <stefanha@linux.vnet.ibm.com>
 *  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 "qemu/error-report.h"
#include "qemu/module.h"
#include "hw/virtio/vhost.h"
#include "hw/virtio/vhost-scsi-common.h"
#include "hw/virtio/virtio-scsi.h"
#include "hw/virtio/virtio-bus.h"
#include "hw/virtio/virtio-access.h"
#include "hw/fw-path-provider.h"

int vhost_scsi_common_start(VHostSCSICommon *vsc)
{
    int ret, i;
    VirtIODevice *vdev = VIRTIO_DEVICE(vsc);
    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);

    if (!k->set_guest_notifiers) {
        error_report("binding does not support guest notifiers");
        return -ENOSYS;
    }

    ret = vhost_dev_enable_notifiers(&vsc->dev, vdev);
    if (ret < 0) {
        return ret;
    }

    ret = k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, true);
    if (ret < 0) {
        error_report("Error binding guest notifier");
        goto err_host_notifiers;
    }

    vsc->dev.acked_features = vdev->guest_features;
    ret = vhost_dev_start(&vsc->dev, vdev);
    if (ret < 0) {
        error_report("Error start vhost dev");
        goto err_guest_notifiers;
    }

    /* guest_notifier_mask/pending not used yet, so just unmask
     * everything here.  virtio-pci will do the right thing by
     * enabling/disabling irqfd.
     */
    for (i = 0; i < vsc->dev.nvqs; i++) {
        vhost_virtqueue_mask(&vsc->dev, vdev, vsc->dev.vq_index + i, false);
    }

    return ret;

err_guest_notifiers:
    k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
err_host_notifiers:
    vhost_dev_disable_notifiers(&vsc->dev, vdev);
    return ret;
}

void vhost_scsi_common_stop(VHostSCSICommon *vsc)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(vsc);
    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
    int ret = 0;

    vhost_dev_stop(&vsc->dev, vdev);

    if (k->set_guest_notifiers) {
        ret = k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
        if (ret < 0) {
                error_report("vhost guest notifier cleanup failed: %d", ret);
        }
    }
    assert(ret >= 0);

    vhost_dev_disable_notifiers(&vsc->dev, vdev);
}

uint64_t vhost_scsi_common_get_features(VirtIODevice *vdev, uint64_t features,
                                        Error **errp)
{
    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(vdev);

    /* Turn on predefined features supported by this device */
    features |= vsc->host_features;

    return vhost_get_features(&vsc->dev, vsc->feature_bits, features);
}

void vhost_scsi_common_set_config(VirtIODevice *vdev, const uint8_t *config)
{
    VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config;
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);

    if ((uint32_t)virtio_ldl_p(vdev, &scsiconf->sense_size) != vs->sense_size ||
        (uint32_t)virtio_ldl_p(vdev, &scsiconf->cdb_size) != vs->cdb_size) {
        error_report("vhost-scsi does not support changing the sense data and "
                     "CDB sizes");
        exit(1);
    }
}

/*
 * Implementation of an interface to adjust firmware path
 * for the bootindex property handling.
 */
char *vhost_scsi_common_get_fw_dev_path(FWPathProvider *p, BusState *bus,
                                        DeviceState *dev)
{
    VHostSCSICommon *vsc = VHOST_SCSI_COMMON(dev);
    /* format: /channel@channel/vhost-scsi@target,lun */
    return g_strdup_printf("/channel@%x/%s@%x,%x", vsc->channel,
                           qdev_fw_name(dev), vsc->target, vsc->lun);
}

static const TypeInfo vhost_scsi_common_info = {
    .name = TYPE_VHOST_SCSI_COMMON,
    .parent = TYPE_VIRTIO_SCSI_COMMON,
    .instance_size = sizeof(VHostSCSICommon),
    .abstract = true,
};

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

type_init(virtio_register_types)