nvme/admin/
create_submission.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use modular_bitfield::prelude::*;

use crate::ds::{
    cmd::{admin::AdminCommand, PrpListOrBuffer},
    queue::{
        subentry::{CommandDword0, CommonCommand, Dptr, FuseSpec, Psdt},
        CommandId, QueueId, QueuePriority, QueueSize,
    },
    Address,
};

// REF: 2b::5.5

#[bitfield(bits = 32)]
#[repr(u32)]
struct CreateIOSubmissionQueueDword10 {
    qid: QueueId,
    qsz: QueueSize,
}

#[bitfield(bits = 32)]
#[repr(u32)]
struct CreateIOSubmissionQueueDword11 {
    phys_contiguous: bool,
    #[bits = 2]
    priority: QueuePriority,
    #[skip]
    res: B13,
    cqid: QueueId,
}

pub struct CreateIOSubmissionQueue {
    dw10: CreateIOSubmissionQueueDword10,
    dw11: CreateIOSubmissionQueueDword11,
    prp: Address,
    cdw0: CommandDword0,
}

impl CreateIOSubmissionQueue {
    pub fn new(
        cid: CommandId,
        qid: QueueId,
        prp: PrpListOrBuffer,
        qsz: QueueSize,
        cqid: QueueId,
        pri: QueuePriority,
    ) -> Self {
        Self {
            dw10: CreateIOSubmissionQueueDword10::new()
                .with_qid(qid)
                .with_qsz(qsz),
            dw11: CreateIOSubmissionQueueDword11::new()
                .with_phys_contiguous(!prp.is_list())
                .with_priority(pri)
                .with_cqid(cqid),
            prp: prp.address(),
            cdw0: CommandDword0::build(
                AdminCommand::CreateSubmissionQueue.into(),
                cid,
                FuseSpec::Normal,
                Psdt::Prp,
            ),
        }
    }
}

impl From<CreateIOSubmissionQueue> for CommonCommand {
    fn from(c: CreateIOSubmissionQueue) -> Self {
        Self::new()
            .with_cdw0(c.cdw0)
            .with_cdw10(c.dw10.into())
            .with_cdw11(c.dw11.into())
            .with_dptr(Dptr::Prp(c.prp, 0))
    }
}