aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/eeh.c
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2014-09-29 22:39:08 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2014-09-30 03:15:19 -0400
commitf2e0be5e76dd626c70f5aa5c6165b4dfa1d14c64 (patch)
treed7d5b09515fc67d529f7d7b8dd5dd5727c95f590 /arch/powerpc/kernel/eeh.c
parent5cfb20b96f624e9852c4f3f1c4397e81ca28d5aa (diff)
powerpc/eeh: Dump PCI config space for all child devices
The PEs can be organized as nested. Current implementation doesn't dump PCI config space for subordinate devices of child PEs. However, the frozen PE could be caused by those subordinate devices of its child PEs. The patch dumps PCI config space for all subordinate devices of the problematic PE. 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/eeh.c')
-rw-r--r--arch/powerpc/kernel/eeh.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 3350b8490dbc..d543e4179c18 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -117,7 +117,7 @@ static DEFINE_MUTEX(eeh_dev_mutex);
117 * not dynamically alloced, so that it ends up in RMO where RTAS 117 * not dynamically alloced, so that it ends up in RMO where RTAS
118 * can access it. 118 * can access it.
119 */ 119 */
120#define EEH_PCI_REGS_LOG_LEN 4096 120#define EEH_PCI_REGS_LOG_LEN 8192
121static unsigned char pci_regs_buf[EEH_PCI_REGS_LOG_LEN]; 121static unsigned char pci_regs_buf[EEH_PCI_REGS_LOG_LEN];
122 122
123/* 123/*
@@ -148,16 +148,12 @@ static int __init eeh_setup(char *str)
148} 148}
149__setup("eeh=", eeh_setup); 149__setup("eeh=", eeh_setup);
150 150
151/** 151/*
152 * eeh_gather_pci_data - Copy assorted PCI config space registers to buff 152 * This routine captures assorted PCI configuration space data
153 * @edev: device to report data for 153 * for the indicated PCI device, and puts them into a buffer
154 * @buf: point to buffer in which to log 154 * for RTAS error logging.
155 * @len: amount of room in buffer
156 *
157 * This routine captures assorted PCI configuration space data,
158 * and puts them into a buffer for RTAS error logging.
159 */ 155 */
160static size_t eeh_gather_pci_data(struct eeh_dev *edev, char *buf, size_t len) 156static size_t eeh_dump_dev_log(struct eeh_dev *edev, char *buf, size_t len)
161{ 157{
162 struct device_node *dn = eeh_dev_to_of_node(edev); 158 struct device_node *dn = eeh_dev_to_of_node(edev);
163 u32 cfg; 159 u32 cfg;
@@ -255,6 +251,19 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char *buf, size_t len)
255 return n; 251 return n;
256} 252}
257 253
254static void *eeh_dump_pe_log(void *data, void *flag)
255{
256 struct eeh_pe *pe = data;
257 struct eeh_dev *edev, *tmp;
258 size_t *plen = flag;
259
260 eeh_pe_for_each_dev(pe, edev, tmp)
261 *plen += eeh_dump_dev_log(edev, pci_regs_buf + *plen,
262 EEH_PCI_REGS_LOG_LEN - *plen);
263
264 return NULL;
265}
266
258/** 267/**
259 * eeh_slot_error_detail - Generate combined log including driver log and error log 268 * eeh_slot_error_detail - Generate combined log including driver log and error log
260 * @pe: EEH PE 269 * @pe: EEH PE
@@ -268,7 +277,6 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char *buf, size_t len)
268void eeh_slot_error_detail(struct eeh_pe *pe, int severity) 277void eeh_slot_error_detail(struct eeh_pe *pe, int severity)
269{ 278{
270 size_t loglen = 0; 279 size_t loglen = 0;
271 struct eeh_dev *edev, *tmp;
272 280
273 /* 281 /*
274 * When the PHB is fenced or dead, it's pointless to collect 282 * When the PHB is fenced or dead, it's pointless to collect
@@ -286,10 +294,7 @@ void eeh_slot_error_detail(struct eeh_pe *pe, int severity)
286 eeh_pe_restore_bars(pe); 294 eeh_pe_restore_bars(pe);
287 295
288 pci_regs_buf[0] = 0; 296 pci_regs_buf[0] = 0;
289 eeh_pe_for_each_dev(pe, edev, tmp) { 297 eeh_pe_traverse(pe, eeh_dump_pe_log, &loglen);
290 loglen += eeh_gather_pci_data(edev, pci_regs_buf + loglen,
291 EEH_PCI_REGS_LOG_LEN - loglen);
292 }
293 } 298 }
294 299
295 eeh_ops->get_log(pe, severity, pci_regs_buf, loglen); 300 eeh_ops->get_log(pe, severity, pci_regs_buf, loglen);