#![no_std]
extern crate alloc;
use alloc::boxed::Box;
use core::ops::{Deref, DerefMut};
pub use dma_api;
pub use rdif_base::{DriverGeneric, KError, io};
pub struct BuffConfig {
pub dma_mask: u64,
pub align: usize,
pub size: usize,
}
#[derive(thiserror::Error, Debug)]
pub enum BlkError {
#[error("Operation not supported")]
NotSupported,
#[error("Operation should be retried")]
Retry,
#[error("Insufficient memory")]
NoMemory,
#[error("Invalid block index: {0} (check device capacity and block accessibility)")]
InvalidBlockIndex(usize),
#[error("Other error: {0}")]
Other(Box<dyn core::error::Error>),
}
impl From<BlkError> for io::ErrorKind {
fn from(value: BlkError) -> Self {
match value {
BlkError::NotSupported => io::ErrorKind::Unsupported,
BlkError::Retry => io::ErrorKind::Interrupted,
BlkError::NoMemory => io::ErrorKind::OutOfMemory,
BlkError::InvalidBlockIndex(_) => io::ErrorKind::NotAvailable,
BlkError::Other(e) => io::ErrorKind::Other(e),
}
}
}
impl From<dma_api::DmaError> for BlkError {
fn from(value: dma_api::DmaError) -> Self {
match value {
dma_api::DmaError::NoMemory => BlkError::NoMemory,
e => BlkError::Other(Box::new(e)),
}
}
}
pub trait Interface: DriverGeneric {
fn create_queue(&mut self) -> Option<Box<dyn IQueue>>;
fn enable_irq(&mut self);
fn disable_irq(&mut self);
fn is_irq_enabled(&self) -> bool;
fn handle_irq(&mut self) -> Event;
}
#[repr(transparent)]
#[derive(Debug, Clone, Copy)]
pub struct IdList(u64);
impl IdList {
pub const fn none() -> Self {
Self(0)
}
pub fn contains(&self, id: usize) -> bool {
(self.0 & (1 << id)) != 0
}
pub fn insert(&mut self, id: usize) {
self.0 |= 1 << id;
}
pub fn remove(&mut self, id: usize) {
self.0 &= !(1 << id);
}
pub fn iter(&self) -> impl Iterator<Item = usize> {
(0..64).filter(move |i| self.contains(*i))
}
}
#[derive(Debug, Clone, Copy)]
pub struct Event {
pub queue: IdList,
}
impl Event {
pub const fn none() -> Self {
Self {
queue: IdList::none(),
}
}
}
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RequestId(usize);
impl RequestId {
pub fn new(id: usize) -> Self {
Self(id)
}
}
impl From<RequestId> for usize {
fn from(value: RequestId) -> Self {
value.0
}
}
#[derive(Clone, Copy)]
pub struct Buffer {
pub virt: *mut u8,
pub bus: u64,
pub size: usize,
}
impl Deref for Buffer {
type Target = [u8];
fn deref(&self) -> &Self::Target {
unsafe { core::slice::from_raw_parts(self.virt, self.size) }
}
}
impl DerefMut for Buffer {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { core::slice::from_raw_parts_mut(self.virt, self.size) }
}
}
pub trait IQueue: Send + 'static {
fn id(&self) -> usize;
fn num_blocks(&self) -> usize;
fn block_size(&self) -> usize;
fn buff_config(&self) -> BuffConfig;
fn submit_request(&mut self, request: Request<'_>) -> Result<RequestId, BlkError>;
fn poll_request(&mut self, request: RequestId) -> Result<(), BlkError>;
}
#[derive(Clone)]
pub struct Request<'a> {
pub block_id: usize,
pub kind: RequestKind<'a>,
}
#[derive(Clone)]
pub enum RequestKind<'a> {
Read(Buffer),
Write(&'a [u8]),
}