From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37795) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YzkI1-0008VM-GS for qemu-devel@nongnu.org; Tue, 02 Jun 2015 07:23:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YzkI0-0000Cx-1b for qemu-devel@nongnu.org; Tue, 02 Jun 2015 07:23:25 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59295) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YzkHz-0000Ck-TM for qemu-devel@nongnu.org; Tue, 02 Jun 2015 07:23:23 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 983DE19F969 for ; Tue, 2 Jun 2015 11:23:23 +0000 (UTC) From: Marcel Apfelbaum Date: Tue, 2 Jun 2015 14:23:00 +0300 Message-Id: <1433244192-27624-6-git-send-email-marcel@redhat.com> In-Reply-To: <1433244192-27624-1-git-send-email-marcel@redhat.com> References: <1433244192-27624-1-git-send-email-marcel@redhat.com> Subject: [Qemu-devel] [PATCH V8 05/17] 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@redhat.com, mst@redhat.com PXB buses are assumed to be children of bus 0. Look for them while scanning the buses. Signed-off-by: Marcel Apfelbaum --- 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; + } } } } -- 2.1.0