From: Yinghai Lu <yinghai@kernel.org>
To: Jesse Barnes <jbarnes@virtuousgeek.org>,
Benjamin Herrenschmidt <benh@kernel.crashing.org>,
Tony Luck <tony.luck@intel.com>,
David Miller <davem@davemloft.net>, x86 <x86@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>,
Dominik Brodowski <linux@dominikbrodowski.net>,
Andrew Morton <akpm@linux-foundation.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arch@vger.kernel.org, Yinghai Lu <yinghai@kernel.org>
Subject: [PATCH 21/24] PCI: Seperate child bus scanning to two passes overall
Date: Tue, 28 Feb 2012 14:07:40 -0800 [thread overview]
Message-ID: <1330466863-28469-22-git-send-email-yinghai@kernel.org> (raw)
In-Reply-To: <1330466863-28469-1-git-send-email-yinghai@kernel.org>
In extreme case: Two bridges are properly setup.
bridge A
bridge AA
bridge AB
bridge B
bridge BA
bridge BB
but AA, AB are not setup properly.
bridge A has small range, and bridge AB could need more, when do the
first pass0 for bridge A, it will do pass0 and pass1 for AA and AB,
during that process, it will extend range of A for AB blindly.
because bridge B is not registered yet.
that could overlap range that is used by bridge B.
Right way should be:
do pass0 for all good bridges at first.
So we could do pass0 for bridge B before pass1 for bridge AB.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/probe.c | 50 ++++++++++++++++++++++++++++++++++----------------
1 files changed, 34 insertions(+), 16 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ba51902..4a38ef4 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -809,6 +809,9 @@ static int __devinit pci_bridge_check_busn_broken(struct pci_bus *bus,
return broken;
}
+
+static unsigned int __devinit __pci_scan_child_bus(struct pci_bus *bus,
+ int pass);
/*
* If it's a bridge, configure it and scan the bus behind it.
* For CardBus bridges, we don't scan behind as the devices will
@@ -865,11 +868,10 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
!is_cardbus && !broken) {
unsigned int cmax;
/*
- * Bus already configured by firmware, process it in the first
- * pass and just note the configuration.
+ * Bus already configured by firmware, still process it in two
+ * passes in extreme case like two adjaced bridges have children
+ * bridges that are not setup properly.
*/
- if (pass)
- goto out;
/*
* If we already got to this bus through a different bridge,
@@ -890,7 +892,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
pci_bus_insert_busn_res(child, secondary, subordinate);
}
- cmax = pci_scan_child_bus(child);
+ cmax = __pci_scan_child_bus(child, pass);
if (cmax > max)
max = cmax;
if (child->subordinate > max)
@@ -1704,12 +1706,13 @@ void pcie_bus_configure_settings(struct pci_bus *bus, u8 mpss)
}
EXPORT_SYMBOL_GPL(pcie_bus_configure_settings);
-unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
+static unsigned int __devinit __pci_scan_child_bus(struct pci_bus *bus,
+ int pass)
{
- unsigned int devfn, pass, max = bus->secondary;
+ unsigned int devfn, max = bus->secondary;
struct pci_dev *dev;
- dev_dbg(&bus->dev, "scanning bus\n");
+ dev_dbg(&bus->dev, "scanning bus pass %d\n", pass);
/* Go find them, Rover! */
for (devfn = 0; devfn < 0x100; devfn += 8)
@@ -1723,18 +1726,16 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
* all PCI-to-PCI bridges on this bus.
*/
if (!bus->is_added) {
- dev_dbg(&bus->dev, "fixups for bus\n");
+ dev_dbg(&bus->dev, "fixups for bus pass %d\n", pass);
pcibios_fixup_bus(bus);
if (pci_is_root_bus(bus))
bus->is_added = 1;
}
- for (pass=0; pass < 2; pass++)
- list_for_each_entry(dev, &bus->devices, bus_list) {
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
- dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
- max = pci_scan_bridge(bus, dev, max, pass);
- }
+ list_for_each_entry(dev, &bus->devices, bus_list)
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+ dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+ max = pci_scan_bridge(bus, dev, max, pass);
/*
* We've scanned the bus and so we know all about what's on
@@ -1743,7 +1744,24 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
*
* Return how far we've got finding sub-buses.
*/
- dev_dbg(&bus->dev, "bus scan returning with max=%02x\n", max);
+ dev_dbg(&bus->dev, "bus scan returning with max=%02x pass %d\n",
+ max, pass);
+
+ return max;
+}
+
+unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
+{
+ int pass;
+ unsigned int max = 0, tmp;
+
+ for (pass = 0; pass < 2; pass++) {
+ tmp = __pci_scan_child_bus(bus, pass);
+
+ if (tmp > max)
+ max = tmp;
+ }
+
return max;
}
--
1.7.7
next prev parent reply other threads:[~2012-02-28 22:07 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-28 22:07 [PATCH -v9 00/24] PCI: allocate pci bus num range for unassigned bridge busn Yinghai Lu
2012-02-28 22:07 ` [PATCH 01/24] x86, PCI: add print all root info for nocrs path Yinghai Lu
2012-02-28 22:07 ` [PATCH 02/24] x86, PCI: Merge pcibios_scan_root and pci_scan_bus_on_node Yinghai Lu
2012-02-28 22:07 ` [PATCH 03/24] PCI: Add busn_res into struct pci_bus Yinghai Lu
2012-02-28 22:07 ` [PATCH 04/24] PCI: Add busn_res operation functions Yinghai Lu
2012-02-28 22:07 ` [PATCH 05/24] PCI: release busn when removing bus Yinghai Lu
2012-02-28 22:07 ` [PATCH 06/24] PCI: insert busn_res in pci_create_root_bus Yinghai Lu
2012-02-28 22:07 ` [PATCH 07/24] PCI: checking busn_res in pci_scan_root_bus Yinghai Lu
2012-02-28 22:07 ` [PATCH 08/24] PCI: default busn_resource Yinghai Lu
2012-02-28 22:07 ` [PATCH 09/24] PCI: add default res for pci_scan_bus Yinghai Lu
2012-02-28 22:07 ` [PATCH 10/24] x86, PCI: put busn resource in pci_root_info for acpi path Yinghai Lu
2012-02-28 22:07 ` [PATCH 11/24] x86, PCI: put busn resource in pci_root_info for no_crs path Yinghai Lu
2012-02-28 22:07 ` [PATCH 12/24] PCI, ia64: Register busn_res for root buses Yinghai Lu
2012-02-29 0:01 ` Bjorn Helgaas
2012-02-29 0:12 ` Yinghai Lu
2012-02-29 0:22 ` Bjorn Helgaas
2012-02-29 4:26 ` Yinghai Lu
2012-02-28 22:07 ` [PATCH 13/24] PCI, sparc: " Yinghai Lu
2012-02-28 22:07 ` [PATCH 14/24] PCI, powerpc: " Yinghai Lu
2012-02-28 22:07 ` [PATCH 15/24] PCI, parisc: " Yinghai Lu
2012-02-28 22:07 ` [PATCH 16/24] PCI: Add pci_bus_extend/shrink_top() Yinghai Lu
2012-02-28 22:07 ` [PATCH 17/24] PCI: Probe safe range that we can use for unassigned bridge Yinghai Lu
2012-02-28 22:07 ` [PATCH 18/24] PCI: Strict checking of valid range for bridge Yinghai Lu
2012-02-28 22:07 ` [PATCH 19/24] PCI: Allocate bus range instead of use max blindly Yinghai Lu
2012-02-28 22:07 ` [PATCH 20/24] PCI: kill pci_fixup_parent_subordinate_busnr() Yinghai Lu
2012-02-28 22:07 ` Yinghai Lu [this message]
2012-02-28 22:07 ` [PATCH 22/24] pcmcia: remove workaround for fixing pci parent bus subordinate Yinghai Lu
2012-02-28 22:07 ` [PATCH 23/24] PCI: Double checking setting for bus register and bus struct Yinghai Lu
2012-02-28 22:07 ` [PATCH 24/24] PCI, pciehp: Remove not needed bus number range checking Yinghai Lu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1330466863-28469-22-git-send-email-yinghai@kernel.org \
--to=yinghai@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=benh@kernel.crashing.org \
--cc=bhelgaas@google.com \
--cc=davem@davemloft.net \
--cc=gregkh@linuxfoundation.org \
--cc=jbarnes@virtuousgeek.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux@dominikbrodowski.net \
--cc=tony.luck@intel.com \
--cc=torvalds@linux-foundation.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).