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