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 + } +} + +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
