[PATCH v3 4/5] rust: usb: add a vendor-and-interface-info device id constructor
Mike Lothian <[email protected]>
| Newsgroups | org.kernel.vger.rust-for-linux,org.kernel.vger.linux-kernel,org.kernel.vger.linux-usb |
|---|---|
| Message-ID | <[email protected]> |
`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 <[email protected]> --- 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 {