1/*
2 * BK Id: SCCS/s.error_log.c 1.6 05/17/01 18:14:21 cort
3 */
4/*
5 *  arch/ppc/kernel/error_log.c
6 *
7 *  Copyright (c) 2000 Tilmann Bitterberg
8 *  (tilmann@bitterberg.de)
9 *
10 *  Error processing of errors found by rtas even-scan routine
11 *  which is done with every heartbeat. (chrp_setup.c)
12 */
13
14#include <linux/sched.h>
15
16#include <asm/prom.h>
17
18#include "error_log.h"
19
20/* ****************************************************************** */
21/*
22 * EVENT-SCAN
23 * The whole stuff below here doesn't take any action when it found
24 * an error, it just prints as much information as possible and
25 * then its up to the user to decide what to do.
26 *
27 * Returns 0 if no errors were found
28 * Returns 1 if there may be more errors
29 */
30int ppc_rtas_errorlog_scan(void)
31{
32const char *_errlog_severity[] = {
33#ifdef VERBOSE_ERRORS
34	"No Error\n\t\
35Should require no further information",
36	"Event\n\t\
37This is not really an error, it is an event. I use events\n\t\
38to communicate with RTAS back and forth.",
39	"Warning\n\t\
40Indicates a non-state-losing error, either fully recovered\n\t\
41by RTAS or not needing recovery. Ignore it.",
42	"Error sync\n\t\
43May only be fatal to a certain program or thread. Recovery\n\t\
44and continuation is possible, if I only had a handler for\n\t\
45this. Less serious",
46	"Error\n\t\
47Less serious, but still causing a loss of data and state.\n\t\
48I can't tell you exactly what to do, You have to decide\n\t\
49with help from the target and initiator field, what kind\n\t\
50of further actions may take place.",
51	"Fatal\n\t\
52Represent a permanent hardware failure and I believe this\n\t\
53affects my overall performance and behaviour. I would not\n\t\
54attempt to continue normal operation."
55#else
56	"No Error",
57	"Event",
58	"Warning",
59	"Error sync",
60	"Error",
61	"Fatal"
62#endif /* VERBOSE_ERRORS */
63};
64
65
66const char *_errlog_extended[] = {
67#ifdef VERBOSE_ERRORS
68	"Not present\n\t\
69Sad, the RTAS call didn't return an extended error log.",
70	"Present\n\t\
71The extended log is present and hopefully it contains a lot of\n\t\
72useful information, which leads to the solution of the problem."
73#else
74	"Not present",
75	"Present"
76#endif /* VERBOSE_ERRORS */
77};
78
79const char *_errlog_initiator[] = {
80	"Unknown or not applicable",
81	"CPU",
82	"PCI",
83	"ISA",
84	"Memory",
85	"Power management"
86};
87
88const char *_errlog_target[] = {
89	"Unknown or not applicable",
90	"CPU",
91	"PCI",
92	"ISA",
93	"Memory",
94	"Power management"
95};
96	rtas_error_log error_log;
97	char logdata[1024];
98	int error;
99
100	error = call_rtas ("event-scan", 4, 1, (unsigned long *)&error_log,
101			INTERNAL_ERROR | EPOW_WARNING,
102			0, __pa(logdata), 1024);
103
104	if (error == 1) /* no errors found */
105		return 0;
106
107	if (error == -1) {
108		printk(KERN_ERR "Unable to get errors. Do you a favor and throw this box away\n");
109		return 0;
110	}
111	if (error_log.version != 1)
112		printk(KERN_WARNING "Unknown version (%d), please implement me\n",
113				error_log.version);
114
115	switch (error_log.disposition) {
116		case DISP_FULLY_RECOVERED:
117			/* there was an error, but everything is fine now */
118			return 0;
119		case DISP_NOT_RECOVERED:
120			printk("We have a really serious Problem!\n");
121		case DISP_LIMITED_RECOVERY:
122			printk("Error classification\n");
123			printk("Severity  : %s\n",
124					ppc_rtas_errorlog_check_severity (error_log));
125			printk("Initiator : %s\n",
126					ppc_rtas_errorlog_check_initiator (error_log));
127			printk("Target    : %s\n",
128					ppc_rtas_errorlog_check_target (error_log));
129			printk("Type      : %s\n",
130					ppc_rtas_errorlog_check_type (error_log));
131			printk("Ext. log  : %s\n",
132					ppc_rtas_errorlog_check_extended (error_log));
133			if (error_log.extended)
134				ppc_rtas_errorlog_disect_extended (logdata);
135			return 1;
136		default:
137			/* nothing */
138			break;
139	}
140	return 0;
141}
142/* ****************************************************************** */
143const char * ppc_rtas_errorlog_check_type (rtas_error_log error_log)
144{
145	const char *_errlog_type[] = {
146		"unknown type",
147		"too many tries failed",
148		"TCE error",
149		"RTAS device failed",
150		"target timed out",
151		"parity error on data",			/* 5 */
152		"parity error on address",
153		"parity error on external cache",
154		"access to invalid address",
155		"uncorrectable ECC error",
156		"corrected ECC error"			/* 10 */
157	};
158	if (error_log.type == TYPE_EPOW)
159		return "EPOW";
160	if (error_log.type >= TYPE_PMGM_POWER_SW_ON)
161		return "PowerMGM Event (not handled right now)";
162	return _errlog_type[error_log.type];
163}
164
165