/*
 * QEMU S390 virtio target
 *
 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "hw/hw.h"
#include "sysemu/block-backend.h"
#include "sysemu/sysemu.h"
#include "hw/boards.h"
#include "monitor/monitor.h"
#include "hw/loader.h"
#include "elf.h"
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-rng.h"
#include "hw/virtio/virtio-serial.h"
#include "hw/virtio/virtio-net.h"
#include "hw/virtio/vhost-scsi.h"
#include "hw/sysbus.h"
#include "sysemu/kvm.h"

#include "hw/s390x/s390-virtio-bus.h"
#include "hw/virtio/virtio-bus.h"

/* #define DEBUG_S390 */

#ifdef DEBUG_S390
#define DPRINTF(fmt, ...) \
    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...) \
    do { } while (0)
#endif

static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size,
                                VirtIOS390Device *dev);

static const TypeInfo s390_virtio_bus_info = {
    .name = TYPE_S390_VIRTIO_BUS,
    .parent = TYPE_BUS,
    .instance_size = sizeof(VirtIOS390Bus),
};

static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev);

/* length of VirtIO device pages */
const hwaddr virtio_size = S390_DEVICE_PAGES * TARGET_PAGE_SIZE;

static void s390_virtio_bus_reset(void *opaque)
{
    VirtIOS390Bus *bus = opaque;
    bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
}

void s390_virtio_reset_idx(VirtIOS390Device *dev)
{
    int i;
    hwaddr idx_addr;
    uint8_t num_vq;

    num_vq = s390_virtio_device_num_vq(dev);
    for (i = 0; i < num_vq; i++) {
        idx_addr = virtio_queue_get_avail_addr(dev->vdev, i) +
            VIRTIO_VRING_AVAIL_IDX_OFFS;
        address_space_stw(&address_space_memory, idx_addr, 0,
                          MEMTXATTRS_UNSPECIFIED, NULL);
        idx_addr = virtio_queue_get_avail_addr(dev->vdev, i) +
            virtio_queue_get_avail_size(dev->vdev, i);
        address_space_stw(&address_space_memory, idx_addr, 0,
                          MEMTXATTRS_UNSPECIFIED, NULL);
        idx_addr = virtio_queue_get_used_addr(dev->vdev, i) +
            VIRTIO_VRING_USED_IDX_OFFS;
        address_space_stw(&address_space_memory, idx_addr, 0,
                          MEMTXATTRS_UNSPECIFIED, NULL);
        idx_addr = virtio_queue_get_used_addr(dev->vdev, i) +
            virtio_queue_get_used_size(dev->vdev, i);
        address_space_stw(&address_space_memory, idx_addr, 0,
                          MEMTXATTRS_UNSPECIFIED, NULL);
    }
}

VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
{
    VirtIOS390Bus *bus;
    BusState *_bus;
    DeviceState *dev;

    /* Create bridge device */
    dev = qdev_create(NULL, "s390-virtio-bridge");
    qdev_init_nofail(dev);

    /* Create bus on bridge device */

    _bus = qbus_create(TYPE_S390_VIRTIO_BUS, dev, "s390-virtio");
    bus = DO_UPCAST(VirtIOS390Bus, bus, _bus);

    bus->dev_page = *ram_size;
    bus->dev_offs = bus->dev_page;
    bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;

    /* Enable hotplugging */
    qbus_set_hotplug_handler(_bus, dev, &error_abort);

    /* Allocate RAM for VirtIO device pages (descriptors, queues, rings) */
    *ram_size += S390_DEVICE_PAGES * TARGET_PAGE_SIZE;

    qemu_register_reset(s390_virtio_bus_reset, bus);
    return bus;
}

static void s390_virtio_device_init(VirtIOS390Device *dev,
                                    VirtIODevice *vdev)
{
    VirtIOS390Bus *bus;
    int dev_len;

    bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
    dev->vdev = vdev;
    dev->dev_offs = bus->dev_offs;
    dev->feat_len = sizeof(uint32_t); /* always keep 32 bits features */

    dev_len = VIRTIO_DEV_OFFS_CONFIG;
    dev_len += s390_virtio_device_num_vq(dev) * VIRTIO_VQCONFIG_LEN;
    dev_len += dev->feat_len * 2;
    dev_len += virtio_bus_get_vdev_config_len(&dev->bus);

    bus->dev_offs += dev_len;

    dev->host_features = virtio_bus_get_vdev_features(&dev->bus,
                                                      dev->host_features);
    s390_virtio_device_sync(dev);
    s390_virtio_reset_idx(dev);
    if (dev->qdev.hotplugged) {
        s390_virtio_irq(VIRTIO_PARAM_DEV_ADD, dev->dev_offs);
    }
}

