blob: 7fb5a2c71c6e962070b2f1a7f27ebae840b0b4c5 [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
30#define AER_AGENT_REQUESTER_MASK (PCI_ERR_UNC_COMP_TIME| \
31 PCI_ERR_UNC_UNSUP)
32
33#define AER_AGENT_COMPLETER_MASK PCI_ERR_UNC_COMP_ABORT
34
35#define AER_AGENT_TRANSMITTER_MASK(t, e) (e & (PCI_ERR_COR_REP_ROLL| \
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090036 ((t == AER_CORRECTABLE) ? PCI_ERR_COR_REP_TIMER : 0)))
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080037
38#define AER_GET_AGENT(t, e) \
39 ((e & AER_AGENT_COMPLETER_MASK) ? AER_AGENT_COMPLETER : \
40 (e & AER_AGENT_REQUESTER_MASK) ? AER_AGENT_REQUESTER : \
41 (AER_AGENT_TRANSMITTER_MASK(t, e)) ? AER_AGENT_TRANSMITTER : \
42 AER_AGENT_RECEIVER)
43
44#define AER_PHYSICAL_LAYER_ERROR_MASK PCI_ERR_COR_RCVR
45#define AER_DATA_LINK_LAYER_ERROR_MASK(t, e) \
46 (PCI_ERR_UNC_DLP| \
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090047 PCI_ERR_COR_BAD_TLP| \
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080048 PCI_ERR_COR_BAD_DLLP| \
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090049 PCI_ERR_COR_REP_ROLL| \
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080050 ((t == AER_CORRECTABLE) ? \
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090051 PCI_ERR_COR_REP_TIMER : 0))
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080052
53#define AER_PHYSICAL_LAYER_ERROR 0
54#define AER_DATA_LINK_LAYER_ERROR 1
55#define AER_TRANSACTION_LAYER_ERROR 2
56
57#define AER_GET_LAYER_ERROR(t, e) \
58 ((e & AER_PHYSICAL_LAYER_ERROR_MASK) ? \
59 AER_PHYSICAL_LAYER_ERROR : \
60 (e & AER_DATA_LINK_LAYER_ERROR_MASK(t, e)) ? \
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090061 AER_DATA_LINK_LAYER_ERROR : \
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080062 AER_TRANSACTION_LAYER_ERROR)
63
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +090064#define AER_PR(info, fmt, args...) \
65 printk("%s" fmt, (info->severity == AER_CORRECTABLE) ? \
66 KERN_WARNING : KERN_ERR, ## args)
67
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080068/*
69 * AER error strings
70 */
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090071static char *aer_error_severity_string[] = {
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080072 "Uncorrected (Non-Fatal)",
73 "Uncorrected (Fatal)",
74 "Corrected"
75};
76
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090077static char *aer_error_layer[] = {
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080078 "Physical Layer",
79 "Data Link Layer",
80 "Transaction Layer"
81};
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090082static char *aer_correctable_error_string[] = {
83 "Receiver Error ", /* Bit Position 0 */
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080084 NULL,
85 NULL,
86 NULL,
87 NULL,
88 NULL,
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090089 "Bad TLP ", /* Bit Position 6 */
90 "Bad DLLP ", /* Bit Position 7 */
91 "RELAY_NUM Rollover ", /* Bit Position 8 */
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080092 NULL,
93 NULL,
94 NULL,
Hidetoshi Setoc9a91882009-09-07 17:07:29 +090095 "Replay Timer Timeout ", /* Bit Position 12 */
96 "Advisory Non-Fatal ", /* Bit Position 13 */
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +080097 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 NULL,
112 NULL,
113 NULL,
114 NULL,
115};
116
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900117static char *aer_uncorrectable_error_string[] = {
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800118 NULL,
119 NULL,
120 NULL,
121 NULL,
122 "Data Link Protocol ", /* Bit Position 4 */
123 NULL,
124 NULL,
125 NULL,
126 NULL,
127 NULL,
128 NULL,
129 NULL,
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900130 "Poisoned TLP ", /* Bit Position 12 */
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800131 "Flow Control Protocol ", /* Bit Position 13 */
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900132 "Completion Timeout ", /* Bit Position 14 */
133 "Completer Abort ", /* Bit Position 15 */
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800134 "Unexpected Completion ", /* Bit Position 16 */
135 "Receiver Overflow ", /* Bit Position 17 */
136 "Malformed TLP ", /* Bit Position 18 */
137 "ECRC ", /* Bit Position 19 */
138 "Unsupported Request ", /* Bit Position 20 */
139 NULL,
140 NULL,
141 NULL,
142 NULL,
143 NULL,
144 NULL,
145 NULL,
146 NULL,
147 NULL,
148 NULL,
149 NULL,
150};
151
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900152static char *aer_agent_string[] = {
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800153 "Receiver ID",
154 "Requester ID",
155 "Completer ID",
156 "Transmitter ID"
157};
158
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900159static char *aer_get_error_source_name(int severity,
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800160 unsigned int status,
161 char errmsg_buff[])
162{
163 int i;
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900164 char *errmsg = NULL;
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800165
166 for (i = 0; i < 32; i++) {
167 if (!(status & (1 << i)))
168 continue;
169
170 if (severity == AER_CORRECTABLE)
171 errmsg = aer_correctable_error_string[i];
172 else
173 errmsg = aer_uncorrectable_error_string[i];
174
175 if (!errmsg) {
176 sprintf(errmsg_buff, "Unknown Error Bit %2d ", i);
177 errmsg = errmsg_buff;
178 }
179
180 break;
181 }
182
183 return errmsg;
184}
185
186static DEFINE_SPINLOCK(logbuf_lock);
187static char errmsg_buff[100];
188void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
189{
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900190 char *errmsg;
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800191 int err_layer, agent;
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800192
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900193 AER_PR(info, "+------ PCI-Express Device Error ------+\n");
194 AER_PR(info, "Error Severity\t\t: %s\n",
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800195 aer_error_severity_string[info->severity]);
196
Hidetoshi Setoc9a91882009-09-07 17:07:29 +0900197 if (info->status == 0) {
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900198 AER_PR(info, "PCIE Bus Error type\t: (Unaccessible)\n");
199 AER_PR(info, "Unaccessible Received\t: %s\n",
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800200 info->flags & AER_MULTI_ERROR_VALID_FLAG ?
201 "Multiple" : "First");
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900202 AER_PR(info, "Unregistered Agent ID\t: %04x\n",
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800203 (dev->bus->number << 8) | dev->devfn);
204 } else {
205 err_layer = AER_GET_LAYER_ERROR(info->severity, info->status);
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900206 AER_PR(info, "PCIE Bus Error type\t: %s\n",
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800207 aer_error_layer[err_layer]);
208
209 spin_lock(&logbuf_lock);
210 errmsg = aer_get_error_source_name(info->severity,
211 info->status,
212 errmsg_buff);
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900213 AER_PR(info, "%s\t: %s\n", errmsg,
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800214 info->flags & AER_MULTI_ERROR_VALID_FLAG ?
215 "Multiple" : "First");
216 spin_unlock(&logbuf_lock);
217
218 agent = AER_GET_AGENT(info->severity, info->status);
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900219 AER_PR(info, "%s\t\t: %04x\n",
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800220 aer_agent_string[agent],
221 (dev->bus->number << 8) | dev->devfn);
222
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900223 AER_PR(info, "VendorID=%04xh, DeviceID=%04xh,"
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800224 " Bus=%02xh, Device=%02xh, Function=%02xh\n",
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800225 dev->vendor,
226 dev->device,
227 dev->bus->number,
228 PCI_SLOT(dev->devfn),
229 PCI_FUNC(dev->devfn));
230
231 if (info->flags & AER_TLP_HEADER_VALID_FLAG) {
232 unsigned char *tlp = (unsigned char *) &info->tlp;
Hidetoshi Setobd8fedd2009-09-07 17:08:14 +0900233 AER_PR(info, "TLP Header:\n");
234 AER_PR(info, "%02x%02x%02x%02x %02x%02x%02x%02x"
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800235 " %02x%02x%02x%02x %02x%02x%02x%02x\n",
Zhang, Yanmin6c2b3742006-07-31 15:21:33 +0800236 *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp,
237 *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4),
238 *(tlp + 11), *(tlp + 10), *(tlp + 9),
239 *(tlp + 8), *(tlp + 15), *(tlp + 14),
240 *(tlp + 13), *(tlp + 12));
241 }
242 }
243}