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