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` 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 + 'static> driver::DriverLayout for Adapter<T> { 43 type DriverType = bindings::usb_driver; 44 type DriverData = T; 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 + 'static> 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 + 'static> 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>>`. 113 let data = unsafe { dev.drvdata_borrow::<T>() }; 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 /// const ID_TABLE: usb::IdTable<Self::IdInfo> = &USB_TABLE; 291 /// 292 /// fn probe( 293 /// _interface: &usb::Interface<Core>, 294 /// _id: &usb::DeviceId, 295 /// _info: &Self::IdInfo, 296 /// ) -> impl PinInit<Self, Error> { 297 /// Err(ENODEV) 298 /// } 299 /// 300 /// fn disconnect(_interface: &usb::Interface<Core>, _data: Pin<&Self>) {} 301 /// } 302 ///``` 303 pub trait Driver { 304 /// The type holding information about each one of the device ids supported by the driver. 305 type IdInfo: 'static; 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( 315 interface: &Interface<device::Core>, 316 id: &DeviceId, 317 id_info: &Self::IdInfo, 318 ) -> impl PinInit<Self, Error>; 319 320 /// USB driver disconnect. 321 /// 322 /// Called when the USB interface is about to be unbound from this driver. 323 fn disconnect(interface: &Interface<device::Core>, data: Pin<&Self>); 324 } 325 326 /// A USB interface. 327 /// 328 /// This structure represents the Rust abstraction for a C [`struct usb_interface`]. 329 /// The implementation abstracts the usage of a C [`struct usb_interface`] passed 330 /// in from the C side. 331 /// 332 /// # Invariants 333 /// 334 /// An [`Interface`] instance represents a valid [`struct usb_interface`] created 335 /// by the C portion of the kernel. 336 /// 337 /// [`struct usb_interface`]: https://www.kernel.org/doc/html/latest/driver-api/usb/usb.html#c.usb_interface 338 #[repr(transparent)] 339 pub struct Interface<Ctx: device::DeviceContext = device::Normal>( 340 Opaque<bindings::usb_interface>, 341 PhantomData<Ctx>, 342 ); 343 344 impl<Ctx: device::DeviceContext> Interface<Ctx> { 345 fn as_raw(&self) -> *mut bindings::usb_interface { 346 self.0.get() 347 } 348 } 349 350 // SAFETY: `usb::Interface` is a transparent wrapper of `struct usb_interface`. 351 // The offset is guaranteed to point to a valid device field inside `usb::Interface`. 352 unsafe impl<Ctx: device::DeviceContext> device::AsBusDevice<Ctx> for Interface<Ctx> { 353 const OFFSET: usize = offset_of!(bindings::usb_interface, dev); 354 } 355 356 // SAFETY: `Interface` is a transparent wrapper of a type that doesn't depend on 357 // `Interface`'s generic argument. 358 kernel::impl_device_context_deref!(unsafe { Interface }); 359 kernel::impl_device_context_into_aref!(Interface); 360 361 impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Interface<Ctx> { 362 fn as_ref(&self) -> &device::Device<Ctx> { 363 // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid 364 // `struct usb_interface`. 365 let dev = unsafe { &raw mut ((*self.as_raw()).dev) }; 366 367 // SAFETY: `dev` points to a valid `struct device`. 368 unsafe { device::Device::from_raw(dev) } 369 } 370 } 371 372 impl<Ctx: device::DeviceContext> AsRef<Device> for Interface<Ctx> { 373 fn as_ref(&self) -> &Device { 374 // SAFETY: `self.as_raw()` is valid by the type invariants. 375 let usb_dev = unsafe { bindings::interface_to_usbdev(self.as_raw()) }; 376 377 // SAFETY: For a valid `struct usb_interface` pointer, the above call to 378 // `interface_to_usbdev()` guarantees to return a valid pointer to a `struct usb_device`. 379 unsafe { &*(usb_dev.cast()) } 380 } 381 } 382 383 // SAFETY: Instances of `Interface` are always reference-counted. 384 unsafe impl AlwaysRefCounted for Interface { 385 fn inc_ref(&self) { 386 // SAFETY: The invariants of `Interface` guarantee that `self.as_raw()` 387 // returns a valid `struct usb_interface` pointer, for which we will 388 // acquire a new refcount. 389 unsafe { bindings::usb_get_intf(self.as_raw()) }; 390 } 391 392 unsafe fn dec_ref(obj: NonNull<Self>) { 393 // SAFETY: The safety requirements guarantee that the refcount is non-zero. 394 unsafe { bindings::usb_put_intf(obj.cast().as_ptr()) } 395 } 396 } 397 398 // SAFETY: A `Interface` is always reference-counted and can be released from any thread. 399 unsafe impl Send for Interface {} 400 401 // SAFETY: It is safe to send a &Interface to another thread because we do not 402 // allow any mutation through a shared reference. 403 unsafe impl Sync for Interface {} 404 405 /// A USB device. 406 /// 407 /// This structure represents the Rust abstraction for a C [`struct usb_device`]. 408 /// The implementation abstracts the usage of a C [`struct usb_device`] passed in 409 /// from the C side. 410 /// 411 /// # Invariants 412 /// 413 /// A [`Device`] instance represents a valid [`struct usb_device`] created by the C portion of the 414 /// kernel. 415 /// 416 /// [`struct usb_device`]: https://www.kernel.org/doc/html/latest/driver-api/usb/usb.html#c.usb_device 417 #[repr(transparent)] 418 struct Device<Ctx: device::DeviceContext = device::Normal>( 419 Opaque<bindings::usb_device>, 420 PhantomData<Ctx>, 421 ); 422 423 impl<Ctx: device::DeviceContext> Device<Ctx> { 424 fn as_raw(&self) -> *mut bindings::usb_device { 425 self.0.get() 426 } 427 } 428 429 // SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic 430 // argument. 431 kernel::impl_device_context_deref!(unsafe { Device }); 432 kernel::impl_device_context_into_aref!(Device); 433 434 // SAFETY: Instances of `Device` are always reference-counted. 435 unsafe impl AlwaysRefCounted for Device { 436 fn inc_ref(&self) { 437 // SAFETY: The invariants of `Device` guarantee that `self.as_raw()` 438 // returns a valid `struct usb_device` pointer, for which we will 439 // acquire a new refcount. 440 unsafe { bindings::usb_get_dev(self.as_raw()) }; 441 } 442 443 unsafe fn dec_ref(obj: NonNull<Self>) { 444 // SAFETY: The safety requirements guarantee that the refcount is non-zero. 445 unsafe { bindings::usb_put_dev(obj.cast().as_ptr()) } 446 } 447 } 448 449 impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> { 450 fn as_ref(&self) -> &device::Device<Ctx> { 451 // SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid 452 // `struct usb_device`. 453 let dev = unsafe { &raw mut ((*self.as_raw()).dev) }; 454 455 // SAFETY: `dev` points to a valid `struct device`. 456 unsafe { device::Device::from_raw(dev) } 457 } 458 } 459 460 // SAFETY: A `Device` is always reference-counted and can be released from any thread. 461 unsafe impl Send for Device {} 462 463 // SAFETY: It is safe to send a &Device to another thread because we do not 464 // allow any mutation through a shared reference. 465 unsafe impl Sync for Device {} 466 467 /// Declares a kernel module that exposes a single USB driver. 468 /// 469 /// # Examples 470 /// 471 /// ```ignore 472 /// module_usb_driver! { 473 /// type: MyDriver, 474 /// name: "Module name", 475 /// author: ["Author name"], 476 /// description: "Description", 477 /// license: "GPL v2", 478 /// } 479 /// ``` 480 #[macro_export] 481 macro_rules! module_usb_driver { 482 ($($f:tt)*) => { 483 $crate::module_driver!(<T>, $crate::usb::Adapter<T>, { $($f)* }); 484 } 485 } 486