Statistics
| Branch: | Revision:

root / hw / s390x / s390-virtio-bus.c @ 2c17449b

History | View | Annotate | Download (21.7 kB)

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

    
48
#define VIRTIO_EXT_CODE   0x2603
49

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

    
53
static const TypeInfo s390_virtio_bus_info = {
54
    .name = TYPE_S390_VIRTIO_BUS,
55
    .parent = TYPE_BUS,
56
    .instance_size = sizeof(VirtIOS390Bus),
57
};
58

    
59
static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev);
60

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

    
64
static void s390_virtio_bus_reset(void *opaque)
65
{
66
    VirtIOS390Bus *bus = opaque;
67
    bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
68
}
69

    
70
void s390_virtio_reset_idx(VirtIOS390Device *dev)
71
{
72
    int i;
73
    hwaddr idx_addr;
74
    uint8_t num_vq;
75

    
76
    num_vq = s390_virtio_device_num_vq(dev);
77
    for (i = 0; i < num_vq; i++) {
78
        idx_addr = virtio_queue_get_avail_addr(dev->vdev, i) +
79
            VIRTIO_VRING_AVAIL_IDX_OFFS;
80
        stw_phys(idx_addr, 0);
81
        idx_addr = virtio_queue_get_used_addr(dev->vdev, i) +
82
            VIRTIO_VRING_USED_IDX_OFFS;
83
        stw_phys(idx_addr, 0);
84
    }
85
}
86

    
87
VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
88
{
89
    VirtIOS390Bus *bus;
90
    BusState *_bus;
91
    DeviceState *dev;
92

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

    
97
    /* Create bus on bridge device */
98

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

    
102
    bus->dev_page = *ram_size;
103
    bus->dev_offs = bus->dev_page;
104
    bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
105

    
106
    /* Enable hotplugging */
107
    _bus->allow_hotplug = 1;
108

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

    
112
    qemu_register_reset(s390_virtio_bus_reset, bus);
113
    return bus;
114
}
115

    
116
static void s390_virtio_irq(S390CPU *cpu, int config_change, uint64_t token)
117
{
118
    if (kvm_enabled()) {
119
        kvm_s390_virtio_irq(cpu, config_change, token);
120
    } else {
121
        cpu_inject_ext(cpu, VIRTIO_EXT_CODE, config_change, token);
122
    }
123
}
124

    
125
static int s390_virtio_device_init(VirtIOS390Device *dev, VirtIODevice *vdev)
126
{
127
    VirtIOS390Bus *bus;
128
    int dev_len;
129

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

    
135
    dev_len = VIRTIO_DEV_OFFS_CONFIG;
136
    dev_len += s390_virtio_device_num_vq(dev) * VIRTIO_VQCONFIG_LEN;
137
    dev_len += dev->feat_len * 2;
138
    dev_len += virtio_bus_get_vdev_config_len(&dev->bus);
139

    
140
    bus->dev_offs += dev_len;
141

    
142
    dev->host_features = virtio_bus_get_vdev_features(&dev->bus,
143
                                                      dev->host_features);
144
    s390_virtio_device_sync(dev);
145
    s390_virtio_reset_idx(dev);
146
    if (dev->qdev.hotplugged) {
147
        S390CPU *cpu = s390_cpu_addr2state(0);
148
        s390_virtio_irq(cpu, VIRTIO_PARAM_DEV_ADD, dev->dev_offs);
149
    }
150

    
151
    return 0;
152
}
153

    
154
static int s390_virtio_net_init(VirtIOS390Device *s390_dev)
155
{
156
    DeviceState *qdev = DEVICE(s390_dev);
157
    VirtIONetS390 *dev = VIRTIO_NET_S390(s390_dev);
158
    DeviceState *vdev = DEVICE(&dev->vdev);
159

    
160
    virtio_net_set_config_size(&dev->vdev, s390_dev->host_features);
161
    virtio_net_set_netclient_name(&dev->vdev, qdev->id,
162
                                  object_get_typename(OBJECT(qdev)));
163
    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
164
    if (qdev_init(vdev) < 0) {
165
        return -1;
166
    }
167

    
168
    return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
169
}
170

    
171
static void s390_virtio_net_instance_init(Object *obj)
172
{
173
    VirtIONetS390 *dev = VIRTIO_NET_S390(obj);
174
    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
175
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
176
}
177

    
178
static int s390_virtio_blk_init(VirtIOS390Device *s390_dev)
179
{
180
    VirtIOBlkS390 *dev = VIRTIO_BLK_S390(s390_dev);
181
    DeviceState *vdev = DEVICE(&dev->vdev);
182
    virtio_blk_set_conf(vdev, &(dev->blk));
183
    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
184
    if (qdev_init(vdev) < 0) {
185
        return -1;
186
    }
187
    return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
188
}
189

    
190
static void s390_virtio_blk_instance_init(Object *obj)
191
{
192
    VirtIOBlkS390 *dev = VIRTIO_BLK_S390(obj);
193
    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BLK);
