1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * S/390 debug facility 4 * 5 * Copyright IBM Corp. 1999, 2000 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 <linux/fs.h> 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 */ 21 #define DEBUG_MAX_NAME_LEN 64 /* max length for a debugfs file name */ 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 29 #define __DEBUG_FEATURE_VERSION 2 /* version of debug feature */ 30 31 struct __debug_entry { 32 union { 33 struct { 34 unsigned long clock : 52; 35 unsigned long exception : 1; 36 unsigned long level : 3; 37 unsigned long cpuid : 8; 38 } fields; 39 unsigned long stck; 40 } id; 41 void *caller; 42 } __packed; 43 44 typedef struct __debug_entry debug_entry_t; 45 46 struct debug_view; 47 48 typedef struct debug_info { 49 struct debug_info *next; 50 struct debug_info *prev; 51 refcount_t ref_count; 52 spinlock_t lock; 53 int level; 54 int nr_areas; 55 int pages_per_area; 56 int buf_size; 57 int entry_size; 58 debug_entry_t ***areas; 59 int active_area; 60 int *active_pages; 61 int *active_entries; 62 struct dentry *debugfs_root_entry; 63 struct dentry *debugfs_entries[DEBUG_MAX_VIEWS]; 64 struct debug_view *views[DEBUG_MAX_VIEWS]; 65 char name[DEBUG_MAX_NAME_LEN]; 66 umode_t mode; 67 } debug_info_t; 68 69 typedef int (debug_header_proc_t) (debug_info_t *id, 70 struct debug_view *view, 71 int area, 72 debug_entry_t *entry, 73 char *out_buf); 74 75 typedef int (debug_format_proc_t) (debug_info_t *id, 76 struct debug_view *view, char *out_buf, 77 const char *in_buf); 78 typedef int (debug_prolog_proc_t) (debug_info_t *id, 79 struct debug_view *view, 80 char *out_buf); 81 typedef int (debug_input_proc_t) (debug_info_t *id, 82 struct debug_view *view, 83 struct file *file, 84 const char __user *user_buf, 85 size_t in_buf_size, loff_t *offset); 86 87 int debug_dflt_header_fn(debug_info_t *id, struct debug_view *view, 88 int area, debug_entry_t *entry, char *out_buf); 89 90 struct debug_view { 91 char name[DEBUG_MAX_NAME_LEN]; 92 debug_prolog_proc_t *prolog_proc; 93 debug_header_proc_t *header_proc; 94 debug_format_proc_t *format_proc; 95 debug_input_proc_t *input_proc; 96 void *private_data; 97 }; 98 99 extern struct debug_view debug_hex_ascii_view; 100 extern struct debug_view debug_sprintf_view; 101 102 /* do NOT use the _common functions */ 103 104 debug_entry_t *debug_event_common(debug_info_t *id, int level, 105 const void *data, int length); 106 107 debug_entry_t *debug_exception_common(debug_info_t *id, int level, 108 const void *data, int length); 109 110 /* Debug Feature API: */ 111 112 debug_info_t *debug_register(const char *name, int pages, int nr_areas, 113 int buf_size); 114 115 debug_info_t *debug_register_mode(const char *name, int pages, int nr_areas, 116 int buf_size, umode_t mode, uid_t uid, 117 gid_t gid); 118 119 void debug_unregister(debug_info_t *id); 120 121 void debug_set_level(debug_info_t *id, int new_level); 122 123 void debug_set_critical(void); 124 125 void debug_stop_all(void); 126 127 /** 128 * debug_level_enabled() - Returns true if debug events for the specified 129 * level would be logged. Otherwise returns false. 130 * 131 * @id: handle for debug log 132 * @level: debug level 133 * 134 * Return: 135 * - %true if level is less or equal to the current debug level. 136 */ 137 static inline bool debug_level_enabled(debug_info_t *id, int level) 138 { 139 return level <= id->level; 140 } 141 142 /** 143 * debug_event() - writes binary debug entry to active debug area 144 * (if level <= actual debug level) 145 * 146 * @id: handle for debug log 147 * @level: debug level 148 * @data: pointer to data for debug entry 149 * @length: length of data in bytes 150 * 151 * Return: 152 * - Address of written debug entry 153 * - %NULL if error 154 */ 155 static inline debug_entry_t *debug_event(debug_info_t *id, int level, 156 void *data, int length) 157 { 158 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 159 return NULL; 160 return debug_event_common(id, level, data, length); 161 } 162 163 /** 164 * debug_int_event() - writes unsigned integer debug entry to active debug area 165 * (if level <= actual debug level) 166 * 167 * @id: handle for debug log 168 * @level: debug level 169 * @tag: integer value for debug entry 170 * 171 * Return: 172 * - Address of written debug entry 173 * - %NULL if error 174 */ 175 static inline debug_entry_t *debug_int_event(debug_info_t *id, int level, 176 unsigned int tag) 177 { 178 unsigned int t = tag; 179 180 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 181 return NULL; 182 return debug_event_common(id, level, &t, sizeof(unsigned int)); 183 } 184 185 /** 186 * debug_long_event() - writes unsigned long debug entry to active debug area 187 * (if level <= actual debug level) 188 * 189 * @id: handle for debug log 190 * @level: debug level 191 * @tag: long integer value for debug entry 192 * 193 * Return: 194 * - Address of written debug entry 195 * - %NULL if error 196 */ 197 static inline debug_entry_t *debug_long_event(debug_info_t *id, int level, 198 unsigned long tag) 199 { 200 unsigned long t = tag; 201 202 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 203 return NULL; 204 return debug_event_common(id, level, &t, sizeof(unsigned long)); 205 } 206 207 /** 208 * debug_text_event() - writes string debug entry in ascii format to active 209 * debug area (if level <= actual debug level) 210 * 211 * @id: handle for debug log 212 * @level: debug level 213 * @txt: string for debug entry 214 * 215 * Return: 216 * - Address of written debug entry 217 * - %NULL if error 218 */ 219 static inline debug_entry_t *debug_text_event(debug_info_t *id, int level, 220 const char *txt) 221 { 222 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 223 return NULL; 224 return debug_event_common(id, level, txt, strlen(txt)); 225 } 226 227 /* 228 * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are 229 * stored in the s390dbf. See Documentation/s390/s390dbf.rst for more details! 230 */ 231 extern debug_entry_t * 232 __debug_sprintf_event(debug_info_t *id, int level, char *string, ...) 233 __attribute__ ((format(printf, 3, 4))); 234 235 /** 236 * debug_sprintf_event() - writes debug entry with format string 237 * and varargs (longs) to active debug area 238 * (if level $<=$ actual debug level). 239 * 240 * @_id: handle for debug log 241 * @_level: debug level 242 * @_fmt: format string for debug entry 243 * @...: varargs used as in sprintf() 244 * 245 * Return: 246 * - Address of written debug entry 247 * - %NULL if error 248 * 249 * floats and long long datatypes cannot be used as varargs. 250 */ 251 #define debug_sprintf_event(_id, _level, _fmt, ...) \ 252 ({ \ 253 debug_entry_t *__ret; \ 254 debug_info_t *__id = _id; \ 255 int __level = _level; \ 256 \ 257 if ((!__id) || (__level > __id->level)) \ 258 __ret = NULL; \ 259 else \ 260 __ret = __debug_sprintf_event(__id, __level, \ 261 _fmt, ## __VA_ARGS__); \ 262 __ret; \ 263 }) 264 265 /** 266 * debug_exception() - writes binary debug entry to active debug area 267 * (if level <= actual debug level) 268 * and switches to next debug area 269 * 270 * @id: handle for debug log 271 * @level: debug level 272 * @data: pointer to data for debug entry 273 * @length: length of data in bytes 274 * 275 * Return: 276 * - Address of written debug entry 277 * - %NULL if error 278 */ 279 static inline debug_entry_t *debug_exception(debug_info_t *id, int level, 280 void *data, int length) 281 { 282 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 283 return NULL; 284 return debug_exception_common(id, level, data, length); 285 } 286 287 /** 288 * debug_int_exception() - writes unsigned int debug entry to active debug area 289 * (if level <= actual debug level) 290 * and switches to next debug area 291 * 292 * @id: handle for debug log 293 * @level: debug level 294 * @tag: integer value for debug entry 295 * 296 * Return: 297 * - Address of written debug entry 298 * - %NULL if error 299 */ 300 static inline debug_entry_t *debug_int_exception(debug_info_t *id, int level, 301 unsigned int tag) 302 { 303 unsigned int t = tag; 304 305 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 306 return NULL; 307 return debug_exception_common(id, level, &t, sizeof(unsigned int)); 308 } 309 310 /** 311 * debug_long_exception() - writes long debug entry to active debug area 312 * (if level <= actual debug level) 313 * and switches to next debug area 314 * 315 * @id: handle for debug log 316 * @level: debug level 317 * @tag: long integer value for debug entry 318 * 319 * Return: 320 * - Address of written debug entry 321 * - %NULL if error 322 */ 323 static inline debug_entry_t *debug_long_exception (debug_info_t *id, int level, 324 unsigned long tag) 325 { 326 unsigned long t = tag; 327 328 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 329 return NULL; 330 return debug_exception_common(id, level, &t, sizeof(unsigned long)); 331 } 332 333 /** 334 * debug_text_exception() - writes string debug entry in ascii format to active 335 * debug area (if level <= actual debug level) 336 * and switches to next debug area 337 * area 338 * 339 * @id: handle for debug log 340 * @level: debug level 341 * @txt: string for debug entry 342 * 343 * Return: 344 * - Address of written debug entry 345 * - %NULL if error 346 */ 347 static inline debug_entry_t *debug_text_exception(debug_info_t *id, int level, 348 const char *txt) 349 { 350 if ((!id) || (level > id->level) || (id->pages_per_area == 0)) 351 return NULL; 352 return debug_exception_common(id, level, txt, strlen(txt)); 353 } 354 355 /* 356 * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are 357 * stored in the s390dbf. See Documentation/s390/s390dbf.rst for more details! 358 */ 359 extern debug_entry_t * 360 __debug_sprintf_exception(debug_info_t *id, int level, char *string, ...) 361 __attribute__ ((format(printf, 3, 4))); 362 363 364 /** 365 * debug_sprintf_exception() - writes debug entry with format string and 366 * varargs (longs) to active debug area 367 * (if level <= actual debug level) 368 * and switches to next debug area. 369 * 370 * @_id: handle for debug log 371 * @_level: debug level 372 * @_fmt: format string for debug entry 373 * @...: varargs used as in sprintf() 374 * 375 * Return: 376 * - Address of written debug entry 377 * - %NULL if error 378 * 379 * floats and long long datatypes cannot be used as varargs. 380 */ 381 #define debug_sprintf_exception(_id, _level, _fmt, ...) \ 382 ({ \ 383 debug_entry_t *__ret; \ 384 debug_info_t *__id = _id; \ 385 int __level = _level; \ 386 \ 387 if ((!__id) || (__level > __id->level)) \ 388 __ret = NULL; \ 389 else \ 390 __ret = __debug_sprintf_exception(__id, __level, \ 391 _fmt, ## __VA_ARGS__);\ 392 __ret; \ 393 }) 394 395 int debug_register_view(debug_info_t *id, struct debug_view *view); 396 397 int debug_unregister_view(debug_info_t *id, struct debug_view *view); 398 399 /* 400 define the debug levels: 401 - 0 No debugging output to console or syslog 402 - 1 Log internal errors to syslog, ignore check conditions 403 - 2 Log internal errors and check conditions to syslog 404 - 3 Log internal errors to console, log check conditions to syslog 405 - 4 Log internal errors and check conditions to console 406 - 5 panic on internal errors, log check conditions to console 407 - 6 panic on both, internal errors and check conditions 408 */ 409 410 #ifndef DEBUG_LEVEL 411 #define DEBUG_LEVEL 4 412 #endif 413 414 #define INTERNAL_ERRMSG(x,y...) "E" __FILE__ "%d: " x, __LINE__, y 415 #define INTERNAL_WRNMSG(x,y...) "W" __FILE__ "%d: " x, __LINE__, y 416 #define INTERNAL_INFMSG(x,y...) "I" __FILE__ "%d: " x, __LINE__, y 417 #define INTERNAL_DEBMSG(x,y...) "D" __FILE__ "%d: " x, __LINE__, y 418 419 #if DEBUG_LEVEL > 0 420 #define PRINT_DEBUG(x...) printk(KERN_DEBUG PRINTK_HEADER x) 421 #define PRINT_INFO(x...) printk(KERN_INFO PRINTK_HEADER x) 422 #define PRINT_WARN(x...) printk(KERN_WARNING PRINTK_HEADER x) 423 #define PRINT_ERR(x...) printk(KERN_ERR PRINTK_HEADER x) 424 #define PRINT_FATAL(x...) panic(PRINTK_HEADER x) 425 #else 426 #define PRINT_DEBUG(x...) printk(KERN_DEBUG PRINTK_HEADER x) 427 #define PRINT_INFO(x...) printk(KERN_DEBUG PRINTK_HEADER x) 428 #define PRINT_WARN(x...) printk(KERN_DEBUG PRINTK_HEADER x) 429 #define PRINT_ERR(x...) printk(KERN_DEBUG PRINTK_HEADER x) 430 #define PRINT_FATAL(x...) printk(KERN_DEBUG PRINTK_HEADER x) 431 #endif /* DASD_DEBUG */ 432 433 #endif /* DEBUG_H */ 434