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 */ 67static char* aer_error_severity_string[] = { 68 "Uncorrected (Non-Fatal)", 69 "Uncorrected (Fatal)", 70 "Corrected" 71}; 72 73static char* aer_error_layer[] = { 74 "Physical Layer", 75 "Data Link Layer", 76 "Transaction Layer" 77}; 78static 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 113static 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 148static char* aer_agent_string[] = { 149 "Receiver ID", 150 "Requester ID", 151 "Completer ID", 152 "Transmitter ID" 153}; 154 155static 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 182static DEFINE_SPINLOCK(logbuf_lock); 183static char errmsg_buff[100]; 184void 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("%sTLB 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