Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6
[pandora-kernel.git] / drivers / acpi / apei / cper.c
index 31464a0..5d41894 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/time.h>
 #include <linux/cper.h>
 #include <linux/acpi.h>
+#include <linux/aer.h>
 
 /*
  * 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)
  * If the output length is longer than 80, multiple line will be
  * printed, with @pfx is printed at the beginning of each line.
  */
-static void cper_print_bits(const char *pfx, unsigned int bits,
-                           const char *strs[], unsigned int strs_size)
+void cper_print_bits(const char *pfx, unsigned int bits,
+                    const char *strs[], unsigned int strs_size)
 {
        int i, len = 0;
        const char *str;
@@ -81,6 +82,8 @@ static void cper_print_bits(const char *pfx, unsigned int bits,
                if (!(bits & (1U << i)))
                        continue;
                str = strs[i];
+               if (!str)
+                       continue;
                if (len && len + strlen(str) + 2 > 80) {
                        printk("%s\n", buf);
                        len = 0;
@@ -243,7 +246,8 @@ static const char *cper_pcie_port_type_strs[] = {
        "root complex event collector",
 };
 
-static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie)
+static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
+                           const struct acpi_hest_generic_data *gdata)
 {
        if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
                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)
                printk(
        "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n",
        pfx, pcie->bridge.secondary_status, pcie->bridge.control);
+#ifdef CONFIG_ACPI_APEI_PCIEAER
+       if (pcie->validation_bits & CPER_PCIE_VALID_AER_INFO) {
+               struct aer_capability_regs *aer_regs = (void *)pcie->aer_info;
+               cper_print_aer(pfx, gdata->error_severity, aer_regs);
+       }
+#endif
 }
 
 static const char *apei_estatus_section_flag_strs[] = {
@@ -322,7 +332,7 @@ static void apei_estatus_print_section(
                struct cper_sec_pcie *pcie = (void *)(gdata + 1);
                printk("%s""section_type: PCIe error\n", pfx);
                if (gdata->error_data_length >= sizeof(*pcie))
-                       cper_print_pcie(pfx, pcie);
+                       cper_print_pcie(pfx, pcie, gdata);
                else
                        goto err_section_too_small;
        } else