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