]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * include/asm-s390/debug.h | |
3 | * S/390 debug facility | |
4 | * | |
5 | * Copyright (C) 1999, 2000 IBM Deutschland Entwicklung GmbH, | |
6 | * IBM Corporation | |
7 | */ | |
8 | ||
9 | #ifndef DEBUG_H | |
10 | #define DEBUG_H | |
11 | ||
66a464db MH |
12 | #include <linux/config.h> |
13 | #include <linux/fs.h> | |
1da177e4 LT |
14 | #include <linux/string.h> |
15 | ||
16 | /* Note: | |
17 | * struct __debug_entry must be defined outside of #ifdef __KERNEL__ | |
18 | * in order to allow a user program to analyze the 'raw'-view. | |
19 | */ | |
20 | ||
21 | struct __debug_entry{ | |
22 | union { | |
23 | struct { | |
24 | unsigned long long clock:52; | |
25 | unsigned long long exception:1; | |
26 | unsigned long long level:3; | |
27 | unsigned long long cpuid:8; | |
28 | } fields; | |
29 | ||
30 | unsigned long long stck; | |
31 | } id; | |
32 | void* caller; | |
33 | } __attribute__((packed)); | |
34 | ||
35 | ||
66a464db | 36 | #define __DEBUG_FEATURE_VERSION 2 /* version of debug feature */ |
1da177e4 LT |
37 | |
38 | #ifdef __KERNEL__ | |
39 | #include <linux/spinlock.h> | |
40 | #include <linux/kernel.h> | |
41 | #include <linux/time.h> | |
1da177e4 LT |
42 | |
43 | #define DEBUG_MAX_LEVEL 6 /* debug levels range from 0 to 6 */ | |
44 | #define DEBUG_OFF_LEVEL -1 /* level where debug is switched off */ | |
45 | #define DEBUG_FLUSH_ALL -1 /* parameter to flush all areas */ | |
46 | #define DEBUG_MAX_VIEWS 10 /* max number of views in proc fs */ | |
66a464db | 47 | #define DEBUG_MAX_NAME_LEN 64 /* max length for a debugfs file name */ |
1da177e4 LT |
48 | #define DEBUG_DEFAULT_LEVEL 3 /* initial debug level */ |
49 | ||
50 | #define DEBUG_DIR_ROOT "s390dbf" /* name of debug root directory in proc fs */ | |
51 | ||
52 | #define DEBUG_DATA(entry) (char*)(entry + 1) /* data is stored behind */ | |
53 | /* the entry information */ | |
54 | ||
55 | #define STCK(x) asm volatile ("STCK 0(%1)" : "=m" (x) : "a" (&(x)) : "cc") | |
56 | ||
57 | typedef struct __debug_entry debug_entry_t; | |
58 | ||
59 | struct debug_view; | |
60 | ||
61 | typedef struct debug_info { | |
62 | struct debug_info* next; | |
63 | struct debug_info* prev; | |
64 | atomic_t ref_count; | |
65 | spinlock_t lock; | |
66 | int level; | |
67 | int nr_areas; | |
66a464db | 68 | int pages_per_area; |
1da177e4 LT |
69 | int buf_size; |
70 | int entry_size; | |
66a464db | 71 | debug_entry_t*** areas; |
1da177e4 | 72 | int active_area; |
66a464db MH |
73 | int *active_pages; |
74 | int *active_entries; | |
75 | struct dentry* debugfs_root_entry; | |
76 | struct dentry* debugfs_entries[DEBUG_MAX_VIEWS]; | |
1da177e4 | 77 | struct debug_view* views[DEBUG_MAX_VIEWS]; |
66a464db | 78 | char name[DEBUG_MAX_NAME_LEN]; |
1da177e4 LT |
79 | } debug_info_t; |
80 | ||
81 | typedef int (debug_header_proc_t) (debug_info_t* id, | |
82 | struct debug_view* view, | |
83 | int area, | |
84 | debug_entry_t* entry, | |
85 | char* out_buf); | |
86 | ||
87 | typedef int (debug_format_proc_t) (debug_info_t* id, | |
88 | struct debug_view* view, char* out_buf, | |
89 | const char* in_buf); | |
90 | typedef int (debug_prolog_proc_t) (debug_info_t* id, | |
91 | struct debug_view* view, | |
92 | char* out_buf); | |
93 | typedef int (debug_input_proc_t) (debug_info_t* id, | |
94 | struct debug_view* view, | |
95 | struct file* file, | |
96 | const char __user *user_buf, | |
97 | size_t in_buf_size, loff_t* offset); | |
98 | ||
99 | int debug_dflt_header_fn(debug_info_t* id, struct debug_view* view, | |
100 | int area, debug_entry_t* entry, char* out_buf); | |
101 | ||
102 | struct debug_view { | |
66a464db | 103 | char name[DEBUG_MAX_NAME_LEN]; |
1da177e4 LT |
104 | debug_prolog_proc_t* prolog_proc; |
105 | debug_header_proc_t* header_proc; | |
106 | debug_format_proc_t* format_proc; | |
107 | debug_input_proc_t* input_proc; | |
108 | void* private_data; | |
109 | }; | |
110 | ||
111 | extern struct debug_view debug_hex_ascii_view; | |
112 | extern struct debug_view debug_raw_view; | |
113 | extern struct debug_view debug_sprintf_view; | |
114 | ||
115 | /* do NOT use the _common functions */ | |
116 | ||
117 | debug_entry_t* debug_event_common(debug_info_t* id, int level, | |
118 | const void* data, int length); | |
119 | ||
120 | debug_entry_t* debug_exception_common(debug_info_t* id, int level, | |
121 | const void* data, int length); | |
122 | ||
123 | /* Debug Feature API: */ | |
124 | ||
66a464db | 125 | debug_info_t* debug_register(char* name, int pages, int nr_areas, |
1da177e4 LT |
126 | int buf_size); |
127 | ||
128 | void debug_unregister(debug_info_t* id); | |
129 | ||
130 | void debug_set_level(debug_info_t* id, int new_level); | |
131 | ||
132 | void debug_stop_all(void); | |
133 | ||
134 | extern inline debug_entry_t* | |
135 | debug_event(debug_info_t* id, int level, void* data, int length) | |
136 | { | |
66a464db MH |
137 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
138 | return NULL; | |
1da177e4 LT |
139 | return debug_event_common(id,level,data,length); |
140 | } | |
141 | ||
142 | extern inline debug_entry_t* | |
143 | debug_int_event(debug_info_t* id, int level, unsigned int tag) | |
144 | { | |
145 | unsigned int t=tag; | |
66a464db MH |
146 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
147 | return NULL; | |
1da177e4 LT |
148 | return debug_event_common(id,level,&t,sizeof(unsigned int)); |
149 | } | |
150 | ||
151 | extern inline debug_entry_t * | |
152 | debug_long_event (debug_info_t* id, int level, unsigned long tag) | |
153 | { | |
154 | unsigned long t=tag; | |
66a464db MH |
155 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
156 | return NULL; | |
1da177e4 LT |
157 | return debug_event_common(id,level,&t,sizeof(unsigned long)); |
158 | } | |
159 | ||
160 | extern inline debug_entry_t* | |
161 | debug_text_event(debug_info_t* id, int level, const char* txt) | |
162 | { | |
66a464db MH |
163 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
164 | return NULL; | |
1da177e4 LT |
165 | return debug_event_common(id,level,txt,strlen(txt)); |
166 | } | |
167 | ||
168 | extern debug_entry_t * | |
169 | debug_sprintf_event(debug_info_t* id,int level,char *string,...) | |
170 | __attribute__ ((format(printf, 3, 4))); | |
171 | ||
172 | ||
173 | extern inline debug_entry_t* | |
174 | debug_exception(debug_info_t* id, int level, void* data, int length) | |
175 | { | |
66a464db MH |
176 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
177 | return NULL; | |
1da177e4 LT |
178 | return debug_exception_common(id,level,data,length); |
179 | } | |
180 | ||
181 | extern inline debug_entry_t* | |
182 | debug_int_exception(debug_info_t* id, int level, unsigned int tag) | |
183 | { | |
184 | unsigned int t=tag; | |
66a464db MH |
185 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
186 | return NULL; | |
1da177e4 LT |
187 | return debug_exception_common(id,level,&t,sizeof(unsigned int)); |
188 | } | |
189 | ||
190 | extern inline debug_entry_t * | |
191 | debug_long_exception (debug_info_t* id, int level, unsigned long tag) | |
192 | { | |
193 | unsigned long t=tag; | |
66a464db MH |
194 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
195 | return NULL; | |
1da177e4 LT |
196 | return debug_exception_common(id,level,&t,sizeof(unsigned long)); |
197 | } | |
198 | ||
199 | extern inline debug_entry_t* | |
200 | debug_text_exception(debug_info_t* id, int level, const char* txt) | |
201 | { | |
66a464db MH |
202 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) |
203 | return NULL; | |
1da177e4 LT |
204 | return debug_exception_common(id,level,txt,strlen(txt)); |
205 | } | |
206 | ||
207 | ||
208 | extern debug_entry_t * | |
209 | debug_sprintf_exception(debug_info_t* id,int level,char *string,...) | |
210 | __attribute__ ((format(printf, 3, 4))); | |
211 | ||
212 | int debug_register_view(debug_info_t* id, struct debug_view* view); | |
213 | int debug_unregister_view(debug_info_t* id, struct debug_view* view); | |
214 | ||
215 | /* | |
216 | define the debug levels: | |
217 | - 0 No debugging output to console or syslog | |
218 | - 1 Log internal errors to syslog, ignore check conditions | |
219 | - 2 Log internal errors and check conditions to syslog | |
220 | - 3 Log internal errors to console, log check conditions to syslog | |
221 | - 4 Log internal errors and check conditions to console | |
222 | - 5 panic on internal errors, log check conditions to console | |
223 | - 6 panic on both, internal errors and check conditions | |
224 | */ | |
225 | ||
226 | #ifndef DEBUG_LEVEL | |
227 | #define DEBUG_LEVEL 4 | |
228 | #endif | |
229 | ||
230 | #define INTERNAL_ERRMSG(x,y...) "E" __FILE__ "%d: " x, __LINE__, y | |
231 | #define INTERNAL_WRNMSG(x,y...) "W" __FILE__ "%d: " x, __LINE__, y | |
232 | #define INTERNAL_INFMSG(x,y...) "I" __FILE__ "%d: " x, __LINE__, y | |
233 | #define INTERNAL_DEBMSG(x,y...) "D" __FILE__ "%d: " x, __LINE__, y | |
234 | ||
235 | #if DEBUG_LEVEL > 0 | |
236 | #define PRINT_DEBUG(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | |
237 | #define PRINT_INFO(x...) printk ( KERN_INFO PRINTK_HEADER x ) | |
238 | #define PRINT_WARN(x...) printk ( KERN_WARNING PRINTK_HEADER x ) | |
239 | #define PRINT_ERR(x...) printk ( KERN_ERR PRINTK_HEADER x ) | |
240 | #define PRINT_FATAL(x...) panic ( PRINTK_HEADER x ) | |
241 | #else | |
242 | #define PRINT_DEBUG(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | |
243 | #define PRINT_INFO(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | |
244 | #define PRINT_WARN(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | |
245 | #define PRINT_ERR(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | |
246 | #define PRINT_FATAL(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | |
247 | #endif /* DASD_DEBUG */ | |
248 | ||
249 | #undef DEBUG_MALLOC | |
250 | #ifdef DEBUG_MALLOC | |
251 | void *b; | |
252 | #define kmalloc(x...) (PRINT_INFO(" kmalloc %p\n",b=kmalloc(x)),b) | |
253 | #define kfree(x) PRINT_INFO(" kfree %p\n",x);kfree(x) | |
254 | #define get_zeroed_page(x...) (PRINT_INFO(" gfp %p\n",b=get_zeroed_page(x)),b) | |
255 | #define __get_free_pages(x...) (PRINT_INFO(" gfps %p\n",b=__get_free_pages(x)),b) | |
256 | #endif /* DEBUG_MALLOC */ | |
257 | ||
258 | #endif /* __KERNEL__ */ | |
259 | #endif /* DEBUG_H */ |