xref: /qemu/hw/s390x/virtio-ccw.c (revision f505a4d74aae6fc8bb5502a6038b5f671aa97713)
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 int virtual_css_bus_reset(BusState *qbus)
31 {
32     /* This should actually be modelled via the generic css */
33     css_reset();
34 
35     /* we dont traverse ourself, return 0 */
36     return 0;
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 static const VirtIOBindings virtio_ccw_bindings;
55 
56 VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
57 {
58     VirtIODevice *vdev = NULL;
59 
60     if (sch->driver_data) {
61         vdev = ((VirtioCcwDevice *)sch->driver_data)->vdev;
62     }
63     return vdev;
64 }
65 
66 VirtualCssBus *virtual_css_bus_init(void)
67 {
68     VirtualCssBus *cbus;
69     BusState *bus;
70     DeviceState *dev;
71 
72     /* Create bridge device */
73     dev = qdev_create(NULL, "virtual-css-bridge");
74     qdev_init_nofail(dev);
75 
76     /* Create bus on bridge device */
77     bus = qbus_create(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
78     cbus = VIRTUAL_CSS_BUS(bus);
79 
80     /* Enable hotplugging */
81     bus->allow_hotplug = 1;
82 
83     return cbus;
84 }
85 
86 /* Communication blocks used by several channel commands. */
87 typedef struct VqInfoBlock {
88     uint64_t queue;
89     uint32_t align;
90     uint16_t index;
91     uint16_t num;
92 } QEMU_PACKED VqInfoBlock;
93 
94 typedef struct VqConfigBlock {
95     uint16_t index;
96     uint16_t num_max;
97 } QEMU_PACKED VqConfigBlock;
98 
99 typedef struct VirtioFeatDesc {
100     uint32_t features;
101     uint8_t index;
102 } QEMU_PACKED VirtioFeatDesc;
103 
104 /* Specify where the virtqueues for the subchannel are in guest memory. */
105 static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
106                               uint16_t index, uint16_t num)
107 {
108     VirtioCcwDevice *dev = sch->driver_data;
109 
110     if (index > VIRTIO_PCI_QUEUE_MAX) {
111         return -EINVAL;
112     }
113 
114     /* Current code in virtio.c relies on 4K alignment. */
115     if (addr && (align != 4096)) {
116         return -EINVAL;
117     }
118 
119     if (!dev) {
120         return -EINVAL;
121     }
122 
123     virtio_queue_set_addr(dev->vdev, index, addr);
124     if (!addr) {
125         virtio_queue_set_vector(dev->vdev, index, 0);
126     } else {
127         /* Fail if we don't have a big enough queue. */
128         /* TODO: Add interface to handle vring.num changing */
129         if (virtio_queue_get_num(dev->vdev, index) > num) {
130             return -EINVAL;
131         }
132         virtio_queue_set_vector(dev->vdev, index, index);
133     }
134     /* tell notify handler in case of config change */
135     dev->vdev->config_vector = VIRTIO_PCI_QUEUE_MAX;
136     return 0;
137 }
138 
139 static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
140 {
141     int ret;
142     VqInfoBlock info;
143     uint8_t status;
144     VirtioFeatDesc features;
145     void *config;
146     hwaddr indicators;
147     VqConfigBlock vq_config;
148     VirtioCcwDevice *dev = sch->driver_data;
149     bool check_len;
150     int len;
151     hwaddr hw_len;
152 
153     if (!dev) {
154         return -EINVAL;
155     }
156 
157     trace_virtio_ccw_interpret_ccw(sch->cssid, sch->ssid, sch->schid,
158                                    ccw.cmd_code);
159     check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));
160 
161     /* Look at the command. */
162     switch (ccw.cmd_code) {
163     case CCW_CMD_SET_VQ:
164         if (check_len) {
165             if (ccw.count != sizeof(info)) {
166                 ret = -EINVAL;
167                 break;
168             }
169         } else if (ccw.count < sizeof(info)) {
170             /* Can't execute command. */
171             ret = -EINVAL;
172             break;
173         }
174         if (!ccw.cda) {
175             ret = -EFAULT;
176         } else {
177             info.queue = ldq_phys(ccw.cda);
178             info.align = ldl_phys(ccw.cda + sizeof(info.queue));
179             info.index = lduw_phys(ccw.cda + sizeof(info.queue)
180                                    + sizeof(info.align));
181             info.num = lduw_phys(ccw.cda + sizeof(info.queue)
182                                  + sizeof(info.align)
183                                  + sizeof(info.index));
184             ret = virtio_ccw_set_vqs(sch, info.queue, info.align, info.index,
185                                      info.num);
186             sch->curr_status.scsw.count = 0;
187         }
188         break;
189     case CCW_CMD_VDEV_RESET:
190         virtio_reset(dev->vdev);
191         ret = 0;
192         break;
193     case CCW_CMD_READ_FEAT:
194         if (check_len) {
195             if (ccw.count != sizeof(features)) {
196                 ret = -EINVAL;
197                 break;
198             }
199         } else if (ccw.count < sizeof(features)) {
200             /* Can't execute command. */
201             ret = -EINVAL;
202             break;
203         }
204         if (!ccw.cda) {
205             ret = -EFAULT;
206         } else {
207             features.index = ldub_phys(ccw.cda + sizeof(features.features));
208             if (features.index < ARRAY_SIZE(dev->host_features)) {
209                 features.features = dev->host_features[features.index];
210             } else {
211                 /* Return zeroes if the guest supports more feature bits. */
212                 features.features = 0;
213             }
214             stl_le_phys(ccw.cda, features.features);
215             sch->curr_status.scsw.count = ccw.count - sizeof(features);
216             ret = 0;
217         }
218         break;
219     case CCW_CMD_WRITE_FEAT:
220         if (check_len) {
221             if (ccw.count != sizeof(features)) {
222                 ret = -EINVAL;
223                 break;
224             }
225         } else if (ccw.count < sizeof(features)) {
226             /* Can't execute command. */
227             ret = -EINVAL;
228             break;
229         }
230         if (!ccw.cda) {
231             ret = -EFAULT;
232         } else {
233             features.index = ldub_phys(ccw.cda + sizeof(features.features));
234             features.features = ldl_le_phys(ccw.cda);
235             if (features.index < ARRAY_SIZE(dev->host_features)) {
236                 if (dev->vdev->set_features) {
237                     dev->vdev->set_features(dev->vdev, features.features);
238                 }
239                 dev->vdev->guest_features = features.features;
240             } else {
241                 /*
242                  * If the guest supports more feature bits, assert that it
243                  * passes us zeroes for those we don't support.
244                  */
245                 if (features.features) {
246                     fprintf(stderr, "Guest bug: features[%i]=%x (expected 0)\n",
247                             features.index, features.features);
248                     /* XXX: do a unit check here? */
249                 }
250             }
251             sch->curr_status.scsw.count = ccw.count - sizeof(features);
252             ret = 0;
253         }
254         break;
255     case CCW_CMD_READ_CONF:
256         if (check_len) {
257             if (ccw.count > dev->vdev->config_len) {
258                 ret = -EINVAL;
259                 break;
260             }
261         }
262         len = MIN(ccw.count, dev->vdev->config_len);
263         if (!ccw.cda) {
264             ret = -EFAULT;
265         } else {
266             dev->vdev->get_config(dev->vdev, dev->vdev->config);
267             /* XXX config space endianness */
268             cpu_physical_memory_write(ccw.cda, dev->vdev->config, len);
269             sch->curr_status.scsw.count = ccw.count - len;
270             ret = 0;
271         }
272         break;
273     case CCW_CMD_WRITE_CONF:
274         if (check_len) {
275             if (ccw.count > dev->vdev->config_len) {
276                 ret = -EINVAL;
277                 break;
278             }
279         }
280         len = MIN(ccw.count, dev->vdev->config_len);
281         hw_len = len;
282         if (!ccw.cda) {
283             ret = -EFAULT;
284         } else {
285             config = cpu_physical_memory_map(ccw.cda, &hw_len, 0);
286             if (!config) {
287                 ret = -EFAULT;
288             } else {
289                 len = hw_len;
290                 /* XXX config space endianness */
291                 memcpy(dev->vdev->config, config, len);
292                 cpu_physical_memory_unmap(config, hw_len, 0, hw_len);
293                 if (dev->vdev->set_config) {
294                     dev->vdev->set_config(dev->vdev, dev->vdev->config);
295                 }
296                 sch->curr_status.scsw.count = ccw.count - len;
297                 ret = 0;
298             }
299         }
300         break;
301     case CCW_CMD_WRITE_STATUS:
302         if (check_len) {
303             if (ccw.count != sizeof(status)) {
304                 ret = -EINVAL;
305                 break;
306             }
307         } else if (ccw.count < sizeof(status)) {
308             /* Can't execute command. */
309             ret = -EINVAL;
310             break;
311         }
312         if (!ccw.cda) {
313             ret = -EFAULT;
314         } else {
315             status = ldub_phys(ccw.cda);
316             virtio_set_status(dev->vdev, status);
317             if (dev->vdev->status == 0) {
318                 virtio_reset(dev->vdev);
319             }
320             sch->curr_status.scsw.count = ccw.count - sizeof(status);
321             ret = 0;
322         }
323         break;
324     case CCW_CMD_SET_IND:
325         if (check_len) {
326             if (ccw.count != sizeof(indicators)) {
327                 ret = -EINVAL;
328                 break;
329             }
330         } else if (ccw.count < sizeof(indicators)) {
331             /* Can't execute command. */
332             ret = -EINVAL;
333             break;
334         }
335         indicators = ldq_phys(ccw.cda);
336         if (!indicators) {
337             ret = -EFAULT;
338         } else {
339             dev->indicators = indicators;
340             sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
341             ret = 0;
342         }
343         break;
344     case CCW_CMD_SET_CONF_IND:
345         if (check_len) {
346             if (ccw.count != sizeof(indicators)) {
347                 ret = -EINVAL;
348                 break;
349             }
350         } else if (ccw.count < sizeof(indicators)) {
351             /* Can't execute command. */
352             ret = -EINVAL;
353             break;
354         }
355         indicators = ldq_phys(ccw.cda);
356         if (!indicators) {
357             ret = -EFAULT;
358         } else {
359             dev->indicators2 = indicators;
360             sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
361             ret = 0;
362         }
363         break;
364     case CCW_CMD_READ_VQ_CONF:
365         if (check_len) {
366             if (ccw.count != sizeof(vq_config)) {
367                 ret = -EINVAL;
368                 break;
369             }
370         } else if (ccw.count < sizeof(vq_config)) {
371             /* Can't execute command. */
372             ret = -EINVAL;
373             break;
374         }
375         if (!ccw.cda) {
376             ret = -EFAULT;
377         } else {
378             vq_config.index = lduw_phys(ccw.cda);
379             vq_config.num_max = virtio_queue_get_num(dev->vdev,
380                                                      vq_config.index);
381             stw_phys(ccw.cda + sizeof(vq_config.index), vq_config.num_max);
382             sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);
383             ret = 0;
384         }
385         break;
386     default:
387         ret = -ENOSYS;
388         break;
389     }
390     return ret;
391 }
392 
393 static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
394 {
395     unsigned int cssid = 0;
396     unsigned int ssid = 0;
397     unsigned int schid;
398     unsigned int devno;
399     bool have_devno = false;
400     bool found = false;
401     SubchDev *sch;
402     int ret;
403     int num;
404     DeviceState *parent = DEVICE(dev);
405 
406     sch = g_malloc0(sizeof(SubchDev));
407 
408     sch->driver_data = dev;
409     dev->sch = sch;
410 
411     dev->vdev = vdev;
412     dev->indicators = 0;
413 
414     /* Initialize subchannel structure. */
415     sch->channel_prog = 0x0;
416     sch->last_cmd_valid = false;
417     sch->orb = NULL;
418     /*
419      * Use a device number if provided. Otherwise, fall back to subchannel
420      * number.
421      */
422     if (dev->bus_id) {
423         num = sscanf(dev->bus_id, "%x.%x.%04x", &cssid, &ssid, &devno);
424         if (num == 3) {
425             if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) {
426                 ret = -EINVAL;
427                 error_report("Invalid cssid or ssid: cssid %x, ssid %x",
428                              cssid, ssid);
429                 goto out_err;
430             }
431             /* Enforce use of virtual cssid. */
432             if (cssid != VIRTUAL_CSSID) {
433                 ret = -EINVAL;
434                 error_report("cssid %x not valid for virtio devices", cssid);
435                 goto out_err;
436             }
437             if (css_devno_used(cssid, ssid, devno)) {
438                 ret = -EEXIST;
439                 error_report("Device %x.%x.%04x already exists", cssid, ssid,
440                              devno);
441                 goto out_err;
442             }
443             sch->cssid = cssid;
444             sch->ssid = ssid;
445             sch->devno = devno;
446             have_devno = true;
447         } else {
448             ret = -EINVAL;
449             error_report("Malformed devno parameter '%s'", dev->bus_id);
450             goto out_err;
451         }
452     }
453 
454     /* Find the next free id. */
455     if (have_devno) {
456         for (schid = 0; schid <= MAX_SCHID; schid++) {
457             if (!css_find_subch(1, cssid, ssid, schid)) {
458                 sch->schid = schid;
459                 css_subch_assign(cssid, ssid, schid, devno, sch);
460                 found = true;
461                 break;
462             }
463         }
464         if (!found) {
465             ret = -ENODEV;
466             error_report("No free subchannel found for %x.%x.%04x", cssid, ssid,
467                          devno);
468             goto out_err;
469         }
470         trace_virtio_ccw_new_device(cssid, ssid, schid, devno,
471                                     "user-configured");
472     } else {
473         cssid = VIRTUAL_CSSID;
474         for (ssid = 0; ssid <= MAX_SSID; ssid++) {
475             for (schid = 0; schid <= MAX_SCHID; schid++) {
476                 if (!css_find_subch(1, cssid, ssid, schid)) {
477                     sch->cssid = cssid;
478                     sch->ssid = ssid;
479                     sch->schid = schid;
480                     devno = schid;
481                     /*
482                      * If the devno is already taken, look further in this
483                      * subchannel set.
484                      */
485                     while (css_devno_used(cssid, ssid, devno)) {
486                         if (devno == MAX_SCHID) {
487                             devno = 0;
488                         } else if (devno == schid - 1) {
489                             ret = -ENODEV;
490                             error_report("No free devno found");
491                             goto out_err;
492                         } else {
493                             devno++;
494                         }
495                     }
496                     sch->devno = devno;
497                     css_subch_assign(cssid, ssid, schid, devno, sch);
498                     found = true;
499                     break;
500                 }
501             }
502             if (found) {
503                 break;
504             }
505         }
506         if (!found) {
507             ret = -ENODEV;
508             error_report("Virtual channel subsystem is full!");
509             goto out_err;
510         }
511         trace_virtio_ccw_new_device(cssid, ssid, schid, devno,
512                                     "auto-configured");
513     }
514 
515     /* Build initial schib. */
516     css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);
517 
518     sch->ccw_cb = virtio_ccw_cb;
519 
520     /* Build senseid data. */
521     memset(&sch->id, 0, sizeof(SenseId));
522     sch->id.reserved = 0xff;
523     sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
524     sch->id.cu_model = dev->vdev->device_id;
525 
526     virtio_bind_device(vdev, &virtio_ccw_bindings, DEVICE(dev));
527     /* Only the first 32 feature bits are used. */
528     dev->host_features[0] = vdev->get_features(vdev, dev->host_features[0]);
529     dev->host_features[0] |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
530     dev->host_features[0] |= 0x1 << VIRTIO_F_BAD_FEATURE;
531 
532     css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
533                           parent->hotplugged, 1);
534     return 0;
535 
536 out_err:
537     dev->sch = NULL;
538     g_free(sch);
539     return ret;
540 }
541 
542 static int virtio_ccw_exit(VirtioCcwDevice *dev)
543 {
544     SubchDev *sch = dev->sch;
545 
546     if (sch) {
547         css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
548         g_free(sch);
549     }
550     dev->indicators = 0;
551     return 0;
552 }
553 
554 static int virtio_ccw_net_init(VirtioCcwDevice *ccw_dev)
555 {
556     VirtIONetCcw *dev = VIRTIO_NET_CCW(ccw_dev);
557     DeviceState *vdev = DEVICE(&dev->vdev);
558 
559     virtio_net_set_config_size(&dev->vdev, ccw_dev->host_features[0]);
560     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
561     if (qdev_init(vdev) < 0) {
562         return -1;
563     }
564 
565     return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
566 }
567 
568 static void virtio_ccw_net_instance_init(Object *obj)
569 {
570     VirtIONetCcw *dev = VIRTIO_NET_CCW(obj);
571     object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_NET);
572     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
573 }
574 
575 static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
576 {
577     VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(ccw_dev);
578     DeviceState *vdev = DEVICE(&dev->vdev);
579     virtio_blk_set_conf(vdev, &(dev->blk));
580     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
581     if (qdev_init(vdev) < 0) {
582         return -1;
583     }
584 
585     return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
586 }
587 
588 static void virtio_ccw_blk_instance_init(Object *obj)
589 {
590     VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(obj);
591     object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BLK);
592     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
593 }
594 
595 static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev)
596 {
597     VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(ccw_dev);
598     DeviceState *vdev = DEVICE(&dev->vdev);
599 
600     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
601     if (qdev_init(vdev) < 0) {
602         return -1;
603     }
604 
605     return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
606 }
607 
608 
609 static void virtio_ccw_serial_instance_init(Object *obj)
610 {
611     VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(obj);
612     object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SERIAL);
613     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
614 }
615 
616 static int virtio_ccw_balloon_init(VirtioCcwDevice *ccw_dev)
617 {
618     VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(ccw_dev);
619     DeviceState *vdev = DEVICE(&dev->vdev);
620 
621     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
622     if (qdev_init(vdev) < 0) {
623         return -1;
624     }
625 
626     return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
627 }
628 
629 static void balloon_ccw_stats_get_all(Object *obj, struct Visitor *v,
630                                       void *opaque, const char *name,
631                                       Error **errp)
632 {
633     VirtIOBalloonCcw *dev = opaque;
634     object_property_get(OBJECT(&dev->vdev), v, "guest-stats", errp);
635 }
636 
637 static void balloon_ccw_stats_get_poll_interval(Object *obj, struct Visitor *v,
638                                                 void *opaque, const char *name,
639                                                 Error **errp)
640 {
641     VirtIOBalloonCcw *dev = opaque;
642     object_property_get(OBJECT(&dev->vdev), v, "guest-stats-polling-interval",
643                         errp);
644 }
645 
646 static void balloon_ccw_stats_set_poll_interval(Object *obj, struct Visitor *v,
647                                                 void *opaque, const char *name,
648                                                 Error **errp)
649 {
650     VirtIOBalloonCcw *dev = opaque;
651     object_property_set(OBJECT(&dev->vdev), v, "guest-stats-polling-interval",
652                         errp);
653 }
654 
655 static void virtio_ccw_balloon_instance_init(Object *obj)
656 {
657     VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj);
658     object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BALLOON);
659     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
660 
661     object_property_add(obj, "guest-stats", "guest statistics",
662                         balloon_ccw_stats_get_all, NULL, NULL, dev, NULL);
663 
664     object_property_add(obj, "guest-stats-polling-interval", "int",
665                         balloon_ccw_stats_get_poll_interval,
666                         balloon_ccw_stats_set_poll_interval,
667                         NULL, dev, NULL);
668 }
669 
670 static int virtio_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
671 {
672     VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(ccw_dev);
673     DeviceState *vdev = DEVICE(&dev->vdev);
674 
675     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
676     if (qdev_init(vdev) < 0) {
677         return -1;
678     }
679 
680     return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
681 }
682 
683 static void virtio_ccw_scsi_instance_init(Object *obj)
684 {
685     VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(obj);
686     object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SCSI);
687     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
688 }
689 
690 static int virtio_ccw_rng_init(VirtioCcwDevice *dev)
691 {
692     VirtIODevice *vdev;
693 
694     if (dev->rng.rng == NULL) {
695         dev->rng.default_backend = RNG_RANDOM(object_new(TYPE_RNG_RANDOM));
696         object_property_add_child(OBJECT(dev), "default-backend",
697                                   OBJECT(dev->rng.default_backend), NULL);
698         object_property_set_link(OBJECT(dev), OBJECT(dev->rng.default_backend),
699                                  "rng", NULL);
700     }
701     vdev = virtio_rng_init((DeviceState *)dev, &dev->rng);
702     if (!vdev) {
703         return -1;
704     }
705     return virtio_ccw_device_init(dev, vdev);
706 }
707 
708 static int virtio_ccw_rng_exit(VirtioCcwDevice *dev)
709 {
710     virtio_rng_exit(dev->vdev);
711     return virtio_ccw_exit(dev);
712 }
713 
714 /* DeviceState to VirtioCcwDevice. Note: used on datapath,
715  * be careful and test performance if you change this.
716  */
717 static inline VirtioCcwDevice *to_virtio_ccw_dev_fast(DeviceState *d)
718 {
719     return container_of(d, VirtioCcwDevice, parent_obj);
720 }
721 
722 static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
723 {
724     VirtioCcwDevice *dev = to_virtio_ccw_dev_fast(d);
725     SubchDev *sch = dev->sch;
726     uint64_t indicators;
727 
728     if (vector >= 128) {
729         return;
730     }
731 
732     if (vector < VIRTIO_PCI_QUEUE_MAX) {
733         indicators = ldq_phys(dev->indicators);
734         indicators |= 1ULL << vector;
735         stq_phys(dev->indicators, indicators);
736     } else {
737         vector = 0;
738         indicators = ldq_phys(dev->indicators2);
739         indicators |= 1ULL << vector;
740         stq_phys(dev->indicators2, indicators);
741     }
742 
743     css_conditional_io_interrupt(sch);
744 
745 }
746 
747 static unsigned virtio_ccw_get_features(DeviceState *d)
748 {
749     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
750 
751     /* Only the first 32 feature bits are used. */
752     return dev->host_features[0];
753 }
754 
755 static void virtio_ccw_reset(DeviceState *d)
756 {
757     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
758 
759     virtio_reset(dev->vdev);
760     css_reset_sch(dev->sch);
761 }
762 
763 /**************** Virtio-ccw Bus Device Descriptions *******************/
764 
765 static const VirtIOBindings virtio_ccw_bindings = {
766     .notify = virtio_ccw_notify,
767     .get_features = virtio_ccw_get_features,
768 };
769 
770 static Property virtio_ccw_net_properties[] = {
771     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
772     DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features[0]),
773     DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetCcw, vdev.net_conf),
774     DEFINE_NIC_PROPERTIES(VirtIONetCcw, vdev.nic_conf),
775     DEFINE_PROP_END_OF_LIST(),
776 };
777 
778 static void virtio_ccw_net_class_init(ObjectClass *klass, void *data)
779 {
780     DeviceClass *dc = DEVICE_CLASS(klass);
781     VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
782 
783     k->init = virtio_ccw_net_init;
784     k->exit = virtio_ccw_exit;
785     dc->reset = virtio_ccw_reset;
786     dc->props = virtio_ccw_net_properties;
787 }
788 
789 static const TypeInfo virtio_ccw_net = {
790     .name          = TYPE_VIRTIO_NET_CCW,
791     .parent        = TYPE_VIRTIO_CCW_DEVICE,
792     .instance_size = sizeof(VirtIONetCcw),
793     .instance_init = virtio_ccw_net_instance_init,
794     .class_init    = virtio_ccw_net_class_init,
795 };
796 
797 static Property virtio_ccw_blk_properties[] = {
798     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
799     DEFINE_VIRTIO_BLK_FEATURES(VirtioCcwDevice, host_features[0]),
800     DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlkCcw, blk),
801     DEFINE_PROP_END_OF_LIST(),
802 };
803 
804 static void virtio_ccw_blk_class_init(ObjectClass *klass, void *data)
805 {
806     DeviceClass *dc = DEVICE_CLASS(klass);
807     VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
808 
809     k->init = virtio_ccw_blk_init;
810     k->exit = virtio_ccw_exit;
811     dc->reset = virtio_ccw_reset;
812     dc->props = virtio_ccw_blk_properties;
813 }
814 
815 static const TypeInfo virtio_ccw_blk = {
816     .name          = TYPE_VIRTIO_BLK_CCW,
817     .parent        = TYPE_VIRTIO_CCW_DEVICE,
818     .instance_size = sizeof(VirtIOBlkCcw),
819     .instance_init = virtio_ccw_blk_instance_init,
820     .class_init    = virtio_ccw_blk_class_init,
821 };
822 
823 static Property virtio_ccw_serial_properties[] = {
824     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
825     DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtioSerialCcw, vdev.serial),
826     DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
827     DEFINE_PROP_END_OF_LIST(),
828 };
829 
830 static void virtio_ccw_serial_class_init(ObjectClass *klass, void *data)
831 {
832     DeviceClass *dc = DEVICE_CLASS(klass);
833     VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
834 
835     k->init = virtio_ccw_serial_init;
836     k->exit = virtio_ccw_exit;
837     dc->reset = virtio_ccw_reset;
838     dc->props = virtio_ccw_serial_properties;
839 }
840 
841 static const TypeInfo virtio_ccw_serial = {
842     .name          = TYPE_VIRTIO_SERIAL_CCW,
843     .parent        = TYPE_VIRTIO_CCW_DEVICE,
844     .instance_size = sizeof(VirtioSerialCcw),
845     .instance_init = virtio_ccw_serial_instance_init,
846     .class_init    = virtio_ccw_serial_class_init,
847 };
848 
849 static Property virtio_ccw_balloon_properties[] = {
850     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
851     DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
852     DEFINE_PROP_END_OF_LIST(),
853 };
854 
855 static void virtio_ccw_balloon_class_init(ObjectClass *klass, void *data)
856 {
857     DeviceClass *dc = DEVICE_CLASS(klass);
858     VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
859 
860     k->init = virtio_ccw_balloon_init;
861     k->exit = virtio_ccw_exit;
862     dc->reset = virtio_ccw_reset;
863     dc->props = virtio_ccw_balloon_properties;
864 }
865 
866 static const TypeInfo virtio_ccw_balloon = {
867     .name          = TYPE_VIRTIO_BALLOON_CCW,
868     .parent        = TYPE_VIRTIO_CCW_DEVICE,
869     .instance_size = sizeof(VirtIOBalloonCcw),
870     .instance_init = virtio_ccw_balloon_instance_init,
871     .class_init    = virtio_ccw_balloon_class_init,
872 };
873 
874 static Property virtio_ccw_scsi_properties[] = {
875     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
876     DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.conf),
877     DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features[0]),
878     DEFINE_PROP_END_OF_LIST(),
879 };
880 
881 static void virtio_ccw_scsi_class_init(ObjectClass *klass, void *data)
882 {
883     DeviceClass *dc = DEVICE_CLASS(klass);
884     VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
885 
886     k->init = virtio_ccw_scsi_init;
887     k->exit = virtio_ccw_exit;
888     dc->reset = virtio_ccw_reset;
889     dc->props = virtio_ccw_scsi_properties;
890 }
891 
892 static const TypeInfo virtio_ccw_scsi = {
893     .name          = TYPE_VIRTIO_SCSI_CCW,
894     .parent        = TYPE_VIRTIO_CCW_DEVICE,
895     .instance_size = sizeof(VirtIOSCSICcw),
896     .instance_init = virtio_ccw_scsi_instance_init,
897     .class_init    = virtio_ccw_scsi_class_init,
898 };
899 
900 static void virtio_ccw_rng_initfn(Object *obj)
901 {
902     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(obj);
903 
904     object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
905                              (Object **)&dev->rng.rng, NULL);
906 }
907 
908 static Property virtio_ccw_rng_properties[] = {
909     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
910     DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
911     DEFINE_PROP_UINT64("max-bytes", VirtioCcwDevice, rng.max_bytes, INT64_MAX),
912     DEFINE_PROP_UINT32("period", VirtioCcwDevice, rng.period_ms, 1 << 16),
913     DEFINE_PROP_END_OF_LIST(),
914 };
915 
916 static void virtio_ccw_rng_class_init(ObjectClass *klass, void *data)
917 {
918     DeviceClass *dc = DEVICE_CLASS(klass);
919     VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
920 
921     k->init = virtio_ccw_rng_init;
922     k->exit = virtio_ccw_rng_exit;
923     dc->reset = virtio_ccw_reset;
924     dc->props = virtio_ccw_rng_properties;
925 }
926 
927 static const TypeInfo virtio_ccw_rng = {
928     .name          = "virtio-rng-ccw",
929     .parent        = TYPE_VIRTIO_CCW_DEVICE,
930     .instance_size = sizeof(VirtioCcwDevice),
931     .instance_init = virtio_ccw_rng_initfn,
932     .class_init    = virtio_ccw_rng_class_init,
933 };
934 
935 static int virtio_ccw_busdev_init(DeviceState *dev)
936 {
937     VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
938     VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
939 
940     virtio_ccw_bus_new(&_dev->bus, _dev);
941 
942     return _info->init(_dev);
943 }
944 
945 static int virtio_ccw_busdev_exit(DeviceState *dev)
946 {
947     VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
948     VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
949 
950     return _info->exit(_dev);
951 }
952 
953 static int virtio_ccw_busdev_unplug(DeviceState *dev)
954 {
955     VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
956     SubchDev *sch = _dev->sch;
957 
958     /*
959      * We should arrive here only for device_del, since we don't support
960      * direct hot(un)plug of channels, but only through virtio.
961      */
962     assert(sch != NULL);
963     /* Subchannel is now disabled and no longer valid. */
964     sch->curr_status.pmcw.flags &= ~(PMCW_FLAGS_MASK_ENA |
965                                      PMCW_FLAGS_MASK_DNV);
966 
967     css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0);
968 
969     qdev_free(dev);
970     return 0;
971 }
972 
973 static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
974 {
975     DeviceClass *dc = DEVICE_CLASS(klass);
976 
977     dc->init = virtio_ccw_busdev_init;
978     dc->exit = virtio_ccw_busdev_exit;
979     dc->unplug = virtio_ccw_busdev_unplug;
980     dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
981 
982 }
983 
984 static const TypeInfo virtio_ccw_device_info = {
985     .name = TYPE_VIRTIO_CCW_DEVICE,
986     .parent = TYPE_DEVICE,
987     .instance_size = sizeof(VirtioCcwDevice),
988     .class_init = virtio_ccw_device_class_init,
989     .class_size = sizeof(VirtIOCCWDeviceClass),
990     .abstract = true,
991 };
992 
993 /***************** Virtual-css Bus Bridge Device ********************/
994 /* Only required to have the virtio bus as child in the system bus */
995 
996 static int virtual_css_bridge_init(SysBusDevice *dev)
997 {
998     /* nothing */
999     return 0;
1000 }
1001 
1002 static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
1003 {
1004     DeviceClass *dc = DEVICE_CLASS(klass);
1005     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1006 
1007     k->init = virtual_css_bridge_init;
1008     dc->no_user = 1;
1009 }
1010 
1011 static const TypeInfo virtual_css_bridge_info = {
1012     .name          = "virtual-css-bridge",
1013     .parent        = TYPE_SYS_BUS_DEVICE,
1014     .instance_size = sizeof(SysBusDevice),
1015     .class_init    = virtual_css_bridge_class_init,
1016 };
1017 
1018 /* virtio-ccw-bus */
1019 
1020 void virtio_ccw_bus_new(VirtioBusState *bus, VirtioCcwDevice *dev)
1021 {
1022     DeviceState *qdev = DEVICE(dev);
1023     BusState *qbus;
1024 
1025     qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_CCW_BUS, qdev, NULL);
1026     qbus = BUS(bus);
1027     qbus->allow_hotplug = 1;
1028 }
1029 
1030 static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data)
1031 {
1032     VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
1033     BusClass *bus_class = BUS_CLASS(klass);
1034 
1035     bus_class->max_dev = 1;
1036     k->notify = virtio_ccw_notify;
1037     k->get_features = virtio_ccw_get_features;
1038 }
1039 
1040 static const TypeInfo virtio_ccw_bus_info = {
1041     .name = TYPE_VIRTIO_CCW_BUS,
1042     .parent = TYPE_VIRTIO_BUS,
1043     .instance_size = sizeof(VirtioCcwBusState),
1044     .class_init = virtio_ccw_bus_class_init,
1045 };
1046 
1047 static void virtio_ccw_register(void)
1048 {
1049     type_register_static(&virtio_ccw_bus_info);
1050     type_register_static(&virtual_css_bus_info);
1051     type_register_static(&virtio_ccw_device_info);
1052     type_register_static(&virtio_ccw_serial);
1053     type_register_static(&virtio_ccw_blk);
1054     type_register_static(&virtio_ccw_net);
1055     type_register_static(&virtio_ccw_balloon);
1056     type_register_static(&virtio_ccw_scsi);
1057     type_register_static(&virtio_ccw_rng);
1058     type_register_static(&virtual_css_bridge_info);
1059 }
1060 
1061 type_init(virtio_ccw_register)
1062