Statistics
| Branch: | Revision:

root / hw / s390x / virtio-ccw.c @ cc3ac9c4

History | View | Annotate | Download (40.7 kB)

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
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
static int virtio_ccw_set_guest2host_notifier(VirtioCcwDevice *dev, int n,
67
                                              bool assign, bool set_handler)
68
{
69
    VirtQueue *vq = virtio_get_queue(dev->vdev, n);
70
    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
71
    int r = 0;
72
    SubchDev *sch = dev->sch;
73
    uint32_t sch_id = (css_build_subchannel_id(sch) << 16) | sch->schid;
74

    
75
    if (assign) {
76
        r = event_notifier_init(notifier, 1);
77
        if (r < 0) {
78
            error_report("%s: unable to init event notifier: %d", __func__, r);
79
            return r;
80
        }
81
        virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
82
        r = s390_assign_subch_ioeventfd(notifier, sch_id, n, assign);
83
        if (r < 0) {
84
            error_report("%s: unable to assign ioeventfd: %d", __func__, r);
85
            virtio_queue_set_host_notifier_fd_handler(vq, false, false);
86
            event_notifier_cleanup(notifier);
87
            return r;
88
        }
89
    } else {
90
        virtio_queue_set_host_notifier_fd_handler(vq, false, false);
91
        s390_assign_subch_ioeventfd(notifier, sch_id, n, assign);
92
        event_notifier_cleanup(notifier);
93
    }
94
    return r;
95
}
96

    
97
static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
98
{
99
    int n, r;
100

    
101
    if (!(dev->flags & VIRTIO_CCW_FLAG_USE_IOEVENTFD) ||
102
        dev->ioeventfd_disabled ||
103
        dev->ioeventfd_started) {
104
        return;
105
    }
106
    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
107
        if (!virtio_queue_get_num(dev->vdev, n)) {
108
            continue;
109
        }
110
        r = virtio_ccw_set_guest2host_notifier(dev, n, true, true);
111
        if (r < 0) {
112
            goto assign_error;
113
        }
114
    }
115
    dev->ioeventfd_started = true;
116
    return;
117

    
118
  assign_error:
119
    while (--n >= 0) {
120
        if (!virtio_queue_get_num(dev->vdev, n)) {
121
            continue;
122
        }
123
        r = virtio_ccw_set_guest2host_notifier(dev, n, false, false);
124
        assert(r >= 0);
125
    }
126
    dev->ioeventfd_started = false;
127
    /* Disable ioeventfd for this device. */
128
    dev->flags &= ~VIRTIO_CCW_FLAG_USE_IOEVENTFD;
129
    error_report("%s: failed. Fallback to userspace (slower).", __func__);
130
}
131

    
132
static void virtio_ccw_stop_ioeventfd(VirtioCcwDevice *dev)
133
{
134
    int n, r;
135

    
136
    if (!dev->ioeventfd_started) {
137
        return;
138
    }
139
    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
140
        if (!virtio_queue_get_num(dev->vdev, n)) {
141
            continue;
142
        }
143
        r = virtio_ccw_set_guest2host_notifier(dev, n, false, false);
144
        assert(r >= 0);
145
    }
146
    dev->ioeventfd_started = false;
147
}
148

    
149
VirtualCssBus *virtual_css_bus_init(void)
150
{
151
    VirtualCssBus *cbus;
152
    BusState *bus;
153
    DeviceState *dev;
154

    
155
    /* Create bridge device */
156
    dev = qdev_create(NULL, "virtual-css-bridge");
157
    qdev_init_nofail(dev);
158

    
159
    /* Create bus on bridge device */
160
    bus = qbus_create(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css");
161
    cbus = VIRTUAL_CSS_BUS(bus);
162

    
163
    /* Enable hotplugging */
164
    bus->allow_hotplug = 1;
165

    
166
    return cbus;
167
}
168

    
169
/* Communication blocks used by several channel commands. */
170
typedef struct VqInfoBlock {
171
    uint64_t queue;
172
    uint32_t align;
173
    uint16_t index;
174
    uint16_t num;
175
} QEMU_PACKED VqInfoBlock;
176

    
177
typedef struct VqConfigBlock {
178
    uint16_t index;
179
    uint16_t num_max;
180
} QEMU_PACKED VqConfigBlock;
181

    
182
typedef struct VirtioFeatDesc {
183
    uint32_t features;
184
    uint8_t index;
185
} QEMU_PACKED VirtioFeatDesc;
186

    
187
/* Specify where the virtqueues for the subchannel are in guest memory. */
188
static int virtio_ccw_set_vqs(SubchDev *sch, uint64_t addr, uint32_t align,
189
                              uint16_t index, uint16_t num)
190
{
191
    VirtioCcwDevice *dev = sch->driver_data;
192

    
193
    if (index > VIRTIO_PCI_QUEUE_MAX) {
194
        return -EINVAL;
195
    }
196

    
197
    /* Current code in virtio.c relies on 4K alignment. */
198
    if (addr && (align != 4096)) {
199
        return -EINVAL;
200
    }
201

    
202
    if (!dev) {
203
        return -EINVAL;
204
    }
205

    
206
    virtio_queue_set_addr(dev->vdev, index, addr);
207
    if (!addr) {
208
        virtio_queue_set_vector(dev->vdev, index, 0);
209
    } else {
210
        /* Fail if we don't have a big enough queue. */
211
        /* TODO: Add interface to handle vring.num changing */
212
        if (virtio_queue_get_num(dev->vdev, index) > num) {
213
            return -EINVAL;
214
        }
215
        virtio_queue_set_vector(dev->vdev, index, index);
216
    }
217
    /* tell notify handler in case of config change */
218
    dev->vdev->config_vector = VIRTIO_PCI_QUEUE_MAX;
219
    return 0;
220
}
221

    
222
static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
223
{
224
    int ret;
225
    VqInfoBlock info;
226
    uint8_t status;
227
    VirtioFeatDesc features;
228
    void *config;
229
    hwaddr indicators;
230
    VqConfigBlock vq_config;
231
    VirtioCcwDevice *dev = sch->driver_data;
232
    bool check_len;
233
    int len;
234
    hwaddr hw_len;
235

    
236
    if (!dev) {
237
        return -EINVAL;
238
    }
239

    
240
    trace_virtio_ccw_interpret_ccw(sch->cssid, sch->ssid, sch->schid,
241
                                   ccw.cmd_code);
242
    check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));
