diff options
author | Huang Ying <ying.huang@intel.com> | 2011-02-21 00:54:43 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2011-03-21 22:59:08 -0400 |
commit | c413d7682020a127f54744a1b30f597692aea1fd (patch) | |
tree | b495af23b2f81b6ab0080925aa988ea9a8068e4e /drivers/acpi/apei | |
parent | b64a44146540a4761bb1cf8047fffd9dbf0c3090 (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/acpi/apei')
-rw-r--r-- | drivers/acpi/apei/Kconfig | 7 | ||||
-rw-r--r-- | drivers/acpi/apei/cper.c | 18 |
2 files changed, 21 insertions, 4 deletions
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index fca34ccfd294..9ecf6feae830 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig | |||
@@ -21,6 +21,13 @@ config ACPI_APEI_GHES | |||
21 | by firmware to produce more valuable hardware error | 21 | by firmware to produce more valuable hardware error |
22 | information for Linux. | 22 | information for Linux. |
23 | 23 | ||
24 | config ACPI_APEI_PCIEAER | ||
25 | bool "APEI PCIe AER logging/recovering support" | ||
26 | depends on ACPI_APEI && PCIEAER | ||
27 | help | ||
28 | PCIe AER errors may be reported via APEI firmware first mode. | ||
29 | Turn on this option to enable the corresponding support. | ||
30 | |||
24 | config ACPI_APEI_EINJ | 31 | config ACPI_APEI_EINJ |
25 | tristate "APEI Error INJection (EINJ)" | 32 | tristate "APEI Error INJection (EINJ)" |
26 | depends on ACPI_APEI && DEBUG_FS | 33 | depends on ACPI_APEI && DEBUG_FS |
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c index 31464a006d76..5d4189464d63 100644 --- a/drivers/acpi/apei/cper.c +++ b/drivers/acpi/apei/cper.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/time.h> | 29 | #include <linux/time.h> |
30 | #include <linux/cper.h> | 30 | #include <linux/cper.h> |
31 | #include <linux/acpi.h> | 31 | #include <linux/acpi.h> |
32 | #include <linux/aer.h> | ||
32 | 33 | ||
33 | /* | 34 | /* |
34 | * CPER record ID need to be unique even after reboot, because record | 35 | * CPER record ID need to be unique even after reboot, because record |
@@ -70,8 +71,8 @@ static const char *cper_severity_str(unsigned int severity) | |||
70 | * If the output length is longer than 80, multiple line will be | 71 | * If the output length is longer than 80, multiple line will be |
71 | * printed, with @pfx is printed at the beginning of each line. | 72 | * printed, with @pfx is printed at the beginning of each line. |
72 | */ | 73 | */ |
73 | static void cper_print_bits(const char *pfx, unsigned int bits, | 74 | void cper_print_bits(const char *pfx, unsigned int bits, |
74 | const char *strs[], unsigned int strs_size) | 75 | const char *strs[], unsigned int strs_size) |
75 | { | 76 | { |
76 | int i, len = 0; | 77 | int i, len = 0; |
77 | const char *str; | 78 | const char *str; |
@@ -81,6 +82,8 @@ static void cper_print_bits(const char *pfx, unsigned int bits, | |||
81 | if (!(bits & (1U << i))) | 82 | if (!(bits & (1U << i))) |
82 | continue; | 83 | continue; |
83 | str = strs[i]; | 84 | str = strs[i]; |
85 | if (!str) | ||
86 | continue; | ||
84 | if (len && len + strlen(str) + 2 > 80) { | 87 | if (len && len + strlen(str) + 2 > 80) { |
85 | printk("%s\n", buf); | 88 | printk("%s\n", buf); |
86 | len = 0; | 89 | len = 0; |
@@ -243,7 +246,8 @@ static const char *cper_pcie_port_type_strs[] = { | |||
243 | "root complex event collector", | 246 | "root complex event collector", |
244 | }; | 247 | }; |
245 | 248 | ||
246 | static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie) | 249 | static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, |
250 | const struct acpi_hest_generic_data *gdata) | ||
247 | { | 251 | { |
248 | if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE) | 252 | if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE) |
249 | printk("%s""port_type: %d, %s\n", pfx, pcie->port_type, | 253 | printk("%s""port_type: %d, %s\n", pfx, pcie->port_type, |
@@ -276,6 +280,12 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie) | |||
276 | printk( | 280 | printk( |
277 | "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n", | 281 | "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n", |
278 | pfx, pcie->bridge.secondary_status, pcie->bridge.control); | 282 | pfx, pcie->bridge.secondary_status, pcie->bridge.control); |
283 | #ifdef CONFIG_ACPI_APEI_PCIEAER | ||
284 | if (pcie->validation_bits & CPER_PCIE_VALID_AER_INFO) { | ||
285 | struct aer_capability_regs *aer_regs = (void *)pcie->aer_info; | ||
286 | cper_print_aer(pfx, gdata->error_severity, aer_regs); | ||
287 | } | ||
288 | #endif | ||
279 | } | 289 | } |
280 | 290 | ||
281 | static const char *apei_estatus_section_flag_strs[] = { | 291 | static const char *apei_estatus_section_flag_strs[] = { |
@@ -322,7 +332,7 @@ static void apei_estatus_print_section( | |||
322 | struct cper_sec_pcie *pcie = (void *)(gdata + 1); | 332 | struct cper_sec_pcie *pcie = (void *)(gdata + 1); |
323 | printk("%s""section_type: PCIe error\n", pfx); | 333 | printk("%s""section_type: PCIe error\n", pfx); |
324 | if (gdata->error_data_length >= sizeof(*pcie)) | 334 | if (gdata->error_data_length >= sizeof(*pcie)) |
325 | cper_print_pcie(pfx, pcie); | 335 | cper_print_pcie(pfx, pcie, gdata); |
326 | else | 336 | else |
327 | goto err_section_too_small; | 337 | goto err_section_too_small; |
328 | } else | 338 | } else |