86 lines
2.4 KiB
Rust
86 lines
2.4 KiB
Rust
use core::{mem::MaybeUninit, ops::Deref};
|
|
|
|
use alloc::boxed::Box;
|
|
use async_trait::async_trait;
|
|
use libk::dma::DmaBuffer;
|
|
|
|
use crate::error::{TransferError, UsbError};
|
|
|
|
use super::UsbGenericPipe;
|
|
|
|
#[async_trait]
|
|
pub trait UsbNormalPipeIn: UsbGenericPipe {
|
|
async fn read_dma(
|
|
&self,
|
|
buffer: &mut DmaBuffer<[MaybeUninit<u8>]>,
|
|
limit: usize,
|
|
) -> Result<usize, UsbError>;
|
|
|
|
async fn read(&self, buffer: &mut [u8]) -> Result<usize, UsbError> {
|
|
let mut dma_buffer = self.allocate_dma_buffer(buffer.len())?;
|
|
let len = self.read_dma(&mut dma_buffer, buffer.len()).await?;
|
|
let dma_slice = unsafe { MaybeUninit::slice_assume_init_ref(&dma_buffer[..len]) };
|
|
buffer[..len].copy_from_slice(dma_slice);
|
|
Ok(len)
|
|
}
|
|
|
|
async fn read_exact(&self, buffer: &mut [u8]) -> Result<(), UsbError> {
|
|
match self.read(buffer).await {
|
|
Ok(len) if len == buffer.len() => Ok(()),
|
|
Ok(len) => Err(UsbError::TransferFailed(TransferError::ShortPacket(len))),
|
|
Err(error) => Err(error),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
pub trait UsbNormalPipeOut: UsbGenericPipe {
|
|
async fn write_dma(&self, buffer: &DmaBuffer<[u8]>) -> Result<usize, UsbError>;
|
|
|
|
async fn write(&self, buffer: &[u8]) -> Result<usize, UsbError> {
|
|
let mut dma_buffer = self.allocate_dma_buffer(buffer.len())?;
|
|
MaybeUninit::copy_from_slice(&mut dma_buffer, buffer);
|
|
let dma_buffer = unsafe { DmaBuffer::assume_init_slice(dma_buffer) };
|
|
|
|
self.write_dma(&dma_buffer).await
|
|
}
|
|
}
|
|
|
|
pub struct UsbBulkInPipeAccess(pub Box<dyn UsbNormalPipeIn>);
|
|
pub struct UsbBulkOutPipeAccess(pub Box<dyn UsbNormalPipeOut>);
|
|
|
|
pub struct UsbInterruptInPipeAccess(pub Box<dyn UsbNormalPipeIn>);
|
|
pub struct UsbInterruptOutPipeAccess(pub Box<dyn UsbNormalPipeOut>);
|
|
|
|
impl Deref for UsbBulkInPipeAccess {
|
|
type Target = dyn UsbNormalPipeIn;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
self.0.deref()
|
|
}
|
|
}
|
|
|
|
impl Deref for UsbBulkOutPipeAccess {
|
|
type Target = dyn UsbNormalPipeOut;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
self.0.deref()
|
|
}
|
|
}
|
|
|
|
impl Deref for UsbInterruptInPipeAccess {
|
|
type Target = dyn UsbNormalPipeIn;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
self.0.deref()
|
|
}
|
|
}
|
|
|
|
impl Deref for UsbInterruptOutPipeAccess {
|
|
type Target = dyn UsbNormalPipeOut;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
self.0.deref()
|
|
}
|
|
}
|