/*
 * 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_used_addr(dev->vdev, i) +
            VIRTIO_VRING_USED_IDX_OFFS;
        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_COMMON_FEATURES(VirtIOS390Device, host_features),
    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 Property s390_virtio_rng_properties[] = {
    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
    DEFINE_PROP_END_OF_LIST(),
};

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;
    dc->props = s390_virtio_rng_properties;
    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 void virtio_s390_device_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    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_COMMON_FEATURES(VirtIOS390Device, host_features),
    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 Property s390_vhost_scsi_properties[] = {
    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
    DEFINE_PROP_END_OF_LIST(),
};

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;
    dc->props = s390_vhost_scsi_properties;
    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)
