Subject: [PATCH 3/3] powerpc/eeh: dump pci bridge status on event

From: [email-masked] (Linas Vepstas)
Date: Thu, 26 Jul 2007 17:35:40 -0500

Gather bridge-specific data on EEH events.

Signed-off-by: Linas Vepstas <[email-masked]>

----
 arch/powerpc/platforms/pseries/eeh.c |   27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

Index: linux-2.6.22-git2/arch/powerpc/platforms/pseries/eeh.c
===================================================================
--- linux-2.6.22-git2.orig/arch/powerpc/platforms/pseries/eeh.c	2007-07-25 16:41:42.000000000 -0500
+++ linux-2.6.22-git2/arch/powerpc/platforms/pseries/eeh.c	2007-07-25 16:42:20.000000000 -0500
@@ -169,6 +169,8 @@ static void rtas_slot_error_detail(struc
  */
 static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
 {
+	struct device_node *dn;
+	struct pci_dev *dev = pdn->pcidev;
 	u32 cfg;
 	int cap, i;
 	int n = 0;
@@ -184,6 +186,17 @@ static size_t gather_pci_data(struct pci
 	n += scnprintf(buf+n, len-n, "cmd/stat:%x\n", cfg);
 	printk(KERN_WARNING "EEH: PCI cmd/status register: %08x\n", cfg);
 
+	/* Gather bridge-specific registers */
+	if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
+		rtas_read_config(pdn, PCI_SEC_STATUS, 2, &cfg);
+		n += scnprintf(buf+n, len-n, "sec stat:%x\n", cfg);
+		printk(KERN_WARNING "EEH: Bridge secondary status: %04x\n", cfg);
+
+		rtas_read_config(pdn, PCI_BRIDGE_CONTROL, 2, &cfg);
+		n += scnprintf(buf+n, len-n, "brdg ctl:%x\n", cfg);
+		printk(KERN_WARNING "EEH: Bridge control: %04x\n", cfg);
+	}
+
 	/* Dump out the PCI-X command and status regs */
 	cap = pci_find_capability(pdn->pcidev, PCI_CAP_ID_PCIX);
 	if (cap) {
@@ -209,7 +222,7 @@ static size_t gather_pci_data(struct pci
 			printk(KERN_WARNING "EEH: PCI-E %02x: %08x\n", i, cfg);
 		}
 
-		cap = pci_find_ext_capability(pdn->pcidev,PCI_EXT_CAP_ID_ERR);
+		cap = pci_find_ext_capability(pdn->pcidev, PCI_EXT_CAP_ID_ERR);
 		if (cap) {
 			n += scnprintf(buf+n, len-n, "pci-e AER:\n");
 			printk(KERN_WARNING
@@ -222,6 +235,18 @@ static size_t gather_pci_data(struct pci
 			}
 		}
 	}
+
+	/* Gather status on devices under the bridge */
+	if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
+		dn = pdn->node->child;
+		while (dn) {
+			pdn = PCI_DN(dn);
+			if (pdn)
+				n += gather_pci_data(pdn, buf+n, len-n);
+			dn = dn->sibling;
+		}
+	}
+
 	return n;
 }