diff options
| -rw-r--r-- | drivers/hid/hid-apple.c | 11 | ||||
| -rw-r--r-- | drivers/hid/hid-core.c | 12 | ||||
| -rw-r--r-- | drivers/hid/hid-ids.h | 3 | ||||
| -rw-r--r-- | drivers/hid/hidraw.c | 30 | ||||
| -rw-r--r-- | drivers/hid/usbhid/hid-core.c | 25 | ||||
| -rw-r--r-- | include/linux/input.h | 2 |
6 files changed, 58 insertions, 25 deletions
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 { | |||
| 55 | 55 | ||
| 56 | static struct apple_key_translation apple_fn_keys[] = { | 56 | static struct apple_key_translation apple_fn_keys[] = { |
| 57 | { KEY_BACKSPACE, KEY_DELETE }, | 57 | { KEY_BACKSPACE, KEY_DELETE }, |
| 58 | { KEY_ENTER, KEY_INSERT }, | ||
| 58 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, | 59 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, |
| 59 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, | 60 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, |
| 60 | { KEY_F3, KEY_FN_F5, APPLE_FLAG_FKEY }, /* Exposé */ | 61 | { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, |
| 61 | { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */ | 62 | { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY }, |
| 62 | { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, | 63 | { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, |
| 63 | { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, | 64 | { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, |
| 64 | { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, | 65 | { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, |
| @@ -418,6 +419,12 @@ static const struct hid_device_id apple_devices[] = { | |||
| 418 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | 419 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, |
| 419 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), | 420 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), |
| 420 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, | 421 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
| 422 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI), | ||
| 423 | .driver_data = APPLE_HAS_FN }, | ||
| 424 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO), | ||
| 425 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | ||
| 426 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), | ||
| 427 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, | ||
| 421 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY), | 428 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY), |
| 422 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 429 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
| 423 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY), | 430 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY), |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index d3671b4049c0..147ec591a806 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -1250,9 +1250,11 @@ static const struct hid_device_id hid_blacklist[] = { | |||
| 1250 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, | 1250 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, |
| 1251 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, | 1251 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, |
| 1252 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, | 1252 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, |
| 1253 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, | ||
| 1254 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, | ||
| 1255 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, | ||
| 1253 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1256 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
| 1254 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1257 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
| 1255 | { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, | ||
| 1256 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, | 1258 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, |
| 1257 | { HID_USB_DEVICE(USB_VENDOR_ID_BRIGHT, USB_DEVICE_ID_BRIGHT_ABNT2) }, | 1259 | { HID_USB_DEVICE(USB_VENDOR_ID_BRIGHT, USB_DEVICE_ID_BRIGHT_ABNT2) }, |
| 1258 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, | 1260 | { 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 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1267 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
| 1266 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) }, | 1268 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) }, |
| 1267 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, | 1269 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, |
| 1268 | { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, | ||
| 1269 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, | 1270 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, |
| 1270 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, | 1271 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, |
| 1271 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, | 1272 | { 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 | { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, | 1410 | { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, |
| 1410 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM)}, | 1411 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM)}, |
| 1411 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2)}, | 1412 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM2)}, |
| 1413 | { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, | ||
| 1412 | { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, | 1414 | { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, |
| 1413 | { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, | 1415 | { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, |
| 1414 | { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, | 1416 | { 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 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, | 1488 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, |
| 1487 | { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, | 1489 | { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, |
| 1488 | { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, | 1490 | { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, |
| 1491 | { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, | ||
| 1489 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, | 1492 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, |
| 1490 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, | 1493 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, |
| 1491 | { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) }, | 1494 | { 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 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, | 1576 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, |
| 1574 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, | 1577 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, |
| 1575 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, | 1578 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, |
| 1579 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, | ||
| 1580 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, | ||
| 1581 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, | ||
| 1576 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1582 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
| 1577 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1583 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
| 1578 | { } | 1584 | { } |
| @@ -1730,7 +1736,7 @@ static int __init hid_init(void) | |||
| 1730 | goto err_bus; | 1736 | goto err_bus; |
| 1731 | 1737 | ||
| 1732 | #ifdef CONFIG_HID_COMPAT | 1738 | #ifdef CONFIG_HID_COMPAT |
| 1733 | hid_compat_wq = create_workqueue("hid_compat"); | 1739 | hid_compat_wq = create_singlethread_workqueue("hid_compat"); |
| 1734 | if (!hid_compat_wq) { | 1740 | if (!hid_compat_wq) { |
| 1735 | hidraw_exit(); | 1741 | hidraw_exit(); |
| 1736 | goto err; | 1742 | goto err; |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index f05bcbbbb0d5..d70075dd3d81 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -82,6 +82,9 @@ | |||
| 82 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 | 82 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 |
| 83 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 | 83 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 |
| 84 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 | 84 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 |
| 85 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 | ||
| 86 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 | ||
| 87 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 | ||
| 85 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a | 88 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a |
| 86 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b | 89 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b |
| 87 | #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 | 90 | #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 |
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; | |||
| 38 | static struct cdev hidraw_cdev; | 38 | static struct cdev hidraw_cdev; |
| 39 | static struct class *hidraw_class; | 39 | static struct class *hidraw_class; |
| 40 | static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; | 40 | static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; |
| 41 | static DEFINE_SPINLOCK(minors_lock); | 41 | static DEFINE_MUTEX(minors_lock); |
| 42 | 42 | ||
| 43 | static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | 43 | static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) |
| 44 | { | 44 | { |
| @@ -159,13 +159,13 @@ static int hidraw_open(struct inode *inode, struct file *file) | |||
| 159 | struct hidraw_list *list; | 159 | struct hidraw_list *list; |
| 160 | int err = 0; | 160 | int err = 0; |
| 161 | 161 | ||
| 162 | lock_kernel(); | ||
| 163 | if (!(list = kzalloc(sizeof(struct hidraw_list), GFP_KERNEL))) { | 162 | if (!(list = kzalloc(sizeof(struct hidraw_list), GFP_KERNEL))) { |
| 164 | err = -ENOMEM; | 163 | err = -ENOMEM; |
| 165 | goto out; | 164 | goto out; |
| 166 | } | 165 | } |
| 167 | 166 | ||
| 168 | spin_lock(&minors_lock); | 167 | lock_kernel(); |
| 168 | mutex_lock(&minors_lock); | ||
| 169 | if (!hidraw_table[minor]) { | 169 | if (!hidraw_table[minor]) { |
| 170 | printk(KERN_EMERG "hidraw device with minor %d doesn't exist\n", | 170 | printk(KERN_EMERG "hidraw device with minor %d doesn't exist\n", |
| 171 | minor); | 171 | minor); |
| @@ -180,13 +180,16 @@ static int hidraw_open(struct inode *inode, struct file *file) | |||
| 180 | file->private_data = list; | 180 | file->private_data = list; |
| 181 | 181 | ||
| 182 | dev = hidraw_table[minor]; | 182 | dev = hidraw_table[minor]; |
| 183 | if (!dev->open++) | 183 | if (!dev->open++) { |
| 184 | dev->hid->ll_driver->open(dev->hid); | 184 | err = dev->hid->ll_driver->open(dev->hid); |
| 185 | if (err < 0) | ||
| 186 | dev->open--; | ||
| 187 | } | ||
| 185 | 188 | ||
| 186 | out_unlock: | 189 | out_unlock: |
| 187 | spin_unlock(&minors_lock); | 190 | mutex_unlock(&minors_lock); |
| 188 | out: | ||
| 189 | unlock_kernel(); | 191 | unlock_kernel(); |
| 192 | out: | ||
| 190 | return err; | 193 | return err; |
| 191 | 194 | ||
| 192 | } | 195 | } |
| @@ -310,7 +313,7 @@ int hidraw_connect(struct hid_device *hid) | |||
| 310 | 313 | ||
| 311 | result = -EINVAL; | 314 | result = -EINVAL; |
| 312 | 315 | ||
| 313 | spin_lock(&minors_lock); | 316 | mutex_lock(&minors_lock); |
| 314 | 317 | ||
| 315 | for (minor = 0; minor < HIDRAW_MAX_DEVICES; minor++) { | 318 | for (minor = 0; minor < HIDRAW_MAX_DEVICES; minor++) { |
| 316 | if (hidraw_table[minor]) | 319 | if (hidraw_table[minor]) |
| @@ -320,9 +323,8 @@ int hidraw_connect(struct hid_device *hid) | |||
| 320 | break; | 323 | break; |
| 321 | } | 324 | } |
| 322 | 325 | ||
| 323 | spin_unlock(&minors_lock); | ||
| 324 | |||
| 325 | if (result) { | 326 | if (result) { |
| 327 | mutex_unlock(&minors_lock); | ||
| 326 | kfree(dev); | 328 | kfree(dev); |
| 327 | goto out; | 329 | goto out; |
| 328 | } | 330 | } |
| @@ -331,14 +333,14 @@ int hidraw_connect(struct hid_device *hid) | |||
| 331 | NULL, "%s%d", "hidraw", minor); | 333 | NULL, "%s%d", "hidraw", minor); |
| 332 | 334 | ||
| 333 | if (IS_ERR(dev->dev)) { | 335 | if (IS_ERR(dev->dev)) { |
| 334 | spin_lock(&minors_lock); | ||
| 335 | hidraw_table[minor] = NULL; | 336 | hidraw_table[minor] = NULL; |
| 336 | spin_unlock(&minors_lock); | 337 | mutex_unlock(&minors_lock); |
| 337 | result = PTR_ERR(dev->dev); | 338 | result = PTR_ERR(dev->dev); |
| 338 | kfree(dev); | 339 | kfree(dev); |
| 339 | goto out; | 340 | goto out; |
| 340 | } | 341 | } |
| 341 | 342 | ||
| 343 | mutex_unlock(&minors_lock); | ||
| 342 | init_waitqueue_head(&dev->wait); | 344 | init_waitqueue_head(&dev->wait); |
| 343 | INIT_LIST_HEAD(&dev->list); | 345 | INIT_LIST_HEAD(&dev->list); |
| 344 | 346 | ||
| @@ -360,9 +362,9 @@ void hidraw_disconnect(struct hid_device *hid) | |||
| 360 | 362 | ||
| 361 | hidraw->exist = 0; | 363 | hidraw->exist = 0; |
| 362 | 364 | ||
| 363 | spin_lock(&minors_lock); | 365 | mutex_lock(&minors_lock); |
| 364 | hidraw_table[hidraw->minor] = NULL; | 366 | hidraw_table[hidraw->minor] = NULL; |
| 365 | spin_unlock(&minors_lock); | 367 | mutex_unlock(&minors_lock); |
| 366 | 368 | ||
| 367 | device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); | 369 | device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); |
| 368 | 370 | ||
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 18e5ddd722cd..d746bf8284dd 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
| @@ -781,6 +781,8 @@ static int usbhid_start(struct hid_device *hid) | |||
| 781 | unsigned int n, insize = 0; | 781 | unsigned int n, insize = 0; |
| 782 | int ret; | 782 | int ret; |
| 783 | 783 | ||
| 784 | clear_bit(HID_DISCONNECTED, &usbhid->iofl); | ||
| 785 | |||
| 784 | usbhid->bufsize = HID_MIN_BUFFER_SIZE; | 786 | usbhid->bufsize = HID_MIN_BUFFER_SIZE; |
| 785 | hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize); | 787 | hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize); |
| 786 | hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize); | 788 | hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize); |
| @@ -847,12 +849,6 @@ static int usbhid_start(struct hid_device *hid) | |||
| 847 | } | 849 | } |
| 848 | } | 850 | } |
| 849 | 851 | ||
| 850 | if (!usbhid->urbin) { | ||
| 851 | err_hid("couldn't find an input interrupt endpoint"); | ||
| 852 | ret = -ENODEV; | ||
| 853 | goto fail; | ||
| 854 | } | ||
| 855 | |||
| 856 | init_waitqueue_head(&usbhid->wait); | 852 | init_waitqueue_head(&usbhid->wait); |
| 857 | INIT_WORK(&usbhid->reset_work, hid_reset); | 853 | INIT_WORK(&usbhid->reset_work, hid_reset); |
| 858 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); | 854 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); |
| @@ -888,6 +884,9 @@ fail: | |||
| 888 | usb_free_urb(usbhid->urbin); | 884 | usb_free_urb(usbhid->urbin); |
| 889 | usb_free_urb(usbhid->urbout); | 885 | usb_free_urb(usbhid->urbout); |
| 890 | usb_free_urb(usbhid->urbctrl); | 886 | usb_free_urb(usbhid->urbctrl); |
| 887 | usbhid->urbin = NULL; | ||
| 888 | usbhid->urbout = NULL; | ||
| 889 | usbhid->urbctrl = NULL; | ||
| 891 | hid_free_buffers(dev, hid); | 890 | hid_free_buffers(dev, hid); |
| 892 | mutex_unlock(&usbhid->setup); | 891 | mutex_unlock(&usbhid->setup); |
| 893 | return ret; | 892 | return ret; |
| @@ -924,6 +923,9 @@ static void usbhid_stop(struct hid_device *hid) | |||
| 924 | usb_free_urb(usbhid->urbin); | 923 | usb_free_urb(usbhid->urbin); |
| 925 | usb_free_urb(usbhid->urbctrl); | 924 | usb_free_urb(usbhid->urbctrl); |
| 926 | usb_free_urb(usbhid->urbout); | 925 | usb_free_urb(usbhid->urbout); |
| 926 | usbhid->urbin = NULL; /* don't mess up next start */ | ||
| 927 | usbhid->urbctrl = NULL; | ||
| 928 | usbhid->urbout = NULL; | ||
| 927 | 929 | ||
| 928 | hid_free_buffers(hid_to_usb_dev(hid), hid); | 930 | hid_free_buffers(hid_to_usb_dev(hid), hid); |
| 929 | mutex_unlock(&usbhid->setup); | 931 | mutex_unlock(&usbhid->setup); |
| @@ -940,15 +942,26 @@ static struct hid_ll_driver usb_hid_driver = { | |||
| 940 | 942 | ||
| 941 | static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | 943 | static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) |
| 942 | { | 944 | { |
| 945 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
| 943 | struct usb_device *dev = interface_to_usbdev(intf); | 946 | struct usb_device *dev = interface_to_usbdev(intf); |
| 944 | struct usbhid_device *usbhid; | 947 | struct usbhid_device *usbhid; |
| 945 | struct hid_device *hid; | 948 | struct hid_device *hid; |
| 949 | unsigned int n, has_in = 0; | ||
| 946 | size_t len; | 950 | size_t len; |
| 947 | int ret; | 951 | int ret; |
| 948 | 952 | ||
| 949 | dbg_hid("HID probe called for ifnum %d\n", | 953 | dbg_hid("HID probe called for ifnum %d\n", |
| 950 | intf->altsetting->desc.bInterfaceNumber); | 954 | intf->altsetting->desc.bInterfaceNumber); |
| 951 | 955 | ||
| 956 | for (n = 0; n < interface->desc.bNumEndpoints; n++) | ||
| 957 | if (usb_endpoint_is_int_in(&interface->endpoint[n].desc)) | ||
| 958 | has_in++; | ||
| 959 | if (!has_in) { | ||
| 960 | dev_err(&intf->dev, "couldn't find an input interrupt " | ||
| 961 | "endpoint\n"); | ||
| 962 | return -ENODEV; | ||
| 963 | } | ||
| 964 | |||
| 952 | hid = hid_allocate_device(); | 965 | hid = hid_allocate_device(); |
| 953 | if (IS_ERR(hid)) | 966 | if (IS_ERR(hid)) |
| 954 | return PTR_ERR(hid); | 967 | return PTR_ERR(hid); |
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 { | |||
| 238 | #define KEY_KPEQUAL 117 | 238 | #define KEY_KPEQUAL 117 |
| 239 | #define KEY_KPPLUSMINUS 118 | 239 | #define KEY_KPPLUSMINUS 118 |
| 240 | #define KEY_PAUSE 119 | 240 | #define KEY_PAUSE 119 |
| 241 | #define KEY_SCALE 120 /* AL Compiz Scale (Expose) */ | ||
| 241 | 242 | ||
| 242 | #define KEY_KPCOMMA 121 | 243 | #define KEY_KPCOMMA 121 |
| 243 | #define KEY_HANGEUL 122 | 244 | #define KEY_HANGEUL 122 |
| @@ -322,6 +323,7 @@ struct input_absinfo { | |||
| 322 | #define KEY_PAUSECD 201 | 323 | #define KEY_PAUSECD 201 |
| 323 | #define KEY_PROG3 202 | 324 | #define KEY_PROG3 202 |
| 324 | #define KEY_PROG4 203 | 325 | #define KEY_PROG4 203 |
| 326 | #define KEY_DASHBOARD 204 /* AL Dashboard */ | ||
| 325 | #define KEY_SUSPEND 205 | 327 | #define KEY_SUSPEND 205 |
| 326 | #define KEY_CLOSE 206 /* AC Close */ | 328 | #define KEY_CLOSE 206 /* AC Close */ |
| 327 | #define KEY_PLAY 207 | 329 | #define KEY_PLAY 207 |
