1use alloc::{collections::btree_map::BTreeMap, vec::Vec};
2
3use rdif_base::DriverGeneric;
4
5use crate::{
6 Descriptor, Device, DeviceId, DeviceOwner, GetDeviceError,
7 error::DriverError,
8 probe::ProbeError,
9 register::{DriverRegister, RegisterContainer},
10};
11
12pub struct Manager {
13 pub registers: RegisterContainer,
14 pub(crate) dev_container: DeviceContainer,
15 }
17
18impl Manager {
19 pub fn new() -> Result<Self, DriverError> {
20 Ok(Self {
21 registers: RegisterContainer::default(),
23 dev_container: DeviceContainer::default(),
24 })
25 }
26
27 pub fn unregistered(&mut self) -> Result<Vec<DriverRegister>, ProbeError> {
28 let mut out = self.registers.unregistered();
29 out.sort_by(|a, b| a.priority.cmp(&b.priority));
30 Ok(out)
31 }
32}
33
34#[derive(Default)]
35pub(crate) struct DeviceContainer {
36 devices: BTreeMap<DeviceId, DeviceOwner>,
37}
38
39impl DeviceContainer {
40 pub fn insert<T: DriverGeneric>(&mut self, descriptor: Descriptor, device: T) {
41 self.devices
42 .insert(descriptor.device_id, DeviceOwner::new(descriptor, device));
43 }
44
45 pub fn get_typed<T: DriverGeneric>(&self, id: DeviceId) -> Result<Device<T>, GetDeviceError> {
46 let dev = self.devices.get(&id).ok_or(GetDeviceError::NotFound)?;
47
48 dev.weak()
49 }
50
51 pub fn get_one<T: DriverGeneric>(&self) -> Option<Device<T>> {
52 for dev in self.devices.values() {
53 if let Ok(val) = dev.weak::<T>() {
54 return Some(val);
55 }
56 }
57 None
58 }
59
60 pub fn devices<T: DriverGeneric>(&self) -> Vec<Device<T>> {
61 let mut result = Vec::new();
62 for dev in self.devices.values() {
63 if let Ok(val) = dev.weak::<T>() {
64 result.push(val);
65 }
66 }
67 result
68 }
69}
70
71#[cfg(test)]
72mod tests {
73
74 use crate::driver::{DriverGeneric, Empty};
75 use rdif_intc::*;
76
77 use super::*;
78
79 struct DeviceTest {
80 opened: bool,
81 }
82
83 impl DriverGeneric for DeviceTest {
84 fn open(&mut self) -> Result<(), rdif_base::KError> {
85 self.opened = true;
86 Ok(())
87 }
88
89 fn close(&mut self) -> Result<(), rdif_base::KError> {
90 if !self.opened {
91 panic!("Device not opened before closing");
92 }
93 self.opened = false;
94 Ok(())
95 }
96 }
97
98 #[test]
99 fn test_device_container() {
100 let mut container = DeviceContainer::default();
101 let desc = Descriptor::new();
102 let id = desc.device_id;
103 container.insert(desc, Empty);
104 let weak = container.get_typed::<Empty>(id).unwrap();
105
106 {
107 let mut device = weak.lock().unwrap();
108
109 assert!(device.open().is_ok());
110 assert!(device.close().is_ok());
111 }
112
113 {
114 let mut device = weak.lock().unwrap();
115
116 assert!(device.open().is_ok());
117 assert!(device.close().is_ok());
118 }
119 }
120 #[test]
121 fn test_get_one() {
122 let mut container = DeviceContainer::default();
123 container.insert(Descriptor::new(), Empty);
124 container.insert(Descriptor::new(), DeviceTest { opened: false });
125
126 let weak = container.get_one::<Empty>().unwrap();
127 {
128 let mut device = weak.lock().unwrap();
129 assert!(device.open().is_ok());
130 assert!(device.close().is_ok());
131 }
132 }
133
134 #[test]
135 fn test_devices() {
136 let mut container = DeviceContainer::default();
137 container.insert(Descriptor::new(), Empty);
138 container.insert(Descriptor::new(), Empty);
139 container.insert(Descriptor::new(), DeviceTest { opened: false });
140 let devices = container.devices::<Empty>();
141 assert_eq!(devices.len(), 2);
142 }
143
144 #[test]
145 fn test_not_found() {
146 let container = DeviceContainer::default();
147 let dev = container.get_one::<Intc>();
148 assert!(dev.is_none(), "Expected no devices found");
149
150 if let Some(dev) = dev {
151 let weak = dev.lock().unwrap();
152 let f = weak.parse_dtb_fn();
153 assert!(f.is_none(), "Expected no parse function for empty device");
154 }
155 }
156
157 struct IrqTest {}
158
159 impl IrqTest {
160 fn is_ok(&mut self) -> bool {
161 true }
163 }
164
165 impl crate::DriverGeneric for IrqTest {
166 fn open(&mut self) -> Result<(), KError> {
167 Ok(())
168 }
169
170 fn close(&mut self) -> Result<(), KError> {
171 Ok(())
172 }
173 }
174
175 impl Interface for IrqTest {}
176
177 #[test]
178 fn test_inner_type() {
179 let mut container = DeviceContainer::default();
180 let desc = Descriptor::new();
181 container.insert(desc, Intc::new(IrqTest {}));
182
183 let weak = container.get_one::<Intc>().unwrap();
184 {
185 let device = weak.lock().unwrap();
186 let intc = device.typed_ref::<IrqTest>();
187 assert!(intc.is_some(), "Expected to find IrqTest device");
188 }
189 }
190
191 #[test]
192 fn test_device_downcast() {
193 let mut container = DeviceContainer::default();
194 let desc = Descriptor::new();
195 container.insert(desc, Intc::new(IrqTest {}));
196
197 let weak = container.get_one::<Intc>().unwrap();
198 let intc_typed = weak.downcast::<IrqTest>().unwrap();
199 let mut device = intc_typed.lock().unwrap();
200 assert!(device.is_ok(), "Expected device to be ok");
201 }
202
203 #[test]
204 fn test_locked_device() {
205 let mut container = DeviceContainer::default();
206 let desc = Descriptor::new();
207 let id = desc.device_id;
208 container.insert(desc, Empty);
209
210 let weak = container.get_typed::<Empty>(id).unwrap();
211 let device = weak.lock().unwrap();
212 let r = weak.try_lock();
213 assert!(
214 r.is_err(),
215 "Expected error when trying to lock an already locked device"
216 );
217 let _ = device;
218 }
219}