usb-hid: echo typed characters to the log — a simple keyboard check

There was no way to confirm a keyboard actually registers keys on real
hardware (enumeration binding the driver only proves the device came
up). The keyboard driver now echoes each decoded printable character
(and newline) to its log: type a known phrase and read it back from
usb-hid-keyboard.log, or watch it appear live on screen in a -Ddiagnose
boot (where the kernel console is a log sink). It exercises the whole
path — HID report -> diff -> layout -> character — not just enumeration,
and works identically for a keyboard behind a hub.

A usb-key-echo QEMU case injects a phrase via QMP send-key and asserts
it echoes (stable across repeated runs). Full suite 92/92.
This commit is contained in:
Daniel Samson
2026-07-21 22:27:47 +01:00
parent e52ae242fc
commit 7ee6033fa4
2 changed files with 24 additions and 0 deletions
+9
View File
@@ -148,6 +148,15 @@ pub fn main(init: runtime.process.Init) void {
.character = character,
.modifiers = modifier_word,
});
// Echo the character to the log — a simple end-to-end
// keyboard check on real hardware: type a known phrase,
// then read it back from usb-hid-keyboard.log (or watch
// it appear live on screen in a -Ddiagnose boot, where
// the kernel console is a log sink). Printable ASCII and
// newline only; other keys are left to the input service.
if (character == '\n' or (character >= 0x20 and character < 0x7F)) {
_ = runtime.system.write(&[1]u8{@intCast(character)});
}
}
},
.released => {
+15
View File
@@ -461,6 +461,21 @@ CASES = [
# usb-kbd/usb-mouse ride the default boot xHCI bus (see qemu_args).
"expect": r"(?=[\s\S]*usb-hid-keyboard: ok)(?=[\s\S]*usb-hid-mouse: ok)",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# Keyboard echo: inject a known phrase via QMP send-key; the usb-hid-keyboard
# driver decodes it and echoes each character to the log (the simple
# real-hardware keyboard check — type a phrase, read it back off the stick,
# or watch it live on screen in a -Ddiagnose boot). Proves the whole path:
# HID report -> decode -> layout -> character.
{"name": "usb-key-echo",
"build_case": "usb-hid",
"smp": 4,
"timeout": 150,
"qmp_sequence": [
{"delay": 8, "command": "send-key", "arguments": {"keys": [{"type": "qcode", "data": c}]}}
for c in ["k", "e", "y", "t", "e", "s", "t"]
],
"expect": r"keytest",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# USB hub (B4a/B4b, docs/usb-hub.md): a USB2 hub on the xHCI bus with a
# keyboard behind it (a STATIC boot topology — no hot-plug event needed).
# B4a: the hub enumerates and powers its downstream ports. B4b extends the