diff options
author | Jing Liu <liujbjl@linux.vnet.ibm.com> | 2016-02-26 06:46:12 +0100 |
---|---|---|
committer | Cornelia Huck <cornelia.huck@de.ibm.com> | 2016-07-11 09:48:05 +0200 |
commit | b804e8a62a25b82637b19aea68ab7d5a7a1ce0fb (patch) | |
tree | 78ef1b18e392672c49478f47480edae0513a16a7 /hw/s390x/virtio-ccw.c | |
parent | dd70bd0d4cf2e10b0437fc75da50423612871101 (diff) | |
download | qemu-b804e8a62a25b82637b19aea68ab7d5a7a1ce0fb.tar.gz qemu-b804e8a62a25b82637b19aea68ab7d5a7a1ce0fb.tar.bz2 qemu-b804e8a62a25b82637b19aea68ab7d5a7a1ce0fb.zip |
s390x/css: Unplug handler of virtual css bridge
The previous patch moved virtual css bridge and bus out from
virtio-ccw, but kept the direct reference of virtio-ccw specific
unplug function inside css-bridge.c.
To make the virtual css bus and bridge useful for non-virtio devices,
this introduces a common unplug function pointer "unplug" to call
specific virtio-ccw unplug parts. Thus, the tight coupling to
virtio-ccw can be removed.
This unplug pointer is a member of CCWDeviceClass, which is introduced
as an abstract device layer called "ccw-device". This layer is between
DeviceState and specific devices which are plugged in virtual css bus,
like virtio-ccw device. The specific unplug handlers should be assigned
to "unplug" during initialization.
Signed-off-by: Jing Liu <liujbjl@linux.vnet.ibm.com>
Reviewed-by: Sascha Silbe <silbe@linux.vnet.ibm.com>
Reviewed-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
Reviewed-by: Yi Min Zhao <zyimin@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'hw/s390x/virtio-ccw.c')
-rw-r--r-- | hw/s390x/virtio-ccw.c | 86 |
1 files changed, 44 insertions, 42 deletions
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 8f1a0e824f..a554a24d06 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -97,7 +97,8 @@ static int virtio_ccw_ioeventfd_assign(DeviceState *d, EventNotifier *notifier, int n, bool assign) { VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); - SubchDev *sch = dev->sch; + CcwDevice *ccw_dev = CCW_DEVICE(dev); + SubchDev *sch = ccw_dev->sch; uint32_t sch_id = (css_build_subchannel_id(sch) << 16) | sch->schid; return s390_assign_subch_ioeventfd(notifier, sch_id, n, assign); @@ -194,6 +195,8 @@ static int virtio_ccw_set_vqs(SubchDev *sch, VqInfoBlock *info, static void virtio_ccw_reset_virtio(VirtioCcwDevice *dev, VirtIODevice *vdev) { + CcwDevice *ccw_dev = CCW_DEVICE(dev); + virtio_ccw_stop_ioeventfd(dev); virtio_reset(vdev); if (dev->indicators) { @@ -208,7 +211,7 @@ static void virtio_ccw_reset_virtio(VirtioCcwDevice *dev, VirtIODevice *vdev) release_indicator(&dev->routes.adapter, dev->summary_indicator); dev->summary_indicator = NULL; } - dev->sch->thinint_active = false; + ccw_dev->sch->thinint_active = false; } static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len, @@ -664,7 +667,8 @@ static void virtio_sch_disable_cb(SubchDev *sch) static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp) { VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_GET_CLASS(dev); - SubchDev *sch = css_create_virtual_sch(dev->bus_id, errp); + CcwDevice *ccw_dev = CCW_DEVICE(dev); + SubchDev *sch = css_create_virtual_sch(ccw_dev->bus_id, errp); Error *err = NULL; if (!sch) { @@ -676,14 +680,14 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp) sch->disable_cb = virtio_sch_disable_cb; sch->id.reserved = 0xff; sch->id.cu_type = VIRTIO_CCW_CU_TYPE; - dev->sch = sch; + ccw_dev->sch = sch; dev->indicators = NULL; dev->revision = -1; css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE); trace_virtio_ccw_new_device( sch->cssid, sch->ssid, sch->schid, sch->devno, - dev->bus_id.valid ? "user-configured" : "auto-configured"); + ccw_dev->bus_id.valid ? "user-configured" : "auto-configured"); if (k->realize) { k->realize(dev, &err); @@ -691,14 +695,15 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp) if (err) { error_propagate(errp, err); css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL); - dev->sch = NULL; + ccw_dev->sch = NULL; g_free(sch); } } static int virtio_ccw_exit(VirtioCcwDevice *dev) { - SubchDev *sch = dev->sch; + CcwDevice *ccw_dev = CCW_DEVICE(dev); + SubchDev *sch = ccw_dev->sch; if (sch) { css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL); @@ -879,7 +884,9 @@ static void virtio_ccw_rng_realize(VirtioCcwDevice *ccw_dev, Error **errp) */ static inline VirtioCcwDevice *to_virtio_ccw_dev_fast(DeviceState *d) { - return container_of(d, VirtioCcwDevice, parent_obj); + CcwDevice *ccw_dev = to_ccw_dev_fast(d); + + return container_of(ccw_dev, VirtioCcwDevice, parent_obj); } static uint8_t virtio_set_ind_atomic(SubchDev *sch, uint64_t ind_loc, @@ -908,7 +915,8 @@ static uint8_t virtio_set_ind_atomic(SubchDev *sch, uint64_t ind_loc, static void virtio_ccw_notify(DeviceState *d, uint16_t vector) { VirtioCcwDevice *dev = to_virtio_ccw_dev_fast(d); - SubchDev *sch = dev->sch; + CcwDevice *ccw_dev = to_ccw_dev_fast(d); + SubchDev *sch = ccw_dev->sch; uint64_t indicators; /* queue indicators + secondary indicators */ @@ -966,9 +974,10 @@ static void virtio_ccw_reset(DeviceState *d) { VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); + CcwDevice *ccw_dev = CCW_DEVICE(d); virtio_ccw_reset_virtio(dev, vdev); - css_reset_sch(dev->sch); + css_reset_sch(ccw_dev->sch); } static void virtio_ccw_vmstate_change(DeviceState *d, bool running) @@ -984,7 +993,7 @@ static void virtio_ccw_vmstate_change(DeviceState *d, bool running) static bool virtio_ccw_query_guest_notifiers(DeviceState *d) { - VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); + CcwDevice *dev = CCW_DEVICE(d); return !!(dev->sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA); } @@ -992,8 +1001,9 @@ static bool virtio_ccw_query_guest_notifiers(DeviceState *d) static int virtio_ccw_get_mappings(VirtioCcwDevice *dev) { int r; + CcwDevice *ccw_dev = CCW_DEVICE(dev); - if (!dev->sch->thinint_active) { + if (!ccw_dev->sch->thinint_active) { return -EINVAL; } @@ -1115,7 +1125,8 @@ static int virtio_ccw_set_guest_notifiers(DeviceState *d, int nvqs, { VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); - bool with_irqfd = dev->sch->thinint_active && kvm_irqfds_enabled(); + CcwDevice *ccw_dev = CCW_DEVICE(d); + bool with_irqfd = ccw_dev->sch->thinint_active && kvm_irqfds_enabled(); int r, n; if (with_irqfd && assigned) { @@ -1174,7 +1185,8 @@ static int virtio_ccw_load_queue(DeviceState *d, int n, QEMUFile *f) static void virtio_ccw_save_config(DeviceState *d, QEMUFile *f) { VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); - SubchDev *s = dev->sch; + CcwDevice *ccw_dev = CCW_DEVICE(d); + SubchDev *s = ccw_dev->sch; VirtIODevice *vdev = virtio_ccw_get_vdev(s); subch_device_save(s, f); @@ -1208,7 +1220,8 @@ static void virtio_ccw_save_config(DeviceState *d, QEMUFile *f) static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f) { VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); - SubchDev *s = dev->sch; + CcwDevice *ccw_dev = CCW_DEVICE(d); + SubchDev *s = ccw_dev->sch; VirtIODevice *vdev = virtio_ccw_get_vdev(s); int len; @@ -1253,7 +1266,8 @@ static void virtio_ccw_device_plugged(DeviceState *d, Error **errp) { VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d); VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); - SubchDev *sch = dev->sch; + CcwDevice *ccw_dev = CCW_DEVICE(d); + SubchDev *sch = ccw_dev->sch; int n = virtio_get_num_queues(vdev); if (virtio_get_num_queues(vdev) > VIRTIO_CCW_QUEUE_MAX) { @@ -1297,7 +1311,7 @@ static void virtio_ccw_device_unplugged(DeviceState *d) /**************** Virtio-ccw Bus Device Descriptions *******************/ static Property virtio_ccw_net_properties[] = { - DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id), + DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id), DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, @@ -1326,7 +1340,7 @@ static const TypeInfo virtio_ccw_net = { }; static Property virtio_ccw_blk_properties[] = { - DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id), + DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id), DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, @@ -1355,7 +1369,7 @@ static const TypeInfo virtio_ccw_blk = { }; static Property virtio_ccw_serial_properties[] = { - DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id), + DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id), DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, @@ -1384,7 +1398,7 @@ static const TypeInfo virtio_ccw_serial = { }; static Property virtio_ccw_balloon_properties[] = { - DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id), + DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id), DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, @@ -1413,7 +1427,7 @@ static const TypeInfo virtio_ccw_balloon = { }; static Property virtio_ccw_scsi_properties[] = { - DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id), + DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id), DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, @@ -1443,7 +1457,7 @@ static const TypeInfo virtio_ccw_scsi = { #ifdef CONFIG_VHOST_SCSI static Property vhost_ccw_scsi_properties[] = { - DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id), + DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id), DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, VIRTIO_CCW_MAX_REV), DEFINE_PROP_END_OF_LIST(), @@ -1481,7 +1495,7 @@ static void virtio_ccw_rng_instance_init(Object *obj) } static Property virtio_ccw_rng_properties[] = { - DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id), + DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id), DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, @@ -1525,32 +1539,20 @@ static int virtio_ccw_busdev_exit(DeviceState *dev) return _info->exit(_dev); } -void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) +static void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) { - VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev; - SubchDev *sch = _dev->sch; + VirtioCcwDevice *_dev = to_virtio_ccw_dev_fast(dev); virtio_ccw_stop_ioeventfd(_dev); - - /* - * We should arrive here only for device_del, since we don't support - * direct hot(un)plug of channels, but only through virtio. - */ - assert(sch != NULL); - /* Subchannel is now disabled and no longer valid. */ - sch->curr_status.pmcw.flags &= ~(PMCW_FLAGS_MASK_ENA | - PMCW_FLAGS_MASK_DNV); - - css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0); - - object_unparent(OBJECT(dev)); } static void virtio_ccw_device_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + CCWDeviceClass *k = CCW_DEVICE_CLASS(dc); + k->unplug = virtio_ccw_busdev_unplug; dc->realize = virtio_ccw_busdev_realize; dc->exit = virtio_ccw_busdev_exit; dc->bus_type = TYPE_VIRTUAL_CSS_BUS; @@ -1558,7 +1560,7 @@ static void virtio_ccw_device_class_init(ObjectClass *klass, void *data) static const TypeInfo virtio_ccw_device_info = { .name = TYPE_VIRTIO_CCW_DEVICE, - .parent = TYPE_DEVICE, + .parent = TYPE_CCW_DEVICE, .instance_size = sizeof(VirtioCcwDevice), .class_init = virtio_ccw_device_class_init, .class_size = sizeof(VirtIOCCWDeviceClass), @@ -1610,7 +1612,7 @@ static const TypeInfo virtio_ccw_bus_info = { #ifdef CONFIG_VIRTFS static Property virtio_ccw_9p_properties[] = { - DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, bus_id), + DEFINE_PROP_CSS_DEV_ID("devno", VirtioCcwDevice, parent_obj.bus_id), DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags, VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_UINT32("max_revision", VirtioCcwDevice, max_rev, |