PCI: pcie, aer: AER_PR for printing in aerdrv_errprint.c
[pandora-kernel.git] / drivers / pci / pcie / aer / aerdrv_errprint.c
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 #define AER_PR(info, fmt, args...)                              \
65         printk("%s" fmt, (info->severity == AER_CORRECTABLE) ?  \
66                 KERN_WARNING : KERN_ERR, ## args)
67
68 /*
69  * AER error strings
70  */
71 static char *aer_error_severity_string[] = {
72         "Uncorrected (Non-Fatal)",
73         "Uncorrected (Fatal)",
74         "Corrected"
75 };
76
77 static char *aer_error_layer[] = {
78         "Physical Layer",
79         "Data Link Layer",
80         "Transaction Layer"
81 };
82 static char *aer_correctable_error_string[] = {
83         "Receiver Error        ",       /* Bit Position 0       */
84         NULL,
85         NULL,
86         NULL,
87         NULL,
88         NULL,
89         "Bad TLP               ",       /* Bit Position 6       */
90         "Bad DLLP              ",       /* Bit Position 7       */
91         "RELAY_NUM Rollover    ",       /* Bit Position 8       */
92         NULL,
93         NULL,
94         NULL,
95         "Replay Timer Timeout  ",       /* Bit Position 12      */
96         "Advisory Non-Fatal    ",       /* Bit Position 13      */
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         NULL,
112         NULL,
113         NULL,
114         NULL,
115 };
116
117 static char *aer_uncorrectable_error_string[] = {
118         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,
130         "Poisoned TLP          ",       /* Bit Position 12      */
131         "Flow Control Protocol ",       /* Bit Position 13      */
132         "Completion Timeout    ",       /* Bit Position 14      */
133         "Completer Abort       ",       /* Bit Position 15      */
134         "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
152 static char *aer_agent_string[] = {
153         "Receiver ID",
154         "Requester ID",
155         "Completer ID",
156         "Transmitter ID"
157 };
158
159 static char *aer_get_error_source_name(int severity,
160                         unsigned int status,
161                         char errmsg_buff[])
162 {
163         int i;
164         char *errmsg = NULL;
165
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
186 static DEFINE_SPINLOCK(logbuf_lock);
187 static char errmsg_buff[100];
188 void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
189 {
190         char *errmsg;
191         int err_layer, agent;
192
193         AER_PR(info, "+------ PCI-Express Device Error ------+\n");
194         AER_PR(info, "Error Severity\t\t: %s\n",
195                 aer_error_severity_string[info->severity]);
196
197         if (info->status == 0) {
198                 AER_PR(info, "PCIE Bus Error type\t: (Unaccessible)\n");
199                 AER_PR(info, "Unaccessible Received\t: %s\n",
200                         info->flags & AER_MULTI_ERROR_VALID_FLAG ?
201                                 "Multiple" : "First");
202                 AER_PR(info, "Unregistered Agent ID\t: %04x\n",
203                         (dev->bus->number << 8) | dev->devfn);
204         } else {
205                 err_layer = AER_GET_LAYER_ERROR(info->severity, info->status);
206                 AER_PR(info, "PCIE Bus Error type\t: %s\n",
207                         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);
213                 AER_PR(info, "%s\t: %s\n", errmsg,
214                         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);
219                 AER_PR(info, "%s\t\t: %04x\n",
220                         aer_agent_string[agent],
221                         (dev->bus->number << 8) | dev->devfn);
222
223                 AER_PR(info, "VendorID=%04xh, DeviceID=%04xh,"
224                         " Bus=%02xh, Device=%02xh, Function=%02xh\n",
225                         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;
233                         AER_PR(info, "TLP Header:\n");
234                         AER_PR(info, "%02x%02x%02x%02x %02x%02x%02x%02x"
235                                 " %02x%02x%02x%02x %02x%02x%02x%02x\n",
236                                 *(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 }