nvme/ds/queue/
subentry.rs1#![allow(dead_code)]
2
3use modular_bitfield::prelude::*;
4
5use super::CommandId;
6use crate::ds::{namespace::NamespaceId, sgl::SglDescriptor, Address};
7#[bitfield(bits = 32)]
10#[derive(Default, Clone, Copy, Debug)]
11pub struct CommandDword0 {
12 op: B8,
13 fuse: FuseSpec,
14 #[skip]
15 res0: B4,
16 psdt: Psdt,
17 cid: CommandId,
18}
19
20impl CommandDword0 {
21 pub fn build(op: u8, cid: CommandId, fuse: FuseSpec, psdt: Psdt) -> Self {
22 Self::new()
23 .with_op(op)
24 .with_cid(cid)
25 .with_fuse(fuse)
26 .with_psdt(psdt)
27 }
28}
29
30#[derive(BitfieldSpecifier, Clone, Copy, Debug)]
31#[bits = 2]
32pub enum Psdt {
33 Prp,
34 Sgl,
35 SglAndMeta,
36}
37
38#[derive(BitfieldSpecifier, Clone, Copy, Debug)]
39#[bits = 2]
40pub enum FuseSpec {
41 Normal,
42 FuseFirst,
43 FuseSecond,
44}
45
46#[derive(Clone, Copy)]
47#[repr(C)]
48union DptrData {
49 prp: [Address; 2],
50 sgl: SglDescriptor,
51}
52
53impl Default for DptrData {
54 fn default() -> Self {
55 Self { prp: [0; 2] }
56 }
57}
58
59#[derive(Default, Clone, Copy)]
60#[repr(C)]
61pub struct CommonCommand {
62 cdw0: CommandDword0,
63 nsid: NamespaceId,
64 cdw2: u32,
65 cdw3: u32,
66 mptr: Address,
67 dptr: DptrData,
68 cdw10: u32,
69 cdw11: u32,
70 cdw12: u32,
71 cdw13: u32,
72 cdw14: u32,
73 cdw15: u32,
74}
75
76impl CommonCommand {
77 pub fn new() -> Self {
78 Self::default()
79 }
80
81 pub fn with_cdw0(self, cdw0: CommandDword0) -> Self {
82 Self { cdw0, ..self }
83 }
84
85 pub fn with_nsid(self, nsid: NamespaceId) -> Self {
86 Self { nsid, ..self }
87 }
88
89 pub fn with_cdw2(self, cdw2: u32) -> Self {
90 Self { cdw2, ..self }
91 }
92
93 pub fn with_cdw3(self, cdw3: u32) -> Self {
94 Self { cdw3, ..self }
95 }
96
97 pub fn with_cdw10(self, cdw10: u32) -> Self {
98 Self { cdw10, ..self }
99 }
100
101 pub fn with_cdw11(self, cdw11: u32) -> Self {
102 Self { cdw11, ..self }
103 }
104
105 pub fn with_cdw12(self, cdw12: u32) -> Self {
106 Self { cdw12, ..self }
107 }
108
109 pub fn with_cdw13(self, cdw13: u32) -> Self {
110 Self { cdw13, ..self }
111 }
112
113 pub fn with_cdw14(self, cdw14: u32) -> Self {
114 Self { cdw14, ..self }
115 }
116
117 pub fn with_cdw15(self, cdw15: u32) -> Self {
118 Self { cdw15, ..self }
119 }
120
121 pub fn with_mptr(self, mptr: Address) -> Self {
122 Self { mptr, ..self }
123 }
124
125 pub fn with_dptr(self, dptr: Dptr) -> Self {
126 match dptr {
127 Dptr::Prp(a1, a2) => Self {
128 dptr: DptrData { prp: [a1, a2] },
129 ..self
130 },
131 Dptr::Sgl(s) => Self {
132 dptr: DptrData { sgl: s },
133 ..self
134 },
135 }
136 }
137
138 pub fn with_cid(self, cid: CommandId) -> Self {
139 let n = self.cdw0.with_cid(cid);
140 self.with_cdw0(n)
141 }
142
143 pub fn set_cid(&mut self, cid: CommandId) {
144 self.cdw0.set_cid(cid);
145 }
146}
147
148pub enum Dptr {
149 Prp(Address, Address),
150 Sgl(SglDescriptor),
151}
152
153impl Dptr {
154 pub fn psdt(&self, meta_is_sgl: bool) -> Psdt {
155 match self {
156 Dptr::Prp(_, _) => Psdt::Prp,
157 Dptr::Sgl(_) => {
158 if meta_is_sgl {
159 Psdt::SglAndMeta
160 } else {
161 Psdt::Sgl
162 }
163 }
164 }
165 }
166}