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