243

    
244
    /* Look at the command. */
245
    switch (ccw.cmd_code) {
246
    case CCW_CMD_SET_VQ:
247
        if (check_len) {
248
            if (ccw.count != sizeof(info)) {
249
                ret = -EINVAL;
250
                break;
251
            }
252
        } else if (ccw.count < sizeof(info)) {
253
            /* Can't execute command. */
254
            ret = -EINVAL;
255
            break;
256
        }
257
        if (!ccw.cda) {
258
            ret = -EFAULT;
259
        } else {
260
            info.queue = ldq_phys(ccw.cda);
261
            info.align = ldl_phys(ccw.cda + sizeof(info.queue));
262
            info.index = lduw_phys(ccw.cda + sizeof(info.queue)
263
                                   + sizeof(info.align));
264
            info.num = lduw_phys(ccw.cda + sizeof(info.queue)
265
                                 + sizeof(info.align)
266
                                 + sizeof(info.index));
267
            ret = virtio_ccw_set_vqs(sch, info.queue, info.align, info.index,
268
                                     info.num);
269
            sch->curr_status.scsw.count = 0;
270
        }
271
        break;
272
    case CCW_CMD_VDEV_RESET:
273
        virtio_ccw_stop_ioeventfd(dev);
274
        virtio_reset(dev->vdev);
275
        ret = 0;
276
        break;
277
    case CCW_CMD_READ_FEAT:
278
        if (check_len) {
279
            if (ccw.count != sizeof(features)) {
280
                ret = -EINVAL;
281
                break;
282
            }
283
        } else if (ccw.count < sizeof(features)) {
284
            /* Can't execute command. */
285
            ret = -EINVAL;
286
            break;
287
        }
288
        if (!ccw.cda) {
289
            ret = -EFAULT;
290
        } else {
291
            features.index = ldub_phys(ccw.cda + sizeof(features.features));
292
            if (features.index < ARRAY_SIZE(dev->host_features)) {
293
                features.features = dev->host_features[features.index];
294
            } else {
295
                /* Return zeroes if the guest supports more feature bits. */
296
                features.features = 0;
297
            }
298
            stl_le_phys(ccw.cda, features.features);
299
            sch->curr_status.scsw.count = ccw.count - sizeof(features);
300
            ret = 0;
301
        }
302
        break;
303
    case CCW_CMD_WRITE_FEAT:
304
        if (check_len) {
305
            if (ccw.count != sizeof(features)) {
306
                ret = -EINVAL;
307
                break;
308
            }
309
        } else if (ccw.count < sizeof(features)) {
310
            /* Can't execute command. */
311
            ret = -EINVAL;
312
            break;
313
        }
314
        if (!ccw.cda) {
315
            ret = -EFAULT;
316
        } else {
317
            features.index = ldub_phys(ccw.cda + sizeof(features.features));
318
            features.features = ldl_le_phys(ccw.cda);
319
            if (features.index < ARRAY_SIZE(dev->host_features)) {
320
                virtio_bus_set_vdev_features(&dev->bus, features.features);
321
                dev->vdev->guest_features = features.features;
322
            } else {
323
                /*
324
                 * If the guest supports more feature bits, assert that it
325
                 * passes us zeroes for those we don't support.
326
                 */
327
                if (features.features) {
328
                    fprintf(stderr, "Guest bug: features[%i]=%x (expected 0)\n",
329
                            features.index, features.features);
330
                    /* XXX: do a unit check here? */
331
                }
332
            }
333
            sch->curr_status.scsw.count = ccw.count - sizeof(features);
334
            ret = 0;
335
        }
336
        break;
337
    case CCW_CMD_READ_CONF:
338
        if (check_len) {
339
            if (ccw.count > dev->vdev->config_len) {
340
                ret = -EINVAL;
341
                break;
342
            }
343
        }
344
        len = MIN(ccw.count, dev->vdev->config_len);
345
        if (!ccw.cda) {
346
            ret = -EFAULT;
347
        } else {
348
            virtio_bus_get_vdev_config(&dev->bus, dev->vdev->config);
349
            /* XXX config space endianness */
350
            cpu_physical_memory_write(ccw.cda, dev->vdev->config, len);
351
            sch->curr_status.scsw.count = ccw.count - len;
352
            ret = 0;
353
        }
354
        break;
355
    case CCW_CMD_WRITE_CONF:
356
        if (check_len) {
357
            if (ccw.count > dev->vdev->config_len) {
358
                ret = -EINVAL;
359
                break;
360
            }
361
        }
362
        len = MIN(ccw.count, dev->vdev->config_len);
363
        hw_len = len;
364
        if (!ccw.cda) {
365
            ret = -EFAULT;
366
        } else {
367
            config = cpu_physical_memory_map(ccw.cda, &hw_len, 0);
368
            if (!config) {
369
                ret = -EFAULT;
370
            } else {
371
                len = hw_len;
372
                /* XXX config space endianness */
373
                memcpy(dev->vdev->config, config, len);
374
                cpu_physical_memory_unmap(config, hw_len, 0, hw_len);
375
                virtio_bus_set_vdev_config(&dev->bus, dev->vdev->config);
376
                sch->curr_status.scsw.count = ccw.count - len;
377
                ret = 0;
378
            }
379
        }
380
        break;
381
    case CCW_CMD_WRITE_STATUS:
382
        if (check_len) {
383
            if (ccw.count != sizeof(status)) {
384
                ret = -EINVAL;
385
                break;
386
            }
387
        } else if (ccw.count < sizeof(status)) {
388
            /* Can't execute command. */
389
            ret = -EINVAL;
390
            break;
391
        }
392
        if (!ccw.cda) {
393
            ret = -EFAULT;
394
        } else {
395
            status = ldub_phys(ccw.cda);
396
            if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
397
                virtio_ccw_stop_ioeventfd(dev);
398
            }
399
            virtio_set_status(dev->vdev, status);
400
            if (dev->vdev->status == 0) {
401
                virtio_reset(dev->vdev);
402
            }
403
            if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
404
                virtio_ccw_start_ioeventfd(dev);
405
            }
