nvme/nvm/
write.rs

1#![allow(dead_code)]
2use modular_bitfield::prelude::*;
3
4use super::{
5    dataset::{AccessFrequency, AccessLatency},
6    NvmCommand,
7};
8use crate::ds::{
9    namespace::NamespaceId,
10    queue::{
11        subentry::{CommandDword0, CommonCommand, Dptr, FuseSpec, Psdt},
12        CommandId,
13    },
14};
15
16#[bitfield(bits = 32)]
17#[repr(u32)]
18struct WriteDword10 {
19    start_lba_lo: u32,
20}
21
22#[bitfield(bits = 32)]
23#[repr(u32)]
24struct WriteDword11 {
25    start_lba_hi: u32,
26}
27
28#[bitfield(bits = 32)]
29#[repr(u32)]
30struct WriteDword12 {
31    pub nr_blocks: u16,
32    #[skip]
33    resv: B14,
34    pub force_unit_access: B1,
35    pub limited_retry: B1,
36}
37
38#[bitfield(bits = 32)]
39#[derive(Debug, Clone, Copy, Default)]
40#[repr(u32)]
41pub struct WriteDword13 {
42    pub access_frequency: AccessFrequency,
43    pub access_latency: AccessLatency,
44    pub sequenial: bool,
45    pub incompressable: bool,
46    #[skip]
47    resv: B24,
48}
49
50pub struct WriteCommand {
51    dw10: WriteDword10,
52    dw11: WriteDword11,
53    dw12: WriteDword12,
54    dw13: WriteDword13,
55    dptr: Dptr,
56    cdw0: CommandDword0,
57    nsid: NamespaceId,
58}
59
60impl WriteCommand {
61    /// Construct a Create IO Completion Queue request. See base spec section 5.4 for more details.
62    pub fn new(
63        cid: CommandId,
64        nsid: NamespaceId,
65        dptr: Dptr,
66        start_lba: u64,
67        nr_blocks: u16,
68        access_info: WriteDword13,
69    ) -> Self {
70        Self {
71            dw10: WriteDword10::new().with_start_lba_lo(start_lba as u32),
72            dw11: WriteDword11::new().with_start_lba_hi((start_lba >> 32) as u32),
73            dw12: WriteDword12::new().with_nr_blocks(nr_blocks - 1),
74            dw13: access_info,
75            dptr,
76            cdw0: CommandDword0::build(NvmCommand::Write.into(), cid, FuseSpec::Normal, Psdt::Prp),
77            nsid,
78        }
79    }
80}
81
82impl From<WriteCommand> for CommonCommand {
83    fn from(c: WriteCommand) -> Self {
84        Self::new()
85            .with_cdw0(c.cdw0)
86            .with_cdw10(c.dw10.into())
87            .with_cdw11(c.dw11.into())
88            .with_cdw12(c.dw12.into())
89            .with_cdw13(c.dw13.into())
90            .with_nsid(c.nsid)
91            .with_dptr(c.dptr)
92    }
93}