Re: Busted keyboard, fix, and Question about default HID device plumbing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Terry,

On Fri, Oct 07, 2011 at 01:44:29PM -0700, Terry Lambert wrote:
> I have a USB keyboard that needs a workaround.  I know what the
> workaround is, but not where to plumb it in.
> 
> This is apparently an issue with a number of keyboards from a number
> of vendors, and Mac OS X and Windows both work around it.  It impacts
> all Linux desktops, Android, and Chrome OS for a number of popular
> folding keyboards, as well as other keyboards.
> 
> I'm perfectly able to write the workaround, and have done so using the
> boot protocol, but now I want to fix the issue in the default stack
> used for the console.
> 
> I don't care about the UHCI/EHCI plumbing, or anything up to hiddev;
> but from there it gets murky as to how an event in the raw driver ends
> up getting turned into a keyboard key.  It appears to be lost in
> callbacks I'm having a hard time tracing through.
> 
> I've read three books on the Linux USB system, two of them very out of
> date, and they're all written from the perspective of "So, you want to
> write a device driver", rather than the perspective of "This book
> documents the plumbing between the driver and userspace and how to
> figure it out".
> 
> So the question is: how are things plumbed between hiddev and the
> console driver,


They aren't. Or maybe we are talking about different "hiddev"s. The
generic HID driver binds devices to hid-input which registers them with
input core as separate input devices. The legacy console registers a
separate input handler (see drivers/tty/vt/keyboard.c) that binds to all
keyboard-like devices, listens to input events and converts them to
keystrokes and sends them to tty.

There is also a evdev input handler (that's where evtest utility gets
its data from) that provides input event data to userspace via
/dev/input/eventX nodes where X picks it does its own thing with it.

> so I can figure out where I need to hack on the
> events.
> 
> I just need to know the correct place/method to interpose the events.
> 
> Any help would be appreciated.
> 
> Thanks,
> -- Terry
> 
> PS: For the curious:
> 
> I put a USB protocol analyzer on this thing, and discovered the problem.
> 
> The issue is that modifier keys are not reported in the bitmap on the
> keyboard, and are instead signaled as in-band key events themselves.
> The Mac OS X and Windows drivers work around the issue by
> pre-processing the event stream looking for in-band modifier keys, and
> then converting them into bit-sets in the (0'ed) bitmap of modifier
> keys, and then dropping them from the key event stream.  Without the
> workaround, the report order is such that it looks like a modifier up
> report followed by a keystroke.  Here's evtest output for the sequence
> after processing by the (unknown to me -- that's what I'm trying to
> find out) code:
> 
> Event: time 1318019769.922534, type 4 (Misc), code 4 (ScanCode), value 700e1
> Event: time 1318019769.922550, type 1 (Key), code 42 (LeftShift), value 1
> Event: time 1318019769.922554, -------------- Report Sync ------------
> Event: time 1318019770.082521, type 4 (Misc), code 4 (ScanCode), value
> 700e1 XXXX
> Event: time 1318019770.082534, type 1 (Key), code 42 (LeftShift),
> value 0          XXXX

Hmm, so the shift is reported as released before we get the next key...
Wierd...

> Event: time 1318019770.082549, type 4 (Misc), code 4 (ScanCode), value 7001e
> Event: time 1318019770.082553, type 1 (Key), code 2 (1), value 1
> Event: time 1318019770.082555, -------------- Report Sync ------------
> 1Event: time 1318019770.242541, type 4 (Misc), code 4 (ScanCode), value 7001e
> Event: time 1318019770.242552, type 1 (Key), code 2 (1), value 0
> Event: time 1318019770.242555, -------------- Report Sync ------------
> 
> This is a shift-1.
> 
> The patch for usbkbd.c looks like this:
> 
> diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c
> index 0658173..d22ecdb 100644
> --- a/drivers/hid/usbhid/usbkbd.c
> +++ b/drivers/hid/usbhid/usbkbd.c
> @@ -2,6 +2,10 @@
>   *  Copyright (c) 1999-2001 Vojtech Pavlik
>   *
>   *  USB HIDBP Keyboard support
> + *
> + * Device Class Definition for Human Interface Devices (HID) Version 1.11
> + * Section 8.3 describes the report formant.
> + * http://www.usb.org/developers/devclass_docs/HID1_11.pdf
>   */
> 
>  /*
> @@ -97,6 +101,16 @@ static void usb_kbd_irq(struct urb *urb)
>                 goto resubmit;
>         }
> 
> +       /* Convert in-band modifier keys to modifier bits */
> +       for (i = 2; i < 8; i++) {
> +               if (kbd->new[i] >= 0xE0 && kbd->new[i] <= 0xE7) {
> +                       kbd->new[0] |= (1 >> (kbd->new[i] - 0xE0));
> +                       kbd->new[i] = 0;
> +               }
> +       }

Wait, why are you using usbkbd? Unless you have very compelling reason
you should be using hid & hid-input.

Thanks.

-- 
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux