aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/Kconfig70
-rw-r--r--drivers/hid/Makefile5
-rw-r--r--drivers/hid/hid-bright.c71
-rw-r--r--drivers/hid/hid-core.c137
-rw-r--r--drivers/hid/hid-dell.c76
-rw-r--r--drivers/hid/hid-dummy.c6
-rw-r--r--drivers/hid/hid-gaff.c185
-rw-r--r--drivers/hid/hid-ids.h26
-rw-r--r--drivers/hid/hid-lg.c7
-rw-r--r--drivers/hid/hid-microsoft.c13
-rw-r--r--drivers/hid/hid-ntrig.c82
-rw-r--r--drivers/hid/hid-sony.c2
-rw-r--r--drivers/hid/hid-topseed.c77
-rw-r--r--drivers/hid/hidraw.c38
-rw-r--r--drivers/hid/usbhid/Kconfig2
-rw-r--r--drivers/hid/usbhid/hid-core.c43
-rw-r--r--drivers/hid/usbhid/hid-quirks.c1
-rw-r--r--drivers/hid/usbhid/hiddev.c137
-rw-r--r--drivers/hid/usbhid/usbhid.h10
19 files changed, 707 insertions, 281 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index b4fd8ca701a4..e85c8fe9ffcf 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -85,14 +85,14 @@ config HID_COMPAT
85config HID_A4TECH 85config HID_A4TECH
86 tristate "A4 tech" if EMBEDDED 86 tristate "A4 tech" if EMBEDDED
87 depends on USB_HID 87 depends on USB_HID
88 default y 88 default !EMBEDDED
89 ---help--- 89 ---help---
90 Support for A4 tech X5 and WOP-35 / Trust 450L mice. 90 Support for A4 tech X5 and WOP-35 / Trust 450L mice.
91 91
92config HID_APPLE 92config HID_APPLE
93 tristate "Apple" if EMBEDDED 93 tristate "Apple" if EMBEDDED
94 depends on (USB_HID || BT_HIDP) 94 depends on (USB_HID || BT_HIDP)
95 default y 95 default !EMBEDDED
96 ---help--- 96 ---help---
97 Support for some Apple devices which less or more break 97 Support for some Apple devices which less or more break
98 HID specification. 98 HID specification.
@@ -103,64 +103,49 @@ config HID_APPLE
103config HID_BELKIN 103config HID_BELKIN
104 tristate "Belkin" if EMBEDDED 104 tristate "Belkin" if EMBEDDED
105 depends on USB_HID 105 depends on USB_HID
106 default y 106 default !EMBEDDED
107 ---help--- 107 ---help---
108 Support for Belkin Flip KVM and Wireless keyboard. 108 Support for Belkin Flip KVM and Wireless keyboard.
109 109
110config HID_BRIGHT
111 tristate "Bright" if EMBEDDED
112 depends on USB_HID
113 default y
114 ---help---
115 Support for Bright ABNT-2 keyboard.
116
117config HID_CHERRY 110config HID_CHERRY
118 tristate "Cherry" if EMBEDDED 111 tristate "Cherry" if EMBEDDED
119 depends on USB_HID 112 depends on USB_HID
120 default y 113 default !EMBEDDED
121 ---help--- 114 ---help---
122 Support for Cherry Cymotion keyboard. 115 Support for Cherry Cymotion keyboard.
123 116
124config HID_CHICONY 117config HID_CHICONY
125 tristate "Chicony" if EMBEDDED 118 tristate "Chicony" if EMBEDDED
126 depends on USB_HID 119 depends on USB_HID
127 default y 120 default !EMBEDDED
128 ---help--- 121 ---help---
129 Support for Chicony Tactical pad. 122 Support for Chicony Tactical pad.
130 123
131config HID_CYPRESS 124config HID_CYPRESS
132 tristate "Cypress" if EMBEDDED 125 tristate "Cypress" if EMBEDDED
133 depends on USB_HID 126 depends on USB_HID
134 default y 127 default !EMBEDDED
135 ---help--- 128 ---help---
136 Support for cypress mouse and barcode readers. 129 Support for cypress mouse and barcode readers.
137 130
138config HID_DELL
139 tristate "Dell" if EMBEDDED
140 depends on USB_HID
141 default y
142 ---help---
143 Support for quirky Dell HID hardware that require
144 special LED handling (W7658 and SK8115 models)
145
146config HID_EZKEY 131config HID_EZKEY
147 tristate "Ezkey" if EMBEDDED 132 tristate "Ezkey" if EMBEDDED
148 depends on USB_HID 133 depends on USB_HID
149 default y 134 default !EMBEDDED
150 ---help--- 135 ---help---
151 Support for Ezkey BTC 8193 keyboard. 136 Support for Ezkey BTC 8193 keyboard.
152 137
153config HID_GYRATION 138config HID_GYRATION
154 tristate "Gyration" if EMBEDDED 139 tristate "Gyration" if EMBEDDED
155 depends on USB_HID 140 depends on USB_HID
156 default y 141 default !EMBEDDED
157 ---help--- 142 ---help---
158 Support for Gyration remote control. 143 Support for Gyration remote control.
159 144
160config HID_LOGITECH 145config HID_LOGITECH
161 tristate "Logitech" if EMBEDDED 146 tristate "Logitech" if EMBEDDED
162 depends on USB_HID 147 depends on USB_HID
163 default y 148 default !EMBEDDED
164 ---help--- 149 ---help---
165 Support for Logitech devices that are not fully compliant with HID standard. 150 Support for Logitech devices that are not fully compliant with HID standard.
166 151
@@ -191,21 +176,28 @@ config LOGIRUMBLEPAD2_FF
191config HID_MICROSOFT 176config HID_MICROSOFT
192 tristate "Microsoft" if EMBEDDED 177 tristate "Microsoft" if EMBEDDED
193 depends on USB_HID 178 depends on USB_HID
194 default y 179 default !EMBEDDED
195 ---help--- 180 ---help---
196 Support for Microsoft devices that are not fully compliant with HID standard. 181 Support for Microsoft devices that are not fully compliant with HID standard.
197 182
198config HID_MONTEREY 183config HID_MONTEREY
199 tristate "Monterey" if EMBEDDED 184 tristate "Monterey" if EMBEDDED
200 depends on USB_HID 185 depends on USB_HID
201 default y 186 default !EMBEDDED
202 ---help--- 187 ---help---
203 Support for Monterey Genius KB29E. 188 Support for Monterey Genius KB29E.
204 189
190config HID_NTRIG
191 tristate "NTrig" if EMBEDDED
192 depends on USB_HID
193 default !EMBEDDED
194 ---help---
195 Support for N-Trig touch screen.
196
205config HID_PANTHERLORD 197config HID_PANTHERLORD
206 tristate "Pantherlord devices support" if EMBEDDED 198 tristate "Pantherlord devices support" if EMBEDDED
207 depends on USB_HID 199 depends on USB_HID
208 default y 200 default !EMBEDDED
209 ---help--- 201 ---help---
210 Support for PantherLord/GreenAsia based device support. 202 Support for PantherLord/GreenAsia based device support.
211 203
@@ -220,31 +212,47 @@ config PANTHERLORD_FF
220config HID_PETALYNX 212config HID_PETALYNX
221 tristate "Petalynx" if EMBEDDED 213 tristate "Petalynx" if EMBEDDED
222 depends on USB_HID 214 depends on USB_HID
223 default y 215 default !EMBEDDED
224 ---help--- 216 ---help---
225 Support for Petalynx Maxter remote control. 217 Support for Petalynx Maxter remote control.
226 218
227config HID_SAMSUNG 219config HID_SAMSUNG
228 tristate "Samsung" if EMBEDDED 220 tristate "Samsung" if EMBEDDED
229 depends on USB_HID 221 depends on USB_HID
230 default y 222 default !EMBEDDED
231 ---help--- 223 ---help---
232 Support for Samsung InfraRed remote control. 224 Support for Samsung InfraRed remote control.
233 225
234config HID_SONY 226config HID_SONY
235 tristate "Sony" if EMBEDDED 227 tristate "Sony" if EMBEDDED
236 depends on USB_HID 228 depends on USB_HID
237 default y 229 default !EMBEDDED
238 ---help--- 230 ---help---
239 Support for Sony PS3 controller. 231 Support for Sony PS3 controller.
240 232
241config HID_SUNPLUS 233config HID_SUNPLUS
242 tristate "Sunplus" if EMBEDDED 234 tristate "Sunplus" if EMBEDDED
243 depends on USB_HID 235 depends on USB_HID
244 default y 236 default !EMBEDDED
245 ---help--- 237 ---help---
246 Support for Sunplus wireless desktop. 238 Support for Sunplus wireless desktop.
247 239
240config GREENASIA_FF
241 tristate "GreenAsia (Product ID 0x12) force feedback support"
242 depends on USB_HID
243 select INPUT_FF_MEMLESS
244 ---help---
245 Say Y here if you have a GreenAsia (Product ID 0x12) based game controller
246 (like MANTA Warior MM816 and SpeedLink Strike2 SL-6635) or adapter
247 and want to enable force feedback support for it.
248
249config HID_TOPSEED
250 tristate "TopSeed Cyberlink remote control support" if EMBEDDED
251 depends on USB_HID
252 default !EMBEDDED
253 ---help---
254 Say Y if you have a TopSeed Cyberlink remote control.
255
248config THRUSTMASTER_FF 256config THRUSTMASTER_FF
249 tristate "ThrustMaster devices support" 257 tristate "ThrustMaster devices support"
250 depends on USB_HID 258 depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index b09e43e7413e..fbd021f153f1 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -23,22 +23,23 @@ endif
23obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o 23obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
24obj-$(CONFIG_HID_APPLE) += hid-apple.o 24obj-$(CONFIG_HID_APPLE) += hid-apple.o
25obj-$(CONFIG_HID_BELKIN) += hid-belkin.o 25obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
26obj-$(CONFIG_HID_BRIGHT) += hid-bright.o
27obj-$(CONFIG_HID_CHERRY) += hid-cherry.o 26obj-$(CONFIG_HID_CHERRY) += hid-cherry.o
28obj-$(CONFIG_HID_CHICONY) += hid-chicony.o 27obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
29obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o 28obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
30obj-$(CONFIG_HID_DELL) += hid-dell.o
31obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o 29obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
32obj-$(CONFIG_HID_GYRATION) += hid-gyration.o 30obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
33obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o 31obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
34obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o 32obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
35obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o 33obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o
34obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o
36obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o 35obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
37obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o 36obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
38obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o 37obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
39obj-$(CONFIG_HID_SONY) += hid-sony.o 38obj-$(CONFIG_HID_SONY) += hid-sony.o
40obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o 39obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o
40obj-$(CONFIG_GREENASIA_FF) += hid-gaff.o
41obj-$(CONFIG_THRUSTMASTER_FF) += hid-tmff.o 41obj-$(CONFIG_THRUSTMASTER_FF) += hid-tmff.o
42obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
42obj-$(CONFIG_ZEROPLUS_FF) += hid-zpff.o 43obj-$(CONFIG_ZEROPLUS_FF) += hid-zpff.o
43 44
44obj-$(CONFIG_USB_HID) += usbhid/ 45obj-$(CONFIG_USB_HID) += usbhid/
diff --git a/drivers/hid/hid-bright.c b/drivers/hid/hid-bright.c
deleted file mode 100644
index 38517a117dfd..000000000000
--- a/drivers/hid/hid-bright.c
+++ /dev/null
@@ -1,71 +0,0 @@
1/*
2 * HID driver for some bright "special" devices
3 *
4 * Copyright (c) 2008 Mauro Carvalho Chehab <mchehab@redhat.com>
5 *
6 * Based on hid-dell driver
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, or (at your option)
13 * any later version.
14 */
15
16#include <linux/device.h>
17#include <linux/hid.h>
18#include <linux/module.h>
19
20#include "hid-ids.h"
21
22static int bright_probe(struct hid_device *hdev, const struct hid_device_id *id)
23{
24 int ret;
25
26 ret = hid_parse(hdev);
27 if (ret) {
28 dev_err(&hdev->dev, "parse failed\n");
29 goto err_free;
30 }
31
32 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
33 if (ret) {
34 dev_err(&hdev->dev, "hw start failed\n");
35 goto err_free;
36 }
37
38 usbhid_set_leds(hdev);
39
40 return 0;
41err_free:
42 return ret;
43}
44
45static const struct hid_device_id bright_devices[] = {
46 { HID_USB_DEVICE(USB_VENDOR_ID_BRIGHT, USB_DEVICE_ID_BRIGHT_ABNT2) },
47 { }
48};
49MODULE_DEVICE_TABLE(hid, bright_devices);
50
51static struct hid_driver bright_driver = {
52 .name = "bright",
53 .id_table = bright_devices,
54 .probe = bright_probe,
55};
56
57static int bright_init(void)
58{
59 return hid_register_driver(&bright_driver);
60}
61
62static void bright_exit(void)
63{
64 hid_unregister_driver(&bright_driver);
65}
66
67module_init(bright_init);
68module_exit(bright_exit);
69MODULE_LICENSE("GPL");
70
71HID_COMPAT_LOAD_DRIVER(bright);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 40df3e1b4bd1..1cc967448f4d 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1218,6 +1218,7 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
1218} 1218}
1219EXPORT_SYMBOL_GPL(hid_connect); 1219EXPORT_SYMBOL_GPL(hid_connect);
1220 1220
1221/* a list of devices for which there is a specialized driver on HID bus */
1221static const struct hid_device_id hid_blacklist[] = { 1222static const struct hid_device_id hid_blacklist[] = {
1222 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, 1223 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
1223 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, 1224 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
@@ -1256,19 +1257,16 @@ static const struct hid_device_id hid_blacklist[] = {
1256 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, 1257 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
1257 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, 1258 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
1258 { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, 1259 { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
1259 { HID_USB_DEVICE(USB_VENDOR_ID_BRIGHT, USB_DEVICE_ID_BRIGHT_ABNT2) },
1260 { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, 1260 { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
1261 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, 1261 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
1262 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, 1262 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
1263 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, 1263 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
1264 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, 1264 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
1265 { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658) },
1266 { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_SK8115) },
1267 { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, 1265 { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
1268 { HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) },
1269 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, 1266 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
1270 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, 1267 { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
1271 { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, 1268 { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) },
1269 { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) },
1272 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, 1270 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
1273 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, 1271 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
1274 { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, 1272 { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
@@ -1279,7 +1277,6 @@ static const struct hid_device_id hid_blacklist[] = {
1279 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, 1277 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) },
1280 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, 1278 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) },
1281 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, 1279 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) },
1282 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD) },
1283 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, 1280 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) },
1284 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, 1281 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) },
1285 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, 1282 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
@@ -1297,23 +1294,111 @@ static const struct hid_device_id hid_blacklist[] = {
1297 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, 1294 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
1298 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, 1295 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
1299 { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, 1296 { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
1297 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
1300 { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, 1298 { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
1301 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, 1299 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
1302 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1300 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
1303 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, 1301 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
1304 { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, 1302 { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
1303 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
1304 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
1305 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
1306 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
1307 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
1308 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
1309 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
1305 1310
1306 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, 1311 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) },
1307 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, 1312 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
1308 { } 1313 { }
1309}; 1314};
1310 1315
1316struct hid_dynid {
1317 struct list_head list;
1318 struct hid_device_id id;
1319};
1320
1321/**
1322 * store_new_id - add a new HID device ID to this driver and re-probe devices
1323 * @driver: target device driver
1324 * @buf: buffer for scanning device ID data
1325 * @count: input size
1326 *
1327 * Adds a new dynamic hid device ID to this driver,
1328 * and causes the driver to probe for all devices again.
1329 */
1330static ssize_t store_new_id(struct device_driver *drv, const char *buf,
1331 size_t count)
1332{
1333 struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver);
1334 struct hid_dynid *dynid;
1335 __u32 bus, vendor, product;
1336 unsigned long driver_data = 0;
1337 int ret;
1338
1339 ret = sscanf(buf, "%x %x %x %lx",
1340 &bus, &vendor, &product, &driver_data);
1341 if (ret < 3)
1342 return -EINVAL;
1343
1344 dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
1345 if (!dynid)
1346 return -ENOMEM;
1347
1348 dynid->id.bus = bus;
1349 dynid->id.vendor = vendor;
1350 dynid->id.product = product;
1351 dynid->id.driver_data = driver_data;
1352
1353 spin_lock(&hdrv->dyn_lock);
1354 list_add_tail(&dynid->list, &hdrv->dyn_list);
1355 spin_unlock(&hdrv->dyn_lock);
1356
1357 ret = 0;
1358 if (get_driver(&hdrv->driver)) {
1359 ret = driver_attach(&hdrv->driver);
1360 put_driver(&hdrv->driver);
1361 }
1362
1363 return ret ? : count;
1364}
1365static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
1366
1367static void hid_free_dynids(struct hid_driver *hdrv)
1368{
1369 struct hid_dynid *dynid, *n;
1370
1371 spin_lock(&hdrv->dyn_lock);
1372 list_for_each_entry_safe(dynid, n, &hdrv->dyn_list, list) {
1373 list_del(&dynid->list);
1374 kfree(dynid);
1375 }
1376 spin_unlock(&hdrv->dyn_lock);
1377}
1378
1379static const struct hid_device_id *hid_match_device(struct hid_device *hdev,
1380 struct hid_driver *hdrv)
1381{
1382 struct hid_dynid *dynid;
1383
1384 spin_lock(&hdrv->dyn_lock);
1385 list_for_each_entry(dynid, &hdrv->dyn_list, list) {
1386 if (hid_match_one_id(hdev, &dynid->id)) {
1387 spin_unlock(&hdrv->dyn_lock);
1388 return &dynid->id;
1389 }
1390 }
1391 spin_unlock(&hdrv->dyn_lock);
1392
1393 return hid_match_id(hdev, hdrv->id_table);
1394}
1395
1311static int hid_bus_match(struct device *dev, struct device_driver *drv) 1396static int hid_bus_match(struct device *dev, struct device_driver *drv)
1312{ 1397{
1313 struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); 1398 struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver);
1314 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1399 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1315 1400
1316 if (!hid_match_id(hdev, hdrv->id_table)) 1401 if (!hid_match_device(hdev, hdrv))
1317 return 0; 1402 return 0;
1318 1403
1319 /* generic wants all non-blacklisted */ 1404 /* generic wants all non-blacklisted */
@@ -1332,7 +1417,7 @@ static int hid_device_probe(struct device *dev)
1332 int ret = 0; 1417 int ret = 0;
1333 1418
1334 if (!hdev->driver) { 1419 if (!hdev->driver) {
1335 id = hid_match_id(hdev, hdrv->id_table); 1420 id = hid_match_device(hdev, hdrv);
1336 if (id == NULL) 1421 if (id == NULL)
1337 return -ENODEV; 1422 return -ENODEV;
1338 1423
@@ -1398,6 +1483,7 @@ static struct bus_type hid_bus_type = {
1398 .uevent = hid_uevent, 1483 .uevent = hid_uevent,
1399}; 1484};
1400 1485
1486/* a list of devices that shouldn't be handled by HID core at all */
1401static const struct hid_device_id hid_ignore_list[] = { 1487static const struct hid_device_id hid_ignore_list[] = {
1402 { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR) }, 1488 { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR) },
1403 { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302) }, 1489 { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302) },
@@ -1420,6 +1506,7 @@ static const struct hid_device_id hid_ignore_list[] = {
1420 { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109) }, 1506 { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109) },
1421 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM) }, 1507 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM) },
1422 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE) }, 1508 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE) },
1509 { HID_USB_DEVICE(USB_VENDOR_ID_DEALEXTREAME, USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701) },
1423 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, 1510 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) },
1424 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, 1511 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) },
1425 { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, 1512 { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
@@ -1524,15 +1611,14 @@ static const struct hid_device_id hid_ignore_list[] = {
1524 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) }, 1611 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) },
1525 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) }, 1612 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) },
1526 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, 1613 { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
1614 { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) },
1527 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) }, 1615 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) },
1528 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) }, 1616 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) },
1529 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) }, 1617 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) },
1618 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4) },
1619 { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5) },
1530 { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) }, 1620 { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) },
1531 { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) }, 1621 { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) },
1532 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
1533 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
1534 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
1535 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
1536 { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, 1622 { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
1537 { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, 1623 { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
1538 { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, 1624 { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
@@ -1543,8 +1629,6 @@ static const struct hid_device_id hid_ignore_list[] = {
1543 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) }, 1629 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) },
1544 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) }, 1630 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) },
1545 { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, 1631 { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) },
1546 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
1547 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
1548 { } 1632 { }
1549}; 1633};
1550 1634
@@ -1577,6 +1661,9 @@ static const struct hid_device_id hid_mouse_ignore_list[] = {
1577 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, 1661 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) },
1578 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, 1662 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) },
1579 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, 1663 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) },
1664 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
1665 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
1666 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) },
1580 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, 1667 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
1581 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, 1668 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
1582 { } 1669 { }
@@ -1618,9 +1705,10 @@ int hid_add_device(struct hid_device *hdev)
1618 if (hid_ignore(hdev)) 1705 if (hid_ignore(hdev))
1619 return -ENODEV; 1706 return -ENODEV;
1620 1707
1621 /* XXX hack, any other cleaner solution < 20 bus_id bytes? */ 1708 /* XXX hack, any other cleaner solution after the driver core
1622 sprintf(hdev->dev.bus_id, "%04X:%04X:%04X.%04X", hdev->bus, 1709 * is converted to allow more than 20 bytes as the device name? */
1623 hdev->vendor, hdev->product, atomic_inc_return(&id)); 1710 dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
1711 hdev->vendor, hdev->product, atomic_inc_return(&id));
1624 1712
1625 ret = device_add(&hdev->dev); 1713 ret = device_add(&hdev->dev);
1626 if (!ret) 1714 if (!ret)
@@ -1695,18 +1783,33 @@ EXPORT_SYMBOL_GPL(hid_destroy_device);
1695int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, 1783int __hid_register_driver(struct hid_driver *hdrv, struct module *owner,
1696 const char *mod_name) 1784 const char *mod_name)
1697{ 1785{
1786 int ret;
1787
1698 hdrv->driver.name = hdrv->name; 1788 hdrv->driver.name = hdrv->name;
1699 hdrv->driver.bus = &hid_bus_type; 1789 hdrv->driver.bus = &hid_bus_type;
1700 hdrv->driver.owner = owner; 1790 hdrv->driver.owner = owner;
1701 hdrv->driver.mod_name = mod_name; 1791 hdrv->driver.mod_name = mod_name;
1702 1792
1703 return driver_register(&hdrv->driver); 1793 INIT_LIST_HEAD(&hdrv->dyn_list);
1794 spin_lock_init(&hdrv->dyn_lock);
1795
1796 ret = driver_register(&hdrv->driver);
1797 if (ret)
1798 return ret;
1799
1800 ret = driver_create_file(&hdrv->driver, &driver_attr_new_id);
1801 if (ret)
1802 driver_unregister(&hdrv->driver);
1803
1804 return ret;
1704} 1805}
1705EXPORT_SYMBOL_GPL(__hid_register_driver); 1806EXPORT_SYMBOL_GPL(__hid_register_driver);
1706 1807
1707void hid_unregister_driver(struct hid_driver *hdrv) 1808void hid_unregister_driver(struct hid_driver *hdrv)
1708{ 1809{
1810 driver_remove_file(&hdrv->driver, &driver_attr_new_id);
1709 driver_unregister(&hdrv->driver); 1811 driver_unregister(&hdrv->driver);
1812 hid_free_dynids(hdrv);
1710} 1813}
1711EXPORT_SYMBOL_GPL(hid_unregister_driver); 1814EXPORT_SYMBOL_GPL(hid_unregister_driver);
1712 1815
diff --git a/drivers/hid/hid-dell.c b/drivers/hid/hid-dell.c
deleted file mode 100644
index f5474300b83a..000000000000
--- a/drivers/hid/hid-dell.c
+++ /dev/null
@@ -1,76 +0,0 @@
1/*
2 * HID driver for some dell "special" devices
3 *
4 * Copyright (c) 1999 Andreas Gal
5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7 * Copyright (c) 2006-2007 Jiri Kosina
8 * Copyright (c) 2007 Paul Walmsley
9 * Copyright (c) 2008 Jiri Slaby
10 */
11
12/*
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 */
18
19#include <linux/device.h>
20#include <linux/hid.h>
21#include <linux/module.h>
22
23#include "hid-ids.h"
24
25static int dell_probe(struct hid_device *hdev, const struct hid_device_id *id)
26{
27 int ret;
28
29 ret = hid_parse(hdev);
30 if (ret) {
31 dev_err(&hdev->dev, "parse failed\n");
32 goto err_free;
33 }
34
35 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
36 if (ret) {
37 dev_err(&hdev->dev, "hw start failed\n");
38 goto err_free;
39 }
40
41 usbhid_set_leds(hdev);
42
43 return 0;
44err_free:
45 return ret;
46}
47
48static const struct hid_device_id dell_devices[] = {
49 { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658) },
50 { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_SK8115) },
51 { HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) },
52 { }
53};
54MODULE_DEVICE_TABLE(hid, dell_devices);
55
56static struct hid_driver dell_driver = {
57 .name = "dell",
58 .id_table = dell_devices,
59 .probe = dell_probe,
60};
61
62static int dell_init(void)
63{
64 return hid_register_driver(&dell_driver);
65}
66
67static void dell_exit(void)
68{
69 hid_unregister_driver(&dell_driver);
70}
71
72module_init(dell_init);
73module_exit(dell_exit);
74MODULE_LICENSE("GPL");
75
76HID_COMPAT_LOAD_DRIVER(dell);
diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c
index e148f86fb58e..b4cc0f743d63 100644
--- a/drivers/hid/hid-dummy.c
+++ b/drivers/hid/hid-dummy.c
@@ -43,6 +43,9 @@ static int __init hid_dummy_init(void)
43#ifdef CONFIG_HID_MONTEREY_MODULE 43#ifdef CONFIG_HID_MONTEREY_MODULE
44 HID_COMPAT_CALL_DRIVER(monterey); 44 HID_COMPAT_CALL_DRIVER(monterey);
45#endif 45#endif
46#ifdef CONFIG_HID_NTRIG_MODULE
47 HID_COMPAT_CALL_DRIVER(ntrig);
48#endif
46#ifdef CONFIG_HID_PANTHERLORD_MODULE 49#ifdef CONFIG_HID_PANTHERLORD_MODULE
47 HID_COMPAT_CALL_DRIVER(pantherlord); 50 HID_COMPAT_CALL_DRIVER(pantherlord);
48#endif 51#endif
@@ -58,6 +61,9 @@ static int __init hid_dummy_init(void)
58#ifdef CONFIG_HID_SUNPLUS_MODULE 61#ifdef CONFIG_HID_SUNPLUS_MODULE
59 HID_COMPAT_CALL_DRIVER(sunplus); 62 HID_COMPAT_CALL_DRIVER(sunplus);
60#endif 63#endif
64#ifdef CONFIG_GREENASIA_FF_MODULE
65 HID_COMPAT_CALL_DRIVER(greenasia);
66#endif
61#ifdef CONFIG_THRUSTMASTER_FF_MODULE 67#ifdef CONFIG_THRUSTMASTER_FF_MODULE
62 HID_COMPAT_CALL_DRIVER(thrustmaster); 68 HID_COMPAT_CALL_DRIVER(thrustmaster);
63#endif 69#endif
diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c
new file mode 100644
index 000000000000..71211f6a4f02
--- /dev/null
+++ b/drivers/hid/hid-gaff.c
@@ -0,0 +1,185 @@
1/*
2 * Force feedback support for GreenAsia (Product ID 0x12) based devices
3 *
4 * The devices are distributed under various names and the same USB device ID
5 * can be used in many game controllers.
6 *
7 *
8 * 0e8f:0012 "GreenAsia Inc. USB Joystick "
9 * - tested with MANTA Warior MM816 and SpeedLink Strike2 SL-6635.
10 *
11 * Copyright (c) 2008 Lukasz Lubojanski <lukasz@lubojanski.info>
12 */
13
14/*
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#include <linux/input.h>
31#include <linux/usb.h>
32#include <linux/hid.h>
33#include "hid-ids.h"
34#include "usbhid/usbhid.h"
35
36struct gaff_device {
37 struct hid_report *report;
38};
39
40static int hid_gaff_play(struct input_dev *dev, void *data,
41 struct ff_effect *effect)
42{
43 struct hid_device *hid = input_get_drvdata(dev);
44 struct gaff_device *gaff = data;
45 int left, right;
46
47 left = effect->u.rumble.strong_magnitude;
48 right = effect->u.rumble.weak_magnitude;
49
50 dbg_hid("called with 0x%04x 0x%04x", left, right);
51
52 left = left * 0xfe / 0xffff;
53 right = right * 0xfe / 0xffff;
54
55 gaff->report->field[0]->value[0] = 0x51;
56 gaff->report->field[0]->value[1] = 0x0;
57 gaff->report->field[0]->value[2] = right;
58 gaff->report->field[0]->value[3] = 0;
59 gaff->report->field[0]->value[4] = left;
60 gaff->report->field[0]->value[5] = 0;
61 dbg_hid("running with 0x%02x 0x%02x", left, right);
62 usbhid_submit_report(hid, gaff->report, USB_DIR_OUT);
63
64 gaff->report->field[0]->value[0] = 0xfa;
65 gaff->report->field[0]->value[1] = 0xfe;
66 gaff->report->field[0]->value[2] = 0x0;
67 gaff->report->field[0]->value[4] = 0x0;
68
69 usbhid_submit_report(hid, gaff->report, USB_DIR_OUT);
70
71 return 0;
72}
73
74static int gaff_init(struct hid_device *hid)
75{
76 struct gaff_device *gaff;
77 struct hid_report *report;
78 struct hid_input *hidinput = list_entry(hid->inputs.next,
79 struct hid_input, list);
80 struct list_head *report_list =
81 &hid->report_enum[HID_OUTPUT_REPORT].report_list;
82 struct list_head *report_ptr = report_list;
83 struct input_dev *dev = hidinput->input;
84 int error;
85
86 if (list_empty(report_list)) {
87 dev_err(&hid->dev, "no output reports found\n");
88 return -ENODEV;
89 }
90
91 report_ptr = report_ptr->next;
92
93 report = list_entry(report_ptr, struct hid_report, list);
94 if (report->maxfield < 1) {
95 dev_err(&hid->dev, "no fields in the report\n");
96 return -ENODEV;
97 }
98
99 if (report->field[0]->report_count < 6) {
100 dev_err(&hid->dev, "not enough values in the field\n");
101 return -ENODEV;
102 }
103
104 gaff = kzalloc(sizeof(struct gaff_device), GFP_KERNEL);
105 if (!gaff)
106 return -ENOMEM;
107
108 set_bit(FF_RUMBLE, dev->ffbit);
109
110 error = input_ff_create_memless(dev, gaff, hid_gaff_play);
111 if (error) {
112 kfree(gaff);
113 return error;
114 }
115
116 gaff->report = report;
117 gaff->report->field[0]->value[0] = 0x51;
118 gaff->report->field[0]->value[1] = 0x00;
119 gaff->report->field[0]->value[2] = 0x00;
120 gaff->report->field[0]->value[3] = 0x00;
121 usbhid_submit_report(hid, gaff->report, USB_DIR_OUT);
122
123 gaff->report->field[0]->value[0] = 0xfa;
124 gaff->report->field[0]->value[1] = 0xfe;
125
126 usbhid_submit_report(hid, gaff->report, USB_DIR_OUT);
127
128 dev_info(&hid->dev, "Force Feedback for GreenAsia 0x12"
129 " devices by Lukasz Lubojanski <lukasz@lubojanski.info>\n");
130
131 return 0;
132}
133
134static int ga_probe(struct hid_device *hdev, const struct hid_device_id *id)
135{
136 int ret;
137
138 dev_dbg(&hdev->dev, "Greenasia HID hardware probe...");
139
140 ret = hid_parse(hdev);
141 if (ret) {
142 dev_err(&hdev->dev, "parse failed\n");
143 goto err;
144 }
145
146 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
147 if (ret) {
148 dev_err(&hdev->dev, "hw start failed\n");
149 goto err;
150 }
151
152 gaff_init(hdev);
153
154 return 0;
155err:
156 return ret;
157}
158
159static const struct hid_device_id ga_devices[] = {
160 { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012), },
161 { }
162};
163MODULE_DEVICE_TABLE(hid, ga_devices);
164
165static struct hid_driver ga_driver = {
166 .name = "greenasia",
167 .id_table = ga_devices,
168 .probe = ga_probe,
169};
170
171static int __init ga_init(void)
172{
173 return hid_register_driver(&ga_driver);
174}
175
176static void __exit ga_exit(void)
177{
178 hid_unregister_driver(&ga_driver);
179}
180
181module_init(ga_init);
182module_exit(ga_exit);
183MODULE_LICENSE("GPL");
184
185HID_COMPAT_LOAD_DRIVER(greenasia);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 39289699c32f..88511970508d 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -107,9 +107,6 @@
107#define USB_VENDOR_ID_BELKIN 0x050d 107#define USB_VENDOR_ID_BELKIN 0x050d
108#define USB_DEVICE_ID_FLIP_KVM 0x3201 108#define USB_DEVICE_ID_FLIP_KVM 0x3201
109 109
110#define USB_VENDOR_ID_BRIGHT 0x1241
111#define USB_DEVICE_ID_BRIGHT_ABNT2 0x1503
112
113#define USB_VENDOR_ID_BERKSHIRE 0x0c98 110#define USB_VENDOR_ID_BERKSHIRE 0x0c98
114#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 111#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
115 112
@@ -141,9 +138,8 @@
141#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61 138#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61
142#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64 139#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64
143 140
144#define USB_VENDOR_ID_DELL 0x413c 141#define USB_VENDOR_ID_DEALEXTREAME 0x10c5
145#define USB_DEVICE_ID_DELL_W7658 0x2005 142#define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a
146#define USB_DEVICE_ID_DELL_SK8115 0x2105
147 143
148#define USB_VENDOR_ID_DELORME 0x1163 144#define USB_VENDOR_ID_DELORME 0x1163
149#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 145#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
@@ -167,9 +163,6 @@
167 163
168#define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc 164#define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc
169 165
170#define USB_VENDOR_ID_GENERIC_13BA 0x13ba
171#define USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE 0x0017
172
173#define USB_VENDOR_ID_GLAB 0x06c2 166#define USB_VENDOR_ID_GLAB 0x06c2
174#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 167#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038
175#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 168#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039
@@ -292,7 +285,6 @@
292#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 285#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294
293#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 286#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295
294#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a 287#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a
295#define USB_DEVICE_ID_LOGITECH_KBD 0xc311
296#define USB_DEVICE_ID_S510_RECEIVER 0xc50c 288#define USB_DEVICE_ID_S510_RECEIVER 0xc50c
297#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 289#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
298#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 290#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512
@@ -339,6 +331,9 @@
339#define USB_VENDOR_ID_NEC 0x073e 331#define USB_VENDOR_ID_NEC 0x073e
340#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 332#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
341 333
334#define USB_VENDOR_ID_NTRIG 0x1b96
335#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001
336
342#define USB_VENDOR_ID_ONTRAK 0x0a07 337#define USB_VENDOR_ID_ONTRAK 0x0a07
343#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 338#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064
344 339
@@ -353,6 +348,9 @@
353#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 348#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43
354#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003 349#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003
355 350
351#define USB_VENDOR_ID_POWERCOM 0x0d9f
352#define USB_DEVICE_ID_POWERCOM_UPS 0x0002
353
356#define USB_VENDOR_ID_SAITEK 0x06a3 354#define USB_VENDOR_ID_SAITEK 0x06a3
357#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 355#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
358 356
@@ -367,6 +365,8 @@
367#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD 0x0038 365#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD 0x0038
368#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2 0x0036 366#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2 0x0036
369#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3 0x0034 367#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3 0x0034
368#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4 0x0044
369#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5 0x0045
370 370
371#define USB_VENDOR_ID_SUN 0x0430 371#define USB_VENDOR_ID_SUN 0x0430
372#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab 372#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab
@@ -383,9 +383,15 @@
383#define USB_VENDOR_ID_TOPMAX 0x0663 383#define USB_VENDOR_ID_TOPMAX 0x0663
384#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 384#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103
385 385
386#define USB_VENDOR_ID_TOPSEED 0x0766
387#define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204
388
386#define USB_VENDOR_ID_TURBOX 0x062a 389#define USB_VENDOR_ID_TURBOX 0x062a
387#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 390#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201
388 391
392#define USB_VENDOR_ID_UCLOGIC 0x5543
393#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042
394
389#define USB_VENDOR_ID_VERNIER 0x08f7 395#define USB_VENDOR_ID_VERNIER 0x08f7
390#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 396#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001
391#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 397#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 2bae340eafe2..83e07c9f4144 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -26,7 +26,6 @@
26#define LG_RDESC 0x001 26#define LG_RDESC 0x001
27#define LG_BAD_RELATIVE_KEYS 0x002 27#define LG_BAD_RELATIVE_KEYS 0x002
28#define LG_DUPLICATE_USAGES 0x004 28#define LG_DUPLICATE_USAGES 0x004
29#define LG_RESET_LEDS 0x008
30#define LG_EXPANDED_KEYMAP 0x010 29#define LG_EXPANDED_KEYMAP 0x010
31#define LG_IGNORE_DOUBLED_WHEEL 0x020 30#define LG_IGNORE_DOUBLED_WHEEL 0x020
32#define LG_WIRELESS 0x040 31#define LG_WIRELESS 0x040
@@ -248,9 +247,6 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
248 goto err_free; 247 goto err_free;
249 } 248 }
250 249
251 if (quirks & LG_RESET_LEDS)
252 usbhid_set_leds(hdev);
253
254 if (quirks & LG_FF) 250 if (quirks & LG_FF)
255 lgff_init(hdev); 251 lgff_init(hdev);
256 if (quirks & LG_FF2) 252 if (quirks & LG_FF2)
@@ -279,9 +275,6 @@ static const struct hid_device_id lg_devices[] = {
279 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI), 275 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI),
280 .driver_data = LG_DUPLICATE_USAGES }, 276 .driver_data = LG_DUPLICATE_USAGES },
281 277
282 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD),
283 .driver_data = LG_RESET_LEDS },
284
285 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD), 278 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD),
286 .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, 279 .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP },
287 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500), 280 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500),
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index d718b1607d0f..25b10dcad90d 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -30,7 +30,7 @@
30#define MS_NOGET 0x10 30#define MS_NOGET 0x10
31 31
32/* 32/*
33 * Microsoft Wireless Desktop Receiver (Model 1028) has several 33 * Microsoft Wireless Desktop Receiver (Model 1028) has
34 * 'Usage Min/Max' where it ought to have 'Physical Min/Max' 34 * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
35 */ 35 */
36static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, 36static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
@@ -38,17 +38,12 @@ static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
38{ 38{
39 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); 39 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
40 40
41 if ((quirks & MS_RDESC) && rsize == 571 && rdesc[284] == 0x19 && 41 if ((quirks & MS_RDESC) && rsize == 571 && rdesc[557] == 0x19 &&
42 rdesc[286] == 0x2a && rdesc[304] == 0x19 &&
43 rdesc[306] == 0x29 && rdesc[352] == 0x1a &&
44 rdesc[355] == 0x2a && rdesc[557] == 0x19 &&
45 rdesc[559] == 0x29) { 42 rdesc[559] == 0x29) {
46 dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver " 43 dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver "
47 "Model 1028 report descriptor\n"); 44 "Model 1028 report descriptor\n");
48 rdesc[284] = rdesc[304] = rdesc[557] = 0x35; 45 rdesc[557] = 0x35;
49 rdesc[352] = 0x36; 46 rdesc[559] = 0x45;
50 rdesc[286] = rdesc[355] = 0x46;
51 rdesc[306] = rdesc[559] = 0x45;
52 } 47 }
53} 48}
54 49
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
new file mode 100644
index 000000000000..db44fbd7bdf6
--- /dev/null
+++ b/drivers/hid/hid-ntrig.c
@@ -0,0 +1,82 @@
1/*
2 * HID driver for some ntrig "special" devices
3 *
4 * Copyright (c) 1999 Andreas Gal
5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7 * Copyright (c) 2006-2007 Jiri Kosina
8 * Copyright (c) 2007 Paul Walmsley
9 * Copyright (c) 2008 Jiri Slaby
10 * Copyright (c) 2008 Rafi Rubin
11 *
12 */
13
14/*
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the Free
17 * Software Foundation; either version 2 of the License, or (at your option)
18 * any later version.
19 */
20
21#include <linux/device.h>
22#include <linux/hid.h>
23#include <linux/module.h>
24
25#include "hid-ids.h"
26
27#define NTRIG_DUPLICATE_USAGES 0x001
28
29#define nt_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
30 EV_KEY, (c))
31
32static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
33 struct hid_field *field, struct hid_usage *usage,
34 unsigned long **bit, int *max)
35{
36 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_DIGITIZER &&
37 (usage->hid & 0xff) == 0x47) {
38 nt_map_key_clear(BTN_TOOL_DOUBLETAP);
39 return 1;
40 }
41 return 0;
42}
43
44static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi,
45 struct hid_field *field, struct hid_usage *usage,
46 unsigned long **bit, int *max)
47{
48 if (usage->type == EV_KEY || usage->type == EV_REL
49 || usage->type == EV_ABS)
50 clear_bit(usage->code, *bit);
51
52 return 0;
53}
54static const struct hid_device_id ntrig_devices[] = {
55 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN),
56 .driver_data = NTRIG_DUPLICATE_USAGES },
57 { }
58};
59MODULE_DEVICE_TABLE(hid, ntrig_devices);
60
61static struct hid_driver ntrig_driver = {
62 .name = "ntrig",
63 .id_table = ntrig_devices,
64 .input_mapping = ntrig_input_mapping,
65 .input_mapped = ntrig_input_mapped,
66};
67
68static int ntrig_init(void)
69{
70 return hid_register_driver(&ntrig_driver);
71}
72
73static void ntrig_exit(void)
74{
75 hid_unregister_driver(&ntrig_driver);
76}
77
78module_init(ntrig_init);
79module_exit(ntrig_exit);
80MODULE_LICENSE("GPL");
81
82HID_COMPAT_LOAD_DRIVER(ntrig);
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 86e563b8d644..dd5a3979a4de 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -102,7 +102,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
102 } 102 }
103 103
104 ret = sony_set_operational(hdev); 104 ret = sony_set_operational(hdev);
105 if (ret) 105 if (ret < 0)
106 goto err_stop; 106 goto err_stop;
107 107
108 return 0; 108 return 0;
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c
new file mode 100644
index 000000000000..cca64a0564a9
--- /dev/null
+++ b/drivers/hid/hid-topseed.c
@@ -0,0 +1,77 @@
1/*
2 * HID driver for TopSeed Cyberlink remote
3 *
4 * Copyright (c) 2008 Lev Babiev
5 * based on hid-cherry driver
6 */
7
8/*
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 */
14
15#include <linux/device.h>
16#include <linux/hid.h>
17#include <linux/module.h>
18
19#include "hid-ids.h"
20
21#define ts_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
22 EV_KEY, (c))
23static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi,
24 struct hid_field *field, struct hid_usage *usage,
25 unsigned long **bit, int *max)
26{
27 if ((usage->hid & HID_USAGE_PAGE) != 0x0ffbc0000)
28 return 0;
29
30 switch (usage->hid & HID_USAGE) {
31 case 0x00d: ts_map_key_clear(KEY_HOME); break;
32 case 0x024: ts_map_key_clear(KEY_MENU); break;
33 case 0x025: ts_map_key_clear(KEY_TV); break;
34 case 0x048: ts_map_key_clear(KEY_RED); break;
35 case 0x047: ts_map_key_clear(KEY_GREEN); break;
36 case 0x049: ts_map_key_clear(KEY_YELLOW); break;
37 case 0x04a: ts_map_key_clear(KEY_BLUE); break;
38 case 0x04b: ts_map_key_clear(KEY_ANGLE); break;
39 case 0x04c: ts_map_key_clear(KEY_LANGUAGE); break;
40 case 0x04d: ts_map_key_clear(KEY_SUBTITLE); break;
41 case 0x031: ts_map_key_clear(KEY_AUDIO); break;
42 case 0x032: ts_map_key_clear(KEY_TEXT); break;
43 case 0x033: ts_map_key_clear(KEY_CHANNEL); break;
44 default:
45 return 0;
46 }
47
48 return 1;
49}
50
51static const struct hid_device_id ts_devices[] = {
52 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
53 { }
54};
55MODULE_DEVICE_TABLE(hid, ts_devices);
56
57static struct hid_driver ts_driver = {
58 .name = "topseed",
59 .id_table = ts_devices,
60 .input_mapping = ts_input_mapping,
61};
62
63static int ts_init(void)
64{
65 return hid_register_driver(&ts_driver);
66}
67
68static void ts_exit(void)
69{
70 hid_unregister_driver(&ts_driver);
71}
72
73module_init(ts_init);
74module_exit(ts_exit);
75MODULE_LICENSE("GPL");
76
77HID_COMPAT_LOAD_DRIVER(topseed);
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 7685ae6808c4..02b19db5442e 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -208,7 +208,7 @@ static int hidraw_release(struct inode * inode, struct file * file)
208 208
209 list_del(&list->node); 209 list_del(&list->node);
210 dev = hidraw_table[minor]; 210 dev = hidraw_table[minor];
211 if (!dev->open--) { 211 if (!--dev->open) {
212 if (list->hidraw->exist) 212 if (list->hidraw->exist)
213 dev->hid->ll_driver->close(dev->hid); 213 dev->hid->ll_driver->close(dev->hid);
214 else 214 else
@@ -265,7 +265,39 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
265 break; 265 break;
266 } 266 }
267 default: 267 default:
268 ret = -ENOTTY; 268 {
269 struct hid_device *hid = dev->hid;
270 if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) {
271 ret = -EINVAL;
272 break;
273 }
274
275 if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) {
276 int len;
277 if (!hid->name)
278 return 0;
279 len = strlen(hid->name) + 1;
280 if (len > _IOC_SIZE(cmd))
281 len = _IOC_SIZE(cmd);
282 ret = copy_to_user(user_arg, hid->name, len) ?
283 -EFAULT : len;
284 break;
285 }
286
287 if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) {
288 int len;
289 if (!hid->phys)
290 return 0;
291 len = strlen(hid->phys) + 1;
292 if (len > _IOC_SIZE(cmd))
293 len = _IOC_SIZE(cmd);
294 ret = copy_to_user(user_arg, hid->phys, len) ?
295 -EFAULT : len;
296 break;
297 }
298 }
299
300 ret = -ENOTTY;
269 } 301 }
270 unlock_kernel(); 302 unlock_kernel();
271 return ret; 303 return ret;
@@ -329,7 +361,7 @@ int hidraw_connect(struct hid_device *hid)
329 goto out; 361 goto out;
330 } 362 }
331 363
332 dev->dev = device_create(hidraw_class, NULL, MKDEV(hidraw_major, minor), 364 dev->dev = device_create(hidraw_class, &hid->dev, MKDEV(hidraw_major, minor),
333 NULL, "%s%d", "hidraw", minor); 365 NULL, "%s%d", "hidraw", minor);
334 366
335 if (IS_ERR(dev->dev)) { 367 if (IS_ERR(dev->dev)) {
diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig
index 5d9aa95fc3ef..4edb3bef94a6 100644
--- a/drivers/hid/usbhid/Kconfig
+++ b/drivers/hid/usbhid/Kconfig
@@ -45,7 +45,7 @@ config USB_HIDDEV
45 If unsure, say Y. 45 If unsure, say Y.
46 46
47menu "USB HID Boot Protocol drivers" 47menu "USB HID Boot Protocol drivers"
48 depends on USB!=n && USB_HID!=y 48 depends on USB!=n && USB_HID!=y && EMBEDDED
49 49
50config USB_KBD 50config USB_KBD
51 tristate "USB HIDBP Keyboard (simple Boot) support" 51 tristate "USB HIDBP Keyboard (simple Boot) support"
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 606369ea24ca..f0a0f72238ab 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -4,7 +4,7 @@
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-2007 Jiri Kosina 7 * Copyright (c) 2006-2008 Jiri Kosina
8 */ 8 */
9 9
10/* 10/*
@@ -102,7 +102,7 @@ static void hid_reset(struct work_struct *work)
102 struct usbhid_device *usbhid = 102 struct usbhid_device *usbhid =
103 container_of(work, struct usbhid_device, reset_work); 103 container_of(work, struct usbhid_device, reset_work);
104 struct hid_device *hid = usbhid->hid; 104 struct hid_device *hid = usbhid->hid;
105 int rc_lock, rc = 0; 105 int rc = 0;
106 106
107 if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) { 107 if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) {
108 dev_dbg(&usbhid->intf->dev, "clear halt\n"); 108 dev_dbg(&usbhid->intf->dev, "clear halt\n");
@@ -113,11 +113,10 @@ static void hid_reset(struct work_struct *work)
113 113
114 else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) { 114 else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) {
115 dev_dbg(&usbhid->intf->dev, "resetting device\n"); 115 dev_dbg(&usbhid->intf->dev, "resetting device\n");
116 rc = rc_lock = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf); 116 rc = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf);
117 if (rc_lock >= 0) { 117 if (rc == 0) {
118 rc = usb_reset_device(hid_to_usb_dev(hid)); 118 rc = usb_reset_device(hid_to_usb_dev(hid));
119 if (rc_lock) 119 usb_unlock_device(hid_to_usb_dev(hid));
120 usb_unlock_device(hid_to_usb_dev(hid));
121 } 120 }
122 clear_bit(HID_RESET_PENDING, &usbhid->iofl); 121 clear_bit(HID_RESET_PENDING, &usbhid->iofl);
123 } 122 }
@@ -641,9 +640,7 @@ static void hid_find_max_report(struct hid_device *hid, unsigned int type,
641 unsigned int size; 640 unsigned int size;
642 641
643 list_for_each_entry(report, &hid->report_enum[type].report_list, list) { 642 list_for_each_entry(report, &hid->report_enum[type].report_list, list) {
644 size = ((report->size - 1) >> 3) + 1; 643 size = ((report->size - 1) >> 3) + 1 + hid->report_enum[type].numbered;
645 if (type == HID_INPUT_REPORT && hid->report_enum[type].numbered)
646 size++;
647 if (*max < size) 644 if (*max < size)
648 *max = size; 645 *max = size;
649 } 646 }
@@ -653,13 +650,16 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
653{ 650{
654 struct usbhid_device *usbhid = hid->driver_data; 651 struct usbhid_device *usbhid = hid->driver_data;
655 652
656 if (!(usbhid->inbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->inbuf_dma))) 653 usbhid->inbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_KERNEL,
657 return -1; 654 &usbhid->inbuf_dma);
658 if (!(usbhid->outbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->outbuf_dma))) 655 usbhid->outbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_KERNEL,
659 return -1; 656 &usbhid->outbuf_dma);
660 if (!(usbhid->cr = usb_buffer_alloc(dev, sizeof(*(usbhid->cr)), GFP_ATOMIC, &usbhid->cr_dma))) 657 usbhid->cr = usb_buffer_alloc(dev, sizeof(*usbhid->cr), GFP_KERNEL,
661 return -1; 658 &usbhid->cr_dma);
662 if (!(usbhid->ctrlbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->ctrlbuf_dma))) 659 usbhid->ctrlbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_KERNEL,
660 &usbhid->ctrlbuf_dma);
661 if (!usbhid->inbuf || !usbhid->outbuf || !usbhid->cr ||
662 !usbhid->ctrlbuf)
663 return -1; 663 return -1;
664 664
665 return 0; 665 return 0;
@@ -807,7 +807,7 @@ static int usbhid_start(struct hid_device *hid)
807 int interval; 807 int interval;
808 808
809 endpoint = &interface->endpoint[n].desc; 809 endpoint = &interface->endpoint[n].desc;
810 if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */ 810 if (!usb_endpoint_xfer_int(endpoint))
811 continue; 811 continue;
812 812
813 interval = endpoint->bInterval; 813 interval = endpoint->bInterval;
@@ -876,6 +876,15 @@ static int usbhid_start(struct hid_device *hid)
876 876
877 set_bit(HID_STARTED, &usbhid->iofl); 877 set_bit(HID_STARTED, &usbhid->iofl);
878 878
879 /* Some keyboards don't work until their LEDs have been set.
880 * Since BIOSes do set the LEDs, it must be safe for any device
881 * that supports the keyboard boot protocol.
882 */
883 if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT &&
884 interface->desc.bInterfaceProtocol ==
885 USB_INTERFACE_PROTOCOL_KEYBOARD)
886 usbhid_set_leds(hid);
887
879 return 0; 888 return 0;
880 889
881fail: 890fail:
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 47ebe045f9b5..4391717d2519 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -54,6 +54,7 @@ static const struct hid_blacklist {
54 { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, 54 { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
55 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, 55 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
56 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, 56 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
57 { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT },
57 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, 58 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
58 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 59 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
59 60
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 83e851a5ed30..4940e4d70c2d 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -49,6 +49,7 @@
49struct hiddev { 49struct hiddev {
50 int exist; 50 int exist;
51 int open; 51 int open;
52 struct mutex existancelock;
52 wait_queue_head_t wait; 53 wait_queue_head_t wait;
53 struct hid_device *hid; 54 struct hid_device *hid;
54 struct list_head list; 55 struct list_head list;
@@ -63,6 +64,7 @@ struct hiddev_list {
63 struct fasync_struct *fasync; 64 struct fasync_struct *fasync;
64 struct hiddev *hiddev; 65 struct hiddev *hiddev;
65 struct list_head node; 66 struct list_head node;
67 struct mutex thread_lock;
66}; 68};
67 69
68static struct hiddev *hiddev_table[HIDDEV_MINORS]; 70static struct hiddev *hiddev_table[HIDDEV_MINORS];
@@ -264,29 +266,48 @@ static int hiddev_release(struct inode * inode, struct file * file)
264static int hiddev_open(struct inode *inode, struct file *file) 266static int hiddev_open(struct inode *inode, struct file *file)
265{ 267{
266 struct hiddev_list *list; 268 struct hiddev_list *list;
267 unsigned long flags; 269 int res;
268 270
269 int i = iminor(inode) - HIDDEV_MINOR_BASE; 271 int i = iminor(inode) - HIDDEV_MINOR_BASE;
270 272
271 if (i >= HIDDEV_MINORS || !hiddev_table[i]) 273 if (i >= HIDDEV_MINORS || i < 0 || !hiddev_table[i])
272 return -ENODEV; 274 return -ENODEV;
273 275
274 if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL))) 276 if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL)))
275 return -ENOMEM; 277 return -ENOMEM;
278 mutex_init(&list->thread_lock);
276 279
277 list->hiddev = hiddev_table[i]; 280 list->hiddev = hiddev_table[i];
278 281
279 spin_lock_irqsave(&list->hiddev->list_lock, flags);
280 list_add_tail(&list->node, &hiddev_table[i]->list);
281 spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
282 282
283 file->private_data = list; 283 file->private_data = list;
284 284
285 if (!list->hiddev->open++) 285 /*
286 if (list->hiddev->exist) 286 * no need for locking because the USB major number
287 usbhid_open(hiddev_table[i]->hid); 287 * is shared which usbcore guards against disconnect
288 */
289 if (list->hiddev->exist) {
290 if (!list->hiddev->open++) {
291 res = usbhid_open(hiddev_table[i]->hid);
292 if (res < 0) {
293 res = -EIO;
294 goto bail;
295 }
296 }
297 } else {
298 res = -ENODEV;
299 goto bail;
300 }
301
302 spin_lock_irq(&list->hiddev->list_lock);
303 list_add_tail(&list->node, &hiddev_table[i]->list);
304 spin_unlock_irq(&list->hiddev->list_lock);
288 305
289 return 0; 306 return 0;
307bail:
308 file->private_data = NULL;
309 kfree(list->hiddev);
310 return res;
290} 311}
291 312
292/* 313/*
@@ -305,7 +326,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun
305 DECLARE_WAITQUEUE(wait, current); 326 DECLARE_WAITQUEUE(wait, current);
306 struct hiddev_list *list = file->private_data; 327 struct hiddev_list *list = file->private_data;
307 int event_size; 328 int event_size;
308 int retval = 0; 329 int retval;
309 330
310 event_size = ((list->flags & HIDDEV_FLAG_UREF) != 0) ? 331 event_size = ((list->flags & HIDDEV_FLAG_UREF) != 0) ?
311 sizeof(struct hiddev_usage_ref) : sizeof(struct hiddev_event); 332 sizeof(struct hiddev_usage_ref) : sizeof(struct hiddev_event);
@@ -313,10 +334,14 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun
313 if (count < event_size) 334 if (count < event_size)
314 return 0; 335 return 0;
315 336
337 /* lock against other threads */
338 retval = mutex_lock_interruptible(&list->thread_lock);
339 if (retval)
340 return -ERESTARTSYS;
341
316 while (retval == 0) { 342 while (retval == 0) {
317 if (list->head == list->tail) { 343 if (list->head == list->tail) {
318 add_wait_queue(&list->hiddev->wait, &wait); 344 prepare_to_wait(&list->hiddev->wait, &wait, TASK_INTERRUPTIBLE);
319 set_current_state(TASK_INTERRUPTIBLE);
320 345
321 while (list->head == list->tail) { 346 while (list->head == list->tail) {
322 if (file->f_flags & O_NONBLOCK) { 347 if (file->f_flags & O_NONBLOCK) {
@@ -332,35 +357,45 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun
332 break; 357 break;
333 } 358 }
334 359
360 /* let O_NONBLOCK tasks run */
361 mutex_unlock(&list->thread_lock);
335 schedule(); 362 schedule();
363 if (mutex_lock_interruptible(&list->thread_lock))
364 return -EINTR;
336 set_current_state(TASK_INTERRUPTIBLE); 365 set_current_state(TASK_INTERRUPTIBLE);
337 } 366 }
367 finish_wait(&list->hiddev->wait, &wait);
338 368
339 set_current_state(TASK_RUNNING);
340 remove_wait_queue(&list->hiddev->wait, &wait);
341 } 369 }
342 370
343 if (retval) 371 if (retval) {
372 mutex_unlock(&list->thread_lock);
344 return retval; 373 return retval;
374 }
345 375
346 376
347 while (list->head != list->tail && 377 while (list->head != list->tail &&
348 retval + event_size <= count) { 378 retval + event_size <= count) {
349 if ((list->flags & HIDDEV_FLAG_UREF) == 0) { 379 if ((list->flags & HIDDEV_FLAG_UREF) == 0) {
350 if (list->buffer[list->tail].field_index != 380 if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE) {
351 HID_FIELD_INDEX_NONE) {
352 struct hiddev_event event; 381 struct hiddev_event event;
382
353 event.hid = list->buffer[list->tail].usage_code; 383 event.hid = list->buffer[list->tail].usage_code;
354 event.value = list->buffer[list->tail].value; 384 event.value = list->buffer[list->tail].value;
355 if (copy_to_user(buffer + retval, &event, sizeof(struct hiddev_event))) 385 if (copy_to_user(buffer + retval, &event, sizeof(struct hiddev_event))) {
386 mutex_unlock(&list->thread_lock);
356 return -EFAULT; 387 return -EFAULT;
388 }
357 retval += sizeof(struct hiddev_event); 389 retval += sizeof(struct hiddev_event);
358 } 390 }
359 } else { 391 } else {
360 if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE || 392 if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE ||
361 (list->flags & HIDDEV_FLAG_REPORT) != 0) { 393 (list->flags & HIDDEV_FLAG_REPORT) != 0) {
362 if (copy_to_user(buffer + retval, list->buffer + list->tail, sizeof(struct hiddev_usage_ref))) 394
395 if (copy_to_user(buffer + retval, list->buffer + list->tail, sizeof(struct hiddev_usage_ref))) {
396 mutex_unlock(&list->thread_lock);
363 return -EFAULT; 397 return -EFAULT;
398 }
364 retval += sizeof(struct hiddev_usage_ref); 399 retval += sizeof(struct hiddev_usage_ref);
365 } 400 }
366 } 401 }
@@ -368,6 +403,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun
368 } 403 }
369 404
370 } 405 }
406 mutex_unlock(&list->thread_lock);
371 407
372 return retval; 408 return retval;
373} 409}
@@ -555,7 +591,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
555 struct hid_field *field; 591 struct hid_field *field;
556 struct usbhid_device *usbhid = hid->driver_data; 592 struct usbhid_device *usbhid = hid->driver_data;
557 void __user *user_arg = (void __user *)arg; 593 void __user *user_arg = (void __user *)arg;
558 int i; 594 int i, r;
559 595
560 /* Called without BKL by compat methods so no BKL taken */ 596 /* Called without BKL by compat methods so no BKL taken */
561 597
@@ -619,10 +655,22 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
619 } 655 }
620 656
621 case HIDIOCGSTRING: 657 case HIDIOCGSTRING:
622 return hiddev_ioctl_string(hiddev, cmd, user_arg); 658 mutex_lock(&hiddev->existancelock);
659 if (hiddev->exist)
660 r = hiddev_ioctl_string(hiddev, cmd, user_arg);
661 else
662 r = -ENODEV;
663 mutex_unlock(&hiddev->existancelock);
664 return r;
623 665
624 case HIDIOCINITREPORT: 666 case HIDIOCINITREPORT:
667 mutex_lock(&hiddev->existancelock);
668 if (!hiddev->exist) {
669 mutex_unlock(&hiddev->existancelock);
670 return -ENODEV;
671 }
625 usbhid_init_reports(hid); 672 usbhid_init_reports(hid);
673 mutex_unlock(&hiddev->existancelock);
626 674
627 return 0; 675 return 0;
628 676
@@ -636,8 +684,12 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
636 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) 684 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
637 return -EINVAL; 685 return -EINVAL;
638 686
639 usbhid_submit_report(hid, report, USB_DIR_IN); 687 mutex_lock(&hiddev->existancelock);
640 usbhid_wait_io(hid); 688 if (hiddev->exist) {
689 usbhid_submit_report(hid, report, USB_DIR_IN);
690 usbhid_wait_io(hid);
691 }
692 mutex_unlock(&hiddev->existancelock);
641 693
642 return 0; 694 return 0;
643 695
@@ -651,8 +703,12 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
651 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) 703 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
652 return -EINVAL; 704 return -EINVAL;
653 705
654 usbhid_submit_report(hid, report, USB_DIR_OUT); 706 mutex_lock(&hiddev->existancelock);
655 usbhid_wait_io(hid); 707 if (hiddev->exist) {
708 usbhid_submit_report(hid, report, USB_DIR_OUT);
709 usbhid_wait_io(hid);
710 }
711 mutex_unlock(&hiddev->existancelock);
656 712
657 return 0; 713 return 0;
658 714
@@ -710,7 +766,13 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
710 case HIDIOCGUSAGES: 766 case HIDIOCGUSAGES:
711 case HIDIOCSUSAGES: 767 case HIDIOCSUSAGES:
712 case HIDIOCGCOLLECTIONINDEX: 768 case HIDIOCGCOLLECTIONINDEX:
713 return hiddev_ioctl_usage(hiddev, cmd, user_arg); 769 mutex_lock(&hiddev->existancelock);
770 if (hiddev->exist)
771 r = hiddev_ioctl_usage(hiddev, cmd, user_arg);
772 else
773 r = -ENODEV;
774 mutex_unlock(&hiddev->existancelock);
775 return r;
714 776
715 case HIDIOCGCOLLECTIONINFO: 777 case HIDIOCGCOLLECTIONINFO:
716 if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) 778 if (copy_from_user(&cinfo, user_arg, sizeof(cinfo)))
@@ -808,23 +870,24 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
808 if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL))) 870 if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL)))
809 return -1; 871 return -1;
810 872
811 retval = usb_register_dev(usbhid->intf, &hiddev_class);
812 if (retval) {
813 err_hid("Not able to get a minor for this device.");
814 kfree(hiddev);
815 return -1;
816 }
817
818 init_waitqueue_head(&hiddev->wait); 873 init_waitqueue_head(&hiddev->wait);
819 INIT_LIST_HEAD(&hiddev->list); 874 INIT_LIST_HEAD(&hiddev->list);
820 spin_lock_init(&hiddev->list_lock); 875 spin_lock_init(&hiddev->list_lock);
876 mutex_init(&hiddev->existancelock);
877 hid->hiddev = hiddev;
821 hiddev->hid = hid; 878 hiddev->hid = hid;
822 hiddev->exist = 1; 879 hiddev->exist = 1;
823 880
824 hid->minor = usbhid->intf->minor; 881 retval = usb_register_dev(usbhid->intf, &hiddev_class);
825 hid->hiddev = hiddev; 882 if (retval) {
826 883 err_hid("Not able to get a minor for this device.");
827 hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; 884 hid->hiddev = NULL;
885 kfree(hiddev);
886 return -1;
887 } else {
888 hid->minor = usbhid->intf->minor;
889 hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
890 }
828 891
829 return 0; 892 return 0;
830} 893}
@@ -839,7 +902,9 @@ void hiddev_disconnect(struct hid_device *hid)
839 struct hiddev *hiddev = hid->hiddev; 902 struct hiddev *hiddev = hid->hiddev;
840 struct usbhid_device *usbhid = hid->driver_data; 903 struct usbhid_device *usbhid = hid->driver_data;
841 904
905 mutex_lock(&hiddev->existancelock);
842 hiddev->exist = 0; 906 hiddev->exist = 0;
907 mutex_unlock(&hiddev->existancelock);
843 908
844 hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL; 909 hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL;
845 usb_deregister_dev(usbhid->intf, &hiddev_class); 910 usb_deregister_dev(usbhid->intf, &hiddev_class);
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h
index 332abcdf9956..9eb30564be9c 100644
--- a/drivers/hid/usbhid/usbhid.h
+++ b/drivers/hid/usbhid/usbhid.h
@@ -40,6 +40,16 @@ int usbhid_open(struct hid_device *hid);
40void usbhid_init_reports(struct hid_device *hid); 40void usbhid_init_reports(struct hid_device *hid);
41void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir); 41void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir);
42 42
43/* iofl flags */
44#define HID_CTRL_RUNNING 1
45#define HID_OUT_RUNNING 2
46#define HID_IN_RUNNING 3
47#define HID_RESET_PENDING 4
48#define HID_SUSPENDED 5
49#define HID_CLEAR_HALT 6
50#define HID_DISCONNECTED 7
51#define HID_STARTED 8
52
43/* 53/*
44 * USB-specific HID struct, to be pointed to 54 * USB-specific HID struct, to be pointed to
45 * from struct hid_device->driver_data 55 * from struct hid_device->driver_data