static void s390_virtio_net_realize(VirtIOS390Device *s390_dev, Error **errp)
{
    DeviceState *qdev = DEVICE(s390_dev);
    VirtIONetS390 *dev = VIRTIO_NET_S390(s390_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
    Error *err = NULL;

    virtio_net_set_config_size(&dev->vdev, s390_dev->host_features);
    virtio_net_set_netclient_name(&dev->vdev, qdev->id,
                                  object_get_typename(OBJECT(qdev)));
    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
}

static void s390_virtio_net_instance_init(Object *obj)
{
    VirtIONetS390 *dev = VIRTIO_NET_S390(obj);

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_NET);
    object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
                              "bootindex", &error_abort);
}

static void s390_virtio_blk_realize(VirtIOS390Device *s390_dev, Error **errp)
{
    VirtIOBlkS390 *dev = VIRTIO_BLK_S390(s390_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
    Error *err = NULL;

    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
}

static void s390_virtio_blk_instance_init(Object *obj)
{
    VirtIOBlkS390 *dev = VIRTIO_BLK_S390(obj);

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_BLK);
    object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
                              &error_abort);
    object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
                              "bootindex", &error_abort);
}

static void s390_virtio_serial_realize(VirtIOS390Device *s390_dev, Error **errp)
{
    VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(s390_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
    DeviceState *qdev = DEVICE(s390_dev);
    Error *err = NULL;
    VirtIOS390Bus *bus;
    char *bus_name;

    bus = DO_UPCAST(VirtIOS390Bus, bus, qdev->parent_bus);

    /*
     * For command line compatibility, this sets the virtio-serial-device bus
     * name as before.
     */
    if (qdev->id) {
        bus_name = g_strdup_printf("%s.0", qdev->id);
        virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name);
        g_free(bus_name);
    }

    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
    bus->console = s390_dev;
}

static void s390_virtio_serial_instance_init(Object *obj)
{
    VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(obj);

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_SERIAL);
}

static void s390_virtio_scsi_realize(VirtIOS390Device *s390_dev, Error **errp)
{
    VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(s390_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
    DeviceState *qdev = DEVICE(s390_dev);
    Error *err = NULL;
    char *bus_name;

    /*
     * For command line compatibility, this sets the virtio-scsi-device bus
     * name as before.
     */
    if (qdev->id) {
        bus_name = g_strdup_printf("%s.0", qdev->id);
        virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name);
        g_free(bus_name);
    }

    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
}

static void s390_virtio_scsi_instance_init(Object *obj)
{
    VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(obj);

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_SCSI);
}

#ifdef CONFIG_VHOST_SCSI
static void s390_vhost_scsi_realize(VirtIOS390Device *s390_dev, Error **errp)
{
    VHostSCSIS390 *dev = VHOST_SCSI_S390(s390_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
    Error *err = NULL;

    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
}

static void s390_vhost_scsi_instance_init(Object *obj)
{
    VHostSCSIS390 *dev = VHOST_SCSI_S390(obj);

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VHOST_SCSI);
}
#endif


static void s390_virtio_rng_realize(VirtIOS390Device *s390_dev, Error **errp)
{
    VirtIORNGS390 *dev = VIRTIO_RNG_S390(s390_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
    Error *err = NULL;

    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    object_property_set_link(OBJECT(dev),
                             OBJECT(dev->vdev.conf.rng), "rng",
                             NULL);

    s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
}

static void s390_virtio_rng_instance_init(Object *obj)
{
    VirtIORNGS390 *dev = VIRTIO_RNG_S390(obj);

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_RNG);
    object_property_add_alias(obj, "rng", OBJECT(&dev->vdev),
                              "rng", &error_abort);
}

