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