Whoops. Flip those last two bit decodes! -- Terry On Fri, Oct 7, 2011 at 4:01 PM, Terry Lambert <tlambert@xxxxxxxxxxxx> wrote: > > Thanks for replying, Dmitry... > > I guess I need to clarify a point or two. > > On Fri, Oct 7, 2011 at 3:07 PM, Dmitry Torokhov > <dmitry.torokhov@xxxxxxxxx> wrote: > > > > 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. > > My question is "who processes USB report packets from a USB keyboard > into EV_KEY events?" > > I understand that there's a separate evdev handler that publishes raw > events as /dev/input/eventX. It's handling the events from somewhere, > but it's not clear to me how a hidraw1 event turns into a console > input event. > > Somewhere someone is translating a USB 1.11 section 8.3 report into an > EV_KEY, and I need to do the modifier magic to alter the contents of > the reports before it gets to whoever that is. > You seem to be saying hid-input.c ... but I'm not seeing the modifier > bits being processed out of the report? > > > > 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. > > I fixed it there because it was accessible and a way to test the fix. > I'm also going to have to do something similar for coreboot/u-boot to > allow the keyboard to be used in the boot loader, so it's not wasted > effort, and it was an OK proof of concept. So there was a good > reason. > > I'm getting the impression from the above that the file I should be > looking in is: > > drivers/hid/hid-input.c > > Where are the modifier bits being decoded there? Maybe I'm just not > seeing something in front of me... > > The analyzer reports the USB over the wire report as: > > <-- left shift key down --> > 00 00 E1 00 00 00 00 00 <- transaction > 69 82 18 <- input packet > 48 00 00 E1 00 00 00 00 00 A8 45 <-- breakout : <-- > Keyboard LeftControl : 0b0 > Keyboard LeftShift : 0b0 <-- ***WRONG *** > Keyboard LeftAlt : 0b0 > Keyboard LeftGUI : 0b0 > Keyboard RightControl : 0b0 > Keyboard RightShiftl : 0b0 > Keyboard RightAlt : 0b0 > Keyboard RightGUI : 0b0 > Keyboard/Keypad Array : Keyboard LeftShift (225) <-- ***WRONG *** > Keyboard/Keypad Array : > Keyboard/Keypad Array : > Keyboard/Keypad Array : > Keyboard/Keypad Array : > Keyboard/Keypad Array : > --> > <-- 1 key down --> > 00 00 E1 1E 00 00 00 00 <- transaction > 69 82 18 <- input packet > C3 00 00 E1 1E 00 00 00 00 A8 45 <-- breakout : <-- > Keyboard LeftControl : 0b0 > Keyboard LeftShift : 0b0 <-- ***WRONG *** > Keyboard LeftAlt : 0b0 > Keyboard LeftGUI : 0b0 > Keyboard RightControl : 0b0 > Keyboard RightShiftl : 0b0 > Keyboard RightAlt : 0b0 > Keyboard RightGUI : 0b0 > Keyboard/Keypad Array : Keyboard LeftShift (d225) <-- *** WRONG *** > Keyboard/Keypad Array : Keyboard 1 and ! (d30) > Keyboard/Keypad Array : 00 > Keyboard/Keypad Array : 00 > Keyboard/Keypad Array : 00 > Keyboard/Keypad Array : 00 > --> > <-- 1 key up -- > > 00 00 E1 00 00 00 00 00 <- transaction > 69 82 18 <- input packet > 48 00 00 E1 00 00 00 00 00 A8 45 <-- breakout : <-- > Keyboard LeftControl : 0b0 > Keyboard LeftShift : 0b0 > Keyboard LeftAlt : 0b0 > Keyboard LeftGUI : 0b0 > Keyboard RightControl : 0b0 > Keyboard RightShiftl : 0b0 > Keyboard RightAlt : 0b0 > Keyboard RightGUI : 0b0 > Keyboard/Keypad Array : 00 > Keyboard/Keypad Array : 00 > Keyboard/Keypad Array : 00 > Keyboard/Keypad Array : 00 > Keyboard/Keypad Array : 00 > Keyboard/Keypad Array : 00 > --> > <-- left shift key up --> > 00 00 00 00 00 00 00 00 <- transaction > 69 82 18 <- input packet > 48 00 00 00 00 00 00 00 00 BF F4 <-- breakout : <-- > Keyboard LeftControl : 0b0 > Keyboard LeftShift : 0b0 <-- ***WRONG *** > Keyboard LeftAlt : 0b0 > Keyboard LeftGUI : 0b0 > Keyboard RightControl : 0b0 > Keyboard RightShiftl : 0b0 > Keyboard RightAlt : 0b0 > Keyboard RightGUI : 0b0 > Keyboard/Keypad Array : Keyboard LeftShift (225) <-- ***WRONG *** > Keyboard/Keypad Array : > Keyboard/Keypad Array : > Keyboard/Keypad Array : > Keyboard/Keypad Array : > Keyboard/Keypad Array : > --> > > I just need to know where in the code to stomp the report into > correctness. Should make a bunch of people happy. 8-) > > Thanks, > -- Terry > > > Thanks. > > > > -- > > Dmitry -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html