From patchwork Wed Nov 11 00:27:58 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 542690 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 07B931402A2 for ; Wed, 11 Nov 2015 11:42:49 +1100 (AEDT) Received: from localhost ([::1]:36519 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZwJUs-00088q-VH for incoming@patchwork.ozlabs.org; Tue, 10 Nov 2015 19:42:46 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38053) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZwJJ9-0002nH-IP for qemu-devel@nongnu.org; Tue, 10 Nov 2015 19:30:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZwJJ8-0004aQ-8r for qemu-devel@nongnu.org; Tue, 10 Nov 2015 19:30:39 -0500 Received: from gate.crashing.org ([63.228.1.57]:48672) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZwJJ7-0004a8-S7; Tue, 10 Nov 2015 19:30:38 -0500 Received: from pasglop.ozlabs.ibm.com. (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.13.8) with ESMTP id tAB0Sb2x024031; Tue, 10 Nov 2015 18:30:33 -0600 From: Benjamin Herrenschmidt To: qemu-ppc@nongnu.org Date: Wed, 11 Nov 2015 11:27:58 +1100 Message-Id: <1447201710-10229-46-git-send-email-benh@kernel.crashing.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1447201710-10229-1-git-send-email-benh@kernel.crashing.org> References: <1447201710-10229-1-git-send-email-benh@kernel.crashing.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 63.228.1.57 Cc: qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 45/77] qdev: Add a hook for a bus to device if it can add devices 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 This allows a bus class to tell whether a given bus has room for any new device. max_dev isn't sufficient as the rules can depend on some arguments or can differ between instances of a bus. This will be used by PCI in subsequent patches Signed-off-by: Benjamin Herrenschmidt Reviewed-by: Paolo Bonzini Acked-by: Paolo Bonzini --- include/hw/qdev-core.h | 1 + qdev-monitor.c | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 8057aed..6f3dd8d 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -202,6 +202,7 @@ struct BusClass { */ char *(*get_fw_dev_path)(DeviceState *dev); void (*reset)(BusState *bus); + bool (*can_add_device)(BusState *bus, QemuOpts *opts); BusRealize realize; BusUnrealize unrealize; diff --git a/qdev-monitor.c b/qdev-monitor.c index a35098f..4023357 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -384,7 +384,7 @@ static inline bool qbus_is_full(BusState *bus) * Return the bus if found, else %NULL. */ static BusState *qbus_find_recursive(BusState *bus, const char *name, - const char *bus_typename) + const char *bus_typename, QemuOpts *opts) { BusChild *kid; BusState *pick, *child, *ret; @@ -398,7 +398,10 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name, } if (match && !qbus_is_full(bus)) { - return bus; /* root matches and isn't full */ + BusClass *bc = BUS_GET_CLASS(bus); + if (!bc->can_add_device || bc->can_add_device(bus, opts)) { + return bus; /* root matches and isn't full */ + } } pick = match ? bus : NULL; @@ -406,7 +409,7 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name, QTAILQ_FOREACH(kid, &bus->children, sibling) { DeviceState *dev = kid->child; QLIST_FOREACH(child, &dev->child_bus, sibling) { - ret = qbus_find_recursive(child, name, bus_typename); + ret = qbus_find_recursive(child, name, bus_typename, opts); if (ret && !qbus_is_full(ret)) { return ret; /* a descendant matches and isn't full */ } @@ -436,7 +439,7 @@ static BusState *qbus_find(const char *path, Error **errp) assert(!path[0]); elem[0] = len = 0; } - bus = qbus_find_recursive(sysbus_get_default(), elem, NULL); + bus = qbus_find_recursive(sysbus_get_default(), elem, NULL, NULL); if (!bus) { error_setg(errp, "Bus '%s' not found", elem); return NULL; @@ -542,7 +545,7 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp) return NULL; } } else if (dc->bus_type != NULL) { - bus = qbus_find_recursive(sysbus_get_default(), NULL, dc->bus_type); + bus = qbus_find_recursive(sysbus_get_default(), NULL, dc->bus_type, opts); if (!bus || qbus_is_full(bus)) { error_setg(errp, "No '%s' bus found for device '%s'", dc->bus_type, driver);