#![cfg_attr(not(test), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(
unsafe_op_in_unsafe_fn,
unused_must_use,
missing_docs,
clippy::undocumented_unsafe_blocks
)]
#![allow(clippy::identity_op)]
#![allow(dead_code)]
#[cfg(any(feature = "alloc", test))]
extern crate alloc;
pub mod config;
pub mod device;
#[cfg(feature = "embedded-io")]
mod embedded_io;
mod hal;
pub mod queue;
pub mod transport;
use device::socket::SocketError;
use thiserror::Error;
pub use self::hal::{BufferDirection, Hal, PhysAddr};
pub use safe_mmio::UniqueMmioPointer;
pub const PAGE_SIZE: usize = 0x1000;
const PAGE_SIZE_PHYS: PhysAddr = PAGE_SIZE as PhysAddr;
pub type Result<T = ()> = core::result::Result<T, Error>;
#[derive(Copy, Clone, Debug, Eq, Error, PartialEq)]
pub enum Error {
#[error("Virtqueue is full")]
QueueFull,
#[error("Device not ready")]
NotReady,
#[error("Device used a different descriptor chain to the one we were expecting")]
WrongToken,
#[error("Virtqueue is already in use")]
AlreadyUsed,
#[error("Invalid parameter")]
InvalidParam,
#[error("Failed to allocate DMA memory")]
DmaError,
#[error("I/O error")]
IoError,
#[error("Request not supported by device")]
Unsupported,
#[error("Config space advertised by the device is smaller than expected")]
ConfigSpaceTooSmall,
#[error("The device doesn't have any config space, but the driver expects some")]
ConfigSpaceMissing,
#[error("Error from the socket device: {0}")]
SocketDeviceError(#[from] SocketError),
}
#[cfg(feature = "alloc")]
impl From<alloc::string::FromUtf8Error> for Error {
fn from(_value: alloc::string::FromUtf8Error) -> Self {
Self::IoError
}
}
fn align_up(size: usize) -> usize {
(size + PAGE_SIZE) & !(PAGE_SIZE - 1)
}
fn align_up_phys(size: PhysAddr) -> PhysAddr {
(size + PAGE_SIZE_PHYS) & !(PAGE_SIZE_PHYS - 1)
}
fn pages(size: usize) -> usize {
size.div_ceil(PAGE_SIZE)
}