static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
{
    ram_addr_t token_off;

    token_off = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
                (vq * VIRTIO_VQCONFIG_LEN) +
                VIRTIO_VQCONFIG_OFFS_TOKEN;

    return address_space_ldq_be(&address_space_memory, token_off,
                                MEMTXATTRS_UNSPECIFIED, NULL);
}

static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev)
{
    VirtIODevice *vdev = dev->vdev;
    int num_vq;

    for (num_vq = 0; num_vq < VIRTIO_PCI_QUEUE_MAX; num_vq++) {
        if (!virtio_queue_get_num(vdev, num_vq)) {
            break;
        }
    }

    return num_vq;
}

static ram_addr_t s390_virtio_next_ring(VirtIOS390Bus *bus)
{
    ram_addr_t r = bus->next_ring;

    bus->next_ring += VIRTIO_RING_LEN;
    return r;
}

void s390_virtio_device_sync(VirtIOS390Device *dev)
{
    VirtIOS390Bus *bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
    ram_addr_t cur_offs;
    uint8_t num_vq;
    int i;

    virtio_reset(dev->vdev);

    /* Sync dev space */
    address_space_stb(&address_space_memory,
                      dev->dev_offs + VIRTIO_DEV_OFFS_TYPE,
                      dev->vdev->device_id,
                      MEMTXATTRS_UNSPECIFIED,
                      NULL);

    address_space_stb(&address_space_memory,
                      dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ,
                      s390_virtio_device_num_vq(dev),
                      MEMTXATTRS_UNSPECIFIED,
                      NULL);
    address_space_stb(&address_space_memory,
                      dev->dev_offs + VIRTIO_DEV_OFFS_FEATURE_LEN,
                      dev->feat_len,
                      MEMTXATTRS_UNSPECIFIED,
                      NULL);

    address_space_stb(&address_space_memory,
                      dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG_LEN,
                      dev->vdev->config_len,
                      MEMTXATTRS_UNSPECIFIED,
                      NULL);

    num_vq = s390_virtio_device_num_vq(dev);
    address_space_stb(&address_space_memory,
                      dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, num_vq,
                      MEMTXATTRS_UNSPECIFIED, NULL);

    /* Sync virtqueues */
    for (i = 0; i < num_vq; i++) {
        ram_addr_t vq = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
                        (i * VIRTIO_VQCONFIG_LEN);
        ram_addr_t vring;

        vring = s390_virtio_next_ring(bus);
        virtio_queue_set_addr(dev->vdev, i, vring);
        virtio_queue_set_vector(dev->vdev, i, i);
        address_space_stq_be(&address_space_memory,
                             vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring,
                             MEMTXATTRS_UNSPECIFIED, NULL);
        address_space_stw_be(&address_space_memory,
                             vq + VIRTIO_VQCONFIG_OFFS_NUM,
                             virtio_queue_get_num(dev->vdev, i),
                             MEMTXATTRS_UNSPECIFIED,
                             NULL);
    }

    cur_offs = dev->dev_offs;
    cur_offs += VIRTIO_DEV_OFFS_CONFIG;
    cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;

    /* Sync feature bitmap */
    address_space_stl_le(&address_space_memory, cur_offs, dev->host_features,
                         MEMTXATTRS_UNSPECIFIED, NULL);

    dev->feat_offs = cur_offs + dev->feat_len;
    cur_offs += dev->feat_len * 2;

    /* Sync config space */
    virtio_bus_get_vdev_config(&dev->bus, dev->vdev->config);

    cpu_physical_memory_write(cur_offs,
                              dev->vdev->config, dev->vdev->config_len);
    cur_offs += dev->vdev->config_len;
}

void s390_virtio_device_update_status(VirtIOS390Device *dev)
{
    VirtIODevice *vdev = dev->vdev;
    uint32_t features;

    virtio_set_status(vdev,
                      address_space_ldub(&address_space_memory,
                                         dev->dev_offs + VIRTIO_DEV_OFFS_STATUS,
                                         MEMTXATTRS_UNSPECIFIED, NULL));

    /* Update guest supported feature bitmap */

    features = bswap32(address_space_ldl_be(&address_space_memory,
                                            dev->feat_offs,
                                            MEMTXATTRS_UNSPECIFIED, NULL));
    virtio_set_features(vdev, features);
}

