Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73e4008d authored by Nikolai Kondrashov's avatar Nikolai Kondrashov Committed by Jiri Kosina
Browse files

HID: allow resizing and replacing report descriptors



Update hid_driver's report_fixup prototype to allow changing report
descriptor size and/or returning completely different report descriptor.
Update existing usage accordingly.

This is to give more freedom in descriptor fixup and to allow having a whole
fixed descriptor in the code for the sake of readability.

Signed-off-by: default avatarNikolai Kondrashov <spbnick@gmail.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 3cfc2c42
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -246,17 +246,18 @@ static int apple_event(struct hid_device *hdev, struct hid_field *field,
/*
 * MacBook JIS keyboard has wrong logical maximum
 */
static void apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
		unsigned int rsize)
static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
		unsigned int *rsize)
{
	struct apple_sc *asc = hid_get_drvdata(hdev);

	if ((asc->quirks & APPLE_RDESC_JIS) && rsize >= 60 &&
	if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 &&
			rdesc[53] == 0x65 && rdesc[59] == 0x65) {
		dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report "
				"descriptor\n");
		rdesc[53] = rdesc[59] = 0xe7;
	}
	return rdesc;
}

static void apple_setup_input(struct input_dev *input)
+4 −3
Original line number Diff line number Diff line
@@ -26,15 +26,16 @@
 * Cherry Cymotion keyboard have an invalid HID report descriptor,
 * that needs fixing before we can parse it.
 */
static void ch_report_fixup(struct hid_device *hdev, __u8 *rdesc,
		unsigned int rsize)
static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc,
		unsigned int *rsize)
{
	if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
	if (*rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
		dev_info(&hdev->dev, "fixing up Cherry Cymotion report "
				"descriptor\n");
		rdesc[11] = rdesc[16] = 0xff;
		rdesc[12] = rdesc[17] = 0x03;
	}
	return rdesc;
}

#define ch_map_key_clear(c)	hid_map_usage_clear(hi, usage, bit, max, \
+1 −1
Original line number Diff line number Diff line
@@ -651,7 +651,7 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
	};

	if (device->driver->report_fixup)
		device->driver->report_fixup(device, start, size);
		start = device->driver->report_fixup(device, start, &size);

	device->rdesc = kmemdup(start, size, GFP_KERNEL);
	if (device->rdesc == NULL)
+5 −4
Original line number Diff line number Diff line
@@ -31,16 +31,16 @@
 * Some USB barcode readers from cypress have usage min and usage max in
 * the wrong order
 */
static void cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
		unsigned int rsize)
static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
		unsigned int *rsize)
{
	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
	unsigned int i;

	if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX))
		return;
		return rdesc;

	for (i = 0; i < rsize - 4; i++)
	for (i = 0; i < *rsize - 4; i++)
		if (rdesc[i] == 0x29 && rdesc[i + 2] == 0x19) {
			__u8 tmp;

@@ -50,6 +50,7 @@ static void cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
			rdesc[i + 3] = rdesc[i + 1];
			rdesc[i + 1] = tmp;
		}
	return rdesc;
}

static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+4 −3
Original line number Diff line number Diff line
@@ -20,14 +20,15 @@

#include "hid-ids.h"

static void elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
		unsigned int rsize)
static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
		unsigned int *rsize)
{
	if (rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
	if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
		dev_info(&hdev->dev, "Fixing up Elecom BM084 "
				"report descriptor.\n");
		rdesc[47] = 0x00;
	}
    return rdesc;
}

static const struct hid_device_id elecom_devices[] = {
Loading