From patchwork Fri Nov 19 09:55:58 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Isaku Yamahata X-Patchwork-Id: 72233 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 4AEAF1007D2 for ; Fri, 19 Nov 2010 21:03:38 +1100 (EST) Received: from localhost ([127.0.0.1]:44253 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PJNod-00029H-AT for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2010 05:03:35 -0500 Received: from [140.186.70.92] (port=45101 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PJNhR-0007We-Vl for qemu-devel@nongnu.org; Fri, 19 Nov 2010 04:56:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PJNhP-0004SO-I9 for qemu-devel@nongnu.org; Fri, 19 Nov 2010 04:56:09 -0500 Received: from mail.valinux.co.jp ([210.128.90.3]:52269) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PJNhO-0004Rj-V6 for qemu-devel@nongnu.org; Fri, 19 Nov 2010 04:56:07 -0500 Received: from ps.local.valinux.co.jp (vagw.valinux.co.jp [210.128.90.14]) by mail.valinux.co.jp (Postfix) with SMTP id 7D5DB27E8E; Fri, 19 Nov 2010 18:56:04 +0900 (JST) Received: (nullmailer pid 21294 invoked by uid 1000); Fri, 19 Nov 2010 09:56:03 -0000 From: Isaku Yamahata To: qemu-devel@nongnu.org Date: Fri, 19 Nov 2010 18:55:58 +0900 Message-Id: X-Mailer: git-send-email 1.7.1.1 In-Reply-To: References: In-Reply-To: References: X-Virus-Scanned: clamav-milter 0.95.2 at va-mail.local.valinux.co.jp X-Virus-Status: Clean X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: skandasa@cisco.com, Anthony Liguori , etmartin@cisco.com, wexu2@cisco.com, mst@redhat.com, yamahata@valinux.co.jp, pbonzini@redhat.com Subject: [Qemu-devel] [PATCH v2 1/6] qbus: add functions to walk both devices and busses X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Anthony Liguori There are some cases where you want to walk the busses, in particular, when searching for a bus either by name or DeviceInfo. Paolo suggested that we model the return values on how GCC's walkers work which allows an actor to skip child transversal, or terminate walking with a positive value that's returned as the qbus_walk_children's result. Signed-off-by: Isaku Yamahata Signed-off-by: Anthony Liguori --- Changes v1 -> v2: - update comments to match the implementation --- hw/qdev.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 11 +++++++++++ 2 files changed, 57 insertions(+), 0 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index 35858cb..11d845a 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -449,6 +449,52 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name) return NULL; } +int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, + qbus_walkerfn *busfn, void *opaque) +{ + DeviceState *dev; + int err; + + if (busfn) { + err = busfn(bus, opaque); + if (err) { + return err; + } + } + + QLIST_FOREACH(dev, &bus->children, sibling) { + err = qdev_walk_children(dev, devfn, busfn, opaque); + if (err < 0) { + return err; + } + } + + return 0; +} + +int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, + qbus_walkerfn *busfn, void *opaque) +{ + BusState *bus; + int err; + + if (devfn) { + err = devfn(dev, opaque); + if (err) { + return err; + } + } + + QLIST_FOREACH(bus, &dev->child_bus, sibling) { + err = qbus_walk_children(bus, devfn, busfn, opaque); + if (err < 0) { + return err; + } + } + + return 0; +} + static BusState *qbus_find_recursive(BusState *bus, const char *name, const BusInfo *info) { diff --git a/hw/qdev.h b/hw/qdev.h index 579328a..550fd9b 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -173,9 +173,20 @@ BusState *qdev_get_parent_bus(DeviceState *dev); /*** BUS API. ***/ +/* Returns 0 to walk children, > 0 to skip walk, < 0 to terminate walk. */ +typedef int (qbus_walkerfn)(BusState *bus, void *opaque); +typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque); + void qbus_create_inplace(BusState *bus, BusInfo *info, DeviceState *parent, const char *name); BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name); +/* Returns > 0 if either devfn or busfn skip walk somewhere in cursion, + * < 0 if either devfn or busfn terminate walk somewhere in cursion, + * 0 otherwise. */ +int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, + qbus_walkerfn *busfn, void *opaque); +int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, + qbus_walkerfn *busfn, void *opaque); void qbus_free(BusState *bus); #define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev)