evdevd: log HID quirk flags at device registration (Gap 10)
R1-R10 audit Gap 10: evdevd had zero HID quirk consumption. The lookup_hid_quirks entry point in redox-driver-sys was populated by R10 with 191 compiled-in entries + TOML support, but no consumer read it. Every InputDevice entering the evdev scheme flew past the HID quirk table. This change: - Adds a redox-driver-sys path dependency to source/Cargo.toml. Path mirrors the depth used by pcid/usbhidd (4 ../ levels to reach local/, then recipes/drivers/redox-driver-sys/source). - Adds source/src/quirks.rs with one public function, log_hid_quirks(vendor, product, kind), that calls lookup_hid_quirks and emits an info-level line on a non-empty result, debug-level on empty. - Wires the call into EvdevScheme::add_device() at the moment the InputDevice is created, before it is pushed onto the device list. - Adds 'mod quirks' to main.rs module declarations. Caveat (carried forward from the audit, 2026-06-07): evdevd currently constructs InputDevice with vendor=0 because the upstream usbhidd produces orbclient::Event streams without forwarding the real USB vendor/product IDs. The lookup therefore returns empty flags in practice. Once the orbclient event pipe is extended to carry the device IDs, the wiring below will start logging the matched flag sets without any further code change. This is documented in the module-level docstring of quirks.rs. 4 unit tests cover the wiring: - synthetic zero-vendor returns empty - synthetic product IDs 0..32 return empty (these are the IDs evdevd currently assigns) - a real Linux HID table entry (0x06d6:0x0025 → BADPAD) returns the expected flag - the log helper does not panic on any input Note on pre-existing test errors: cargo test fails to compile the test binary because of unrelated errors in src/translate.rs:517,534 and src/gesture.rs:1 (a 'translate_gesture' function that no longer exists). These pre-date this change and are out of scope for Gap 10. cargo check is clean (zero new warnings from this change); the failing tests are in the existing scheme.rs and device.rs test modules that have nothing to do with the new quirks module.
This commit is contained in:
@@ -9,6 +9,7 @@ syscall = { package = "redox_syscall", version = "0.4" }
|
|||||||
log = { version = "0.4", features = ["std"] }
|
log = { version = "0.4", features = ["std"] }
|
||||||
thiserror = "2"
|
thiserror = "2"
|
||||||
orbclient = { version = "=0.3.47", default-features = false }
|
orbclient = { version = "=0.3.47", default-features = false }
|
||||||
|
redox-driver-sys = { path = "../../../../recipes/drivers/redox-driver-sys/source" }
|
||||||
|
|
||||||
[target.'cfg(target_os = "redox")'.dependencies]
|
[target.'cfg(target_os = "redox")'.dependencies]
|
||||||
redox_event = "0.4"
|
redox_event = "0.4"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
mod device;
|
mod device;
|
||||||
mod gesture;
|
mod gesture;
|
||||||
mod key_filter;
|
mod key_filter;
|
||||||
|
mod quirks;
|
||||||
mod scheme;
|
mod scheme;
|
||||||
mod translate;
|
mod translate;
|
||||||
mod types;
|
mod types;
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
//! R1–R10 audit Gap 10: HID quirk flag reporting at evdevd device registration.
|
||||||
|
//!
|
||||||
|
//! HID quirks are observability-only in this tree (the same
|
||||||
|
//! situation as Blocker 3 in `usbhidd`). The lookup is purely
|
||||||
|
//! informational: `lookup_hid_quirks` returns a `HidQuirkFlags`
|
||||||
|
//! bitflags struct built from the compiled-in Linux 7.1
|
||||||
|
//! `hid_quirks[]` table + the runtime `quirks.d/*.toml` files,
|
||||||
|
//! and the call site is responsible for logging the result.
|
||||||
|
//!
|
||||||
|
//! Caveat (carried forward from the R1–R10 audit, 2026-06-07):
|
||||||
|
//! evdevd currently constructs `InputDevice` with `vendor: 0` and
|
||||||
|
//! a synthetic `product` value, because the upstream `usbhidd`
|
||||||
|
//! produces `orbclient::Event`s without forwarding the real USB
|
||||||
|
//! vendor / product IDs. The lookup therefore returns empty
|
||||||
|
//! flags in practice. Once the orbclient event pipe is extended
|
||||||
|
//! to carry the device IDs, the wiring below will start logging
|
||||||
|
//! the matched flag sets without any further code change.
|
||||||
|
//!
|
||||||
|
//! Section markers:
|
||||||
|
//! - R10 unblock: HID device flags become visible at the
|
||||||
|
//! evdev registration boundary.
|
||||||
|
|
||||||
|
use redox_driver_sys::quirks::lookup_hid_quirks;
|
||||||
|
|
||||||
|
/// Log the HID quirk flags for the given device, if any. Runs
|
||||||
|
/// at the moment an `InputDevice` enters the scheme in
|
||||||
|
/// `EvdevScheme::add_device()`.
|
||||||
|
pub(crate) fn log_hid_quirks(vendor: u16, product: u16, kind: &str) {
|
||||||
|
let flags = lookup_hid_quirks(vendor, product);
|
||||||
|
if !flags.is_empty() {
|
||||||
|
log::info!(
|
||||||
|
"HID quirks for {} ({:04X}:{:04X}) flags=0x{:016X} bits={:?}",
|
||||||
|
kind,
|
||||||
|
vendor,
|
||||||
|
product,
|
||||||
|
flags.bits(),
|
||||||
|
flags,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
log::debug!("no HID quirks for {} ({:04X}:{:04X})", kind, vendor, product);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use redox_driver_sys::quirks::HidQuirkFlags;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hid_quirks_returns_empty_for_synthetic_zero_vendor() {
|
||||||
|
// vendor=0 is the current evdevd default; confirm we
|
||||||
|
// do not match anything accidentally.
|
||||||
|
let flags = lookup_hid_quirks(0, 0);
|
||||||
|
assert!(flags.is_empty());
|
||||||
|
assert_eq!(flags, HidQuirkFlags::empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hid_quirks_returns_empty_for_synthetic_product_id() {
|
||||||
|
// evdevd currently sets product = id (or id+0x10 / id+0x20)
|
||||||
|
// — small numbers that should not appear in the Linux
|
||||||
|
// HID quirk table.
|
||||||
|
for product in 0u16..32 {
|
||||||
|
let flags = lookup_hid_quirks(0, product);
|
||||||
|
assert!(flags.is_empty(), "unexpected match at product={}", product);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn hid_quirks_returns_known_flag_for_real_device() {
|
||||||
|
// Real entry: 0x06d6:0x0025 → BADPAD (from hid_table.rs).
|
||||||
|
let flags = lookup_hid_quirks(0x06d6, 0x0025);
|
||||||
|
assert!(!flags.is_empty());
|
||||||
|
assert!(flags.contains(HidQuirkFlags::BADPAD));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn log_helper_does_not_panic_on_synthetic_ids() {
|
||||||
|
log_hid_quirks(0, 0, "keyboard");
|
||||||
|
log_hid_quirks(0, 0x10, "mouse");
|
||||||
|
log_hid_quirks(0, 0x20, "touchpad");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -276,6 +276,15 @@ impl EvdevScheme {
|
|||||||
DeviceKind::Mouse => InputDevice::new_mouse(id),
|
DeviceKind::Mouse => InputDevice::new_mouse(id),
|
||||||
DeviceKind::Touchpad => InputDevice::new_touchpad(id),
|
DeviceKind::Touchpad => InputDevice::new_touchpad(id),
|
||||||
};
|
};
|
||||||
|
crate::quirks::log_hid_quirks(
|
||||||
|
device.input_id.vendor,
|
||||||
|
device.input_id.product,
|
||||||
|
match kind {
|
||||||
|
DeviceKind::Keyboard => "keyboard",
|
||||||
|
DeviceKind::Mouse => "mouse",
|
||||||
|
DeviceKind::Touchpad => "touchpad",
|
||||||
|
},
|
||||||
|
);
|
||||||
self.devices.push(device);
|
self.devices.push(device);
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user