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