aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/usbhid
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-22 22:21:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-22 22:21:48 -0400
commit3c2c4b73aa79e4a1b601710b59e092441175f4bb (patch)
treefbd08c3e18517871b25fe9c886caae423947d578 /drivers/hid/usbhid
parentf08b9c2f8af0d61faa1170aeae4fbca1eff6a504 (diff)
parent99ce58ddc4eadec8c35d9a1d64ff57703fdcfacc (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID subsystem updates from Jiri Kosina: "Apart from various driver updates and added support for a number of new devices (mostly multitouch ones, but not limited to), there is one change that is worth pointing out explicitly: creation of HID device groups and proper autoloading of hid-multitouch, implemented by Henrik Rydberg." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (50 commits) HID: wacom: fix build breakage without CONFIG_LEDS_CLASS HID: waltop: Extend barrel button fix HID: hyperv: Set the hid drvdata correctly HID: wacom: Unify speed setting HID: wacom: Add speed setting for Intuos4 WL HID: wacom: Move Graphire raport header check. HID: uclogic: Add support for UC-Logic TWHL850 HID: explain the signed/unsigned handling in hid_add_field() HID: handle logical min/max signedness properly in parser HID: logitech: read all 32 bits of report type bitfield HID: wacom: Add LED selector control for Wacom Intuos4 WL HID: hid-multitouch: fix wrong protocol detection HID: wiimote: Fix IR data parser HID: wacom: Add tilt reporting for Intuos4 WL HID: multitouch: MT interface matching for Baanto HID: hid-multitouch: Only match MT interfaces HID: Create a common generic driver HID: hid-multitouch: Switch to device groups HID: Create a generic device group HID: Allow bus wildcard matching ...
Diffstat (limited to 'drivers/hid/usbhid')
-rw-r--r--drivers/hid/usbhid/hid-core.c81
-rw-r--r--drivers/hid/usbhid/hid-quirks.c1
-rw-r--r--drivers/hid/usbhid/hiddev.c9
-rw-r--r--drivers/hid/usbhid/usbhid.h1
4 files changed, 62 insertions, 30 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 340d6ae646ed..482f936fc29b 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -28,6 +28,7 @@
28#include <linux/input.h> 28#include <linux/input.h>
29#include <linux/wait.h> 29#include <linux/wait.h>
30#include <linux/workqueue.h> 30#include <linux/workqueue.h>
31#include <linux/string.h>
31 32
32#include <linux/usb.h> 33#include <linux/usb.h>
33 34
@@ -86,8 +87,13 @@ static int hid_start_in(struct hid_device *hid)
86 !test_bit(HID_REPORTED_IDLE, &usbhid->iofl) && 87 !test_bit(HID_REPORTED_IDLE, &usbhid->iofl) &&
87 !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) { 88 !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
88 rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC); 89 rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC);
89 if (rc != 0) 90 if (rc != 0) {
90 clear_bit(HID_IN_RUNNING, &usbhid->iofl); 91 clear_bit(HID_IN_RUNNING, &usbhid->iofl);
92 if (rc == -ENOSPC)
93 set_bit(HID_NO_BANDWIDTH, &usbhid->iofl);
94 } else {
95 clear_bit(HID_NO_BANDWIDTH, &usbhid->iofl);
96 }
91 } 97 }
92 spin_unlock_irqrestore(&usbhid->lock, flags); 98 spin_unlock_irqrestore(&usbhid->lock, flags);
93 return rc; 99 return rc;
@@ -173,8 +179,10 @@ static void hid_io_error(struct hid_device *hid)
173 179
174 if (time_after(jiffies, usbhid->stop_retry)) { 180 if (time_after(jiffies, usbhid->stop_retry)) {
175 181
176 /* Retries failed, so do a port reset */ 182 /* Retries failed, so do a port reset unless we lack bandwidth*/
177 if (!test_and_set_bit(HID_RESET_PENDING, &usbhid->iofl)) { 183 if (test_bit(HID_NO_BANDWIDTH, &usbhid->iofl)
184 && !test_and_set_bit(HID_RESET_PENDING, &usbhid->iofl)) {
185
178 schedule_work(&usbhid->reset_work); 186 schedule_work(&usbhid->reset_work);
179 goto done; 187 goto done;
180 } 188 }
@@ -749,7 +757,7 @@ static int hid_get_class_descriptor(struct usb_device *dev, int ifnum,
749int usbhid_open(struct hid_device *hid) 757int usbhid_open(struct hid_device *hid)
750{ 758{
751 struct usbhid_device *usbhid = hid->driver_data; 759 struct usbhid_device *usbhid = hid->driver_data;
752 int res; 760 int res = 0;
753 761
754 mutex_lock(&hid_open_mut); 762 mutex_lock(&hid_open_mut);
755 if (!hid->open++) { 763 if (!hid->open++) {
@@ -757,17 +765,27 @@ int usbhid_open(struct hid_device *hid)
757 /* the device must be awake to reliably request remote wakeup */ 765 /* the device must be awake to reliably request remote wakeup */
758 if (res < 0) { 766 if (res < 0) {
759 hid->open--; 767 hid->open--;
760 mutex_unlock(&hid_open_mut); 768 res = -EIO;
761 return -EIO; 769 goto done;
762 } 770 }
763 usbhid->intf->needs_remote_wakeup = 1; 771 usbhid->intf->needs_remote_wakeup = 1;
764 if (hid_start_in(hid)) 772 res = hid_start_in(hid);
765 hid_io_error(hid); 773 if (res) {
766 774 if (res != -ENOSPC) {
775 hid_io_error(hid);
776 res = 0;
777 } else {
778 /* no use opening if resources are insufficient */
779 hid->open--;
780 res = -EBUSY;
781 usbhid->intf->needs_remote_wakeup = 0;
782 }
783 }
767 usb_autopm_put_interface(usbhid->intf); 784 usb_autopm_put_interface(usbhid->intf);
768 } 785 }
786done:
769 mutex_unlock(&hid_open_mut); 787 mutex_unlock(&hid_open_mut);
770 return 0; 788 return res;
771} 789}
772 790
773void usbhid_close(struct hid_device *hid) 791void usbhid_close(struct hid_device *hid)
@@ -1396,7 +1414,34 @@ static int hid_post_reset(struct usb_interface *intf)
1396 struct usb_device *dev = interface_to_usbdev (intf); 1414 struct usb_device *dev = interface_to_usbdev (intf);
1397 struct hid_device *hid = usb_get_intfdata(intf); 1415 struct hid_device *hid = usb_get_intfdata(intf);
1398 struct usbhid_device *usbhid = hid->driver_data; 1416 struct usbhid_device *usbhid = hid->driver_data;
1417 struct usb_host_interface *interface = intf->cur_altsetting;
1399 int status; 1418 int status;
1419 char *rdesc;
1420
1421 /* Fetch and examine the HID report descriptor. If this
1422 * has changed, then rebind. Since usbcore's check of the
1423 * configuration descriptors passed, we already know that
1424 * the size of the HID report descriptor has not changed.
1425 */
1426 rdesc = kmalloc(hid->rsize, GFP_KERNEL);
1427 if (!rdesc) {
1428 dbg_hid("couldn't allocate rdesc memory (post_reset)\n");
1429 return 1;
1430 }
1431 status = hid_get_class_descriptor(dev,
1432 interface->desc.bInterfaceNumber,
1433 HID_DT_REPORT, rdesc, hid->rsize);
1434 if (status < 0) {
1435 dbg_hid("reading report descriptor failed (post_reset)\n");
1436 kfree(rdesc);
1437 return 1;
1438 }
1439 status = memcmp(rdesc, hid->rdesc, hid->rsize);
1440 kfree(rdesc);
1441 if (status != 0) {
1442 dbg_hid("report descriptor changed\n");
1443 return 1;
1444 }
1400 1445
1401 spin_lock_irq(&usbhid->lock); 1446 spin_lock_irq(&usbhid->lock);
1402 clear_bit(HID_RESET_PENDING, &usbhid->iofl); 1447 clear_bit(HID_RESET_PENDING, &usbhid->iofl);
@@ -1553,28 +1598,15 @@ static struct usb_driver hid_driver = {
1553 .supports_autosuspend = 1, 1598 .supports_autosuspend = 1,
1554}; 1599};
1555 1600
1556static const struct hid_device_id hid_usb_table[] = {
1557 { HID_USB_DEVICE(HID_ANY_ID, HID_ANY_ID) },
1558 { }
1559};
1560
1561struct usb_interface *usbhid_find_interface(int minor) 1601struct usb_interface *usbhid_find_interface(int minor)
1562{ 1602{
1563 return usb_find_interface(&hid_driver, minor); 1603 return usb_find_interface(&hid_driver, minor);
1564} 1604}
1565 1605
1566static struct hid_driver hid_usb_driver = {
1567 .name = "generic-usb",
1568 .id_table = hid_usb_table,
1569};
1570
1571static int __init hid_init(void) 1606static int __init hid_init(void)
1572{ 1607{
1573 int retval = -ENOMEM; 1608 int retval = -ENOMEM;
1574 1609
1575 retval = hid_register_driver(&hid_usb_driver);
1576 if (retval)
1577 goto hid_register_fail;
1578 retval = usbhid_quirks_init(quirks_param); 1610 retval = usbhid_quirks_init(quirks_param);
1579 if (retval) 1611 if (retval)
1580 goto usbhid_quirks_init_fail; 1612 goto usbhid_quirks_init_fail;
@@ -1587,8 +1619,6 @@ static int __init hid_init(void)
1587usb_register_fail: 1619usb_register_fail:
1588 usbhid_quirks_exit(); 1620 usbhid_quirks_exit();
1589usbhid_quirks_init_fail: 1621usbhid_quirks_init_fail:
1590 hid_unregister_driver(&hid_usb_driver);
1591hid_register_fail:
1592 return retval; 1622 return retval;
1593} 1623}
1594 1624
@@ -1596,7 +1626,6 @@ static void __exit hid_exit(void)
1596{ 1626{
1597 usb_deregister(&hid_driver); 1627 usb_deregister(&hid_driver);
1598 usbhid_quirks_exit(); 1628 usbhid_quirks_exit();
1599 hid_unregister_driver(&hid_usb_driver);
1600} 1629}
1601 1630
1602module_init(hid_init); 1631module_init(hid_init);
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 782c63955f29..0597ee604f6e 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -88,6 +88,7 @@ static const struct hid_blacklist {
88 { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT }, 88 { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT },
89 { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT }, 89 { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT },
90 { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT }, 90 { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT },
91 { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET, HID_QUIRK_MULTI_INPUT },
91 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 92 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
92 93
93 { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 94 { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index b1ec0e2aeb57..14599e256791 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -34,6 +34,7 @@
34#include <linux/hid.h> 34#include <linux/hid.h>
35#include <linux/hiddev.h> 35#include <linux/hiddev.h>
36#include <linux/compat.h> 36#include <linux/compat.h>
37#include <linux/vmalloc.h>
37#include "usbhid.h" 38#include "usbhid.h"
38 39
39#ifdef CONFIG_USB_DYNAMIC_MINORS 40#ifdef CONFIG_USB_DYNAMIC_MINORS
@@ -250,13 +251,13 @@ static int hiddev_release(struct inode * inode, struct file * file)
250 } else { 251 } else {
251 mutex_unlock(&list->hiddev->existancelock); 252 mutex_unlock(&list->hiddev->existancelock);
252 kfree(list->hiddev); 253 kfree(list->hiddev);
253 kfree(list); 254 vfree(list);
254 return 0; 255 return 0;
255 } 256 }
256 } 257 }
257 258
258 mutex_unlock(&list->hiddev->existancelock); 259 mutex_unlock(&list->hiddev->existancelock);
259 kfree(list); 260 vfree(list);
260 261
261 return 0; 262 return 0;
262} 263}
@@ -278,7 +279,7 @@ static int hiddev_open(struct inode *inode, struct file *file)
278 hid = usb_get_intfdata(intf); 279 hid = usb_get_intfdata(intf);
279 hiddev = hid->hiddev; 280 hiddev = hid->hiddev;
280 281
281 if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL))) 282 if (!(list = vzalloc(sizeof(struct hiddev_list))))
282 return -ENOMEM; 283 return -ENOMEM;
283 mutex_init(&list->thread_lock); 284 mutex_init(&list->thread_lock);
284 list->hiddev = hiddev; 285 list->hiddev = hiddev;
@@ -322,7 +323,7 @@ bail_unlock:
322 mutex_unlock(&hiddev->existancelock); 323 mutex_unlock(&hiddev->existancelock);
323bail: 324bail:
324 file->private_data = NULL; 325 file->private_data = NULL;
325 kfree(list); 326 vfree(list);
326 return res; 327 return res;
327} 328}
328 329
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h
index cb8f703efde5..1883d7b94870 100644
--- a/drivers/hid/usbhid/usbhid.h
+++ b/drivers/hid/usbhid/usbhid.h
@@ -55,6 +55,7 @@ struct usb_interface *usbhid_find_interface(int minor);
55#define HID_STARTED 8 55#define HID_STARTED 8
56#define HID_REPORTED_IDLE 9 56#define HID_REPORTED_IDLE 9
57#define HID_KEYS_PRESSED 10 57#define HID_KEYS_PRESSED 10
58#define HID_NO_BANDWIDTH 11
58 59
59/* 60/*
60 * USB-specific HID struct, to be pointed to 61 * USB-specific HID struct, to be pointed to