Skip to content

Commit f6adeb5

Browse files
authored
feat(storage): define storagemanager (#649)
* add storage device trait Signed-off-by: Koichi <[email protected]> * fix warings Signed-off-by: Koichi <[email protected]> * add get_namespaceid, get_blocksize Signed-off-by: Koichi <[email protected]> * fix namespace_id Signed-off-by: Koichi <[email protected]> * delete unnecessary comments Signed-off-by: Koichi <[email protected]> * fix add_storage_device Signed-off-by: Koichi <[email protected]> * separate trait and manager Signed-off-by: Koichi <[email protected]> * separate trait and amanger Signed-off-by: Koichi <[email protected]> * fix order Signed-off-by: Koichi <[email protected]> * fix get_device_block_size Signed-off-by: Koichi <[email protected]> * add get_storage_device Signed-off-by: Koichi <[email protected]> * fix Signed-off-by: Koichi <[email protected]> * delete device_info Signed-off-by: Koichi <[email protected]> * replace and_then Signed-off-by: Koichi <[email protected]> --------- Signed-off-by: Koichi <[email protected]>
1 parent 8d34229 commit f6adeb5

File tree

2 files changed

+180
-0
lines changed

2 files changed

+180
-0
lines changed

awkernel_lib/src/storage.rs

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,177 @@
1+
use crate::sync::{mcs::MCSNode, mutex::Mutex, rwlock::RwLock};
2+
use alloc::{
3+
borrow::Cow,
4+
collections::{btree_map::Entry, BTreeMap},
5+
sync::Arc,
6+
vec::Vec,
7+
};
8+
use storage_device::{StorageDevError, StorageDevice, StorageDeviceType};
9+
110
pub mod storage_device;
11+
12+
#[derive(Debug)]
13+
pub enum StorageManagerError {
14+
InvalidDeviceID,
15+
InvalidTransferID,
16+
DeviceError(StorageDevError),
17+
NotYetImplemented,
18+
PoolNotInitialized,
19+
}
20+
21+
#[derive(Debug)]
22+
pub struct StorageStatus {
23+
pub device_id: u64,
24+
pub device_name: Cow<'static, str>,
25+
pub device_type: StorageDeviceType,
26+
pub irqs: Vec<u16>,
27+
pub block_size: usize,
28+
pub num_blocks: u64,
29+
}
30+
31+
static STORAGE_MANAGER: RwLock<StorageManager> = RwLock::new(StorageManager {
32+
devices: BTreeMap::new(),
33+
device_id: 0,
34+
});
35+
36+
static IRQ_WAKERS: Mutex<BTreeMap<u16, IRQWaker>> = Mutex::new(BTreeMap::new());
37+
38+
pub struct StorageManager {
39+
devices: BTreeMap<u64, Arc<dyn StorageDevice>>,
40+
device_id: u64,
41+
}
42+
43+
enum IRQWaker {
44+
Waker(core::task::Waker),
45+
Interrupted,
46+
}
47+
48+
pub fn add_storage_device(device: Arc<dyn StorageDevice + Sync + Send>) -> u64 {
49+
let mut manager = STORAGE_MANAGER.write();
50+
51+
if manager.device_id == u64::MAX {
52+
panic!("storage device id overflow");
53+
}
54+
55+
let id = manager.device_id;
56+
manager.device_id += 1;
57+
58+
manager.devices.insert(id, device);
59+
60+
id
61+
}
62+
63+
pub fn get_device_block_size(device_id: u64) -> Result<usize, StorageManagerError> {
64+
let manager = STORAGE_MANAGER.read();
65+
66+
let device = manager
67+
.devices
68+
.get(&device_id)
69+
.ok_or(StorageManagerError::InvalidDeviceID)?;
70+
71+
Ok(device.block_size())
72+
}
73+
74+
pub fn get_storage_device(device_id: u64) -> Result<Arc<dyn StorageDevice>, StorageManagerError> {
75+
let manager = STORAGE_MANAGER.read();
76+
77+
let device = manager
78+
.devices
79+
.get(&device_id)
80+
.ok_or(StorageManagerError::InvalidDeviceID)?;
81+
82+
Ok(device.clone())
83+
}
84+
85+
pub fn get_storage_status(device_id: u64) -> Result<StorageStatus, StorageManagerError> {
86+
let manager = STORAGE_MANAGER.read();
87+
88+
let device = manager
89+
.devices
90+
.get(&device_id)
91+
.ok_or(StorageManagerError::InvalidDeviceID)?;
92+
93+
let status = StorageStatus {
94+
device_id,
95+
device_name: device.device_name(),
96+
device_type: device.device_type(),
97+
irqs: device.irqs(),
98+
block_size: device.block_size(),
99+
num_blocks: device.num_blocks(),
100+
};
101+
102+
Ok(status)
103+
}
104+
105+
pub fn get_all_storage_statuses() -> Vec<StorageStatus> {
106+
let manager = STORAGE_MANAGER.read();
107+
108+
let mut result = Vec::new();
109+
110+
for id in manager.devices.keys() {
111+
if let Ok(status) = get_storage_status(*id) {
112+
result.push(status);
113+
}
114+
}
115+
116+
result
117+
}
118+
119+
pub fn get_device_namespace(device_id: u64) -> Option<u32> {
120+
let manager = STORAGE_MANAGER.read();
121+
122+
let device = manager.devices.get(&device_id)?;
123+
device.get_namespace_id()
124+
}
125+
126+
/// Service routine for storage device interrupt.
127+
/// This routine should be called by interrupt handlers provided by device drivers.
128+
pub fn storage_interrupt(irq: u16) {
129+
let mut node = MCSNode::new();
130+
let mut w = IRQ_WAKERS.lock(&mut node);
131+
132+
match w.entry(irq) {
133+
Entry::Occupied(e) => {
134+
if matches!(e.get(), IRQWaker::Waker(_)) {
135+
let IRQWaker::Waker(w) = e.remove() else {
136+
return;
137+
};
138+
139+
w.wake();
140+
}
141+
}
142+
Entry::Vacant(e) => {
143+
e.insert(IRQWaker::Interrupted);
144+
}
145+
}
146+
}
147+
148+
/// Register a waker for a storage device interrupt service.
149+
///
150+
/// The old waker will be replaced.
151+
/// The waker will be called when the storage device interrupt occurs once
152+
/// and it will be removed after it is called.
153+
///
154+
/// Returns true if the waker is registered successfully.
155+
/// Returns false if the interrupt occurred before.
156+
pub fn register_waker_for_storage_interrupt(irq: u16, waker: core::task::Waker) -> bool {
157+
let mut node = MCSNode::new();
158+
let mut w = IRQ_WAKERS.lock(&mut node);
159+
160+
let entry = w.entry(irq);
161+
162+
match entry {
163+
Entry::Occupied(mut e) => {
164+
if matches!(e.get(), IRQWaker::Interrupted) {
165+
e.remove();
166+
false
167+
} else {
168+
e.insert(IRQWaker::Waker(waker));
169+
true
170+
}
171+
}
172+
Entry::Vacant(e) => {
173+
e.insert(IRQWaker::Waker(waker));
174+
true
175+
}
176+
}
177+
}

awkernel_lib/src/storage/storage_device.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,8 @@ pub trait StorageDevice: Send + Sync {
4343
fn flush(&self, _transfer_id: u16) -> Result<(), StorageDevError> {
4444
Ok(())
4545
}
46+
47+
fn get_namespace_id(&self) -> Option<u32> {
48+
None
49+
}
4650
}

0 commit comments

Comments
 (0)