kernel/
usb.rs

1// SPDX-License-Identifier: GPL-2.0
2// SPDX-FileCopyrightText: Copyright (C) 2025 Collabora Ltd.
3
4//! Abstractions for the USB bus.
5//!
6//! C header: [`include/linux/usb.h`](srctree/include/linux/usb.h)
7
8use crate::{
9    bindings, device,
10    device_id::{RawDeviceId, RawDeviceIdIndex},
11    driver,
12    error::{from_result, to_result, Result},
13    prelude::*,
14    str::CStr,
15    types::{AlwaysRefCounted, Opaque},
16    ThisModule,
17};
18use core::{marker::PhantomData, mem::MaybeUninit, ptr::NonNull};
19
20/// An adapter for the registration of USB drivers.
21pub struct Adapter<T: Driver>(T);
22
23// SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if
24// a preceding call to `register` has been successful.
25unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> {
26    type RegType = bindings::usb_driver;
27
28    unsafe fn register(
29        udrv: &Opaque<Self::RegType>,
30        name: &'static CStr,
31        module: &'static ThisModule,
32    ) -> Result {
33        // SAFETY: It's safe to set the fields of `struct usb_driver` on initialization.
34        unsafe {
35            (*udrv.get()).name = name.as_char_ptr();
36            (*udrv.get()).probe = Some(Self::probe_callback);
37            (*udrv.get()).disconnect = Some(Self::disconnect_callback);
38            (*udrv.get()).id_table = T::ID_TABLE.as_ptr();
39        }
40
41        // SAFETY: `udrv` is guaranteed to be a valid `RegType`.
42        to_result(unsafe {
43            bindings::usb_register_driver(udrv.get(), module.0, name.as_char_ptr())
44        })
45    }
46
47    unsafe fn unregister(udrv: &Opaque<Self::RegType>) {
48        // SAFETY: `udrv` is guaranteed to be a valid `RegType`.
49        unsafe { bindings::usb_deregister(udrv.get()) };
50    }
51}
52
53impl<T: Driver + 'static> Adapter<T> {
54    extern "C" fn probe_callback(
55        intf: *mut bindings::usb_interface,
56        id: *const bindings::usb_device_id,
57    ) -> kernel::ffi::c_int {
58        // SAFETY: The USB core only ever calls the probe callback with a valid pointer to a
59        // `struct usb_interface` and `struct usb_device_id`.
60        //
61        // INVARIANT: `intf` is valid for the duration of `probe_callback()`.
62        let intf = unsafe { &*intf.cast::<Interface<device::CoreInternal>>() };
63
64        from_result(|| {
65            // SAFETY: `DeviceId` is a `#[repr(transparent)]` wrapper of `struct usb_device_id` and
66            // does not add additional invariants, so it's safe to transmute.
67            let id = unsafe { &*id.cast::<DeviceId>() };
68
69            let info = T::ID_TABLE.info(id.index());
70            let data = T::probe(intf, id, info)?;
71
72            let dev: &device::Device<device::CoreInternal> = intf.as_ref();
73            dev.set_drvdata(data);
74            Ok(0)
75        })
76    }
77
78    extern "C" fn disconnect_callback(intf: *mut bindings::usb_interface) {
79        // SAFETY: The USB core only ever calls the disconnect callback with a valid pointer to a
80        // `struct usb_interface`.
81        //
82        // INVARIANT: `intf` is valid for the duration of `disconnect_callback()`.
83        let intf = unsafe { &*intf.cast::<Interface<device::CoreInternal>>() };
84
85        let dev: &device::Device<device::CoreInternal> = intf.as_ref();
86
87        // SAFETY: `disconnect_callback` is only ever called after a successful call to
88        // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called
89        // and stored a `Pin<KBox<T>>`.
90        let data = unsafe { dev.drvdata_obtain::<Pin<KBox<T>>>() };
91
92        T::disconnect(intf, data.as_ref());
93    }
94}
95
96/// Abstraction for the USB device ID structure, i.e. [`struct usb_device_id`].
97///
98/// [`struct usb_device_id`]: https://docs.kernel.org/driver-api/basics.html#c.usb_device_id
99#[repr(transparent)]
100#[derive(Clone, Copy)]
101pub struct DeviceId(bindings::usb_device_id);
102
103impl DeviceId {
104    /// Equivalent to C's `USB_DEVICE` macro.
105    pub const fn from_id(vendor: u16, product: u16) -> Self {
106        Self(bindings::usb_device_id {
107            match_flags: bindings::USB_DEVICE_ID_MATCH_DEVICE as u16,
108            idVendor: vendor,
109            idProduct: product,
110            // SAFETY: It is safe to use all zeroes for the other fields of `usb_device_id`.
111            ..unsafe { MaybeUninit::zeroed().assume_init() }
112        })
113    }
114
115    /// Equivalent to C's `USB_DEVICE_VER` macro.
116    pub const fn from_device_ver(vendor: u16, product: u16, bcd_lo: u16, bcd_hi: u16) -> Self {
117        Self(bindings::usb_device_id {
118            match_flags: bindings::USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION as u16,
119            idVendor: vendor,
120            idProduct: product,
121            bcdDevice_lo: bcd_lo,
122            bcdDevice_hi: bcd_hi,
123            // SAFETY: It is safe to use all zeroes for the other fields of `usb_device_id`.
124            ..unsafe { MaybeUninit::zeroed().assume_init() }
125        })
126    }
127
128    /// Equivalent to C's `USB_DEVICE_INFO` macro.
129    pub const fn from_device_info(class: u8, subclass: u8, protocol: u8) -> Self {
130        Self(bindings::usb_device_id {
131            match_flags: bindings::USB_DEVICE_ID_MATCH_DEV_INFO as u16,
132            bDeviceClass: class,
133            bDeviceSubClass: subclass,
134            bDeviceProtocol: protocol,
135            // SAFETY: It is safe to use all zeroes for the other fields of `usb_device_id`.
136            ..unsafe { MaybeUninit::zeroed().assume_init() }
137        })
138    }
139
140    /// Equivalent to C's `USB_INTERFACE_INFO` macro.
141    pub const fn from_interface_info(class: u8, subclass: u8, protocol: u8) -> Self {
142        Self(bindings::usb_device_id {
143            match_flags: bindings::USB_DEVICE_ID_MATCH_INT_INFO as u16,
144            bInterfaceClass: class,
145            bInterfaceSubClass: subclass,
146            bInterfaceProtocol: protocol,
147            // SAFETY: It is safe to use all zeroes for the other fields of `usb_device_id`.
148            ..unsafe { MaybeUninit::zeroed().assume_init() }
149        })
150    }
151
152    /// Equivalent to C's `USB_DEVICE_INTERFACE_CLASS` macro.
153    pub const fn from_device_interface_class(vendor: u16, product: u16, class: u8) -> Self {
154        Self(bindings::usb_device_id {
155            match_flags: (bindings::USB_DEVICE_ID_MATCH_DEVICE
156                | bindings::USB_DEVICE_ID_MATCH_INT_CLASS) as u16,
157            idVendor: vendor,
158            idProduct: product,
159            bInterfaceClass: class,
160            // SAFETY: It is safe to use all zeroes for the other fields of `usb_device_id`.
161            ..unsafe { MaybeUninit::zeroed().assume_init() }
162        })
163    }
164
165    /// Equivalent to C's `USB_DEVICE_INTERFACE_PROTOCOL` macro.
166    pub const fn from_device_interface_protocol(vendor: u16, product: u16, protocol: u8) -> Self {
167        Self(bindings::usb_device_id {
168            match_flags: (bindings::USB_DEVICE_ID_MATCH_DEVICE
169                | bindings::USB_DEVICE_ID_MATCH_INT_PROTOCOL) as u16,
170            idVendor: vendor,
171            idProduct: product,
172            bInterfaceProtocol: protocol,
173            // SAFETY: It is safe to use all zeroes for the other fields of `usb_device_id`.
174            ..unsafe { MaybeUninit::zeroed().assume_init() }
175        })
176    }
177
178    /// Equivalent to C's `USB_DEVICE_INTERFACE_NUMBER` macro.
179    pub const fn from_device_interface_number(vendor: u16, product: u16, number: u8) -> Self {
180        Self(bindings::usb_device_id {
181            match_flags: (bindings::USB_DEVICE_ID_MATCH_DEVICE
182                | bindings::USB_DEVICE_ID_MATCH_INT_NUMBER) as u16,
183            idVendor: vendor,
184            idProduct: product,
185            bInterfaceNumber: number,
186            // SAFETY: It is safe to use all zeroes for the other fields of `usb_device_id`.
187            ..unsafe { MaybeUninit::zeroed().assume_init() }
188        })
189    }
190
191    /// Equivalent to C's `USB_DEVICE_AND_INTERFACE_INFO` macro.
192    pub const fn from_device_and_interface_info(
193        vendor: u16,
194        product: u16,
195        class: u8,
196        subclass: u8,
197        protocol: u8,
198    ) -> Self {
199        Self(bindings::usb_device_id {
200            match_flags: (bindings::USB_DEVICE_ID_MATCH_INT_INFO
201                | bindings::USB_DEVICE_ID_MATCH_DEVICE) as u16,
202            idVendor: vendor,
203            idProduct: product,
204            bInterfaceClass: class,
205            bInterfaceSubClass: subclass,
206            bInterfaceProtocol: protocol,
207            // SAFETY: It is safe to use all zeroes for the other fields of `usb_device_id`.
208            ..unsafe { MaybeUninit::zeroed().assume_init() }
209        })
210    }
211}
212
213// SAFETY: `DeviceId` is a `#[repr(transparent)]` wrapper of `usb_device_id` and does not add
214// additional invariants, so it's safe to transmute to `RawType`.
215unsafe impl RawDeviceId for DeviceId {
216    type RawType = bindings::usb_device_id;
217}
218
219// SAFETY: `DRIVER_DATA_OFFSET` is the offset to the `driver_info` field.
220unsafe impl RawDeviceIdIndex for DeviceId {
221    const DRIVER_DATA_OFFSET: usize = core::mem::offset_of!(bindings::usb_device_id, driver_info);
222
223    fn index(&self) -> usize {
224        self.0.driver_info
225    }
226}
227
228/// [`IdTable`](kernel::device_id::IdTable) type for USB.
229pub type IdTable<T> = &'static dyn kernel::device_id::IdTable<DeviceId, T>;
230
231/// Create a USB `IdTable` with its alias for modpost.
232#[macro_export]
233macro_rules! usb_device_table {
234    ($table_name:ident, $module_table_name:ident, $id_info_type: ty, $table_data: expr) => {
235        const $table_name: $crate::device_id::IdArray<
236            $crate::usb::DeviceId,
237            $id_info_type,
238            { $table_data.len() },
239        > = $crate::device_id::IdArray::new($table_data);
240
241        $crate::module_device_table!("usb", $module_table_name, $table_name);
242    };
243}
244
245/// The USB driver trait.
246///
247/// # Examples
248///
249///```
250/// # use kernel::{bindings, device::Core, usb};
251/// use kernel::prelude::*;
252///
253/// struct MyDriver;
254///
255/// kernel::usb_device_table!(
256///     USB_TABLE,
257///     MODULE_USB_TABLE,
258///     <MyDriver as usb::Driver>::IdInfo,
259///     [
260///         (usb::DeviceId::from_id(0x1234, 0x5678), ()),
261///         (usb::DeviceId::from_id(0xabcd, 0xef01), ()),
262///     ]
263/// );
264///
265/// impl usb::Driver for MyDriver {
266///     type IdInfo = ();
267///     const ID_TABLE: usb::IdTable<Self::IdInfo> = &USB_TABLE;
268///
269///     fn probe(
270///         _interface: &usb::Interface<Core>,
271///         _id: &usb::DeviceId,
272///         _info: &Self::IdInfo,
273///     ) -> Result<Pin<KBox<Self>>> {
274///         Err(ENODEV)
275///     }
276///
277///     fn disconnect(_interface: &usb::Interface<Core>, _data: Pin<&Self>) {}
278/// }
279///```
280pub trait Driver {
281    /// The type holding information about each one of the device ids supported by the driver.
282    type IdInfo: 'static;
283
284    /// The table of device ids supported by the driver.
285    const ID_TABLE: IdTable<Self::IdInfo>;
286
287    /// USB driver probe.
288    ///
289    /// Called when a new USB interface is bound to this driver.
290    /// Implementers should attempt to initialize the interface here.
291    fn probe(
292        interface: &Interface<device::Core>,
293        id: &DeviceId,
294        id_info: &Self::IdInfo,
295    ) -> Result<Pin<KBox<Self>>>;
296
297    /// USB driver disconnect.
298    ///
299    /// Called when the USB interface is about to be unbound from this driver.
300    fn disconnect(interface: &Interface<device::Core>, data: Pin<&Self>);
301}
302
303/// A USB interface.
304///
305/// This structure represents the Rust abstraction for a C [`struct usb_interface`].
306/// The implementation abstracts the usage of a C [`struct usb_interface`] passed
307/// in from the C side.
308///
309/// # Invariants
310///
311/// An [`Interface`] instance represents a valid [`struct usb_interface`] created
312/// by the C portion of the kernel.
313///
314/// [`struct usb_interface`]: https://www.kernel.org/doc/html/latest/driver-api/usb/usb.html#c.usb_interface
315#[repr(transparent)]
316pub struct Interface<Ctx: device::DeviceContext = device::Normal>(
317    Opaque<bindings::usb_interface>,
318    PhantomData<Ctx>,
319);
320
321impl<Ctx: device::DeviceContext> Interface<Ctx> {
322    fn as_raw(&self) -> *mut bindings::usb_interface {
323        self.0.get()
324    }
325}
326
327// SAFETY: `Interface` is a transparent wrapper of a type that doesn't depend on
328// `Interface`'s generic argument.
329kernel::impl_device_context_deref!(unsafe { Interface });
330kernel::impl_device_context_into_aref!(Interface);
331
332impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Interface<Ctx> {
333    fn as_ref(&self) -> &device::Device<Ctx> {
334        // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid
335        // `struct usb_interface`.
336        let dev = unsafe { &raw mut ((*self.as_raw()).dev) };
337
338        // SAFETY: `dev` points to a valid `struct device`.
339        unsafe { device::Device::from_raw(dev) }
340    }
341}
342
343impl<Ctx: device::DeviceContext> AsRef<Device> for Interface<Ctx> {
344    fn as_ref(&self) -> &Device {
345        // SAFETY: `self.as_raw()` is valid by the type invariants.
346        let usb_dev = unsafe { bindings::interface_to_usbdev(self.as_raw()) };
347
348        // SAFETY: For a valid `struct usb_interface` pointer, the above call to
349        // `interface_to_usbdev()` guarantees to return a valid pointer to a `struct usb_device`.
350        unsafe { &*(usb_dev.cast()) }
351    }
352}
353
354// SAFETY: Instances of `Interface` are always reference-counted.
355unsafe impl AlwaysRefCounted for Interface {
356    fn inc_ref(&self) {
357        // SAFETY: The invariants of `Interface` guarantee that `self.as_raw()`
358        // returns a valid `struct usb_interface` pointer, for which we will
359        // acquire a new refcount.
360        unsafe { bindings::usb_get_intf(self.as_raw()) };
361    }
362
363    unsafe fn dec_ref(obj: NonNull<Self>) {
364        // SAFETY: The safety requirements guarantee that the refcount is non-zero.
365        unsafe { bindings::usb_put_intf(obj.cast().as_ptr()) }
366    }
367}
368
369// SAFETY: A `Interface` is always reference-counted and can be released from any thread.
370unsafe impl Send for Interface {}
371
372// SAFETY: It is safe to send a &Interface to another thread because we do not
373// allow any mutation through a shared reference.
374unsafe impl Sync for Interface {}
375
376/// A USB device.
377///
378/// This structure represents the Rust abstraction for a C [`struct usb_device`].
379/// The implementation abstracts the usage of a C [`struct usb_device`] passed in
380/// from the C side.
381///
382/// # Invariants
383///
384/// A [`Device`] instance represents a valid [`struct usb_device`] created by the C portion of the
385/// kernel.
386///
387/// [`struct usb_device`]: https://www.kernel.org/doc/html/latest/driver-api/usb/usb.html#c.usb_device
388#[repr(transparent)]
389struct Device<Ctx: device::DeviceContext = device::Normal>(
390    Opaque<bindings::usb_device>,
391    PhantomData<Ctx>,
392);
393
394impl<Ctx: device::DeviceContext> Device<Ctx> {
395    fn as_raw(&self) -> *mut bindings::usb_device {
396        self.0.get()
397    }
398}
399
400// SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic
401// argument.
402kernel::impl_device_context_deref!(unsafe { Device });
403kernel::impl_device_context_into_aref!(Device);
404
405// SAFETY: Instances of `Device` are always reference-counted.
406unsafe impl AlwaysRefCounted for Device {
407    fn inc_ref(&self) {
408        // SAFETY: The invariants of `Device` guarantee that `self.as_raw()`
409        // returns a valid `struct usb_device` pointer, for which we will
410        // acquire a new refcount.
411        unsafe { bindings::usb_get_dev(self.as_raw()) };
412    }
413
414    unsafe fn dec_ref(obj: NonNull<Self>) {
415        // SAFETY: The safety requirements guarantee that the refcount is non-zero.
416        unsafe { bindings::usb_put_dev(obj.cast().as_ptr()) }
417    }
418}
419
420impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> {
421    fn as_ref(&self) -> &device::Device<Ctx> {
422        // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid
423        // `struct usb_device`.
424        let dev = unsafe { &raw mut ((*self.as_raw()).dev) };
425
426        // SAFETY: `dev` points to a valid `struct device`.
427        unsafe { device::Device::from_raw(dev) }
428    }
429}
430
431// SAFETY: A `Device` is always reference-counted and can be released from any thread.
432unsafe impl Send for Device {}
433
434// SAFETY: It is safe to send a &Device to another thread because we do not
435// allow any mutation through a shared reference.
436unsafe impl Sync for Device {}
437
438/// Declares a kernel module that exposes a single USB driver.
439///
440/// # Examples
441///
442/// ```ignore
443/// module_usb_driver! {
444///     type: MyDriver,
445///     name: "Module name",
446///     author: ["Author name"],
447///     description: "Description",
448///     license: "GPL v2",
449/// }
450/// ```
451#[macro_export]
452macro_rules! module_usb_driver {
453    ($($f:tt)*) => {
454        $crate::module_driver!(<T>, $crate::usb::Adapter<T>, { $($f)* });
455    }
456}