Nothing to see here, move along meow
1#[derive(Clone, Copy)]
2#[repr(C)]
3pub struct SubmissionEntry {
4 pub cdw0: u32,
5 pub nsid: u32,
6 pub cdw2: u32,
7 pub cdw3: u32,
8 pub mptr: u64,
9 pub prp1: u64,
10 pub prp2: u64,
11 pub cdw10: u32,
12 pub cdw11: u32,
13 pub cdw12: u32,
14 pub cdw13: u32,
15 pub cdw14: u32,
16 pub cdw15: u32,
17}
18
19impl SubmissionEntry {
20 pub const fn zeroed() -> Self {
21 Self {
22 cdw0: 0,
23 nsid: 0,
24 cdw2: 0,
25 cdw3: 0,
26 mptr: 0,
27 prp1: 0,
28 prp2: 0,
29 cdw10: 0,
30 cdw11: 0,
31 cdw12: 0,
32 cdw13: 0,
33 cdw14: 0,
34 cdw15: 0,
35 }
36 }
37
38 pub const fn cid(&self) -> u16 {
39 (self.cdw0 >> 16) as u16
40 }
41
42 const fn with_opcode_cid(opcode: u8, cid: u16) -> Self {
43 let mut e = Self::zeroed();
44 e.cdw0 = (opcode as u32) | ((cid as u32) << 16);
45 e
46 }
47}
48
49#[derive(Clone, Copy)]
50#[repr(C)]
51pub struct CompletionEntry {
52 pub dw0: u32,
53 pub dw1: u32,
54 pub sq_head_sqid: u32,
55 pub status_phase: u32,
56}
57
58impl CompletionEntry {
59 pub fn status(&self) -> u16 {
60 ((self.status_phase >> 17) & 0x7FFF) as u16
61 }
62
63 pub fn cid(&self) -> u16 {
64 (self.status_phase & 0xFFFF) as u16
65 }
66}
67
68const ADMIN_IDENTIFY: u8 = 0x06;
69const ADMIN_CREATE_IO_CQ: u8 = 0x05;
70const ADMIN_CREATE_IO_SQ: u8 = 0x01;
71
72pub fn identify_controller(cid: u16, prp1_iova: u64) -> SubmissionEntry {
73 let mut e = SubmissionEntry::with_opcode_cid(ADMIN_IDENTIFY, cid);
74 e.prp1 = prp1_iova;
75 e.cdw10 = 1;
76 e
77}
78
79pub fn identify_namespace(cid: u16, nsid: u32, prp1_iova: u64) -> SubmissionEntry {
80 let mut e = SubmissionEntry::with_opcode_cid(ADMIN_IDENTIFY, cid);
81 e.nsid = nsid;
82 e.prp1 = prp1_iova;
83 e.cdw10 = 0;
84 e
85}
86
87pub fn create_io_cq(cid: u16, qcid: u16, qsize: u16, prp1_iova: u64, iv: u16) -> SubmissionEntry {
88 let mut e = SubmissionEntry::with_opcode_cid(ADMIN_CREATE_IO_CQ, cid);
89 e.prp1 = prp1_iova;
90 e.cdw10 = ((qsize as u32) << 16) | (qcid as u32);
91 e.cdw11 = ((iv as u32) << 16) | (1 << 1) | 1;
92 e
93}
94
95pub fn create_io_sq(cid: u16, qsid: u16, qsize: u16, prp1_iova: u64, cqid: u16) -> SubmissionEntry {
96 let mut e = SubmissionEntry::with_opcode_cid(ADMIN_CREATE_IO_SQ, cid);
97 e.prp1 = prp1_iova;
98 e.cdw10 = ((qsize as u32) << 16) | (qsid as u32);
99 e.cdw11 = ((cqid as u32) << 16) | 1;
100 e
101}
102
103const NVM_FLUSH: u8 = 0x00;
104const NVM_READ: u8 = 0x02;
105const NVM_WRITE: u8 = 0x01;
106
107pub fn nvm_flush(cid: u16, nsid: u32) -> SubmissionEntry {
108 let mut e = SubmissionEntry::with_opcode_cid(NVM_FLUSH, cid);
109 e.nsid = nsid;
110 e
111}
112
113pub fn nvm_read(
114 cid: u16,
115 nsid: u32,
116 lba: u64,
117 block_count: u16,
118 prp1: u64,
119 prp2: u64,
120) -> SubmissionEntry {
121 assert!(block_count >= 1, "NVM Read block_count must be >= 1");
122 let mut e = SubmissionEntry::with_opcode_cid(NVM_READ, cid);
123 e.nsid = nsid;
124 e.prp1 = prp1;
125 e.prp2 = prp2;
126 e.cdw10 = lba as u32;
127 e.cdw11 = (lba >> 32) as u32;
128 e.cdw12 = (block_count - 1) as u32;
129 e
130}
131
132pub fn nvm_write(
133 cid: u16,
134 nsid: u32,
135 lba: u64,
136 block_count: u16,
137 prp1: u64,
138 prp2: u64,
139) -> SubmissionEntry {
140 assert!(block_count >= 1, "NVM Write block_count must be >= 1");
141 let mut e = SubmissionEntry::with_opcode_cid(NVM_WRITE, cid);
142 e.nsid = nsid;
143 e.prp1 = prp1;
144 e.prp2 = prp2;
145 e.cdw10 = lba as u32;
146 e.cdw11 = (lba >> 32) as u32;
147 e.cdw12 = (block_count - 1) as u32;
148 e
149}