On Tue, Oct 27, 2026 at 12:41:02AM +0800, Ke Sun wrote:
> From: Sami Tolvanen <[email protected]>
> 
> A driver may need to know whether its device is DMA-coherent, but
> rust/kernel exposes no accessor for the attribute today.
> 
> Add a transparent DmaAttr wrapper around device_get_dma_attr(), so all
> three attribute values (unset, non-coherent, coherent) are covered, and
> an is_coherent() accessor for the boolean case.
> 
> Signed-off-by: Sami Tolvanen <[email protected]>
> [ Replace dma_coherent() with a DmaAttr wrapper covering all three
>   attribute values. - Alvin ]
> Co-developed-by: Alvin Sun <[email protected]>
> Signed-off-by: Alvin Sun <[email protected]>
> ---
>  rust/kernel/device.rs | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
> index 2291d85b6849e..d5bbebdf620df 100644
> --- a/rust/kernel/device.rs
> +++ b/rust/kernel/device.rs
> @@ -260,6 +260,30 @@ pub unsafe fn drvdata_borrow<T>(&self) -> Pin<&T> {
>      }
>  }
>  
> +/// The DMA attribute of a device, as reported by firmware. A transparent
> +/// wrapper around the kernel's `enum dev_dma_attr`, covering all its states.
> +#[repr(transparent)]
> +pub struct DmaAttr(bindings::dev_dma_attr);
> +
> +impl DmaAttr {
> +    /// This wraps `device_get_dma_attr()` and only returns `true` for the
> +    /// `DEV_DMA_COHERENT` attribute; no attribute or `DEV_DMA_NON_COHERENT` 
> is non-coherent.
> +    #[inline]
> +    pub fn is_coherent(&self) -> bool {
> +        self.0 == bindings::dev_dma_attr_DEV_DMA_COHERENT
> +    }

I think Danilo was suggesting in the last version that all three enum
variants be exposed to the caller. You could remove this is_coherent() helper
and just provide something like this:

     /// The device has no reported DMA attributes.
     pub const NOT_SUPPORTED: Self = 
Self(bindings::dev_dma_attr_DEV_DMA_NOT_SUPPORTED);
     /// The device is not DMA-coherent.
     pub const NON_COHERENT: Self = 
Self(bindings::dev_dma_attr_DEV_DMA_NON_COHERENT);
     /// The device is DMA-coherent.
     pub const COHERENT: Self = Self(bindings::dev_dma_attr_DEV_DMA_COHERENT);

Then as long as you annotate struct DmaAttr with:
#[derive(Clone, Copy, PartialEq, Eq)]

Tyr can later do its own check like this:
  let coherent = pdev.as_ref().dma_attr() == DmaAttr::COHERENT;

> +}
> +
> +impl Device<Bound> {
> +    /// Returns the DMA attribute of the device as reported by firmware.
> +    #[inline]
> +    pub fn dma_attr(&self) -> DmaAttr {
> +        // SAFETY: By the type invariants, `self.as_raw()` is a valid pointer
> +        // to a `struct device`.
> +        unsafe { DmaAttr(bindings::device_get_dma_attr(self.as_raw())) }
> +    }
> +}
> +
>  impl<Ctx: DeviceContext> Device<Ctx> {
>      /// Obtain the raw `struct device *`.
>      pub(crate) fn as_raw(&self) -> *mut bindings::device {
> 
> -- 
> 2.43.0
> 

Reply via email to