Re: [PATCH v1] PCI: work around Stratus ftServer broken PCIe hierarchy

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Apr 26, 2012 at 9:35 PM, Wei Yang <weiyang.kernel@xxxxxxxxx> wrote:
> Bjorn
>
> One question, both Upstream and DownStream port is represented by
> pci_dev in kernel?

Yes.

> 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


[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux