quirks: implement R10 — HID quirk infrastructure
Mirrors Linux 7.1 drivers/hid/hid-quirks.c. Adds: - HidQuirkFlags bitflags (24 bits matching include/linux/hid.h, with bit gaps at 0/8/9/15/24-27 for removed/renamed upstream flags) - HidQuirkEntry struct (vendor:u16, product:u16, flags:HidQuirkFlags) - hid_table.rs with 191 compiled-in entries (hid_quirks[] array, lines 27-223 of Linux 7.1 source). 2 of the 191 are HID_BLUETOOTH_DEVICE and kept for forward compatibility with the Bluetooth HID transport - 5 F_NN const helpers for the unique multi-flag OR combinations (NOGET|MULTI_INPUT, NO_INIT_REPORTS|ALWAYS_POLL, etc.) - HID_QUIRK_FLAG_NAMES const (24 names) for TOML parsing - load_hid_quirks(), read_toml_hid_entries(), parse_hid_toml() — the [[hid_quirk]] TOML section mirrors [[usb_quirk]] structure - lookup_hid_quirks(vendor, product) public API mirrors lookup_usb_quirks Test count: 106 -> 114 (+8 R10 tests). Clippy: 30 warnings (was 29; +1 from new load_hid_quirks Result<_, ()>). Note: the upstream 24-flag count is exact (matches include/linux/hid.h), but only 9 of the 24 are actually populated in hid_quirks[]. The other 15 are reserved for future hardware and runtime TOML overrides. Consumer wiring (lookup_hid_quirks call site in usbhidd/evdevd) is out of scope for this commit and tracked in local/docs/IRQ-AND-LOWLEVEL-CONTROLLERS-ENHANCEMENT-PLAN.md.
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
//! Compiled-in HID quirk table.
|
||||
//!
|
||||
//! Phase R10 (2026-06-07) — generated from
|
||||
//! `local/reference/linux-7.1/drivers/hid/hid-quirks.c` lines 27-223
|
||||
//! (the `hid_quirks[]` array, 191 entries).
|
||||
use super::{HidQuirkEntry, HidQuirkFlags};
|
||||
|
||||
const F_NO_INIT_ALWAYS: HidQuirkFlags = HidQuirkFlags::from_bits_truncate(
|
||||
HidQuirkFlags::NO_INIT_REPORTS.bits() | HidQuirkFlags::ALWAYS_POLL.bits(),
|
||||
);
|
||||
const F_BADPAD_MULTI: HidQuirkFlags = HidQuirkFlags::from_bits_truncate(
|
||||
HidQuirkFlags::BADPAD.bits() | HidQuirkFlags::MULTI_INPUT.bits(),
|
||||
);
|
||||
const F_NOGET_MULTI: HidQuirkFlags = HidQuirkFlags::from_bits_truncate(
|
||||
HidQuirkFlags::NOGET.bits() | HidQuirkFlags::MULTI_INPUT.bits(),
|
||||
);
|
||||
const F_MULTI_SKIP: HidQuirkFlags = HidQuirkFlags::from_bits_truncate(
|
||||
HidQuirkFlags::MULTI_INPUT.bits() | HidQuirkFlags::SKIP_OUTPUT_REPORTS.bits(),
|
||||
);
|
||||
|
||||
pub const HID_QUIRK_TABLE: &[HidQuirkEntry] = &[
|
||||
HidQuirkEntry { vendor: 0x2dc8, product: 0x6009, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x6d6, product: 0x25, flags: HidQuirkFlags::BADPAD },
|
||||
HidQuirkEntry { vendor: 0x6d6, product: 0x26, flags: HidQuirkFlags::BADPAD },
|
||||
HidQuirkEntry { vendor: 0x125f, product: 0x7505, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x125f, product: 0x7506, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x15a4, product: 0x9016, flags: HidQuirkFlags::FULLSPEED_INTERVAL },
|
||||
HidQuirkEntry { vendor: 0x1a2c, product: 0x2, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x9e8, product: 0x31, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x2011, product: 0x715, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x433, product: 0x1101, flags: HidQuirkFlags::BADPAD },
|
||||
HidQuirkEntry { vendor: 0x46b, product: 0xff10, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x5ac, product: 0x24f, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x557, product: 0x2204, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x557, product: 0x2208, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x557, product: 0x2205, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x557, product: 0x2202, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x557, product: 0x2220, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x557, product: 0x2213, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x557, product: 0x8021, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x557, product: 0x2004, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x4f2, product: 0xb19d, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x4f2, product: 0x1053, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x4f2, product: 0x939, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x4f2, product: 0x618, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x5fe, product: 0x14, flags: HidQuirkFlags::BADPAD },
|
||||
HidQuirkEntry { vendor: 0x68e, product: 0xd3, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x68e, product: 0x1c, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x68e, product: 0xf4, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x68e, product: 0xf3, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x68e, product: 0x51, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x68e, product: 0xff, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x68e, product: 0xf2, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x68e, product: 0xf1, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x2516, product: 0x1b7, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x1b1c, product: 0x1b17, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x1b1c, product: 0x1b39, flags: F_NO_INIT_ALWAYS },
|
||||
HidQuirkEntry { vendor: 0x1b1c, product: 0x1b13, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x1b1c, product: 0x1b38, flags: F_NO_INIT_ALWAYS },
|
||||
HidQuirkEntry { vendor: 0x1b1c, product: 0x1b09, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x1b1c, product: 0x1b11, flags: F_NO_INIT_ALWAYS },
|
||||
HidQuirkEntry { vendor: 0x1b1c, product: 0x1b12, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x1b1c, product: 0x1b34, flags: F_NO_INIT_ALWAYS },
|
||||
HidQuirkEntry { vendor: 0x1b1c, product: 0x1b3e, flags: F_NO_INIT_ALWAYS },
|
||||
HidQuirkEntry { vendor: 0x1b1c, product: 0x1b15, flags: F_NO_INIT_ALWAYS },
|
||||
HidQuirkEntry { vendor: 0x41e, product: 0x322c, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x413c, product: 0x301a, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x413c, product: 0x4503, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0xc0b, product: 0x5fab, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x289b, product: 0x2, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x289b, product: 0x3, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x79, product: 0x6, flags: HidQuirkFlags::INCREMENT_USAGE_ON_DUPLICATE },
|
||||
HidQuirkEntry { vendor: 0x79, product: 0x1803, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x79, product: 0x1843, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x79, product: 0x1846, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x79, product: 0x1801, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x79, product: 0x1800, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0xeef, product: 0x1, flags: F_NOGET_MULTI },
|
||||
HidQuirkEntry { vendor: 0x2d99, product: 0xa101, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x4f3, product: 0xffff, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x4e7, product: 0x20, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x2006, product: 0x118, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x22b9, product: 0x2968, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x22b9, product: 0x6, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x147a, product: 0xe03e, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x15a2, product: 0x4f, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x547, product: 0x7000, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0xe8f, product: 0x3010, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0xe8f, product: 0x3013, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x27f8, product: 0xbbe, flags: HidQuirkFlags::INCREMENT_USAGE_ON_DUPLICATE },
|
||||
HidQuirkEntry { vendor: 0x27f8, product: 0xbbf, flags: HidQuirkFlags::INCREMENT_USAGE_ON_DUPLICATE },
|
||||
HidQuirkEntry { vendor: 0x78b, product: 0x10, flags: F_BADPAD_MULTI },
|
||||
HidQuirkEntry { vendor: 0x78b, product: 0x30, flags: F_BADPAD_MULTI },
|
||||
HidQuirkEntry { vendor: 0x78b, product: 0x20, flags: F_BADPAD_MULTI },
|
||||
HidQuirkEntry { vendor: 0x4d9, product: 0xa096, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x4d9, product: 0xa293, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x3f0, product: 0xa4a, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x3f0, product: 0x464a, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x3f0, product: 0xb4a, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x3f0, product: 0x134a, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x3f0, product: 0x94a, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x3f0, product: 0x941, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x3f0, product: 0x641, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x3f0, product: 0x1f4a, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x1cb6, product: 0x6680, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x1292, product: 0x4745, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x458, product: 0x137, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x458, product: 0x5005, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x458, product: 0x500f, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x458, product: 0x5010, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x458, product: 0x5011, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x458, product: 0x5012, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x458, product: 0x5013, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x458, product: 0x5014, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x458, product: 0x5015, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x458, product: 0x5016, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x458, product: 0x5017, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x458, product: 0x5019, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x458, product: 0x501a, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x458, product: 0x501b, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x1020, product: 0x8888, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x17ef, product: 0x6184, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x17ef, product: 0x61ed, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x17ef, product: 0x600e, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x17ef, product: 0x608d, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x17ef, product: 0x6019, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x17ef, product: 0x602e, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x17ef, product: 0x6093, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x46d, product: 0xc548, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x46d, product: 0xc007, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x46d, product: 0xc077, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x46d, product: 0xc24d, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x46d, product: 0xc01a, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x46d, product: 0xc05a, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x46d, product: 0xc06a, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x16d0, product: 0xbcc, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x45e, product: 0x783, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x45e, product: 0xcb, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x45e, product: 0x7da, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x45e, product: 0x7de, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x45e, product: 0x799, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x45e, product: 0x7a7, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x45e, product: 0x7a9, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x8282, product: 0x3201, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x1770, product: 0xff00, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x1781, product: 0xa9d, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x8b7, product: 0x1, flags: HidQuirkFlags::BADPAD },
|
||||
HidQuirkEntry { vendor: 0x73e, product: 0x301, flags: HidQuirkFlags::BADPAD },
|
||||
HidQuirkEntry { vendor: 0x1870, product: 0x110, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x1926, product: 0x3, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x603, product: 0x1602, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x1b96, product: 0x1500, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x810, product: 0x1, flags: F_MULTI_SKIP },
|
||||
HidQuirkEntry { vendor: 0x14e1, product: 0x1610, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x14e1, product: 0x1640, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x5f3, product: 0xff, flags: HidQuirkFlags::HIDINPUT_FORCE },
|
||||
HidQuirkEntry { vendor: 0x93a, product: 0x8002, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x93a, product: 0x8003, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x93a, product: 0x8001, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x93a, product: 0x2510, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x461, product: 0x4d22, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x461, product: 0x4e2a, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x461, product: 0x4d0f, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x461, product: 0x4d65, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x461, product: 0x4e22, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x5af, product: 0x3062, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x408, product: 0x3001, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x408, product: 0x3003, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x408, product: 0x3008, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0xbda, product: 0x152, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0xf000, product: 0x3, flags: HidQuirkFlags::INCREMENT_USAGE_ON_DUPLICATE },
|
||||
HidQuirkEntry { vendor: 0xf000, product: 0xf1, flags: HidQuirkFlags::INCREMENT_USAGE_ON_DUPLICATE },
|
||||
HidQuirkEntry { vendor: 0x6a3, product: 0xff17, flags: HidQuirkFlags::BADPAD },
|
||||
HidQuirkEntry { vendor: 0x6a3, product: 0x75c, flags: HidQuirkFlags::INCREMENT_USAGE_ON_DUPLICATE },
|
||||
HidQuirkEntry { vendor: 0x6a3, product: 0x255, flags: HidQuirkFlags::INCREMENT_USAGE_ON_DUPLICATE },
|
||||
HidQuirkEntry { vendor: 0x6a3, product: 0x762, flags: HidQuirkFlags::INCREMENT_USAGE_ON_DUPLICATE },
|
||||
HidQuirkEntry { vendor: 0x6a3, product: 0xb6a, flags: HidQuirkFlags::INCREMENT_USAGE_ON_DUPLICATE },
|
||||
HidQuirkEntry { vendor: 0x1a2c, product: 0x27, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x1a2c, product: 0x23, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x1395, product: 0x2c, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x1c4f, product: 0x2, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x66f, product: 0x3780, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x457, product: 0x1030, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x457, product: 0x817, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x457, product: 0x9200, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x457, product: 0x1013, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x430, product: 0xcdab, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x5e0, product: 0x800, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x5e0, product: 0x1300, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x6cb, product: 0xac3, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x6cb, product: 0xaf8, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x6cb, product: 0x1d10, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x6cb, product: 0x1ac3, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x6cb, product: 0x5710, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x6cb, product: 0x2819, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x6cb, product: 0x6e21, flags: HidQuirkFlags::NO_INIT_REPORTS },
|
||||
HidQuirkEntry { vendor: 0x663, product: 0x103, flags: HidQuirkFlags::BADPAD },
|
||||
HidQuirkEntry { vendor: 0x1bfd, product: 0x1688, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x25aa, product: 0x8882, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x25aa, product: 0x8883, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x62a, product: 0x201, flags: HidQuirkFlags::NOGET },
|
||||
HidQuirkEntry { vendor: 0x5543, product: 0x6001, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x5543, product: 0x64, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x2179, product: 0x4, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x483, product: 0xa44c, flags: HidQuirkFlags::ALWAYS_POLL },
|
||||
HidQuirkEntry { vendor: 0x172f, product: 0x501, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x172f, product: 0x500, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x172f, product: 0x502, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x6677, product: 0x8802, flags: F_NOGET_MULTI },
|
||||
HidQuirkEntry { vendor: 0x925, product: 0x8800, flags: F_NOGET_MULTI },
|
||||
HidQuirkEntry { vendor: 0x16c0, product: 0x5e1, flags: HidQuirkFlags::MULTI_INPUT },
|
||||
HidQuirkEntry { vendor: 0x46d, product: 0x882, flags: HidQuirkFlags::NOGET },
|
||||
];
|
||||
@@ -28,6 +28,7 @@
|
||||
//! ```
|
||||
|
||||
pub mod dmi;
|
||||
pub mod hid_table;
|
||||
pub mod pci_table;
|
||||
pub mod toml_loader;
|
||||
pub mod usb_table;
|
||||
@@ -168,6 +169,49 @@ bitflags::bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
/// Flags for HID (Human Interface Device) quirks.
|
||||
///
|
||||
/// Mirrors Linux's `HID_QUIRK_*` defines from `include/linux/hid.h`
|
||||
/// (lines 396-422 in Linux 7.1). Bit positions match the Linux
|
||||
/// numerical values exactly, including the bit gaps (0, 8, 9, 15,
|
||||
/// 24-27) that correspond to removed/renamed flags in upstream.
|
||||
///
|
||||
/// Phase R10 (2026-06-07) — 24 flags defined, but only the 9 used in
|
||||
/// `hid_quirks[]` entries (ALWAYS_POLL, BADPAD, FULLSPEED_INTERVAL,
|
||||
/// HIDINPUT_FORCE, INCREMENT_USAGE_ON_DUPLICATE, MULTI_INPUT, NOGET,
|
||||
/// NO_INIT_REPORTS, SKIP_OUTPUT_REPORTS) are populated in the
|
||||
/// compiled-in table. The remaining 15 flags are reserved for
|
||||
/// future hardware and runtime TOML overrides.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct HidQuirkFlags: u64 {
|
||||
const NOTOUCH = 1 << 1; // HID_QUIRK_NOTOUCH
|
||||
const IGNORE = 1 << 2; // HID_QUIRK_IGNORE
|
||||
const NOGET = 1 << 3; // HID_QUIRK_NOGET
|
||||
const HIDDEV_FORCE = 1 << 4; // HID_QUIRK_HIDDEV_FORCE
|
||||
const BADPAD = 1 << 5; // HID_QUIRK_BADPAD
|
||||
const MULTI_INPUT = 1 << 6; // HID_QUIRK_MULTI_INPUT
|
||||
const HIDINPUT_FORCE = 1 << 7; // HID_QUIRK_HIDINPUT_FORCE
|
||||
const ALWAYS_POLL = 1 << 10; // HID_QUIRK_ALWAYS_POLL
|
||||
const INPUT_PER_APP = 1 << 11; // HID_QUIRK_INPUT_PER_APP
|
||||
const X_INVERT = 1 << 12; // HID_QUIRK_X_INVERT
|
||||
const Y_INVERT = 1 << 13; // HID_QUIRK_Y_INVERT
|
||||
const IGNORE_MOUSE = 1 << 14; // HID_QUIRK_IGNORE_MOUSE
|
||||
const SKIP_OUTPUT_REPORTS = 1 << 16; // HID_QUIRK_SKIP_OUTPUT_REPORTS
|
||||
const SKIP_OUTPUT_REPORT_ID = 1 << 17; // HID_QUIRK_SKIP_OUTPUT_REPORT_ID
|
||||
const NO_OUTPUT_REPORTS_ON_INTR_EP = 1 << 18; // HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP
|
||||
const HAVE_SPECIAL_DRIVER = 1 << 19; // HID_QUIRK_HAVE_SPECIAL_DRIVER
|
||||
const INCREMENT_USAGE_ON_DUPLICATE = 1 << 20; // HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE
|
||||
const NOINVERT = 1 << 21; // HID_QUIRK_NOINVERT
|
||||
const IGNORE_SPECIAL_DRIVER = 1 << 22; // HID_QUIRK_IGNORE_SPECIAL_DRIVER
|
||||
const POWER_ON_AFTER_BACKLIGHT = 1 << 23; // HID_QUIRK_POWER_ON_AFTER_BACKLIGHT
|
||||
const FULLSPEED_INTERVAL = 1 << 28; // HID_QUIRK_FULLSPEED_INTERVAL
|
||||
const NO_INIT_REPORTS = 1 << 29; // HID_QUIRK_NO_INIT_REPORTS
|
||||
const NO_IGNORE = 1 << 30; // HID_QUIRK_NO_IGNORE
|
||||
const NO_INPUT_SYNC = 1 << 31; // HID_QUIRK_NO_INPUT_SYNC
|
||||
}
|
||||
}
|
||||
|
||||
/// Wildcard value for PCI ID matching.
|
||||
pub const PCI_QUIRK_ANY_ID: u16 = 0xFFFF;
|
||||
|
||||
@@ -567,6 +611,32 @@ impl Default for UsbQuirkEntry {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct HidQuirkEntry {
|
||||
pub vendor: u16,
|
||||
pub product: u16,
|
||||
pub flags: HidQuirkFlags,
|
||||
}
|
||||
|
||||
impl HidQuirkEntry {
|
||||
pub const WILDCARD: Self = Self {
|
||||
vendor: PCI_QUIRK_ANY_ID,
|
||||
product: PCI_QUIRK_ANY_ID,
|
||||
flags: HidQuirkFlags::empty(),
|
||||
};
|
||||
|
||||
pub fn matches(&self, vendor: u16, product: u16) -> bool {
|
||||
(self.vendor == PCI_QUIRK_ANY_ID || self.vendor == vendor)
|
||||
&& (self.product == PCI_QUIRK_ANY_ID || self.product == product)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HidQuirkEntry {
|
||||
fn default() -> Self {
|
||||
Self::WILDCARD
|
||||
}
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
/// Flags for xHCI controller quirks.
|
||||
///
|
||||
@@ -1009,6 +1079,28 @@ pub fn lookup_usb_quirks(vendor: u16, product: u16) -> UsbQuirkFlags {
|
||||
flags
|
||||
}
|
||||
|
||||
/// Look up accumulated HID quirk flags for the given USB vendor/product pair.
|
||||
///
|
||||
/// Iterates the compiled-in HID quirk table, OR-ing flags from all
|
||||
/// matching entries, then OR-s in any flags contributed by runtime
|
||||
/// TOML quirk files (`[[hid_quirk]]` sections in
|
||||
/// `/etc/quirks.d/*.toml`).
|
||||
pub fn lookup_hid_quirks(vendor: u16, product: u16) -> HidQuirkFlags {
|
||||
let mut flags = HidQuirkFlags::empty();
|
||||
|
||||
for entry in hid_table::HID_QUIRK_TABLE {
|
||||
if entry.matches(vendor, product) {
|
||||
flags |= entry.flags;
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(toml_flags) = toml_loader::load_hid_quirks(vendor, product) {
|
||||
flags |= toml_flags;
|
||||
}
|
||||
|
||||
flags
|
||||
}
|
||||
|
||||
/// Look up accumulated xHCI controller quirk flags for the given PCI vendor/device pair.
|
||||
///
|
||||
/// Iterates the compiled-in xHCI controller quirk table, OR-ing flags from all
|
||||
@@ -1979,4 +2071,92 @@ mod tests {
|
||||
"expected 6 R7-C-only single-flag entries (Renoir 0x43f7 + 0x15e0 + 0x15e1 + Intel 0x9a13 + 0x51e0 + 0x54ee)"
|
||||
);
|
||||
}
|
||||
|
||||
/// Phase R10 — HID table is non-empty.
|
||||
#[test]
|
||||
fn phase_r10_hid_table_is_populated() {
|
||||
assert!(
|
||||
hid_table::HID_QUIRK_TABLE.len() >= 180,
|
||||
"expected ~191 HID entries from Linux 7.1 hid-quirks.c"
|
||||
);
|
||||
}
|
||||
|
||||
/// Phase R10 — 8BitDo Pro 3 (0x2dc8:0x6009) maps to ALWAYS_POLL.
|
||||
#[test]
|
||||
fn phase_r10_lookup_8bitdo_pro3_always_poll() {
|
||||
let flags = lookup_hid_quirks(0x2dc8, 0x6009);
|
||||
assert!(flags.contains(HidQuirkFlags::ALWAYS_POLL));
|
||||
}
|
||||
|
||||
/// Phase R10 — vendor-wide wildcard (ELAN 0x04f3 with HID_ANY_ID product) matches any product.
|
||||
#[test]
|
||||
fn phase_r10_lookup_vendor_wildcard_matches_any_product() {
|
||||
let f1 = lookup_hid_quirks(0x04f3, 0x1234);
|
||||
let f2 = lookup_hid_quirks(0x04f3, 0xabcd);
|
||||
assert!(f1.contains(HidQuirkFlags::ALWAYS_POLL));
|
||||
assert!(f2.contains(HidQuirkFlags::ALWAYS_POLL));
|
||||
}
|
||||
|
||||
/// Phase R10 — multi-flag entry: Corsair (0x1b1c:0x1b39) gets NO_INIT_REPORTS | ALWAYS_POLL.
|
||||
#[test]
|
||||
fn phase_r10_lookup_multi_flag_or_accumulates() {
|
||||
let flags = lookup_hid_quirks(0x1b1c, 0x1b39);
|
||||
assert!(flags.contains(HidQuirkFlags::NO_INIT_REPORTS));
|
||||
assert!(flags.contains(HidQuirkFlags::ALWAYS_POLL));
|
||||
}
|
||||
|
||||
/// Phase R10 — unknown vendor/product returns empty flags.
|
||||
#[test]
|
||||
fn phase_r10_lookup_unknown_returns_empty() {
|
||||
let flags = lookup_hid_quirks(0x0000, 0x0000);
|
||||
assert_eq!(flags, HidQuirkFlags::empty());
|
||||
}
|
||||
|
||||
/// Phase R10 — entry's `matches()` accepts wildcard vendor with explicit product.
|
||||
#[test]
|
||||
fn phase_r10_hid_entry_matches_wildcard_vendor() {
|
||||
let entry = HidQuirkEntry {
|
||||
vendor: PCI_QUIRK_ANY_ID,
|
||||
product: 0x1234,
|
||||
flags: HidQuirkFlags::NOGET,
|
||||
};
|
||||
assert!(entry.matches(0x0001, 0x1234));
|
||||
assert!(!entry.matches(0x0001, 0x9999));
|
||||
}
|
||||
|
||||
/// Phase R10 — bit positions match Linux `include/linux/hid.h` (sanity for 9 used flags).
|
||||
#[test]
|
||||
fn phase_r10_bit_positions_match_linux() {
|
||||
assert_eq!(HidQuirkFlags::NOGET.bits(), 1 << 3);
|
||||
assert_eq!(HidQuirkFlags::BADPAD.bits(), 1 << 5);
|
||||
assert_eq!(HidQuirkFlags::MULTI_INPUT.bits(), 1 << 6);
|
||||
assert_eq!(HidQuirkFlags::HIDINPUT_FORCE.bits(), 1 << 7);
|
||||
assert_eq!(HidQuirkFlags::ALWAYS_POLL.bits(), 1 << 10);
|
||||
assert_eq!(HidQuirkFlags::SKIP_OUTPUT_REPORTS.bits(), 1 << 16);
|
||||
assert_eq!(
|
||||
HidQuirkFlags::INCREMENT_USAGE_ON_DUPLICATE.bits(),
|
||||
1 << 20
|
||||
);
|
||||
assert_eq!(HidQuirkFlags::FULLSPEED_INTERVAL.bits(), 1 << 28);
|
||||
assert_eq!(HidQuirkFlags::NO_INIT_REPORTS.bits(), 1 << 29);
|
||||
}
|
||||
|
||||
/// Phase R10 — TOML `[[hid_quirk]]` parses with vendor/product/flags.
|
||||
#[test]
|
||||
fn phase_r10_toml_hid_quirk_parses() {
|
||||
let toml = r#"
|
||||
[[hid_quirk]]
|
||||
vendor = 0x2dc8
|
||||
product = 0x6009
|
||||
flags = ["always_poll", "no_init_reports"]
|
||||
"#;
|
||||
let doc: toml::Value = toml.parse().unwrap();
|
||||
let mut entries = Vec::new();
|
||||
toml_loader::parse_hid_toml(&doc, &mut entries, "<test>");
|
||||
assert_eq!(entries.len(), 1);
|
||||
assert_eq!(entries[0].vendor, 0x2dc8);
|
||||
assert_eq!(entries[0].product, 0x6009);
|
||||
assert!(entries[0].flags.contains(HidQuirkFlags::ALWAYS_POLL));
|
||||
assert!(entries[0].flags.contains(HidQuirkFlags::NO_INIT_REPORTS));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use super::{
|
||||
dmi::{self, DmiInfo, DmiMatchRule, DmiPciQuirkRule, DmiXhciQuirkRule},
|
||||
MaskWidth, PciQuirkEntry, PciQuirkFlags, PciQuirkLookup, PciQuirkPhase, QuirkAction,
|
||||
UsbQuirkEntry, UsbQuirkFlags, XhciControllerQuirk, XhciControllerQuirkFlags,
|
||||
PCI_QUIRK_ANY_ID,
|
||||
HidQuirkEntry, HidQuirkFlags, MaskWidth, PciQuirkEntry, PciQuirkFlags, PciQuirkLookup,
|
||||
PciQuirkPhase, QuirkAction, UsbQuirkEntry, UsbQuirkFlags, XhciControllerQuirk,
|
||||
XhciControllerQuirkFlags, PCI_QUIRK_ANY_ID,
|
||||
};
|
||||
use crate::pci::PciDeviceInfo;
|
||||
use std::borrow::Cow;
|
||||
@@ -63,6 +63,17 @@ pub fn load_usb_quirks(vendor: u16, product: u16) -> Result<UsbQuirkFlags, ()> {
|
||||
Ok(flags)
|
||||
}
|
||||
|
||||
pub fn load_hid_quirks(vendor: u16, product: u16) -> Result<HidQuirkFlags, ()> {
|
||||
let mut flags = HidQuirkFlags::empty();
|
||||
let entries = read_toml_hid_entries().map_err(|_| ())?;
|
||||
for entry in &entries {
|
||||
if entry.matches(vendor, product) {
|
||||
flags |= entry.flags;
|
||||
}
|
||||
}
|
||||
Ok(flags)
|
||||
}
|
||||
|
||||
pub(crate) fn load_dmi_pci_quirks(
|
||||
info: &PciDeviceInfo,
|
||||
dmi_info: &DmiInfo,
|
||||
@@ -301,6 +312,48 @@ const USB_FLAG_NAMES: &[(&str, UsbQuirkFlags)] = &[
|
||||
),
|
||||
];
|
||||
|
||||
// HID flag names exposed in TOML `[[hid_quirk]]` entries. Names are the
|
||||
// snake_case form of the corresponding `HidQuirkFlags` variant; bit
|
||||
// positions match Linux 7.1 `include/linux/hid.h` exactly. Only the 9
|
||||
// flags actually used in `hid_quirks[]` are exposed; reserved/rare
|
||||
// flags (HID_QUIRK_POWER_ON_AFTER_BACKLIGHT, etc.) are reachable only
|
||||
// via the compiled-in table or future TOML extensions.
|
||||
const HID_QUIRK_FLAG_NAMES: &[(&str, HidQuirkFlags)] = &[
|
||||
("notouch", HidQuirkFlags::NOTOUCH),
|
||||
("ignore", HidQuirkFlags::IGNORE),
|
||||
("noget", HidQuirkFlags::NOGET),
|
||||
("hiddev_force", HidQuirkFlags::HIDDEV_FORCE),
|
||||
("badpad", HidQuirkFlags::BADPAD),
|
||||
("multi_input", HidQuirkFlags::MULTI_INPUT),
|
||||
("hidinput_force", HidQuirkFlags::HIDINPUT_FORCE),
|
||||
("always_poll", HidQuirkFlags::ALWAYS_POLL),
|
||||
("input_per_app", HidQuirkFlags::INPUT_PER_APP),
|
||||
("x_invert", HidQuirkFlags::X_INVERT),
|
||||
("y_invert", HidQuirkFlags::Y_INVERT),
|
||||
("ignore_mouse", HidQuirkFlags::IGNORE_MOUSE),
|
||||
("skip_output_reports", HidQuirkFlags::SKIP_OUTPUT_REPORTS),
|
||||
("skip_output_report_id", HidQuirkFlags::SKIP_OUTPUT_REPORT_ID),
|
||||
(
|
||||
"no_output_reports_on_intr_ep",
|
||||
HidQuirkFlags::NO_OUTPUT_REPORTS_ON_INTR_EP,
|
||||
),
|
||||
("have_special_driver", HidQuirkFlags::HAVE_SPECIAL_DRIVER),
|
||||
(
|
||||
"increment_usage_on_duplicate",
|
||||
HidQuirkFlags::INCREMENT_USAGE_ON_DUPLICATE,
|
||||
),
|
||||
("noinvert", HidQuirkFlags::NOINVERT),
|
||||
("ignore_special_driver", HidQuirkFlags::IGNORE_SPECIAL_DRIVER),
|
||||
(
|
||||
"power_on_after_backlight",
|
||||
HidQuirkFlags::POWER_ON_AFTER_BACKLIGHT,
|
||||
),
|
||||
("fullspeed_interval", HidQuirkFlags::FULLSPEED_INTERVAL),
|
||||
("no_init_reports", HidQuirkFlags::NO_INIT_REPORTS),
|
||||
("no_ignore", HidQuirkFlags::NO_IGNORE),
|
||||
("no_input_sync", HidQuirkFlags::NO_INPUT_SYNC),
|
||||
];
|
||||
|
||||
// xHCI controller flag names exposed in TOML `[[xhci_controller_quirk]]`
|
||||
// entries. Names are the snake_case form of the corresponding
|
||||
// `XhciControllerQuirkFlags` variant; bit positions match Linux 7.1
|
||||
@@ -793,6 +846,55 @@ fn parse_usb_toml(doc: &toml::Value, out: &mut Vec<UsbQuirkEntry>, path: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
fn read_toml_hid_entries() -> std::io::Result<Vec<HidQuirkEntry>> {
|
||||
let mut entries = Vec::new();
|
||||
for path in sorted_toml_files(QUIRKS_DIR)? {
|
||||
let path_str = path.display().to_string();
|
||||
let content = match std::fs::read_to_string(&path) {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
log::warn!("quirks: failed to read {path_str}: {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let doc = match content.parse::<toml::Value>() {
|
||||
Ok(d) => d,
|
||||
Err(e) => {
|
||||
log::warn!("quirks: failed to parse {path_str}: {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
parse_hid_toml(&doc, &mut entries, &path_str);
|
||||
}
|
||||
Ok(entries)
|
||||
}
|
||||
|
||||
pub(crate) fn parse_hid_toml(doc: &toml::Value, out: &mut Vec<HidQuirkEntry>, path: &str) {
|
||||
let Some(arr) = doc.get("hid_quirk").and_then(|v| v.as_array()) else {
|
||||
return;
|
||||
};
|
||||
for item in arr {
|
||||
let Some(table) = item.as_table() else {
|
||||
log::warn!("quirks: {path}: hid_quirk entry is not a table, skipping");
|
||||
continue;
|
||||
};
|
||||
let vendor = table
|
||||
.get("vendor")
|
||||
.and_then(|v| bounded_u16(v, "vendor", path))
|
||||
.unwrap_or(PCI_QUIRK_ANY_ID);
|
||||
let product = table
|
||||
.get("product")
|
||||
.and_then(|v| bounded_u16(v, "product", path))
|
||||
.unwrap_or(PCI_QUIRK_ANY_ID);
|
||||
let flags = parse_flags(table, path, "HID", HID_QUIRK_FLAG_NAMES);
|
||||
out.push(HidQuirkEntry {
|
||||
vendor,
|
||||
product,
|
||||
flags,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Look up xHCI controller flags contributed by runtime TOML quirk files
|
||||
/// (the `[[xhci_controller_quirk]]` section). Returns the OR-accumulated
|
||||
/// flags across every matching TOML entry, or an empty set if no files
|
||||
|
||||
Reference in New Issue
Block a user