linux/drivers/pci/pcie/aer/aerdrv_errprint.c
<<
>>
Prefs
   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
 249