linux/arch/alpha/kernel/err_marvel.c
<<
>>
Prefs
   1/*
   2 *      linux/arch/alpha/kernel/err_marvel.c
   3 *
   4 *      Copyright (C) 2001 Jeff Wiedemeier (Compaq Computer Corporation)
   5 *
   6 */
   7
   8#include <linux/init.h>
   9#include <linux/pci.h>
  10#include <linux/sched.h>
  11
  12#include <asm/io.h>
  13#include <asm/console.h>
  14#include <asm/core_marvel.h>
  15#include <asm/hwrpb.h>
  16#include <asm/smp.h>
  17#include <asm/err_common.h>
  18#include <asm/err_ev7.h>
  19
  20#include "err_impl.h"
  21#include "proto.h"
  22
  23static void
  24marvel_print_680_frame(struct ev7_lf_subpackets *lf_subpackets)
  25{
  26#ifdef CONFIG_VERBOSE_MCHECK
  27        struct ev7_pal_environmental_subpacket *env;
  28        struct { int type; char *name; } ev_packets[] = {
  29                { EL_TYPE__PAL__ENV__AMBIENT_TEMPERATURE,
  30                  "Ambient Temperature" },
  31                { EL_TYPE__PAL__ENV__AIRMOVER_FAN,
  32                  "AirMover / Fan" },
  33                { EL_TYPE__PAL__ENV__VOLTAGE,
  34                  "Voltage" },
  35                { EL_TYPE__PAL__ENV__INTRUSION,
  36                  "Intrusion" },
  37                { EL_TYPE__PAL__ENV__POWER_SUPPLY,
  38                  "Power Supply" },
  39                { EL_TYPE__PAL__ENV__LAN,
  40                  "LAN" },
  41                { EL_TYPE__PAL__ENV__HOT_PLUG,
  42                  "Hot Plug" },
  43                { 0, NULL }
  44        };
  45        int i;
  46
  47        for (i = 0; ev_packets[i].type != 0; i++) {
  48                env = lf_subpackets->env[ev7_lf_env_index(ev_packets[i].type)];
  49                if (!env)
  50                        continue;
  51
  52                printk("%s**%s event (cabinet %d, drawer %d)\n",
  53                       err_print_prefix,
  54                       ev_packets[i].name,
  55                       env->cabinet,
  56                       env->drawer);
  57                printk("%s   Module Type: 0x%x - Unit ID 0x%x - "
  58                       "Condition 0x%x\n",
  59                       err_print_prefix,
  60                       env->module_type,
  61                       env->unit_id,
  62                       env->condition);
  63        }
  64#endif /* CONFIG_VERBOSE_MCHECK */
  65}
  66
  67static int
  68marvel_process_680_frame(struct ev7_lf_subpackets *lf_subpackets, int print)
  69{
  70        int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
  71        int i;
  72
  73        for (i = ev7_lf_env_index(EL_TYPE__PAL__ENV__AMBIENT_TEMPERATURE);
  74             i <= ev7_lf_env_index(EL_TYPE__PAL__ENV__HOT_PLUG);
  75             i++) {
  76                if (lf_subpackets->env[i])
  77                        status = MCHK_DISPOSITION_REPORT;
  78        }
  79
  80        if (print)
  81                marvel_print_680_frame(lf_subpackets);
  82
  83        return status;
  84}
  85
  86#ifdef CONFIG_VERBOSE_MCHECK
  87
  88static void
  89marvel_print_err_cyc(u64 err_cyc)
  90{
  91        static char *packet_desc[] = {
  92                "No Error",
  93                "UNKNOWN",
  94                "1 cycle (1 or 2 flit packet)",
  95                "2 cycles (3 flit packet)",
  96                "9 cycles (18 flit packet)",
  97                "10 cycles (19 flit packet)",
  98                "UNKNOWN",
  99                "UNKNOWN",
 100                "UNKNOWN"
 101        };
 102
 103#define IO7__ERR_CYC__ODD_FLT   (1UL <<  0)
 104#define IO7__ERR_CYC__EVN_FLT   (1UL <<  1)
 105#define IO7__ERR_CYC__PACKET__S (6)
 106#define IO7__ERR_CYC__PACKET__M (0x7)
 107#define IO7__ERR_CYC__LOC       (1UL <<  5)
 108#define IO7__ERR_CYC__CYCLE__S  (2)
 109#define IO7__ERR_CYC__CYCLE__M  (0x7)
 110
 111        printk("%s        Packet In Error: %s\n"
 112               "%s        Error in %s, cycle %lld%s%s\n",
 113               err_print_prefix, 
 114               packet_desc[EXTRACT(err_cyc, IO7__ERR_CYC__PACKET)],
 115               err_print_prefix,
 116               (err_cyc & IO7__ERR_CYC__LOC) ? "DATA" : "HEADER",
 117               EXTRACT(err_cyc, IO7__ERR_CYC__CYCLE),
 118               (err_cyc & IO7__ERR_CYC__ODD_FLT) ? " [ODD Flit]": "",
 119               (err_cyc & IO7__ERR_CYC__EVN_FLT) ? " [Even Flit]": "");
 120}
 121
 122static void
 123marvel_print_po7_crrct_sym(u64 crrct_sym)
 124{
 125#define IO7__PO7_CRRCT_SYM__SYN__S      (0)
 126#define IO7__PO7_CRRCT_SYM__SYN__M      (0x7f)
 127#define IO7__PO7_CRRCT_SYM__ERR_CYC__S  (7)   /* ERR_CYC + ODD_FLT + EVN_FLT */
 128#define IO7__PO7_CRRCT_SYM__ERR_CYC__M  (0x1ff)
 129
 130
 131        printk("%s      Correctable Error Symptoms:\n"
 132               "%s        Syndrome: 0x%llx\n",
 133               err_print_prefix,
 134               err_print_prefix, EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__SYN));
 135        marvel_print_err_cyc(EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__ERR_CYC));
 136}
 137
 138static void
 139marvel_print_po7_uncrr_sym(u64 uncrr_sym, u64 valid_mask)
 140{
 141        static char *clk_names[] = { "_h[0]", "_h[1]", "_n[0]", "_n[1]" };
 142        static char *clk_decode[] = {
 143                "No Error",
 144                "One extra rising edge",
 145                "Two extra rising edges",
 146                "Lost one clock"
 147        };
 148        static char *port_names[] = { "Port 0",         "Port 1", 
 149                                      "Port 2",         "Port 3",
 150                                      "Unknown Port",   "Unknown Port",
 151                                      "Unknown Port",   "Port 7" };
 152        int scratch, i;
 153
 154#define IO7__PO7_UNCRR_SYM__SYN__S          (0)
 155#define IO7__PO7_UNCRR_SYM__SYN__M          (0x7f)
 156#define IO7__PO7_UNCRR_SYM__ERR_CYC__S      (7)      /* ERR_CYC + ODD_FLT... */
 157#define IO7__PO7_UNCRR_SYM__ERR_CYC__M      (0x1ff)  /* ... + EVN_FLT        */
 158#define IO7__PO7_UNCRR_SYM__CLK__S          (16)
 159#define IO7__PO7_UNCRR_SYM__CLK__M          (0xff)
 160#define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__REQ (1UL << 24)
 161#define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__RIO (1UL << 25)
 162#define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__WIO (1UL << 26)
 163#define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__BLK (1UL << 27)
 164#define IO7__PO7_UNCRR_SYM__CDT_OVF_TO__NBK (1UL << 28)
 165#define IO7__PO7_UNCRR_SYM__OVF__READIO     (1UL << 29)
 166#define IO7__PO7_UNCRR_SYM__OVF__WRITEIO    (1UL << 30)
 167#define IO7__PO7_UNCRR_SYM__OVF__FWD        (1UL << 31)
 168#define IO7__PO7_UNCRR_SYM__VICTIM_SP__S    (32)
 169#define IO7__PO7_UNCRR_SYM__VICTIM_SP__M    (0xff)
 170#define IO7__PO7_UNCRR_SYM__DETECT_SP__S    (40)
 171#define IO7__PO7_UNCRR_SYM__DETECT_SP__M    (0xff)
 172#define IO7__PO7_UNCRR_SYM__STRV_VTR__S     (48)
 173#define IO7__PO7_UNCRR_SYM__STRV_VTR__M     (0x3ff)
 174
 175#define IO7__STRV_VTR__LSI__INTX__S         (0)
 176#define IO7__STRV_VTR__LSI__INTX__M         (0x3)
 177#define IO7__STRV_VTR__LSI__SLOT__S         (2)
 178#define IO7__STRV_VTR__LSI__SLOT__M         (0x7)
 179#define IO7__STRV_VTR__LSI__BUS__S          (5)
 180#define IO7__STRV_VTR__LSI__BUS__M          (0x3)
 181#define IO7__STRV_VTR__MSI__INTNUM__S       (0)
 182#define IO7__STRV_VTR__MSI__INTNUM__M       (0x1ff)
 183#define IO7__STRV_VTR__IS_MSI               (1UL << 9)
 184
 185        printk("%s      Uncorrectable Error Symptoms:\n", err_print_prefix);
 186        uncrr_sym &= valid_mask;
 187
 188        if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__SYN))
 189                printk("%s        Syndrome: 0x%llx\n",
 190                       err_print_prefix, 
 191                       EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__SYN));
 192
 193        if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__ERR_CYC))
 194                marvel_print_err_cyc(EXTRACT(uncrr_sym, 
 195                                             IO7__PO7_UNCRR_SYM__ERR_CYC));
 196
 197        scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__CLK);
 198        for (i = 0; i < 4; i++, scratch >>= 2) {
 199                if (scratch & 0x3)
 200                        printk("%s        Clock %s: %s\n",
 201                               err_print_prefix,
 202                               clk_names[i], clk_decode[scratch & 0x3]);
 203        }
 204
 205        if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__REQ) 
 206                printk("%s       REQ Credit Timeout or Overflow\n",
 207                       err_print_prefix);
 208        if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__RIO) 
 209                printk("%s       RIO Credit Timeout or Overflow\n",
 210                       err_print_prefix);
 211        if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__WIO) 
 212                printk("%s       WIO Credit Timeout or Overflow\n",
 213                       err_print_prefix);
 214        if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__BLK) 
 215                printk("%s       BLK Credit Timeout or Overflow\n",
 216                       err_print_prefix);
 217        if (uncrr_sym & IO7__PO7_UNCRR_SYM__CDT_OVF_TO__NBK) 
 218                printk("%s       NBK Credit Timeout or Overflow\n",
 219                       err_print_prefix);
 220
 221        if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__READIO) 
 222                printk("%s       Read I/O Buffer Overflow\n", 
 223                       err_print_prefix);
 224        if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__WRITEIO) 
 225                printk("%s       Write I/O Buffer Overflow\n", 
 226                       err_print_prefix);
 227        if (uncrr_sym & IO7__PO7_UNCRR_SYM__OVF__FWD) 
 228                printk("%s       FWD Buffer Overflow\n", 
 229                       err_print_prefix);
 230
 231        if ((scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__VICTIM_SP))) {
 232                int lost = scratch & (1UL << 4);
 233                scratch &= ~lost;
 234                for (i = 0; i < 8; i++, scratch >>= 1) {
 235                        if (!(scratch & 1))
 236                                continue;
 237                        printk("%s        Error Response sent to %s",
 238                               err_print_prefix, port_names[i]);
 239                }
 240                if (lost)
 241                        printk("%s        Lost Error sent somewhere else\n",
 242                               err_print_prefix);
 243        }
 244        
 245        if ((scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__DETECT_SP))) {
 246                for (i = 0; i < 8; i++, scratch >>= 1) {
 247                        if (!(scratch & 1))
 248                                continue;
 249                        printk("%s        Error Reported by %s",
 250                               err_print_prefix, port_names[i]);
 251                }
 252        }
 253
 254        if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__STRV_VTR)) {
 255                char starvation_message[80];
 256
 257                scratch = EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__STRV_VTR);
 258                if (scratch & IO7__STRV_VTR__IS_MSI) 
 259                        sprintf(starvation_message, 
 260                                "MSI Interrupt 0x%x",
 261                                EXTRACT(scratch, IO7__STRV_VTR__MSI__INTNUM));
 262                else
 263                        sprintf(starvation_message,
 264                                "LSI INT%c for Bus:Slot (%d:%d)\n",
 265                                'A' + EXTRACT(scratch, 
 266                                              IO7__STRV_VTR__LSI__INTX),
 267                                EXTRACT(scratch, IO7__STRV_VTR__LSI__BUS),
 268                                EXTRACT(scratch, IO7__STRV_VTR__LSI__SLOT));
 269
 270                printk("%s        Starvation Int Trigger By: %s\n",
 271                       err_print_prefix, starvation_message);
 272        }
 273}
 274
 275static void
 276marvel_print_po7_ugbge_sym(u64 ugbge_sym)
 277{
 278        char opcode_str[10];
 279
 280#define IO7__PO7_UGBGE_SYM__UPH_PKT_OFF__S      (6)
 281#define IO7__PO7_UGBGE_SYM__UPH_PKT_OFF__M      (0xfffffffful)
 282#define IO7__PO7_UGBGE_SYM__UPH_OPCODE__S       (40)
 283#define IO7__PO7_UGBGE_SYM__UPH_OPCODE__M       (0xff)
 284#define IO7__PO7_UGBGE_SYM__UPH_SRC_PORT__S     (48)
 285#define IO7__PO7_UGBGE_SYM__UPH_SRC_PORT__M     (0xf)
 286#define IO7__PO7_UGBGE_SYM__UPH_DEST_PID__S     (52)
 287#define IO7__PO7_UGBGE_SYM__UPH_DEST_PID__M     (0x7ff)
 288#define IO7__PO7_UGBGE_SYM__VALID               (1UL << 63)
 289
 290        if (!(ugbge_sym & IO7__PO7_UGBGE_SYM__VALID))
 291                return;
 292
 293        switch(EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE)) {
 294        case 0x51:
 295                sprintf(opcode_str, "Wr32");
 296                break;
 297        case 0x50:
 298                sprintf(opcode_str, "WrQW");
 299                break;
 300        case 0x54:
 301                sprintf(opcode_str, "WrIPR");
 302                break;
 303        case 0xD8:
 304                sprintf(opcode_str, "Victim");
 305                break;
 306        case 0xC5:
 307                sprintf(opcode_str, "BlkIO");
 308                break;
 309        default:
 310                sprintf(opcode_str, "0x%llx\n",
 311                        EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE));
 312                break;
 313        }
 314
 315        printk("%s      Up Hose Garbage Symptom:\n"
 316               "%s        Source Port: %lld - Dest PID: %lld - OpCode: %s\n",
 317               err_print_prefix,
 318               err_print_prefix, 
 319               EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_SRC_PORT),
 320               EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_DEST_PID),
 321               opcode_str);
 322
 323        if (0xC5 != EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE))
 324                printk("%s        Packet Offset 0x%08llx\n",
 325                       err_print_prefix,
 326                       EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_PKT_OFF));
 327}
 328
 329static void
 330marvel_print_po7_err_sum(struct ev7_pal_io_subpacket *io)
 331{
 332        u64     uncrr_sym_valid = 0;
 333
 334#define IO7__PO7_ERRSUM__CR_SBE         (1UL << 32)
 335#define IO7__PO7_ERRSUM__CR_SBE2        (1UL << 33)
 336#define IO7__PO7_ERRSUM__CR_PIO_WBYTE   (1UL << 34)
 337#define IO7__PO7_ERRSUM__CR_CSR_NXM     (1UL << 35)
 338#define IO7__PO7_ERRSUM__CR_RPID_ACV    (1UL << 36)
 339#define IO7__PO7_ERRSUM__CR_RSP_NXM     (1UL << 37)
 340#define IO7__PO7_ERRSUM__CR_ERR_RESP    (1UL << 38)
 341#define IO7__PO7_ERRSUM__CR_CLK_DERR    (1UL << 39)
 342#define IO7__PO7_ERRSUM__CR_DAT_DBE     (1UL << 40)
 343#define IO7__PO7_ERRSUM__CR_DAT_GRBG    (1UL << 41)
 344#define IO7__PO7_ERRSUM__MAF_TO         (1UL << 42)
 345#define IO7__PO7_ERRSUM__UGBGE          (1UL << 43)
 346#define IO7__PO7_ERRSUM__UN_MAF_LOST    (1UL << 44)
 347#define IO7__PO7_ERRSUM__UN_PKT_OVF     (1UL << 45)
 348#define IO7__PO7_ERRSUM__UN_CDT_OVF     (1UL << 46)
 349#define IO7__PO7_ERRSUM__UN_DEALLOC     (1UL << 47)
 350#define IO7__PO7_ERRSUM__BH_CDT_TO      (1UL << 51)
 351#define IO7__PO7_ERRSUM__BH_CLK_HDR     (1UL << 52)
 352#define IO7__PO7_ERRSUM__BH_DBE_HDR     (1UL << 53)
 353#define IO7__PO7_ERRSUM__BH_GBG_HDR     (1UL << 54)
 354#define IO7__PO7_ERRSUM__BH_BAD_CMD     (1UL << 55)
 355#define IO7__PO7_ERRSUM__HLT_INT        (1UL << 56)
 356#define IO7__PO7_ERRSUM__HP_INT         (1UL << 57)
 357#define IO7__PO7_ERRSUM__CRD_INT        (1UL << 58)
 358#define IO7__PO7_ERRSUM__STV_INT        (1UL << 59)
 359#define IO7__PO7_ERRSUM__HRD_INT        (1UL << 60)
 360#define IO7__PO7_ERRSUM__BH_SUM         (1UL << 61)
 361#define IO7__PO7_ERRSUM__ERR_LST        (1UL << 62)
 362#define IO7__PO7_ERRSUM__ERR_VALID      (1UL << 63)
 363
 364#define IO7__PO7_ERRSUM__ERR_MASK       (IO7__PO7_ERRSUM__ERR_VALID |   \
 365                                         IO7__PO7_ERRSUM__CR_SBE)
 366
 367        /*
 368         * Single bit errors aren't covered by ERR_VALID.
 369         */
 370        if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_SBE) {
 371                printk("%s    %sSingle Bit Error(s) detected/corrected\n",
 372                       err_print_prefix,
 373                       (io->po7_error_sum & IO7__PO7_ERRSUM__CR_SBE2) 
 374                       ? "Multiple " : "");
 375                marvel_print_po7_crrct_sym(io->po7_crrct_sym);
 376        }
 377
 378        /*
 379         * Neither are the interrupt status bits
 380         */
 381        if (io->po7_error_sum & IO7__PO7_ERRSUM__HLT_INT)
 382                printk("%s    Halt Interrupt posted", err_print_prefix);
 383        if (io->po7_error_sum & IO7__PO7_ERRSUM__HP_INT) {
 384                printk("%s    Hot Plug Event Interrupt posted", 
 385                       err_print_prefix);
 386                uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__DETECT_SP);
 387        }
 388        if (io->po7_error_sum & IO7__PO7_ERRSUM__CRD_INT)
 389                printk("%s    Correctable Error Interrupt posted", 
 390                       err_print_prefix);
 391        if (io->po7_error_sum & IO7__PO7_ERRSUM__STV_INT) {
 392                printk("%s    Starvation Interrupt posted", err_print_prefix);
 393                uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__STRV_VTR);
 394        }
 395        if (io->po7_error_sum & IO7__PO7_ERRSUM__HRD_INT) {
 396                printk("%s    Hard Error Interrupt posted", err_print_prefix);
 397                uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__DETECT_SP);
 398        }
 399
 400        /*
 401         * Everything else is valid only with ERR_VALID, so skip to the end
 402         * (uncrr_sym check) unless ERR_VALID is set.
 403         */
 404        if (!(io->po7_error_sum & IO7__PO7_ERRSUM__ERR_VALID)) 
 405                goto check_uncrr_sym;
 406
 407        /*
 408         * Since ERR_VALID is set, VICTIM_SP in uncrr_sym is valid.
 409         * For bits [29:0] to also be valid, the following bits must
 410         * not be set:
 411         *      CR_PIO_WBYTE    CR_CSR_NXM      CR_RSP_NXM
 412         *      CR_ERR_RESP     MAF_TO
 413         */
 414        uncrr_sym_valid |= GEN_MASK(IO7__PO7_UNCRR_SYM__VICTIM_SP);
 415        if (!(io->po7_error_sum & (IO7__PO7_ERRSUM__CR_PIO_WBYTE |
 416                                   IO7__PO7_ERRSUM__CR_CSR_NXM |
 417                                   IO7__PO7_ERRSUM__CR_RSP_NXM |
 418                                   IO7__PO7_ERRSUM__CR_ERR_RESP |
 419                                   IO7__PO7_ERRSUM__MAF_TO)))
 420                uncrr_sym_valid |= 0x3ffffffful;
 421
 422        if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_PIO_WBYTE)
 423                printk("%s    Write byte into IO7 CSR\n", err_print_prefix);
 424        if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_CSR_NXM)
 425                printk("%s    PIO to non-existent CSR\n", err_print_prefix);
 426        if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_RPID_ACV)
 427                printk("%s    Bus Requester PID (Access Violation)\n",
 428                       err_print_prefix);
 429        if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_RSP_NXM)
 430                printk("%s    Received NXM response from EV7\n",
 431                       err_print_prefix);
 432        if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_ERR_RESP)
 433                printk("%s    Received ERROR RESPONSE\n", err_print_prefix);
 434        if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_CLK_DERR)
 435                printk("%s    Clock error on data flit\n", err_print_prefix);
 436        if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_DAT_DBE)
 437                printk("%s    Double Bit Error Data Error Detected\n",
 438                       err_print_prefix);
 439        if (io->po7_error_sum & IO7__PO7_ERRSUM__CR_DAT_GRBG)
 440                printk("%s    Garbage Encoding Detected on the data\n",
 441                       err_print_prefix);
 442        if (io->po7_error_sum & IO7__PO7_ERRSUM__UGBGE) {
 443                printk("%s    Garbage Encoding sent up hose\n",
 444                       err_print_prefix);
 445                marvel_print_po7_ugbge_sym(io->po7_ugbge_sym);
 446        }
 447        if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_MAF_LOST)
 448                printk("%s    Orphan response (unexpected response)\n",
 449                       err_print_prefix);
 450        if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_PKT_OVF)
 451                printk("%s    Down hose packet overflow\n", err_print_prefix);
 452        if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_CDT_OVF)
 453                printk("%s    Down hose credit overflow\n", err_print_prefix);
 454        if (io->po7_error_sum & IO7__PO7_ERRSUM__UN_DEALLOC)
 455                printk("%s    Unexpected or bad dealloc field\n",
 456                       err_print_prefix);
 457
 458        /*
 459         * The black hole events.
 460         */
 461        if (io->po7_error_sum & IO7__PO7_ERRSUM__MAF_TO)
 462                printk("%s    BLACK HOLE: Timeout for all responses\n",
 463                       err_print_prefix);
 464        if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_CDT_TO)
 465                printk("%s    BLACK HOLE: Credit Timeout\n", err_print_prefix);
 466        if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_CLK_HDR)
 467                printk("%s    BLACK HOLE: Clock check on header\n", 
 468                       err_print_prefix);
 469        if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_DBE_HDR)
 470                printk("%s    BLACK HOLE: Uncorrectable Error on header\n",
 471                       err_print_prefix);
 472        if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_GBG_HDR)
 473                printk("%s    BLACK HOLE: Garbage on header\n", 
 474                       err_print_prefix);
 475        if (io->po7_error_sum & IO7__PO7_ERRSUM__BH_BAD_CMD)
 476                printk("%s    BLACK HOLE: Bad EV7 command\n", 
 477                       err_print_prefix);
 478
 479        if (io->po7_error_sum & IO7__PO7_ERRSUM__ERR_LST) 
 480                printk("%s    Lost Error\n", err_print_prefix);
 481
 482        printk("%s    Failing Packet:\n"
 483               "%s      Cycle 1: %016llx\n"
 484               "%s      Cycle 2: %016llx\n",
 485               err_print_prefix,
 486               err_print_prefix, io->po7_err_pkt0,
 487               err_print_prefix, io->po7_err_pkt1);
 488        /*
 489         * If there are any valid bits in UNCRR sym for this err, 
 490         * print UNCRR_SYM as well.
 491         */
 492check_uncrr_sym:
 493        if (uncrr_sym_valid)
 494                marvel_print_po7_uncrr_sym(io->po7_uncrr_sym, uncrr_sym_valid);
 495}
 496
 497static void
 498marvel_print_pox_tlb_err(u64 tlb_err)
 499{
 500        static char *tlb_errors[] = {
 501                "No Error",
 502                "North Port Signaled Error fetching TLB entry",
 503                "PTE invalid or UCC or GBG error on this entry",
 504                "Address did not hit any DMA window"
 505        };
 506
 507#define IO7__POX_TLBERR__ERR_VALID              (1UL << 63)
 508#define IO7__POX_TLBERR__ERRCODE__S             (0)
 509#define IO7__POX_TLBERR__ERRCODE__M             (0x3)
 510#define IO7__POX_TLBERR__ERR_TLB_PTR__S         (3)
 511#define IO7__POX_TLBERR__ERR_TLB_PTR__M         (0x7)
 512#define IO7__POX_TLBERR__FADDR__S               (6)
 513#define IO7__POX_TLBERR__FADDR__M               (0x3fffffffffful)
 514
 515        if (!(tlb_err & IO7__POX_TLBERR__ERR_VALID))
 516                return;
 517
 518        printk("%s      TLB Error on index 0x%llx:\n"
 519               "%s        - %s\n"
 520               "%s        - Addr: 0x%016llx\n",
 521               err_print_prefix,
 522               EXTRACT(tlb_err, IO7__POX_TLBERR__ERR_TLB_PTR),
 523               err_print_prefix,
 524               tlb_errors[EXTRACT(tlb_err, IO7__POX_TLBERR__ERRCODE)],
 525               err_print_prefix,
 526               EXTRACT(tlb_err, IO7__POX_TLBERR__FADDR) << 6);
 527}
 528
 529static  void
 530marvel_print_pox_spl_cmplt(u64 spl_cmplt)
 531{
 532        char message[80];
 533
 534#define IO7__POX_SPLCMPLT__MESSAGE__S           (0)
 535#define IO7__POX_SPLCMPLT__MESSAGE__M           (0x0fffffffful)
 536#define IO7__POX_SPLCMPLT__SOURCE_BUS__S        (40)
 537#define IO7__POX_SPLCMPLT__SOURCE_BUS__M        (0xfful)
 538#define IO7__POX_SPLCMPLT__SOURCE_DEV__S        (35)
 539#define IO7__POX_SPLCMPLT__SOURCE_DEV__M        (0x1ful)
 540#define IO7__POX_SPLCMPLT__SOURCE_FUNC__S       (32)
 541#define IO7__POX_SPLCMPLT__SOURCE_FUNC__M       (0x07ul)
 542
 543#define IO7__POX_SPLCMPLT__MSG_CLASS__S         (28)
 544#define IO7__POX_SPLCMPLT__MSG_CLASS__M         (0xf)
 545#define IO7__POX_SPLCMPLT__MSG_INDEX__S         (20)
 546#define IO7__POX_SPLCMPLT__MSG_INDEX__M         (0xff)
 547#define IO7__POX_SPLCMPLT__MSG_CLASSINDEX__S    (20)
 548#define IO7__POX_SPLCMPLT__MSG_CLASSINDEX__M    (0xfff)
 549#define IO7__POX_SPLCMPLT__REM_LOWER_ADDR__S    (12)
 550#define IO7__POX_SPLCMPLT__REM_LOWER_ADDR__M    (0x7f)
 551#define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__S    (0)
 552#define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__M    (0xfff)
 553
 554        printk("%s      Split Completion Error:\n"      
 555               "%s         Source (Bus:Dev:Func): %lld:%lld:%lld\n",
 556               err_print_prefix,
 557               err_print_prefix,
 558               EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_BUS),
 559               EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_DEV),
 560               EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_FUNC));
 561
 562        switch(EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MSG_CLASSINDEX)) {
 563        case 0x000:
 564                sprintf(message, "Normal completion");
 565                break;
 566        case 0x100:
 567                sprintf(message, "Bridge - Master Abort");
 568                break;
 569        case 0x101:
 570                sprintf(message, "Bridge - Target Abort");
 571                break;
 572        case 0x102:
 573                sprintf(message, "Bridge - Uncorrectable Write Data Error");
 574                break;
 575        case 0x200:
 576                sprintf(message, "Byte Count Out of Range");
 577                break;
 578        case 0x201:
 579                sprintf(message, "Uncorrectable Split Write Data Error");
 580                break;
 581        default:
 582                sprintf(message, "%08llx\n",
 583                        EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MESSAGE));
 584                break;
 585        }
 586        printk("%s         Message: %s\n", err_print_prefix, message);
 587}
 588
 589static void
 590marvel_print_pox_trans_sum(u64 trans_sum)
 591{
 592        static const char * const pcix_cmd[] = {
 593                "Interrupt Acknowledge",
 594                "Special Cycle",
 595                "I/O Read",
 596                "I/O Write",
 597                "Reserved",
 598                "Reserved / Device ID Message",
 599                "Memory Read",
 600                "Memory Write",
 601                "Reserved / Alias to Memory Read Block",
 602                "Reserved / Alias to Memory Write Block",
 603                "Configuration Read",
 604                "Configuration Write",
 605                "Memory Read Multiple / Split Completion",
 606                "Dual Address Cycle",
 607                "Memory Read Line / Memory Read Block",
 608                "Memory Write and Invalidate / Memory Write Block"
 609        };
 610
 611#define IO7__POX_TRANSUM__PCI_ADDR__S           (0)
 612#define IO7__POX_TRANSUM__PCI_ADDR__M           (0x3fffffffffffful)
 613#define IO7__POX_TRANSUM__DAC                   (1UL << 50)
 614#define IO7__POX_TRANSUM__PCIX_MASTER_SLOT__S   (52)
 615#define IO7__POX_TRANSUM__PCIX_MASTER_SLOT__M   (0xf)
 616#define IO7__POX_TRANSUM__PCIX_CMD__S           (56)
 617#define IO7__POX_TRANSUM__PCIX_CMD__M           (0xf)
 618#define IO7__POX_TRANSUM__ERR_VALID             (1UL << 63)
 619
 620        if (!(trans_sum & IO7__POX_TRANSUM__ERR_VALID))
 621                return;
 622
 623        printk("%s      Transaction Summary:\n"
 624               "%s        Command: 0x%llx - %s\n"
 625               "%s        Address: 0x%016llx%s\n"
 626               "%s        PCI-X Master Slot: 0x%llx\n",
 627               err_print_prefix, 
 628               err_print_prefix, 
 629               EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD),
 630               pcix_cmd[EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD)],
 631               err_print_prefix,
 632               EXTRACT(trans_sum, IO7__POX_TRANSUM__PCI_ADDR),
 633               (trans_sum & IO7__POX_TRANSUM__DAC) ? " (DAC)" : "",
 634               err_print_prefix,
 635               EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_MASTER_SLOT));
 636}
 637
 638static void
 639marvel_print_pox_err(u64 err_sum, struct ev7_pal_io_one_port *port)
 640{
 641#define IO7__POX_ERRSUM__AGP_REQQ_OVFL    (1UL <<  4)
 642#define IO7__POX_ERRSUM__AGP_SYNC_ERR     (1UL <<  5)
 643#define IO7__POX_ERRSUM__MRETRY_TO        (1UL <<  6)
 644#define IO7__POX_ERRSUM__PCIX_UX_SPL      (1UL <<  7)
 645#define IO7__POX_ERRSUM__PCIX_SPLIT_TO    (1UL <<  8)
 646#define IO7__POX_ERRSUM__PCIX_DISCARD_SPL (1UL <<  9)
 647#define IO7__POX_ERRSUM__DMA_RD_TO        (1UL << 10)
 648#define IO7__POX_ERRSUM__CSR_NXM_RD       (1UL << 11)
 649#define IO7__POX_ERRSUM__CSR_NXM_WR       (1UL << 12)
 650#define IO7__POX_ERRSUM__DMA_TO           (1UL << 13)
 651#define IO7__POX_ERRSUM__ALL_MABORTS      (1UL << 14)
 652#define IO7__POX_ERRSUM__MABORT           (1UL << 15)
 653#define IO7__POX_ERRSUM__MABORT_MASK      (IO7__POX_ERRSUM__ALL_MABORTS|\
 654                                           IO7__POX_ERRSUM__MABORT)
 655#define IO7__POX_ERRSUM__PT_TABORT        (1UL << 16)
 656#define IO7__POX_ERRSUM__PM_TABORT        (1UL << 17)
 657#define IO7__POX_ERRSUM__TABORT_MASK      (IO7__POX_ERRSUM__PT_TABORT | \
 658                                           IO7__POX_ERRSUM__PM_TABORT)
 659#define IO7__POX_ERRSUM__SERR             (1UL << 18)
 660#define IO7__POX_ERRSUM__ADDRERR_STB      (1UL << 19)
 661#define IO7__POX_ERRSUM__DETECTED_SERR    (1UL << 20)
 662#define IO7__POX_ERRSUM__PERR             (1UL << 21)
 663#define IO7__POX_ERRSUM__DATAERR_STB_NIOW (1UL << 22)
 664#define IO7__POX_ERRSUM__DETECTED_PERR    (1UL << 23)
 665#define IO7__POX_ERRSUM__PM_PERR          (1UL << 24)
 666#define IO7__POX_ERRSUM__PT_SCERROR       (1UL << 26)
 667#define IO7__POX_ERRSUM__HUNG_BUS         (1UL << 28)
 668#define IO7__POX_ERRSUM__UPE_ERROR__S     (51)
 669#define IO7__POX_ERRSUM__UPE_ERROR__M     (0xffUL)
 670#define IO7__POX_ERRSUM__UPE_ERROR        GEN_MASK(IO7__POX_ERRSUM__UPE_ERROR)
 671#define IO7__POX_ERRSUM__TLB_ERR          (1UL << 59)
 672#define IO7__POX_ERRSUM__ERR_VALID        (1UL << 63)
 673
 674#define IO7__POX_ERRSUM__TRANS_SUM__MASK  (IO7__POX_ERRSUM__MRETRY_TO |       \
 675                                           IO7__POX_ERRSUM__PCIX_UX_SPL |     \
 676                                           IO7__POX_ERRSUM__PCIX_SPLIT_TO |   \
 677                                           IO7__POX_ERRSUM__DMA_TO |          \
 678                                           IO7__POX_ERRSUM__MABORT_MASK |     \
 679                                           IO7__POX_ERRSUM__TABORT_MASK |     \
 680                                           IO7__POX_ERRSUM__SERR |            \
 681                                           IO7__POX_ERRSUM__ADDRERR_STB |     \
 682                                           IO7__POX_ERRSUM__PERR |            \
 683                                           IO7__POX_ERRSUM__DATAERR_STB_NIOW |\
 684                                           IO7__POX_ERRSUM__DETECTED_PERR |   \
 685                                           IO7__POX_ERRSUM__PM_PERR |         \
 686                                           IO7__POX_ERRSUM__PT_SCERROR |      \
 687                                           IO7__POX_ERRSUM__UPE_ERROR)
 688
 689        if (!(err_sum & IO7__POX_ERRSUM__ERR_VALID))
 690                return;
 691
 692        /*
 693         * First the transaction summary errors
 694         */
 695        if (err_sum & IO7__POX_ERRSUM__MRETRY_TO)
 696                printk("%s    IO7 Master Retry Timeout expired\n",
 697                       err_print_prefix);
 698        if (err_sum & IO7__POX_ERRSUM__PCIX_UX_SPL)
 699                printk("%s    Unexpected Split Completion\n",
 700                       err_print_prefix);
 701        if (err_sum & IO7__POX_ERRSUM__PCIX_SPLIT_TO)
 702                printk("%s    IO7 Split Completion Timeout expired\n",
 703                       err_print_prefix);
 704        if (err_sum & IO7__POX_ERRSUM__DMA_TO)
 705                printk("%s    Hung bus during DMA transaction\n",
 706                       err_print_prefix);
 707        if (err_sum & IO7__POX_ERRSUM__MABORT_MASK)
 708                printk("%s    Master Abort\n", err_print_prefix);
 709        if (err_sum & IO7__POX_ERRSUM__PT_TABORT)
 710                printk("%s    IO7 Asserted Target Abort\n", err_print_prefix);
 711        if (err_sum & IO7__POX_ERRSUM__PM_TABORT)
 712                printk("%s    IO7 Received Target Abort\n", err_print_prefix);
 713        if (err_sum & IO7__POX_ERRSUM__ADDRERR_STB) {
 714                printk("%s    Address or PCI-X Attribute Parity Error\n", 
 715                       err_print_prefix);
 716                if (err_sum & IO7__POX_ERRSUM__SERR)
 717                        printk("%s     IO7 Asserted SERR\n", err_print_prefix);
 718        }
 719        if (err_sum & IO7__POX_ERRSUM__PERR) {
 720                if (err_sum & IO7__POX_ERRSUM__DATAERR_STB_NIOW)
 721                        printk("%s    IO7 Detected Data Parity Error\n",
 722                               err_print_prefix);
 723                else
 724                        printk("%s    Split Completion Response with "
 725                               "Parity Error\n", err_print_prefix);
 726        }
 727        if (err_sum & IO7__POX_ERRSUM__DETECTED_PERR)
 728                printk("%s    PERR detected\n", err_print_prefix);
 729        if (err_sum & IO7__POX_ERRSUM__PM_PERR)
 730                printk("%s    PERR while IO7 is master\n", err_print_prefix);
 731        if (err_sum & IO7__POX_ERRSUM__PT_SCERROR) {
 732                printk("%s    IO7 Received Split Completion Error message\n",
 733                       err_print_prefix);
 734                marvel_print_pox_spl_cmplt(port->pox_spl_cmplt);
 735        }
 736        if (err_sum & IO7__POX_ERRSUM__UPE_ERROR) {
 737                unsigned int upe_error = EXTRACT(err_sum,
 738                                                 IO7__POX_ERRSUM__UPE_ERROR);
 739                int i;
 740                static char *upe_errors[] = {
 741                        "Parity Error on MSI write data",
 742                        "MSI read (MSI window is write only",
 743                        "TLB - Invalid WR transaction",
 744                        "TLB - Invalid RD transaction",
 745                        "DMA - WR error (see north port)",
 746                        "DMA - RD error (see north port)",
 747                        "PPR - WR error (see north port)",
 748                        "PPR - RD error (see north port)"
 749                };
 750
 751                printk("%s    UPE Error:\n", err_print_prefix);
 752                for (i = 0; i < 8; i++) {
 753                        if (upe_error & (1 << i))
 754                                printk("%s      %s\n", err_print_prefix,
 755                                       upe_errors[i]);
 756                }
 757        }
 758
 759        /*
 760         * POx_TRANS_SUM, if appropriate.
 761         */
 762        if (err_sum & IO7__POX_ERRSUM__TRANS_SUM__MASK) 
 763                marvel_print_pox_trans_sum(port->pox_trans_sum);
 764
 765        /*
 766         * Then TLB_ERR.
 767         */
 768        if (err_sum & IO7__POX_ERRSUM__TLB_ERR) {
 769                printk("%s    TLB ERROR\n", err_print_prefix);
 770                marvel_print_pox_tlb_err(port->pox_tlb_err);
 771        }
 772
 773        /*
 774         * And the single bit status errors.
 775         */
 776        if (err_sum & IO7__POX_ERRSUM__AGP_REQQ_OVFL)
 777                printk("%s    AGP Request Queue Overflow\n", err_print_prefix);
 778        if (err_sum & IO7__POX_ERRSUM__AGP_SYNC_ERR)
 779                printk("%s    AGP Sync Error\n", err_print_prefix);
 780        if (err_sum & IO7__POX_ERRSUM__PCIX_DISCARD_SPL)
 781                printk("%s    Discarded split completion\n", err_print_prefix);
 782        if (err_sum & IO7__POX_ERRSUM__DMA_RD_TO)
 783                printk("%s    DMA Read Timeout\n", err_print_prefix);
 784        if (err_sum & IO7__POX_ERRSUM__CSR_NXM_RD)
 785                printk("%s    CSR NXM READ\n", err_print_prefix);
 786        if (err_sum & IO7__POX_ERRSUM__CSR_NXM_WR)
 787                printk("%s    CSR NXM WRITE\n", err_print_prefix);
 788        if (err_sum & IO7__POX_ERRSUM__DETECTED_SERR)
 789                printk("%s    SERR detected\n", err_print_prefix);
 790        if (err_sum & IO7__POX_ERRSUM__HUNG_BUS)
 791                printk("%s    HUNG BUS detected\n", err_print_prefix);
 792}
 793
 794#endif /* CONFIG_VERBOSE_MCHECK */
 795
 796static struct ev7_pal_io_subpacket *
 797marvel_find_io7_with_error(struct ev7_lf_subpackets *lf_subpackets)
 798{
 799        struct ev7_pal_io_subpacket *io = lf_subpackets->io;
 800        struct io7 *io7;
 801        int i;
 802
 803        /*
 804         * Caller must provide the packet to fill
 805         */
 806        if (!io)
 807                return NULL;
 808
 809        /*
 810         * Fill the subpacket with the console's standard fill pattern
 811         */
 812        memset(io, 0x55, sizeof(*io));
 813
 814        for (io7 = NULL; NULL != (io7 = marvel_next_io7(io7)); ) {
 815                unsigned long err_sum = 0;
 816
 817                err_sum |= io7->csrs->PO7_ERROR_SUM.csr;
 818                for (i = 0; i < IO7_NUM_PORTS; i++) {
 819                        if (!io7->ports[i].enabled)
 820                                continue;
 821                        err_sum |= io7->ports[i].csrs->POx_ERR_SUM.csr;
 822                }
 823
 824                /*
 825                 * Is there at least one error? 
 826                 */
 827                if (err_sum & (1UL << 63))
 828                        break;
 829        }
 830
 831        /*
 832         * Did we find an IO7 with an error?
 833         */
 834        if (!io7)
 835                return NULL;
 836
 837        /*
 838         * We have an IO7 with an error. 
 839         *
 840         * Fill in the IO subpacket.
 841         */
 842        io->io_asic_rev   = io7->csrs->IO_ASIC_REV.csr;
 843        io->io_sys_rev    = io7->csrs->IO_SYS_REV.csr;
 844        io->io7_uph       = io7->csrs->IO7_UPH.csr;
 845        io->hpi_ctl       = io7->csrs->HPI_CTL.csr;
 846        io->crd_ctl       = io7->csrs->CRD_CTL.csr;
 847        io->hei_ctl       = io7->csrs->HEI_CTL.csr;
 848        io->po7_error_sum = io7->csrs->PO7_ERROR_SUM.csr;
 849        io->po7_uncrr_sym = io7->csrs->PO7_UNCRR_SYM.csr;
 850        io->po7_crrct_sym = io7->csrs->PO7_CRRCT_SYM.csr;
 851        io->po7_ugbge_sym = io7->csrs->PO7_UGBGE_SYM.csr;
 852        io->po7_err_pkt0  = io7->csrs->PO7_ERR_PKT[0].csr;
 853        io->po7_err_pkt1  = io7->csrs->PO7_ERR_PKT[1].csr;
 854        
 855        for (i = 0; i < IO7_NUM_PORTS; i++) {
 856                io7_ioport_csrs *csrs = io7->ports[i].csrs;
 857
 858                if (!io7->ports[i].enabled)
 859                        continue;
 860
 861                io->ports[i].pox_err_sum   = csrs->POx_ERR_SUM.csr;
 862                io->ports[i].pox_tlb_err   = csrs->POx_TLB_ERR.csr;
 863                io->ports[i].pox_spl_cmplt = csrs->POx_SPL_COMPLT.csr;
 864                io->ports[i].pox_trans_sum = csrs->POx_TRANS_SUM.csr;
 865                io->ports[i].pox_first_err = csrs->POx_FIRST_ERR.csr;
 866                io->ports[i].pox_mult_err  = csrs->POx_MULT_ERR.csr;
 867                io->ports[i].pox_dm_source = csrs->POx_DM_SOURCE.csr;
 868                io->ports[i].pox_dm_dest   = csrs->POx_DM_DEST.csr;
 869                io->ports[i].pox_dm_size   = csrs->POx_DM_SIZE.csr;
 870                io->ports[i].pox_dm_ctrl   = csrs->POx_DM_CTRL.csr;
 871
 872                /*
 873                 * Ack this port's errors, if any. POx_ERR_SUM must be last.
 874                 *
 875                 * Most of the error registers get cleared and unlocked when
 876                 * the associated bits in POx_ERR_SUM are cleared (by writing
 877                 * 1). POx_TLB_ERR is an exception and must be explicitly 
 878                 * cleared.
 879                 */
 880                csrs->POx_TLB_ERR.csr = io->ports[i].pox_tlb_err;
 881                csrs->POx_ERR_SUM.csr = io->ports[i].pox_err_sum;
 882                mb();
 883                csrs->POx_ERR_SUM.csr;          
 884        }
 885
 886        /*
 887         * Ack any port 7 error(s).
 888         */
 889        io7->csrs->PO7_ERROR_SUM.csr = io->po7_error_sum;
 890        mb();
 891        io7->csrs->PO7_ERROR_SUM.csr;
 892        
 893        /*
 894         * Correct the io7_pid.
 895         */
 896        lf_subpackets->io_pid = io7->pe;
 897
 898        return io;
 899}
 900
 901static int
 902marvel_process_io_error(struct ev7_lf_subpackets *lf_subpackets, int print)
 903{
 904        int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
 905
 906#ifdef CONFIG_VERBOSE_MCHECK
 907        struct ev7_pal_io_subpacket *io = lf_subpackets->io;
 908        int i;
 909#endif /* CONFIG_VERBOSE_MCHECK */
 910
 911#define MARVEL_IO_ERR_VALID(x)  ((x) & (1UL << 63))
 912
 913        if (!lf_subpackets->logout || !lf_subpackets->io)
 914                return status;
 915
 916        /*
 917         * The PALcode only builds an IO subpacket if there is a 
 918         * locally connected IO7. In the cases of
 919         *      1) a uniprocessor kernel
 920         *      2) an mp kernel before the local secondary has called in
 921         * error interrupts are all directed to the primary processor.
 922         * In that case, we may not have an IO subpacket at all and, event
 923         * if we do, it may not be the right now. 
 924         *
 925         * If the RBOX indicates an I/O error interrupt, make sure we have
 926         * the correct IO7 information. If we don't have an IO subpacket
 927         * or it's the wrong one, try to find the right one.
 928         *
 929         * RBOX I/O error interrupts are indicated by RBOX_INT<29> and
 930         * RBOX_INT<10>.
 931         */
 932        if ((lf_subpackets->io->po7_error_sum & (1UL << 32)) ||
 933            ((lf_subpackets->io->po7_error_sum        |
 934              lf_subpackets->io->ports[0].pox_err_sum |
 935              lf_subpackets->io->ports[1].pox_err_sum |
 936              lf_subpackets->io->ports[2].pox_err_sum |
 937              lf_subpackets->io->ports[3].pox_err_sum) & (1UL << 63))) {
 938                /*
 939                 * Either we have no IO subpacket or no error is
 940                 * indicated in the one we do have. Try find the
 941                 * one with the error.
 942                 */
 943                if (!marvel_find_io7_with_error(lf_subpackets))
 944                        return status;
 945        }
 946
 947        /*
 948         * We have an IO7 indicating an error - we're going to report it
 949         */
 950        status = MCHK_DISPOSITION_REPORT;
 951
 952#ifdef CONFIG_VERBOSE_MCHECK
 953
 954        if (!print)
 955                return status;
 956
 957        printk("%s*Error occurred on IO7 at PID %u\n", 
 958               err_print_prefix, lf_subpackets->io_pid);
 959
 960        /*
 961         * Check port 7 first
 962         */
 963        if (lf_subpackets->io->po7_error_sum & IO7__PO7_ERRSUM__ERR_MASK) {
 964                marvel_print_po7_err_sum(io);
 965
 966#if 0
 967                printk("%s  PORT 7 ERROR:\n"
 968                       "%s    PO7_ERROR_SUM: %016llx\n"
 969                       "%s    PO7_UNCRR_SYM: %016llx\n"
 970                       "%s    PO7_CRRCT_SYM: %016llx\n"
 971                       "%s    PO7_UGBGE_SYM: %016llx\n"
 972                       "%s    PO7_ERR_PKT0:  %016llx\n"
 973                       "%s    PO7_ERR_PKT1:  %016llx\n",
 974                       err_print_prefix,
 975                       err_print_prefix, io->po7_error_sum,
 976                       err_print_prefix, io->po7_uncrr_sym,
 977                       err_print_prefix, io->po7_crrct_sym,
 978                       err_print_prefix, io->po7_ugbge_sym,
 979                       err_print_prefix, io->po7_err_pkt0,
 980                       err_print_prefix, io->po7_err_pkt1);
 981#endif
 982        }
 983
 984        /*
 985         * Then loop through the ports
 986         */
 987        for (i = 0; i < IO7_NUM_PORTS; i++) {
 988                if (!MARVEL_IO_ERR_VALID(io->ports[i].pox_err_sum))
 989                        continue;
 990
 991                printk("%s  PID %u PORT %d POx_ERR_SUM: %016llx\n",
 992                       err_print_prefix, 
 993                       lf_subpackets->io_pid, i, io->ports[i].pox_err_sum);
 994                marvel_print_pox_err(io->ports[i].pox_err_sum, &io->ports[i]);
 995
 996                printk("%s  [ POx_FIRST_ERR: %016llx ]\n",
 997                       err_print_prefix, io->ports[i].pox_first_err);
 998                marvel_print_pox_err(io->ports[i].pox_first_err, 
 999                                     &io->ports[i]);
1000
1001        }
1002
1003
1004#endif /* CONFIG_VERBOSE_MCHECK */
1005
1006        return status;
1007}
1008
1009static int
1010marvel_process_logout_frame(struct ev7_lf_subpackets *lf_subpackets, int print)
1011{
1012        int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
1013
1014        /*
1015         * I/O error? 
1016         */
1017#define EV7__RBOX_INT__IO_ERROR__MASK 0x20000400ul
1018        if (lf_subpackets->logout &&
1019            (lf_subpackets->logout->rbox_int & 0x20000400ul))
1020                status = marvel_process_io_error(lf_subpackets, print);
1021
1022        /*
1023         * Probing behind PCI-X bridges can cause machine checks on
1024         * Marvel when the probe is handled by the bridge as a split
1025         * completion transaction. The symptom is an ERROR_RESPONSE 
1026         * to a CONFIG address. Since these errors will happen in
1027         * normal operation, dismiss them.
1028         *
1029         * Dismiss if:
1030         *      C_STAT          = 0x14          (Error Response)
1031         *      C_STS<3>        = 0             (C_ADDR valid)
1032         *      C_ADDR<42>      = 1             (I/O)
1033         *      C_ADDR<31:22>   = 111110xxb     (PCI Config space)
1034         */
1035        if (lf_subpackets->ev7 &&
1036            (lf_subpackets->ev7->c_stat == 0x14) &&
1037            !(lf_subpackets->ev7->c_sts & 0x8) &&
1038            ((lf_subpackets->ev7->c_addr & 0x400ff000000ul) 
1039             == 0x400fe000000ul))
1040                status = MCHK_DISPOSITION_DISMISS;
1041
1042        return status;
1043}
1044
1045void
1046marvel_machine_check(unsigned long vector, unsigned long la_ptr)
1047{
1048        struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr;
1049        int (*process_frame)(struct ev7_lf_subpackets *, int) = NULL;
1050        struct ev7_lf_subpackets subpacket_collection = { NULL, };
1051        struct ev7_pal_io_subpacket scratch_io_packet = { 0, };
1052        struct ev7_lf_subpackets *lf_subpackets = NULL;
1053        int disposition = MCHK_DISPOSITION_UNKNOWN_ERROR;
1054        char *saved_err_prefix = err_print_prefix;
1055        char *error_type = NULL;
1056
1057        /*
1058         * Sync the processor
1059         */
1060        mb();
1061        draina();
1062
1063        switch(vector) {
1064        case SCB_Q_SYSEVENT:
1065                process_frame = marvel_process_680_frame;
1066                error_type = "System Event";
1067                break;
1068
1069        case SCB_Q_SYSMCHK:
1070                process_frame = marvel_process_logout_frame;
1071                error_type = "System Uncorrectable Error";
1072                break;
1073
1074        case SCB_Q_SYSERR:
1075                process_frame = marvel_process_logout_frame;
1076                error_type = "System Correctable Error";
1077                break;
1078
1079        default:
1080                /* Don't know it - pass it up.  */
1081                ev7_machine_check(vector, la_ptr);
1082                return;
1083        }       
1084
1085        /*
1086         * A system event or error has occurred, handle it here.
1087         *
1088         * Any errors in the logout frame have already been cleared by the
1089         * PALcode, so just parse it.
1090         */
1091        err_print_prefix = KERN_CRIT;
1092
1093        /* 
1094         * Parse the logout frame without printing first. If the only error(s)
1095         * found are classified as "dismissable", then just dismiss them and
1096         * don't print any message
1097         */
1098        lf_subpackets = 
1099                ev7_collect_logout_frame_subpackets(el_ptr,
1100                                                    &subpacket_collection);
1101        if (process_frame && lf_subpackets && lf_subpackets->logout) {
1102                /*
1103                 * We might not have the correct (or any) I/O subpacket.
1104                 * [ See marvel_process_io_error() for explanation. ]
1105                 * If we don't have one, point the io subpacket in
1106                 * lf_subpackets at scratch_io_packet so that 
1107                 * marvel_find_io7_with_error() will have someplace to
1108                 * store the info.
1109                 */
1110                if (!lf_subpackets->io)
1111                        lf_subpackets->io = &scratch_io_packet;
1112
1113                /*
1114                 * Default io_pid to the processor reporting the error
1115                 * [this will get changed in marvel_find_io7_with_error()
1116                 * if a different one is needed]
1117                 */
1118                lf_subpackets->io_pid = lf_subpackets->logout->whami;
1119
1120                /*
1121                 * Evaluate the frames.
1122                 */
1123                disposition = process_frame(lf_subpackets, 0);
1124        }
1125        switch(disposition) {
1126        case MCHK_DISPOSITION_DISMISS:
1127                /* Nothing to do. */
1128                break;
1129
1130        case MCHK_DISPOSITION_REPORT:
1131                /* Recognized error, report it. */
1132                printk("%s*%s (Vector 0x%x) reported on CPU %d\n",
1133                       err_print_prefix, error_type,
1134                       (unsigned int)vector, (int)smp_processor_id());
1135                el_print_timestamp(&lf_subpackets->logout->timestamp);
1136                process_frame(lf_subpackets, 1);
1137                break;
1138
1139        default:
1140                /* Unknown - dump the annotated subpackets. */
1141                printk("%s*%s (Vector 0x%x) reported on CPU %d\n",
1142                       err_print_prefix, error_type,
1143                       (unsigned int)vector, (int)smp_processor_id());
1144                el_process_subpacket(el_ptr);
1145                break;
1146
1147        }
1148
1149        err_print_prefix = saved_err_prefix;
1150
1151        /* Release the logout frame.  */
1152        wrmces(0x7);
1153        mb();
1154}
1155
1156void __init
1157marvel_register_error_handlers(void)
1158{
1159        ev7_register_error_handlers();
1160}
1161