diff options
Diffstat (limited to 'rust/kernel')
-rw-r--r-- | rust/kernel/dma.rs | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs index 34a406a0602e..25dfa0e6cc3c 100644 --- a/rust/kernel/dma.rs +++ b/rust/kernel/dma.rs @@ -238,6 +238,20 @@ impl<T: AsBytes + FromBytes> CoherentAllocation<T> { self.dma_handle } + /// Returns a DMA handle starting at `offset` (in units of `T`) which may be given to the + /// device as the DMA address base of the region. + /// + /// Returns `EINVAL` if `offset` is not within the bounds of the allocation. + pub fn dma_handle_with_offset(&self, offset: usize) -> Result<bindings::dma_addr_t> { + if offset >= self.count { + Err(EINVAL) + } else { + // INVARIANT: The type invariant of `Self` guarantees that `size_of::<T> * count` fits + // into a `usize`, and `offset` is inferior to `count`. + Ok(self.dma_handle + (offset * core::mem::size_of::<T>()) as bindings::dma_addr_t) + } + } + /// Common helper to validate a range applied from the allocated region in the CPU's virtual /// address space. fn validate_range(&self, offset: usize, count: usize) -> Result { |