rdrive/
lib.rs

1#![no_std]
2
3extern crate alloc;
4
5use core::ptr::NonNull;
6pub use fdt_parser::Phandle;
7
8use register::DriverRegister;
9use spin::Mutex;
10
11mod device;
12pub mod error;
13mod id;
14mod manager;
15pub mod probe;
16pub mod register;
17pub use device::*;
18pub use manager::*;
19pub use probe::ProbeError;
20pub use rdif_base::{DriverGeneric, DriverResult, IrqId, io};
21
22static MANAGER: Mutex<Option<Manager>> = Mutex::new(None);
23
24#[derive(Debug, Clone)]
25pub enum DriverInfoKind {
26    Fdt { addr: NonNull<u8> },
27}
28
29unsafe impl Send for DriverInfoKind {}
30
31pub fn init(probe_kind: DriverInfoKind) {
32    MANAGER.lock().replace(Manager::new(probe_kind));
33}
34
35pub fn edit<F, T>(f: F) -> T
36where
37    F: FnOnce(&mut Manager) -> T,
38{
39    let mut g = MANAGER.lock();
40    f(g.as_mut().expect("manager not init"))
41}
42
43pub fn read<F, T>(f: F) -> T
44where
45    F: FnOnce(&Manager) -> T,
46{
47    let g = MANAGER.lock();
48    f(g.as_ref().expect("manager not init"))
49}
50
51pub fn register_add(register: DriverRegister) {
52    edit(|manager| manager.registers.add(register));
53}
54
55pub fn register_append(registers: &[DriverRegister]) {
56    edit(|manager| manager.registers.append(registers))
57}
58
59pub fn probe_pre_kernel() -> Result<(), ProbeError> {
60    edit(|manager| manager.probe_pre_kernel())
61}
62
63pub fn probe() -> Result<(), ProbeError> {
64    edit(|manager| manager.probe())
65}
66
67#[macro_export]
68macro_rules! dev_list {
69    ($k: ident) => {
70        $crate::read(|manager| {
71            manager
72                .dev_map
73                .iter()
74                .filter_map(|(_, v)| {
75                    if let $crate::DeviceKind::$k(dev) = v {
76                        Some(dev.weak())
77                    } else {
78                        None
79                    }
80                })
81                .collect::<alloc::vec::Vec<_>>()
82        })
83    };
84}
85#[macro_export]
86macro_rules! get_dev {
87    ($k:ident) => {
88        $crate::read(|m| {
89            manager
90                .dev_map
91                .iter()
92                .filter_map(|(_, v)| {
93                    if let $crate::DeviceKind::$k(dev) = v {
94                        Some(dev.weak())
95                    } else {
96                        None
97                    }
98                })
99                .next()
100        })
101    };
102    ($id:expr, $k:ident) => {
103        $crate::read(|m| {
104            let dev = m.dev_map.get(&$id)?;
105            if let $crate::DeviceKind::$k(dev) = dev {
106                Some(dev.weak())
107            } else {
108                None
109            }
110        })
111    };
112}