194
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
195
}
196

    
197
static int s390_virtio_serial_init(VirtIOS390Device *s390_dev)
198
{
199
    VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(s390_dev);
200
    DeviceState *vdev = DEVICE(&dev->vdev);
201
    DeviceState *qdev = DEVICE(s390_dev);
202
    VirtIOS390Bus *bus;
203
    int r;
204
    char *bus_name;
205

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

    
208
    /*
209
     * For command line compatibility, this sets the virtio-serial-device bus
210
     * name as before.
211
     */
212
    if (qdev->id) {
213
        bus_name = g_strdup_printf("%s.0", qdev->id);
214
        virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name);
215
        g_free(bus_name);
216
    }
217

    
218
    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
219
    if (qdev_init(vdev) < 0) {
220
        return -1;
221
    }
222

    
223
    r = s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
224
    if (!r) {
225
        bus->console = s390_dev;
226
    }
227

    
228
    return r;
229
}
230

    
231
static void s390_virtio_serial_instance_init(Object *obj)
232
{
233
    VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(obj);
234
    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
235
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
236
}
237

    
238
static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev)
239
{
240
    VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(s390_dev);
241
    DeviceState *vdev = DEVICE(&dev->vdev);
242
    DeviceState *qdev = DEVICE(s390_dev);
243
    char *bus_name;
244

    
245
    /*
246
     * For command line compatibility, this sets the virtio-scsi-device bus
247
     * name as before.
248
     */
249
    if (qdev->id) {
250
        bus_name = g_strdup_printf("%s.0", qdev->id);
251
        virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name);
252
        g_free(bus_name);
253
    }
254

    
255
    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
256
    if (qdev_init(vdev) < 0) {
257
        return -1;
258
    }
259

    
260
    return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
261
}
262

    
263
static void s390_virtio_scsi_instance_init(Object *obj)
264
{
265
    VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(obj);
266
    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
267
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
268
}
269

    
270
#ifdef CONFIG_VHOST_SCSI
271
static int s390_vhost_scsi_init(VirtIOS390Device *s390_dev)
272
{
273
    VHostSCSIS390 *dev = VHOST_SCSI_S390(s390_dev);
274
    DeviceState *vdev = DEVICE(&dev->vdev);
275

    
276
    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
277
    if (qdev_init(vdev) < 0) {
278
        return -1;
279
    }
280

    
281
    return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
282
}
283

    
284
static void s390_vhost_scsi_instance_init(Object *obj)
285
{
286
    VHostSCSIS390 *dev = VHOST_SCSI_S390(obj);
287
    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
288
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
289
}
290
#endif
291

    
292

    
293
static int s390_virtio_rng_init(VirtIOS390Device *s390_dev)
294
{
295
    VirtIORNGS390 *dev = VIRTIO_RNG_S390(s390_dev);
296
    DeviceState *vdev = DEVICE(&dev->vdev);
297

    
298
    qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
299
    if (qdev_init(vdev) < 0) {
300
        return -1;
301
    }
302

    
303
    object_property_set_link(OBJECT(dev),
304
                             OBJECT(dev->vdev.conf.rng), "rng",
305
                             NULL);
306

    
307
    return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
308
}
309

    
310
static void s390_virtio_rng_instance_init(Object *obj)
311
{
312
    VirtIORNGS390 *dev = VIRTIO_RNG_S390(obj);
313
    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
314
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
315
    object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
316
                             (Object **)&dev->vdev.conf.rng, NULL);
