aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie/aer
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/pci/pcie/aer
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/pci/pcie/aer')
-rw-r--r--drivers/pci/pcie/aer/aer_inject.c32
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c3
-rw-r--r--drivers/pci/pcie/aer/aerdrv.h18
-rw-r--r--drivers/pci/pcie/aer/aerdrv_acpi.c34
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv_errprint.c182
6 files changed, 174 insertions, 97 deletions
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 909924692b8a..95489cd9a555 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -27,6 +27,10 @@
27#include <linux/stddef.h> 27#include <linux/stddef.h>
28#include "aerdrv.h" 28#include "aerdrv.h"
29 29
30/* Override the existing corrected and uncorrected error masks */
31static int aer_mask_override;
32module_param(aer_mask_override, bool, 0);
33
30struct aer_error_inj { 34struct aer_error_inj {
31 u8 bus; 35 u8 bus;
32 u8 dev; 36 u8 dev;
@@ -322,7 +326,7 @@ static int aer_inject(struct aer_error_inj *einj)
322 unsigned long flags; 326 unsigned long flags;
323 unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn); 327 unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn);
324 int pos_cap_err, rp_pos_cap_err; 328 int pos_cap_err, rp_pos_cap_err;
325 u32 sever, cor_mask, uncor_mask; 329 u32 sever, cor_mask, uncor_mask, cor_mask_orig = 0, uncor_mask_orig = 0;
326 int ret = 0; 330 int ret = 0;
327 331
328 dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn); 332 dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn);
@@ -361,6 +365,18 @@ static int aer_inject(struct aer_error_inj *einj)
361 goto out_put; 365 goto out_put;
362 } 366 }
363 367
368 if (aer_mask_override) {
369 cor_mask_orig = cor_mask;
370 cor_mask &= !(einj->cor_status);
371 pci_write_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK,
372 cor_mask);
373
374 uncor_mask_orig = uncor_mask;
375 uncor_mask &= !(einj->uncor_status);
376 pci_write_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK,
377 uncor_mask);
378 }
379
364 spin_lock_irqsave(&inject_lock, flags); 380 spin_lock_irqsave(&inject_lock, flags);
365 381
366 err = __find_aer_error_by_dev(dev); 382 err = __find_aer_error_by_dev(dev);
@@ -378,14 +394,16 @@ static int aer_inject(struct aer_error_inj *einj)
378 err->header_log2 = einj->header_log2; 394 err->header_log2 = einj->header_log2;
379 err->header_log3 = einj->header_log3; 395 err->header_log3 = einj->header_log3;
380 396
381 if (einj->cor_status && !(einj->cor_status & ~cor_mask)) { 397 if (!aer_mask_override && einj->cor_status &&
398 !(einj->cor_status & ~cor_mask)) {
382 ret = -EINVAL; 399 ret = -EINVAL;
383 printk(KERN_WARNING "The correctable error(s) is masked " 400 printk(KERN_WARNING "The correctable error(s) is masked "
384 "by device\n"); 401 "by device\n");
385 spin_unlock_irqrestore(&inject_lock, flags); 402 spin_unlock_irqrestore(&inject_lock, flags);
386 goto out_put; 403 goto out_put;
387 } 404 }
388 if (einj->uncor_status && !(einj->uncor_status & ~uncor_mask)) { 405 if (!aer_mask_override && einj->uncor_status &&
406 !(einj->uncor_status & ~uncor_mask)) {
389 ret = -EINVAL; 407 ret = -EINVAL;
390 printk(KERN_WARNING "The uncorrectable error(s) is masked " 408 printk(KERN_WARNING "The uncorrectable error(s) is masked "
391 "by device\n"); 409 "by device\n");
@@ -425,6 +443,13 @@ static int aer_inject(struct aer_error_inj *einj)
425 } 443 }
426 spin_unlock_irqrestore(&inject_lock, flags); 444 spin_unlock_irqrestore(&inject_lock, flags);
427 445
446 if (aer_mask_override) {
447 pci_write_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK,
448 cor_mask_orig);
449 pci_write_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK,
450 uncor_mask_orig);
451 }
452
428 ret = pci_bus_set_aer_ops(dev->bus); 453 ret = pci_bus_set_aer_ops(dev->bus);
429 if (ret) 454 if (ret)
430 goto out_put; 455 goto out_put;
@@ -472,6 +497,7 @@ static ssize_t aer_inject_write(struct file *filp, const char __user *ubuf,
472static const struct file_operations aer_inject_fops = { 497static const struct file_operations aer_inject_fops = {
473 .write = aer_inject_write, 498 .write = aer_inject_write,
474 .owner = THIS_MODULE, 499 .owner = THIS_MODULE,
500 .llseek = noop_llseek,
475}; 501};
476 502
477static struct miscdevice aer_inject_device = { 503static struct miscdevice aer_inject_device = {
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index f409948e1a9b..58ad7917553c 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -17,6 +17,7 @@
17 17
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/pci.h> 19#include <linux/pci.h>
20#include <linux/pci-acpi.h>
20#include <linux/sched.h> 21#include <linux/sched.h>
21#include <linux/kernel.h> 22#include <linux/kernel.h>
22#include <linux/errno.h> 23#include <linux/errno.h>
@@ -416,7 +417,7 @@ static void aer_error_resume(struct pci_dev *dev)
416 */ 417 */
417static int __init aer_service_init(void) 418static int __init aer_service_init(void)
418{ 419{
419 if (!pci_aer_available()) 420 if (!pci_aer_available() || aer_acpi_firmware_first())
420 return -ENXIO; 421 return -ENXIO;
421 return pcie_port_service_register(&aerdriver); 422 return pcie_port_service_register(&aerdriver);
422} 423}
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index 80c11d131499..94a7598eb262 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 {
@@ -121,15 +114,6 @@ extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
121extern void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info); 114extern void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info);
122extern irqreturn_t aer_irq(int irq, void *context); 115extern irqreturn_t aer_irq(int irq, void *context);
123 116
124#ifdef CONFIG_ACPI
125extern int aer_osc_setup(struct pcie_device *pciedev);
126#else
127static inline int aer_osc_setup(struct pcie_device *pciedev)
128{
129 return 0;
130}
131#endif
132
133#ifdef CONFIG_ACPI_APEI 117#ifdef CONFIG_ACPI_APEI
134extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); 118extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev);
135#else 119#else
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c
index 2bb9b8972211..275bf158ffa7 100644
--- a/drivers/pci/pcie/aer/aerdrv_acpi.c
+++ b/drivers/pci/pcie/aer/aerdrv_acpi.c
@@ -93,4 +93,38 @@ int pcie_aer_get_firmware_first(struct pci_dev *dev)
93 aer_set_firmware_first(dev); 93 aer_set_firmware_first(dev);
94 return dev->__aer_firmware_first; 94 return dev->__aer_firmware_first;
95} 95}
96
97static bool aer_firmware_first;
98
99static int aer_hest_parse_aff(struct acpi_hest_header *hest_hdr, void *data)
100{
101 struct acpi_hest_aer_common *p;
102
103 if (aer_firmware_first)
104 return 0;
105
106 switch (hest_hdr->type) {
107 case ACPI_HEST_TYPE_AER_ROOT_PORT:
108 case ACPI_HEST_TYPE_AER_ENDPOINT:
109 case ACPI_HEST_TYPE_AER_BRIDGE:
110 p = (struct acpi_hest_aer_common *)(hest_hdr + 1);
111 aer_firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST);
112 default:
113 return 0;
114 }
115}
116
117/**
118 * aer_acpi_firmware_first - Check if APEI should control AER.
119 */
120bool aer_acpi_firmware_first(void)
121{
122 static bool parsed = false;
123
124 if (!parsed) {
125 apei_hest_parse(aer_hest_parse_aff, NULL);
126 parsed = true;
127 }
128 return aer_firmware_first;
129}
96#endif 130#endif
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 29e268fadf14..43421fbe080a 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -754,7 +754,7 @@ void aer_isr(struct work_struct *work)
754{ 754{
755 struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler); 755 struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler);
756 struct pcie_device *p_device = rpc->rpd; 756 struct pcie_device *p_device = rpc->rpd;
757 struct aer_err_source e_src; 757 struct aer_err_source uninitialized_var(e_src);
758 758
759 mutex_lock(&rpc->rpc_mutex); 759 mutex_lock(&rpc->rpc_mutex);
760 while (get_e_source(rpc, &e_src)) 760 while (get_e_source(rpc, &e_src))
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c
index 9d3e4c8d0184..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
@@ -57,86 +58,44 @@
57 (e & AER_DATA_LINK_LAYER_ERROR_MASK(t)) ? AER_DATA_LINK_LAYER_ERROR : \ 58 (e & AER_DATA_LINK_LAYER_ERROR_MASK(t)) ? AER_DATA_LINK_LAYER_ERROR : \
58 AER_TRANSACTION_LAYER_ERROR) 59 AER_TRANSACTION_LAYER_ERROR)
59 60
60#define AER_PR(info, pdev, fmt, args...) \
61 printk("%s%s %s: " fmt, (info->severity == AER_CORRECTABLE) ? \
62 KERN_WARNING : KERN_ERR, dev_driver_string(&pdev->dev), \
63 dev_name(&pdev->dev), ## args)
64
65/* 61/*
66 * AER error strings 62 * AER error strings
67 */ 63 */
68static char *aer_error_severity_string[] = { 64static const char *aer_error_severity_string[] = {
69 "Uncorrected (Non-Fatal)", 65 "Uncorrected (Non-Fatal)",
70 "Uncorrected (Fatal)", 66 "Uncorrected (Fatal)",
71 "Corrected" 67 "Corrected"
72}; 68};
73 69
74static char *aer_error_layer[] = { 70static const char *aer_error_layer[] = {
75 "Physical Layer", 71 "Physical Layer",
76 "Data Link Layer", 72 "Data Link Layer",
77 "Transaction Layer" 73 "Transaction Layer"
78}; 74};
79static char *aer_correctable_error_string[] = { 75
80 "Receiver Error ", /* Bit Position 0 */ 76static const char *aer_correctable_error_string[] = {
81 NULL, 77 "Receiver Error", /* Bit Position 0 */
82 NULL,
83 NULL,
84 NULL,
85 NULL,
86 "Bad TLP ", /* Bit Position 6 */
87 "Bad DLLP ", /* Bit Position 7 */
88 "RELAY_NUM Rollover ", /* Bit Position 8 */
89 NULL,
90 NULL,
91 NULL,
92 "Replay Timer Timeout ", /* Bit Position 12 */
93 "Advisory Non-Fatal ", /* Bit Position 13 */
94 NULL,
95 NULL,
96 NULL,
97 NULL,
98 NULL,
99 NULL,
100 NULL,
101 NULL,
102 NULL,
103 NULL,
104 NULL, 78 NULL,
105 NULL, 79 NULL,
106 NULL, 80 NULL,
107 NULL, 81 NULL,
108 NULL, 82 NULL,
83 "Bad TLP", /* Bit Position 6 */
84 "Bad DLLP", /* Bit Position 7 */
85 "RELAY_NUM Rollover", /* Bit Position 8 */
109 NULL, 86 NULL,
110 NULL, 87 NULL,
111 NULL, 88 NULL,
89 "Replay Timer Timeout", /* Bit Position 12 */
90 "Advisory Non-Fatal", /* Bit Position 13 */
112}; 91};
113 92
114static char *aer_uncorrectable_error_string[] = { 93static const char *aer_uncorrectable_error_string[] = {
115 NULL,
116 NULL,
117 NULL,
118 NULL,
119 "Data Link Protocol ", /* Bit Position 4 */
120 NULL,
121 NULL,
122 NULL,
123 NULL,
124 NULL,
125 NULL,
126 NULL,
127 "Poisoned TLP ", /* Bit Position 12 */
128 "Flow Control Protocol ", /* Bit Position 13 */
129 "Completion Timeout ", /* Bit Position 14 */
130 "Completer Abort ", /* Bit Position 15 */
131 "Unexpected Completion ", /* Bit Position 16 */
132 "Receiver Overflow ", /* Bit Position 17 */
133 "Malformed TLP ", /* Bit Position 18 */
134 "ECRC ", /* Bit Position 19 */
135 "Unsupported Request ", /* Bit Position 20 */
136 NULL, 94 NULL,
137 NULL, 95 NULL,
138 NULL, 96 NULL,
139 NULL, 97 NULL,
98 "Data Link Protocol", /* Bit Position 4 */
140 NULL, 99 NULL,
141 NULL, 100 NULL,
142 NULL, 101 NULL,
@@ -144,19 +103,29 @@ static char *aer_uncorrectable_error_string[] = {
144 NULL, 103 NULL,
145 NULL, 104 NULL,
146 NULL, 105 NULL,
106 "Poisoned TLP", /* Bit Position 12 */
107 "Flow Control Protocol", /* Bit Position 13 */
108 "Completion Timeout", /* Bit Position 14 */
109 "Completer Abort", /* Bit Position 15 */
110 "Unexpected Completion", /* Bit Position 16 */
111 "Receiver Overflow", /* Bit Position 17 */
112 "Malformed TLP", /* Bit Position 18 */
113 "ECRC", /* Bit Position 19 */
114 "Unsupported Request", /* Bit Position 20 */
147}; 115};
148 116
149static char *aer_agent_string[] = { 117static const char *aer_agent_string[] = {
150 "Receiver ID", 118 "Receiver ID",
151 "Requester ID", 119 "Requester ID",
152 "Completer ID", 120 "Completer ID",
153 "Transmitter ID" 121 "Transmitter ID"
154}; 122};
155 123
156static void __aer_print_error(struct aer_err_info *info, struct pci_dev *dev) 124static void __aer_print_error(const char *prefix,
125 struct aer_err_info *info)
157{ 126{
158 int i, status; 127 int i, status;
159 char *errmsg = NULL; 128 const char *errmsg = NULL;
160 129
161 status = (info->status & ~info->mask); 130 status = (info->status & ~info->mask);
162 131
@@ -165,15 +134,17 @@ static void __aer_print_error(struct aer_err_info *info, struct pci_dev *dev)
165 continue; 134 continue;
166 135
167 if (info->severity == AER_CORRECTABLE) 136 if (info->severity == AER_CORRECTABLE)
168 errmsg = aer_correctable_error_string[i]; 137 errmsg = i < ARRAY_SIZE(aer_correctable_error_string) ?
138 aer_correctable_error_string[i] : NULL;
169 else 139 else
170 errmsg = aer_uncorrectable_error_string[i]; 140 errmsg = i < ARRAY_SIZE(aer_uncorrectable_error_string) ?
141 aer_uncorrectable_error_string[i] : NULL;
171 142
172 if (errmsg) 143 if (errmsg)
173 AER_PR(info, dev, " [%2d] %s%s\n", i, errmsg, 144 printk("%s"" [%2d] %-22s%s\n", prefix, i, errmsg,
174 info->first_error == i ? " (First)" : ""); 145 info->first_error == i ? " (First)" : "");
175 else 146 else
176 AER_PR(info, dev, " [%2d] Unknown Error Bit%s\n", i, 147 printk("%s"" [%2d] Unknown Error Bit%s\n", prefix, i,
177 info->first_error == i ? " (First)" : ""); 148 info->first_error == i ? " (First)" : "");
178 } 149 }
179} 150}
@@ -181,11 +152,15 @@ static void __aer_print_error(struct aer_err_info *info, struct pci_dev *dev)
181void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) 152void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
182{ 153{
183 int id = ((dev->bus->number << 8) | dev->devfn); 154 int id = ((dev->bus->number << 8) | dev->devfn);
155 char prefix[44];
156
157 snprintf(prefix, sizeof(prefix), "%s%s %s: ",
158 (info->severity == AER_CORRECTABLE) ? KERN_WARNING : KERN_ERR,
159 dev_driver_string(&dev->dev), dev_name(&dev->dev));
184 160
185 if (info->status == 0) { 161 if (info->status == 0) {
186 AER_PR(info, dev, 162 printk("%s""PCIe Bus Error: severity=%s, type=Unaccessible, "
187 "PCIe Bus Error: severity=%s, type=Unaccessible, " 163 "id=%04x(Unregistered Agent ID)\n", prefix,
188 "id=%04x(Unregistered Agent ID)\n",
189 aer_error_severity_string[info->severity], id); 164 aer_error_severity_string[info->severity], id);
190 } else { 165 } else {
191 int layer, agent; 166 int layer, agent;
@@ -193,23 +168,22 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
193 layer = AER_GET_LAYER_ERROR(info->severity, info->status); 168 layer = AER_GET_LAYER_ERROR(info->severity, info->status);
194 agent = AER_GET_AGENT(info->severity, info->status); 169 agent = AER_GET_AGENT(info->severity, info->status);
195 170
196 AER_PR(info, dev, 171 printk("%s""PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n",
197 "PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n", 172 prefix, aer_error_severity_string[info->severity],
198 aer_error_severity_string[info->severity],
199 aer_error_layer[layer], id, aer_agent_string[agent]); 173 aer_error_layer[layer], id, aer_agent_string[agent]);
200 174
201 AER_PR(info, dev, 175 printk("%s"" device [%04x:%04x] error status/mask=%08x/%08x\n",
202 " device [%04x:%04x] error status/mask=%08x/%08x\n", 176 prefix, dev->vendor, dev->device,
203 dev->vendor, dev->device, info->status, info->mask); 177 info->status, info->mask);
204 178
205 __aer_print_error(info, dev); 179 __aer_print_error(prefix, info);
206 180
207 if (info->tlp_header_valid) { 181 if (info->tlp_header_valid) {
208 unsigned char *tlp = (unsigned char *) &info->tlp; 182 unsigned char *tlp = (unsigned char *) &info->tlp;
209 AER_PR(info, dev, " TLP Header:" 183 printk("%s"" TLP Header:"
210 " %02x%02x%02x%02x %02x%02x%02x%02x" 184 " %02x%02x%02x%02x %02x%02x%02x%02x"
211 " %02x%02x%02x%02x %02x%02x%02x%02x\n", 185 " %02x%02x%02x%02x %02x%02x%02x%02x\n",
212 *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp, 186 prefix, *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp,
213 *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4), 187 *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4),
214 *(tlp + 11), *(tlp + 10), *(tlp + 9), 188 *(tlp + 11), *(tlp + 10), *(tlp + 9),
215 *(tlp + 8), *(tlp + 15), *(tlp + 14), 189 *(tlp + 8), *(tlp + 15), *(tlp + 14),
@@ -218,8 +192,8 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
218 } 192 }
219 193
220 if (info->id && info->error_dev_num > 1 && info->id == id) 194 if (info->id && info->error_dev_num > 1 && info->id == id)
221 AER_PR(info, dev, 195 printk("%s"" Error of this Agent(%04x) is reported first\n",
222 " Error of this Agent(%04x) is reported first\n", id); 196 prefix, id);
223} 197}
224 198
225void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info) 199void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info)
@@ -228,3 +202,61 @@ void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info)
228 info->multi_error_valid ? "Multiple " : "", 202 info->multi_error_valid ? "Multiple " : "",
229 aer_error_severity_string[info->severity], info->id); 203 aer_error_severity_string[info->severity], info->id);
230} 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