From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50959) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z0T2u-0004o7-Pd for qemu-devel@nongnu.org; Thu, 04 Jun 2015 07:10:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z0T2t-0001g6-QI for qemu-devel@nongnu.org; Thu, 04 Jun 2015 07:10:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43084) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z0T2t-0001fv-M3 for qemu-devel@nongnu.org; Thu, 04 Jun 2015 07:10:47 -0400 Date: Thu, 4 Jun 2015 13:10:44 +0200 From: "Michael S. Tsirkin" Message-ID: <1433416111-19022-12-git-send-email-mst@redhat.com> References: <1433416111-19022-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1433416111-19022-1-git-send-email-mst@redhat.com> Subject: [Qemu-devel] [PULL 11/28] hw/pci: extend PCI config access to support devices behind PXB List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Marcel Apfelbaum , Peter Maydell , Laszlo Ersek , Eduardo Habkost From: Marcel Apfelbaum PXB buses are assumed to be children of bus 0. Look for them while scanning the buses. Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Acked-by: Laszlo Ersek --- hw/pci/pci.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 2f24f74..3361d85 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1699,10 +1699,28 @@ static bool pci_secondary_bus_in_range(PCIDevice *dev, int bus_num) { return !(pci_get_word(dev->config + PCI_BRIDGE_CONTROL) & PCI_BRIDGE_CTL_BUS_RESET) /* Don't walk the bus if it's reset. */ && - dev->config[PCI_SECONDARY_BUS] < bus_num && + dev->config[PCI_SECONDARY_BUS] <= bus_num && bus_num <= dev->config[PCI_SUBORDINATE_BUS]; } +/* Whether a given bus number is in a range of a root bus */ +static bool pci_root_bus_in_range(PCIBus *bus, int bus_num) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) { + PCIDevice *dev = bus->devices[i]; + + if (dev && PCI_DEVICE_GET_CLASS(dev)->is_bridge) { + if (pci_secondary_bus_in_range(dev, bus_num)) { + return true; + } + } + } + + return false; +} + static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num) { PCIBus *sec; @@ -1724,12 +1742,18 @@ static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num) /* try child bus */ for (; bus; bus = sec) { QLIST_FOREACH(sec, &bus->child, sibling) { - assert(!pci_bus_is_root(sec)); - if (sec->parent_dev->config[PCI_SECONDARY_BUS] == bus_num) { + if (pci_bus_num(sec) == bus_num) { return sec; } - if (pci_secondary_bus_in_range(sec->parent_dev, bus_num)) { - break; + /* PXB buses assumed to be children of bus 0 */ + if (pci_bus_is_root(sec)) { + if (pci_root_bus_in_range(sec, bus_num)) { + break; + } + } else { + if (pci_secondary_bus_in_range(sec->parent_dev, bus_num)) { + break; + } } } } -- MST