aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-core.c
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2007-05-30 09:07:13 -0400
committerJiri Kosina <jkosina@suse.cz>2007-07-09 08:03:35 -0400
commit58037eb961f859607b161c50d9d4ecb374de1e8f (patch)
treec192854fa4cfc16cce272b800a0393e21429191e /drivers/hid/hid-core.c
parent7dcca30a32aadb0520417521b0c44f42d09fe05c (diff)
HID: make debugging output runtime-configurable
There have been many reports recently about broken HID devices, the diagnosis of which required users to recompile their kernels in order to be able to provide debugging output needed for coding a quirk for a particular device. This patch makes CONFIG_HID_DEBUG default y if !EMBEDDED and makes it possible to control debugging output produced by HID code by supplying 'debug=1' module parameter. Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-core.c')
-rw-r--r--drivers/hid/hid-core.c93
1 files changed, 47 insertions, 46 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 6ec04e79f685..317cf8a7b63c 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -40,6 +40,13 @@
40#define DRIVER_DESC "HID core driver" 40#define DRIVER_DESC "HID core driver"
41#define DRIVER_LICENSE "GPL" 41#define DRIVER_LICENSE "GPL"
42 42
43#ifdef CONFIG_HID_DEBUG
44int hid_debug = 0;
45module_param_named(debug, hid_debug, bool, 0600);
46MODULE_PARM_DESC(debug, "Turn HID debugging mode on and off");
47EXPORT_SYMBOL_GPL(hid_debug);
48#endif
49
43/* 50/*
44 * Register a new report for a device. 51 * Register a new report for a device.
45 */ 52 */
@@ -78,7 +85,7 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned
78 struct hid_field *field; 85 struct hid_field *field;
79 86
80 if (report->maxfield == HID_MAX_FIELDS) { 87 if (report->maxfield == HID_MAX_FIELDS) {
81 dbg("too many fields in report"); 88 dbg_hid("too many fields in report\n");
82 return NULL; 89 return NULL;
83 } 90 }
84 91
@@ -106,7 +113,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
106 usage = parser->local.usage[0]; 113 usage = parser->local.usage[0];
107 114
108 if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { 115 if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
109 dbg("collection stack overflow"); 116 dbg_hid("collection stack overflow\n");
110 return -1; 117 return -1;
111 } 118 }
112 119
@@ -114,7 +121,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
114 collection = kmalloc(sizeof(struct hid_collection) * 121 collection = kmalloc(sizeof(struct hid_collection) *
115 parser->device->collection_size * 2, GFP_KERNEL); 122 parser->device->collection_size * 2, GFP_KERNEL);
116 if (collection == NULL) { 123 if (collection == NULL) {
117 dbg("failed to reallocate collection array"); 124 dbg_hid("failed to reallocate collection array\n");
118 return -1; 125 return -1;
119 } 126 }
120 memcpy(collection, parser->device->collection, 127 memcpy(collection, parser->device->collection,
@@ -150,7 +157,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
150static int close_collection(struct hid_parser *parser) 157static int close_collection(struct hid_parser *parser)
151{ 158{
152 if (!parser->collection_stack_ptr) { 159 if (!parser->collection_stack_ptr) {
153 dbg("collection stack underflow"); 160 dbg_hid("collection stack underflow\n");
154 return -1; 161 return -1;
155 } 162 }
156 parser->collection_stack_ptr--; 163 parser->collection_stack_ptr--;
@@ -178,7 +185,7 @@ static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type)
178static int hid_add_usage(struct hid_parser *parser, unsigned usage) 185static int hid_add_usage(struct hid_parser *parser, unsigned usage)
179{ 186{
180 if (parser->local.usage_index >= HID_MAX_USAGES) { 187 if (parser->local.usage_index >= HID_MAX_USAGES) {
181 dbg("usage index exceeded"); 188 dbg_hid("usage index exceeded\n");
182 return -1; 189 return -1;
183 } 190 }
184 parser->local.usage[parser->local.usage_index] = usage; 191 parser->local.usage[parser->local.usage_index] = usage;
@@ -202,12 +209,12 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
202 int i; 209 int i;
203 210
204 if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { 211 if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) {
205 dbg("hid_register_report failed"); 212 dbg_hid("hid_register_report failed\n");
206 return -1; 213 return -1;
207 } 214 }
208 215
209 if (parser->global.logical_maximum < parser->global.logical_minimum) { 216 if (parser->global.logical_maximum < parser->global.logical_minimum) {
210 dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum); 217 dbg_hid("logical range invalid %d %d\n", parser->global.logical_minimum, parser->global.logical_maximum);
211 return -1; 218 return -1;
212 } 219 }
213 220
@@ -287,7 +294,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
287 case HID_GLOBAL_ITEM_TAG_PUSH: 294 case HID_GLOBAL_ITEM_TAG_PUSH:
288 295
289 if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { 296 if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) {
290 dbg("global enviroment stack overflow"); 297 dbg_hid("global enviroment stack overflow\n");
291 return -1; 298 return -1;
292 } 299 }
293 300
@@ -298,7 +305,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
298 case HID_GLOBAL_ITEM_TAG_POP: 305 case HID_GLOBAL_ITEM_TAG_POP:
299 306
300 if (!parser->global_stack_ptr) { 307 if (!parser->global_stack_ptr) {
301 dbg("global enviroment stack underflow"); 308 dbg_hid("global enviroment stack underflow\n");
302 return -1; 309 return -1;
303 } 310 }
304 311
@@ -342,27 +349,27 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
342 349
343 case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: 350 case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
344 if ((parser->global.report_size = item_udata(item)) > 32) { 351 if ((parser->global.report_size = item_udata(item)) > 32) {
345 dbg("invalid report_size %d", parser->global.report_size); 352 dbg_hid("invalid report_size %d\n", parser->global.report_size);
346 return -1; 353 return -1;
347 } 354 }
348 return 0; 355 return 0;
349 356
350 case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: 357 case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
351 if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) { 358 if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) {
352 dbg("invalid report_count %d", parser->global.report_count); 359 dbg_hid("invalid report_count %d\n", parser->global.report_count);
353 return -1; 360 return -1;
354 } 361 }
355 return 0; 362 return 0;
356 363
357 case HID_GLOBAL_ITEM_TAG_REPORT_ID: 364 case HID_GLOBAL_ITEM_TAG_REPORT_ID:
358 if ((parser->global.report_id = item_udata(item)) == 0) { 365 if ((parser->global.report_id = item_udata(item)) == 0) {
359 dbg("report_id 0 is invalid"); 366 dbg_hid("report_id 0 is invalid\n");
360 return -1; 367 return -1;
361 } 368 }
362 return 0; 369 return 0;
363 370
364 default: 371 default:
365 dbg("unknown global tag 0x%x", item->tag); 372 dbg_hid("unknown global tag 0x%x\n", item->tag);
366 return -1; 373 return -1;
367 } 374 }
368} 375}
@@ -377,7 +384,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
377 unsigned n; 384 unsigned n;
378 385
379 if (item->size == 0) { 386 if (item->size == 0) {
380 dbg("item data expected for local item"); 387 dbg_hid("item data expected for local item\n");
381 return -1; 388 return -1;
382 } 389 }
383 390
@@ -395,14 +402,14 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
395 * items and the first delimiter set. 402 * items and the first delimiter set.
396 */ 403 */
397 if (parser->local.delimiter_depth != 0) { 404 if (parser->local.delimiter_depth != 0) {
398 dbg("nested delimiters"); 405 dbg_hid("nested delimiters\n");
399 return -1; 406 return -1;
400 } 407 }
401 parser->local.delimiter_depth++; 408 parser->local.delimiter_depth++;
402 parser->local.delimiter_branch++; 409 parser->local.delimiter_branch++;
403 } else { 410 } else {
404 if (parser->local.delimiter_depth < 1) { 411 if (parser->local.delimiter_depth < 1) {
405 dbg("bogus close delimiter"); 412 dbg_hid("bogus close delimiter\n");
406 return -1; 413 return -1;
407 } 414 }
408 parser->local.delimiter_depth--; 415 parser->local.delimiter_depth--;
@@ -412,7 +419,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
412 case HID_LOCAL_ITEM_TAG_USAGE: 419 case HID_LOCAL_ITEM_TAG_USAGE:
413 420
414 if (parser->local.delimiter_branch > 1) { 421 if (parser->local.delimiter_branch > 1) {
415 dbg("alternative usage ignored"); 422 dbg_hid("alternative usage ignored\n");
416 return 0; 423 return 0;
417 } 424 }
418 425
@@ -424,7 +431,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
424 case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: 431 case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
425 432
426 if (parser->local.delimiter_branch > 1) { 433 if (parser->local.delimiter_branch > 1) {
427 dbg("alternative usage ignored"); 434 dbg_hid("alternative usage ignored\n");
428 return 0; 435 return 0;
429 } 436 }
430 437
@@ -437,7 +444,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
437 case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: 444 case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
438 445
439 if (parser->local.delimiter_branch > 1) { 446 if (parser->local.delimiter_branch > 1) {
440 dbg("alternative usage ignored"); 447 dbg_hid("alternative usage ignored\n");
441 return 0; 448 return 0;
442 } 449 }
443 450
@@ -446,14 +453,14 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
446 453
447 for (n = parser->local.usage_minimum; n <= data; n++) 454 for (n = parser->local.usage_minimum; n <= data; n++)
448 if (hid_add_usage(parser, n)) { 455 if (hid_add_usage(parser, n)) {
449 dbg("hid_add_usage failed\n"); 456 dbg_hid("hid_add_usage failed\n");
450 return -1; 457 return -1;
451 } 458 }
452 return 0; 459 return 0;
453 460
454 default: 461 default:
455 462
456 dbg("unknown local item tag 0x%x", item->tag); 463 dbg_hid("unknown local item tag 0x%x\n", item->tag);
457 return 0; 464 return 0;
458 } 465 }
459 return 0; 466 return 0;
@@ -487,7 +494,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
487 ret = hid_add_field(parser, HID_FEATURE_REPORT, data); 494 ret = hid_add_field(parser, HID_FEATURE_REPORT, data);
488 break; 495 break;
489 default: 496 default:
490 dbg("unknown main item tag 0x%x", item->tag); 497 dbg_hid("unknown main item tag 0x%x\n", item->tag);
491 ret = 0; 498 ret = 0;
492 } 499 }
493 500
@@ -502,7 +509,7 @@ static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
502 509
503static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) 510static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item)
504{ 511{
505 dbg("reserved item type, tag 0x%x", item->tag); 512 dbg_hid("reserved item type, tag 0x%x\n", item->tag);
506 return 0; 513 return 0;
507} 514}
508 515
@@ -667,14 +674,14 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size)
667 while ((start = fetch_item(start, end, &item)) != NULL) { 674 while ((start = fetch_item(start, end, &item)) != NULL) {
668 675
669 if (item.format != HID_ITEM_FORMAT_SHORT) { 676 if (item.format != HID_ITEM_FORMAT_SHORT) {
670 dbg("unexpected long global item"); 677 dbg_hid("unexpected long global item\n");
671 hid_free_device(device); 678 hid_free_device(device);
672 vfree(parser); 679 vfree(parser);
673 return NULL; 680 return NULL;
674 } 681 }
675 682
676 if (dispatch_type[item.type](parser, &item)) { 683 if (dispatch_type[item.type](parser, &item)) {
677 dbg("item %u %u %u %u parsing failed\n", 684 dbg_hid("item %u %u %u %u parsing failed\n",
678 item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); 685 item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
679 hid_free_device(device); 686 hid_free_device(device);
680 vfree(parser); 687 vfree(parser);
@@ -683,13 +690,13 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size)
683 690
684 if (start == end) { 691 if (start == end) {
685 if (parser->collection_stack_ptr) { 692 if (parser->collection_stack_ptr) {
686 dbg("unbalanced collection at end of report description"); 693 dbg_hid("unbalanced collection at end of report description\n");
687 hid_free_device(device); 694 hid_free_device(device);
688 vfree(parser); 695 vfree(parser);
689 return NULL; 696 return NULL;
690 } 697 }
691 if (parser->local.delimiter_depth) { 698 if (parser->local.delimiter_depth) {
692 dbg("unbalanced delimiter at end of report description"); 699 dbg_hid("unbalanced delimiter at end of report description\n");
693 hid_free_device(device); 700 hid_free_device(device);
694 vfree(parser); 701 vfree(parser);
695 return NULL; 702 return NULL;
@@ -699,7 +706,7 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size)
699 } 706 }
700 } 707 }
701 708
702 dbg("item fetching failed at offset %d\n", (int)(end - start)); 709 dbg_hid("item fetching failed at offset %d\n", (int)(end - start));
703 hid_free_device(device); 710 hid_free_device(device);
704 vfree(parser); 711 vfree(parser);
705 return NULL; 712 return NULL;
@@ -915,13 +922,13 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
915 hid_dump_input(field->usage + offset, value); 922 hid_dump_input(field->usage + offset, value);
916 923
917 if (offset >= field->report_count) { 924 if (offset >= field->report_count) {
918 dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count); 925 dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count);
919 hid_dump_field(field, 8); 926 hid_dump_field(field, 8);
920 return -1; 927 return -1;
921 } 928 }
922 if (field->logical_minimum < 0) { 929 if (field->logical_minimum < 0) {
923 if (value != snto32(s32ton(value, size), size)) { 930 if (value != snto32(s32ton(value, size), size)) {
924 dbg("value %d is out of range", value); 931 dbg_hid("value %d is out of range\n", value);
925 return -1; 932 return -1;
926 } 933 }
927 } 934 }
@@ -934,19 +941,17 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
934{ 941{
935 struct hid_report_enum *report_enum = hid->report_enum + type; 942 struct hid_report_enum *report_enum = hid->report_enum + type;
936 struct hid_report *report; 943 struct hid_report *report;
937 int n, rsize; 944 int n, rsize, i;
938 945
939 if (!hid) 946 if (!hid)
940 return -ENODEV; 947 return -ENODEV;
941 948
942 if (!size) { 949 if (!size) {
943 dbg("empty report"); 950 dbg_hid("empty report\n");
944 return -1; 951 return -1;
945 } 952 }
946 953
947#ifdef CONFIG_HID_DEBUG 954 dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
948 printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
949#endif
950 955
951 n = 0; /* Normally report number is 0 */ 956 n = 0; /* Normally report number is 0 */
952 if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ 957 if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */
@@ -954,25 +959,21 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
954 size--; 959 size--;
955 } 960 }
956 961
957#ifdef CONFIG_HID_DEBUG 962 /* dump the report descriptor */
958 { 963 dbg_hid("report %d (size %u) = ", n, size);
959 int i; 964 for (i = 0; i < size; i++)
960 printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, size); 965 dbg_hid_line(" %02x", data[i]);
961 for (i = 0; i < size; i++) 966 dbg_hid_line("\n");
962 printk(" %02x", data[i]);
963 printk("\n");
964 }
965#endif
966 967
967 if (!(report = report_enum->report_id_hash[n])) { 968 if (!(report = report_enum->report_id_hash[n])) {
968 dbg("undefined report_id %d received", n); 969 dbg_hid("undefined report_id %d received\n", n);
969 return -1; 970 return -1;
970 } 971 }
971 972
972 rsize = ((report->size - 1) >> 3) + 1; 973 rsize = ((report->size - 1) >> 3) + 1;
973 974
974 if (size < rsize) { 975 if (size < rsize) {
975 dbg("report %d is too short, (%d < %d)", report->id, size, rsize); 976 dbg_hid("report %d is too short, (%d < %d)\n", report->id, size, rsize);
976 memset(data + size, 0, rsize - size); 977 memset(data + size, 0, rsize - size);
977 } 978 }
978 979