diff mbox

[1/1] HID: microsoft, fix invalid rdesc for 3k kbd

Message ID 1350646126-28537-1-git-send-email-jslaby@suse.cz (mailing list archive)
State New, archived
Delegated to: Jiri Kosina
Headers show

Commit Message

Jiri Slaby Oct. 19, 2012, 11:28 a.m. UTC
Microsoft Digital Media Keyboard 3000 has two interfaces, and the
second one has a report descriptor with a bug. The second collection
says:
05 01 -- global; usage page -- 01 -- Generic Desktop Controls
09 80 -- local; usage -- 80 -- System Control
a1 01 -- main; collection -- 01 -- application

85 03 -- global; report ID -- 03
19 00 -- local; Usage Minimum -- 00
29 ff -- local; Usage Maximum -- ff
15 00 -- global; Logical Minimum -- 0
26 ff 00 -- global; Logical Maximum -- ff
81 00 -- main; input

c0 -- main; End Collection

I.e. it makes us think that there are all kinds of usages of system
control. That the keyboard is a not only a keyboard, but also a
joystick, mouse, gamepad, keypad, etc. The same as for the Wireless
Desktop Receiver, this should be Physical Min/Max. So fix that
appropriately.

References: https://bugzilla.novell.com/show_bug.cgi?id=776834
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/hid/hid-microsoft.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

Comments

Jiri Kosina Oct. 22, 2012, 9 a.m. UTC | #1
On Fri, 19 Oct 2012, Jiri Slaby wrote:

> Microsoft Digital Media Keyboard 3000 has two interfaces, and the
> second one has a report descriptor with a bug. The second collection
> says:
> 05 01 -- global; usage page -- 01 -- Generic Desktop Controls
> 09 80 -- local; usage -- 80 -- System Control
> a1 01 -- main; collection -- 01 -- application
> 
> 85 03 -- global; report ID -- 03
> 19 00 -- local; Usage Minimum -- 00
> 29 ff -- local; Usage Maximum -- ff
> 15 00 -- global; Logical Minimum -- 0
> 26 ff 00 -- global; Logical Maximum -- ff
> 81 00 -- main; input
> 
> c0 -- main; End Collection
> 
> I.e. it makes us think that there are all kinds of usages of system
> control. That the keyboard is a not only a keyboard, but also a
> joystick, mouse, gamepad, keypad, etc. The same as for the Wireless
> Desktop Receiver, this should be Physical Min/Max. So fix that
> appropriately.
> 
> References: https://bugzilla.novell.com/show_bug.cgi?id=776834
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>

