qemu/hw/xen/xen-bus.c
Paul Durrant 108f7bba15 xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
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>
2019-01-14 13:45:40 +00:00

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);
}