nvme/admin/
create_completion.rs

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