Expand the documentation around DeviceContext states and types, in order
to provide detailed information about their purpose and relationship
with each other.
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/device.rs | 63 +++++++++++++++++++++++++++++++++++--------
1 file changed, 52 insertions(+), 11 deletions(-)
diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
index ca82926fd67f..d7ac56628fe5 100644
--- a/rust/kernel/device.rs
+++ b/rust/kernel/device.rs
@@ -311,28 +311,69 @@ unsafe impl Send for Device {}
// synchronization in `struct device`.
unsafe impl Sync for Device {}
-/// Marker trait for the context of a bus specific device.
+/// Marker trait for the context or scope of a bus specific device.
///
-/// Some functions of a bus specific device should only be called from a certain context, i.e. bus
-/// callbacks, such as `probe()`.
+/// [`DeviceContext`] is a marker trait for structures representing the context of a bus specific
+/// [`Device`].
///
-/// This is the marker trait for structures representing the context of a bus specific device.
+/// The specific device context types are: [`CoreInternal`], [`Core`], [`Bound`] and [`Normal`].
+///
+/// [`DeviceContext`] types are hierarchical, which means that there is a strict hierarchy that
+/// defines which [`DeviceContext`] type can be derived from another. For instance, any
+/// [`Device<Core>`] can dereference to a [`Device<Bound>`].
+///
+/// The following enunumeration illustrates the dereference hierarchy of [`DeviceContext`] types.
+///
+/// - [`CoreInternal`] => [`Core`] => [`Bound`] => [`Normal`]
+/// - [`Core`] => [`Bound`] => [`Normal`]
+/// - [`Bound`] => [`Normal`]
+/// - [`Normal`]
+///
+/// Bus devices can automatically implement the dereference hierarchy by using
+/// [`impl_device_context_deref`](kernel::impl_device_context_deref).
pub trait DeviceContext: private::Sealed {}
-/// The [`Normal`] context is the context of a bus specific device when it is not an argument of
-/// any bus callback.
+/// The [`Normal`] context is the default [`DeviceContext`] of any [`Device`].
+///
+/// The normal context does not indicate any specific scope. Any `Device<Ctx>` is also a valid
+/// [`Device<Normal>`]. It is the only [`DeviceContext`] for which it is valid to implement
+/// [`AlwaysRefCounted`](kernel::types::AlwaysRefCounted) for.
pub struct Normal;
-/// The [`Core`] context is the context of a bus specific device when it is supplied as argument of
-/// any of the bus callbacks, such as `probe()`.
+/// The [`Core`] context is the context of a bus specific device when it appears as argument of
+/// any bus specific callback, such as `probe()`.
+///
+/// The core context indicates that the [`Device<Core>`] reference's scope is limited to the bus
+/// callback it appears in. It is intended to be used for synchronization purposes. Bus device
+/// implementations can implement methods for [`Device<Core>`], such that they can only be called
+/// from bus callbacks.
pub struct Core;
-/// Semantically the same as [`Core`] but reserved for internal usage of the corresponding bus
+/// Semantically the same as [`Core`], but reserved for internal usage of the corresponding bus
/// abstraction.
+///
+/// The internal core context is intended to be used in exactly the same way as the [Core] context,
+/// with the difference that this [`DeviceContext`] is internal to the corresponding bus
+/// abstraction.
+///
+/// This context mainly exists to share generic [`Device`] infrastructure that should only be called
+/// from bus callbacks with bus abstractions, but without making them accessible for drivers.
pub struct CoreInternal;
-/// The [`Bound`] context is the context of a bus specific device reference when it is guaranteed to
-/// be bound for the duration of its lifetime.
+/// The [`Bound`] context is the [`DeviceContext`] of a bus specific device when it is guaranteed to
+/// be bound to a driver.
+///
+/// The bound context indicates that for the entire duration of the lifetime of a [`Device<Bound>`]
+/// reference, the [`Device`] is guaranteed to be bound to a driver.
+///
+/// Some APIs, such as [`dma::CoherentAllocation`](kernel::dma::CoherentAllocation) or
+/// [`Devres`](kernel::devres::Devres) rely on the [`Device`] to be bound, which can be proven with
+/// the [`Bound`] device context.
+///
+/// Any abstraction that can guarantee a scope where the corresponding bus device is bound, should
+/// provide a [`Device<Bound>`] reference to its users for this scope. This allows users to benefit
+/// from optimizations for accessing device resources, see also
+/// [Devres::access](kernel::devres::Devres::access).
pub struct Bound;
mod private {
--
2.50.0
Hi Danilo, > On 17 Jul 2025, at 19:45, Danilo Krummrich <dakr@kernel.org> wrote: > > Expand the documentation around DeviceContext states and types, in order > to provide detailed information about their purpose and relationship > with each other. > > Signed-off-by: Danilo Krummrich <dakr@kernel.org> > --- > rust/kernel/device.rs | 63 +++++++++++++++++++++++++++++++++++-------- > 1 file changed, 52 insertions(+), 11 deletions(-) > > diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs > index ca82926fd67f..d7ac56628fe5 100644 > --- a/rust/kernel/device.rs > +++ b/rust/kernel/device.rs > @@ -311,28 +311,69 @@ unsafe impl Send for Device {} > // synchronization in `struct device`. > unsafe impl Sync for Device {} > > -/// Marker trait for the context of a bus specific device. > +/// Marker trait for the context or scope of a bus specific device. > /// > -/// Some functions of a bus specific device should only be called from a certain context, i.e. bus > -/// callbacks, such as `probe()`. > +/// [`DeviceContext`] is a marker trait for structures representing the context of a bus specific > +/// [`Device`]. > /// > -/// This is the marker trait for structures representing the context of a bus specific device. > +/// The specific device context types are: [`CoreInternal`], [`Core`], [`Bound`] and [`Normal`]. > +/// > +/// [`DeviceContext`] types are hierarchical, which means that there is a strict hierarchy that > +/// defines which [`DeviceContext`] type can be derived from another. For instance, any > +/// [`Device<Core>`] can dereference to a [`Device<Bound>`]. > +/// > +/// The following enunumeration illustrates the dereference hierarchy of [`DeviceContext`] types. > +/// > +/// - [`CoreInternal`] => [`Core`] => [`Bound`] => [`Normal`] > +/// - [`Core`] => [`Bound`] => [`Normal`] > +/// - [`Bound`] => [`Normal`] > +/// - [`Normal`] > +/// > +/// Bus devices can automatically implement the dereference hierarchy by using > +/// [`impl_device_context_deref`](kernel::impl_device_context_deref). > pub trait DeviceContext: private::Sealed {} Overall this looks good to me. I think that one point you could perhaps consider is that, to me at least, it wasn't clear that the contexts were only valid for a given scope. Or what was precisely meant by “scope”. I.e.: I thought that once you saw Device<Bound>, for example, that would be valid indefinitely. If we retrieve one of our past conversations at [0]: > > > Fine, but can’t you get a &Device<Bound> from a ARef<drm::Device>, for example? > > Perhaps a nicer solution would be to offer this capability instead? > > I think you're confusing quite some things here. > > [...] > > (2) Owning a reference count of a device (i.e. ARef<Device>) does *not* > guarantee that the device is bound. You can own a reference count to the > device object way beyond it being bound. Instead, the guarantee comes from > the scope. > > In this case, the scope is the IRQ callback, since the irq::Registration > guarantees to call and complete free_irq() before the underlying bus > device is unbound. I see that you mention the word "scope" a few times, but perhaps it would be more instructional if you say a few more things on this topic. For example, when you mention probe(), it would be useful to emphasize that the Core state would only be guaranteed for the _scope of that function_, and that it wouldn't mean that "the state Core is active from now on", or "I can assume that we have a Device<Core> from now on in other parts of the driver". Kind of like you do here: > +/// The core context indicates that the [`Device<Core>`] reference's scope is limited to the bus > +/// callback it appears in. But generalizing to all states if possible. The difference is very subtle so this can sound a bit confusing. Let me know if you want me to clarify this further. [0] https://lore.kernel.org/rust-for-linux/DBB0NXU86D6G.2M3WZMS2NUV10@kernel.org/ — Daniel
On Fri Jul 18, 2025 at 3:09 PM CEST, Daniel Almeida wrote: > Hi Danilo, > >> On 17 Jul 2025, at 19:45, Danilo Krummrich <dakr@kernel.org> wrote: >> >> Expand the documentation around DeviceContext states and types, in order >> to provide detailed information about their purpose and relationship >> with each other. >> >> Signed-off-by: Danilo Krummrich <dakr@kernel.org> >> --- >> rust/kernel/device.rs | 63 +++++++++++++++++++++++++++++++++++-------- >> 1 file changed, 52 insertions(+), 11 deletions(-) >> >> diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs >> index ca82926fd67f..d7ac56628fe5 100644 >> --- a/rust/kernel/device.rs >> +++ b/rust/kernel/device.rs >> @@ -311,28 +311,69 @@ unsafe impl Send for Device {} >> // synchronization in `struct device`. >> unsafe impl Sync for Device {} >> >> -/// Marker trait for the context of a bus specific device. >> +/// Marker trait for the context or scope of a bus specific device. >> /// >> -/// Some functions of a bus specific device should only be called from a certain context, i.e. bus >> -/// callbacks, such as `probe()`. >> +/// [`DeviceContext`] is a marker trait for structures representing the context of a bus specific >> +/// [`Device`]. >> /// >> -/// This is the marker trait for structures representing the context of a bus specific device. >> +/// The specific device context types are: [`CoreInternal`], [`Core`], [`Bound`] and [`Normal`]. >> +/// >> +/// [`DeviceContext`] types are hierarchical, which means that there is a strict hierarchy that >> +/// defines which [`DeviceContext`] type can be derived from another. For instance, any >> +/// [`Device<Core>`] can dereference to a [`Device<Bound>`]. >> +/// >> +/// The following enunumeration illustrates the dereference hierarchy of [`DeviceContext`] types. >> +/// >> +/// - [`CoreInternal`] => [`Core`] => [`Bound`] => [`Normal`] >> +/// - [`Core`] => [`Bound`] => [`Normal`] >> +/// - [`Bound`] => [`Normal`] >> +/// - [`Normal`] >> +/// >> +/// Bus devices can automatically implement the dereference hierarchy by using >> +/// [`impl_device_context_deref`](kernel::impl_device_context_deref). >> pub trait DeviceContext: private::Sealed {} > > Overall this looks good to me. I think that one point you could perhaps > consider is that, to me at least, it wasn't clear that the contexts were only > valid for a given scope. Or what was precisely meant by “scope”. Scope really means scope in the sense of programming languages, which is why I didn't define it more specifically. So, a reference to a Device<Bound> (i.e. &Device<Bound>) indicates that the device is guaranteed to be bound for the scope the reference is valid in. Please also note that the added documentation on Device already says: "This structure represents the Rust abstraction for a C `struct device`. A [`Device`] can either exist as temporary reference (see also [`Device::from_raw`]), which is only valid within a certain scope or as [`ARef<Device>`], owning a dedicated reference count." I think this should clarify it already, or are you looking for something else? > I.e.: I thought that once you saw Device<Bound>, for example, that would be > valid indefinitely. If we retrieve one of our past conversations at [0]: You can't create or have a Device<Bound>, but a &Device<Bound>, which has a defined lifetime that can't be extended arbitrarily with safe code. >> >> > Fine, but can’t you get a &Device<Bound> from a ARef<drm::Device>, for example? >> > Perhaps a nicer solution would be to offer this capability instead? >> >> I think you're confusing quite some things here. >> >> [...] >> >> (2) Owning a reference count of a device (i.e. ARef<Device>) does *not* >> guarantee that the device is bound. You can own a reference count to the >> device object way beyond it being bound. Instead, the guarantee comes from >> the scope. >> >> In this case, the scope is the IRQ callback, since the irq::Registration >> guarantees to call and complete free_irq() before the underlying bus >> device is unbound. > > > I see that you mention the word "scope" a few times, but perhaps it would be > more instructional if you say a few more things on this topic. > > For example, when you mention probe(), it would be useful to emphasize that the > Core state would only be guaranteed for the _scope of that function_, and that > it wouldn't mean that "the state Core is active from now on", or "I can assume > that we have a Device<Core> from now on in other parts of the driver". > > Kind of like you do here: > >> +/// The core context indicates that the [`Device<Core>`] reference's scope is limited to the bus >> +/// callback it appears in. > > But generalizing to all states if possible. That's not possible. Core is specific as in that it's really meant to be the context of a device when it appears in a bus callback. But the Bound context may appear whereever we it can be proven that within a certain scope (e.g. the IRQ callback) the device is guaranteed to be bound. So the generalization really is to say "scope". > The difference is very subtle so this can sound a bit confusing. Let me know if > you want me to clarify this further. > > > [0] https://lore.kernel.org/rust-for-linux/DBB0NXU86D6G.2M3WZMS2NUV10@kernel.org/ > > — Daniel
Hi Danilo, […] >>> unsafe impl Sync for Device {} >>> >>> -/// Marker trait for the context of a bus specific device. >>> +/// Marker trait for the context or scope of a bus specific device. >>> /// >>> -/// Some functions of a bus specific device should only be called from a certain context, i.e. bus >>> -/// callbacks, such as `probe()`. >>> +/// [`DeviceContext`] is a marker trait for structures representing the context of a bus specific >>> +/// [`Device`]. >>> /// >>> -/// This is the marker trait for structures representing the context of a bus specific device. >>> +/// The specific device context types are: [`CoreInternal`], [`Core`], [`Bound`] and [`Normal`]. >>> +/// >>> +/// [`DeviceContext`] types are hierarchical, which means that there is a strict hierarchy that >>> +/// defines which [`DeviceContext`] type can be derived from another. For instance, any >>> +/// [`Device<Core>`] can dereference to a [`Device<Bound>`]. >>> +/// >>> +/// The following enunumeration illustrates the dereference hierarchy of [`DeviceContext`] types. >>> +/// >>> +/// - [`CoreInternal`] => [`Core`] => [`Bound`] => [`Normal`] >>> +/// - [`Core`] => [`Bound`] => [`Normal`] >>> +/// - [`Bound`] => [`Normal`] >>> +/// - [`Normal`] >>> +/// >>> +/// Bus devices can automatically implement the dereference hierarchy by using >>> +/// [`impl_device_context_deref`](kernel::impl_device_context_deref). >>> pub trait DeviceContext: private::Sealed {} >> >> Overall this looks good to me. I think that one point you could perhaps >> consider is that, to me at least, it wasn't clear that the contexts were only >> valid for a given scope. Or what was precisely meant by “scope”. > > Scope really means scope in the sense of programming languages, which is why I > didn't define it more specifically. > > So, a reference to a Device<Bound> (i.e. &Device<Bound>) indicates that the > device is guaranteed to be bound for the scope the reference is valid in. Maybe this is the piece of information that I missed, i.e.: that scope was being used in the usual sense in a programming language, and that the term wasn't being borrowed to describe some other sort of device behavior. This might look obvious now, but wasn't when I saw it the first time. Anyway, this is starting to look like I was the only one to get confused, so scratch what I said :) Also, looking at this patch again, it looks like you already explain this well enough, for example in the docs for Device<Core>, where "reference's scope" is mentioned: /// The core context indicates that the [`Device<Core>`] reference's scope is limited to the bus /// callback it appears in. […] > >>> >>>> Fine, but can’t you get a &Device<Bound> from a ARef<drm::Device>, for example? >>>> Perhaps a nicer solution would be to offer this capability instead? >>> >>> I think you're confusing quite some things here. >>> >>> [...] >>> >>> (2) Owning a reference count of a device (i.e. ARef<Device>) does *not* >>> guarantee that the device is bound. You can own a reference count to the >>> device object way beyond it being bound. Instead, the guarantee comes from >>> the scope. >>> I wonder if it would be helpful to specifically state this in the docs somehow? Perhaps as an extra "Note that ...". It doesn't hurt to repeat ourselves a bit here, IMHO. — Daniel
On Fri Jul 18, 2025 at 7:45 AM JST, Danilo Krummrich wrote: > Expand the documentation around DeviceContext states and types, in order > to provide detailed information about their purpose and relationship > with each other. > > Signed-off-by: Danilo Krummrich <dakr@kernel.org> Thanks, that's a welcome clarification and I think I finally understand the Rust device model after going through this series! A few minor nits/questions below. > --- > rust/kernel/device.rs | 63 +++++++++++++++++++++++++++++++++++-------- > 1 file changed, 52 insertions(+), 11 deletions(-) > > diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs > index ca82926fd67f..d7ac56628fe5 100644 > --- a/rust/kernel/device.rs > +++ b/rust/kernel/device.rs > @@ -311,28 +311,69 @@ unsafe impl Send for Device {} > // synchronization in `struct device`. > unsafe impl Sync for Device {} > > -/// Marker trait for the context of a bus specific device. > +/// Marker trait for the context or scope of a bus specific device. > /// > -/// Some functions of a bus specific device should only be called from a certain context, i.e. bus > -/// callbacks, such as `probe()`. > +/// [`DeviceContext`] is a marker trait for structures representing the context of a bus specific > +/// [`Device`]. > /// > -/// This is the marker trait for structures representing the context of a bus specific device. Shall we say `types` instead of `structures`, since these are ZSTs? `structures` carries the hint that they will contain data, when they don't (but maybe that's only me :)). > +/// The specific device context types are: [`CoreInternal`], [`Core`], [`Bound`] and [`Normal`]. > +/// > +/// [`DeviceContext`] types are hierarchical, which means that there is a strict hierarchy that > +/// defines which [`DeviceContext`] type can be derived from another. For instance, any > +/// [`Device<Core>`] can dereference to a [`Device<Bound>`]. > +/// > +/// The following enunumeration illustrates the dereference hierarchy of [`DeviceContext`] types. > +/// > +/// - [`CoreInternal`] => [`Core`] => [`Bound`] => [`Normal`] > +/// - [`Core`] => [`Bound`] => [`Normal`] > +/// - [`Bound`] => [`Normal`] > +/// - [`Normal`] That graph is super helpful. The last 3 lines look redundant though, since the graph can be followed from any node. > +/// > +/// Bus devices can automatically implement the dereference hierarchy by using > +/// [`impl_device_context_deref`](kernel::impl_device_context_deref). > pub trait DeviceContext: private::Sealed {} > > -/// The [`Normal`] context is the context of a bus specific device when it is not an argument of > -/// any bus callback. > +/// The [`Normal`] context is the default [`DeviceContext`] of any [`Device`]. > +/// > +/// The normal context does not indicate any specific scope. Any `Device<Ctx>` is also a valid > +/// [`Device<Normal>`]. It is the only [`DeviceContext`] for which it is valid to implement > +/// [`AlwaysRefCounted`](kernel::types::AlwaysRefCounted) for. > pub struct Normal; `Normal` as a name can be interpreted in many different ways, and in the case of a device context it is not clear what the "normal" state is. I think it would be helpful if we can elaborate a bit more on what this implies (i.e. what concretely speaking are the limitations), and if possible why this name has been chosen.
On Fri Jul 18, 2025 at 2:32 PM CEST, Alexandre Courbot wrote: > On Fri Jul 18, 2025 at 7:45 AM JST, Danilo Krummrich wrote: >> Expand the documentation around DeviceContext states and types, in order >> to provide detailed information about their purpose and relationship >> with each other. >> >> Signed-off-by: Danilo Krummrich <dakr@kernel.org> > > Thanks, that's a welcome clarification and I think I finally understand > the Rust device model after going through this series! > > A few minor nits/questions below. > >> --- >> rust/kernel/device.rs | 63 +++++++++++++++++++++++++++++++++++-------- >> 1 file changed, 52 insertions(+), 11 deletions(-) >> >> diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs >> index ca82926fd67f..d7ac56628fe5 100644 >> --- a/rust/kernel/device.rs >> +++ b/rust/kernel/device.rs >> @@ -311,28 +311,69 @@ unsafe impl Send for Device {} >> // synchronization in `struct device`. >> unsafe impl Sync for Device {} >> >> -/// Marker trait for the context of a bus specific device. >> +/// Marker trait for the context or scope of a bus specific device. >> /// >> -/// Some functions of a bus specific device should only be called from a certain context, i.e. bus >> -/// callbacks, such as `probe()`. >> +/// [`DeviceContext`] is a marker trait for structures representing the context of a bus specific >> +/// [`Device`]. >> /// >> -/// This is the marker trait for structures representing the context of a bus specific device. > > Shall we say `types` instead of `structures`, since these are ZSTs? > `structures` carries the hint that they will contain data, when they > don't (but maybe that's only me :)). I agree, 'types' is better. >> +/// The specific device context types are: [`CoreInternal`], [`Core`], [`Bound`] and [`Normal`]. >> +/// >> +/// [`DeviceContext`] types are hierarchical, which means that there is a strict hierarchy that >> +/// defines which [`DeviceContext`] type can be derived from another. For instance, any >> +/// [`Device<Core>`] can dereference to a [`Device<Bound>`]. >> +/// >> +/// The following enunumeration illustrates the dereference hierarchy of [`DeviceContext`] types. >> +/// >> +/// - [`CoreInternal`] => [`Core`] => [`Bound`] => [`Normal`] >> +/// - [`Core`] => [`Bound`] => [`Normal`] >> +/// - [`Bound`] => [`Normal`] >> +/// - [`Normal`] > > That graph is super helpful. The last 3 lines look redundant though, > since the graph can be followed from any node. Yeah, it's indeed unnecessarily redundant. >> +/// >> +/// Bus devices can automatically implement the dereference hierarchy by using >> +/// [`impl_device_context_deref`](kernel::impl_device_context_deref). >> pub trait DeviceContext: private::Sealed {} >> >> -/// The [`Normal`] context is the context of a bus specific device when it is not an argument of >> -/// any bus callback. >> +/// The [`Normal`] context is the default [`DeviceContext`] of any [`Device`]. >> +/// >> +/// The normal context does not indicate any specific scope. Any `Device<Ctx>` is also a valid >> +/// [`Device<Normal>`]. It is the only [`DeviceContext`] for which it is valid to implement >> +/// [`AlwaysRefCounted`](kernel::types::AlwaysRefCounted) for. >> pub struct Normal; > > `Normal` as a name can be interpreted in many different ways, and in the > case of a device context it is not clear what the "normal" state is. I > think it would be helpful if we can elaborate a bit more on what this > implies (i.e. what concretely speaking are the limitations), and if > possible why this name has been chosen. It's the context that does not guarantee any specific scope. But that's also what the documentation says. I also wouldn't speak of limitations, it's just that it doesn't allow to make *additional* assumptions compared to other device context types. Yet, if you have suggestions on what to add specifically, please let me know (maybe simply my previous sentence?). Regarding the name, "Normal" seems reasonable for the device context that does not guarantee any specific scope. We could have also named it just "Default". I think "Normal" is fine, as in "it's just a normal device reference, no specific scope guaranteed".
On Fri Jul 18, 2025 at 3:14 PM CEST, Danilo Krummrich wrote: > On Fri Jul 18, 2025 at 2:32 PM CEST, Alexandre Courbot wrote: >> On Fri Jul 18, 2025 at 7:45 AM JST, Danilo Krummrich wrote: >>> +/// >>> +/// Bus devices can automatically implement the dereference hierarchy by using >>> +/// [`impl_device_context_deref`](kernel::impl_device_context_deref). >>> pub trait DeviceContext: private::Sealed {} >>> >>> -/// The [`Normal`] context is the context of a bus specific device when it is not an argument of >>> -/// any bus callback. >>> +/// The [`Normal`] context is the default [`DeviceContext`] of any [`Device`]. >>> +/// >>> +/// The normal context does not indicate any specific scope. Any `Device<Ctx>` is also a valid >>> +/// [`Device<Normal>`]. It is the only [`DeviceContext`] for which it is valid to implement >>> +/// [`AlwaysRefCounted`](kernel::types::AlwaysRefCounted) for. >>> pub struct Normal; >> >> `Normal` as a name can be interpreted in many different ways, and in the >> case of a device context it is not clear what the "normal" state is. I >> think it would be helpful if we can elaborate a bit more on what this >> implies (i.e. what concretely speaking are the limitations), and if >> possible why this name has been chosen. > > It's the context that does not guarantee any specific scope. But that's also > what the documentation says. > > I also wouldn't speak of limitations, it's just that it doesn't allow to make > *additional* assumptions compared to other device context types. > > Yet, if you have suggestions on what to add specifically, please let me know > (maybe simply my previous sentence?). > > Regarding the name, "Normal" seems reasonable for the device context that does > not guarantee any specific scope. We could have also named it just "Default". > > I think "Normal" is fine, as in "it's just a normal device reference, no > specific scope guaranteed". Not sure if this helps, but `Plain` might carry a slightly different meaning from `Normal` that is better in this case? (but you probably can't infer much from the name anyways) --- Cheers, Benno
© 2016 - 2025 Red Hat, Inc.