Bjorn One question, both Upstream and DownStream port is represented by pci_dev in kernel? 2012/4/26 Bjorn Helgaas <bhelgaas@xxxxxxxxxx>: > 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-[0000:03]--+-00.0 > \-01.0-[0000:xx]--+-[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@xxxxxxxxxx> > CC: Don Dutile <ddutile@xxxxxxxxxx> > CC: James Paradis <jim.paradis@xxxxxxxxxxx> > CC: Matthew Wilcox <matthew.wilcox@xxxxxxxxxxxxxxx> > CC: Jesse Barnes <jbarnes@xxxxxxxxxxxxxxxx> > CC: Prarit Bhargava <prarit@xxxxxxxxxx> > Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> > --- > Documentation/kernel-parameters.txt | 3 +++ > arch/x86/pci/common.c | 16 ++++++++++++++++ > drivers/pci/pci.c | 3 +++ > drivers/pci/probe.c | 8 ++++++-- > include/asm-generic/pci-bridge.h | 6 ++++++ > 5 files changed, 34 insertions(+), 2 deletions(-) > > diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt > index c1601e5..57c3870 100644 > --- a/Documentation/kernel-parameters.txt > +++ b/Documentation/kernel-parameters.txt > @@ -2161,6 +2161,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. > on: Turn realloc on > realloc same as realloc=on > noari do not use PCIe ARI. > + pcie_scan_all Scan all possible PCIE devices. Otherwise we > + only look for one device below a PCIE downstream > + port. > > pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power > Management. > diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c > index 323481e..16c5d78 100644 > --- a/arch/x86/pci/common.c > +++ b/arch/x86/pci/common.c > @@ -11,6 +11,7 @@ > #include <linux/dmi.h> > #include <linux/slab.h> > > +#include <asm-generic/pci-bridge.h> > #include <asm/acpi.h> > #include <asm/segment.h> > #include <asm/io.h> > @@ -229,6 +230,14 @@ static int __devinit assign_all_busses(const struct dmi_system_id *d) > } > #endif > > +static int __devinit set_scan_all(const struct dmi_system_id *d) > +{ > + printk(KERN_INFO "PCI: %s detected, enabling pci=pcie_scan_all\n", > + d->ident); > + pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS); > + return 0; > +} > + > static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = { > #ifdef __i386__ > /* > @@ -420,6 +429,13 @@ static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = { > DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"), > }, > }, > + { > + .callback = set_scan_all, > + .ident = "Stratus/NEC ftServer", > + .matches = { > + DMI_MATCH(DMI_SYS_VENDOR, "ftServer"), > + }, > + }, > {} > }; > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c > index 9e31c0a..8f16900 100644 > --- a/drivers/pci/pci.c > +++ b/drivers/pci/pci.c > @@ -22,6 +22,7 @@ > #include <linux/interrupt.h> > #include <linux/device.h> > #include <linux/pm_runtime.h> > +#include <asm-generic/pci-bridge.h> > #include <asm/setup.h> > #include "pci.h" > > @@ -3900,6 +3901,8 @@ static int __init pci_setup(char *str) > pcie_bus_config = PCIE_BUS_PERFORMANCE; > } else if (!strncmp(str, "pcie_bus_peer2peer", 18)) { > pcie_bus_config = PCIE_BUS_PEER2PEER; > + } else if (!strncmp(str, "pcie_scan_all", 13)) { > + pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS); > } else { > printk(KERN_ERR "PCI: Unknown option `%s'\n", > str); > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c > index 5e1ca3c..2dc8675 100644 > --- a/drivers/pci/probe.c > +++ b/drivers/pci/probe.c > @@ -10,6 +10,7 @@ > #include <linux/module.h> > #include <linux/cpumask.h> > #include <linux/pci-aspm.h> > +#include <asm-generic/pci-bridge.h> > #include "pci.h" > > #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ > @@ -1395,10 +1396,13 @@ static unsigned no_next_fn(struct pci_dev *dev, unsigned fn) > static int only_one_child(struct pci_bus *bus) > { > struct pci_dev *parent = bus->self; > + > if (!parent || !pci_is_pcie(parent)) > return 0; > - if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT || > - parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) > + if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT) > + return 1; > + if (parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM && > + !pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS)) > return 1; > return 0; > } > diff --git a/include/asm-generic/pci-bridge.h b/include/asm-generic/pci-bridge.h > index a5b5d5a..20db2e5 100644 > --- a/include/asm-generic/pci-bridge.h > +++ b/include/asm-generic/pci-bridge.h > @@ -30,6 +30,12 @@ enum { > PCI_ENABLE_PROC_DOMAINS = 0x00000010, > /* ... except for domain 0 */ > PCI_COMPAT_DOMAIN_0 = 0x00000020, > + > + /* PCIe downstream ports are bridges that normally lead to only a > + * device 0, but if this is set, we scan all possible devices, not > + * just device 0. > + */ > + PCI_SCAN_ALL_PCIE_DEVS = 0x00000040, > }; > > #ifdef CONFIG_PCI > > -- > To unsubscribe from this list: send the line "unsubscribe linux-pci" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Richard Yang Help You, Help Me -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html