diff options
Diffstat (limited to 'drivers/pci/pcie/aer/aerdrv_errprint.c')
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_errprint.c | 190 |
1 files changed, 86 insertions, 104 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c index 0fc29ae80df8..44acde72294f 100644 --- a/drivers/pci/pcie/aer/aerdrv_errprint.c +++ b/drivers/pci/pcie/aer/aerdrv_errprint.c | |||
@@ -27,69 +27,70 @@ | |||
27 | #define AER_AGENT_COMPLETER 2 | 27 | #define AER_AGENT_COMPLETER 2 |
28 | #define AER_AGENT_TRANSMITTER 3 | 28 | #define AER_AGENT_TRANSMITTER 3 |
29 | 29 | ||
30 | #define AER_AGENT_REQUESTER_MASK (PCI_ERR_UNC_COMP_TIME| \ | 30 | #define AER_AGENT_REQUESTER_MASK(t) ((t == AER_CORRECTABLE) ? \ |
31 | PCI_ERR_UNC_UNSUP) | 31 | 0 : (PCI_ERR_UNC_COMP_TIME|PCI_ERR_UNC_UNSUP)) |
32 | 32 | #define AER_AGENT_COMPLETER_MASK(t) ((t == AER_CORRECTABLE) ? \ | |
33 | #define AER_AGENT_COMPLETER_MASK PCI_ERR_UNC_COMP_ABORT | 33 | 0 : PCI_ERR_UNC_COMP_ABORT) |
34 | 34 | #define AER_AGENT_TRANSMITTER_MASK(t) ((t == AER_CORRECTABLE) ? \ | |
35 | #define AER_AGENT_TRANSMITTER_MASK(t, e) (e & (PCI_ERR_COR_REP_ROLL| \ | 35 | (PCI_ERR_COR_REP_ROLL|PCI_ERR_COR_REP_TIMER) : 0) |
36 | ((t == AER_CORRECTABLE) ? PCI_ERR_COR_REP_TIMER: 0))) | ||
37 | 36 | ||
38 | #define AER_GET_AGENT(t, e) \ | 37 | #define AER_GET_AGENT(t, e) \ |
39 | ((e & AER_AGENT_COMPLETER_MASK) ? AER_AGENT_COMPLETER : \ | 38 | ((e & AER_AGENT_COMPLETER_MASK(t)) ? AER_AGENT_COMPLETER : \ |
40 | (e & AER_AGENT_REQUESTER_MASK) ? AER_AGENT_REQUESTER : \ | 39 | (e & AER_AGENT_REQUESTER_MASK(t)) ? AER_AGENT_REQUESTER : \ |
41 | (AER_AGENT_TRANSMITTER_MASK(t, e)) ? AER_AGENT_TRANSMITTER : \ | 40 | (e & AER_AGENT_TRANSMITTER_MASK(t)) ? AER_AGENT_TRANSMITTER : \ |
42 | AER_AGENT_RECEIVER) | 41 | AER_AGENT_RECEIVER) |
43 | 42 | ||
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 | 43 | #define AER_PHYSICAL_LAYER_ERROR 0 |
54 | #define AER_DATA_LINK_LAYER_ERROR 1 | 44 | #define AER_DATA_LINK_LAYER_ERROR 1 |
55 | #define AER_TRANSACTION_LAYER_ERROR 2 | 45 | #define AER_TRANSACTION_LAYER_ERROR 2 |
56 | 46 | ||
57 | #define AER_GET_LAYER_ERROR(t, e) \ | 47 | #define AER_PHYSICAL_LAYER_ERROR_MASK(t) ((t == AER_CORRECTABLE) ? \ |
58 | ((e & AER_PHYSICAL_LAYER_ERROR_MASK) ? \ | 48 | PCI_ERR_COR_RCVR : 0) |
59 | AER_PHYSICAL_LAYER_ERROR : \ | 49 | #define AER_DATA_LINK_LAYER_ERROR_MASK(t) ((t == AER_CORRECTABLE) ? \ |
60 | (e & AER_DATA_LINK_LAYER_ERROR_MASK(t, e)) ? \ | 50 | (PCI_ERR_COR_BAD_TLP| \ |
61 | AER_DATA_LINK_LAYER_ERROR : \ | 51 | PCI_ERR_COR_BAD_DLLP| \ |
62 | AER_TRANSACTION_LAYER_ERROR) | 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) | ||
59 | |||
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) | ||
63 | 64 | ||
64 | /* | 65 | /* |
65 | * AER error strings | 66 | * AER error strings |
66 | */ | 67 | */ |
67 | static char* aer_error_severity_string[] = { | 68 | static char *aer_error_severity_string[] = { |
68 | "Uncorrected (Non-Fatal)", | 69 | "Uncorrected (Non-Fatal)", |
69 | "Uncorrected (Fatal)", | 70 | "Uncorrected (Fatal)", |
70 | "Corrected" | 71 | "Corrected" |
71 | }; | 72 | }; |
72 | 73 | ||
73 | static char* aer_error_layer[] = { | 74 | static char *aer_error_layer[] = { |
74 | "Physical Layer", | 75 | "Physical Layer", |
75 | "Data Link Layer", | 76 | "Data Link Layer", |
76 | "Transaction Layer" | 77 | "Transaction Layer" |
77 | }; | 78 | }; |
78 | static char* aer_correctable_error_string[] = { | 79 | static char *aer_correctable_error_string[] = { |
79 | "Receiver Error ", /* Bit Position 0 */ | 80 | "Receiver Error ", /* Bit Position 0 */ |
80 | NULL, | 81 | NULL, |
81 | NULL, | 82 | NULL, |
82 | NULL, | 83 | NULL, |
83 | NULL, | 84 | NULL, |
84 | NULL, | 85 | NULL, |
85 | "Bad TLP ", /* Bit Position 6 */ | 86 | "Bad TLP ", /* Bit Position 6 */ |
86 | "Bad DLLP ", /* Bit Position 7 */ | 87 | "Bad DLLP ", /* Bit Position 7 */ |
87 | "RELAY_NUM Rollover ", /* Bit Position 8 */ | 88 | "RELAY_NUM Rollover ", /* Bit Position 8 */ |
88 | NULL, | 89 | NULL, |
89 | NULL, | 90 | NULL, |
90 | NULL, | 91 | NULL, |
91 | "Replay Timer Timeout ", /* Bit Position 12 */ | 92 | "Replay Timer Timeout ", /* Bit Position 12 */ |
92 | "Advisory Non-Fatal ", /* Bit Position 13 */ | 93 | "Advisory Non-Fatal ", /* Bit Position 13 */ |
93 | NULL, | 94 | NULL, |
94 | NULL, | 95 | NULL, |
95 | NULL, | 96 | NULL, |
@@ -110,7 +111,7 @@ static char* aer_correctable_error_string[] = { | |||
110 | NULL, | 111 | NULL, |
111 | }; | 112 | }; |
112 | 113 | ||
113 | static char* aer_uncorrectable_error_string[] = { | 114 | static char *aer_uncorrectable_error_string[] = { |
114 | NULL, | 115 | NULL, |
115 | NULL, | 116 | NULL, |
116 | NULL, | 117 | NULL, |
@@ -123,10 +124,10 @@ static char* aer_uncorrectable_error_string[] = { | |||
123 | NULL, | 124 | NULL, |
124 | NULL, | 125 | NULL, |
125 | NULL, | 126 | NULL, |
126 | "Poisoned TLP ", /* Bit Position 12 */ | 127 | "Poisoned TLP ", /* Bit Position 12 */ |
127 | "Flow Control Protocol ", /* Bit Position 13 */ | 128 | "Flow Control Protocol ", /* Bit Position 13 */ |
128 | "Completion Timeout ", /* Bit Position 14 */ | 129 | "Completion Timeout ", /* Bit Position 14 */ |
129 | "Completer Abort ", /* Bit Position 15 */ | 130 | "Completer Abort ", /* Bit Position 15 */ |
130 | "Unexpected Completion ", /* Bit Position 16 */ | 131 | "Unexpected Completion ", /* Bit Position 16 */ |
131 | "Receiver Overflow ", /* Bit Position 17 */ | 132 | "Receiver Overflow ", /* Bit Position 17 */ |
132 | "Malformed TLP ", /* Bit Position 18 */ | 133 | "Malformed TLP ", /* Bit Position 18 */ |
@@ -145,98 +146,69 @@ static char* aer_uncorrectable_error_string[] = { | |||
145 | NULL, | 146 | NULL, |
146 | }; | 147 | }; |
147 | 148 | ||
148 | static char* aer_agent_string[] = { | 149 | static char *aer_agent_string[] = { |
149 | "Receiver ID", | 150 | "Receiver ID", |
150 | "Requester ID", | 151 | "Requester ID", |
151 | "Completer ID", | 152 | "Completer ID", |
152 | "Transmitter ID" | 153 | "Transmitter ID" |
153 | }; | 154 | }; |
154 | 155 | ||
155 | static char * aer_get_error_source_name(int severity, | 156 | static void __aer_print_error(struct aer_err_info *info, struct pci_dev *dev) |
156 | unsigned int status, | ||
157 | char errmsg_buff[]) | ||
158 | { | 157 | { |
159 | int i; | 158 | int i, status; |
160 | char * errmsg = NULL; | 159 | char *errmsg = NULL; |
160 | |||
161 | status = (info->status & ~info->mask); | ||
161 | 162 | ||
162 | for (i = 0; i < 32; i++) { | 163 | for (i = 0; i < 32; i++) { |
163 | if (!(status & (1 << i))) | 164 | if (!(status & (1 << i))) |
164 | continue; | 165 | continue; |
165 | 166 | ||
166 | if (severity == AER_CORRECTABLE) | 167 | if (info->severity == AER_CORRECTABLE) |
167 | errmsg = aer_correctable_error_string[i]; | 168 | errmsg = aer_correctable_error_string[i]; |
168 | else | 169 | else |
169 | errmsg = aer_uncorrectable_error_string[i]; | 170 | errmsg = aer_uncorrectable_error_string[i]; |
170 | 171 | ||
171 | if (!errmsg) { | 172 | if (errmsg) |
172 | sprintf(errmsg_buff, "Unknown Error Bit %2d ", i); | 173 | AER_PR(info, dev, " [%2d] %s%s\n", i, errmsg, |
173 | errmsg = errmsg_buff; | 174 | info->first_error == i ? " (First)" : ""); |
174 | } | 175 | else |
175 | 176 | AER_PR(info, dev, " [%2d] Unknown Error Bit%s\n", i, | |
176 | break; | 177 | info->first_error == i ? " (First)" : ""); |
177 | } | 178 | } |
178 | |||
179 | return errmsg; | ||
180 | } | 179 | } |
181 | 180 | ||
182 | static DEFINE_SPINLOCK(logbuf_lock); | ||
183 | static char errmsg_buff[100]; | ||
184 | void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) | 181 | void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) |
185 | { | 182 | { |
186 | char * errmsg; | 183 | int id = ((dev->bus->number << 8) | dev->devfn); |
187 | int err_layer, agent; | 184 | |
188 | char * loglevel; | 185 | if (info->status == 0) { |
189 | 186 | AER_PR(info, dev, | |
190 | if (info->severity == AER_CORRECTABLE) | 187 | "PCIE Bus Error: severity=%s, type=Unaccessible, " |
191 | loglevel = KERN_WARNING; | 188 | "id=%04x(Unregistered Agent ID)\n", |
192 | else | 189 | aer_error_severity_string[info->severity], id); |
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 { | 190 | } else { |
207 | err_layer = AER_GET_LAYER_ERROR(info->severity, info->status); | 191 | int layer, agent; |
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 | 192 | ||
193 | layer = AER_GET_LAYER_ERROR(info->severity, info->status); | ||
220 | agent = AER_GET_AGENT(info->severity, info->status); | 194 | agent = AER_GET_AGENT(info->severity, info->status); |
221 | printk("%s%s\t\t: %04x\n", loglevel, | 195 | |
222 | aer_agent_string[agent], | 196 | AER_PR(info, dev, |
223 | (dev->bus->number << 8) | dev->devfn); | 197 | "PCIE Bus Error: severity=%s, type=%s, id=%04x(%s)\n", |
224 | 198 | aer_error_severity_string[info->severity], | |
225 | printk("%sVendorID=%04xh, DeviceID=%04xh," | 199 | aer_error_layer[layer], id, aer_agent_string[agent]); |
226 | " Bus=%02xh, Device=%02xh, Function=%02xh\n", | 200 | |
227 | loglevel, | 201 | AER_PR(info, dev, |
228 | dev->vendor, | 202 | " device [%04x:%04x] error status/mask=%08x/%08x\n", |
229 | dev->device, | 203 | dev->vendor, dev->device, info->status, info->mask); |
230 | dev->bus->number, | 204 | |
231 | PCI_SLOT(dev->devfn), | 205 | __aer_print_error(info, dev); |
232 | PCI_FUNC(dev->devfn)); | 206 | |
233 | 207 | if (info->tlp_header_valid) { | |
234 | if (info->flags & AER_TLP_HEADER_VALID_FLAG) { | ||
235 | unsigned char *tlp = (unsigned char *) &info->tlp; | 208 | unsigned char *tlp = (unsigned char *) &info->tlp; |
236 | printk("%sTLP Header:\n", loglevel); | 209 | AER_PR(info, dev, " TLP Header:" |
237 | printk("%s%02x%02x%02x%02x %02x%02x%02x%02x" | 210 | " %02x%02x%02x%02x %02x%02x%02x%02x" |
238 | " %02x%02x%02x%02x %02x%02x%02x%02x\n", | 211 | " %02x%02x%02x%02x %02x%02x%02x%02x\n", |
239 | loglevel, | ||
240 | *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp, | 212 | *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp, |
241 | *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4), | 213 | *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4), |
242 | *(tlp + 11), *(tlp + 10), *(tlp + 9), | 214 | *(tlp + 11), *(tlp + 10), *(tlp + 9), |
@@ -244,5 +216,15 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) | |||
244 | *(tlp + 13), *(tlp + 12)); | 216 | *(tlp + 13), *(tlp + 12)); |
245 | } | 217 | } |
246 | } | 218 | } |
219 | |||
220 | if (info->id && info->error_dev_num > 1 && info->id == id) | ||
221 | AER_PR(info, dev, | ||
222 | " Error of this Agent(%04x) is reported first\n", id); | ||
247 | } | 223 | } |
248 | 224 | ||
225 | void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info) | ||
226 | { | ||
227 | dev_info(&dev->dev, "AER: %s%s error received: id=%04x\n", | ||
228 | info->multi_error_valid ? "Multiple " : "", | ||
229 | aer_error_severity_string[info->severity], info->id); | ||
230 | } | ||