From ccc68cbf7cb2fe1b92b490a08e8989ac3470c5cd Mon Sep 17 00:00:00 2001 From: Brady McDonough Date: Mon, 1 Feb 2016 21:20:45 -0700 Subject: [PATCH] Initial commit --- Makefile | 48 ++++++++++++++++++++++++++++++++++++ README.md | 30 ++++++++++++++++++++++ acer-hids.h | 7 ++++++ hid-acer-one.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 152 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100644 acer-hids.h create mode 100644 hid-acer-one.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1b85436 --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +# Comment/uncomment the following line to disable/enable debugging +# DEBUG = y +MODULE_NAME = hid-acer-one +KVER = $(shell uname -r) +MODDESTDIR = /lib/modules/$(KVER)/kernel/drivers/hid/ + +# Add your debugging flag (or not) to CFLAGS +ifeq ($(DEBUG),y) + DEBFLAGS = -O -g -DSHORT_DEBUG # "-O" is needed to expand inlines +else + DEBFLAGS = -O2 +endif + +ccflags-y += $(DEBFLAGS) + +ifneq ($(KERNELRELEASE),) +# call from kernel build system + +obj-m := hid-acer-one.o + +else + +KERNELDIR ?= /lib/modules/$(KVER)/build +PWD := $(shell pwd) + +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules + +endif + + +clean: + rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions + +depend .depend dep: + $(CC) $(CFLAGS) -M *.c > .depend + +install: + install -p -m 644 $(MODULE_NAME).ko $(MODDESTDIR) + /sbin/depmod -a ${KVER} + +uninstall: + rm -f $(MODDESTDIR)/$(MODULE_NAME).ko + /sbin/depmod -a ${KVER} + +ifeq (.depend,$(wildcard .depend)) +include .depend +endif diff --git a/README.md b/README.md new file mode 100644 index 0000000..2381684 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# Overview of the error +Some Acer keyboards report excessively large max usage values. This causes an error at boot which leaves the keyboard inoperable; since the max use values in the report descriptor exceed HID_MAX_USAGES the descriptor isn't parsed. + +This module simply changes the report descriptor to have more sensible max usage values during boot before passing the edited version up to the generic hid module for parsing. + +##### Known keyboards with this issue +* `06CB:73F4` (This is the only one targeted by this fix at present) +* `06CB:2968` +* `06CB:2991` + +This module specifically targets keyboards identifying themsleves as ` 06CB:73F4 `. If your device identifies itself as `06CB:2968` or `06CB:2991` they should work OOTB on Linux Kernels version 4.3 and above, for older kernels the fix (which this module was adapted from) can be found [here](https://github.com/SWW13/hid-acer). + +#### Symptoms of the error + +Symptoms that this might be a problem you are experiencing is a message along the lines of `hid (null): usage index exceeded` followed by hid-generic complaining that `parsing failed` in your dmesg logs. + +## Build / Install +First install linux-headers for your version of Linux, some details can be found [here](http://www.cyberciti.biz/tips/build-linux-kernel-module-against-installed-kernel-source-tree.html). + +``` +git clone https://github.com/BradyMcD/hid-acer-one.git +cd hid-acer-one +make +sudo make install +``` + +#### Uninstall +``` +sudo make uninstall +``` diff --git a/acer-hids.h b/acer-hids.h new file mode 100644 index 0000000..796589a --- /dev/null +++ b/acer-hids.h @@ -0,0 +1,7 @@ +#ifndef ACER_HIDS +#define ACER_HIDS + +#define USB_VENDOR_ID_ACER_SYNAPTICS 0x06cb +#define USB_VENDOR_ID_ACER_SYNAPTICS_TP_73F4 0x73F4 + +#endif//ACER_HIDS diff --git a/hid-acer-one.c b/hid-acer-one.c new file mode 100644 index 0000000..83b0015 --- /dev/null +++ b/hid-acer-one.c @@ -0,0 +1,67 @@ +/* + * HID driver for acer devices + * + * Copyright (c) 2016 Brady McDonough + * Modified from Simon Wörner's hid-acer + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include +#include +#include + +#include "acer-hids.h" + +/* Some Acer keyboards have an issue where they report an excessive max usages value + * The kyboard targeted in this fix identifies itself as 06CB:73F4 + * + * At boot this module pre-parses the report descriptor and changes the values so that they will parse properly + */ + +#define ACER_KBD_RDESC_ORIG_SIZE 188 +#define ACER_KBD_RDESC_CHECK_POS (173 * sizeof(__u8)) +#define ACER_KBD_RDESC_CHECK_DATA 0x2AFFFF150026FFFF +#define ACER_KBD_RDESC_FIX_POS1 ACER_KBD_RDESC_CHECK_POS + 2 +#define ACER_KBD_RDESC_FIX_POS2 ACER_KBD_RDESC_CHECK_POS + 7 + +static __u8 *acer_kbd_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize){ + + /* Check that we are looking at the same correct descirptor */ + if (*rsize == ACER_KBD_RDESC_ORIG_SIZE) { + __u64 check = be64_to_cpu(*(__be64 *)(rdesc + ACER_KBD_RDESC_CHECK_POS)); + + /* check for invalid max usages */ + if (check == ACER_KBD_RDESC_CHECK_DATA) { + hid_info(hdev, "fixing up acer keyboard report descriptor\n"); + + /* change max values to 0xFF00 */ + rdesc[ACER_KBD_RDESC_FIX_POS1] = 0x00; + rdesc[ACER_KBD_RDESC_FIX_POS2] = 0x00; + } + } + + return rdesc; +} + +static const struct hid_device_id acer_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ACER_SYNAPTICS, + USB_VENDOR_ID_ACER_SYNAPTICS_TP_73F4) }, + { } +}; +MODULE_DEVICE_TABLE(hid, acer_devices); + +static struct hid_driver acer_driver = { + .name = "acer", + .id_table = acer_devices, + .report_fixup = acer_kbd_report_fixup, +}; +module_hid_driver(acer_driver); + +MODULE_AUTHOR("Brady McDonough"); +MODULE_LICENSE("GPL");