#![cfg_attr(
feature = "nightly",
feature(non_exhaustive_omitted_patterns_lint, strict_provenance_lints)
)]
#![cfg_attr(
feature = "nightly",
warn(
fuzzy_provenance_casts,
lossy_provenance_casts,
unnameable_types,
non_exhaustive_omitted_patterns,
)
)]
#![doc = include_str!("../README.md")]
#![allow(unsafe_code)]
use core::fmt;
use std::{
fs::File,
io,
os::{fd::AsFd as _, unix::io::OwnedFd},
path::PathBuf,
};
mod ioctl;
use ioctl::dma_heap_alloc;
use log::debug;
#[derive(Clone, Debug)]
pub enum HeapKind {
Cma,
System,
Custom(PathBuf),
}
impl fmt::Display for HeapKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
HeapKind::Cma => f.write_str("CMA"),
HeapKind::System => f.write_str("System"),
HeapKind::Custom(p) => f.write_fmt(format_args!("Custom Heap ({})", p.display())),
}
}
}
#[derive(Debug)]
pub struct Heap {
file: File,
name: HeapKind,
}
impl Heap {
pub fn new(name: HeapKind) -> io::Result<Self> {
let path = match &name {
HeapKind::Cma => PathBuf::from("/dev/dma_heap/linux,cma"),
HeapKind::System => PathBuf::from("/dev/dma_heap/system"),
HeapKind::Custom(p) => p.clone(),
};
debug!("Using the {name} DMA-Buf Heap, at {}", path.display());
let file = File::open(&path)?;
debug!("Heap found!");
Ok(Self { file, name })
}
pub fn allocate(&self, len: usize) -> io::Result<OwnedFd> {
debug!("Allocating Buffer of size {} on {} Heap", len, self.name);
let fd = dma_heap_alloc(self.file.as_fd(), len)?;
debug!("Allocation succeeded, Buffer File Descriptor {fd:#?}");
Ok(fd)
}
}