~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to .pc/virtio-rng-fix-crash/hw/s390x/virtio-ccw.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-10-22 22:47:07 UTC
  • mfrom: (1.8.3) (10.1.42 sid)
  • Revision ID: package-import@ubuntu.com-20131022224707-1lya34fw3k3f24tv
Tags: 1.6.0+dfsg-2ubuntu1
* Merge 1.6.0~rc0+dfsg-2exp from debian experimental.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
      - drop openbios-ppc and openhackware Depends to Suggests (for now)
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - New linaro patches from qemu-linaro rebasing branch
  - Dropped patches:
    * xen-simplify-xen_enabled.patch
    * sparc-linux-user-fix-missing-symbols-in-.rel-.rela.plt-sections.patch
    * main_loop-do-not-set-nonblocking-if-xen_enabled.patch
    * xen_machine_pv-do-not-create-a-dummy-CPU-in-machine-.patch
    * virtio-rng-fix-crash
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * linaro arm patches from qemu-linaro rebasing branch
  - New patches:
    * fix-pci-add: change CONFIG variable in ifdef to make sure that
      pci_add is defined.
* Add linaro patches
* Add experimental mach-virt patches for arm virtualization.
* qemu-system-common.install: add debian/tmp/usr/lib to install the
  qemu-bridge-helper

Show diffs side-by-side

added added

removed removed

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