2 * arch/s390/kernel/debug.c
5 * Copyright (C) 1999, 2000 IBM Deutschland Entwicklung GmbH,
7 * Author(s): Michael Holzheu (holzheu@de.ibm.com),
8 * Holger Smolinski (Holger.Smolinski@de.ibm.com)
10 * Bugreports to: <Linux390@de.ibm.com>
13 #include <linux/config.h>
14 #include <linux/stddef.h>
15 #include <linux/kernel.h>
16 #include <linux/errno.h>
17 #include <linux/slab.h>
18 #include <linux/ctype.h>
19 #include <linux/sysctl.h>
20 #include <asm/uaccess.h>
21 #include <asm/semaphore.h>
23 #include <linux/module.h>
24 #include <linux/init.h>
26 #include <asm/debug.h>
28 #define DEBUG_PROLOG_ENTRY -1
32 typedef struct file_private_info
{
33 loff_t offset
; /* offset of last read in file */
34 int act_area
; /* number of last formated area */
35 int act_entry
; /* last formated entry (offset */
36 /* relative to beginning of last */
38 size_t act_entry_offset
; /* up to this offset we copied */
39 /* in last read the last formated */
40 /* entry to userland */
41 char temp_buf
[2048]; /* buffer for output */
42 debug_info_t
*debug_info_org
; /* original debug information */
43 debug_info_t
*debug_info_snap
; /* snapshot of debug information */
44 struct debug_view
*view
; /* used view of debug info */
45 } file_private_info_t
;
51 * This assumes that all args are converted into longs
52 * on L/390 this is the case for all types of parameter
53 * except of floats, and long long (32 bit)
57 } debug_sprintf_entry_t
;
60 extern void tod_to_timeval(uint64_t todval
, struct timeval
*xtime
);
62 /* internal function prototyes */
64 static int debug_init(void);
65 static ssize_t
debug_output(struct file
*file
, char __user
*user_buf
,
66 size_t user_len
, loff_t
* offset
);
67 static ssize_t
debug_input(struct file
*file
, const char __user
*user_buf
,
68 size_t user_len
, loff_t
* offset
);
69 static int debug_open(struct inode
*inode
, struct file
*file
);
70 static int debug_close(struct inode
*inode
, struct file
*file
);
71 static debug_info_t
* debug_info_create(char *name
, int page_order
, int nr_areas
, int buf_size
);
72 static void debug_info_get(debug_info_t
*);
73 static void debug_info_put(debug_info_t
*);
74 static int debug_prolog_level_fn(debug_info_t
* id
,
75 struct debug_view
*view
, char *out_buf
);
76 static int debug_input_level_fn(debug_info_t
* id
, struct debug_view
*view
,
77 struct file
*file
, const char __user
*user_buf
,
78 size_t user_buf_size
, loff_t
* offset
);
79 static int debug_input_flush_fn(debug_info_t
* id
, struct debug_view
*view
,
80 struct file
*file
, const char __user
*user_buf
,
81 size_t user_buf_size
, loff_t
* offset
);
82 static int debug_hex_ascii_format_fn(debug_info_t
* id
, struct debug_view
*view
,
83 char *out_buf
, const char *in_buf
);
84 static int debug_raw_format_fn(debug_info_t
* id
,
85 struct debug_view
*view
, char *out_buf
,
87 static int debug_raw_header_fn(debug_info_t
* id
, struct debug_view
*view
,
88 int area
, debug_entry_t
* entry
, char *out_buf
);
90 static int debug_sprintf_format_fn(debug_info_t
* id
, struct debug_view
*view
,
91 char *out_buf
, debug_sprintf_entry_t
*curr_event
);
95 struct debug_view debug_raw_view
= {
104 struct debug_view debug_hex_ascii_view
= {
107 &debug_dflt_header_fn
,
108 &debug_hex_ascii_format_fn
,
113 struct debug_view debug_level_view
= {
115 &debug_prolog_level_fn
,
118 &debug_input_level_fn
,
122 struct debug_view debug_flush_view
= {
127 &debug_input_flush_fn
,
131 struct debug_view debug_sprintf_view
= {
134 &debug_dflt_header_fn
,
135 (debug_format_proc_t
*)&debug_sprintf_format_fn
,
141 unsigned int debug_feature_version
= __DEBUG_FEATURE_VERSION
;
145 static debug_info_t
*debug_area_first
= NULL
;
146 static debug_info_t
*debug_area_last
= NULL
;
147 DECLARE_MUTEX(debug_lock
);
149 static int initialized
;
151 static struct file_operations debug_file_ops
= {
152 .owner
= THIS_MODULE
,
153 .read
= debug_output
,
154 .write
= debug_input
,
156 .release
= debug_close
,
159 static struct proc_dir_entry
*debug_proc_root_entry
;
165 * - alloc new debug-info
168 static debug_info_t
* debug_info_alloc(char *name
, int page_order
,
169 int nr_areas
, int buf_size
)
174 /* alloc everything */
176 rc
= (debug_info_t
*) kmalloc(sizeof(debug_info_t
), GFP_ATOMIC
);
179 rc
->active_entry
= (int*)kmalloc(nr_areas
* sizeof(int), GFP_ATOMIC
);
180 if(!rc
->active_entry
)
181 goto fail_malloc_active_entry
;
182 memset(rc
->active_entry
, 0, nr_areas
* sizeof(int));
183 rc
->areas
= (debug_entry_t
**) kmalloc(nr_areas
*
184 sizeof(debug_entry_t
*),
187 goto fail_malloc_areas
;
188 for (i
= 0; i
< nr_areas
; i
++) {
189 rc
->areas
[i
] = (debug_entry_t
*) __get_free_pages(GFP_ATOMIC
,
192 for (i
--; i
>= 0; i
--) {
193 free_pages((unsigned long) rc
->areas
[i
],
196 goto fail_malloc_areas2
;
198 memset(rc
->areas
[i
], 0, PAGE_SIZE
<< page_order
);
202 /* initialize members */
204 spin_lock_init(&rc
->lock
);
205 rc
->page_order
= page_order
;
206 rc
->nr_areas
= nr_areas
;
208 rc
->level
= DEBUG_DEFAULT_LEVEL
;
209 rc
->buf_size
= buf_size
;
210 rc
->entry_size
= sizeof(debug_entry_t
) + buf_size
;
211 strlcpy(rc
->name
, name
, sizeof(rc
->name
));
212 memset(rc
->views
, 0, DEBUG_MAX_VIEWS
* sizeof(struct debug_view
*));
213 #ifdef CONFIG_PROC_FS
214 memset(rc
->proc_entries
, 0 ,DEBUG_MAX_VIEWS
*
215 sizeof(struct proc_dir_entry
*));
216 #endif /* CONFIG_PROC_FS */
217 atomic_set(&(rc
->ref_count
), 0);
224 kfree(rc
->active_entry
);
225 fail_malloc_active_entry
:
233 * - free memory debug-info
236 static void debug_info_free(debug_info_t
* db_info
){
238 for (i
= 0; i
< db_info
->nr_areas
; i
++) {
239 free_pages((unsigned long) db_info
->areas
[i
],
240 db_info
->page_order
);
242 kfree(db_info
->areas
);
243 kfree(db_info
->active_entry
);
249 * - create new debug-info
252 static debug_info_t
* debug_info_create(char *name
, int page_order
,
253 int nr_areas
, int buf_size
)
257 rc
= debug_info_alloc(name
, page_order
, nr_areas
, buf_size
);
262 /* create proc rood directory */
263 rc
->proc_root_entry
= proc_mkdir(rc
->name
, debug_proc_root_entry
);
265 /* append new element to linked list */
266 if (debug_area_first
== NULL
) {
267 /* first element in list */
268 debug_area_first
= rc
;
271 /* append element to end of list */
272 debug_area_last
->next
= rc
;
273 rc
->prev
= debug_area_last
;
275 debug_area_last
= rc
;
288 static debug_info_t
* debug_info_copy(debug_info_t
* in
)
292 rc
= debug_info_alloc(in
->name
, in
->page_order
,
293 in
->nr_areas
, in
->buf_size
);
297 for(i
= 0; i
< in
->nr_areas
; i
++){
298 memcpy(rc
->areas
[i
],in
->areas
[i
], PAGE_SIZE
<< in
->page_order
);
306 * - increments reference count for debug-info
309 static void debug_info_get(debug_info_t
* db_info
)
312 atomic_inc(&db_info
->ref_count
);
317 * - decreases reference count for debug-info and frees it if necessary
320 static void debug_info_put(debug_info_t
*db_info
)
326 if (atomic_dec_and_test(&db_info
->ref_count
)) {
328 printk(KERN_INFO
"debug: freeing debug area %p (%s)\n",
329 db_info
, db_info
->name
);
331 for (i
= 0; i
< DEBUG_MAX_VIEWS
; i
++) {
332 if (db_info
->views
[i
] == NULL
)
334 #ifdef CONFIG_PROC_FS
335 remove_proc_entry(db_info
->proc_entries
[i
]->name
,
336 db_info
->proc_root_entry
);
339 #ifdef CONFIG_PROC_FS
340 remove_proc_entry(db_info
->proc_root_entry
->name
,
341 debug_proc_root_entry
);
343 if(db_info
== debug_area_first
)
344 debug_area_first
= db_info
->next
;
345 if(db_info
== debug_area_last
)
346 debug_area_last
= db_info
->prev
;
347 if(db_info
->prev
) db_info
->prev
->next
= db_info
->next
;
348 if(db_info
->next
) db_info
->next
->prev
= db_info
->prev
;
349 debug_info_free(db_info
);
354 * debug_format_entry:
355 * - format one debug entry and return size of formated data
358 static int debug_format_entry(file_private_info_t
*p_info
)
360 debug_info_t
*id_org
= p_info
->debug_info_org
;
361 debug_info_t
*id_snap
= p_info
->debug_info_snap
;
362 struct debug_view
*view
= p_info
->view
;
363 debug_entry_t
*act_entry
;
365 if(p_info
->act_entry
== DEBUG_PROLOG_ENTRY
){
367 if (view
->prolog_proc
)
368 len
+= view
->prolog_proc(id_org
, view
,p_info
->temp_buf
);
372 act_entry
= (debug_entry_t
*) ((char*)id_snap
->areas
[p_info
->act_area
] +
375 if (act_entry
->id
.stck
== 0LL)
376 goto out
; /* empty entry */
377 if (view
->header_proc
)
378 len
+= view
->header_proc(id_org
, view
, p_info
->act_area
,
379 act_entry
, p_info
->temp_buf
+ len
);
380 if (view
->format_proc
)
381 len
+= view
->format_proc(id_org
, view
, p_info
->temp_buf
+ len
,
382 DEBUG_DATA(act_entry
));
389 * - goto next entry in p_info
392 extern inline int debug_next_entry(file_private_info_t
*p_info
)
394 debug_info_t
*id
= p_info
->debug_info_snap
;
395 if(p_info
->act_entry
== DEBUG_PROLOG_ENTRY
){
396 p_info
->act_entry
= 0;
399 if ((p_info
->act_entry
+= id
->entry_size
)
400 > ((PAGE_SIZE
<< (id
->page_order
))
404 p_info
->act_entry
= 0;
406 if(p_info
->act_area
>= id
->nr_areas
)
415 * - called for user read()
416 * - copies formated debug entries to the user buffer
419 static ssize_t
debug_output(struct file
*file
, /* file descriptor */
420 char __user
*user_buf
, /* user buffer */
421 size_t len
, /* length of buffer */
422 loff_t
*offset
) /* offset in the file */
425 size_t entry_offset
, size
= 0;
426 file_private_info_t
*p_info
;
428 p_info
= ((file_private_info_t
*) file
->private_data
);
429 if (*offset
!= p_info
->offset
)
431 if(p_info
->act_area
>= p_info
->debug_info_snap
->nr_areas
)
434 entry_offset
= p_info
->act_entry_offset
;
437 size
= debug_format_entry(p_info
);
438 size
= min((len
- count
), (size
- entry_offset
));
441 if (copy_to_user(user_buf
+ count
,
442 p_info
->temp_buf
+ entry_offset
, size
))
448 if(debug_next_entry(p_info
))
452 p_info
->offset
= *offset
+ count
;
453 p_info
->act_entry_offset
= size
;
454 *offset
= p_info
->offset
;
460 * - called for user write()
461 * - calls input function of view
464 static ssize_t
debug_input(struct file
*file
,
465 const char __user
*user_buf
, size_t length
,
469 file_private_info_t
*p_info
;
472 p_info
= ((file_private_info_t
*) file
->private_data
);
473 if (p_info
->view
->input_proc
)
474 rc
= p_info
->view
->input_proc(p_info
->debug_info_org
,
475 p_info
->view
, file
, user_buf
,
480 return rc
; /* number of input characters */
485 * - called for user open()
486 * - copies formated output to private_data area of the file
490 static int debug_open(struct inode
*inode
, struct file
*file
)
493 file_private_info_t
*p_info
;
494 debug_info_t
*debug_info
, *debug_info_snapshot
;
497 printk("debug_open\n");
501 /* find debug log and view */
503 debug_info
= debug_area_first
;
504 while(debug_info
!= NULL
){
505 for (i
= 0; i
< DEBUG_MAX_VIEWS
; i
++) {
506 if (debug_info
->views
[i
] == NULL
)
508 else if (debug_info
->proc_entries
[i
] ==
509 PDE(file
->f_dentry
->d_inode
)) {
510 goto found
; /* found view ! */
513 debug_info
= debug_info
->next
;
521 /* make snapshot of current debug areas to get it consistent */
523 debug_info_snapshot
= debug_info_copy(debug_info
);
525 if(!debug_info_snapshot
){
527 printk(KERN_ERR
"debug_open: debug_info_copy failed (out of mem)\n");
533 if ((file
->private_data
=
534 kmalloc(sizeof(file_private_info_t
), GFP_ATOMIC
)) == 0) {
536 printk(KERN_ERR
"debug_open: kmalloc failed\n");
538 debug_info_free(debug_info_snapshot
);
542 p_info
= (file_private_info_t
*) file
->private_data
;
544 p_info
->debug_info_snap
= debug_info_snapshot
;
545 p_info
->debug_info_org
= debug_info
;
546 p_info
->view
= debug_info
->views
[i
];
547 p_info
->act_area
= 0;
548 p_info
->act_entry
= DEBUG_PROLOG_ENTRY
;
549 p_info
->act_entry_offset
= 0;
551 debug_info_get(debug_info
);
560 * - called for user close()
561 * - deletes private_data area of the file handle
564 static int debug_close(struct inode
*inode
, struct file
*file
)
566 file_private_info_t
*p_info
;
568 printk("debug_close\n");
570 p_info
= (file_private_info_t
*) file
->private_data
;
571 debug_info_free(p_info
->debug_info_snap
);
572 debug_info_put(p_info
->debug_info_org
);
573 kfree(file
->private_data
);
574 return 0; /* success */
579 * - creates and initializes debug area for the caller
580 * - returns handle for debug area
583 debug_info_t
*debug_register
584 (char *name
, int page_order
, int nr_areas
, int buf_size
)
586 debug_info_t
*rc
= NULL
;
592 /* create new debug_info */
594 rc
= debug_info_create(name
, page_order
, nr_areas
, buf_size
);
597 debug_register_view(rc
, &debug_level_view
);
598 debug_register_view(rc
, &debug_flush_view
);
601 "debug: reserved %d areas of %d pages for debugging %s\n",
602 nr_areas
, 1 << page_order
, rc
->name
);
606 printk(KERN_ERR
"debug: debug_register failed for %s\n",name
);
614 * - give back debug area
617 void debug_unregister(debug_info_t
* id
)
623 printk(KERN_INFO
"debug: unregistering %s\n", id
->name
);
634 * - set actual debug level
637 void debug_set_level(debug_info_t
* id
, int new_level
)
642 spin_lock_irqsave(&id
->lock
,flags
);
643 if(new_level
== DEBUG_OFF_LEVEL
){
644 id
->level
= DEBUG_OFF_LEVEL
;
645 printk(KERN_INFO
"debug: %s: switched off\n",id
->name
);
646 } else if ((new_level
> DEBUG_MAX_LEVEL
) || (new_level
< 0)) {
648 "debug: %s: level %i is out of range (%i - %i)\n",
649 id
->name
, new_level
, 0, DEBUG_MAX_LEVEL
);
651 id
->level
= new_level
;
654 "debug: %s: new level %i\n",id
->name
,id
->level
);
657 spin_unlock_irqrestore(&id
->lock
,flags
);
662 * proceed_active_entry:
663 * - set active entry to next in the ring buffer
666 extern inline void proceed_active_entry(debug_info_t
* id
)
668 if ((id
->active_entry
[id
->active_area
] += id
->entry_size
)
669 > ((PAGE_SIZE
<< (id
->page_order
)) - id
->entry_size
))
670 id
->active_entry
[id
->active_area
] = 0;
674 * proceed_active_area:
675 * - set active area to next in the ring buffer
678 extern inline void proceed_active_area(debug_info_t
* id
)
681 id
->active_area
= id
->active_area
% id
->nr_areas
;
688 extern inline debug_entry_t
*get_active_entry(debug_info_t
* id
)
690 return (debug_entry_t
*) ((char *) id
->areas
[id
->active_area
] +
691 id
->active_entry
[id
->active_area
]);
695 * debug_finish_entry:
696 * - set timestamp, caller address, cpu number etc.
699 extern inline void debug_finish_entry(debug_info_t
* id
, debug_entry_t
* active
,
700 int level
, int exception
)
702 STCK(active
->id
.stck
);
703 active
->id
.fields
.cpuid
= smp_processor_id();
704 active
->caller
= __builtin_return_address(0);
705 active
->id
.fields
.exception
= exception
;
706 active
->id
.fields
.level
= level
;
707 proceed_active_entry(id
);
709 proceed_active_area(id
);
712 static int debug_stoppable
=1;
713 static int debug_active
=1;
715 #define CTL_S390DBF 5677
716 #define CTL_S390DBF_STOPPABLE 5678
717 #define CTL_S390DBF_ACTIVE 5679
720 * proc handler for the running debug_active sysctl
721 * always allow read, allow write only if debug_stoppable is set or
722 * if debug_active is already off
724 static int s390dbf_procactive(ctl_table
*table
, int write
, struct file
*filp
,
725 void __user
*buffer
, size_t *lenp
, loff_t
*ppos
)
727 if (!write
|| debug_stoppable
|| !debug_active
)
728 return proc_dointvec(table
, write
, filp
, buffer
, lenp
, ppos
);
734 static struct ctl_table s390dbf_table
[] = {
736 .ctl_name
= CTL_S390DBF_STOPPABLE
,
737 .procname
= "debug_stoppable",
738 .data
= &debug_stoppable
,
739 .maxlen
= sizeof(int),
740 .mode
= S_IRUGO
| S_IWUSR
,
741 .proc_handler
= &proc_dointvec
,
742 .strategy
= &sysctl_intvec
,
745 .ctl_name
= CTL_S390DBF_ACTIVE
,
746 .procname
= "debug_active",
747 .data
= &debug_active
,
748 .maxlen
= sizeof(int),
749 .mode
= S_IRUGO
| S_IWUSR
,
750 .proc_handler
= &s390dbf_procactive
,
751 .strategy
= &sysctl_intvec
,
756 static struct ctl_table s390dbf_dir_table
[] = {
758 .ctl_name
= CTL_S390DBF
,
759 .procname
= "s390dbf",
761 .mode
= S_IRUGO
| S_IXUGO
,
762 .child
= s390dbf_table
,
767 struct ctl_table_header
*s390dbf_sysctl_header
;
769 void debug_stop_all(void)
777 * debug_event_common:
778 * - write debug entry with given size
781 debug_entry_t
*debug_event_common(debug_info_t
* id
, int level
, const void *buf
,
785 debug_entry_t
*active
;
789 spin_lock_irqsave(&id
->lock
, flags
);
790 active
= get_active_entry(id
);
791 memset(DEBUG_DATA(active
), 0, id
->buf_size
);
792 memcpy(DEBUG_DATA(active
), buf
, min(len
, id
->buf_size
));
793 debug_finish_entry(id
, active
, level
, 0);
794 spin_unlock_irqrestore(&id
->lock
, flags
);
800 * debug_exception_common:
801 * - write debug entry with given size and switch to next debug area
804 debug_entry_t
*debug_exception_common(debug_info_t
* id
, int level
,
805 const void *buf
, int len
)
808 debug_entry_t
*active
;
812 spin_lock_irqsave(&id
->lock
, flags
);
813 active
= get_active_entry(id
);
814 memset(DEBUG_DATA(active
), 0, id
->buf_size
);
815 memcpy(DEBUG_DATA(active
), buf
, min(len
, id
->buf_size
));
816 debug_finish_entry(id
, active
, level
, 1);
817 spin_unlock_irqrestore(&id
->lock
, flags
);
823 * counts arguments in format string for sprintf view
826 extern inline int debug_count_numargs(char *string
)
838 * debug_sprintf_event:
841 debug_entry_t
*debug_sprintf_event(debug_info_t
* id
,
842 int level
,char *string
,...)
847 debug_sprintf_entry_t
*curr_event
;
848 debug_entry_t
*active
;
850 if((!id
) || (level
> id
->level
))
854 numargs
=debug_count_numargs(string
);
856 spin_lock_irqsave(&id
->lock
, flags
);
857 active
= get_active_entry(id
);
858 curr_event
=(debug_sprintf_entry_t
*) DEBUG_DATA(active
);
860 curr_event
->string
=string
;
861 for(idx
=0;idx
<min(numargs
,(int)(id
->buf_size
/ sizeof(long))-1);idx
++)
862 curr_event
->args
[idx
]=va_arg(ap
,long);
864 debug_finish_entry(id
, active
, level
, 0);
865 spin_unlock_irqrestore(&id
->lock
, flags
);
871 * debug_sprintf_exception:
874 debug_entry_t
*debug_sprintf_exception(debug_info_t
* id
,
875 int level
,char *string
,...)
880 debug_sprintf_entry_t
*curr_event
;
881 debug_entry_t
*active
;
883 if((!id
) || (level
> id
->level
))
888 numargs
=debug_count_numargs(string
);
890 spin_lock_irqsave(&id
->lock
, flags
);
891 active
= get_active_entry(id
);
892 curr_event
=(debug_sprintf_entry_t
*)DEBUG_DATA(active
);
894 curr_event
->string
=string
;
895 for(idx
=0;idx
<min(numargs
,(int)(id
->buf_size
/ sizeof(long))-1);idx
++)
896 curr_event
->args
[idx
]=va_arg(ap
,long);
898 debug_finish_entry(id
, active
, level
, 1);
899 spin_unlock_irqrestore(&id
->lock
, flags
);
906 * - is called exactly once to initialize the debug feature
909 static int __init
debug_init(void)
913 s390dbf_sysctl_header
= register_sysctl_table(s390dbf_dir_table
, 1);
915 #ifdef CONFIG_PROC_FS
916 debug_proc_root_entry
= proc_mkdir(DEBUG_DIR_ROOT
, NULL
);
917 #endif /* CONFIG_PROC_FS */
918 printk(KERN_INFO
"debug: Initialization complete\n");
926 * debug_register_view:
929 int debug_register_view(debug_info_t
* id
, struct debug_view
*view
)
934 mode_t mode
= S_IFREG
;
935 struct proc_dir_entry
*pde
;
939 if (view
->prolog_proc
|| view
->format_proc
|| view
->header_proc
)
941 if (view
->input_proc
)
943 pde
= create_proc_entry(view
->name
, mode
, id
->proc_root_entry
);
945 printk(KERN_WARNING
"debug: create_proc_entry() failed! Cannot register view %s/%s\n", id
->name
,view
->name
);
950 spin_lock_irqsave(&id
->lock
, flags
);
951 for (i
= 0; i
< DEBUG_MAX_VIEWS
; i
++) {
952 if (id
->views
[i
] == NULL
)
955 if (i
== DEBUG_MAX_VIEWS
) {
956 printk(KERN_WARNING
"debug: cannot register view %s/%s\n",
957 id
->name
,view
->name
);
959 "debug: maximum number of views reached (%i)!\n", i
);
960 remove_proc_entry(pde
->name
, id
->proc_root_entry
);
965 pde
->proc_fops
= &debug_file_ops
;
966 id
->proc_entries
[i
] = pde
;
968 spin_unlock_irqrestore(&id
->lock
, flags
);
974 * debug_unregister_view:
977 int debug_unregister_view(debug_info_t
* id
, struct debug_view
*view
)
985 spin_lock_irqsave(&id
->lock
, flags
);
986 for (i
= 0; i
< DEBUG_MAX_VIEWS
; i
++) {
987 if (id
->views
[i
] == view
)
990 if (i
== DEBUG_MAX_VIEWS
)
993 #ifdef CONFIG_PROC_FS
994 remove_proc_entry(id
->proc_entries
[i
]->name
,
995 id
->proc_root_entry
);
1000 spin_unlock_irqrestore(&id
->lock
, flags
);
1006 * functions for debug-views
1007 ***********************************
1011 * prints out actual debug level
1014 static int debug_prolog_level_fn(debug_info_t
* id
,
1015 struct debug_view
*view
, char *out_buf
)
1019 if(id
->level
== -1) rc
= sprintf(out_buf
,"-\n");
1020 else rc
= sprintf(out_buf
, "%i\n", id
->level
);
1025 * reads new debug level
1028 static int debug_input_level_fn(debug_info_t
* id
, struct debug_view
*view
,
1029 struct file
*file
, const char __user
*user_buf
,
1030 size_t in_buf_size
, loff_t
* offset
)
1033 int rc
= in_buf_size
;
1037 if (copy_from_user(input_buf
, user_buf
, 1)){
1041 if (isdigit(input_buf
[0])) {
1042 int new_level
= ((int) input_buf
[0] - (int) '0');
1043 debug_set_level(id
, new_level
);
1044 } else if(input_buf
[0] == '-') {
1045 debug_set_level(id
, DEBUG_OFF_LEVEL
);
1047 printk(KERN_INFO
"debug: level `%c` is not valid\n",
1051 *offset
+= in_buf_size
;
1052 return rc
; /* number of input characters */
1057 * flushes debug areas
1060 void debug_flush(debug_info_t
* id
, int area
)
1062 unsigned long flags
;
1067 spin_lock_irqsave(&id
->lock
,flags
);
1068 if(area
== DEBUG_FLUSH_ALL
){
1069 id
->active_area
= 0;
1070 memset(id
->active_entry
, 0, id
->nr_areas
* sizeof(int));
1071 for (i
= 0; i
< id
->nr_areas
; i
++)
1072 memset(id
->areas
[i
], 0, PAGE_SIZE
<< id
->page_order
);
1073 printk(KERN_INFO
"debug: %s: all areas flushed\n",id
->name
);
1074 } else if(area
>= 0 && area
< id
->nr_areas
) {
1075 id
->active_entry
[area
] = 0;
1076 memset(id
->areas
[area
], 0, PAGE_SIZE
<< id
->page_order
);
1078 "debug: %s: area %i has been flushed\n",
1082 "debug: %s: area %i cannot be flushed (range: %i - %i)\n",
1083 id
->name
, area
, 0, id
->nr_areas
-1);
1085 spin_unlock_irqrestore(&id
->lock
,flags
);
1089 * view function: flushes debug areas
1092 static int debug_input_flush_fn(debug_info_t
* id
, struct debug_view
*view
,
1093 struct file
*file
, const char __user
*user_buf
,
1094 size_t in_buf_size
, loff_t
* offset
)
1097 int rc
= in_buf_size
;
1101 if (copy_from_user(input_buf
, user_buf
, 1)){
1105 if(input_buf
[0] == '-') {
1106 debug_flush(id
, DEBUG_FLUSH_ALL
);
1109 if (isdigit(input_buf
[0])) {
1110 int area
= ((int) input_buf
[0] - (int) '0');
1111 debug_flush(id
, area
);
1115 printk(KERN_INFO
"debug: area `%c` is not valid\n", input_buf
[0]);
1118 *offset
+= in_buf_size
;
1119 return rc
; /* number of input characters */
1123 * prints debug header in raw format
1126 int debug_raw_header_fn(debug_info_t
* id
, struct debug_view
*view
,
1127 int area
, debug_entry_t
* entry
, char *out_buf
)
1131 rc
= sizeof(debug_entry_t
);
1132 memcpy(out_buf
,entry
,sizeof(debug_entry_t
));
1137 * prints debug data in raw format
1140 static int debug_raw_format_fn(debug_info_t
* id
, struct debug_view
*view
,
1141 char *out_buf
, const char *in_buf
)
1146 memcpy(out_buf
, in_buf
, id
->buf_size
);
1151 * prints debug data in hex/ascii format
1154 static int debug_hex_ascii_format_fn(debug_info_t
* id
, struct debug_view
*view
,
1155 char *out_buf
, const char *in_buf
)
1159 for (i
= 0; i
< id
->buf_size
; i
++) {
1160 rc
+= sprintf(out_buf
+ rc
, "%02x ",
1161 ((unsigned char *) in_buf
)[i
]);
1163 rc
+= sprintf(out_buf
+ rc
, "| ");
1164 for (i
= 0; i
< id
->buf_size
; i
++) {
1165 unsigned char c
= in_buf
[i
];
1167 rc
+= sprintf(out_buf
+ rc
, ".");
1169 rc
+= sprintf(out_buf
+ rc
, "%c", c
);
1171 rc
+= sprintf(out_buf
+ rc
, "\n");
1176 * prints header for debug entry
1179 int debug_dflt_header_fn(debug_info_t
* id
, struct debug_view
*view
,
1180 int area
, debug_entry_t
* entry
, char *out_buf
)
1182 struct timeval time_val
;
1183 unsigned long long time
;
1185 unsigned long caller
;
1189 level
= entry
->id
.fields
.level
;
1190 time
= entry
->id
.stck
;
1191 /* adjust todclock to 1970 */
1192 time
-= 0x8126d60e46000000LL
- (0x3c26700LL
* 1000000 * 4096);
1193 tod_to_timeval(time
, &time_val
);
1195 if (entry
->id
.fields
.exception
)
1199 caller
= ((unsigned long) entry
->caller
) & PSW_ADDR_INSN
;
1200 rc
+= sprintf(out_buf
, "%02i %011lu:%06lu %1u %1s %02i %p ",
1201 area
, time_val
.tv_sec
, time_val
.tv_usec
, level
,
1202 except_str
, entry
->id
.fields
.cpuid
, (void *) caller
);
1207 * prints debug data sprintf-formated:
1208 * debug_sprinf_event/exception calls must be used together with this view
1211 #define DEBUG_SPRINTF_MAX_ARGS 10
1213 int debug_sprintf_format_fn(debug_info_t
* id
, struct debug_view
*view
,
1214 char *out_buf
, debug_sprintf_entry_t
*curr_event
)
1216 int num_longs
, num_used_args
= 0,i
, rc
= 0;
1217 int index
[DEBUG_SPRINTF_MAX_ARGS
];
1219 /* count of longs fit into one entry */
1220 num_longs
= id
->buf_size
/ sizeof(long);
1223 goto out
; /* bufsize of entry too small */
1224 if(num_longs
== 1) {
1225 /* no args, we use only the string */
1226 strcpy(out_buf
, curr_event
->string
);
1227 rc
= strlen(curr_event
->string
);
1231 /* number of arguments used for sprintf (without the format string) */
1232 num_used_args
= min(DEBUG_SPRINTF_MAX_ARGS
, (num_longs
- 1));
1234 memset(index
,0, DEBUG_SPRINTF_MAX_ARGS
* sizeof(int));
1236 for(i
= 0; i
< num_used_args
; i
++)
1239 rc
= sprintf(out_buf
, curr_event
->string
, curr_event
->args
[index
[0]],
1240 curr_event
->args
[index
[1]], curr_event
->args
[index
[2]],
1241 curr_event
->args
[index
[3]], curr_event
->args
[index
[4]],
1242 curr_event
->args
[index
[5]], curr_event
->args
[index
[6]],
1243 curr_event
->args
[index
[7]], curr_event
->args
[index
[8]],
1244 curr_event
->args
[index
[9]]);
1254 void __exit
debug_exit(void)
1257 printk("debug_cleanup_module: \n");
1259 #ifdef CONFIG_PROC_FS
1260 remove_proc_entry(debug_proc_root_entry
->name
, NULL
);
1261 #endif /* CONFIG_PROC_FS */
1262 unregister_sysctl_table(s390dbf_sysctl_header
);
1267 * module definitions
1269 core_initcall(debug_init
);
1270 module_exit(debug_exit
);
1271 MODULE_LICENSE("GPL");
1273 EXPORT_SYMBOL(debug_register
);
1274 EXPORT_SYMBOL(debug_unregister
);
1275 EXPORT_SYMBOL(debug_set_level
);
1276 EXPORT_SYMBOL(debug_stop_all
);
1277 EXPORT_SYMBOL(debug_register_view
);
1278 EXPORT_SYMBOL(debug_unregister_view
);
1279 EXPORT_SYMBOL(debug_event_common
);
1280 EXPORT_SYMBOL(debug_exception_common
);
1281 EXPORT_SYMBOL(debug_hex_ascii_view
);
1282 EXPORT_SYMBOL(debug_raw_view
);
1283 EXPORT_SYMBOL(debug_dflt_header_fn
);
1284 EXPORT_SYMBOL(debug_sprintf_view
);
1285 EXPORT_SYMBOL(debug_sprintf_exception
);
1286 EXPORT_SYMBOL(debug_sprintf_event
);