diff options
-rw-r--r-- | drivers/hid/Kconfig | 15 | ||||
-rw-r--r-- | drivers/hid/Makefile | 2 | ||||
-rw-r--r-- | drivers/hid/hid-apple.c | 11 | ||||
-rw-r--r-- | drivers/hid/hid-bright.c | 71 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 20 | ||||
-rw-r--r-- | drivers/hid/hid-dell.c | 76 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 14 | ||||
-rw-r--r-- | drivers/hid/hid-lg.c | 7 | ||||
-rw-r--r-- | drivers/hid/hidraw.c | 30 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 23 | ||||
-rw-r--r-- | include/linux/input.h | 2 |
11 files changed, 60 insertions, 211 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index b4fd8ca701a4..65b577eaf823 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -107,13 +107,6 @@ config HID_BELKIN ---help--- Support for Belkin Flip KVM and Wireless keyboard. -config HID_BRIGHT - tristate "Bright" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for Bright ABNT-2 keyboard. - config HID_CHERRY tristate "Cherry" if EMBEDDED depends on USB_HID @@ -135,14 +128,6 @@ config HID_CYPRESS ---help--- Support for cypress mouse and barcode readers. -config HID_DELL - tristate "Dell" if EMBEDDED - depends on USB_HID - default y - ---help--- - Support for quirky Dell HID hardware that require - special LED handling (W7658 and SK8115 models) - config HID_EZKEY tristate "Ezkey" if EMBEDDED depends on USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index b09e43e7413e..e2294a8b2a68 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -23,11 +23,9 @@ endif obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o obj-$(CONFIG_HID_APPLE) += hid-apple.o obj-$(CONFIG_HID_BELKIN) += hid-belkin.o -obj-$(CONFIG_HID_BRIGHT) += hid-bright.o obj-$(CONFIG_HID_CHERRY) += hid-cherry.o obj-$(CONFIG_HID_CHICONY) += hid-chicony.o obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o -obj-$(CONFIG_HID_DELL) += hid-dell.o obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o obj-$(CONFIG_HID_GYRATION) += hid-gyration.o obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index c6ab4ba60c52..9b97795e45ad 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -55,10 +55,11 @@ struct apple_key_translation { static struct apple_key_translation apple_fn_keys[] = { { KEY_BACKSPACE, KEY_DELETE }, + { KEY_ENTER, KEY_INSERT }, { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, - { KEY_F3, KEY_FN_F5, APPLE_FLAG_FKEY }, /* Exposé */ - { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */ + { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, + { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY }, { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, @@ -418,6 +419,12 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_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), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY), diff --git a/drivers/hid/hid-bright.c b/drivers/hid/hid-bright.c deleted file mode 100644 index 38517a117dfd..000000000000 --- a/drivers/hid/hid-bright.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * HID driver for some bright "special" devices - * - * Copyright (c) 2008 Mauro Carvalho Chehab <mchehab@redhat.com> - * - * Based on hid-dell driver - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include <linux/device.h> -#include <linux/hid.h> -#include <linux/module.h> - -#include "hid-ids.h" - -static int bright_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free; - } - - usbhid_set_leds(hdev); - - return 0; -err_free: - return ret; -} - -static const struct hid_device_id bright_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_BRIGHT, USB_DEVICE_ID_BRIGHT_ABNT2) }, - { } -}; -MODULE_DEVICE_TABLE(hid, bright_devices); - -static struct hid_driver bright_driver = { - .name = "bright", - .id_table = bright_devices, - .probe = bright_probe, -}; - -static int bright_init(void) -{ - return hid_register_driver(&bright_driver); -} - -static void bright_exit(void) -{ - hid_unregister_driver(&bright_driver); -} - -module_init(bright_init); -module_exit(bright_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(bright); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index d3671b4049c0..349ded22acc8 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1250,20 +1250,19 @@ 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_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_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_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_BRIGHT, USB_DEVICE_ID_BRIGHT_ABNT2) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_SK8115) }, { 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_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) }, @@ -1275,7 +1274,6 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, @@ -1573,6 +1571,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_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_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_GEYSER1_TP_ONLY) }, { } @@ -1614,9 +1615,10 @@ int hid_add_device(struct hid_device *hdev) if (hid_ignore(hdev)) return -ENODEV; - /* XXX hack, any other cleaner solution < 20 bus_id bytes? */ - sprintf(hdev->dev.bus_id, "%04X:%04X:%04X.%04X", hdev->bus, - hdev->vendor, hdev->product, atomic_inc_return(&id)); + /* XXX hack, any other cleaner solution after the driver core + * is converted to allow more than 20 bytes as the device name? */ + dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, + hdev->vendor, hdev->product, atomic_inc_return(&id)); ret = device_add(&hdev->dev); if (!ret) @@ -1730,7 +1732,7 @@ static int __init hid_init(void) goto err_bus; #ifdef CONFIG_HID_COMPAT - hid_compat_wq = create_workqueue("hid_compat"); + hid_compat_wq = create_singlethread_workqueue("hid_compat"); if (!hid_compat_wq) { hidraw_exit(); goto err; diff --git a/drivers/hid/hid-dell.c b/drivers/hid/hid-dell.c deleted file mode 100644 index f5474300b83a..000000000000 --- a/drivers/hid/hid-dell.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * HID driver for some dell "special" devices - * - * Copyright (c) 1999 Andreas Gal - * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> - * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina - * Copyright (c) 2007 Paul Walmsley - * Copyright (c) 2008 Jiri Slaby - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include <linux/device.h> -#include <linux/hid.h> -#include <linux/module.h> - -#include "hid-ids.h" - -static int dell_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - - ret = hid_parse(hdev); - if (ret) { - dev_err(&hdev->dev, "parse failed\n"); - goto err_free; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); - goto err_free; - } - - usbhid_set_leds(hdev); - - return 0; -err_free: - return ret; -} - -static const struct hid_device_id dell_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_SK8115) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) }, - { } -}; -MODULE_DEVICE_TABLE(hid, dell_devices); - -static struct hid_driver dell_driver = { - .name = "dell", - .id_table = dell_devices, - .probe = dell_probe, -}; - -static int dell_init(void) -{ - return hid_register_driver(&dell_driver); -} - -static void dell_exit(void) -{ - hid_unregister_driver(&dell_driver); -} - -module_init(dell_init); -module_exit(dell_exit); -MODULE_LICENSE("GPL"); - -HID_COMPAT_LOAD_DRIVER(dell); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index f05bcbbbb0d5..7e5567f18afc 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -82,6 +82,9 @@ #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_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_GEYSER1_TP_ONLY 0x030b #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 @@ -104,9 +107,6 @@ #define USB_VENDOR_ID_BELKIN 0x050d #define USB_DEVICE_ID_FLIP_KVM 0x3201 -#define USB_VENDOR_ID_BRIGHT 0x1241 -#define USB_DEVICE_ID_BRIGHT_ABNT2 0x1503 - #define USB_VENDOR_ID_BERKSHIRE 0x0c98 #define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 @@ -138,10 +138,6 @@ #define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61 #define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64 -#define USB_VENDOR_ID_DELL 0x413c -#define USB_DEVICE_ID_DELL_W7658 0x2005 -#define USB_DEVICE_ID_DELL_SK8115 0x2105 - #define USB_VENDOR_ID_DELORME 0x1163 #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 #define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 @@ -163,9 +159,6 @@ #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc -#define USB_VENDOR_ID_GENERIC_13BA 0x13ba -#define USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE 0x0017 - #define USB_VENDOR_ID_GLAB 0x06c2 #define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 #define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 @@ -288,7 +281,6 @@ #define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 #define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a -#define USB_DEVICE_ID_LOGITECH_KBD 0xc311 #define USB_DEVICE_ID_S510_RECEIVER 0xc50c #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 #define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 2bae340eafe2..83e07c9f4144 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -26,7 +26,6 @@ #define LG_RDESC 0x001 #define LG_BAD_RELATIVE_KEYS 0x002 #define LG_DUPLICATE_USAGES 0x004 -#define LG_RESET_LEDS 0x008 #define LG_EXPANDED_KEYMAP 0x010 #define LG_IGNORE_DOUBLED_WHEEL 0x020 #define LG_WIRELESS 0x040 @@ -248,9 +247,6 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) goto err_free; } - if (quirks & LG_RESET_LEDS) - usbhid_set_leds(hdev); - if (quirks & LG_FF) lgff_init(hdev); if (quirks & LG_FF2) @@ -279,9 +275,6 @@ static const struct hid_device_id lg_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI), .driver_data = LG_DUPLICATE_USAGES }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD), - .driver_data = LG_RESET_LEDS }, - { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD), .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500), diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 894d52e05bf9..7685ae6808c4 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -38,7 +38,7 @@ static int hidraw_major; static struct cdev hidraw_cdev; static struct class *hidraw_class; 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) { @@ -159,13 +159,13 @@ static int hidraw_open(struct inode *inode, struct file *file) struct hidraw_list *list; int err = 0; - lock_kernel(); if (!(list = kzalloc(sizeof(struct hidraw_list), GFP_KERNEL))) { err = -ENOMEM; goto out; } - spin_lock(&minors_lock); + lock_kernel(); + mutex_lock(&minors_lock); if (!hidraw_table[minor]) { printk(KERN_EMERG "hidraw device with minor %d doesn't exist\n", minor); @@ -180,13 +180,16 @@ static int hidraw_open(struct inode *inode, struct file *file) file->private_data = list; dev = hidraw_table[minor]; - if (!dev->open++) - dev->hid->ll_driver->open(dev->hid); + if (!dev->open++) { + err = dev->hid->ll_driver->open(dev->hid); + if (err < 0) + dev->open--; + } out_unlock: - spin_unlock(&minors_lock); -out: + mutex_unlock(&minors_lock); unlock_kernel(); +out: return err; } @@ -310,7 +313,7 @@ int hidraw_connect(struct hid_device *hid) result = -EINVAL; - spin_lock(&minors_lock); + mutex_lock(&minors_lock); for (minor = 0; minor < HIDRAW_MAX_DEVICES; minor++) { if (hidraw_table[minor]) @@ -320,9 +323,8 @@ int hidraw_connect(struct hid_device *hid) break; } - spin_unlock(&minors_lock); - if (result) { + mutex_unlock(&minors_lock); kfree(dev); goto out; } @@ -331,14 +333,14 @@ int hidraw_connect(struct hid_device *hid) NULL, "%s%d", "hidraw", minor); if (IS_ERR(dev->dev)) { - spin_lock(&minors_lock); hidraw_table[minor] = NULL; - spin_unlock(&minors_lock); + mutex_unlock(&minors_lock); result = PTR_ERR(dev->dev); kfree(dev); goto out; } + mutex_unlock(&minors_lock); init_waitqueue_head(&dev->wait); INIT_LIST_HEAD(&dev->list); @@ -360,9 +362,9 @@ void hidraw_disconnect(struct hid_device *hid) hidraw->exist = 0; - spin_lock(&minors_lock); + mutex_lock(&minors_lock); hidraw_table[hidraw->minor] = NULL; - spin_unlock(&minors_lock); + mutex_unlock(&minors_lock); device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 18e5ddd722cd..586f835f1caa 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -4,7 +4,7 @@ * Copyright (c) 1999 Andreas Gal * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina + * Copyright (c) 2006-2008 Jiri Kosina */ /* @@ -641,9 +641,7 @@ static void hid_find_max_report(struct hid_device *hid, unsigned int type, unsigned int size; list_for_each_entry(report, &hid->report_enum[type].report_list, list) { - size = ((report->size - 1) >> 3) + 1; - if (type == HID_INPUT_REPORT && hid->report_enum[type].numbered) - size++; + size = ((report->size - 1) >> 3) + 1 + hid->report_enum[type].numbered; if (*max < size) *max = size; } @@ -781,6 +779,8 @@ static int usbhid_start(struct hid_device *hid) unsigned int n, insize = 0; int ret; + clear_bit(HID_DISCONNECTED, &usbhid->iofl); + usbhid->bufsize = HID_MIN_BUFFER_SIZE; hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize); hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize); @@ -882,12 +882,24 @@ static int usbhid_start(struct hid_device *hid) set_bit(HID_STARTED, &usbhid->iofl); mutex_unlock(&usbhid->setup); + /* Some keyboards don't work until their LEDs have been set. + * Since BIOSes do set the LEDs, it must be safe for any device + * that supports the keyboard boot protocol. + */ + if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT && + interface->desc.bInterfaceProtocol == + USB_INTERFACE_PROTOCOL_KEYBOARD) + usbhid_set_leds(hid); + return 0; fail: usb_free_urb(usbhid->urbin); usb_free_urb(usbhid->urbout); usb_free_urb(usbhid->urbctrl); + usbhid->urbin = NULL; + usbhid->urbout = NULL; + usbhid->urbctrl = NULL; hid_free_buffers(dev, hid); mutex_unlock(&usbhid->setup); return ret; @@ -924,6 +936,9 @@ static void usbhid_stop(struct hid_device *hid) usb_free_urb(usbhid->urbin); usb_free_urb(usbhid->urbctrl); 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); mutex_unlock(&usbhid->setup); diff --git a/include/linux/input.h b/include/linux/input.h index b86fb5581ce6..5341e8251f8c 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -238,6 +238,7 @@ struct input_absinfo { #define KEY_KPEQUAL 117 #define KEY_KPPLUSMINUS 118 #define KEY_PAUSE 119 +#define KEY_SCALE 120 /* AL Compiz Scale (Expose) */ #define KEY_KPCOMMA 121 #define KEY_HANGEUL 122 @@ -322,6 +323,7 @@ struct input_absinfo { #define KEY_PAUSECD 201 #define KEY_PROG3 202 #define KEY_PROG4 203 +#define KEY_DASHBOARD 204 /* AL Dashboard */ #define KEY_SUSPEND 205 #define KEY_CLOSE 206 /* AC Close */ #define KEY_PLAY 207 |