Skip to content

Commit 8a1e377

Browse files
committed
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
2 parents b6ffb11 + 4973ca9 commit 8a1e377

File tree

4 files changed

+48
-62
lines changed

4 files changed

+48
-62
lines changed

drivers/hid/hid-dr.c

Lines changed: 25 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -234,58 +234,6 @@ static __u8 pid0011_rdesc_fixed[] = {
234234
0xC0 /* End Collection */
235235
};
236236

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-
289237
static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
290238
unsigned int *rsize)
291239
{
@@ -296,16 +244,34 @@ static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
296244
*rsize = sizeof(pid0011_rdesc_fixed);
297245
}
298246
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;
305247
}
306248
return rdesc;
307249
}
308250

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+
309275
static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
310276
{
311277
int ret;
@@ -352,6 +318,7 @@ static struct hid_driver dr_driver = {
352318
.id_table = dr_devices,
353319
.report_fixup = dr_report_fixup,
354320
.probe = dr_probe,
321+
.input_mapping = dr_input_mapping,
355322
};
356323
module_hid_driver(dr_driver);
357324

drivers/hid/hid-ids.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@
6464
#define USB_VENDOR_ID_AKAI 0x2011
6565
#define USB_DEVICE_ID_AKAI_MPKMINI2 0x0715
6666

67+
#define USB_VENDOR_ID_AKAI_09E8 0x09E8
68+
#define USB_DEVICE_ID_AKAI_09E8_MIDIMIX 0x0031
69+
6770
#define USB_VENDOR_ID_ALCOR 0x058f
6871
#define USB_DEVICE_ID_ALCOR_USBRS232 0x9720
6972

drivers/hid/hid-led.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ struct hidled_device {
100100
const struct hidled_config *config;
101101
struct hid_device *hdev;
102102
struct hidled_rgb *rgb;
103+
u8 *buf;
103104
struct mutex lock;
104105
};
105106

@@ -118,13 +119,19 @@ static int hidled_send(struct hidled_device *ldev, __u8 *buf)
118119

119120
mutex_lock(&ldev->lock);
120121

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+
121128
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,
123130
ldev->config->report_size,
124131
HID_FEATURE_REPORT,
125132
HID_REQ_SET_REPORT);
126133
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,
128135
ldev->config->report_size);
129136
else
130137
ret = -EINVAL;
@@ -147,17 +154,21 @@ static int hidled_recv(struct hidled_device *ldev, __u8 *buf)
147154

148155
mutex_lock(&ldev->lock);
149156

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,
151160
ldev->config->report_size,
152161
HID_FEATURE_REPORT,
153162
HID_REQ_SET_REPORT);
154163
if (ret < 0)
155164
goto err;
156165

157-
ret = hid_hw_raw_request(ldev->hdev, buf[0], buf,
166+
ret = hid_hw_raw_request(ldev->hdev, buf[0], ldev->buf,
158167
ldev->config->report_size,
159168
HID_FEATURE_REPORT,
160169
HID_REQ_GET_REPORT);
170+
171+
memcpy(buf, ldev->buf, ldev->config->report_size);
161172
err:
162173
mutex_unlock(&ldev->lock);
163174

@@ -447,6 +458,10 @@ static int hidled_probe(struct hid_device *hdev, const struct hid_device_id *id)
447458
if (!ldev)
448459
return -ENOMEM;
449460

461+
ldev->buf = devm_kmalloc(&hdev->dev, MAX_REPORT_SIZE, GFP_KERNEL);
462+
if (!ldev->buf)
463+
return -ENOMEM;
464+
450465
ret = hid_parse(hdev);
451466
if (ret)
452467
return ret;

drivers/hid/usbhid/hid-quirks.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ static const struct hid_blacklist {
5656

5757
{ USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET },
5858
{ 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 },
5960
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
6061
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
6162
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },

0 commit comments

Comments
 (0)