nvme/admin/
create_submission.rs

1#![allow(dead_code)]
2
3use modular_bitfield::prelude::*;
4
5use crate::ds::{
6    cmd::{admin::AdminCommand, PrpListOrBuffer},
7    queue::{
8        subentry::{CommandDword0, CommonCommand, Dptr, FuseSpec, Psdt},
9        CommandId, QueueId, QueuePriority, QueueSize,
10    },
11    Address,
12};
13
14// REF: 2b::5.5
15
16#[bitfield(bits = 32)]
17#[repr(u32)]
18struct CreateIOSubmissionQueueDword10 {
19    qid: QueueId,
20    qsz: QueueSize,
21}
22
23#[bitfield(bits = 32)]
24#[repr(u32)]
25struct CreateIOSubmissionQueueDword11 {
26    phys_contiguous: bool,
27    #[bits = 2]
28    priority: QueuePriority,
29    #[skip]
30    res: B13,
31    cqid: QueueId,
32}
33
34pub struct CreateIOSubmissionQueue {
35    dw10: CreateIOSubmissionQueueDword10,
36    dw11: CreateIOSubmissionQueueDword11,
37    prp: Address,
38    cdw0: CommandDword0,
39}
40
41impl CreateIOSubmissionQueue {
42    pub fn new(
43        cid: CommandId,
44        qid: QueueId,
45        prp: PrpListOrBuffer,
46        qsz: QueueSize,
47        cqid: QueueId,
48        pri: QueuePriority,
49    ) -> Self {
50        Self {
51            dw10: CreateIOSubmissionQueueDword10::new()
52                .with_qid(qid)
53                .with_qsz(qsz),
54            dw11: CreateIOSubmissionQueueDword11::new()
55                .with_phys_contiguous(!prp.is_list())
56                .with_priority(pri)
57                .with_cqid(cqid),
58            prp: prp.address(),
59            cdw0: CommandDword0::build(
60                AdminCommand::CreateSubmissionQueue.into(),
61                cid,
62                FuseSpec::Normal,
63                Psdt::Prp,
64            ),
65        }
66    }
67}
68
69impl From<CreateIOSubmissionQueue> for CommonCommand {
70    fn from(c: CreateIOSubmissionQueue) -> Self {
71        Self::new()
72            .with_cdw0(c.cdw0)
73            .with_cdw10(c.dw10.into())
74            .with_cdw11(c.dw11.into())
75            .with_dptr(Dptr::Prp(c.prp, 0))
76    }
77}