317
}
318

    
319
static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
320
{
321
    ram_addr_t token_off;
322

    
323
    token_off = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
324
                (vq * VIRTIO_VQCONFIG_LEN) +
325
                VIRTIO_VQCONFIG_OFFS_TOKEN;
326

    
327
    return ldq_be_phys(&address_space_memory, token_off);
328
}
329

    
330
static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev)
331
{
332
    VirtIODevice *vdev = dev->vdev;
333
    int num_vq;
334

    
335
    for (num_vq = 0; num_vq < VIRTIO_PCI_QUEUE_MAX; num_vq++) {
336
        if (!virtio_queue_get_num(vdev, num_vq)) {
337
            break;
338
        }
339
    }
340

    
341
    return num_vq;
342
}
343

    
344
static ram_addr_t s390_virtio_next_ring(VirtIOS390Bus *bus)
345
{
346
    ram_addr_t r = bus->next_ring;
347

    
348
    bus->next_ring += VIRTIO_RING_LEN;
349
    return r;
350
}
351

    
352
void s390_virtio_device_sync(VirtIOS390Device *dev)
353
{
354
    VirtIOS390Bus *bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
355
    ram_addr_t cur_offs;
356
    uint8_t num_vq;
357
    int i;
358

    
359
    virtio_reset(dev->vdev);
360

    
361
    /* Sync dev space */
362
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_TYPE, dev->vdev->device_id);
363

    
364
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, s390_virtio_device_num_vq(dev));
365
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_FEATURE_LEN, dev->feat_len);
366

    
367
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG_LEN, dev->vdev->config_len);
368

    
369
    num_vq = s390_virtio_device_num_vq(dev);
370
    stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, num_vq);
371

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

    
378
        vring = s390_virtio_next_ring(bus);
379
        virtio_queue_set_addr(dev->vdev, i, vring);
380
        virtio_queue_set_vector(dev->vdev, i, i);
381
        stq_be_phys(vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
382
        stw_be_phys(vq + VIRTIO_VQCONFIG_OFFS_NUM, virtio_queue_get_num(dev->vdev, i));
383
    }
384

    
385
    cur_offs = dev->dev_offs;
386
    cur_offs += VIRTIO_DEV_OFFS_CONFIG;
387
    cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;
388

    
389
    /* Sync feature bitmap */
390
    stl_le_phys(cur_offs, dev->host_features);
391

    
392
    dev->feat_offs = cur_offs + dev->feat_len;
393
    cur_offs += dev->feat_len * 2;
394

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

    
398
    cpu_physical_memory_write(cur_offs,
399
                              dev->vdev->config, dev->vdev->config_len);
400
    cur_offs += dev->vdev->config_len;
401
}
402

    
403
void s390_virtio_device_update_status(VirtIOS390Device *dev)
404
{
405
    VirtIODevice *vdev = dev->vdev;
406
    uint32_t features;
407

    
408
    virtio_set_status(vdev, ldub_phys(&address_space_memory,
409
                                      dev->dev_offs + VIRTIO_DEV_OFFS_STATUS));
410

    
411
    /* Update guest supported feature bitmap */
412

    
413
    features = bswap32(ldl_be_phys(&address_space_memory, dev->feat_offs));
414
    virtio_set_features(vdev, features);
415
}
416

    
417
VirtIOS390Device *s390_virtio_bus_console(VirtIOS390Bus *bus)
418
{
419
    return bus->console;
420
}
421

    
422
/* Find a device by vring address */
423
VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
424
                                             ram_addr_t mem,
425
                                             int *vq_num)
426
{
427
    BusChild *kid;
428
    int i;
429

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

    
433
        for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
434
            if (!virtio_queue_get_addr(dev->vdev, i))
435
                break;
436
            if (virtio_queue_get_addr(dev->vdev, i) == mem) {
437
                if (vq_num) {
438
                    *vq_num = i;
439
                }
440
                return dev;
441
            }
442
        }
443
    }
444

    
445
    return NULL;
446
}
447

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

    
453
    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
454
        VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
455
        if (dev->dev_offs == mem) {
456
            return dev;
457
        }
458
    }
459

    
460
    return NULL;
461
}
462

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

    
471
/* DeviceState to VirtIOS390Device. TODO: use QOM. */
472
static inline VirtIOS390Device *to_virtio_s390_device(DeviceState *d)
473
{
474
    return container_of(d, VirtIOS390Device, qdev);
475
}
476

    
477
static void virtio_s390_notify(DeviceState *d, uint16_t vector)
478
{
479
    VirtIOS390Device *dev = to_virtio_s390_device_fast(d);
480
    uint64_t token = s390_virtio_device_vq_token(dev, vector);
481
    S390CPU *cpu = s390_cpu_addr2state(0);
482

    
483
    s390_virtio_irq(cpu, 0, token);
484
}
485

    
486
static unsigned virtio_s390_get_features(DeviceState *d)
487
{
488
    VirtIOS390Device *dev = to_virtio_s390_device(d);
489
    return dev->host_features;
490
}
491

    
492
/**************** S390 Virtio Bus Device Descriptions *******************/
493

    
494
static Property s390_virtio_net_properties[] = {
495
    DEFINE_NIC_PROPERTIES(VirtIONetS390, vdev.nic_conf),
496
    DEFINE_VIRTIO_NET_FEATURES(VirtIOS390Device, host_features),
497
    DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetS390, vdev.net_conf),
