0001
0002
0003
0004
0005
0006
0007 #ifndef DEBUG_H
0008 #define DEBUG_H
0009
0010 #include <linux/string.h>
0011 #include <linux/spinlock.h>
0012 #include <linux/kernel.h>
0013 #include <linux/time.h>
0014 #include <linux/refcount.h>
0015 #include <linux/fs.h>
0016 #include <linux/init.h>
0017
0018 #define DEBUG_MAX_LEVEL 6
0019 #define DEBUG_OFF_LEVEL -1
0020 #define DEBUG_FLUSH_ALL -1
0021 #define DEBUG_MAX_VIEWS 10
0022 #define DEBUG_MAX_NAME_LEN 64
0023 #define DEBUG_DEFAULT_LEVEL 3
0024
0025 #define DEBUG_DIR_ROOT "s390dbf"
0026
0027 #define DEBUG_DATA(entry) (char *)(entry + 1)
0028
0029
0030 #define __DEBUG_FEATURE_VERSION 3
0031
0032 struct __debug_entry {
0033 unsigned long clock : 60;
0034 unsigned long exception : 1;
0035 unsigned long level : 3;
0036 void *caller;
0037 unsigned short cpu;
0038 } __packed;
0039
0040 typedef struct __debug_entry debug_entry_t;
0041
0042 struct debug_view;
0043
0044 typedef struct debug_info {
0045 struct debug_info *next;
0046 struct debug_info *prev;
0047 refcount_t ref_count;
0048 spinlock_t lock;
0049 int level;
0050 int nr_areas;
0051 int pages_per_area;
0052 int buf_size;
0053 int entry_size;
0054 debug_entry_t ***areas;
0055 int active_area;
0056 int *active_pages;
0057 int *active_entries;
0058 struct dentry *debugfs_root_entry;
0059 struct dentry *debugfs_entries[DEBUG_MAX_VIEWS];
0060 struct debug_view *views[DEBUG_MAX_VIEWS];
0061 char name[DEBUG_MAX_NAME_LEN];
0062 umode_t mode;
0063 } debug_info_t;
0064
0065 typedef int (debug_header_proc_t) (debug_info_t *id,
0066 struct debug_view *view,
0067 int area,
0068 debug_entry_t *entry,
0069 char *out_buf);
0070
0071 typedef int (debug_format_proc_t) (debug_info_t *id,
0072 struct debug_view *view, char *out_buf,
0073 const char *in_buf);
0074 typedef int (debug_prolog_proc_t) (debug_info_t *id,
0075 struct debug_view *view,
0076 char *out_buf);
0077 typedef int (debug_input_proc_t) (debug_info_t *id,
0078 struct debug_view *view,
0079 struct file *file,
0080 const char __user *user_buf,
0081 size_t in_buf_size, loff_t *offset);
0082
0083 int debug_dflt_header_fn(debug_info_t *id, struct debug_view *view,
0084 int area, debug_entry_t *entry, char *out_buf);
0085
0086 struct debug_view {
0087 char name[DEBUG_MAX_NAME_LEN];
0088 debug_prolog_proc_t *prolog_proc;
0089 debug_header_proc_t *header_proc;
0090 debug_format_proc_t *format_proc;
0091 debug_input_proc_t *input_proc;
0092 void *private_data;
0093 };
0094
0095 extern struct debug_view debug_hex_ascii_view;
0096 extern struct debug_view debug_sprintf_view;
0097
0098
0099
0100 debug_entry_t *debug_event_common(debug_info_t *id, int level,
0101 const void *data, int length);
0102
0103 debug_entry_t *debug_exception_common(debug_info_t *id, int level,
0104 const void *data, int length);
0105
0106
0107
0108 debug_info_t *debug_register(const char *name, int pages, int nr_areas,
0109 int buf_size);
0110
0111 debug_info_t *debug_register_mode(const char *name, int pages, int nr_areas,
0112 int buf_size, umode_t mode, uid_t uid,
0113 gid_t gid);
0114
0115 void debug_unregister(debug_info_t *id);
0116
0117 void debug_set_level(debug_info_t *id, int new_level);
0118
0119 void debug_set_critical(void);
0120
0121 void debug_stop_all(void);
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 static inline bool debug_level_enabled(debug_info_t *id, int level)
0134 {
0135 return level <= id->level;
0136 }
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151 static inline debug_entry_t *debug_event(debug_info_t *id, int level,
0152 void *data, int length)
0153 {
0154 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
0155 return NULL;
0156 return debug_event_common(id, level, data, length);
0157 }
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171 static inline debug_entry_t *debug_int_event(debug_info_t *id, int level,
0172 unsigned int tag)
0173 {
0174 unsigned int t = tag;
0175
0176 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
0177 return NULL;
0178 return debug_event_common(id, level, &t, sizeof(unsigned int));
0179 }
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193 static inline debug_entry_t *debug_long_event(debug_info_t *id, int level,
0194 unsigned long tag)
0195 {
0196 unsigned long t = tag;
0197
0198 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
0199 return NULL;
0200 return debug_event_common(id, level, &t, sizeof(unsigned long));
0201 }
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215 static inline debug_entry_t *debug_text_event(debug_info_t *id, int level,
0216 const char *txt)
0217 {
0218 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
0219 return NULL;
0220 return debug_event_common(id, level, txt, strlen(txt));
0221 }
0222
0223
0224
0225
0226
0227 extern debug_entry_t *
0228 __debug_sprintf_event(debug_info_t *id, int level, char *string, ...)
0229 __attribute__ ((format(printf, 3, 4)));
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 #define debug_sprintf_event(_id, _level, _fmt, ...) \
0248 ({ \
0249 debug_entry_t *__ret; \
0250 debug_info_t *__id = _id; \
0251 int __level = _level; \
0252 \
0253 if ((!__id) || (__level > __id->level)) \
0254 __ret = NULL; \
0255 else \
0256 __ret = __debug_sprintf_event(__id, __level, \
0257 _fmt, ## __VA_ARGS__); \
0258 __ret; \
0259 })
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275 static inline debug_entry_t *debug_exception(debug_info_t *id, int level,
0276 void *data, int length)
0277 {
0278 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
0279 return NULL;
0280 return debug_exception_common(id, level, data, length);
0281 }
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296 static inline debug_entry_t *debug_int_exception(debug_info_t *id, int level,
0297 unsigned int tag)
0298 {
0299 unsigned int t = tag;
0300
0301 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
0302 return NULL;
0303 return debug_exception_common(id, level, &t, sizeof(unsigned int));
0304 }
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319 static inline debug_entry_t *debug_long_exception (debug_info_t *id, int level,
0320 unsigned long tag)
0321 {
0322 unsigned long t = tag;
0323
0324 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
0325 return NULL;
0326 return debug_exception_common(id, level, &t, sizeof(unsigned long));
0327 }
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343 static inline debug_entry_t *debug_text_exception(debug_info_t *id, int level,
0344 const char *txt)
0345 {
0346 if ((!id) || (level > id->level) || (id->pages_per_area == 0))
0347 return NULL;
0348 return debug_exception_common(id, level, txt, strlen(txt));
0349 }
0350
0351
0352
0353
0354
0355 extern debug_entry_t *
0356 __debug_sprintf_exception(debug_info_t *id, int level, char *string, ...)
0357 __attribute__ ((format(printf, 3, 4)));
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377 #define debug_sprintf_exception(_id, _level, _fmt, ...) \
0378 ({ \
0379 debug_entry_t *__ret; \
0380 debug_info_t *__id = _id; \
0381 int __level = _level; \
0382 \
0383 if ((!__id) || (__level > __id->level)) \
0384 __ret = NULL; \
0385 else \
0386 __ret = __debug_sprintf_exception(__id, __level, \
0387 _fmt, ## __VA_ARGS__);\
0388 __ret; \
0389 })
0390
0391 int debug_register_view(debug_info_t *id, struct debug_view *view);
0392
0393 int debug_unregister_view(debug_info_t *id, struct debug_view *view);
0394
0395 #ifndef MODULE
0396
0397
0398
0399
0400
0401
0402 #define EARLY_PAGES 8
0403 #define EARLY_AREAS 1
0404
0405 #define VNAME(var, suffix) __##var##_##suffix
0406
0407
0408
0409
0410
0411
0412 #define __DEFINE_STATIC_AREA(var) \
0413 static char VNAME(var, data)[EARLY_PAGES][PAGE_SIZE] __initdata; \
0414 static debug_entry_t *VNAME(var, pages)[EARLY_PAGES] __initdata = { \
0415 (debug_entry_t *)VNAME(var, data)[0], \
0416 (debug_entry_t *)VNAME(var, data)[1], \
0417 (debug_entry_t *)VNAME(var, data)[2], \
0418 (debug_entry_t *)VNAME(var, data)[3], \
0419 (debug_entry_t *)VNAME(var, data)[4], \
0420 (debug_entry_t *)VNAME(var, data)[5], \
0421 (debug_entry_t *)VNAME(var, data)[6], \
0422 (debug_entry_t *)VNAME(var, data)[7], \
0423 }; \
0424 static debug_entry_t **VNAME(var, areas)[EARLY_AREAS] __initdata = { \
0425 (debug_entry_t **)VNAME(var, pages), \
0426 }; \
0427 static int VNAME(var, active_pages)[EARLY_AREAS] __initdata; \
0428 static int VNAME(var, active_entries)[EARLY_AREAS] __initdata
0429
0430 #define __DEBUG_INFO_INIT(var, _name, _buf_size) { \
0431 .next = NULL, \
0432 .prev = NULL, \
0433 .ref_count = REFCOUNT_INIT(1), \
0434 .lock = __SPIN_LOCK_UNLOCKED(var.lock), \
0435 .level = DEBUG_DEFAULT_LEVEL, \
0436 .nr_areas = EARLY_AREAS, \
0437 .pages_per_area = EARLY_PAGES, \
0438 .buf_size = (_buf_size), \
0439 .entry_size = sizeof(debug_entry_t) + (_buf_size), \
0440 .areas = VNAME(var, areas), \
0441 .active_area = 0, \
0442 .active_pages = VNAME(var, active_pages), \
0443 .active_entries = VNAME(var, active_entries), \
0444 .debugfs_root_entry = NULL, \
0445 .debugfs_entries = { NULL }, \
0446 .views = { NULL }, \
0447 .name = (_name), \
0448 .mode = 0600, \
0449 }
0450
0451 #define __REGISTER_STATIC_DEBUG_INFO(var, name, pages, areas, view) \
0452 static int __init VNAME(var, reg)(void) \
0453 { \
0454 debug_register_static(&var, (pages), (areas)); \
0455 debug_register_view(&var, (view)); \
0456 return 0; \
0457 } \
0458 arch_initcall(VNAME(var, reg))
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480 #define DEFINE_STATIC_DEBUG_INFO(var, name, pages, nr_areas, buf_size, view) \
0481 __DEFINE_STATIC_AREA(var); \
0482 static debug_info_t __refdata var = \
0483 __DEBUG_INFO_INIT(var, (name), (buf_size)); \
0484 __REGISTER_STATIC_DEBUG_INFO(var, name, pages, nr_areas, view)
0485
0486 void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas);
0487
0488 #endif
0489
0490 #endif