[PATCH v3 4/5] rust: usb: add a vendor-and-interface-info device id constructor

From: Mike Lothian

Date: Wed Aug 26 2026 - 12:33:12 EST


`USB_VENDOR_AND_INTERFACE_INFO` is the C macro a driver uses to bind to
a function rather than to a list of product IDs: one vendor, plus an
interface class, subclass and protocol, matching every product that
exposes it.

The existing constructors cover `USB_DEVICE_INFO` and
`USB_INTERFACE_INFO`, which between them can express "any device of this
class" or "any interface of this class from any vendor", but not the
combination -- and the combination is what a vendor-specific function
needs, because class `0xff` means nothing without the vendor beside it.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Mike Lothian <mike@xxxxxxxxxxxxxx>
---
rust/kernel/usb.rs | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)

diff --git a/rust/kernel/usb.rs b/rust/kernel/usb.rs
index 782bae53584d..b2a0fb104ddf 100644
--- a/rust/kernel/usb.rs
+++ b/rust/kernel/usb.rs
@@ -307,6 +307,29 @@ pub const fn from_interface_info(class: u8, subclass: u8, protocol: u8) -> Self
})
}

+ /// Equivalent to C's `USB_VENDOR_AND_INTERFACE_INFO` macro.
+ ///
+ /// Matches every device from one vendor that exposes an interface of the given class,
+ /// subclass and protocol, whatever its product ID. This is how a driver binds to a *function*
+ /// rather than to a list of the products someone happened to test.
+ pub const fn from_vendor_and_interface_info(
+ vendor: u16,
+ class: u8,
+ subclass: u8,
+ protocol: u8,
+ ) -> Self {
+ Self(bindings::usb_device_id {
+ match_flags: (bindings::USB_DEVICE_ID_MATCH_VENDOR
+ | bindings::USB_DEVICE_ID_MATCH_INT_INFO) as u16,
+ idVendor: vendor,
+ bInterfaceClass: class,
+ bInterfaceSubClass: subclass,
+ bInterfaceProtocol: protocol,
+ // SAFETY: It is safe to use all zeroes for the other fields of `usb_device_id`.
+ ..unsafe { MaybeUninit::zeroed().assume_init() }
+ })
+ }
+
/// Equivalent to C's `USB_DEVICE_INTERFACE_CLASS` macro.
pub const fn from_device_interface_class(vendor: u16, product: u16, class: u8) -> Self {
Self(bindings::usb_device_id {