Skip to main content

proka_kernel/drivers/
device.rs

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,                                 // 设备唯一标识
44    pub protocol_type: String,                             // 通信协议类型(如USB/PCI/I2C)
45    pub vendor_id: Option<u16>,                            // 供应商ID
46    pub product_id: Option<u16>,                           // 产品ID
47    pub additional_data: Option<BTreeMap<String, String>>, // 附加数据
48}
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    // 新增擦除块操作
85    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}