406
            sch->curr_status.scsw.count = ccw.count - sizeof(status);
407
            ret = 0;
408
        }
409
        break;
410
    case CCW_CMD_SET_IND:
411
        if (check_len) {
412
            if (ccw.count != sizeof(indicators)) {
413
                ret = -EINVAL;
414
                break;
415
            }
416
        } else if (ccw.count < sizeof(indicators)) {
417
            /* Can't execute command. */
418
            ret = -EINVAL;
419
            break;
420
        }
421
        if (!ccw.cda) {
422
            ret = -EFAULT;
423
        } else {
424
            indicators = ldq_phys(ccw.cda);
425
            dev->indicators = indicators;
426
            sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
427
            ret = 0;
428
        }
429
        break;
430
    case CCW_CMD_SET_CONF_IND:
431
        if (check_len) {
432
            if (ccw.count != sizeof(indicators)) {
433
                ret = -EINVAL;
434
                break;
435
            }
436
        } else if (ccw.count < sizeof(indicators)) {
437
            /* Can't execute command. */
438
            ret = -EINVAL;
439
            break;
440
        }
441
        if (!ccw.cda) {
442
            ret = -EFAULT;
443
        } else {
444
            indicators = ldq_phys(ccw.cda);
445
            dev->indicators2 = indicators;
446
            sch->curr_status.scsw.count = ccw.count - sizeof(indicators);
447
            ret = 0;
448
        }
449
        break;
450
    case CCW_CMD_READ_VQ_CONF:
451
        if (check_len) {
452
            if (ccw.count != sizeof(vq_config)) {
453
                ret = -EINVAL;
454
                break;
455
            }
456
        } else if (ccw.count < sizeof(vq_config)) {
457
            /* Can't execute command. */
458
            ret = -EINVAL;
459
            break;
460
        }
461
        if (!ccw.cda) {
462
            ret = -EFAULT;
463
        } else {
464
            vq_config.index = lduw_phys(ccw.cda);
465
            vq_config.num_max = virtio_queue_get_num(dev->vdev,
466
                                                     vq_config.index);
467
            stw_phys(ccw.cda + sizeof(vq_config.index), vq_config.num_max);
468
            sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);
469
            ret = 0;
470
        }
471
        break;
472
    default:
473
        ret = -ENOSYS;
474
        break;
475
    }
476
    return ret;
477
}
478

    
479
static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
480
{
481
    unsigned int cssid = 0;
482
    unsigned int ssid = 0;
483
    unsigned int schid;
484
    unsigned int devno;
485
    bool have_devno = false;
486
    bool found = false;
487
    SubchDev *sch;
488
    int ret;
489
    int num;
490
    DeviceState *parent = DEVICE(dev);
491

    
492
    sch = g_malloc0(sizeof(SubchDev));
493

    
494
    sch->driver_data = dev;
495
    dev->sch = sch;
496

    
497
    dev->vdev = vdev;
498
    dev->indicators = 0;
499

    
500
    /* Initialize subchannel structure. */
501
    sch->channel_prog = 0x0;
502
    sch->last_cmd_valid = false;
503
    sch->orb = NULL;
504
    /*
505
     * Use a device number if provided. Otherwise, fall back to subchannel
506
     * number.
507
     */
508
    if (dev->bus_id) {
509
        num = sscanf(dev->bus_id, "%x.%x.%04x", &cssid, &ssid, &devno);
510
        if (num == 3) {
511
            if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) {
512
                ret = -EINVAL;
513
                error_report("Invalid cssid or ssid: cssid %x, ssid %x",
514
                             cssid, ssid);
515
                goto out_err;
516
            }
517
            /* Enforce use of virtual cssid. */
518
            if (cssid != VIRTUAL_CSSID) {
519
                ret = -EINVAL;
520
                error_report("cssid %x not valid for virtio devices", cssid);
521
                goto out_err;
522
            }
523
            if (css_devno_used(cssid, ssid, devno)) {
524
                ret = -EEXIST;
525
                error_report("Device %x.%x.%04x already exists", cssid, ssid,
526
                             devno);
527
                goto out_err;
528
            }
529
            sch->cssid = cssid;
530
            sch->ssid = ssid;
531
            sch->devno = devno;
532
            have_devno = true;
533
        } else {
534
            ret = -EINVAL;
535
            error_report("Malformed devno parameter '%s'", dev->bus_id);
536
            goto out_err;
537
        }
538
    }
539

    
540
    /* Find the next free id. */
