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