Expand USB quirks and hardware validation

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-04-17 13:32:32 +01:00
parent 07a9238e06
commit 6f93b6ed43
7 changed files with 3395 additions and 47 deletions
+50 -2
View File
@@ -179,6 +179,41 @@ of this interface: it queries `pci_get_quirk_flags()` during AMD DC init, logs t
resulting IRQ expectations, and treats `PCI_QUIRK_NEED_FIRMWARE` as a hard failure resulting IRQ expectations, and treats `PCI_QUIRK_NEED_FIRMWARE` as a hard failure
instead of a warn-and-continue path when that quirk is active. instead of a warn-and-continue path when that quirk is active.
### For USB Storage Drivers (usbscsid)
The USB SCSI driver (`drivers/storage/usbscsid`) carries its own self-contained quirk
module (`src/quirks.rs`) that reads `[[usb_storage_quirk]]` entries from `/etc/quirks.d/*.toml`.
It does not depend on `redox-driver-sys` — the quirk lookup is inline.
At daemon startup, `usbscsid` extracts vendor/product IDs from the USB device descriptor
and looks up matching quirks from both the compiled-in table and TOML files. The resulting
`UsbStorageQuirkFlags` propagate to both the BOT transport and the SCSI command layer.
Active behavioral flags and their injection points:
| Flag | Layer | Effect |
|------|-------|--------|
| `IGNORE_RESIDUE` | BOT (`bot.rs`) | Suppresses CSW data_residue; avoids false short-transfer errors |
| `FIX_CAPACITY` | SCSI (`scsi/mod.rs`) | Subtracts 1 from READ CAPACITY(10) block count |
| `SINGLE_LUN` | BOT (`bot.rs`) | Enforces LUN=0 in CBW |
| `MAX_SECTORS_64` | SCSI (`scsi/mod.rs`) | Clamps transfer_len to 64 sectors per command |
| `INITIAL_READ10` | SCSI (`scsi/mod.rs`) | Uses READ(10)/WRITE(10) instead of READ(16)/WRITE(16) |
TOML format for storage quirks:
```toml
[[usb_storage_quirk]]
vendor = 0x03EB
product = 0x2002
revision = "0100-0100"
manufacturer = "ATMEL"
description = "SND1 Storage"
flags = ["ignore_residue"]
```
The full 214-entry table lives in `quirks.d/30-storage.toml`, mined from Linux 7.0's
`drivers/usb/storage/unusual_devs.h`.
Available C quirk flag macros (defined in `linux/pci.h`): Available C quirk flag macros (defined in `linux/pci.h`):
| Macro | Bit | Meaning | | Macro | Bit | Meaning |
@@ -223,6 +258,16 @@ vendor = 0xVENDOR
device = 0xDEVICE device = 0xDEVICE
flags = ["need_firmware", "no_aspm"] flags = ["need_firmware", "no_aspm"]
[[usb_quirk]]
vendor = 0xVENDOR
product = 0xPRODUCT
flags = ["no_lpm", "need_reset"]
[[usb_storage_quirk]]
vendor = 0xVENDOR
product = 0xPRODUCT
flags = ["ignore_residue", "fix_capacity"]
[[dmi_system_quirk]] [[dmi_system_quirk]]
pci_vendor = 0xVENDOR pci_vendor = 0xVENDOR
flags = ["disable_accel"] flags = ["disable_accel"]
@@ -312,7 +357,7 @@ the honest breakdown.
**Flags consumed by drivers (runtime checks in production code):** **Flags consumed by drivers (runtime checks in production code):**
- redox-drm: `NO_MSIX`, `NO_MSI`, `FORCE_LEGACY_IRQ`, `DISABLE_ACCEL` (interrupt setup + driver probe) - redox-drm: `NO_MSIX`, `NO_MSI`, `FORCE_LEGACY_IRQ`, `DISABLE_ACCEL` (interrupt setup + driver probe)
- xhcid: `RESET_DELAY_MS`, `NO_MSI`, `NO_MSIX`, `FORCE_LEGACY_IRQ` (interrupt selection + port reset delay) - xhcid: `RESET_DELAY_MS`, `NO_MSI`, `NO_MSIX`, `FORCE_LEGACY_IRQ` (interrupt selection + port reset delay)
- xhcid (USB device path): `NO_SET_CONFIG`, `NO_STRING_FETCH`, `BAD_DESCRIPTOR`, `NO_USB3`, `NO_LPM`, `NO_U1U2` (enumeration/configuration/BOS handling) - xhcid (USB device path): `NO_STRING_FETCH`, `BAD_DESCRIPTOR`, `RESET_DELAY`, `HUB_SLOW_RESET`, `NO_BOS`, `SHORT_SET_ADDR_TIMEOUT`, `FORCE_ONE_CONFIG`, `HONOR_BNUMINTERFACES`, `DELAY_CTRL_MSG`, `NO_SET_CONFIG`, `NO_SET_INTF`, `NEED_RESET`, `NO_SUSPEND` (enumeration/configuration/BOS/runtime recovery plus suspend gating)
- amdgpu: `NEED_FIRMWARE` (hard firmware gate), with real quirk-aware logging for `NO_ASPM`, `NEED_IOMMU`, `NO_MSI`, `NO_MSIX` - amdgpu: `NEED_FIRMWARE` (hard firmware gate), with real quirk-aware logging for `NO_ASPM`, `NEED_IOMMU`, `NO_MSI`, `NO_MSIX`
**Infrastructure (data flows, reporting, and partial integration):** **Infrastructure (data flows, reporting, and partial integration):**
@@ -324,6 +369,7 @@ the honest breakdown.
- DMI compiled-in rules: 8 entries match systems by vendor/product/board (served through `acpid` at `/scheme/acpi/dmi`) - DMI compiled-in rules: 8 entries match systems by vendor/product/board (served through `acpid` at `/scheme/acpi/dmi`)
**Observed/logged but not yet strongly enforced in runtime policy:** **Observed/logged but not yet strongly enforced in runtime policy:**
- xhcid `NO_SUSPEND` is now enforced and `usbhubd` mirrors USB 2 hub-port suspend state into child xhcid devices, but suspend policy origination and USB 3 link-state coordination are still pending in the broader hub/power-management layer
- `NO_ASPM`, `NEED_IOMMU`, `NO_MSI`, `NO_MSIX` in the amdgpu path are surfaced in quirk-aware logs before broader driver policy exists. - `NO_ASPM`, `NEED_IOMMU`, `NO_MSI`, `NO_MSIX` in the amdgpu path are surfaced in quirk-aware logs before broader driver policy exists.
**Defined but not yet consumed by any real driver path:** **Defined but not yet consumed by any real driver path:**
@@ -331,7 +377,9 @@ the honest breakdown.
`firmware-loader` itself does not interpret `NEED_FIRMWARE`; that policy is now enforced in the amdgpu driver path instead. `firmware-loader` itself does not interpret `NEED_FIRMWARE`; that policy is now enforced in the amdgpu driver path instead.
`NEED_RESET` remains defined for USB devices but is not yet consumed by a runtime USB driver path. For early xhcid timing quirks, `[[usb_quirk]]` entries may also carry `port = "1.2.3"` selectors.
Those selectors are used only for pre-descriptor timing flags (`RESET_DELAY`, `HUB_SLOW_RESET`,
`SHORT_SET_ADDR_TIMEOUT`) where vendor/product IDs are not yet available.
**Remaining infrastructure work:** **Remaining infrastructure work:**
- none in the current quirks scope - none in the current quirks scope
@@ -69,18 +69,35 @@ bitflags::bitflags! {
bitflags::bitflags! { bitflags::bitflags! {
/// Flags for USB device quirks. /// Flags for USB device quirks.
/// ///
/// Mirrors Linux's `USB_QUIRK_*` defines. /// Mirrors Linux's `USB_QUIRK_*` defines from `include/linux/usb/quirks.h`.
/// Flags 08 are the original Red Bear set. Flags 921 are mined from
/// Linux 7.0 (`drivers/usb/core/quirks.c`, released 2026-04-13).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct UsbQuirkFlags: u64 { pub struct UsbQuirkFlags: u64 {
const NO_STRING_FETCH = 1 << 0; // Original Red Bear flags (08)
const RESET_DELAY = 1 << 1; const NO_STRING_FETCH = 1 << 0; // USB_QUIRK_STRING_FETCH_255
const NO_USB3 = 1 << 2; const RESET_DELAY = 1 << 1; // USB_QUIRK_DELAY_INIT
const NO_SET_CONFIG = 1 << 3; const NO_USB3 = 1 << 2; // no Linux equivalent (Red Bear-specific)
const NO_SUSPEND = 1 << 4; const NO_SET_CONFIG = 1 << 3; // USB_QUIRK_NO_SET_INTF (SET_INTERFACE)
const NEED_RESET = 1 << 5; const NO_SUSPEND = 1 << 4; // USB_QUIRK_DISCONNECT_SUSPEND
const BAD_DESCRIPTOR = 1 << 6; const NEED_RESET = 1 << 5; // USB_QUIRK_RESET_RESUME
const NO_LPM = 1 << 7; const BAD_DESCRIPTOR = 1 << 6; // USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL
const NO_U1U2 = 1 << 8; const NO_LPM = 1 << 7; // USB_QUIRK_NO_LPM
const NO_U1U2 = 1 << 8; // USB_QUIRK_NO_U1_U2
// Mined from Linux 7.0 (922)
const NO_SET_INTF = 1 << 9; // USB_QUIRK_NO_SET_INTF
const CONFIG_INTF_STRINGS = 1 << 10; // USB_QUIRK_CONFIG_INTF_STRINGS
const NO_RESET = 1 << 11; // USB_QUIRK_RESET (device can't be reset)
const HONOR_BNUMINTERFACES = 1 << 12; // USB_QUIRK_HONOR_BNUMINTERFACES
const DEVICE_QUALIFIER = 1 << 13; // USB_QUIRK_DEVICE_QUALIFIER
const IGNORE_REMOTE_WAKEUP = 1 << 14; // USB_QUIRK_IGNORE_REMOTE_WAKEUP
const DELAY_CTRL_MSG = 1 << 15; // USB_QUIRK_DELAY_CTRL_MSG
const HUB_SLOW_RESET = 1 << 16; // USB_QUIRK_HUB_SLOW_RESET
const NO_BOS = 1 << 17; // USB_QUIRK_NO_BOS
const SHORT_SET_ADDR_TIMEOUT = 1 << 18; // USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT
const FORCE_ONE_CONFIG = 1 << 19; // USB_QUIRK_FORCE_ONE_CONFIG
const ENDPOINT_IGNORE = 1 << 20; // USB_QUIRK_ENDPOINT_IGNORE
const LINEAR_FRAME_BINTERVAL = 1 << 21; // USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL
} }
} }
@@ -126,6 +126,25 @@ const USB_FLAG_NAMES: &[(&str, UsbQuirkFlags)] = &[
("bad_descriptor", UsbQuirkFlags::BAD_DESCRIPTOR), ("bad_descriptor", UsbQuirkFlags::BAD_DESCRIPTOR),
("no_lpm", UsbQuirkFlags::NO_LPM), ("no_lpm", UsbQuirkFlags::NO_LPM),
("no_u1u2", UsbQuirkFlags::NO_U1U2), ("no_u1u2", UsbQuirkFlags::NO_U1U2),
("no_set_intf", UsbQuirkFlags::NO_SET_INTF),
("config_intf_strings", UsbQuirkFlags::CONFIG_INTF_STRINGS),
("no_reset", UsbQuirkFlags::NO_RESET),
("honor_bnuminterfaces", UsbQuirkFlags::HONOR_BNUMINTERFACES),
("device_qualifier", UsbQuirkFlags::DEVICE_QUALIFIER),
("ignore_remote_wakeup", UsbQuirkFlags::IGNORE_REMOTE_WAKEUP),
("delay_ctrl_msg", UsbQuirkFlags::DELAY_CTRL_MSG),
("hub_slow_reset", UsbQuirkFlags::HUB_SLOW_RESET),
("no_bos", UsbQuirkFlags::NO_BOS),
(
"short_set_addr_timeout",
UsbQuirkFlags::SHORT_SET_ADDR_TIMEOUT,
),
("force_one_config", UsbQuirkFlags::FORCE_ONE_CONFIG),
("endpoint_ignore", UsbQuirkFlags::ENDPOINT_IGNORE),
(
"linear_frame_binterval",
UsbQuirkFlags::LINEAR_FRAME_BINTERVAL,
),
]; ];
fn flag_from_name<F: Copy>(name: &str, mapping: &[(&str, F)]) -> Option<F> { fn flag_from_name<F: Copy>(name: &str, mapping: &[(&str, F)]) -> Option<F> {
@@ -1,51 +1,752 @@
use super::{UsbQuirkEntry, UsbQuirkFlags, PCI_QUIRK_ANY_ID}; use super::{UsbQuirkEntry, UsbQuirkFlags, PCI_QUIRK_ANY_ID};
const F_NO_SUSP_RESET: UsbQuirkFlags = UsbQuirkFlags::from_bits_truncate( const F_00: UsbQuirkFlags = UsbQuirkFlags::from_bits_truncate(
UsbQuirkFlags::NO_SUSPEND.bits() | UsbQuirkFlags::NEED_RESET.bits(), UsbQuirkFlags::NEED_RESET.bits() | UsbQuirkFlags::NO_LPM.bits(),
); );
const F_BAD_DESC_NO_CFG: UsbQuirkFlags = UsbQuirkFlags::from_bits_truncate( const F_01: UsbQuirkFlags = UsbQuirkFlags::from_bits_truncate(
UsbQuirkFlags::BAD_DESCRIPTOR.bits() | UsbQuirkFlags::NO_SET_CONFIG.bits(), UsbQuirkFlags::NO_LPM.bits() | UsbQuirkFlags::RESET_DELAY.bits(),
);
const F_02: UsbQuirkFlags = UsbQuirkFlags::from_bits_truncate(
UsbQuirkFlags::DELAY_CTRL_MSG.bits() | UsbQuirkFlags::RESET_DELAY.bits(),
);
const F_03: UsbQuirkFlags = UsbQuirkFlags::from_bits_truncate(
UsbQuirkFlags::NO_SUSPEND.bits() | UsbQuirkFlags::NEED_RESET.bits(),
); );
pub const USB_QUIRK_TABLE: &[UsbQuirkEntry] = &[ pub const USB_QUIRK_TABLE: &[UsbQuirkEntry] = &[
UsbQuirkEntry { UsbQuirkEntry {
vendor: 0x0BDA, vendor: 0x0204,
product: 0x8153, product: 0x6025,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x0218,
product: 0x0201,
flags: UsbQuirkFlags::CONFIG_INTF_STRINGS,
},
UsbQuirkEntry {
vendor: 0x0218,
product: 0x0401,
flags: UsbQuirkFlags::CONFIG_INTF_STRINGS,
},
UsbQuirkEntry {
vendor: 0x03F0,
product: 0x0701,
flags: UsbQuirkFlags::NO_STRING_FETCH, flags: UsbQuirkFlags::NO_STRING_FETCH,
}, },
UsbQuirkEntry { UsbQuirkEntry {
vendor: 0x0BDA, vendor: 0x03F0,
product: 0x8156, product: 0x3F40,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x03F0,
product: 0xA31D,
flags: UsbQuirkFlags::NO_SUSPEND,
},
UsbQuirkEntry {
vendor: 0x041E,
product: 0x3020,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x0424,
product: 0x3503,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x045E,
product: 0x00E1,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x045E,
product: 0x0770,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x045E,
product: 0x07C6,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x046A,
product: 0x0023,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x0825,
flags: F_00,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x082D,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x0841,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x0843,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x085B,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x085C,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x0847,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x0848,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x0853,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x086C,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x08C1,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x08C2,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x08C3,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x08C5,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x08C6,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0x08C7,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0xC122,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x0471,
product: 0x0155,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x047F,
product: 0xC008,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x047F,
product: 0xC013,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x04B4,
product: 0x0526,
flags: UsbQuirkFlags::CONFIG_INTF_STRINGS,
},
UsbQuirkEntry {
vendor: 0x04D8,
product: 0x000C,
flags: UsbQuirkFlags::CONFIG_INTF_STRINGS,
},
UsbQuirkEntry {
vendor: 0x04E7,
product: 0x0009,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x04E7,
product: 0x0030,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x04E8,
product: 0x6601,
flags: UsbQuirkFlags::CONFIG_INTF_STRINGS,
},
UsbQuirkEntry {
vendor: 0x04F3,
product: 0x0089,
flags: UsbQuirkFlags::DEVICE_QUALIFIER,
},
UsbQuirkEntry {
vendor: 0x04F3,
product: 0x009B,
flags: UsbQuirkFlags::DEVICE_QUALIFIER,
},
UsbQuirkEntry {
vendor: 0x04F3,
product: 0x010C,
flags: UsbQuirkFlags::DEVICE_QUALIFIER,
},
UsbQuirkEntry {
vendor: 0x04F3,
product: 0x0125,
flags: UsbQuirkFlags::DEVICE_QUALIFIER,
},
UsbQuirkEntry {
vendor: 0x04F3,
product: 0x016F,
flags: UsbQuirkFlags::DEVICE_QUALIFIER,
},
UsbQuirkEntry {
vendor: 0x04F3,
product: 0x0381,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x04F3,
product: 0x21B8,
flags: UsbQuirkFlags::DEVICE_QUALIFIER,
},
UsbQuirkEntry {
vendor: 0x0582,
product: 0x0007,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x0582,
product: 0x0027,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x058F,
product: 0x9254,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x05AC,
product: 0x021A,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x05E3,
product: 0x0612,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x05CC,
product: 0x2267,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x05E3,
product: 0x0616,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x0638,
product: 0x0A13,
flags: UsbQuirkFlags::NO_STRING_FETCH, flags: UsbQuirkFlags::NO_STRING_FETCH,
}, },
UsbQuirkEntry {
vendor: 0x067B,
product: 0x2731,
flags: F_01,
},
UsbQuirkEntry {
vendor: 0x06A3,
product: 0x0006,
flags: UsbQuirkFlags::CONFIG_INTF_STRINGS,
},
UsbQuirkEntry {
vendor: 0x06BD,
product: 0x0001,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x06F8,
product: 0x0804,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x06F8,
product: 0x3005,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x06F8,
product: 0xB000,
flags: UsbQuirkFlags::ENDPOINT_IGNORE,
},
UsbQuirkEntry {
vendor: 0x0763,
product: 0x0192,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x0781,
product: 0x5583,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x0781,
product: 0x5591,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x0781,
product: 0x5596,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x0781,
product: 0x55A3,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x0781,
product: 0x55AE,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x07CA,
product: 0x2553,
flags: UsbQuirkFlags::NO_BOS,
},
UsbQuirkEntry {
vendor: 0x0853,
product: 0x011B,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x08EC,
product: 0x1000,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x0904,
product: 0x6101,
flags: UsbQuirkFlags::LINEAR_FRAME_BINTERVAL,
},
UsbQuirkEntry {
vendor: 0x0904,
product: 0x6102,
flags: UsbQuirkFlags::LINEAR_FRAME_BINTERVAL,
},
UsbQuirkEntry {
vendor: 0x0904,
product: 0x6103,
flags: UsbQuirkFlags::LINEAR_FRAME_BINTERVAL,
},
UsbQuirkEntry {
vendor: 0x090C,
product: 0x1000,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x090C,
product: 0x2000,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x0926,
product: 0x0202,
flags: UsbQuirkFlags::ENDPOINT_IGNORE,
},
UsbQuirkEntry {
vendor: 0x0926,
product: 0x0208,
flags: UsbQuirkFlags::ENDPOINT_IGNORE,
},
UsbQuirkEntry {
vendor: 0x0926,
product: 0x3333,
flags: UsbQuirkFlags::CONFIG_INTF_STRINGS,
},
UsbQuirkEntry {
vendor: 0x0951,
product: 0x1666,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x0930,
product: 0x1408,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x0955,
product: 0x7018,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x0955,
product: 0x7019,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x0955,
product: 0x7418,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x0955,
product: 0x7721,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x0955,
product: 0x7C18,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x0955,
product: 0x7E19,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x0955,
product: 0x7F21,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x0971,
product: 0x2000,
flags: UsbQuirkFlags::NO_SET_INTF,
},
UsbQuirkEntry {
vendor: 0x09A1,
product: 0x0028,
flags: UsbQuirkFlags::DELAY_CTRL_MSG,
},
UsbQuirkEntry {
vendor: 0x0A5C,
product: 0x2021,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x0A92,
product: 0x0091,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x0B05,
product: 0x17E0,
flags: UsbQuirkFlags::IGNORE_REMOTE_WAKEUP,
},
UsbQuirkEntry {
vendor: 0x0B05,
product: 0x1AB9,
flags: UsbQuirkFlags::NO_BOS,
},
UsbQuirkEntry {
vendor: 0x0BDA,
product: 0x0151,
flags: UsbQuirkFlags::CONFIG_INTF_STRINGS,
},
UsbQuirkEntry {
vendor: 0x0BDA,
product: 0x0487,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x0BDA,
product: 0x8153,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x0C45,
product: 0x7056,
flags: UsbQuirkFlags::IGNORE_REMOTE_WAKEUP,
},
UsbQuirkEntry {
vendor: 0x0FD9,
product: 0x009B,
flags: UsbQuirkFlags::NO_BOS,
},
UsbQuirkEntry {
vendor: 0x0FCE,
product: 0x0DDE,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x10D6,
product: 0x2200,
flags: UsbQuirkFlags::NO_STRING_FETCH,
},
UsbQuirkEntry {
vendor: 0x1235,
product: 0x0061,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x1235,
product: 0x8211,
flags: UsbQuirkFlags::NO_SUSPEND,
},
UsbQuirkEntry {
vendor: 0x12D1,
product: 0x15BB,
flags: UsbQuirkFlags::NO_SUSPEND,
},
UsbQuirkEntry {
vendor: 0x12D1,
product: 0x15C1,
flags: UsbQuirkFlags::NO_SUSPEND,
},
UsbQuirkEntry {
vendor: 0x12D1,
product: 0x15C3,
flags: UsbQuirkFlags::NO_SUSPEND,
},
UsbQuirkEntry {
vendor: 0x1516,
product: 0x8628,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x1532,
product: 0x0116,
flags: UsbQuirkFlags::BAD_DESCRIPTOR,
},
UsbQuirkEntry {
vendor: 0x1532,
product: 0x0E05,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x17EF,
product: 0x1018,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x17EF,
product: 0x1019,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x17EF,
product: 0x720C,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x17EF,
product: 0x721E,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x17EF,
product: 0xA012,
flags: UsbQuirkFlags::NO_SUSPEND,
},
UsbQuirkEntry {
vendor: 0x17EF,
product: 0xA387,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x1908,
product: 0x1315,
flags: UsbQuirkFlags::HONOR_BNUMINTERFACES,
},
UsbQuirkEntry {
vendor: 0x1A0A,
product: 0x0200,
flags: UsbQuirkFlags::BAD_DESCRIPTOR,
},
UsbQuirkEntry { UsbQuirkEntry {
vendor: 0x1A40, vendor: 0x1A40,
product: 0x0101, product: 0x0101,
flags: UsbQuirkFlags::HUB_SLOW_RESET,
},
UsbQuirkEntry {
vendor: 0x1B1C,
product: 0x1B13,
flags: F_02,
},
UsbQuirkEntry {
vendor: 0x1B1C,
product: 0x1B15,
flags: F_02,
},
UsbQuirkEntry {
vendor: 0x1B1C,
product: 0x1B20,
flags: F_02,
},
UsbQuirkEntry {
vendor: 0x1B1C,
product: 0x1B33,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x1B1C,
product: 0x1B36,
flags: UsbQuirkFlags::RESET_DELAY,
},
UsbQuirkEntry {
vendor: 0x1B1C,
product: 0x1B38,
flags: F_02,
},
UsbQuirkEntry {
vendor: 0x1BC3,
product: 0x0003,
flags: UsbQuirkFlags::NO_SET_INTF,
},
UsbQuirkEntry {
vendor: 0x1C75,
product: 0x0204,
flags: UsbQuirkFlags::CONFIG_INTF_STRINGS,
},
UsbQuirkEntry {
vendor: 0x1DE1,
product: 0xC102,
flags: UsbQuirkFlags::NO_LPM, flags: UsbQuirkFlags::NO_LPM,
}, },
UsbQuirkEntry { UsbQuirkEntry {
vendor: 0x2109, vendor: 0x1EDB,
product: 0x2813, product: 0xBD3B,
flags: UsbQuirkFlags::NO_LPM, flags: UsbQuirkFlags::NO_LPM,
}, },
UsbQuirkEntry { UsbQuirkEntry {
vendor: 0x2109, vendor: 0x1EDB,
product: 0x0815, product: 0xBD4F,
flags: UsbQuirkFlags::NO_U1U2, flags: UsbQuirkFlags::NO_LPM,
}, },
UsbQuirkEntry { UsbQuirkEntry {
vendor: 0x8087, vendor: 0x1F75,
product: 0x0025, product: 0x0917,
flags: UsbQuirkFlags::NO_SUSPEND, flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x2040,
product: 0x7200,
flags: UsbQuirkFlags::CONFIG_INTF_STRINGS,
},
UsbQuirkEntry {
vendor: 0x2109,
product: 0x0711,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x2386,
product: 0x3114,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x2386,
product: 0x3119,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x2386,
product: 0x350E,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x2B89,
product: 0x5871,
flags: UsbQuirkFlags::NO_BOS,
},
UsbQuirkEntry {
vendor: 0x2C48,
product: 0x0132,
flags: UsbQuirkFlags::SHORT_SET_ADDR_TIMEOUT,
},
UsbQuirkEntry {
vendor: 0x2CA3,
product: 0x0031,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x2CE3,
product: 0x9563,
flags: UsbQuirkFlags::NO_LPM,
},
UsbQuirkEntry {
vendor: 0x32ED,
product: 0x0401,
flags: UsbQuirkFlags::NO_BOS,
},
UsbQuirkEntry {
vendor: 0x413C,
product: 0xB062,
flags: F_00,
},
UsbQuirkEntry {
vendor: 0x4296,
product: 0x7570,
flags: UsbQuirkFlags::CONFIG_INTF_STRINGS,
},
UsbQuirkEntry {
vendor: 0x5131,
product: 0x2007,
flags: UsbQuirkFlags::FORCE_ONE_CONFIG,
},
UsbQuirkEntry {
vendor: 0x8086,
product: 0xF1A5,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x17EF,
product: 0x602E,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x093A,
product: 0x2500,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x093A,
product: 0x2510,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x093A,
product: 0x2521,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x03F0,
product: 0x2B4A,
flags: UsbQuirkFlags::NEED_RESET,
},
UsbQuirkEntry {
vendor: 0x046D,
product: 0xC05A,
flags: UsbQuirkFlags::NEED_RESET,
}, },
UsbQuirkEntry { UsbQuirkEntry {
vendor: 0x8087, vendor: 0x8087,
product: 0x0A2B, product: 0x0A2B,
flags: F_NO_SUSP_RESET, flags: F_03,
},
UsbQuirkEntry {
vendor: 0x0A12,
product: PCI_QUIRK_ANY_ID,
flags: F_BAD_DESC_NO_CFG,
}, },
]; ];
@@ -1,28 +1,764 @@
# USB controller and device quirks. # USB device quirks mined from Linux 7.0 (drivers/usb/core/quirks.c).
# Generated by local/scripts/extract-linux-quirks.py.
# Includes: usb_quirk_list (64 entries) + usb_amd_resume_quirk_list (5 entries) = 146 total.
[[usb_quirk]]
vendor = 0x0204
product = 0x6025
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x0218
product = 0x0201
flags = ["config_intf_strings"]
[[usb_quirk]]
vendor = 0x0218
product = 0x0401
flags = ["config_intf_strings"]
[[usb_quirk]]
vendor = 0x03F0
product = 0x0701
flags = ["no_string_fetch"]
[[usb_quirk]]
vendor = 0x03F0
product = 0x3F40
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x03F0
product = 0xA31D
flags = ["no_suspend"]
[[usb_quirk]]
vendor = 0x041E
product = 0x3020
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x0424
product = 0x3503
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x045E
product = 0x00E1
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x045E
product = 0x0770
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x045E
product = 0x07C6
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x046A
product = 0x0023
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x046D
product = 0x0825
flags = ["need_reset", "no_lpm"]
[[usb_quirk]]
vendor = 0x046D
product = 0x082D
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x046D
product = 0x0841
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x046D
product = 0x0843
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x046D
product = 0x085B
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x046D
product = 0x085C
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x046D
product = 0x0847
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x046D
product = 0x0848
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x046D
product = 0x0853
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x046D
product = 0x086C
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x046D
product = 0x08C1
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x046D
product = 0x08C2
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x046D
product = 0x08C3
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x046D
product = 0x08C5
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x046D
product = 0x08C6
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x046D
product = 0x08C7
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x046D
product = 0xC122
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x0471
product = 0x0155
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x047F
product = 0xC008
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x047F
product = 0xC013
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x04B4
product = 0x0526
flags = ["config_intf_strings"]
[[usb_quirk]]
vendor = 0x04D8
product = 0x000C
flags = ["config_intf_strings"]
[[usb_quirk]]
vendor = 0x04E7
product = 0x0009
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x04E7
product = 0x0030
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x04E8
product = 0x6601
flags = ["config_intf_strings"]
[[usb_quirk]]
vendor = 0x04F3
product = 0x0089
flags = ["device_qualifier"]
[[usb_quirk]]
vendor = 0x04F3
product = 0x009B
flags = ["device_qualifier"]
[[usb_quirk]]
vendor = 0x04F3
product = 0x010C
flags = ["device_qualifier"]
[[usb_quirk]]
vendor = 0x04F3
product = 0x0125
flags = ["device_qualifier"]
[[usb_quirk]]
vendor = 0x04F3
product = 0x016F
flags = ["device_qualifier"]
[[usb_quirk]]
vendor = 0x04F3
product = 0x0381
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x04F3
product = 0x21B8
flags = ["device_qualifier"]
[[usb_quirk]]
vendor = 0x0582
product = 0x0007
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x0582
product = 0x0027
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x058F
product = 0x9254
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x05AC
product = 0x021A
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x05E3
product = 0x0612
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x05CC
product = 0x2267
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x05E3
product = 0x0616
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x0638
product = 0x0A13
flags = ["no_string_fetch"]
[[usb_quirk]]
vendor = 0x067B
product = 0x2731
flags = ["reset_delay", "no_lpm"]
[[usb_quirk]]
vendor = 0x06A3
product = 0x0006
flags = ["config_intf_strings"]
[[usb_quirk]]
vendor = 0x06BD
product = 0x0001
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x06F8
product = 0x0804
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x06F8
product = 0x3005
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x06F8
product = 0xB000
flags = ["endpoint_ignore"]
[[usb_quirk]]
vendor = 0x0763
product = 0x0192
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x0781
product = 0x5583
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x0781
product = 0x5591
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x0781
product = 0x5596
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x0781
product = 0x55A3
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x0781
product = 0x55AE
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x07CA
product = 0x2553
flags = ["no_bos"]
[[usb_quirk]]
vendor = 0x0853
product = 0x011B
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x08EC
product = 0x1000
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x0904
product = 0x6101
flags = ["linear_frame_binterval"]
[[usb_quirk]]
vendor = 0x0904
product = 0x6102
flags = ["linear_frame_binterval"]
[[usb_quirk]]
vendor = 0x0904
product = 0x6103
flags = ["linear_frame_binterval"]
[[usb_quirk]]
vendor = 0x090C
product = 0x1000
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x090C
product = 0x2000
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x0926
product = 0x0202
flags = ["endpoint_ignore"]
[[usb_quirk]]
vendor = 0x0926
product = 0x0208
flags = ["endpoint_ignore"]
[[usb_quirk]]
vendor = 0x0926
product = 0x3333
flags = ["config_intf_strings"]
[[usb_quirk]]
vendor = 0x0951
product = 0x1666
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x0930
product = 0x1408
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x0955
product = 0x7018
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x0955
product = 0x7019
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x0955
product = 0x7418
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x0955
product = 0x7721
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x0955
product = 0x7C18
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x0955
product = 0x7E19
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x0955
product = 0x7F21
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x0971
product = 0x2000
flags = ["no_set_intf"]
[[usb_quirk]]
vendor = 0x09A1
product = 0x0028
flags = ["delay_ctrl_msg"]
[[usb_quirk]]
vendor = 0x0A5C
product = 0x2021
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x0A92
product = 0x0091
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x0B05
product = 0x17E0
flags = ["ignore_remote_wakeup"]
[[usb_quirk]]
vendor = 0x0B05
product = 0x1AB9
flags = ["no_bos"]
[[usb_quirk]]
vendor = 0x0BDA
product = 0x0151
flags = ["config_intf_strings"]
[[usb_quirk]]
vendor = 0x0BDA
product = 0x0487
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x0BDA
product = 0x8153
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x0C45
product = 0x7056
flags = ["ignore_remote_wakeup"]
[[usb_quirk]]
vendor = 0x0FD9
product = 0x009B
flags = ["no_bos"]
[[usb_quirk]]
vendor = 0x0FCE
product = 0x0DDE
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x10D6
product = 0x2200
flags = ["no_string_fetch"]
[[usb_quirk]]
vendor = 0x1235
product = 0x0061
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x1235
product = 0x8211
flags = ["no_suspend"]
[[usb_quirk]]
vendor = 0x12D1
product = 0x15BB
flags = ["no_suspend"]
[[usb_quirk]]
vendor = 0x12D1
product = 0x15C1
flags = ["no_suspend"]
[[usb_quirk]]
vendor = 0x12D1
product = 0x15C3
flags = ["no_suspend"]
[[usb_quirk]]
vendor = 0x1516
product = 0x8628
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x1532
product = 0x0116
flags = ["bad_descriptor"]
[[usb_quirk]]
vendor = 0x1532
product = 0x0E05
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x17EF
product = 0x1018
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x17EF
product = 0x1019
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x17EF
product = 0x720C
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x17EF
product = 0x721E
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x17EF
product = 0xA012
flags = ["no_suspend"]
[[usb_quirk]]
vendor = 0x17EF
product = 0xA387
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x1908
product = 0x1315
flags = ["honor_bnuminterfaces"]
[[usb_quirk]]
vendor = 0x1A0A
product = 0x0200
flags = ["bad_descriptor"]
[[usb_quirk]] [[usb_quirk]]
vendor = 0x1A40 vendor = 0x1A40
product = 0x0101 product = 0x0101
flags = ["hub_slow_reset"]
[[usb_quirk]]
vendor = 0x1B1C
product = 0x1B13
flags = ["reset_delay", "delay_ctrl_msg"]
[[usb_quirk]]
vendor = 0x1B1C
product = 0x1B15
flags = ["reset_delay", "delay_ctrl_msg"]
[[usb_quirk]]
vendor = 0x1B1C
product = 0x1B20
flags = ["reset_delay", "delay_ctrl_msg"]
[[usb_quirk]]
vendor = 0x1B1C
product = 0x1B33
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x1B1C
product = 0x1B36
flags = ["reset_delay"]
[[usb_quirk]]
vendor = 0x1B1C
product = 0x1B38
flags = ["reset_delay", "delay_ctrl_msg"]
[[usb_quirk]]
vendor = 0x1BC3
product = 0x0003
flags = ["no_set_intf"]
[[usb_quirk]]
vendor = 0x1C75
product = 0x0204
flags = ["config_intf_strings"]
[[usb_quirk]]
vendor = 0x1DE1
product = 0xC102
flags = ["no_lpm"] flags = ["no_lpm"]
[[usb_quirk]] [[usb_quirk]]
vendor = 0x2109 vendor = 0x1EDB
product = 0x2813 product = 0xBD3B
flags = ["no_lpm"] flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x1EDB
product = 0xBD4F
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x1F75
product = 0x0917
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x2040
product = 0x7200
flags = ["config_intf_strings"]
[[usb_quirk]]
vendor = 0x2109
product = 0x0711
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x2386
product = 0x3114
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x2386
product = 0x3119
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x2386
product = 0x350E
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x2B89
product = 0x5871
flags = ["no_bos"]
[[usb_quirk]]
vendor = 0x2C48
product = 0x0132
flags = ["short_set_addr_timeout"]
[[usb_quirk]]
vendor = 0x2CA3
product = 0x0031
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x2CE3
product = 0x9563
flags = ["no_lpm"]
[[usb_quirk]]
vendor = 0x32ED
product = 0x0401
flags = ["no_bos"]
[[usb_quirk]]
vendor = 0x413C
product = 0xB062
flags = ["need_reset", "no_lpm"]
[[usb_quirk]]
vendor = 0x4296
product = 0x7570
flags = ["config_intf_strings"]
[[usb_quirk]]
vendor = 0x5131
product = 0x2007
flags = ["force_one_config"]
[[usb_quirk]]
vendor = 0x8086
product = 0xF1A5
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x17EF
product = 0x602E
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x093A
product = 0x2500
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x093A
product = 0x2510
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x093A
product = 0x2521
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x03F0
product = 0x2B4A
flags = ["need_reset"]
[[usb_quirk]]
vendor = 0x046D
product = 0xC05A
flags = ["need_reset"]
# Red Bear OS specific entries (not in Linux upstream).
[[usb_quirk]]
vendor = 0x8087
product = 0x0025
flags = ["no_suspend"]
[[usb_quirk]]
vendor = 0x0A12
flags = ["bad_descriptor", "no_set_config"]
[[usb_quirk]] [[usb_quirk]]
vendor = 0x2109 vendor = 0x2109
product = 0x0815 product = 0x0815
flags = ["no_u1u2"] flags = ["no_u1u2"]
[[usb_quirk]]
vendor = 0x0BDA
product = 0x8156
flags = ["no_string_fetch"]
[[usb_quirk]] [[usb_quirk]]
vendor = 0x8087 vendor = 0x8087
product = 0x0A2B product = 0x0A2B
flags = ["no_suspend", "need_reset"] flags = ["no_suspend", "need_reset"]
[[usb_quirk]] # PCI USB controller quirks (Red Bear OS specific).
vendor = 0x0A12
flags = ["bad_descriptor", "no_set_config"]
[[pci_quirk]] [[pci_quirk]]
vendor = 0x1022 vendor = 0x1022
@@ -38,3 +774,4 @@ flags = ["no_aspm"]
vendor = 0x8086 vendor = 0x8086
device = 0x7AE0 device = 0x7AE0
flags = ["reset_delay_ms"] flags = ["reset_delay_ms"]
File diff suppressed because it is too large Load Diff
+111 -7
View File
@@ -4,6 +4,7 @@
Usage: Usage:
python3 extract-linux-quirks.py /path/to/linux/drivers/pci/quirks.c python3 extract-linux-quirks.py /path/to/linux/drivers/pci/quirks.c
python3 extract-linux-quirks.py /path/to/linux/drivers/usb/core/quirks.c python3 extract-linux-quirks.py /path/to/linux/drivers/usb/core/quirks.c
python3 extract-linux-quirks.py /path/to/linux/drivers/usb/storage/unusual_devs.h
Outputs TOML quirk entries to stdout that can be appended to files in Outputs TOML quirk entries to stdout that can be appended to files in
/etc/quirks.d/ or local/recipes/system/redbear-quirks/source/quirks.d/. /etc/quirks.d/ or local/recipes/system/redbear-quirks/source/quirks.d/.
@@ -27,14 +28,25 @@ PCI_FLAG_MAP = {
} }
USB_FLAG_MAP = { USB_FLAG_MAP = {
"USB_QUIRK_STRING_FETCH": "no_string_fetch", "USB_QUIRK_STRING_FETCH_255": "no_string_fetch",
"USB_QUIRK_NO_RESET_RESUME": "need_reset", "USB_QUIRK_RESET_RESUME": "need_reset",
"USB_QUIRK_NO_SET_INTF": "no_set_config", "USB_QUIRK_NO_SET_INTF": "no_set_intf",
"USB_QUIRK_NO_LPM": "no_lpm", "USB_QUIRK_CONFIG_INTF_STRINGS": "config_intf_strings",
"USB_QUIRK_NO_U1_U2": "no_u1u2", "USB_QUIRK_RESET": "no_reset",
"USB_QUIRK_HONOR_BNUMINTERFACES": "honor_bnuminterfaces",
"USB_QUIRK_DELAY_INIT": "reset_delay", "USB_QUIRK_DELAY_INIT": "reset_delay",
"USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL": "bad_descriptor", "USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL": "bad_descriptor",
"USB_QUIRK_DEVICE_QUALIFIER": "device_qualifier",
"USB_QUIRK_IGNORE_REMOTE_WAKEUP": "ignore_remote_wakeup",
"USB_QUIRK_NO_LPM": "no_lpm",
"USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL": "linear_frame_binterval",
"USB_QUIRK_DISCONNECT_SUSPEND": "no_suspend", "USB_QUIRK_DISCONNECT_SUSPEND": "no_suspend",
"USB_QUIRK_DELAY_CTRL_MSG": "delay_ctrl_msg",
"USB_QUIRK_HUB_SLOW_RESET": "hub_slow_reset",
"USB_QUIRK_ENDPOINT_IGNORE": "endpoint_ignore",
"USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT": "short_set_addr_timeout",
"USB_QUIRK_NO_BOS": "no_bos",
"USB_QUIRK_FORCE_ONE_CONFIG": "force_one_config",
} }
PCI_FIXUP_RE = re.compile( PCI_FIXUP_RE = re.compile(
@@ -73,7 +85,8 @@ def extract_usb_quirks(source):
flags_raw = m.group(3) flags_raw = m.group(3)
flags = [] flags = []
for flag_name, toml_name in USB_FLAG_MAP.items(): for flag_name, toml_name in USB_FLAG_MAP.items():
if flag_name in flags_raw: pattern = re.escape(flag_name) + r'(?:\s|$|\||\))'
if re.search(pattern, flags_raw):
flags.append(toml_name) flags.append(toml_name)
entries.append((vendor, product, flags)) entries.append((vendor, product, flags))
return entries return entries
@@ -109,6 +122,91 @@ def format_usb_toml(entries):
return "\n".join(lines) return "\n".join(lines)
STORAGE_FLAG_MAP = {
"US_FL_IGNORE_RESIDUE": "ignore_residue",
"US_FL_FIX_CAPACITY": "fix_capacity",
"US_FL_SINGLE_LUN": "single_lun",
"US_FL_MAX_SECTORS_64": "max_sectors_64",
"US_FL_FIX_INQUIRY": "fix_inquiry",
"US_FL_GO_SLOW": "go_slow",
"US_FL_SANE_SENSE": "sane_sense",
"US_FL_BAD_SENSE": "bad_sense",
"US_FL_NOT_LOCKABLE": "not_lockable",
"US_FL_NO_WP_DETECT": "no_wp_detect",
"US_FL_IGNORE_DEVICE": "ignore_device",
"US_FL_IGNORE_UAS": "ignore_uas",
"US_FL_CAPACITY_HEURISTICS": "capacity_heuristics",
"US_FL_CAPACITY_OK": "capacity_ok",
"US_FL_BROKEN_FUA": "broken_fua",
"US_FL_BULK_IGNORE_TAG": "bulk_ignore_tag",
"US_FL_BULK32": "bulk32",
"US_FL_NEED_OVERRIDE": "need_override",
"US_FL_NO_READ_CAPACITY_16": "no_read_cap16",
"US_FL_NO_REPORT_OPCODES": "no_report_opcodes",
"US_FL_NO_READ_DISC_INFO": "no_read_disc_info",
"US_FL_INITIAL_READ10": "initial_read10",
"US_FL_WRITE_CACHE": "write_cache",
"US_FL_SCM_MULT_TARG": "scm_mult_targ",
"US_FL_ALWAYS_SYNC": "always_sync",
"US_FL_SENSE_AFTER_SYNC": "sense_after_sync",
"US_FL_NO_ATA_1X": "no_ata_1x",
"US_FL_NEEDS_CAP16": "needs_cap16",
"US_FL_MAX_SECTORS_MIN": "max_sectors_min",
}
UNUSUAL_DEV_RE = re.compile(
r'UNUSUAL_DEV\s*\(\s*'
r'0x([0-9a-fA-F]+)\s*,\s*'
r'0x([0-9a-fA-F]+)\s*,\s*'
r'0x([0-9a-fA-F]+)\s*,\s*'
r'0x([0-9a-fA-F]+)\s*,\s*'
r'"([^"]*)"\s*,\s*'
r'"([^"]*)"\s*,\s*'
r'[^,]+,\s*[^,]+,\s*[^,]*,\s*'
r'([^)]+)\)',
re.MULTILINE | re.DOTALL
)
def extract_storage_quirks(source):
entries = []
for m in UNUSUAL_DEV_RE.finditer(source):
vendor = int(m.group(1), 16)
product = int(m.group(2), 16)
rev_lo = m.group(3)
rev_hi = m.group(4)
mfr = m.group(5)
product_name = m.group(6)
flags_raw = m.group(7)
flags = []
for flag_name, toml_name in STORAGE_FLAG_MAP.items():
if flag_name in flags_raw:
flags.append(toml_name)
entries.append((vendor, product, rev_lo, rev_hi, mfr, product_name, flags))
return entries
def format_storage_toml(entries):
lines = []
lines.append("# USB mass storage device quirks from Linux unusual_devs.h.")
lines.append("# Type: [[usb_storage_quirk]] with vendor, product, flags, and metadata fields.")
lines.append("")
for vendor, product, rev_lo, rev_hi, mfr, product_name, flags in entries:
if not flags:
continue
lines.append("[[usb_storage_quirk]]")
lines.append(f"vendor = 0x{vendor:04X}")
lines.append(f"product = 0x{product:04X}")
lines.append(f'revision = "{rev_lo}-{rev_hi}"')
if mfr:
lines.append(f'manufacturer = "{mfr}"')
if product_name:
lines.append(f'description = "{product_name}"')
lines.append(f'flags = [{", ".join(f"\"{f}\"" for f in flags)}]')
lines.append("")
return "\n".join(lines)
def main(): def main():
if len(sys.argv) < 2: if len(sys.argv) < 2:
print(__doc__, file=sys.stderr) print(__doc__, file=sys.stderr)
@@ -118,7 +216,13 @@ def main():
with open(path) as f: with open(path) as f:
source = f.read() source = f.read()
if "usb_quirk" in source.lower() or "USB_QUIRK" in source: if "UNUSUAL_DEV" in source:
entries = extract_storage_quirks(source)
total = len(entries)
with_flags = sum(1 for e in entries if e[6])
print(f"# Extracted {with_flags} entries with flags out of {total} total from unusual_devs.h")
print(format_storage_toml(entries))
elif "usb_quirk" in source.lower() or "USB_QUIRK" in source:
entries = extract_usb_quirks(source) entries = extract_usb_quirks(source)
print(format_usb_toml(entries)) print(format_usb_toml(entries))
else: else: