diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-19 12:56:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-19 12:56:57 -0400 |
commit | 8a1e377e55f2dca5c689926313beeaa8ac2adb22 (patch) | |
tree | a0123dcf7c2268e48f6c23900df74eca0ae477e8 | |
parent | b6ffb11e4e5b6d1ae61c26c90255877fa4749eca (diff) | |
parent | 4973ca9a01e2354b159acedec1b9b8eb8de02ab7 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID fixes from Jiri Kosina:
- hid-dr regression fix for certain dragonrise gamepads (device ID
0079:0006), from Ioan-Adrian Ratiu
- dma-on-stack fix for hid-led driver, from Heiner Kallweit
- quirk for Akai MIDImix device
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
HID: add quirk for Akai MIDImix.
Revert "HID: dragonrise: fix HID Descriptor for 0x0006 PID"
HID: hid-dr: add input mapping for axis selection
HID: hid-led: fix issue with transfer buffer not being dma capable
-rw-r--r-- | drivers/hid/hid-dr.c | 83 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 3 | ||||
-rw-r--r-- | drivers/hid/hid-led.c | 23 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 1 |
4 files changed, 48 insertions, 62 deletions
diff --git a/drivers/hid/hid-dr.c b/drivers/hid/hid-dr.c index 8fd4bf77f264..818ea7d93533 100644 --- a/drivers/hid/hid-dr.c +++ b/drivers/hid/hid-dr.c | |||
@@ -234,58 +234,6 @@ static __u8 pid0011_rdesc_fixed[] = { | |||
234 | 0xC0 /* End Collection */ | 234 | 0xC0 /* End Collection */ |
235 | }; | 235 | }; |
236 | 236 | ||
237 | static __u8 pid0006_rdesc_fixed[] = { | ||
238 | 0x05, 0x01, /* Usage Page (Generic Desktop) */ | ||
239 | 0x09, 0x04, /* Usage (Joystick) */ | ||
240 | 0xA1, 0x01, /* Collection (Application) */ | ||
241 | 0xA1, 0x02, /* Collection (Logical) */ | ||
242 | 0x75, 0x08, /* Report Size (8) */ | ||
243 | 0x95, 0x05, /* Report Count (5) */ | ||
244 | 0x15, 0x00, /* Logical Minimum (0) */ | ||
245 | 0x26, 0xFF, 0x00, /* Logical Maximum (255) */ | ||
246 | 0x35, 0x00, /* Physical Minimum (0) */ | ||
247 | 0x46, 0xFF, 0x00, /* Physical Maximum (255) */ | ||
248 | 0x09, 0x30, /* Usage (X) */ | ||
249 | 0x09, 0x33, /* Usage (Ry) */ | ||
250 | 0x09, 0x32, /* Usage (Z) */ | ||
251 | 0x09, 0x31, /* Usage (Y) */ | ||
252 | 0x09, 0x34, /* Usage (Ry) */ | ||
253 | 0x81, 0x02, /* Input (Variable) */ | ||
254 | 0x75, 0x04, /* Report Size (4) */ | ||
255 | 0x95, 0x01, /* Report Count (1) */ | ||
256 | 0x25, 0x07, /* Logical Maximum (7) */ | ||
257 | 0x46, 0x3B, 0x01, /* Physical Maximum (315) */ | ||
258 | 0x65, 0x14, /* Unit (Centimeter) */ | ||
259 | 0x09, 0x39, /* Usage (Hat switch) */ | ||
260 | 0x81, 0x42, /* Input (Variable) */ | ||
261 | 0x65, 0x00, /* Unit (None) */ | ||
262 | 0x75, 0x01, /* Report Size (1) */ | ||
263 | 0x95, 0x0C, /* Report Count (12) */ | ||
264 | 0x25, 0x01, /* Logical Maximum (1) */ | ||
265 | 0x45, 0x01, /* Physical Maximum (1) */ | ||
266 | 0x05, 0x09, /* Usage Page (Button) */ | ||
267 | 0x19, 0x01, /* Usage Minimum (0x01) */ | ||
268 | 0x29, 0x0C, /* Usage Maximum (0x0C) */ | ||
269 | 0x81, 0x02, /* Input (Variable) */ | ||
270 | 0x06, 0x00, 0xFF, /* Usage Page (Vendor Defined) */ | ||
271 | 0x75, 0x01, /* Report Size (1) */ | ||
272 | 0x95, 0x08, /* Report Count (8) */ | ||
273 | 0x25, 0x01, /* Logical Maximum (1) */ | ||
274 | 0x45, 0x01, /* Physical Maximum (1) */ | ||
275 | 0x09, 0x01, /* Usage (0x01) */ | ||
276 | 0x81, 0x02, /* Input (Variable) */ | ||
277 | 0xC0, /* End Collection */ | ||
278 | 0xA1, 0x02, /* Collection (Logical) */ | ||
279 | 0x75, 0x08, /* Report Size (8) */ | ||
280 | 0x95, 0x07, /* Report Count (7) */ | ||
281 | 0x46, 0xFF, 0x00, /* Physical Maximum (255) */ | ||
282 | 0x26, 0xFF, 0x00, /* Logical Maximum (255) */ | ||
283 | 0x09, 0x02, /* Usage (0x02) */ | ||
284 | 0x91, 0x02, /* Output (Variable) */ | ||
285 | 0xC0, /* End Collection */ | ||
286 | 0xC0 /* End Collection */ | ||
287 | }; | ||
288 | |||
289 | static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 237 | static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
290 | unsigned int *rsize) | 238 | unsigned int *rsize) |
291 | { | 239 | { |
@@ -296,16 +244,34 @@ static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
296 | *rsize = sizeof(pid0011_rdesc_fixed); | 244 | *rsize = sizeof(pid0011_rdesc_fixed); |
297 | } | 245 | } |
298 | break; | 246 | break; |
299 | case 0x0006: | ||
300 | if (*rsize == sizeof(pid0006_rdesc_fixed)) { | ||
301 | rdesc = pid0006_rdesc_fixed; | ||
302 | *rsize = sizeof(pid0006_rdesc_fixed); | ||
303 | } | ||
304 | break; | ||
305 | } | 247 | } |
306 | return rdesc; | 248 | return rdesc; |
307 | } | 249 | } |
308 | 250 | ||
251 | #define map_abs(c) hid_map_usage(hi, usage, bit, max, EV_ABS, (c)) | ||
252 | #define map_rel(c) hid_map_usage(hi, usage, bit, max, EV_REL, (c)) | ||
253 | |||
254 | static int dr_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
255 | struct hid_field *field, struct hid_usage *usage, | ||
256 | unsigned long **bit, int *max) | ||
257 | { | ||
258 | switch (usage->hid) { | ||
259 | /* | ||
260 | * revert to the old hid-input behavior where axes | ||
261 | * can be randomly assigned when hid->usage is reused. | ||
262 | */ | ||
263 | case HID_GD_X: case HID_GD_Y: case HID_GD_Z: | ||
264 | case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ: | ||
265 | if (field->flags & HID_MAIN_ITEM_RELATIVE) | ||
266 | map_rel(usage->hid & 0xf); | ||
267 | else | ||
268 | map_abs(usage->hid & 0xf); | ||
269 | return 1; | ||
270 | } | ||
271 | |||
272 | return 0; | ||
273 | } | ||
274 | |||
309 | static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id) | 275 | static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id) |
310 | { | 276 | { |
311 | int ret; | 277 | int ret; |
@@ -352,6 +318,7 @@ static struct hid_driver dr_driver = { | |||
352 | .id_table = dr_devices, | 318 | .id_table = dr_devices, |
353 | .report_fixup = dr_report_fixup, | 319 | .report_fixup = dr_report_fixup, |
354 | .probe = dr_probe, | 320 | .probe = dr_probe, |
321 | .input_mapping = dr_input_mapping, | ||
355 | }; | 322 | }; |
356 | module_hid_driver(dr_driver); | 323 | module_hid_driver(dr_driver); |
357 | 324 | ||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index cd59c79eebdd..6cfb5cacc253 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -64,6 +64,9 @@ | |||
64 | #define USB_VENDOR_ID_AKAI 0x2011 | 64 | #define USB_VENDOR_ID_AKAI 0x2011 |
65 | #define USB_DEVICE_ID_AKAI_MPKMINI2 0x0715 | 65 | #define USB_DEVICE_ID_AKAI_MPKMINI2 0x0715 |
66 | 66 | ||
67 | #define USB_VENDOR_ID_AKAI_09E8 0x09E8 | ||
68 | #define USB_DEVICE_ID_AKAI_09E8_MIDIMIX 0x0031 | ||
69 | |||
67 | #define USB_VENDOR_ID_ALCOR 0x058f | 70 | #define USB_VENDOR_ID_ALCOR 0x058f |
68 | #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 | 71 | #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 |
69 | 72 | ||
diff --git a/drivers/hid/hid-led.c b/drivers/hid/hid-led.c index d8d55f37b4f5..d3e1ab162f7c 100644 --- a/drivers/hid/hid-led.c +++ b/drivers/hid/hid-led.c | |||
@@ -100,6 +100,7 @@ struct hidled_device { | |||
100 | const struct hidled_config *config; | 100 | const struct hidled_config *config; |
101 | struct hid_device *hdev; | 101 | struct hid_device *hdev; |
102 | struct hidled_rgb *rgb; | 102 | struct hidled_rgb *rgb; |
103 | u8 *buf; | ||
103 | struct mutex lock; | 104 | struct mutex lock; |
104 | }; | 105 | }; |
105 | 106 | ||
@@ -118,13 +119,19 @@ static int hidled_send(struct hidled_device *ldev, __u8 *buf) | |||
118 | 119 | ||
119 | mutex_lock(&ldev->lock); | 120 | mutex_lock(&ldev->lock); |
120 | 121 | ||
122 | /* | ||
123 | * buffer provided to hid_hw_raw_request must not be on the stack | ||
124 | * and must not be part of a data structure | ||
125 | */ | ||
126 | memcpy(ldev->buf, buf, ldev->config->report_size); | ||
127 | |||
121 | if (ldev->config->report_type == RAW_REQUEST) | 128 | if (ldev->config->report_type == RAW_REQUEST) |
122 | ret = hid_hw_raw_request(ldev->hdev, buf[0], buf, | 129 | ret = hid_hw_raw_request(ldev->hdev, buf[0], ldev->buf, |
123 | ldev->config->report_size, | 130 | ldev->config->report_size, |
124 | HID_FEATURE_REPORT, | 131 | HID_FEATURE_REPORT, |
125 | HID_REQ_SET_REPORT); | 132 | HID_REQ_SET_REPORT); |
126 | else if (ldev->config->report_type == OUTPUT_REPORT) | 133 | else if (ldev->config->report_type == OUTPUT_REPORT) |
127 | ret = hid_hw_output_report(ldev->hdev, buf, | 134 | ret = hid_hw_output_report(ldev->hdev, ldev->buf, |
128 | ldev->config->report_size); | 135 | ldev->config->report_size); |
129 | else | 136 | else |
130 | ret = -EINVAL; | 137 | ret = -EINVAL; |
@@ -147,17 +154,21 @@ static int hidled_recv(struct hidled_device *ldev, __u8 *buf) | |||
147 | 154 | ||
148 | mutex_lock(&ldev->lock); | 155 | mutex_lock(&ldev->lock); |
149 | 156 | ||
150 | ret = hid_hw_raw_request(ldev->hdev, buf[0], buf, | 157 | memcpy(ldev->buf, buf, ldev->config->report_size); |
158 | |||
159 | ret = hid_hw_raw_request(ldev->hdev, buf[0], ldev->buf, | ||
151 | ldev->config->report_size, | 160 | ldev->config->report_size, |
152 | HID_FEATURE_REPORT, | 161 | HID_FEATURE_REPORT, |
153 | HID_REQ_SET_REPORT); | 162 | HID_REQ_SET_REPORT); |
154 | if (ret < 0) | 163 | if (ret < 0) |
155 | goto err; | 164 | goto err; |
156 | 165 | ||
157 | ret = hid_hw_raw_request(ldev->hdev, buf[0], buf, | 166 | ret = hid_hw_raw_request(ldev->hdev, buf[0], ldev->buf, |
158 | ldev->config->report_size, | 167 | ldev->config->report_size, |
159 | HID_FEATURE_REPORT, | 168 | HID_FEATURE_REPORT, |
160 | HID_REQ_GET_REPORT); | 169 | HID_REQ_GET_REPORT); |
170 | |||
171 | memcpy(buf, ldev->buf, ldev->config->report_size); | ||
161 | err: | 172 | err: |
162 | mutex_unlock(&ldev->lock); | 173 | mutex_unlock(&ldev->lock); |
163 | 174 | ||
@@ -447,6 +458,10 @@ static int hidled_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
447 | if (!ldev) | 458 | if (!ldev) |
448 | return -ENOMEM; | 459 | return -ENOMEM; |
449 | 460 | ||
461 | ldev->buf = devm_kmalloc(&hdev->dev, MAX_REPORT_SIZE, GFP_KERNEL); | ||
462 | if (!ldev->buf) | ||
463 | return -ENOMEM; | ||
464 | |||
450 | ret = hid_parse(hdev); | 465 | ret = hid_parse(hdev); |
451 | if (ret) | 466 | if (ret) |
452 | return ret; | 467 | return ret; |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 0a0eca5da47d..354d49ea36dd 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -56,6 +56,7 @@ static const struct hid_blacklist { | |||
56 | 56 | ||
57 | { USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET }, | 57 | { USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET }, |
58 | { USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS }, | 58 | { USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS }, |
59 | { USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX, HID_QUIRK_NO_INIT_REPORTS }, | ||
59 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, | 60 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, |
60 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, | 61 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, |
61 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, | 62 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, |