Bug 37982

Summary: Microsoft Wired Keyboard 600 create a spurious joystick device.
Product: Drivers Reporter: Michel Hermier (michel.hermier)
Component: Input DevicesAssignee: drivers_input-devices
Status: RESOLVED OBSOLETE    
Severity: normal CC: alan, alexanderemmanuelpacheco, benjamin.tissoires, denilsonsa, dmitry.torokhov, ghallberg, leslie_alistair, michel.hermier, victor.quicksilver
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 2.6.39+ 3.10.x 4.x Subsystem:
Regression: No Bisected commit-id:
Attachments: rdesc output of the first entry
rdesc output of the second entry
rdesc output of the second entry
First attempt to patch the issue and uniformise fixes.
Patch V2, add Microsoft Digital Media 3KV1 workaround.
Proposed upstream patch

Description Michel Hermier 2011-06-20 18:59:05 UTC
Hi,
This devices produce a broken joystick extra device which puzzled me for a while.
This device has 2 HID interfaces like a lot of keyboards (One for the regular device, and one for the extra buttons).
Looking at the HID report description (following) it seems that the parsing of the second descriptor is at fault producing a full featured event device that support every thing (which is annoying since it produce a spurious broken joystick device).
Comment 1 Michel Hermier 2011-06-20 19:00:16 UTC
Created attachment 62952 [details]
rdesc output of the first entry
Comment 2 Michel Hermier 2011-06-20 19:00:51 UTC
Created attachment 62962 [details]
rdesc output of the second entry
Comment 3 Michel Hermier 2011-06-20 19:05:21 UTC
Comment on attachment 62962 [details]
rdesc output of the second entry

Oups this got altered while I trying to understand how hid worked
Comment 4 Michel Hermier 2011-06-20 19:05:55 UTC
Created attachment 62972 [details]
rdesc output of the second entry
Comment 5 Víctor Enríquez 2013-02-23 12:48:03 UTC
This is still happening with Kernel 3.7.8 and udev-197 in a Gentoo Linux. If you have access to joystick tools you can calibrate this /dev/input/js0 with jscal -c /dev/input/js0, and at least it won't interfere with the programs, also plug first your gamepad so /dev/input/js0 get's assigned to it first.

It's a very annoying bug if you want to use wine or other programs.

Any ideas on how to fix it?.
Comment 7 Víctor Enríquez 2013-02-23 13:16:44 UTC
lsusb -v:

Bus 002 Device 005: ID 045e:0750 Microsoft Corp. Wired Keyboard 600
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x045e Microsoft Corp.
  idProduct          0x0750 Wired Keyboard 600
  bcdDevice            1.10
  iManufacturer           1 Microsoft
  iProduct                2 Wired Keyboard 600
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           59
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      65
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval              10
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength     106
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval              10
Device Status:     0x0000
  (Bus Powered)
