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