108f7bba15
This patch adds the basic boilerplate for a 'XenBus' object that will act as a parent to 'XenDevice' PV backends. A new 'XenBridge' object is also added to connect XenBus to the system bus. The XenBus object is instantiated by a new xen_bus_init() function called from the same sites as the legacy xen_be_init() function. Subsequent patches will flesh-out the functionality of these objects. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> Reviewed-by: Anthony Perard <anthony.perard@citrix.com> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
128 lines
3.1 KiB
C
128 lines
3.1 KiB
C
/*
|
|
* Copyright (c) 2018 Citrix Systems Inc.
|
|
*
|
|
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
* See the COPYING file in the top-level directory.
|
|
*/
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "hw/hw.h"
|
|
#include "hw/sysbus.h"
|
|
#include "hw/xen/xen-bus.h"
|
|
#include "qapi/error.h"
|
|
#include "trace.h"
|
|
|
|
static void xen_bus_unrealize(BusState *bus, Error **errp)
|
|
{
|
|
trace_xen_bus_unrealize();
|
|
}
|
|
|
|
static void xen_bus_realize(BusState *bus, Error **errp)
|
|
{
|
|
trace_xen_bus_realize();
|
|
}
|
|
|
|
static void xen_bus_class_init(ObjectClass *class, void *data)
|
|
{
|
|
BusClass *bus_class = BUS_CLASS(class);
|
|
|
|
bus_class->realize = xen_bus_realize;
|
|
bus_class->unrealize = xen_bus_unrealize;
|
|
}
|
|
|
|
static const TypeInfo xen_bus_type_info = {
|
|
.name = TYPE_XEN_BUS,
|
|
.parent = TYPE_BUS,
|
|
.instance_size = sizeof(XenBus),
|
|
.class_size = sizeof(XenBusClass),
|
|
.class_init = xen_bus_class_init,
|
|
.interfaces = (InterfaceInfo[]) {
|
|
{ TYPE_HOTPLUG_HANDLER },
|
|
{ }
|
|
},
|
|
};
|
|
|
|
static void xen_device_unrealize(DeviceState *dev, Error **errp)
|
|
{
|
|
XenDevice *xendev = XEN_DEVICE(dev);
|
|
XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
|
|
const char *type = object_get_typename(OBJECT(xendev));
|
|
|
|
trace_xen_device_unrealize(type);
|
|
|
|
if (xendev_class->unrealize) {
|
|
xendev_class->unrealize(xendev, errp);
|
|
}
|
|
}
|
|
|
|
static void xen_device_realize(DeviceState *dev, Error **errp)
|
|
{
|
|
XenDevice *xendev = XEN_DEVICE(dev);
|
|
XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
|
|
const char *type = object_get_typename(OBJECT(xendev));
|
|
Error *local_err = NULL;
|
|
|
|
trace_xen_device_realize(type);
|
|
|
|
if (xendev_class->realize) {
|
|
xendev_class->realize(xendev, &local_err);
|
|
if (local_err) {
|
|
error_propagate(errp, local_err);
|
|
goto unrealize;
|
|
}
|
|
}
|
|
|
|
return;
|
|
|
|
unrealize:
|
|
xen_device_unrealize(dev, &error_abort);
|
|
}
|
|
|
|
static void xen_device_class_init(ObjectClass *class, void *data)
|
|
{
|
|
DeviceClass *dev_class = DEVICE_CLASS(class);
|
|
|
|
dev_class->realize = xen_device_realize;
|
|
dev_class->unrealize = xen_device_unrealize;
|
|
dev_class->bus_type = TYPE_XEN_BUS;
|
|
}
|
|
|
|
static const TypeInfo xen_device_type_info = {
|
|
.name = TYPE_XEN_DEVICE,
|
|
.parent = TYPE_DEVICE,
|
|
.instance_size = sizeof(XenDevice),
|
|
.abstract = true,
|
|
.class_size = sizeof(XenDeviceClass),
|
|
.class_init = xen_device_class_init,
|
|
};
|
|
|
|
typedef struct XenBridge {
|
|
SysBusDevice busdev;
|
|
} XenBridge;
|
|
|
|
#define TYPE_XEN_BRIDGE "xen-bridge"
|
|
|
|
static const TypeInfo xen_bridge_type_info = {
|
|
.name = TYPE_XEN_BRIDGE,
|
|
.parent = TYPE_SYS_BUS_DEVICE,
|
|
.instance_size = sizeof(XenBridge),
|
|
};
|
|
|
|
static void xen_register_types(void)
|
|
{
|
|
type_register_static(&xen_bridge_type_info);
|
|
type_register_static(&xen_bus_type_info);
|
|
type_register_static(&xen_device_type_info);
|
|
}
|
|
|
|
type_init(xen_register_types)
|
|
|
|
void xen_bus_init(void)
|
|
{
|
|
DeviceState *dev = qdev_create(NULL, TYPE_XEN_BRIDGE);
|
|
BusState *bus = qbus_create(TYPE_XEN_BUS, dev, NULL);
|
|
|
|
qdev_init_nofail(dev);
|
|
qbus_set_bus_hotplug_handler(bus, &error_abort);
|
|
}
|