Comment 8 Michel Hermier 2013-02-23 19:03:44 UTC
Seems to be a problem in the hid parser, that default some inputs to a joystick if it miss interpret some of the values (for some good or wrong reasons). But last time I check was when I created the bug report.
Comment 9 Alan 2013-12-23 13:56:54 UTC
If this is still present in modern kernels please update the bug
Comment 10 Michel Hermier 2013-12-24 11:53:55 UTC
Still valid as of kernel-3.10
Comment 11 ghallberg 2015-01-24 22:13:33 UTC
Seems to still be valid as of 3.18.2
Comment 12 ghallberg 2015-03-24 18:54:40 UTC
And still in 3.19.2
Comment 14 Dmitry Torokhov 2015-05-15 21:09:53 UTC
Can I get output of /proc/bus/input/devices for that mouse please?
Comment 15 Michel Hermier 2015-05-16 07:33:26 UTC
For my keybord it exposes the following (kernel 3.14.x but I guess it 
doesn't mater):

I: Bus=0003 Vendor=045e Product=0750 Version=0111
N: Name="Microsoft Wired Keyboard 600"
P: Phys=usb-0000:00:1d.0-1.6/input0
S: 
Sysfs=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.6/2-1.6:1.0/0003:045E:0750.0003/input/input20
U: Uniq=
H: Handlers=kbd event17
B: PROP=0
B: EV=120013
B: KEY=1000000000007 ff9f207ac14057ff febeffdfffefffff fffffffffffffffe
B: MSC=10
B: LED=7

I: Bus=0003 Vendor=045e Product=0750 Version=0111
N: Name="Microsoft Wired Keyboard 600"
P: Phys=usb-0000:00:1d.0-1.6/input1
S: 
Sysfs=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.6/2-1.6:1.1/0003:045E:0750.0004/input/input21
U: Uniq=
H: Handlers=kbd event18 js0
B: PROP=0
B: EV=10001f
B: KEY=4c37fff072ff32d bf54445600000000 c00000000000001 30f908b17c007 
ffff7bfad951dfff febeffdfffefffff fffffffffffffffe
B: REL=40
B: ABS=ffffff01000701ff
B: MSC=10

 From my understanding it was due to a default behaviour of the 
descriptor parser. It is falling back to a dummy joystik input in case 
of error, and the keyboard device descriptor has a constructor private 
interface, for the multimedia keys, that was wrongly parsed leading to 
the creation of the dummy joystick device.
Comment 16 ghallberg 2015-09-22 17:55:04 UTC
Has there been any progress on this Dmitry?
Comment 17 Alistair Leslie-Hughes 2016-06-29 05:20:12 UTC
This issue still occurs on 4.6 series.

Any advise on where to starting look to fix this issue?
Comment 18 Michel Hermier 2016-06-29 06:22:00 UTC
I think there was an udev rule that banned the device creation on some 
distribution for these kind of devices. So it maybe be the wiser 
temporary solution, without touching the kernel code.
Comment 19 Alistair Leslie-Hughes 2016-06-29 06:37:40 UTC
Yes, there is udev rules.

Since I have one of the keyboards that causes the issue.  I thought I might have a go at fixing it but would like some advise on a good place to start.
Comment 20 Michel Hermier 2016-06-29 07:44:01 UTC
Ahh, ok I thought you meant a quick fix.
I looked at the code again, and I don't seems to find the place I was 
thinking was causing the issue.
 From my memory, the place I had find was a bug in the hid descriptor 
parser, that was miss interpreting some vendor private range field, 
making the device mutate to a joystick. So if I remember well, it was in 
interaction between drivers/hid/hid-{core,input}.c and 
drivers/input/input.c.
Comment 21 Michel Hermier 2016-07-03 07:14:49 UTC
Created attachment 221851 [details]
First attempt to patch the issue and uniformise fixes.

The attached patch tries to uniformise the patching of microsoft keyboard.
I add Microsoft media 600 (that I own) and 7k (that Alistair Leslie-Hughes owns) that were tested with the patch.
The only small deviation I made from original code is that Microsoft Wireless Receiver Model 1028 check is now stronger (I was not able to test it or find a copy of the report descriptor to ensure it is correct)
Comment 22 Michel Hermier 2016-07-07 09:16:16 UTC
Created attachment 222351 [details]
Patch V2, add Microsoft Digital Media 3KV1 workaround.
Comment 23 Benjamin Tissoires 2016-09-14 15:46:12 UTC
Created attachment 233381 [details]
Proposed upstream patch

This is the patch I sent upstream which should solve all Microsoft devices.

Reference: https://patchwork.kernel.org/patch/9328671/
Comment 24 Michel Hermier 2016-09-14 17:06:22 UTC
I took the time to update my kernel with the patch, and so far everything is good. I successfully tried various multimedia keys (using hid-microsoft since my keybord was not work-arounded). And /dev/input/js0 is gone.

So the new patch seems good for me and should be good for almost all Microsoft Digital Media Keyboard series (since they seems to share the same report descriptors).

Will see with a bit longer testing but ok for me.
Comment 25 Michel Hermier 2018-06-24 19:51:56 UTC
Fixed a while ago. Forgot it was still open.