Merge branch 'stable/bug-fixes-rc2' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / arch / alpha / kernel / err_marvel.c
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
23 static void
24 marvel_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
67 static int
68 marvel_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
88 static void
89 marvel_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
122 static void
123 marvel_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
138 static void
139 marvel_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
275 static void
276 marvel_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
329 static void
330 marvel_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          */
492 check_uncrr_sym:
493         if (uncrr_sym_valid)
494                 marvel_print_po7_uncrr_sym(io->po7_uncrr_sym, uncrr_sym_valid);
495 }
496
497 static void
498 marvel_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
529 static  void
530 marvel_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
589 static void
590 marvel_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
638 static void
639 marvel_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
796 static struct ev7_pal_io_subpacket *
797 marvel_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
901 static int
902 marvel_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
1009 static int
1010 marvel_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
1045 void
1046 marvel_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
1156 void __init
1157 marvel_register_error_handlers(void)
1158 {
1159         ev7_register_error_handlers();
1160 }