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