~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/rust/kernel/device.rs

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 
  3 //! Generic devices that are part of the kernel's driver model.
  4 //!
  5 //! C header: [`include/linux/device.h`](srctree/include/linux/device.h)
  6 
  7 use crate::{
  8     bindings,
  9     types::{ARef, Opaque},
 10 };
 11 use core::ptr;
 12 
 13 /// A reference-counted device.
 14 ///
 15 /// This structure represents the Rust abstraction for a C `struct device`. This implementation
 16 /// abstracts the usage of an already existing C `struct device` within Rust code that we get
 17 /// passed from the C side.
 18 ///
 19 /// An instance of this abstraction can be obtained temporarily or permanent.
 20 ///
 21 /// A temporary one is bound to the lifetime of the C `struct device` pointer used for creation.
 22 /// A permanent instance is always reference-counted and hence not restricted by any lifetime
 23 /// boundaries.
 24 ///
 25 /// For subsystems it is recommended to create a permanent instance to wrap into a subsystem
 26 /// specific device structure (e.g. `pci::Device`). This is useful for passing it to drivers in
 27 /// `T::probe()`, such that a driver can store the `ARef<Device>` (equivalent to storing a
 28 /// `struct device` pointer in a C driver) for arbitrary purposes, e.g. allocating DMA coherent
 29 /// memory.
 30 ///
 31 /// # Invariants
 32 ///
 33 /// A `Device` instance represents a valid `struct device` created by the C portion of the kernel.
 34 ///
 35 /// Instances of this type are always reference-counted, that is, a call to `get_device` ensures
 36 /// that the allocation remains valid at least until the matching call to `put_device`.
 37 ///
 38 /// `bindings::device::release` is valid to be called from any thread, hence `ARef<Device>` can be
 39 /// dropped from any thread.
 40 #[repr(transparent)]
 41 pub struct Device(Opaque<bindings::device>);
 42 
 43 impl Device {
 44     /// Creates a new reference-counted abstraction instance of an existing `struct device` pointer.
 45     ///
 46     /// # Safety
 47     ///
 48     /// Callers must ensure that `ptr` is valid, non-null, and has a non-zero reference count,
 49     /// i.e. it must be ensured that the reference count of the C `struct device` `ptr` points to
 50     /// can't drop to zero, for the duration of this function call.
 51     ///
 52     /// It must also be ensured that `bindings::device::release` can be called from any thread.
 53     /// While not officially documented, this should be the case for any `struct device`.
 54     pub unsafe fn from_raw(ptr: *mut bindings::device) -> ARef<Self> {
 55         // SAFETY: By the safety requirements, ptr is valid.
 56         // Initially increase the reference count by one to compensate for the final decrement once
 57         // this newly created `ARef<Device>` instance is dropped.
 58         unsafe { bindings::get_device(ptr) };
 59 
 60         // CAST: `Self` is a `repr(transparent)` wrapper around `bindings::device`.
 61         let ptr = ptr.cast::<Self>();
 62 
 63         // SAFETY: `ptr` is valid by the safety requirements of this function. By the above call to
 64         // `bindings::get_device` we also own a reference to the underlying `struct device`.
 65         unsafe { ARef::from_raw(ptr::NonNull::new_unchecked(ptr)) }
 66     }
 67 
 68     /// Obtain the raw `struct device *`.
 69     pub(crate) fn as_raw(&self) -> *mut bindings::device {
 70         self.0.get()
 71     }
 72 
 73     /// Convert a raw C `struct device` pointer to a `&'a Device`.
 74     ///
 75     /// # Safety
 76     ///
 77     /// Callers must ensure that `ptr` is valid, non-null, and has a non-zero reference count,
 78     /// i.e. it must be ensured that the reference count of the C `struct device` `ptr` points to
 79     /// can't drop to zero, for the duration of this function call and the entire duration when the
 80     /// returned reference exists.
 81     pub unsafe fn as_ref<'a>(ptr: *mut bindings::device) -> &'a Self {
 82         // SAFETY: Guaranteed by the safety requirements of the function.
 83         unsafe { &*ptr.cast() }
 84     }
 85 }
 86 
 87 // SAFETY: Instances of `Device` are always reference-counted.
 88 unsafe impl crate::types::AlwaysRefCounted for Device {
 89     fn inc_ref(&self) {
 90         // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
 91         unsafe { bindings::get_device(self.as_raw()) };
 92     }
 93 
 94     unsafe fn dec_ref(obj: ptr::NonNull<Self>) {
 95         // SAFETY: The safety requirements guarantee that the refcount is non-zero.
 96         unsafe { bindings::put_device(obj.cast().as_ptr()) }
 97     }
 98 }
 99 
100 // SAFETY: As by the type invariant `Device` can be sent to any thread.
101 unsafe impl Send for Device {}
102 
103 // SAFETY: `Device` can be shared among threads because all immutable methods are protected by the
104 // synchronization in `struct device`.
105 unsafe impl Sync for Device {}

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php