diff options
| -rw-r--r-- | drivers/hid/hid-input.c | 33 | ||||
| -rw-r--r-- | include/linux/hid.h | 2 |
2 files changed, 33 insertions, 2 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 6836a856c243..04056773102e 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
| @@ -1100,8 +1100,31 @@ mapped: | |||
| 1100 | 1100 | ||
| 1101 | set_bit(usage->type, input->evbit); | 1101 | set_bit(usage->type, input->evbit); |
| 1102 | 1102 | ||
| 1103 | while (usage->code <= max && test_and_set_bit(usage->code, bit)) | 1103 | /* |
| 1104 | usage->code = find_next_zero_bit(bit, max + 1, usage->code); | 1104 | * This part is *really* controversial: |
| 1105 | * - HID aims at being generic so we should do our best to export | ||
| 1106 | * all incoming events | ||
| 1107 | * - HID describes what events are, so there is no reason for ABS_X | ||
| 1108 | * to be mapped to ABS_Y | ||
| 1109 | * - HID is using *_MISC+N as a default value, but nothing prevents | ||
| 1110 | * *_MISC+N to overwrite a legitimate even, which confuses userspace | ||
| 1111 | * (for instance ABS_MISC + 7 is ABS_MT_SLOT, which has a different | ||
| 1112 | * processing) | ||
| 1113 | * | ||
| 1114 | * If devices still want to use this (at their own risk), they will | ||
| 1115 | * have to use the quirk HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE, but | ||
| 1116 | * the default should be a reliable mapping. | ||
| 1117 | */ | ||
| 1118 | while (usage->code <= max && test_and_set_bit(usage->code, bit)) { | ||
| 1119 | if (device->quirks & HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE) { | ||
| 1120 | usage->code = find_next_zero_bit(bit, | ||
| 1121 | max + 1, | ||
| 1122 | usage->code); | ||
| 1123 | } else { | ||
| 1124 | device->status |= HID_STAT_DUP_DETECTED; | ||
| 1125 | goto ignore; | ||
| 1126 | } | ||
| 1127 | } | ||
| 1105 | 1128 | ||
| 1106 | if (usage->code > max) | 1129 | if (usage->code > max) |
| 1107 | goto ignore; | 1130 | goto ignore; |
| @@ -1611,6 +1634,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) | |||
| 1611 | INIT_LIST_HEAD(&hid->inputs); | 1634 | INIT_LIST_HEAD(&hid->inputs); |
| 1612 | INIT_WORK(&hid->led_work, hidinput_led_worker); | 1635 | INIT_WORK(&hid->led_work, hidinput_led_worker); |
| 1613 | 1636 | ||
| 1637 | hid->status &= ~HID_STAT_DUP_DETECTED; | ||
| 1638 | |||
| 1614 | if (!force) { | 1639 | if (!force) { |
| 1615 | for (i = 0; i < hid->maxcollection; i++) { | 1640 | for (i = 0; i < hid->maxcollection; i++) { |
| 1616 | struct hid_collection *col = &hid->collection[i]; | 1641 | struct hid_collection *col = &hid->collection[i]; |
| @@ -1677,6 +1702,10 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) | |||
| 1677 | goto out_unwind; | 1702 | goto out_unwind; |
| 1678 | } | 1703 | } |
| 1679 | 1704 | ||
| 1705 | if (hid->status & HID_STAT_DUP_DETECTED) | ||
| 1706 | hid_dbg(hid, | ||
| 1707 | "Some usages could not be mapped, please use HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE if this is legitimate.\n"); | ||
| 1708 | |||
| 1680 | return 0; | 1709 | return 0; |
| 1681 | 1710 | ||
| 1682 | out_unwind: | 1711 | out_unwind: |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 8da3e1f48195..0267aa5c1ea3 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
| @@ -345,6 +345,7 @@ struct hid_item { | |||
| 345 | #define HID_QUIRK_SKIP_OUTPUT_REPORT_ID BIT(17) | 345 | #define HID_QUIRK_SKIP_OUTPUT_REPORT_ID BIT(17) |
| 346 | #define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18) | 346 | #define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18) |
| 347 | #define HID_QUIRK_HAVE_SPECIAL_DRIVER BIT(19) | 347 | #define HID_QUIRK_HAVE_SPECIAL_DRIVER BIT(19) |
| 348 | #define HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE BIT(20) | ||
| 348 | #define HID_QUIRK_FULLSPEED_INTERVAL BIT(28) | 349 | #define HID_QUIRK_FULLSPEED_INTERVAL BIT(28) |
| 349 | #define HID_QUIRK_NO_INIT_REPORTS BIT(29) | 350 | #define HID_QUIRK_NO_INIT_REPORTS BIT(29) |
| 350 | #define HID_QUIRK_NO_IGNORE BIT(30) | 351 | #define HID_QUIRK_NO_IGNORE BIT(30) |
| @@ -502,6 +503,7 @@ struct hid_output_fifo { | |||
| 502 | 503 | ||
| 503 | #define HID_STAT_ADDED BIT(0) | 504 | #define HID_STAT_ADDED BIT(0) |
| 504 | #define HID_STAT_PARSED BIT(1) | 505 | #define HID_STAT_PARSED BIT(1) |
| 506 | #define HID_STAT_DUP_DETECTED BIT(2) | ||
| 505 | 507 | ||
| 506 | struct hid_input { | 508 | struct hid_input { |
| 507 | struct list_head list; | 509 | struct list_head list; |
