File: error_log.c

package info (click to toggle)
kernel-image-2.4.17-hppa 32.4
  • links: PTS
  • area: main
  • in suites: woody
  • size: 156,356 kB
  • ctags: 442,585
  • sloc: ansic: 2,542,442; asm: 144,771; makefile: 8,468; sh: 3,097; perl: 2,578; yacc: 1,177; tcl: 577; lex: 352; awk: 251; lisp: 218; sed: 72
file content (186 lines) | stat: -rw-r--r-- 5,059 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/*
 * BK Id: SCCS/s.error_log.c 1.6 05/17/01 18:14:21 cort
 */
/*
 *  arch/ppc/kernel/error_log.c
 *  
 *  Copyright (c) 2000 Tilmann Bitterberg
 *  (tilmann@bitterberg.de)
 *
 *  Error processing of errors found by rtas even-scan routine
 *  which is done with every heartbeat. (chrp_setup.c)
 */

#include <linux/sched.h>

#include <asm/prom.h>

#include "error_log.h"

/* ****************************************************************** */
/* 
 * EVENT-SCAN
 * The whole stuff below here doesn't take any action when it found
 * an error, it just prints as much information as possible and 
 * then its up to the user to decide what to do.
 *
 * Returns 0 if no errors were found
 * Returns 1 if there may be more errors
 */
int ppc_rtas_errorlog_scan(void)
{
const char *_errlog_severity[] = {
#ifdef VERBOSE_ERRORS
	"No Error\n\t\
Should require no further information",
	"Event\n\t\
This is not really an error, it is an event. I use events\n\t\
to communicate with RTAS back and forth.",
	"Warning\n\t\
Indicates a non-state-losing error, either fully recovered\n\t\
by RTAS or not needing recovery. Ignore it.",
	"Error sync\n\t\
May only be fatal to a certain program or thread. Recovery\n\t\
and continuation is possible, if I only had a handler for\n\t\
this. Less serious",
	"Error\n\t\
Less serious, but still causing a loss of data and state.\n\t\
I can't tell you exactly what to do, You have to decide\n\t\
with help from the target and initiator field, what kind\n\t\
of further actions may take place.",
	"Fatal\n\t\
Represent a permanent hardware failure and I believe this\n\t\
affects my overall performance and behaviour. I would not\n\t\
attempt to continue normal operation."
#else
	"No Error",
	"Event",
	"Warning",
	"Error sync",
	"Error",
	"Fatal"
#endif /* VERBOSE_ERRORS */
};

#if 0 /* unused?? */
const char *_errlog_disposition[] = {
#ifdef VERBOSE_ERRORS
	"Fully recovered\n\t\
There was an error, but it is fully recovered by RTAS.",
	"Limited recovery\n\t\
RTAS was able to recover the state of the machine, but some\n\t\
feature of the machine has been disabled or lost (for example\n\t\
error checking) or performance may suffer.",
	"Not recovered\n\t\
Whether RTAS did not try to recover anything or recovery failed:\n\t\
HOUSTON, WE HAVE A PROBLEM!"
#else
	"Fully recovered",
	"Limited recovery",
	"Not recovered"
#endif /* VERBOSE_ERRORS */
};
#endif

const char *_errlog_extended[] = {
#ifdef VERBOSE_ERRORS
	"Not present\n\t\
Sad, the RTAS call didn't return an extended error log.",
	"Present\n\t\
The extended log is present and hopefully it contains a lot of\n\t\
useful information, which leads to the solution of the problem."
#else
	"Not present",
	"Present"
#endif /* VERBOSE_ERRORS */
};

const char *_errlog_initiator[] = { 
	"Unknown or not applicable",
	"CPU",
	"PCI",
	"ISA",
	"Memory",
	"Power management"
};

const char *_errlog_target[] = { 
	"Unknown or not applicable",
	"CPU",
	"PCI",
	"ISA",
	"Memory",
	"Power management"
};
	rtas_error_log error_log;
	char logdata[1024];
	int error;
#if 0 /* unused?? */
	int retries = 0; /* if HW error, try 10 times */
#endif

	error = call_rtas ("event-scan", 4, 1, (unsigned long *)&error_log,
			INTERNAL_ERROR | EPOW_WARNING,
			0, __pa(logdata), 1024);

	if (error == 1) /* no errors found */
		return 0;

	if (error == -1) {
		printk(KERN_ERR "Unable to get errors. Do you a favor and throw this box away\n");
		return 0;
	}
	if (error_log.version != 1)
		printk(KERN_WARNING "Unknown version (%d), please implement me\n", 
				error_log.version);

	switch (error_log.disposition) {
		case DISP_FULLY_RECOVERED:
			/* there was an error, but everything is fine now */
			return 0;
		case DISP_NOT_RECOVERED:
			printk("We have a really serious Problem!\n");
		case DISP_LIMITED_RECOVERY:
			printk("Error classification\n");
			printk("Severity  : %s\n", 
					ppc_rtas_errorlog_check_severity (error_log));
			printk("Initiator : %s\n", 
					ppc_rtas_errorlog_check_initiator (error_log));
			printk("Target    : %s\n", 
					ppc_rtas_errorlog_check_target (error_log));
			printk("Type      : %s\n", 
					ppc_rtas_errorlog_check_type (error_log));
			printk("Ext. log  : %s\n", 
					ppc_rtas_errorlog_check_extended (error_log));
			if (error_log.extended)
				ppc_rtas_errorlog_disect_extended (logdata);
			return 1;	
		default:
			/* nothing */
			break;
	}
	return 0;
}
/* ****************************************************************** */
const char * ppc_rtas_errorlog_check_type (rtas_error_log error_log)
{
	const char *_errlog_type[] = {
		"unknown type",
		"too many tries failed",
		"TCE error",
		"RTAS device failed",
		"target timed out",
		"parity error on data",			/* 5 */
		"parity error on address",
		"parity error on external cache",
		"access to invalid address",
		"uncorrectable ECC error",
		"corrected ECC error"			/* 10 */
	};
	if (error_log.type == TYPE_EPOW) 
		return "EPOW"; 
	if (error_log.type >= TYPE_PMGM_POWER_SW_ON)
		return "PowerMGM Event (not handled right now)";
	return _errlog_type[error_log.type];
}