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 | ||