541
    if (have_devno) {
542
        for (schid = 0; schid <= MAX_SCHID; schid++) {
543
            if (!css_find_subch(1, cssid, ssid, schid)) {
544
                sch->schid = schid;
545
                css_subch_assign(cssid, ssid, schid, devno, sch);
546
                found = true;
547
                break;
548
            }
549
        }
550
        if (!found) {
551
            ret = -ENODEV;
552
            error_report("No free subchannel found for %x.%x.%04x", cssid, ssid,
553
                         devno);
554
            goto out_err;
555
        }
556
        trace_virtio_ccw_new_device(cssid, ssid, schid, devno,
557
                                    "user-configured");
558
    } else {
559
        cssid = VIRTUAL_CSSID;
560
        for (ssid = 0; ssid <= MAX_SSID; ssid++) {
561
            for (schid = 0; schid <= MAX_SCHID; schid++) {
562
                if (!css_find_subch(1, cssid, ssid, schid)) {
563
                    sch->cssid = cssid;
564
                    sch->ssid = ssid;
565
                    sch->schid = schid;
566
                    devno = schid;
567
                    /*
568
                     * If the devno is already taken, look further in this
569
                     * subchannel set.
570
                     */
571
                    while (css_devno_used(cssid, ssid, devno)) {
572
                        if (devno == MAX_SCHID) {
573
                            devno = 0;
574
                        } else if (devno == schid - 1) {
575
                            ret = -ENODEV;
576
                            error_report("No free devno found");
577
                            goto out_err;
578
                        } else {
579
                            devno++;
580
                        }
581
                    }
582
                    sch->devno = devno;
583
                    css_subch_assign(cssid, ssid, schid, devno, sch);
584
                    found = true;
585
                    break;
586
                }
587
            }
588
            if (found) {
589
                break;
590
            }
591
        }
592
        if (!found) {
593
            ret = -ENODEV;
594
            error_report("Virtual channel subsystem is full!");
595
            goto out_err;
596
        }
597
        trace_virtio_ccw_new_device(cssid, ssid, schid, devno,
598
                                    "auto-configured");
599
    }
600

    
601
    /* Build initial schib. */
602
    css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);
603

    
604
    sch->ccw_cb = virtio_ccw_cb;
605

    
606
    /* Build senseid data. */
607
    memset(&sch->id, 0, sizeof(SenseId));
608
    sch->id.reserved = 0xff;
609
    sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
610
    sch->id.cu_model = dev->vdev->device_id;
611

    
612
    /* Only the first 32 feature bits are used. */
613
    dev->host_features[0] = virtio_bus_get_vdev_features(&dev->bus,
614
                                                         dev->host_features[0]);
615

    
616
    dev->host_features[0] |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
617
    dev->host_features[0] |= 0x1 << VIRTIO_F_BAD_FEATURE;
618

    
619
    css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
620
                          parent->hotplugged, 1);
621
    return 0;
622

    
623
out_err:
624
    dev->sch = NULL;
625
    g_free(sch);
626
    return ret;
627
}
628

    
629
static int virtio_ccw_exit(VirtioCcwDevice *dev)
630
{
631
    SubchDev *sch = dev->sch;
632

    
633
    virtio_ccw_stop_ioeventfd(dev);
634
    if (sch) {
635
        css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
636
        g_free(sch);
637
    }
638
    dev->indicators = 0;
639
    return 0;
640
}
641

    
642
static int virtio_ccw_net_init(VirtioCcwDevice *ccw_dev)
643
{
644
    DeviceState *qdev = DEVICE(ccw_dev);
645
    VirtIONetCcw *dev = VIRTIO_NET_CCW(ccw_dev);
646
    DeviceState *vdev = DEVICE(&dev->vdev);
647

    
648
    virtio_net_set_config_size(&dev->vdev, ccw_dev->host_features[0]);
649
    virtio_net_set_netclient_name(&dev->vdev, qdev->id,
650
                                  object_get_typename(OBJECT(qdev)));
651
    qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
652
    if (qdev_init(vdev) < 0) {
653
        return -1;
654
    }
655

    
656
    return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
657
}
658

    
659
static void virtio_ccw_net_instance_init(Object *obj)
660
{
661
    VirtIONetCcw *dev = VIRTIO_NET_CCW(obj);
662
    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_NET);
663
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
664
}
665

    
666
static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
667
{
668
    VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(ccw_dev);
669
    DeviceState *vdev = DEVICE(&dev->vdev);
670
    virtio_blk_set_conf(vdev, &(dev->blk));
671
    qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
672
    if (qdev_init(vdev) < 0) {
673
        return -1;
674
    }
675

    
676
    return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
677
}
678

    
679
static void virtio_ccw_blk_instance_init(Object *obj)
680
{
681
    VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(obj);
682
    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BLK);
683
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
684
}
685

    
686
static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev)
687
{
688
    VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(ccw_dev);
689
    DeviceState *vdev = DEVICE(&dev->vdev);
690
    DeviceState *proxy = DEVICE(ccw_dev);
691
    char *bus_name;
692

    
693
    /*
694
     * For command line compatibility, this sets the virtio-serial-device bus
695
     * name as before.
696
     */
697
    if (proxy->id) {
698
        bus_name = g_strdup_printf("%s.0", proxy->id);
699
        virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name);
700
        g_free(bus_name);
701
    }
702

    
703
    qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
704
    if (qdev_init(vdev) < 0) {
705
        return -1;
706
    }
707

    
708
    return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
709
}
710

    
711

    
712
static void virtio_ccw_serial_instance_init(Object *obj)
713
{
714
    VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(obj);
715
    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SERIAL);
716
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
717
}
718

    
719
static int virtio_ccw_balloon_init(VirtioCcwDevice *ccw_dev)
720
{
721
    VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(ccw_dev);
722
    DeviceState *vdev = DEVICE(&dev->vdev);
723

    
724
    qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
725
    if (qdev_init(vdev) < 0) {
726
        return -1;
727
    }
728

    
729
    return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
730
}
731

    
732
static void balloon_ccw_stats_get_all(Object *obj, struct Visitor *v,
733
                                      void *opaque, const char *name,
734
                                      Error **errp)
