diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-23 12:44:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-23 12:44:31 -0400 |
commit | 876a4256d25b7fd7917f53e767da1ebdf3168457 (patch) | |
tree | 7dc10fad31d1048b8337d049a3572fa35e79e3fb | |
parent | 7c1fed03b9fa32d4323d5caa6a9c7dcdd7eba767 (diff) | |
parent | b22d8370061898f3029cdc2601fbdec493443f03 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
HID: apple_fn_keys F5 and F6
HID: remove quirk lookup from usbkbd/usbmouse
HID: Add mapping of new KEY_MEDIA_REPEAT keycode
HID: gyration remote support
HID: gyration sleep button quirk
HID: add quirk for Logitech DiNovo desktop
HID: fix quirk handling in usbmouse/kbd
HID: fix memory leak in hidraw_release
HID: add n-trig digitizer usage
HID: Invert HWHEEL mappings for some Logitech mice
HID:usbkbd:mark usb_kbd_keycode array as const
HID: add fn key support on Macbook Pro 4,1 and Macbook Air
HID: remove unused variable from hiddev compat ioctl
HID: fix compile issue in hiddev ioctl
HID: Push down BKL into ioctl handler in hidraw
HID: Switch hiddev to unlocked_ioctl
HID: use get/put_unaligned_* helpers
HID: fix report descriptor handling for MS Wireless model 1028
-rw-r--r-- | drivers/hid/hid-core.c | 10 | ||||
-rw-r--r-- | drivers/hid/hid-input-quirks.c | 40 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 3 | ||||
-rw-r--r-- | drivers/hid/hidraw.c | 48 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 22 | ||||
-rw-r--r-- | drivers/hid/usbhid/hiddev.c | 14 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbkbd.c | 10 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbmouse.c | 8 | ||||
-rw-r--r-- | include/linux/hid.h | 2 |
9 files changed, 106 insertions, 51 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index f43d6d3cf2fa..426ac5add585 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -780,7 +780,7 @@ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) | |||
780 | */ | 780 | */ |
781 | static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) | 781 | static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) |
782 | { | 782 | { |
783 | __le64 x; | 783 | u64 x; |
784 | u64 m = (1ULL << n) - 1; | 784 | u64 m = (1ULL << n) - 1; |
785 | 785 | ||
786 | if (n > 32) | 786 | if (n > 32) |
@@ -796,10 +796,10 @@ static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u3 | |||
796 | report += offset >> 3; | 796 | report += offset >> 3; |
797 | offset &= 7; | 797 | offset &= 7; |
798 | 798 | ||
799 | x = get_unaligned((__le64 *)report); | 799 | x = get_unaligned_le64(report); |
800 | x &= cpu_to_le64(~(m << offset)); | 800 | x &= ~(m << offset); |
801 | x |= cpu_to_le64(((u64) value) << offset); | 801 | x |= ((u64)value) << offset; |
802 | put_unaligned(x, (__le64 *) report); | 802 | put_unaligned_le64(x, report); |
803 | } | 803 | } |
804 | 804 | ||
805 | /* | 805 | /* |
diff --git a/drivers/hid/hid-input-quirks.c b/drivers/hid/hid-input-quirks.c index 4c2052c658f1..16feea014494 100644 --- a/drivers/hid/hid-input-quirks.c +++ b/drivers/hid/hid-input-quirks.c | |||
@@ -89,6 +89,29 @@ static int quirk_logitech_ultrax_remote(struct hid_usage *usage, struct input_de | |||
89 | return 1; | 89 | return 1; |
90 | } | 90 | } |
91 | 91 | ||
92 | static int quirk_gyration_remote(struct hid_usage *usage, struct input_dev *input, | ||
93 | unsigned long **bit, int *max) | ||
94 | { | ||
95 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) | ||
96 | return 0; | ||
97 | |||
98 | set_bit(EV_REP, input->evbit); | ||
99 | switch(usage->hid & HID_USAGE) { | ||
100 | /* Reported on Gyration MCE Remote */ | ||
101 | case 0x00d: map_key_clear(KEY_HOME); break; | ||
102 | case 0x024: map_key_clear(KEY_DVD); break; | ||
103 | case 0x025: map_key_clear(KEY_PVR); break; | ||
104 | case 0x046: map_key_clear(KEY_MEDIA); break; | ||
105 | case 0x047: map_key_clear(KEY_MP3); break; | ||
106 | case 0x049: map_key_clear(KEY_CAMERA); break; | ||
107 | case 0x04a: map_key_clear(KEY_VIDEO); break; | ||
108 | |||
109 | default: | ||
110 | return 0; | ||
111 | } | ||
112 | return 1; | ||
113 | } | ||
114 | |||
92 | static int quirk_chicony_tactical_pad(struct hid_usage *usage, struct input_dev *input, | 115 | static int quirk_chicony_tactical_pad(struct hid_usage *usage, struct input_dev *input, |
93 | unsigned long **bit, int *max) | 116 | unsigned long **bit, int *max) |
94 | { | 117 | { |
@@ -303,6 +326,9 @@ static int quirk_sunplus_wdesktop(struct hid_usage *usage, struct input_dev *inp | |||
303 | #define VENDOR_ID_EZKEY 0x0518 | 326 | #define VENDOR_ID_EZKEY 0x0518 |
304 | #define DEVICE_ID_BTC_8193 0x0002 | 327 | #define DEVICE_ID_BTC_8193 0x0002 |
305 | 328 | ||
329 | #define VENDOR_ID_GYRATION 0x0c16 | ||
330 | #define DEVICE_ID_GYRATION_REMOTE 0x0002 | ||
331 | |||
306 | #define VENDOR_ID_LOGITECH 0x046d | 332 | #define VENDOR_ID_LOGITECH 0x046d |
307 | #define DEVICE_ID_LOGITECH_RECEIVER 0xc101 | 333 | #define DEVICE_ID_LOGITECH_RECEIVER 0xc101 |
308 | #define DEVICE_ID_S510_RECEIVER 0xc50c | 334 | #define DEVICE_ID_S510_RECEIVER 0xc50c |
@@ -337,6 +363,8 @@ static const struct hid_input_blacklist { | |||
337 | 363 | ||
338 | { VENDOR_ID_EZKEY, DEVICE_ID_BTC_8193, quirk_btc_8193 }, | 364 | { VENDOR_ID_EZKEY, DEVICE_ID_BTC_8193, quirk_btc_8193 }, |
339 | 365 | ||
366 | { VENDOR_ID_GYRATION, DEVICE_ID_GYRATION_REMOTE, quirk_gyration_remote }, | ||
367 | |||
340 | { VENDOR_ID_LOGITECH, DEVICE_ID_LOGITECH_RECEIVER, quirk_logitech_ultrax_remote }, | 368 | { VENDOR_ID_LOGITECH, DEVICE_ID_LOGITECH_RECEIVER, quirk_logitech_ultrax_remote }, |
341 | { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER, quirk_logitech_wireless }, | 369 | { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER, quirk_logitech_wireless }, |
342 | { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER_2, quirk_logitech_wireless }, | 370 | { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER_2, quirk_logitech_wireless }, |
@@ -438,6 +466,18 @@ int hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struc | |||
438 | input_event(input, usage->type, REL_WHEEL, -value); | 466 | input_event(input, usage->type, REL_WHEEL, -value); |
439 | return 1; | 467 | return 1; |
440 | } | 468 | } |
469 | |||
470 | /* Gyration MCE remote "Sleep" key */ | ||
471 | if (hid->vendor == VENDOR_ID_GYRATION && | ||
472 | hid->product == DEVICE_ID_GYRATION_REMOTE && | ||
473 | (usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK && | ||
474 | (usage->hid & 0xff) == 0x82) { | ||
475 | input_event(input, usage->type, usage->code, 1); | ||
476 | input_sync(input); | ||
477 | input_event(input, usage->type, usage->code, 0); | ||
478 | input_sync(input); | ||
479 | return 1; | ||
480 | } | ||
441 | return 0; | 481 | return 0; |
442 | } | 482 | } |
443 | 483 | ||
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 5c52a20ad344..1b2e8dc3398d 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -100,6 +100,8 @@ static struct hidinput_key_translation apple_fn_keys[] = { | |||
100 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, | 100 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, |
101 | { KEY_F3, KEY_FN_F5, APPLE_FLAG_FKEY }, /* Exposé */ | 101 | { KEY_F3, KEY_FN_F5, APPLE_FLAG_FKEY }, /* Exposé */ |
102 | { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */ | 102 | { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */ |
103 | { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, | ||
104 | { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, | ||
103 | { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, | 105 | { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, |
104 | { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, | 106 | { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, |
105 | { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, | 107 | { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, |
@@ -612,6 +614,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
612 | case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break; | 614 | case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break; |
613 | case 0x0b7: map_key_clear(KEY_STOPCD); break; | 615 | case 0x0b7: map_key_clear(KEY_STOPCD); break; |
614 | case 0x0b8: map_key_clear(KEY_EJECTCD); break; | 616 | case 0x0b8: map_key_clear(KEY_EJECTCD); break; |
617 | case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT); break; | ||
615 | 618 | ||
616 | case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; | 619 | case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; |
617 | case 0x0e0: map_abs_clear(ABS_VOLUME); break; | 620 | case 0x0e0: map_abs_clear(ABS_VOLUME); break; |
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 0c6b4d4e7e27..c40f0403edaf 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
@@ -105,6 +105,7 @@ out: | |||
105 | static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | 105 | static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) |
106 | { | 106 | { |
107 | unsigned int minor = iminor(file->f_path.dentry->d_inode); | 107 | unsigned int minor = iminor(file->f_path.dentry->d_inode); |
108 | /* FIXME: What stops hidraw_table going NULL */ | ||
108 | struct hid_device *dev = hidraw_table[minor]->hid; | 109 | struct hid_device *dev = hidraw_table[minor]->hid; |
109 | __u8 *buf; | 110 | __u8 *buf; |
110 | int ret = 0; | 111 | int ret = 0; |
@@ -211,38 +212,43 @@ static int hidraw_release(struct inode * inode, struct file * file) | |||
211 | kfree(list->hidraw); | 212 | kfree(list->hidraw); |
212 | } | 213 | } |
213 | 214 | ||
215 | kfree(list); | ||
216 | |||
214 | return 0; | 217 | return 0; |
215 | } | 218 | } |
216 | 219 | ||
217 | static int hidraw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 220 | static long hidraw_ioctl(struct file *file, unsigned int cmd, |
221 | unsigned long arg) | ||
218 | { | 222 | { |
223 | struct inode *inode = file->f_path.dentry->d_inode; | ||
219 | unsigned int minor = iminor(inode); | 224 | unsigned int minor = iminor(inode); |
225 | long ret = 0; | ||
226 | /* FIXME: What stops hidraw_table going NULL */ | ||
220 | struct hidraw *dev = hidraw_table[minor]; | 227 | struct hidraw *dev = hidraw_table[minor]; |
221 | void __user *user_arg = (void __user*) arg; | 228 | void __user *user_arg = (void __user*) arg; |
222 | 229 | ||
230 | lock_kernel(); | ||
223 | switch (cmd) { | 231 | switch (cmd) { |
224 | case HIDIOCGRDESCSIZE: | 232 | case HIDIOCGRDESCSIZE: |
225 | if (put_user(dev->hid->rsize, (int __user *)arg)) | 233 | if (put_user(dev->hid->rsize, (int __user *)arg)) |
226 | return -EFAULT; | 234 | ret = -EFAULT; |
227 | return 0; | 235 | break; |
228 | 236 | ||
229 | case HIDIOCGRDESC: | 237 | case HIDIOCGRDESC: |
230 | { | 238 | { |
231 | __u32 len; | 239 | __u32 len; |
232 | 240 | ||
233 | if (get_user(len, (int __user *)arg)) | 241 | if (get_user(len, (int __user *)arg)) |
234 | return -EFAULT; | 242 | ret = -EFAULT; |
235 | 243 | else if (len > HID_MAX_DESCRIPTOR_SIZE - 1) | |
236 | if (len > HID_MAX_DESCRIPTOR_SIZE - 1) | 244 | ret = -EINVAL; |
237 | return -EINVAL; | 245 | else if (copy_to_user(user_arg + offsetof( |
238 | 246 | struct hidraw_report_descriptor, | |
239 | if (copy_to_user(user_arg + offsetof( | 247 | value[0]), |
240 | struct hidraw_report_descriptor, | 248 | dev->hid->rdesc, |
241 | value[0]), | 249 | min(dev->hid->rsize, len))) |
242 | dev->hid->rdesc, | 250 | ret = -EFAULT; |
243 | min(dev->hid->rsize, len))) | 251 | break; |
244 | return -EFAULT; | ||
245 | return 0; | ||
246 | } | 252 | } |
247 | case HIDIOCGRAWINFO: | 253 | case HIDIOCGRAWINFO: |
248 | { | 254 | { |
@@ -252,15 +258,13 @@ static int hidraw_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
252 | dinfo.vendor = dev->hid->vendor; | 258 | dinfo.vendor = dev->hid->vendor; |
253 | dinfo.product = dev->hid->product; | 259 | dinfo.product = dev->hid->product; |
254 | if (copy_to_user(user_arg, &dinfo, sizeof(dinfo))) | 260 | if (copy_to_user(user_arg, &dinfo, sizeof(dinfo))) |
255 | return -EFAULT; | 261 | ret = -EFAULT; |
256 | 262 | break; | |
257 | return 0; | ||
258 | } | 263 | } |
259 | default: | 264 | default: |
260 | printk(KERN_EMERG "hidraw: unsupported ioctl() %x\n", | 265 | ret = -ENOTTY; |
261 | cmd); | ||
262 | } | 266 | } |
263 | return -EINVAL; | 267 | return ret; |
264 | } | 268 | } |
265 | 269 | ||
266 | static const struct file_operations hidraw_ops = { | 270 | static const struct file_operations hidraw_ops = { |
@@ -270,7 +274,7 @@ static const struct file_operations hidraw_ops = { | |||
270 | .poll = hidraw_poll, | 274 | .poll = hidraw_poll, |
271 | .open = hidraw_open, | 275 | .open = hidraw_open, |
272 | .release = hidraw_release, | 276 | .release = hidraw_release, |
273 | .ioctl = hidraw_ioctl, | 277 | .unlocked_ioctl = hidraw_ioctl, |
274 | }; | 278 | }; |
275 | 279 | ||
276 | void hidraw_report_event(struct hid_device *hid, u8 *data, int len) | 280 | void hidraw_report_event(struct hid_device *hid, u8 *data, int len) |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 1df832a8fcbc..61e78a4369b9 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -69,12 +69,18 @@ | |||
69 | #define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220 | 69 | #define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220 |
70 | #define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221 | 70 | #define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221 |
71 | #define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222 | 71 | #define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222 |
72 | #define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223 | ||
73 | #define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224 | ||
74 | #define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225 | ||
72 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229 | 75 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229 |
73 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a | 76 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a |
74 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b | 77 | #define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b |
75 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c | 78 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c |
76 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d | 79 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d |
77 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e | 80 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e |
81 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 | ||
82 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 | ||
83 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 | ||
78 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a | 84 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a |
79 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b | 85 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b |
80 | #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 | 86 | #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 |
@@ -241,6 +247,8 @@ | |||
241 | #define USB_DEVICE_ID_LD_MACHINETEST 0x2040 | 247 | #define USB_DEVICE_ID_LD_MACHINETEST 0x2040 |
242 | 248 | ||
243 | #define USB_VENDOR_ID_LOGITECH 0x046d | 249 | #define USB_VENDOR_ID_LOGITECH 0x046d |
250 | #define USB_DEVICE_ID_LOGITECH_LX3 0xc044 | ||
251 | #define USB_DEVICE_ID_LOGITECH_V150 0xc047 | ||
244 | #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 | 252 | #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 |
245 | #define USB_DEVICE_ID_LOGITECH_HARMONY 0xc110 | 253 | #define USB_DEVICE_ID_LOGITECH_HARMONY 0xc110 |
246 | #define USB_DEVICE_ID_LOGITECH_HARMONY_2 0xc111 | 254 | #define USB_DEVICE_ID_LOGITECH_HARMONY_2 0xc111 |
@@ -314,6 +322,7 @@ | |||
314 | #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 | 322 | #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 |
315 | #define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 | 323 | #define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 |
316 | #define USB_DEVICE_ID_MX3000_RECEIVER 0xc513 | 324 | #define USB_DEVICE_ID_MX3000_RECEIVER 0xc513 |
325 | #define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 | ||
317 | #define USB_DEVICE_ID_DINOVO_EDGE 0xc714 | 326 | #define USB_DEVICE_ID_DINOVO_EDGE 0xc714 |
318 | #define USB_DEVICE_ID_DINOVO_MINI 0xc71f | 327 | #define USB_DEVICE_ID_DINOVO_MINI 0xc71f |
319 | 328 | ||
@@ -443,7 +452,8 @@ static const struct hid_blacklist { | |||
443 | { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD }, | 452 | { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD }, |
444 | { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, | 453 | { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, |
445 | { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, | 454 | { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, |
446 | 455 | ||
456 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP, HID_QUIRK_DUPLICATE_USAGES }, | ||
447 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES }, | 457 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES }, |
448 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI, HID_QUIRK_DUPLICATE_USAGES }, | 458 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI, HID_QUIRK_DUPLICATE_USAGES }, |
449 | 459 | ||
@@ -593,6 +603,8 @@ static const struct hid_blacklist { | |||
593 | 603 | ||
594 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, | 604 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, |
595 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, | 605 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, |
606 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_LX3, HID_QUIRK_INVERT_HWHEEL }, | ||
607 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150, HID_QUIRK_INVERT_HWHEEL }, | ||
596 | 608 | ||
597 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS }, | 609 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS }, |
598 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS }, | 610 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS }, |
@@ -642,6 +654,12 @@ static const struct hid_blacklist { | |||
642 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, | 654 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, |
643 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, | 655 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, |
644 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, | 656 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, |
657 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, HID_QUIRK_APPLE_HAS_FN }, | ||
658 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, | ||
659 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS, HID_QUIRK_APPLE_HAS_FN }, | ||
660 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, HID_QUIRK_APPLE_HAS_FN }, | ||
661 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, | ||
662 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, HID_QUIRK_APPLE_HAS_FN }, | ||
645 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 663 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
646 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 664 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
647 | 665 | ||
@@ -1128,7 +1146,7 @@ static void usbhid_fixup_microsoft_descriptor(unsigned char *rdesc, int rsize) | |||
1128 | && rdesc[557] == 0x19 | 1146 | && rdesc[557] == 0x19 |
1129 | && rdesc[559] == 0x29) { | 1147 | && rdesc[559] == 0x29) { |
1130 | printk(KERN_INFO "Fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); | 1148 | printk(KERN_INFO "Fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); |
1131 | rdesc[284] = rdesc[304] = rdesc[558] = 0x35; | 1149 | rdesc[284] = rdesc[304] = rdesc[557] = 0x35; |
1132 | rdesc[352] = 0x36; | 1150 | rdesc[352] = 0x36; |
1133 | rdesc[286] = rdesc[355] = 0x46; | 1151 | rdesc[286] = rdesc[355] = 0x46; |
1134 | rdesc[306] = rdesc[559] = 0x45; | 1152 | rdesc[306] = rdesc[559] = 0x45; |
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 95cc192bc7af..842e9edb888e 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -406,6 +406,7 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, | |||
406 | uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL); | 406 | uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL); |
407 | if (!uref_multi) | 407 | if (!uref_multi) |
408 | return -ENOMEM; | 408 | return -ENOMEM; |
409 | lock_kernel(); | ||
409 | uref = &uref_multi->uref; | 410 | uref = &uref_multi->uref; |
410 | if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) { | 411 | if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) { |
411 | if (copy_from_user(uref_multi, user_arg, | 412 | if (copy_from_user(uref_multi, user_arg, |
@@ -501,12 +502,15 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, | |||
501 | } | 502 | } |
502 | 503 | ||
503 | goodreturn: | 504 | goodreturn: |
505 | unlock_kernel(); | ||
504 | kfree(uref_multi); | 506 | kfree(uref_multi); |
505 | return 0; | 507 | return 0; |
506 | fault: | 508 | fault: |
509 | unlock_kernel(); | ||
507 | kfree(uref_multi); | 510 | kfree(uref_multi); |
508 | return -EFAULT; | 511 | return -EFAULT; |
509 | inval: | 512 | inval: |
513 | unlock_kernel(); | ||
510 | kfree(uref_multi); | 514 | kfree(uref_multi); |
511 | return -EINVAL; | 515 | return -EINVAL; |
512 | } | 516 | } |
@@ -540,7 +544,7 @@ static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd, | |||
540 | return len; | 544 | return len; |
541 | } | 545 | } |
542 | 546 | ||
543 | static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 547 | static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
544 | { | 548 | { |
545 | struct hiddev_list *list = file->private_data; | 549 | struct hiddev_list *list = file->private_data; |
546 | struct hiddev *hiddev = list->hiddev; | 550 | struct hiddev *hiddev = list->hiddev; |
@@ -555,7 +559,10 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
555 | struct usbhid_device *usbhid = hid->driver_data; | 559 | struct usbhid_device *usbhid = hid->driver_data; |
556 | void __user *user_arg = (void __user *)arg; | 560 | void __user *user_arg = (void __user *)arg; |
557 | int i; | 561 | int i; |
562 | |||
563 | /* Called without BKL by compat methods so no BKL taken */ | ||
558 | 564 | ||
565 | /* FIXME: Who or what stop this racing with a disconnect ?? */ | ||
559 | if (!hiddev->exist) | 566 | if (!hiddev->exist) |
560 | return -EIO; | 567 | return -EIO; |
561 | 568 | ||
@@ -756,8 +763,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
756 | #ifdef CONFIG_COMPAT | 763 | #ifdef CONFIG_COMPAT |
757 | static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 764 | static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
758 | { | 765 | { |
759 | struct inode *inode = file->f_path.dentry->d_inode; | 766 | return hiddev_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); |
760 | return hiddev_ioctl(inode, file, cmd, (unsigned long)compat_ptr(arg)); | ||
761 | } | 767 | } |
762 | #endif | 768 | #endif |
763 | 769 | ||
@@ -768,7 +774,7 @@ static const struct file_operations hiddev_fops = { | |||
768 | .poll = hiddev_poll, | 774 | .poll = hiddev_poll, |
769 | .open = hiddev_open, | 775 | .open = hiddev_open, |
770 | .release = hiddev_release, | 776 | .release = hiddev_release, |
771 | .ioctl = hiddev_ioctl, | 777 | .unlocked_ioctl = hiddev_ioctl, |
772 | .fasync = hiddev_fasync, | 778 | .fasync = hiddev_fasync, |
773 | #ifdef CONFIG_COMPAT | 779 | #ifdef CONFIG_COMPAT |
774 | .compat_ioctl = hiddev_compat_ioctl, | 780 | .compat_ioctl = hiddev_compat_ioctl, |
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c index 3cd46d2e53c1..0caaafe01843 100644 --- a/drivers/hid/usbhid/usbkbd.c +++ b/drivers/hid/usbhid/usbkbd.c | |||
@@ -43,7 +43,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR); | |||
43 | MODULE_DESCRIPTION(DRIVER_DESC); | 43 | MODULE_DESCRIPTION(DRIVER_DESC); |
44 | MODULE_LICENSE(DRIVER_LICENSE); | 44 | MODULE_LICENSE(DRIVER_LICENSE); |
45 | 45 | ||
46 | static unsigned char usb_kbd_keycode[256] = { | 46 | static const unsigned char usb_kbd_keycode[256] = { |
47 | 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, | 47 | 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, |
48 | 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, | 48 | 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, |
49 | 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, | 49 | 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, |
@@ -233,14 +233,6 @@ static int usb_kbd_probe(struct usb_interface *iface, | |||
233 | if (!usb_endpoint_is_int_in(endpoint)) | 233 | if (!usb_endpoint_is_int_in(endpoint)) |
234 | return -ENODEV; | 234 | return -ENODEV; |
235 | 235 | ||
236 | #ifdef CONFIG_USB_HID | ||
237 | if (usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), | ||
238 | le16_to_cpu(dev->descriptor.idProduct)) | ||
239 | & HID_QUIRK_IGNORE) { | ||
240 | return -ENODEV; | ||
241 | } | ||
242 | #endif | ||
243 | |||
244 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | 236 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); |
245 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | 237 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); |
246 | 238 | ||
diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c index 703e9d0e8714..35689ef172cc 100644 --- a/drivers/hid/usbhid/usbmouse.c +++ b/drivers/hid/usbhid/usbmouse.c | |||
@@ -129,14 +129,6 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i | |||
129 | if (!usb_endpoint_is_int_in(endpoint)) | 129 | if (!usb_endpoint_is_int_in(endpoint)) |
130 | return -ENODEV; | 130 | return -ENODEV; |
131 | 131 | ||
132 | #ifdef CONFIG_USB_HID | ||
133 | if (usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), | ||
134 | le16_to_cpu(dev->descriptor.idProduct)) | ||
135 | & (HID_QUIRK_IGNORE|HID_QUIRK_IGNORE_MOUSE)) { | ||
136 | return -ENODEV; | ||
137 | } | ||
138 | #endif | ||
139 | |||
140 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | 132 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); |
141 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | 133 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); |
142 | 134 | ||
diff --git a/include/linux/hid.h b/include/linux/hid.h index fe56b86f2c67..ac4e678a04ed 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -512,7 +512,7 @@ struct hid_descriptor { | |||
512 | 512 | ||
513 | /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ | 513 | /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ |
514 | /* We ignore a few input applications that are not widely used */ | 514 | /* We ignore a few input applications that are not widely used */ |
515 | #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001)) | 515 | #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || (a == 0x000d0002)) |
516 | 516 | ||
517 | /* HID core API */ | 517 | /* HID core API */ |
518 | 518 | ||