Nothing to see here, move along meow
1#[derive(Clone, Copy)]
2#[repr(u8)]
3pub enum BlockOpType {
4 Read = 0,
5 Write = 1,
6 ReadComplete = 2,
7 WriteComplete = 3,
8 Flush = 4,
9 FlushComplete = 5,
10}
11
12impl BlockOpType {
13 pub const fn from_u8(v: u8) -> Option<Self> {
14 match v {
15 0 => Some(Self::Read),
16 1 => Some(Self::Write),
17 2 => Some(Self::ReadComplete),
18 3 => Some(Self::WriteComplete),
19 4 => Some(Self::Flush),
20 5 => Some(Self::FlushComplete),
21 _ => None,
22 }
23 }
24}
25
26#[derive(Clone, Copy)]
27#[repr(C)]
28pub struct BlockRequest {
29 pub op: u8,
30 pub _pad: [u8; 3],
31 pub tag: u32,
32 pub lba: u64,
33 pub count: u16,
34 pub _pad2: [u8; 2],
35 pub buf_offset: u32,
36}
37
38impl BlockRequest {
39 pub const SIZE: usize = core::mem::size_of::<Self>();
40
41 pub const fn read(tag: u32, lba: u64, count: u16, buf_offset: u32) -> Self {
42 Self {
43 op: BlockOpType::Read as u8,
44 _pad: [0; 3],
45 tag,
46 lba,
47 count,
48 _pad2: [0; 2],
49 buf_offset,
50 }
51 }
52
53 pub const fn write(tag: u32, lba: u64, count: u16, buf_offset: u32) -> Self {
54 Self {
55 op: BlockOpType::Write as u8,
56 _pad: [0; 3],
57 tag,
58 lba,
59 count,
60 _pad2: [0; 2],
61 buf_offset,
62 }
63 }
64
65 pub const fn flush(tag: u32) -> Self {
66 Self {
67 op: BlockOpType::Flush as u8,
68 _pad: [0; 3],
69 tag,
70 lba: 0,
71 count: 0,
72 _pad2: [0; 2],
73 buf_offset: 0,
74 }
75 }
76
77 pub fn op_type(&self) -> Option<BlockOpType> {
78 BlockOpType::from_u8(self.op)
79 }
80
81 pub fn as_bytes(&self) -> &[u8] {
82 unsafe { core::slice::from_raw_parts(self as *const Self as *const u8, Self::SIZE) }
83 }
84
85 pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
86 match bytes.len() >= Self::SIZE {
87 true => Some(unsafe { core::ptr::read_unaligned(bytes.as_ptr() as *const Self) }),
88 false => None,
89 }
90 }
91}
92
93#[derive(Clone, Copy)]
94#[repr(C)]
95pub struct BlockResponse {
96 pub op: u8,
97 pub _pad: [u8; 1],
98 pub status: u16,
99 pub tag: u32,
100}
101
102impl BlockResponse {
103 pub const SIZE: usize = core::mem::size_of::<Self>();
104
105 pub const fn read_complete(tag: u32, status: u16) -> Self {
106 Self {
107 op: BlockOpType::ReadComplete as u8,
108 _pad: [0; 1],
109 status,
110 tag,
111 }
112 }
113
114 pub const fn write_complete(tag: u32, status: u16) -> Self {
115 Self {
116 op: BlockOpType::WriteComplete as u8,
117 _pad: [0; 1],
118 status,
119 tag,
120 }
121 }
122
123 pub const fn flush_complete(tag: u32, status: u16) -> Self {
124 Self {
125 op: BlockOpType::FlushComplete as u8,
126 _pad: [0; 1],
127 status,
128 tag,
129 }
130 }
131
132 pub fn as_bytes(&self) -> &[u8] {
133 unsafe { core::slice::from_raw_parts(self as *const Self as *const u8, Self::SIZE) }
134 }
135
136 pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
137 match bytes.len() >= Self::SIZE {
138 true => Some(unsafe { core::ptr::read_unaligned(bytes.as_ptr() as *const Self) }),
139 false => None,
140 }
141 }
142}