2 * css bridge implementation
4 * Copyright 2012,2016 IBM Corp.
5 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
6 * Pierre Morel <pmorel@linux.vnet.ibm.com>
8 * This work is licensed under the terms of the GNU GPL, version 2 or (at
9 * your option) any later version. See the COPYING file in the top-level
12 #include "qemu/osdep.h"
13 #include "qapi/error.h"
14 #include "hw/hotplug.h"
15 #include "hw/sysbus.h"
16 #include "qemu/bitops.h"
17 #include "hw/s390x/css.h"
18 #include "ccw-device.h"
19 #include "hw/s390x/css-bridge.h"
22 * Invoke device-specific unplug handler, disable the subchannel
23 * (including sending a channel report to the guest) and remove the
24 * device from the virtual css bus.
26 static void ccw_device_unplug(HotplugHandler
*hotplug_dev
,
27 DeviceState
*dev
, Error
**errp
)
29 CcwDevice
*ccw_dev
= CCW_DEVICE(dev
);
30 CCWDeviceClass
*k
= CCW_DEVICE_GET_CLASS(ccw_dev
);
31 SubchDev
*sch
= ccw_dev
->sch
;
35 k
->unplug(hotplug_dev
, dev
, &err
);
37 error_propagate(errp
, err
);
43 * We should arrive here only for device_del, since we don't support
44 * direct hot(un)plug of channels.
47 /* Subchannel is now disabled and no longer valid. */
48 sch
->curr_status
.pmcw
.flags
&= ~(PMCW_FLAGS_MASK_ENA
|
51 css_generate_sch_crws(sch
->cssid
, sch
->ssid
, sch
->schid
, 1, 0);
53 object_unparent(OBJECT(dev
));
56 static void virtual_css_bus_reset(BusState
*qbus
)
58 /* This should actually be modelled via the generic css */
62 static char *virtual_css_bus_get_dev_path(DeviceState
*dev
)
64 CcwDevice
*ccw_dev
= CCW_DEVICE(dev
);
65 SubchDev
*sch
= ccw_dev
->sch
;
66 VirtualCssBridge
*bridge
=
67 VIRTUAL_CSS_BRIDGE(qdev_get_parent_bus(dev
)->parent
);
70 * We can't provide a dev path for backward compatibility on
71 * older machines, as it is visible in the migration stream.
73 return bridge
->css_dev_path
?
74 g_strdup_printf("/%02x.%1x.%04x", sch
->cssid
, sch
->ssid
, sch
->devno
) :
78 static void virtual_css_bus_class_init(ObjectClass
*klass
, void *data
)
80 BusClass
*k
= BUS_CLASS(klass
);
82 k
->reset
= virtual_css_bus_reset
;
83 k
->get_dev_path
= virtual_css_bus_get_dev_path
;
86 static const TypeInfo virtual_css_bus_info
= {
87 .name
= TYPE_VIRTUAL_CSS_BUS
,
89 .instance_size
= sizeof(VirtualCssBus
),
90 .class_init
= virtual_css_bus_class_init
,
93 VirtualCssBus
*virtual_css_bus_init(void)
99 /* Create bridge device */
100 dev
= qdev_create(NULL
, TYPE_VIRTUAL_CSS_BRIDGE
);
101 qdev_init_nofail(dev
);
103 /* Create bus on bridge device */
104 bus
= qbus_create(TYPE_VIRTUAL_CSS_BUS
, dev
, "virtual-css");
105 cbus
= VIRTUAL_CSS_BUS(bus
);
107 /* Enable hotplugging */
108 qbus_set_hotplug_handler(bus
, dev
, &error_abort
);
113 /***************** Virtual-css Bus Bridge Device ********************/
115 static Property virtual_css_bridge_properties
[] = {
116 DEFINE_PROP_BOOL("css_dev_path", VirtualCssBridge
, css_dev_path
,
118 DEFINE_PROP_END_OF_LIST(),
121 static void virtual_css_bridge_class_init(ObjectClass
*klass
, void *data
)
123 HotplugHandlerClass
*hc
= HOTPLUG_HANDLER_CLASS(klass
);
124 DeviceClass
*dc
= DEVICE_CLASS(klass
);
126 hc
->unplug
= ccw_device_unplug
;
127 set_bit(DEVICE_CATEGORY_BRIDGE
, dc
->categories
);
128 dc
->props
= virtual_css_bridge_properties
;
131 static const TypeInfo virtual_css_bridge_info
= {
132 .name
= TYPE_VIRTUAL_CSS_BRIDGE
,
133 .parent
= TYPE_SYS_BUS_DEVICE
,
134 .instance_size
= sizeof(VirtualCssBridge
),
135 .class_init
= virtual_css_bridge_class_init
,
136 .interfaces
= (InterfaceInfo
[]) {
137 { TYPE_HOTPLUG_HANDLER
},
142 static void virtual_css_register(void)
144 type_register_static(&virtual_css_bridge_info
);
145 type_register_static(&virtual_css_bus_info
);
148 type_init(virtual_css_register
)