kernel/device/block/
mod.rs1use core::any::Any;
2
3use alloc::{boxed::Box, vec::Vec};
4use request::{BlockIORequest, BlockIOResult};
5use spin::Mutex;
6
7use super::Device;
8use crate::object::capability::selectable::Selectable;
9use crate::object::capability::{ControlOps, MemoryMappingOps};
10
11pub mod request;
12
13extern crate alloc;
14
15pub trait BlockDevice: Device {
20 fn get_disk_name(&self) -> &'static str;
22
23 fn get_disk_size(&self) -> usize;
25
26 fn enqueue_request(&self, request: Box<BlockIORequest>);
28
29 fn process_requests(&self) -> Vec<BlockIOResult>;
35}
36
37pub struct GenericBlockDevice {
39 disk_name: &'static str,
40 disk_size: usize,
41 request_fn: fn(&mut BlockIORequest) -> Result<(), &'static str>,
42 request_queue: Mutex<Vec<Box<BlockIORequest>>>,
43}
44
45impl GenericBlockDevice {
46 pub fn new(
47 disk_name: &'static str,
48 disk_size: usize,
49 request_fn: fn(&mut BlockIORequest) -> Result<(), &'static str>,
50 ) -> Self {
51 Self {
52 disk_name,
53 disk_size,
54 request_fn,
55 request_queue: Mutex::new(Vec::new()),
56 }
57 }
58}
59
60impl Device for GenericBlockDevice {
61 fn device_type(&self) -> super::DeviceType {
62 super::DeviceType::Block
63 }
64
65 fn name(&self) -> &'static str {
66 self.disk_name
67 }
68
69 fn as_any(&self) -> &dyn Any {
70 self
71 }
72
73 fn as_any_mut(&mut self) -> &mut dyn Any {
74 self
75 }
76
77 fn as_block_device(&self) -> Option<&dyn BlockDevice> {
78 Some(self)
79 }
80}
81
82impl ControlOps for GenericBlockDevice {
83 fn control(&self, _command: u32, _arg: usize) -> Result<i32, &'static str> {
85 Err("Control operations not supported")
86 }
87}
88
89impl MemoryMappingOps for GenericBlockDevice {
90 fn get_mapping_info(
91 &self,
92 _offset: usize,
93 _length: usize,
94 ) -> Result<(usize, usize, bool), &'static str> {
95 Err("Memory mapping not supported by this block device")
96 }
97
98 fn on_mapped(&self, _vaddr: usize, _paddr: usize, _length: usize, _offset: usize) {
99 }
101
102 fn on_unmapped(&self, _vaddr: usize, _length: usize) {
103 }
105
106 fn supports_mmap(&self) -> bool {
107 false
108 }
109}
110
111impl Selectable for GenericBlockDevice {
112 fn wait_until_ready(
113 &self,
114 _interest: crate::object::capability::selectable::ReadyInterest,
115 _trapframe: &mut crate::arch::Trapframe,
116 _timeout_ticks: Option<u64>,
117 ) -> crate::object::capability::selectable::SelectWaitOutcome {
118 crate::object::capability::selectable::SelectWaitOutcome::Ready
119 }
120}
121
122impl BlockDevice for GenericBlockDevice {
123 fn get_disk_name(&self) -> &'static str {
124 self.disk_name
125 }
126
127 fn get_disk_size(&self) -> usize {
128 self.disk_size
129 }
130
131 fn enqueue_request(&self, request: Box<BlockIORequest>) {
132 self.request_queue.lock().push(request);
134 }
135
136 fn process_requests(&self) -> Vec<BlockIOResult> {
153 let mut results = Vec::new();
154
155 let requests = {
157 let mut queue = self.request_queue.lock();
158 core::mem::replace(&mut *queue, Vec::new())
159 }; for mut request in requests {
163 let result = (self.request_fn)(&mut *request);
165
166 results.push(BlockIOResult { request, result });
168 }
169
170 results
171 }
172}
173
174#[cfg(test)]
175mod tests;
176
177#[cfg(test)]
178pub mod mockblk;