Commit 876a4256 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 7c1fed03 b22d8370
...@@ -780,7 +780,7 @@ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) ...@@ -780,7 +780,7 @@ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
*/ */
static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
{ {
__le64 x; u64 x;
u64 m = (1ULL << n) - 1; u64 m = (1ULL << n) - 1;
if (n > 32) if (n > 32)
...@@ -796,10 +796,10 @@ static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u3 ...@@ -796,10 +796,10 @@ static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u3
report += offset >> 3; report += offset >> 3;
offset &= 7; offset &= 7;
x = get_unaligned((__le64 *)report); x = get_unaligned_le64(report);
x &= cpu_to_le64(~(m << offset)); x &= ~(m << offset);
x |= cpu_to_le64(((u64) value) << offset); x |= ((u64)value) << offset;
put_unaligned(x, (__le64 *) report); put_unaligned_le64(x, report);
} }
/* /*
......
...@@ -89,6 +89,29 @@ static int quirk_logitech_ultrax_remote(struct hid_usage *usage, struct input_de ...@@ -89,6 +89,29 @@ static int quirk_logitech_ultrax_remote(struct hid_usage *usage, struct input_de
return 1; return 1;
} }
static int quirk_gyration_remote(struct hid_usage *usage, struct input_dev *input,
unsigned long **bit, int *max)
{
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
return 0;
set_bit(EV_REP, input->evbit);
switch(usage->hid & HID_USAGE) {
/* Reported on Gyration MCE Remote */
case 0x00d: map_key_clear(KEY_HOME); break;
case 0x024: map_key_clear(KEY_DVD); break;
case 0x025: map_key_clear(KEY_PVR); break;
case 0x046: map_key_clear(KEY_MEDIA); break;
case 0x047: map_key_clear(KEY_MP3); break;
case 0x049: map_key_clear(KEY_CAMERA); break;
case 0x04a: map_key_clear(KEY_VIDEO); break;
default:
return 0;
}
return 1;
}
static int quirk_chicony_tactical_pad(struct hid_usage *usage, struct input_dev *input, static int quirk_chicony_tactical_pad(struct hid_usage *usage, struct input_dev *input,
unsigned long **bit, int *max) unsigned long **bit, int *max)
{ {
...@@ -303,6 +326,9 @@ static int quirk_sunplus_wdesktop(struct hid_usage *usage, struct input_dev *inp ...@@ -303,6 +326,9 @@ static int quirk_sunplus_wdesktop(struct hid_usage *usage, struct input_dev *inp
#define VENDOR_ID_EZKEY 0x0518 #define VENDOR_ID_EZKEY 0x0518
#define DEVICE_ID_BTC_8193 0x0002 #define DEVICE_ID_BTC_8193 0x0002
#define VENDOR_ID_GYRATION 0x0c16
#define DEVICE_ID_GYRATION_REMOTE 0x0002
#define VENDOR_ID_LOGITECH 0x046d #define VENDOR_ID_LOGITECH 0x046d
#define DEVICE_ID_LOGITECH_RECEIVER 0xc101 #define DEVICE_ID_LOGITECH_RECEIVER 0xc101
#define DEVICE_ID_S510_RECEIVER 0xc50c #define DEVICE_ID_S510_RECEIVER 0xc50c
...@@ -337,6 +363,8 @@ static const struct hid_input_blacklist { ...@@ -337,6 +363,8 @@ static const struct hid_input_blacklist {
{ VENDOR_ID_EZKEY, DEVICE_ID_BTC_8193, quirk_btc_8193 }, { VENDOR_ID_EZKEY, DEVICE_ID_BTC_8193, quirk_btc_8193 },
{ VENDOR_ID_GYRATION, DEVICE_ID_GYRATION_REMOTE, quirk_gyration_remote },
{ VENDOR_ID_LOGITECH, DEVICE_ID_LOGITECH_RECEIVER, quirk_logitech_ultrax_remote }, { VENDOR_ID_LOGITECH, DEVICE_ID_LOGITECH_RECEIVER, quirk_logitech_ultrax_remote },
{ VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER, quirk_logitech_wireless }, { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER, quirk_logitech_wireless },
{ VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER_2, quirk_logitech_wireless }, { 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,6 +466,18 @@ int hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struc
input_event(input, usage->type, REL_WHEEL, -value); input_event(input, usage->type, REL_WHEEL, -value);
return 1; return 1;
} }
/* Gyration MCE remote "Sleep" key */
if (hid->vendor == VENDOR_ID_GYRATION &&
hid->product == DEVICE_ID_GYRATION_REMOTE &&
(usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK &&
(usage->hid & 0xff) == 0x82) {
input_event(input, usage->type, usage->code, 1);
input_sync(input);
input_event(input, usage->type, usage->code, 0);
input_sync(input);
return 1;
}
return 0; return 0;
} }
......
...@@ -100,6 +100,8 @@ static struct hidinput_key_translation apple_fn_keys[] = { ...@@ -100,6 +100,8 @@ static struct hidinput_key_translation apple_fn_keys[] = {
{ KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
{ KEY_F3, KEY_FN_F5, APPLE_FLAG_FKEY }, /* Expos */ { KEY_F3, KEY_FN_F5, APPLE_FLAG_FKEY }, /* Expos */
{ KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */ { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */
{ KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY },
{ KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY },
{ KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
{ KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
{ KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY },
...@@ -612,6 +614,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel ...@@ -612,6 +614,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break; case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break;
case 0x0b7: map_key_clear(KEY_STOPCD); break; case 0x0b7: map_key_clear(KEY_STOPCD); break;
case 0x0b8: map_key_clear(KEY_EJECTCD); break; case 0x0b8: map_key_clear(KEY_EJECTCD); break;
case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT); break;
case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break;
case 0x0e0: map_abs_clear(ABS_VOLUME); break; case 0x0e0: map_abs_clear(ABS_VOLUME); break;
......
...@@ -105,6 +105,7 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, ...@@ -105,6 +105,7 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{ {
unsigned int minor = iminor(file->f_path.dentry->d_inode); unsigned int minor = iminor(file->f_path.dentry->d_inode);
/* FIXME: What stops hidraw_table going NULL */
struct hid_device *dev = hidraw_table[minor]->hid; struct hid_device *dev = hidraw_table[minor]->hid;
__u8 *buf; __u8 *buf;
int ret = 0; int ret = 0;
...@@ -211,38 +212,43 @@ static int hidraw_release(struct inode * inode, struct file * file) ...@@ -211,38 +212,43 @@ static int hidraw_release(struct inode * inode, struct file * file)
kfree(list->hidraw); kfree(list->hidraw);
} }
kfree(list);
return 0; return 0;
} }
static int hidraw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static long hidraw_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{ {
struct inode *inode = file->f_path.dentry->d_inode;
unsigned int minor = iminor(inode); unsigned int minor = iminor(inode);
long ret = 0;
/* FIXME: What stops hidraw_table going NULL */
struct hidraw *dev = hidraw_table[minor]; struct hidraw *dev = hidraw_table[minor];
void __user *user_arg = (void __user*) arg; void __user *user_arg = (void __user*) arg;
lock_kernel();
switch (cmd) { switch (cmd) {
case HIDIOCGRDESCSIZE: case HIDIOCGRDESCSIZE:
if (put_user(dev->hid->rsize, (int __user *)arg)) if (put_user(dev->hid->rsize, (int __user *)arg))
return -EFAULT; ret = -EFAULT;
return 0; break;
case HIDIOCGRDESC: case HIDIOCGRDESC:
{ {
__u32 len; __u32 len;
if (get_user(len, (int __user *)arg)) if (get_user(len, (int __user *)arg))
return -EFAULT; ret = -EFAULT;
else if (len > HID_MAX_DESCRIPTOR_SIZE - 1)
if (len > HID_MAX_DESCRIPTOR_SIZE - 1) ret = -EINVAL;
return -EINVAL; else if (copy_to_user(user_arg + offsetof(
struct hidraw_report_descriptor,
if (copy_to_user(user_arg + offsetof( value[0]),
struct hidraw_report_descriptor, dev->hid->rdesc,
value[0]), min(dev->hid->rsize, len)))
dev->hid->rdesc, ret = -EFAULT;
min(dev->hid->rsize, len))) break;
return -EFAULT;
return 0;
} }
case HIDIOCGRAWINFO: case HIDIOCGRAWINFO:
{ {
...@@ -252,15 +258,13 @@ static int hidraw_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -252,15 +258,13 @@ static int hidraw_ioctl(struct inode *inode, struct file *file, unsigned int cmd
dinfo.vendor = dev->hid->vendor; dinfo.vendor = dev->hid->vendor;
dinfo.product = dev->hid->product; dinfo.product = dev->hid->product;
if (copy_to_user(user_arg, &dinfo, sizeof(dinfo))) if (copy_to_user(user_arg, &dinfo, sizeof(dinfo)))
return -EFAULT; ret = -EFAULT;
break;
return 0;
} }
default: default:
printk(KERN_EMERG "hidraw: unsupported ioctl() %x\n", ret = -ENOTTY;
cmd);
} }
return -EINVAL; return ret;
} }
static const struct file_operations hidraw_ops = { static const struct file_operations hidraw_ops = {
...@@ -270,7 +274,7 @@ static const struct file_operations hidraw_ops = { ...@@ -270,7 +274,7 @@ static const struct file_operations hidraw_ops = {
.poll = hidraw_poll, .poll = hidraw_poll,
.open = hidraw_open, .open = hidraw_open,
.release = hidraw_release, .release = hidraw_release,
.ioctl = hidraw_ioctl, .unlocked_ioctl = hidraw_ioctl,
}; };
void hidraw_report_event(struct hid_device *hid, u8 *data, int len) void hidraw_report_event(struct hid_device *hid, u8 *data, int len)
......
...@@ -69,12 +69,18 @@ ...@@ -69,12 +69,18 @@
#define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220 #define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220
#define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221 #define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221
#define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222 #define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222
#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223
#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224
#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225
#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229 #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229
#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a #define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a
#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b #define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e
#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
#define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242
...@@ -241,6 +247,8 @@ ...@@ -241,6 +247,8 @@
#define USB_DEVICE_ID_LD_MACHINETEST 0x2040 #define USB_DEVICE_ID_LD_MACHINETEST 0x2040
#define USB_VENDOR_ID_LOGITECH 0x046d #define USB_VENDOR_ID_LOGITECH 0x046d
#define USB_DEVICE_ID_LOGITECH_LX3 0xc044
#define USB_DEVICE_ID_LOGITECH_V150 0xc047
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
#define USB_DEVICE_ID_LOGITECH_HARMONY 0xc110 #define USB_DEVICE_ID_LOGITECH_HARMONY 0xc110
#define USB_DEVICE_ID_LOGITECH_HARMONY_2 0xc111 #define USB_DEVICE_ID_LOGITECH_HARMONY_2 0xc111
...@@ -314,6 +322,7 @@ ...@@ -314,6 +322,7 @@
#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 #define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512
#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513 #define USB_DEVICE_ID_MX3000_RECEIVER 0xc513
#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704
#define USB_DEVICE_ID_DINOVO_EDGE 0xc714 #define USB_DEVICE_ID_DINOVO_EDGE 0xc714
#define USB_DEVICE_ID_DINOVO_MINI 0xc71f #define USB_DEVICE_ID_DINOVO_MINI 0xc71f
...@@ -443,7 +452,8 @@ static const struct hid_blacklist { ...@@ -443,7 +452,8 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP, HID_QUIRK_DUPLICATE_USAGES },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI, HID_QUIRK_DUPLICATE_USAGES }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI, HID_QUIRK_DUPLICATE_USAGES },
...@@ -593,6 +603,8 @@ static const struct hid_blacklist { ...@@ -593,6 +603,8 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_LX3, HID_QUIRK_INVERT_HWHEEL },
{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150, HID_QUIRK_INVERT_HWHEEL },
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS }, { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS },
{ USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS }, { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS },
...@@ -642,6 +654,12 @@ static const struct hid_blacklist { ...@@ -642,6 +654,12 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN },
{ 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 }, { 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 },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, HID_QUIRK_APPLE_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS, HID_QUIRK_APPLE_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, HID_QUIRK_APPLE_HAS_FN },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, HID_QUIRK_APPLE_HAS_FN },
{ 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 }, { 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 },
{ 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 }, { 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 },
...@@ -1128,7 +1146,7 @@ static void usbhid_fixup_microsoft_descriptor(unsigned char *rdesc, int rsize) ...@@ -1128,7 +1146,7 @@ static void usbhid_fixup_microsoft_descriptor(unsigned char *rdesc, int rsize)
&& rdesc[557] == 0x19 && rdesc[557] == 0x19
&& rdesc[559] == 0x29) { && rdesc[559] == 0x29) {
printk(KERN_INFO "Fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); printk(KERN_INFO "Fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n");
rdesc[284] = rdesc[304] = rdesc[558] = 0x35; rdesc[284] = rdesc[304] = rdesc[557] = 0x35;
rdesc[352] = 0x36; rdesc[352] = 0x36;
rdesc[286] = rdesc[355] = 0x46; rdesc[286] = rdesc[355] = 0x46;
rdesc[306] = rdesc[559] = 0x45; rdesc[306] = rdesc[559] = 0x45;
......
...@@ -406,6 +406,7 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, ...@@ -406,6 +406,7 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL); uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
if (!uref_multi) if (!uref_multi)
return -ENOMEM; return -ENOMEM;
lock_kernel();
uref = &uref_multi->uref; uref = &uref_multi->uref;
if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) { if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
if (copy_from_user(uref_multi, user_arg, 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,12 +502,15 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
} }
goodreturn: goodreturn:
unlock_kernel();
kfree(uref_multi); kfree(uref_multi);
return 0; return 0;
fault: fault:
unlock_kernel();
kfree(uref_multi); kfree(uref_multi);
return -EFAULT; return -EFAULT;
inval: inval:
unlock_kernel();
kfree(uref_multi); kfree(uref_multi);
return -EINVAL; return -EINVAL;
} }
...@@ -540,7 +544,7 @@ static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd, ...@@ -540,7 +544,7 @@ static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd,
return len; return len;
} }
static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{ {
struct hiddev_list *list = file->private_data; struct hiddev_list *list = file->private_data;
struct hiddev *hiddev = list->hiddev; struct hiddev *hiddev = list->hiddev;
...@@ -555,7 +559,10 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -555,7 +559,10 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
struct usbhid_device *usbhid = hid->driver_data; struct usbhid_device *usbhid = hid->driver_data;
void __user *user_arg = (void __user *)arg; void __user *user_arg = (void __user *)arg;
int i; int i;
/* Called without BKL by compat methods so no BKL taken */
/* FIXME: Who or what stop this racing with a disconnect ?? */
if (!hiddev->exist) if (!hiddev->exist)
return -EIO; return -EIO;
...@@ -756,8 +763,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -756,8 +763,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{ {
struct inode *inode = file->f_path.dentry->d_inode; return hiddev_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
return hiddev_ioctl(inode, file, cmd, (unsigned long)compat_ptr(arg));
} }
#endif #endif
...@@ -768,7 +774,7 @@ static const struct file_operations hiddev_fops = { ...@@ -768,7 +774,7 @@ static const struct file_operations hiddev_fops = {
.poll = hiddev_poll, .poll = hiddev_poll,
.open = hiddev_open, .open = hiddev_open,
.release = hiddev_release, .release = hiddev_release,
.ioctl = hiddev_ioctl, .unlocked_ioctl = hiddev_ioctl,
.fasync = hiddev_fasync, .fasync = hiddev_fasync,
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
.compat_ioctl = hiddev_compat_ioctl, .compat_ioctl = hiddev_compat_ioctl,
......
...@@ -43,7 +43,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR); ...@@ -43,7 +43,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC); MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE(DRIVER_LICENSE); MODULE_LICENSE(DRIVER_LICENSE);
static unsigned char usb_kbd_keycode[256] = { static const unsigned char usb_kbd_keycode[256] = {
0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, 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,14 +233,6 @@ static int usb_kbd_probe(struct usb_interface *iface,
if (!usb_endpoint_is_int_in(endpoint)) if (!usb_endpoint_is_int_in(endpoint))
return -ENODEV; return -ENODEV;
#ifdef CONFIG_USB_HID
if (usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct))
& HID_QUIRK_IGNORE) {
return -ENODEV;
}
#endif
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
......
...@@ -129,14 +129,6 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i ...@@ -129,14 +129,6 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i
if (!usb_endpoint_is_int_in(endpoint)) if (!usb_endpoint_is_int_in(endpoint))
return -ENODEV; return -ENODEV;
#ifdef CONFIG_USB_HID
if (usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct))
& (HID_QUIRK_IGNORE|HID_QUIRK_IGNORE_MOUSE)) {
return -ENODEV;
}
#endif
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
......
...@@ -512,7 +512,7 @@ struct hid_descriptor { ...@@ -512,7 +512,7 @@ struct hid_descriptor {
/* Applications from HID Usage Tables 4/8/99 Version 1.1 */ /* Applications from HID Usage Tables 4/8/99 Version 1.1 */
/* We ignore a few input applications that are not widely used */ /* We ignore a few input applications that are not widely used */
#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001)) #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || (a == 0x000d0002))
/* HID core API */ /* HID core API */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment