Hi,

I have a MS keyboard which is USB-only and has 3 interfaces:

1. Normal keyboard
2. Extra keys (there are many - volume controls, favourite buttons, application buttons, ...)
3. Fingerprint reader

I'm trying to get the 2nd interface going with Linux.

It's HID descriptor is:

    00000000: 05 0c 09 01 a1 01 85 01 05 0c 19 00 2a ff ff 95
    00000010: 01 75 10 15 00 27 ff ff 00 00 81 00 05 07 19 00
    00000020: 29 ff 75 08 26 ff 00 81 00 81 01 06 00 ff 0a 03
    00000030: fe 0a 04 fe 95 02 75 01 25 01 81 02 0a 05 ff 95
    00000040: 01 75 05 25 1f 81 02 75 09 81 01 0a 02 ff 26 ff
    00000050: 00 75 08 81 02 c0 05 01 09 80 a1 01 85 03 19 00
    00000060: 29 ff 15 00 26 ff 00 81 00 c0

The "lsusb -v" output is attached.

The current usbhid driver (2.6.15-rc5) tries to claim the device, but fails:

        drivers/usb/input/hid-core.c: HID probe called for ifnum 1
        drivers/usb/input/hid-core.c: usage index exceeded
        drivers/usb/input/hid-core.c: hid_add_usage failed
        drivers/usb/input/hid-core.c: item 0 2 2 2 parsing failed
        drivers/usb/input/hid-core.c: parsing report descriptor failed

I think this is because early on in the descriptor, it defines a range of 0-65535 (bigger than HID_MAX_USAGES):

            Item(Global): Usage Page, data= [ 0x0c ] 12
                            Consumer
            Item(Local ): Usage Minimum, data= [ 0x00 ] 0
                            Unassigned
            Item(Local ): Usage Maximum, data= [ 0xff 0xff ] 65535
                            (null)

In hid_parser_local() where it processes HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM the value of "data" is actually 851967. I haven't looked into this, but adding in a hack to set it as 0x29C (the last usage ID in consumer tables) gives some success:

