diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00debug.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00debug.c | 90 |
1 files changed, 76 insertions, 14 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 4e048ac0a684..21af11a97334 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include "rt2x00lib.h" | 33 | #include "rt2x00lib.h" |
34 | #include "rt2x00dump.h" | 34 | #include "rt2x00dump.h" |
35 | 35 | ||
36 | #define PRINT_LINE_LEN_MAX 32 | 36 | #define MAX_LINE_LENGTH 64 |
37 | 37 | ||
38 | struct rt2x00debug_intf { | 38 | struct rt2x00debug_intf { |
39 | /* | 39 | /* |
@@ -60,8 +60,9 @@ struct rt2x00debug_intf { | |||
60 | * - eeprom offset/value files | 60 | * - eeprom offset/value files |
61 | * - bbp offset/value files | 61 | * - bbp offset/value files |
62 | * - rf offset/value files | 62 | * - rf offset/value files |
63 | * - frame dump folder | 63 | * - queue folder |
64 | * - frame dump file | 64 | * - frame dump file |
65 | * - queue stats file | ||
65 | */ | 66 | */ |
66 | struct dentry *driver_folder; | 67 | struct dentry *driver_folder; |
67 | struct dentry *driver_entry; | 68 | struct dentry *driver_entry; |
@@ -76,8 +77,9 @@ struct rt2x00debug_intf { | |||
76 | struct dentry *bbp_val_entry; | 77 | struct dentry *bbp_val_entry; |
77 | struct dentry *rf_off_entry; | 78 | struct dentry *rf_off_entry; |
78 | struct dentry *rf_val_entry; | 79 | struct dentry *rf_val_entry; |
79 | struct dentry *frame_folder; | 80 | struct dentry *queue_folder; |
80 | struct dentry *frame_dump_entry; | 81 | struct dentry *queue_frame_dump_entry; |
82 | struct dentry *queue_stats_entry; | ||
81 | 83 | ||
82 | /* | 84 | /* |
83 | * The frame dump file only allows a single reader, | 85 | * The frame dump file only allows a single reader, |
@@ -269,6 +271,61 @@ static const struct file_operations rt2x00debug_fop_queue_dump = { | |||
269 | .release = rt2x00debug_release_queue_dump, | 271 | .release = rt2x00debug_release_queue_dump, |
270 | }; | 272 | }; |
271 | 273 | ||
274 | static ssize_t rt2x00debug_read_queue_stats(struct file *file, | ||
275 | char __user *buf, | ||
276 | size_t length, | ||
277 | loff_t *offset) | ||
278 | { | ||
279 | struct rt2x00debug_intf *intf = file->private_data; | ||
280 | struct data_queue *queue; | ||
281 | unsigned int lines = 1 + intf->rt2x00dev->data_queues; | ||
282 | size_t size; | ||
283 | char *data; | ||
284 | char *temp; | ||
285 | |||
286 | if (*offset) | ||
287 | return 0; | ||
288 | |||
289 | data = kzalloc(lines * MAX_LINE_LENGTH, GFP_KERNEL); | ||
290 | if (!data) | ||
291 | return -ENOMEM; | ||
292 | |||
293 | temp = data + | ||
294 | sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n"); | ||
295 | |||
296 | queue_for_each(intf->rt2x00dev, queue) { | ||
297 | spin_lock(&queue->lock); | ||
298 | |||
299 | temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, | ||
300 | queue->count, queue->limit, queue->length, | ||
301 | queue->index[Q_INDEX], | ||
302 | queue->index[Q_INDEX_DONE], | ||
303 | queue->index[Q_INDEX_CRYPTO]); | ||
304 | |||
305 | spin_unlock(&queue->lock); | ||
306 | } | ||
307 | |||
308 | size = strlen(data); | ||
309 | size = min(size, length); | ||
310 | |||
311 | if (copy_to_user(buf, data, size)) { | ||
312 | kfree(data); | ||
313 | return -EFAULT; | ||
314 | } | ||
315 | |||
316 | kfree(data); | ||
317 | |||
318 | *offset += size; | ||
319 | return size; | ||
320 | } | ||
321 | |||
322 | static const struct file_operations rt2x00debug_fop_queue_stats = { | ||
323 | .owner = THIS_MODULE, | ||
324 | .read = rt2x00debug_read_queue_stats, | ||
325 | .open = rt2x00debug_file_open, | ||
326 | .release = rt2x00debug_file_release, | ||
327 | }; | ||
328 | |||
272 | #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \ | 329 | #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \ |
273 | static ssize_t rt2x00debug_read_##__name(struct file *file, \ | 330 | static ssize_t rt2x00debug_read_##__name(struct file *file, \ |
274 | char __user *buf, \ | 331 | char __user *buf, \ |
@@ -386,7 +443,7 @@ static struct dentry *rt2x00debug_create_file_driver(const char *name, | |||
386 | { | 443 | { |
387 | char *data; | 444 | char *data; |
388 | 445 | ||
389 | data = kzalloc(3 * PRINT_LINE_LEN_MAX, GFP_KERNEL); | 446 | data = kzalloc(3 * MAX_LINE_LENGTH, GFP_KERNEL); |
390 | if (!data) | 447 | if (!data) |
391 | return NULL; | 448 | return NULL; |
392 | 449 | ||
@@ -409,7 +466,7 @@ static struct dentry *rt2x00debug_create_file_chipset(const char *name, | |||
409 | const struct rt2x00debug *debug = intf->debug; | 466 | const struct rt2x00debug *debug = intf->debug; |
410 | char *data; | 467 | char *data; |
411 | 468 | ||
412 | data = kzalloc(8 * PRINT_LINE_LEN_MAX, GFP_KERNEL); | 469 | data = kzalloc(8 * MAX_LINE_LENGTH, GFP_KERNEL); |
413 | if (!data) | 470 | if (!data) |
414 | return NULL; | 471 | return NULL; |
415 | 472 | ||
@@ -496,20 +553,24 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | |||
496 | 553 | ||
497 | #undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY | 554 | #undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY |
498 | 555 | ||
499 | intf->frame_folder = | 556 | intf->queue_folder = |
500 | debugfs_create_dir("frame", intf->driver_folder); | 557 | debugfs_create_dir("queue", intf->driver_folder); |
501 | if (IS_ERR(intf->frame_folder)) | 558 | if (IS_ERR(intf->queue_folder)) |
502 | goto exit; | 559 | goto exit; |
503 | 560 | ||
504 | intf->frame_dump_entry = | 561 | intf->queue_frame_dump_entry = |
505 | debugfs_create_file("dump", S_IRUGO, intf->frame_folder, | 562 | debugfs_create_file("dump", S_IRUGO, intf->queue_folder, |
506 | intf, &rt2x00debug_fop_queue_dump); | 563 | intf, &rt2x00debug_fop_queue_dump); |
507 | if (IS_ERR(intf->frame_dump_entry)) | 564 | if (IS_ERR(intf->queue_frame_dump_entry)) |
508 | goto exit; | 565 | goto exit; |
509 | 566 | ||
510 | skb_queue_head_init(&intf->frame_dump_skbqueue); | 567 | skb_queue_head_init(&intf->frame_dump_skbqueue); |
511 | init_waitqueue_head(&intf->frame_dump_waitqueue); | 568 | init_waitqueue_head(&intf->frame_dump_waitqueue); |
512 | 569 | ||
570 | intf->queue_stats_entry = | ||
571 | debugfs_create_file("queue", S_IRUGO, intf->queue_folder, | ||
572 | intf, &rt2x00debug_fop_queue_stats); | ||
573 | |||
513 | return; | 574 | return; |
514 | 575 | ||
515 | exit: | 576 | exit: |
@@ -528,8 +589,9 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) | |||
528 | 589 | ||
529 | skb_queue_purge(&intf->frame_dump_skbqueue); | 590 | skb_queue_purge(&intf->frame_dump_skbqueue); |
530 | 591 | ||
531 | debugfs_remove(intf->frame_dump_entry); | 592 | debugfs_remove(intf->queue_stats_entry); |
532 | debugfs_remove(intf->frame_folder); | 593 | debugfs_remove(intf->queue_frame_dump_entry); |
594 | debugfs_remove(intf->queue_folder); | ||
533 | debugfs_remove(intf->rf_val_entry); | 595 | debugfs_remove(intf->rf_val_entry); |
534 | debugfs_remove(intf->rf_off_entry); | 596 | debugfs_remove(intf->rf_off_entry); |
535 | debugfs_remove(intf->bbp_val_entry); | 597 | debugfs_remove(intf->bbp_val_entry); |