From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50540) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WQeUT-0007L9-Pi for qemu-devel@nongnu.org; Thu, 20 Mar 2014 11:02:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WQeUN-0001Um-62 for qemu-devel@nongnu.org; Thu, 20 Mar 2014 11:02:41 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52383) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WQeUM-0001Ue-Up for qemu-devel@nongnu.org; Thu, 20 Mar 2014 11:02:35 -0400 From: Igor Mammedov Date: Thu, 20 Mar 2014 16:01:12 +0100 Message-Id: <1395327676-29753-5-git-send-email-imammedo@redhat.com> In-Reply-To: <1395327676-29753-1-git-send-email-imammedo@redhat.com> References: <1395327676-29753-1-git-send-email-imammedo@redhat.com> Subject: [Qemu-devel] [RFC 4/8] qdev: link based hotplug List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: marcel.a@redhat.com, mst@redhat.com, vasilis.liaskovitis@profitbricks.com, aliguori@amazon.com, pbonzini@redhat.com, afaerber@suse.de Signed-off-by: Igor Mammedov --- hw/core/hotplug.c | 30 ++++++++++++++++++++++++++++++ hw/core/qdev.c | 15 +++++++++++++++ include/hw/hotplug.h | 2 ++ include/hw/qdev-core.h | 6 ++++++ 4 files changed, 53 insertions(+), 0 deletions(-) diff --git a/hw/core/hotplug.c b/hw/core/hotplug.c index 5573d9d..1a13ca3 100644 --- a/hw/core/hotplug.c +++ b/hw/core/hotplug.c @@ -11,6 +11,36 @@ */ #include "hw/hotplug.h" #include "qemu/module.h" +#include + +HotplugHandler *hotplug_handler_get_from_path(const char *path) +{ + Object *obj; + const char *sep; + bool ambiguous = false; + HotplugHandler *hh = NULL; + char *current_path = g_strdup(path); + + while ((sep = strrchr(current_path, '/'))) { + char *old_path = current_path; + if (!sep || sep == current_path) { + break; + } + + current_path = g_strndup(current_path, sep - current_path); + g_free(old_path); + + obj = object_resolve_path(current_path, &ambiguous); + g_assert(!ambiguous); + hh = (HotplugHandler *)object_dynamic_cast(obj, TYPE_HOTPLUG_HANDLER); + if (hh != NULL) { + break; + } + } + + g_free(current_path); + return hh; +} void hotplug_handler_plug(HotplugHandler *plug_handler, DeviceState *plugged_dev, diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 9f0a522..a8d6eea 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -743,6 +743,21 @@ static void device_set_realized(Object *obj, bool value, Error **err) local_err == NULL) { hotplug_handler_plug(dev->parent_bus->hotplug_handler, dev, &local_err); + } else if (dc->hotplug_path != NULL && local_err == NULL) { + HotplugHandler *hotplug_ctrl; + char *target_name; + char *path = dc->hotplug_path(dev); + + hotplug_ctrl = hotplug_handler_get_from_path(path); + g_assert(hotplug_ctrl); + + target_name = g_strdup(strrchr(path, '/') + 1); + object_property_set_link(OBJECT(hotplug_ctrl), OBJECT(dev), + target_name, &local_err); + g_free(target_name); + g_free(path); + + hotplug_handler_plug(hotplug_ctrl, dev, &local_err); } if (qdev_get_vmsd(dev) && local_err == NULL) { diff --git a/include/hw/hotplug.h b/include/hw/hotplug.h index a6533cb..7a3815e 100644 --- a/include/hw/hotplug.h +++ b/include/hw/hotplug.h @@ -75,4 +75,6 @@ void hotplug_handler_plug(HotplugHandler *plug_handler, void hotplug_handler_unplug(HotplugHandler *plug_handler, DeviceState *plugged_dev, Error **errp); + +HotplugHandler *hotplug_handler_get_from_path(const char *path); #endif diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index dbe473c..6cd936d 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -116,6 +116,12 @@ typedef struct DeviceClass { bool cannot_instantiate_with_device_add_yet; bool hotpluggable; + /* + * Returns path to link<> that should be set/unset on dev hotplug. + * Used for link based bussless devices hotplug. + */ + char* (*hotplug_path)(DeviceState *dev); + /* callbacks */ void (*reset)(DeviceState *dev); DeviceRealize realize; -- 1.7.1