1extern crate alloc;
2use alloc::collections::BTreeMap;
3use alloc::string::String;
4use alloc::sync::Arc;
5use alloc::vec::Vec;
6use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
7use lazy_static::lazy_static;
8use spin::RwLock;
9
10lazy_static! {
11 pub static ref DEVICE_MANAGER: RwLock<DeviceManager> = RwLock::new(DeviceManager::new());
12}
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum DeviceType {
16 Block,
17 Char,
18}
19
20#[derive(Debug, PartialEq, Eq, Clone, Copy)]
21pub enum DeviceError {
22 InvalidParam,
23 NotSupported,
24 IoError,
25 PermissionsDenied,
26 NoSuchDevice,
27 WouldBlock,
28 Busy,
29 OutOfMemory,
30 DeviceClosed,
31 BufferTooSmall,
32 AlreadyOpen,
33 NotOpen,
34 AddressOutOfRange,
35 DeviceAlreadyRegistered,
36 DeviceNumberConflict,
37 DeviceNotRegistered,
38 DeviceStillInUse,
39}
40
41#[derive(Debug, Clone, PartialEq, Eq)]
42pub struct ScanInfo {
43 pub device_id: String, pub protocol_type: String, pub vendor_id: Option<u16>, pub product_id: Option<u16>, pub additional_data: Option<BTreeMap<String, String>>, }
49
50pub trait SharedDeviceOps: Send + Sync {
51 fn name(&self) -> &str;
52 fn device_type(&self) -> DeviceType;
53
54 fn open(&self) -> Result<(), DeviceError>;
55 fn close(&self) -> Result<(), DeviceError>;
56 fn ioctl(&self, cmd: u64, arg: u64) -> Result<u64, DeviceError>;
57
58 fn sync(&self) -> Result<(), DeviceError> {
59 Err(DeviceError::NotSupported)
60 }
61 fn is_compatible(&self, _scan_info: &ScanInfo) -> bool {
62 false
63 }
64}
65
66pub trait BlockDevice: SharedDeviceOps {
67 fn block_size(&self) -> usize;
68 fn num_blocks(&self) -> usize;
69
70 fn read_blocks(
71 &self,
72 block_idx: usize,
73 num_blocks: usize,
74 buf: &mut [u8],
75 ) -> Result<usize, DeviceError>;
76
77 fn write_blocks(
78 &self,
79 block_idx: usize,
80 num_blocks: usize,
81 buf: &[u8],
82 ) -> Result<usize, DeviceError>;
83
84 fn erase_blocks(&self, start_block: usize, num_blocks: usize) -> Result<usize, DeviceError> {
86 let _ = (start_block, num_blocks);
87 Err(DeviceError::NotSupported)
88 }
89}
90
91pub trait CharDevice: SharedDeviceOps {
92 fn read(&self, buf: &mut [u8]) -> Result<usize, DeviceError>;
93 fn write(&self, buf: &[u8]) -> Result<usize, DeviceError>;
94
95 fn peek(&self, buf: &mut [u8]) -> Result<usize, DeviceError> {
96 let _ = buf;
97 Err(DeviceError::NotSupported)
98 }
99
100 fn has_data(&self) -> bool {
101 false
102 }
103
104 fn has_space(&self) -> bool {
105 false
106 }
107
108 fn set_nonblocking(&self, nonblocking: bool) -> Result<(), DeviceError> {
109 let _ = nonblocking;
110 Err(DeviceError::NotSupported)
111 }
112}
113
114#[derive(Clone)]
115pub enum DeviceInner {
116 Char(Arc<dyn CharDevice>),
117 Block(Arc<dyn BlockDevice>),
118}
119
120#[cfg(test)]
121pub struct TestDevice;
122
123#[cfg(test)]
124impl SharedDeviceOps for TestDevice {
125 fn name(&self) -> &str {
126 "null"
127 }
128 fn device_type(&self) -> DeviceType {
129 DeviceType::Char
130 }
131
132 fn open(&self) -> Result<(), DeviceError> {
133 Ok(())
134 }
135 fn close(&self) -> Result<(), DeviceError> {
136 Ok(())
137 }
138 fn ioctl(&self, _cmd: u64, _arg: u64) -> Result<u64, DeviceError> {
139 Err(DeviceError::NotSupported)
140 }
141}
142
143#[cfg(test)]
144impl CharDevice for TestDevice {
145 fn read(&self, _buf: &mut [u8]) -> Result<usize, DeviceError> {
146 Ok(0)
147 }
148 fn write(&self, buf: &[u8]) -> Result<usize, DeviceError> {
149 Ok(buf.len())
150 }
151}
152
153pub struct Device {
154 pub name: String,
155 pub major: u16,
156 pub minor: u16,
157 pub inner: DeviceInner,
158 open_count: AtomicUsize,
159 is_registered: AtomicBool,
160}
161
162impl Device {
163 pub fn new(name: String, major: u16, minor: u16, inner: DeviceInner) -> Self {
164 Self {
165 name,
166 major,
167 minor,
168 inner,
169 open_count: AtomicUsize::new(0),
170 is_registered: AtomicBool::new(false),
171 }
172 }
173
174 pub fn new_auto_assign(name: String, inner: DeviceInner) -> Self {
175 Self {
176 name,
177 major: 0,
178 minor: 0,
179 inner,
180 open_count: AtomicUsize::new(0),
181 is_registered: AtomicBool::new(false),
182 }
183 }
184
185 #[cfg(test)]
186 pub fn null() -> Self {
187 Self::new_auto_assign(
188 String::from("null"),
189 DeviceInner::Char(Arc::new(TestDevice)),
190 )
191 }
192
193 #[inline]
194 fn shared_ops(&self) -> &dyn SharedDeviceOps {
195 match &self.inner {
196 DeviceInner::Block(ops) => ops.as_ref(),
197 DeviceInner::Char(ops) => ops.as_ref(),
198 }
199 }
200
201 pub fn device_type(&self) -> DeviceType {
202 self.shared_ops().device_type()
203 }
204
205 pub fn open(&self) -> Result<(), DeviceError> {
206 if !self.is_registered.load(Ordering::SeqCst) {
207 return Err(DeviceError::DeviceNotRegistered);
208 }
209
210 let current_count = self.open_count.fetch_add(1, Ordering::SeqCst);
211 if current_count == 0 {
212 self.shared_ops().open()?;
213 }
214 Ok(())
215 }
216
217 pub fn close(&self) -> Result<(), DeviceError> {
218 if !self.is_registered.load(Ordering::SeqCst) {
219 return Err(DeviceError::DeviceNotRegistered);
220 }
221
222 let current_count = self.open_count.fetch_sub(1, Ordering::SeqCst);
223 if current_count == 1 {
224 self.shared_ops().close()?;
225 } else if current_count == 0 {
226 return Err(DeviceError::NotOpen);
227 }
228 Ok(())
229 }
230
231 pub fn ioctl(&self, cmd: u64, arg: u64) -> Result<u64, DeviceError> {
232 if !self.is_registered.load(Ordering::SeqCst) {
233 return Err(DeviceError::DeviceNotRegistered);
234 }
235 if self.open_count.load(Ordering::SeqCst) == 0 {
236 return Err(DeviceError::DeviceClosed);
237 }
238 self.shared_ops().ioctl(cmd, arg)
239 }
240
241 pub fn is_open(&self) -> bool {
242 self.open_count.load(Ordering::Relaxed) > 0
243 }
244
245 pub fn as_block_device(&self) -> Option<&Arc<dyn BlockDevice>> {
246 if let DeviceInner::Block(ref ops) = self.inner {
247 Some(ops)
248 } else {
249 None
250 }
251 }
252
253 pub fn as_char_device(&self) -> Option<&Arc<dyn CharDevice>> {
254 if let DeviceInner::Char(ref ops) = self.inner {
255 Some(ops)
256 } else {
257 None
258 }
259 }
260
261 fn mark_registered(&self) {
262 self.is_registered.store(true, Ordering::SeqCst);
263 }
264
265 fn mark_unregistered(&self) {
266 self.is_registered.store(false, Ordering::SeqCst);
267 }
268}
269
270impl core::fmt::Debug for Device {
271 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
272 write!(
273 f,
274 "Device {{ name: {}, major: {}, minor: {}, open_count: {}, is_registered: {} }}",
275 self.name,
276 self.major,
277 self.minor,
278 self.open_count.load(Ordering::SeqCst),
279 self.is_registered.load(Ordering::SeqCst)
280 )
281 }
282}
283
284impl Clone for Device {
285 fn clone(&self) -> Self {
286 Self {
287 name: self.name.clone(),
288 major: self.major,
289 minor: self.minor,
290 open_count: AtomicUsize::new(self.open_count.load(Ordering::SeqCst)),
291 is_registered: AtomicBool::new(self.is_registered.load(Ordering::SeqCst)),
292 inner: self.inner.clone(),
293 }
294 }
295}
296
297#[derive(Default)]
298pub struct DeviceManager {
299 devices: Vec<Arc<Device>>,
300 next_minor_counters: BTreeMap<u16, u16>,
301 free_minors: BTreeMap<u16, Vec<u16>>,
302}
303
304impl DeviceManager {
305 pub fn new() -> Self {
306 Self::default()
307 }
308
309 pub fn register_device(&mut self, mut device: Device) -> Result<Arc<Device>, DeviceError> {
310 if self.devices.iter().any(|d| d.name == device.name) {
311 return Err(DeviceError::DeviceAlreadyRegistered);
312 }
313
314 if device.major == 0 && device.minor == 0 {
315 let (major, minor) = self.alloc_device_number(device.device_type())?;
316 device.major = major;
317 device.minor = minor;
318 } else {
319 if self
320 .devices
321 .iter()
322 .any(|d| d.major == device.major && d.minor == device.minor)
323 {
324 return Err(DeviceError::DeviceNumberConflict);
325 }
326
327 self.update_minor_counter(device.major, device.minor);
328 }
329
330 device.mark_registered();
331 let device_arc = Arc::new(device);
332 self.devices.push(device_arc.clone());
333 Ok(device_arc)
334 }
335
336 fn alloc_device_number(&mut self, device_type: DeviceType) -> Result<(u16, u16), DeviceError> {
337 let major = match device_type {
338 DeviceType::Char => 1,
339 DeviceType::Block => 2,
340 };
341
342 if let Some(minor) = self.free_minors.get_mut(&major).and_then(|v| v.pop()) {
343 return Ok((major, minor));
344 }
345
346 let next_minor = self.next_minor_counters.entry(major).or_insert(0);
347 let mut current_minor = *next_minor;
348
349 for _ in 0..u16::MAX as usize {
350 let is_used = self
351 .devices
352 .iter()
353 .any(|d| d.major == major && d.minor == current_minor);
354
355 if !is_used {
356 *next_minor = current_minor.checked_add(1).unwrap_or(0);
357 return Ok((major, current_minor));
358 }
359 current_minor = current_minor.checked_add(1).unwrap_or(0);
360 }
361
362 Err(DeviceError::OutOfMemory)
363 }
364
365 pub fn is_minor_used(&self, major: u16, minor: u16) -> bool {
366 self.devices
367 .iter()
368 .any(|d| d.major == major && d.minor == minor)
369 }
370
371 fn update_minor_counter(&mut self, major: u16, minor: u16) {
372 let counter = self.next_minor_counters.entry(major).or_insert(0);
373 if minor >= *counter {
374 *counter = minor + 1;
375 }
376 }
377
378 pub fn unregister_device(&mut self, name: &str) -> Result<(), DeviceError> {
379 let position = self.devices.iter().position(|d| d.name == name);
380
381 if let Some(index) = position {
382 if self.devices[index].is_open() {
383 return Err(DeviceError::DeviceStillInUse);
384 }
385
386 let device_arc = self.devices.remove(index);
387 device_arc.mark_unregistered();
388 self.reclaim_device_number(device_arc.major, device_arc.minor);
389 Ok(())
390 } else {
391 Err(DeviceError::NoSuchDevice)
392 }
393 }
394
395 fn reclaim_device_number(&mut self, major: u16, minor: u16) {
396 self.free_minors.entry(major).or_default().push(minor);
397 }
398
399 pub fn get_device(&self, name: &str) -> Option<Arc<Device>> {
400 self.devices.iter().find(|d| d.name == name).cloned()
401 }
402
403 pub fn get_device_by_major_minor(&self, major: u16, minor: u16) -> Option<Arc<Device>> {
404 self.devices
405 .iter()
406 .find(|d| d.major == major && d.minor == minor)
407 .cloned()
408 }
409
410 pub fn get_devices_by_type(&self, device_type: DeviceType) -> Vec<Arc<Device>> {
411 self.devices
412 .iter()
413 .filter(|d| d.device_type() == device_type)
414 .cloned()
415 .collect()
416 }
417
418 pub fn list_devices(&self) -> Vec<Arc<Device>> {
419 self.devices.clone()
420 }
421}
422
423pub fn init_devices() {
424 let mut manager = DEVICE_MANAGER.write();
425 manager
426 .register_device(super::char::serial::SerialDevice::create_device(
427 1, 0, 0x3f8,
428 ))
429 .expect("Failed to register serial device");
430
431 manager
432 .register_device(super::input::keyboard::Keyboard::create_device())
433 .expect("Failed to register keyboard device");
434}