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