From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38618) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YwuOh-0006BM-Kp for qemu-devel@nongnu.org; Mon, 25 May 2015 11:34:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YwuOc-0003rG-FQ for qemu-devel@nongnu.org; Mon, 25 May 2015 11:34:35 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33400) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YwuOc-0003rC-89 for qemu-devel@nongnu.org; Mon, 25 May 2015 11:34:30 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t4PFYTFL025909 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Mon, 25 May 2015 11:34:29 -0400 From: Marcel Apfelbaum Date: Mon, 25 May 2015 18:33:50 +0300 Message-Id: <1432568042-19553-13-git-send-email-marcel@redhat.com> In-Reply-To: <1432568042-19553-1-git-send-email-marcel@redhat.com> References: <1432568042-19553-1-git-send-email-marcel@redhat.com> Subject: [Qemu-devel] [PATCH V7 12/24] 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, pbonzini@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