diff options
author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2014-11-25 09:27:00 +1100 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2015-01-23 14:02:52 +1100 |
commit | 2aa5cf9e48f2f39cc255f8e29964df3ff9ca017b (patch) | |
tree | f2aaa35edbb58d7e714f76e5163e26ae7edac04f /arch/powerpc/kernel | |
parent | 6f20e7f2e930211613a66d0603fa4abaaf3ce662 (diff) |
powerpc/eeh: Fix missed PE#0 on P7IOC
PE#0 should be regarded as valid for P7IOC, while it's invalid for
PHB3. The patch adds flag EEH_VALID_PE_ZERO to differentiate those
two cases. Without the patch, we possibly see frozen PE#0 state is
cleared without EEH recovery taken on P7IOC as following kernel logs
indicate:
[root@ltcfbl8eb ~]# dmesg
:
pci 0000:00 : [PE# 000] Secondary bus 0 associated with PE#0
pci 0000:01 : [PE# 001] Secondary bus 1 associated with PE#1
pci 0001:00 : [PE# 000] Secondary bus 0 associated with PE#0
pci 0001:01 : [PE# 001] Secondary bus 1 associated with PE#1
pci 0002:00 : [PE# 000] Secondary bus 0 associated with PE#0
pci 0002:01 : [PE# 001] Secondary bus 1 associated with PE#1
pci 0003:00 : [PE# 000] Secondary bus 0 associated with PE#0
pci 0003:01 : [PE# 001] Secondary bus 1 associated with PE#1
pci 0003:20 : [PE# 002] Secondary bus 32..63 associated with PE#2
:
EEH: Clear non-existing PHB#3-PE#0
EEH: PHB location: U78AE.001.WZS00M9-P1-002
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/eeh_pe.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index 5a63e2b0f65..fa950fbc2d9 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c @@ -239,10 +239,18 @@ static void *__eeh_pe_get(void *data, void *flag) if (pe->type & EEH_PE_PHB) return NULL; - /* We prefer PE address */ - if (edev->pe_config_addr && - (edev->pe_config_addr == pe->addr)) + /* + * We prefer PE address. For most cases, we should + * have non-zero PE address + */ + if (eeh_has_flag(EEH_VALID_PE_ZERO)) { + if (edev->pe_config_addr == pe->addr) + return pe; + } else { + if (edev->pe_config_addr && + (edev->pe_config_addr == pe->addr)) return pe; + } /* Try BDF address */ if (edev->config_addr && |