blob: 48f70fa7f6844f61404e70bee76fa2f16372b065 [file] [log] [blame]
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +08001/*
2 * drivers/pci/pcie/aer/aerdrv_errprint.c
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Format error messages and print them to console.
9 *
10 * Copyright (C) 2006 Intel Corp.
11 * Tom Long Nguyen (tom.l.nguyen@intel.com)
12 * Zhang Yanmin (yanmin.zhang@intel.com)
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/pci.h>
18#include <linux/kernel.h>
19#include <linux/errno.h>
20#include <linux/pm.h>
21#include <linux/suspend.h>
22
23#include "aerdrv.h"
24
25#define AER_AGENT_RECEIVER 0
26#define AER_AGENT_REQUESTER 1
27#define AER_AGENT_COMPLETER 2
28#define AER_AGENT_TRANSMITTER 3
29
Hidetoshi Setof1585752009-09-07 17:08:59 +090030#define AER_AGENT_REQUESTER_MASK(t) ((t == AER_CORRECTABLE) ? \
31 0 : (PCI_ERR_UNC_COMP_TIME|PCI_ERR_UNC_UNSUP))
32#define AER_AGENT_COMPLETER_MASK(t) ((t == AER_CORRECTABLE) ? \
33 0 : PCI_ERR_UNC_COMP_ABORT)
34#define AER_AGENT_TRANSMITTER_MASK(t) ((t == AER_CORRECTABLE) ? \
35 (PCI_ERR_COR_REP_ROLL|PCI_ERR_COR_REP_TIMER) : 0)
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080036
37#define AER_GET_AGENT(t, e) \
Hidetoshi Setof1585752009-09-07 17:08:59 +090038 ((e & AER_AGENT_COMPLETER_MASK(t)) ? AER_AGENT_COMPLETER : \
39 (e & AER_AGENT_REQUESTER_MASK(t)) ? AER_AGENT_REQUESTER : \
40 (e & AER_AGENT_TRANSMITTER_MASK(t)) ? AER_AGENT_TRANSMITTER : \
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080041 AER_AGENT_RECEIVER)
42
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080043#define AER_PHYSICAL_LAYER_ERROR 0
44#define AER_DATA_LINK_LAYER_ERROR 1
45#define AER_TRANSACTION_LAYER_ERROR 2
46
Hidetoshi Setof1585752009-09-07 17:08:59 +090047#define AER_PHYSICAL_LAYER_ERROR_MASK(t) ((t == AER_CORRECTABLE) ? \
48 PCI_ERR_COR_RCVR : 0)
49#define AER_DATA_LINK_LAYER_ERROR_MASK(t) ((t == AER_CORRECTABLE) ? \
50 (PCI_ERR_COR_BAD_TLP| \
51 PCI_ERR_COR_BAD_DLLP| \
52 PCI_ERR_COR_REP_ROLL| \
53 PCI_ERR_COR_REP_TIMER) : PCI_ERR_UNC_DLP)
54
55#define AER_GET_LAYER_ERROR(t, e) \
56 ((e & AER_PHYSICAL_LAYER_ERROR_MASK(t)) ? AER_PHYSICAL_LAYER_ERROR : \
57 (e & AER_DATA_LINK_LAYER_ERROR_MASK(t)) ? AER_DATA_LINK_LAYER_ERROR : \
58 AER_TRANSACTION_LAYER_ERROR)
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080059
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +090060#define AER_PR(info, fmt, args...) \
61 printk("%s" fmt, (info->severity == AER_CORRECTABLE) ? \
62 KERN_WARNING : KERN_ERR, ## args)
63
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080064/*
65 * AER error strings
66 */
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090067static char *aer_error_severity_string[] = {
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080068 "Uncorrected (Non-Fatal)",
69 "Uncorrected (Fatal)",
70 "Corrected"
71};
72
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090073static char *aer_error_layer[] = {
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080074 "Physical Layer",
75 "Data Link Layer",
76 "Transaction Layer"
77};
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090078static char *aer_correctable_error_string[] = {
79 "Receiver Error ", /* Bit Position 0 */
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080080 NULL,
81 NULL,
82 NULL,
83 NULL,
84 NULL,
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090085 "Bad TLP ", /* Bit Position 6 */
86 "Bad DLLP ", /* Bit Position 7 */
87 "RELAY_NUM Rollover ", /* Bit Position 8 */
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080088 NULL,
89 NULL,
90 NULL,
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090091 "Replay Timer Timeout ", /* Bit Position 12 */
92 "Advisory Non-Fatal ", /* Bit Position 13 */
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080093 NULL,
94 NULL,
95 NULL,
96 NULL,
97 NULL,
98 NULL,
99 NULL,
100 NULL,
101 NULL,
102 NULL,
103 NULL,
104 NULL,
105 NULL,
106 NULL,
107 NULL,
108 NULL,
109 NULL,
110 NULL,
111};
112
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900113static char *aer_uncorrectable_error_string[] = {
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800114 NULL,
115 NULL,
116 NULL,
117 NULL,
118 "Data Link Protocol ", /* Bit Position 4 */
119 NULL,
120 NULL,
121 NULL,
122 NULL,
123 NULL,
124 NULL,
125 NULL,
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900126 "Poisoned TLP ", /* Bit Position 12 */
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800127 "Flow Control Protocol ", /* Bit Position 13 */
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900128 "Completion Timeout ", /* Bit Position 14 */
129 "Completer Abort ", /* Bit Position 15 */
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800130 "Unexpected Completion ", /* Bit Position 16 */
131 "Receiver Overflow ", /* Bit Position 17 */
132 "Malformed TLP ", /* Bit Position 18 */
133 "ECRC ", /* Bit Position 19 */
134 "Unsupported Request ", /* Bit Position 20 */
135 NULL,
136 NULL,
137 NULL,
138 NULL,
139 NULL,
140 NULL,
141 NULL,
142 NULL,
143 NULL,
144 NULL,
145 NULL,
146};
147
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900148static char *aer_agent_string[] = {
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800149 "Receiver ID",
150 "Requester ID",
151 "Completer ID",
152 "Transmitter ID"
153};
154
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900155static char *aer_get_error_source_name(int severity,
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800156 unsigned int status,
157 char errmsg_buff[])
158{
159 int i;
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900160 char *errmsg = NULL;
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800161
162 for (i = 0; i < 32; i++) {
163 if (!(status & (1 << i)))
164 continue;
165
166 if (severity == AER_CORRECTABLE)
167 errmsg = aer_correctable_error_string[i];
168 else
169 errmsg = aer_uncorrectable_error_string[i];
170
171 if (!errmsg) {
172 sprintf(errmsg_buff, "Unknown Error Bit %2d ", i);
173 errmsg = errmsg_buff;
174 }
175
176 break;
177 }
178
179 return errmsg;
180}
181
182static DEFINE_SPINLOCK(logbuf_lock);
183static char errmsg_buff[100];
184void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
185{
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900186 char *errmsg;
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800187 int err_layer, agent;
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800188
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900189 AER_PR(info, "+------ PCI-Express Device Error ------+\n");
190 AER_PR(info, "Error Severity\t\t: %s\n",
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800191 aer_error_severity_string[info->severity]);
192
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900193 if (info->status == 0) {
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900194 AER_PR(info, "PCIE Bus Error type\t: (Unaccessible)\n");
195 AER_PR(info, "Unaccessible Received\t: %s\n",
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800196 info->flags & AER_MULTI_ERROR_VALID_FLAG ?
197 "Multiple" : "First");
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900198 AER_PR(info, "Unregistered Agent ID\t: %04x\n",
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800199 (dev->bus->number << 8) | dev->devfn);
200 } else {
201 err_layer = AER_GET_LAYER_ERROR(info->severity, info->status);
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900202 AER_PR(info, "PCIE Bus Error type\t: %s\n",
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800203 aer_error_layer[err_layer]);
204
205 spin_lock(&logbuf_lock);
206 errmsg = aer_get_error_source_name(info->severity,
207 info->status,
208 errmsg_buff);
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900209 AER_PR(info, "%s\t: %s\n", errmsg,
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800210 info->flags & AER_MULTI_ERROR_VALID_FLAG ?
211 "Multiple" : "First");
212 spin_unlock(&logbuf_lock);
213
214 agent = AER_GET_AGENT(info->severity, info->status);
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900215 AER_PR(info, "%s\t\t: %04x\n",
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800216 aer_agent_string[agent],
217 (dev->bus->number << 8) | dev->devfn);
218
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900219 AER_PR(info, "VendorID=%04xh, DeviceID=%04xh,"
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800220 " Bus=%02xh, Device=%02xh, Function=%02xh\n",
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800221 dev->vendor,
222 dev->device,
223 dev->bus->number,
224 PCI_SLOT(dev->devfn),
225 PCI_FUNC(dev->devfn));
226
227 if (info->flags & AER_TLP_HEADER_VALID_FLAG) {
228 unsigned char *tlp = (unsigned char *) &info->tlp;
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900229 AER_PR(info, "TLP Header:\n");
230 AER_PR(info, "%02x%02x%02x%02x %02x%02x%02x%02x"
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800231 " %02x%02x%02x%02x %02x%02x%02x%02x\n",
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800232 *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp,
233 *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4),
234 *(tlp + 11), *(tlp + 10), *(tlp + 9),
235 *(tlp + 8), *(tlp + 15), *(tlp + 14),
236 *(tlp + 13), *(tlp + 12));
237 }
238 }
239}