From patchwork Fri Dec 6 16:54:27 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 298198 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 31D452C0077 for ; Sat, 7 Dec 2013 05:57:20 +1100 (EST) Received: from localhost ([::1]:60203 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Voykx-0004co-Lc for incoming@patchwork.ozlabs.org; Fri, 06 Dec 2013 11:59:59 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36813) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Voyg4-000608-Py for qemu-devel@nongnu.org; Fri, 06 Dec 2013 11:55:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Voyfw-0000cw-4R for qemu-devel@nongnu.org; Fri, 06 Dec 2013 11:54:56 -0500 Received: from mail-ee0-x22c.google.com ([2a00:1450:4013:c00::22c]:63841) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Voyfv-0000cq-Pt for qemu-devel@nongnu.org; Fri, 06 Dec 2013 11:54:48 -0500 Received: by mail-ee0-f44.google.com with SMTP id b57so418067eek.3 for ; Fri, 06 Dec 2013 08:54:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=0Ic21w0JmGhC9DicUxzkCS/qH4WKNjC1F9YRwbJOLNU=; b=JzvDczW9t8B4JLy8qIzkecIrCGnbJSMWvZVZNlKOEMpGOUKqXSej6lmnLkN9f+YSuZ 2f4ZbykWDW7BLLOCyirOmkYjyUFMqIiPTuLejLZojhqetcvaPuUUu7HVoltJ7zILdMuu 450FvzkLv+FwsRKk3BSNicWiAyRJhaM5TW1OJ8MzKgKQEhsrg9HorXimIwEozhiM6nkT l10KpLtYGnHtRbGVybBy8KJK/mSjb9bVtlA/r82Z0XD6oqV5GBuz97E5QQFAlZLpeq6U zFQXBkqixm1ABECL1L1ZWjX/nM6FH8uIsMnUxatX/bhrMSXmN0ClYTfmA3v8HjLYZPKb /I7A== X-Received: by 10.14.108.134 with SMTP id q6mr3363516eeg.96.1386348886933; Fri, 06 Dec 2013 08:54:46 -0800 (PST) Received: from localhost.localdomain (net-2-35-202-54.cust.dsl.vodafone.it. [2.35.202.54]) by mx.google.com with ESMTPSA id z42sm47261952eeo.17.2013.12.06.08.54.45 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Fri, 06 Dec 2013 08:54:46 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 6 Dec 2013 17:54:27 +0100 Message-Id: <1386348867-25038-5-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1386348867-25038-1-git-send-email-pbonzini@redhat.com> References: <1386348867-25038-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4013:c00::22c Cc: mst@redhat.com Subject: [Qemu-devel] [PATCH 4/4] qdev: switch reset to post-order 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 Post-order is the only sensible direction for the reset signals. For example, suppose pre-order is used and the parent has some data structures that cache children state (for example a list of active requests). When the reset method is invoked on the parent, these caches could be in any state. If post-order is used, on the other hand, these will be in a known state when the reset method is invoked on the parent. This change means that it is no longer possible to block the visit of the devices, so the callback is changed to return void. This is not a problem, because PCI was returning 1 exactly in order to achieve the same ordering that this patch implements. PCI can then rely on the qdev core having sent a "reset signal" (whatever that means) to the device, and only do the PCI-specific initialization with pci_do_device_reset. Signed-off-by: Paolo Bonzini --- hw/core/qdev.c | 6 +++--- hw/pci/pci.c | 31 ++++++++++++++++--------------- include/hw/qdev-core.h | 2 +- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 1c114b7..9ba8ab1 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -233,19 +233,19 @@ static int qbus_reset_one(BusState *bus, void *opaque) { BusClass *bc = BUS_GET_CLASS(bus); if (bc->reset) { - return bc->reset(bus); + bc->reset(bus); } return 0; } void qdev_reset_all(DeviceState *dev) { - qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL); + qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL); } void qbus_reset_all(BusState *bus) { - qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL); + qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL); } void qbus_reset_all_fn(void *opaque) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 0efc544..e10d74b 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -46,7 +46,7 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent); static char *pcibus_get_dev_path(DeviceState *dev); static char *pcibus_get_fw_dev_path(DeviceState *dev); -static int pcibus_reset(BusState *qbus); +static void pcibus_reset(BusState *qbus); static Property pci_props[] = { DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1), @@ -165,16 +165,10 @@ void pci_device_deassert_intx(PCIDevice *dev) } } -/* - * This function is called on #RST and FLR. - * FLR if PCI_EXP_DEVCTL_BCR_FLR is set - */ -void pci_device_reset(PCIDevice *dev) +static void pci_do_device_reset(PCIDevice *dev) { int r; - qdev_reset_all(&dev->qdev); - dev->irq_state = 0; pci_update_irq_status(dev); pci_device_deassert_intx(dev); @@ -207,27 +201,34 @@ void pci_device_reset(PCIDevice *dev) } /* + * This function is called on #RST and FLR. + * FLR if PCI_EXP_DEVCTL_BCR_FLR is set + */ +void pci_device_reset(PCIDevice *dev) +{ + qdev_reset_all(&dev->qdev); + pci_do_device_reset(dev); +} + +/* * Trigger pci bus reset under a given bus. - * To be called on RST# assert. + * Called via qbus_reset_all on RST# assert, after the devices + * have been reset qdev_reset_all-ed already. */ -static int pcibus_reset(BusState *qbus) +static void pcibus_reset(BusState *qbus) { PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus); int i; for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) { if (bus->devices[i]) { - pci_device_reset(bus->devices[i]); + pci_do_device_reset(bus->devices[i]); } } for (i = 0; i < bus->nirq; i++) { assert(bus->irq_count[i] == 0); } - - /* topology traverse is done by pci_bus_reset(). - Tell qbus/qdev walker not to traverse the tree */ - return 1; } static void pci_host_bus_register(PCIBus *bus, DeviceState *parent) diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 21ea2c6..409fd71 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -178,7 +178,7 @@ struct BusClass { * bindings can be found at http://playground.sun.com/1275/bindings/. */ char *(*get_fw_dev_path)(DeviceState *dev); - int (*reset)(BusState *bus); + void (*reset)(BusState *bus); /* maximum devices allowed on the bus, 0: no limit. */ int max_dev; };