]> git.proxmox.com Git - qemu.git/blame - hw/s390x/virtio-ccw.c
virtio-bus: make virtio_x_bus_new static.
[qemu.git] / hw / s390x / virtio-ccw.c
CommitLineData
a5cf2bb4
CH
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"
0d09e41a
PB
18#include "hw/virtio/virtio.h"
19#include "hw/virtio/virtio-serial.h"
20#include "hw/virtio/virtio-net.h"
a5cf2bb4
CH
21#include "hw/sysbus.h"
22#include "qemu/bitops.h"
0d09e41a 23#include "hw/virtio/virtio-bus.h"
a5cf2bb4
CH
24
25#include "ioinst.h"
26#include "css.h"
27#include "virtio-ccw.h"
28#include "trace.h"
29
d51fcfac
KF
30static void virtio_ccw_bus_new(VirtioBusState *bus, VirtioCcwDevice *dev);
31
a5cf2bb4
CH
32static 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
42static 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
49static 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
56static const VirtIOBindings virtio_ccw_bindings;
57
58VirtIODevice *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
68VirtualCssBus *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. */
89typedef struct VqInfoBlock {
90 uint64_t queue;
91 uint32_t align;
92 uint16_t index;
93 uint16_t num;
94} QEMU_PACKED VqInfoBlock;
95
96typedef struct VqConfigBlock {
97 uint16_t index;
98 uint16_t num_max;
99} QEMU_PACKED VqConfigBlock;
100
101typedef 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. */
107static 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
141static 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 if (dev->vdev->set_features) {
239 dev->vdev->set_features(dev->vdev, features.features);
240 }
241 dev->vdev->guest_features = features.features;
242 } else {
243 /*
244 * If the guest supports more feature bits, assert that it
245 * passes us zeroes for those we don't support.
246 */
247 if (features.features) {
248 fprintf(stderr, "Guest bug: features[%i]=%x (expected 0)\n",
249 features.index, features.features);
250 /* XXX: do a unit check here? */
251 }
252 }
253 sch->curr_status.scsw.count = ccw.count - sizeof(features);
254 ret = 0;
255 }
256 break;
257 case CCW_CMD_READ_CONF:
258 if (check_len) {
259 if (ccw.count > dev->vdev->config_len) {
260 ret = -EINVAL;
261 break;
262 }
263 }
264 len = MIN(ccw.count, dev->vdev->config_len);
265 if (!ccw.cda) {
266 ret = -EFAULT;
267 } else {
268 dev->vdev->get_config(dev->vdev, dev->vdev->config);
269 /* XXX config space endianness */
270 cpu_physical_memory_write(ccw.cda, dev->vdev->config, len);
271 sch->curr_status.scsw.count = ccw.count - len;
272 ret = 0;
273 }
274 break;
275 case CCW_CMD_WRITE_CONF:
276 if (check_len) {
277 if (ccw.count > dev->vdev->config_len) {
278 ret = -EINVAL;
279 break;
280 }
281 }
282 len = MIN(ccw.count, dev->vdev->config_len);
283 hw_len = len;
284 if (!ccw.cda) {
285 ret = -EFAULT;
286 } else {
287 config = cpu_physical_memory_map(ccw.cda, &hw_len, 0);
288 if (!config) {
289 ret = -EFAULT;
290 } else {
291 len = hw_len;
292 /* XXX config space endianness */
293 memcpy(dev->vdev->config, config, len);
294 cpu_physical_memory_unmap(config, hw_len, 0, hw_len);
295 if (dev->vdev->set_config) {
296 dev->vdev->set_config(dev->vdev, dev->vdev->config);
297 }
298 sch->curr_status.scsw.count = ccw.count - len;
299 ret = 0;
300 }
301 }
302 break;
303 case CCW_CMD_WRITE_STATUS:
304 if (check_len) {
305 if (ccw.count != sizeof(status)) {
306 ret = -EINVAL;
307 break;
308 }
309 } else if (ccw.count < sizeof(status)) {
310 /* Can't execute command. */
311 ret = -EINVAL;
312 break;
313 }
314 if (!ccw.cda) {
315 ret = -EFAULT;
316 } else {
317 status = ldub_phys(ccw.cda);
318 virtio_set_status(dev->vdev, status);
319 if (dev->vdev->status == 0) {
320 virtio_reset(dev->vdev);
321 }
322 sch->curr_status.scsw.count = ccw.count - sizeof(status);
323 ret = 0;
324 }
325 break;
326 case CCW_CMD_SET_IND:
327 if (check_len) {
328 if (ccw.count != sizeof(indicators)) {
329 ret = -EINVAL;
330 break;
331 }
332 } else if (ccw.count < sizeof(indicators)) {
333 /* Can't execute command. */
334 ret = -EINVAL;
335 break;
336 }
337 indicators = ldq_phys(ccw.cda);
338 if (!indicators) {
339 ret = -EFAULT;
340 } else {
341 dev->indicators = indicators;
342 sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
343 ret = 0;
344 }
345 break;
346 case CCW_CMD_SET_CONF_IND:
347 if (check_len) {
348 if (ccw.count != sizeof(indicators)) {
349 ret = -EINVAL;
350 break;
351 }
352 } else if (ccw.count < sizeof(indicators)) {
353 /* Can't execute command. */
354 ret = -EINVAL;
355 break;
356 }
357 indicators = ldq_phys(ccw.cda);
358 if (!indicators) {
359 ret = -EFAULT;
360 } else {
361 dev->indicators2 = indicators;
362 sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
363 ret = 0;
364 }
365 break;
366 case CCW_CMD_READ_VQ_CONF:
367 if (check_len) {
368 if (ccw.count != sizeof(vq_config)) {
369 ret = -EINVAL;
370 break;
371 }
372 } else if (ccw.count < sizeof(vq_config)) {
373 /* Can't execute command. */
374 ret = -EINVAL;
375 break;
376 }
377 if (!ccw.cda) {
378 ret = -EFAULT;
379 } else {
380 vq_config.index = lduw_phys(ccw.cda);
381 vq_config.num_max = virtio_queue_get_num(dev->vdev,
382 vq_config.index);
383 stw_phys(ccw.cda + sizeof(vq_config.index), vq_config.num_max);
384 sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);
385 ret = 0;
386 }
387 break;
388 default:
8d034a6f 389 ret = -ENOSYS;
a5cf2bb4
CH
390 break;
391 }
392 return ret;
393}
394
395static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
396{
397 unsigned int cssid = 0;
398 unsigned int ssid = 0;
399 unsigned int schid;
400 unsigned int devno;
401 bool have_devno = false;
402 bool found = false;
403 SubchDev *sch;
404 int ret;
405 int num;
406 DeviceState *parent = DEVICE(dev);
407
408 sch = g_malloc0(sizeof(SubchDev));
409
410 sch->driver_data = dev;
411 dev->sch = sch;
412
413 dev->vdev = vdev;
414 dev->indicators = 0;
415
416 /* Initialize subchannel structure. */
417 sch->channel_prog = 0x0;
418 sch->last_cmd_valid = false;
419 sch->orb = NULL;
420 /*
421 * Use a device number if provided. Otherwise, fall back to subchannel
422 * number.
423 */
424 if (dev->bus_id) {
425 num = sscanf(dev->bus_id, "%x.%x.%04x", &cssid, &ssid, &devno);
426 if (num == 3) {
427 if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) {
428 ret = -EINVAL;
429 error_report("Invalid cssid or ssid: cssid %x, ssid %x",
430 cssid, ssid);
431 goto out_err;
432 }
433 /* Enforce use of virtual cssid. */
434 if (cssid != VIRTUAL_CSSID) {
435 ret = -EINVAL;
436 error_report("cssid %x not valid for virtio devices", cssid);
437 goto out_err;
438 }
439 if (css_devno_used(cssid, ssid, devno)) {
440 ret = -EEXIST;
441 error_report("Device %x.%x.%04x already exists", cssid, ssid,
442 devno);
443 goto out_err;
444 }
445 sch->cssid = cssid;
446 sch->ssid = ssid;
447 sch->devno = devno;
448 have_devno = true;
449 } else {
450 ret = -EINVAL;
451 error_report("Malformed devno parameter '%s'", dev->bus_id);
452 goto out_err;
453 }
454 }
455
456 /* Find the next free id. */
457 if (have_devno) {
458 for (schid = 0; schid <= MAX_SCHID; schid++) {
459 if (!css_find_subch(1, cssid, ssid, schid)) {
460 sch->schid = schid;
461 css_subch_assign(cssid, ssid, schid, devno, sch);
462 found = true;
463 break;
464 }
465 }
466 if (!found) {
467 ret = -ENODEV;
468 error_report("No free subchannel found for %x.%x.%04x", cssid, ssid,
469 devno);
470 goto out_err;
471 }
472 trace_virtio_ccw_new_device(cssid, ssid, schid, devno,
473 "user-configured");
474 } else {
475 cssid = VIRTUAL_CSSID;
476 for (ssid = 0; ssid <= MAX_SSID; ssid++) {
477 for (schid = 0; schid <= MAX_SCHID; schid++) {
478 if (!css_find_subch(1, cssid, ssid, schid)) {
479 sch->cssid = cssid;
480 sch->ssid = ssid;
481 sch->schid = schid;
482 devno = schid;
483 /*
484 * If the devno is already taken, look further in this
485 * subchannel set.
486 */
487 while (css_devno_used(cssid, ssid, devno)) {
488 if (devno == MAX_SCHID) {
489 devno = 0;
490 } else if (devno == schid - 1) {
491 ret = -ENODEV;
492 error_report("No free devno found");
493 goto out_err;
494 } else {
495 devno++;
496 }
497 }
498 sch->devno = devno;
499 css_subch_assign(cssid, ssid, schid, devno, sch);
500 found = true;
501 break;
502 }
503 }
504 if (found) {
505 break;
506 }
507 }
508 if (!found) {
509 ret = -ENODEV;
510 error_report("Virtual channel subsystem is full!");
511 goto out_err;
512 }
513 trace_virtio_ccw_new_device(cssid, ssid, schid, devno,
514 "auto-configured");
515 }
516
517 /* Build initial schib. */
518 css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);
519
520 sch->ccw_cb = virtio_ccw_cb;
521
522 /* Build senseid data. */
523 memset(&sch->id, 0, sizeof(SenseId));
524 sch->id.reserved = 0xff;
525 sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
526 sch->id.cu_model = dev->vdev->device_id;
527
528 virtio_bind_device(vdev, &virtio_ccw_bindings, DEVICE(dev));
529 /* Only the first 32 feature bits are used. */
530 dev->host_features[0] = vdev->get_features(vdev, dev->host_features[0]);
531 dev->host_features[0] |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
532 dev->host_features[0] |= 0x1 << VIRTIO_F_BAD_FEATURE;
533
534 css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
535 parent->hotplugged, 1);
536 return 0;
537
538out_err:
539 dev->sch = NULL;
540 g_free(sch);
541 return ret;
542}
543
544static int virtio_ccw_exit(VirtioCcwDevice *dev)
545{
546 SubchDev *sch = dev->sch;
547
548 if (sch) {
549 css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
550 g_free(sch);
551 }
552 dev->indicators = 0;
553 return 0;
554}
555
89334c8b 556static int virtio_ccw_net_init(VirtioCcwDevice *ccw_dev)
a5cf2bb4 557{
89334c8b
KF
558 VirtIONetCcw *dev = VIRTIO_NET_CCW(ccw_dev);
559 DeviceState *vdev = DEVICE(&dev->vdev);
a5cf2bb4 560
89334c8b
KF
561 virtio_net_set_config_size(&dev->vdev, ccw_dev->host_features[0]);
562 qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
563 if (qdev_init(vdev) < 0) {
a5cf2bb4
CH
564 return -1;
565 }
566
89334c8b 567 return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
a5cf2bb4
CH
568}
569
89334c8b 570static void virtio_ccw_net_instance_init(Object *obj)
a5cf2bb4 571{
89334c8b
KF
572 VirtIONetCcw *dev = VIRTIO_NET_CCW(obj);
573 object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_NET);
574 object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
a5cf2bb4
CH
575}
576
3400c455 577static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
a5cf2bb4 578{
3400c455
KF
579 VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(ccw_dev);
580 DeviceState *vdev = DEVICE(&dev->vdev);
581 virtio_blk_set_conf(vdev, &(dev->blk));
582 qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
583 if (qdev_init(vdev) < 0) {
a5cf2bb4
CH
584 return -1;
585 }
586
3400c455 587 return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
a5cf2bb4
CH
588}
589
3400c455 590static void virtio_ccw_blk_instance_init(Object *obj)
a5cf2bb4 591{
3400c455
KF
592 VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(obj);
593 object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BLK);
594 object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
a5cf2bb4
CH
595}
596
6acf69cd 597static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev)
a5cf2bb4 598{
6acf69cd
KF
599 VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(ccw_dev);
600 DeviceState *vdev = DEVICE(&dev->vdev);
a5cf2bb4 601
6acf69cd
KF
602 qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
603 if (qdev_init(vdev) < 0) {
a5cf2bb4
CH
604 return -1;
605 }
606
6acf69cd 607 return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
a5cf2bb4
CH
608}
609
6acf69cd
KF
610
611static void virtio_ccw_serial_instance_init(Object *obj)
a5cf2bb4 612{
6acf69cd
KF
613 VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(obj);
614 object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SERIAL);
615 object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
a5cf2bb4
CH
616}
617
30bff6a0 618static int virtio_ccw_balloon_init(VirtioCcwDevice *ccw_dev)
a5cf2bb4 619{
30bff6a0
KF
620 VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(ccw_dev);
621 DeviceState *vdev = DEVICE(&dev->vdev);
a5cf2bb4 622
30bff6a0
KF
623 qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
624 if (qdev_init(vdev) < 0) {
a5cf2bb4
CH
625 return -1;
626 }
627
30bff6a0 628 return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
a5cf2bb4
CH
629}
630
24a6e7f4
KF
631static void balloon_ccw_stats_get_all(Object *obj, struct Visitor *v,
632 void *opaque, const char *name,
633 Error **errp)
634{
635 VirtIOBalloonCcw *dev = opaque;
636 object_property_get(OBJECT(&dev->vdev), v, "guest-stats", errp);
637}
638
639static void balloon_ccw_stats_get_poll_interval(Object *obj, struct Visitor *v,
640 void *opaque, const char *name,
641 Error **errp)
642{
643 VirtIOBalloonCcw *dev = opaque;
644 object_property_get(OBJECT(&dev->vdev), v, "guest-stats-polling-interval",
645 errp);
646}
647
648static void balloon_ccw_stats_set_poll_interval(Object *obj, struct Visitor *v,
649 void *opaque, const char *name,
650 Error **errp)
651{
652 VirtIOBalloonCcw *dev = opaque;
653 object_property_set(OBJECT(&dev->vdev), v, "guest-stats-polling-interval",
654 errp);
655}
656
30bff6a0 657static void virtio_ccw_balloon_instance_init(Object *obj)
a5cf2bb4 658{
30bff6a0
KF
659 VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj);
660 object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BALLOON);
661 object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
24a6e7f4
KF
662
663 object_property_add(obj, "guest-stats", "guest statistics",
664 balloon_ccw_stats_get_all, NULL, NULL, dev, NULL);
665
666 object_property_add(obj, "guest-stats-polling-interval", "int",
667 balloon_ccw_stats_get_poll_interval,
668 balloon_ccw_stats_set_poll_interval,
669 NULL, dev, NULL);
a5cf2bb4
CH
670}
671
c908ea10 672static int virtio_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
a5cf2bb4 673{
c908ea10
KF
674 VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(ccw_dev);
675 DeviceState *vdev = DEVICE(&dev->vdev);
a5cf2bb4 676
c908ea10
KF
677 qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
678 if (qdev_init(vdev) < 0) {
a5cf2bb4
CH
679 return -1;
680 }
681
c908ea10 682 return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
a5cf2bb4
CH
683}
684
c908ea10 685static void virtio_ccw_scsi_instance_init(Object *obj)
a5cf2bb4 686{
c908ea10
KF
687 VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(obj);
688 object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SCSI);
689 object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
a5cf2bb4
CH
690}
691
ccf6916c
PB
692#ifdef CONFIG_VHOST_SCSI
693static int vhost_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
694{
695 VHostSCSICcw *dev = VHOST_SCSI_CCW(ccw_dev);
696 DeviceState *vdev = DEVICE(&dev->vdev);
697
698 qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
699 if (qdev_init(vdev) < 0) {
700 return -1;
701 }
702
703 return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
704}
705
706static void vhost_ccw_scsi_instance_init(Object *obj)
707{
708 VHostSCSICcw *dev = VHOST_SCSI_CCW(obj);
709 object_initialize(OBJECT(&dev->vdev), TYPE_VHOST_SCSI);
710 object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
711}
712#endif
713
2db26d4c 714static int virtio_ccw_rng_init(VirtioCcwDevice *ccw_dev)
2362ecc5 715{
2db26d4c
KF
716 VirtIORNGCcw *dev = VIRTIO_RNG_CCW(ccw_dev);
717 DeviceState *vdev = DEVICE(&dev->vdev);
2362ecc5 718
2db26d4c
KF
719 qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
720 if (qdev_init(vdev) < 0) {
2362ecc5
CH
721 return -1;
722 }
2362ecc5 723
2db26d4c
KF
724 object_property_set_link(OBJECT(dev),
725 OBJECT(dev->vdev.conf.default_backend), "rng",
726 NULL);
727
728 return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
2362ecc5
CH
729}
730
a5cf2bb4
CH
731/* DeviceState to VirtioCcwDevice. Note: used on datapath,
732 * be careful and test performance if you change this.
733 */
734static inline VirtioCcwDevice *to_virtio_ccw_dev_fast(DeviceState *d)
735{
736 return container_of(d, VirtioCcwDevice, parent_obj);
737}
738
739static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
740{
741 VirtioCcwDevice *dev = to_virtio_ccw_dev_fast(d);
742 SubchDev *sch = dev->sch;
743 uint64_t indicators;
744
745 if (vector >= 128) {
746 return;
747 }
748
749 if (vector < VIRTIO_PCI_QUEUE_MAX) {
750 indicators = ldq_phys(dev->indicators);
19380b1b 751 indicators |= 1ULL << vector;
a5cf2bb4
CH
752 stq_phys(dev->indicators, indicators);
753 } else {
754 vector = 0;
755 indicators = ldq_phys(dev->indicators2);
19380b1b 756 indicators |= 1ULL << vector;
a5cf2bb4
CH
757 stq_phys(dev->indicators2, indicators);
758 }
759
760 css_conditional_io_interrupt(sch);
761
762}
763
764static unsigned virtio_ccw_get_features(DeviceState *d)
765{
766 VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
767
768 /* Only the first 32 feature bits are used. */
769 return dev->host_features[0];
770}
771
772static void virtio_ccw_reset(DeviceState *d)
773{
774 VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
775
776 virtio_reset(dev->vdev);
777 css_reset_sch(dev->sch);
778}
779
780/**************** Virtio-ccw Bus Device Descriptions *******************/
781
782static const VirtIOBindings virtio_ccw_bindings = {
783 .notify = virtio_ccw_notify,
784 .get_features = virtio_ccw_get_features,
785};
786
787static Property virtio_ccw_net_properties[] = {
788 DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
789 DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features[0]),
89334c8b
KF
790 DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetCcw, vdev.net_conf),
791 DEFINE_NIC_PROPERTIES(VirtIONetCcw, vdev.nic_conf),
a5cf2bb4
CH
792 DEFINE_PROP_END_OF_LIST(),
793};
794
795static void virtio_ccw_net_class_init(ObjectClass *klass, void *data)
796{
797 DeviceClass *dc = DEVICE_CLASS(klass);
798 VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
799
800 k->init = virtio_ccw_net_init;
89334c8b 801 k->exit = virtio_ccw_exit;
a5cf2bb4
CH
802 dc->reset = virtio_ccw_reset;
803 dc->props = virtio_ccw_net_properties;
804}
805
806static const TypeInfo virtio_ccw_net = {
89334c8b 807 .name = TYPE_VIRTIO_NET_CCW,
a5cf2bb4 808 .parent = TYPE_VIRTIO_CCW_DEVICE,
89334c8b
KF
809 .instance_size = sizeof(VirtIONetCcw),
810 .instance_init = virtio_ccw_net_instance_init,
a5cf2bb4
CH
811 .class_init = virtio_ccw_net_class_init,
812};
813
814static Property virtio_ccw_blk_properties[] = {
815 DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
a5cf2bb4 816 DEFINE_VIRTIO_BLK_FEATURES(VirtioCcwDevice, host_features[0]),
fe42d7fb 817 DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlkCcw, blk),
a5cf2bb4
CH
818 DEFINE_PROP_END_OF_LIST(),
819};
820
821static void virtio_ccw_blk_class_init(ObjectClass *klass, void *data)
822{
823 DeviceClass *dc = DEVICE_CLASS(klass);
824 VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
825
826 k->init = virtio_ccw_blk_init;
3400c455 827 k->exit = virtio_ccw_exit;
a5cf2bb4
CH
828 dc->reset = virtio_ccw_reset;
829 dc->props = virtio_ccw_blk_properties;
830}
831
832static const TypeInfo virtio_ccw_blk = {
3400c455 833 .name = TYPE_VIRTIO_BLK_CCW,
a5cf2bb4 834 .parent = TYPE_VIRTIO_CCW_DEVICE,
3400c455
KF
835 .instance_size = sizeof(VirtIOBlkCcw),
836 .instance_init = virtio_ccw_blk_instance_init,
a5cf2bb4
CH
837 .class_init = virtio_ccw_blk_class_init,
838};
839
840static Property virtio_ccw_serial_properties[] = {
841 DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
6acf69cd 842 DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtioSerialCcw, vdev.serial),
a5cf2bb4
CH
843 DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
844 DEFINE_PROP_END_OF_LIST(),
845};
846
847static void virtio_ccw_serial_class_init(ObjectClass *klass, void *data)
848{
849 DeviceClass *dc = DEVICE_CLASS(klass);
850 VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
851
852 k->init = virtio_ccw_serial_init;
6acf69cd 853 k->exit = virtio_ccw_exit;
a5cf2bb4
CH
854 dc->reset = virtio_ccw_reset;
855 dc->props = virtio_ccw_serial_properties;
856}
857
858static const TypeInfo virtio_ccw_serial = {
6acf69cd 859 .name = TYPE_VIRTIO_SERIAL_CCW,
a5cf2bb4 860 .parent = TYPE_VIRTIO_CCW_DEVICE,
6acf69cd
KF
861 .instance_size = sizeof(VirtioSerialCcw),
862 .instance_init = virtio_ccw_serial_instance_init,
a5cf2bb4
CH
863 .class_init = virtio_ccw_serial_class_init,
864};
865
866static Property virtio_ccw_balloon_properties[] = {
867 DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
868 DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
869 DEFINE_PROP_END_OF_LIST(),
870};
871
872static void virtio_ccw_balloon_class_init(ObjectClass *klass, void *data)
873{
874 DeviceClass *dc = DEVICE_CLASS(klass);
875 VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
876
877 k->init = virtio_ccw_balloon_init;
30bff6a0 878 k->exit = virtio_ccw_exit;
a5cf2bb4
CH
879 dc->reset = virtio_ccw_reset;
880 dc->props = virtio_ccw_balloon_properties;
881}
882
883static const TypeInfo virtio_ccw_balloon = {
30bff6a0 884 .name = TYPE_VIRTIO_BALLOON_CCW,
a5cf2bb4 885 .parent = TYPE_VIRTIO_CCW_DEVICE,
30bff6a0
KF
886 .instance_size = sizeof(VirtIOBalloonCcw),
887 .instance_init = virtio_ccw_balloon_instance_init,
a5cf2bb4
CH
888 .class_init = virtio_ccw_balloon_class_init,
889};
890
891static Property virtio_ccw_scsi_properties[] = {
892 DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
292c8e50 893 DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
4bfeb18a 894 DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features[0]),
a5cf2bb4
CH
895 DEFINE_PROP_END_OF_LIST(),
896};
897
898static void virtio_ccw_scsi_class_init(ObjectClass *klass, void *data)
899{
900 DeviceClass *dc = DEVICE_CLASS(klass);
901 VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
902
903 k->init = virtio_ccw_scsi_init;
c908ea10 904 k->exit = virtio_ccw_exit;
a5cf2bb4
CH
905 dc->reset = virtio_ccw_reset;
906 dc->props = virtio_ccw_scsi_properties;
907}
908
909static const TypeInfo virtio_ccw_scsi = {
c908ea10 910 .name = TYPE_VIRTIO_SCSI_CCW,
a5cf2bb4 911 .parent = TYPE_VIRTIO_CCW_DEVICE,
c908ea10
KF
912 .instance_size = sizeof(VirtIOSCSICcw),
913 .instance_init = virtio_ccw_scsi_instance_init,
a5cf2bb4
CH
914 .class_init = virtio_ccw_scsi_class_init,
915};
916
ccf6916c
PB
917#ifdef CONFIG_VHOST_SCSI
918static Property vhost_ccw_scsi_properties[] = {
919 DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
920 DEFINE_VHOST_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
921 DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
922 DEFINE_PROP_END_OF_LIST(),
923};
924
925static void vhost_ccw_scsi_class_init(ObjectClass *klass, void *data)
926{
927 DeviceClass *dc = DEVICE_CLASS(klass);
928 VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
929
930 k->init = vhost_ccw_scsi_init;
931 k->exit = virtio_ccw_exit;
932 dc->reset = virtio_ccw_reset;
933 dc->props = vhost_ccw_scsi_properties;
934}
935
936static const TypeInfo vhost_ccw_scsi = {
937 .name = TYPE_VHOST_SCSI_CCW,
938 .parent = TYPE_VIRTIO_CCW_DEVICE,
939 .instance_size = sizeof(VirtIOSCSICcw),
940 .instance_init = vhost_ccw_scsi_instance_init,
941 .class_init = vhost_ccw_scsi_class_init,
942};
943#endif
944
2db26d4c 945static void virtio_ccw_rng_instance_init(Object *obj)
2362ecc5 946{
2db26d4c
KF
947 VirtIORNGCcw *dev = VIRTIO_RNG_CCW(obj);
948 object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_RNG);
949 object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
2362ecc5 950 object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
2db26d4c 951 (Object **)&dev->vdev.conf.rng, NULL);
2362ecc5
CH
952}
953
954static Property virtio_ccw_rng_properties[] = {
955 DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
956 DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
2db26d4c 957 DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGCcw, vdev.conf),
2362ecc5
CH
958 DEFINE_PROP_END_OF_LIST(),
959};
960
961static void virtio_ccw_rng_class_init(ObjectClass *klass, void *data)
962{
963 DeviceClass *dc = DEVICE_CLASS(klass);
964 VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
965
966 k->init = virtio_ccw_rng_init;
2db26d4c 967 k->exit = virtio_ccw_exit;
2362ecc5
CH
968 dc->reset = virtio_ccw_reset;
969 dc->props = virtio_ccw_rng_properties;
970}
971
972static const TypeInfo virtio_ccw_rng = {
2db26d4c 973 .name = TYPE_VIRTIO_RNG_CCW,
2362ecc5 974 .parent = TYPE_VIRTIO_CCW_DEVICE,
2db26d4c
KF
975 .instance_size = sizeof(VirtIORNGCcw),
976 .instance_init = virtio_ccw_rng_instance_init,
2362ecc5
CH
977 .class_init = virtio_ccw_rng_class_init,
978};
979
a5cf2bb4
CH
980static int virtio_ccw_busdev_init(DeviceState *dev)
981{
982 VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
983 VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
984
985 virtio_ccw_bus_new(&_dev->bus, _dev);
986
987 return _info->init(_dev);
988}
989
990static int virtio_ccw_busdev_exit(DeviceState *dev)
991{
992 VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
993 VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
994
995 return _info->exit(_dev);
996}
997
998static int virtio_ccw_busdev_unplug(DeviceState *dev)
999{
1000 VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
1001 SubchDev *sch = _dev->sch;
1002
1003 /*
1004 * We should arrive here only for device_del, since we don't support
1005 * direct hot(un)plug of channels, but only through virtio.
1006 */
1007 assert(sch != NULL);
1008 /* Subchannel is now disabled and no longer valid. */
1009 sch->curr_status.pmcw.flags &= ~(PMCW_FLAGS_MASK_ENA |
1010 PMCW_FLAGS_MASK_DNV);
1011
1012 css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0);
1013
a5cf2bb4
CH
1014 qdev_free(dev);
1015 return 0;
1016}
1017
1018static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
1019{
1020 DeviceClass *dc = DEVICE_CLASS(klass);
1021
1022 dc->init = virtio_ccw_busdev_init;
1023 dc->exit = virtio_ccw_busdev_exit;
1024 dc->unplug = virtio_ccw_busdev_unplug;
1025 dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
1026
1027}
1028
1029static const TypeInfo virtio_ccw_device_info = {
1030 .name = TYPE_VIRTIO_CCW_DEVICE,
1031 .parent = TYPE_DEVICE,
1032 .instance_size = sizeof(VirtioCcwDevice),
1033 .class_init = virtio_ccw_device_class_init,
1034 .class_size = sizeof(VirtIOCCWDeviceClass),
1035 .abstract = true,
1036};
1037
1038/***************** Virtual-css Bus Bridge Device ********************/
1039/* Only required to have the virtio bus as child in the system bus */
1040
1041static int virtual_css_bridge_init(SysBusDevice *dev)
1042{
1043 /* nothing */
1044 return 0;
1045}
1046
1047static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
1048{
1049 DeviceClass *dc = DEVICE_CLASS(klass);
1050 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1051
1052 k->init = virtual_css_bridge_init;
1053 dc->no_user = 1;
1054}
1055
1056static const TypeInfo virtual_css_bridge_info = {
1057 .name = "virtual-css-bridge",
1058 .parent = TYPE_SYS_BUS_DEVICE,
1059 .instance_size = sizeof(SysBusDevice),
1060 .class_init = virtual_css_bridge_class_init,
1061};
1062
1063/* virtio-ccw-bus */
1064
d51fcfac 1065static void virtio_ccw_bus_new(VirtioBusState *bus, VirtioCcwDevice *dev)
a5cf2bb4
CH
1066{
1067 DeviceState *qdev = DEVICE(dev);
1068 BusState *qbus;
1069
1070 qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_CCW_BUS, qdev, NULL);
1071 qbus = BUS(bus);
cbd19063 1072 qbus->allow_hotplug = 1;
a5cf2bb4
CH
1073}
1074
1075static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data)
1076{
1077 VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
1078 BusClass *bus_class = BUS_CLASS(klass);
1079
1080 bus_class->max_dev = 1;
1081 k->notify = virtio_ccw_notify;
1082 k->get_features = virtio_ccw_get_features;
1083}
1084
1085static const TypeInfo virtio_ccw_bus_info = {
1086 .name = TYPE_VIRTIO_CCW_BUS,
1087 .parent = TYPE_VIRTIO_BUS,
1088 .instance_size = sizeof(VirtioCcwBusState),
1089 .class_init = virtio_ccw_bus_class_init,
1090};
1091
1092static void virtio_ccw_register(void)
1093{
1094 type_register_static(&virtio_ccw_bus_info);
1095 type_register_static(&virtual_css_bus_info);
1096 type_register_static(&virtio_ccw_device_info);
1097 type_register_static(&virtio_ccw_serial);
1098 type_register_static(&virtio_ccw_blk);
1099 type_register_static(&virtio_ccw_net);
1100 type_register_static(&virtio_ccw_balloon);
1101 type_register_static(&virtio_ccw_scsi);
ccf6916c 1102 type_register_static(&vhost_ccw_scsi);
2362ecc5 1103 type_register_static(&virtio_ccw_rng);
a5cf2bb4
CH
1104 type_register_static(&virtual_css_bridge_info);
1105}
1106
1107type_init(virtio_ccw_register)