nvme/ds/identify/
namespace.rs1use core::{cmp::min, fmt::Debug};
2
3use modular_bitfield::prelude::*;
4
5#[derive(Clone)]
6#[repr(C)]
7pub struct IdentifyNamespaceDataStructure {
8 pub size: u64,
9 pub capacity: u64,
10 pub utilization: u64,
11 pub features: NamespaceFeatures,
12 num_lba_formats: u8,
13 pub formatted_lba_size: FormattedLbaSize,
14 _resv: [u8; 101],
15 lba_format_support: [LbaFormat; 64],
16 _resv2: [u8; 4096 - 384],
17}
18
19impl Default for IdentifyNamespaceDataStructure {
20 fn default() -> Self {
21 Self {
22 size: Default::default(),
23 capacity: Default::default(),
24 utilization: Default::default(),
25 features: Default::default(),
26 num_lba_formats: Default::default(),
27 formatted_lba_size: Default::default(),
28 _resv: [0; 101],
29 lba_format_support: [Default::default(); 64],
30 _resv2: [0; 4096 - 384],
31 }
32 }
33}
34
35impl Debug for IdentifyNamespaceDataStructure {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 f.debug_struct("IdentifyNamespaceDataStructure")
38 .field("size", &self.size)
39 .field("capacity", &self.capacity)
40 .field("utilization", &self.utilization)
41 .field("features", &self.features)
42 .field("num_lba_formats", &self.num_lba_formats)
43 .field("formatted_lba_size", &self.formatted_lba_size)
44 .field("lba_format_support", &self.lba_formats())
45 .finish()
46 }
47}
48
49impl IdentifyNamespaceDataStructure {
50 pub fn lba_formats(&self) -> &[LbaFormat] {
51 &self.lba_format_support[0..=min(self.num_lba_formats.into(), 63)]
52 }
53}
54
55const _SIZE_CHECKER: [u8; 0x1000] = [0; std::mem::size_of::<IdentifyNamespaceDataStructure>()];
56
57#[bitfield(bits = 32)]
58#[derive(Default, Clone, Debug, Copy)]
59pub struct LbaFormat {
60 #[skip(setters)]
61 pub metadata_size: u16,
62 #[skip(setters)]
63 pub data_size_log2: u8,
64 #[skip(setters)]
65 pub relative_performance: RelativePerformance,
66 #[skip]
67 res: B6,
68}
69
70impl LbaFormat {
71 pub fn data_size(&self) -> usize {
72 1 << self.data_size_log2()
73 }
74}
75
76#[derive(Specifier, Clone, Debug)]
77#[bits = 2]
78pub enum RelativePerformance {
79 Best = 0,
80 Better = 1,
81 Good = 2,
82 Degraded = 3,
83}
84
85#[bitfield(bits = 8)]
86#[derive(Debug, Default, Clone)]
87pub struct FormattedLbaSize {
88 #[skip(setters)]
89 idx_lo: B4,
90 #[skip(setters)]
91 pub extended_block: B1,
92 #[skip(setters)]
93 idx_hi: B2,
94 #[skip]
95 resv: B1,
96}
97
98impl FormattedLbaSize {
99 pub fn index(&self) -> usize {
100 usize::from(self.idx_lo()) | usize::from(self.idx_hi()) << 4
101 }
102}
103
104#[bitfield(bits = 8)]
105#[derive(Debug, Default, Clone)]
106pub struct NamespaceFeatures {
107 #[skip(setters)]
108 pub supports_thin_provisioning: B1,
109 #[skip(setters)]
110 pub supports_atomic_fields: B1,
111 #[skip(setters)]
112 pub supports_dealloc_lb_err: B1,
113 #[skip(setters)]
114 pub uid_reuse: B1,
115 #[skip(setters)]
116 pub opt_perf: B1,
117 #[skip]
118 resv: B3,
119}