1use alloc::{boxed::Box, vec::Vec};
2
3use crate::{
4 BlkError, DeviceInfo, DriverGeneric, IrqHandler, IrqSourceList, QueueInfo, QueueLimits,
5 Request, RequestId, RequestStatus,
6};
7
8pub trait Interface: DriverGeneric {
9 fn device_info(&self) -> DeviceInfo;
10
11 fn queue_limits(&self) -> QueueLimits;
12
13 fn create_queue(&mut self) -> Option<Box<dyn IQueue>>;
14
15 fn enable_irq(&self) {}
16
17 fn disable_irq(&self) {}
18
19 fn is_irq_enabled(&self) -> bool {
20 false
21 }
22
23 fn irq_sources(&self) -> IrqSourceList {
24 Vec::new()
25 }
26
27 fn take_irq_handler(&mut self, _source_id: usize) -> Option<Box<dyn IrqHandler>> {
28 None
29 }
30}
31
32pub unsafe trait IQueue: Send + 'static {
42 fn id(&self) -> usize;
43
44 fn info(&self) -> QueueInfo;
45
46 fn submit_request(&mut self, request: Request<'_>) -> Result<RequestId, BlkError>;
47
48 fn poll_request(&mut self, request: RequestId) -> Result<RequestStatus, BlkError>;
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54 use crate::{DeviceInfo, Event, QueueLimits, RequestOp};
55
56 struct NoopIrq;
57
58 impl IrqHandler for NoopIrq {
59 fn handle_irq(&self) -> Event {
60 let mut event = Event::none();
61 event.queues.insert(1);
62 event
63 }
64 }
65
66 struct Queue;
67
68 unsafe impl IQueue for Queue {
71 fn id(&self) -> usize {
72 1
73 }
74
75 fn info(&self) -> QueueInfo {
76 QueueInfo {
77 id: 1,
78 device: DeviceInfo::new(8, 512),
79 limits: QueueLimits::simple(512, u64::MAX),
80 }
81 }
82
83 fn submit_request(&mut self, request: Request<'_>) -> Result<RequestId, BlkError> {
84 assert!(matches!(request.op, RequestOp::Read | RequestOp::Write));
85 Ok(RequestId::new(1))
86 }
87
88 fn poll_request(&mut self, _request: RequestId) -> Result<RequestStatus, BlkError> {
89 Ok(RequestStatus::Complete)
90 }
91 }
92
93 #[test]
94 fn block_api_uses_unified_queue_and_irq_events() {
95 fn assert_queue<T: IQueue>() {}
96 fn assert_irq_handler<T: IrqHandler>() {}
97
98 assert_queue::<Queue>();
99 assert_irq_handler::<NoopIrq>();
100
101 let event = NoopIrq.handle_irq();
102 assert!(event.queues.contains(1));
103 }
104}