Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust: Add trait to convert a device reference to a bus device reference

Implement the `AsBusDevice` trait for converting a `Device` reference to a
bus device reference for all bus devices.

The `AsBusDevice` trait allows abstractions to provide the bus device in
class device callbacks. It must not be used by drivers and is intended for
bus and class device abstractions only.

Signed-off-by: Markus Probst <markus.probst@posteo.de>
Link: https://patch.msgid.link/20251027200547.1038967-2-markus.probst@posteo.de
[ * Remove unused import.
* Change visibility of AsBusDevice to public.
* Fix build for USB.
* Add impl for I2cClient.
- Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>

authored by

Markus Probst and committed by
Danilo Krummrich
e4addc7c 13ae55e2

+75 -1
+7
rust/kernel/auxiliary.rs
··· 16 16 }; 17 17 use core::{ 18 18 marker::PhantomData, 19 + mem::offset_of, 19 20 ptr::{addr_of_mut, NonNull}, 20 21 }; 21 22 ··· 244 243 // `KBox::new(Opaque::<bindings::auxiliary_device>::zeroed(), GFP_KERNEL)`. 245 244 let _ = unsafe { KBox::<Opaque<bindings::auxiliary_device>>::from_raw(adev.cast()) }; 246 245 } 246 + } 247 + 248 + // SAFETY: `auxiliary::Device` is a transparent wrapper of `struct auxiliary_device`. 249 + // The offset is guaranteed to point to a valid device field inside `auxiliary::Device`. 250 + unsafe impl<Ctx: device::DeviceContext> device::AsBusDevice<Ctx> for Device<Ctx> { 251 + const OFFSET: usize = offset_of!(bindings::auxiliary_device, dev); 247 252 } 248 253 249 254 // SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic
+33
rust/kernel/device.rs
··· 594 594 impl DeviceContext for CoreInternal {} 595 595 impl DeviceContext for Normal {} 596 596 597 + /// Convert device references to bus device references. 598 + /// 599 + /// Bus devices can implement this trait to allow abstractions to provide the bus device in 600 + /// class device callbacks. 601 + /// 602 + /// This must not be used by drivers and is intended for bus and class device abstractions only. 603 + /// 604 + /// # Safety 605 + /// 606 + /// `AsBusDevice::OFFSET` must be the offset of the embedded base `struct device` field within a 607 + /// bus device structure. 608 + pub unsafe trait AsBusDevice<Ctx: DeviceContext>: AsRef<Device<Ctx>> { 609 + /// The relative offset to the device field. 610 + /// 611 + /// Use `offset_of!(bindings, field)` macro to avoid breakage. 612 + const OFFSET: usize; 613 + 614 + /// Convert a reference to [`Device`] into `Self`. 615 + /// 616 + /// # Safety 617 + /// 618 + /// `dev` must be contained in `Self`. 619 + unsafe fn from_device(dev: &Device<Ctx>) -> &Self 620 + where 621 + Self: Sized, 622 + { 623 + let raw = dev.as_raw(); 624 + // SAFETY: `raw - Self::OFFSET` is guaranteed by the safety requirements 625 + // to be a valid pointer to `Self`. 626 + unsafe { &*raw.byte_sub(Self::OFFSET).cast::<Self>() } 627 + } 628 + } 629 + 597 630 /// # Safety 598 631 /// 599 632 /// The type given as `$device` must be a transparent wrapper of a type that doesn't depend on the
+7
rust/kernel/i2c.rs
··· 24 24 25 25 use core::{ 26 26 marker::PhantomData, 27 + mem::offset_of, 27 28 ptr::{ 28 29 from_ref, 29 30 NonNull, // ··· 475 474 fn as_raw(&self) -> *mut bindings::i2c_client { 476 475 self.0.get() 477 476 } 477 + } 478 + 479 + // SAFETY: `I2cClient` is a transparent wrapper of `struct i2c_client`. 480 + // The offset is guaranteed to point to a valid device field inside `I2cClient`. 481 + unsafe impl<Ctx: device::DeviceContext> device::AsBusDevice<Ctx> for I2cClient<Ctx> { 482 + const OFFSET: usize = offset_of!(bindings::i2c_client, dev); 478 483 } 479 484 480 485 // SAFETY: `I2cClient` is a transparent wrapper of a type that doesn't depend on
+7
rust/kernel/pci.rs
··· 24 24 }; 25 25 use core::{ 26 26 marker::PhantomData, 27 + mem::offset_of, 27 28 ptr::{ 28 29 addr_of_mut, 29 30 NonNull, // ··· 442 441 // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`. 443 442 unsafe { bindings::pci_set_master(self.as_raw()) }; 444 443 } 444 + } 445 + 446 + // SAFETY: `pci::Device` is a transparent wrapper of `struct pci_dev`. 447 + // The offset is guaranteed to point to a valid device field inside `pci::Device`. 448 + unsafe impl<Ctx: device::DeviceContext> device::AsBusDevice<Ctx> for Device<Ctx> { 449 + const OFFSET: usize = offset_of!(bindings::pci_dev, dev); 445 450 } 446 451 447 452 // SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s generic
+7
rust/kernel/platform.rs
··· 19 19 20 20 use core::{ 21 21 marker::PhantomData, 22 + mem::offset_of, 22 23 ptr::{addr_of_mut, NonNull}, 23 24 }; 24 25 ··· 286 285 // lifetime of the `IoRequest`. 287 286 .map(|resource| unsafe { IoRequest::new(self.as_ref(), resource) }) 288 287 } 288 + } 289 + 290 + // SAFETY: `platform::Device` is a transparent wrapper of `struct platform_device`. 291 + // The offset is guaranteed to point to a valid device field inside `platform::Device`. 292 + unsafe impl<Ctx: device::DeviceContext> device::AsBusDevice<Ctx> for Device<Ctx> { 293 + const OFFSET: usize = offset_of!(bindings::platform_device, dev); 289 294 } 290 295 291 296 macro_rules! define_irq_accessor_by_index {
+14 -1
rust/kernel/usb.rs
··· 15 15 types::{AlwaysRefCounted, Opaque}, 16 16 ThisModule, 17 17 }; 18 - use core::{marker::PhantomData, mem::MaybeUninit, ptr::NonNull}; 18 + use core::{ 19 + marker::PhantomData, 20 + mem::{ 21 + offset_of, 22 + MaybeUninit, // 23 + }, 24 + ptr::NonNull, 25 + }; 19 26 20 27 /// An adapter for the registration of USB drivers. 21 28 pub struct Adapter<T: Driver>(T); ··· 329 322 fn as_raw(&self) -> *mut bindings::usb_interface { 330 323 self.0.get() 331 324 } 325 + } 326 + 327 + // SAFETY: `usb::Interface` is a transparent wrapper of `struct usb_interface`. 328 + // The offset is guaranteed to point to a valid device field inside `usb::Interface`. 329 + unsafe impl<Ctx: device::DeviceContext> device::AsBusDevice<Ctx> for Interface<Ctx> { 330 + const OFFSET: usize = offset_of!(bindings::usb_interface, dev); 332 331 } 333 332 334 333 // SAFETY: `Interface` is a transparent wrapper of a type that doesn't depend on