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