From: Brad Peters <bpeters@redhat.com> Date: Wed, 13 Aug 2008 14:41:39 -0400 Subject: [ppc] PERR/SERR disabled after EEH error recovery Message-id: 20080813184139.29193.28018.sendpatchset@squad5-lp1.lab.bos.redhat.com O-Subject: [PATCH RHEL5.3 bz457468] PERR/SERR disabled after EEH error recovery Bugzilla: 457468 RH-Acked-by: David Howells <dhowells@redhat.com> RHBZ#: ====== https://bugzilla.redhat.com/show_bug.cgi?id=457468 Description: =========== Bug Fix / Affects only ppc arch During JS22 testing, the hardware test group discovered that the PERR and SERR bits were not reenabled during EEH recovery of an Agilent Technologies 64 Bit 133MHz PCI-X Analyzer & Exerciser. The PERR/SERR bits were set to 1 by firmware at boot time, but were not reset to 1 during EEH recovery. The patch corrects this, setting these bits to 1 to properly detect and recover from PCI errors on this card. RHEL Version Found: ================ RHEL 5.2 kABI Status: ============ No symbols were harmed. Brew: ===== Built on all platforms. http://brewweb.devel.redhat.com/brew/taskinfo?taskID=1417858 Upstream Status: ================ Patch posted to upstream, not yet committed: http://ozlabs.org/pipermail/linuxppc-dev/2008-July/059559.html Test Status: ============ Tested by Mike Mason <IBM>, using an Agilent test card. Mike then confirmed fix on several network cards. =============================================================== Brad Peters 1-978-392-1000 x 23183 IBM on-site partner. Proposed Patch: =============== This patch is based on 2.6.18-101.el5 diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index ff9190b..e055867 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c @@ -676,6 +676,7 @@ int rtas_set_slot_reset(struct pci_dn *pdn) static inline void __restore_bars (struct pci_dn *pdn) { int i; + u32 cmd; if (NULL==pdn->phb) return; for (i=4; i<10; i++) { @@ -696,6 +697,19 @@ static inline void __restore_bars (struct pci_dn *pdn) /* max latency, min grant, interrupt pin and line */ rtas_write_config(pdn, 15*4, 4, pdn->config_space[15]); + + /* Restore PERR & SERR bits, some devices require it, + don't touch the other command bits */ + rtas_read_config(pdn, PCI_COMMAND, 4, &cmd); + if (pdn->config_space[1] & PCI_COMMAND_PARITY) + cmd |= PCI_COMMAND_PARITY; + else + cmd &= ~PCI_COMMAND_PARITY; + if (pdn->config_space[1] & PCI_COMMAND_SERR) + cmd |= PCI_COMMAND_SERR; + else + cmd &= ~PCI_COMMAND_SERR; + rtas_write_config(pdn, PCI_COMMAND, 4, cmd); } /**