* [PATCH] pci: Workaround Stratus broken PCIE hierarchy
@ 2011-11-10 14:00 Prarit Bhargava
2011-11-10 14:31 ` Matthew Wilcox
0 siblings, 1 reply; 26+ messages in thread
From: Prarit Bhargava @ 2011-11-10 14:00 UTC (permalink / raw)
To: linux-pci
Cc: Prarit Bhargava, mstowe, ddutile, jparadis, matthew.wilcox,
jbarnes
Stratus systems have a hierarchy that includes a PCIE Downstream bridge
connected to a PCIE Upstream bridge and a PCI Downstream bridge. The system
boots with this wrong hierarchy into a crippled mode (USB doesn't work,
network doesn't work ...). Avoiding the Downstream bridge check in
only_one_child() causes all the bridges to be enumerated and the system
to function properly.
Unfortunately this hardware is currently available so we should at least
keep it functional.
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Cc: mstowe@redhat.com
Cc: ddutile@redhat.com
Cc: jparadis@redhat.com
Cc: matthew.wilcox@linux.intel.com
Cc: jbarnes@virtuousgeek.org
---
drivers/pci/probe.c | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 04e74f4..bc76812 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 <linux/dmi.h>
#include "pci.h"
#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */
@@ -1275,7 +1276,15 @@ 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 ||
+ if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+ return 1;
+ /*
+ * Stratus/NEC ftServer systems have a broken PCIE hierarchy in which
+ * one upstream and one downstream port are plugged into a downstream
+ * port. Avoiding the downstream port check here results in a
+ * functional system.
+ */
+ if (!dmi_name_in_vendors("ftServer") &&
parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
return 1;
return 0;
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-10 14:00 [PATCH] pci: Workaround Stratus broken PCIE hierarchy Prarit Bhargava
@ 2011-11-10 14:31 ` Matthew Wilcox
2011-11-10 16:50 ` Don Dutile
0 siblings, 1 reply; 26+ messages in thread
From: Matthew Wilcox @ 2011-11-10 14:31 UTC (permalink / raw)
To: Prarit Bhargava
Cc: linux-pci, mstowe, ddutile, jparadis, matthew.wilcox, jbarnes
On Thu, Nov 10, 2011 at 09:00:13AM -0500, Prarit Bhargava wrote:
> Stratus systems have a hierarchy that includes a PCIE Downstream bridge
> connected to a PCIE Upstream bridge and a PCI Downstream bridge. The system
> boots with this wrong hierarchy into a crippled mode (USB doesn't work,
> network doesn't work ...). Avoiding the Downstream bridge check in
> only_one_child() causes all the bridges to be enumerated and the system
> to function properly.
> @@ -1275,7 +1276,15 @@ 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 ||
> + if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
> + return 1;
> + /*
> + * Stratus/NEC ftServer systems have a broken PCIE hierarchy in which
> + * one upstream and one downstream port are plugged into a downstream
> + * port. Avoiding the downstream port check here results in a
> + * functional system.
> + */
> + if (!dmi_name_in_vendors("ftServer") &&
> parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
> return 1;
> return 0;
dmi_name_in_vendors is relatively expensive, so the order of these two
should be swapped, at least:
> if (parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM &&
> !dmi_name_in_vendors("ftServer"))
Plus, this gets called for every PCI bridge. We should be caching it
somewhere, so it's only called once.
--
Matthew Wilcox Intel Open Source Technology Centre
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours. We can't possibly take such
a retrograde step."
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-10 14:31 ` Matthew Wilcox
@ 2011-11-10 16:50 ` Don Dutile
2011-11-11 17:41 ` James Paradis
0 siblings, 1 reply; 26+ messages in thread
From: Don Dutile @ 2011-11-10 16:50 UTC (permalink / raw)
To: Matthew Wilcox
Cc: Prarit Bhargava, linux-pci, mstowe, jparadis, matthew.wilcox,
jbarnes
On 11/10/2011 09:31 AM, Matthew Wilcox wrote:
> On Thu, Nov 10, 2011 at 09:00:13AM -0500, Prarit Bhargava wrote:
>> Stratus systems have a hierarchy that includes a PCIE Downstream bridge
>> connected to a PCIE Upstream bridge and a PCI Downstream bridge. The system
>> boots with this wrong hierarchy into a crippled mode (USB doesn't work,
>> network doesn't work ...). Avoiding the Downstream bridge check in
>> only_one_child() causes all the bridges to be enumerated and the system
>> to function properly.
>
>> @@ -1275,7 +1276,15 @@ 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 ||
>> + if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
>> + return 1;
>> + /*
>> + * Stratus/NEC ftServer systems have a broken PCIE hierarchy in which
>> + * one upstream and one downstream port are plugged into a downstream
>> + * port. Avoiding the downstream port check here results in a
>> + * functional system.
>> + */
>> + if (!dmi_name_in_vendors("ftServer")&&
>> parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
>> return 1;
>> return 0;
>
> dmi_name_in_vendors is relatively expensive, so the order of these two
> should be swapped, at least:
>
>> if (parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM&&
>> !dmi_name_in_vendors("ftServer"))
>
> Plus, this gets called for every PCI bridge. We should be caching it
> somewhere, so it's only called once.
>
Then i recommend a dmi_name_in_vendors() check at init; stick result in
global (or local static), and then it's not exec'd on each bridge, just
a simple flag check.
If that's the case, I'd re-cast my vote for putting the code in pci_quirks
with an export, so it is tracked as a quirk. that may get messy
wrt other arches though (the export in common code; not sure if quirks is
included on all arches).
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-10 16:50 ` Don Dutile
@ 2011-11-11 17:41 ` James Paradis
2011-11-11 19:13 ` Don Dutile
0 siblings, 1 reply; 26+ messages in thread
From: James Paradis @ 2011-11-11 17:41 UTC (permalink / raw)
To: Don Dutile
Cc: Prarit Bhargava, linux-pci, mstowe, matthew wilcox, jbarnes,
Matthew Wilcox
Hmmm... would it be better to do this as a quirk or as a boot
parameter? I've heard reports that other systems may be running
into similar issues... if we don't know exactly which systems
these are then maybe a boot parameter would be a more flexible
approach...
--jim
----- Original Message -----
> On 11/10/2011 09:31 AM, Matthew Wilcox wrote:
> > On Thu, Nov 10, 2011 at 09:00:13AM -0500, Prarit Bhargava wrote:
> >> Stratus systems have a hierarchy that includes a PCIE Downstream
> >> bridge
> >> connected to a PCIE Upstream bridge and a PCI Downstream bridge.
> >> The system
> >> boots with this wrong hierarchy into a crippled mode (USB doesn't
> >> work,
> >> network doesn't work ...). Avoiding the Downstream bridge check
> >> in
> >> only_one_child() causes all the bridges to be enumerated and the
> >> system
> >> to function properly.
> >
> >> @@ -1275,7 +1276,15 @@ 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 ||
> >> + if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
> >> + return 1;
> >> + /*
> >> + * Stratus/NEC ftServer systems have a broken PCIE hierarchy in
> >> which
> >> + * one upstream and one downstream port are plugged into a
> >> downstream
> >> + * port. Avoiding the downstream port check here results in a
> >> + * functional system.
> >> + */
> >> + if (!dmi_name_in_vendors("ftServer")&&
> >> parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
> >> return 1;
> >> return 0;
> >
> > dmi_name_in_vendors is relatively expensive, so the order of these
> > two
> > should be swapped, at least:
> >
> >> if (parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM&&
> >> !dmi_name_in_vendors("ftServer"))
> >
> > Plus, this gets called for every PCI bridge. We should be caching
> > it
> > somewhere, so it's only called once.
> >
> Then i recommend a dmi_name_in_vendors() check at init; stick result
> in
> global (or local static), and then it's not exec'd on each bridge,
> just
> a simple flag check.
> If that's the case, I'd re-cast my vote for putting the code in
> pci_quirks
> with an export, so it is tracked as a quirk. that may get messy
> wrt other arches though (the export in common code; not sure if
> quirks is
> included on all arches).
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-11 17:41 ` James Paradis
@ 2011-11-11 19:13 ` Don Dutile
2011-11-11 20:29 ` Bjorn Helgaas
0 siblings, 1 reply; 26+ messages in thread
From: Don Dutile @ 2011-11-11 19:13 UTC (permalink / raw)
To: James Paradis
Cc: Prarit Bhargava, linux-pci, mstowe, matthew wilcox, jbarnes,
Matthew Wilcox
On 11/11/2011 12:41 PM, James Paradis wrote:
> Hmmm... would it be better to do this as a quirk or as a boot
> parameter? I've heard reports that other systems may be running
Hearsay? if you have definite cases, then please share them,
so folks know when to flip the boot parameter on.
note: it would have to be an early boot param as well.
> into similar issues... if we don't know exactly which systems
> these are then maybe a boot parameter would be a more flexible
> approach...
>
> --jim
>
> ----- Original Message -----
>> On 11/10/2011 09:31 AM, Matthew Wilcox wrote:
>>> On Thu, Nov 10, 2011 at 09:00:13AM -0500, Prarit Bhargava wrote:
>>>> Stratus systems have a hierarchy that includes a PCIE Downstream
>>>> bridge
>>>> connected to a PCIE Upstream bridge and a PCI Downstream bridge.
>>>> The system
>>>> boots with this wrong hierarchy into a crippled mode (USB doesn't
>>>> work,
>>>> network doesn't work ...). Avoiding the Downstream bridge check
>>>> in
>>>> only_one_child() causes all the bridges to be enumerated and the
>>>> system
>>>> to function properly.
>>>
>>>> @@ -1275,7 +1276,15 @@ 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 ||
>>>> + if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
>>>> + return 1;
>>>> + /*
>>>> + * Stratus/NEC ftServer systems have a broken PCIE hierarchy in
>>>> which
>>>> + * one upstream and one downstream port are plugged into a
>>>> downstream
>>>> + * port. Avoiding the downstream port check here results in a
>>>> + * functional system.
>>>> + */
>>>> + if (!dmi_name_in_vendors("ftServer")&&
>>>> parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
>>>> return 1;
>>>> return 0;
>>>
>>> dmi_name_in_vendors is relatively expensive, so the order of these
>>> two
>>> should be swapped, at least:
>>>
>>>> if (parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM&&
>>>> !dmi_name_in_vendors("ftServer"))
>>>
>>> Plus, this gets called for every PCI bridge. We should be caching
>>> it
>>> somewhere, so it's only called once.
>>>
>> Then i recommend a dmi_name_in_vendors() check at init; stick result
>> in
>> global (or local static), and then it's not exec'd on each bridge,
>> just
>> a simple flag check.
>> If that's the case, I'd re-cast my vote for putting the code in
>> pci_quirks
>> with an export, so it is tracked as a quirk. that may get messy
>> wrt other arches though (the export in common code; not sure if
>> quirks is
>> included on all arches).
>>
>>
> --
> 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
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-11 19:13 ` Don Dutile
@ 2011-11-11 20:29 ` Bjorn Helgaas
2011-11-11 20:35 ` Don Dutile
2011-11-15 22:27 ` James Paradis
0 siblings, 2 replies; 26+ messages in thread
From: Bjorn Helgaas @ 2011-11-11 20:29 UTC (permalink / raw)
To: Don Dutile
Cc: James Paradis, Prarit Bhargava, linux-pci, mstowe, matthew wilcox,
jbarnes, Matthew Wilcox
On Fri, Nov 11, 2011 at 12:13 PM, Don Dutile <ddutile@redhat.com> wrote:
> On 11/11/2011 12:41 PM, James Paradis wrote:
>>
>> Hmmm... would it be better to do this as a quirk or as a boot
>> parameter? I've heard reports that other systems may be running
>
> Hearsay? if you have definite cases, then please share them,
> so folks know when to flip the boot parameter on. note: it would have to be
> an early boot param as well.
It'd definitely be good to know all the specific cases.
But merely sharing them so folks will know when to use the parameter
is a broken model. We should make it work automatically, either with
some sort of machine-dependent quirk, or (preferably) with a change to
the generic algorithm so it can handle these "broken" topologies along
with all the correct ones.
Bjorn
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-11 20:29 ` Bjorn Helgaas
@ 2011-11-11 20:35 ` Don Dutile
2011-11-14 14:44 ` Prarit Bhargava
2011-11-15 22:27 ` James Paradis
1 sibling, 1 reply; 26+ messages in thread
From: Don Dutile @ 2011-11-11 20:35 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: James Paradis, Prarit Bhargava, linux-pci, mstowe, matthew wilcox,
jbarnes, Matthew Wilcox
On 11/11/2011 03:29 PM, Bjorn Helgaas wrote:
> On Fri, Nov 11, 2011 at 12:13 PM, Don Dutile<ddutile@redhat.com> wrote:
>> On 11/11/2011 12:41 PM, James Paradis wrote:
>>>
>>> Hmmm... would it be better to do this as a quirk or as a boot
>>> parameter? I've heard reports that other systems may be running
>>
>> Hearsay? if you have definite cases, then please share them,
>> so folks know when to flip the boot parameter on. note: it would have to be
>> an early boot param as well.
>
> It'd definitely be good to know all the specific cases.
>
> But merely sharing them so folks will know when to use the parameter
> is a broken model. We should make it work automatically, either with
> some sort of machine-dependent quirk, or (preferably) with a change to
> the generic algorithm so it can handle these "broken" topologies along
> with all the correct ones.
>
> Bjorn
In this case, doing a check that the parent is downstream PPB and the child is
downstream PPB could be done to identify the broken topology and automatically
scan dev nums > 0.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-11 20:35 ` Don Dutile
@ 2011-11-14 14:44 ` Prarit Bhargava
2011-11-14 18:14 ` Matthew Wilcox
0 siblings, 1 reply; 26+ messages in thread
From: Prarit Bhargava @ 2011-11-14 14:44 UTC (permalink / raw)
To: Don Dutile
Cc: Bjorn Helgaas, James Paradis, linux-pci, mstowe, matthew wilcox,
jbarnes, Matthew Wilcox
On 11/11/2011 03:35 PM, Don Dutile wrote:
> On 11/11/2011 03:29 PM, Bjorn Helgaas wrote:
>> On Fri, Nov 11, 2011 at 12:13 PM, Don Dutile<ddutile@redhat.com> wrote:
>>> On 11/11/2011 12:41 PM, James Paradis wrote:
>>>>
>>>> Hmmm... would it be better to do this as a quirk or as a boot
>>>> parameter? I've heard reports that other systems may be running
>>>
>>> Hearsay? if you have definite cases, then please share them,
>>> so folks know when to flip the boot parameter on. note: it would have to be
>>> an early boot param as well.
>>
>> It'd definitely be good to know all the specific cases.
>>
>> But merely sharing them so folks will know when to use the parameter
>> is a broken model.
Yeah -- I'd rather do something that "works", but I'm not sure we can without dropping the only_one_child() check.
We should make it work automatically, either with
>> some sort of machine-dependent quirk, or (preferably) with a change to
>> the generic algorithm so it can handle these "broken" topologies along
>> with all the correct ones.
The problem is when I'm examining "this" PCIE bridge I have no knowledge of the remaining hierarchy below it. In order to find the broken topology we need to do a two pass enumeration (NO.) or minimally query all possible devices immediately connected to it. If we do that then what is the purpose of the only_one_child() check?
> In this case, doing a check that the parent is downstream PPB and the child is
> downstream PPB could be done to identify the broken topology and automatically
> scan dev nums > 0.
I'm in favor of adding a kernel parameter that in addition to implementing the workaround Stratus will have, will also dump out a HW_ERR broken message of some sort. I don't want to see a stack trace.
... maybe we need to add in a pci_bridge_quirk() or something?
P.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-14 14:44 ` Prarit Bhargava
@ 2011-11-14 18:14 ` Matthew Wilcox
2011-11-14 19:50 ` Prarit Bhargava
2011-11-15 15:56 ` Prarit Bhargava
0 siblings, 2 replies; 26+ messages in thread
From: Matthew Wilcox @ 2011-11-14 18:14 UTC (permalink / raw)
To: Prarit Bhargava
Cc: Don Dutile, Bjorn Helgaas, James Paradis, linux-pci, mstowe,
matthew wilcox, jbarnes
On Mon, Nov 14, 2011 at 09:44:50AM -0500, Prarit Bhargava wrote:
> On 11/11/2011 03:35 PM, Don Dutile wrote:
> We should make it work automatically, either with
> >> some sort of machine-dependent quirk, or (preferably) with a change to
> >> the generic algorithm so it can handle these "broken" topologies along
> >> with all the correct ones.
>
> The problem is when I'm examining "this" PCIE bridge I have no knowledge of the remaining hierarchy below it. In order to find the broken topology we need to do a two pass enumeration (NO.) or minimally query all possible devices immediately connected to it. If we do that then what is the purpose of the only_one_child() check?
We have enough information to do this quirk.
pci_scan_slot calls pci_scan_single_device() for the devfn 0.
We can look at the device we found and quirk the parent device.
Something like this ...
int pci_scan_slot(struct pci_bus *bus, int devfn)
[...]
dev = pci_scan_single_device(bus, devfn);
if (!dev)
return 0;
if (!dev->is_added)
nr++;
+ /* Quirk to fix NEC/Stratus broken PCIe topologies */
+ if ((dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) &&
+ (bus->self->pcie_type == PCI_EXP_TYPE_DOWNSTREAM))
+ bus->self->pcie_type = PCI_EXP_TYPE_UPSTREAM;
if (pci_ari_enabled(bus))
next_fn = next_ari_fn;
[...]
As an aside, I'm quite shocked that this patch has been in the kernel
for almost two years and this is the first time anybody's tested it on
one of these systems.
--
Matthew Wilcox Intel Open Source Technology Centre
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours. We can't possibly take such
a retrograde step."
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-14 18:14 ` Matthew Wilcox
@ 2011-11-14 19:50 ` Prarit Bhargava
2011-11-15 20:16 ` Matthew Wilcox
2011-11-15 15:56 ` Prarit Bhargava
1 sibling, 1 reply; 26+ messages in thread
From: Prarit Bhargava @ 2011-11-14 19:50 UTC (permalink / raw)
To: Matthew Wilcox
Cc: Don Dutile, Bjorn Helgaas, James Paradis, linux-pci, mstowe,
matthew wilcox, jbarnes
On 11/14/2011 01:14 PM, Matthew Wilcox wrote:
> On Mon, Nov 14, 2011 at 09:44:50AM -0500, Prarit Bhargava wrote:
>> On 11/11/2011 03:35 PM, Don Dutile wrote:
>> We should make it work automatically, either with
>>>> some sort of machine-dependent quirk, or (preferably) with a change to
>>>> the generic algorithm so it can handle these "broken" topologies along
>>>> with all the correct ones.
>>
>> The problem is when I'm examining "this" PCIE bridge I have no knowledge of the remaining hierarchy below it. In order to find the broken topology we need to do a two pass enumeration (NO.) or minimally query all possible devices immediately connected to it. If we do that then what is the purpose of the only_one_child() check?
>
> We have enough information to do this quirk.
>
> pci_scan_slot calls pci_scan_single_device() for the devfn 0.
> We can look at the device we found and quirk the parent device.
> Something like this ...
>
> int pci_scan_slot(struct pci_bus *bus, int devfn)
> [...]
> dev = pci_scan_single_device(bus, devfn);
> if (!dev)
> return 0;
> if (!dev->is_added)
> nr++;
> + /* Quirk to fix NEC/Stratus broken PCIe topologies */
> + if ((dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) &&
> + (bus->self->pcie_type == PCI_EXP_TYPE_DOWNSTREAM))
> + bus->self->pcie_type = PCI_EXP_TYPE_UPSTREAM;
I'm undoubtedly missing something obvious here, or I'm being dense.
This only works if there is a single Down bridge connected to a single Down bridge. What Stratus/NEC has is a single Up bridge (02:00.0) connected to a Up bridge (03:00.0) and a Down bridge (03:01.0), which we know to be illegal in PCIE. So the scan of the first bridge, 03:00.0 works and no fixup is done. The code still misses the second bridge, 03:01.0.
Again -- I'm likely not seeing the bigger picture here or I'm missing something obvious why your patch works ... care to explain in detail?
>
> As an aside, I'm quite shocked that this patch has been in the kernel
> for almost two years and this is the first time anybody's tested it on
> one of these systems.
>
Heh ... we recently have asked some of our partners to monitor upstream more closely to avoid last minute "gotchyas" exactly like this one.
P.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-14 18:14 ` Matthew Wilcox
2011-11-14 19:50 ` Prarit Bhargava
@ 2011-11-15 15:56 ` Prarit Bhargava
2011-11-15 16:08 ` Rolf Eike Beer
` (2 more replies)
1 sibling, 3 replies; 26+ messages in thread
From: Prarit Bhargava @ 2011-11-15 15:56 UTC (permalink / raw)
To: Matthew Wilcox
Cc: Don Dutile, Bjorn Helgaas, James Paradis, linux-pci, mstowe,
jbarnes
Trying [v2]....
pci: Workaround Stratus broken PCIE hierarchy
Stratus systems have a hierarchy that includes a PCIE Downstream bridge
connected to a PCIE Upstream bridge and a PCI Downstream bridge. The system
boots with this wrong hierarchy into a crippled mode (USB doesn't work,
network doesn't work ...). Avoiding the Downstream bridge check in
only_one_child() causes all the bridges to be enumerated and the system
to function properly.
Unfortunately this hardware is currently available so we should at least
keep it functional.
[v2]
- ddutile@redhat.com requested drivers/pci/quirks.c code
- matthew@will.cx requested that dmi_name_in_vendors() be called only once with a static var check
- added a kernel parameter to enable scanning of all PCIE devices.
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index a0c5c5f..7af458f 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2069,6 +2069,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
on: Turn ECRC on.
realloc reallocate PCI resources if allocations done by BIOS
are erroneous.
+ pcie_scan_all Scan all possible PCIE devices.
pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
Management.
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6f45a73..f478bd5 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3589,6 +3589,9 @@ 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)) {
+ printk(KERN_ERR HW_ERR "PCIE: Scanning all devices.\n");
+ pcie_scan_all = 1;
} else {
printk(KERN_ERR "PCI: Unknown option `%s'\n",
str);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index b74084e..5a07895 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -309,11 +309,16 @@ struct pci_dev_reset_methods {
#ifdef CONFIG_PCI_QUIRKS
extern int pci_dev_specific_reset(struct pci_dev *dev, int probe);
+extern int is_broken_pcie_port(void);
#else
static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
{
return -ENOTTY;
}
+static inline int is_broken_pcie_port(void)
+{
+ return 0;
+}
#endif
#endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 04e74f4..fc88a9b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1270,13 +1270,18 @@ static unsigned no_next_fn(struct pci_dev *dev, unsigned fn)
return 0;
}
+int pcie_scan_all = 0; /* set via pci=pcie_scan_all */
static int only_one_child(struct pci_bus *bus)
{
struct pci_dev *parent = bus->self;
+ if (pcie_scan_all)
+ return 0;
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 &&
+ !is_broken_pcie_port())
return 1;
return 0;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 7285145..ef4d0e7 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3092,3 +3092,21 @@ int pci_dev_specific_reset(struct pci_dev *dev, int probe)
return -ENOTTY;
}
+
+static int _is_broken_pcie_port = -1;
+int is_broken_pcie_port(void)
+{
+ if (_is_broken_pcie_port >= 0)
+ return _is_broken_pcie_port;
+ /*
+ * Stratus/NEC ftServer systems have a broken PCIE hierarchy in which
+ * one upstream and one downstream port are plugged into a downstream
+ * port. Avoiding the downstream port check in only_one_child() results
+ * in a functional system.
+ */
+ if (dmi_name_in_vendors("ftServer"))
+ _is_broken_pcie_port = 1;
+ else
+ _is_broken_pcie_port = 0;
+ return _is_broken_pcie_port;
+}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 337df0d..745b98e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1647,5 +1647,7 @@ static inline void pci_release_bus_of_node(struct pci_bus *bus) { }
*/
struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev);
+/* set via pci=pcie_scan_all in order to enumerate all possible PCIE busses */
+extern int pcie_scan_all;
#endif /* __KERNEL__ */
#endif /* LINUX_PCI_H */
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-15 15:56 ` Prarit Bhargava
@ 2011-11-15 16:08 ` Rolf Eike Beer
2011-11-15 18:14 ` Bjorn Helgaas
2011-11-15 20:15 ` Matthew Wilcox
2011-11-15 21:53 ` James Paradis
2 siblings, 1 reply; 26+ messages in thread
From: Rolf Eike Beer @ 2011-11-15 16:08 UTC (permalink / raw)
To: Prarit Bhargava
Cc: Matthew Wilcox, Don Dutile, Bjorn Helgaas, James Paradis,
linux-pci, mstowe, jbarnes
> Trying [v2]....
>
>
> pci: Workaround Stratus broken PCIE hierarchy
>
> Stratus systems have a hierarchy that includes a PCIE Downstream bridge
> connected to a PCIE Upstream bridge and a PCI Downstream bridge. The
> system
> boots with this wrong hierarchy into a crippled mode (USB doesn't work,
> network doesn't work ...). Avoiding the Downstream bridge check in
> only_one_child() causes all the bridges to be enumerated and the system
> to function properly.
>
> Unfortunately this hardware is currently available so we should at least
> keep it functional.
>
> [v2]
> - ddutile@redhat.com requested drivers/pci/quirks.c code
> - matthew@will.cx requested that dmi_name_in_vendors() be called only once
> with a static var check
> - added a kernel parameter to enable scanning of all PCIE devices.
>
> Signed-off-by: Prarit Bhargava <prarit@redhat.com>
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 6f45a73..f478bd5 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -3589,6 +3589,9 @@ 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)) {
> + printk(KERN_ERR HW_ERR "PCIE: Scanning all devices.\n");
> + pcie_scan_all = 1;
> } else {
> printk(KERN_ERR "PCI: Unknown option `%s'\n",
> str);
To scan all devices isn't an error, is it? The user has requested this, so
KERN_INFO should be enough.
Eike
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-15 16:08 ` Rolf Eike Beer
@ 2011-11-15 18:14 ` Bjorn Helgaas
2011-11-15 18:25 ` Prarit Bhargava
0 siblings, 1 reply; 26+ messages in thread
From: Bjorn Helgaas @ 2011-11-15 18:14 UTC (permalink / raw)
To: Rolf Eike Beer
Cc: Prarit Bhargava, Matthew Wilcox, Don Dutile, James Paradis,
linux-pci, mstowe, jbarnes
On Tue, Nov 15, 2011 at 9:08 AM, Rolf Eike Beer <eike-kernel@sf-tec.de> wrote:
>> Trying [v2]....
>>
>>
>> pci: Workaround Stratus broken PCIE hierarchy
>>
>> Stratus systems have a hierarchy that includes a PCIE Downstream bridge
>> connected to a PCIE Upstream bridge and a PCI Downstream bridge. The
>> system
>> boots with this wrong hierarchy into a crippled mode (USB doesn't work,
>> network doesn't work ...). Avoiding the Downstream bridge check in
>> only_one_child() causes all the bridges to be enumerated and the system
>> to function properly.
>>
>> Unfortunately this hardware is currently available so we should at least
>> keep it functional.
>>
>> [v2]
>> - ddutile@redhat.com requested drivers/pci/quirks.c code
>> - matthew@will.cx requested that dmi_name_in_vendors() be called only once
>> with a static var check
>> - added a kernel parameter to enable scanning of all PCIE devices.
>>
>> Signed-off-by: Prarit Bhargava <prarit@redhat.com>
>>
>> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
>> index 6f45a73..f478bd5 100644
>> --- a/drivers/pci/pci.c
>> +++ b/drivers/pci/pci.c
>> @@ -3589,6 +3589,9 @@ 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)) {
>> + printk(KERN_ERR HW_ERR "PCIE: Scanning all devices.\n");
>> + pcie_scan_all = 1;
>> } else {
>> printk(KERN_ERR "PCI: Unknown option `%s'\n",
>> str);
>
> To scan all devices isn't an error, is it? The user has requested this, so
> KERN_INFO should be enough.
>
> Eike
Is this problem a regression? If so, what commit caused it?
f07852d6442, which introduced only_one_child()?
Does Windows work on this system?
Is this something that could be fixed by a firmware upgrade? If so,
is there a Stratus/NEC bug report?
Is there a Red Hat bugzilla URL you could include?
What bad things would happen if we just turned on this
Stratus-specific behavior all the time on all systems? It looks like
f07852d6442 is basically an optimization that makes pci_scan_slot()
faster, so I assume one effect would be to slow down PCI enumeration
for everybody. By how much?
Bjorn
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-15 18:14 ` Bjorn Helgaas
@ 2011-11-15 18:25 ` Prarit Bhargava
2011-11-15 21:08 ` James Paradis
0 siblings, 1 reply; 26+ messages in thread
From: Prarit Bhargava @ 2011-11-15 18:25 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Rolf Eike Beer, Matthew Wilcox, Don Dutile, James Paradis,
linux-pci, mstowe, jbarnes
Bjorn,
>
> Is this problem a regression? If so, what commit caused it?
> f07852d6442, which introduced only_one_child()?
That's a tough question to answer. AFAICT the broken (HARDWARE broken) Stratus systems only enumerated properly by chance. Did they work prior to f07852d6? From what jparadis told me, yes. Is it a regression? ... depends on how you look at it.
>
> Does Windows work on this system?
I don't know. jparadis? Any clue?
>
> Is this something that could be fixed by a firmware upgrade? If so,
> is there a Stratus/NEC bug report?
Hmmm, the idea of a FW upgrade somehow fixing this never occurred to me. jparadis? Is that possible?
>
> Is there a Red Hat bugzilla URL you could include?
Only happens upstream.
>
> What bad things would happen if we just turned on this
> Stratus-specific behavior all the time on all systems? It looks like
> f07852d6442 is basically an optimization that makes pci_scan_slot()
> faster, so I assume one effect would be to slow down PCI enumeration
> for everybody. By how much?
Not a huge amount -- estimated lt 0.5 seconds on this Stratus system. As for other systems, it obviously depends on how complicated the PCIE hierarchy is.
P.
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-15 15:56 ` Prarit Bhargava
2011-11-15 16:08 ` Rolf Eike Beer
@ 2011-11-15 20:15 ` Matthew Wilcox
2011-11-16 16:53 ` Prarit Bhargava
2011-11-15 21:53 ` James Paradis
2 siblings, 1 reply; 26+ messages in thread
From: Matthew Wilcox @ 2011-11-15 20:15 UTC (permalink / raw)
To: Prarit Bhargava
Cc: Don Dutile, Bjorn Helgaas, James Paradis, linux-pci, mstowe,
jbarnes
On Tue, Nov 15, 2011 at 10:56:03AM -0500, Prarit Bhargava wrote:
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 04e74f4..fc88a9b 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1270,13 +1270,18 @@ static unsigned no_next_fn(struct pci_dev *dev, unsigned fn)
> return 0;
> }
>
> +int pcie_scan_all = 0; /* set via pci=pcie_scan_all */
> static int only_one_child(struct pci_bus *bus)
> {
> struct pci_dev *parent = bus->self;
> + if (pcie_scan_all)
> + return 0;
> 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 &&
> + !is_broken_pcie_port())
> return 1;
> return 0;
> }
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index 7285145..ef4d0e7 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -3092,3 +3092,21 @@ int pci_dev_specific_reset(struct pci_dev *dev, int probe)
>
> return -ENOTTY;
> }
> +
> +static int _is_broken_pcie_port = -1;
> +int is_broken_pcie_port(void)
> +{
> + if (_is_broken_pcie_port >= 0)
> + return _is_broken_pcie_port;
> + /*
> + * Stratus/NEC ftServer systems have a broken PCIE hierarchy in which
> + * one upstream and one downstream port are plugged into a downstream
> + * port. Avoiding the downstream port check in only_one_child() results
> + * in a functional system.
> + */
> + if (dmi_name_in_vendors("ftServer"))
> + _is_broken_pcie_port = 1;
> + else
> + _is_broken_pcie_port = 0;
> + return _is_broken_pcie_port;
> +}
This feels like belt-and-braces. Why don't you just set pcie_scan_all
if the DMI string contains ftServer?
--
Matthew Wilcox Intel Open Source Technology Centre
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours. We can't possibly take such
a retrograde step."
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-14 19:50 ` Prarit Bhargava
@ 2011-11-15 20:16 ` Matthew Wilcox
0 siblings, 0 replies; 26+ messages in thread
From: Matthew Wilcox @ 2011-11-15 20:16 UTC (permalink / raw)
To: Prarit Bhargava
Cc: Don Dutile, Bjorn Helgaas, James Paradis, linux-pci, mstowe,
matthew wilcox, jbarnes
On Mon, Nov 14, 2011 at 02:50:00PM -0500, Prarit Bhargava wrote:
> This only works if there is a single Down bridge connected to a single Down bridge. What Stratus/NEC has is a single Up bridge (02:00.0) connected to a Up bridge (03:00.0) and a Down bridge (03:01.0), which we know to be illegal in PCIE. So the scan of the first bridge, 03:00.0 works and no fixup is done. The code still misses the second bridge, 03:01.0.
I'd forgotten that the Down - Down link was at slot 1; I thought it was
at slot 0. So this won't help.
--
Matthew Wilcox Intel Open Source Technology Centre
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours. We can't possibly take such
a retrograde step."
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-15 18:25 ` Prarit Bhargava
@ 2011-11-15 21:08 ` James Paradis
2011-11-15 21:52 ` Myron Stowe
0 siblings, 1 reply; 26+ messages in thread
From: James Paradis @ 2011-11-15 21:08 UTC (permalink / raw)
To: Prarit Bhargava
Cc: Rolf Eike Beer, Matthew Wilcox, Don Dutile, linux-pci, mstowe,
jbarnes, Bjorn Helgaas
> Bjorn,
>
> >
> > Is this problem a regression? If so, what commit caused it?
> > f07852d6442, which introduced only_one_child()?
>
> That's a tough question to answer. AFAICT the broken (HARDWARE
> broken) Stratus systems only enumerated properly by chance. Did
> they work prior to f07852d6? From what jparadis told me, yes. Is
> it a regression? ... depends on how you look at it.
Yes, that is the commit that caused the problem.
> > Does Windows work on this system?
>
> I don't know. jparadis? Any clue?
Windows works just fine on this system, probably because they
don't optimize the PCIE scan in this way...
> > Is this something that could be fixed by a firmware upgrade? If
> > so,
> > is there a Stratus/NEC bug report?
>
> Hmmm, the idea of a FW upgrade somehow fixing this never occurred to
> me. jparadis? Is that possible?
I seriously doubt it, but I can ask the hardware folks at Stratus.
I believe that at least some of this topology is baked in...
> > Is there a Red Hat bugzilla URL you could include?
>
> Only happens upstream.
Well, to be fair, we actually saw this behavior beginning with
Fedora 14, but never pursued the matter until now. I suppose
we could have filed a Fedora bug, but we wanted to root-cause the
problem first.
--jim
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-15 21:08 ` James Paradis
@ 2011-11-15 21:52 ` Myron Stowe
2011-11-15 22:14 ` James Paradis
0 siblings, 1 reply; 26+ messages in thread
From: Myron Stowe @ 2011-11-15 21:52 UTC (permalink / raw)
To: James Paradis
Cc: Prarit Bhargava, Rolf Eike Beer, Matthew Wilcox, Don Dutile,
linux-pci, jbarnes, Bjorn Helgaas
On Tue, 2011-11-15 at 16:08 -0500, James Paradis wrote:
> > Bjorn,
> >
> > >
> > > Is this problem a regression? If so, what commit caused it?
> > > f07852d6442, which introduced only_one_child()?
> >
> > That's a tough question to answer. AFAICT the broken (HARDWARE
> > broken) Stratus systems only enumerated properly by chance. Did
> > they work prior to f07852d6? From what jparadis told me, yes. Is
> > it a regression? ... depends on how you look at it.
>
> Yes, that is the commit that caused the problem.
>
> > > Does Windows work on this system?
> >
> > I don't know. jparadis? Any clue?
>
> Windows works just fine on this system, probably because they
> don't optimize the PCIE scan in this way...
>
> > > Is this something that could be fixed by a firmware upgrade? If
> > > so,
> > > is there a Stratus/NEC bug report?
> >
> > Hmmm, the idea of a FW upgrade somehow fixing this never occurred to
> > me. jparadis? Is that possible?
>
> I seriously doubt it, but I can ask the hardware folks at Stratus.
> I believe that at least some of this topology is baked in...
James,
I think a lot of people are wondering why this is only now coming up as
the patch in question has been upstream for a couple of years.
While the system has been in the field for awhile - has the I/O
subsystem that exhibits this issue been there since the introduction of
this type of system -or- is there a new, PCI Express based, I/O
subsystem now being introduced that can be used with the original
platform and this is why we are just now seeing the issue?
Myron
>
> > > Is there a Red Hat bugzilla URL you could include?
> >
> > Only happens upstream.
>
> Well, to be fair, we actually saw this behavior beginning with
> Fedora 14, but never pursued the matter until now. I suppose
> we could have filed a Fedora bug, but we wanted to root-cause the
> problem first.
>
> --jim
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-15 15:56 ` Prarit Bhargava
2011-11-15 16:08 ` Rolf Eike Beer
2011-11-15 20:15 ` Matthew Wilcox
@ 2011-11-15 21:53 ` James Paradis
2 siblings, 0 replies; 26+ messages in thread
From: James Paradis @ 2011-11-15 21:53 UTC (permalink / raw)
To: Prarit Bhargava
Cc: Don Dutile, Bjorn Helgaas, linux-pci, mstowe, jbarnes,
Matthew Wilcox
Prarit,
FYI, this patch does the trick on Draco. I'll try it in the
Stratus lab as well, but I'm 99.99% sure that it will work there
too.
There was one concern when we had a meeting at Stratus to talk
about this: we're not sure if the NEC-branded systems have the
same DMI string or not... I'm trying to find out.
--jim
----- Original Message -----
> Trying [v2]....
>
>
> pci: Workaround Stratus broken PCIE hierarchy
>
> Stratus systems have a hierarchy that includes a PCIE Downstream
> bridge
> connected to a PCIE Upstream bridge and a PCI Downstream bridge. The
> system
> boots with this wrong hierarchy into a crippled mode (USB doesn't
> work,
> network doesn't work ...). Avoiding the Downstream bridge check in
> only_one_child() causes all the bridges to be enumerated and the
> system
> to function properly.
>
> Unfortunately this hardware is currently available so we should at
> least
> keep it functional.
>
> [v2]
> - ddutile@redhat.com requested drivers/pci/quirks.c code
> - matthew@will.cx requested that dmi_name_in_vendors() be called only
> once with a static var check
> - added a kernel parameter to enable scanning of all PCIE devices.
>
> Signed-off-by: Prarit Bhargava <prarit@redhat.com>
>
> diff --git a/Documentation/kernel-parameters.txt
> b/Documentation/kernel-parameters.txt
> index a0c5c5f..7af458f 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -2069,6 +2069,7 @@ bytes respectively. Such letter suffixes can
> also be entirely omitted.
> on: Turn ECRC on.
> realloc reallocate PCI resources if allocations done by BIOS
> are erroneous.
> + pcie_scan_all Scan all possible PCIE devices.
>
> pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State
> Power
> Management.
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 6f45a73..f478bd5 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -3589,6 +3589,9 @@ 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)) {
> + printk(KERN_ERR HW_ERR "PCIE: Scanning all devices.\n");
> + pcie_scan_all = 1;
> } else {
> printk(KERN_ERR "PCI: Unknown option `%s'\n",
> str);
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index b74084e..5a07895 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -309,11 +309,16 @@ struct pci_dev_reset_methods {
>
> #ifdef CONFIG_PCI_QUIRKS
> extern int pci_dev_specific_reset(struct pci_dev *dev, int probe);
> +extern int is_broken_pcie_port(void);
> #else
> static inline int pci_dev_specific_reset(struct pci_dev *dev, int
> probe)
> {
> return -ENOTTY;
> }
> +static inline int is_broken_pcie_port(void)
> +{
> + return 0;
> +}
> #endif
>
> #endif /* DRIVERS_PCI_H */
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 04e74f4..fc88a9b 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1270,13 +1270,18 @@ static unsigned no_next_fn(struct pci_dev
> *dev, unsigned fn)
> return 0;
> }
>
> +int pcie_scan_all = 0; /* set via pci=pcie_scan_all */
> static int only_one_child(struct pci_bus *bus)
> {
> struct pci_dev *parent = bus->self;
> + if (pcie_scan_all)
> + return 0;
> 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 &&
> + !is_broken_pcie_port())
> return 1;
> return 0;
> }
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index 7285145..ef4d0e7 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -3092,3 +3092,21 @@ int pci_dev_specific_reset(struct pci_dev
> *dev, int probe)
>
> return -ENOTTY;
> }
> +
> +static int _is_broken_pcie_port = -1;
> +int is_broken_pcie_port(void)
> +{
> + if (_is_broken_pcie_port >= 0)
> + return _is_broken_pcie_port;
> + /*
> + * Stratus/NEC ftServer systems have a broken PCIE hierarchy in
> which
> + * one upstream and one downstream port are plugged into a
> downstream
> + * port. Avoiding the downstream port check in only_one_child()
> results
> + * in a functional system.
> + */
> + if (dmi_name_in_vendors("ftServer"))
> + _is_broken_pcie_port = 1;
> + else
> + _is_broken_pcie_port = 0;
> + return _is_broken_pcie_port;
> +}
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 337df0d..745b98e 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1647,5 +1647,7 @@ static inline void
> pci_release_bus_of_node(struct pci_bus *bus) { }
> */
> struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev);
>
> +/* set via pci=pcie_scan_all in order to enumerate all possible PCIE
> busses */
> +extern int pcie_scan_all;
> #endif /* __KERNEL__ */
> #endif /* LINUX_PCI_H */
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-15 21:52 ` Myron Stowe
@ 2011-11-15 22:14 ` James Paradis
0 siblings, 0 replies; 26+ messages in thread
From: James Paradis @ 2011-11-15 22:14 UTC (permalink / raw)
To: Myron Stowe
Cc: Prarit Bhargava, Rolf Eike Beer, Matthew Wilcox, Don Dutile,
linux-pci, jbarnes, Bjorn Helgaas
> James,
>
> I think a lot of people are wondering why this is only now coming up
> as
> the patch in question has been upstream for a couple of years.
>
> While the system has been in the field for awhile - has the I/O
> subsystem that exhibits this issue been there since the introduction
> of
> this type of system -or- is there a new, PCI Express based, I/O
> subsystem now being introduced that can be used with the original
> platform and this is why we are just now seeing the issue?
This system has been available since late 2009, and the I/O subsystem
has not changed since its introduction. One reason we haven't
seen this problem until now is that RHEL6 (kernel 2.6.32) is the only
supported Linux operating system for this platform, and this problem
surfaced in 2.6.34. I found this problem because I recently started
thinking ahead to RHEL7 and so started trying to work with recent
Fedora releases. It looks like from now on I'm going to be banging
on upstream kernels as soon as they come out so we catch this sort of
thing sooner...
--jim
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-11 20:29 ` Bjorn Helgaas
2011-11-11 20:35 ` Don Dutile
@ 2011-11-15 22:27 ` James Paradis
2011-11-15 23:07 ` Don Dutile
1 sibling, 1 reply; 26+ messages in thread
From: James Paradis @ 2011-11-15 22:27 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Prarit Bhargava, linux-pci, mstowe, matthew wilcox, jbarnes,
Matthew Wilcox, Don Dutile
BTW - for everyone's edification, here is a report on fedoraforum.org
that looks suspiciously like the same problem we're dealing with:
http://forums.fedoraforum.org/showthread.php?t=255025
The mobo worked with F13, broke with F14, nothing he did seemed to
bring the keyboard back, ended up fixing it by getting another
brand of motherboard. I'm going to see if I can find a copy of
that motherboard for testing...
--jim
----- Original Message -----
> On Fri, Nov 11, 2011 at 12:13 PM, Don Dutile <ddutile@redhat.com>
> wrote:
> > On 11/11/2011 12:41 PM, James Paradis wrote:
> >>
> >> Hmmm... would it be better to do this as a quirk or as a boot
> >> parameter? I've heard reports that other systems may be running
> >
> > Hearsay? if you have definite cases, then please share them,
> > so folks know when to flip the boot parameter on. note: it would
> > have to be
> > an early boot param as well.
>
> It'd definitely be good to know all the specific cases.
>
> But merely sharing them so folks will know when to use the parameter
> is a broken model. We should make it work automatically, either with
> some sort of machine-dependent quirk, or (preferably) with a change
> to
> the generic algorithm so it can handle these "broken" topologies
> along
> with all the correct ones.
>
> Bjorn
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-15 22:27 ` James Paradis
@ 2011-11-15 23:07 ` Don Dutile
0 siblings, 0 replies; 26+ messages in thread
From: Don Dutile @ 2011-11-15 23:07 UTC (permalink / raw)
To: James Paradis
Cc: Bjorn Helgaas, Prarit Bhargava, linux-pci, mstowe, matthew wilcox,
jbarnes, Matthew Wilcox
On 11/15/2011 05:27 PM, James Paradis wrote:
>
> BTW - for everyone's edification, here is a report on fedoraforum.org
> that looks suspiciously like the same problem we're dealing with:
>
> http://forums.fedoraforum.org/showthread.php?t=255025
>
> The mobo worked with F13, broke with F14, nothing he did seemed to
> bring the keyboard back, ended up fixing it by getting another
> brand of motherboard. I'm going to see if I can find a copy of
> that motherboard for testing...
>
> --jim
>
No, the original mobo worked on F13; new mobo broken on f13 & f14.
It sounds like an intr-rewiring problem; note, that he got it booted once,
(in the thread) and it took 30mins to do so.
> ----- Original Message -----
>> On Fri, Nov 11, 2011 at 12:13 PM, Don Dutile<ddutile@redhat.com>
>> wrote:
>>> On 11/11/2011 12:41 PM, James Paradis wrote:
>>>>
>>>> Hmmm... would it be better to do this as a quirk or as a boot
>>>> parameter? I've heard reports that other systems may be running
>>>
>>> Hearsay? if you have definite cases, then please share them,
>>> so folks know when to flip the boot parameter on. note: it would
>>> have to be
>>> an early boot param as well.
>>
>> It'd definitely be good to know all the specific cases.
>>
>> But merely sharing them so folks will know when to use the parameter
>> is a broken model. We should make it work automatically, either with
>> some sort of machine-dependent quirk, or (preferably) with a change
>> to
>> the generic algorithm so it can handle these "broken" topologies
>> along
>> with all the correct ones.
>>
>> Bjorn
>>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-15 20:15 ` Matthew Wilcox
@ 2011-11-16 16:53 ` Prarit Bhargava
2011-11-17 0:18 ` Prarit Bhargava
0 siblings, 1 reply; 26+ messages in thread
From: Prarit Bhargava @ 2011-11-16 16:53 UTC (permalink / raw)
To: Matthew Wilcox
Cc: Don Dutile, Bjorn Helgaas, James Paradis, linux-pci, mstowe,
jbarnes
pci: Workaround Stratus broken PCIE hierarchy
Stratus systems have a hierarchy that includes a PCIE Downstream bridge
connected to a PCIE Upstream bridge and a PCI Downstream bridge. The system
boots with this wrong hierarchy into a crippled mode (USB doesn't work,
network doesn't work ...). Avoiding the Downstream bridge check in
only_one_child() causes all the bridges to be enumerated and the system
to function properly.
Unfortunately this hardware is currently available so we should at least
keep it functional.
[v2]
- ddutile@redhat.com requested drivers/pci/quirks.c code
- matthew@wil.cx requested that dmi_name_in_vendors() be called only once with a static var check
- added a kernel parameter to enable scanning of all PCIE devices.
[v3]
- matthew@wil.cx requested a clean up of is_broken_pcie_port(
- eike-kernel@sf-tec.de requested a clean up of the printk level and message
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index a0c5c5f..7af458f 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2069,6 +2069,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
on: Turn ECRC on.
realloc reallocate PCI resources if allocations done by BIOS
are erroneous.
+ pcie_scan_all Scan all possible PCIE devices.
pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
Management.
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6f45a73..8c96fff 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3589,6 +3589,9 @@ 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)) {
+ printk(KERN_INFO HW_ERR "PCIE: User request scan of all PCIE devices. Your PCIE hardware is broken if you require this to boot.\n");
+ pcie_scan_all = 1;
} else {
printk(KERN_ERR "PCI: Unknown option `%s'\n",
str);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index b74084e..5a07895 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -309,11 +309,16 @@ struct pci_dev_reset_methods {
#ifdef CONFIG_PCI_QUIRKS
extern int pci_dev_specific_reset(struct pci_dev *dev, int probe);
+extern int is_broken_pcie_port(void);
#else
static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
{
return -ENOTTY;
}
+static inline int is_broken_pcie_port(void)
+{
+ return 0;
+}
#endif
#endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 04e74f4..fc88a9b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1270,13 +1270,18 @@ static unsigned no_next_fn(struct pci_dev *dev, unsigned fn)
return 0;
}
+int pcie_scan_all = 0; /* set via pci=pcie_scan_all */
static int only_one_child(struct pci_bus *bus)
{
struct pci_dev *parent = bus->self;
+ if (pcie_scan_all)
+ return 0;
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 &&
+ !is_broken_pcie_port())
return 1;
return 0;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 7285145..704e66d 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3092,3 +3092,17 @@ int pci_dev_specific_reset(struct pci_dev *dev, int probe)
return -ENOTTY;
}
+
+int is_broken_pcie_port(void)
+{
+ /*
+ * Stratus/NEC ftServer systems have a broken PCIE hierarchy in which
+ * one upstream and one downstream port are plugged into a downstream
+ * port. Avoiding the downstream port check in only_one_child() results
+ * in a functional system.
+ */
+ if (dmi_name_in_vendors("ftServer"))
+ pcie_scan_all = 1;
+
+ return pcie_scan_all;
+}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 337df0d..745b98e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1647,5 +1647,7 @@ static inline void pci_release_bus_of_node(struct pci_bus *bus) { }
*/
struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev);
+/* set via pci=pcie_scan_all in order to enumerate all possible PCIE busses */
+extern int pcie_scan_all;
#endif /* __KERNEL__ */
#endif /* LINUX_PCI_H */
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2011-11-16 16:53 ` Prarit Bhargava
@ 2011-11-17 0:18 ` Prarit Bhargava
0 siblings, 0 replies; 26+ messages in thread
From: Prarit Bhargava @ 2011-11-17 0:18 UTC (permalink / raw)
To: Matthew Wilcox
Cc: Don Dutile, Bjorn Helgaas, James Paradis, linux-pci, mstowe,
jbarnes
[v2]
- ddutile@redhat.com requested drivers/pci/quirks.c code
- matthew@wil.cx requested that dmi_name_in_vendors() be called only once with a static var check
- added a kernel parameter to enable scanning of all PCIE devices.
[v3]
- matthew@wil.cx requested a clean up of is_broken_pcie_port(
- eike-kernel@sf-tec.de requested a clean up of the printk level and message
[v4]
- ddutile pointed out a logic error in is_broken_pcie_port. It was no longer
being called only once on failure.
----8<----
pci: Workaround Stratus broken PCIE hierarchy
Stratus systems have a hierarchy that includes a PCIE Downstream bridge
connected to a PCIE Upstream bridge and a PCI Downstream bridge. The system
boots with this wrong hierarchy into a crippled mode (USB doesn't work,
network doesn't work ...). Avoiding the Downstream bridge check in
only_one_child() causes all the bridges to be enumerated and the system
to function properly.
Unfortunately this hardware is currently available so we should at least
keep it functional.
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index a0c5c5f..7af458f 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2069,6 +2069,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
on: Turn ECRC on.
realloc reallocate PCI resources if allocations done by BIOS
are erroneous.
+ pcie_scan_all Scan all possible PCIE devices.
pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
Management.
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6f45a73..8c96fff 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3589,6 +3589,9 @@ 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)) {
+ printk(KERN_INFO HW_ERR "PCIE: User request scan of all PCIE devices. Your PCIE hardware is broken if you require this to boot.\n");
+ pcie_scan_all = 1;
} else {
printk(KERN_ERR "PCI: Unknown option `%s'\n",
str);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index b74084e..5a07895 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -309,11 +309,16 @@ struct pci_dev_reset_methods {
#ifdef CONFIG_PCI_QUIRKS
extern int pci_dev_specific_reset(struct pci_dev *dev, int probe);
+extern int is_broken_pcie_port(void);
#else
static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
{
return -ENOTTY;
}
+static inline int is_broken_pcie_port(void)
+{
+ return 0;
+}
#endif
#endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 04e74f4..fc88a9b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1270,13 +1270,18 @@ static unsigned no_next_fn(struct pci_dev *dev, unsigned fn)
return 0;
}
+int pcie_scan_all = 0; /* set via pci=pcie_scan_all */
static int only_one_child(struct pci_bus *bus)
{
struct pci_dev *parent = bus->self;
+ if (pcie_scan_all)
+ return 0;
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 &&
+ !is_broken_pcie_port())
return 1;
return 0;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 7285145..6c9f72b 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3092,3 +3092,21 @@ int pci_dev_specific_reset(struct pci_dev *dev, int probe)
return -ENOTTY;
}
+
+static int is_broken_pcie_port_called;
+int is_broken_pcie_port(void)
+{
+ if (is_broken_pcie_port_called)
+ return pcie_scan_all;
+ /*
+ * Stratus/NEC ftServer systems have a broken PCIE hierarchy in which
+ * one upstream and one downstream port are plugged into a downstream
+ * port. Avoiding the downstream port check in only_one_child() results
+ * in a functional system.
+ */
+ if (dmi_name_in_vendors("ftServer"))
+ pcie_scan_all = 1;
+
+ is_broken_pcie_port_called = 1;
+ return pcie_scan_all;
+}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 337df0d..745b98e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1647,5 +1647,7 @@ static inline void pci_release_bus_of_node(struct pci_bus *bus) { }
*/
struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev);
+/* set via pci=pcie_scan_all in order to enumerate all possible PCIE busses */
+extern int pcie_scan_all;
#endif /* __KERNEL__ */
#endif /* LINUX_PCI_H */
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH] pci: Workaround Stratus broken PCIE hierarchy
@ 2012-04-25 17:56 Prarit Bhargava
2012-04-25 23:35 ` Bjorn Helgaas
0 siblings, 1 reply; 26+ messages in thread
From: Prarit Bhargava @ 2012-04-25 17:56 UTC (permalink / raw)
To: linux-pci
Cc: Prarit Bhargava, ddutile, matthew, eike-kernel, bhelgaas,
jim.paradis
This patch died on the vine after some reviews. The last version of this
patch was posted here:
http://marc.info/?l=linux-pci&m=132148921701034&w=2
P.
-----8<-----
pci: Workaround Stratus broken PCIE hierarchy
Stratus systems have a hierarchy that includes a PCIE Downstream bridge
connected to a PCIE Upstream bridge and a PCI Downstream bridge. The
system boots with this wrong hierarchy into a crippled mode (USB doesn't
work, network doesn't work ...). Avoiding the Downstream bridge check in
only_one_child() causes all the bridges to be enumerated and the system to
function properly.
Unfortunately this hardware is currently available so we should at least
keep it functional.
[v2]
- ddutile@redhat.com requested drivers/pci/quirks.c code
- matthew@wil.cx requested that dmi_name_in_vendors() be called only once with a static var check
- added a kernel parameter to enable scanning of all PCIE devices.
[v3]
- matthew@wil.cx requested a clean up of is_broken_pcie_port(
- eike-kernel@sf-tec.de requested a clean up of the printk level and message
[v4]
- ddutile pointed out a logic error in is_broken_pcie_port. It was no longer
being called only once on failure.
Cc: ddutile@redhat.com
Cc: matthew@wil.cx
Cc: eike-kernel@sf-tec.de
Cc: bhelgaas@google.com
Cc: jim.paradis@stratus.com
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
---
Documentation/kernel-parameters.txt | 1 +
drivers/pci/pci.c | 3 +++
drivers/pci/pci.h | 5 +++++
drivers/pci/probe.c | 9 +++++++--
drivers/pci/quirks.c | 18 ++++++++++++++++++
include/linux/pci.h | 2 ++
6 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index c1601e5..1284b2e 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2161,6 +2161,7 @@ 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.
pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
Management.
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 111569c..82e89ad 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3893,6 +3893,9 @@ 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)) {
+ printk(KERN_INFO HW_ERR "PCIE: User request scan of all PCIE devices. Your PCIE hardware is broken if you require this to boot.\n");
+ pcie_scan_all = 1;
} else {
printk(KERN_ERR "PCI: Unknown option `%s'\n",
str);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index e494347..a1baad2 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -319,11 +319,16 @@ struct pci_dev_reset_methods {
#ifdef CONFIG_PCI_QUIRKS
extern int pci_dev_specific_reset(struct pci_dev *dev, int probe);
+extern int is_broken_pcie_port(void);
#else
static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
{
return -ENOTTY;
}
+static inline int is_broken_pcie_port(void)
+{
+ return 0;
+}
#endif
#endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 5e1ca3c..07c6245 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1392,13 +1392,18 @@ static unsigned no_next_fn(struct pci_dev *dev, unsigned fn)
return 0;
}
+int pcie_scan_all; /* set via pci=pcie_scan_all */
static int only_one_child(struct pci_bus *bus)
{
struct pci_dev *parent = bus->self;
+ if (pcie_scan_all)
+ return 0;
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 &&
+ !is_broken_pcie_port())
return 1;
return 0;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 4bf7102..d60e99c 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3109,3 +3109,21 @@ int pci_dev_specific_reset(struct pci_dev *dev, int probe)
return -ENOTTY;
}
+
+static int is_broken_pcie_port_called;
+int is_broken_pcie_port(void)
+{
+ if (is_broken_pcie_port_called)
+ return pcie_scan_all;
+ /*
+ * Stratus/NEC ftServer systems have a broken PCIE hierarchy in which
+ * one upstream and one downstream port are plugged into a downstream
+ * port. Avoiding the downstream port check in only_one_child() results
+ * in a functional system.
+ */
+ if (dmi_name_in_vendors("ftServer"))
+ pcie_scan_all = 1;
+
+ is_broken_pcie_port_called = 1;
+ return pcie_scan_all;
+}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index e444f5b..bb3daa7 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1720,5 +1720,7 @@ static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
*/
struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev);
+/* set via pci=pcie_scan_all in order to enumerate all possible PCIE busses */
+extern int pcie_scan_all;
#endif /* __KERNEL__ */
#endif /* LINUX_PCI_H */
--
1.7.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH] pci: Workaround Stratus broken PCIE hierarchy
2012-04-25 17:56 Prarit Bhargava
@ 2012-04-25 23:35 ` Bjorn Helgaas
0 siblings, 0 replies; 26+ messages in thread
From: Bjorn Helgaas @ 2012-04-25 23:35 UTC (permalink / raw)
To: Prarit Bhargava; +Cc: linux-pci, ddutile, matthew, eike-kernel, jim.paradis
On Wed, Apr 25, 2012 at 11:56 AM, Prarit Bhargava <prarit@redhat.com> wrote:
> This patch died on the vine after some reviews. The last version of this
> patch was posted here:
>
> http://marc.info/?l=linux-pci&m=132148921701034&w=2
Sorry this fell through the cracks. I fiddled with it some more and
tried to understand the topology more clearly. I'll post it right
now; please take a look and tell me where I screwed up :)
Bjorn
> -----8<-----
>
> pci: Workaround Stratus broken PCIE hierarchy
>
> Stratus systems have a hierarchy that includes a PCIE Downstream bridge
> connected to a PCIE Upstream bridge and a PCI Downstream bridge. The
> system boots with this wrong hierarchy into a crippled mode (USB doesn't
> work, network doesn't work ...). Avoiding the Downstream bridge check in
> only_one_child() causes all the bridges to be enumerated and the system to
> function properly.
>
> Unfortunately this hardware is currently available so we should at least
> keep it functional.
>
> [v2]
> - ddutile@redhat.com requested drivers/pci/quirks.c code
> - matthew@wil.cx requested that dmi_name_in_vendors() be called only once with a static var check
> - added a kernel parameter to enable scanning of all PCIE devices.
>
> [v3]
> - matthew@wil.cx requested a clean up of is_broken_pcie_port(
> - eike-kernel@sf-tec.de requested a clean up of the printk level and message
>
> [v4]
> - ddutile pointed out a logic error in is_broken_pcie_port. It was no longer
> being called only once on failure.
>
> Cc: ddutile@redhat.com
> Cc: matthew@wil.cx
> Cc: eike-kernel@sf-tec.de
> Cc: bhelgaas@google.com
> Cc: jim.paradis@stratus.com
> Signed-off-by: Prarit Bhargava <prarit@redhat.com>
> ---
> Documentation/kernel-parameters.txt | 1 +
> drivers/pci/pci.c | 3 +++
> drivers/pci/pci.h | 5 +++++
> drivers/pci/probe.c | 9 +++++++--
> drivers/pci/quirks.c | 18 ++++++++++++++++++
> include/linux/pci.h | 2 ++
> 6 files changed, 36 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index c1601e5..1284b2e 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -2161,6 +2161,7 @@ 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.
>
> pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
> Management.
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 111569c..82e89ad 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -3893,6 +3893,9 @@ 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)) {
> + printk(KERN_INFO HW_ERR "PCIE: User request scan of all PCIE devices. Your PCIE hardware is broken if you require this to boot.\n");
> + pcie_scan_all = 1;
> } else {
> printk(KERN_ERR "PCI: Unknown option `%s'\n",
> str);
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index e494347..a1baad2 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -319,11 +319,16 @@ struct pci_dev_reset_methods {
>
> #ifdef CONFIG_PCI_QUIRKS
> extern int pci_dev_specific_reset(struct pci_dev *dev, int probe);
> +extern int is_broken_pcie_port(void);
> #else
> static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
> {
> return -ENOTTY;
> }
> +static inline int is_broken_pcie_port(void)
> +{
> + return 0;
> +}
> #endif
>
> #endif /* DRIVERS_PCI_H */
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 5e1ca3c..07c6245 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1392,13 +1392,18 @@ static unsigned no_next_fn(struct pci_dev *dev, unsigned fn)
> return 0;
> }
>
> +int pcie_scan_all; /* set via pci=pcie_scan_all */
> static int only_one_child(struct pci_bus *bus)
> {
> struct pci_dev *parent = bus->self;
> + if (pcie_scan_all)
> + return 0;
> 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 &&
> + !is_broken_pcie_port())
> return 1;
> return 0;
> }
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index 4bf7102..d60e99c 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -3109,3 +3109,21 @@ int pci_dev_specific_reset(struct pci_dev *dev, int probe)
>
> return -ENOTTY;
> }
> +
> +static int is_broken_pcie_port_called;
> +int is_broken_pcie_port(void)
> +{
> + if (is_broken_pcie_port_called)
> + return pcie_scan_all;
> + /*
> + * Stratus/NEC ftServer systems have a broken PCIE hierarchy in which
> + * one upstream and one downstream port are plugged into a downstream
> + * port. Avoiding the downstream port check in only_one_child() results
> + * in a functional system.
> + */
> + if (dmi_name_in_vendors("ftServer"))
> + pcie_scan_all = 1;
> +
> + is_broken_pcie_port_called = 1;
> + return pcie_scan_all;
> +}
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index e444f5b..bb3daa7 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1720,5 +1720,7 @@ static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev)
> */
> struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev);
>
> +/* set via pci=pcie_scan_all in order to enumerate all possible PCIE busses */
> +extern int pcie_scan_all;
> #endif /* __KERNEL__ */
> #endif /* LINUX_PCI_H */
> --
> 1.7.1
>
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2012-04-25 23:35 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-10 14:00 [PATCH] pci: Workaround Stratus broken PCIE hierarchy Prarit Bhargava
2011-11-10 14:31 ` Matthew Wilcox
2011-11-10 16:50 ` Don Dutile
2011-11-11 17:41 ` James Paradis
2011-11-11 19:13 ` Don Dutile
2011-11-11 20:29 ` Bjorn Helgaas
2011-11-11 20:35 ` Don Dutile
2011-11-14 14:44 ` Prarit Bhargava
2011-11-14 18:14 ` Matthew Wilcox
2011-11-14 19:50 ` Prarit Bhargava
2011-11-15 20:16 ` Matthew Wilcox
2011-11-15 15:56 ` Prarit Bhargava
2011-11-15 16:08 ` Rolf Eike Beer
2011-11-15 18:14 ` Bjorn Helgaas
2011-11-15 18:25 ` Prarit Bhargava
2011-11-15 21:08 ` James Paradis
2011-11-15 21:52 ` Myron Stowe
2011-11-15 22:14 ` James Paradis
2011-11-15 20:15 ` Matthew Wilcox
2011-11-16 16:53 ` Prarit Bhargava
2011-11-17 0:18 ` Prarit Bhargava
2011-11-15 21:53 ` James Paradis
2011-11-15 22:27 ` James Paradis
2011-11-15 23:07 ` Don Dutile
-- strict thread matches above, loose matches on Subject: below --
2012-04-25 17:56 Prarit Bhargava
2012-04-25 23:35 ` Bjorn Helgaas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).