aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-core.c
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2011-10-25 03:59:04 -0400
committerJiri Kosina <jkosina@suse.cz>2011-10-25 03:59:04 -0400
commitb3aec7b686329e6bb65aa08c7f9458f7fd512f06 (patch)
tree67ae55567b5747f32ddd76dd63621bd2ca756a88 /drivers/hid/hid-core.c
parentf6f12427844516bc8e9cf84f43aca7bbbaa48157 (diff)
parent1bcc20675a1ac1ba47eaa201e02a89b0508e17b2 (diff)
Merge branch 'upstream' into for-linus
Conflicts: drivers/hid/hid-core.c drivers/hid/hid-ids.h
Diffstat (limited to 'drivers/hid/hid-core.c')
-rw-r--r--drivers/hid/hid-core.c68
1 files changed, 57 insertions, 11 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index c5606724b77a..91adcc5bad28 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -29,6 +29,7 @@
29#include <linux/wait.h> 29#include <linux/wait.h>
30#include <linux/vmalloc.h> 30#include <linux/vmalloc.h>
31#include <linux/sched.h> 31#include <linux/sched.h>
32#include <linux/semaphore.h>
32 33
33#include <linux/hid.h> 34#include <linux/hid.h>
34#include <linux/hiddev.h> 35#include <linux/hiddev.h>
@@ -1085,16 +1086,25 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
1085 struct hid_report *report; 1086 struct hid_report *report;
1086 char *buf; 1087 char *buf;
1087 unsigned int i; 1088 unsigned int i;
1088 int ret; 1089 int ret = 0;
1089 1090
1090 if (!hid || !hid->driver) 1091 if (!hid)
1091 return -ENODEV; 1092 return -ENODEV;
1093
1094 if (down_trylock(&hid->driver_lock))
1095 return -EBUSY;
1096
1097 if (!hid->driver) {
1098 ret = -ENODEV;
1099 goto unlock;
1100 }
1092 report_enum = hid->report_enum + type; 1101 report_enum = hid->report_enum + type;
1093 hdrv = hid->driver; 1102 hdrv = hid->driver;
1094 1103
1095 if (!size) { 1104 if (!size) {
1096 dbg_hid("empty report\n"); 1105 dbg_hid("empty report\n");
1097 return -1; 1106 ret = -1;
1107 goto unlock;
1098 } 1108 }
1099 1109
1100 buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC); 1110 buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC);
@@ -1118,18 +1128,24 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
1118nomem: 1128nomem:
1119 report = hid_get_report(report_enum, data); 1129 report = hid_get_report(report_enum, data);
1120 1130
1121 if (!report) 1131 if (!report) {
1122 return -1; 1132 ret = -1;
1133 goto unlock;
1134 }
1123 1135
1124 if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) { 1136 if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) {
1125 ret = hdrv->raw_event(hid, report, data, size); 1137 ret = hdrv->raw_event(hid, report, data, size);
1126 if (ret != 0) 1138 if (ret != 0) {
1127 return ret < 0 ? ret : 0; 1139 ret = ret < 0 ? ret : 0;
1140 goto unlock;
1141 }
1128 } 1142 }
1129 1143
1130 hid_report_raw_event(hid, type, data, size, interrupt); 1144 hid_report_raw_event(hid, type, data, size, interrupt);
1131 1145
1132 return 0; 1146unlock:
1147 up(&hid->driver_lock);
1148 return ret;
1133} 1149}
1134EXPORT_SYMBOL_GPL(hid_input_report); 1150EXPORT_SYMBOL_GPL(hid_input_report);
1135 1151
@@ -1349,6 +1365,12 @@ static const struct hid_device_id hid_have_special_driver[] = {
1349 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI) }, 1365 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI) },
1350 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO) }, 1366 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO) },
1351 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS) }, 1367 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS) },
1368 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) },
1369 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) },
1370 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) },
1371 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) },
1372 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) },
1373 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) },
1352 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, 1374 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
1353 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, 1375 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
1354 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, 1376 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
@@ -1472,6 +1494,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1472 { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, 1494 { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
1473 { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) }, 1495 { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) },
1474 { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, 1496 { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
1497 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
1475 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, 1498 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
1476 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, 1499 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
1477 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, 1500 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
@@ -1512,6 +1535,10 @@ static const struct hid_device_id hid_have_special_driver[] = {
1512 { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, 1535 { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) },
1513 { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, 1536 { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
1514 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, 1537 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
1538 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) },
1539 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) },
1540 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) },
1541 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) },
1515 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, 1542 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
1516 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) }, 1543 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
1517 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) }, 1544 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
@@ -1631,10 +1658,15 @@ static int hid_device_probe(struct device *dev)
1631 const struct hid_device_id *id; 1658 const struct hid_device_id *id;
1632 int ret = 0; 1659 int ret = 0;
1633 1660
1661 if (down_interruptible(&hdev->driver_lock))
1662 return -EINTR;
1663
1634 if (!hdev->driver) { 1664 if (!hdev->driver) {
1635 id = hid_match_device(hdev, hdrv); 1665 id = hid_match_device(hdev, hdrv);
1636 if (id == NULL) 1666 if (id == NULL) {
1637 return -ENODEV; 1667 ret = -ENODEV;
1668 goto unlock;
1669 }
1638 1670
1639 hdev->driver = hdrv; 1671 hdev->driver = hdrv;
1640 if (hdrv->probe) { 1672 if (hdrv->probe) {
@@ -1647,14 +1679,20 @@ static int hid_device_probe(struct device *dev)
1647 if (ret) 1679 if (ret)
1648 hdev->driver = NULL; 1680 hdev->driver = NULL;
1649 } 1681 }
1682unlock:
1683 up(&hdev->driver_lock);
1650 return ret; 1684 return ret;
1651} 1685}
1652 1686
1653static int hid_device_remove(struct device *dev) 1687static int hid_device_remove(struct device *dev)
1654{ 1688{
1655 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1689 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1656 struct hid_driver *hdrv = hdev->driver; 1690 struct hid_driver *hdrv;
1691
1692 if (down_interruptible(&hdev->driver_lock))
1693 return -EINTR;
1657 1694
1695 hdrv = hdev->driver;
1658 if (hdrv) { 1696 if (hdrv) {
1659 if (hdrv->remove) 1697 if (hdrv->remove)
1660 hdrv->remove(hdev); 1698 hdrv->remove(hdev);
@@ -1663,6 +1701,7 @@ static int hid_device_remove(struct device *dev)
1663 hdev->driver = NULL; 1701 hdev->driver = NULL;
1664 } 1702 }
1665 1703
1704 up(&hdev->driver_lock);
1666 return 0; 1705 return 0;
1667} 1706}
1668 1707
@@ -1903,6 +1942,12 @@ static const struct hid_device_id hid_mouse_ignore_list[] = {
1903 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) }, 1942 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) },
1904 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) }, 1943 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) },
1905 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) }, 1944 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) },
1945 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) },
1946 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) },
1947 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) },
1948 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) },
1949 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) },
1950 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) },
1906 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, 1951 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
1907 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, 1952 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
1908 { } 1953 { }
@@ -2010,6 +2055,7 @@ struct hid_device *hid_allocate_device(void)
2010 2055
2011 init_waitqueue_head(&hdev->debug_wait); 2056 init_waitqueue_head(&hdev->debug_wait);
2012 INIT_LIST_HEAD(&hdev->debug_list); 2057 INIT_LIST_HEAD(&hdev->debug_list);
2058 sema_init(&hdev->driver_lock, 1);
2013 2059
2014 return hdev; 2060 return hdev;
2015err: 2061err: