From patchwork Sun Jan 6 18:48:42 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andreas_F=C3=A4rber?= X-Patchwork-Id: 209792 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 813262C0087 for ; Mon, 7 Jan 2013 05:49:37 +1100 (EST) Received: from localhost ([::1]:47175 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TrvHr-00043F-P0 for incoming@patchwork.ozlabs.org; Sun, 06 Jan 2013 13:49:35 -0500 Received: from eggs.gnu.org ([208.118.235.92]:49069) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TrvHJ-0002aZ-4u for qemu-devel@nongnu.org; Sun, 06 Jan 2013 13:49:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TrvHG-0004mi-R8 for qemu-devel@nongnu.org; Sun, 06 Jan 2013 13:49:01 -0500 Received: from cantor2.suse.de ([195.135.220.15]:55995 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TrvHG-0004md-HS for qemu-devel@nongnu.org; Sun, 06 Jan 2013 13:48:58 -0500 Received: from relay1.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 01365A51B7; Sun, 6 Jan 2013 19:48:58 +0100 (CET) From: =?UTF-8?q?Andreas=20F=C3=A4rber?= To: qemu-devel@nongnu.org Date: Sun, 6 Jan 2013 19:48:42 +0100 Message-Id: <1357498122-1129-3-git-send-email-afaerber@suse.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1357498122-1129-1-git-send-email-afaerber@suse.de> References: <1357498122-1129-1-git-send-email-afaerber@suse.de> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 195.135.220.15 Cc: pbonzini@redhat.com, =?UTF-8?q?Andreas=20F=C3=A4rber?= , anthony@codemonkey.ws Subject: [Qemu-devel] [PATCH v2 2/2] qdev: Prepare "realized" property X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Based on earlier patches by Paolo and me, introduce the QOM realizefn at device level only, as requested by Anthony. For now this just wraps the qdev initfn, which it deprecates. Signed-off-by: Paolo Bonzini Signed-off-by: Andreas Färber Cc: Anthony Liguori --- hw/qdev-core.h | 4 +++ hw/qdev.c | 96 ++++++++++++++++++++++++++++++++++++++++++-------------- 2 Dateien geändert, 76 Zeilen hinzugefügt(+), 24 Zeilen entfernt(-) diff --git a/hw/qdev-core.h b/hw/qdev-core.h index 5836e35..e50c866 100644 --- a/hw/qdev-core.h +++ b/hw/qdev-core.h @@ -20,6 +20,8 @@ enum { typedef int (*qdev_initfn)(DeviceState *dev); typedef int (*qdev_event)(DeviceState *dev); typedef void (*qdev_resetfn)(DeviceState *dev); +typedef void (*DeviceRealize)(DeviceState *dev, Error **err); +typedef void (*DeviceUnrealize)(DeviceState *dev, Error **err); struct VMStateDescription; @@ -38,6 +40,8 @@ typedef struct DeviceClass { const struct VMStateDescription *vmsd; /* Private to qdev / bus. */ + DeviceRealize realize; + DeviceUnrealize unrealize; qdev_initfn init; qdev_event unplug; qdev_event exit; diff --git a/hw/qdev.c b/hw/qdev.c index b214c8a..f45ab14 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -148,37 +148,30 @@ DeviceState *qdev_try_create(BusState *bus, const char *type) Return 0 on success. */ int qdev_init(DeviceState *dev) { - DeviceClass *dc = DEVICE_GET_CLASS(dev); - int rc; + Error *local_err = NULL; assert(!dev->realized); - rc = dc->init(dev); - if (rc < 0) { + object_property_set_bool(OBJECT(dev), true, "realized", &local_err); + if (local_err != NULL) { + error_free(local_err); qdev_free(dev); - return rc; + return -1; } + return 0; +} - if (!OBJECT(dev)->parent) { - static int unattached_count = 0; - gchar *name = g_strdup_printf("device[%d]", unattached_count++); - - object_property_add_child(container_get(qdev_get_machine(), - "/unattached"), - name, OBJECT(dev), NULL); - g_free(name); - } +static void device_realize(DeviceState *dev, Error **err) +{ + DeviceClass *dc = DEVICE_GET_CLASS(dev); - if (qdev_get_vmsd(dev)) { - vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev, - dev->instance_id_alias, - dev->alias_required_for_version); - } - dev->realized = true; - if (dev->hotplugged) { - device_reset(dev); + if (dc->init) { + int rc = dc->init(dev); + if (rc < 0) { + error_setg(err, "Device initialization failed."); + return; + } } - return 0; } void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id, @@ -636,6 +629,55 @@ void qdev_property_add_static(DeviceState *dev, Property *prop, assert_no_error(local_err); } +static bool device_get_realized(Object *obj, Error **err) +{ + DeviceState *dev = DEVICE(obj); + return dev->realized; +} + +static void device_set_realized(Object *obj, bool value, Error **err) +{ + DeviceState *dev = DEVICE(obj); + DeviceClass *dc = DEVICE_GET_CLASS(dev); + Error *local_err = NULL; + + if (value && !dev->realized) { + if (dc->realize) { + dc->realize(dev, &local_err); + } + + if (!obj->parent && local_err == NULL) { + static int unattached_count; + gchar *name = g_strdup_printf("device[%d]", unattached_count++); + + object_property_add_child(container_get(qdev_get_machine(), + "/unattached"), + name, obj, &local_err); + g_free(name); + } + + if (qdev_get_vmsd(dev) && local_err == NULL) { + vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev, + dev->instance_id_alias, + dev->alias_required_for_version); + } + if (dev->hotplugged && local_err == NULL) { + device_reset(dev); + } + } else if (!value && dev->realized) { + if (dc->unrealize) { + dc->unrealize(dev, &local_err); + } + } + + if (local_err != NULL) { + error_propagate(err, local_err); + return; + } + + dev->realized = value; +} + static void device_initfn(Object *obj) { DeviceState *dev = DEVICE(obj); @@ -650,6 +692,9 @@ static void device_initfn(Object *obj) dev->instance_id_alias = -1; dev->realized = false; + object_property_add_bool(obj, "realized", + device_get_realized, device_set_realized, NULL); + class = object_get_class(OBJECT(dev)); do { for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) { @@ -707,7 +752,10 @@ static void qdev_remove_from_bus(Object *obj) static void device_class_init(ObjectClass *class, void *data) { + DeviceClass *dc = DEVICE_CLASS(class); + class->unparent = qdev_remove_from_bus; + dc->realize = device_realize; } void device_reset(DeviceState *dev) @@ -730,7 +778,7 @@ Object *qdev_get_machine(void) return dev; } -static TypeInfo device_type_info = { +static const TypeInfo device_type_info = { .name = TYPE_DEVICE, .parent = TYPE_OBJECT, .instance_size = sizeof(DeviceState),