1
2
3
4
5
6
7#ifndef DEBUG_H
8#define DEBUG_H
9
10#include <linux/string.h>
11#include <linux/spinlock.h>
12#include <linux/kernel.h>
13#include <linux/time.h>
14#include <linux/refcount.h>
15#include <uapi/asm/debug.h>
16
17#define DEBUG_MAX_LEVEL 6
18#define DEBUG_OFF_LEVEL -1
19#define DEBUG_FLUSH_ALL -1
20#define DEBUG_MAX_VIEWS 10
21#define DEBUG_MAX_NAME_LEN 64
22#define DEBUG_DEFAULT_LEVEL 3
23
24#define DEBUG_DIR_ROOT "s390dbf"
25
26#define DEBUG_DATA(entry) (char *)(entry + 1)
27
28
29typedef struct __debug_entry debug_entry_t;
30
31struct debug_view;
32
33typedef struct debug_info {
34 struct debug_info *next;
35 struct debug_info *prev;
36 refcount_t ref_count;
37 spinlock_t lock;
38 int level;
39 int nr_areas;
40 int pages_per_area;
41 int buf_size;
42 int entry_size;
43 debug_entry_t ***areas;
44 int active_area;
45 int *active_pages;
46 int *active_entries;
47 struct dentry *debugfs_root_entry;
48 struct dentry *debugfs_entries[DEBUG_MAX_VIEWS];
49 struct debug_view *views[DEBUG_MAX_VIEWS];
50 char name[DEBUG_MAX_NAME_LEN];
51 umode_t mode;
52} debug_info_t;
53
54typedef int (debug_header_proc_t) (debug_info_t *id,
55 struct debug_view *view,
56 int area,
57 debug_entry_t *entry,
58 char *out_buf);
59
60typedef int (debug_format_proc_t) (debug_info_t *id,
61 struct debug_view *view, char *out_buf,
62 const char *in_buf);
63typedef int (debug_prolog_proc_t) (debug_info_t *id,
64 struct debug_view *view,
65 char *out_buf);
66typedef int (debug_input_proc_t) (debug_info_t *id,
67 struct debug_view *view,
68 struct file *file,
69 const char __user *user_buf,
70 size_t in_buf_size, loff_t *offset);
71
72int debug_dflt_header_fn(debug_info_t *id, struct debug_view *view,
73 int area, debug_entry_t *entry, char *out_buf);
74
75struct debug_view {
76 char name[DEBUG_MAX_NAME_LEN];
77 debug_prolog_proc_t *prolog_proc;
78 debug_header_proc_t *header_proc;
79 debug_format_proc_t *format_proc;
80 debug_input_proc_t *input_proc;
81 void *private_data;
82};
83
84extern struct debug_view debug_hex_ascii_view;
85extern struct debug_view debug_raw_view;
86extern struct debug_view debug_sprintf_view;
87
88
89
90debug_entry_t *debug_event_common(debug_info_t *id, int level,
91 const void *data, int length);
92
93debug_entry_t *debug_exception_common(debug_info_t *id, int level,
94 const void *data, int length);
95
96
97
98debug_info_t *debug_register(const char *name, int pages, int nr_areas,
99 int buf_size);
100
101debug_info_t *debug_register_mode(const char *name, int pages, int nr_areas,
102 int buf_size, umode_t mode, uid_t uid,
103 gid_t gid);
104
105void debug_unregister(debug_info_t *id);
106
107void debug_set_level(debug_info_t *id, int new_level);
108
109void debug_set_critical(void);
110
111void debug_stop_all(void);
112
113
114
115
116
117
118
119
120
121
122
123static inline bool debug_level_enabled(debug_info_t *id, int level)
124{
125 return level <= id->level;
126}
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141static inline debug_entry_t *debug_event(debug_info_t *id, int level,
142 void *data, int length)
143{
144 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
145 return NULL;
146 return debug_event_common(id, level, data, length);
147}
148
149
150
151
152
153
154
155
156
157
158
159
160
161static inline debug_entry_t *debug_int_event(debug_info_t *id, int level,
162 unsigned int tag)
163{
164 unsigned int t = tag;
165
166 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
167 return NULL;
168 return debug_event_common(id, level, &t, sizeof(unsigned int));
169}
170
171
172
173
174
175
176
177
178
179
180
181
182
183static inline debug_entry_t *debug_long_event(debug_info_t *id, int level,
184 unsigned long tag)
185{
186 unsigned long t = tag;
187
188 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
189 return NULL;
190 return debug_event_common(id, level, &t, sizeof(unsigned long));
191}
192
193
194
195
196
197
198
199
200
201
202
203
204
205static inline debug_entry_t *debug_text_event(debug_info_t *id, int level,
206 const char *txt)
207{
208 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
209 return NULL;
210 return debug_event_common(id, level, txt, strlen(txt));
211}
212
213
214
215
216
217extern debug_entry_t *
218__debug_sprintf_event(debug_info_t *id, int level, char *string, ...)
219 __attribute__ ((format(printf, 3, 4)));
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237#define debug_sprintf_event(_id, _level, _fmt, ...) \
238({ \
239 debug_entry_t *__ret; \
240 debug_info_t *__id = _id; \
241 int __level = _level; \
242 \
243 if ((!__id) || (__level > __id->level)) \
244 __ret = NULL; \
245 else \
246 __ret = __debug_sprintf_event(__id, __level, \
247 _fmt, ## __VA_ARGS__); \
248 __ret; \
249})
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265static inline debug_entry_t *debug_exception(debug_info_t *id, int level,
266 void *data, int length)
267{
268 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
269 return NULL;
270 return debug_exception_common(id, level, data, length);
271}
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286static inline debug_entry_t *debug_int_exception(debug_info_t *id, int level,
287 unsigned int tag)
288{
289 unsigned int t = tag;
290
291 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
292 return NULL;
293 return debug_exception_common(id, level, &t, sizeof(unsigned int));
294}
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309static inline debug_entry_t *debug_long_exception (debug_info_t *id, int level,
310 unsigned long tag)
311{
312 unsigned long t = tag;
313
314 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
315 return NULL;
316 return debug_exception_common(id, level, &t, sizeof(unsigned long));
317}
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333static inline debug_entry_t *debug_text_exception(debug_info_t *id, int level,
334 const char *txt)
335{
336 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
337 return NULL;
338 return debug_exception_common(id, level, txt, strlen(txt));
339}
340
341
342
343
344
345extern debug_entry_t *
346__debug_sprintf_exception(debug_info_t *id, int level, char *string, ...)
347 __attribute__ ((format(printf, 3, 4)));
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367#define debug_sprintf_exception(_id, _level, _fmt, ...) \
368({ \
369 debug_entry_t *__ret; \
370 debug_info_t *__id = _id; \
371 int __level = _level; \
372 \
373 if ((!__id) || (__level > __id->level)) \
374 __ret = NULL; \
375 else \
376 __ret = __debug_sprintf_exception(__id, __level, \
377 _fmt, ## __VA_ARGS__);\
378 __ret; \
379})
380
381int debug_register_view(debug_info_t *id, struct debug_view *view);
382
383int debug_unregister_view(debug_info_t *id, struct debug_view *view);
384
385
386
387
388
389
390
391
392
393
394
395
396#ifndef DEBUG_LEVEL
397#define DEBUG_LEVEL 4
398#endif
399
400#define INTERNAL_ERRMSG(x,y...) "E" __FILE__ "%d: " x, __LINE__, y
401#define INTERNAL_WRNMSG(x,y...) "W" __FILE__ "%d: " x, __LINE__, y
402#define INTERNAL_INFMSG(x,y...) "I" __FILE__ "%d: " x, __LINE__, y
403#define INTERNAL_DEBMSG(x,y...) "D" __FILE__ "%d: " x, __LINE__, y
404
405#if DEBUG_LEVEL > 0
406#define PRINT_DEBUG(x...) printk(KERN_DEBUG PRINTK_HEADER x)
407#define PRINT_INFO(x...) printk(KERN_INFO PRINTK_HEADER x)
408#define PRINT_WARN(x...) printk(KERN_WARNING PRINTK_HEADER x)
409#define PRINT_ERR(x...) printk(KERN_ERR PRINTK_HEADER x)
410#define PRINT_FATAL(x...) panic(PRINTK_HEADER x)
411#else
412#define PRINT_DEBUG(x...) printk(KERN_DEBUG PRINTK_HEADER x)
413#define PRINT_INFO(x...) printk(KERN_DEBUG PRINTK_HEADER x)
414#define PRINT_WARN(x...) printk(KERN_DEBUG PRINTK_HEADER x)
415#define PRINT_ERR(x...) printk(KERN_DEBUG PRINTK_HEADER x)
416#define PRINT_FATAL(x...) printk(KERN_DEBUG PRINTK_HEADER x)
417#endif
418
419#endif
420