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