/* Find a device by vring address */
VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
                                             ram_addr_t mem,
                                             int *vq_num)
{
    BusChild *kid;
    int i;

    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
        VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;

        for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
            if (!virtio_queue_get_addr(dev->vdev, i))
                break;
            if (virtio_queue_get_addr(dev->vdev, i) == mem) {
                if (vq_num) {
                    *vq_num = i;
                }
                return dev;
            }
        }
    }

    return NULL;
}

/* Find a device by device descriptor location */
VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem)
{
    BusChild *kid;

    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
        VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
        if (dev->dev_offs == mem) {
            return dev;
        }
    }

    return NULL;
}

/* DeviceState to VirtIOS390Device. Note: used on datapath,
 * be careful and test performance if you change this.
 */
static inline VirtIOS390Device *to_virtio_s390_device_fast(DeviceState *d)
{
    return container_of(d, VirtIOS390Device, qdev);
}

/* DeviceState to VirtIOS390Device. TODO: use QOM. */
static inline VirtIOS390Device *to_virtio_s390_device(DeviceState *d)
{
    return container_of(d, VirtIOS390Device, qdev);
}

static void virtio_s390_notify(DeviceState *d, uint16_t vector)
{
    VirtIOS390Device *dev = to_virtio_s390_device_fast(d);
    uint64_t token = s390_virtio_device_vq_token(dev, vector);

    s390_virtio_irq(0, token);
}

static unsigned virtio_s390_get_features(DeviceState *d)
{
    VirtIOS390Device *dev = to_virtio_s390_device(d);
    return dev->host_features;
}

/**************** S390 Virtio Bus Device Descriptions *******************/

static Property s390_virtio_net_properties[] = {
    DEFINE_VIRTIO_NET_FEATURES(VirtIOS390Device, host_features),
    DEFINE_PROP_END_OF_LIST(),
};

static void s390_virtio_net_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);

    k->realize = s390_virtio_net_realize;
    dc->props = s390_virtio_net_properties;
    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}

static const TypeInfo s390_virtio_net = {
    .name          = TYPE_VIRTIO_NET_S390,
    .parent        = TYPE_VIRTIO_S390_DEVICE,
    .instance_size = sizeof(VirtIONetS390),
    .instance_init = s390_virtio_net_instance_init,
    .class_init    = s390_virtio_net_class_init,
};

static void s390_virtio_blk_class_init(ObjectClass *klass, void *data)
{
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
    DeviceClass *dc = DEVICE_CLASS(klass);

    k->realize = s390_virtio_blk_realize;
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}

static const TypeInfo s390_virtio_blk = {
    .name          = "virtio-blk-s390",
    .parent        = TYPE_VIRTIO_S390_DEVICE,
    .instance_size = sizeof(VirtIOBlkS390),
    .instance_init = s390_virtio_blk_instance_init,
    .class_init    = s390_virtio_blk_class_init,
};

static Property s390_virtio_serial_properties[] = {
    DEFINE_PROP_END_OF_LIST(),
};

static void s390_virtio_serial_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);

    k->realize = s390_virtio_serial_realize;
    dc->props = s390_virtio_serial_properties;
    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
}

static const TypeInfo s390_virtio_serial = {
    .name          = TYPE_VIRTIO_SERIAL_S390,
    .parent        = TYPE_VIRTIO_S390_DEVICE,
    .instance_size = sizeof(VirtIOSerialS390),
    .instance_init = s390_virtio_serial_instance_init,
    .class_init    = s390_virtio_serial_class_init,
};

static void s390_virtio_rng_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);

    k->realize = s390_virtio_rng_realize;
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}

static const TypeInfo s390_virtio_rng = {
    .name          = TYPE_VIRTIO_RNG_S390,
    .parent        = TYPE_VIRTIO_S390_DEVICE,
    .instance_size = sizeof(VirtIORNGS390),
    .instance_init = s390_virtio_rng_instance_init,
    .class_init    = s390_virtio_rng_class_init,
};

static void s390_virtio_busdev_realize(DeviceState *dev, Error **errp)
{
    VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
    VirtIOS390DeviceClass *_info = VIRTIO_S390_DEVICE_GET_CLASS(dev);

    virtio_s390_bus_new(&_dev->bus, sizeof(_dev->bus), _dev);

    _info->realize(_dev, errp);
}