735
{
736
    VirtIOBalloonCcw *dev = opaque;
737
    object_property_get(OBJECT(&dev->vdev), v, "guest-stats", errp);
738
}
739

    
740
static void balloon_ccw_stats_get_poll_interval(Object *obj, struct Visitor *v,
741
                                                void *opaque, const char *name,
742
                                                Error **errp)
743
{
744
    VirtIOBalloonCcw *dev = opaque;
745
    object_property_get(OBJECT(&dev->vdev), v, "guest-stats-polling-interval",
746
                        errp);
747
}
748

    
749
static void balloon_ccw_stats_set_poll_interval(Object *obj, struct Visitor *v,
750
                                                void *opaque, const char *name,
751
                                                Error **errp)
752
{
753
    VirtIOBalloonCcw *dev = opaque;
754
    object_property_set(OBJECT(&dev->vdev), v, "guest-stats-polling-interval",
755
                        errp);
756
}
757

    
758
static void virtio_ccw_balloon_instance_init(Object *obj)
759
{
760
    VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj);
761
    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BALLOON);
762
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
763

    
764
    object_property_add(obj, "guest-stats", "guest statistics",
765
                        balloon_ccw_stats_get_all, NULL, NULL, dev, NULL);
766

    
767
    object_property_add(obj, "guest-stats-polling-interval", "int",
768
                        balloon_ccw_stats_get_poll_interval,
769
                        balloon_ccw_stats_set_poll_interval,
770
                        NULL, dev, NULL);
771
}
772

    
773
static int virtio_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
774
{
775
    VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(ccw_dev);
776
    DeviceState *vdev = DEVICE(&dev->vdev);
777
    DeviceState *qdev = DEVICE(ccw_dev);
778
    char *bus_name;
779

    
780
    /*
781
     * For command line compatibility, this sets the virtio-scsi-device bus
782
     * name as before.
783
     */
784
    if (qdev->id) {
785
        bus_name = g_strdup_printf("%s.0", qdev->id);
786
        virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name);
787
        g_free(bus_name);
788
    }
789

    
790
    qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
791
    if (qdev_init(vdev) < 0) {
792
        return -1;
793
    }
794

    
795
    return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
796
}
797

    
798
static void virtio_ccw_scsi_instance_init(Object *obj)
799
{
800
    VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(obj);
801
    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SCSI);
802
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
803
}
804

    
805
#ifdef CONFIG_VHOST_SCSI
806
static int vhost_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
807
{
808
    VHostSCSICcw *dev = VHOST_SCSI_CCW(ccw_dev);
809
    DeviceState *vdev = DEVICE(&dev->vdev);
810

    
811
    qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
812
    if (qdev_init(vdev) < 0) {
813
        return -1;
814
    }
815

    
816
    return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
817
}
818

    
819
static void vhost_ccw_scsi_instance_init(Object *obj)
820
{
821
    VHostSCSICcw *dev = VHOST_SCSI_CCW(obj);
822
    object_initialize(OBJECT(&dev->vdev), TYPE_VHOST_SCSI);
823
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
824
}
825
#endif
826

    
827
static int virtio_ccw_rng_init(VirtioCcwDevice *ccw_dev)
828
{
829
    VirtIORNGCcw *dev = VIRTIO_RNG_CCW(ccw_dev);
830
    DeviceState *vdev = DEVICE(&dev->vdev);
831

    
832
    qdev_set_parent_bus(vdev, BUS(&ccw_dev->bus));
833
    if (qdev_init(vdev) < 0) {
834
        return -1;
835
    }
836

    
837
    object_property_set_link(OBJECT(dev),
838
                             OBJECT(dev->vdev.conf.rng), "rng",
839
                             NULL);
840

    
841
    return virtio_ccw_device_init(ccw_dev, VIRTIO_DEVICE(vdev));
842
}
843

    
844
/* DeviceState to VirtioCcwDevice. Note: used on datapath,
845
 * be careful and test performance if you change this.
846
 */
847
static inline VirtioCcwDevice *to_virtio_ccw_dev_fast(DeviceState *d)
848
{
849
    return container_of(d, VirtioCcwDevice, parent_obj);
850
}
851

    
852
static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
853
{
854
    VirtioCcwDevice *dev = to_virtio_ccw_dev_fast(d);
855
    SubchDev *sch = dev->sch;
856
    uint64_t indicators;
857

    
858
    if (vector >= 128) {
859
        return;
860
    }
861

    
862
    if (vector < VIRTIO_PCI_QUEUE_MAX) {
863
        if (!dev->indicators) {
864
            return;
865
        }
866
        indicators = ldq_phys(dev->indicators);
867
        indicators |= 1ULL << vector;
868
        stq_phys(dev->indicators, indicators);
869
    } else {
870
        if (!dev->indicators2) {
871
            return;
872
        }
873
        vector = 0;
874
        indicators = ldq_phys(dev->indicators2);
875
        indicators |= 1ULL << vector;
876
        stq_phys(dev->indicators2, indicators);
877
    }
878

    
879
    css_conditional_io_interrupt(sch);
880

    
881
}
882

    
883
static unsigned virtio_ccw_get_features(DeviceState *d)
884
{
885
    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
886

    
887
    /* Only the first 32 feature bits are used. */
888
    return dev->host_features[0];
889
}
890

    
891
static void virtio_ccw_reset(DeviceState *d)
892
{
893
    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
894

    
895
    virtio_ccw_stop_ioeventfd(dev);
896
    virtio_reset(dev->vdev);
897
    css_reset_sch(dev->sch);
898
    dev->indicators = 0;
899
    dev->indicators2 = 0;
900
}
901

    
902
static void virtio_ccw_vmstate_change(DeviceState *d, bool running)
903
{
904
    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
905

    
906
    if (running) {
907
        virtio_ccw_start_ioeventfd(dev);
908
    } else {
909
        virtio_ccw_stop_ioeventfd(dev);
910
    }
911
}
912

    
913
static bool virtio_ccw_query_guest_notifiers(DeviceState *d)
914
{
915
    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
916

    
917
    return !!(dev->sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA);
918
}
919

    
920
static int virtio_ccw_set_host_notifier(DeviceState *d, int n, bool assign)
921
{
922
    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
923

    
924
    /* Stop using the generic ioeventfd, we are doing eventfd handling
925
     * ourselves below */
926
    dev->ioeventfd_disabled = assign;
927
    if (assign) {
928
        virtio_ccw_stop_ioeventfd(dev);
929
    }
930
    return virtio_ccw_set_guest2host_notifier(dev, n, assign, false);
931
}
932

    
933
static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n,
934
                                         bool assign, bool with_irqfd)
