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 <[email protected]>
CC: Jesse Barnes <[email protected]>
CC: Zhang Yanmin <[email protected]>
Signed-off-by: Len Brown <[email protected]>
This commit is contained in:
Huang Ying 2011-02-21 13:54:43 +08:00 • committed by Len Brown
commit c413d76820
7 changed files with 132 additions and 12 deletions

View file

@ -35,13 +35,6 @@
PCI_ERR_UNC_UNX_COMP| \
PCI_ERR_UNC_MALF_TLP)
struct header_log_regs {
unsigned int dw0;
unsigned int dw1;
unsigned int dw2;
unsigned int dw3;
};
#define AER_MAX_MULTI_ERR_DEVICES 5 /* Not likely to have more */
struct aer_err_info {
struct pci_dev *dev[AER_MAX_MULTI_ERR_DEVICES];
@ -59,7 +52,7 @@ struct aer_err_info {
unsigned int status; /* COR/UNCOR Error Status */
unsigned int mask; /* COR/UNCOR Error Mask */
struct header_log_regs tlp; /* TLP Header */
struct aer_header_log_regs tlp; /* TLP Header */
};
struct aer_err_source {

View file

@ -19,6 +19,7 @@
#include <linux/errno.h>
#include <linux/pm.h>
#include <linux/suspend.h>
#include <linux/cper.h>
#include "aerdrv.h"
@ -201,3 +202,61 @@ void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info)
info->multi_error_valid ? "Multiple " : "",
aer_error_severity_string[info->severity], info->id);
}
#ifdef CONFIG_ACPI_APEI_PCIEAER
static int cper_severity_to_aer(int cper_severity)
{
switch (cper_severity) {
case CPER_SEV_RECOVERABLE:
return AER_NONFATAL;
case CPER_SEV_FATAL:
return AER_FATAL;
default:
return AER_CORRECTABLE;
}
}
void cper_print_aer(const char *prefix, int cper_severity,
struct aer_capability_regs *aer)
{
int aer_severity, layer, agent, status_strs_size, tlp_header_valid = 0;
u32 status, mask;
const char **status_strs;
aer_severity = cper_severity_to_aer(cper_severity);
if (aer_severity == AER_CORRECTABLE) {
status = aer->cor_status;
mask = aer->cor_mask;
status_strs = aer_correctable_error_string;
status_strs_size = ARRAY_SIZE(aer_correctable_error_string);
} else {
status = aer->uncor_status;
mask = aer->uncor_mask;
status_strs = aer_uncorrectable_error_string;
status_strs_size = ARRAY_SIZE(aer_uncorrectable_error_string);
tlp_header_valid = status & AER_LOG_TLP_MASKS;
}
layer = AER_GET_LAYER_ERROR(aer_severity, status);
agent = AER_GET_AGENT(aer_severity, status);
printk("%s""aer_status: 0x%08x, aer_mask: 0x%08x\n",
prefix, status, mask);
cper_print_bits(prefix, status, status_strs, status_strs_size);
printk("%s""aer_layer=%s, aer_agent=%s\n", prefix,
aer_error_layer[layer], aer_agent_string[agent]);
if (aer_severity != AER_CORRECTABLE)
printk("%s""aer_uncor_severity: 0x%08x\n",
prefix, aer->uncor_severity);
if (tlp_header_valid) {
const unsigned char *tlp;
tlp = (const unsigned char *)&aer->header_log;
printk("%s""aer_tlp_header:"
" %02x%02x%02x%02x %02x%02x%02x%02x"
" %02x%02x%02x%02x %02x%02x%02x%02x\n",
prefix, *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp,
*(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4),
*(tlp + 11), *(tlp + 10), *(tlp + 9),
*(tlp + 8), *(tlp + 15), *(tlp + 14),
*(tlp + 13), *(tlp + 12));
}
}
#endif