Dec 15 23:51:53 dsd drivers/usb/input/hid-core.c: HID probe called for ifnum 1
Dec 15 23:51:53 dsd drivers/usb/input/hid-core.c: submitting ctrl urb: Get_Report wValue=0x0101 wIndex=0x0001 wLength=8Dec 15 23:51:53 dsd hid-debug: input ff00.fe03 = 1
Dec 15 23:51:53 dsd hid-debug: input ff00.fe04 = 0
Dec 15 23:51:53 dsd hid-debug: input ff00.ff05 = 0
Dec 15 23:51:53 dsd hid-debug: input ff00.ff02 = 0
Dec 15 23:51:53 dsd drivers/usb/input/hid-core.c: submitting ctrl urb: Get_Report wValue=0x0103 wIndex=0x0001 wLength=2
Dec 15 23:51:53 dsd INPUT(1)[INPUT]
Dec 15 23:51:53 dsd Field(0)
Dec 15 23:51:53 dsd Usage(256)
Dec 15 23:51:53 dsd Keyboard.0000
Dec 15 23:51:53 dsd Keyboard.0001
snip
Dec 15 23:51:53 dsd Keyboard.00fe
Dec 15 23:51:53 dsd Keyboard.00ff
Dec 15 23:51:53 dsd Logical Minimum(0)
Dec 15 23:51:53 dsd Logical Maximum(255)
Dec 15 23:51:53 dsd Report Size(8)
Dec 15 23:51:53 dsd Report Count(1)
Dec 15 23:51:53 dsd Report Offset(16)
Dec 15 23:51:53 dsd Flags( Array Absolute )
Dec 15 23:51:53 dsd Field(1)
Dec 15 23:51:53 dsd Usage(2)
Dec 15 23:51:53 dsd ff00.fe03
Dec 15 23:51:53 dsd ff00.fe04
Dec 15 23:51:53 dsd Logical Minimum(0)
Dec 15 23:51:53 dsd Logical Maximum(1)
Dec 15 23:51:53 dsd Report Size(1)
Dec 15 23:51:53 dsd Report Count(2)
Dec 15 23:51:53 dsd Report Offset(32)
Dec 15 23:51:53 dsd Flags( Variable Absolute )
Dec 15 23:51:53 dsd Field(2)
Dec 15 23:51:53 dsd Usage(1)
Dec 15 23:51:53 dsd ff00.ff05
Dec 15 23:51:53 dsd Logical Minimum(0)
Dec 15 23:51:53 dsd Logical Maximum(31)
Dec 15 23:51:53 dsd Report Size(5)
Dec 15 23:51:53 dsd Report Count(1)
Dec 15 23:51:53 dsd Report Offset(34)
Dec 15 23:51:53 dsd Flags( Variable Absolute )
Dec 15 23:51:53 dsd Field(3)
Dec 15 23:51:53 dsd Usage(1)
Dec 15 23:51:53 dsd ff00.ff02
Dec 15 23:51:53 dsd Logical Minimum(0)
Dec 15 23:51:53 dsd Logical Maximum(255)
Dec 15 23:51:53 dsd Report Size(8)
Dec 15 23:51:53 dsd Report Count(1)
Dec 15 23:51:53 dsd Report Offset(48)
Dec 15 23:51:53 dsd Flags( Variable Absolute )
Dec 15 23:51:53 dsd INPUT(3)[INPUT]
Dec 15 23:51:53 dsd Field(0)
Dec 15 23:51:53 dsd Usage(256)
Dec 15 23:51:53 dsd GenericDesktop.0000
Dec 15 23:51:53 dsd GenericDesktop.Pointer
Dec 15 23:51:53 dsd GenericDesktop.Mouse
Dec 15 23:51:53 dsd GenericDesktop.0003
Dec 15 23:51:53 dsd GenericDesktop.Joystick
Dec 15 23:51:53 dsd GenericDesktop.GamePad
Dec 15 23:51:53 dsd GenericDesktop.Keyboard
Dec 15 23:51:53 dsd GenericDesktop.Keypad
Dec 15 23:51:53 dsd GenericDesktop.MultiAxis
Dec 15 23:51:53 dsd GenericDesktop.0009
Dec 15 23:51:53 dsd GenericDesktop.000a
snip
Dec 15 23:51:53 dsd GenericDesktop.002f
Dec 15 23:51:53 dsd GenericDesktop.X
Dec 15 23:51:53 dsd GenericDesktop.Y
Dec 15 23:51:53 dsd GenericDesktop.Z
Dec 15 23:51:53 dsd GenericDesktop.Rx
Dec 15 23:51:53 dsd GenericDesktop.Ry
Dec 15 23:51:53 dsd GenericDesktop.Rz
Dec 15 23:51:53 dsd GenericDesktop.Slider
Dec 15 23:51:53 dsd GenericDesktop.Dial
Dec 15 23:51:53 dsd GenericDesktop.Wheel
Dec 15 23:51:53 dsd GenericDesktop.HatSwitch
Dec 15 23:51:53 dsd GenericDesktop.CountedBuffer
Dec 15 23:51:53 dsd GenericDesktop.ByteCount
Dec 15 23:51:53 dsd GenericDesktop.MotionWakeup
Dec 15 23:51:53 dsd GenericDesktop.Start
Dec 15 23:51:53 dsd GenericDesktop.Select
Dec 15 23:51:53 dsd GenericDesktop.003f
Dec 15 23:51:53 dsd GenericDesktop.Vx
Dec 15 23:51:53 dsd GenericDesktop.Vy
Dec 15 23:51:53 dsd GenericDesktop.Vz
Dec 15 23:51:53 dsd GenericDesktop.Vbrx
Dec 15 23:51:53 dsd GenericDesktop.Vbry
Dec 15 23:51:53 dsd GenericDesktop.Vbrz
Dec 15 23:51:53 dsd GenericDesktop.Vno
Dec 15 23:51:53 dsd GenericDesktop.0047
Dec 15 23:51:53 dsd GenericDesktop.0048
snip
Dec 15 23:51:53 dsd GenericDesktop.007e
Dec 15 23:51:53 dsd GenericDesktop.007f
Dec 15 23:51:53 dsd GenericDesktop.SystemControl
Dec 15 23:51:53 dsd GenericDesktop.SystemPowerDown
Dec 15 23:51:53 dsd GenericDesktop.SystemSleep
Dec 15 23:51:53 dsd GenericDesktop.SystemWakeUp
Dec 15 23:51:53 dsd GenericDesktop.SystemContextMenu
Dec 15 23:51:53 dsd GenericDesktop.SystemMainMenu
Dec 15 23:51:53 dsd GenericDesktop.SystemAppMenu
Dec 15 23:51:53 dsd GenericDesktop.SystemMenuHelp
Dec 15 23:51:53 dsd GenericDesktop.SystemMenuExit
Dec 15 23:51:53 dsd GenericDesktop.SystemMenuSelect
Dec 15 23:51:53 dsd GenericDesktop.SystemMenuRight
Dec 15 23:51:53 dsd GenericDesktop.SystemMenuLeft
Dec 15 23:51:53 dsd GenericDesktop.SystemMenuUp
Dec 15 23:51:53 dsd GenericDesktop.SystemMenuDown
Dec 15 23:51:53 dsd GenericDesktop.008e
Dec 15 23:51:53 dsd GenericDesktop.008f
Dec 15 23:51:53 dsd GenericDesktop.D-PadUp
Dec 15 23:51:53 dsd GenericDesktop.D-PadDown
Dec 15 23:51:53 dsd GenericDesktop.D-PadRight
Dec 15 23:51:53 dsd GenericDesktop.D-PadLeft
Dec 15 23:51:53 dsd GenericDesktop.0094
Dec 15 23:51:53 dsd GenericDesktop.0095
snip
Dec 15 23:51:53 dsd GenericDesktop.00fe
Dec 15 23:51:53 dsd GenericDesktop.00ff
Dec 15 23:51:53 dsd Logical Minimum(0)
Dec 15 23:51:53 dsd Logical Maximum(255)
Dec 15 23:51:53 dsd Report Size(8)
Dec 15 23:51:53 dsd Report Count(1)
Dec 15 23:51:53 dsd Report Offset(0)
Dec 15 23:51:53 dsd Flags( Array Absolute )
Dec 15 23:51:53 dsd input: Microsoft Microsoft\uffff Keyboard with Fingerprint Reader as /class/input/input9 Dec 15 23:51:53 dsd input: USB HID v1.11 Device [Microsoft Microsoft\uffff Keyboard with Fingerprint Reader] on usb-0000:00:02.0-3
Dec 15 23:51:53 dsd usbcore: registered new driver usbhid
Dec 15 23:51:53 dsd drivers/usb/input/hid-core.c: v2.6:USB HID core driver