935
{
936
    VirtQueue *vq = virtio_get_queue(dev->vdev, n);
937
    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
938
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(dev->vdev);
939

    
940
    if (assign) {
941
        int r = event_notifier_init(notifier, 0);
942

    
943
        if (r < 0) {
944
            return r;
945
        }
946
        virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd);
947
        /* We do not support irqfd for classic I/O interrupts, because the
948
         * classic interrupts are intermixed with the subchannel status, that
949
         * is queried with test subchannel. We want to use vhost, though.
950
         * Lets make sure to have vhost running and wire up the irq fd to
951
         * land in qemu (and only the irq fd) in this code.
952
         */
953
        if (k->guest_notifier_mask) {
954
            k->guest_notifier_mask(dev->vdev, n, false);
955
        }
956
        /* get lost events and re-inject */
957
        if (k->guest_notifier_pending &&
958
            k->guest_notifier_pending(dev->vdev, n)) {
959
            event_notifier_set(notifier);
960
        }
961
    } else {
962
        if (k->guest_notifier_mask) {
963
            k->guest_notifier_mask(dev->vdev, n, true);
964
        }
965
        virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd);
966
        event_notifier_cleanup(notifier);
967
    }
968
    return 0;
969
}
970

    
971
static int virtio_ccw_set_guest_notifiers(DeviceState *d, int nvqs,
972
                                          bool assigned)
973
{
974
    VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
975
    VirtIODevice *vdev = dev->vdev;
976
    int r, n;
977

    
978
    for (n = 0; n < nvqs; n++) {
979
        if (!virtio_queue_get_num(vdev, n)) {
980
            break;
981
        }
982
        /* false -> true, as soon as irqfd works */
983
        r = virtio_ccw_set_guest_notifier(dev, n, assigned, false);
984
        if (r < 0) {
985
            goto assign_error;
986
        }
987
    }
988
    return 0;
989

    
990
assign_error:
991
    while (--n >= 0) {
992
        virtio_ccw_set_guest_notifier(dev, n, !assigned, false);
993
    }
994
    return r;
995
}
996

    
997
/**************** Virtio-ccw Bus Device Descriptions *******************/
998

    
999
static Property virtio_ccw_net_properties[] = {
1000
    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
1001
    DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features[0]),
1002
    DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetCcw, vdev.net_conf),
1003
    DEFINE_NIC_PROPERTIES(VirtIONetCcw, vdev.nic_conf),
1004
    DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
1005
                    VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
1006
    DEFINE_PROP_END_OF_LIST(),
1007
};
1008

    
1009
static void virtio_ccw_net_class_init(ObjectClass *klass, void *data)
1010
{
1011
    DeviceClass *dc = DEVICE_CLASS(klass);
1012
    VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
1013

    
1014
    k->init = virtio_ccw_net_init;
1015
    k->exit = virtio_ccw_exit;
1016
    dc->reset = virtio_ccw_reset;
1017
    dc->props = virtio_ccw_net_properties;
1018
}
1019

    
1020
static const TypeInfo virtio_ccw_net = {
1021
    .name          = TYPE_VIRTIO_NET_CCW,
1022
    .parent        = TYPE_VIRTIO_CCW_DEVICE,
1023
    .instance_size = sizeof(VirtIONetCcw),
1024
    .instance_init = virtio_ccw_net_instance_init,
1025
    .class_init    = virtio_ccw_net_class_init,
1026
};
1027

    
1028
static Property virtio_ccw_blk_properties[] = {
1029
    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
1030
    DEFINE_VIRTIO_BLK_FEATURES(VirtioCcwDevice, host_features[0]),
1031
    DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlkCcw, blk),
1032
    DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
1033
                    VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
1034
    DEFINE_PROP_END_OF_LIST(),
1035
};
1036

    
1037
static void virtio_ccw_blk_class_init(ObjectClass *klass, void *data)
1038
{
1039
    DeviceClass *dc = DEVICE_CLASS(klass);
1040
    VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
1041

    
1042
    k->init = virtio_ccw_blk_init;
1043
    k->exit = virtio_ccw_exit;
1044
    dc->reset = virtio_ccw_reset;
1045
    dc->props = virtio_ccw_blk_properties;
1046
}
1047

    
1048
static const TypeInfo virtio_ccw_blk = {
1049
    .name          = TYPE_VIRTIO_BLK_CCW,
1050
    .parent        = TYPE_VIRTIO_CCW_DEVICE,
1051
    .instance_size = sizeof(VirtIOBlkCcw),
1052
    .instance_init = virtio_ccw_blk_instance_init,
1053
    .class_init    = virtio_ccw_blk_class_init,
1054
};
1055

    
1056
static Property virtio_ccw_serial_properties[] = {
1057
    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
1058
    DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtioSerialCcw, vdev.serial),
