mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-19 12:36:46 +00:00
Improve flexibility of DmaStreamSlice
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
29ebfa3934
commit
d37da228ab
@ -322,12 +322,12 @@ impl DeviceInner {
|
|||||||
resp_slice
|
resp_slice
|
||||||
};
|
};
|
||||||
|
|
||||||
let dma_slices: Vec<DmaStreamSlice> = dma_streams
|
let dma_slices: Vec<DmaStreamSlice<_>> = dma_streams
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(stream, offset, len)| DmaStreamSlice::new(stream, *offset, *len))
|
.map(|(stream, offset, len)| DmaStreamSlice::new(stream, *offset, *len))
|
||||||
.collect();
|
.collect();
|
||||||
let outputs = {
|
let outputs = {
|
||||||
let mut outputs: Vec<&DmaStreamSlice> = Vec::with_capacity(dma_streams.len() + 1);
|
let mut outputs: Vec<&DmaStreamSlice<_>> = Vec::with_capacity(dma_streams.len() + 1);
|
||||||
outputs.extend(dma_slices.iter());
|
outputs.extend(dma_slices.iter());
|
||||||
outputs.push(&resp_slice);
|
outputs.push(&resp_slice);
|
||||||
outputs
|
outputs
|
||||||
@ -384,12 +384,12 @@ impl DeviceInner {
|
|||||||
resp_slice
|
resp_slice
|
||||||
};
|
};
|
||||||
|
|
||||||
let dma_slices: Vec<DmaStreamSlice> = dma_streams
|
let dma_slices: Vec<DmaStreamSlice<_>> = dma_streams
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(stream, offset, len)| DmaStreamSlice::new(stream, *offset, *len))
|
.map(|(stream, offset, len)| DmaStreamSlice::new(stream, *offset, *len))
|
||||||
.collect();
|
.collect();
|
||||||
let inputs = {
|
let inputs = {
|
||||||
let mut inputs: Vec<&DmaStreamSlice> = Vec::with_capacity(dma_streams.len() + 1);
|
let mut inputs: Vec<&DmaStreamSlice<_>> = Vec::with_capacity(dma_streams.len() + 1);
|
||||||
inputs.push(&req_slice);
|
inputs.push(&req_slice);
|
||||||
inputs.extend(dma_slices.iter());
|
inputs.extend(dma_slices.iter());
|
||||||
inputs
|
inputs
|
||||||
|
@ -19,7 +19,7 @@ impl DmaBuf for DmaStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DmaBuf for DmaStreamSlice<'_> {
|
impl<Dma: AsRef<DmaStream>> DmaBuf for DmaStreamSlice<Dma> {
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.nbytes()
|
self.nbytes()
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ struct DmaStreamInner {
|
|||||||
pub enum DmaDirection {
|
pub enum DmaDirection {
|
||||||
/// Data flows to the device
|
/// Data flows to the device
|
||||||
ToDevice,
|
ToDevice,
|
||||||
/// Data flows form the device
|
/// Data flows from the device
|
||||||
FromDevice,
|
FromDevice,
|
||||||
/// Data flows both from and to the device
|
/// Data flows both from and to the device
|
||||||
Bidirectional,
|
Bidirectional,
|
||||||
@ -117,16 +117,21 @@ impl DmaStream {
|
|||||||
&self.inner.vm_segment
|
&self.inner.vm_segment
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of frames
|
/// Returns the number of frames.
|
||||||
pub fn nframes(&self) -> usize {
|
pub fn nframes(&self) -> usize {
|
||||||
self.inner.vm_segment.nbytes() / PAGE_SIZE
|
self.inner.vm_segment.nbytes() / PAGE_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of bytes
|
/// Returns the number of bytes.
|
||||||
pub fn nbytes(&self) -> usize {
|
pub fn nbytes(&self) -> usize {
|
||||||
self.inner.vm_segment.nbytes()
|
self.inner.vm_segment.nbytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the DMA direction.
|
||||||
|
pub fn direction(&self) -> DmaDirection {
|
||||||
|
self.inner.direction
|
||||||
|
}
|
||||||
|
|
||||||
/// Synchronizes the streaming DMA mapping with the device.
|
/// Synchronizes the streaming DMA mapping with the device.
|
||||||
///
|
///
|
||||||
/// This method should be called under one of the two conditions:
|
/// This method should be called under one of the two conditions:
|
||||||
@ -242,15 +247,21 @@ impl HasPaddr for DmaStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsRef<DmaStream> for DmaStream {
|
||||||
|
fn as_ref(&self) -> &DmaStream {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A slice of streaming DMA mapping.
|
/// A slice of streaming DMA mapping.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DmaStreamSlice<'a> {
|
pub struct DmaStreamSlice<Dma> {
|
||||||
stream: &'a DmaStream,
|
stream: Dma,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
len: usize,
|
len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DmaStreamSlice<'a> {
|
impl<Dma: AsRef<DmaStream>> DmaStreamSlice<Dma> {
|
||||||
/// Constructs a `DmaStreamSlice` from the [`DmaStream`].
|
/// Constructs a `DmaStreamSlice` from the [`DmaStream`].
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
@ -259,9 +270,9 @@ impl<'a> DmaStreamSlice<'a> {
|
|||||||
/// this method will panic.
|
/// this method will panic.
|
||||||
/// If the `offset + len` is greater than the length of the stream,
|
/// If the `offset + len` is greater than the length of the stream,
|
||||||
/// this method will panic.
|
/// this method will panic.
|
||||||
pub fn new(stream: &'a DmaStream, offset: usize, len: usize) -> Self {
|
pub fn new(stream: Dma, offset: usize, len: usize) -> Self {
|
||||||
assert!(offset < stream.nbytes());
|
assert!(offset < stream.as_ref().nbytes());
|
||||||
assert!(offset + len <= stream.nbytes());
|
assert!(offset + len <= stream.as_ref().nbytes());
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
stream,
|
stream,
|
||||||
@ -270,6 +281,16 @@ impl<'a> DmaStreamSlice<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the underlying `DmaStream`.
|
||||||
|
pub fn stream(&self) -> &DmaStream {
|
||||||
|
self.stream.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the offset of the slice.
|
||||||
|
pub fn offset(&self) -> usize {
|
||||||
|
self.offset
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the number of bytes.
|
/// Returns the number of bytes.
|
||||||
pub fn nbytes(&self) -> usize {
|
pub fn nbytes(&self) -> usize {
|
||||||
self.len
|
self.len
|
||||||
@ -277,35 +298,69 @@ impl<'a> DmaStreamSlice<'a> {
|
|||||||
|
|
||||||
/// Synchronizes the slice of streaming DMA mapping with the device.
|
/// Synchronizes the slice of streaming DMA mapping with the device.
|
||||||
pub fn sync(&self) -> Result<(), Error> {
|
pub fn sync(&self) -> Result<(), Error> {
|
||||||
self.stream.sync(self.offset..self.offset + self.len)
|
self.stream
|
||||||
|
.as_ref()
|
||||||
|
.sync(self.offset..self.offset + self.len)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a reader to read data from it.
|
||||||
|
pub fn reader(&self) -> Result<VmReader<Infallible>, Error> {
|
||||||
|
let stream_reader = self
|
||||||
|
.stream
|
||||||
|
.as_ref()
|
||||||
|
.reader()?
|
||||||
|
.skip(self.offset)
|
||||||
|
.limit(self.len);
|
||||||
|
Ok(stream_reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a writer to write data into it.
|
||||||
|
pub fn writer(&self) -> Result<VmWriter<Infallible>, Error> {
|
||||||
|
let stream_writer = self
|
||||||
|
.stream
|
||||||
|
.as_ref()
|
||||||
|
.writer()?
|
||||||
|
.skip(self.offset)
|
||||||
|
.limit(self.len);
|
||||||
|
Ok(stream_writer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VmIo for DmaStreamSlice<'_> {
|
impl<Dma: AsRef<DmaStream> + Send + Sync> VmIo for DmaStreamSlice<Dma> {
|
||||||
fn read(&self, offset: usize, writer: &mut VmWriter) -> Result<(), Error> {
|
fn read(&self, offset: usize, writer: &mut VmWriter) -> Result<(), Error> {
|
||||||
if writer.avail() + offset > self.len {
|
if writer.avail() + offset > self.len {
|
||||||
return Err(Error::InvalidArgs);
|
return Err(Error::InvalidArgs);
|
||||||
}
|
}
|
||||||
self.stream.read(self.offset + offset, writer)
|
self.stream.as_ref().read(self.offset + offset, writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&self, offset: usize, reader: &mut VmReader) -> Result<(), Error> {
|
fn write(&self, offset: usize, reader: &mut VmReader) -> Result<(), Error> {
|
||||||
if reader.remain() + offset > self.len {
|
if reader.remain() + offset > self.len {
|
||||||
return Err(Error::InvalidArgs);
|
return Err(Error::InvalidArgs);
|
||||||
}
|
}
|
||||||
self.stream.write(self.offset + offset, reader)
|
self.stream.as_ref().write(self.offset + offset, reader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasDaddr for DmaStreamSlice<'_> {
|
impl<Dma: AsRef<DmaStream>> HasDaddr for DmaStreamSlice<Dma> {
|
||||||
fn daddr(&self) -> Daddr {
|
fn daddr(&self) -> Daddr {
|
||||||
self.stream.daddr() + self.offset
|
self.stream.as_ref().daddr() + self.offset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasPaddr for DmaStreamSlice<'_> {
|
impl<Dma: AsRef<DmaStream>> HasPaddr for DmaStreamSlice<Dma> {
|
||||||
fn paddr(&self) -> Paddr {
|
fn paddr(&self) -> Paddr {
|
||||||
self.stream.paddr() + self.offset
|
self.stream.as_ref().paddr() + self.offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for DmaStreamSlice<DmaStream> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
stream: self.stream.clone(),
|
||||||
|
offset: self.offset,
|
||||||
|
len: self.len,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user