Added CC to stable and applied, thanks.
Geert Uytterhoeven Nov. 4, 2012, 9:06 p.m. UTC | #2
On Fri, Oct 19, 2012 at 1:28 PM, Jiri Slaby <jslaby@suse.cz> wrote:
> +       if ((quirks & MS_RDESC_3K) && *rsize == 106 &&
> +                       !memcmp((char []){ 0x19, 0x00, 0x29, 0xff },
> +                               &rdesc[94], 4)) {

Which version of gcc are you using?

I'm getting (m68k-linux-gnu-gcc 4.1.2):

drivers/hid/hid-microsoft.c:51:18: error: macro "memcmp" passed 6
arguments, but takes just 3
drivers/hid/hid-microsoft.c: In function ‘ms_report_fixup’:
drivers/hid/hid-microsoft.c:50: error: ‘memcmp’ undeclared (first use
in this function)
drivers/hid/hid-microsoft.c:50: error: (Each undeclared identifier is
reported only once
/drivers/hid/hid-microsoft.c:50: error: for each function it appears in.)

Extracted into this test case:

---snip---
#include <string.h>

#define memcmp(a, b, c) memcmp((a), (b), (c))

int f(unsigned char *rdesc)
{
    return memcmp((char []){ 0x19, 0x00, 0x29, 0xff }, &rdesc[94], 4);
}
---snip---

it also fails with gcc-3.4/4.1/4.2/4.3/4.4 of Ubuntu 10.04 on amd64.

Interestingly, it doesn't fail if I remove the #define for memcmp. So it seems
to work if memcmp() is a real function, not a #define.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jiri Slaby Nov. 4, 2012, 10:37 p.m. UTC | #3
On 11/04/2012 10:06 PM, Geert Uytterhoeven wrote:
> On Fri, Oct 19, 2012 at 1:28 PM, Jiri Slaby <jslaby@suse.cz> wrote:
>> +       if ((quirks & MS_RDESC_3K) && *rsize == 106 &&
>> +                       !memcmp((char []){ 0x19, 0x00, 0x29, 0xff },
>> +                               &rdesc[94], 4)) {
> 
> Which version of gcc are you using?

4.7.1. But that indeed fails too if memcmp is a macro. This is of course
not the case for x86, so that I didn't hit that. I will post a patch to
change this to standard array accesses. (This looked prettier though.)

@Greg: please drop that patch from the stable queues for now.

thanks,
Geert Uytterhoeven Nov. 5, 2012, 8:05 a.m. UTC | #4
Hi Jiri,

On Sun, Nov 4, 2012 at 11:37 PM, Jiri Slaby <jslaby@suse.cz> wrote:
> On 11/04/2012 10:06 PM, Geert Uytterhoeven wrote:
>> On Fri, Oct 19, 2012 at 1:28 PM, Jiri Slaby <jslaby@suse.cz> wrote:
>>> +       if ((quirks & MS_RDESC_3K) && *rsize == 106 &&
>>> +                       !memcmp((char []){ 0x19, 0x00, 0x29, 0xff },
>>> +                               &rdesc[94], 4)) {
>>
>> Which version of gcc are you using?
>
> 4.7.1. But that indeed fails too if memcmp is a macro. This is of course
> not the case for x86, so that I didn't hit that. I will post a patch to
> change this to standard array accesses. (This looked prettier though.)

On x86/32 it's also a macro, but a different one, which doesn't process the
parameters:

arch/m68k/include/asm/string.h:#define memcmp(d, s, n) __builtin_memcmp(d, s, n)
arch/x86/include/asm/string_32.h:#define memcmp __builtin_memcmp

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Geert Uytterhoeven Nov. 11, 2012, 4:35 p.m. UTC | #5
On Sun, Nov 4, 2012 at 11:37 PM, Jiri Slaby <jslaby@suse.cz> wrote:
> On 11/04/2012 10:06 PM, Geert Uytterhoeven wrote:
>> On Fri, Oct 19, 2012 at 1:28 PM, Jiri Slaby <jslaby@suse.cz> wrote:
>>> +       if ((quirks & MS_RDESC_3K) && *rsize == 106 &&
>>> +                       !memcmp((char []){ 0x19, 0x00, 0x29, 0xff },
>>> +                               &rdesc[94], 4)) {
>>
>> Which version of gcc are you using?
>
> 4.7.1. But that indeed fails too if memcmp is a macro. This is of course
> not the case for x86, so that I didn't hit that. I will post a patch to
> change this to standard array accesses. (This looked prettier though.)

BTW, you also have to add

#include <linux/string.h>

as on some configs, I get

drivers/hid/hid-microsoft.c:50: error: ‘memcmp’ undeclared (first use
in this function)

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 3acdcfc..f676c01 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -28,22 +28,30 @@ 
 #define MS_RDESC		0x08
 #define MS_NOGET		0x10
 #define MS_DUPLICATE_USAGES	0x20
+#define MS_RDESC_3K		0x40
 
-/*
- * Microsoft Wireless Desktop Receiver (Model 1028) has
- * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
- */
 static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		unsigned int *rsize)
 {
 	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
 
+	/*
+	 * Microsoft Wireless Desktop Receiver (Model 1028) has
+	 * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
+	 */
 	if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 &&
 			rdesc[559] == 0x29) {
 		hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n");
 		rdesc[557] = 0x35;
 		rdesc[559] = 0x45;
 	}
+	/* the same as above (s/usage/physical/) */
+	if ((quirks & MS_RDESC_3K) && *rsize == 106 &&
+			!memcmp((char []){ 0x19, 0x00, 0x29, 0xff },
+				&rdesc[94], 4)) {
+		rdesc[94] = 0x35;
+		rdesc[96] = 0x45;
+	}
 	return rdesc;
 }
 
@@ -192,7 +200,7 @@  static const struct hid_device_id ms_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB),
 		.driver_data = MS_PRESENTER },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K),
-		.driver_data = MS_ERGONOMY },
+		.driver_data = MS_ERGONOMY | MS_RDESC_3K },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0),
 		.driver_data = MS_NOGET },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500),