nvme/nvm/
read.rs

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