@@ -15,23 +15,130 @@ use crate::c_str;
15
15
16
16
pub mod property;
17
17
18
- /// A reference-counted device.
18
+ /// The core representation of a device in the kernel's driver model .
19
19
///
20
- /// This structure represents the Rust abstraction for a C `struct device`. This implementation
21
- /// abstracts the usage of an already existing C `struct device` within Rust code that we get
22
- /// passed from the C side .
20
+ /// This structure represents the Rust abstraction for a C `struct device`. A [`Device`] can either
21
+ /// exist as temporary reference (see also [`Device::from_raw`]), which is only valid within a
22
+ /// certain scope or as [`ARef<Device>`], owning a dedicated reference count .
23
23
///
24
- /// An instance of this abstraction can be obtained temporarily or permanent.
24
+ /// # Device Types
25
25
///
26
- /// A temporary one is bound to the lifetime of the C `struct device` pointer used for creation.
27
- /// A permanent instance is always reference-counted and hence not restricted by any lifetime
28
- /// boundaries.
26
+ /// A [`Device`] can represent either a bus device or a class device.
29
27
///
30
- /// For subsystems it is recommended to create a permanent instance to wrap into a subsystem
31
- /// specific device structure (e.g. `pci::Device`). This is useful for passing it to drivers in
32
- /// `T::probe()`, such that a driver can store the `ARef<Device>` (equivalent to storing a
33
- /// `struct device` pointer in a C driver) for arbitrary purposes, e.g. allocating DMA coherent
34
- /// memory.
28
+ /// ## Bus Devices
29
+ ///
30
+ /// A bus device is a [`Device`] that is associated with a physical or virtual bus. Examples of
31
+ /// buses include PCI, USB, I2C, and SPI. Devices attached to a bus are registered with a specific
32
+ /// bus type, which facilitates matching devices with appropriate drivers based on IDs or other
33
+ /// identifying information. Bus devices are visible in sysfs under `/sys/bus/<bus-name>/devices/`.
34
+ ///
35
+ /// ## Class Devices
36
+ ///
37
+ /// A class device is a [`Device`] that is associated with a logical category of functionality
38
+ /// rather than a physical bus. Examples of classes include block devices, network interfaces, sound
39
+ /// cards, and input devices. Class devices are grouped under a common class and exposed to
40
+ /// userspace via entries in `/sys/class/<class-name>/`.
41
+ ///
42
+ /// # Device Context
43
+ ///
44
+ /// [`Device`] references are generic over a [`DeviceContext`], which represents the type state of
45
+ /// a [`Device`].
46
+ ///
47
+ /// As the name indicates, this type state represents the context of the scope the [`Device`]
48
+ /// reference is valid in. For instance, the [`Bound`] context guarantees that the [`Device`] is
49
+ /// bound to a driver for the entire duration of the existence of a [`Device<Bound>`] reference.
50
+ ///
51
+ /// Other [`DeviceContext`] types besides [`Bound`] are [`Normal`], [`Core`] and [`CoreInternal`].
52
+ ///
53
+ /// Unless selected otherwise [`Device`] defaults to the [`Normal`] [`DeviceContext`], which by
54
+ /// itself has no additional requirements.
55
+ ///
56
+ /// It is always up to the caller of [`Device::from_raw`] to select the correct [`DeviceContext`]
57
+ /// type for the corresponding scope the [`Device`] reference is created in.
58
+ ///
59
+ /// All [`DeviceContext`] types other than [`Normal`] are intended to be used with
60
+ /// [bus devices](#bus-devices) only.
61
+ ///
62
+ /// # Implementing Bus Devices
63
+ ///
64
+ /// This section provides a guideline to implement bus specific devices, such as [`pci::Device`] or
65
+ /// [`platform::Device`].
66
+ ///
67
+ /// A bus specific device should be defined as follows.
68
+ ///
69
+ /// ```ignore
70
+ /// #[repr(transparent)]
71
+ /// pub struct Device<Ctx: device::DeviceContext = device::Normal>(
72
+ /// Opaque<bindings::bus_device_type>,
73
+ /// PhantomData<Ctx>,
74
+ /// );
75
+ /// ```
76
+ ///
77
+ /// Since devices are reference counted, [`AlwaysRefCounted`] should be implemented for `Device`
78
+ /// (i.e. `Device<Normal>`). Note that [`AlwaysRefCounted`] must not be implemented for any other
79
+ /// [`DeviceContext`], since all other device context types are only valid within a certain scope.
80
+ ///
81
+ /// In order to be able to implement the [`DeviceContext`] dereference hierarchy, bus device
82
+ /// implementations should call the [`impl_device_context_deref`] macro as shown below.
83
+ ///
84
+ /// ```ignore
85
+ /// // SAFETY: `Device` is a transparent wrapper of a type that doesn't depend on `Device`'s
86
+ /// // generic argument.
87
+ /// kernel::impl_device_context_deref!(unsafe { Device });
88
+ /// ```
89
+ ///
90
+ /// In order to convert from a any [`Device<Ctx>`] to [`ARef<Device>`], bus devices can implement
91
+ /// the following macro call.
92
+ ///
93
+ /// ```ignore
94
+ /// kernel::impl_device_context_into_aref!(Device);
95
+ /// ```
96
+ ///
97
+ /// Bus devices should also implement the following [`AsRef`] implementation, such that users can
98
+ /// easily derive a generic [`Device`] reference.
99
+ ///
100
+ /// ```ignore
101
+ /// impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> {
102
+ /// fn as_ref(&self) -> &device::Device<Ctx> {
103
+ /// ...
104
+ /// }
105
+ /// }
106
+ /// ```
107
+ ///
108
+ /// # Implementing Class Devices
109
+ ///
110
+ /// Class device implementations require less infrastructure and depend slightly more on the
111
+ /// specific subsystem.
112
+ ///
113
+ /// An example implementation for a class device could look like this.
114
+ ///
115
+ /// ```ignore
116
+ /// #[repr(C)]
117
+ /// pub struct Device<T: class::Driver> {
118
+ /// dev: Opaque<bindings::class_device_type>,
119
+ /// data: T::Data,
120
+ /// }
121
+ /// ```
122
+ ///
123
+ /// This class device uses the sub-classing pattern to embed the driver's private data within the
124
+ /// allocation of the class device. For this to be possible the class device is generic over the
125
+ /// class specific `Driver` trait implementation.
126
+ ///
127
+ /// Just like any device, class devices are reference counted and should hence implement
128
+ /// [`AlwaysRefCounted`] for `Device`.
129
+ ///
130
+ /// Class devices should also implement the following [`AsRef`] implementation, such that users can
131
+ /// easily derive a generic [`Device`] reference.
132
+ ///
133
+ /// ```ignore
134
+ /// impl<T: class::Driver> AsRef<device::Device> for Device<T> {
135
+ /// fn as_ref(&self) -> &device::Device {
136
+ /// ...
137
+ /// }
138
+ /// }
139
+ /// ```
140
+ ///
141
+ /// An example for a class device implementation is [`drm::Device`].
35
142
///
36
143
/// # Invariants
37
144
///
@@ -42,6 +149,12 @@ pub mod property;
42
149
///
43
150
/// `bindings::device::release` is valid to be called from any thread, hence `ARef<Device>` can be
44
151
/// dropped from any thread.
152
+ ///
153
+ /// [`AlwaysRefCounted`]: kernel::types::AlwaysRefCounted
154
+ /// [`drm::Device`]: kernel::drm::Device
155
+ /// [`impl_device_context_deref`]: kernel::impl_device_context_deref
156
+ /// [`pci::Device`]: kernel::pci::Device
157
+ /// [`platform::Device`]: kernel::platform::Device
45
158
#[ repr( transparent) ]
46
159
pub struct Device < Ctx : DeviceContext = Normal > ( Opaque < bindings:: device > , PhantomData < Ctx > ) ;
47
160
@@ -311,28 +424,75 @@ unsafe impl Send for Device {}
311
424
// synchronization in `struct device`.
312
425
unsafe impl Sync for Device { }
313
426
314
- /// Marker trait for the context of a bus specific device.
427
+ /// Marker trait for the context or scope of a bus specific device.
428
+ ///
429
+ /// [`DeviceContext`] is a marker trait for types representing the context of a bus specific
430
+ /// [`Device`].
431
+ ///
432
+ /// The specific device context types are: [`CoreInternal`], [`Core`], [`Bound`] and [`Normal`].
315
433
///
316
- /// Some functions of a bus specific device should only be called from a certain context, i.e. bus
317
- /// callbacks, such as `probe()`.
434
+ /// [`DeviceContext`] types are hierarchical, which means that there is a strict hierarchy that
435
+ /// defines which [`DeviceContext`] type can be derived from another. For instance, any
436
+ /// [`Device<Core>`] can dereference to a [`Device<Bound>`].
318
437
///
319
- /// This is the marker trait for structures representing the context of a bus specific device.
438
+ /// The following enumeration illustrates the dereference hierarchy of [`DeviceContext`] types.
439
+ ///
440
+ /// - [`CoreInternal`] => [`Core`] => [`Bound`] => [`Normal`]
441
+ ///
442
+ /// Bus devices can automatically implement the dereference hierarchy by using
443
+ /// [`impl_device_context_deref`].
444
+ ///
445
+ /// Note that the guarantee for a [`Device`] reference to have a certain [`DeviceContext`] comes
446
+ /// from the specific scope the [`Device`] reference is valid in.
447
+ ///
448
+ /// [`impl_device_context_deref`]: kernel::impl_device_context_deref
320
449
pub trait DeviceContext : private:: Sealed { }
321
450
322
- /// The [`Normal`] context is the context of a bus specific device when it is not an argument of
323
- /// any bus callback.
451
+ /// The [`Normal`] context is the default [`DeviceContext`] of any [`Device`].
452
+ ///
453
+ /// The normal context does not indicate any specific context. Any `Device<Ctx>` is also a valid
454
+ /// [`Device<Normal>`]. It is the only [`DeviceContext`] for which it is valid to implement
455
+ /// [`AlwaysRefCounted`] for.
456
+ ///
457
+ /// [`AlwaysRefCounted`]: kernel::types::AlwaysRefCounted
324
458
pub struct Normal ;
325
459
326
- /// The [`Core`] context is the context of a bus specific device when it is supplied as argument of
327
- /// any of the bus callbacks, such as `probe()`.
460
+ /// The [`Core`] context is the context of a bus specific device when it appears as argument of
461
+ /// any bus specific callback, such as `probe()`.
462
+ ///
463
+ /// The core context indicates that the [`Device<Core>`] reference's scope is limited to the bus
464
+ /// callback it appears in. It is intended to be used for synchronization purposes. Bus device
465
+ /// implementations can implement methods for [`Device<Core>`], such that they can only be called
466
+ /// from bus callbacks.
328
467
pub struct Core ;
329
468
330
- /// Semantically the same as [`Core`] but reserved for internal usage of the corresponding bus
469
+ /// Semantically the same as [`Core`], but reserved for internal usage of the corresponding bus
331
470
/// abstraction.
471
+ ///
472
+ /// The internal core context is intended to be used in exactly the same way as the [`Core`]
473
+ /// context, with the difference that this [`DeviceContext`] is internal to the corresponding bus
474
+ /// abstraction.
475
+ ///
476
+ /// This context mainly exists to share generic [`Device`] infrastructure that should only be called
477
+ /// from bus callbacks with bus abstractions, but without making them accessible for drivers.
332
478
pub struct CoreInternal ;
333
479
334
- /// The [`Bound`] context is the context of a bus specific device reference when it is guaranteed to
335
- /// be bound for the duration of its lifetime.
480
+ /// The [`Bound`] context is the [`DeviceContext`] of a bus specific device when it is guaranteed to
481
+ /// be bound to a driver.
482
+ ///
483
+ /// The bound context indicates that for the entire duration of the lifetime of a [`Device<Bound>`]
484
+ /// reference, the [`Device`] is guaranteed to be bound to a driver.
485
+ ///
486
+ /// Some APIs, such as [`dma::CoherentAllocation`] or [`Devres`] rely on the [`Device`] to be bound,
487
+ /// which can be proven with the [`Bound`] device context.
488
+ ///
489
+ /// Any abstraction that can guarantee a scope where the corresponding bus device is bound, should
490
+ /// provide a [`Device<Bound>`] reference to its users for this scope. This allows users to benefit
491
+ /// from optimizations for accessing device resources, see also [`Devres::access`].
492
+ ///
493
+ /// [`Devres`]: kernel::devres::Devres
494
+ /// [`Devres::access`]: kernel::devres::Devres::access
495
+ /// [`dma::CoherentAllocation`]: kernel::dma::CoherentAllocation
336
496
pub struct Bound ;
337
497
338
498
mod private {
0 commit comments