498
    DEFINE_PROP_END_OF_LIST(),
499
};
500

    
501
static void s390_virtio_net_class_init(ObjectClass *klass, void *data)
502
{
503
    DeviceClass *dc = DEVICE_CLASS(klass);
504
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
505

    
506
    k->init = s390_virtio_net_init;
507
    dc->props = s390_virtio_net_properties;
508
}
509

    
510
static const TypeInfo s390_virtio_net = {
511
    .name          = TYPE_VIRTIO_NET_S390,
512
    .parent        = TYPE_VIRTIO_S390_DEVICE,
513
    .instance_size = sizeof(VirtIONetS390),
514
    .instance_init = s390_virtio_net_instance_init,
515
    .class_init    = s390_virtio_net_class_init,
516
};
517

    
518
static Property s390_virtio_blk_properties[] = {
519
    DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlkS390, blk),
520
    DEFINE_PROP_END_OF_LIST(),
521
};
522

    
523
static void s390_virtio_blk_class_init(ObjectClass *klass, void *data)
524
{
525
    DeviceClass *dc = DEVICE_CLASS(klass);
526
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
527

    
528
    k->init = s390_virtio_blk_init;
529
    dc->props = s390_virtio_blk_properties;
530
}
531

    
532
static const TypeInfo s390_virtio_blk = {
533
    .name          = "virtio-blk-s390",
534
    .parent        = TYPE_VIRTIO_S390_DEVICE,
535
    .instance_size = sizeof(VirtIOBlkS390),
536
    .instance_init = s390_virtio_blk_instance_init,
537
    .class_init    = s390_virtio_blk_class_init,
538
};
539

    
540
static Property s390_virtio_serial_properties[] = {
541
    DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtIOSerialS390, vdev.serial),
542
    DEFINE_PROP_END_OF_LIST(),
543
};
544

    
545
static void s390_virtio_serial_class_init(ObjectClass *klass, void *data)
546
{
547
    DeviceClass *dc = DEVICE_CLASS(klass);
548
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
549

    
550
    k->init = s390_virtio_serial_init;
551
    dc->props = s390_virtio_serial_properties;
552
}
553

    
554
static const TypeInfo s390_virtio_serial = {
555
    .name          = TYPE_VIRTIO_SERIAL_S390,
556
    .parent        = TYPE_VIRTIO_S390_DEVICE,
557
    .instance_size = sizeof(VirtIOSerialS390),
558
    .instance_init = s390_virtio_serial_instance_init,
559
    .class_init    = s390_virtio_serial_class_init,
560
};
561

    
562
static Property s390_virtio_rng_properties[] = {
563
    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
564
    DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGS390, vdev.conf),
565
    DEFINE_PROP_END_OF_LIST(),
566
};
567

    
568
static void s390_virtio_rng_class_init(ObjectClass *klass, void *data)
569
{
570
    DeviceClass *dc = DEVICE_CLASS(klass);
571
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
572

    
573
    k->init = s390_virtio_rng_init;
574
    dc->props = s390_virtio_rng_properties;
575
}
576

    
577
static const TypeInfo s390_virtio_rng = {
578
    .name          = TYPE_VIRTIO_RNG_S390,
579
    .parent        = TYPE_VIRTIO_S390_DEVICE,
580
    .instance_size = sizeof(VirtIORNGS390),
581
    .instance_init = s390_virtio_rng_instance_init,
582
    .class_init    = s390_virtio_rng_class_init,
583
};
584

    
585
static int s390_virtio_busdev_init(DeviceState *dev)
586
{
587
    VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
588
    VirtIOS390DeviceClass *_info = VIRTIO_S390_DEVICE_GET_CLASS(dev);
589

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

    
592
    return _info->init(_dev);
593
}
594

    
595
static void s390_virtio_busdev_reset(DeviceState *dev)
596
{
597
    VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
598

    
599
    virtio_reset(_dev->vdev);
600
}
601

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

    
606
    dc->init = s390_virtio_busdev_init;
607
    dc->bus_type = TYPE_S390_VIRTIO_BUS;
608
    dc->unplug = qdev_simple_unplug_cb;
609
    dc->reset = s390_virtio_busdev_reset;
610
}
611

    
612
static const TypeInfo virtio_s390_device_info = {
613
    .name = TYPE_VIRTIO_S390_DEVICE,
614
    .parent = TYPE_DEVICE,
615
    .instance_size = sizeof(VirtIOS390Device),
616
    .class_init = virtio_s390_device_class_init,
617
    .class_size = sizeof(VirtIOS390DeviceClass),
618
    .abstract = true,
619
};
620

    
621
static Property s390_virtio_scsi_properties[] = {
622
    DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSIS390, vdev.parent_obj.conf),
