• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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| \
36 	((t == AER_CORRECTABLE) ? PCI_ERR_COR_REP_TIMER: 0)))
37 
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|		\
47 		PCI_ERR_COR_BAD_TLP| 		\
48 		PCI_ERR_COR_BAD_DLLP|		\
49 		PCI_ERR_COR_REP_ROLL| 		\
50 		((t == AER_CORRECTABLE) ?	\
51 		PCI_ERR_COR_REP_TIMER: 0))
52 
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)) ?		\
61 		AER_DATA_LINK_LAYER_ERROR : 			\
62 		AER_TRANSACTION_LAYER_ERROR)
63 
64 /*
65  * AER error strings
66  */
67 static char* aer_error_severity_string[] = {
68 	"Uncorrected (Non-Fatal)",
69 	"Uncorrected (Fatal)",
70 	"Corrected"
71 };
72 
73 static char* aer_error_layer[] = {
74 	"Physical Layer",
75 	"Data Link Layer",
76 	"Transaction Layer"
77 };
78 static char* aer_correctable_error_string[] = {
79 	"Receiver Error        ",	/* Bit Position 0 	*/
80 	NULL,
81 	NULL,
82 	NULL,
83 	NULL,
84 	NULL,
85 	"Bad TLP               ",	/* Bit Position 6 	*/
86 	"Bad DLLP              ",	/* Bit Position 7 	*/
87 	"RELAY_NUM Rollover    ",	/* Bit Position 8 	*/
88 	NULL,
89 	NULL,
90 	NULL,
91 	"Replay Timer Timeout  ",	/* Bit Position 12 	*/
92 	"Advisory Non-Fatal    ", 	/* Bit Position 13	*/
93 	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 
113 static char* aer_uncorrectable_error_string[] = {
114 	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,
126 	"Poisoned TLP          ",	/* Bit Position 12 	*/
127 	"Flow Control Protocol ",	/* Bit Position 13	*/
128 	"Completion Timeout    ",	/* Bit Position 14 	*/
129 	"Completer Abort       ",	/* Bit Position 15 	*/
130 	"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 
148 static char* aer_agent_string[] = {
149 	"Receiver ID",
150 	"Requester ID",
151 	"Completer ID",
152 	"Transmitter ID"
153 };
154 
aer_get_error_source_name(int severity,unsigned int status,char errmsg_buff[])155 static char * aer_get_error_source_name(int severity,
156 			unsigned int status,
157 			char errmsg_buff[])
158 {
159 	int i;
160 	char * errmsg = NULL;
161 
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 
182 static DEFINE_SPINLOCK(logbuf_lock);
183 static char errmsg_buff[100];
aer_print_error(struct pci_dev * dev,struct aer_err_info * info)184 void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
185 {
186 	char * errmsg;
187 	int err_layer, agent;
188 	char * loglevel;
189 
190 	if (info->severity == AER_CORRECTABLE)
191 		loglevel = KERN_WARNING;
192 	else
193 		loglevel = KERN_ERR;
194 
195 	printk("%s+------ PCI-Express Device Error ------+\n", loglevel);
196 	printk("%sError Severity\t\t: %s\n", loglevel,
197 		aer_error_severity_string[info->severity]);
198 
199 	if ( info->status == 0) {
200 		printk("%sPCIE Bus Error type\t: (Unaccessible)\n", loglevel);
201 		printk("%sUnaccessible Received\t: %s\n", loglevel,
202 			info->flags & AER_MULTI_ERROR_VALID_FLAG ?
203 				"Multiple" : "First");
204 		printk("%sUnregistered Agent ID\t: %04x\n", loglevel,
205 			(dev->bus->number << 8) | dev->devfn);
206 	} else {
207 		err_layer = AER_GET_LAYER_ERROR(info->severity, info->status);
208 		printk("%sPCIE Bus Error type\t: %s\n", loglevel,
209 			aer_error_layer[err_layer]);
210 
211 		spin_lock(&logbuf_lock);
212 		errmsg = aer_get_error_source_name(info->severity,
213 				info->status,
214 				errmsg_buff);
215 		printk("%s%s\t: %s\n", loglevel, errmsg,
216 			info->flags & AER_MULTI_ERROR_VALID_FLAG ?
217 				"Multiple" : "First");
218 		spin_unlock(&logbuf_lock);
219 
220 		agent = AER_GET_AGENT(info->severity, info->status);
221 		printk("%s%s\t\t: %04x\n", loglevel,
222 			aer_agent_string[agent],
223 			(dev->bus->number << 8) | dev->devfn);
224 
225 		printk("%sVendorID=%04xh, DeviceID=%04xh,"
226 			" Bus=%02xh, Device=%02xh, Function=%02xh\n",
227 			loglevel,
228 			dev->vendor,
229 			dev->device,
230 			dev->bus->number,
231 			PCI_SLOT(dev->devfn),
232 			PCI_FUNC(dev->devfn));
233 
234 		if (info->flags & AER_TLP_HEADER_VALID_FLAG) {
235 			unsigned char *tlp = (unsigned char *) &info->tlp;
236 			printk("%sTLP Header:\n", loglevel);
237 			printk("%s%02x%02x%02x%02x %02x%02x%02x%02x"
238 				" %02x%02x%02x%02x %02x%02x%02x%02x\n",
239 				loglevel,
240 				*(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp,
241 				*(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4),
242 				*(tlp + 11), *(tlp + 10), *(tlp + 9),
243 				*(tlp + 8), *(tlp + 15), *(tlp + 14),
244 				*(tlp + 13), *(tlp + 12));
245 		}
246 	}
247 }
248 
249