aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/debug.c')
-rw-r--r--arch/s390/kernel/debug.c820
1 files changed, 535 insertions, 285 deletions
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index 91f8ce5543d3..960ba6029c3a 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -19,22 +19,27 @@
19#include <linux/sysctl.h> 19#include <linux/sysctl.h>
20#include <asm/uaccess.h> 20#include <asm/uaccess.h>
21#include <asm/semaphore.h> 21#include <asm/semaphore.h>
22
23#include <linux/module.h> 22#include <linux/module.h>
24#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/fs.h>
25#include <linux/debugfs.h>
25 26
26#include <asm/debug.h> 27#include <asm/debug.h>
27 28
28#define DEBUG_PROLOG_ENTRY -1 29#define DEBUG_PROLOG_ENTRY -1
29 30
31#define ALL_AREAS 0 /* copy all debug areas */
32#define NO_AREAS 1 /* copy no debug areas */
33
30/* typedefs */ 34/* typedefs */
31 35
32typedef struct file_private_info { 36typedef struct file_private_info {
33 loff_t offset; /* offset of last read in file */ 37 loff_t offset; /* offset of last read in file */
34 int act_area; /* number of last formated area */ 38 int act_area; /* number of last formated area */
39 int act_page; /* act page in given area */
35 int act_entry; /* last formated entry (offset */ 40 int act_entry; /* last formated entry (offset */
36 /* relative to beginning of last */ 41 /* relative to beginning of last */
37 /* formated area) */ 42 /* formated page) */
38 size_t act_entry_offset; /* up to this offset we copied */ 43 size_t act_entry_offset; /* up to this offset we copied */
39 /* in last read the last formated */ 44 /* in last read the last formated */
40 /* entry to userland */ 45 /* entry to userland */
@@ -51,8 +56,8 @@ typedef struct
51 * This assumes that all args are converted into longs 56 * This assumes that all args are converted into longs
52 * on L/390 this is the case for all types of parameter 57 * on L/390 this is the case for all types of parameter
53 * except of floats, and long long (32 bit) 58 * except of floats, and long long (32 bit)
54 * 59 *
55 */ 60 */
56 long args[0]; 61 long args[0];
57} debug_sprintf_entry_t; 62} debug_sprintf_entry_t;
58 63
@@ -63,32 +68,38 @@ extern void tod_to_timeval(uint64_t todval, struct timeval *xtime);
63 68
64static int debug_init(void); 69static int debug_init(void);
65static ssize_t debug_output(struct file *file, char __user *user_buf, 70static ssize_t debug_output(struct file *file, char __user *user_buf,
66 size_t user_len, loff_t * offset); 71 size_t user_len, loff_t * offset);
67static ssize_t debug_input(struct file *file, const char __user *user_buf, 72static ssize_t debug_input(struct file *file, const char __user *user_buf,
68 size_t user_len, loff_t * offset); 73 size_t user_len, loff_t * offset);
69static int debug_open(struct inode *inode, struct file *file); 74static int debug_open(struct inode *inode, struct file *file);
70static int debug_close(struct inode *inode, struct file *file); 75static int debug_close(struct inode *inode, struct file *file);
71static debug_info_t* debug_info_create(char *name, int page_order, int nr_areas, int buf_size); 76static debug_info_t* debug_info_create(char *name, int pages_per_area,
77 int nr_areas, int buf_size);
72static void debug_info_get(debug_info_t *); 78static void debug_info_get(debug_info_t *);
73static void debug_info_put(debug_info_t *); 79static void debug_info_put(debug_info_t *);
74static int debug_prolog_level_fn(debug_info_t * id, 80static int debug_prolog_level_fn(debug_info_t * id,
75 struct debug_view *view, char *out_buf); 81 struct debug_view *view, char *out_buf);
76static int debug_input_level_fn(debug_info_t * id, struct debug_view *view, 82static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
77 struct file *file, const char __user *user_buf, 83 struct file *file, const char __user *user_buf,
78 size_t user_buf_size, loff_t * offset); 84 size_t user_buf_size, loff_t * offset);
85static int debug_prolog_pages_fn(debug_info_t * id,
86 struct debug_view *view, char *out_buf);
87static int debug_input_pages_fn(debug_info_t * id, struct debug_view *view,
88 struct file *file, const char __user *user_buf,
89 size_t user_buf_size, loff_t * offset);
79static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, 90static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
80 struct file *file, const char __user *user_buf, 91 struct file *file, const char __user *user_buf,
81 size_t user_buf_size, loff_t * offset); 92 size_t user_buf_size, loff_t * offset);
82static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, 93static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
83 char *out_buf, const char *in_buf); 94 char *out_buf, const char *in_buf);
84static int debug_raw_format_fn(debug_info_t * id, 95static int debug_raw_format_fn(debug_info_t * id,
85 struct debug_view *view, char *out_buf, 96 struct debug_view *view, char *out_buf,
86 const char *in_buf); 97 const char *in_buf);
87static int debug_raw_header_fn(debug_info_t * id, struct debug_view *view, 98static int debug_raw_header_fn(debug_info_t * id, struct debug_view *view,
88 int area, debug_entry_t * entry, char *out_buf); 99 int area, debug_entry_t * entry, char *out_buf);
89 100
90static int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view, 101static int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view,
91 char *out_buf, debug_sprintf_entry_t *curr_event); 102 char *out_buf, debug_sprintf_entry_t *curr_event);
92 103
93/* globals */ 104/* globals */
94 105
@@ -119,6 +130,15 @@ struct debug_view debug_level_view = {
119 NULL 130 NULL
120}; 131};
121 132
133struct debug_view debug_pages_view = {
134 "pages",
135 &debug_prolog_pages_fn,
136 NULL,
137 NULL,
138 &debug_input_pages_fn,
139 NULL
140};
141
122struct debug_view debug_flush_view = { 142struct debug_view debug_flush_view = {
123 "flush", 143 "flush",
124 NULL, 144 NULL,
@@ -149,98 +169,161 @@ DECLARE_MUTEX(debug_lock);
149static int initialized; 169static int initialized;
150 170
151static struct file_operations debug_file_ops = { 171static struct file_operations debug_file_ops = {
152 .owner = THIS_MODULE, 172 .owner = THIS_MODULE,
153 .read = debug_output, 173 .read = debug_output,
154 .write = debug_input, 174 .write = debug_input,
155 .open = debug_open, 175 .open = debug_open,
156 .release = debug_close, 176 .release = debug_close,
157}; 177};
158 178
159static struct proc_dir_entry *debug_proc_root_entry; 179static struct dentry *debug_debugfs_root_entry;
160 180
161/* functions */ 181/* functions */
162 182
163/* 183/*
184 * debug_areas_alloc
185 * - Debug areas are implemented as a threedimensonal array:
186 * areas[areanumber][pagenumber][pageoffset]
187 */
188
189static debug_entry_t***
190debug_areas_alloc(int pages_per_area, int nr_areas)
191{
192 debug_entry_t*** areas;
193 int i,j;
194
195 areas = (debug_entry_t ***) kmalloc(nr_areas *
196 sizeof(debug_entry_t**),
197 GFP_KERNEL);
198 if (!areas)
199 goto fail_malloc_areas;
200 for (i = 0; i < nr_areas; i++) {
201 areas[i] = (debug_entry_t**) kmalloc(pages_per_area *
202 sizeof(debug_entry_t*),GFP_KERNEL);
203 if (!areas[i]) {
204 goto fail_malloc_areas2;
205 }
206 for(j = 0; j < pages_per_area; j++) {
207 areas[i][j] = (debug_entry_t*)kmalloc(PAGE_SIZE,
208 GFP_KERNEL);
209 if(!areas[i][j]) {
210 for(j--; j >=0 ; j--) {
211 kfree(areas[i][j]);
212 }
213 kfree(areas[i]);
214 goto fail_malloc_areas2;
215 } else {
216 memset(areas[i][j],0,PAGE_SIZE);
217 }
218 }
219 }
220 return areas;
221
222fail_malloc_areas2:
223 for(i--; i >= 0; i--){
224 for(j=0; j < pages_per_area;j++){
225 kfree(areas[i][j]);
226 }
227 kfree(areas[i]);
228 }
229 kfree(areas);
230fail_malloc_areas:
231 return NULL;
232
233}
234
235
236/*
164 * debug_info_alloc 237 * debug_info_alloc
165 * - alloc new debug-info 238 * - alloc new debug-info
166 */ 239 */
167 240
168static debug_info_t* debug_info_alloc(char *name, int page_order, 241static debug_info_t*
169 int nr_areas, int buf_size) 242debug_info_alloc(char *name, int pages_per_area, int nr_areas, int buf_size,
243 int level, int mode)
170{ 244{
171 debug_info_t* rc; 245 debug_info_t* rc;
172 int i;
173 246
174 /* alloc everything */ 247 /* alloc everything */
175 248
176 rc = (debug_info_t*) kmalloc(sizeof(debug_info_t), GFP_ATOMIC); 249 rc = (debug_info_t*) kmalloc(sizeof(debug_info_t), GFP_KERNEL);
177 if(!rc) 250 if(!rc)
178 goto fail_malloc_rc; 251 goto fail_malloc_rc;
179 rc->active_entry = (int*)kmalloc(nr_areas * sizeof(int), GFP_ATOMIC); 252 rc->active_entries = (int*)kmalloc(nr_areas * sizeof(int), GFP_KERNEL);
180 if(!rc->active_entry) 253 if(!rc->active_entries)
181 goto fail_malloc_active_entry; 254 goto fail_malloc_active_entries;
182 memset(rc->active_entry, 0, nr_areas * sizeof(int)); 255 memset(rc->active_entries, 0, nr_areas * sizeof(int));
183 rc->areas = (debug_entry_t **) kmalloc(nr_areas * 256 rc->active_pages = (int*)kmalloc(nr_areas * sizeof(int), GFP_KERNEL);
184 sizeof(debug_entry_t *), 257 if(!rc->active_pages)
185 GFP_ATOMIC); 258 goto fail_malloc_active_pages;
186 if (!rc->areas) 259 memset(rc->active_pages, 0, nr_areas * sizeof(int));
187 goto fail_malloc_areas; 260 if((mode == ALL_AREAS) && (pages_per_area != 0)){
188 for (i = 0; i < nr_areas; i++) { 261 rc->areas = debug_areas_alloc(pages_per_area, nr_areas);
189 rc->areas[i] = (debug_entry_t *) __get_free_pages(GFP_ATOMIC, 262 if(!rc->areas)
190 page_order); 263 goto fail_malloc_areas;
191 if (!rc->areas[i]) { 264 } else {
192 for (i--; i >= 0; i--) { 265 rc->areas = NULL;
193 free_pages((unsigned long) rc->areas[i],
194 page_order);
195 }
196 goto fail_malloc_areas2;
197 } else {
198 memset(rc->areas[i], 0, PAGE_SIZE << page_order);
199 }
200 } 266 }
201 267
202 /* initialize members */ 268 /* initialize members */
203 269
204 spin_lock_init(&rc->lock); 270 spin_lock_init(&rc->lock);
205 rc->page_order = page_order; 271 rc->pages_per_area = pages_per_area;
206 rc->nr_areas = nr_areas; 272 rc->nr_areas = nr_areas;
207 rc->active_area = 0; 273 rc->active_area = 0;
208 rc->level = DEBUG_DEFAULT_LEVEL; 274 rc->level = level;
209 rc->buf_size = buf_size; 275 rc->buf_size = buf_size;
210 rc->entry_size = sizeof(debug_entry_t) + buf_size; 276 rc->entry_size = sizeof(debug_entry_t) + buf_size;
211 strlcpy(rc->name, name, sizeof(rc->name)); 277 strlcpy(rc->name, name, sizeof(rc->name)-1);
212 memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *)); 278 memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *));
213#ifdef CONFIG_PROC_FS 279 memset(rc->debugfs_entries, 0 ,DEBUG_MAX_VIEWS *
214 memset(rc->proc_entries, 0 ,DEBUG_MAX_VIEWS * 280 sizeof(struct dentry*));
215 sizeof(struct proc_dir_entry*));
216#endif /* CONFIG_PROC_FS */
217 atomic_set(&(rc->ref_count), 0); 281 atomic_set(&(rc->ref_count), 0);
218 282
219 return rc; 283 return rc;
220 284
221fail_malloc_areas2:
222 kfree(rc->areas);
223fail_malloc_areas: 285fail_malloc_areas:
224 kfree(rc->active_entry); 286 kfree(rc->active_pages);
225fail_malloc_active_entry: 287fail_malloc_active_pages:
288 kfree(rc->active_entries);
289fail_malloc_active_entries:
226 kfree(rc); 290 kfree(rc);
227fail_malloc_rc: 291fail_malloc_rc:
228 return NULL; 292 return NULL;
229} 293}
230 294
231/* 295/*
232 * debug_info_free 296 * debug_areas_free
233 * - free memory debug-info 297 * - free all debug areas
234 */ 298 */
235 299
236static void debug_info_free(debug_info_t* db_info){ 300static void
237 int i; 301debug_areas_free(debug_info_t* db_info)
302{
303 int i,j;
304
305 if(!db_info->areas)
306 return;
238 for (i = 0; i < db_info->nr_areas; i++) { 307 for (i = 0; i < db_info->nr_areas; i++) {
239 free_pages((unsigned long) db_info->areas[i], 308 for(j = 0; j < db_info->pages_per_area; j++) {
240 db_info->page_order); 309 kfree(db_info->areas[i][j]);
310 }
311 kfree(db_info->areas[i]);
241 } 312 }
242 kfree(db_info->areas); 313 kfree(db_info->areas);
243 kfree(db_info->active_entry); 314 db_info->areas = NULL;
315}
316
317/*
318 * debug_info_free
319 * - free memory debug-info
320 */
321
322static void
323debug_info_free(debug_info_t* db_info){
324 debug_areas_free(db_info);
325 kfree(db_info->active_entries);
326 kfree(db_info->active_pages);
244 kfree(db_info); 327 kfree(db_info);
245} 328}
246 329
@@ -249,21 +332,22 @@ static void debug_info_free(debug_info_t* db_info){
249 * - create new debug-info 332 * - create new debug-info
250 */ 333 */
251 334
252static debug_info_t* debug_info_create(char *name, int page_order, 335static debug_info_t*
253 int nr_areas, int buf_size) 336debug_info_create(char *name, int pages_per_area, int nr_areas, int buf_size)
254{ 337{
255 debug_info_t* rc; 338 debug_info_t* rc;
256 339
257 rc = debug_info_alloc(name, page_order, nr_areas, buf_size); 340 rc = debug_info_alloc(name, pages_per_area, nr_areas, buf_size,
341 DEBUG_DEFAULT_LEVEL, ALL_AREAS);
258 if(!rc) 342 if(!rc)
259 goto out; 343 goto out;
260 344
261 345 /* create root directory */
262 /* create proc rood directory */ 346 rc->debugfs_root_entry = debugfs_create_dir(rc->name,
263 rc->proc_root_entry = proc_mkdir(rc->name, debug_proc_root_entry); 347 debug_debugfs_root_entry);
264 348
265 /* append new element to linked list */ 349 /* append new element to linked list */
266 if (debug_area_first == NULL) { 350 if (!debug_area_first) {
267 /* first element in list */ 351 /* first element in list */
268 debug_area_first = rc; 352 debug_area_first = rc;
269 rc->prev = NULL; 353 rc->prev = NULL;
@@ -285,17 +369,21 @@ out:
285 * - copy debug-info 369 * - copy debug-info
286 */ 370 */
287 371
288static debug_info_t* debug_info_copy(debug_info_t* in) 372static debug_info_t*
373debug_info_copy(debug_info_t* in, int mode)
289{ 374{
290 int i; 375 int i,j;
291 debug_info_t* rc; 376 debug_info_t* rc;
292 rc = debug_info_alloc(in->name, in->page_order, 377
293 in->nr_areas, in->buf_size); 378 rc = debug_info_alloc(in->name, in->pages_per_area, in->nr_areas,
294 if(!rc) 379 in->buf_size, in->level, mode);
380 if(!rc || (mode == NO_AREAS))
295 goto out; 381 goto out;
296 382
297 for(i = 0; i < in->nr_areas; i++){ 383 for(i = 0; i < in->nr_areas; i++){
298 memcpy(rc->areas[i],in->areas[i], PAGE_SIZE << in->page_order); 384 for(j = 0; j < in->pages_per_area; j++) {
385 memcpy(rc->areas[i][j], in->areas[i][j],PAGE_SIZE);
386 }
299 } 387 }
300out: 388out:
301 return rc; 389 return rc;
@@ -306,7 +394,8 @@ out:
306 * - increments reference count for debug-info 394 * - increments reference count for debug-info
307 */ 395 */
308 396
309static void debug_info_get(debug_info_t * db_info) 397static void
398debug_info_get(debug_info_t * db_info)
310{ 399{
311 if (db_info) 400 if (db_info)
312 atomic_inc(&db_info->ref_count); 401 atomic_inc(&db_info->ref_count);
@@ -317,29 +406,20 @@ static void debug_info_get(debug_info_t * db_info)
317 * - decreases reference count for debug-info and frees it if necessary 406 * - decreases reference count for debug-info and frees it if necessary
318 */ 407 */
319 408
320static void debug_info_put(debug_info_t *db_info) 409static void
410debug_info_put(debug_info_t *db_info)
321{ 411{
322 int i; 412 int i;
323 413
324 if (!db_info) 414 if (!db_info)
325 return; 415 return;
326 if (atomic_dec_and_test(&db_info->ref_count)) { 416 if (atomic_dec_and_test(&db_info->ref_count)) {
327#ifdef DEBUG
328 printk(KERN_INFO "debug: freeing debug area %p (%s)\n",
329 db_info, db_info->name);
330#endif
331 for (i = 0; i < DEBUG_MAX_VIEWS; i++) { 417 for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
332 if (db_info->views[i] == NULL) 418 if (!db_info->views[i])
333 continue; 419 continue;
334#ifdef CONFIG_PROC_FS 420 debugfs_remove(db_info->debugfs_entries[i]);
335 remove_proc_entry(db_info->proc_entries[i]->name,
336 db_info->proc_root_entry);
337#endif
338 } 421 }
339#ifdef CONFIG_PROC_FS 422 debugfs_remove(db_info->debugfs_root_entry);
340 remove_proc_entry(db_info->proc_root_entry->name,
341 debug_proc_root_entry);
342#endif
343 if(db_info == debug_area_first) 423 if(db_info == debug_area_first)
344 debug_area_first = db_info->next; 424 debug_area_first = db_info->next;
345 if(db_info == debug_area_last) 425 if(db_info == debug_area_last)
@@ -355,9 +435,9 @@ static void debug_info_put(debug_info_t *db_info)
355 * - format one debug entry and return size of formated data 435 * - format one debug entry and return size of formated data
356 */ 436 */
357 437
358static int debug_format_entry(file_private_info_t *p_info) 438static int
439debug_format_entry(file_private_info_t *p_info)
359{ 440{
360 debug_info_t *id_org = p_info->debug_info_org;
361 debug_info_t *id_snap = p_info->debug_info_snap; 441 debug_info_t *id_snap = p_info->debug_info_snap;
362 struct debug_view *view = p_info->view; 442 struct debug_view *view = p_info->view;
363 debug_entry_t *act_entry; 443 debug_entry_t *act_entry;
@@ -365,22 +445,23 @@ static int debug_format_entry(file_private_info_t *p_info)
365 if(p_info->act_entry == DEBUG_PROLOG_ENTRY){ 445 if(p_info->act_entry == DEBUG_PROLOG_ENTRY){
366 /* print prolog */ 446 /* print prolog */
367 if (view->prolog_proc) 447 if (view->prolog_proc)
368 len += view->prolog_proc(id_org, view,p_info->temp_buf); 448 len += view->prolog_proc(id_snap,view,p_info->temp_buf);
369 goto out; 449 goto out;
370 } 450 }
371 451 if (!id_snap->areas) /* this is true, if we have a prolog only view */
372 act_entry = (debug_entry_t *) ((char*)id_snap->areas[p_info->act_area] + 452 goto out; /* or if 'pages_per_area' is 0 */
373 p_info->act_entry); 453 act_entry = (debug_entry_t *) ((char*)id_snap->areas[p_info->act_area]
454 [p_info->act_page] + p_info->act_entry);
374 455
375 if (act_entry->id.stck == 0LL) 456 if (act_entry->id.stck == 0LL)
376 goto out; /* empty entry */ 457 goto out; /* empty entry */
377 if (view->header_proc) 458 if (view->header_proc)
378 len += view->header_proc(id_org, view, p_info->act_area, 459 len += view->header_proc(id_snap, view, p_info->act_area,
379 act_entry, p_info->temp_buf + len); 460 act_entry, p_info->temp_buf + len);
380 if (view->format_proc) 461 if (view->format_proc)
381 len += view->format_proc(id_org, view, p_info->temp_buf + len, 462 len += view->format_proc(id_snap, view, p_info->temp_buf + len,
382 DEBUG_DATA(act_entry)); 463 DEBUG_DATA(act_entry));
383 out: 464out:
384 return len; 465 return len;
385} 466}
386 467
@@ -389,20 +470,30 @@ static int debug_format_entry(file_private_info_t *p_info)
389 * - goto next entry in p_info 470 * - goto next entry in p_info
390 */ 471 */
391 472
392extern inline int debug_next_entry(file_private_info_t *p_info) 473extern inline int
474debug_next_entry(file_private_info_t *p_info)
393{ 475{
394 debug_info_t *id = p_info->debug_info_snap; 476 debug_info_t *id;
477
478 id = p_info->debug_info_snap;
395 if(p_info->act_entry == DEBUG_PROLOG_ENTRY){ 479 if(p_info->act_entry == DEBUG_PROLOG_ENTRY){
396 p_info->act_entry = 0; 480 p_info->act_entry = 0;
481 p_info->act_page = 0;
397 goto out; 482 goto out;
398 } 483 }
399 if ((p_info->act_entry += id->entry_size) 484 if(!id->areas)
400 > ((PAGE_SIZE << (id->page_order)) 485 return 1;
401 - id->entry_size)){ 486 p_info->act_entry += id->entry_size;
402 487 /* switch to next page, if we reached the end of the page */
403 /* next area */ 488 if (p_info->act_entry > (PAGE_SIZE - id->entry_size)){
489 /* next page */
404 p_info->act_entry = 0; 490 p_info->act_entry = 0;
405 p_info->act_area++; 491 p_info->act_page += 1;
492 if((p_info->act_page % id->pages_per_area) == 0) {
493 /* next area */
494 p_info->act_area++;
495 p_info->act_page=0;
496 }
406 if(p_info->act_area >= id->nr_areas) 497 if(p_info->act_area >= id->nr_areas)
407 return 1; 498 return 1;
408 } 499 }
@@ -416,13 +507,14 @@ out:
416 * - copies formated debug entries to the user buffer 507 * - copies formated debug entries to the user buffer
417 */ 508 */
418 509
419static ssize_t debug_output(struct file *file, /* file descriptor */ 510static ssize_t
420 char __user *user_buf, /* user buffer */ 511debug_output(struct file *file, /* file descriptor */
421 size_t len, /* length of buffer */ 512 char __user *user_buf, /* user buffer */
422 loff_t *offset) /* offset in the file */ 513 size_t len, /* length of buffer */
514 loff_t *offset) /* offset in the file */
423{ 515{
424 size_t count = 0; 516 size_t count = 0;
425 size_t entry_offset, size = 0; 517 size_t entry_offset;
426 file_private_info_t *p_info; 518 file_private_info_t *p_info;
427 519
428 p_info = ((file_private_info_t *) file->private_data); 520 p_info = ((file_private_info_t *) file->private_data);
@@ -430,27 +522,33 @@ static ssize_t debug_output(struct file *file, /* file descriptor */
430 return -EPIPE; 522 return -EPIPE;
431 if(p_info->act_area >= p_info->debug_info_snap->nr_areas) 523 if(p_info->act_area >= p_info->debug_info_snap->nr_areas)
432 return 0; 524 return 0;
433
434 entry_offset = p_info->act_entry_offset; 525 entry_offset = p_info->act_entry_offset;
435
436 while(count < len){ 526 while(count < len){
437 size = debug_format_entry(p_info); 527 int formatted_line_size;
438 size = min((len - count), (size - entry_offset)); 528 int formatted_line_residue;
439 529 int user_buf_residue;
440 if(size){ 530 size_t copy_size;
441 if (copy_to_user(user_buf + count, 531
442 p_info->temp_buf + entry_offset, size)) 532 formatted_line_size = debug_format_entry(p_info);
443 return -EFAULT; 533 formatted_line_residue = formatted_line_size - entry_offset;
534 user_buf_residue = len-count;
535 copy_size = min(user_buf_residue, formatted_line_residue);
536 if(copy_size){
537 if (copy_to_user(user_buf + count, p_info->temp_buf
538 + entry_offset, copy_size))
539 return -EFAULT;
540 count += copy_size;
541 entry_offset += copy_size;
444 } 542 }
445 count += size; 543 if(copy_size == formatted_line_residue){
446 entry_offset = 0; 544 entry_offset = 0;
447 if(count != len) 545 if(debug_next_entry(p_info))
448 if(debug_next_entry(p_info))
449 goto out; 546 goto out;
547 }
450 } 548 }
451out: 549out:
452 p_info->offset = *offset + count; 550 p_info->offset = *offset + count;
453 p_info->act_entry_offset = size; 551 p_info->act_entry_offset = entry_offset;
454 *offset = p_info->offset; 552 *offset = p_info->offset;
455 return count; 553 return count;
456} 554}
@@ -461,9 +559,9 @@ out:
461 * - calls input function of view 559 * - calls input function of view
462 */ 560 */
463 561
464static ssize_t debug_input(struct file *file, 562static ssize_t
465 const char __user *user_buf, size_t length, 563debug_input(struct file *file, const char __user *user_buf, size_t length,
466 loff_t *offset) 564 loff_t *offset)
467{ 565{
468 int rc = 0; 566 int rc = 0;
469 file_private_info_t *p_info; 567 file_private_info_t *p_info;
@@ -487,26 +585,23 @@ static ssize_t debug_input(struct file *file,
487 * handle 585 * handle
488 */ 586 */
489 587
490static int debug_open(struct inode *inode, struct file *file) 588static int
589debug_open(struct inode *inode, struct file *file)
491{ 590{
492 int i = 0, rc = 0; 591 int i = 0, rc = 0;
493 file_private_info_t *p_info; 592 file_private_info_t *p_info;
494 debug_info_t *debug_info, *debug_info_snapshot; 593 debug_info_t *debug_info, *debug_info_snapshot;
495 594
496#ifdef DEBUG
497 printk("debug_open\n");
498#endif
499 down(&debug_lock); 595 down(&debug_lock);
500 596
501 /* find debug log and view */ 597 /* find debug log and view */
502
503 debug_info = debug_area_first; 598 debug_info = debug_area_first;
504 while(debug_info != NULL){ 599 while(debug_info != NULL){
505 for (i = 0; i < DEBUG_MAX_VIEWS; i++) { 600 for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
506 if (debug_info->views[i] == NULL) 601 if (!debug_info->views[i])
507 continue; 602 continue;
508 else if (debug_info->proc_entries[i] == 603 else if (debug_info->debugfs_entries[i] ==
509 PDE(file->f_dentry->d_inode)) { 604 file->f_dentry) {
510 goto found; /* found view ! */ 605 goto found; /* found view ! */
511 } 606 }
512 } 607 }
@@ -516,41 +611,42 @@ static int debug_open(struct inode *inode, struct file *file)
516 rc = -EINVAL; 611 rc = -EINVAL;
517 goto out; 612 goto out;
518 613
519 found: 614found:
520 615
521 /* make snapshot of current debug areas to get it consistent */ 616 /* Make snapshot of current debug areas to get it consistent. */
617 /* To copy all the areas is only needed, if we have a view which */
618 /* formats the debug areas. */
522 619
523 debug_info_snapshot = debug_info_copy(debug_info); 620 if(!debug_info->views[i]->format_proc &&
621 !debug_info->views[i]->header_proc){
622 debug_info_snapshot = debug_info_copy(debug_info, NO_AREAS);
623 } else {
624 debug_info_snapshot = debug_info_copy(debug_info, ALL_AREAS);
625 }
524 626
525 if(!debug_info_snapshot){ 627 if(!debug_info_snapshot){
526#ifdef DEBUG
527 printk(KERN_ERR "debug_open: debug_info_copy failed (out of mem)\n");
528#endif
529 rc = -ENOMEM; 628 rc = -ENOMEM;
530 goto out; 629 goto out;
531 } 630 }
532 631 p_info = (file_private_info_t *) kmalloc(sizeof(file_private_info_t),
533 if ((file->private_data = 632 GFP_KERNEL);
534 kmalloc(sizeof(file_private_info_t), GFP_ATOMIC)) == 0) { 633 if(!p_info){
535#ifdef DEBUG 634 if(debug_info_snapshot)
536 printk(KERN_ERR "debug_open: kmalloc failed\n"); 635 debug_info_free(debug_info_snapshot);
537#endif
538 debug_info_free(debug_info_snapshot);
539 rc = -ENOMEM; 636 rc = -ENOMEM;
540 goto out; 637 goto out;
541 } 638 }
542 p_info = (file_private_info_t *) file->private_data;
543 p_info->offset = 0; 639 p_info->offset = 0;
544 p_info->debug_info_snap = debug_info_snapshot; 640 p_info->debug_info_snap = debug_info_snapshot;
545 p_info->debug_info_org = debug_info; 641 p_info->debug_info_org = debug_info;
546 p_info->view = debug_info->views[i]; 642 p_info->view = debug_info->views[i];
547 p_info->act_area = 0; 643 p_info->act_area = 0;
644 p_info->act_page = 0;
548 p_info->act_entry = DEBUG_PROLOG_ENTRY; 645 p_info->act_entry = DEBUG_PROLOG_ENTRY;
549 p_info->act_entry_offset = 0; 646 p_info->act_entry_offset = 0;
550 647 file->private_data = p_info;
551 debug_info_get(debug_info); 648 debug_info_get(debug_info);
552 649out:
553 out:
554 up(&debug_lock); 650 up(&debug_lock);
555 return rc; 651 return rc;
556} 652}
@@ -561,14 +657,13 @@ static int debug_open(struct inode *inode, struct file *file)
561 * - deletes private_data area of the file handle 657 * - deletes private_data area of the file handle
562 */ 658 */
563 659
564static int debug_close(struct inode *inode, struct file *file) 660static int
661debug_close(struct inode *inode, struct file *file)
565{ 662{
566 file_private_info_t *p_info; 663 file_private_info_t *p_info;
567#ifdef DEBUG
568 printk("debug_close\n");
569#endif
570 p_info = (file_private_info_t *) file->private_data; 664 p_info = (file_private_info_t *) file->private_data;
571 debug_info_free(p_info->debug_info_snap); 665 if(p_info->debug_info_snap)
666 debug_info_free(p_info->debug_info_snap);
572 debug_info_put(p_info->debug_info_org); 667 debug_info_put(p_info->debug_info_org);
573 kfree(file->private_data); 668 kfree(file->private_data);
574 return 0; /* success */ 669 return 0; /* success */
@@ -580,8 +675,8 @@ static int debug_close(struct inode *inode, struct file *file)
580 * - returns handle for debug area 675 * - returns handle for debug area
581 */ 676 */
582 677
583debug_info_t *debug_register 678debug_info_t*
584 (char *name, int page_order, int nr_areas, int buf_size) 679debug_register (char *name, int pages_per_area, int nr_areas, int buf_size)
585{ 680{
586 debug_info_t *rc = NULL; 681 debug_info_t *rc = NULL;
587 682
@@ -591,18 +686,14 @@ debug_info_t *debug_register
591 686
592 /* create new debug_info */ 687 /* create new debug_info */
593 688
594 rc = debug_info_create(name, page_order, nr_areas, buf_size); 689 rc = debug_info_create(name, pages_per_area, nr_areas, buf_size);
595 if(!rc) 690 if(!rc)
596 goto out; 691 goto out;
597 debug_register_view(rc, &debug_level_view); 692 debug_register_view(rc, &debug_level_view);
598 debug_register_view(rc, &debug_flush_view); 693 debug_register_view(rc, &debug_flush_view);
599#ifdef DEBUG 694 debug_register_view(rc, &debug_pages_view);
600 printk(KERN_INFO 695out:
601 "debug: reserved %d areas of %d pages for debugging %s\n", 696 if (!rc){
602 nr_areas, 1 << page_order, rc->name);
603#endif
604 out:
605 if (rc == NULL){
606 printk(KERN_ERR "debug: debug_register failed for %s\n",name); 697 printk(KERN_ERR "debug: debug_register failed for %s\n",name);
607 } 698 }
608 up(&debug_lock); 699 up(&debug_lock);
@@ -614,27 +705,65 @@ debug_info_t *debug_register
614 * - give back debug area 705 * - give back debug area
615 */ 706 */
616 707
617void debug_unregister(debug_info_t * id) 708void
709debug_unregister(debug_info_t * id)
618{ 710{
619 if (!id) 711 if (!id)
620 goto out; 712 goto out;
621 down(&debug_lock); 713 down(&debug_lock);
622#ifdef DEBUG
623 printk(KERN_INFO "debug: unregistering %s\n", id->name);
624#endif
625 debug_info_put(id); 714 debug_info_put(id);
626 up(&debug_lock); 715 up(&debug_lock);
627 716
628 out: 717out:
629 return; 718 return;
630} 719}
631 720
632/* 721/*
722 * debug_set_size:
723 * - set area size (number of pages) and number of areas
724 */
725static int
726debug_set_size(debug_info_t* id, int nr_areas, int pages_per_area)
727{
728 unsigned long flags;
729 debug_entry_t *** new_areas;
730 int rc=0;
731
732 if(!id || (nr_areas <= 0) || (pages_per_area < 0))
733 return -EINVAL;
734 if(pages_per_area > 0){
735 new_areas = debug_areas_alloc(pages_per_area, nr_areas);
736 if(!new_areas) {
737 printk(KERN_WARNING "debug: could not allocate memory "\
738 "for pagenumber: %i\n",pages_per_area);
739 rc = -ENOMEM;
740 goto out;
741 }
742 } else {
743 new_areas = NULL;
744 }
745 spin_lock_irqsave(&id->lock,flags);
746 debug_areas_free(id);
747 id->areas = new_areas;
748 id->nr_areas = nr_areas;
749 id->pages_per_area = pages_per_area;
750 id->active_area = 0;
751 memset(id->active_entries,0,sizeof(int)*id->nr_areas);
752 memset(id->active_pages, 0, sizeof(int)*id->nr_areas);
753 spin_unlock_irqrestore(&id->lock,flags);
754 printk(KERN_INFO "debug: %s: set new size (%i pages)\n"\
755 ,id->name, pages_per_area);
756out:
757 return rc;
758}
759
760/*
633 * debug_set_level: 761 * debug_set_level:
634 * - set actual debug level 762 * - set actual debug level
635 */ 763 */
636 764
637void debug_set_level(debug_info_t* id, int new_level) 765void
766debug_set_level(debug_info_t* id, int new_level)
638{ 767{
639 unsigned long flags; 768 unsigned long flags;
640 if(!id) 769 if(!id)
@@ -649,10 +778,6 @@ void debug_set_level(debug_info_t* id, int new_level)
649 id->name, new_level, 0, DEBUG_MAX_LEVEL); 778 id->name, new_level, 0, DEBUG_MAX_LEVEL);
650 } else { 779 } else {
651 id->level = new_level; 780 id->level = new_level;
652#ifdef DEBUG
653 printk(KERN_INFO
654 "debug: %s: new level %i\n",id->name,id->level);
655#endif
656 } 781 }
657 spin_unlock_irqrestore(&id->lock,flags); 782 spin_unlock_irqrestore(&id->lock,flags);
658} 783}
@@ -663,11 +788,16 @@ void debug_set_level(debug_info_t* id, int new_level)
663 * - set active entry to next in the ring buffer 788 * - set active entry to next in the ring buffer
664 */ 789 */
665 790
666extern inline void proceed_active_entry(debug_info_t * id) 791extern inline void
792proceed_active_entry(debug_info_t * id)
667{ 793{
668 if ((id->active_entry[id->active_area] += id->entry_size) 794 if ((id->active_entries[id->active_area] += id->entry_size)
669 > ((PAGE_SIZE << (id->page_order)) - id->entry_size)) 795 > (PAGE_SIZE - id->entry_size)){
670 id->active_entry[id->active_area] = 0; 796 id->active_entries[id->active_area] = 0;
797 id->active_pages[id->active_area] =
798 (id->active_pages[id->active_area] + 1) %
799 id->pages_per_area;
800 }
671} 801}
672 802
673/* 803/*
@@ -675,7 +805,8 @@ extern inline void proceed_active_entry(debug_info_t * id)
675 * - set active area to next in the ring buffer 805 * - set active area to next in the ring buffer
676 */ 806 */
677 807
678extern inline void proceed_active_area(debug_info_t * id) 808extern inline void
809proceed_active_area(debug_info_t * id)
679{ 810{
680 id->active_area++; 811 id->active_area++;
681 id->active_area = id->active_area % id->nr_areas; 812 id->active_area = id->active_area % id->nr_areas;
@@ -685,10 +816,12 @@ extern inline void proceed_active_area(debug_info_t * id)
685 * get_active_entry: 816 * get_active_entry:
686 */ 817 */
687 818
688extern inline debug_entry_t *get_active_entry(debug_info_t * id) 819extern inline debug_entry_t*
820get_active_entry(debug_info_t * id)
689{ 821{
690 return (debug_entry_t *) ((char *) id->areas[id->active_area] + 822 return (debug_entry_t *) (((char *) id->areas[id->active_area]
691 id->active_entry[id->active_area]); 823 [id->active_pages[id->active_area]]) +
824 id->active_entries[id->active_area]);
692} 825}
693 826
694/* 827/*
@@ -696,8 +829,9 @@ extern inline debug_entry_t *get_active_entry(debug_info_t * id)
696 * - set timestamp, caller address, cpu number etc. 829 * - set timestamp, caller address, cpu number etc.
697 */ 830 */
698 831
699extern inline void debug_finish_entry(debug_info_t * id, debug_entry_t* active, 832extern inline void
700 int level, int exception) 833debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level,
834 int exception)
701{ 835{
702 STCK(active->id.stck); 836 STCK(active->id.stck);
703 active->id.fields.cpuid = smp_processor_id(); 837 active->id.fields.cpuid = smp_processor_id();
@@ -721,7 +855,8 @@ static int debug_active=1;
721 * always allow read, allow write only if debug_stoppable is set or 855 * always allow read, allow write only if debug_stoppable is set or
722 * if debug_active is already off 856 * if debug_active is already off
723 */ 857 */
724static int s390dbf_procactive(ctl_table *table, int write, struct file *filp, 858static int
859s390dbf_procactive(ctl_table *table, int write, struct file *filp,
725 void __user *buffer, size_t *lenp, loff_t *ppos) 860 void __user *buffer, size_t *lenp, loff_t *ppos)
726{ 861{
727 if (!write || debug_stoppable || !debug_active) 862 if (!write || debug_stoppable || !debug_active)
@@ -766,7 +901,8 @@ static struct ctl_table s390dbf_dir_table[] = {
766 901
767struct ctl_table_header *s390dbf_sysctl_header; 902struct ctl_table_header *s390dbf_sysctl_header;
768 903
769void debug_stop_all(void) 904void
905debug_stop_all(void)
770{ 906{
771 if (debug_stoppable) 907 if (debug_stoppable)
772 debug_active = 0; 908 debug_active = 0;
@@ -778,13 +914,13 @@ void debug_stop_all(void)
778 * - write debug entry with given size 914 * - write debug entry with given size
779 */ 915 */
780 916
781debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf, 917debug_entry_t*
782 int len) 918debug_event_common(debug_info_t * id, int level, const void *buf, int len)
783{ 919{
784 unsigned long flags; 920 unsigned long flags;
785 debug_entry_t *active; 921 debug_entry_t *active;
786 922
787 if (!debug_active) 923 if (!debug_active || !id->areas)
788 return NULL; 924 return NULL;
789 spin_lock_irqsave(&id->lock, flags); 925 spin_lock_irqsave(&id->lock, flags);
790 active = get_active_entry(id); 926 active = get_active_entry(id);
@@ -801,13 +937,13 @@ debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf,
801 * - write debug entry with given size and switch to next debug area 937 * - write debug entry with given size and switch to next debug area
802 */ 938 */
803 939
804debug_entry_t *debug_exception_common(debug_info_t * id, int level, 940debug_entry_t
805 const void *buf, int len) 941*debug_exception_common(debug_info_t * id, int level, const void *buf, int len)
806{ 942{
807 unsigned long flags; 943 unsigned long flags;
808 debug_entry_t *active; 944 debug_entry_t *active;
809 945
810 if (!debug_active) 946 if (!debug_active || !id->areas)
811 return NULL; 947 return NULL;
812 spin_lock_irqsave(&id->lock, flags); 948 spin_lock_irqsave(&id->lock, flags);
813 active = get_active_entry(id); 949 active = get_active_entry(id);
@@ -823,7 +959,8 @@ debug_entry_t *debug_exception_common(debug_info_t * id, int level,
823 * counts arguments in format string for sprintf view 959 * counts arguments in format string for sprintf view
824 */ 960 */
825 961
826extern inline int debug_count_numargs(char *string) 962extern inline int
963debug_count_numargs(char *string)
827{ 964{
828 int numargs=0; 965 int numargs=0;
829 966
@@ -838,8 +975,8 @@ extern inline int debug_count_numargs(char *string)
838 * debug_sprintf_event: 975 * debug_sprintf_event:
839 */ 976 */
840 977
841debug_entry_t *debug_sprintf_event(debug_info_t* id, 978debug_entry_t*
842 int level,char *string,...) 979debug_sprintf_event(debug_info_t* id, int level,char *string,...)
843{ 980{
844 va_list ap; 981 va_list ap;
845 int numargs,idx; 982 int numargs,idx;
@@ -849,7 +986,7 @@ debug_entry_t *debug_sprintf_event(debug_info_t* id,
849 986
850 if((!id) || (level > id->level)) 987 if((!id) || (level > id->level))
851 return NULL; 988 return NULL;
852 if (!debug_active) 989 if (!debug_active || !id->areas)
853 return NULL; 990 return NULL;
854 numargs=debug_count_numargs(string); 991 numargs=debug_count_numargs(string);
855 992
@@ -871,8 +1008,8 @@ debug_entry_t *debug_sprintf_event(debug_info_t* id,
871 * debug_sprintf_exception: 1008 * debug_sprintf_exception:
872 */ 1009 */
873 1010
874debug_entry_t *debug_sprintf_exception(debug_info_t* id, 1011debug_entry_t*
875 int level,char *string,...) 1012debug_sprintf_exception(debug_info_t* id, int level,char *string,...)
876{ 1013{
877 va_list ap; 1014 va_list ap;
878 int numargs,idx; 1015 int numargs,idx;
@@ -882,7 +1019,7 @@ debug_entry_t *debug_sprintf_exception(debug_info_t* id,
882 1019
883 if((!id) || (level > id->level)) 1020 if((!id) || (level > id->level))
884 return NULL; 1021 return NULL;
885 if (!debug_active) 1022 if (!debug_active || !id->areas)
886 return NULL; 1023 return NULL;
887 1024
888 numargs=debug_count_numargs(string); 1025 numargs=debug_count_numargs(string);
@@ -906,15 +1043,14 @@ debug_entry_t *debug_sprintf_exception(debug_info_t* id,
906 * - is called exactly once to initialize the debug feature 1043 * - is called exactly once to initialize the debug feature
907 */ 1044 */
908 1045
909static int __init debug_init(void) 1046static int
1047__init debug_init(void)
910{ 1048{
911 int rc = 0; 1049 int rc = 0;
912 1050
913 s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table, 1); 1051 s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table, 1);
914 down(&debug_lock); 1052 down(&debug_lock);
915#ifdef CONFIG_PROC_FS 1053 debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL);
916 debug_proc_root_entry = proc_mkdir(DEBUG_DIR_ROOT, NULL);
917#endif /* CONFIG_PROC_FS */
918 printk(KERN_INFO "debug: Initialization complete\n"); 1054 printk(KERN_INFO "debug: Initialization complete\n");
919 initialized = 1; 1055 initialized = 1;
920 up(&debug_lock); 1056 up(&debug_lock);
@@ -926,13 +1062,14 @@ static int __init debug_init(void)
926 * debug_register_view: 1062 * debug_register_view:
927 */ 1063 */
928 1064
929int debug_register_view(debug_info_t * id, struct debug_view *view) 1065int
1066debug_register_view(debug_info_t * id, struct debug_view *view)
930{ 1067{
931 int rc = 0; 1068 int rc = 0;
932 int i; 1069 int i;
933 unsigned long flags; 1070 unsigned long flags;
934 mode_t mode = S_IFREG; 1071 mode_t mode = S_IFREG;
935 struct proc_dir_entry *pde; 1072 struct dentry *pde;
936 1073
937 if (!id) 1074 if (!id)
938 goto out; 1075 goto out;
@@ -940,16 +1077,17 @@ int debug_register_view(debug_info_t * id, struct debug_view *view)
940 mode |= S_IRUSR; 1077 mode |= S_IRUSR;
941 if (view->input_proc) 1078 if (view->input_proc)
942 mode |= S_IWUSR; 1079 mode |= S_IWUSR;
943 pde = create_proc_entry(view->name, mode, id->proc_root_entry); 1080 pde = debugfs_create_file(view->name, mode, id->debugfs_root_entry,
1081 NULL, &debug_file_ops);
944 if (!pde){ 1082 if (!pde){
945 printk(KERN_WARNING "debug: create_proc_entry() failed! Cannot register view %s/%s\n", id->name,view->name); 1083 printk(KERN_WARNING "debug: debugfs_create_file() failed!"\
1084 " Cannot register view %s/%s\n", id->name,view->name);
946 rc = -1; 1085 rc = -1;
947 goto out; 1086 goto out;
948 } 1087 }
949
950 spin_lock_irqsave(&id->lock, flags); 1088 spin_lock_irqsave(&id->lock, flags);
951 for (i = 0; i < DEBUG_MAX_VIEWS; i++) { 1089 for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
952 if (id->views[i] == NULL) 1090 if (!id->views[i])
953 break; 1091 break;
954 } 1092 }
955 if (i == DEBUG_MAX_VIEWS) { 1093 if (i == DEBUG_MAX_VIEWS) {
@@ -957,16 +1095,14 @@ int debug_register_view(debug_info_t * id, struct debug_view *view)
957 id->name,view->name); 1095 id->name,view->name);
958 printk(KERN_WARNING 1096 printk(KERN_WARNING
959 "debug: maximum number of views reached (%i)!\n", i); 1097 "debug: maximum number of views reached (%i)!\n", i);
960 remove_proc_entry(pde->name, id->proc_root_entry); 1098 debugfs_remove(pde);
961 rc = -1; 1099 rc = -1;
962 } 1100 } else {
963 else {
964 id->views[i] = view; 1101 id->views[i] = view;
965 pde->proc_fops = &debug_file_ops; 1102 id->debugfs_entries[i] = pde;
966 id->proc_entries[i] = pde;
967 } 1103 }
968 spin_unlock_irqrestore(&id->lock, flags); 1104 spin_unlock_irqrestore(&id->lock, flags);
969 out: 1105out:
970 return rc; 1106 return rc;
971} 1107}
972 1108
@@ -974,7 +1110,8 @@ int debug_register_view(debug_info_t * id, struct debug_view *view)
974 * debug_unregister_view: 1110 * debug_unregister_view:
975 */ 1111 */
976 1112
977int debug_unregister_view(debug_info_t * id, struct debug_view *view) 1113int
1114debug_unregister_view(debug_info_t * id, struct debug_view *view)
978{ 1115{
979 int rc = 0; 1116 int rc = 0;
980 int i; 1117 int i;
@@ -990,15 +1127,46 @@ int debug_unregister_view(debug_info_t * id, struct debug_view *view)
990 if (i == DEBUG_MAX_VIEWS) 1127 if (i == DEBUG_MAX_VIEWS)
991 rc = -1; 1128 rc = -1;
992 else { 1129 else {
993#ifdef CONFIG_PROC_FS 1130 debugfs_remove(id->debugfs_entries[i]);
994 remove_proc_entry(id->proc_entries[i]->name,
995 id->proc_root_entry);
996#endif
997 id->views[i] = NULL; 1131 id->views[i] = NULL;
998 rc = 0; 1132 rc = 0;
999 } 1133 }
1000 spin_unlock_irqrestore(&id->lock, flags); 1134 spin_unlock_irqrestore(&id->lock, flags);
1001 out: 1135out:
1136 return rc;
1137}
1138
1139static inline char *
1140debug_get_user_string(const char __user *user_buf, size_t user_len)
1141{
1142 char* buffer;
1143
1144 buffer = kmalloc(user_len + 1, GFP_KERNEL);
1145 if (!buffer)
1146 return ERR_PTR(-ENOMEM);
1147 if (copy_from_user(buffer, user_buf, user_len) != 0) {
1148 kfree(buffer);
1149 return ERR_PTR(-EFAULT);
1150 }
1151 /* got the string, now strip linefeed. */
1152 if (buffer[user_len - 1] == '\n')
1153 buffer[user_len - 1] = 0;
1154 else
1155 buffer[user_len] = 0;
1156 return buffer;
1157}
1158
1159static inline int
1160debug_get_uint(char *buf)
1161{
1162 int rc;
1163
1164 for(; isspace(*buf); buf++);
1165 rc = simple_strtoul(buf, &buf, 10);
1166 if(*buf){
1167 printk("debug: no integer specified!\n");
1168 rc = -EINVAL;
1169 }
1002 return rc; 1170 return rc;
1003} 1171}
1004 1172
@@ -1011,13 +1179,69 @@ int debug_unregister_view(debug_info_t * id, struct debug_view *view)
1011 * prints out actual debug level 1179 * prints out actual debug level
1012 */ 1180 */
1013 1181
1014static int debug_prolog_level_fn(debug_info_t * id, 1182static int
1183debug_prolog_pages_fn(debug_info_t * id,
1015 struct debug_view *view, char *out_buf) 1184 struct debug_view *view, char *out_buf)
1016{ 1185{
1186 return sprintf(out_buf, "%i\n", id->pages_per_area);
1187}
1188
1189/*
1190 * reads new size (number of pages per debug area)
1191 */
1192
1193static int
1194debug_input_pages_fn(debug_info_t * id, struct debug_view *view,
1195 struct file *file, const char __user *user_buf,
1196 size_t user_len, loff_t * offset)
1197{
1198 char *str;
1199 int rc,new_pages;
1200
1201 if (user_len > 0x10000)
1202 user_len = 0x10000;
1203 if (*offset != 0){
1204 rc = -EPIPE;
1205 goto out;
1206 }
1207 str = debug_get_user_string(user_buf,user_len);
1208 if(IS_ERR(str)){
1209 rc = PTR_ERR(str);
1210 goto out;
1211 }
1212 new_pages = debug_get_uint(str);
1213 if(new_pages < 0){
1214 rc = -EINVAL;
1215 goto free_str;
1216 }
1217 rc = debug_set_size(id,id->nr_areas, new_pages);
1218 if(rc != 0){
1219 rc = -EINVAL;
1220 goto free_str;
1221 }
1222 rc = user_len;
1223free_str:
1224 kfree(str);
1225out:
1226 *offset += user_len;
1227 return rc; /* number of input characters */
1228}
1229
1230/*
1231 * prints out actual debug level
1232 */
1233
1234static int
1235debug_prolog_level_fn(debug_info_t * id, struct debug_view *view, char *out_buf)
1236{
1017 int rc = 0; 1237 int rc = 0;
1018 1238
1019 if(id->level == -1) rc = sprintf(out_buf,"-\n"); 1239 if(id->level == DEBUG_OFF_LEVEL) {
1020 else rc = sprintf(out_buf, "%i\n", id->level); 1240 rc = sprintf(out_buf,"-\n");
1241 }
1242 else {
1243 rc = sprintf(out_buf, "%i\n", id->level);
1244 }
1021 return rc; 1245 return rc;
1022} 1246}
1023 1247
@@ -1025,30 +1249,43 @@ static int debug_prolog_level_fn(debug_info_t * id,
1025 * reads new debug level 1249 * reads new debug level
1026 */ 1250 */
1027 1251
1028static int debug_input_level_fn(debug_info_t * id, struct debug_view *view, 1252static int
1029 struct file *file, const char __user *user_buf, 1253debug_input_level_fn(debug_info_t * id, struct debug_view *view,
1030 size_t in_buf_size, loff_t * offset) 1254 struct file *file, const char __user *user_buf,
1255 size_t user_len, loff_t * offset)
1031{ 1256{
1032 char input_buf[1]; 1257 char *str;
1033 int rc = in_buf_size; 1258 int rc,new_level;
1034 1259
1035 if (*offset != 0) 1260 if (user_len > 0x10000)
1261 user_len = 0x10000;
1262 if (*offset != 0){
1263 rc = -EPIPE;
1036 goto out; 1264 goto out;
1037 if (copy_from_user(input_buf, user_buf, 1)){ 1265 }
1038 rc = -EFAULT; 1266 str = debug_get_user_string(user_buf,user_len);
1267 if(IS_ERR(str)){
1268 rc = PTR_ERR(str);
1039 goto out; 1269 goto out;
1040 } 1270 }
1041 if (isdigit(input_buf[0])) { 1271 if(str[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); 1272 debug_set_level(id, DEBUG_OFF_LEVEL);
1273 rc = user_len;
1274 goto free_str;
1046 } else { 1275 } else {
1047 printk(KERN_INFO "debug: level `%c` is not valid\n", 1276 new_level = debug_get_uint(str);
1048 input_buf[0]);
1049 } 1277 }
1050 out: 1278 if(new_level < 0) {
1051 *offset += in_buf_size; 1279 printk(KERN_INFO "debug: level `%s` is not valid\n", str);
1280 rc = -EINVAL;
1281 } else {
1282 debug_set_level(id, new_level);
1283 rc = user_len;
1284 }
1285free_str:
1286 kfree(str);
1287out:
1288 *offset += user_len;
1052 return rc; /* number of input characters */ 1289 return rc; /* number of input characters */
1053} 1290}
1054 1291
@@ -1057,29 +1294,36 @@ static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
1057 * flushes debug areas 1294 * flushes debug areas
1058 */ 1295 */
1059 1296
1060void debug_flush(debug_info_t* id, int area) 1297void
1298debug_flush(debug_info_t* id, int area)
1061{ 1299{
1062 unsigned long flags; 1300 unsigned long flags;
1063 int i; 1301 int i,j;
1064 1302
1065 if(!id) 1303 if(!id || !id->areas)
1066 return; 1304 return;
1067 spin_lock_irqsave(&id->lock,flags); 1305 spin_lock_irqsave(&id->lock,flags);
1068 if(area == DEBUG_FLUSH_ALL){ 1306 if(area == DEBUG_FLUSH_ALL){
1069 id->active_area = 0; 1307 id->active_area = 0;
1070 memset(id->active_entry, 0, id->nr_areas * sizeof(int)); 1308 memset(id->active_entries, 0, id->nr_areas * sizeof(int));
1071 for (i = 0; i < id->nr_areas; i++) 1309 for (i = 0; i < id->nr_areas; i++) {
1072 memset(id->areas[i], 0, PAGE_SIZE << id->page_order); 1310 id->active_pages[i] = 0;
1311 for(j = 0; j < id->pages_per_area; j++) {
1312 memset(id->areas[i][j], 0, PAGE_SIZE);
1313 }
1314 }
1073 printk(KERN_INFO "debug: %s: all areas flushed\n",id->name); 1315 printk(KERN_INFO "debug: %s: all areas flushed\n",id->name);
1074 } else if(area >= 0 && area < id->nr_areas) { 1316 } else if(area >= 0 && area < id->nr_areas) {
1075 id->active_entry[area] = 0; 1317 id->active_entries[area] = 0;
1076 memset(id->areas[area], 0, PAGE_SIZE << id->page_order); 1318 id->active_pages[area] = 0;
1077 printk(KERN_INFO 1319 for(i = 0; i < id->pages_per_area; i++) {
1078 "debug: %s: area %i has been flushed\n", 1320 memset(id->areas[area][i],0,PAGE_SIZE);
1321 }
1322 printk(KERN_INFO "debug: %s: area %i has been flushed\n",
1079 id->name, area); 1323 id->name, area);
1080 } else { 1324 } else {
1081 printk(KERN_INFO 1325 printk(KERN_INFO
1082 "debug: %s: area %i cannot be flushed (range: %i - %i)\n", 1326 "debug: %s: area %i cannot be flushed (range: %i - %i)\n",
1083 id->name, area, 0, id->nr_areas-1); 1327 id->name, area, 0, id->nr_areas-1);
1084 } 1328 }
1085 spin_unlock_irqrestore(&id->lock,flags); 1329 spin_unlock_irqrestore(&id->lock,flags);
@@ -1089,15 +1333,20 @@ void debug_flush(debug_info_t* id, int area)
1089 * view function: flushes debug areas 1333 * view function: flushes debug areas
1090 */ 1334 */
1091 1335
1092static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, 1336static int
1093 struct file *file, const char __user *user_buf, 1337debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
1094 size_t in_buf_size, loff_t * offset) 1338 struct file *file, const char __user *user_buf,
1339 size_t user_len, loff_t * offset)
1095{ 1340{
1096 char input_buf[1]; 1341 char input_buf[1];
1097 int rc = in_buf_size; 1342 int rc = user_len;
1098 1343
1099 if (*offset != 0) 1344 if (user_len > 0x10000)
1345 user_len = 0x10000;
1346 if (*offset != 0){
1347 rc = -EPIPE;
1100 goto out; 1348 goto out;
1349 }
1101 if (copy_from_user(input_buf, user_buf, 1)){ 1350 if (copy_from_user(input_buf, user_buf, 1)){
1102 rc = -EFAULT; 1351 rc = -EFAULT;
1103 goto out; 1352 goto out;
@@ -1114,8 +1363,8 @@ static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
1114 1363
1115 printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]); 1364 printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]);
1116 1365
1117 out: 1366out:
1118 *offset += in_buf_size; 1367 *offset += user_len;
1119 return rc; /* number of input characters */ 1368 return rc; /* number of input characters */
1120} 1369}
1121 1370
@@ -1123,8 +1372,9 @@ static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
1123 * prints debug header in raw format 1372 * prints debug header in raw format
1124 */ 1373 */
1125 1374
1126int debug_raw_header_fn(debug_info_t * id, struct debug_view *view, 1375static int
1127 int area, debug_entry_t * entry, char *out_buf) 1376debug_raw_header_fn(debug_info_t * id, struct debug_view *view,
1377 int area, debug_entry_t * entry, char *out_buf)
1128{ 1378{
1129 int rc; 1379 int rc;
1130 1380
@@ -1137,7 +1387,8 @@ int debug_raw_header_fn(debug_info_t * id, struct debug_view *view,
1137 * prints debug data in raw format 1387 * prints debug data in raw format
1138 */ 1388 */
1139 1389
1140static int debug_raw_format_fn(debug_info_t * id, struct debug_view *view, 1390static int
1391debug_raw_format_fn(debug_info_t * id, struct debug_view *view,
1141 char *out_buf, const char *in_buf) 1392 char *out_buf, const char *in_buf)
1142{ 1393{
1143 int rc; 1394 int rc;
@@ -1151,8 +1402,9 @@ static int debug_raw_format_fn(debug_info_t * id, struct debug_view *view,
1151 * prints debug data in hex/ascii format 1402 * prints debug data in hex/ascii format
1152 */ 1403 */
1153 1404
1154static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, 1405static int
1155 char *out_buf, const char *in_buf) 1406debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
1407 char *out_buf, const char *in_buf)
1156{ 1408{
1157 int i, rc = 0; 1409 int i, rc = 0;
1158 1410
@@ -1176,7 +1428,8 @@ static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
1176 * prints header for debug entry 1428 * prints header for debug entry
1177 */ 1429 */
1178 1430
1179int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, 1431int
1432debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
1180 int area, debug_entry_t * entry, char *out_buf) 1433 int area, debug_entry_t * entry, char *out_buf)
1181{ 1434{
1182 struct timeval time_val; 1435 struct timeval time_val;
@@ -1210,8 +1463,9 @@ int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
1210 1463
1211#define DEBUG_SPRINTF_MAX_ARGS 10 1464#define DEBUG_SPRINTF_MAX_ARGS 10
1212 1465
1213int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view, 1466static int
1214 char *out_buf, debug_sprintf_entry_t *curr_event) 1467debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view,
1468 char *out_buf, debug_sprintf_entry_t *curr_event)
1215{ 1469{
1216 int num_longs, num_used_args = 0,i, rc = 0; 1470 int num_longs, num_used_args = 0,i, rc = 0;
1217 int index[DEBUG_SPRINTF_MAX_ARGS]; 1471 int index[DEBUG_SPRINTF_MAX_ARGS];
@@ -1251,14 +1505,10 @@ out:
1251/* 1505/*
1252 * clean up module 1506 * clean up module
1253 */ 1507 */
1254void __exit debug_exit(void) 1508void
1509__exit debug_exit(void)
1255{ 1510{
1256#ifdef DEBUG 1511 debugfs_remove(debug_debugfs_root_entry);
1257 printk("debug_cleanup_module: \n");
1258#endif
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); 1512 unregister_sysctl_table(s390dbf_sysctl_header);
1263 return; 1513 return;
1264} 1514}
@@ -1266,7 +1516,7 @@ void __exit debug_exit(void)
1266/* 1516/*
1267 * module definitions 1517 * module definitions
1268 */ 1518 */
1269core_initcall(debug_init); 1519postcore_initcall(debug_init);
1270module_exit(debug_exit); 1520module_exit(debug_exit);
1271MODULE_LICENSE("GPL"); 1521MODULE_LICENSE("GPL");
1272 1522