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