At this point, pressing any of the keys produces some output in the logs, but doesn't seem to affect the X server input. Except for the sleep key, which seems to be picked up correctly:

<press>
Dec 15 23:55:56 dsd hid-debug: input GenericDesktop.0000 = 0
Dec 15 23:55:56 dsd hid-debug: input GenericDesktop.SystemSleep = 1
<release>
Dec 15 23:55:59 dsd hid-debug: input GenericDesktop.SystemSleep = 0
Dec 15 23:55:59 dsd hid-debug: input GenericDesktop.0000 = 1

It also gets passed to xev (yay!).


Now I press the MUTE key: (I also defined DEBUG_DATA here)

<press>
Dec 15 23:58:25 dsd drivers/usb/input/hid-core.c: report (size 8) (numbered)
Dec 15 23:58:25 dsd drivers/usb/input/hid-core.c: report 1 (size 7) = e2 00 00 00 01 00 00
Dec 15 23:58:25 dsd hid-debug: input ff00.fe03 = 1
Dec 15 23:58:25 dsd hid-debug: input ff00.fe04 = 0
Dec 15 23:58:25 dsd hid-debug: input ff00.ff05 = 0
Dec 15 23:58:25 dsd hid-debug: input ff00.ff02 = 0
<release>
Dec 15 23:58:31 dsd drivers/usb/input/hid-core.c: report (size 8) (numbered)
Dec 15 23:58:31 dsd drivers/usb/input/hid-core.c: report 1 (size 7) = 00 00 00 00 01 00 00
Dec 15 23:58:31 dsd hid-debug: input ff00.fe03 = 1
Dec 15 23:58:31 dsd hid-debug: input ff00.fe04 = 0
Dec 15 23:58:31 dsd hid-debug: input ff00.ff05 = 0
Dec 15 23:58:31 dsd hid-debug: input ff00.ff02 = 0

xev doesn't pick up anything.



So, I seem to be making some progress, but I'm not sure I'm taking the right approach. My interpretation is that the device has an invalid or strange HID descriptor (but this is my first adventure into HID-land).

Should I continue like this, making some kind of HID quirk for this device?

Or should I write a separate driver? The windows driver uses HID BP, and it shouldn't be too hard just to write a separate driver here, there are only 22 keys to take care of... On the other hand, the logic for interpreting which keys are pressed and which aren't looks like it is already present in the usbhid driver...

Any input appreciated.

Daniel


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to