nvme/ds/controller/properties/
capabilities.rs

1use modular_bitfield::prelude::*;
2
3use crate::ds::HalfSeconds;
4
5#[derive(Clone, Copy)]
6#[bitfield(bits = 64)]
7#[repr(u64)]
8pub struct ControllerCap {
9    #[skip(setters)]
10    pub max_queue_entries: u16,
11    #[skip(setters)]
12    pub contiguous_queues_required: bool,
13    #[skip(setters)]
14    arbitration_mechanism: B2,
15    #[skip]
16    res: B5,
17    #[skip(setters)]
18    pub timeout: HalfSeconds,
19    #[skip(setters)]
20    pub doorbell_stride: B4,
21    #[skip(setters)]
22    pub nvm_subsystem_reset_supported: bool,
23    #[skip(setters)]
24    command_sets_supported: B8,
25    #[skip(setters)]
26    pub boot_partition_supported: bool,
27    #[skip(setters)]
28    pub controller_power_scope: ControllerPowerScope,
29    #[skip(setters)]
30    pub memory_page_sz_min: B4,
31    #[skip(setters)]
32    pub memory_page_sz_max: B4,
33    #[skip(setters)]
34    pub persistent_mem_region_supported: bool,
35    #[skip(setters)]
36    pub controller_mem_buffer_supported: bool,
37    #[skip(setters)]
38    pub nvm_subsystem_shutdown_supported: bool,
39    #[skip(setters)]
40    pub controller_ready_modes_supported: B2,
41    #[skip]
42    res2: B3,
43}
44
45#[derive(Clone, Copy, BitfieldSpecifier, Debug)]
46#[bits = 2]
47pub enum ControllerPowerScope {
48    NotReported,
49    Controller,
50    Domain,
51    NVMSubSystem,
52}
53
54impl ControllerCap {
55    pub fn controller_ready_with_media_support(&self) -> bool {
56        self.controller_ready_modes_supported() & 1 != 0
57    }
58
59    pub fn controller_ready_independent_of_media_support(&self) -> bool {
60        self.controller_ready_modes_supported() & 2 != 0
61    }
62
63    pub fn arbitration_urgent_with_wrr(&self) -> bool {
64        self.arbitration_mechanism() & 1 != 0
65    }
66
67    pub fn arbitration_vendor_specific(&self) -> bool {
68        self.arbitration_mechanism() & 2 != 0
69    }
70
71    pub fn supports_nvm_command_set(&self) -> bool {
72        self.command_sets_supported() & 1 != 0
73    }
74
75    pub fn supports_more_io_command_sets(&self) -> bool {
76        self.command_sets_supported() & (1 << 6) != 0
77    }
78
79    pub fn doorbell_stride_bytes(&self) -> usize {
80        1 << (self.doorbell_stride() as usize + 2)
81    }
82
83    pub fn memory_page_sz_min_bytes(&self) -> usize {
84        1 << (self.memory_page_sz_min() + 12)
85    }
86
87    pub fn memory_page_sz_max_bytes(&self) -> usize {
88        1 << (self.memory_page_sz_max() + 12)
89    }
90}