1#![expect(missing_docs)]
10#![forbid(unsafe_code)]
11#![no_std]
12
13pub mod nvm;
14
15use bitfield_struct::bitfield;
16use inspect::Inspect;
17use open_enum::open_enum;
18use storage_string::AsciiString;
19use zerocopy::FromBytes;
20use zerocopy::Immutable;
21use zerocopy::IntoBytes;
22use zerocopy::KnownLayout;
23
24type U128LE = zerocopy::U128<zerocopy::LE>;
25
26open_enum! {
27 pub enum Register: u16 {
28 CAP = 0x0,
29 VS = 0x8,
30 INTMS = 0xc,
31 INTMC = 0x10,
32 CC = 0x14,
33 RESERVED = 0x18,
34 CSTS = 0x1c,
35 NSSR = 0x20,
36 AQA = 0x24,
37 ASQ = 0x28,
38 ACQ = 0x30,
39 CMBLOC = 0x38,
40 CMBSZ = 0x3c,
41 BPINFO = 0x40,
42 BPRSEL = 0x44,
43 BPMBL = 0x48,
44 }
45}
46
47#[derive(Inspect)]
48#[bitfield(u64)]
49pub struct Cap {
50 pub mqes_z: u16,
51 pub cqr: bool,
52 pub ams_weighted_round_robin_with_urgent: bool,
53 pub ams_vendor_specific: bool,
54 #[bits(5)]
55 pub reserved: u8,
56 pub to: u8,
57 #[bits(4)]
58 pub dstrd: u8,
59 pub nssrs: bool,
60 pub css_nvm: bool,
61 #[bits(5)]
62 pub css_reserved: u8,
63 pub multiple_io: bool,
64 pub admin_only: bool,
65 pub bps: bool,
66 #[bits(2)]
67 pub cps: u8,
68 #[bits(4)]
69 pub mpsmin: u8,
70 #[bits(4)]
71 pub mpsmax: u8,
72 pub pmrs: bool,
73 pub cmbs: bool,
74 pub nsss: bool,
75 pub crwms: bool,
76 pub crims: bool,
77 #[bits(3)]
78 pub reserved2: u64,
79}
80
81#[derive(Inspect)]
82#[bitfield(u32)]
83pub struct Cc {
84 pub en: bool,
85 #[bits(3)]
86 pub reserved: u8,
87 #[bits(3)]
88 pub css: u8,
89 #[bits(4)]
90 pub mps: u8,
91 #[bits(3)]
92 pub ams: u8,
93 #[bits(2)]
94 pub shn: u8,
95 #[bits(4)]
96 pub iosqes: u8,
97 #[bits(4)]
98 pub iocqes: u8,
99 pub crime: bool,
100 #[bits(7)]
101 pub reserved2: u8,
102}
103
104#[derive(Inspect)]
105#[bitfield(u32)]
106pub struct Csts {
107 pub rdy: bool,
108 pub cfs: bool,
109 #[bits(2)]
110 pub shst: u8,
111 pub nssro: bool,
112 pub pp: bool,
113 pub st: bool,
114 #[bits(25)]
115 pub reserved: u32,
116}
117
118#[derive(Inspect)]
119#[bitfield(u32)]
120pub struct Aqa {
121 #[bits(12)]
122 pub asqs_z: u16,
123 #[bits(4)]
124 pub reserved: u8,
125 #[bits(12)]
126 pub acqs_z: u16,
127 #[bits(4)]
128 pub reserved2: u8,
129}
130
131#[repr(C)]
132#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Inspect)]
133pub struct Command {
134 pub cdw0: Cdw0,
135 pub nsid: u32,
136 pub cdw2: u32,
137 pub cdw3: u32,
138 pub mptr: u64,
139 #[inspect(iter_by_index)]
140 pub dptr: [u64; 2],
141 pub cdw10: u32,
142 pub cdw11: u32,
143 pub cdw12: u32,
144 pub cdw13: u32,
145 pub cdw14: u32,
146 pub cdw15: u32,
147}
148
149#[derive(Inspect)]
150#[bitfield(u32)]
151#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
152pub struct Cdw0 {
153 pub opcode: u8,
154 #[bits(2)]
155 pub fuse: u8,
156 #[bits(4)]
157 pub reserved: u8,
158 #[bits(2)]
159 pub psdt: u8,
160 pub cid: u16,
161}
162
163#[repr(C)]
164pub struct Opcode(pub u8);
165
166impl Opcode {
167 pub fn transfer_controller_to_host(&self) -> bool {
168 self.0 & 0b10 != 0
169 }
170
171 pub fn transfer_host_to_controller(&self) -> bool {
172 self.0 & 0b01 != 0
173 }
174}
175
176open_enum! {
177 pub enum AdminOpcode: u8 {
178 DELETE_IO_SUBMISSION_QUEUE = 0x00,
179 CREATE_IO_SUBMISSION_QUEUE = 0x01,
180 GET_LOG_PAGE = 0x02,
181 DELETE_IO_COMPLETION_QUEUE = 0x04,
182 CREATE_IO_COMPLETION_QUEUE = 0x05,
183 IDENTIFY = 0x06,
184 ABORT = 0x08,
185 SET_FEATURES = 0x09,
186 GET_FEATURES = 0x0a,
187 ASYNCHRONOUS_EVENT_REQUEST = 0x0c,
188 NAMESPACE_MANAGEMENT = 0x0d,
189 FIRMWARE_COMMIT = 0x10,
190 FIRMWARE_IMAGE_DOWNLOAD = 0x11,
191 DEVICE_SELF_TEST = 0x14,
192 NAMESPACE_ATTACHMENT = 0x15,
193 KEEP_ALIVE = 0x18,
194 DIRECTIVE_SEND = 0x19,
195 DIRECTIVE_RECEIVE = 0x1a,
196 VIRTUALIZATION_MANAGEMENT = 0x1c,
197 NV_ME_MI_SEND = 0x1d,
198 NV_ME_MI_RECEIVE = 0x1e,
199 CAPACITY_MANAGEMENT = 0x20,
200 LOCKDOWN = 0x24,
201 DOORBELL_BUFFER_CONFIG = 0x7c,
202 FABRICS_COMMANDS = 0x7f,
203 FORMAT_NVM = 0x80,
204 SECURITY_SEND = 0x81,
205 SECURITY_RECEIVE = 0x82,
206 SANITIZE = 0x84,
207 GET_LBA_STATUS = 0x86,
208 }
209}
210
211#[repr(C)]
212#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
213pub struct Completion {
214 pub dw0: u32,
215 pub dw1: u32,
216 pub sqhd: u16,
217 pub sqid: u16,
218 pub cid: u16,
219 pub status: CompletionStatus,
220}
221
222#[bitfield(u16)]
223#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
224pub struct CompletionStatus {
225 pub phase: bool,
226 #[bits(11)]
228 pub status: u16,
229 #[bits(2)]
230 pub crd: u8,
231 pub more: bool,
232 pub dnr: bool,
233}
234
235open_enum! {
236 #[derive(Default)]
237 pub enum StatusCodeType: u8 {
238 GENERIC = 0,
239 COMMAND_SPECIFIC = 1,
240 MEDIA_ERROR = 2,
241 PATH_RELATED = 3,
242 VENDOR_SPECIFIC = 7,
243 }
244}
245
246open_enum! {
247 #[derive(Default)]
248 pub enum Status: u16 {
249 SUCCESS = 0x00,
250 INVALID_COMMAND_OPCODE = 0x01,
251 INVALID_FIELD_IN_COMMAND = 0x02,
252 COMMAND_ID_CONFLICT = 0x03,
253 DATA_TRANSFER_ERROR = 0x04,
254 COMMANDS_ABORTED_DUE_TO_POWER_LOSS_NOTIFICATION = 0x05,
255 INTERNAL_ERROR = 0x06,
256 COMMAND_ABORT_REQUESTED = 0x07,
257 COMMAND_ABORTED_DUE_TO_SQ_DELETION = 0x08,
258 COMMAND_ABORTED_DUE_TO_FAILED_FUSED_COMMAND = 0x09,
259 COMMAND_ABORTED_DUE_TO_MISSING_FUSED_COMMAND = 0x0a,
260 INVALID_NAMESPACE_OR_FORMAT = 0x0b,
261 COMMAND_SEQUENCE_ERROR = 0x0c,
262 INVALID_SGL_SEGMENT_DESCRIPTOR = 0x0d,
263 INVALID_NUMBER_OF_SGL_DESCRIPTORS = 0x0e,
264 DATA_SGL_LENGTH_INVALID = 0x0f,
265 METADATA_SGL_LENGTH_INVALID = 0x10,
266 SGL_DESCRIPTOR_TYPE_INVALID = 0x11,
267 INVALID_USE_OF_CONTROLLER_MEMORY_BUFFER = 0x12,
268 PRP_OFFSET_INVALID = 0x13,
269 ATOMIC_WRITE_UNIT_EXCEEDED = 0x14,
270 OPERATION_DENIED = 0x15,
271 SGL_OFFSET_INVALID = 0x16,
272 RESERVED = 0x17,
273 HOST_IDENTIFIER_INCONSISTENT_FORMAT = 0x18,
274 KEEP_ALIVE_TIMER_EXPIRED = 0x19,
275 KEEP_ALIVE_TIMEOUT_INVALID = 0x1a,
276 COMMAND_ABORTED_DUE_TO_PREEMPT_AND_ABORT = 0x1b,
277 SANITIZE_FAILED = 0x1c,
278 SANITIZE_IN_PROGRESS = 0x1d,
279 SGL_DATA_BLOCK_GRANULARITY_INVALID = 0x1e,
280 COMMAND_NOT_SUPPORTED_FOR_QUEUE_IN_CMB = 0x1f,
281 NAMESPACE_IS_WRITE_PROTECTED = 0x20,
282 COMMAND_INTERRUPTED = 0x21,
283 TRANSIENT_TRANSPORT_ERROR = 0x22,
284 COMMAND_PROHIBITED_BY_COMMAND_AND_FEATURE_LOCKDOWN = 0x23,
285 ADMIN_COMMAND_MEDIA_NOT_READY = 0x24,
286
287 LBA_OUT_OF_RANGE = 0x80,
288 CAPACITY_EXCEEDED = 0x81,
289 NAMESPACE_NOT_READY = 0x82,
290 RESERVATION_CONFLICT = 0x83,
291 FORMAT_IN_PROGRESS = 0x84,
292
293 COMPLETION_QUEUE_INVALID = 0x100,
294 INVALID_QUEUE_IDENTIFIER = 0x101,
295 INVALID_QUEUE_SIZE = 0x102,
296 ABORT_COMMAND_LIMIT_EXCEEDED = 0x103,
297 RESERVED2 = 0x104,
298 ASYNCHRONOUS_EVENT_REQUEST_LIMIT_EXCEEDED = 0x105,
299 INVALID_FIRMWARE_SLOT = 0x106,
300 INVALID_FIRMWARE_IMAGE = 0x107,
301 INVALID_INTERRUPT_VECTOR = 0x108,
302 INVALID_LOG_PAGE = 0x109,
303 INVALID_FORMAT = 0x10a,
304 FIRMWARE_ACTIVATION_REQUIRES_CONVENTIONAL_RESET = 0x10b,
305 INVALID_QUEUE_DELETION = 0x10c,
306 FEATURE_IDENTIFIER_NOT_SAVEABLE = 0x10d,
307 FEATURE_NOT_CHANGEABLE = 0x10e,
308 FEATURE_NOT_NAMESPACE_SPECIFIC = 0x10f,
309 FIRMWARE_ACTIVATION_REQUIRES_NVM_SUBSYSTEM_RESET = 0x110,
310 FIRMWARE_ACTIVATION_REQUIRES_CONTROLLER_LEVEL_RESET = 0x111,
311 FIRMWARE_ACTIVATION_REQUIRES_MAXIMUM_TIME_VIOLATION = 0x112,
312 FIRMWARE_ACTIVATION_PROHIBITED = 0x113,
313 OVERLAPPING_RANGE = 0x114,
314 NAMESPACE_INSUFFICIENT_CAPACITY = 0x115,
315 NAMESPACE_IDENTIFIER_UNAVAILABLE = 0x116,
316 RESERVED3 = 0x117,
317 NAMESPACE_ALREADY_ATTACHED = 0x118,
318 NAMESPACE_IS_PRIVATE = 0x119,
319 NAMESPACE_NOT_ATTACHED = 0x11a,
320 THIN_PROVISIONING_NOT_SUPPORTED = 0x11b,
321 CONTROLLER_LIST_INVALID = 0x11c,
322 DEVICE_SELF_TEST_IN_PROGRESS = 0x11d,
323 BOOT_PARTITION_WRITE_PROHIBITED = 0x11e,
324 INVALID_CONTROLLER_IDENTIFIER = 0x11f,
325 INVALID_SECONDARY_CONTROLLER_STATE = 0x120,
326 INVALID_NUMBER_OF_CONTROLLER_RESOURCES = 0x121,
327 INVALID_RESOURCE_IDENTIFIER = 0x122,
328 SANITIZE_PROHIBITED_WHILE_PERSISTENT_MEMORY_REGION_IS_ENABLED = 0x123,
329 ANA_GROUP_IDENTIFIER_INVALID = 0x124,
330 ANA_ATTACH_FAILED = 0x125,
331 INSUFFICIENT_CAPACITY = 0x126,
332 NAMESPACE_ATTACHMENT_LIMIT_EXCEEDED = 0x127,
333 PROHIBITION_OF_COMMAND_EXECUTION_NOT_SUPPORTED = 0x128,
334 IO_COMMAND_SET_NOT_SUPPORTED = 0x129,
335 IO_COMMAND_SET_NOT_ENABLED = 0x12a,
336 IO_COMMAND_SET_COMBINATION_REJECTED = 0x12b,
337 INVALID_IO_COMMAND_SET = 0x12c,
338 IDENTIFIER_UNAVAILABLE = 0x12d,
339
340 CONFLICTING_ATTRIBUTES = 0x180, INVALID_PROTECTION_INFORMATION = 0x181, ATTEMPTED_WRITE_TO_READ_ONLY_RANGE = 0x182, COMMAND_SIZE_LIMIT_EXCEEDED = 0x183, MEDIA_WRITE_FAULT = 0x280,
346 MEDIA_UNRECOVERED_READ_ERROR = 0x281,
347 MEDIA_END_TO_END_GUARD_CHECK_ERROR = 0x282,
348 MEDIA_END_TO_END_APPLICATION_TAG_CHECK_ERROR = 0x283,
349 MEDIA_END_TO_END_REFERENCE_TAG_CHECK_ERROR = 0x284,
350 MEDIA_COMPARE_FAILURE = 0x285,
351 MEDIA_ACCESS_DENIED = 0x286,
352 MEDIA_DEALLOCATED_OR_UNWRITTEN_LOGICAL_BLOCK = 0x287,
353 }
354}
355
356impl Status {
357 pub fn status_code(&self) -> u8 {
358 self.0 as u8
359 }
360
361 pub fn status_code_type(&self) -> StatusCodeType {
362 StatusCodeType((self.0 >> 8) as u8)
363 }
364}
365
366#[bitfield(u32)]
368pub struct Cdw10Identify {
369 pub cns: u8,
370 pub reserved: u8,
371 pub cntid: u16,
372}
373
374open_enum! {
375 pub enum Cns: u8 {
376 NAMESPACE = 0x0,
377 CONTROLLER = 0x1,
378 ACTIVE_NAMESPACES = 0x2,
379 DESCRIPTOR_NAMESPACE = 0x3,
380 NVM_SET = 0x4,
381 SPECIFIC_NAMESPACE_IO_COMMAND_SET = 0x5,
382 SPECIFIC_CONTROLLER_IO_COMMAND_SET = 0x6,
383 ACTIVE_NAMESPACE_LIST_IO_COMMAND_SET = 0x7,
384 ALLOCATED_NAMESPACE_LIST = 0x10,
385 ALLOCATED_NAMESPACE = 0x11,
386 CONTROLLER_LIST_OF_NSID = 0x12,
387 CONTROLLER_LIST_OF_NVM_SUBSYSTEM = 0x13,
388 PRIMARY_CONTROLLER_CAPABILITIES = 0x14,
389 SECONDARY_CONTROLLER_LIST = 0x15,
390 NAMESPACE_GRANULARITY_LIST = 0x16,
391 UUID_LIST = 0x17,
392 DOMAIN_LIST = 0x18,
393 ENDURANCE_GROUP_LIST = 0x19,
394 ALLOCATED_NAMESPACE_LIST_IO_COMMAND_SET = 0x1a,
395 ALLOCATED_NAMESPACE_IO_COMMAND_SET = 0x1b,
396 IO_COMMAND_SET = 0x1c,
397 }
398}
399
400#[derive(Inspect)]
401#[bitfield(u16)]
402#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
403pub struct OptionalAdminCommandSupport {
404 pub security_send_security_receive: bool,
405 pub format_nvm: bool,
406 pub firmware_activate_firmware_download: bool,
407 pub ns_management: bool,
408 pub self_test: bool,
409 pub directives: bool,
410 pub nvme_mi_send_nvme_mi_receive: bool,
411 pub virtualization_management: bool,
412 pub doorbell_buffer_config: bool,
413 pub get_lba_status: bool,
414 pub command_feature_lockdown: bool,
415 #[bits(5)]
416 pub rsvd: u16,
417}
418
419#[repr(C)]
420#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes, Inspect, Clone)]
421pub struct IdentifyController {
422 pub vid: u16,
423 pub ssvid: u16,
424 pub sn: AsciiString<20>,
425 pub mn: AsciiString<40>,
426 pub fr: AsciiString<8>,
427 pub rab: u8,
428 pub ieee: [u8; 3],
429 pub cmic: u8,
430 pub mdts: u8,
433 pub cntlid: u16,
434 pub ver: u32,
435 pub rtd3r: u32,
436 pub rtd3e: u32,
437 pub oaes: Oaes,
438 pub ctratt: u32,
439 pub rrls: u16,
440 #[inspect(skip)]
441 pub rsvd1: [u8; 9],
442 pub cntrltype: ControllerType,
443 pub fguid: [u8; 16],
444 pub crdt1: u16,
445 pub crdt2: u16,
446 pub crdt3: u16,
447 #[inspect(skip)]
448 pub rsvd2: [u8; 106],
449 #[inspect(skip)]
450 pub rsvd3: [u8; 13],
451 pub nvmsr: u8,
452 pub vwci: u8,
453 pub mec: u8,
454 pub oacs: OptionalAdminCommandSupport,
455 pub acl: u8,
456 pub aerl: u8,
457 pub frmw: FirmwareUpdates,
458 pub lpa: u8,
459 pub elpe: u8,
460 pub npss: u8,
461 pub avscc: u8,
462 pub apsta: u8,
463 pub wctemp: u16,
464 pub cctemp: u16,
465 pub mtfa: u16,
466 pub hmpre: u32,
467 pub hmmin: u32,
468 #[inspect(display)]
469 pub tnvmcap: U128LE,
470 #[inspect(display)]
471 pub unvmcap: U128LE,
472 pub rpmbs: u32,
473 pub edstt: u16,
474 pub dsto: u8,
475 pub fwug: u8,
476 pub kas: u16,
477 pub hctma: u16,
478 pub mntmt: u16,
479 pub mxtmt: u16,
480 pub sanicap: u32,
481 pub hmminds: u32,
482 pub hmmaxd: u16,
483 pub nsetidmax: u16,
484 pub endgidmax: u16,
485 pub anatt: u8,
486 pub anacap: u8,
487 pub anagrpmax: u32,
488 pub nanagrpid: u32,
489 pub pels: u32,
490 pub domain_id: u16,
491 #[inspect(skip)]
492 pub rsvd4: [u8; 10],
493 #[inspect(display)]
494 pub megcap: U128LE,
495 #[inspect(skip)]
496 pub rsvd5: [u8; 128],
497 pub sqes: QueueEntrySize,
498 pub cqes: QueueEntrySize,
499 pub maxcmd: u16,
500 pub nn: u32,
501 pub oncs: Oncs,
502 pub fuses: u16,
503 pub fna: u8,
504 pub vwc: VolatileWriteCache,
505 pub awun: u16,
506 pub awupf: u16,
507 pub icsvscc: u8,
508 pub nwpc: u8,
509 pub acwu: u16,
510 pub copy_descriptor_fmt: u16,
511 pub sgls: u32,
512 pub mnan: u32,
513 #[inspect(display)]
514 pub maxdna: U128LE,
515 pub maxcna: u32,
516 #[inspect(skip)]
517 pub rsvd6: [u8; 204],
518 #[inspect(with = "|x| core::str::from_utf8(x).map(|s| s.trim_end_matches('\0')).ok()")]
519 pub subnqn: [u8; 256],
520 #[inspect(skip)]
521 pub rsvd7: [u8; 768],
522 pub ioccsz: u32,
523 pub iorcsz: u32,
524 pub icdoff: u16,
525 pub fcatt: u8,
526 pub msdbd: u8,
527 pub ofcs: u16,
528 #[inspect(skip)]
529 pub rsvd8: [u8; 242],
530 #[inspect(skip)]
531 pub power: [u8; 1024],
532 #[inspect(skip)]
533 pub vendor: [u8; 1024],
534}
535
536const _: () = assert!(size_of::<IdentifyController>() == 4096);
537
538#[derive(Inspect)]
539#[bitfield(u8)]
540#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
541pub struct QueueEntrySize {
542 #[bits(4)]
543 pub min: u8,
544 #[bits(4)]
545 pub max: u8,
546}
547
548#[derive(Inspect)]
549#[bitfield(u8)]
550#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
551pub struct FirmwareUpdates {
552 pub ffsro: bool,
553 #[bits(3)]
554 pub nofs: u8,
555 pub fawr: bool,
556 pub smud: bool,
557 #[bits(2)]
558 pub rsvd: u8,
559}
560
561#[derive(Inspect)]
563#[bitfield(u32)]
564#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
565pub struct Oaes {
566 _rsvd: u8,
567 pub namespace_attribute: bool,
568 pub firmware_activation: bool,
569 _rsvd2: bool,
570 pub asymmetric_namespace_access_change: bool,
571 pub predictable_latency_event_aggregate_log_change: bool,
572 pub lba_status_information: bool,
573 pub endurance_group_event_aggregate_log_page_change: bool,
574 pub normal_nvm_subsystem_shutdown: bool,
575 _rsvd3: u16,
576}
577
578#[derive(Inspect)]
580#[bitfield(u16)]
581#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
582pub struct Oncs {
583 pub compare: bool,
584 pub write_uncorrectable: bool,
585 pub dataset_management: bool,
586 pub write_zeroes: bool,
587 pub save: bool,
588 pub reservations: bool,
589 pub timestamp: bool,
590 pub verify: bool,
591 pub copy: bool,
592 #[bits(7)]
593 _rsvd: u16,
594}
595
596open_enum! {
597 #[derive(IntoBytes, Immutable, KnownLayout, FromBytes, Inspect)]
598 #[inspect(debug)]
599 pub enum ControllerType: u8 {
600 RESERVED = 0,
601 IO_CONTROLLER = 1,
602 DISCOVERY_CONTROLLER = 2,
603 ADMINISTRATIVE_CONTROLLER = 3,
604 }
605}
606
607#[derive(Inspect)]
608#[bitfield(u8)]
609#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
610pub struct VolatileWriteCache {
611 pub present: bool,
612 #[bits(2)]
613 pub broadcast_flush_behavior: u8,
614 #[bits(5)]
615 _rsvd: u8,
616}
617
618open_enum! {
619 pub enum BroadcastFlushBehavior: u8 {
620 NOT_INDICATED = 0,
621 NOT_SUPPORTED = 2,
622 SUPPORTED = 3,
623 }
624}
625
626#[bitfield(u32)]
627pub struct Cdw10SetFeatures {
628 pub fid: u8,
629 #[bits(23)]
630 _rsvd: u32,
631 pub save: bool,
632}
633
634#[bitfield(u32)]
635pub struct Cdw10GetFeatures {
636 pub fid: u8,
637 #[bits(3)]
638 pub sel: u8,
639 #[bits(21)]
640 _rsvd: u32,
641}
642
643open_enum! {
644 pub enum Feature: u8 {
645 ARBITRATION = 0x01,
646 POWER_MANAGEMENT = 0x02,
647 LBA_RANGE_TYPE = 0x03,
648 TEMPERATURE_THRESHOLD = 0x04,
649 ERROR_RECOVERY = 0x05,
650 VOLATILE_WRITE_CACHE = 0x06,
651 NUMBER_OF_QUEUES = 0x07,
652 INTERRUPT_COALESCING = 0x08,
653 INTERRUPT_VECTOR_CONFIG = 0x09,
654 WRITE_ATOMICITY = 0x0a,
655 ASYNC_EVENT_CONFIG = 0x0b,
656 AUTONOMOUS_POWER_STATE_TRANSITION = 0x0c,
657 HOST_MEMORY_BUFFER = 0x0d,
658 TIMESTAMP = 0x0e,
659 KEEP_ALIVE = 0x0f,
660 HOST_CONTROLLED_THERMAL_MANAGEMENT = 0x10,
661 NONOPERATIONAL_POWER_STATE = 0x11,
662 READ_RECOVERY_LEVEL_CONFIG = 0x12,
663 PREDICTABLE_LATENCY_MODE_CONFIG = 0x13,
664 PREDICTABLE_LATENCY_MODE_WINDOW = 0x14,
665 LBA_STATUS_INFORMATION_REPORT_INTERVAL = 0x15,
666 HOST_BEHAVIOR_SUPPORT = 0x16,
667 SANITIZE_CONFIG = 0x17,
668 ENDURANCE_GROUP_EVENT_CONFIG = 0x18,
669 IO_COMMAND_SET_PROFILE = 0x19,
670 ENHANCED_CONTROLLER_METADATA = 0x7d,
671 CONTROLLER_METADATA = 0x7e,
672 NAMESPACE_METADATA = 0x7f,
673 NVM_SOFTWARE_PROGRESS_MARKER = 0x80,
674 NVM_HOST_IDENTIFIER = 0x81,
675 NVM_RESERVATION_NOTIFICATION_MASK = 0x82,
676 NVM_RESERVATION_PERSISTENCE = 0x83,
677 NVM_NAMESPACE_WRITE_PROTECTION_CONFIG = 0x84,
678 }
679}
680
681#[bitfield(u32)]
682pub struct Cdw11FeatureNumberOfQueues {
683 pub nsq_z: u16,
684 pub ncq_z: u16,
685}
686
687#[bitfield(u32)]
688pub struct Cdw11FeatureVolatileWriteCache {
689 pub wce: bool,
690 #[bits(31)]
691 _rsvd: u32,
692}
693
694#[bitfield(u32)]
695pub struct Cdw11FeatureReservationPersistence {
696 pub ptpl: bool,
698 #[bits(31)]
699 _rsvd: u32,
700}
701
702#[bitfield(u32)]
703pub struct Cdw10CreateIoQueue {
704 pub qid: u16,
705 pub qsize_z: u16,
706}
707
708#[bitfield(u32)]
709pub struct Cdw11CreateIoCompletionQueue {
710 pub pc: bool,
711 pub ien: bool,
712 #[bits(14)]
713 pub rsvd: u16,
714 pub iv: u16,
715}
716
717#[bitfield(u32)]
718pub struct Cdw11CreateIoSubmissionQueue {
719 pub pc: bool,
720 #[bits(2)]
721 pub qprio: u8,
722 #[bits(13)]
723 pub rsvd: u16,
724 pub cqid: u16,
725}
726
727#[bitfield(u32)]
728pub struct Cdw10DeleteIoQueue {
729 pub qid: u16,
730 pub rsvd: u16,
731}
732
733#[bitfield(u32)]
734pub struct Cdw10GetLogPage {
735 pub lid: u8,
737 #[bits(7)]
738 pub lsp: u8,
739 pub rae: bool,
741 pub numdl_z: u16,
742}
743
744#[bitfield(u32)]
745pub struct Cdw11GetLogPage {
746 pub numdu: u16,
747 pub lsi: u16,
748}
749
750open_enum! {
751 pub enum LogPageIdentifier: u8 {
752 SUPPORTED_LOG_PAGES = 0,
753 ERROR_INFORMATION = 1,
754 HEALTH_INFORMATION = 2,
755 FIRMWARE_SLOT_INFORMATION = 3,
756 CHANGED_NAMESPACE_LIST = 4,
757 }
758}
759
760#[bitfield(u32)]
761pub struct AsynchronousEventRequestDw0 {
762 #[bits(3)]
763 pub event_type: u8,
764 #[bits(5)]
765 _rsvd: u8,
766 pub information: u8,
767 pub log_page_identifier: u8,
768 _rsvd2: u8,
769}
770
771open_enum! {
772 pub enum AsynchronousEventType: u8 {
773 ERROR_STATUS = 0b000,
774 HEALTH_STATUS = 0b001,
775 NOTICE = 0b010,
776 IMMEDIATE = 0b011,
777 IO_COMMAND_SPECIFIC = 0b110,
778 VENDOR_SPECIFIC = 0b111,
779 }
780}
781
782open_enum! {
783 pub enum AsynchronousEventInformationNotice: u8 {
784 NAMESPACE_ATTRIBUTE_CHANGED = 0,
785 FIRMWARE_ACTIVATION_STARTING = 1,
786 TELEMETRY_LOG_CHANGED = 2,
787 ASYMMETRIC_NAMESPACE_ACCESS_CHANGE = 3,
788 PREDICTABLE_LATENCY_EVENT_AGGREGATE_LOG_CHANGE = 4,
789 LBA_STATUS_INFORMATION_ALERT = 5,
790 ENDURANCE_GROUP_EVENT_AGGREGATE_LOG_PAGE_CHANGE = 6,
791 }
792}