aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2009-06-12 09:20:55 -0400
committerJiri Kosina <jkosina@suse.cz>2009-06-12 09:20:55 -0400
commita635f9dd83f3382577f4544a96df12356e951a40 (patch)
treec6fa27df6d01c34e304a32c9f423d569f7358346 /drivers/hid
parent8ebf975608aaebd7feb33d77f07ba21a6380e086 (diff)
HID: use debugfs for report dumping descriptor
It is a little bit inconvenient for people who have some non-standard HID hardware (usually violating the HID specification) to have to recompile kernel with CONFIG_HID_DEBUG to be able to see kernel's perspective of the HID report descriptor and observe the parsed events. Plus the messages are then mixed up inconveniently with the rest of the dmesg stuff. This patch implements /sys/kernel/debug/hid/<device>/rdesc file, which represents the kernel's view of report descriptor (both the raw report descriptor data and parsed contents). With all the device-specific debug data being available through debugfs, there is no need for keeping CONFIG_HID_DEBUG, as the 'debug' parameter to the hid module will now only output only driver-specific debugging options, which has absolutely minimal memory footprint, just a few error messages and one global flag (hid_debug). We use the current set of output formatting functions. The ones that need to be used both for one-shot rdesc seq_file and also for continuous flow of data (individual reports, as being sent by the device) distinguish according to the passed seq_file parameter, and if it is NULL, it still output to kernel ringbuffer, otherwise the corresponding seq_file is used for output. The format of the output is preserved. Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/Kconfig15
-rw-r--r--drivers/hid/Makefile5
-rw-r--r--drivers/hid/hid-core.c13
-rw-r--r--drivers/hid/hid-debug.c227
-rw-r--r--drivers/hid/hid-input.c13
-rw-r--r--drivers/hid/usbhid/hid-core.c8
6 files changed, 172 insertions, 109 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 7e67dcb3d4f6..05950a783560 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -31,21 +31,6 @@ config HID
31 31
32 If unsure, say Y. 32 If unsure, say Y.
33 33
34config HID_DEBUG
35 bool "HID debugging support"
36 default y
37 depends on HID
38 ---help---
39 This option lets the HID layer output diagnostics about its internal
40 state, resolve HID usages, dump HID fields, etc. Individual HID drivers
41 use this debugging facility to output information about individual HID
42 devices, etc.
43
44 This feature is useful for those who are either debugging the HID parser
45 or any HID hardware device.
46
47 If unsure, say Y.
48
49config HIDRAW 34config HIDRAW
50 bool "/dev/hidraw raw HID device support" 35 bool "/dev/hidraw raw HID device support"
51 depends on HID 36 depends on HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 1f7cb0fd4505..cf3687d1ed63 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -3,9 +3,12 @@
3# 3#
4hid-objs := hid-core.o hid-input.o 4hid-objs := hid-core.o hid-input.o
5 5
6ifdef CONFIG_DEBUG_FS
7 hid-objs += hid-debug.o
8endif
9
6obj-$(CONFIG_HID) += hid.o 10obj-$(CONFIG_HID) += hid.o
7 11
8hid-$(CONFIG_HID_DEBUG) += hid-debug.o
9hid-$(CONFIG_HIDRAW) += hidraw.o 12hid-$(CONFIG_HIDRAW) += hidraw.o
10 13
11hid-logitech-objs := hid-lg.o 14hid-logitech-objs := hid-lg.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 8551693d645f..d4317db85b54 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -44,12 +44,10 @@
44#define DRIVER_DESC "HID core driver" 44#define DRIVER_DESC "HID core driver"
45#define DRIVER_LICENSE "GPL" 45#define DRIVER_LICENSE "GPL"
46 46
47#ifdef CONFIG_HID_DEBUG
48int hid_debug = 0; 47int hid_debug = 0;
49module_param_named(debug, hid_debug, int, 0600); 48module_param_named(debug, hid_debug, int, 0600);
50MODULE_PARM_DESC(debug, "HID debugging (0=off, 1=probing info, 2=continuous data dumping)"); 49MODULE_PARM_DESC(debug, "HID debugging (0=off, 1=probing info, 2=continuous data dumping)");
51EXPORT_SYMBOL_GPL(hid_debug); 50EXPORT_SYMBOL_GPL(hid_debug);
52#endif
53 51
54/* 52/*
55 * Register a new report for a device. 53 * Register a new report for a device.
@@ -987,7 +985,6 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
987 985
988 if (offset >= field->report_count) { 986 if (offset >= field->report_count) {
989 dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count); 987 dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count);
990 hid_dump_field(field, 8);
991 return -1; 988 return -1;
992 } 989 }
993 if (field->logical_minimum < 0) { 990 if (field->logical_minimum < 0) {
@@ -1721,6 +1718,8 @@ int hid_add_device(struct hid_device *hdev)
1721 if (!ret) 1718 if (!ret)
1722 hdev->status |= HID_STAT_ADDED; 1719 hdev->status |= HID_STAT_ADDED;
1723 1720
1721 hid_debug_register(hdev, dev_name(&hdev->dev));
1722
1724 return ret; 1723 return ret;
1725} 1724}
1726EXPORT_SYMBOL_GPL(hid_add_device); 1725EXPORT_SYMBOL_GPL(hid_add_device);
@@ -1768,6 +1767,7 @@ static void hid_remove_device(struct hid_device *hdev)
1768{ 1767{
1769 if (hdev->status & HID_STAT_ADDED) { 1768 if (hdev->status & HID_STAT_ADDED) {
1770 device_del(&hdev->dev); 1769 device_del(&hdev->dev);
1770 hid_debug_unregister(hdev);
1771 hdev->status &= ~HID_STAT_ADDED; 1771 hdev->status &= ~HID_STAT_ADDED;
1772 } 1772 }
1773} 1773}
@@ -1843,6 +1843,10 @@ static int __init hid_init(void)
1843{ 1843{
1844 int ret; 1844 int ret;
1845 1845
1846 if (hid_debug)
1847 printk(KERN_WARNING "HID: hid_debug parameter has been deprecated. "
1848 "Debugging data are now provided via debugfs\n");
1849
1846 ret = bus_register(&hid_bus_type); 1850 ret = bus_register(&hid_bus_type);
1847 if (ret) { 1851 if (ret) {
1848 printk(KERN_ERR "HID: can't register hid bus\n"); 1852 printk(KERN_ERR "HID: can't register hid bus\n");
@@ -1853,6 +1857,8 @@ static int __init hid_init(void)
1853 if (ret) 1857 if (ret)
1854 goto err_bus; 1858 goto err_bus;
1855 1859
1860 hid_debug_init();
1861
1856 return 0; 1862 return 0;
1857err_bus: 1863err_bus:
1858 bus_unregister(&hid_bus_type); 1864 bus_unregister(&hid_bus_type);
@@ -1862,6 +1868,7 @@ err:
1862 1868
1863static void __exit hid_exit(void) 1869static void __exit hid_exit(void)
1864{ 1870{
1871 hid_debug_exit();
1865 hidraw_exit(); 1872 hidraw_exit();
1866 bus_unregister(&hid_bus_type); 1873 bus_unregister(&hid_bus_type);
1867} 1874}
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index 47ac1a7d66e1..067e173aa3e4 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * (c) 1999 Andreas Gal <gal@cs.uni-magdeburg.de> 2 * (c) 1999 Andreas Gal <gal@cs.uni-magdeburg.de>
3 * (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz> 3 * (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz>
4 * (c) 2007 Jiri Kosina 4 * (c) 2007-2009 Jiri Kosina
5 * 5 *
6 * Some debug stuff for the HID parser. 6 * HID debugging support
7 */ 7 */
8 8
9/* 9/*
@@ -26,9 +26,13 @@
26 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic 26 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
27 */ 27 */
28 28
29#include <linux/debugfs.h>
30#include <linux/seq_file.h>
29#include <linux/hid.h> 31#include <linux/hid.h>
30#include <linux/hid-debug.h> 32#include <linux/hid-debug.h>
31 33
34static struct dentry *hid_debug_root;
35
32struct hid_usage_entry { 36struct hid_usage_entry {
33 unsigned page; 37 unsigned page;
34 unsigned usage; 38 unsigned usage;
@@ -331,72 +335,83 @@ static const struct hid_usage_entry hid_usage_table[] = {
331 { 0, 0, NULL } 335 { 0, 0, NULL }
332}; 336};
333 337
334static void resolv_usage_page(unsigned page) { 338static void resolv_usage_page(unsigned page, struct seq_file *f) {
335 const struct hid_usage_entry *p; 339 const struct hid_usage_entry *p;
336 340
337 for (p = hid_usage_table; p->description; p++) 341 for (p = hid_usage_table; p->description; p++)
338 if (p->page == page) { 342 if (p->page == page) {
339 printk("%s", p->description); 343 if (!f)
344 printk("%s", p->description);
345 else
346 seq_printf(f, "%s", p->description);
340 return; 347 return;
341 } 348 }
342 printk("%04x", page); 349 if (!f)
350 printk("%04x", page);
351 else
352 seq_printf(f, "%04x", page);
343} 353}
344 354
345void hid_resolv_usage(unsigned usage) { 355void hid_resolv_usage(unsigned usage, struct seq_file *f) {
346 const struct hid_usage_entry *p; 356 const struct hid_usage_entry *p;
347 357
348 if (!hid_debug) 358 resolv_usage_page(usage >> 16, f);
349 return; 359 if (!f)
350 360 printk(".");
351 resolv_usage_page(usage >> 16); 361 else
352 printk("."); 362 seq_printf(f, ".");
353 for (p = hid_usage_table; p->description; p++) 363 for (p = hid_usage_table; p->description; p++)
354 if (p->page == (usage >> 16)) { 364 if (p->page == (usage >> 16)) {
355 for(++p; p->description && p->usage != 0; p++) 365 for(++p; p->description && p->usage != 0; p++)
356 if (p->usage == (usage & 0xffff)) { 366 if (p->usage == (usage & 0xffff)) {
357 printk("%s", p->description); 367 if (!f)
368 printk("%s", p->description);
369 else
370 seq_printf(f,
371 "%s",
372 p->description);
358 return; 373 return;
359 } 374 }
360 break; 375 break;
361 } 376 }
362 printk("%04x", usage & 0xffff); 377 if (!f)
378 printk("%04x", usage & 0xffff);
379 else
380 seq_printf(f, "%04x", usage & 0xffff);
363} 381}
364EXPORT_SYMBOL_GPL(hid_resolv_usage); 382EXPORT_SYMBOL_GPL(hid_resolv_usage);
365 383
366static void tab(int n) { 384static void tab(int n, struct seq_file *f) {
367 printk(KERN_DEBUG "%*s", n, ""); 385 seq_printf(f, "%*s", n, "");
368} 386}
369 387
370void hid_dump_field(struct hid_field *field, int n) { 388void hid_dump_field(struct hid_field *field, int n, struct seq_file *f) {
371 int j; 389 int j;
372 390
373 if (!hid_debug)
374 return;
375
376 if (field->physical) { 391 if (field->physical) {
377 tab(n); 392 tab(n, f);
378 printk("Physical("); 393 seq_printf(f, "Physical(");
379 hid_resolv_usage(field->physical); printk(")\n"); 394 hid_resolv_usage(field->physical, f); seq_printf(f, ")\n");
380 } 395 }
381 if (field->logical) { 396 if (field->logical) {
382 tab(n); 397 tab(n, f);
383 printk("Logical("); 398 seq_printf(f, "Logical(");
384 hid_resolv_usage(field->logical); printk(")\n"); 399 hid_resolv_usage(field->logical, f); seq_printf(f, ")\n");
385 } 400 }
386 tab(n); printk("Usage(%d)\n", field->maxusage); 401 tab(n, f); seq_printf(f, "Usage(%d)\n", field->maxusage);
387 for (j = 0; j < field->maxusage; j++) { 402 for (j = 0; j < field->maxusage; j++) {
388 tab(n+2); hid_resolv_usage(field->usage[j].hid); printk("\n"); 403 tab(n+2, f); hid_resolv_usage(field->usage[j].hid, f); seq_printf(f, "\n");
389 } 404 }
390 if (field->logical_minimum != field->logical_maximum) { 405 if (field->logical_minimum != field->logical_maximum) {
391 tab(n); printk("Logical Minimum(%d)\n", field->logical_minimum); 406 tab(n, f); seq_printf(f, "Logical Minimum(%d)\n", field->logical_minimum);
392 tab(n); printk("Logical Maximum(%d)\n", field->logical_maximum); 407 tab(n, f); seq_printf(f, "Logical Maximum(%d)\n", field->logical_maximum);
393 } 408 }
394 if (field->physical_minimum != field->physical_maximum) { 409 if (field->physical_minimum != field->physical_maximum) {
395 tab(n); printk("Physical Minimum(%d)\n", field->physical_minimum); 410 tab(n, f); seq_printf(f, "Physical Minimum(%d)\n", field->physical_minimum);
396 tab(n); printk("Physical Maximum(%d)\n", field->physical_maximum); 411 tab(n, f); seq_printf(f, "Physical Maximum(%d)\n", field->physical_maximum);
397 } 412 }
398 if (field->unit_exponent) { 413 if (field->unit_exponent) {
399 tab(n); printk("Unit Exponent(%d)\n", field->unit_exponent); 414 tab(n, f); seq_printf(f, "Unit Exponent(%d)\n", field->unit_exponent);
400 } 415 }
401 if (field->unit) { 416 if (field->unit) {
402 static const char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" }; 417 static const char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" };
@@ -417,77 +432,75 @@ void hid_dump_field(struct hid_field *field, int n) {
417 data >>= 4; 432 data >>= 4;
418 433
419 if(sys > 4) { 434 if(sys > 4) {
420 tab(n); printk("Unit(Invalid)\n"); 435 tab(n, f); seq_printf(f, "Unit(Invalid)\n");
421 } 436 }
422 else { 437 else {
423 int earlier_unit = 0; 438 int earlier_unit = 0;
424 439
425 tab(n); printk("Unit(%s : ", systems[sys]); 440 tab(n, f); seq_printf(f, "Unit(%s : ", systems[sys]);
426 441
427 for (i=1 ; i<sizeof(__u32)*2 ; i++) { 442 for (i=1 ; i<sizeof(__u32)*2 ; i++) {
428 char nibble = data & 0xf; 443 char nibble = data & 0xf;
429 data >>= 4; 444 data >>= 4;
430 if (nibble != 0) { 445 if (nibble != 0) {
431 if(earlier_unit++ > 0) 446 if(earlier_unit++ > 0)
432 printk("*"); 447 seq_printf(f, "*");
433 printk("%s", units[sys][i]); 448 seq_printf(f, "%s", units[sys][i]);
434 if(nibble != 1) { 449 if(nibble != 1) {
435 /* This is a _signed_ nibble(!) */ 450 /* This is a _signed_ nibble(!) */
436 451
437 int val = nibble & 0x7; 452 int val = nibble & 0x7;
438 if(nibble & 0x08) 453 if(nibble & 0x08)
439 val = -((0x7 & ~val) +1); 454 val = -((0x7 & ~val) +1);
440 printk("^%d", val); 455 seq_printf(f, "^%d", val);
441 } 456 }
442 } 457 }
443 } 458 }
444 printk(")\n"); 459 seq_printf(f, ")\n");
445 } 460 }
446 } 461 }
447 tab(n); printk("Report Size(%u)\n", field->report_size); 462 tab(n, f); seq_printf(f, "Report Size(%u)\n", field->report_size);
448 tab(n); printk("Report Count(%u)\n", field->report_count); 463 tab(n, f); seq_printf(f, "Report Count(%u)\n", field->report_count);
449 tab(n); printk("Report Offset(%u)\n", field->report_offset); 464 tab(n, f); seq_printf(f, "Report Offset(%u)\n", field->report_offset);
450 465
451 tab(n); printk("Flags( "); 466 tab(n, f); seq_printf(f, "Flags( ");
452 j = field->flags; 467 j = field->flags;
453 printk("%s", HID_MAIN_ITEM_CONSTANT & j ? "Constant " : ""); 468 seq_printf(f, "%s", HID_MAIN_ITEM_CONSTANT & j ? "Constant " : "");
454 printk("%s", HID_MAIN_ITEM_VARIABLE & j ? "Variable " : "Array "); 469 seq_printf(f, "%s", HID_MAIN_ITEM_VARIABLE & j ? "Variable " : "Array ");
455 printk("%s", HID_MAIN_ITEM_RELATIVE & j ? "Relative " : "Absolute "); 470 seq_printf(f, "%s", HID_MAIN_ITEM_RELATIVE & j ? "Relative " : "Absolute ");
456 printk("%s", HID_MAIN_ITEM_WRAP & j ? "Wrap " : ""); 471 seq_printf(f, "%s", HID_MAIN_ITEM_WRAP & j ? "Wrap " : "");
457 printk("%s", HID_MAIN_ITEM_NONLINEAR & j ? "NonLinear " : ""); 472 seq_printf(f, "%s", HID_MAIN_ITEM_NONLINEAR & j ? "NonLinear " : "");
458 printk("%s", HID_MAIN_ITEM_NO_PREFERRED & j ? "NoPreferredState " : ""); 473 seq_printf(f, "%s", HID_MAIN_ITEM_NO_PREFERRED & j ? "NoPreferredState " : "");
459 printk("%s", HID_MAIN_ITEM_NULL_STATE & j ? "NullState " : ""); 474 seq_printf(f, "%s", HID_MAIN_ITEM_NULL_STATE & j ? "NullState " : "");
460 printk("%s", HID_MAIN_ITEM_VOLATILE & j ? "Volatile " : ""); 475 seq_printf(f, "%s", HID_MAIN_ITEM_VOLATILE & j ? "Volatile " : "");
461 printk("%s", HID_MAIN_ITEM_BUFFERED_BYTE & j ? "BufferedByte " : ""); 476 seq_printf(f, "%s", HID_MAIN_ITEM_BUFFERED_BYTE & j ? "BufferedByte " : "");
462 printk(")\n"); 477 seq_printf(f, ")\n");
463} 478}
464EXPORT_SYMBOL_GPL(hid_dump_field); 479EXPORT_SYMBOL_GPL(hid_dump_field);
465 480
466void hid_dump_device(struct hid_device *device) { 481void hid_dump_device(struct hid_device *device, struct seq_file *f)
482{
467 struct hid_report_enum *report_enum; 483 struct hid_report_enum *report_enum;
468 struct hid_report *report; 484 struct hid_report *report;
469 struct list_head *list; 485 struct list_head *list;
470 unsigned i,k; 486 unsigned i,k;
471 static const char *table[] = {"INPUT", "OUTPUT", "FEATURE"}; 487 static const char *table[] = {"INPUT", "OUTPUT", "FEATURE"};
472 488
473 if (!hid_debug)
474 return;
475
476 for (i = 0; i < HID_REPORT_TYPES; i++) { 489 for (i = 0; i < HID_REPORT_TYPES; i++) {
477 report_enum = device->report_enum + i; 490 report_enum = device->report_enum + i;
478 list = report_enum->report_list.next; 491 list = report_enum->report_list.next;
479 while (list != &report_enum->report_list) { 492 while (list != &report_enum->report_list) {
480 report = (struct hid_report *) list; 493 report = (struct hid_report *) list;
481 tab(2); 494 tab(2, f);
482 printk("%s", table[i]); 495 seq_printf(f, "%s", table[i]);
483 if (report->id) 496 if (report->id)
484 printk("(%d)", report->id); 497 seq_printf(f, "(%d)", report->id);
485 printk("[%s]", table[report->type]); 498 seq_printf(f, "[%s]", table[report->type]);
486 printk("\n"); 499 seq_printf(f, "\n");
487 for (k = 0; k < report->maxfield; k++) { 500 for (k = 0; k < report->maxfield; k++) {
488 tab(4); 501 tab(4, f);
489 printk("Field(%d)\n", k); 502 seq_printf(f, "Field(%d)\n", k);
490 hid_dump_field(report->field[k], 6); 503 hid_dump_field(report->field[k], 6, f);
491 } 504 }
492 list = list->next; 505 list = list->next;
493 } 506 }
@@ -500,7 +513,7 @@ void hid_dump_input(struct hid_usage *usage, __s32 value) {
500 return; 513 return;
501 514
502 printk(KERN_DEBUG "hid-debug: input "); 515 printk(KERN_DEBUG "hid-debug: input ");
503 hid_resolv_usage(usage->hid); 516 hid_resolv_usage(usage->hid, NULL);
504 printk(" = %d\n", value); 517 printk(" = %d\n", value);
505} 518}
506EXPORT_SYMBOL_GPL(hid_dump_input); 519EXPORT_SYMBOL_GPL(hid_dump_input);
@@ -767,12 +780,84 @@ static const char **names[EV_MAX + 1] = {
767 [EV_SND] = sounds, [EV_REP] = repeats, 780 [EV_SND] = sounds, [EV_REP] = repeats,
768}; 781};
769 782
770void hid_resolv_event(__u8 type, __u16 code) { 783void hid_resolv_event(__u8 type, __u16 code, struct seq_file *f) {
771
772 if (!hid_debug)
773 return;
774 784
775 printk("%s.%s", events[type] ? events[type] : "?", 785 seq_printf(f, "%s.%s", events[type] ? events[type] : "?",
776 names[type] ? (names[type][code] ? names[type][code] : "?") : "?"); 786 names[type] ? (names[type][code] ? names[type][code] : "?") : "?");
777} 787}
778EXPORT_SYMBOL_GPL(hid_resolv_event); 788
789void hid_dump_input_mapping(struct hid_device *hid, struct seq_file *f)
790{
791 int i, j, k;
792 struct hid_report *report;
793 struct hid_usage *usage;
794
795 for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
796 list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
797 for (i = 0; i < report->maxfield; i++) {
798 for ( j = 0; j < report->field[i]->maxusage; j++) {
799 usage = report->field[i]->usage + j;
800 hid_resolv_usage(usage->hid, f);
801 seq_printf(f, " ---> ");
802 hid_resolv_event(usage->type, usage->code, f);
803 seq_printf(f, "\n");
804 }
805 }
806 }
807 }
808
809}
810
811static int hid_debug_rdesc_show(struct seq_file *f, void *p)
812{
813 struct hid_device *hdev = f->private;
814 int i;
815
816 /* dump HID report descriptor */
817 for (i = 0; i < hdev->rsize; i++)
818 seq_printf(f, "%02x ", hdev->rdesc[i]);
819 seq_printf(f, "\n\n");
820
821 /* dump parsed data and input mappings */
822 hid_dump_device(hdev, f);
823 seq_printf(f, "\n");
824 hid_dump_input_mapping(hdev, f);
825
826 return 0;
827}
828
829static int hid_debug_rdesc_open(struct inode *inode, struct file *file)
830{
831 return single_open(file, hid_debug_rdesc_show, inode->i_private);
832}
833
834static const struct file_operations hid_debug_rdesc_fops = {
835 .open = hid_debug_rdesc_open,
836 .read = seq_read,
837 .llseek = seq_lseek,
838 .release = single_release,
839};
840
841void hid_debug_register(struct hid_device *hdev, const char *name)
842{
843 hdev->debug_dir = debugfs_create_dir(name, hid_debug_root);
844 hdev->debug_rdesc = debugfs_create_file("rdesc", 0400,
845 hdev->debug_dir, hdev, &hid_debug_rdesc_fops);
846}
847
848void hid_debug_unregister(struct hid_device *hdev)
849{
850 debugfs_remove(hdev->debug_rdesc);
851 debugfs_remove(hdev->debug_dir);
852}
853
854void hid_debug_init(void)
855{
856 hid_debug_root = debugfs_create_dir("hid", NULL);
857}
858
859void hid_debug_exit(void)
860{
861 debugfs_remove_recursive(hid_debug_root);
862}
863
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 7f183b7147e1..5862b0f3b55d 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -159,17 +159,12 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
159 159
160 field->hidinput = hidinput; 160 field->hidinput = hidinput;
161 161
162 dbg_hid("Mapping: ");
163 hid_resolv_usage(usage->hid);
164 dbg_hid_line(" ---> ");
165
166 if (field->flags & HID_MAIN_ITEM_CONSTANT) 162 if (field->flags & HID_MAIN_ITEM_CONSTANT)
167 goto ignore; 163 goto ignore;
168 164
169 /* only LED usages are supported in output fields */ 165 /* only LED usages are supported in output fields */
170 if (field->report_type == HID_OUTPUT_REPORT && 166 if (field->report_type == HID_OUTPUT_REPORT &&
171 (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) { 167 (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) {
172 dbg_hid_line(" [non-LED output field] ");
173 goto ignore; 168 goto ignore;
174 } 169 }
175 170
@@ -561,15 +556,9 @@ mapped:
561 set_bit(MSC_SCAN, input->mscbit); 556 set_bit(MSC_SCAN, input->mscbit);
562 } 557 }
563 558
564 hid_resolv_event(usage->type, usage->code);
565
566 dbg_hid_line("\n");
567
568 return;
569
570ignore: 559ignore:
571 dbg_hid_line("IGNORED\n");
572 return; 560 return;
561
573} 562}
574 563
575void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) 564void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index ac8049b5f1e9..708aa52d0753 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -4,8 +4,8 @@
4 * Copyright (c) 1999 Andreas Gal 4 * Copyright (c) 1999 Andreas Gal
5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> 5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc 6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7 * Copyright (c) 2006-2008 Jiri Kosina
8 * Copyright (c) 2007-2008 Oliver Neukum 7 * Copyright (c) 2007-2008 Oliver Neukum
8 * Copyright (c) 2006-2009 Jiri Kosina
9 */ 9 */
10 10
11/* 11/*
@@ -886,11 +886,6 @@ static int usbhid_parse(struct hid_device *hid)
886 goto err; 886 goto err;
887 } 887 }
888 888
889 dbg_hid("report descriptor (size %u, read %d) = ", rsize, n);
890 for (n = 0; n < rsize; n++)
891 dbg_hid_line(" %02x", (unsigned char) rdesc[n]);
892 dbg_hid_line("\n");
893
894 ret = hid_parse_report(hid, rdesc, rsize); 889 ret = hid_parse_report(hid, rdesc, rsize);
895 kfree(rdesc); 890 kfree(rdesc);
896 if (ret) { 891 if (ret) {
@@ -1005,7 +1000,6 @@ static int usbhid_start(struct hid_device *hid)
1005 usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); 1000 usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
1006 1001
1007 usbhid_init_reports(hid); 1002 usbhid_init_reports(hid);
1008 hid_dump_device(hid);
1009 1003
1010 set_bit(HID_STARTED, &usbhid->iofl); 1004 set_bit(HID_STARTED, &usbhid->iofl);
1011 1005