aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2011-02-21 00:54:43 -0500
committerLen Brown <len.brown@intel.com>2011-03-21 22:59:08 -0400
commitc413d7682020a127f54744a1b30f597692aea1fd (patch)
treeb495af23b2f81b6ab0080925aa988ea9a8068e4e /drivers/pci/pcie
parentb64a44146540a4761bb1cf8047fffd9dbf0c3090 (diff)
ACPI, APEI, Add PCIe AER error information printing support
The AER error information printing support is implemented in drivers/pci/pcie/aer/aer_print.c. So some string constants, functions and macros definitions can be re-used without being exported. The original PCIe AER error information printing function is not re-used directly because the overall format is quite different. And changing the original printing format may make some original users' scripts broken. Signed-off-by: Huang Ying <ying.huang@intel.com> CC: Jesse Barnes <jbarnes@virtuousgeek.org> CC: Zhang Yanmin <yanmin.zhang@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/pci/pcie')
-rw-r--r--drivers/pci/pcie/aer/aerdrv.h9
-rw-r--r--drivers/pci/pcie/aer/aerdrv_errprint.c59
2 files changed, 60 insertions, 8 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index 80c11d131499..3eb77080366a 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -35,13 +35,6 @@
35 PCI_ERR_UNC_UNX_COMP| \ 35 PCI_ERR_UNC_UNX_COMP| \
36 PCI_ERR_UNC_MALF_TLP) 36 PCI_ERR_UNC_MALF_TLP)
37 37
38struct header_log_regs {
39 unsigned int dw0;
40 unsigned int dw1;
41 unsigned int dw2;
42 unsigned int dw3;
43};
44
45#define AER_MAX_MULTI_ERR_DEVICES 5 /* Not likely to have more */ 38#define AER_MAX_MULTI_ERR_DEVICES 5 /* Not likely to have more */
46struct aer_err_info { 39struct aer_err_info {
47 struct pci_dev *dev[AER_MAX_MULTI_ERR_DEVICES]; 40 struct pci_dev *dev[AER_MAX_MULTI_ERR_DEVICES];
@@ -59,7 +52,7 @@ struct aer_err_info {
59 52
60 unsigned int status; /* COR/UNCOR Error Status */ 53 unsigned int status; /* COR/UNCOR Error Status */
61 unsigned int mask; /* COR/UNCOR Error Mask */ 54 unsigned int mask; /* COR/UNCOR Error Mask */
62 struct header_log_regs tlp; /* TLP Header */ 55 struct aer_header_log_regs tlp; /* TLP Header */
63}; 56};
64 57
65struct aer_err_source { 58struct aer_err_source {
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c
index 7a237f67129e..b07a42e0b350 100644
--- a/drivers/pci/pcie/aer/aerdrv_errprint.c
+++ b/drivers/pci/pcie/aer/aerdrv_errprint.c
@@ -19,6 +19,7 @@
19#include <linux/errno.h> 19#include <linux/errno.h>
20#include <linux/pm.h> 20#include <linux/pm.h>
21#include <linux/suspend.h> 21#include <linux/suspend.h>
22#include <linux/cper.h>
22 23
23#include "aerdrv.h" 24#include "aerdrv.h"
24 25
@@ -201,3 +202,61 @@ void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info)
201 info->multi_error_valid ? "Multiple " : "", 202 info->multi_error_valid ? "Multiple " : "",
202 aer_error_severity_string[info->severity], info->id); 203 aer_error_severity_string[info->severity], info->id);
203} 204}
205
206#ifdef CONFIG_ACPI_APEI_PCIEAER
207static int cper_severity_to_aer(int cper_severity)
208{
209 switch (cper_severity) {
210 case CPER_SEV_RECOVERABLE:
211 return AER_NONFATAL;
212 case CPER_SEV_FATAL:
213 return AER_FATAL;
214 default:
215 return AER_CORRECTABLE;
216 }
217}
218
219void cper_print_aer(const char *prefix, int cper_severity,
220 struct aer_capability_regs *aer)
221{
222 int aer_severity, layer, agent, status_strs_size, tlp_header_valid = 0;
223 u32 status, mask;
224 const char **status_strs;
225
226 aer_severity = cper_severity_to_aer(cper_severity);
227 if (aer_severity == AER_CORRECTABLE) {
228 status = aer->cor_status;
229 mask = aer->cor_mask;
230 status_strs = aer_correctable_error_string;
231 status_strs_size = ARRAY_SIZE(aer_correctable_error_string);
232 } else {
233 status = aer->uncor_status;
234 mask = aer->uncor_mask;
235 status_strs = aer_uncorrectable_error_string;
236 status_strs_size = ARRAY_SIZE(aer_uncorrectable_error_string);
237 tlp_header_valid = status & AER_LOG_TLP_MASKS;
238 }
239 layer = AER_GET_LAYER_ERROR(aer_severity, status);
240 agent = AER_GET_AGENT(aer_severity, status);
241 printk("%s""aer_status: 0x%08x, aer_mask: 0x%08x\n",
242 prefix, status, mask);
243 cper_print_bits(prefix, status, status_strs, status_strs_size);
244 printk("%s""aer_layer=%s, aer_agent=%s\n", prefix,
245 aer_error_layer[layer], aer_agent_string[agent]);
246 if (aer_severity != AER_CORRECTABLE)
247 printk("%s""aer_uncor_severity: 0x%08x\n",
248 prefix, aer->uncor_severity);
249 if (tlp_header_valid) {
250 const unsigned char *tlp;
251 tlp = (const unsigned char *)&aer->header_log;
252 printk("%s""aer_tlp_header:"
253 " %02x%02x%02x%02x %02x%02x%02x%02x"
254 " %02x%02x%02x%02x %02x%02x%02x%02x\n",
255 prefix, *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp,
256 *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4),
257 *(tlp + 11), *(tlp + 10), *(tlp + 9),
258 *(tlp + 8), *(tlp + 15), *(tlp + 14),
259 *(tlp + 13), *(tlp + 12));
260 }
261}
262#endif