summary refs log tree commit diff stats
path: root/hw/s390x/css-bridge.c
diff options
context:
space:
mode:
authorJing Liu <liujbjl@linux.vnet.ibm.com>2016-02-26 06:46:12 +0100
committerCornelia Huck <cornelia.huck@de.ibm.com>2016-07-11 09:48:05 +0200
commitb804e8a62a25b82637b19aea68ab7d5a7a1ce0fb (patch)
tree78ef1b18e392672c49478f47480edae0513a16a7 /hw/s390x/css-bridge.c
parentdd70bd0d4cf2e10b0437fc75da50423612871101 (diff)
downloadfocaccia-qemu-b804e8a62a25b82637b19aea68ab7d5a7a1ce0fb.tar.gz
focaccia-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/css-bridge.c')
-rw-r--r--hw/s390x/css-bridge.c39
1 files changed, 37 insertions, 2 deletions
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);
 }