aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/usbhid/hid-core.c
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/hid-core.c
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/hid-core.c')
-rw-r--r--drivers/hid/usbhid/hid-core.c81
1 files changed, 55 insertions, 26 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);