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; |
