diff options
author | Murillo Fernandes Bernardes <bernarde@br.ibm.com> | 2007-08-10 22:31:00 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-08-11 15:58:12 -0700 |
commit | f055a0619aae795832ef6a783021184925758b67 (patch) | |
tree | 56fb79b8aea479310be34664576119e5b5cbd4c6 | |
parent | 3320ad994afb2c44ad34b3b34c3c5cf0da297331 (diff) |
x86_64: Calgary - Fix mis-handled PCI topology
Current code assumed that devices were directly connected to a Calgary
bridge, as it tried to get the iommu table directly from the parent bus
controller.
When we have another bridge between the Calgary/CalIOC2 bridge and the
device we should look upwards until we get to the top (Calgary/CalIOC2
bridge), where the iommu table resides.
Signed-off-by: Murillo Fernandes Bernardes <mfb@br.ibm.com>
Signed-off-by: Muli Ben-Yehuda <muli@il.ibm.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/x86_64/kernel/pci-calgary.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index ba16c968ca3..71da01e73f0 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -367,16 +367,15 @@ static inline struct iommu_table *find_iommu_table(struct device *dev) pdev = to_pci_dev(dev); - /* is the device behind a bridge? */ - if (unlikely(pdev->bus->parent)) - pbus = pdev->bus->parent; - else - pbus = pdev->bus; + pbus = pdev->bus; + + /* is the device behind a bridge? Look for the root bus */ + while (pbus->parent) + pbus = pbus->parent; tbl = pci_iommu(pbus); - BUG_ON(pdev->bus->parent && - (tbl->it_busno != pdev->bus->parent->number)); + BUG_ON(tbl && (tbl->it_busno != pbus->number)); return tbl; } |