Hello,
Since I have a Sharkoon Drakonia which by default doesn't work with Linux, I
did some research into making it work. A solution isn't hard to find, the usual
suggestion is to increase HID_MAX_USAGES to at least 32k, e.g. in
http://askubuntu.com/questions/232564/sharkoon-drakonia-gaming-mouse-doesnt-work-at-all
Searching for HID_MAX_USAGES turns up
http://www.spinics.net/lists/linux-input/msg09832.html and
http://www.spinics.net/lists/linux-input/msg22479.html, both of which ask about
increasing it in the mainline kernel (which would make all such devices work
without the need for a custom driver for each of them), but both didn't get any
reaction.
Is there any reason why HID_MAX_USAGES shouldn't be more than 12288? Digging
through the kernel history it started out as 256 in 2.3.36pre6, then was
quickly increased to 512 in 2.3.47pre4 and 1024 in 2.3.49pre2. Then it stayed
that way for ~7 years, until b55fd23ccdf32f969a7b4180c6e52d62d8e99972 changed
it to 8192 in 2007 and 5f1ab74f650b392ebcaa7cf3283e56d8dc6c7e56 to its current
value of 12288 in 2008. To me every change looks like "we found hardware that
needed a higher value, so we increased it". Now it seems to be "the hardware
surely reports a wrong value". Investigating if there is a limit for usages, I
only found http://www.usb.org/developers/devclass_docs/Hut1_12v2.pdf which says
on page 15 that "Usage ID values are limited to 16 bits".
But in case there is a reason why HID_MAX_USAGES should stay at 12288 that I
just didn't find, I've written a little driver for some of the mice that then
need their report descriptors adjusted.
The first patch adds a driver for USB ID 04d9:a067 (aka Sharkoon Drakonia or
Perixx MX-2000). The only thing it does is adjust the usage maximum and logical
maximum, like hid-holtek-kbd.c does. I'm not sure why that one also changes the
logical maximum, and the driver works without that here as well.
The second patch adds support for USB ID 04d9:a04a (aka Tracer Sniper TRM-503,
NOVA Gaming Slider X200 or Zalman ZM-GM1). I don't have that one, but found a
full report descriptor for it in
https://bugzilla.novell.com/show_bug.cgi?id=774676, compared it to mine, and
the only relevant difference seems to be that this report is nine bytes
shorter, and misses a portion before the usages maximum, so I adjusted all
offsets by -9.
There's also 04d9:a078
(http://forums.opensuse.org/english/get-technical-help-here/hardware/473200-usb-gaming-mouse-04d9-a078-not-working-linux-plus-workaround.html)
for which I didn't find a full report descriptor, but the relevant part seems
to have the same length as that of 04d9:a04a. I guess it wouldn't hurt to add
the a078 id to the a04a case, since either the values check out, then it works,
or they don't, then nothing happens. But that is even more speculative than the
second patch, so no third patch for that.
Best regards,
Christian Ohm
---
Christian Ohm (2):
HID: Add driver for Holtek gaming mouse 04d9:a067
HID: Add support for Holtek gaming mouse 04d9:a04a
drivers/hid/Kconfig | 3 ++
drivers/hid/Makefile | 1 +
drivers/hid/hid-holtek-mouse.c | 88 ++++++++++++++++++++++++++++++++++++++++
drivers/hid/hid-ids.h | 2 +
4 files changed, 94 insertions(+)
create mode 100644 drivers/hid/hid-holtek-mouse.c
--
1.7.10.4
This mouse is sold as Sharkoon Drakonia and Perixx MX-2000 and reports a
too high usage maximum and logical maximum. This driver fixes the report
descriptor so those values don't exceed HID_MAX_USAGES.
Signed-off-by: Christian Ohm <[email protected]>
---
drivers/hid/Kconfig | 1 +
drivers/hid/Makefile | 1 +
drivers/hid/hid-holtek-mouse.c | 72 ++++++++++++++++++++++++++++++++++++++++
drivers/hid/hid-ids.h | 1 +
4 files changed, 75 insertions(+)
create mode 100644 drivers/hid/hid-holtek-mouse.c
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index e7d6a13..d661a41 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -220,6 +220,7 @@ config HID_HOLTEK
Support for Holtek based devices:
- Holtek On Line Grip based game controller
- Trust GXT 18 Gaming Keyboard
+ - Sharkoon Drakonia / Perixx MX-2000 gaming mice
config HOLTEK_FF
bool "Holtek On Line Grip force feedback support"
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index b622157..c39bfc4 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_HID_ELECOM) += hid-elecom.o
obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o
+obj-$(CONFIG_HID_HOLTEK) += hid-holtek-mouse.o
obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o
obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o
obj-$(CONFIG_HID_ICADE) += hid-icade.o
diff --git a/drivers/hid/hid-holtek-mouse.c b/drivers/hid/hid-holtek-mouse.c
new file mode 100644
index 0000000..f32e29a
--- /dev/null
+++ b/drivers/hid/hid-holtek-mouse.c
@@ -0,0 +1,72 @@
+/*
+ * HID driver for Holtek gaming mice
+ * Copyright (c) 2013 Christian Ohm
+ * Heavily inspired by various other HID drivers that adjust the report
+ * descriptor.
+*/
+
+/*
+ * 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 <linux/hid.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include "hid-ids.h"
+
+/*
+ * The report descriptor of some Holtek based gaming mice specifies an
+ * excessively large number of consumer usages (2^15), which is more than
+ * HID_MAX_USAGES. This prevents proper parsing of the report descriptor.
+ *
+ * This driver fixes the report descriptor for USB ID 04d9:a067, sold as
+ * Sharkoon Drakonia and Perixx MX-2000.
+ */
+
+static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
+{
+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+
+ if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
+ /* Change usage maximum and logical maximum from 0x7fff to
+ * 0x2fff, so they don't exceed HID_MAX_USAGES */
+ if (*rsize >= 122 && rdesc[115] == 0xff && rdesc[116] == 0x7f
+ && rdesc[120] == 0xff && rdesc[121] == 0x7f) {
+ hid_info(hdev, "Fixing up report descriptor\n");
+ rdesc[116] = rdesc[121] = 0x2f;
+ }
+ }
+ return rdesc;
+}
+
+static const struct hid_device_id holtek_mouse_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
+ USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, holtek_mouse_devices);
+
+static struct hid_driver holtek_mouse_driver = {
+ .name = "holtek_mouse",
+ .id_table = holtek_mouse_devices,
+ .report_fixup = holtek_mouse_report_fixup,
+};
+
+static int __init holtek_mouse_init(void)
+{
+ return hid_register_driver(&holtek_mouse_driver);
+}
+
+static void __exit holtek_mouse_exit(void)
+{
+ hid_unregister_driver(&holtek_mouse_driver);
+}
+
+module_exit(holtek_mouse_exit);
+module_init(holtek_mouse_init);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 160a309..00f7ba9 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -435,6 +435,7 @@
#define USB_VENDOR_ID_HOLTEK_ALT 0x04d9
#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD 0xa055
+#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067 0xa067
#define USB_VENDOR_ID_IMATION 0x0718
#define USB_DEVICE_ID_DISC_STAKKA 0xd000
--
1.7.10.4
This mouse is sold as Tracer Sniper TRM-503, NOVA Gaming Slider X200 and
Zalman ZM-GM1, and reports too high usage maximum and logical maximum
(like 04d9:a067, but its report descriptor is different). This patch
adds its USB ID and fixes the report descriptor in the same way.
Note: I don't actually have such a mouse to test, I took the report
descriptor posted at https://bugzilla.novell.com/show_bug.cgi?id=774676,
compared it to the one from 04d9:a067 and changed the offsets
accordingly (all numbers minus 9, since it is 9 bytes shorter, and the
difference is before the values that need changing). That Surely Works™.
Signed-off-by: Christian Ohm <[email protected]>
---
drivers/hid/Kconfig | 2 ++
drivers/hid/hid-holtek-mouse.c | 28 ++++++++++++++++++++++------
drivers/hid/hid-ids.h | 1 +
3 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index d661a41..ec55049 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -221,6 +221,8 @@ config HID_HOLTEK
- Holtek On Line Grip based game controller
- Trust GXT 18 Gaming Keyboard
- Sharkoon Drakonia / Perixx MX-2000 gaming mice
+ - Tracer Sniper TRM-503 / NOVA Gaming Slider X200 /
+ Zalman ZM-GM1
config HOLTEK_FF
bool "Holtek On Line Grip force feedback support"
diff --git a/drivers/hid/hid-holtek-mouse.c b/drivers/hid/hid-holtek-mouse.c
index f32e29a..6a23ee6 100644
--- a/drivers/hid/hid-holtek-mouse.c
+++ b/drivers/hid/hid-holtek-mouse.c
@@ -23,8 +23,10 @@
* excessively large number of consumer usages (2^15), which is more than
* HID_MAX_USAGES. This prevents proper parsing of the report descriptor.
*
- * This driver fixes the report descriptor for USB ID 04d9:a067, sold as
- * Sharkoon Drakonia and Perixx MX-2000.
+ * This driver fixes the report descriptor for:
+ * - USB ID 04d9:a067, sold as Sharkoon Drakonia and Perixx MX-2000
+ * - USB ID 04d9:a04a, sold as Tracer Sniper TRM-503, NOVA Gaming Slider X200
+ * and Zalman ZM-GM1
*/
static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
@@ -35,11 +37,23 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
/* Change usage maximum and logical maximum from 0x7fff to
* 0x2fff, so they don't exceed HID_MAX_USAGES */
- if (*rsize >= 122 && rdesc[115] == 0xff && rdesc[116] == 0x7f
- && rdesc[120] == 0xff && rdesc[121] == 0x7f) {
- hid_info(hdev, "Fixing up report descriptor\n");
- rdesc[116] = rdesc[121] = 0x2f;
+ switch (hdev->product) {
+ case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067:
+ if (*rsize >= 122 && rdesc[115] == 0xff && rdesc[116] == 0x7f
+ && rdesc[120] == 0xff && rdesc[121] == 0x7f) {
+ hid_info(hdev, "Fixing up report descriptor\n");
+ rdesc[116] = rdesc[121] = 0x2f;
+ }
+ break;
+ case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A:
+ if (*rsize >= 113 && rdesc[106] == 0xff && rdesc[107] == 0x7f
+ && rdesc[111] == 0xff && rdesc[112] == 0x7f) {
+ hid_info(hdev, "Fixing up report descriptor\n");
+ rdesc[107] = rdesc[112] = 0x2f;
+ }
+ break;
}
+
}
return rdesc;
}
@@ -47,6 +61,8 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
static const struct hid_device_id holtek_mouse_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
+ USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) },
{ }
};
MODULE_DEVICE_TABLE(hid, holtek_mouse_devices);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 00f7ba9..fdde254 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -436,6 +436,7 @@
#define USB_VENDOR_ID_HOLTEK_ALT 0x04d9
#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD 0xa055
#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067 0xa067
+#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A 0xa04a
#define USB_VENDOR_ID_IMATION 0x0718
#define USB_DEVICE_ID_DISC_STAKKA 0xd000
--
1.7.10.4
On Tue, 21 May 2013, Christian Ohm wrote:
> Is there any reason why HID_MAX_USAGES shouldn't be more than 12288?
Well, the reasoning is a mixture of current implementation, and
reasonability.
- we currently have statically allocated arrays on a per-parser basis, for
parsing usages and collection indices. If the number of max usages is
going to grow in an uncontrolled manner, we'll have to change the way
our parser works (which is not impossible, of course).
- most of the ocurences of huge max usages being presented by the devices
have actually turned out to be bogus and could have been fixed by
patching the report descriptor in order to reflect the real behavior of
the device
Thanks,
--
Jiri Kosina
SUSE Labs
On Tue, 21 May 2013, Christian Ohm wrote:
> This mouse is sold as Sharkoon Drakonia and Perixx MX-2000 and reports a
> too high usage maximum and logical maximum. This driver fixes the report
> descriptor so those values don't exceed HID_MAX_USAGES.
>
> Signed-off-by: Christian Ohm <[email protected]>
> ---
> drivers/hid/Kconfig | 1 +
> drivers/hid/Makefile | 1 +
> drivers/hid/hid-holtek-mouse.c | 72 ++++++++++++++++++++++++++++++++++++++++
> drivers/hid/hid-ids.h | 1 +
> 4 files changed, 75 insertions(+)
> create mode 100644 drivers/hid/hid-holtek-mouse.c
You also need an entry in hid_have_special_driver[] for the devices in
order for the device <-> driver binding work properly.
I have applied your patches and fixed that omission.
--
Jiri Kosina
SUSE Labs
On Tue, May 21, 2013 at 2:31 AM, Christian Ohm <[email protected]> wrote:
> This mouse is sold as Sharkoon Drakonia and Perixx MX-2000 and reports a
> too high usage maximum and logical maximum. This driver fixes the report
> descriptor so those values don't exceed HID_MAX_USAGES.
Patch is already applied, but I think it worth to go through my
nitpicks as well.
> +++ b/drivers/hid/hid-holtek-mouse.c
> @@ -0,0 +1,72 @@
> +/*
> + * HID driver for Holtek gaming mice
> + * Copyright (c) 2013 Christian Ohm
> + * Heavily inspired by various other HID drivers that adjust the report
> + * descriptor.
> +*/
> +
> +/*
There is no need to break comments here.
> + * 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.
> + */
> +module_exit(holtek_mouse_exit);
> +module_init(holtek_mouse_init);
module_hid_driver() instead.
--
With Best Regards,
Andy Shevchenko
On Tuesday, 28 May 2013 at 12:20, Jiri Kosina wrote:
> I have applied your patches and fixed that omission.
I see the driver made it into Linus's tree. Thanks for applying, and the
fixes!
Best regards,
Christian Ohm