diff options
-rw-r--r-- | drivers/hid/Kconfig | 13 | ||||
-rw-r--r-- | drivers/hid/Makefile | 1 | ||||
-rw-r--r-- | drivers/hid/hid-apple.c | 15 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 68 | ||||
-rw-r--r-- | drivers/hid/hid-debug.c | 5 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 12 | ||||
-rw-r--r-- | drivers/hid/hid-primax.c | 117 | ||||
-rw-r--r-- | drivers/hid/hid-prodikeys.c | 8 | ||||
-rw-r--r-- | drivers/hid/hid-sjoy.c | 75 | ||||
-rw-r--r-- | drivers/hid/hid-zydacron.c | 4 | ||||
-rw-r--r-- | drivers/hid/hidraw.c | 3 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 2 | ||||
-rw-r--r-- | include/linux/hid.h | 2 |
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 | ||
462 | config 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 | |||
462 | config HID_QUANTA | 469 | config 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 | ||
562 | config SMARTJOYPLUS_FF | 573 | config 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 | |||
55 | obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o | 55 | obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o |
56 | obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o | 56 | obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o |
57 | obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o | 57 | obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o |
58 | obj-$(CONFIG_HID_PRIMAX) += hid-primax.o | ||
58 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o | 59 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o |
59 | obj-$(CONFIG_HID_ROCCAT_COMMON) += hid-roccat-common.o | 60 | obj-$(CONFIG_HID_ROCCAT_COMMON) += hid-roccat-common.o |
60 | obj-$(CONFIG_HID_ROCCAT_ARVO) += hid-roccat-arvo.o | 61 | obj-$(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 | |||
1118 | nomem: | 1128 | nomem: |
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; | 1146 | unlock: |
1147 | up(&hid->driver_lock); | ||
1148 | return ret; | ||
1133 | } | 1149 | } |
1134 | EXPORT_SYMBOL_GPL(hid_input_report); | 1150 | EXPORT_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 | } |
1682 | unlock: | ||
1683 | up(&hdev->driver_lock); | ||
1650 | return ret; | 1684 | return ret; |
1651 | } | 1685 | } |
1652 | 1686 | ||
1653 | static int hid_device_remove(struct device *dev) | 1687 | static 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; |
2015 | err: | 2061 | err: |
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 | |||
25 | static 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 | |||
67 | static 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 | |||
81 | fail: | ||
82 | return ret; | ||
83 | } | ||
84 | |||
85 | static void px_remove(struct hid_device *hid) | ||
86 | { | ||
87 | hid_hw_stop(hid); | ||
88 | } | ||
89 | |||
90 | static const struct hid_device_id px_devices[] = { | ||
91 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, | ||
92 | { } | ||
93 | }; | ||
94 | MODULE_DEVICE_TABLE(hid, px_devices); | ||
95 | |||
96 | static 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 | |||
104 | static int __init px_init(void) | ||
105 | { | ||
106 | return hid_register_driver(&px_driver); | ||
107 | } | ||
108 | |||
109 | static void __exit px_exit(void) | ||
110 | { | ||
111 | hid_unregister_driver(&px_driver); | ||
112 | } | ||
113 | |||
114 | module_init(px_init); | ||
115 | module_exit(px_exit); | ||
116 | MODULE_AUTHOR("Terry Lambert <tlambert@google.com>"); | ||
117 | MODULE_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) | |||
849 | err_stop: | 849 | err_stop: |
850 | hid_hw_stop(hdev); | 850 | hid_hw_stop(hdev); |
851 | err_free: | 851 | err_free: |
852 | if (pm != NULL) | 852 | kfree(pm); |
853 | kfree(pm); | 853 | err_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 | ||
153 | static const struct hid_device_id sjoy_devices[] = { | 156 | static 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 | }; |
157 | MODULE_DEVICE_TABLE(hid, sjoy_devices); | 170 | MODULE_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 | ||
209 | static const struct hid_device_id zc_devices[] = { | 207 | static 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) | |||
287 | out_unlock: | 286 | out_unlock: |
288 | mutex_unlock(&minors_lock); | 287 | mutex_unlock(&minors_lock); |
289 | out: | 288 | out: |
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; |