1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "hw/hw.h"
21#include "sysemu/block-backend.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
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
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
92 dev = qdev_create(NULL, "s390-virtio-bridge");
93 qdev_init_nofail(dev);
94
95
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
105 qbus_set_hotplug_handler(_bus, dev, &error_abort);
106
107
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);
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
163 virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
164 TYPE_VIRTIO_NET);
165 object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
166 "bootindex", &error_abort);
167}
168
169static int s390_virtio_blk_init(VirtIOS390Device *s390_dev)
170{
171 VirtIOBlkS390 *dev = VIRTIO_BLK_S390(s390_dev);
172 DeviceState *vdev = DEVICE(&dev->vdev);
173 qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
174 if (qdev_init(vdev) < 0) {
175 return -1;
176 }
177 return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
178}
179
180static void s390_virtio_blk_instance_init(Object *obj)
181{
182 VirtIOBlkS390 *dev = VIRTIO_BLK_S390(obj);
183
184 virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
185 TYPE_VIRTIO_BLK);
186 object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
187 &error_abort);
188 object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
189 "bootindex", &error_abort);
190}
191
192static int s390_virtio_serial_init(VirtIOS390Device *s390_dev)
193{
194 VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(s390_dev);
195 DeviceState *vdev = DEVICE(&dev->vdev);
196 DeviceState *qdev = DEVICE(s390_dev);
197 VirtIOS390Bus *bus;
198 int r;
199 char *bus_name;
200
201 bus = DO_UPCAST(VirtIOS390Bus, bus, qdev->parent_bus);
202
203
204
205
206
207 if (qdev->id) {
208 bus_name = g_strdup_printf("%s.0", qdev->id);
209 virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name);
210 g_free(bus_name);
211 }
212
213 qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
214 if (qdev_init(vdev) < 0) {
215 return -1;
216 }
217
218 r = s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
219 if (!r) {
220 bus->console = s390_dev;
221 }
222
223 return r;
224}
225
226static void s390_virtio_serial_instance_init(Object *obj)
227{
228 VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(obj);
229
230 virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
231 TYPE_VIRTIO_SERIAL);
232}
233
234static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev)
235{
236 VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(s390_dev);
237 DeviceState *vdev = DEVICE(&dev->vdev);
238 DeviceState *qdev = DEVICE(s390_dev);
239 char *bus_name;
240
241
242
243
244
245 if (qdev->id) {
246 bus_name = g_strdup_printf("%s.0", qdev->id);
247 virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name);
248 g_free(bus_name);
249 }
250
251 qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
252 if (qdev_init(vdev) < 0) {
253 return -1;
254 }
255
256 return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
257}
258
259static void s390_virtio_scsi_instance_init(Object *obj)
260{
261 VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(obj);
262
263 virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
264 TYPE_VIRTIO_SCSI);
265}
266
267#ifdef CONFIG_VHOST_SCSI
268static int s390_vhost_scsi_init(VirtIOS390Device *s390_dev)
269{
270 VHostSCSIS390 *dev = VHOST_SCSI_S390(s390_dev);
271 DeviceState *vdev = DEVICE(&dev->vdev);
272
273 qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
274 if (qdev_init(vdev) < 0) {
275 return -1;
276 }
277
278 return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
279}
280
281static void s390_vhost_scsi_instance_init(Object *obj)
282{
283 VHostSCSIS390 *dev = VHOST_SCSI_S390(obj);
284
285 virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
286 TYPE_VHOST_SCSI);
287}
288#endif
289
290
291static int s390_virtio_rng_init(VirtIOS390Device *s390_dev)
292{
293 VirtIORNGS390 *dev = VIRTIO_RNG_S390(s390_dev);
294 DeviceState *vdev = DEVICE(&dev->vdev);
295
296 qdev_set_parent_bus(vdev, BUS(&s390_dev->bus));
297 if (qdev_init(vdev) < 0) {
298 return -1;
299 }
300
301 object_property_set_link(OBJECT(dev),
302 OBJECT(dev->vdev.conf.rng), "rng",
303 NULL);
304
305 return s390_virtio_device_init(s390_dev, VIRTIO_DEVICE(vdev));
306}
307
308static void s390_virtio_rng_instance_init(Object *obj)
309{
310 VirtIORNGS390 *dev = VIRTIO_RNG_S390(obj);
311
312 virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
313 TYPE_VIRTIO_RNG);
314 object_property_add_alias(obj, "rng", OBJECT(&dev->vdev),
315 "rng", &error_abort);
316}
317
318static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
319{
320 ram_addr_t token_off;
321
322 token_off = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
323 (vq * VIRTIO_VQCONFIG_LEN) +
324 VIRTIO_VQCONFIG_OFFS_TOKEN;
325
326 return ldq_be_phys(&address_space_memory, token_off);
327}
328
329static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev)
330{
331 VirtIODevice *vdev = dev->vdev;
332 int num_vq;
333
334 for (num_vq = 0; num_vq < VIRTIO_PCI_QUEUE_MAX; num_vq++) {
335 if (!virtio_queue_get_num(vdev, num_vq)) {
336 break;
337 }
338 }
339
340 return num_vq;
341}
342
343static ram_addr_t s390_virtio_next_ring(VirtIOS390Bus *bus)
344{
345 ram_addr_t r = bus->next_ring;
346
347 bus->next_ring += VIRTIO_RING_LEN;
348 return r;
349}
350
351void s390_virtio_device_sync(VirtIOS390Device *dev)
352{
353 VirtIOS390Bus *bus = DO_UPCAST(VirtIOS390Bus, bus, dev->qdev.parent_bus);
354 ram_addr_t cur_offs;
355 uint8_t num_vq;
356 int i;
357
358 virtio_reset(dev->vdev);
359
360
361 stb_phys(&address_space_memory,
362 dev->dev_offs + VIRTIO_DEV_OFFS_TYPE, dev->vdev->device_id);
363
364 stb_phys(&address_space_memory,
365 dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ,
366 s390_virtio_device_num_vq(dev));
367 stb_phys(&address_space_memory,
368 dev->dev_offs + VIRTIO_DEV_OFFS_FEATURE_LEN, dev->feat_len);
369
370 stb_phys(&address_space_memory,
371 dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG_LEN, dev->vdev->config_len);
372
373 num_vq = s390_virtio_device_num_vq(dev);
374 stb_phys(&address_space_memory,
375 dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, num_vq);
376
377
378 for (i = 0; i < num_vq; i++) {
379 ram_addr_t vq = (dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG) +
380 (i * VIRTIO_VQCONFIG_LEN);
381 ram_addr_t vring;
382
383 vring = s390_virtio_next_ring(bus);
384 virtio_queue_set_addr(dev->vdev, i, vring);
385 virtio_queue_set_vector(dev->vdev, i, i);
386 stq_be_phys(&address_space_memory,
387 vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring);
388 stw_be_phys(&address_space_memory,
389 vq + VIRTIO_VQCONFIG_OFFS_NUM,
390 virtio_queue_get_num(dev->vdev, i));
391 }
392
393 cur_offs = dev->dev_offs;
394 cur_offs += VIRTIO_DEV_OFFS_CONFIG;
395 cur_offs += num_vq * VIRTIO_VQCONFIG_LEN;
396
397
398 stl_le_phys(&address_space_memory, cur_offs, dev->host_features);
399
400 dev->feat_offs = cur_offs + dev->feat_len;
401 cur_offs += dev->feat_len * 2;
402
403
404 virtio_bus_get_vdev_config(&dev->bus, dev->vdev->config);
405
406 cpu_physical_memory_write(cur_offs,
407 dev->vdev->config, dev->vdev->config_len);
408 cur_offs += dev->vdev->config_len;
409}
410
411void s390_virtio_device_update_status(VirtIOS390Device *dev)
412{
413 VirtIODevice *vdev = dev->vdev;
414 uint32_t features;
415
416 virtio_set_status(vdev, ldub_phys(&address_space_memory,
417 dev->dev_offs + VIRTIO_DEV_OFFS_STATUS));
418
419
420
421 features = bswap32(ldl_be_phys(&address_space_memory, dev->feat_offs));
422 virtio_set_features(vdev, features);
423}
424
425VirtIOS390Device *s390_virtio_bus_console(VirtIOS390Bus *bus)
426{
427 return bus->console;
428}
429
430
431VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
432 ram_addr_t mem,
433 int *vq_num)
434{
435 BusChild *kid;
436 int i;
437
438 QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
439 VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
440
441 for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
442 if (!virtio_queue_get_addr(dev->vdev, i))
443 break;
444 if (virtio_queue_get_addr(dev->vdev, i) == mem) {
445 if (vq_num) {
446 *vq_num = i;
447 }
448 return dev;
449 }
450 }
451 }
452
453 return NULL;
454}
455
456
457VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem)
458{
459 BusChild *kid;
460
461 QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
462 VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
463 if (dev->dev_offs == mem) {
464 return dev;
465 }
466 }
467
468 return NULL;
469}
470
471
472
473
474static inline VirtIOS390Device *to_virtio_s390_device_fast(DeviceState *d)
475{
476 return container_of(d, VirtIOS390Device, qdev);
477}
478
479
480static inline VirtIOS390Device *to_virtio_s390_device(DeviceState *d)
481{
482 return container_of(d, VirtIOS390Device, qdev);
483}
484
485static void virtio_s390_notify(DeviceState *d, uint16_t vector)
486{
487 VirtIOS390Device *dev = to_virtio_s390_device_fast(d);
488 uint64_t token = s390_virtio_device_vq_token(dev, vector);
489
490 s390_virtio_irq(0, token);
491}
492
493static unsigned virtio_s390_get_features(DeviceState *d)
494{
495 VirtIOS390Device *dev = to_virtio_s390_device(d);
496 return dev->host_features;
497}
498
499
500
501static Property s390_virtio_net_properties[] = {
502 DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
503 DEFINE_VIRTIO_NET_FEATURES(VirtIOS390Device, host_features),
504 DEFINE_PROP_END_OF_LIST(),
505};
506
507static void s390_virtio_net_class_init(ObjectClass *klass, void *data)
508{
509 DeviceClass *dc = DEVICE_CLASS(klass);
510 VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
511
512 k->init = s390_virtio_net_init;
513 dc->props = s390_virtio_net_properties;
514}
515
516static const TypeInfo s390_virtio_net = {
517 .name = TYPE_VIRTIO_NET_S390,
518 .parent = TYPE_VIRTIO_S390_DEVICE,
519 .instance_size = sizeof(VirtIONetS390),
520 .instance_init = s390_virtio_net_instance_init,
521 .class_init = s390_virtio_net_class_init,
522};
523
524static void s390_virtio_blk_class_init(ObjectClass *klass, void *data)
525{
526 VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
527
528 k->init = s390_virtio_blk_init;
529}
530
531static const TypeInfo s390_virtio_blk = {
532 .name = "virtio-blk-s390",
533 .parent = TYPE_VIRTIO_S390_DEVICE,
534 .instance_size = sizeof(VirtIOBlkS390),
535 .instance_init = s390_virtio_blk_instance_init,
536 .class_init = s390_virtio_blk_class_init,
537};
538
539static Property s390_virtio_serial_properties[] = {
540 DEFINE_PROP_END_OF_LIST(),
541};
542
543static void s390_virtio_serial_class_init(ObjectClass *klass, void *data)
544{
545 DeviceClass *dc = DEVICE_CLASS(klass);
546 VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
547
548 k->init = s390_virtio_serial_init;
549 dc->props = s390_virtio_serial_properties;
550}
551
552static const TypeInfo s390_virtio_serial = {
553 .name = TYPE_VIRTIO_SERIAL_S390,
554 .parent = TYPE_VIRTIO_S390_DEVICE,
555 .instance_size = sizeof(VirtIOSerialS390),
556 .instance_init = s390_virtio_serial_instance_init,
557 .class_init = s390_virtio_serial_class_init,
558};
559
560static Property s390_virtio_rng_properties[] = {
561 DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
562 DEFINE_PROP_END_OF_LIST(),
563};
564
565static void s390_virtio_rng_class_init(ObjectClass *klass, void *data)
566{
567 DeviceClass *dc = DEVICE_CLASS(klass);
568 VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
569
570 k->init = s390_virtio_rng_init;
571 dc->props = s390_virtio_rng_properties;
572}
573
574static const TypeInfo s390_virtio_rng = {
575 .name = TYPE_VIRTIO_RNG_S390,
576 .parent = TYPE_VIRTIO_S390_DEVICE,
577 .instance_size = sizeof(VirtIORNGS390),
578 .instance_init = s390_virtio_rng_instance_init,
579 .class_init = s390_virtio_rng_class_init,
580};
581
582static int s390_virtio_busdev_init(DeviceState *dev)
583{
584 VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
585 VirtIOS390DeviceClass *_info = VIRTIO_S390_DEVICE_GET_CLASS(dev);
586
587 virtio_s390_bus_new(&_dev->bus, sizeof(_dev->bus), _dev);
588
589 return _info->init(_dev);
590}
591
592static void s390_virtio_busdev_reset(DeviceState *dev)
593{
594 VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
595
596 virtio_reset(_dev->vdev);
597}
598
599static void virtio_s390_device_class_init(ObjectClass *klass, void *data)
600{
601 DeviceClass *dc = DEVICE_CLASS(klass);
602
603 dc->init = s390_virtio_busdev_init;
604 dc->bus_type = TYPE_S390_VIRTIO_BUS;
605 dc->reset = s390_virtio_busdev_reset;
606}
607
608static const TypeInfo virtio_s390_device_info = {
609 .name = TYPE_VIRTIO_S390_DEVICE,
610 .parent = TYPE_DEVICE,
611 .instance_size = sizeof(VirtIOS390Device),
612 .class_init = virtio_s390_device_class_init,
613 .class_size = sizeof(VirtIOS390DeviceClass),
614 .abstract = true,
615};
616
617static Property s390_virtio_scsi_properties[] = {
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_PROP_END_OF_LIST(),
644};
645
646static void s390_vhost_scsi_class_init(ObjectClass *klass, void *data)
647{
648 DeviceClass *dc = DEVICE_CLASS(klass);
649 VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
650
651 k->init = s390_vhost_scsi_init;
652 dc->props = s390_vhost_scsi_properties;
653}
654
655static const TypeInfo s390_vhost_scsi = {
656 .name = TYPE_VHOST_SCSI_S390,
657 .parent = TYPE_VIRTIO_S390_DEVICE,
658 .instance_size = sizeof(VHostSCSIS390),
659 .instance_init = s390_vhost_scsi_instance_init,
660 .class_init = s390_vhost_scsi_class_init,
661};
662#endif
663
664
665
666
667static int s390_virtio_bridge_init(SysBusDevice *dev)
668{
669
670 return 0;
671}
672
673static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data)
674{
675 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
676
677 k->init = s390_virtio_bridge_init;
678}
679
680static const TypeInfo s390_virtio_bridge_info = {
681 .name = "s390-virtio-bridge",
682 .parent = TYPE_SYS_BUS_DEVICE,
683 .instance_size = sizeof(SysBusDevice),
684 .class_init = s390_virtio_bridge_class_init,
685 .interfaces = (InterfaceInfo[]) {
686 { TYPE_HOTPLUG_HANDLER },
687 { }
688 }
689};
690
691
692
693static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size,
694 VirtIOS390Device *dev)
695{
696 DeviceState *qdev = DEVICE(dev);
697 char virtio_bus_name[] = "virtio-bus";
698
699 qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_S390_BUS,
700 qdev, virtio_bus_name);
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