Message ID | 20120425233632.12292.32916.stgit@bhelgaas.mtv.corp.google.com |
---|---|
State | Accepted |
Headers | show |
On Wed, Apr 25, 2012 at 4:36 PM, Bjorn Helgaas <bhelgaas@google.com> wrote: > 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. is there output for lspci -vvxxx -s 03:00.0 lspci -vvxxx -s 03:00.1 like to know what is the 03:00.0. Thanks Yinghai -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 04/25/2012 07:36 PM, Bjorn Helgaas wrote: > 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@redhat.com> > CC: Don Dutile <ddutile@redhat.com> > CC: James Paradis <jim.paradis@stratus.com> Nuts. This is my fault. I'm so used to calling him "Jim" that I screwed up his email address. It should be james.paradis@stratus.com . Jim, can you retest with this updated version of the patch so we can confirm it works? http://marc.info/?l=linux-pci&m=133539711207345&w=2 Thanks, P. -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 04/25/2012 08:30 PM, Yinghai Lu wrote: > On Wed, Apr 25, 2012 at 4:36 PM, Bjorn Helgaas <bhelgaas@google.com> wrote: >> 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. > > is there output for > lspci -vvxxx -s 03:00.0 > lspci -vvxxx -s 03:00.1 > > like to know what is the 03:00.0. [Adding correct email addy for Jim@stratus] Jim, can you provide this output? Thanks, P. > > Thanks > > Yinghai -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Apr 26, 2012 at 6:29 AM, Prarit Bhargava <prarit@redhat.com> wrote: > > > On 04/25/2012 08:30 PM, Yinghai Lu wrote: >> On Wed, Apr 25, 2012 at 4:36 PM, Bjorn Helgaas <bhelgaas@google.com> wrote: >>> 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. >> >> is there output for >> lspci -vvxxx -s 03:00.0 >> lspci -vvxxx -s 03:00.1 >> >> like to know what is the 03:00.0. > > [Adding correct email addy for Jim@stratus] > > Jim, can you provide this output? Also note that I only looked for "ftServer" in the DMI SYS_VENDOR field. Prarit's original patch looked at both SYS_VENDOR and BOARD_VENDOR. I don't know whether BOARD_VENDOR is necessary. My guess was dmi_name_in_vendors() was just a convenient interface, and we only need to check one place. Bjorn -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Bjorn One question, both Upstream and DownStream port is represented by pci_dev in kernel? 2012/4/26 Bjorn Helgaas <bhelgaas@google.com>: > 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@redhat.com> > CC: Don Dutile <ddutile@redhat.com> > CC: James Paradis <jim.paradis@stratus.com> > CC: Matthew Wilcox <matthew.wilcox@linux.intel.com> > CC: Jesse Barnes <jbarnes@virtuousgeek.org> > CC: Prarit Bhargava <prarit@redhat.com> > Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> > --- > 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@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Apr 26, 2012 at 9:35 PM, Wei Yang <weiyang.kernel@gmail.com> wrote: > Bjorn > > One question, both Upstream and DownStream port is represented by > pci_dev in kernel? Yes. > 2012/4/26 Bjorn Helgaas <bhelgaas@google.com>: >> 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@redhat.com> >> CC: Don Dutile <ddutile@redhat.com> >> CC: James Paradis <jim.paradis@stratus.com> >> CC: Matthew Wilcox <matthew.wilcox@linux.intel.com> >> CC: Jesse Barnes <jbarnes@virtuousgeek.org> >> CC: Prarit Bhargava <prarit@redhat.com> >> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> >> --- >> 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@vger.kernel.org >> 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@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Apr 25, 2012 at 05:36:32PM -0600, Bjorn Helgaas wrote: > @@ -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. We should probably s/device/slot/ throughout. I've recently become aware of a hype-rvisor that doesn't include PCI device number remapping, so if you assign, say, function 03.6 to a guest, the PCI scanning code doesn't find it.
On Sat, Apr 28, 2012 at 1:26 PM, Matthew Wilcox <matthew@wil.cx> wrote: > On Wed, Apr 25, 2012 at 05:36:32PM -0600, Bjorn Helgaas wrote: >> @@ -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. > > We should probably s/device/slot/ throughout. I've recently become > aware of a hype-rvisor that doesn't include PCI device number remapping, > so if you assign, say, function 03.6 to a guest, the PCI scanning code > doesn't find it. "Device" has a clear meaning in the context of PCIe addressing, i.e., bus/device/function numbers. But the spec uses "slot" to refer to a physical place where an add-in card can be inserted and things related to that place, e.g., power, hot-plug buttons, latches, chassis labels, etc. So I don't understand what you're proposing here. I don't know what "scan all possible PCIe slots" would mean because I don't know what that change would look like in the code. Bjorn -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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
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@redhat.com> CC: Don Dutile <ddutile@redhat.com> CC: James Paradis <jim.paradis@stratus.com> CC: Matthew Wilcox <matthew.wilcox@linux.intel.com> CC: Jesse Barnes <jbarnes@virtuousgeek.org> CC: Prarit Bhargava <prarit@redhat.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> --- 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(-) -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html