aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/Kconfig13
-rw-r--r--drivers/hid/Makefile1
-rw-r--r--drivers/hid/hid-apple.c15
-rw-r--r--drivers/hid/hid-core.c68
-rw-r--r--drivers/hid/hid-debug.c5
-rw-r--r--drivers/hid/hid-ids.h12
-rw-r--r--drivers/hid/hid-primax.c117
-rw-r--r--drivers/hid/hid-prodikeys.c8
-rw-r--r--drivers/hid/hid-sjoy.c75
-rw-r--r--drivers/hid/hid-zydacron.c4
-rw-r--r--drivers/hid/hidraw.c3
-rw-r--r--drivers/hid/usbhid/hid-quirks.c2
-rw-r--r--include/linux/hid.h2
13 files changed, 272 insertions, 53 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 2b006bfa0935..22a4a051f221 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -459,6 +459,13 @@ config HID_PICOLCD_LEDS
459 ---help--- 459 ---help---
460 Provide access to PicoLCD's GPO pins via leds class. 460 Provide access to PicoLCD's GPO pins via leds class.
461 461
462config HID_PRIMAX
463 tristate "Primax non-fully HID-compliant devices"
464 depends on USB_HID
465 ---help---
466 Support for Primax devices that are not fully compliant with the
467 HID standard.
468
462config HID_QUANTA 469config HID_QUANTA
463 tristate "Quanta Optical Touch panels" 470 tristate "Quanta Optical Touch panels"
464 depends on USB_HID 471 depends on USB_HID
@@ -557,7 +564,11 @@ config HID_SMARTJOYPLUS
557 tristate "SmartJoy PLUS PS2/USB adapter support" 564 tristate "SmartJoy PLUS PS2/USB adapter support"
558 depends on USB_HID 565 depends on USB_HID
559 ---help--- 566 ---help---
560 Support for SmartJoy PLUS PS2/USB adapter. 567 Support for SmartJoy PLUS PS2/USB adapter, Super Dual Box,
568 Super Joy Box 3 Pro, Super Dual Box Pro, and Super Joy Box 5 Pro.
569
570 Note that DDR (Dance Dance Revolution) mode is not supported, nor
571 is pressure sensitive buttons on the pro models.
561 572
562config SMARTJOYPLUS_FF 573config SMARTJOYPLUS_FF
563 bool "SmartJoy PLUS PS2/USB adapter force feedback support" 574 bool "SmartJoy PLUS PS2/USB adapter force feedback support"
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index b7ddabb0b34c..1e0d2a638b28 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -55,6 +55,7 @@ obj-$(CONFIG_HID_QUANTA) += hid-quanta.o
55obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o 55obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
56obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o 56obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
57obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o 57obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
58obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
58obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o 59obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o
59obj-$(CONFIG_HID_ROCCAT_COMMON) += hid-roccat-common.o 60obj-$(CONFIG_HID_ROCCAT_COMMON) += hid-roccat-common.o
60obj-$(CONFIG_HID_ROCCAT_ARVO) += hid-roccat-arvo.o 61obj-$(CONFIG_HID_ROCCAT_ARVO) += hid-roccat-arvo.o
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index 18b3bc646bf3..9bc7b03269df 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -183,6 +183,9 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
183 if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && 183 if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
184 hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) 184 hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS)
185 table = macbookair_fn_keys; 185 table = macbookair_fn_keys;
186 else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI &&
187 hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING6_JIS)
188 table = macbookair_fn_keys;
186 else if (hid->product < 0x21d || hid->product >= 0x300) 189 else if (hid->product < 0x21d || hid->product >= 0x300)
187 table = powerbook_fn_keys; 190 table = powerbook_fn_keys;
188 else 191 else
@@ -493,6 +496,18 @@ static const struct hid_device_id apple_devices[] = {
493 .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, 496 .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
494 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS), 497 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS),
495 .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, 498 .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
499 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI),
500 .driver_data = APPLE_HAS_FN },
501 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO),
502 .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
503 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS),
504 .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
505 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI),
506 .driver_data = APPLE_HAS_FN },
507 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO),
508 .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
509 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS),
510 .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
496 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), 511 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
497 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, 512 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
498 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), 513 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
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:
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index bae48745bb42..9a243ca96e6d 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -450,6 +450,11 @@ void hid_dump_field(struct hid_field *field, int n, struct seq_file *f) {
450 seq_printf(f, "Logical("); 450 seq_printf(f, "Logical(");
451 hid_resolv_usage(field->logical, f); seq_printf(f, ")\n"); 451 hid_resolv_usage(field->logical, f); seq_printf(f, ")\n");
452 } 452 }
453 if (field->application) {
454 tab(n, f);
455 seq_printf(f, "Application(");
456 hid_resolv_usage(field->application, f); seq_printf(f, ")\n");
457 }
453 tab(n, f); seq_printf(f, "Usage(%d)\n", field->maxusage); 458 tab(n, f); seq_printf(f, "Usage(%d)\n", field->maxusage);
454 for (j = 0; j < field->maxusage; j++) { 459 for (j = 0; j < field->maxusage; j++) {
455 tab(n+2, f); hid_resolv_usage(field->usage[j].hid, f); seq_printf(f, "\n"); 460 tab(n+2, f); hid_resolv_usage(field->usage[j].hid, f); seq_printf(f, "\n");
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index d5dbb1a4f76b..1680e99b4816 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -112,6 +112,12 @@
112#define USB_DEVICE_ID_APPLE_ALU_REVB_ANSI 0x024f 112#define USB_DEVICE_ID_APPLE_ALU_REVB_ANSI 0x024f
113#define USB_DEVICE_ID_APPLE_ALU_REVB_ISO 0x0250 113#define USB_DEVICE_ID_APPLE_ALU_REVB_ISO 0x0250
114#define USB_DEVICE_ID_APPLE_ALU_REVB_JIS 0x0251 114#define USB_DEVICE_ID_APPLE_ALU_REVB_JIS 0x0251
115#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249
116#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a
117#define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b
118#define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI 0x024c
119#define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO 0x024d
120#define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS 0x024e
115#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 121#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239
116#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a 122#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a
117#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b 123#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b
@@ -687,6 +693,9 @@
687#define USB_VENDOR_ID_WISEGROUP_LTD 0x6666 693#define USB_VENDOR_ID_WISEGROUP_LTD 0x6666
688#define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677 694#define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677
689#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802 695#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802
696#define USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO 0x8801
697#define USB_DEVICE_ID_SUPER_DUAL_BOX_PRO 0x8802
698#define USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO 0x8804
690 699
691#define USB_VENDOR_ID_X_TENSIONS 0x1ae7 700#define USB_VENDOR_ID_X_TENSIONS 0x1ae7
692#define USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE 0x9001 701#define USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE 0x9001
@@ -702,4 +711,7 @@
702#define USB_VENDOR_ID_ZYDACRON 0x13EC 711#define USB_VENDOR_ID_ZYDACRON 0x13EC
703#define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006 712#define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006
704 713
714#define USB_VENDOR_ID_PRIMAX 0x0461
715#define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05
716
705#endif 717#endif
diff --git a/drivers/hid/hid-primax.c b/drivers/hid/hid-primax.c
new file mode 100644
index 000000000000..4d3c60d88318
--- /dev/null
+++ b/drivers/hid/hid-primax.c
@@ -0,0 +1,117 @@
1/*
2 * HID driver for primax and similar keyboards with in-band modifiers
3 *
4 * Copyright 2011 Google Inc. All Rights Reserved
5 *
6 * Author:
7 * Terry Lambert <tlambert@google.com>
8 *
9 * This software is licensed under the terms of the GNU General Public
10 * License version 2, as published by the Free Software Foundation, and
11 * may be copied, distributed, and modified under those terms.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/device.h>
20#include <linux/hid.h>
21#include <linux/module.h>
22
23#include "hid-ids.h"
24
25static int px_raw_event(struct hid_device *hid, struct hid_report *report,
26 u8 *data, int size)
27{
28 int idx = size;
29
30 switch (report->id) {
31 case 0: /* keyboard input */
32 /*
33 * Convert in-band modifier key values into out of band
34 * modifier bits and pull the key strokes from the report.
35 * Thus a report data set which looked like:
36 *
37 * [00][00][E0][30][00][00][00][00]
38 * (no modifier bits + "Left Shift" key + "1" key)
39 *
40 * Would be converted to:
41 *
42 * [01][00][00][30][00][00][00][00]
43 * (Left Shift modifier bit + "1" key)
44 *
45 * As long as it's in the size range, the upper level
46 * drivers don't particularly care if there are in-band
47 * 0-valued keys, so they don't stop parsing.
48 */
49 while (--idx > 1) {
50 if (data[idx] < 0xE0 || data[idx] > 0xE7)
51 continue;
52 data[0] |= (1 << (data[idx] - 0xE0));
53 data[idx] = 0;
54 }
55 hid_report_raw_event(hid, HID_INPUT_REPORT, data, size, 0);
56 return 1;
57
58 default: /* unknown report */
59 /* Unknown report type; pass upstream */
60 hid_info(hid, "unknown report type %d\n", report->id);
61 break;
62 }
63
64 return 0;
65}
66
67static int px_probe(struct hid_device *hid, const struct hid_device_id *id)
68{
69 int ret;
70
71 ret = hid_parse(hid);
72 if (ret) {
73 hid_err(hid, "parse failed\n");
74 goto fail;
75 }
76
77 ret = hid_hw_start(hid, HID_CONNECT_DEFAULT);
78 if (ret)
79 hid_err(hid, "hw start failed\n");
80
81fail:
82 return ret;
83}
84
85static void px_remove(struct hid_device *hid)
86{
87 hid_hw_stop(hid);
88}
89
90static const struct hid_device_id px_devices[] = {
91 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
92 { }
93};
94MODULE_DEVICE_TABLE(hid, px_devices);
95
96static struct hid_driver px_driver = {
97 .name = "primax",
98 .id_table = px_devices,
99 .raw_event = px_raw_event,
100 .probe = px_probe,
101 .remove = px_remove,
102};
103
104static int __init px_init(void)
105{
106 return hid_register_driver(&px_driver);
107}
108
109static void __exit px_exit(void)
110{
111 hid_unregister_driver(&px_driver);
112}
113
114module_init(px_init);
115module_exit(px_exit);
116MODULE_AUTHOR("Terry Lambert <tlambert@google.com>");
117MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c
index 158b389d0fb7..f779009104eb 100644
--- a/drivers/hid/hid-prodikeys.c
+++ b/drivers/hid/hid-prodikeys.c
@@ -816,7 +816,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
816 if (pm == NULL) { 816 if (pm == NULL) {
817 hid_err(hdev, "can't alloc descriptor\n"); 817 hid_err(hdev, "can't alloc descriptor\n");
818 ret = -ENOMEM; 818 ret = -ENOMEM;
819 goto err_free; 819 goto err_free_pk;
820 } 820 }
821 821
822 pm->pk = pk; 822 pm->pk = pk;
@@ -849,10 +849,10 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
849err_stop: 849err_stop:
850 hid_hw_stop(hdev); 850 hid_hw_stop(hdev);
851err_free: 851err_free:
852 if (pm != NULL) 852 kfree(pm);
853 kfree(pm); 853err_free_pk:
854
855 kfree(pk); 854 kfree(pk);
855
856 return ret; 856 return ret;
857} 857}
858 858
diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c
index 16f7cafc9695..670da9109f86 100644
--- a/drivers/hid/hid-sjoy.c
+++ b/drivers/hid/hid-sjoy.c
@@ -65,8 +65,7 @@ static int sjoyff_init(struct hid_device *hid)
65{ 65{
66 struct sjoyff_device *sjoyff; 66 struct sjoyff_device *sjoyff;
67 struct hid_report *report; 67 struct hid_report *report;
68 struct hid_input *hidinput = list_entry(hid->inputs.next, 68 struct hid_input *hidinput;
69 struct hid_input, list);
70 struct list_head *report_list = 69 struct list_head *report_list =
71 &hid->report_enum[HID_OUTPUT_REPORT].report_list; 70 &hid->report_enum[HID_OUTPUT_REPORT].report_list;
72 struct list_head *report_ptr = report_list; 71 struct list_head *report_ptr = report_list;
@@ -78,43 +77,45 @@ static int sjoyff_init(struct hid_device *hid)
78 return -ENODEV; 77 return -ENODEV;
79 } 78 }
80 79
81 report_ptr = report_ptr->next; 80 list_for_each_entry(hidinput, &hid->inputs, list) {
81 report_ptr = report_ptr->next;
82 82
83 if (report_ptr == report_list) { 83 if (report_ptr == report_list) {
84 hid_err(hid, "required output report is missing\n"); 84 hid_err(hid, "required output report is missing\n");
85 return -ENODEV; 85 return -ENODEV;
86 } 86 }
87 87
88 report = list_entry(report_ptr, struct hid_report, list); 88 report = list_entry(report_ptr, struct hid_report, list);
89 if (report->maxfield < 1) { 89 if (report->maxfield < 1) {
90 hid_err(hid, "no fields in the report\n"); 90 hid_err(hid, "no fields in the report\n");
91 return -ENODEV; 91 return -ENODEV;
92 } 92 }
93 93
94 if (report->field[0]->report_count < 3) { 94 if (report->field[0]->report_count < 3) {
95 hid_err(hid, "not enough values in the field\n"); 95 hid_err(hid, "not enough values in the field\n");
96 return -ENODEV; 96 return -ENODEV;
97 } 97 }
98 98
99 sjoyff = kzalloc(sizeof(struct sjoyff_device), GFP_KERNEL); 99 sjoyff = kzalloc(sizeof(struct sjoyff_device), GFP_KERNEL);
100 if (!sjoyff) 100 if (!sjoyff)
101 return -ENOMEM; 101 return -ENOMEM;
102 102
103 dev = hidinput->input; 103 dev = hidinput->input;
104 104
105 set_bit(FF_RUMBLE, dev->ffbit); 105 set_bit(FF_RUMBLE, dev->ffbit);
106 106
107 error = input_ff_create_memless(dev, sjoyff, hid_sjoyff_play); 107 error = input_ff_create_memless(dev, sjoyff, hid_sjoyff_play);
108 if (error) { 108 if (error) {
109 kfree(sjoyff); 109 kfree(sjoyff);
110 return error; 110 return error;
111 } 111 }
112 112
113 sjoyff->report = report; 113 sjoyff->report = report;
114 sjoyff->report->field[0]->value[0] = 0x01; 114 sjoyff->report->field[0]->value[0] = 0x01;
115 sjoyff->report->field[0]->value[1] = 0x00; 115 sjoyff->report->field[0]->value[1] = 0x00;
116 sjoyff->report->field[0]->value[2] = 0x00; 116 sjoyff->report->field[0]->value[2] = 0x00;
117 usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT); 117 usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT);
118 }
118 119
119 hid_info(hid, "Force feedback for SmartJoy PLUS PS2/USB adapter\n"); 120 hid_info(hid, "Force feedback for SmartJoy PLUS PS2/USB adapter\n");
120 121
@@ -131,6 +132,8 @@ static int sjoy_probe(struct hid_device *hdev, const struct hid_device_id *id)
131{ 132{
132 int ret; 133 int ret;
133 134
135 hdev->quirks |= id->driver_data;
136
134 ret = hid_parse(hdev); 137 ret = hid_parse(hdev);
135 if (ret) { 138 if (ret) {
136 hid_err(hdev, "parse failed\n"); 139 hid_err(hdev, "parse failed\n");
@@ -151,7 +154,17 @@ err:
151} 154}
152 155
153static const struct hid_device_id sjoy_devices[] = { 156static const struct hid_device_id sjoy_devices[] = {
157 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) },
158 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO),
159 .driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET |
160 HID_QUIRK_SKIP_OUTPUT_REPORTS },
161 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO),
162 .driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET |
163 HID_QUIRK_SKIP_OUTPUT_REPORTS },
154 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, 164 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
165 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD),
166 .driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET |
167 HID_QUIRK_SKIP_OUTPUT_REPORTS },
155 { } 168 { }
156}; 169};
157MODULE_DEVICE_TABLE(hid, sjoy_devices); 170MODULE_DEVICE_TABLE(hid, sjoy_devices);
diff --git a/drivers/hid/hid-zydacron.c b/drivers/hid/hid-zydacron.c
index e90371508fd2..1ad85f2257b4 100644
--- a/drivers/hid/hid-zydacron.c
+++ b/drivers/hid/hid-zydacron.c
@@ -201,9 +201,7 @@ static void zc_remove(struct hid_device *hdev)
201 struct zc_device *zc = hid_get_drvdata(hdev); 201 struct zc_device *zc = hid_get_drvdata(hdev);
202 202
203 hid_hw_stop(hdev); 203 hid_hw_stop(hdev);
204 204 kfree(zc);
205 if (NULL != zc)
206 kfree(zc);
207} 205}
208 206
209static const struct hid_device_id zc_devices[] = { 207static const struct hid_device_id zc_devices[] = {
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 6d65d4e35120..cf7d6d58e79f 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -259,7 +259,6 @@ static int hidraw_open(struct inode *inode, struct file *file)
259 259
260 mutex_lock(&minors_lock); 260 mutex_lock(&minors_lock);
261 if (!hidraw_table[minor]) { 261 if (!hidraw_table[minor]) {
262 kfree(list);
263 err = -ENODEV; 262 err = -ENODEV;
264 goto out_unlock; 263 goto out_unlock;
265 } 264 }
@@ -287,6 +286,8 @@ static int hidraw_open(struct inode *inode, struct file *file)
287out_unlock: 286out_unlock:
288 mutex_unlock(&minors_lock); 287 mutex_unlock(&minors_lock);
289out: 288out:
289 if (err < 0)
290 kfree(list);
290 return err; 291 return err;
291 292
292} 293}
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 3146fdcda272..4ea464151c3b 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -80,10 +80,8 @@ static const struct hid_blacklist {
80 { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT }, 80 { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT },
81 { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT }, 81 { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT },
82 { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT }, 82 { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT },
83 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
84 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 83 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
85 84
86 { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
87 { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 85 { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
88 86
89 { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE }, 87 { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE },
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 6fb743d72bfe..deed5f9a1e1c 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -71,6 +71,7 @@
71#include <linux/timer.h> 71#include <linux/timer.h>
72#include <linux/workqueue.h> 72#include <linux/workqueue.h>
73#include <linux/input.h> 73#include <linux/input.h>
74#include <linux/semaphore.h>
74 75
75/* 76/*
76 * We parse each description item into this structure. Short items data 77 * We parse each description item into this structure. Short items data
@@ -476,6 +477,7 @@ struct hid_device { /* device report descriptor */
476 unsigned country; /* HID country */ 477 unsigned country; /* HID country */
477 struct hid_report_enum report_enum[HID_REPORT_TYPES]; 478 struct hid_report_enum report_enum[HID_REPORT_TYPES];
478 479
480 struct semaphore driver_lock; /* protects the current driver */
479 struct device dev; /* device */ 481 struct device dev; /* device */
480 struct hid_driver *driver; 482 struct hid_driver *driver;
481 struct hid_ll_driver *ll_driver; 483 struct hid_ll_driver *ll_driver;