diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2012-04-30 17:21:02 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-04-30 17:21:02 -0400 |
commit | 284f5f9dbac170b054c1e386ef92cbf654e91bba (patch) | |
tree | 74cacc94070d5590378c368fa7378d37319d07be /drivers/pci/probe.c | |
parent | 66f75a5d028beaf67c931435fdc3e7823125730c (diff) |
PCI: work around Stratus ftServer broken PCIe hierarchy
A PCIe downstream port is a P2P bridge. Its secondary interface is
a link that should lead only to device 0 (unless ARI is enabled)[1], so
we don't probe for non-zero device numbers.
Some Stratus ftServer systems have a PCIe downstream port (02:00.0) that
leads to both an upstream port (03:00.0) and a downstream port (03:01.0),
and 03:01.0 has important devices below it:
[0000:02]-+-00.0-[03-3c]--+-00.0-[04-09]--...
\-01.0-[0a-0d]--+-[USB]
+-[NIC]
+-...
Previously, we didn't enumerate device 03:01.0, so USB and the network
didn't work. This patch adds a DMI quirk to scan all device numbers,
not just 0, below a downstream port.
Based on a patch by Prarit Bhargava.
[1] PCIe spec r3.0, sec 7.3.1
CC: Myron Stowe <mstowe@redhat.com>
CC: Don Dutile <ddutile@redhat.com>
CC: James Paradis <james.paradis@stratus.com>
CC: Matthew Wilcox <matthew.r.wilcox@intel.com>
CC: Jesse Barnes <jbarnes@virtuousgeek.org>
CC: Prarit Bhargava <prarit@redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 5e1ca3c58a7d..2dc8675eea1a 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/cpumask.h> | 11 | #include <linux/cpumask.h> |
12 | #include <linux/pci-aspm.h> | 12 | #include <linux/pci-aspm.h> |
13 | #include <asm-generic/pci-bridge.h> | ||
13 | #include "pci.h" | 14 | #include "pci.h" |
14 | 15 | ||
15 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ | 16 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ |
@@ -1395,10 +1396,13 @@ static unsigned no_next_fn(struct pci_dev *dev, unsigned fn) | |||
1395 | static int only_one_child(struct pci_bus *bus) | 1396 | static int only_one_child(struct pci_bus *bus) |
1396 | { | 1397 | { |
1397 | struct pci_dev *parent = bus->self; | 1398 | struct pci_dev *parent = bus->self; |
1399 | |||
1398 | if (!parent || !pci_is_pcie(parent)) | 1400 | if (!parent || !pci_is_pcie(parent)) |
1399 | return 0; | 1401 | return 0; |
1400 | if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT || | 1402 | if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT) |
1401 | parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) | 1403 | return 1; |
1404 | if (parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM && | ||
1405 | !pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS)) | ||
1402 | return 1; | 1406 | return 1; |
1403 | return 0; | 1407 | return 0; |
1404 | } | 1408 | } |