Commit b42ccbc5 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: don't grab devices with no input
  HID: fix radio-mr800 hidquirks
  HID: fix kworld fm700 radio hidquirks
  HID: fix start/stop cycle in usbhid driver
  HID: use single threaded work queue for hid_compat
  HID: map macbook keys for "Expose" and "Dashboard"
  HID: support for new unibody macbooks
  HID: fix locking in hidraw_open()
parents d659fc14 131d3a7a
...@@ -55,10 +55,11 @@ struct apple_key_translation { ...@@ -55,10 +55,11 @@ struct apple_key_translation {
static struct apple_key_translation apple_fn_keys[] = { static struct apple_key_translation apple_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE }, { KEY_BACKSPACE, KEY_DELETE },
{ KEY_ENTER, KEY_INSERT },
{ KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
{ 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_SCALE, APPLE_FLAG_FKEY },
{ KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */ { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY },
{ KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY },
{ KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY },
{ KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
...@@ -418,6 +419,12 @@ static const struct hid_device_id apple_devices[] = { ...@@ -418,6 +419,12 @@ static const struct hid_device_id apple_devices[] = {
.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),
.driver_data = APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),
.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY), { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY), { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY),
......
...@@ -1250,9 +1250,11 @@ static const struct hid_device_id hid_blacklist[] = { ...@@ -1250,9 +1250,11 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
{ HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) },
{ HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
{ HID_USB_DEVICE(USB_VENDOR_ID_BRIGHT, USB_DEVICE_ID_BRIGHT_ABNT2) }, { HID_USB_DEVICE(USB_VENDOR_ID_BRIGHT, USB_DEVICE_ID_BRIGHT_ABNT2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
...@@ -1265,7 +1267,6 @@ static const struct hid_device_id hid_blacklist[] = { ...@@ -1265,7 +1267,6 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
...@@ -1409,6 +1410,7 @@ static const struct hid_device_id hid_ignore_list[] = { ...@@ -1409,6 +1410,7 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM)}, { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM)},
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2)}, { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2)},
{ HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) },
{ HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) },
...@@ -1486,6 +1488,7 @@ static const struct hid_device_id hid_ignore_list[] = { ...@@ -1486,6 +1488,7 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) },
{ HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) }, { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) },
...@@ -1573,6 +1576,9 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { ...@@ -1573,6 +1576,9 @@ static const struct hid_device_id hid_mouse_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
{ } { }
...@@ -1730,7 +1736,7 @@ static int __init hid_init(void) ...@@ -1730,7 +1736,7 @@ static int __init hid_init(void)
goto err_bus; goto err_bus;
#ifdef CONFIG_HID_COMPAT #ifdef CONFIG_HID_COMPAT
hid_compat_wq = create_workqueue("hid_compat"); hid_compat_wq = create_singlethread_workqueue("hid_compat");
if (!hid_compat_wq) { if (!hid_compat_wq) {
hidraw_exit(); hidraw_exit();
goto err; goto err;
......
...@@ -82,6 +82,9 @@ ...@@ -82,6 +82,9 @@
#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236
#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237
#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238
#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_ATV_IRCONTROL 0x8241 #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241
......
...@@ -38,7 +38,7 @@ static int hidraw_major; ...@@ -38,7 +38,7 @@ static int hidraw_major;
static struct cdev hidraw_cdev; static struct cdev hidraw_cdev;
static struct class *hidraw_class; static struct class *hidraw_class;
static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES];
static DEFINE_SPINLOCK(minors_lock); static DEFINE_MUTEX(minors_lock);
static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{ {
...@@ -159,13 +159,13 @@ static int hidraw_open(struct inode *inode, struct file *file) ...@@ -159,13 +159,13 @@ static int hidraw_open(struct inode *inode, struct file *file)
struct hidraw_list *list; struct hidraw_list *list;
int err = 0; int err = 0;
lock_kernel();
if (!(list = kzalloc(sizeof(struct hidraw_list), GFP_KERNEL))) { if (!(list = kzalloc(sizeof(struct hidraw_list), GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto out; goto out;
} }
spin_lock(&minors_lock); lock_kernel();
mutex_lock(&minors_lock);
if (!hidraw_table[minor]) { if (!hidraw_table[minor]) {
printk(KERN_EMERG "hidraw device with minor %d doesn't exist\n", printk(KERN_EMERG "hidraw device with minor %d doesn't exist\n",
minor); minor);
...@@ -180,13 +180,16 @@ static int hidraw_open(struct inode *inode, struct file *file) ...@@ -180,13 +180,16 @@ static int hidraw_open(struct inode *inode, struct file *file)
file->private_data = list; file->private_data = list;
dev = hidraw_table[minor]; dev = hidraw_table[minor];
if (!dev->open++) if (!dev->open++) {
dev->hid->ll_driver->open(dev->hid); err = dev->hid->ll_driver->open(dev->hid);
if (err < 0)
dev->open--;
}
out_unlock: out_unlock:
spin_unlock(&minors_lock); mutex_unlock(&minors_lock);
out:
unlock_kernel(); unlock_kernel();
out:
return err; return err;
} }
...@@ -310,7 +313,7 @@ int hidraw_connect(struct hid_device *hid) ...@@ -310,7 +313,7 @@ int hidraw_connect(struct hid_device *hid)
result = -EINVAL; result = -EINVAL;
spin_lock(&minors_lock); mutex_lock(&minors_lock);
for (minor = 0; minor < HIDRAW_MAX_DEVICES; minor++) { for (minor = 0; minor < HIDRAW_MAX_DEVICES; minor++) {
if (hidraw_table[minor]) if (hidraw_table[minor])
...@@ -320,9 +323,8 @@ int hidraw_connect(struct hid_device *hid) ...@@ -320,9 +323,8 @@ int hidraw_connect(struct hid_device *hid)
break; break;
} }
spin_unlock(&minors_lock);
if (result) { if (result) {
mutex_unlock(&minors_lock);
kfree(dev); kfree(dev);
goto out; goto out;
} }
...@@ -331,14 +333,14 @@ int hidraw_connect(struct hid_device *hid) ...@@ -331,14 +333,14 @@ int hidraw_connect(struct hid_device *hid)
NULL, "%s%d", "hidraw", minor); NULL, "%s%d", "hidraw", minor);
if (IS_ERR(dev->dev)) { if (IS_ERR(dev->dev)) {
spin_lock(&minors_lock);
hidraw_table[minor] = NULL; hidraw_table[minor] = NULL;
spin_unlock(&minors_lock); mutex_unlock(&minors_lock);
result = PTR_ERR(dev->dev); result = PTR_ERR(dev->dev);
kfree(dev); kfree(dev);
goto out; goto out;
} }
mutex_unlock(&minors_lock);
init_waitqueue_head(&dev->wait); init_waitqueue_head(&dev->wait);
INIT_LIST_HEAD(&dev->list); INIT_LIST_HEAD(&dev->list);
...@@ -360,9 +362,9 @@ void hidraw_disconnect(struct hid_device *hid) ...@@ -360,9 +362,9 @@ void hidraw_disconnect(struct hid_device *hid)
hidraw->exist = 0; hidraw->exist = 0;
spin_lock(&minors_lock); mutex_lock(&minors_lock);
hidraw_table[hidraw->minor] = NULL; hidraw_table[hidraw->minor] = NULL;
spin_unlock(&minors_lock); mutex_unlock(&minors_lock);
device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
......
...@@ -781,6 +781,8 @@ static int usbhid_start(struct hid_device *hid) ...@@ -781,6 +781,8 @@ static int usbhid_start(struct hid_device *hid)
unsigned int n, insize = 0; unsigned int n, insize = 0;
int ret; int ret;
clear_bit(HID_DISCONNECTED, &usbhid->iofl);
usbhid->bufsize = HID_MIN_BUFFER_SIZE; usbhid->bufsize = HID_MIN_BUFFER_SIZE;
hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize); hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize);
hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize); hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize);
...@@ -847,12 +849,6 @@ static int usbhid_start(struct hid_device *hid) ...@@ -847,12 +849,6 @@ static int usbhid_start(struct hid_device *hid)
} }
} }
if (!usbhid->urbin) {
err_hid("couldn't find an input interrupt endpoint");
ret = -ENODEV;
goto fail;
}
init_waitqueue_head(&usbhid->wait); init_waitqueue_head(&usbhid->wait);
INIT_WORK(&usbhid->reset_work, hid_reset); INIT_WORK(&usbhid->reset_work, hid_reset);
setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
...@@ -888,6 +884,9 @@ static int usbhid_start(struct hid_device *hid) ...@@ -888,6 +884,9 @@ static int usbhid_start(struct hid_device *hid)
usb_free_urb(usbhid->urbin); usb_free_urb(usbhid->urbin);
usb_free_urb(usbhid->urbout); usb_free_urb(usbhid->urbout);
usb_free_urb(usbhid->urbctrl); usb_free_urb(usbhid->urbctrl);
usbhid->urbin = NULL;
usbhid->urbout = NULL;
usbhid->urbctrl = NULL;
hid_free_buffers(dev, hid); hid_free_buffers(dev, hid);
mutex_unlock(&usbhid->setup); mutex_unlock(&usbhid->setup);
return ret; return ret;
...@@ -924,6 +923,9 @@ static void usbhid_stop(struct hid_device *hid) ...@@ -924,6 +923,9 @@ static void usbhid_stop(struct hid_device *hid)
usb_free_urb(usbhid->urbin); usb_free_urb(usbhid->urbin);
usb_free_urb(usbhid->urbctrl); usb_free_urb(usbhid->urbctrl);
usb_free_urb(usbhid->urbout); usb_free_urb(usbhid->urbout);
usbhid->urbin = NULL; /* don't mess up next start */
usbhid->urbctrl = NULL;
usbhid->urbout = NULL;
hid_free_buffers(hid_to_usb_dev(hid), hid); hid_free_buffers(hid_to_usb_dev(hid), hid);
mutex_unlock(&usbhid->setup); mutex_unlock(&usbhid->setup);
...@@ -940,15 +942,26 @@ static struct hid_ll_driver usb_hid_driver = { ...@@ -940,15 +942,26 @@ static struct hid_ll_driver usb_hid_driver = {
static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
{ {
struct usb_host_interface *interface = intf->cur_altsetting;
struct usb_device *dev = interface_to_usbdev(intf); struct usb_device *dev = interface_to_usbdev(intf);
struct usbhid_device *usbhid; struct usbhid_device *usbhid;
struct hid_device *hid; struct hid_device *hid;
unsigned int n, has_in = 0;
size_t len; size_t len;
int ret; int ret;
dbg_hid("HID probe called for ifnum %d\n", dbg_hid("HID probe called for ifnum %d\n",
intf->altsetting->desc.bInterfaceNumber); intf->altsetting->desc.bInterfaceNumber);
for (n = 0; n < interface->desc.bNumEndpoints; n++)
if (usb_endpoint_is_int_in(&interface->endpoint[n].desc))
has_in++;
if (!has_in) {
dev_err(&intf->dev, "couldn't find an input interrupt "
"endpoint\n");
return -ENODEV;
}
hid = hid_allocate_device(); hid = hid_allocate_device();
if (IS_ERR(hid)) if (IS_ERR(hid))
return PTR_ERR(hid); return PTR_ERR(hid);
......
...@@ -238,6 +238,7 @@ struct input_absinfo { ...@@ -238,6 +238,7 @@ struct input_absinfo {
#define KEY_KPEQUAL 117 #define KEY_KPEQUAL 117
#define KEY_KPPLUSMINUS 118 #define KEY_KPPLUSMINUS 118
#define KEY_PAUSE 119 #define KEY_PAUSE 119
#define KEY_SCALE 120 /* AL Compiz Scale (Expose) */
#define KEY_KPCOMMA 121 #define KEY_KPCOMMA 121
#define KEY_HANGEUL 122 #define KEY_HANGEUL 122
...@@ -322,6 +323,7 @@ struct input_absinfo { ...@@ -322,6 +323,7 @@ struct input_absinfo {
#define KEY_PAUSECD 201 #define KEY_PAUSECD 201
#define KEY_PROG3 202 #define KEY_PROG3 202
#define KEY_PROG4 203 #define KEY_PROG4 203
#define KEY_DASHBOARD 204 /* AL Dashboard */
#define KEY_SUSPEND 205 #define KEY_SUSPEND 205
#define KEY_CLOSE 206 /* AC Close */ #define KEY_CLOSE 206 /* AC Close */
#define KEY_PLAY 207 #define KEY_PLAY 207
......
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