From owner-freebsd-usb@FreeBSD.ORG Tue Aug 20 11:10:00 2013 Return-Path: Delivered-To: freebsd-usb@smarthost.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 8D0EEFDA for ; Tue, 20 Aug 2013 11:10:00 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 6CA9825E7 for ; Tue, 20 Aug 2013 11:10:00 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.7/8.14.7) with ESMTP id r7KBA0Ci014816 for ; Tue, 20 Aug 2013 11:10:00 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.7/8.14.7/Submit) id r7KBA0UT014815; Tue, 20 Aug 2013 11:10:00 GMT (envelope-from gnats) Resent-Date: Tue, 20 Aug 2013 11:10:00 GMT Resent-Message-Id: <201308201110.r7KBA0UT014815@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-usb@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Andrey Zholos Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 21D0FE42 for ; Tue, 20 Aug 2013 11:09:16 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from oldred.freebsd.org (oldred.freebsd.org [8.8.178.121]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id F3D4025DE for ; Tue, 20 Aug 2013 11:09:15 +0000 (UTC) Received: from oldred.freebsd.org ([127.0.1.6]) by oldred.freebsd.org (8.14.5/8.14.7) with ESMTP id r7KB9FLs055347 for ; Tue, 20 Aug 2013 11:09:15 GMT (envelope-from nobody@oldred.freebsd.org) Received: (from nobody@localhost) by oldred.freebsd.org (8.14.5/8.14.5/Submit) id r7KB9FB0055279; Tue, 20 Aug 2013 11:09:15 GMT (envelope-from nobody) Message-Id: <201308201109.r7KB9FB0055279@oldred.freebsd.org> Date: Tue, 20 Aug 2013 11:09:15 GMT From: Andrey Zholos To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Subject: usb/181425: USB keyboard with full N-key rollover not working X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Aug 2013 11:10:00 -0000 >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: at usbus0 ukbd0: 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: 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: