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 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}