1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Simple DMA object wrapper. 4 5 // To be removed when all code is used. 6 #![expect(dead_code)] 7 8 use core::ops::{Deref, DerefMut}; 9 10 use kernel::device; 11 use kernel::dma::CoherentAllocation; 12 use kernel::page::PAGE_SIZE; 13 use kernel::prelude::*; 14 15 pub(crate) struct DmaObject { 16 dma: CoherentAllocation<u8>, 17 } 18 19 impl DmaObject { 20 pub(crate) fn new(dev: &device::Device<device::Bound>, len: usize) -> Result<Self> { 21 let len = core::alloc::Layout::from_size_align(len, PAGE_SIZE) 22 .map_err(|_| EINVAL)? 23 .pad_to_align() 24 .size(); 25 let dma = CoherentAllocation::alloc_coherent(dev, len, GFP_KERNEL | __GFP_ZERO)?; 26 27 Ok(Self { dma }) 28 } 29 30 pub(crate) fn from_data(dev: &device::Device<device::Bound>, data: &[u8]) -> Result<Self> { 31 Self::new(dev, data.len()).map(|mut dma_obj| { 32 // TODO: replace with `CoherentAllocation::write()` once available. 33 // SAFETY: 34 // - `dma_obj`'s size is at least `data.len()`. 35 // - We have just created this object and there is no other user at this stage. 36 unsafe { 37 core::ptr::copy_nonoverlapping( 38 data.as_ptr(), 39 dma_obj.dma.start_ptr_mut(), 40 data.len(), 41 ); 42 } 43 44 dma_obj 45 }) 46 } 47 } 48 49 impl Deref for DmaObject { 50 type Target = CoherentAllocation<u8>; 51 52 fn deref(&self) -> &Self::Target { 53 &self.dma 54 } 55 } 56 57 impl DerefMut for DmaObject { 58 fn deref_mut(&mut self) -> &mut Self::Target { 59 &mut self.dma 60 } 61 } 62