1059
    DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
1060
    DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
1061
                    VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
1062
    DEFINE_PROP_END_OF_LIST(),
1063
};
1064

    
1065
static void virtio_ccw_serial_class_init(ObjectClass *klass, void *data)
1066
{
1067
    DeviceClass *dc = DEVICE_CLASS(klass);
1068
    VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
1069

    
1070
    k->init = virtio_ccw_serial_init;
1071
    k->exit = virtio_ccw_exit;
1072
    dc->reset = virtio_ccw_reset;
1073
    dc->props = virtio_ccw_serial_properties;
1074
}
1075

    
1076
static const TypeInfo virtio_ccw_serial = {
1077
    .name          = TYPE_VIRTIO_SERIAL_CCW,
1078
    .parent        = TYPE_VIRTIO_CCW_DEVICE,
1079
    .instance_size = sizeof(VirtioSerialCcw),
1080
    .instance_init = virtio_ccw_serial_instance_init,
1081
    .class_init    = virtio_ccw_serial_class_init,
1082
};
1083

    
1084
static Property virtio_ccw_balloon_properties[] = {
1085
    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
1086
    DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
1087
    DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
1088
                    VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
1089
    DEFINE_PROP_END_OF_LIST(),
1090
};
1091

    
1092
static void virtio_ccw_balloon_class_init(ObjectClass *klass, void *data)
1093
{
1094
    DeviceClass *dc = DEVICE_CLASS(klass);
1095
    VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
1096

    
1097
    k->init = virtio_ccw_balloon_init;
1098
    k->exit = virtio_ccw_exit;
1099
    dc->reset = virtio_ccw_reset;
1100
    dc->props = virtio_ccw_balloon_properties;
1101
}
1102

    
1103
static const TypeInfo virtio_ccw_balloon = {
1104
    .name          = TYPE_VIRTIO_BALLOON_CCW,
1105
    .parent        = TYPE_VIRTIO_CCW_DEVICE,
1106
    .instance_size = sizeof(VirtIOBalloonCcw),
1107
    .instance_init = virtio_ccw_balloon_instance_init,
1108
    .class_init    = virtio_ccw_balloon_class_init,
1109
};
1110

    
1111
static Property virtio_ccw_scsi_properties[] = {
1112
    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
1113
    DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
1114
    DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features[0]),
1115
    DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
1116
                    VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
1117
    DEFINE_PROP_END_OF_LIST(),
1118
};
1119

    
1120
static void virtio_ccw_scsi_class_init(ObjectClass *klass, void *data)
1121
{
1122
    DeviceClass *dc = DEVICE_CLASS(klass);
1123
    VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
1124

    
1125
    k->init = virtio_ccw_scsi_init;
1126
    k->exit = virtio_ccw_exit;
1127
    dc->reset = virtio_ccw_reset;
1128
    dc->props = virtio_ccw_scsi_properties;
1129
}
1130

    
1131
static const TypeInfo virtio_ccw_scsi = {
1132
    .name          = TYPE_VIRTIO_SCSI_CCW,
1133
    .parent        = TYPE_VIRTIO_CCW_DEVICE,
1134
    .instance_size = sizeof(VirtIOSCSICcw),
1135
    .instance_init = virtio_ccw_scsi_instance_init,
1136
    .class_init    = virtio_ccw_scsi_class_init,
1137
};
1138

    
1139
#ifdef CONFIG_VHOST_SCSI
1140
static Property vhost_ccw_scsi_properties[] = {
1141
    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
1142
    DEFINE_VHOST_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
1143
    DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
1144
    DEFINE_PROP_END_OF_LIST(),
1145
};
1146

    
1147
static void vhost_ccw_scsi_class_init(ObjectClass *klass, void *data)
1148
{
1149
    DeviceClass *dc = DEVICE_CLASS(klass);
1150
    VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
1151

    
1152
    k->init = vhost_ccw_scsi_init;
1153
    k->exit = virtio_ccw_exit;
1154
    dc->reset = virtio_ccw_reset;
1155
    dc->props = vhost_ccw_scsi_properties;
1156
}
1157

    
1158
static const TypeInfo vhost_ccw_scsi = {
1159
    .name          = TYPE_VHOST_SCSI_CCW,
1160
    .parent        = TYPE_VIRTIO_CCW_DEVICE,
1161
    .instance_size = sizeof(VirtIOSCSICcw),
1162
    .instance_init = vhost_ccw_scsi_instance_init,
1163
    .class_init    = vhost_ccw_scsi_class_init,
1164
};
1165
#endif
1166

    
1167
static void virtio_ccw_rng_instance_init(Object *obj)
1168
{
1169
    VirtIORNGCcw *dev = VIRTIO_RNG_CCW(obj);
1170
    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_RNG);
1171
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
1172
    object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
1173
                             (Object **)&dev->vdev.conf.rng, NULL);
1174
}
1175

    
1176
static Property virtio_ccw_rng_properties[] = {
1177
    DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
1178
    DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
1179
    DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGCcw, vdev.conf),
1180
    DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
1181
                    VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
1182
    DEFINE_PROP_END_OF_LIST(),