623
    DEFINE_VIRTIO_SCSI_FEATURES(VirtIOS390Device, host_features),
624
    DEFINE_PROP_END_OF_LIST(),
625
};
626

    
627
static void s390_virtio_scsi_class_init(ObjectClass *klass, void *data)
628
{
629
    DeviceClass *dc = DEVICE_CLASS(klass);
630
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
631

    
632
    k->init = s390_virtio_scsi_init;
633
    dc->props = s390_virtio_scsi_properties;
634
}
635

    
636
static const TypeInfo s390_virtio_scsi = {
637
    .name          = TYPE_VIRTIO_SCSI_S390,
638
    .parent        = TYPE_VIRTIO_S390_DEVICE,
639
    .instance_size = sizeof(VirtIOSCSIS390),
640
    .instance_init = s390_virtio_scsi_instance_init,
641
    .class_init    = s390_virtio_scsi_class_init,
642
};
643

    
644
#ifdef CONFIG_VHOST_SCSI
645
static Property s390_vhost_scsi_properties[] = {
646
    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
647
    DEFINE_VHOST_SCSI_PROPERTIES(VHostSCSIS390, vdev.parent_obj.conf),
648
    DEFINE_PROP_END_OF_LIST(),
649
};
650

    
651
static void s390_vhost_scsi_class_init(ObjectClass *klass, void *data)
652
{
653
    DeviceClass *dc = DEVICE_CLASS(klass);
654
    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
655

    
656
    k->init = s390_vhost_scsi_init;
657
    dc->props = s390_vhost_scsi_properties;
658
}
659

    
660
static const TypeInfo s390_vhost_scsi = {
661
    .name          = TYPE_VHOST_SCSI_S390,
662
    .parent        = TYPE_VIRTIO_S390_DEVICE,
663
    .instance_size = sizeof(VHostSCSIS390),
664
    .instance_init = s390_vhost_scsi_instance_init,
665
    .class_init    = s390_vhost_scsi_class_init,
666
};
667
#endif
668

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

    
672
static int s390_virtio_bridge_init(SysBusDevice *dev)
673
{
674
    /* nothing */
675
    return 0;
676
}
677

    
678
static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data)
679
{
680
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
681

    
682
    k->init = s390_virtio_bridge_init;
683
}
684

    
685
static const TypeInfo s390_virtio_bridge_info = {
686
    .name          = "s390-virtio-bridge",
687
    .parent        = TYPE_SYS_BUS_DEVICE,
688
    .instance_size = sizeof(SysBusDevice),
689
    .class_init    = s390_virtio_bridge_class_init,
690
};
691

    
692
/* virtio-s390-bus */
693

    
694
static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size,
695
                                VirtIOS390Device *dev)
696
{
697
    DeviceState *qdev = DEVICE(dev);
698
    BusState *qbus;
699
    char virtio_bus_name[] = "virtio-bus";
700

    
701
    qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_S390_BUS,
702
                        qdev, virtio_bus_name);
703
    qbus = BUS(bus);
704
    qbus->allow_hotplug = 1;
705
}
706

    
707
static void virtio_s390_bus_class_init(ObjectClass *klass, void *data)
708
{
709
    VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
710
    BusClass *bus_class = BUS_CLASS(klass);
711
    bus_class->max_dev = 1;
712
    k->notify = virtio_s390_notify;
713
    k->get_features = virtio_s390_get_features;
714
}
715

    
716
static const TypeInfo virtio_s390_bus_info = {
717
    .name          = TYPE_VIRTIO_S390_BUS,
718
    .parent        = TYPE_VIRTIO_BUS,
719
    .instance_size = sizeof(VirtioS390BusState),
720
    .class_init    = virtio_s390_bus_class_init,
721
};
722

    
723
static void s390_virtio_register_types(void)
724
{
725
    type_register_static(&virtio_s390_bus_info);
726
    type_register_static(&s390_virtio_bus_info);
727
    type_register_static(&virtio_s390_device_info);
728
    type_register_static(&s390_virtio_serial);
729
    type_register_static(&s390_virtio_blk);
730
    type_register_static(&s390_virtio_net);
731
    type_register_static(&s390_virtio_scsi);
732
#ifdef CONFIG_VHOST_SCSI
733
    type_register_static(&s390_vhost_scsi);
734
#endif
735
    type_register_static(&s390_virtio_rng);
736
    type_register_static(&s390_virtio_bridge_info);
737
}
738

    
739
type_init(s390_virtio_register_types)