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