aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/Kconfig29
-rw-r--r--drivers/hid/Makefile6
-rw-r--r--drivers/hid/hid-a4tech.c4
-rw-r--r--drivers/hid/hid-apple.c4
-rw-r--r--drivers/hid/hid-belkin.c4
-rw-r--r--drivers/hid/hid-cherry.c4
-rw-r--r--drivers/hid/hid-chicony.c4
-rw-r--r--drivers/hid/hid-core.c71
-rw-r--r--drivers/hid/hid-cypress.c4
-rw-r--r--drivers/hid/hid-debug.c439
-rw-r--r--drivers/hid/hid-ezkey.c4
-rw-r--r--drivers/hid/hid-gyration.c4
-rw-r--r--drivers/hid/hid-ids.h14
-rw-r--r--drivers/hid/hid-input.c13
-rw-r--r--drivers/hid/hid-kensington.c4
-rw-r--r--drivers/hid/hid-kye.c4
-rw-r--r--drivers/hid/hid-lg.c6
-rw-r--r--drivers/hid/hid-lgff.c6
-rw-r--r--drivers/hid/hid-microsoft.c4
-rw-r--r--drivers/hid/hid-monterey.c4
-rw-r--r--drivers/hid/hid-ntrig.c37
-rw-r--r--drivers/hid/hid-petalynx.c4
-rw-r--r--drivers/hid/hid-pl.c4
-rw-r--r--drivers/hid/hid-samsung.c43
-rw-r--r--drivers/hid/hid-sjoy.c4
-rw-r--r--drivers/hid/hid-sony.c4
-rw-r--r--drivers/hid/hid-sunplus.c4
-rw-r--r--drivers/hid/hid-tmff.c10
-rw-r--r--drivers/hid/hid-topseed.c4
-rw-r--r--drivers/hid/hid-twinhan.c147
-rw-r--r--drivers/hid/hid-wacom.c4
-rw-r--r--drivers/hid/hid-zpff.c4
-rw-r--r--drivers/hid/usbhid/hid-core.c12
-rw-r--r--drivers/hid/usbhid/hid-quirks.c2
-rw-r--r--drivers/hid/usbhid/hiddev.c2
35 files changed, 713 insertions, 204 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 7831a0318d3c..111afbe8de03 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
@@ -152,6 +137,13 @@ config HID_GYRATION
152 ---help--- 137 ---help---
153 Support for Gyration remote control. 138 Support for Gyration remote control.
154 139
140config HID_TWINHAN
141 tristate "Twinhan" if EMBEDDED
142 depends on USB_HID
143 default !EMBEDDED
144 ---help---
145 Support for Twinhan IR remote control.
146
155config HID_KENSINGTON 147config HID_KENSINGTON
156 tristate "Kensington" if EMBEDDED 148 tristate "Kensington" if EMBEDDED
157 depends on USB_HID 149 depends on USB_HID
@@ -176,6 +168,7 @@ config LOGITECH_FF
176 - Logitech WingMan Cordless RumblePad 2 168 - Logitech WingMan Cordless RumblePad 2
177 - Logitech WingMan Force 3D 169 - Logitech WingMan Force 3D
178 - Logitech Formula Force EX 170 - Logitech Formula Force EX
171 - Logitech WingMan Formula Force GP
179 - Logitech MOMO Force wheel 172 - Logitech MOMO Force wheel
180 173
181 and if you want to enable force feedback for them. 174 and if you want to enable force feedback for them.
@@ -314,9 +307,9 @@ config THRUSTMASTER_FF
314 depends on HID_THRUSTMASTER 307 depends on HID_THRUSTMASTER
315 select INPUT_FF_MEMLESS 308 select INPUT_FF_MEMLESS
316 ---help--- 309 ---help---
317 Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or 310 Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or 3,
318 a THRUSTMASTER Ferrari GT Rumble Force or Force Feedback Wheel and 311 a THRUSTMASTER Dual Trigger 3-in-1 or a THRUSTMASTER Ferrari GT
319 want to enable force feedback support for it. 312 Rumble Force or Force Feedback Wheel.
320 313
321config HID_WACOM 314config HID_WACOM
322 tristate "Wacom Bluetooth devices support" if EMBEDDED 315 tristate "Wacom Bluetooth devices support" if EMBEDDED
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index db35151673b1..0de2dff5542c 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
@@ -40,6 +43,7 @@ obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o
40obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o 43obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
41obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o 44obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o
42obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o 45obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
46obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o
43obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o 47obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o
44obj-$(CONFIG_HID_WACOM) += hid-wacom.o 48obj-$(CONFIG_HID_WACOM) += hid-wacom.o
45 49
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c
index 42ea359e94cf..df474c699fb8 100644
--- a/drivers/hid/hid-a4tech.c
+++ b/drivers/hid/hid-a4tech.c
@@ -145,12 +145,12 @@ static struct hid_driver a4_driver = {
145 .remove = a4_remove, 145 .remove = a4_remove,
146}; 146};
147 147
148static int a4_init(void) 148static int __init a4_init(void)
149{ 149{
150 return hid_register_driver(&a4_driver); 150 return hid_register_driver(&a4_driver);
151} 151}
152 152
153static void a4_exit(void) 153static void __exit a4_exit(void)
154{ 154{
155 hid_unregister_driver(&a4_driver); 155 hid_unregister_driver(&a4_driver);
156} 156}
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index 303ccce05bb3..4b96e7a898cf 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -451,7 +451,7 @@ static struct hid_driver apple_driver = {
451 .input_mapped = apple_input_mapped, 451 .input_mapped = apple_input_mapped,
452}; 452};
453 453
454static int apple_init(void) 454static int __init apple_init(void)
455{ 455{
456 int ret; 456 int ret;
457 457
@@ -462,7 +462,7 @@ static int apple_init(void)
462 return ret; 462 return ret;
463} 463}
464 464
465static void apple_exit(void) 465static void __exit apple_exit(void)
466{ 466{
467 hid_unregister_driver(&apple_driver); 467 hid_unregister_driver(&apple_driver);
468} 468}
diff --git a/drivers/hid/hid-belkin.c b/drivers/hid/hid-belkin.c
index 2f6723133a4b..4ce7aa3a519f 100644
--- a/drivers/hid/hid-belkin.c
+++ b/drivers/hid/hid-belkin.c
@@ -88,12 +88,12 @@ static struct hid_driver belkin_driver = {
88 .probe = belkin_probe, 88 .probe = belkin_probe,
89}; 89};
90 90
91static int belkin_init(void) 91static int __init belkin_init(void)
92{ 92{
93 return hid_register_driver(&belkin_driver); 93 return hid_register_driver(&belkin_driver);
94} 94}
95 95
96static void belkin_exit(void) 96static void __exit belkin_exit(void)
97{ 97{
98 hid_unregister_driver(&belkin_driver); 98 hid_unregister_driver(&belkin_driver);
99} 99}
diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c
index ab8209e7e45c..7e597d7f770f 100644
--- a/drivers/hid/hid-cherry.c
+++ b/drivers/hid/hid-cherry.c
@@ -70,12 +70,12 @@ static struct hid_driver ch_driver = {
70 .input_mapping = ch_input_mapping, 70 .input_mapping = ch_input_mapping,
71}; 71};
72 72
73static int ch_init(void) 73static int __init ch_init(void)
74{ 74{
75 return hid_register_driver(&ch_driver); 75 return hid_register_driver(&ch_driver);
76} 76}
77 77
78static void ch_exit(void) 78static void __exit ch_exit(void)
79{ 79{
80 hid_unregister_driver(&ch_driver); 80 hid_unregister_driver(&ch_driver);
81} 81}
diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c
index 7f91076d8493..8965ad93d510 100644
--- a/drivers/hid/hid-chicony.c
+++ b/drivers/hid/hid-chicony.c
@@ -63,12 +63,12 @@ static struct hid_driver ch_driver = {
63 .input_mapping = ch_input_mapping, 63 .input_mapping = ch_input_mapping,
64}; 64};
65 65
66static int ch_init(void) 66static int __init ch_init(void)
67{ 67{
68 return hid_register_driver(&ch_driver); 68 return hid_register_driver(&ch_driver);
69} 69}
70 70
71static void ch_exit(void) 71static void __exit ch_exit(void)
72{ 72{
73 hid_unregister_driver(&ch_driver); 73 hid_unregister_driver(&ch_driver);
74} 74}
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 5eb10c2ce665..342b7d36d7bb 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, "toggle HID debugging messages");
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.
@@ -861,7 +859,7 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field,
861 struct hid_driver *hdrv = hid->driver; 859 struct hid_driver *hdrv = hid->driver;
862 int ret; 860 int ret;
863 861
864 hid_dump_input(usage, value); 862 hid_dump_input(hid, usage, value);
865 863
866 if (hdrv && hdrv->event && hid_match_usage(hid, usage)) { 864 if (hdrv && hdrv->event && hid_match_usage(hid, usage)) {
867 ret = hdrv->event(hid, field, usage, value); 865 ret = hdrv->event(hid, field, usage, value);
@@ -983,11 +981,10 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
983{ 981{
984 unsigned size = field->report_size; 982 unsigned size = field->report_size;
985 983
986 hid_dump_input(field->usage + offset, value); 984 hid_dump_input(field->report->device, field->usage + offset, 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) {
@@ -1078,6 +1075,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
1078 struct hid_report_enum *report_enum; 1075 struct hid_report_enum *report_enum;
1079 struct hid_driver *hdrv; 1076 struct hid_driver *hdrv;
1080 struct hid_report *report; 1077 struct hid_report *report;
1078 char *buf;
1081 unsigned int i; 1079 unsigned int i;
1082 int ret; 1080 int ret;
1083 1081
@@ -1091,18 +1089,38 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
1091 return -1; 1089 return -1;
1092 } 1090 }
1093 1091
1094 dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un"); 1092 buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE,
1093 interrupt ? GFP_ATOMIC : GFP_KERNEL);
1094
1095 if (!buf) {
1096 report = hid_get_report(report_enum, data);
1097 goto nomem;
1098 }
1099
1100 snprintf(buf, HID_DEBUG_BUFSIZE - 1,
1101 "\nreport (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
1102 hid_debug_event(hid, buf);
1095 1103
1096 report = hid_get_report(report_enum, data); 1104 report = hid_get_report(report_enum, data);
1097 if (!report) 1105 if (!report) {
1106 kfree(buf);
1098 return -1; 1107 return -1;
1108 }
1099 1109
1100 /* dump the report */ 1110 /* dump the report */
1101 dbg_hid("report %d (size %u) = ", report->id, size); 1111 snprintf(buf, HID_DEBUG_BUFSIZE - 1,
1102 for (i = 0; i < size; i++) 1112 "report %d (size %u) = ", report->id, size);
1103 dbg_hid_line(" %02x", data[i]); 1113 hid_debug_event(hid, buf);
1104 dbg_hid_line("\n"); 1114 for (i = 0; i < size; i++) {
1115 snprintf(buf, HID_DEBUG_BUFSIZE - 1,
1116 " %02x", data[i]);
1117 hid_debug_event(hid, buf);
1118 }
1119 hid_debug_event(hid, "\n");
1120
1121 kfree(buf);
1105 1122
1123nomem:
1106 if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) { 1124 if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) {
1107 ret = hdrv->raw_event(hid, report, data, size); 1125 ret = hdrv->raw_event(hid, report, data, size);
1108 if (ret != 0) 1126 if (ret != 0)
@@ -1292,6 +1310,7 @@ static const struct hid_device_id hid_blacklist[] = {
1292 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, 1310 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
1293 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, 1311 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
1294 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, 1312 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
1313 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) },
1295 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, 1314 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
1296 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) }, 1315 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) },
1297 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, 1316 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
@@ -1311,15 +1330,17 @@ static const struct hid_device_id hid_blacklist[] = {
1311 { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, 1330 { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
1312 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, 1331 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
1313 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, 1332 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
1333 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
1334 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) },
1314 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, 1335 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
1315 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, 1336 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
1316 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, 1337 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
1338 { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
1317 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, 1339 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
1318 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, 1340 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
1319 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, 1341 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
1320 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, 1342 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
1321 1343
1322 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) },
1323 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, 1344 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
1324 { } 1345 { }
1325}; 1346};
@@ -1622,12 +1643,8 @@ static const struct hid_device_id hid_ignore_list[] = {
1622 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) }, 1643 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) },
1623 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) }, 1644 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) },
1624 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, 1645 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
1646 { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) },
1625 { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) }, 1647 { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) },
1626 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) },
1627 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) },
1628 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) },
1629 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4) },
1630 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5) },
1631 { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) }, 1648 { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) },
1632 { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) }, 1649 { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) },
1633 { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, 1650 { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
@@ -1694,6 +1711,11 @@ static bool hid_ignore(struct hid_device *hdev)
1694 hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST) 1711 hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST)
1695 return true; 1712 return true;
1696 break; 1713 break;
1714 case USB_VENDOR_ID_SOUNDGRAPH:
1715 if (hdev->product >= USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST &&
1716 hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST)
1717 return true;
1718 break;
1697 } 1719 }
1698 1720
1699 if (hdev->type == HID_TYPE_USBMOUSE && 1721 if (hdev->type == HID_TYPE_USBMOUSE &&
@@ -1725,6 +1747,8 @@ int hid_add_device(struct hid_device *hdev)
1725 if (!ret) 1747 if (!ret)
1726 hdev->status |= HID_STAT_ADDED; 1748 hdev->status |= HID_STAT_ADDED;
1727 1749
1750 hid_debug_register(hdev, dev_name(&hdev->dev));
1751
1728 return ret; 1752 return ret;
1729} 1753}
1730EXPORT_SYMBOL_GPL(hid_add_device); 1754EXPORT_SYMBOL_GPL(hid_add_device);
@@ -1761,6 +1785,9 @@ struct hid_device *hid_allocate_device(void)
1761 for (i = 0; i < HID_REPORT_TYPES; i++) 1785 for (i = 0; i < HID_REPORT_TYPES; i++)
1762 INIT_LIST_HEAD(&hdev->report_enum[i].report_list); 1786 INIT_LIST_HEAD(&hdev->report_enum[i].report_list);
1763 1787
1788 init_waitqueue_head(&hdev->debug_wait);
1789 INIT_LIST_HEAD(&hdev->debug_list);
1790
1764 return hdev; 1791 return hdev;
1765err: 1792err:
1766 put_device(&hdev->dev); 1793 put_device(&hdev->dev);
@@ -1772,6 +1799,7 @@ static void hid_remove_device(struct hid_device *hdev)
1772{ 1799{
1773 if (hdev->status & HID_STAT_ADDED) { 1800 if (hdev->status & HID_STAT_ADDED) {
1774 device_del(&hdev->dev); 1801 device_del(&hdev->dev);
1802 hid_debug_unregister(hdev);
1775 hdev->status &= ~HID_STAT_ADDED; 1803 hdev->status &= ~HID_STAT_ADDED;
1776 } 1804 }
1777} 1805}
@@ -1847,6 +1875,10 @@ static int __init hid_init(void)
1847{ 1875{
1848 int ret; 1876 int ret;
1849 1877
1878 if (hid_debug)
1879 printk(KERN_WARNING "HID: hid_debug is now used solely for parser and driver debugging.\n"
1880 "HID: debugfs is now used for inspecting the device (report descriptor, reports)\n");
1881
1850 ret = bus_register(&hid_bus_type); 1882 ret = bus_register(&hid_bus_type);
1851 if (ret) { 1883 if (ret) {
1852 printk(KERN_ERR "HID: can't register hid bus\n"); 1884 printk(KERN_ERR "HID: can't register hid bus\n");
@@ -1857,6 +1889,8 @@ static int __init hid_init(void)
1857 if (ret) 1889 if (ret)
1858 goto err_bus; 1890 goto err_bus;
1859 1891
1892 hid_debug_init();
1893
1860 return 0; 1894 return 0;
1861err_bus: 1895err_bus:
1862 bus_unregister(&hid_bus_type); 1896 bus_unregister(&hid_bus_type);
@@ -1866,6 +1900,7 @@ err:
1866 1900
1867static void __exit hid_exit(void) 1901static void __exit hid_exit(void)
1868{ 1902{
1903 hid_debug_exit();
1869 hidraw_exit(); 1904 hidraw_exit();
1870 bus_unregister(&hid_bus_type); 1905 bus_unregister(&hid_bus_type);
1871} 1906}
diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
index 9d6d3b91773b..62e9cb10e88c 100644
--- a/drivers/hid/hid-cypress.c
+++ b/drivers/hid/hid-cypress.c
@@ -141,12 +141,12 @@ static struct hid_driver cp_driver = {
141 .probe = cp_probe, 141 .probe = cp_probe,
142}; 142};
143 143
144static int cp_init(void) 144static int __init cp_init(void)
145{ 145{
146 return hid_register_driver(&cp_driver); 146 return hid_register_driver(&cp_driver);
147} 147}
148 148
149static void cp_exit(void) 149static void __exit cp_exit(void)
150{ 150{
151 hid_unregister_driver(&cp_driver); 151 hid_unregister_driver(&cp_driver);
152} 152}
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index 04359ed64b87..6abd0369aedb 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,17 @@
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>
31#include <linux/sched.h>
32#include <linux/uaccess.h>
33#include <linux/poll.h>
34
29#include <linux/hid.h> 35#include <linux/hid.h>
30#include <linux/hid-debug.h> 36#include <linux/hid-debug.h>
31 37
38static struct dentry *hid_debug_root;
39
32struct hid_usage_entry { 40struct hid_usage_entry {
33 unsigned page; 41 unsigned page;
34 unsigned usage; 42 unsigned usage;
@@ -339,72 +347,120 @@ static const struct hid_usage_entry hid_usage_table[] = {
339 { 0, 0, NULL } 347 { 0, 0, NULL }
340}; 348};
341 349
342static void resolv_usage_page(unsigned page) { 350/* Either output directly into simple seq_file, or (if f == NULL)
351 * allocate a separate buffer that will then be passed to the 'events'
352 * ringbuffer.
353 *
354 * This is because these functions can be called both for "one-shot"
355 * "rdesc" while resolving, or for blocking "events".
356 *
357 * This holds both for resolv_usage_page() and hid_resolv_usage().
358 */
359static char *resolv_usage_page(unsigned page, struct seq_file *f) {
343 const struct hid_usage_entry *p; 360 const struct hid_usage_entry *p;
361 char *buf = NULL;
362
363 if (!f) {
364 buf = kzalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC);
365 if (!buf)
366 return ERR_PTR(-ENOMEM);
367 }
344 368
345 for (p = hid_usage_table; p->description; p++) 369 for (p = hid_usage_table; p->description; p++)
346 if (p->page == page) { 370 if (p->page == page) {
347 printk("%s", p->description); 371 if (!f) {
348 return; 372 snprintf(buf, HID_DEBUG_BUFSIZE, "%s",
373 p->description);
374 return buf;
375 }
376 else {
377 seq_printf(f, "%s", p->description);
378 return NULL;
379 }
349 } 380 }
350 printk("%04x", page); 381 if (!f)
382 snprintf(buf, HID_DEBUG_BUFSIZE, "%04x", page);
383 else
384 seq_printf(f, "%04x", page);
385 return buf;
351} 386}
352 387
353void hid_resolv_usage(unsigned usage) { 388char *hid_resolv_usage(unsigned usage, struct seq_file *f) {
354 const struct hid_usage_entry *p; 389 const struct hid_usage_entry *p;
390 char *buf = NULL;
391 int len = 0;
392
393 buf = resolv_usage_page(usage >> 16, f);
394 if (IS_ERR(buf)) {
395 printk(KERN_ERR "error allocating HID debug buffer\n");
396 return NULL;
397 }
355 398
356 if (!hid_debug)
357 return;
358 399
359 resolv_usage_page(usage >> 16); 400 if (!f) {
360 printk("."); 401 len = strlen(buf);
402 snprintf(buf+len, max(0, HID_DEBUG_BUFSIZE - len), ".");
403 len++;
404 }
405 else {
406 seq_printf(f, ".");
407 }
361 for (p = hid_usage_table; p->description; p++) 408 for (p = hid_usage_table; p->description; p++)
362 if (p->page == (usage >> 16)) { 409 if (p->page == (usage >> 16)) {
363 for(++p; p->description && p->usage != 0; p++) 410 for(++p; p->description && p->usage != 0; p++)
364 if (p->usage == (usage & 0xffff)) { 411 if (p->usage == (usage & 0xffff)) {
365 printk("%s", p->description); 412 if (!f)
366 return; 413 snprintf(buf + len,
414 max(0,HID_DEBUG_BUFSIZE - len - 1),
415 "%s", p->description);
416 else
417 seq_printf(f,
418 "%s",
419 p->description);
420 return buf;
367 } 421 }
368 break; 422 break;
369 } 423 }
370 printk("%04x", usage & 0xffff); 424 if (!f)
425 snprintf(buf + len, max(0, HID_DEBUG_BUFSIZE - len - 1),
426 "%04x", usage & 0xffff);
427 else
428 seq_printf(f, "%04x", usage & 0xffff);
429 return buf;
371} 430}
372EXPORT_SYMBOL_GPL(hid_resolv_usage); 431EXPORT_SYMBOL_GPL(hid_resolv_usage);
373 432
374static void tab(int n) { 433static void tab(int n, struct seq_file *f) {
375 printk(KERN_DEBUG "%*s", n, ""); 434 seq_printf(f, "%*s", n, "");
376} 435}
377 436
378void hid_dump_field(struct hid_field *field, int n) { 437void hid_dump_field(struct hid_field *field, int n, struct seq_file *f) {
379 int j; 438 int j;
380 439
381 if (!hid_debug)
382 return;
383
384 if (field->physical) { 440 if (field->physical) {
385 tab(n); 441 tab(n, f);
386 printk("Physical("); 442 seq_printf(f, "Physical(");
387 hid_resolv_usage(field->physical); printk(")\n"); 443 hid_resolv_usage(field->physical, f); seq_printf(f, ")\n");
388 } 444 }
389 if (field->logical) { 445 if (field->logical) {
390 tab(n); 446 tab(n, f);
391 printk("Logical("); 447 seq_printf(f, "Logical(");
392 hid_resolv_usage(field->logical); printk(")\n"); 448 hid_resolv_usage(field->logical, f); seq_printf(f, ")\n");
393 } 449 }
394 tab(n); printk("Usage(%d)\n", field->maxusage); 450 tab(n, f); seq_printf(f, "Usage(%d)\n", field->maxusage);
395 for (j = 0; j < field->maxusage; j++) { 451 for (j = 0; j < field->maxusage; j++) {
396 tab(n+2); hid_resolv_usage(field->usage[j].hid); printk("\n"); 452 tab(n+2, f); hid_resolv_usage(field->usage[j].hid, f); seq_printf(f, "\n");
397 } 453 }
398 if (field->logical_minimum != field->logical_maximum) { 454 if (field->logical_minimum != field->logical_maximum) {
399 tab(n); printk("Logical Minimum(%d)\n", field->logical_minimum); 455 tab(n, f); seq_printf(f, "Logical Minimum(%d)\n", field->logical_minimum);
400 tab(n); printk("Logical Maximum(%d)\n", field->logical_maximum); 456 tab(n, f); seq_printf(f, "Logical Maximum(%d)\n", field->logical_maximum);
401 } 457 }
402 if (field->physical_minimum != field->physical_maximum) { 458 if (field->physical_minimum != field->physical_maximum) {
403 tab(n); printk("Physical Minimum(%d)\n", field->physical_minimum); 459 tab(n, f); seq_printf(f, "Physical Minimum(%d)\n", field->physical_minimum);
404 tab(n); printk("Physical Maximum(%d)\n", field->physical_maximum); 460 tab(n, f); seq_printf(f, "Physical Maximum(%d)\n", field->physical_maximum);
405 } 461 }
406 if (field->unit_exponent) { 462 if (field->unit_exponent) {
407 tab(n); printk("Unit Exponent(%d)\n", field->unit_exponent); 463 tab(n, f); seq_printf(f, "Unit Exponent(%d)\n", field->unit_exponent);
408 } 464 }
409 if (field->unit) { 465 if (field->unit) {
410 static const char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" }; 466 static const char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" };
@@ -425,77 +481,75 @@ void hid_dump_field(struct hid_field *field, int n) {
425 data >>= 4; 481 data >>= 4;
426 482
427 if(sys > 4) { 483 if(sys > 4) {
428 tab(n); printk("Unit(Invalid)\n"); 484 tab(n, f); seq_printf(f, "Unit(Invalid)\n");
429 } 485 }
430 else { 486 else {
431 int earlier_unit = 0; 487 int earlier_unit = 0;
432 488
433 tab(n); printk("Unit(%s : ", systems[sys]); 489 tab(n, f); seq_printf(f, "Unit(%s : ", systems[sys]);
434 490
435 for (i=1 ; i<sizeof(__u32)*2 ; i++) { 491 for (i=1 ; i<sizeof(__u32)*2 ; i++) {
436 char nibble = data & 0xf; 492 char nibble = data & 0xf;
437 data >>= 4; 493 data >>= 4;
438 if (nibble != 0) { 494 if (nibble != 0) {
439 if(earlier_unit++ > 0) 495 if(earlier_unit++ > 0)
440 printk("*"); 496 seq_printf(f, "*");
441 printk("%s", units[sys][i]); 497 seq_printf(f, "%s", units[sys][i]);
442 if(nibble != 1) { 498 if(nibble != 1) {
443 /* This is a _signed_ nibble(!) */ 499 /* This is a _signed_ nibble(!) */
444 500
445 int val = nibble & 0x7; 501 int val = nibble & 0x7;
446 if(nibble & 0x08) 502 if(nibble & 0x08)
447 val = -((0x7 & ~val) +1); 503 val = -((0x7 & ~val) +1);
448 printk("^%d", val); 504 seq_printf(f, "^%d", val);
449 } 505 }
450 } 506 }
451 } 507 }
452 printk(")\n"); 508 seq_printf(f, ")\n");
453 } 509 }
454 } 510 }
455 tab(n); printk("Report Size(%u)\n", field->report_size); 511 tab(n, f); seq_printf(f, "Report Size(%u)\n", field->report_size);
456 tab(n); printk("Report Count(%u)\n", field->report_count); 512 tab(n, f); seq_printf(f, "Report Count(%u)\n", field->report_count);
457 tab(n); printk("Report Offset(%u)\n", field->report_offset); 513 tab(n, f); seq_printf(f, "Report Offset(%u)\n", field->report_offset);
458 514
459 tab(n); printk("Flags( "); 515 tab(n, f); seq_printf(f, "Flags( ");
460 j = field->flags; 516 j = field->flags;
461 printk("%s", HID_MAIN_ITEM_CONSTANT & j ? "Constant " : ""); 517 seq_printf(f, "%s", HID_MAIN_ITEM_CONSTANT & j ? "Constant " : "");
462 printk("%s", HID_MAIN_ITEM_VARIABLE & j ? "Variable " : "Array "); 518 seq_printf(f, "%s", HID_MAIN_ITEM_VARIABLE & j ? "Variable " : "Array ");
463 printk("%s", HID_MAIN_ITEM_RELATIVE & j ? "Relative " : "Absolute "); 519 seq_printf(f, "%s", HID_MAIN_ITEM_RELATIVE & j ? "Relative " : "Absolute ");
464 printk("%s", HID_MAIN_ITEM_WRAP & j ? "Wrap " : ""); 520 seq_printf(f, "%s", HID_MAIN_ITEM_WRAP & j ? "Wrap " : "");
465 printk("%s", HID_MAIN_ITEM_NONLINEAR & j ? "NonLinear " : ""); 521 seq_printf(f, "%s", HID_MAIN_ITEM_NONLINEAR & j ? "NonLinear " : "");
466 printk("%s", HID_MAIN_ITEM_NO_PREFERRED & j ? "NoPreferredState " : ""); 522 seq_printf(f, "%s", HID_MAIN_ITEM_NO_PREFERRED & j ? "NoPreferredState " : "");
467 printk("%s", HID_MAIN_ITEM_NULL_STATE & j ? "NullState " : ""); 523 seq_printf(f, "%s", HID_MAIN_ITEM_NULL_STATE & j ? "NullState " : "");
468 printk("%s", HID_MAIN_ITEM_VOLATILE & j ? "Volatile " : ""); 524 seq_printf(f, "%s", HID_MAIN_ITEM_VOLATILE & j ? "Volatile " : "");
469 printk("%s", HID_MAIN_ITEM_BUFFERED_BYTE & j ? "BufferedByte " : ""); 525 seq_printf(f, "%s", HID_MAIN_ITEM_BUFFERED_BYTE & j ? "BufferedByte " : "");
470 printk(")\n"); 526 seq_printf(f, ")\n");
471} 527}
472EXPORT_SYMBOL_GPL(hid_dump_field); 528EXPORT_SYMBOL_GPL(hid_dump_field);
473 529
474void hid_dump_device(struct hid_device *device) { 530void hid_dump_device(struct hid_device *device, struct seq_file *f)
531{
475 struct hid_report_enum *report_enum; 532 struct hid_report_enum *report_enum;
476 struct hid_report *report; 533 struct hid_report *report;
477 struct list_head *list; 534 struct list_head *list;
478 unsigned i,k; 535 unsigned i,k;
479 static const char *table[] = {"INPUT", "OUTPUT", "FEATURE"}; 536 static const char *table[] = {"INPUT", "OUTPUT", "FEATURE"};
480 537
481 if (!hid_debug)
482 return;
483
484 for (i = 0; i < HID_REPORT_TYPES; i++) { 538 for (i = 0; i < HID_REPORT_TYPES; i++) {
485 report_enum = device->report_enum + i; 539 report_enum = device->report_enum + i;
486 list = report_enum->report_list.next; 540 list = report_enum->report_list.next;
487 while (list != &report_enum->report_list) { 541 while (list != &report_enum->report_list) {
488 report = (struct hid_report *) list; 542 report = (struct hid_report *) list;
489 tab(2); 543 tab(2, f);
490 printk("%s", table[i]); 544 seq_printf(f, "%s", table[i]);
491 if (report->id) 545 if (report->id)
492 printk("(%d)", report->id); 546 seq_printf(f, "(%d)", report->id);
493 printk("[%s]", table[report->type]); 547 seq_printf(f, "[%s]", table[report->type]);
494 printk("\n"); 548 seq_printf(f, "\n");
495 for (k = 0; k < report->maxfield; k++) { 549 for (k = 0; k < report->maxfield; k++) {
496 tab(4); 550 tab(4, f);
497 printk("Field(%d)\n", k); 551 seq_printf(f, "Field(%d)\n", k);
498 hid_dump_field(report->field[k], 6); 552 hid_dump_field(report->field[k], 6, f);
499 } 553 }
500 list = list->next; 554 list = list->next;
501 } 555 }
@@ -503,13 +557,37 @@ void hid_dump_device(struct hid_device *device) {
503} 557}
504EXPORT_SYMBOL_GPL(hid_dump_device); 558EXPORT_SYMBOL_GPL(hid_dump_device);
505 559
506void hid_dump_input(struct hid_usage *usage, __s32 value) { 560/* enqueue string to 'events' ring buffer */
507 if (hid_debug < 2) 561void hid_debug_event(struct hid_device *hdev, char *buf)
562{
563 int i;
564 struct hid_debug_list *list;
565
566 list_for_each_entry(list, &hdev->debug_list, node) {
567 for (i = 0; i <= strlen(buf); i++)
568 list->hid_debug_buf[(list->tail + i) % (HID_DEBUG_BUFSIZE - 1)] =
569 buf[i];
570 list->tail = (list->tail + i) % (HID_DEBUG_BUFSIZE - 1);
571 }
572}
573EXPORT_SYMBOL_GPL(hid_debug_event);
574
575void hid_dump_input(struct hid_device *hdev, struct hid_usage *usage, __s32 value)
576{
577 char *buf;
578 int len;
579
580 buf = hid_resolv_usage(usage->hid, NULL);
581 if (!buf)
508 return; 582 return;
583 len = strlen(buf);
584 snprintf(buf + len, HID_DEBUG_BUFSIZE - len - 1, " = %d\n", value);
585
586 hid_debug_event(hdev, buf);
587
588 kfree(buf);
589 wake_up_interruptible(&hdev->debug_wait);
509 590
510 printk(KERN_DEBUG "hid-debug: input ");
511 hid_resolv_usage(usage->hid);
512 printk(" = %d\n", value);
513} 591}
514EXPORT_SYMBOL_GPL(hid_dump_input); 592EXPORT_SYMBOL_GPL(hid_dump_input);
515 593
@@ -786,12 +864,221 @@ static const char **names[EV_MAX + 1] = {
786 [EV_SND] = sounds, [EV_REP] = repeats, 864 [EV_SND] = sounds, [EV_REP] = repeats,
787}; 865};
788 866
789void hid_resolv_event(__u8 type, __u16 code) { 867void hid_resolv_event(__u8 type, __u16 code, struct seq_file *f) {
790 868
791 if (!hid_debug) 869 seq_printf(f, "%s.%s", events[type] ? events[type] : "?",
792 return;
793
794 printk("%s.%s", events[type] ? events[type] : "?",
795 names[type] ? (names[type][code] ? names[type][code] : "?") : "?"); 870 names[type] ? (names[type][code] ? names[type][code] : "?") : "?");
796} 871}
797EXPORT_SYMBOL_GPL(hid_resolv_event); 872
873void hid_dump_input_mapping(struct hid_device *hid, struct seq_file *f)
874{
875 int i, j, k;
876 struct hid_report *report;
877 struct hid_usage *usage;
878
879 for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
880 list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
881 for (i = 0; i < report->maxfield; i++) {
882 for ( j = 0; j < report->field[i]->maxusage; j++) {
883 usage = report->field[i]->usage + j;
884 hid_resolv_usage(usage->hid, f);
885 seq_printf(f, " ---> ");
886 hid_resolv_event(usage->type, usage->code, f);
887 seq_printf(f, "\n");
888 }
889 }
890 }
891 }
892
893}
894
895
896static int hid_debug_rdesc_show(struct seq_file *f, void *p)
897{
898 struct hid_device *hdev = f->private;
899 int i;
900
901 /* dump HID report descriptor */
902 for (i = 0; i < hdev->rsize; i++)
903 seq_printf(f, "%02x ", hdev->rdesc[i]);
904 seq_printf(f, "\n\n");
905
906 /* dump parsed data and input mappings */
907 hid_dump_device(hdev, f);
908 seq_printf(f, "\n");
909 hid_dump_input_mapping(hdev, f);
910
911 return 0;
912}
913
914static int hid_debug_rdesc_open(struct inode *inode, struct file *file)
915{
916 return single_open(file, hid_debug_rdesc_show, inode->i_private);
917}
918
919static int hid_debug_events_open(struct inode *inode, struct file *file)
920{
921 int err = 0;
922 struct hid_debug_list *list;
923
924 if (!(list = kzalloc(sizeof(struct hid_debug_list), GFP_KERNEL))) {
925 err = -ENOMEM;
926 goto out;
927 }
928
929 if (!(list->hid_debug_buf = kzalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_KERNEL))) {
930 err = -ENOMEM;
931 kfree(list);
932 goto out;
933 }
934 list->hdev = (struct hid_device *) inode->i_private;
935 file->private_data = list;
936 mutex_init(&list->read_mutex);
937
938 list_add_tail(&list->node, &list->hdev->debug_list);
939
940out:
941 return err;
942}
943
944static ssize_t hid_debug_events_read(struct file *file, char __user *buffer,
945 size_t count, loff_t *ppos)
946{
947 struct hid_debug_list *list = file->private_data;
948 int ret = 0, len;
949 DECLARE_WAITQUEUE(wait, current);
950
951 while (ret == 0) {
952 mutex_lock(&list->read_mutex);
953 if (list->head == list->tail) {
954 add_wait_queue(&list->hdev->debug_wait, &wait);
955 set_current_state(TASK_INTERRUPTIBLE);
956
957 while (list->head == list->tail) {
958 if (file->f_flags & O_NONBLOCK) {
959 ret = -EAGAIN;
960 break;
961 }
962 if (signal_pending(current)) {
963 ret = -ERESTARTSYS;
964 break;
965 }
966
967 if (!list->hdev || !list->hdev->debug) {
968 ret = -EIO;
969 break;
970 }
971
972 /* allow O_NONBLOCK from other threads */
973 mutex_unlock(&list->read_mutex);
974 schedule();
975 mutex_lock(&list->read_mutex);
976 set_current_state(TASK_INTERRUPTIBLE);
977 }
978
979 set_current_state(TASK_RUNNING);
980 remove_wait_queue(&list->hdev->debug_wait, &wait);
981 }
982
983 if (ret)
984 goto out;
985
986 /* pass the ringbuffer contents to userspace */
987copy_rest:
988 if (list->tail == list->head)
989 goto out;
990 if (list->tail > list->head) {
991 len = list->tail - list->head;
992
993 if (copy_to_user(buffer + ret, &list->hid_debug_buf[list->head], len)) {
994 ret = -EFAULT;
995 goto out;
996 }
997 ret += len;
998 list->head += len;
999 } else {
1000 len = HID_DEBUG_BUFSIZE - list->head;
1001
1002 if (copy_to_user(buffer, &list->hid_debug_buf[list->head], len)) {
1003 ret = -EFAULT;
1004 goto out;
1005 }
1006 list->head = 0;
1007 ret += len;
1008 goto copy_rest;
1009 }
1010
1011 }
1012out:
1013 mutex_unlock(&list->read_mutex);
1014 return ret;
1015}
1016
1017static unsigned int hid_debug_events_poll(struct file *file, poll_table *wait)
1018{
1019 struct hid_debug_list *list = file->private_data;
1020
1021 poll_wait(file, &list->hdev->debug_wait, wait);
1022 if (list->head != list->tail)
1023 return POLLIN | POLLRDNORM;
1024 if (!list->hdev->debug)
1025 return POLLERR | POLLHUP;
1026 return 0;
1027}
1028
1029static int hid_debug_events_release(struct inode *inode, struct file *file)
1030{
1031 struct hid_debug_list *list = file->private_data;
1032
1033 list_del(&list->node);
1034 kfree(list->hid_debug_buf);
1035 kfree(list);
1036
1037 return 0;
1038}
1039
1040static const struct file_operations hid_debug_rdesc_fops = {
1041 .open = hid_debug_rdesc_open,
1042 .read = seq_read,
1043 .llseek = seq_lseek,
1044 .release = single_release,
1045};
1046
1047static const struct file_operations hid_debug_events_fops = {
1048 .owner = THIS_MODULE,
1049 .open = hid_debug_events_open,
1050 .read = hid_debug_events_read,
1051 .poll = hid_debug_events_poll,
1052 .release = hid_debug_events_release,
1053};
1054
1055
1056void hid_debug_register(struct hid_device *hdev, const char *name)
1057{
1058 hdev->debug_dir = debugfs_create_dir(name, hid_debug_root);
1059 hdev->debug_rdesc = debugfs_create_file("rdesc", 0400,
1060 hdev->debug_dir, hdev, &hid_debug_rdesc_fops);
1061 hdev->debug_events = debugfs_create_file("events", 0400,
1062 hdev->debug_dir, hdev, &hid_debug_events_fops);
1063 hdev->debug = 1;
1064}
1065
1066void hid_debug_unregister(struct hid_device *hdev)
1067{
1068 hdev->debug = 0;
1069 wake_up_interruptible(&hdev->debug_wait);
1070 debugfs_remove(hdev->debug_rdesc);
1071 debugfs_remove(hdev->debug_events);
1072 debugfs_remove(hdev->debug_dir);
1073}
1074
1075void hid_debug_init(void)
1076{
1077 hid_debug_root = debugfs_create_dir("hid", NULL);
1078}
1079
1080void hid_debug_exit(void)
1081{
1082 debugfs_remove_recursive(hid_debug_root);
1083}
1084
diff --git a/drivers/hid/hid-ezkey.c b/drivers/hid/hid-ezkey.c
index 0a1fe054799b..ca1163e9d42d 100644
--- a/drivers/hid/hid-ezkey.c
+++ b/drivers/hid/hid-ezkey.c
@@ -78,12 +78,12 @@ static struct hid_driver ez_driver = {
78 .event = ez_event, 78 .event = ez_event,
79}; 79};
80 80
81static int ez_init(void) 81static int __init ez_init(void)
82{ 82{
83 return hid_register_driver(&ez_driver); 83 return hid_register_driver(&ez_driver);
84} 84}
85 85
86static void ez_exit(void) 86static void __exit ez_exit(void)
87{ 87{
88 hid_unregister_driver(&ez_driver); 88 hid_unregister_driver(&ez_driver);
89} 89}
diff --git a/drivers/hid/hid-gyration.c b/drivers/hid/hid-gyration.c
index d42d222097a8..cab13e8c7d29 100644
--- a/drivers/hid/hid-gyration.c
+++ b/drivers/hid/hid-gyration.c
@@ -81,12 +81,12 @@ static struct hid_driver gyration_driver = {
81 .event = gyration_event, 81 .event = gyration_event,
82}; 82};
83 83
84static int gyration_init(void) 84static int __init gyration_init(void)
85{ 85{
86 return hid_register_driver(&gyration_driver); 86 return hid_register_driver(&gyration_driver);
87} 87}
88 88
89static void gyration_exit(void) 89static void __exit gyration_exit(void)
90{ 90{
91 hid_unregister_driver(&gyration_driver); 91 hid_unregister_driver(&gyration_driver);
92} 92}
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 630101037921..adbef5d069c4 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -296,6 +296,7 @@
296#define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 296#define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283
297#define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 297#define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286
298#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 298#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294
299#define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293
299#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 300#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295
300#define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 301#define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299
301#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a 302#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a
@@ -359,6 +360,9 @@
359#define USB_VENDOR_ID_PETALYNX 0x18b1 360#define USB_VENDOR_ID_PETALYNX 0x18b1
360#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 361#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
361 362
363#define USB_VENDOR_ID_PHILIPS 0x0471
364#define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617
365
362#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 366#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43
363#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003 367#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003
364 368
@@ -376,11 +380,8 @@
376#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 380#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
377 381
378#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 382#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
379#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD 0x0038 383#define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034
380#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2 0x0036 384#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST 0x0046
381#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3 0x0034
382#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4 0x0044
383#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5 0x0045
384 385
385#define USB_VENDOR_ID_SUN 0x0430 386#define USB_VENDOR_ID_SUN 0x0430
386#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab 387#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab
@@ -403,6 +404,9 @@
403#define USB_VENDOR_ID_TURBOX 0x062a 404#define USB_VENDOR_ID_TURBOX 0x062a
404#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 405#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201
405 406
407#define USB_VENDOR_ID_TWINHAN 0x6253
408#define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100
409
406#define USB_VENDOR_ID_UCLOGIC 0x5543 410#define USB_VENDOR_ID_UCLOGIC 0x5543
407#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 411#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042
408 412
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/hid-kensington.c b/drivers/hid/hid-kensington.c
index 7353bd79cbe9..a5b4016e9bd7 100644
--- a/drivers/hid/hid-kensington.c
+++ b/drivers/hid/hid-kensington.c
@@ -48,12 +48,12 @@ static struct hid_driver ks_driver = {
48 .input_mapping = ks_input_mapping, 48 .input_mapping = ks_input_mapping,
49}; 49};
50 50
51static int ks_init(void) 51static int __init ks_init(void)
52{ 52{
53 return hid_register_driver(&ks_driver); 53 return hid_register_driver(&ks_driver);
54} 54}
55 55
56static void ks_exit(void) 56static void __exit ks_exit(void)
57{ 57{
58 hid_unregister_driver(&ks_driver); 58 hid_unregister_driver(&ks_driver);
59} 59}
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c
index 72ee3fec56d9..f8871712b7b5 100644
--- a/drivers/hid/hid-kye.c
+++ b/drivers/hid/hid-kye.c
@@ -54,12 +54,12 @@ static struct hid_driver kye_driver = {
54 .report_fixup = kye_report_fixup, 54 .report_fixup = kye_report_fixup,
55}; 55};
56 56
57static int kye_init(void) 57static int __init kye_init(void)
58{ 58{
59 return hid_register_driver(&kye_driver); 59 return hid_register_driver(&kye_driver);
60} 60}
61 61
62static void kye_exit(void) 62static void __exit kye_exit(void)
63{ 63{
64 hid_unregister_driver(&kye_driver); 64 hid_unregister_driver(&kye_driver);
65} 65}
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 7afbaa0efd18..0f870a3243ed 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -299,6 +299,8 @@ static const struct hid_device_id lg_devices[] = {
299 .driver_data = LG_FF }, 299 .driver_data = LG_FF },
300 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), 300 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
301 .driver_data = LG_FF }, 301 .driver_data = LG_FF },
302 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ),
303 .driver_data = LG_FF },
302 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), 304 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
303 .driver_data = LG_FF2 }, 305 .driver_data = LG_FF2 },
304 { } 306 { }
@@ -315,12 +317,12 @@ static struct hid_driver lg_driver = {
315 .probe = lg_probe, 317 .probe = lg_probe,
316}; 318};
317 319
318static int lg_init(void) 320static int __init lg_init(void)
319{ 321{
320 return hid_register_driver(&lg_driver); 322 return hid_register_driver(&lg_driver);
321} 323}
322 324
323static void lg_exit(void) 325static void __exit lg_exit(void)
324{ 326{
325 hid_unregister_driver(&lg_driver); 327 hid_unregister_driver(&lg_driver);
326} 328}
diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c
index 56099709581c..987abebe0829 100644
--- a/drivers/hid/hid-lgff.c
+++ b/drivers/hid/hid-lgff.c
@@ -67,6 +67,7 @@ static const struct dev_type devices[] = {
67 { 0x046d, 0xc219, ff_rumble }, 67 { 0x046d, 0xc219, ff_rumble },
68 { 0x046d, 0xc283, ff_joystick }, 68 { 0x046d, 0xc283, ff_joystick },
69 { 0x046d, 0xc286, ff_joystick_ac }, 69 { 0x046d, 0xc286, ff_joystick_ac },
70 { 0x046d, 0xc293, ff_joystick },
70 { 0x046d, 0xc294, ff_wheel }, 71 { 0x046d, 0xc294, ff_wheel },
71 { 0x046d, 0xc295, ff_joystick }, 72 { 0x046d, 0xc295, ff_joystick },
72 { 0x046d, 0xca03, ff_wheel }, 73 { 0x046d, 0xca03, ff_wheel },
@@ -150,11 +151,6 @@ int lgff_init(struct hid_device* hid)
150 151
151 /* Check that the report looks ok */ 152 /* Check that the report looks ok */
152 report = list_entry(report_list->next, struct hid_report, list); 153 report = list_entry(report_list->next, struct hid_report, list);
153 if (!report) {
154 err_hid("NULL output report");
155 return -1;
156 }
157
158 field = report->field[0]; 154 field = report->field[0];
159 if (!field) { 155 if (!field) {
160 err_hid("NULL field"); 156 err_hid("NULL field");
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 5e9e37a0506d..359cc447c6c6 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -197,12 +197,12 @@ static struct hid_driver ms_driver = {
197 .probe = ms_probe, 197 .probe = ms_probe,
198}; 198};
199 199
200static int ms_init(void) 200static int __init ms_init(void)
201{ 201{
202 return hid_register_driver(&ms_driver); 202 return hid_register_driver(&ms_driver);
203} 203}
204 204
205static void ms_exit(void) 205static void __exit ms_exit(void)
206{ 206{
207 hid_unregister_driver(&ms_driver); 207 hid_unregister_driver(&ms_driver);
208} 208}
diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c
index 240f87618be6..2cd05aa244b9 100644
--- a/drivers/hid/hid-monterey.c
+++ b/drivers/hid/hid-monterey.c
@@ -65,12 +65,12 @@ static struct hid_driver mr_driver = {
65 .input_mapping = mr_input_mapping, 65 .input_mapping = mr_input_mapping,
66}; 66};
67 67
68static int mr_init(void) 68static int __init mr_init(void)
69{ 69{
70 return hid_register_driver(&mr_driver); 70 return hid_register_driver(&mr_driver);
71} 71}
72 72
73static void mr_exit(void) 73static void __exit mr_exit(void)
74{ 74{
75 hid_unregister_driver(&mr_driver); 75 hid_unregister_driver(&mr_driver);
76} 76}
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index 75ed9d2c1a36..49ce69d7bba7 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -27,6 +27,9 @@
27struct ntrig_data { 27struct ntrig_data {
28 __s32 x, y, id, w, h; 28 __s32 x, y, id, w, h;
29 char reading_a_point, found_contact_id; 29 char reading_a_point, found_contact_id;
30 char pen_active;
31 char finger_active;
32 char inverted;
30}; 33};
31 34
32/* 35/*
@@ -63,10 +66,7 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
63 case HID_UP_DIGITIZER: 66 case HID_UP_DIGITIZER:
64 switch (usage->hid) { 67 switch (usage->hid) {
65 /* we do not want to map these for now */ 68 /* we do not want to map these for now */
66 case HID_DG_INVERT: /* value is always 0 */
67 case HID_DG_ERASER: /* value is always 0 */
68 case HID_DG_CONTACTID: /* value is useless */ 69 case HID_DG_CONTACTID: /* value is useless */
69 case HID_DG_BARRELSWITCH: /* doubtful */
70 case HID_DG_INPUTMODE: 70 case HID_DG_INPUTMODE:
71 case HID_DG_DEVICEINDEX: 71 case HID_DG_DEVICEINDEX:
72 case HID_DG_CONTACTCOUNT: 72 case HID_DG_CONTACTCOUNT:
@@ -125,6 +125,18 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
125 125
126 if (hid->claimed & HID_CLAIMED_INPUT) { 126 if (hid->claimed & HID_CLAIMED_INPUT) {
127 switch (usage->hid) { 127 switch (usage->hid) {
128
129 case HID_DG_INRANGE:
130 if (field->application & 0x3)
131 nd->pen_active = (value != 0);
132 else
133 nd->finger_active = (value != 0);
134 return 0;
135
136 case HID_DG_INVERT:
137 nd->inverted = value;
138 return 0;
139
128 case HID_GD_X: 140 case HID_GD_X:
129 nd->x = value; 141 nd->x = value;
130 nd->reading_a_point = 1; 142 nd->reading_a_point = 1;
@@ -147,7 +159,11 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
147 * report received in a finger event. We want 159 * report received in a finger event. We want
148 * to emit a normal (X, Y) position 160 * to emit a normal (X, Y) position
149 */ 161 */
150 if (! nd->found_contact_id) { 162 if (!nd->found_contact_id) {
163 if (nd->pen_active && nd->finger_active) {
164 input_report_key(input, BTN_TOOL_DOUBLETAP, 0);
165 input_report_key(input, BTN_TOOL_DOUBLETAP, 1);
166 }
151 input_event(input, EV_ABS, ABS_X, nd->x); 167 input_event(input, EV_ABS, ABS_X, nd->x);
152 input_event(input, EV_ABS, ABS_Y, nd->y); 168 input_event(input, EV_ABS, ABS_Y, nd->y);
153 } 169 }
@@ -159,6 +175,14 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
159 * to emit a normal (X, Y) position 175 * to emit a normal (X, Y) position
160 */ 176 */
161 if (! nd->found_contact_id) { 177 if (! nd->found_contact_id) {
178 if (nd->pen_active && nd->finger_active) {
179 input_report_key(input,
180 nd->inverted ? BTN_TOOL_RUBBER : BTN_TOOL_PEN
181 , 0);
182 input_report_key(input,
183 nd->inverted ? BTN_TOOL_RUBBER : BTN_TOOL_PEN
184 , 1);
185 }
162 input_event(input, EV_ABS, ABS_X, nd->x); 186 input_event(input, EV_ABS, ABS_X, nd->x);
163 input_event(input, EV_ABS, ABS_Y, nd->y); 187 input_event(input, EV_ABS, ABS_Y, nd->y);
164 input_event(input, EV_ABS, ABS_PRESSURE, value); 188 input_event(input, EV_ABS, ABS_PRESSURE, value);
@@ -233,6 +257,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
233 257
234 if (ret) 258 if (ret)
235 kfree (nd); 259 kfree (nd);
260
236 return ret; 261 return ret;
237} 262}
238 263
@@ -265,12 +290,12 @@ static struct hid_driver ntrig_driver = {
265 .event = ntrig_event, 290 .event = ntrig_event,
266}; 291};
267 292
268static int ntrig_init(void) 293static int __init ntrig_init(void)
269{ 294{
270 return hid_register_driver(&ntrig_driver); 295 return hid_register_driver(&ntrig_driver);
271} 296}
272 297
273static void ntrig_exit(void) 298static void __exit ntrig_exit(void)
274{ 299{
275 hid_unregister_driver(&ntrig_driver); 300 hid_unregister_driver(&ntrig_driver);
276} 301}
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c
index 2e83e8ff891a..500fbd0652dc 100644
--- a/drivers/hid/hid-petalynx.c
+++ b/drivers/hid/hid-petalynx.c
@@ -105,12 +105,12 @@ static struct hid_driver pl_driver = {
105 .probe = pl_probe, 105 .probe = pl_probe,
106}; 106};
107 107
108static int pl_init(void) 108static int __init pl_init(void)
109{ 109{
110 return hid_register_driver(&pl_driver); 110 return hid_register_driver(&pl_driver);
111} 111}
112 112
113static void pl_exit(void) 113static void __exit pl_exit(void)
114{ 114{
115 hid_unregister_driver(&pl_driver); 115 hid_unregister_driver(&pl_driver);
116} 116}
diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c
index 4db9a3483760..c6d7dbc935b1 100644
--- a/drivers/hid/hid-pl.c
+++ b/drivers/hid/hid-pl.c
@@ -217,12 +217,12 @@ static struct hid_driver pl_driver = {
217 .probe = pl_probe, 217 .probe = pl_probe,
218}; 218};
219 219
220static int pl_init(void) 220static int __init pl_init(void)
221{ 221{
222 return hid_register_driver(&pl_driver); 222 return hid_register_driver(&pl_driver);
223} 223}
224 224
225static void pl_exit(void) 225static void __exit pl_exit(void)
226{ 226{
227 hid_unregister_driver(&pl_driver); 227 hid_unregister_driver(&pl_driver);
228} 228}
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
index 07083aa6c19a..5b222eed0692 100644
--- a/drivers/hid/hid-samsung.c
+++ b/drivers/hid/hid-samsung.c
@@ -25,25 +25,48 @@
25/* 25/*
26 * Samsung IrDA remote controller (reports as Cypress USB Mouse). 26 * Samsung IrDA remote controller (reports as Cypress USB Mouse).
27 * 27 *
28 * There are several variants for 0419:0001:
29 *
30 * 1. 184 byte report descriptor
28 * Vendor specific report #4 has a size of 48 bit, 31 * Vendor specific report #4 has a size of 48 bit,
29 * and therefore is not accepted when inspecting the descriptors. 32 * and therefore is not accepted when inspecting the descriptors.
30 * As a workaround we reinterpret the report as: 33 * As a workaround we reinterpret the report as:
31 * Variable type, count 6, size 8 bit, log. maximum 255 34 * Variable type, count 6, size 8 bit, log. maximum 255
32 * The burden to reconstruct the data is moved into user space. 35 * The burden to reconstruct the data is moved into user space.
36 *
37 * 2. 203 byte report descriptor
38 * Report #4 has an array field with logical range 0..18 instead of 1..15.
39 *
40 * 3. 135 byte report descriptor
41 * Report #4 has an array field with logical range 0..17 instead of 1..14.
33 */ 42 */
34static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, 43static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
35 unsigned int rsize) 44 unsigned int rsize)
36{ 45{
37 if (rsize >= 182 && rdesc[175] == 0x25 && rdesc[176] == 0x40 && 46 if (rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 &&
38 rdesc[177] == 0x75 && rdesc[178] == 0x30 && 47 rdesc[177] == 0x75 && rdesc[178] == 0x30 &&
39 rdesc[179] == 0x95 && rdesc[180] == 0x01 && 48 rdesc[179] == 0x95 && rdesc[180] == 0x01 &&
40 rdesc[182] == 0x40) { 49 rdesc[182] == 0x40) {
41 dev_info(&hdev->dev, "fixing up Samsung IrDA report " 50 dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
42 "descriptor\n"); 51 "descriptor\n", 184);
43 rdesc[176] = 0xff; 52 rdesc[176] = 0xff;
44 rdesc[178] = 0x08; 53 rdesc[178] = 0x08;
45 rdesc[180] = 0x06; 54 rdesc[180] = 0x06;
46 rdesc[182] = 0x42; 55 rdesc[182] = 0x42;
56 } else
57 if (rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
58 rdesc[194] == 0x25 && rdesc[195] == 0x12) {
59 dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
60 "descriptor\n", 203);
61 rdesc[193] = 0x1;
62 rdesc[195] = 0xf;
63 } else
64 if (rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
65 rdesc[126] == 0x25 && rdesc[127] == 0x11) {
66 dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
67 "descriptor\n", 135);
68 rdesc[125] = 0x1;
69 rdesc[127] = 0xe;
47 } 70 }
48} 71}
49 72
@@ -51,6 +74,7 @@ static int samsung_probe(struct hid_device *hdev,
51 const struct hid_device_id *id) 74 const struct hid_device_id *id)
52{ 75{
53 int ret; 76 int ret;
77 unsigned int cmask = HID_CONNECT_DEFAULT;
54 78
55 ret = hid_parse(hdev); 79 ret = hid_parse(hdev);
56 if (ret) { 80 if (ret) {
@@ -58,8 +82,13 @@ static int samsung_probe(struct hid_device *hdev,
58 goto err_free; 82 goto err_free;
59 } 83 }
60 84
61 ret = hid_hw_start(hdev, (HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT) | 85 if (hdev->rsize == 184) {
62 HID_CONNECT_HIDDEV_FORCE); 86 /* disable hidinput, force hiddev */
87 cmask = (cmask & ~HID_CONNECT_HIDINPUT) |
88 HID_CONNECT_HIDDEV_FORCE;
89 }
90
91 ret = hid_hw_start(hdev, cmask);
63 if (ret) { 92 if (ret) {
64 dev_err(&hdev->dev, "hw start failed\n"); 93 dev_err(&hdev->dev, "hw start failed\n");
65 goto err_free; 94 goto err_free;
@@ -83,12 +112,12 @@ static struct hid_driver samsung_driver = {
83 .probe = samsung_probe, 112 .probe = samsung_probe,
84}; 113};
85 114
86static int samsung_init(void) 115static int __init samsung_init(void)
87{ 116{
88 return hid_register_driver(&samsung_driver); 117 return hid_register_driver(&samsung_driver);
89} 118}
90 119
91static void samsung_exit(void) 120static void __exit samsung_exit(void)
92{ 121{
93 hid_unregister_driver(&samsung_driver); 122 hid_unregister_driver(&samsung_driver);
94} 123}
diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c
index eab169e5c371..203c438b016f 100644
--- a/drivers/hid/hid-sjoy.c
+++ b/drivers/hid/hid-sjoy.c
@@ -163,12 +163,12 @@ static struct hid_driver sjoy_driver = {
163 .probe = sjoy_probe, 163 .probe = sjoy_probe,
164}; 164};
165 165
166static int sjoy_init(void) 166static int __init sjoy_init(void)
167{ 167{
168 return hid_register_driver(&sjoy_driver); 168 return hid_register_driver(&sjoy_driver);
169} 169}
170 170
171static void sjoy_exit(void) 171static void __exit sjoy_exit(void)
172{ 172{
173 hid_unregister_driver(&sjoy_driver); 173 hid_unregister_driver(&sjoy_driver);
174} 174}
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index c2599388a350..4e8450228a24 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -135,12 +135,12 @@ static struct hid_driver sony_driver = {
135 .report_fixup = sony_report_fixup, 135 .report_fixup = sony_report_fixup,
136}; 136};
137 137
138static int sony_init(void) 138static int __init sony_init(void)
139{ 139{
140 return hid_register_driver(&sony_driver); 140 return hid_register_driver(&sony_driver);
141} 141}
142 142
143static void sony_exit(void) 143static void __exit sony_exit(void)
144{ 144{
145 hid_unregister_driver(&sony_driver); 145 hid_unregister_driver(&sony_driver);
146} 146}
diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c
index e0a8fd36a85b..438107d9f1b2 100644
--- a/drivers/hid/hid-sunplus.c
+++ b/drivers/hid/hid-sunplus.c
@@ -65,12 +65,12 @@ static struct hid_driver sp_driver = {
65 .input_mapping = sp_input_mapping, 65 .input_mapping = sp_input_mapping,
66}; 66};
67 67
68static int sp_init(void) 68static int __init sp_init(void)
69{ 69{
70 return hid_register_driver(&sp_driver); 70 return hid_register_driver(&sp_driver);
71} 71}
72 72
73static void sp_exit(void) 73static void __exit sp_exit(void)
74{ 74{
75 hid_unregister_driver(&sp_driver); 75 hid_unregister_driver(&sp_driver);
76} 76}
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
index fcd6ccd02fee..167ea746fb9c 100644
--- a/drivers/hid/hid-tmff.c
+++ b/drivers/hid/hid-tmff.c
@@ -243,7 +243,11 @@ err:
243static const struct hid_device_id tm_devices[] = { 243static const struct hid_device_id tm_devices[] = {
244 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300), 244 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300),
245 .driver_data = (unsigned long)ff_rumble }, 245 .driver_data = (unsigned long)ff_rumble },
246 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304), 246 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304), /* FireStorm Dual Power 2 (and 3) */
247 .driver_data = (unsigned long)ff_rumble },
248 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323), /* Dual Trigger 3-in-1 (PC Mode) */
249 .driver_data = (unsigned long)ff_rumble },
250 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324), /* Dual Trigger 3-in-1 (PS3 Mode) */
247 .driver_data = (unsigned long)ff_rumble }, 251 .driver_data = (unsigned long)ff_rumble },
248 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651), /* FGT Rumble Force Wheel */ 252 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651), /* FGT Rumble Force Wheel */
249 .driver_data = (unsigned long)ff_rumble }, 253 .driver_data = (unsigned long)ff_rumble },
@@ -259,12 +263,12 @@ static struct hid_driver tm_driver = {
259 .probe = tm_probe, 263 .probe = tm_probe,
260}; 264};
261 265
262static int tm_init(void) 266static int __init tm_init(void)
263{ 267{
264 return hid_register_driver(&tm_driver); 268 return hid_register_driver(&tm_driver);
265} 269}
266 270
267static void tm_exit(void) 271static void __exit tm_exit(void)
268{ 272{
269 hid_unregister_driver(&tm_driver); 273 hid_unregister_driver(&tm_driver);
270} 274}
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c
index 152ccfabeba5..6925eda1081a 100644
--- a/drivers/hid/hid-topseed.c
+++ b/drivers/hid/hid-topseed.c
@@ -60,12 +60,12 @@ static struct hid_driver ts_driver = {
60 .input_mapping = ts_input_mapping, 60 .input_mapping = ts_input_mapping,
61}; 61};
62 62
63static int ts_init(void) 63static int __init ts_init(void)
64{ 64{
65 return hid_register_driver(&ts_driver); 65 return hid_register_driver(&ts_driver);
66} 66}
67 67
68static void ts_exit(void) 68static void __exit ts_exit(void)
69{ 69{
70 hid_unregister_driver(&ts_driver); 70 hid_unregister_driver(&ts_driver);
71} 71}
diff --git a/drivers/hid/hid-twinhan.c b/drivers/hid/hid-twinhan.c
new file mode 100644
index 000000000000..b05f602c051e
--- /dev/null
+++ b/drivers/hid/hid-twinhan.c
@@ -0,0 +1,147 @@
1/*
2 * HID driver for TwinHan IR remote control
3 *
4 * Based on hid-gyration.c
5 *
6 * Copyright (c) 2009 Bruno Prémont <bonbons@linux-vserver.org>
7 */
8
9/*
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License.
13 */
14
15#include <linux/device.h>
16#include <linux/input.h>
17#include <linux/hid.h>
18#include <linux/module.h>
19
20#include "hid-ids.h"
21
22/* Remote control key layout + listing:
23 *
24 * Full Screen Power
25 * KEY_SCREEN KEY_POWER2
26 *
27 * 1 2 3
28 * KEY_NUMERIC_1 KEY_NUMERIC_2 KEY_NUMERIC_3
29 *
30 * 4 5 6
31 * KEY_NUMERIC_4 KEY_NUMERIC_5 KEY_NUMERIC_6
32 *
33 * 7 8 9
34 * KEY_NUMERIC_7 KEY_NUMERIC_8 KEY_NUMERIC_9
35 *
36 * REC 0 Favorite
37 * KEY_RECORD KEY_NUMERIC_0 KEY_FAVORITES
38 *
39 * Rewind Forward
40 * KEY_REWIND CH+ KEY_FORWARD
41 * KEY_CHANNELUP
42 *
43 * VOL- > VOL+
44 * KEY_VOLUMEDOWN KEY_PLAY KEY_VOLUMEUP
45 *
46 * CH-
47 * KEY_CHANNELDOWN
48 * Recall Stop
49 * KEY_RESTART KEY_STOP
50 *
51 * Timeshift/Pause Mute Cancel
52 * KEY_PAUSE KEY_MUTE KEY_CANCEL
53 *
54 * Capture Preview EPG
55 * KEY_PRINT KEY_PROGRAM KEY_EPG
56 *
57 * Record List Tab Teletext
58 * KEY_LIST KEY_TAB KEY_TEXT
59 */
60
61#define th_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
62 EV_KEY, (c))
63static int twinhan_input_mapping(struct hid_device *hdev, struct hid_input *hi,
64 struct hid_field *field, struct hid_usage *usage,
65 unsigned long **bit, int *max)
66{
67 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_KEYBOARD)
68 return 0;
69
70 switch (usage->hid & HID_USAGE) {
71 /* Map all keys from Twinhan Remote */
72 case 0x004: th_map_key_clear(KEY_TEXT); break;
73 case 0x006: th_map_key_clear(KEY_RESTART); break;
74 case 0x008: th_map_key_clear(KEY_EPG); break;
75 case 0x00c: th_map_key_clear(KEY_REWIND); break;
76 case 0x00e: th_map_key_clear(KEY_PROGRAM); break;
77 case 0x00f: th_map_key_clear(KEY_LIST); break;
78 case 0x010: th_map_key_clear(KEY_MUTE); break;
79 case 0x011: th_map_key_clear(KEY_FORWARD); break;
80 case 0x013: th_map_key_clear(KEY_PRINT); break;
81 case 0x017: th_map_key_clear(KEY_PAUSE); break;
82 case 0x019: th_map_key_clear(KEY_FAVORITES); break;
83 case 0x01d: th_map_key_clear(KEY_SCREEN); break;
84 case 0x01e: th_map_key_clear(KEY_NUMERIC_1); break;
85 case 0x01f: th_map_key_clear(KEY_NUMERIC_2); break;
86 case 0x020: th_map_key_clear(KEY_NUMERIC_3); break;
87 case 0x021: th_map_key_clear(KEY_NUMERIC_4); break;
88 case 0x022: th_map_key_clear(KEY_NUMERIC_5); break;
89 case 0x023: th_map_key_clear(KEY_NUMERIC_6); break;
90 case 0x024: th_map_key_clear(KEY_NUMERIC_7); break;
91 case 0x025: th_map_key_clear(KEY_NUMERIC_8); break;
92 case 0x026: th_map_key_clear(KEY_NUMERIC_9); break;
93 case 0x027: th_map_key_clear(KEY_NUMERIC_0); break;
94 case 0x028: th_map_key_clear(KEY_PLAY); break;
95 case 0x029: th_map_key_clear(KEY_CANCEL); break;
96 case 0x02b: th_map_key_clear(KEY_TAB); break;
97 /* Power = 0x0e0 + 0x0e1 + 0x0e2 + 0x03f */
98 case 0x03f: th_map_key_clear(KEY_POWER2); break;
99 case 0x04a: th_map_key_clear(KEY_RECORD); break;
100 case 0x04b: th_map_key_clear(KEY_CHANNELUP); break;
101 case 0x04d: th_map_key_clear(KEY_STOP); break;
102 case 0x04e: th_map_key_clear(KEY_CHANNELDOWN); break;
103 /* Volume down = 0x0e1 + 0x051 */
104 case 0x051: th_map_key_clear(KEY_VOLUMEDOWN); break;
105 /* Volume up = 0x0e1 + 0x052 */
106 case 0x052: th_map_key_clear(KEY_VOLUMEUP); break;
107 /* Kill the extra keys used for multi-key "power" and "volume" keys
108 * as well as continuously to release CTRL,ALT,META,... keys */
109 case 0x0e0:
110 case 0x0e1:
111 case 0x0e2:
112 case 0x0e3:
113 case 0x0e4:
114 case 0x0e5:
115 case 0x0e6:
116 case 0x0e7:
117 default:
118 return -1;
119 }
120 return 1;
121}
122
123static const struct hid_device_id twinhan_devices[] = {
124 { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
125 { }
126};
127MODULE_DEVICE_TABLE(hid, twinhan_devices);
128
129static struct hid_driver twinhan_driver = {
130 .name = "twinhan",
131 .id_table = twinhan_devices,
132 .input_mapping = twinhan_input_mapping,
133};
134
135static int twinhan_init(void)
136{
137 return hid_register_driver(&twinhan_driver);
138}
139
140static void twinhan_exit(void)
141{
142 hid_unregister_driver(&twinhan_driver);
143}
144
145module_init(twinhan_init);
146module_exit(twinhan_exit);
147MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
index 1f9237f511e3..747542172242 100644
--- a/drivers/hid/hid-wacom.c
+++ b/drivers/hid/hid-wacom.c
@@ -237,7 +237,7 @@ static struct hid_driver wacom_driver = {
237 .raw_event = wacom_raw_event, 237 .raw_event = wacom_raw_event,
238}; 238};
239 239
240static int wacom_init(void) 240static int __init wacom_init(void)
241{ 241{
242 int ret; 242 int ret;
243 243
@@ -248,7 +248,7 @@ static int wacom_init(void)
248 return ret; 248 return ret;
249} 249}
250 250
251static void wacom_exit(void) 251static void __exit wacom_exit(void)
252{ 252{
253 hid_unregister_driver(&wacom_driver); 253 hid_unregister_driver(&wacom_driver);
254} 254}
diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
index 57f710757bf4..a79f0d78c6be 100644
--- a/drivers/hid/hid-zpff.c
+++ b/drivers/hid/hid-zpff.c
@@ -152,12 +152,12 @@ static struct hid_driver zp_driver = {
152 .probe = zp_probe, 152 .probe = zp_probe,
153}; 153};
154 154
155static int zp_init(void) 155static int __init zp_init(void)
156{ 156{
157 return hid_register_driver(&zp_driver); 157 return hid_register_driver(&zp_driver);
158} 158}
159 159
160static void zp_exit(void) 160static void __exit zp_exit(void)
161{ 161{
162 hid_unregister_driver(&zp_driver); 162 hid_unregister_driver(&zp_driver);
163} 163}
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 3c1fcb7640ab..1b0e07a67d6d 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/*
@@ -489,7 +489,8 @@ static void hid_ctrl(struct urb *urb)
489 wake_up(&usbhid->wait); 489 wake_up(&usbhid->wait);
490} 490}
491 491
492void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) 492static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report,
493 unsigned char dir)
493{ 494{
494 int head; 495 int head;
495 struct usbhid_device *usbhid = hid->driver_data; 496 struct usbhid_device *usbhid = hid->driver_data;
@@ -885,11 +886,6 @@ static int usbhid_parse(struct hid_device *hid)
885 goto err; 886 goto err;
886 } 887 }
887 888
888 dbg_hid("report descriptor (size %u, read %d) = ", rsize, n);
889 for (n = 0; n < rsize; n++)
890 dbg_hid_line(" %02x", (unsigned char) rdesc[n]);
891 dbg_hid_line("\n");
892
893 ret = hid_parse_report(hid, rdesc, rsize); 889 ret = hid_parse_report(hid, rdesc, rsize);
894 kfree(rdesc); 890 kfree(rdesc);
895 if (ret) { 891 if (ret) {
@@ -986,7 +982,6 @@ static int usbhid_start(struct hid_device *hid)
986 setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); 982 setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
987 983
988 spin_lock_init(&usbhid->lock); 984 spin_lock_init(&usbhid->lock);
989 spin_lock_init(&usbhid->lock);
990 985
991 usbhid->intf = intf; 986 usbhid->intf = intf;
992 usbhid->ifnum = interface->desc.bInterfaceNumber; 987 usbhid->ifnum = interface->desc.bInterfaceNumber;
@@ -1004,7 +999,6 @@ static int usbhid_start(struct hid_device *hid)
1004 usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); 999 usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
1005 1000
1006 usbhid_init_reports(hid); 1001 usbhid_init_reports(hid);
1007 hid_dump_device(hid);
1008 1002
1009 set_bit(HID_STARTED, &usbhid->iofl); 1003 set_bit(HID_STARTED, &usbhid->iofl);
1010 1004
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index d8f7423f363e..0d9045aa2c4b 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -201,7 +201,7 @@ int usbhid_quirks_init(char **quirks_param)
201 u32 quirks; 201 u32 quirks;
202 int n = 0, m; 202 int n = 0, m;
203 203
204 for (; quirks_param[n] && n < MAX_USBHID_BOOT_QUIRKS; n++) { 204 for (; n < MAX_USBHID_BOOT_QUIRKS && quirks_param[n]; n++) {
205 205
206 m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x", 206 m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x",
207 &idVendor, &idProduct, &quirks); 207 &idVendor, &idProduct, &quirks);
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 215b2addddbb..4d1dc0cf1401 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -44,7 +44,7 @@
44#define HIDDEV_MINOR_BASE 96 44#define HIDDEV_MINOR_BASE 96
45#define HIDDEV_MINORS 16 45#define HIDDEV_MINORS 16
46#endif 46#endif
47#define HIDDEV_BUFFER_SIZE 64 47#define HIDDEV_BUFFER_SIZE 2048
48 48
49struct hiddev { 49struct hiddev {
50 int exist; 50 int exist;