xref: /openbmc/qemu/hw/s390x/virtio-ccw.c (revision 181103cd)
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, VirtioCcwDevice *dev);
31 
32 static int virtual_css_bus_reset(BusState *qbus)
33 {
34     /* This should actually be modelled via the generic css */
35     css_reset();
36 
37     /* we dont traverse ourself, return 0 */
38     return 0;
39 }
40 
41 
42 static void virtual_css_bus_class_init(ObjectClass *klass, void *data)
43 {
44     BusClass *k = BUS_CLASS(klass);
45 
46     k->reset = virtual_css_bus_reset;
47 }
48 
49 static const TypeInfo virtual_css_bus_info = {
50     .name = TYPE_VIRTUAL_CSS_BUS,
51     .parent = TYPE_BUS,
52     .instance_size = sizeof(VirtualCssBus),
53     .class_init = virtual_css_bus_class_init,
54 };
55 
56 static const VirtIOBindings virtio_ccw_bindings;
57 
58 VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
59 {
60     VirtIODevice *vdev = NULL;
61 
62     if (sch->driver_data) {
63         vdev = ((VirtioCcwDevice *)sch->driver_data)->vdev;
64     }
65     return vdev;
66 }
67 
68 VirtualCssBus *virtual_css_bus_init(void)
69 {
70     VirtualCssBus *cbus;
71     BusState *bus;
72     DeviceState *dev;
73 
74     /* Create bridge device */
75     dev = qdev_create(NULL, "virtual-css-bridge");
76     qdev_init_nofail(dev);
77 
78     /* Create bus on bridge device */
79     bus = qbus_create(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
80     cbus = VIRTUAL_CSS_BUS(bus);
81 
82     /* Enable hotplugging */
83     bus->allow_hotplug = 1;
84 
85     return cbus;
86 }
87 
88 /* Communication blocks used by several channel commands. */
89 typedef struct VqInfoBlock {
90     uint64_t queue;
91     uint32_t align;
92     uint16_t index;
93     uint16_t num;
94 } QEMU_PACKED VqInfoBlock;
95 
96 typedef struct VqConfigBlock {
97     uint16_t index;
98     uint16_t num_max;
99 } QEMU_PACKED VqConfigBlock;
100 
101 typedef struct VirtioFeatDesc {
102     uint32_t features;
103     uint8_t index;
104 } QEMU_PACKED VirtioFeatDesc;
105 
106 /* Specify where the virtqueues for the subchannel are in guest memory. */
107 static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
108                               uint16_t index, uint16_t num)
109 {
110     VirtioCcwDevice *dev = sch->driver_data;
111 
112     if (index > VIRTIO_PCI_QUEUE_MAX) {
113         return -EINVAL;
114     }
115 
116     /* Current code in virtio.c relies on 4K alignment. */
117     if (addr && (align != 4096)) {
118         return -EINVAL;
119     }
120 
121     if (!dev) {
122         return -EINVAL;
123     }
124 
125     virtio_queue_set_addr(dev->vdev, index, addr);
126     if (!addr) {
127         virtio_queue_set_vector(dev->vdev, index, 0);
128     } else {
129         /* Fail if we don't have a big enough queue. */
130         /* TODO: Add interface to handle vring.num changing */
131         if (virtio_queue_get_num(dev->vdev, index) > num) {
132             return -EINVAL;
133         }
134         virtio_queue_set_vector(dev->vdev, index, index);
135     }
136     /* tell notify handler in case of config change */
137     dev->vdev->config_vector = VIRTIO_PCI_QUEUE_MAX;
138     return 0;
139 }
140 
141 static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
142 {
143     int ret;
144     VqInfoBlock info;
145     uint8_t status;
146     VirtioFeatDesc features;
147     void *config;
148     hwaddr indicators;
149     VqConfigBlock vq_config;
150     VirtioCcwDevice *dev = sch->driver_data;
151     bool check_len;
152     int len;
153     hwaddr hw_len;
154 
155     if (!dev) {
156         return -EINVAL;
157     }
158 
159     trace_virtio_ccw_interpret_ccw(sch->cssid, sch->ssid, sch->schid,
160                                    ccw.cmd_code);
161     check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));
162 
163     /* Look at the command. */
164     switch (ccw.cmd_code) {
165     case CCW_CMD_SET_VQ:
166         if (check_len) {
167             if (ccw.count != sizeof(info)) {
168                 ret = -EINVAL;
169                 break;
170             }
171         } else if (ccw.count < sizeof(info)) {
172             /* Can't execute command. */
173             ret = -EINVAL;
174             break;
175         }
176         if (!ccw.cda) {
177             ret = -EFAULT;
178         } else {
179             info.queue = ldq_phys(ccw.cda);
180             info.align = ldl_phys(ccw.cda + sizeof(info.queue));
181             info.index = lduw_phys(ccw.cda + sizeof(info.queue)
182                                    + sizeof(info.align));
183             info.num = lduw_phys(ccw.cda + sizeof(info.queue)
184                                  + sizeof(info.align)
185                                  + sizeof(info.index));
186             ret = virtio_ccw_set_vqs(sch, info.queue, info.align, info.index,
187                                      info.num);
188             sch->curr_status.scsw.count = 0;
189         }
190         break;
191     case CCW_CMD_VDEV_RESET:
192         virtio_reset(dev->vdev);
193         ret = 0;
194         break;
195     case CCW_CMD_READ_FEAT:
196         if (check_len) {
197             if (ccw.count != sizeof(features)) {
198                 ret = -EINVAL;
199                 break;
200             }
201         } else if (ccw.count < sizeof(features)) {
202             /* Can't execute command. */
203             ret = -EINVAL;
204             break;
205         }
206         if (!ccw.cda) {
207             ret = -EFAULT;
208         } else {
209             features.index = ldub_phys(ccw.cda + sizeof(features.features));
210             if (features.index < ARRAY_SIZE(dev->host_features)) {
211                 features.features = dev->host_features[features.index];
212             } else {
213                 /* Return zeroes if the guest supports more feature bits. */
214                 features.features = 0;
215             }
216             stl_le_phys(ccw.cda, features.features);
217             sch->curr_status.scsw.count = ccw.count - sizeof(features);
218             ret = 0;
219         }
220         break;
221     case CCW_CMD_WRITE_FEAT:
222         if (check_len) {
223             if (ccw.count != sizeof(features)) {
224                 ret = -EINVAL;
225                 break;
226             }
227         } else if (ccw.count < sizeof(features)) {
228             /* Can't execute command. */
229             ret = -EINVAL;
230             break;
231         }
232         if (!ccw.cda) {
233             ret = -EFAULT;
234         } else {
235             features.index = ldub_phys(ccw.cda + sizeof(features.features));
236             features.features = ldl_le_phys(ccw.cda);
237             if (features.index < ARRAY_SIZE(dev->host_features)) {
238                 virtio_bus_set_vdev_features(&dev->bus, features.features);
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             virtio_bus_get_vdev_config(&dev->bus, 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                 virtio_bus_set_vdev_config(&dev->bus, dev->vdev->config);
294                 sch->curr_status.scsw.count = ccw.count - len;
295                 ret = 0;
296             }
297         }
298         break;
299     case CCW_CMD_WRITE_STATUS:
300         if (check_len) {
301             if (ccw.count != sizeof(status)) {
302                 ret = -EINVAL;
303                 break;
304             }
305         } else if (ccw.count < sizeof(status)) {
306             /* Can't execute command. */
307             ret = -EINVAL;
308             break;
309         }
310         if (!ccw.cda) {
311             ret = -EFAULT;
312         } else {
313             status = ldub_phys(ccw.cda);
314             virtio_set_status(dev->vdev, status);
315             if (dev->vdev->status == 0) {
316                 virtio_reset(dev->vdev);
317             }
318             sch->curr_status.scsw.count = ccw.count - sizeof(status);
319             ret = 0;
320         }
321         break;
322     case CCW_CMD_SET_IND:
323         if (check_len) {
324             if (ccw.count != sizeof(indicators)) {
325                 ret = -EINVAL;
326                 break;
327             }
328         } else if (ccw.count < sizeof(indicators)) {
329             /* Can't execute command. */
330             ret = -EINVAL;
331             break;
332         }
333         indicators = ldq_phys(ccw.cda);
334         if (!indicators) {
335             ret = -EFAULT;
336         } else {
337             dev->indicators = indicators;
338             sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
339             ret = 0;
340         }
341         break;
342     case CCW_CMD_SET_CONF_IND:
343         if (check_len) {
344             if (ccw.count != sizeof(indicators)) {
345                 ret = -EINVAL;
346                 break;
347             }
348         } else if (ccw.count < sizeof(indicators)) {
349             /* Can't execute command. */
350             ret = -EINVAL;
351             break;
352         }
353         indicators = ldq_phys(ccw.cda);
354         if (!indicators) {
355             ret = -EFAULT;
356         } else {
357             dev->indicators2 = indicators;
358             sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
359             ret = 0;
360         }
361         break;
362     case CCW_CMD_READ_VQ_CONF:
363         if (check_len) {
364             if (ccw.count != sizeof(vq_config)) {
365                 ret = -EINVAL;
366                 break;
367             }
368         } else if (ccw.count < sizeof(vq_config)) {
369             /* Can't execute command. */
370             ret = -EINVAL;
371             break;
372         }
373         if (!ccw.cda) {
374             ret = -EFAULT;
375         } else {
376             vq_config.index = lduw_phys(ccw.cda);
377             vq_config.num_max = virtio_queue_get_num(dev->vdev,
378                                                      vq_config.index);
379             stw_phys(ccw.cda + sizeof(vq_config.index), vq_config.num_max);
380             sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);
381             ret = 0;
382         }
383         break;
384     default:
385         ret = -ENOSYS;
386         break;
387     }
388     return ret;
389 }
390 
391 static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
392 {
393     unsigned int cssid = 0;
394     unsigned int ssid = 0;
395     unsigned int schid;
396     unsigned int devno;
397     bool have_devno = false;
398     bool found = false;
399     SubchDev *sch;
400     int ret;
401     int num;
402     DeviceState *parent = DEVICE(dev);
403 
404     sch = g_malloc0(sizeof(SubchDev));
405 
406     sch->driver_data = dev;
407     dev->sch = sch;
408 
409     dev->vdev = vdev;
410     dev->indicators = 0;
411 
412     /* Initialize subchannel structure. */
413     sch->channel_prog = 0x0;
414     sch->last_cmd_valid = false;
415     sch->orb = NULL;
416     /*
417      * Use a device number if provided. Otherwise, fall back to subchannel
418      * number.
419      */
420     if (dev->bus_id) {
421         num = sscanf(dev->bus_id, "%x.%x.%04x", &cssid, &ssid, &devno);
422         if (num == 3) {
423             if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) {
424                 ret = -EINVAL;
425                 error_report("Invalid cssid or ssid: cssid %x, ssid %x",
426                              cssid, ssid);
427                 goto out_err;
428             }
429             /* Enforce use of virtual cssid. */
430             if (cssid != VIRTUAL_CSSID) {
431                 ret = -EINVAL;
432                 error_report("cssid %x not valid for virtio devices", cssid);
433                 goto out_err;
434             }
435             if (css_devno_used(cssid, ssid, devno)) {
436                 ret = -EEXIST;
437                 error_report("Device %x.%x.%04x already exists", cssid, ssid,
438                              devno);
439                 goto out_err;
440             }
441             sch->cssid = cssid;
442             sch->ssid = ssid;
443             sch->devno = devno;
444             have_devno = true;
445         } else {
446             ret = -EINVAL;
447             error_report("Malformed devno parameter '%s'", dev->bus_id);
448             goto out_err;
449         }
450     }
451 
452     /* Find the next free id. */
453     if (have_devno) {
454         for (schid = 0; schid <= MAX_SCHID; schid++) {
455             if (!css_find_subch(1, cssid, ssid, schid)) {
456                 sch->schid = schid;
457                 css_subch_assign(cssid, ssid, schid, devno, sch);
458                 found = true;
459                 break;
460             }
461         }
462         if (!found) {
463             ret = -ENODEV;
464             error_report("No free subchannel found for %x.%x.%04x", cssid, ssid,
465                          devno);
466             goto out_err;
467         }
468         trace_virtio_ccw_new_device(cssid, ssid, schid, devno,
469                                     "user-configured");
470     } else {
471         cssid = VIRTUAL_CSSID;
472         for (ssid = 0; ssid <= MAX_SSID; ssid++) {
473             for (schid = 0; schid <= MAX_SCHID; schid++) {
474                 if (!css_find_subch(1, cssid, ssid, schid)) {
475                     sch->cssid = cssid;
476                     sch->ssid = ssid;
477                     sch->schid = schid;
478                     devno = schid;
479                     /*
480                      * If the devno is already taken, look further in this
481                      * subchannel set.
482                      */
483                     while (css_devno_used(cssid, ssid, devno)) {
484                         if (devno == MAX_SCHID) {
485                             devno = 0;
486                         } else if (devno == schid - 1) {
487                             ret = -ENODEV;
488                             error_report("No free devno found");
489                             goto out_err;
490                         } else {
491                             devno++;
492                         }
493                     }
494                     sch->devno = devno;
495                     css_subch_assign(cssid, ssid, schid, devno, sch);
496                     found = true;
497                     break;
498                 }
499             }
500             if (found) {
501                 break;
502             }
503         }
504         if (!found) {
505             ret = -ENODEV;
506             error_report("Virtual channel subsystem is full!");
507             goto out_err;
508         }
509         trace_virtio_ccw_new_device(cssid, ssid, schid, devno,
510                                     "auto-configured");
511     }
512 
513     /* Build initial schib. */
514     css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);
515 
516     sch->ccw_cb = virtio_ccw_cb;
517 
518     /* Build senseid data. */
519     memset(&sch->id, 0, sizeof(SenseId));
520     sch->id.reserved = 0xff;
521     sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
522     sch->id.cu_model = dev->vdev->device_id;
523 
524     virtio_bind_device(vdev, &virtio_ccw_bindings, DEVICE(dev));
525     /* Only the first 32 feature bits are used. */
526     dev->host_features[0] = virtio_bus_get_vdev_features(&dev->bus,
527                                                          dev->host_features[0]);
528 
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 #ifdef CONFIG_VHOST_SCSI
691 static int vhost_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
692 {
693     VHostSCSICcw *dev = VHOST_SCSI_CCW(ccw_dev);
694     DeviceState *vdev = DEVICE(&dev->vdev);
695 
696     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
697     if (qdev_init(vdev) < 0) {
698         return -1;
699     }
700 
701     return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
702 }
703 
704 static void vhost_ccw_scsi_instance_init(Object *obj)
705 {
706     VHostSCSICcw *dev = VHOST_SCSI_CCW(obj);
707     object_initialize(OBJECT(&dev->vdev), TYPE_VHOST_SCSI);
708     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
709 }
710 #endif
711 
712 static int virtio_ccw_rng_init(VirtioCcwDevice *ccw_dev)
713 {
714     VirtIORNGCcw *dev = VIRTIO_RNG_CCW(ccw_dev);
715     DeviceState *vdev = DEVICE(&dev->vdev);
716 
717     qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
718     if (qdev_init(vdev) < 0) {
719         return -1;
720     }
721 
722     object_property_set_link(OBJECT(dev),
723                              OBJECT(dev->vdev.conf.default_backend), "rng",
724                              NULL);
725 
726     return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
727 }
728 
729 /* DeviceState to VirtioCcwDevice. Note: used on datapath,
730  * be careful and test performance if you change this.
731  */
732 static inline VirtioCcwDevice *to_virtio_ccw_dev_fast(DeviceState *d)
733 {
734     return container_of(d, VirtioCcwDevice, parent_obj);
735 }
736 
737 static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
738 {
739     VirtioCcwDevice *dev = to_virtio_ccw_dev_fast(d);
740     SubchDev *sch = dev->sch;
741     uint64_t indicators;
742 
743     if (vector >= 128) {
744         return;
745     }
746 
747     if (vector < VIRTIO_PCI_QUEUE_MAX) {
748         indicators = ldq_phys(dev->indicators);
749         indicators |= 1ULL << vector;
750         stq_phys(dev->indicators, indicators);
751     } else {
752         vector = 0;
753         indicators = ldq_phys(dev->indicators2);
754         indicators |= 1ULL << vector;
755         stq_phys(dev->indicators2, indicators);
756     }
757 
758     css_conditional_io_interrupt(sch);
759 
760 }
761 
762 static unsigned virtio_ccw_get_features(DeviceState *d)
763 {
764     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
765 
766     /* Only the first 32 feature bits are used. */
767     return dev->host_features[0];
768 }
769 
770 static void virtio_ccw_reset(DeviceState *d)
771 {
772     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
773 
774     virtio_reset(dev->vdev);
775     css_reset_sch(dev->sch);
776 }
777 
778 /**************** Virtio-ccw Bus Device Descriptions *******************/
779 
780 static const VirtIOBindings virtio_ccw_bindings = {
781     .notify = virtio_ccw_notify,
782     .get_features = virtio_ccw_get_features,
783 };
784 
785 static Property virtio_ccw_net_properties[] = {
786     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
787     DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features[0]),
788     DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetCcw, vdev.net_conf),
789     DEFINE_NIC_PROPERTIES(VirtIONetCcw, vdev.nic_conf),
790     DEFINE_PROP_END_OF_LIST(),
791 };
792 
793 static void virtio_ccw_net_class_init(ObjectClass *klass, void *data)
794 {
795     DeviceClass *dc = DEVICE_CLASS(klass);
796     VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
797 
798     k->init = virtio_ccw_net_init;
799     k->exit = virtio_ccw_exit;
800     dc->reset = virtio_ccw_reset;
801     dc->props = virtio_ccw_net_properties;
802 }
803 
804 static const TypeInfo virtio_ccw_net = {
805     .name          = TYPE_VIRTIO_NET_CCW,
806     .parent        = TYPE_VIRTIO_CCW_DEVICE,
807     .instance_size = sizeof(VirtIONetCcw),
808     .instance_init = virtio_ccw_net_instance_init,
809     .class_init    = virtio_ccw_net_class_init,
810 };
811 
812 static Property virtio_ccw_blk_properties[] = {
813     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
814     DEFINE_VIRTIO_BLK_FEATURES(VirtioCcwDevice, host_features[0]),
815     DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlkCcw, blk),
816     DEFINE_PROP_END_OF_LIST(),
817 };
818 
819 static void virtio_ccw_blk_class_init(ObjectClass *klass, void *data)
820 {
821     DeviceClass *dc = DEVICE_CLASS(klass);
822     VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
823 
824     k->init = virtio_ccw_blk_init;
825     k->exit = virtio_ccw_exit;
826     dc->reset = virtio_ccw_reset;
827     dc->props = virtio_ccw_blk_properties;
828 }
829 
830 static const TypeInfo virtio_ccw_blk = {
831     .name          = TYPE_VIRTIO_BLK_CCW,
832     .parent        = TYPE_VIRTIO_CCW_DEVICE,
833     .instance_size = sizeof(VirtIOBlkCcw),
834     .instance_init = virtio_ccw_blk_instance_init,
835     .class_init    = virtio_ccw_blk_class_init,
836 };
837 
838 static Property virtio_ccw_serial_properties[] = {
839     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
840     DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtioSerialCcw, vdev.serial),
841     DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
842     DEFINE_PROP_END_OF_LIST(),
843 };
844 
845 static void virtio_ccw_serial_class_init(ObjectClass *klass, void *data)
846 {
847     DeviceClass *dc = DEVICE_CLASS(klass);
848     VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
849 
850     k->init = virtio_ccw_serial_init;
851     k->exit = virtio_ccw_exit;
852     dc->reset = virtio_ccw_reset;
853     dc->props = virtio_ccw_serial_properties;
854 }
855 
856 static const TypeInfo virtio_ccw_serial = {
857     .name          = TYPE_VIRTIO_SERIAL_CCW,
858     .parent        = TYPE_VIRTIO_CCW_DEVICE,
859     .instance_size = sizeof(VirtioSerialCcw),
860     .instance_init = virtio_ccw_serial_instance_init,
861     .class_init    = virtio_ccw_serial_class_init,
862 };
863 
864 static Property virtio_ccw_balloon_properties[] = {
865     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
866     DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
867     DEFINE_PROP_END_OF_LIST(),
868 };
869 
870 static void virtio_ccw_balloon_class_init(ObjectClass *klass, void *data)
871 {
872     DeviceClass *dc = DEVICE_CLASS(klass);
873     VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
874 
875     k->init = virtio_ccw_balloon_init;
876     k->exit = virtio_ccw_exit;
877     dc->reset = virtio_ccw_reset;
878     dc->props = virtio_ccw_balloon_properties;
879 }
880 
881 static const TypeInfo virtio_ccw_balloon = {
882     .name          = TYPE_VIRTIO_BALLOON_CCW,
883     .parent        = TYPE_VIRTIO_CCW_DEVICE,
884     .instance_size = sizeof(VirtIOBalloonCcw),
885     .instance_init = virtio_ccw_balloon_instance_init,
886     .class_init    = virtio_ccw_balloon_class_init,
887 };
888 
889 static Property virtio_ccw_scsi_properties[] = {
890     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
891     DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
892     DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features[0]),
893     DEFINE_PROP_END_OF_LIST(),
894 };
895 
896 static void virtio_ccw_scsi_class_init(ObjectClass *klass, void *data)
897 {
898     DeviceClass *dc = DEVICE_CLASS(klass);
899     VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
900 
901     k->init = virtio_ccw_scsi_init;
902     k->exit = virtio_ccw_exit;
903     dc->reset = virtio_ccw_reset;
904     dc->props = virtio_ccw_scsi_properties;
905 }
906 
907 static const TypeInfo virtio_ccw_scsi = {
908     .name          = TYPE_VIRTIO_SCSI_CCW,
909     .parent        = TYPE_VIRTIO_CCW_DEVICE,
910     .instance_size = sizeof(VirtIOSCSICcw),
911     .instance_init = virtio_ccw_scsi_instance_init,
912     .class_init    = virtio_ccw_scsi_class_init,
913 };
914 
915 #ifdef CONFIG_VHOST_SCSI
916 static Property vhost_ccw_scsi_properties[] = {
917     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
918     DEFINE_VHOST_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
919     DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
920     DEFINE_PROP_END_OF_LIST(),
921 };
922 
923 static void vhost_ccw_scsi_class_init(ObjectClass *klass, void *data)
924 {
925     DeviceClass *dc = DEVICE_CLASS(klass);
926     VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
927 
928     k->init = vhost_ccw_scsi_init;
929     k->exit = virtio_ccw_exit;
930     dc->reset = virtio_ccw_reset;
931     dc->props = vhost_ccw_scsi_properties;
932 }
933 
934 static const TypeInfo vhost_ccw_scsi = {
935     .name          = TYPE_VHOST_SCSI_CCW,
936     .parent        = TYPE_VIRTIO_CCW_DEVICE,
937     .instance_size = sizeof(VirtIOSCSICcw),
938     .instance_init = vhost_ccw_scsi_instance_init,
939     .class_init    = vhost_ccw_scsi_class_init,
940 };
941 #endif
942 
943 static void virtio_ccw_rng_instance_init(Object *obj)
944 {
945     VirtIORNGCcw *dev = VIRTIO_RNG_CCW(obj);
946     object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_RNG);
947     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
948     object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
949                              (Object **)&dev->vdev.conf.rng, NULL);
950 }
951 
952 static Property virtio_ccw_rng_properties[] = {
953     DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
954     DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
955     DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGCcw, vdev.conf),
956     DEFINE_PROP_END_OF_LIST(),
957 };
958 
959 static void virtio_ccw_rng_class_init(ObjectClass *klass, void *data)
960 {
961     DeviceClass *dc = DEVICE_CLASS(klass);
962     VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
963 
964     k->init = virtio_ccw_rng_init;
965     k->exit = virtio_ccw_exit;
966     dc->reset = virtio_ccw_reset;
967     dc->props = virtio_ccw_rng_properties;
968 }
969 
970 static const TypeInfo virtio_ccw_rng = {
971     .name          = TYPE_VIRTIO_RNG_CCW,
972     .parent        = TYPE_VIRTIO_CCW_DEVICE,
973     .instance_size = sizeof(VirtIORNGCcw),
974     .instance_init = virtio_ccw_rng_instance_init,
975     .class_init    = virtio_ccw_rng_class_init,
976 };
977 
978 static int virtio_ccw_busdev_init(DeviceState *dev)
979 {
980     VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
981     VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
982 
983     virtio_ccw_bus_new(&_dev->bus, _dev);
984 
985     return _info->init(_dev);
986 }
987 
988 static int virtio_ccw_busdev_exit(DeviceState *dev)
989 {
990     VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
991     VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
992 
993     return _info->exit(_dev);
994 }
995 
996 static int virtio_ccw_busdev_unplug(DeviceState *dev)
997 {
998     VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
999     SubchDev *sch = _dev->sch;
1000 
1001     /*
1002      * We should arrive here only for device_del, since we don't support
1003      * direct hot(un)plug of channels, but only through virtio.
1004      */
1005     assert(sch != NULL);
1006     /* Subchannel is now disabled and no longer valid. */
1007     sch->curr_status.pmcw.flags &= ~(PMCW_FLAGS_MASK_ENA |
1008                                      PMCW_FLAGS_MASK_DNV);
1009 
1010     css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0);
1011 
1012     qdev_free(dev);
1013     return 0;
1014 }
1015 
1016 static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
1017 {
1018     DeviceClass *dc = DEVICE_CLASS(klass);
1019 
1020     dc->init = virtio_ccw_busdev_init;
1021     dc->exit = virtio_ccw_busdev_exit;
1022     dc->unplug = virtio_ccw_busdev_unplug;
1023     dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
1024 
1025 }
1026 
1027 static const TypeInfo virtio_ccw_device_info = {
1028     .name = TYPE_VIRTIO_CCW_DEVICE,
1029     .parent = TYPE_DEVICE,
1030     .instance_size = sizeof(VirtioCcwDevice),
1031     .class_init = virtio_ccw_device_class_init,
1032     .class_size = sizeof(VirtIOCCWDeviceClass),
1033     .abstract = true,
1034 };
1035 
1036 /***************** Virtual-css Bus Bridge Device ********************/
1037 /* Only required to have the virtio bus as child in the system bus */
1038 
1039 static int virtual_css_bridge_init(SysBusDevice *dev)
1040 {
1041     /* nothing */
1042     return 0;
1043 }
1044 
1045 static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
1046 {
1047     DeviceClass *dc = DEVICE_CLASS(klass);
1048     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1049 
1050     k->init = virtual_css_bridge_init;
1051     dc->no_user = 1;
1052 }
1053 
1054 static const TypeInfo virtual_css_bridge_info = {
1055     .name          = "virtual-css-bridge",
1056     .parent        = TYPE_SYS_BUS_DEVICE,
1057     .instance_size = sizeof(SysBusDevice),
1058     .class_init    = virtual_css_bridge_class_init,
1059 };
1060 
1061 /* virtio-ccw-bus */
1062 
1063 static void virtio_ccw_bus_new(VirtioBusState *bus, VirtioCcwDevice *dev)
1064 {
1065     DeviceState *qdev = DEVICE(dev);
1066     BusState *qbus;
1067 
1068     qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_CCW_BUS, qdev, NULL);
1069     qbus = BUS(bus);
1070     qbus->allow_hotplug = 1;
1071 }
1072 
1073 static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data)
1074 {
1075     VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
1076     BusClass *bus_class = BUS_CLASS(klass);
1077 
1078     bus_class->max_dev = 1;
1079     k->notify = virtio_ccw_notify;
1080     k->get_features = virtio_ccw_get_features;
1081 }
1082 
1083 static const TypeInfo virtio_ccw_bus_info = {
1084     .name = TYPE_VIRTIO_CCW_BUS,
1085     .parent = TYPE_VIRTIO_BUS,
1086     .instance_size = sizeof(VirtioCcwBusState),
1087     .class_init = virtio_ccw_bus_class_init,
1088 };
1089 
1090 static void virtio_ccw_register(void)
1091 {
1092     type_register_static(&virtio_ccw_bus_info);
1093     type_register_static(&virtual_css_bus_info);
1094     type_register_static(&virtio_ccw_device_info);
1095     type_register_static(&virtio_ccw_serial);
1096     type_register_static(&virtio_ccw_blk);
1097     type_register_static(&virtio_ccw_net);
1098     type_register_static(&virtio_ccw_balloon);
1099     type_register_static(&virtio_ccw_scsi);
1100     type_register_static(&vhost_ccw_scsi);
1101     type_register_static(&virtio_ccw_rng);
1102     type_register_static(&virtual_css_bridge_info);
1103 }
1104 
1105 type_init(virtio_ccw_register)
1106