]> git.proxmox.com Git - mirror_qemu.git/blob - hw/s390x/virtio-ccw.c
qdev: Pass size to qbus_create_inplace()
[mirror_qemu.git] / hw / s390x / virtio-ccw.c
1 /*
2 * virtio ccw target implementation
3 *
4 * Copyright 2012 IBM Corp.
5 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
6 *
7 * This work is licensed under the terms of the GNU GPL, version 2 or (at
8 * your option) any later version. See the COPYING file in the top-level
9 * directory.
10 */
11
12 #include "hw/hw.h"
13 #include "block/block.h"
14 #include "sysemu/blockdev.h"
15 #include "sysemu/sysemu.h"
16 #include "net/net.h"
17 #include "monitor/monitor.h"
18 #include "hw/virtio/virtio.h"
19 #include "hw/virtio/virtio-serial.h"
20 #include "hw/virtio/virtio-net.h"
21 #include "hw/sysbus.h"
22 #include "qemu/bitops.h"
23 #include "hw/virtio/virtio-bus.h"
24
25 #include "ioinst.h"
26 #include "css.h"
27 #include "virtio-ccw.h"
28 #include "trace.h"
29
30 static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
31 VirtioCcwDevice *dev);
32
33 static int virtual_css_bus_reset(BusState *qbus)
34 {
35 /* This should actually be modelled via the generic css */
36 css_reset();
37
38 /* we dont traverse ourself, return 0 */
39 return 0;
40 }
41
42
43 static void virtual_css_bus_class_init(ObjectClass *klass, void *data)
44 {
45 BusClass *k = BUS_CLASS(klass);
46
47 k->reset = virtual_css_bus_reset;
48 }
49
50 static const TypeInfo virtual_css_bus_info = {
51 .name = TYPE_VIRTUAL_CSS_BUS,
52 .parent = TYPE_BUS,
53 .instance_size = sizeof(VirtualCssBus),
54 .class_init = virtual_css_bus_class_init,
55 };
56
57 VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
58 {
59 VirtIODevice *vdev = NULL;
60
61 if (sch->driver_data) {
62 vdev = ((VirtioCcwDevice *)sch->driver_data)->vdev;
63 }
64 return vdev;
65 }
66
67 static int virtio_ccw_set_guest2host_notifier(VirtioCcwDevice *dev, int n,
68 bool assign, bool set_handler)
69 {
70 VirtQueue *vq = virtio_get_queue(dev->vdev, n);
71 EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
72 int r = 0;
73 SubchDev *sch = dev->sch;
74 uint32_t sch_id = (css_build_subchannel_id(sch) << 16) | sch->schid;
75
76 if (assign) {
77 r = event_notifier_init(notifier, 1);
78 if (r < 0) {
79 error_report("%s: unable to init event notifier: %d", __func__, r);
80 return r;
81 }
82 virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
83 r = s390_assign_subch_ioeventfd(notifier, sch_id, n, assign);
84 if (r < 0) {
85 error_report("%s: unable to assign ioeventfd: %d", __func__, r);
86 virtio_queue_set_host_notifier_fd_handler(vq, false, false);
87 event_notifier_cleanup(notifier);
88 return r;
89 }
90 } else {
91 virtio_queue_set_host_notifier_fd_handler(vq, false, false);
92 s390_assign_subch_ioeventfd(notifier, sch_id, n, assign);
93 event_notifier_cleanup(notifier);
94 }
95 return r;
96 }
97
98 static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
99 {
100 int n, r;
101
102 if (!(dev->flags & VIRTIO_CCW_FLAG_USE_IOEVENTFD) ||
103 dev->ioeventfd_disabled ||
104 dev->ioeventfd_started) {
105 return;
106 }
107 for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
108 if (!virtio_queue_get_num(dev->vdev, n)) {
109 continue;
110 }
111 r = virtio_ccw_set_guest2host_notifier(dev, n, true, true);
112 if (r < 0) {
113 goto assign_error;
114 }
115 }
116 dev->ioeventfd_started = true;
117 return;
118
119 assign_error:
120 while (--n >= 0) {
121 if (!virtio_queue_get_num(dev->vdev, n)) {
122 continue;
123 }
124 r = virtio_ccw_set_guest2host_notifier(dev, n, false, false);
125 assert(r >= 0);
126 }
127 dev->ioeventfd_started = false;
128 /* Disable ioeventfd for this device. */
129 dev->flags &= ~VIRTIO_CCW_FLAG_USE_IOEVENTFD;
130 error_report("%s: failed. Fallback to userspace (slower).", __func__);
131 }
132
133 static void virtio_ccw_stop_ioeventfd(VirtioCcwDevice *dev)
134 {
135 int n, r;
136
137 if (!dev->ioeventfd_started) {
138 return;
139 }
140 for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
141 if (!virtio_queue_get_num(dev->vdev, n)) {
142 continue;
143 }
144 r = virtio_ccw_set_guest2host_notifier(dev, n, false, false);
145 assert(r >= 0);
146 }
147 dev->ioeventfd_started = false;
148 }
149
150 VirtualCssBus *virtual_css_bus_init(void)
151 {
152 VirtualCssBus *cbus;
153 BusState *bus;
154 DeviceState *dev;
155
156 /* Create bridge device */
157 dev = qdev_create(NULL, "virtual-css-bridge");
158 qdev_init_nofail(dev);
159
160 /* Create bus on bridge device */
161 bus = qbus_create(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
162 cbus = VIRTUAL_CSS_BUS(bus);
163
164 /* Enable hotplugging */
165 bus->allow_hotplug = 1;
166
167 return cbus;
168 }
169
170 /* Communication blocks used by several channel commands. */
171 typedef struct VqInfoBlock {
172 uint64_t queue;
173 uint32_t align;
174 uint16_t index;
175 uint16_t num;
176 } QEMU_PACKED VqInfoBlock;
177
178 typedef struct VqConfigBlock {
179 uint16_t index;
180 uint16_t num_max;
181 } QEMU_PACKED VqConfigBlock;
182
183 typedef struct VirtioFeatDesc {
184 uint32_t features;
185 uint8_t index;
186 } QEMU_PACKED VirtioFeatDesc;
187
188 /* Specify where the virtqueues for the subchannel are in guest memory. */
189 static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
190 uint16_t index, uint16_t num)
191 {
192 VirtioCcwDevice *dev = sch->driver_data;
193
194 if (index > VIRTIO_PCI_QUEUE_MAX) {
195 return -EINVAL;
196 }
197
198 /* Current code in virtio.c relies on 4K alignment. */
199 if (addr && (align != 4096)) {
200 return -EINVAL;
201 }
202
203 if (!dev) {
204 return -EINVAL;
205 }
206
207 virtio_queue_set_addr(dev->vdev, index, addr);
208 if (!addr) {
209 virtio_queue_set_vector(dev->vdev, index, 0);
210 } else {
211 /* Fail if we don't have a big enough queue. */
212 /* TODO: Add interface to handle vring.num changing */
213 if (virtio_queue_get_num(dev->vdev, index) > num) {
214 return -EINVAL;
215 }
216 virtio_queue_set_vector(dev->vdev, index, index);
217 }
218 /* tell notify handler in case of config change */
219 dev->vdev->config_vector = VIRTIO_PCI_QUEUE_MAX;
220 return 0;
221 }
222
223 static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
224 {
225 int ret;
226 VqInfoBlock info;
227 uint8_t status;
228 VirtioFeatDesc features;
229 void *config;
230 hwaddr indicators;
231 VqConfigBlock vq_config;
232 VirtioCcwDevice *dev = sch->driver_data;
233 bool check_len;
234 int len;
235 hwaddr hw_len;
236
237 if (!dev) {
238 return -EINVAL;
239 }
240
241 trace_virtio_ccw_interpret_ccw(sch->cssid, sch->ssid, sch->schid,
242 ccw.cmd_code);
243 check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));
244
245 /* Look at the command. */
246 switch (ccw.cmd_code) {
247 case CCW_CMD_SET_VQ:
248 if (check_len) {
249 if (ccw.count != sizeof(info)) {
250 ret = -EINVAL;
251 break;
252 }
253 } else if (ccw.count < sizeof(info)) {
254 /* Can't execute command. */
255 ret = -EINVAL;
256 break;
257 }
258 if (!ccw.cda) {
259 ret = -EFAULT;
260 } else {
261 info.queue = ldq_phys(ccw.cda);
262 info.align = ldl_phys(ccw.cda + sizeof(info.queue));
263 info.index = lduw_phys(ccw.cda + sizeof(info.queue)
264 + sizeof(info.align));
265 info.num = lduw_phys(ccw.cda + sizeof(info.queue)
266 + sizeof(info.align)
267 + sizeof(info.index));
268 ret = virtio_ccw_set_vqs(sch, info.queue, info.align, info.index,
269 info.num);
270 sch->curr_status.scsw.count = 0;
271 }
272 break;
273 case CCW_CMD_VDEV_RESET:
274 virtio_ccw_stop_ioeventfd(dev);
275 virtio_reset(dev->vdev);
276 ret = 0;
277 break;
278 case CCW_CMD_READ_FEAT:
279 if (check_len) {
280 if (ccw.count != sizeof(features)) {
281 ret = -EINVAL;
282 break;
283 }
284 } else if (ccw.count < sizeof(features)) {
285 /* Can't execute command. */
286 ret = -EINVAL;
287 break;
288 }
289 if (!ccw.cda) {
290 ret = -EFAULT;
291 } else {
292 features.index = ldub_phys(ccw.cda + sizeof(features.features));
293 if (features.index < ARRAY_SIZE(dev->host_features)) {
294 features.features = dev->host_features[features.index];
295 } else {
296 /* Return zeroes if the guest supports more feature bits. */
297 features.features = 0;
298 }
299 stl_le_phys(ccw.cda, features.features);
300 sch->curr_status.scsw.count = ccw.count - sizeof(features);
301 ret = 0;
302 }
303 break;
304 case CCW_CMD_WRITE_FEAT:
305 if (check_len) {
306 if (ccw.count != sizeof(features)) {
307 ret = -EINVAL;
308 break;
309 }
310 } else if (ccw.count < sizeof(features)) {
311 /* Can't execute command. */
312 ret = -EINVAL;
313 break;
314 }
315 if (!ccw.cda) {
316 ret = -EFAULT;
317 } else {
318 features.index = ldub_phys(ccw.cda + sizeof(features.features));
319 features.features = ldl_le_phys(ccw.cda);
320 if (features.index < ARRAY_SIZE(dev->host_features)) {
321 virtio_bus_set_vdev_features(&dev->bus, features.features);
322 dev->vdev->guest_features = features.features;
323 } else {
324 /*
325 * If the guest supports more feature bits, assert that it
326 * passes us zeroes for those we don't support.
327 */
328 if (features.features) {
329 fprintf(stderr, "Guest bug: features[%i]=%x (expected 0)\n",
330 features.index, features.features);
331 /* XXX: do a unit check here? */
332 }
333 }
334 sch->curr_status.scsw.count = ccw.count - sizeof(features);
335 ret = 0;
336 }
337 break;
338 case CCW_CMD_READ_CONF:
339 if (check_len) {
340 if (ccw.count > dev->vdev->config_len) {
341 ret = -EINVAL;
342 break;
343 }
344 }
345 len = MIN(ccw.count, dev->vdev->config_len);
346 if (!ccw.cda) {
347 ret = -EFAULT;
348 } else {
349 virtio_bus_get_vdev_config(&dev->bus, dev->vdev->config);
350 /* XXX config space endianness */
351 cpu_physical_memory_write(ccw.cda, dev->vdev->config, len);
352 sch->curr_status.scsw.count = ccw.count - len;
353 ret = 0;
354 }
355 break;
356 case CCW_CMD_WRITE_CONF:
357 if (check_len) {
358 if (ccw.count > dev->vdev->config_len) {
359 ret = -EINVAL;
360 break;
361 }
362 }
363 len = MIN(ccw.count, dev->vdev->config_len);
364 hw_len = len;
365 if (!ccw.cda) {
366 ret = -EFAULT;
367 } else {
368 config = cpu_physical_memory_map(ccw.cda, &hw_len, 0);
369 if (!config) {
370 ret = -EFAULT;
371 } else {
372 len = hw_len;
373 /* XXX config space endianness */
374 memcpy(dev->vdev->config, config, len);
375 cpu_physical_memory_unmap(config, hw_len, 0, hw_len);
376 virtio_bus_set_vdev_config(&dev->bus, dev->vdev->config);
377 sch->curr_status.scsw.count = ccw.count - len;
378 ret = 0;
379 }
380 }
381 break;
382 case CCW_CMD_WRITE_STATUS:
383 if (check_len) {
384 if (ccw.count != sizeof(status)) {
385 ret = -EINVAL;
386 break;
387 }
388 } else if (ccw.count < sizeof(status)) {
389 /* Can't execute command. */
390 ret = -EINVAL;
391 break;
392 }
393 if (!ccw.cda) {
394 ret = -EFAULT;
395 } else {
396 status = ldub_phys(ccw.cda);
397 if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
398 virtio_ccw_stop_ioeventfd(dev);
399 }
400 virtio_set_status(dev->vdev, status);
401 if (dev->vdev->status == 0) {
402 virtio_reset(dev->vdev);
403 }
404 if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
405 virtio_ccw_start_ioeventfd(dev);
406 }
407 sch->curr_status.scsw.count = ccw.count - sizeof(status);
408 ret = 0;
409 }
410 break;
411 case CCW_CMD_SET_IND:
412 if (check_len) {
413 if (ccw.count != sizeof(indicators)) {
414 ret = -EINVAL;
415 break;
416 }
417 } else if (ccw.count < sizeof(indicators)) {
418 /* Can't execute command. */
419 ret = -EINVAL;
420 break;
421 }
422 if (!ccw.cda) {
423 ret = -EFAULT;
424 } else {
425 indicators = ldq_phys(ccw.cda);
426 dev->indicators = indicators;
427 sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
428 ret = 0;
429 }
430 break;
431 case CCW_CMD_SET_CONF_IND:
432 if (check_len) {
433 if (ccw.count != sizeof(indicators)) {
434 ret = -EINVAL;
435 break;
436 }
437 } else if (ccw.count < sizeof(indicators)) {
438 /* Can't execute command. */
439 ret = -EINVAL;
440 break;
441 }
442 if (!ccw.cda) {
443 ret = -EFAULT;
444 } else {
445 indicators = ldq_phys(ccw.cda);
446 dev->indicators2 = indicators;
447 sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
448 ret = 0;
449 }
450 break;
451 case CCW_CMD_READ_VQ_CONF:
452 if (check_len) {
453 if (ccw.count != sizeof(vq_config)) {
454 ret = -EINVAL;
455 break;
456 }
457 } else if (ccw.count < sizeof(vq_config)) {
458 /* Can't execute command. */
459 ret = -EINVAL;
460 break;
461 }
462 if (!ccw.cda) {
463 ret = -EFAULT;
464 } else {
465 vq_config.index = lduw_phys(ccw.cda);
466 vq_config.num_max = virtio_queue_get_num(dev->vdev,
467 vq_config.index);
468 stw_phys(ccw.cda + sizeof(vq_config.index), vq_config.num_max);
469 sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);
470 ret = 0;
471 }
472 break;
473 default:
474 ret = -ENOSYS;
475 break;
476 }
477 return ret;
478 }
479
480 static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
481 {
482 unsigned int cssid = 0;
483 unsigned int ssid = 0;
484 unsigned int schid;
485 unsigned int devno;
486 bool have_devno = false;
487 bool found = false;
488 SubchDev *sch;
489 int ret;
490 int num;
491 DeviceState *parent = DEVICE(dev);
492
493 sch = g_malloc0(sizeof(SubchDev));
494
495 sch->driver_data = dev;
496 dev->sch = sch;
497
498 dev->vdev = vdev;
499 dev->indicators = 0;
500
501 /* Initialize subchannel structure. */
502 sch->channel_prog = 0x0;
503 sch->last_cmd_valid = false;
504 sch->orb = NULL;
505 /*
506 * Use a device number if provided. Otherwise, fall back to subchannel
507 * number.
508 */
509 if (dev->bus_id) {
510 num = sscanf(dev->bus_id, "%x.%x.%04x", &cssid, &ssid, &devno);
511 if (num == 3) {
512 if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) {
513 ret = -EINVAL;
514 error_report("Invalid cssid or ssid: cssid %x, ssid %x",
515 cssid, ssid);
516 goto out_err;
517 }
518 /* Enforce use of virtual cssid. */
519 if (cssid != VIRTUAL_CSSID) {
520 ret = -EINVAL;
521 error_report("cssid %x not valid for virtio devices", cssid);
522 goto out_err;
523 }
524 if (css_devno_used(cssid, ssid, devno)) {
525 ret = -EEXIST;
526 error_report("Device %x.%x.%04x already exists", cssid, ssid,
527 devno);
528 goto out_err;
529 }
530 sch->cssid = cssid;
531 sch->ssid = ssid;
532 sch->devno = devno;
533 have_devno = true;
534 } else {
535 ret = -EINVAL;
536 error_report("Malformed devno parameter '%s'", dev->bus_id);
537 goto out_err;
538 }
539 }
540
541 /* Find the next free id. */
542 if (have_devno) {
543 for (schid = 0; schid <= MAX_SCHID; schid++) {
544 if (!css_find_subch(1, cssid, ssid, schid)) {
545 sch->schid = schid;
546 css_subch_assign(cssid, ssid, schid, devno, sch);
547 found = true;
548 break;
549 }
550 }
551 if (!found) {
552 ret = -ENODEV;
553 error_report("No free subchannel found for %x.%x.%04x", cssid, ssid,
554 devno);
555 goto out_err;
556 }
557 trace_virtio_ccw_new_device(cssid, ssid, schid, devno,
558 "user-configured");
559 } else {
560 cssid = VIRTUAL_CSSID;
561 for (ssid = 0; ssid <= MAX_SSID; ssid++) {
562 for (schid = 0; schid <= MAX_SCHID; schid++) {
563 if (!css_find_subch(1, cssid, ssid, schid)) {
564 sch->cssid = cssid;
565 sch->ssid = ssid;
566 sch->schid = schid;
567 devno = schid;
568 /*
569 * If the devno is already taken, look further in this
570 * subchannel set.
571 */
572 while (css_devno_used(cssid, ssid, devno)) {
573 if (devno == MAX_SCHID) {
574 devno = 0;
575 } else if (devno == schid - 1) {
576 ret = -ENODEV;
577 error_report("No free devno found");
578 goto out_err;
579 } else {
580 devno++;
581 }
582 }
583 sch->devno = devno;
584 css_subch_assign(cssid, ssid, schid, devno, sch);
585 found = true;
586 break;
587 }
588 }
589 if (found) {
590 break;
591 }
592 }
593 if (!found) {
594 ret = -ENODEV;
595 error_report("Virtual channel subsystem is full!");
596 goto out_err;
597 }
598 trace_virtio_ccw_new_device(cssid, ssid, schid, devno,
599 "auto-configured");
600 }
601
602 /* Build initial schib. */
603 css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);
604
605 sch->ccw_cb = virtio_ccw_cb;
606
607 /* Build senseid data. */
608 memset(&sch->id, 0, sizeof(SenseId));
609 sch->id.reserved = 0xff;
610 sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
611 sch->id.cu_model = dev->vdev->device_id;
612
613 /* Only the first 32 feature bits are used. */
614 dev->host_features[0] = virtio_bus_get_vdev_features(&dev->bus,
615 dev->host_features[0]);
616
617 dev->host_features[0] |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
618 dev->host_features[0] |= 0x1 << VIRTIO_F_BAD_FEATURE;
619
620 css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
621 parent->hotplugged, 1);
622 return 0;
623
624 out_err:
625 dev->sch = NULL;
626 g_free(sch);
627 return ret;
628 }
629
630 static int virtio_ccw_exit(VirtioCcwDevice *dev)
631 {
632 SubchDev *sch = dev->sch;
633
634 virtio_ccw_stop_ioeventfd(dev);
635 if (sch) {
636 css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
637 g_free(sch);
638 }
639 dev->indicators = 0;
640 return 0;
641 }
642
643 static int virtio_ccw_net_init(VirtioCcwDevice *ccw_dev)
644 {
645 DeviceState *qdev = DEVICE(ccw_dev);
646 VirtIONetCcw *dev = VIRTIO_NET_CCW(ccw_dev);
647 DeviceState *vdev = DEVICE(&dev->vdev);
648
649 virtio_net_set_config_size(&dev->vdev, ccw_dev->host_features[0]);
650 virtio_net_set_netclient_name(&dev->vdev, qdev->id,
651 object_get_typename(OBJECT(qdev)));
652 qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
653 if (qdev_init(vdev) < 0) {
654 return -1;
655 }
656
657 return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
658 }
659
660 static void virtio_ccw_net_instance_init(Object *obj)
661 {
662 VirtIONetCcw *dev = VIRTIO_NET_CCW(obj);
663 object_initialize(&dev->vdev, TYPE_VIRTIO_NET);
664 object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
665 }
666
667 static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
668 {
669 VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(ccw_dev);
670 DeviceState *vdev = DEVICE(&dev->vdev);
671 virtio_blk_set_conf(vdev, &(dev->blk));
672 qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
673 if (qdev_init(vdev) < 0) {
674 return -1;
675 }
676
677 return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
678 }
679
680 static void virtio_ccw_blk_instance_init(Object *obj)
681 {
682 VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(obj);
683 object_initialize(&dev->vdev, TYPE_VIRTIO_BLK);
684 object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
685 }
686
687 static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev)
688 {
689 VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(ccw_dev);
690 DeviceState *vdev = DEVICE(&dev->vdev);
691 DeviceState *proxy = DEVICE(ccw_dev);
692 char *bus_name;
693
694 /*
695 * For command line compatibility, this sets the virtio-serial-device bus
696 * name as before.
697 */
698 if (proxy->id) {
699 bus_name = g_strdup_printf("%s.0", proxy->id);
700 virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name);
701 g_free(bus_name);
702 }
703
704 qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
705 if (qdev_init(vdev) < 0) {
706 return -1;
707 }
708
709 return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
710 }
711
712
713 static void virtio_ccw_serial_instance_init(Object *obj)
714 {
715 VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(obj);
716 object_initialize(&dev->vdev, TYPE_VIRTIO_SERIAL);
717 object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
718 }
719
720 static int virtio_ccw_balloon_init(VirtioCcwDevice *ccw_dev)
721 {
722 VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(ccw_dev);
723 DeviceState *vdev = DEVICE(&dev->vdev);
724
725 qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
726 if (qdev_init(vdev) < 0) {
727 return -1;
728 }
729
730 return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
731 }
732
733 static void balloon_ccw_stats_get_all(Object *obj, struct Visitor *v,
734 void *opaque, const char *name,
735 Error **errp)
736 {
737 VirtIOBalloonCcw *dev = opaque;
738 object_property_get(OBJECT(&dev->vdev), v, "guest-stats", errp);
739 }
740
741 static void balloon_ccw_stats_get_poll_interval(Object *obj, struct Visitor *v,
742 void *opaque, const char *name,
743 Error **errp)
744 {
745 VirtIOBalloonCcw *dev = opaque;
746 object_property_get(OBJECT(&dev->vdev), v, "guest-stats-polling-interval",
747 errp);
748 }
749
750 static void balloon_ccw_stats_set_poll_interval(Object *obj, struct Visitor *v,
751 void *opaque, const char *name,
752 Error **errp)
753 {
754 VirtIOBalloonCcw *dev = opaque;
755 object_property_set(OBJECT(&dev->vdev), v, "guest-stats-polling-interval",
756 errp);
757 }
758
759 static void virtio_ccw_balloon_instance_init(Object *obj)
760 {
761 VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj);
762 object_initialize(&dev->vdev, TYPE_VIRTIO_BALLOON);
763 object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
764
765 object_property_add(obj, "guest-stats", "guest statistics",
766 balloon_ccw_stats_get_all, NULL, NULL, dev, NULL);
767
768 object_property_add(obj, "guest-stats-polling-interval", "int",
769 balloon_ccw_stats_get_poll_interval,
770 balloon_ccw_stats_set_poll_interval,
771 NULL, dev, NULL);
772 }
773
774 static int virtio_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
775 {
776 VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(ccw_dev);
777 DeviceState *vdev = DEVICE(&dev->vdev);
778 DeviceState *qdev = DEVICE(ccw_dev);
779 char *bus_name;
780
781 /*
782 * For command line compatibility, this sets the virtio-scsi-device bus
783 * name as before.
784 */
785 if (qdev->id) {
786 bus_name = g_strdup_printf("%s.0", qdev->id);
787 virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name);
788 g_free(bus_name);
789 }
790
791 qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
792 if (qdev_init(vdev) < 0) {
793 return -1;
794 }
795
796 return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
797 }
798
799 static void virtio_ccw_scsi_instance_init(Object *obj)
800 {
801 VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(obj);
802 object_initialize(&dev->vdev, TYPE_VIRTIO_SCSI);
803 object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
804 }
805
806 #ifdef CONFIG_VHOST_SCSI
807 static int vhost_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
808 {
809 VHostSCSICcw *dev = VHOST_SCSI_CCW(ccw_dev);
810 DeviceState *vdev = DEVICE(&dev->vdev);
811
812 qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
813 if (qdev_init(vdev) < 0) {
814 return -1;
815 }
816
817 return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
818 }
819
820 static void vhost_ccw_scsi_instance_init(Object *obj)
821 {
822 VHostSCSICcw *dev = VHOST_SCSI_CCW(obj);
823 object_initialize(&dev->vdev, TYPE_VHOST_SCSI);
824 object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
825 }
826 #endif
827
828 static int virtio_ccw_rng_init(VirtioCcwDevice *ccw_dev)
829 {
830 VirtIORNGCcw *dev = VIRTIO_RNG_CCW(ccw_dev);
831 DeviceState *vdev = DEVICE(&dev->vdev);
832
833 qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
834 if (qdev_init(vdev) < 0) {
835 return -1;
836 }
837
838 object_property_set_link(OBJECT(dev),
839 OBJECT(dev->vdev.conf.rng), "rng",
840 NULL);
841
842 return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
843 }
844
845 /* DeviceState to VirtioCcwDevice. Note: used on datapath,
846 * be careful and test performance if you change this.
847 */
848 static inline VirtioCcwDevice *to_virtio_ccw_dev_fast(DeviceState *d)
849 {
850 return container_of(d, VirtioCcwDevice, parent_obj);
851 }
852
853 static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
854 {
855 VirtioCcwDevice *dev = to_virtio_ccw_dev_fast(d);
856 SubchDev *sch = dev->sch;
857 uint64_t indicators;
858
859 if (vector >= 128) {
860 return;
861 }
862
863 if (vector < VIRTIO_PCI_QUEUE_MAX) {
864 if (!dev->indicators) {
865 return;
866 }
867 indicators = ldq_phys(dev->indicators);
868 indicators |= 1ULL << vector;
869 stq_phys(dev->indicators, indicators);
870 } else {
871 if (!dev->indicators2) {
872 return;
873 }
874 vector = 0;
875 indicators = ldq_phys(dev->indicators2);
876 indicators |= 1ULL << vector;
877 stq_phys(dev->indicators2, indicators);
878 }
879
880 css_conditional_io_interrupt(sch);
881
882 }
883
884 static unsigned virtio_ccw_get_features(DeviceState *d)
885 {
886 VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
887
888 /* Only the first 32 feature bits are used. */
889 return dev->host_features[0];
890 }
891
892 static void virtio_ccw_reset(DeviceState *d)
893 {
894 VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
895
896 virtio_ccw_stop_ioeventfd(dev);
897 virtio_reset(dev->vdev);
898 css_reset_sch(dev->sch);
899 dev->indicators = 0;
900 dev->indicators2 = 0;
901 }
902
903 static void virtio_ccw_vmstate_change(DeviceState *d, bool running)
904 {
905 VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
906
907 if (running) {
908 virtio_ccw_start_ioeventfd(dev);
909 } else {
910 virtio_ccw_stop_ioeventfd(dev);
911 }
912 }
913
914 static bool virtio_ccw_query_guest_notifiers(DeviceState *d)
915 {
916 VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
917
918 return !!(dev->sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA);
919 }
920
921 static int virtio_ccw_set_host_notifier(DeviceState *d, int n, bool assign)
922 {
923 VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
924
925 /* Stop using the generic ioeventfd, we are doing eventfd handling
926 * ourselves below */
927 dev->ioeventfd_disabled = assign;
928 if (assign) {
929 virtio_ccw_stop_ioeventfd(dev);
930 }
931 return virtio_ccw_set_guest2host_notifier(dev, n, assign, false);
932 }
933
934 static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n,
935 bool assign, bool with_irqfd)
936 {
937 VirtQueue *vq = virtio_get_queue(dev->vdev, n);
938 EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
939 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(dev->vdev);
940
941 if (assign) {
942 int r = event_notifier_init(notifier, 0);
943
944 if (r < 0) {
945 return r;
946 }
947 virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd);
948 /* We do not support irqfd for classic I/O interrupts, because the
949 * classic interrupts are intermixed with the subchannel status, that
950 * is queried with test subchannel. We want to use vhost, though.
951 * Lets make sure to have vhost running and wire up the irq fd to
952 * land in qemu (and only the irq fd) in this code.
953 */
954 if (k->guest_notifier_mask) {
955 k->guest_notifier_mask(dev->vdev, n, false);
956 }
957 /* get lost events and re-inject */
958 if (k->guest_notifier_pending &&
959 k->guest_notifier_pending(dev->vdev, n)) {
960 event_notifier_set(notifier);
961 }
962 } else {
963 if (k->guest_notifier_mask) {
964 k->guest_notifier_mask(dev->vdev, n, true);
965 }
966 virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd);
967 event_notifier_cleanup(notifier);
968 }
969 return 0;
970 }
971
972 static int virtio_ccw_set_guest_notifiers(DeviceState *d, int nvqs,
973 bool assigned)
974 {
975 VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
976 VirtIODevice *vdev = dev->vdev;
977 int r, n;
978
979 for (n = 0; n < nvqs; n++) {
980 if (!virtio_queue_get_num(vdev, n)) {
981 break;
982 }
983 /* false -> true, as soon as irqfd works */
984 r = virtio_ccw_set_guest_notifier(dev, n, assigned, false);
985 if (r < 0) {
986 goto assign_error;
987 }
988 }
989 return 0;
990
991 assign_error:
992 while (--n >= 0) {
993 virtio_ccw_set_guest_notifier(dev, n, !assigned, false);
994 }
995 return r;
996 }
997
998 /**************** Virtio-ccw Bus Device Descriptions *******************/
999
1000 static Property virtio_ccw_net_properties[] = {
1001 DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
1002 DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features[0]),
1003 DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetCcw, vdev.net_conf),
1004 DEFINE_NIC_PROPERTIES(VirtIONetCcw, vdev.nic_conf),
1005 DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
1006 VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
1007 DEFINE_PROP_END_OF_LIST(),
1008 };
1009
1010 static void virtio_ccw_net_class_init(ObjectClass *klass, void *data)
1011 {
1012 DeviceClass *dc = DEVICE_CLASS(klass);
1013 VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
1014
1015 k->init = virtio_ccw_net_init;
1016 k->exit = virtio_ccw_exit;
1017 dc->reset = virtio_ccw_reset;
1018 dc->props = virtio_ccw_net_properties;
1019 }
1020
1021 static const TypeInfo virtio_ccw_net = {
1022 .name = TYPE_VIRTIO_NET_CCW,
1023 .parent = TYPE_VIRTIO_CCW_DEVICE,
1024 .instance_size = sizeof(VirtIONetCcw),
1025 .instance_init = virtio_ccw_net_instance_init,
1026 .class_init = virtio_ccw_net_class_init,
1027 };
1028
1029 static Property virtio_ccw_blk_properties[] = {
1030 DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
1031 DEFINE_VIRTIO_BLK_FEATURES(VirtioCcwDevice, host_features[0]),
1032 DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlkCcw, blk),
1033 DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
1034 VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
1035 #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
1036 DEFINE_PROP_BIT("x-data-plane", VirtIOBlkCcw, blk.data_plane, 0, false),
1037 #endif
1038 DEFINE_PROP_END_OF_LIST(),
1039 };
1040
1041 static void virtio_ccw_blk_class_init(ObjectClass *klass, void *data)
1042 {
1043 DeviceClass *dc = DEVICE_CLASS(klass);
1044 VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
1045
1046 k->init = virtio_ccw_blk_init;
1047 k->exit = virtio_ccw_exit;
1048 dc->reset = virtio_ccw_reset;
1049 dc->props = virtio_ccw_blk_properties;
1050 }
1051
1052 static const TypeInfo virtio_ccw_blk = {
1053 .name = TYPE_VIRTIO_BLK_CCW,
1054 .parent = TYPE_VIRTIO_CCW_DEVICE,
1055 .instance_size = sizeof(VirtIOBlkCcw),
1056 .instance_init = virtio_ccw_blk_instance_init,
1057 .class_init = virtio_ccw_blk_class_init,
1058 };
1059
1060 static Property virtio_ccw_serial_properties[] = {
1061 DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
1062 DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtioSerialCcw, vdev.serial),
1063 DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
1064 DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
1065 VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
1066 DEFINE_PROP_END_OF_LIST(),
1067 };
1068
1069 static void virtio_ccw_serial_class_init(ObjectClass *klass, void *data)
1070 {
1071 DeviceClass *dc = DEVICE_CLASS(klass);
1072 VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
1073
1074 k->init = virtio_ccw_serial_init;
1075 k->exit = virtio_ccw_exit;
1076 dc->reset = virtio_ccw_reset;
1077 dc->props = virtio_ccw_serial_properties;
1078 }
1079
1080 static const TypeInfo virtio_ccw_serial = {
1081 .name = TYPE_VIRTIO_SERIAL_CCW,
1082 .parent = TYPE_VIRTIO_CCW_DEVICE,
1083 .instance_size = sizeof(VirtioSerialCcw),
1084 .instance_init = virtio_ccw_serial_instance_init,
1085 .class_init = virtio_ccw_serial_class_init,
1086 };
1087
1088 static Property virtio_ccw_balloon_properties[] = {
1089 DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
1090 DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
1091 DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
1092 VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
1093 DEFINE_PROP_END_OF_LIST(),
1094 };
1095
1096 static void virtio_ccw_balloon_class_init(ObjectClass *klass, void *data)
1097 {
1098 DeviceClass *dc = DEVICE_CLASS(klass);
1099 VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
1100
1101 k->init = virtio_ccw_balloon_init;
1102 k->exit = virtio_ccw_exit;
1103 dc->reset = virtio_ccw_reset;
1104 dc->props = virtio_ccw_balloon_properties;
1105 }
1106
1107 static const TypeInfo virtio_ccw_balloon = {
1108 .name = TYPE_VIRTIO_BALLOON_CCW,
1109 .parent = TYPE_VIRTIO_CCW_DEVICE,
1110 .instance_size = sizeof(VirtIOBalloonCcw),
1111 .instance_init = virtio_ccw_balloon_instance_init,
1112 .class_init = virtio_ccw_balloon_class_init,
1113 };
1114
1115 static Property virtio_ccw_scsi_properties[] = {
1116 DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
1117 DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
1118 DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features[0]),
1119 DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
1120 VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
1121 DEFINE_PROP_END_OF_LIST(),
1122 };
1123
1124 static void virtio_ccw_scsi_class_init(ObjectClass *klass, void *data)
1125 {
1126 DeviceClass *dc = DEVICE_CLASS(klass);
1127 VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
1128
1129 k->init = virtio_ccw_scsi_init;
1130 k->exit = virtio_ccw_exit;
1131 dc->reset = virtio_ccw_reset;
1132 dc->props = virtio_ccw_scsi_properties;
1133 }
1134
1135 static const TypeInfo virtio_ccw_scsi = {
1136 .name = TYPE_VIRTIO_SCSI_CCW,
1137 .parent = TYPE_VIRTIO_CCW_DEVICE,
1138 .instance_size = sizeof(VirtIOSCSICcw),
1139 .instance_init = virtio_ccw_scsi_instance_init,
1140 .class_init = virtio_ccw_scsi_class_init,
1141 };
1142
1143 #ifdef CONFIG_VHOST_SCSI
1144 static Property vhost_ccw_scsi_properties[] = {
1145 DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
1146 DEFINE_VHOST_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
1147 DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
1148 DEFINE_PROP_END_OF_LIST(),
1149 };
1150
1151 static void vhost_ccw_scsi_class_init(ObjectClass *klass, void *data)
1152 {
1153 DeviceClass *dc = DEVICE_CLASS(klass);
1154 VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
1155
1156 k->init = vhost_ccw_scsi_init;
1157 k->exit = virtio_ccw_exit;
1158 dc->reset = virtio_ccw_reset;
1159 dc->props = vhost_ccw_scsi_properties;
1160 }
1161
1162 static const TypeInfo vhost_ccw_scsi = {
1163 .name = TYPE_VHOST_SCSI_CCW,
1164 .parent = TYPE_VIRTIO_CCW_DEVICE,
1165 .instance_size = sizeof(VirtIOSCSICcw),
1166 .instance_init = vhost_ccw_scsi_instance_init,
1167 .class_init = vhost_ccw_scsi_class_init,
1168 };
1169 #endif
1170
1171 static void virtio_ccw_rng_instance_init(Object *obj)
1172 {
1173 VirtIORNGCcw *dev = VIRTIO_RNG_CCW(obj);
1174 object_initialize(&dev->vdev, TYPE_VIRTIO_RNG);
1175 object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
1176 object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
1177 (Object **)&dev->vdev.conf.rng, NULL);
1178 }
1179
1180 static Property virtio_ccw_rng_properties[] = {
1181 DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
1182 DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
1183 DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGCcw, vdev.conf),
1184 DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
1185 VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
1186 DEFINE_PROP_END_OF_LIST(),
1187 };
1188
1189 static void virtio_ccw_rng_class_init(ObjectClass *klass, void *data)
1190 {
1191 DeviceClass *dc = DEVICE_CLASS(klass);
1192 VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
1193
1194 k->init = virtio_ccw_rng_init;
1195 k->exit = virtio_ccw_exit;
1196 dc->reset = virtio_ccw_reset;
1197 dc->props = virtio_ccw_rng_properties;
1198 }
1199
1200 static const TypeInfo virtio_ccw_rng = {
1201 .name = TYPE_VIRTIO_RNG_CCW,
1202 .parent = TYPE_VIRTIO_CCW_DEVICE,
1203 .instance_size = sizeof(VirtIORNGCcw),
1204 .instance_init = virtio_ccw_rng_instance_init,
1205 .class_init = virtio_ccw_rng_class_init,
1206 };
1207
1208 static int virtio_ccw_busdev_init(DeviceState *dev)
1209 {
1210 VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
1211 VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
1212
1213 virtio_ccw_bus_new(&_dev->bus, sizeof(_dev->bus), _dev);
1214
1215 return _info->init(_dev);
1216 }
1217
1218 static int virtio_ccw_busdev_exit(DeviceState *dev)
1219 {
1220 VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
1221 VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
1222
1223 return _info->exit(_dev);
1224 }
1225
1226 static int virtio_ccw_busdev_unplug(DeviceState *dev)
1227 {
1228 VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
1229 SubchDev *sch = _dev->sch;
1230
1231 /*
1232 * We should arrive here only for device_del, since we don't support
1233 * direct hot(un)plug of channels, but only through virtio.
1234 */
1235 assert(sch != NULL);
1236 /* Subchannel is now disabled and no longer valid. */
1237 sch->curr_status.pmcw.flags &= ~(PMCW_FLAGS_MASK_ENA |
1238 PMCW_FLAGS_MASK_DNV);
1239
1240 css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0);
1241
1242 qdev_free(dev);
1243 return 0;
1244 }
1245
1246 static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
1247 {
1248 DeviceClass *dc = DEVICE_CLASS(klass);
1249
1250 dc->init = virtio_ccw_busdev_init;
1251 dc->exit = virtio_ccw_busdev_exit;
1252 dc->unplug = virtio_ccw_busdev_unplug;
1253 dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
1254
1255 }
1256
1257 static const TypeInfo virtio_ccw_device_info = {
1258 .name = TYPE_VIRTIO_CCW_DEVICE,
1259 .parent = TYPE_DEVICE,
1260 .instance_size = sizeof(VirtioCcwDevice),
1261 .class_init = virtio_ccw_device_class_init,
1262 .class_size = sizeof(VirtIOCCWDeviceClass),
1263 .abstract = true,
1264 };
1265
1266 /***************** Virtual-css Bus Bridge Device ********************/
1267 /* Only required to have the virtio bus as child in the system bus */
1268
1269 static int virtual_css_bridge_init(SysBusDevice *dev)
1270 {
1271 /* nothing */
1272 return 0;
1273 }
1274
1275 static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
1276 {
1277 DeviceClass *dc = DEVICE_CLASS(klass);
1278 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1279
1280 k->init = virtual_css_bridge_init;
1281 dc->no_user = 1;
1282 }
1283
1284 static const TypeInfo virtual_css_bridge_info = {
1285 .name = "virtual-css-bridge",
1286 .parent = TYPE_SYS_BUS_DEVICE,
1287 .instance_size = sizeof(SysBusDevice),
1288 .class_init = virtual_css_bridge_class_init,
1289 };
1290
1291 /* virtio-ccw-bus */
1292
1293 static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
1294 VirtioCcwDevice *dev)
1295 {
1296 DeviceState *qdev = DEVICE(dev);
1297 BusState *qbus;
1298 char virtio_bus_name[] = "virtio-bus";
1299
1300 qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_CCW_BUS,
1301 qdev, virtio_bus_name);
1302 qbus = BUS(bus);
1303 qbus->allow_hotplug = 1;
1304 }
1305
1306 static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data)
1307 {
1308 VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
1309 BusClass *bus_class = BUS_CLASS(klass);
1310
1311 bus_class->max_dev = 1;
1312 k->notify = virtio_ccw_notify;
1313 k->get_features = virtio_ccw_get_features;
1314 k->vmstate_change = virtio_ccw_vmstate_change;
1315 k->query_guest_notifiers = virtio_ccw_query_guest_notifiers;
1316 k->set_host_notifier = virtio_ccw_set_host_notifier;
1317 k->set_guest_notifiers = virtio_ccw_set_guest_notifiers;
1318 }
1319
1320 static const TypeInfo virtio_ccw_bus_info = {
1321 .name = TYPE_VIRTIO_CCW_BUS,
1322 .parent = TYPE_VIRTIO_BUS,
1323 .instance_size = sizeof(VirtioCcwBusState),
1324 .class_init = virtio_ccw_bus_class_init,
1325 };
1326
1327 static void virtio_ccw_register(void)
1328 {
1329 type_register_static(&virtio_ccw_bus_info);
1330 type_register_static(&virtual_css_bus_info);
1331 type_register_static(&virtio_ccw_device_info);
1332 type_register_static(&virtio_ccw_serial);
1333 type_register_static(&virtio_ccw_blk);
1334 type_register_static(&virtio_ccw_net);
1335 type_register_static(&virtio_ccw_balloon);
1336 type_register_static(&virtio_ccw_scsi);
1337 #ifdef CONFIG_VHOST_SCSI
1338 type_register_static(&vhost_ccw_scsi);
1339 #endif
1340 type_register_static(&virtio_ccw_rng);
1341 type_register_static(&virtual_css_bridge_info);
1342 }
1343
1344 type_init(virtio_ccw_register)