qemu/hw/s390x/s390-virtio-bus.c
<<
>>
Prefs
   1/*
   2 * QEMU S390 virtio target
   3 *
   4 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include "hw/hw.h"
  21#include "block/block.h"
  22#include "sysemu/sysemu.h"
  23#include "hw/boards.h"
  24#include "monitor/monitor.h"
  25#include "hw/loader.h"
  26#include "elf.h"
  27#include "hw/virtio/virtio.h"
  28#include "hw/virtio/virtio-rng.h"
  29#include "hw/virtio/virtio-serial.h"
  30#include "hw/virtio/virtio-net.h"
  31#include "hw/virtio/vhost-scsi.h"
  32#include "hw/sysbus.h"
  33#include "sysemu/kvm.h"
  34
  35#include "hw/s390x/s390-virtio-bus.h"
  36#include "hw/virtio/virtio-bus.h"
  37
  38/* #define DEBUG_S390 */
  39
  40#ifdef DEBUG_S390
  41#define DPRINTF(fmt, ...) \
  42    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
  43#else
  44#define DPRINTF(fmt, ...) \
  45    do { } while (0)
  46#endif
  47
  48static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size,
  49                                VirtIOS390Device *dev);
  50
  51static const TypeInfo s390_virtio_bus_info = {
  52    .name = TYPE_S390_VIRTIO_BUS,
  53    .parent = TYPE_BUS,
  54    .instance_size = sizeof(VirtIOS390Bus),
  55};
  56
  57static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev);
  58
  59/* length of VirtIO device pages */
  60const hwaddr virtio_size = S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
  61
  62static void s390_virtio_bus_reset(void *opaque)
  63{
  64    VirtIOS390Bus *bus = opaque;
  65    bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
  66}
  67
  68void s390_virtio_reset_idx(VirtIOS390Device *dev)
  69{
  70    int i;
  71    hwaddr idx_addr;
  72    uint8_t num_vq;
  73
  74    num_vq = s390_virtio_device_num_vq(dev);
  75    for (i = 0; i < num_vq; i++) {
  76        idx_addr = virtio_queue_get_avail_addr(dev->vdev, i) +
  77            VIRTIO_VRING_AVAIL_IDX_OFFS;
  78        stw_phys(&address_space_memory, idx_addr, 0);
  79        idx_addr = virtio_queue_get_used_addr(dev->vdev, i) +
  80            VIRTIO_VRING_USED_IDX_OFFS;
  81        stw_phys(&address_space_memory, idx_addr, 0);
  82    }
  83}
  84
  85VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
  86{
  87    VirtIOS390Bus *bus;
  88    BusState *_bus;
  89    DeviceState *dev;
  90
  91    /* Create bridge device */
  92    dev = qdev_create(NULL, "s390-virtio-bridge");
  93    qdev_init_nofail(dev);
  94
  95    /* Create bus on bridge device */
  96
  97    _bus = qbus_create(TYPE_S390_VIRTIO_BUS, dev, "s390-virtio");
  98    bus = DO_UPCAST(VirtIOS390Bus, bus, _bus);
  99
 100    bus->dev_page = *ram_size;
 101    bus->dev_offs = bus->dev_page;
 102    bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
 103
 104    /* Enable hotplugging */
 105    _bus->allow_hotplug = 1;
 106
 107    /* Allocate RAM for VirtIO device pages (descriptors, queues, rings) */
 108    *ram_size += S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
 109
 110    qemu_register_reset(s390_virtio_bus_reset, bus);
 111    return bus;
 112}
 113
 114static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev)
 115{
 116    VirtIOS390Bus *bus;
 117    int dev_len;
 118
 119    bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
 120    dev->vdev = vdev;
 121    dev->dev_offs = bus->dev_offs;
 122    dev->feat_len = sizeof(uint32_t); /* always keep 32 bits features */
 123
 124    dev_len = VIRTIO_DEV_OFFS_CONFIG;
 125    dev_len += s390_virtio_device_num_vq(dev) * VIRTIO_VQCONFIG_LEN;
 126    dev_len += dev->feat_len * 2;
 127    dev_len += virtio_bus_get_vdev_config_len(&dev->bus);
 128
 129    bus->dev_offs += dev_len;
 130
 131    dev->host_features = virtio_bus_get_vdev_features(&dev->bus,
 132                                                      dev->host_features);
 133    s390_virtio_device_sync(dev);
 134    s390_virtio_reset_idx(dev);
 135    if (dev->qdev.hotplugged) {
 136        s390_virtio_irq(VIRTIO_PARAM_DEV_ADD, dev->dev_offs);
 137    }
 138
 139    return 0;
 140}
 141
 142static int s390_virtio_net_init(VirtIOS390Device *s390_dev)
 143{
 144    DeviceState *qdev = DEVICE(s390_dev);
 145    VirtIONetS390 *dev = VIRTIO_NET_S390(s390_dev);
 146    DeviceState *vdev = DEVICE(&dev->vdev);
 147
 148    virtio_net_set_config_size(&dev->vdev, s390_dev->host_features);
 149    virtio_net_set_netclient_name(&dev->vdev, qdev->id,
 150                                  object_get_typename(OBJECT(qdev)));
 151    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
 152    if (qdev_init(vdev) < 0) {
 153        return -1;
 154    }
 155
 156    return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
 157}
 158
 159static void s390_virtio_net_instance_init(Object *obj)
 160{
 161    VirtIONetS390 *dev = VIRTIO_NET_S390(obj);
 162    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
 163    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 164}
 165
 166static int s390_virtio_blk_init(VirtIOS390Device *s390_dev)
 167{
 168    VirtIOBlkS390 *dev = VIRTIO_BLK_S390(s390_dev);
 169    DeviceState *vdev = DEVICE(&dev->vdev);
 170    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
 171    if (qdev_init(vdev) < 0) {
 172        return -1;
 173    }
 174    return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
 175}
 176
 177static void s390_virtio_blk_instance_init(Object *obj)
 178{
 179    VirtIOBlkS390 *dev = VIRTIO_BLK_S390(obj);
 180    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BLK);
 181    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 182    object_unref(OBJECT(&dev->vdev));
 183    qdev_alias_all_properties(DEVICE(&dev->vdev), obj);
 184    object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
 185                              &error_abort);
 186}
 187
 188static int s390_virtio_serial_init(VirtIOS390Device *s390_dev)
 189{
 190    VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(s390_dev);
 191    DeviceState *vdev = DEVICE(&dev->vdev);
 192    DeviceState *qdev = DEVICE(s390_dev);
 193    VirtIOS390Bus *bus;
 194    int r;
 195    char *bus_name;
 196
 197    bus = DO_UPCAST(VirtIOS390Bus, bus, qdev->parent_bus);
 198
 199    /*
 200     * For command line compatibility, this sets the virtio-serial-device bus
 201     * name as before.
 202     */
 203    if (qdev->id) {
 204        bus_name = g_strdup_printf("%s.0", qdev->id);
 205        virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name);
 206        g_free(bus_name);
 207    }
 208
 209    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
 210    if (qdev_init(vdev) < 0) {
 211        return -1;
 212    }
 213
 214    r = s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
 215    if (!r) {
 216        bus->console = s390_dev;
 217    }
 218
 219    return r;
 220}
 221
 222static void s390_virtio_serial_instance_init(Object *obj)
 223{
 224    VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(obj);
 225    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
 226    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 227}
 228
 229static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev)
 230{
 231    VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(s390_dev);
 232    DeviceState *vdev = DEVICE(&dev->vdev);
 233    DeviceState *qdev = DEVICE(s390_dev);
 234    char *bus_name;
 235
 236    /*
 237     * For command line compatibility, this sets the virtio-scsi-device bus
 238     * name as before.
 239     */
 240    if (qdev->id) {
 241        bus_name = g_strdup_printf("%s.0", qdev->id);
 242        virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name);
 243        g_free(bus_name);
 244    }
 245
 246    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
 247    if (qdev_init(vdev) < 0) {
 248        return -1;
 249    }
 250
 251    return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
 252}
 253
 254static void s390_virtio_scsi_instance_init(Object *obj)
 255{
 256    VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(obj);
 257    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
 258    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 259}
 260
 261#ifdef CONFIG_VHOST_SCSI
 262static int s390_vhost_scsi_init(VirtIOS390Device *s390_dev)
 263{
 264    VHostSCSIS390 *dev = VHOST_SCSI_S390(s390_dev);
 265    DeviceState *vdev = DEVICE(&dev->vdev);
 266
 267    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
 268    if (qdev_init(vdev) < 0) {
 269        return -1;
 270    }
 271
 272    return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
 273}
 274
 275static void s390_vhost_scsi_instance_init(Object *obj)
 276{
 277    VHostSCSIS390 *dev = VHOST_SCSI_S390(obj);
 278    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
 279    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 280}
 281#endif
 282
 283
 284static int s390_virtio_rng_init(VirtIOS390Device *s390_dev)
 285{
 286    VirtIORNGS390 *dev = VIRTIO_RNG_S390(s390_dev);
 287    DeviceState *vdev = DEVICE(&dev->vdev);
 288
 289    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
 290    if (qdev_init(vdev) < 0) {
 291        return -1;
 292    }
 293
 294    object_property_set_link(OBJECT(dev),
 295                             OBJECT(dev->vdev.conf.rng), "rng",
 296                             NULL);
 297
 298    return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
 299}
 300
 301static void s390_virtio_rng_instance_init(Object *obj)
 302{
 303    VirtIORNGS390 *dev = VIRTIO_RNG_S390(obj);
 304    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
 305    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 306    object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
 307                             (Object **)&dev->vdev.conf.rng,
 308                             qdev_prop_allow_set_link_before_realize,
 309                             OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
 310}
 311
 312static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
 313{
 314    ram_addr_t token_off;
 315
 316    token_off = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
 317                (vq * VIRTIO_VQCONFIG_LEN) +
 318                VIRTIO_VQCONFIG_OFFS_TOKEN;
 319
 320    return ldq_be_phys(&address_space_memory, token_off);
 321}
 322
 323static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev)
 324{
 325    VirtIODevice *vdev = dev->vdev;
 326    int num_vq;
 327
 328    for (num_vq = 0; num_vq < VIRTIO_PCI_QUEUE_MAX; num_vq++) {
 329        if (!virtio_queue_get_num(vdev, num_vq)) {
 330            break;
 331        }
 332    }
 333
 334    return num_vq;
 335}
 336
 337static ram_addr_t s390_virtio_next_ring(VirtIOS390Bus *bus)
 338{
 339    ram_addr_t r = bus->next_ring;
 340
 341    bus->next_ring += VIRTIO_RING_LEN;
 342    return r;
 343}
 344
 345void s390_virtio_device_sync(VirtIOS390Device *dev)
 346{
 347    VirtIOS390Bus *bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
 348    ram_addr_t cur_offs;
 349    uint8_t num_vq;
 350    int i;
 351
 352    virtio_reset(dev->vdev);
 353
 354    /* Sync dev space */
 355    stb_phys(&address_space_memory,
 356             dev->dev_offs + VIRTIO_DEV_OFFS_TYPE, dev->vdev->device_id);
 357
 358    stb_phys(&address_space_memory,
 359             dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ,
 360             s390_virtio_device_num_vq(dev));
 361    stb_phys(&address_space_memory,
 362             dev->dev_offs + VIRTIO_DEV_OFFS_FEATURE_LEN, dev->feat_len);
 363
 364    stb_phys(&address_space_memory,
 365             dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG_LEN, dev->vdev->config_len);
 366
 367    num_vq = s390_virtio_device_num_vq(dev);
 368    stb_phys(&address_space_memory,
 369             dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, num_vq);
 370
 371    /* Sync virtqueues */
 372    for (i = 0; i < num_vq; i++) {
 373        ram_addr_t vq = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
 374                        (i * VIRTIO_VQCONFIG_LEN);
 375        ram_addr_t vring;
 376
 377        vring = s390_virtio_next_ring(bus);
 378        virtio_queue_set_addr(dev->vdev, i, vring);
 379        virtio_queue_set_vector(dev->vdev, i, i);
 380        stq_be_phys(&address_space_memory,
 381                    vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
 382        stw_be_phys(&address_space_memory,
 383                    vq + VIRTIO_VQCONFIG_OFFS_NUM,
 384                    virtio_queue_get_num(dev->vdev, i));
 385    }
 386
 387    cur_offs = dev->dev_offs;
 388    cur_offs += VIRTIO_DEV_OFFS_CONFIG;
 389    cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;
 390
 391    /* Sync feature bitmap */
 392    stl_le_phys(&address_space_memory, cur_offs, dev->host_features);
 393
 394    dev->feat_offs = cur_offs + dev->feat_len;
 395    cur_offs += dev->feat_len * 2;
 396
 397    /* Sync config space */
 398    virtio_bus_get_vdev_config(&dev->bus, dev->vdev->config);
 399
 400    cpu_physical_memory_write(cur_offs,
 401                              dev->vdev->config, dev->vdev->config_len);
 402    cur_offs += dev->vdev->config_len;
 403}
 404
 405void s390_virtio_device_update_status(VirtIOS390Device *dev)
 406{
 407    VirtIODevice *vdev = dev->vdev;
 408    uint32_t features;
 409
 410    virtio_set_status(vdev, ldub_phys(&address_space_memory,
 411                                      dev->dev_offs + VIRTIO_DEV_OFFS_STATUS));
 412
 413    /* Update guest supported feature bitmap */
 414
 415    features = bswap32(ldl_be_phys(&address_space_memory, dev->feat_offs));
 416    virtio_set_features(vdev, features);
 417}
 418
 419VirtIOS390Device *s390_virtio_bus_console(VirtIOS390Bus *bus)
 420{
 421    return bus->console;
 422}
 423
 424/* Find a device by vring address */
 425VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
 426                                             ram_addr_t mem,
 427                                             int *vq_num)
 428{
 429    BusChild *kid;
 430    int i;
 431
 432    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
 433        VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
 434
 435        for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
 436            if (!virtio_queue_get_addr(dev->vdev, i))
 437                break;
 438            if (virtio_queue_get_addr(dev->vdev, i) == mem) {
 439                if (vq_num) {
 440                    *vq_num = i;
 441                }
 442                return dev;
 443            }
 444        }
 445    }
 446
 447    return NULL;
 448}
 449
 450/* Find a device by device descriptor location */
 451VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem)
 452{
 453    BusChild *kid;
 454
 455    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
 456        VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
 457        if (dev->dev_offs == mem) {
 458            return dev;
 459        }
 460    }
 461
 462    return NULL;
 463}
 464
 465/* DeviceState to VirtIOS390Device. Note: used on datapath,
 466 * be careful and test performance if you change this.
 467 */
 468static inline VirtIOS390Device *to_virtio_s390_device_fast(DeviceState *d)
 469{
 470    return container_of(d, VirtIOS390Device, qdev);
 471}
 472
 473/* DeviceState to VirtIOS390Device. TODO: use QOM. */
 474static inline VirtIOS390Device *to_virtio_s390_device(DeviceState *d)
 475{
 476    return container_of(d, VirtIOS390Device, qdev);
 477}
 478
 479static void virtio_s390_notify(DeviceState *d, uint16_t vector)
 480{
 481    VirtIOS390Device *dev = to_virtio_s390_device_fast(d);
 482    uint64_t token = s390_virtio_device_vq_token(dev, vector);
 483
 484    s390_virtio_irq(0, token);
 485}
 486
 487static unsigned virtio_s390_get_features(DeviceState *d)
 488{
 489    VirtIOS390Device *dev = to_virtio_s390_device(d);
 490    return dev->host_features;
 491}
 492
 493/**************** S390 Virtio Bus Device Descriptions *******************/
 494
 495static Property s390_virtio_net_properties[] = {
 496    DEFINE_NIC_PROPERTIES(VirtIONetS390, vdev.nic_conf),
 497    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
 498    DEFINE_VIRTIO_NET_FEATURES(VirtIOS390Device, host_features),
 499    DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetS390, vdev.net_conf),
 500    DEFINE_PROP_END_OF_LIST(),
 501};
 502
 503static void s390_virtio_net_class_init(ObjectClass *klass, void *data)
 504{
 505    DeviceClass *dc = DEVICE_CLASS(klass);
 506    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
 507
 508    k->init = s390_virtio_net_init;
 509    dc->props = s390_virtio_net_properties;
 510}
 511
 512static const TypeInfo s390_virtio_net = {
 513    .name          = TYPE_VIRTIO_NET_S390,
 514    .parent        = TYPE_VIRTIO_S390_DEVICE,
 515    .instance_size = sizeof(VirtIONetS390),
 516    .instance_init = s390_virtio_net_instance_init,
 517    .class_init    = s390_virtio_net_class_init,
 518};
 519
 520static void s390_virtio_blk_class_init(ObjectClass *klass, void *data)
 521{
 522    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
 523
 524    k->init = s390_virtio_blk_init;
 525}
 526
 527static const TypeInfo s390_virtio_blk = {
 528    .name          = "virtio-blk-s390",
 529    .parent        = TYPE_VIRTIO_S390_DEVICE,
 530    .instance_size = sizeof(VirtIOBlkS390),
 531    .instance_init = s390_virtio_blk_instance_init,
 532    .class_init    = s390_virtio_blk_class_init,
 533};
 534
 535static Property s390_virtio_serial_properties[] = {
 536    DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtIOSerialS390, vdev.serial),
 537    DEFINE_PROP_END_OF_LIST(),
 538};
 539
 540static void s390_virtio_serial_class_init(ObjectClass *klass, void *data)
 541{
 542    DeviceClass *dc = DEVICE_CLASS(klass);
 543    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
 544
 545    k->init = s390_virtio_serial_init;
 546    dc->props = s390_virtio_serial_properties;
 547}
 548
 549static const TypeInfo s390_virtio_serial = {
 550    .name          = TYPE_VIRTIO_SERIAL_S390,
 551    .parent        = TYPE_VIRTIO_S390_DEVICE,
 552    .instance_size = sizeof(VirtIOSerialS390),
 553    .instance_init = s390_virtio_serial_instance_init,
 554    .class_init    = s390_virtio_serial_class_init,
 555};
 556
 557static Property s390_virtio_rng_properties[] = {
 558    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
 559    DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGS390, vdev.conf),
 560    DEFINE_PROP_END_OF_LIST(),
 561};
 562
 563static void s390_virtio_rng_class_init(ObjectClass *klass, void *data)
 564{
 565    DeviceClass *dc = DEVICE_CLASS(klass);
 566    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
 567
 568    k->init = s390_virtio_rng_init;
 569    dc->props = s390_virtio_rng_properties;
 570}
 571
 572static const TypeInfo s390_virtio_rng = {
 573    .name          = TYPE_VIRTIO_RNG_S390,
 574    .parent        = TYPE_VIRTIO_S390_DEVICE,
 575    .instance_size = sizeof(VirtIORNGS390),
 576    .instance_init = s390_virtio_rng_instance_init,
 577    .class_init    = s390_virtio_rng_class_init,
 578};
 579
 580static int s390_virtio_busdev_init(DeviceState *dev)
 581{
 582    VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
 583    VirtIOS390DeviceClass *_info = VIRTIO_S390_DEVICE_GET_CLASS(dev);
 584
 585    virtio_s390_bus_new(&_dev->bus, sizeof(_dev->bus), _dev);
 586
 587    return _info->init(_dev);
 588}
 589
 590static void s390_virtio_busdev_reset(DeviceState *dev)
 591{
 592    VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
 593
 594    virtio_reset(_dev->vdev);
 595}
 596
 597static void virtio_s390_device_class_init(ObjectClass *klass, void *data)
 598{
 599    DeviceClass *dc = DEVICE_CLASS(klass);
 600
 601    dc->init = s390_virtio_busdev_init;
 602    dc->bus_type = TYPE_S390_VIRTIO_BUS;
 603    dc->unplug = qdev_simple_unplug_cb;
 604    dc->reset = s390_virtio_busdev_reset;
 605}
 606
 607static const TypeInfo virtio_s390_device_info = {
 608    .name = TYPE_VIRTIO_S390_DEVICE,
 609    .parent = TYPE_DEVICE,
 610    .instance_size = sizeof(VirtIOS390Device),
 611    .class_init = virtio_s390_device_class_init,
 612    .class_size = sizeof(VirtIOS390DeviceClass),
 613    .abstract = true,
 614};
 615
 616static Property s390_virtio_scsi_properties[] = {
 617    DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSIS390, vdev.parent_obj.conf),
 618    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
 619    DEFINE_VIRTIO_SCSI_FEATURES(VirtIOS390Device, host_features),
 620    DEFINE_PROP_END_OF_LIST(),
 621};
 622
 623static void s390_virtio_scsi_class_init(ObjectClass *klass, void *data)
 624{
 625    DeviceClass *dc = DEVICE_CLASS(klass);
 626    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
 627
 628    k->init = s390_virtio_scsi_init;
 629    dc->props = s390_virtio_scsi_properties;
 630}
 631
 632static const TypeInfo s390_virtio_scsi = {
 633    .name          = TYPE_VIRTIO_SCSI_S390,
 634    .parent        = TYPE_VIRTIO_S390_DEVICE,
 635    .instance_size = sizeof(VirtIOSCSIS390),
 636    .instance_init = s390_virtio_scsi_instance_init,
 637    .class_init    = s390_virtio_scsi_class_init,
 638};
 639
 640#ifdef CONFIG_VHOST_SCSI
 641static Property s390_vhost_scsi_properties[] = {
 642    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
 643    DEFINE_VHOST_SCSI_PROPERTIES(VHostSCSIS390, vdev.parent_obj.conf),
 644    DEFINE_PROP_END_OF_LIST(),
 645};
 646
 647static void s390_vhost_scsi_class_init(ObjectClass *klass, void *data)
 648{
 649    DeviceClass *dc = DEVICE_CLASS(klass);
 650    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
 651
 652    k->init = s390_vhost_scsi_init;
 653    dc->props = s390_vhost_scsi_properties;
 654}
 655
 656static const TypeInfo s390_vhost_scsi = {
 657    .name          = TYPE_VHOST_SCSI_S390,
 658    .parent        = TYPE_VIRTIO_S390_DEVICE,
 659    .instance_size = sizeof(VHostSCSIS390),
 660    .instance_init = s390_vhost_scsi_instance_init,
 661    .class_init    = s390_vhost_scsi_class_init,
 662};
 663#endif
 664
 665/***************** S390 Virtio Bus Bridge Device *******************/
 666/* Only required to have the virtio bus as child in the system bus */
 667
 668static int s390_virtio_bridge_init(SysBusDevice *dev)
 669{
 670    /* nothing */
 671    return 0;
 672}
 673
 674static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data)
 675{
 676    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 677
 678    k->init = s390_virtio_bridge_init;
 679}
 680
 681static const TypeInfo s390_virtio_bridge_info = {
 682    .name          = "s390-virtio-bridge",
 683    .parent        = TYPE_SYS_BUS_DEVICE,
 684    .instance_size = sizeof(SysBusDevice),
 685    .class_init    = s390_virtio_bridge_class_init,
 686};
 687
 688/* virtio-s390-bus */
 689
 690static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size,
 691                                VirtIOS390Device *dev)
 692{
 693    DeviceState *qdev = DEVICE(dev);
 694    BusState *qbus;
 695    char virtio_bus_name[] = "virtio-bus";
 696
 697    qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_S390_BUS,
 698                        qdev, virtio_bus_name);
 699    qbus = BUS(bus);
 700    qbus->allow_hotplug = 1;
 701}
 702
 703static void virtio_s390_bus_class_init(ObjectClass *klass, void *data)
 704{
 705    VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
 706    BusClass *bus_class = BUS_CLASS(klass);
 707    bus_class->max_dev = 1;
 708    k->notify = virtio_s390_notify;
 709    k->get_features = virtio_s390_get_features;
 710}
 711
 712static const TypeInfo virtio_s390_bus_info = {
 713    .name          = TYPE_VIRTIO_S390_BUS,
 714    .parent        = TYPE_VIRTIO_BUS,
 715    .instance_size = sizeof(VirtioS390BusState),
 716    .class_init    = virtio_s390_bus_class_init,
 717};
 718
 719static void s390_virtio_register_types(void)
 720{
 721    type_register_static(&virtio_s390_bus_info);
 722    type_register_static(&s390_virtio_bus_info);
 723    type_register_static(&virtio_s390_device_info);
 724    type_register_static(&s390_virtio_serial);
 725    type_register_static(&s390_virtio_blk);
 726    type_register_static(&s390_virtio_net);
 727    type_register_static(&s390_virtio_scsi);
 728#ifdef CONFIG_VHOST_SCSI
 729    type_register_static(&s390_vhost_scsi);
 730#endif
 731    type_register_static(&s390_virtio_rng);
 732    type_register_static(&s390_virtio_bridge_info);
 733}
 734
 735type_init(s390_virtio_register_types)
 736