From b804e8a62a25b82637b19aea68ab7d5a7a1ce0fb Mon Sep 17 00:00:00 2001 From: Jing Liu Date: Fri, 26 Feb 2016 06:46:12 +0100 Subject: 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 Reviewed-by: Sascha Silbe Reviewed-by: Dong Jia Shi Reviewed-by: Yi Min Zhao Signed-off-by: Cornelia Huck --- hw/s390x/css-bridge.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'hw/s390x/css-bridge.c') diff --git a/hw/s390x/css-bridge.c b/hw/s390x/css-bridge.c index e74cc1cfda..e4c24e21f3 100644 --- a/hw/s390x/css-bridge.c +++ b/hw/s390x/css-bridge.c @@ -11,13 +11,48 @@ */ #include "qemu/osdep.h" #include "qapi/error.h" -#include "virtio-ccw.h" #include "hw/hotplug.h" #include "hw/sysbus.h" #include "qemu/bitops.h" #include "hw/s390x/css.h" +#include "ccw-device.h" #include "hw/s390x/css-bridge.h" +/* + * Invoke device-specific unplug handler, disable the subchannel + * (including sending a channel report to the guest) and remove the + * device from the virtual css bus. + */ +static void ccw_device_unplug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + CcwDevice *ccw_dev = CCW_DEVICE(dev); + CCWDeviceClass *k = CCW_DEVICE_GET_CLASS(ccw_dev); + SubchDev *sch = ccw_dev->sch; + Error *err = NULL; + + if (k->unplug) { + k->unplug(hotplug_dev, dev, &err); + if (err) { + error_propagate(errp, err); + return; + } + } + + /* + * We should arrive here only for device_del, since we don't support + * direct hot(un)plug of channels. + */ + 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 virtual_css_bus_reset(BusState *qbus) { /* This should actually be modelled via the generic css */ @@ -65,7 +100,7 @@ static void virtual_css_bridge_class_init(ObjectClass *klass, void *data) HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - hc->unplug = virtio_ccw_busdev_unplug; + hc->unplug = ccw_device_unplug; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } -- cgit 1.4.1