1*108f7bbaSPaul Durrant /* 2*108f7bbaSPaul Durrant * Copyright (c) 2018 Citrix Systems Inc. 3*108f7bbaSPaul Durrant * 4*108f7bbaSPaul Durrant * This work is licensed under the terms of the GNU GPL, version 2 or later. 5*108f7bbaSPaul Durrant * See the COPYING file in the top-level directory. 6*108f7bbaSPaul Durrant */ 7*108f7bbaSPaul Durrant 8*108f7bbaSPaul Durrant #include "qemu/osdep.h" 9*108f7bbaSPaul Durrant #include "hw/hw.h" 10*108f7bbaSPaul Durrant #include "hw/sysbus.h" 11*108f7bbaSPaul Durrant #include "hw/xen/xen-bus.h" 12*108f7bbaSPaul Durrant #include "qapi/error.h" 13*108f7bbaSPaul Durrant #include "trace.h" 14*108f7bbaSPaul Durrant 15*108f7bbaSPaul Durrant static void xen_bus_unrealize(BusState *bus, Error **errp) 16*108f7bbaSPaul Durrant { 17*108f7bbaSPaul Durrant trace_xen_bus_unrealize(); 18*108f7bbaSPaul Durrant } 19*108f7bbaSPaul Durrant 20*108f7bbaSPaul Durrant static void xen_bus_realize(BusState *bus, Error **errp) 21*108f7bbaSPaul Durrant { 22*108f7bbaSPaul Durrant trace_xen_bus_realize(); 23*108f7bbaSPaul Durrant } 24*108f7bbaSPaul Durrant 25*108f7bbaSPaul Durrant static void xen_bus_class_init(ObjectClass *class, void *data) 26*108f7bbaSPaul Durrant { 27*108f7bbaSPaul Durrant BusClass *bus_class = BUS_CLASS(class); 28*108f7bbaSPaul Durrant 29*108f7bbaSPaul Durrant bus_class->realize = xen_bus_realize; 30*108f7bbaSPaul Durrant bus_class->unrealize = xen_bus_unrealize; 31*108f7bbaSPaul Durrant } 32*108f7bbaSPaul Durrant 33*108f7bbaSPaul Durrant static const TypeInfo xen_bus_type_info = { 34*108f7bbaSPaul Durrant .name = TYPE_XEN_BUS, 35*108f7bbaSPaul Durrant .parent = TYPE_BUS, 36*108f7bbaSPaul Durrant .instance_size = sizeof(XenBus), 37*108f7bbaSPaul Durrant .class_size = sizeof(XenBusClass), 38*108f7bbaSPaul Durrant .class_init = xen_bus_class_init, 39*108f7bbaSPaul Durrant .interfaces = (InterfaceInfo[]) { 40*108f7bbaSPaul Durrant { TYPE_HOTPLUG_HANDLER }, 41*108f7bbaSPaul Durrant { } 42*108f7bbaSPaul Durrant }, 43*108f7bbaSPaul Durrant }; 44*108f7bbaSPaul Durrant 45*108f7bbaSPaul Durrant static void xen_device_unrealize(DeviceState *dev, Error **errp) 46*108f7bbaSPaul Durrant { 47*108f7bbaSPaul Durrant XenDevice *xendev = XEN_DEVICE(dev); 48*108f7bbaSPaul Durrant XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 49*108f7bbaSPaul Durrant const char *type = object_get_typename(OBJECT(xendev)); 50*108f7bbaSPaul Durrant 51*108f7bbaSPaul Durrant trace_xen_device_unrealize(type); 52*108f7bbaSPaul Durrant 53*108f7bbaSPaul Durrant if (xendev_class->unrealize) { 54*108f7bbaSPaul Durrant xendev_class->unrealize(xendev, errp); 55*108f7bbaSPaul Durrant } 56*108f7bbaSPaul Durrant } 57*108f7bbaSPaul Durrant 58*108f7bbaSPaul Durrant static void xen_device_realize(DeviceState *dev, Error **errp) 59*108f7bbaSPaul Durrant { 60*108f7bbaSPaul Durrant XenDevice *xendev = XEN_DEVICE(dev); 61*108f7bbaSPaul Durrant XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 62*108f7bbaSPaul Durrant const char *type = object_get_typename(OBJECT(xendev)); 63*108f7bbaSPaul Durrant Error *local_err = NULL; 64*108f7bbaSPaul Durrant 65*108f7bbaSPaul Durrant trace_xen_device_realize(type); 66*108f7bbaSPaul Durrant 67*108f7bbaSPaul Durrant if (xendev_class->realize) { 68*108f7bbaSPaul Durrant xendev_class->realize(xendev, &local_err); 69*108f7bbaSPaul Durrant if (local_err) { 70*108f7bbaSPaul Durrant error_propagate(errp, local_err); 71*108f7bbaSPaul Durrant goto unrealize; 72*108f7bbaSPaul Durrant } 73*108f7bbaSPaul Durrant } 74*108f7bbaSPaul Durrant 75*108f7bbaSPaul Durrant return; 76*108f7bbaSPaul Durrant 77*108f7bbaSPaul Durrant unrealize: 78*108f7bbaSPaul Durrant xen_device_unrealize(dev, &error_abort); 79*108f7bbaSPaul Durrant } 80*108f7bbaSPaul Durrant 81*108f7bbaSPaul Durrant static void xen_device_class_init(ObjectClass *class, void *data) 82*108f7bbaSPaul Durrant { 83*108f7bbaSPaul Durrant DeviceClass *dev_class = DEVICE_CLASS(class); 84*108f7bbaSPaul Durrant 85*108f7bbaSPaul Durrant dev_class->realize = xen_device_realize; 86*108f7bbaSPaul Durrant dev_class->unrealize = xen_device_unrealize; 87*108f7bbaSPaul Durrant dev_class->bus_type = TYPE_XEN_BUS; 88*108f7bbaSPaul Durrant } 89*108f7bbaSPaul Durrant 90*108f7bbaSPaul Durrant static const TypeInfo xen_device_type_info = { 91*108f7bbaSPaul Durrant .name = TYPE_XEN_DEVICE, 92*108f7bbaSPaul Durrant .parent = TYPE_DEVICE, 93*108f7bbaSPaul Durrant .instance_size = sizeof(XenDevice), 94*108f7bbaSPaul Durrant .abstract = true, 95*108f7bbaSPaul Durrant .class_size = sizeof(XenDeviceClass), 96*108f7bbaSPaul Durrant .class_init = xen_device_class_init, 97*108f7bbaSPaul Durrant }; 98*108f7bbaSPaul Durrant 99*108f7bbaSPaul Durrant typedef struct XenBridge { 100*108f7bbaSPaul Durrant SysBusDevice busdev; 101*108f7bbaSPaul Durrant } XenBridge; 102*108f7bbaSPaul Durrant 103*108f7bbaSPaul Durrant #define TYPE_XEN_BRIDGE "xen-bridge" 104*108f7bbaSPaul Durrant 105*108f7bbaSPaul Durrant static const TypeInfo xen_bridge_type_info = { 106*108f7bbaSPaul Durrant .name = TYPE_XEN_BRIDGE, 107*108f7bbaSPaul Durrant .parent = TYPE_SYS_BUS_DEVICE, 108*108f7bbaSPaul Durrant .instance_size = sizeof(XenBridge), 109*108f7bbaSPaul Durrant }; 110*108f7bbaSPaul Durrant 111*108f7bbaSPaul Durrant static void xen_register_types(void) 112*108f7bbaSPaul Durrant { 113*108f7bbaSPaul Durrant type_register_static(&xen_bridge_type_info); 114*108f7bbaSPaul Durrant type_register_static(&xen_bus_type_info); 115*108f7bbaSPaul Durrant type_register_static(&xen_device_type_info); 116*108f7bbaSPaul Durrant } 117*108f7bbaSPaul Durrant 118*108f7bbaSPaul Durrant type_init(xen_register_types) 119*108f7bbaSPaul Durrant 120*108f7bbaSPaul Durrant void xen_bus_init(void) 121*108f7bbaSPaul Durrant { 122*108f7bbaSPaul Durrant DeviceState *dev = qdev_create(NULL, TYPE_XEN_BRIDGE); 123*108f7bbaSPaul Durrant BusState *bus = qbus_create(TYPE_XEN_BUS, dev, NULL); 124*108f7bbaSPaul Durrant 125*108f7bbaSPaul Durrant qdev_init_nofail(dev); 126*108f7bbaSPaul Durrant qbus_set_bus_hotplug_handler(bus, &error_abort); 127*108f7bbaSPaul Durrant } 128