1183
};
1184

    
1185
static void virtio_ccw_rng_class_init(ObjectClass *klass, void *data)
1186
{
1187
    DeviceClass *dc = DEVICE_CLASS(klass);
1188
    VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
1189

    
1190
    k->init = virtio_ccw_rng_init;
1191
    k->exit = virtio_ccw_exit;
1192
    dc->reset = virtio_ccw_reset;
1193
    dc->props = virtio_ccw_rng_properties;
1194
}
1195

    
1196
static const TypeInfo virtio_ccw_rng = {
1197
    .name          = TYPE_VIRTIO_RNG_CCW,
1198
    .parent        = TYPE_VIRTIO_CCW_DEVICE,
1199
    .instance_size = sizeof(VirtIORNGCcw),
1200
    .instance_init = virtio_ccw_rng_instance_init,
1201
    .class_init    = virtio_ccw_rng_class_init,
1202
};
1203

    
1204
static int virtio_ccw_busdev_init(DeviceState *dev)
1205
{
1206
    VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
1207
    VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
1208

    
1209
    virtio_ccw_bus_new(&_dev->bus, _dev);
1210

    
1211
    return _info->init(_dev);
1212
}
1213

    
1214
static int virtio_ccw_busdev_exit(DeviceState *dev)
1215
{
1216
    VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
1217
    VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
1218

    
1219
    return _info->exit(_dev);
1220
}
1221

    
1222
static int virtio_ccw_busdev_unplug(DeviceState *dev)
1223
{
1224
    VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
1225
    SubchDev *sch = _dev->sch;
1226

    
1227
    /*
1228
     * We should arrive here only for device_del, since we don't support
1229
     * direct hot(un)plug of channels, but only through virtio.
1230
     */
1231
    assert(sch != NULL);
1232
    /* Subchannel is now disabled and no longer valid. */
1233
    sch->curr_status.pmcw.flags &= ~(PMCW_FLAGS_MASK_ENA |
1234
                                     PMCW_FLAGS_MASK_DNV);
1235

    
1236
    css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0);
1237

    
1238
    qdev_free(dev);
1239
    return 0;
1240
}
1241

    
1242
static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
1243
{
1244
    DeviceClass *dc = DEVICE_CLASS(klass);
1245

    
1246
    dc->init = virtio_ccw_busdev_init;
1247
    dc->exit = virtio_ccw_busdev_exit;
1248
    dc->unplug = virtio_ccw_busdev_unplug;
1249
    dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
1250

    
1251
}
1252

    
1253
static const TypeInfo virtio_ccw_device_info = {
1254
    .name = TYPE_VIRTIO_CCW_DEVICE,
1255
    .parent = TYPE_DEVICE,
1256
    .instance_size = sizeof(VirtioCcwDevice),
1257
    .class_init = virtio_ccw_device_class_init,
1258
    .class_size = sizeof(VirtIOCCWDeviceClass),
1259
    .abstract = true,
1260
};
1261

    
1262
/***************** Virtual-css Bus Bridge Device ********************/
1263
/* Only required to have the virtio bus as child in the system bus */
1264

    
1265
static int virtual_css_bridge_init(SysBusDevice *dev)
1266
{
1267
    /* nothing */
1268
    return 0;
1269
}
1270

    
1271
static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
1272
{
1273
    DeviceClass *dc = DEVICE_CLASS(klass);
1274
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1275

    
1276
    k->init = virtual_css_bridge_init;
1277
    dc->no_user = 1;
1278
}
1279

    
1280
static const TypeInfo virtual_css_bridge_info = {
1281
    .name          = "virtual-css-bridge",
1282
    .parent        = TYPE_SYS_BUS_DEVICE,
1283
    .instance_size = sizeof(SysBusDevice),
1284
    .class_init    = virtual_css_bridge_class_init,
1285
};
1286

    
1287
/* virtio-ccw-bus */
1288

    
1289
static void virtio_ccw_bus_new(VirtioBusState *bus, VirtioCcwDevice *dev)
1290
{
1291
    DeviceState *qdev = DEVICE(dev);
1292
    BusState *qbus;
1293
    char virtio_bus_name[] = "virtio-bus";
1294

    
1295
    qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_CCW_BUS, qdev,
1296
                        virtio_bus_name);
1297
    qbus = BUS(bus);
1298
    qbus->allow_hotplug = 1;
1299
}
1300

    
1301
static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data)
1302
{
1303
    VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
1304
    BusClass *bus_class = BUS_CLASS(klass);
1305

    
1306
    bus_class->max_dev = 1;
1307
    k->notify = virtio_ccw_notify;
1308
    k->get_features = virtio_ccw_get_features;
1309
    k->vmstate_change = virtio_ccw_vmstate_change;
1310
    k->query_guest_notifiers = virtio_ccw_query_guest_notifiers;
1311
    k->set_host_notifier = virtio_ccw_set_host_notifier;
1312
    k->set_guest_notifiers = virtio_ccw_set_guest_notifiers;
1313
}
1314

    
1315
static const TypeInfo virtio_ccw_bus_info = {
1316
    .name = TYPE_VIRTIO_CCW_BUS,
1317
    .parent = TYPE_VIRTIO_BUS,
1318
    .instance_size = sizeof(VirtioCcwBusState),
1319
    .class_init = virtio_ccw_bus_class_init,
1320
};
1321

    
1322
static void virtio_ccw_register(void)
1323
{
1324
    type_register_static(&virtio_ccw_bus_info);
1325
    type_register_static(&virtual_css_bus_info);
1326
    type_register_static(&virtio_ccw_device_info);
1327
    type_register_static(&virtio_ccw_serial);
1328
    type_register_static(&virtio_ccw_blk);
1329
    type_register_static(&virtio_ccw_net);
1330
    type_register_static(&virtio_ccw_balloon);
1331
    type_register_static(&virtio_ccw_scsi);
1332
#ifdef CONFIG_VHOST_SCSI
1333
    type_register_static(&vhost_ccw_scsi);
1334
#endif
1335
    type_register_static(&virtio_ccw_rng);
1336
    type_register_static(&virtual_css_bridge_info);
1337
}
1338

    
1339
type_init(virtio_ccw_register)