Date: Tue, 20 Aug 2013 11:09:15 GMT From: Andrey Zholos <aaz@q-fu.com> To: freebsd-gnats-submit@FreeBSD.org Subject: usb/181425: USB keyboard with full N-key rollover not working Message-ID: <201308201109.r7KB9FB0055279@oldred.freebsd.org> Resent-Message-ID: <201308201110.r7KBA0UT014815@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201308201109.r7KB9FB0055279>