1#![cfg_attr(
6 feature = "nightly",
7 feature(non_exhaustive_omitted_patterns_lint, strict_provenance_lints)
8)]
9#![cfg_attr(
10 feature = "nightly",
11 warn(
12 fuzzy_provenance_casts,
13 lossy_provenance_casts,
14 unnameable_types,
15 non_exhaustive_omitted_patterns,
16 )
17)]
18#![doc = include_str!("../README.md")]
19#![allow(unsafe_code)]
20
21use core::fmt;
22use std::{
23 fs::File,
24 io,
25 os::{fd::AsFd as _, unix::io::OwnedFd},
26 path::PathBuf,
27};
28
29mod ioctl;
30use ioctl::dma_heap_alloc;
31use log::debug;
32
33#[derive(Clone, Debug)]
35pub enum HeapKind {
36 Cma,
39
40 System,
43
44 Custom(PathBuf),
46}
47
48impl fmt::Display for HeapKind {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 match self {
51 HeapKind::Cma => f.write_str("CMA"),
52 HeapKind::System => f.write_str("System"),
53 HeapKind::Custom(p) => f.write_fmt(format_args!("Custom Heap ({})", p.display())),
54 }
55 }
56}
57
58#[derive(Debug)]
60pub struct Heap {
61 file: File,
62 name: HeapKind,
63}
64
65impl Heap {
66 pub fn new(name: HeapKind) -> io::Result<Self> {
72 let path = match &name {
73 HeapKind::Cma => PathBuf::from("/dev/dma_heap/linux,cma"),
74 HeapKind::System => PathBuf::from("/dev/dma_heap/system"),
75 HeapKind::Custom(p) => p.clone(),
76 };
77
78 debug!("Using the {name} DMA-Buf Heap, at {}", path.display());
79
80 let file = File::open(&path)?;
81
82 debug!("Heap found!");
83
84 Ok(Self { file, name })
85 }
86
87 pub fn allocate(&self, len: usize) -> io::Result<OwnedFd> {
98 debug!("Allocating Buffer of size {} on {} Heap", len, self.name);
99
100 let fd = dma_heap_alloc(self.file.as_fd(), len)?;
101
102 debug!("Allocation succeeded, Buffer File Descriptor {fd:#?}");
103
104 Ok(fd)
105 }
106}