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