From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43638) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5hRr-0000J9-5E for qemu-devel@nongnu.org; Wed, 25 May 2016 18:38:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b5hRk-0003eV-R4 for qemu-devel@nongnu.org; Wed, 25 May 2016 18:38:42 -0400 Received: from mx2.suse.de ([195.135.220.15]:42644) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5hRk-0003eG-Fz for qemu-devel@nongnu.org; Wed, 25 May 2016 18:38:36 -0400 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id E1525ABF1 for ; Wed, 25 May 2016 22:38:35 +0000 (UTC) From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 26 May 2016 00:38:33 +0200 Message-Id: <1464215913-18971-2-git-send-email-afaerber@suse.de> In-Reply-To: <1464215913-18971-1-git-send-email-afaerber@suse.de> References: <1464215913-18971-1-git-send-email-afaerber@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PULL 1/1] qdev: Start disentangling bus from device List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Andreas=20F=C3=A4rber?= Move bus type and related APIs to a separate file bus.c. This is a first step in breaking up qdev.c into more manageable chunks. Reviewed-by: Peter Maydell [AF: Rebased onto osdep.h] Signed-off-by: Andreas F=C3=A4rber --- hw/core/Makefile.objs | 1 + hw/core/bus.c | 251 ++++++++++++++++++++++++++++++++++++++++++++= ++++++ hw/core/qdev.c | 222 -------------------------------------------- 3 files changed, 252 insertions(+), 222 deletions(-) create mode 100644 hw/core/bus.c diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs index 70951d4..82a9ef8 100644 --- a/hw/core/Makefile.objs +++ b/hw/core/Makefile.objs @@ -1,5 +1,6 @@ # core qdev-related obj files, also used by *-user: common-obj-y +=3D qdev.o qdev-properties.o +common-obj-y +=3D bus.o common-obj-y +=3D fw-path-provider.o # irq.o needed for qdev GPIO handling: common-obj-y +=3D irq.o diff --git a/hw/core/bus.c b/hw/core/bus.c new file mode 100644 index 0000000..3e3f8ac --- /dev/null +++ b/hw/core/bus.c @@ -0,0 +1,251 @@ +/* + * Dynamic device configuration and creation -- buses. + * + * Copyright (c) 2009 CodeSourcery + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "hw/qdev.h" +#include "qapi/error.h" + +static void qbus_set_hotplug_handler_internal(BusState *bus, Object *han= dler, + Error **errp) +{ + + object_property_set_link(OBJECT(bus), OBJECT(handler), + QDEV_HOTPLUG_HANDLER_PROPERTY, errp); +} + +void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler, Error= **errp) +{ + qbus_set_hotplug_handler_internal(bus, OBJECT(handler), errp); +} + +void qbus_set_bus_hotplug_handler(BusState *bus, Error **errp) +{ + qbus_set_hotplug_handler_internal(bus, OBJECT(bus), errp); +} + +int qbus_walk_children(BusState *bus, + qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busf= n, + qdev_walkerfn *post_devfn, qbus_walkerfn *post_bu= sfn, + void *opaque) +{ + BusChild *kid; + int err; + + if (pre_busfn) { + err =3D pre_busfn(bus, opaque); + if (err) { + return err; + } + } + + QTAILQ_FOREACH(kid, &bus->children, sibling) { + err =3D qdev_walk_children(kid->child, + pre_devfn, pre_busfn, + post_devfn, post_busfn, opaque); + if (err < 0) { + return err; + } + } + + if (post_busfn) { + err =3D post_busfn(bus, opaque); + if (err) { + return err; + } + } + + return 0; +} + +static void qbus_realize(BusState *bus, DeviceState *parent, const char = *name) +{ + const char *typename =3D object_get_typename(OBJECT(bus)); + BusClass *bc; + char *buf; + int i, len, bus_id; + + bus->parent =3D parent; + + if (name) { + bus->name =3D g_strdup(name); + } else if (bus->parent && bus->parent->id) { + /* parent device has id -> use it plus parent-bus-id for bus nam= e */ + bus_id =3D bus->parent->num_child_bus; + + len =3D strlen(bus->parent->id) + 16; + buf =3D g_malloc(len); + snprintf(buf, len, "%s.%d", bus->parent->id, bus_id); + bus->name =3D buf; + } else { + /* no id -> use lowercase bus type plus global bus-id for bus na= me */ + bc =3D BUS_GET_CLASS(bus); + bus_id =3D bc->automatic_ids++; + + len =3D strlen(typename) + 16; + buf =3D g_malloc(len); + len =3D snprintf(buf, len, "%s.%d", typename, bus_id); + for (i =3D 0; i < len; i++) { + buf[i] =3D qemu_tolower(buf[i]); + } + bus->name =3D buf; + } + + if (bus->parent) { + QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling); + bus->parent->num_child_bus++; + object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT= (bus), NULL); + object_unref(OBJECT(bus)); + } else if (bus !=3D sysbus_get_default()) { + /* TODO: once all bus devices are qdevified, + only reset handler for main_system_bus should be registered h= ere. */ + qemu_register_reset(qbus_reset_all_fn, bus); + } +} + +static void bus_unparent(Object *obj) +{ + BusState *bus =3D BUS(obj); + BusChild *kid; + + while ((kid =3D QTAILQ_FIRST(&bus->children)) !=3D NULL) { + DeviceState *dev =3D kid->child; + object_unparent(OBJECT(dev)); + } + if (bus->parent) { + QLIST_REMOVE(bus, sibling); + bus->parent->num_child_bus--; + bus->parent =3D NULL; + } else { + assert(bus !=3D sysbus_get_default()); /* main_system_bus is nev= er freed */ + qemu_unregister_reset(qbus_reset_all_fn, bus); + } +} + +void qbus_create_inplace(void *bus, size_t size, const char *typename, + DeviceState *parent, const char *name) +{ + object_initialize(bus, size, typename); + qbus_realize(bus, parent, name); +} + +BusState *qbus_create(const char *typename, DeviceState *parent, const c= har *name) +{ + BusState *bus; + + bus =3D BUS(object_new(typename)); + qbus_realize(bus, parent, name); + + return bus; +} + +static bool bus_get_realized(Object *obj, Error **errp) +{ + BusState *bus =3D BUS(obj); + + return bus->realized; +} + +static void bus_set_realized(Object *obj, bool value, Error **errp) +{ + BusState *bus =3D BUS(obj); + BusClass *bc =3D BUS_GET_CLASS(bus); + BusChild *kid; + Error *local_err =3D NULL; + + if (value && !bus->realized) { + if (bc->realize) { + bc->realize(bus, &local_err); + } + + /* TODO: recursive realization */ + } else if (!value && bus->realized) { + QTAILQ_FOREACH(kid, &bus->children, sibling) { + DeviceState *dev =3D kid->child; + object_property_set_bool(OBJECT(dev), false, "realized", + &local_err); + if (local_err !=3D NULL) { + break; + } + } + if (bc->unrealize && local_err =3D=3D NULL) { + bc->unrealize(bus, &local_err); + } + } + + if (local_err !=3D NULL) { + error_propagate(errp, local_err); + return; + } + + bus->realized =3D value; +} + +static void qbus_initfn(Object *obj) +{ + BusState *bus =3D BUS(obj); + + QTAILQ_INIT(&bus->children); + object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY, + TYPE_HOTPLUG_HANDLER, + (Object **)&bus->hotplug_handler, + object_property_allow_set_link, + OBJ_PROP_LINK_UNREF_ON_RELEASE, + NULL); + object_property_add_bool(obj, "realized", + bus_get_realized, bus_set_realized, NULL); +} + +static char *default_bus_get_fw_dev_path(DeviceState *dev) +{ + return g_strdup(object_get_typename(OBJECT(dev))); +} + +static void bus_class_init(ObjectClass *class, void *data) +{ + BusClass *bc =3D BUS_CLASS(class); + + class->unparent =3D bus_unparent; + bc->get_fw_dev_path =3D default_bus_get_fw_dev_path; +} + +static void qbus_finalize(Object *obj) +{ + BusState *bus =3D BUS(obj); + + g_free((char *)bus->name); +} + +static const TypeInfo bus_info =3D { + .name =3D TYPE_BUS, + .parent =3D TYPE_OBJECT, + .instance_size =3D sizeof(BusState), + .abstract =3D true, + .class_size =3D sizeof(BusClass), + .instance_init =3D qbus_initfn, + .instance_finalize =3D qbus_finalize, + .class_init =3D bus_class_init, +}; + +static void bus_register_types(void) +{ + type_register_static(&bus_info); +} + +type_init(bus_register_types) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index db41aa1..853162b 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -109,24 +109,6 @@ void qdev_set_parent_bus(DeviceState *dev, BusState = *bus) bus_add_child(bus, dev); } =20 -static void qbus_set_hotplug_handler_internal(BusState *bus, Object *han= dler, - Error **errp) -{ - - object_property_set_link(OBJECT(bus), OBJECT(handler), - QDEV_HOTPLUG_HANDLER_PROPERTY, errp); -} - -void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler, Error= **errp) -{ - qbus_set_hotplug_handler_internal(bus, OBJECT(handler), errp); -} - -void qbus_set_bus_hotplug_handler(BusState *bus, Error **errp) -{ - qbus_set_hotplug_handler_internal(bus, OBJECT(bus), errp); -} - /* Create a new device. This only initializes the device state structure and allows properties to be set. The device still needs to be realized. See qdev-core.h. */ @@ -595,40 +577,6 @@ BusState *qdev_get_child_bus(DeviceState *dev, const= char *name) return NULL; } =20 -int qbus_walk_children(BusState *bus, - qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busf= n, - qdev_walkerfn *post_devfn, qbus_walkerfn *post_bu= sfn, - void *opaque) -{ - BusChild *kid; - int err; - - if (pre_busfn) { - err =3D pre_busfn(bus, opaque); - if (err) { - return err; - } - } - - QTAILQ_FOREACH(kid, &bus->children, sibling) { - err =3D qdev_walk_children(kid->child, - pre_devfn, pre_busfn, - post_devfn, post_busfn, opaque); - if (err < 0) { - return err; - } - } - - if (post_busfn) { - err =3D post_busfn(bus, opaque); - if (err) { - return err; - } - } - - return 0; -} - int qdev_walk_children(DeviceState *dev, qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busf= n, qdev_walkerfn *post_devfn, qbus_walkerfn *post_bu= sfn, @@ -685,129 +633,6 @@ DeviceState *qdev_find_recursive(BusState *bus, con= st char *id) return NULL; } =20 -static void qbus_realize(BusState *bus, DeviceState *parent, const char = *name) -{ - const char *typename =3D object_get_typename(OBJECT(bus)); - BusClass *bc; - char *buf; - int i, len, bus_id; - - bus->parent =3D parent; - - if (name) { - bus->name =3D g_strdup(name); - } else if (bus->parent && bus->parent->id) { - /* parent device has id -> use it plus parent-bus-id for bus nam= e */ - bus_id =3D bus->parent->num_child_bus; - - len =3D strlen(bus->parent->id) + 16; - buf =3D g_malloc(len); - snprintf(buf, len, "%s.%d", bus->parent->id, bus_id); - bus->name =3D buf; - } else { - /* no id -> use lowercase bus type plus global bus-id for bus na= me */ - bc =3D BUS_GET_CLASS(bus); - bus_id =3D bc->automatic_ids++; - - len =3D strlen(typename) + 16; - buf =3D g_malloc(len); - len =3D snprintf(buf, len, "%s.%d", typename, bus_id); - for (i =3D 0; i < len; i++) { - buf[i] =3D qemu_tolower(buf[i]); - } - bus->name =3D buf; - } - - if (bus->parent) { - QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling); - bus->parent->num_child_bus++; - object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT= (bus), NULL); - object_unref(OBJECT(bus)); - } else if (bus !=3D sysbus_get_default()) { - /* TODO: once all bus devices are qdevified, - only reset handler for main_system_bus should be registered h= ere. */ - qemu_register_reset(qbus_reset_all_fn, bus); - } -} - -static void bus_unparent(Object *obj) -{ - BusState *bus =3D BUS(obj); - BusChild *kid; - - while ((kid =3D QTAILQ_FIRST(&bus->children)) !=3D NULL) { - DeviceState *dev =3D kid->child; - object_unparent(OBJECT(dev)); - } - if (bus->parent) { - QLIST_REMOVE(bus, sibling); - bus->parent->num_child_bus--; - bus->parent =3D NULL; - } else { - assert(bus !=3D sysbus_get_default()); /* main_system_bus is nev= er freed */ - qemu_unregister_reset(qbus_reset_all_fn, bus); - } -} - -static bool bus_get_realized(Object *obj, Error **errp) -{ - BusState *bus =3D BUS(obj); - - return bus->realized; -} - -static void bus_set_realized(Object *obj, bool value, Error **errp) -{ - BusState *bus =3D BUS(obj); - BusClass *bc =3D BUS_GET_CLASS(bus); - BusChild *kid; - Error *local_err =3D NULL; - - if (value && !bus->realized) { - if (bc->realize) { - bc->realize(bus, &local_err); - } - - /* TODO: recursive realization */ - } else if (!value && bus->realized) { - QTAILQ_FOREACH(kid, &bus->children, sibling) { - DeviceState *dev =3D kid->child; - object_property_set_bool(OBJECT(dev), false, "realized", - &local_err); - if (local_err !=3D NULL) { - break; - } - } - if (bc->unrealize && local_err =3D=3D NULL) { - bc->unrealize(bus, &local_err); - } - } - - if (local_err !=3D NULL) { - error_propagate(errp, local_err); - return; - } - - bus->realized =3D value; -} - -void qbus_create_inplace(void *bus, size_t size, const char *typename, - DeviceState *parent, const char *name) -{ - object_initialize(bus, size, typename); - qbus_realize(bus, parent, name); -} - -BusState *qbus_create(const char *typename, DeviceState *parent, const c= har *name) -{ - BusState *bus; - - bus =3D BUS(object_new(typename)); - qbus_realize(bus, parent, name); - - return bus; -} - static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev) { BusClass *bc =3D BUS_GET_CLASS(bus); @@ -1315,55 +1140,8 @@ static const TypeInfo device_type_info =3D { .class_size =3D sizeof(DeviceClass), }; =20 -static void qbus_initfn(Object *obj) -{ - BusState *bus =3D BUS(obj); - - QTAILQ_INIT(&bus->children); - object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY, - TYPE_HOTPLUG_HANDLER, - (Object **)&bus->hotplug_handler, - object_property_allow_set_link, - OBJ_PROP_LINK_UNREF_ON_RELEASE, - NULL); - object_property_add_bool(obj, "realized", - bus_get_realized, bus_set_realized, NULL); -} - -static char *default_bus_get_fw_dev_path(DeviceState *dev) -{ - return g_strdup(object_get_typename(OBJECT(dev))); -} - -static void bus_class_init(ObjectClass *class, void *data) -{ - BusClass *bc =3D BUS_CLASS(class); - - class->unparent =3D bus_unparent; - bc->get_fw_dev_path =3D default_bus_get_fw_dev_path; -} - -static void qbus_finalize(Object *obj) -{ - BusState *bus =3D BUS(obj); - - g_free((char *)bus->name); -} - -static const TypeInfo bus_info =3D { - .name =3D TYPE_BUS, - .parent =3D TYPE_OBJECT, - .instance_size =3D sizeof(BusState), - .abstract =3D true, - .class_size =3D sizeof(BusClass), - .instance_init =3D qbus_initfn, - .instance_finalize =3D qbus_finalize, - .class_init =3D bus_class_init, -}; - static void qdev_register_types(void) { - type_register_static(&bus_info); type_register_static(&device_type_info); } =20 --=20 2.6.6