static void s390_virtio_busdev_reset(DeviceState *dev)
{
    VirtIOS390Device *_dev = (VirtIOS390Device *)dev;

    virtio_reset(_dev->vdev);
}

static Property virtio_s390_properties[] = {
    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
    DEFINE_PROP_END_OF_LIST(),
};

static void virtio_s390_device_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->props = virtio_s390_properties;
    dc->realize = s390_virtio_busdev_realize;
    dc->bus_type = TYPE_S390_VIRTIO_BUS;
    dc->reset = s390_virtio_busdev_reset;
}

static const TypeInfo virtio_s390_device_info = {
    .name = TYPE_VIRTIO_S390_DEVICE,
    .parent = TYPE_DEVICE,
    .instance_size = sizeof(VirtIOS390Device),
    .class_init = virtio_s390_device_class_init,
    .class_size = sizeof(VirtIOS390DeviceClass),
    .abstract = true,
};

static Property s390_virtio_scsi_properties[] = {
    DEFINE_VIRTIO_SCSI_FEATURES(VirtIOS390Device, host_features),
    DEFINE_PROP_END_OF_LIST(),
};

static void s390_virtio_scsi_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);

    k->realize = s390_virtio_scsi_realize;
    dc->props = s390_virtio_scsi_properties;
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}

static const TypeInfo s390_virtio_scsi = {
    .name          = TYPE_VIRTIO_SCSI_S390,
    .parent        = TYPE_VIRTIO_S390_DEVICE,
    .instance_size = sizeof(VirtIOSCSIS390),
    .instance_init = s390_virtio_scsi_instance_init,
    .class_init    = s390_virtio_scsi_class_init,
};

#ifdef CONFIG_VHOST_SCSI
static void s390_vhost_scsi_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);

    k->realize = s390_vhost_scsi_realize;
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}

static const TypeInfo s390_vhost_scsi = {
    .name          = TYPE_VHOST_SCSI_S390,
    .parent        = TYPE_VIRTIO_S390_DEVICE,
    .instance_size = sizeof(VHostSCSIS390),
    .instance_init = s390_vhost_scsi_instance_init,
    .class_init    = s390_vhost_scsi_class_init,
};
#endif

/***************** S390 Virtio Bus Bridge Device *******************/
/* Only required to have the virtio bus as child in the system bus */

static int s390_virtio_bridge_init(SysBusDevice *dev)
{
    /* nothing */
    return 0;
}

static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data)
{
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
    DeviceClass *dc = DEVICE_CLASS(klass);

    k->init = s390_virtio_bridge_init;
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
}

static const TypeInfo s390_virtio_bridge_info = {
    .name          = "s390-virtio-bridge",
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(SysBusDevice),
    .class_init    = s390_virtio_bridge_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_HOTPLUG_HANDLER },
        { }
    }
};

/* virtio-s390-bus */

static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size,
                                VirtIOS390Device *dev)
{
    DeviceState *qdev = DEVICE(dev);
    char virtio_bus_name[] = "virtio-bus";

    qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_S390_BUS,
                        qdev, virtio_bus_name);
}

static void virtio_s390_bus_class_init(ObjectClass *klass, void *data)
{
    VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
    BusClass *bus_class = BUS_CLASS(klass);
    bus_class->max_dev = 1;
    k->notify = virtio_s390_notify;
    k->get_features = virtio_s390_get_features;
}

static const TypeInfo virtio_s390_bus_info = {
    .name          = TYPE_VIRTIO_S390_BUS,
    .parent        = TYPE_VIRTIO_BUS,
    .instance_size = sizeof(VirtioS390BusState),
    .class_init    = virtio_s390_bus_class_init,
};

static void s390_virtio_register_types(void)
{
    type_register_static(&virtio_s390_bus_info);
    type_register_static(&s390_virtio_bus_info);
    type_register_static(&virtio_s390_device_info);
    type_register_static(&s390_virtio_serial);
    type_register_static(&s390_virtio_blk);
    type_register_static(&s390_virtio_net);
    type_register_static(&s390_virtio_scsi);
#ifdef CONFIG_VHOST_SCSI
    type_register_static(&s390_vhost_scsi);
#endif
    type_register_static(&s390_virtio_rng);
    type_register_static(&s390_virtio_bridge_info);
}

type_init(s390_virtio_register_types)
