Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 1786

kernel-2.6.18-128.1.10.el5.src.rpm

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);
 }
 
 /**