usb/181425: USB keyboard with full N-key rollover not working
Andrey Zholos
aaz at q-fu.com
Tue Aug 20 11:10:00 UTC 2013
>Number: 181425
>Category: usb
>Synopsis: USB keyboard with full N-key rollover not working
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-usb
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Tue Aug 20 11:10:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator: Andrey Zholos
>Release: FreeBSD 10.0-CURRENT #0 r254515
>Organization:
>Environment:
FreeBSD ukbd-test 10.0-CURRENT FreeBSD 10.0-CURRENT #0 r254515: Mon Aug 19 15:58:40 EEST 2013 root at ukbd-test:/usr/obj/usr/src/sys/GENERIC amd64
>Description:
The keyboard I am using is a Max Keyboard Nighthawk X9. It features
full N-key rollover, which is supposed to allow pressing all keys at
once, so it reports all keys as a bitmap, rather than the usual 6-byte
array of keycodes. This confuses the ukbd driver.
The relevant part of dmesg with hw.usb.ukbd.debug=1:
ugen0.4: <EST> at usbus0
ukbd0: <EST Gaming keyboard, class 0/0, rev 2.00/0.97, addr 3> on usbus0
ukbd_attach: Parsing HID descriptor of 65 bytes
ukbd_parse_hid: Found left control
ukbd_parse_hid: Found right control
ukbd_parse_hid: Found left shift
ukbd_parse_hid: Found right shift
ukbd_parse_hid: Found left alt
ukbd_parse_hid: Found right alt
ukbd_parse_hid: Found left GUI
ukbd_parse_hid: Found right GUI
ukbd_parse_hid: Found keyboard events
ukbd_parse_hid: Found keyboard numlock
ukbd_parse_hid: Found keyboard capslock
ukbd_parse_hid: Found keyboard scrolllock
ukbd_set_leds: leds=0x00
ukbd_set_leds: leds=0x00
kbd2 at ukbd0
ukbd_set_leds_callback: len=1, id=0
ukbd1: <EST Gaming keyboard, class 0/0, rev 2.00/0.97, addr 3> on usbus0
ukbd_intr_callback: actlen=8 bytes
ukbd_intr_callback: modifiers = 0x0000
ukbd_attach: Parsing HID descriptor of 37 bytes
ukbd_parse_hid: Found left control
ukbd_parse_hid: Found right control
ukbd_parse_hid: Found left shift
ukbd_parse_hid: Found right shift
ukbd_parse_hid: Found left alt
ukbd_parse_hid: Found right alt
ukbd_parse_hid: Found left GUI
ukbd_parse_hid: Found right GUI
ukbd_parse_hid: Found keyboard events
ukbd_set_leds: leds=0x00
ukbd_set_leds: leds=0x00
kbd3 at ukbd1
Most keys don't work and show this:
ukbd_intr_callback: actlen=15 bytes
ukbd_intr_callback: modifiers = 0x0000
ukbd_intr_callback: actlen=15 bytes
ukbd_intr_callback: modifiers = 0x0000
Modifier keys (e.g. Ctrl) appear to work:
ukbd_intr_callback: actlen=15 bytes
ukbd_intr_callback: modifiers = 0x0001
ukbd_put_key: 0xe0 (224) pressed
ukbd_intr_callback: actlen=15 bytes
ukbd_intr_callback: modifiers = 0x0000
ukbd_put_key: 0x4e0 (1248) released
Multimedia keys don't do anything at all.
Special profile keys (e.g. Fn+PF1) also appear to work:
ukbd_intr_callback: actlen=8 bytes
ukbd_intr_callback: modifiers = 0x0000
ukbd_intr_callback: [0] = 0xf1
ukbd_put_key: 0xf1 (241) pressed
ukbd_intr_callback: actlen=8 bytes
ukbd_intr_callback: modifiers = 0x0000
ukbd_put_key: 0x4f1 (1265) released
ukbd_intr_callback: actlen=8 bytes
ukbd_intr_callback: modifiers = 0x0000
There are three HID descriptors:
# uhidd -D /dev/ugen0.4
ugen0.4[0]-> Report descriptor dump:
USAGE PAGE Generic Desktop(0x1)
USAGE Keyboard(0x6)[Generic Desktop(0x1)]
COLLECTION Application(1)
USAGE PAGE Keyboard(0x7)
USAGE MINIMUM Keyboard LeftControl(224)
USAGE MAXIMUM Keyboard Right GUI(231)
LOGICAL MINIMUM 0
LOGICAL MAXIMUM 1
REPORT SIZE 1
REPORT COUNT 8
INPUT ( Data Variable Absolute ) (2)
REPORT SIZE 8
REPORT COUNT 1
INPUT ( Const Array Absolute ) (1)
USAGE PAGE Keyboard(0x7)
USAGE MINIMUM Reserved (no event indicated)(0)
USAGE MAXIMUM Unknown Usage(255)
LOGICAL MINIMUM 0
LOGICAL MAXIMUM 255
REPORT SIZE 8
REPORT COUNT 6
INPUT ( Data Array Absolute ) (0)
USAGE PAGE LEDs(0x8)
USAGE MINIMUM Num Lock(1)
USAGE MAXIMUM Scroll Lock(3)
LOGICAL MAXIMUM 1
REPORT SIZE 1
REPORT COUNT 3
OUTPUT ( Data Variable Absolute ) (2)
REPORT COUNT 5
OUTPUT ( Const Array Absolute ) (1)
END COLLECTION
ugen0.4[0]-> Kernel driver is active
ugen0.4[0]-> Abort attach since kernel driver is active
ugen0.4[0]-> Please try running uhidd with option '-u' to detach the kernel drivers
ugen0.4[1]-> Report descriptor dump:
USAGE PAGE Consumer(0xc)
USAGE Consumer Control(0x1)[Consumer(0xc)]
COLLECTION Application(1)
USAGE PAGE Consumer(0xc)
USAGE MINIMUM Unassigned(0)
USAGE MAXIMUM Unknown Usage(4095)
LOGICAL MINIMUM 0
LOGICAL MAXIMUM 4095
REPORT SIZE 16
REPORT COUNT 2
INPUT ( Data Array Absolute ) (0)
END COLLECTION
ugen0.4[1]-> Kernel driver is active
ugen0.4[1]-> Abort attach since kernel driver is active
ugen0.4[1]-> Please try running uhidd with option '-u' to detach the kernel drivers
ugen0.4[2]-> Report descriptor dump:
USAGE PAGE Generic Desktop(0x1)
USAGE Keyboard(0x6)[Generic Desktop(0x1)]
COLLECTION Application(1)
USAGE PAGE Keyboard(0x7)
USAGE MINIMUM Keyboard LeftControl(224)
USAGE MAXIMUM Keyboard Right GUI(231)
LOGICAL MINIMUM 0
LOGICAL MAXIMUM 1
REPORT SIZE 1
REPORT COUNT 8
INPUT ( Data Variable Absolute ) (2)
USAGE MINIMUM Reserved (no event indicated)(0)
USAGE MAXIMUM Keyboard F20(111)
LOGICAL MINIMUM 0
LOGICAL MAXIMUM 1
REPORT SIZE 1
REPORT COUNT 112
INPUT ( Data Variable Absolute ) (2)
END COLLECTION
ugen0.4[2]-> Kernel driver is active
ugen0.4[2]-> Abort attach since kernel driver is active
ugen0.4[2]-> Please try running uhidd with option '-u' to detach the kernel drivers
Note the 112-count bitmap in descriptor number 2. This is what is in
the 15-byte report used for most keys. There is a 6-byte array in
descriptor number 0, but that is only used to report the special
profile keys. Descriptor number 1 is used for multimedia keys.
>How-To-Repeat:
Plug in a Max Keyboard Nighthawk X9 keyboard. It works in BIOS and in
the FreeBSD boot loader menu, but stops working after boot.
>Fix:
The keyboard works fine in boot protocol. Running this
# usbconfig -d 0.4 add_quirk UQ_KBD_BOOTPROTO
and unplugging and plugging the keyboard back in fixes it, as does
adding the quirk for vendor 0x0665 product 0x6000 in usb_quirk.c.
However, I think it's better to detect this type of HID descriptor,
rather than to enumerate all the products that have it, so I propose
the attached patch.
Without UKBD_FLAG_EVENTS the keyboard gets forced into boot protocol in
ukbd_attach(). I have tested this and it works. Ordinary USB keyboard
should continue working in normal protocol as before, but I haven't
tested this.
I suspect this patch also obviates the need for the Corsair Vengeance
K60 keyboard quirk in usb_quirk.c, because that keyboard has 20-key
rollover and so probably the same sort of descriptor, but I don't have
one to test.
Ideally I would like to get this keyboard to work in normal protocol
with full rollover for perfectionist reasons, but I guess that would
require too many changes to ukbd.c and introduce overhead for the
majority of keyboards.
Patch attached with submission follows:
--- sys/dev/usb/input/ukbd.c (revision 254515)
+++ sys/dev/usb/input/ukbd.c (working copy)
@@ -1130,8 +1130,12 @@
HID_USAGE2(HUP_KEYBOARD, 0x00),
hid_input, 0, &sc->sc_loc_events, &flags,
&sc->sc_id_events)) {
- sc->sc_flags |= UKBD_FLAG_EVENTS;
- DPRINTFN(1, "Found keyboard events\n");
+ if (flags & HIO_VARIABLE)
+ DPRINTFN(1, "Ignoring key bitmap\n");
+ else {
+ sc->sc_flags |= UKBD_FLAG_EVENTS;
+ DPRINTFN(1, "Found keyboard events\n");
+ }
}
/* figure out leds on keyboard */
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-usb
mailing list