]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/include/spdk/nvme_spec.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / include / spdk / nvme_spec.h
1 /*-
2 * BSD LICENSE
3 *
4 * Copyright (c) Intel Corporation.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /**
35 * \file
36 * NVMe specification definitions
37 */
38
39 #ifndef SPDK_NVME_SPEC_H
40 #define SPDK_NVME_SPEC_H
41
42 #include "spdk/stdinc.h"
43
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47
48 #include "spdk/assert.h"
49
50 /**
51 * Use to mark a command to apply to all namespaces, or to retrieve global
52 * log pages.
53 */
54 #define SPDK_NVME_GLOBAL_NS_TAG ((uint32_t)0xFFFFFFFF)
55
56 #define SPDK_NVME_MAX_IO_QUEUES (65535)
57
58 #define SPDK_NVME_ADMIN_QUEUE_MIN_ENTRIES 2
59 #define SPDK_NVME_ADMIN_QUEUE_MAX_ENTRIES 4096
60
61 #define SPDK_NVME_IO_QUEUE_MIN_ENTRIES 2
62 #define SPDK_NVME_IO_QUEUE_MAX_ENTRIES 65536
63
64 /**
65 * Indicates the maximum number of range sets that may be specified
66 * in the dataset management command.
67 */
68 #define SPDK_NVME_DATASET_MANAGEMENT_MAX_RANGES 256
69
70 /**
71 * Maximum number of blocks that may be specified in a single dataset management range.
72 */
73 #define SPDK_NVME_DATASET_MANAGEMENT_RANGE_MAX_BLOCKS 0xFFFFFFFFu
74
75 union spdk_nvme_cap_register {
76 uint64_t raw;
77 struct {
78 /** maximum queue entries supported */
79 uint32_t mqes : 16;
80
81 /** contiguous queues required */
82 uint32_t cqr : 1;
83
84 /** arbitration mechanism supported */
85 uint32_t ams : 2;
86
87 uint32_t reserved1 : 5;
88
89 /** timeout */
90 uint32_t to : 8;
91
92 /** doorbell stride */
93 uint32_t dstrd : 4;
94
95 /** NVM subsystem reset supported */
96 uint32_t nssrs : 1;
97
98 /** command sets supported */
99 uint32_t css : 8;
100
101 /** boot partition support */
102 uint32_t bps : 1;
103
104 uint32_t reserved2 : 2;
105
106 /** memory page size minimum */
107 uint32_t mpsmin : 4;
108
109 /** memory page size maximum */
110 uint32_t mpsmax : 4;
111
112 uint32_t reserved3 : 8;
113 } bits;
114 };
115 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cap_register) == 8, "Incorrect size");
116
117 /**
118 * I/O Command Set Selected
119 *
120 * Only a single command set is defined as of NVMe 1.3 (NVM). Later, it became
121 * possible to disable I/O Command Sets, that is, configuring it to only use the
122 * Admin Command Set. With 1.4c and Namespace Types, additional I/O Command Sets
123 * are available.
124 */
125 enum spdk_nvme_cc_css {
126 SPDK_NVME_CC_CSS_NVM = 0x0, /**< NVM command set */
127 SPDK_NVME_CC_CSS_IOCS = 0x6, /**< One or more I/O command sets */
128 SPDK_NVME_CC_CSS_NOIO = 0x7, /**< No I/O, only admin */
129 };
130
131 #define SPDK_NVME_CAP_CSS_NVM (1u << SPDK_NVME_CC_CSS_NVM) /**< NVM command set supported */
132 #define SPDK_NVME_CAP_CSS_IOCS (1u << SPDK_NVME_CC_CSS_IOCS) /**< One or more I/O Command sets supported */
133 #define SPDK_NVME_CAP_CSS_NOIO (1u << SPDK_NVME_CC_CSS_NOIO) /**< No I/O, only admin */
134
135 union spdk_nvme_cc_register {
136 uint32_t raw;
137 struct {
138 /** enable */
139 uint32_t en : 1;
140
141 uint32_t reserved1 : 3;
142
143 /** i/o command set selected */
144 uint32_t css : 3;
145
146 /** memory page size */
147 uint32_t mps : 4;
148
149 /** arbitration mechanism selected */
150 uint32_t ams : 3;
151
152 /** shutdown notification */
153 uint32_t shn : 2;
154
155 /** i/o submission queue entry size */
156 uint32_t iosqes : 4;
157
158 /** i/o completion queue entry size */
159 uint32_t iocqes : 4;
160
161 uint32_t reserved2 : 8;
162 } bits;
163 };
164 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cc_register) == 4, "Incorrect size");
165
166 enum spdk_nvme_shn_value {
167 SPDK_NVME_SHN_NORMAL = 0x1,
168 SPDK_NVME_SHN_ABRUPT = 0x2,
169 };
170
171 union spdk_nvme_csts_register {
172 uint32_t raw;
173 struct {
174 /** ready */
175 uint32_t rdy : 1;
176
177 /** controller fatal status */
178 uint32_t cfs : 1;
179
180 /** shutdown status */
181 uint32_t shst : 2;
182
183 /** NVM subsystem reset occurred */
184 uint32_t nssro : 1;
185
186 /** Processing paused */
187 uint32_t pp : 1;
188
189 uint32_t reserved1 : 26;
190 } bits;
191 };
192 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_csts_register) == 4, "Incorrect size");
193
194 enum spdk_nvme_shst_value {
195 SPDK_NVME_SHST_NORMAL = 0x0,
196 SPDK_NVME_SHST_OCCURRING = 0x1,
197 SPDK_NVME_SHST_COMPLETE = 0x2,
198 };
199
200 union spdk_nvme_aqa_register {
201 uint32_t raw;
202 struct {
203 /** admin submission queue size */
204 uint32_t asqs : 12;
205
206 uint32_t reserved1 : 4;
207
208 /** admin completion queue size */
209 uint32_t acqs : 12;
210
211 uint32_t reserved2 : 4;
212 } bits;
213 };
214 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_aqa_register) == 4, "Incorrect size");
215
216 union spdk_nvme_vs_register {
217 uint32_t raw;
218 struct {
219 /** indicates the tertiary version */
220 uint32_t ter : 8;
221 /** indicates the minor version */
222 uint32_t mnr : 8;
223 /** indicates the major version */
224 uint32_t mjr : 16;
225 } bits;
226 };
227 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_vs_register) == 4, "Incorrect size");
228
229 /** Generate raw version in the same format as \ref spdk_nvme_vs_register for comparison. */
230 #define SPDK_NVME_VERSION(mjr, mnr, ter) \
231 (((uint32_t)(mjr) << 16) | \
232 ((uint32_t)(mnr) << 8) | \
233 (uint32_t)(ter))
234
235 /* Test that the shifts are correct */
236 SPDK_STATIC_ASSERT(SPDK_NVME_VERSION(1, 0, 0) == 0x00010000, "version macro error");
237 SPDK_STATIC_ASSERT(SPDK_NVME_VERSION(1, 2, 1) == 0x00010201, "version macro error");
238
239 union spdk_nvme_cmbloc_register {
240 uint32_t raw;
241 struct {
242 /** indicator of BAR which contains controller memory buffer(CMB) */
243 uint32_t bir : 3;
244 uint32_t reserved1 : 9;
245 /** offset of CMB in multiples of the size unit */
246 uint32_t ofst : 20;
247 } bits;
248 };
249 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmbloc_register) == 4, "Incorrect size");
250
251 union spdk_nvme_cmbsz_register {
252 uint32_t raw;
253 struct {
254 /** support submission queues in CMB */
255 uint32_t sqs : 1;
256 /** support completion queues in CMB */
257 uint32_t cqs : 1;
258 /** support PRP and SGLs lists in CMB */
259 uint32_t lists : 1;
260 /** support read data and metadata in CMB */
261 uint32_t rds : 1;
262 /** support write data and metadata in CMB */
263 uint32_t wds : 1;
264 uint32_t reserved1 : 3;
265 /** indicates the granularity of the size unit */
266 uint32_t szu : 4;
267 /** size of CMB in multiples of the size unit */
268 uint32_t sz : 20;
269 } bits;
270 };
271 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmbsz_register) == 4, "Incorrect size");
272
273 union spdk_nvme_cmbmsc_register {
274 uint64_t raw;
275 struct {
276 /** capability registers enabled */
277 uint64_t cre : 1;
278
279 /** controller memory space enable */
280 uint64_t cmse : 1;
281
282 uint64_t reserved : 10;
283
284 /** controller base address */
285 uint64_t cba : 52;
286 } bits;
287
288 };
289 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmbmsc_register) == 8, "Incorrect size");
290
291 union spdk_nvme_cmbsts_register {
292 uint32_t raw;
293 struct {
294 /** controller base address invalid */
295 uint32_t cbai : 1;
296
297 uint32_t reserved : 31;
298 } bits;
299 };
300 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmbsts_register) == 4, "Incorrect size");
301
302 /** Boot partition information */
303 union spdk_nvme_bpinfo_register {
304 uint32_t raw;
305 struct {
306 /** Boot partition size in 128KB multiples */
307 uint32_t bpsz : 15;
308
309 uint32_t reserved1 : 9;
310
311 /**
312 * Boot read status
313 * 00b: No Boot Partition read operation requested
314 * 01b: Boot Partition read in progress
315 * 10b: Boot Partition read completed successfully
316 * 11b: Error completing Boot Partition read
317 */
318 uint32_t brs : 2;
319
320 uint32_t reserved2 : 5;
321
322 /** Active Boot Partition ID */
323 uint32_t abpid : 1;
324 } bits;
325 };
326 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_bpinfo_register) == 4, "Incorrect size");
327
328 /** Boot partition read select */
329 union spdk_nvme_bprsel_register {
330 uint32_t raw;
331 struct {
332 /** Boot partition read size in multiples of 4KB */
333 uint32_t bprsz : 10;
334
335 /** Boot partition read offset in multiples of 4KB */
336 uint32_t bprof : 20;
337
338 uint32_t reserved : 1;
339
340 /** Boot Partition Identifier */
341 uint32_t bpid : 1;
342 } bits;
343 };
344 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_bprsel_register) == 4, "Incorrect size");
345
346 /** Value to write to NSSR to indicate a NVM subsystem reset ("NVMe") */
347 #define SPDK_NVME_NSSR_VALUE 0x4E564D65
348
349 struct spdk_nvme_registers {
350 /** controller capabilities */
351 union spdk_nvme_cap_register cap;
352
353 /** version of NVMe specification */
354 union spdk_nvme_vs_register vs;
355 uint32_t intms; /* interrupt mask set */
356 uint32_t intmc; /* interrupt mask clear */
357
358 /** controller configuration */
359 union spdk_nvme_cc_register cc;
360
361 uint32_t reserved1;
362 union spdk_nvme_csts_register csts; /* controller status */
363 uint32_t nssr; /* NVM subsystem reset */
364
365 /** admin queue attributes */
366 union spdk_nvme_aqa_register aqa;
367
368 uint64_t asq; /* admin submission queue base addr */
369 uint64_t acq; /* admin completion queue base addr */
370 /** controller memory buffer location */
371 union spdk_nvme_cmbloc_register cmbloc;
372 /** controller memory buffer size */
373 union spdk_nvme_cmbsz_register cmbsz;
374
375 /** boot partition information */
376 union spdk_nvme_bpinfo_register bpinfo;
377
378 /** boot partition read select */
379 union spdk_nvme_bprsel_register bprsel;
380
381 /** boot partition memory buffer location (must be 4KB aligned) */
382 uint64_t bpmbl;
383
384 /** controller memory buffer memory space control */
385 union spdk_nvme_cmbmsc_register cmbmsc;
386
387 /** controller memory buffer status */
388 union spdk_nvme_cmbsts_register cmbsts;
389
390 uint32_t reserved3[0x3e9];
391
392 struct {
393 uint32_t sq_tdbl; /* submission queue tail doorbell */
394 uint32_t cq_hdbl; /* completion queue head doorbell */
395 } doorbell[1];
396 };
397
398 /* NVMe controller register space offsets */
399 SPDK_STATIC_ASSERT(0x00 == offsetof(struct spdk_nvme_registers, cap),
400 "Incorrect register offset");
401 SPDK_STATIC_ASSERT(0x08 == offsetof(struct spdk_nvme_registers, vs), "Incorrect register offset");
402 SPDK_STATIC_ASSERT(0x0C == offsetof(struct spdk_nvme_registers, intms),
403 "Incorrect register offset");
404 SPDK_STATIC_ASSERT(0x10 == offsetof(struct spdk_nvme_registers, intmc),
405 "Incorrect register offset");
406 SPDK_STATIC_ASSERT(0x14 == offsetof(struct spdk_nvme_registers, cc), "Incorrect register offset");
407 SPDK_STATIC_ASSERT(0x1C == offsetof(struct spdk_nvme_registers, csts), "Incorrect register offset");
408 SPDK_STATIC_ASSERT(0x20 == offsetof(struct spdk_nvme_registers, nssr), "Incorrect register offset");
409 SPDK_STATIC_ASSERT(0x24 == offsetof(struct spdk_nvme_registers, aqa), "Incorrect register offset");
410 SPDK_STATIC_ASSERT(0x28 == offsetof(struct spdk_nvme_registers, asq), "Incorrect register offset");
411 SPDK_STATIC_ASSERT(0x30 == offsetof(struct spdk_nvme_registers, acq), "Incorrect register offset");
412 SPDK_STATIC_ASSERT(0x38 == offsetof(struct spdk_nvme_registers, cmbloc),
413 "Incorrect register offset");
414 SPDK_STATIC_ASSERT(0x3C == offsetof(struct spdk_nvme_registers, cmbsz),
415 "Incorrect register offset");
416 SPDK_STATIC_ASSERT(0x40 == offsetof(struct spdk_nvme_registers, bpinfo),
417 "Incorrect register offset");
418 SPDK_STATIC_ASSERT(0x44 == offsetof(struct spdk_nvme_registers, bprsel),
419 "Incorrect register offset");
420 SPDK_STATIC_ASSERT(0x48 == offsetof(struct spdk_nvme_registers, bpmbl),
421 "Incorrect register offset");
422 SPDK_STATIC_ASSERT(0x50 == offsetof(struct spdk_nvme_registers, cmbmsc),
423 "Incorrect register offset");
424 SPDK_STATIC_ASSERT(0x58 == offsetof(struct spdk_nvme_registers, cmbsts),
425 "Incorrect register offset");
426
427 enum spdk_nvme_sgl_descriptor_type {
428 SPDK_NVME_SGL_TYPE_DATA_BLOCK = 0x0,
429 SPDK_NVME_SGL_TYPE_BIT_BUCKET = 0x1,
430 SPDK_NVME_SGL_TYPE_SEGMENT = 0x2,
431 SPDK_NVME_SGL_TYPE_LAST_SEGMENT = 0x3,
432 SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK = 0x4,
433 SPDK_NVME_SGL_TYPE_TRANSPORT_DATA_BLOCK = 0x5,
434 /* 0x6 - 0xE reserved */
435 SPDK_NVME_SGL_TYPE_VENDOR_SPECIFIC = 0xF
436 };
437
438 enum spdk_nvme_sgl_descriptor_subtype {
439 SPDK_NVME_SGL_SUBTYPE_ADDRESS = 0x0,
440 SPDK_NVME_SGL_SUBTYPE_OFFSET = 0x1,
441 SPDK_NVME_SGL_SUBTYPE_TRANSPORT = 0xa,
442 };
443
444 struct __attribute__((packed)) spdk_nvme_sgl_descriptor {
445 uint64_t address;
446 union {
447 struct {
448 uint8_t reserved[7];
449 uint8_t subtype : 4;
450 uint8_t type : 4;
451 } generic;
452
453 struct {
454 uint32_t length;
455 uint8_t reserved[3];
456 uint8_t subtype : 4;
457 uint8_t type : 4;
458 } unkeyed;
459
460 struct {
461 uint64_t length : 24;
462 uint64_t key : 32;
463 uint64_t subtype : 4;
464 uint64_t type : 4;
465 } keyed;
466 };
467 };
468 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_sgl_descriptor) == 16, "Incorrect size");
469
470 enum spdk_nvme_psdt_value {
471 SPDK_NVME_PSDT_PRP = 0x0,
472 SPDK_NVME_PSDT_SGL_MPTR_CONTIG = 0x1,
473 SPDK_NVME_PSDT_SGL_MPTR_SGL = 0x2,
474 SPDK_NVME_PSDT_RESERVED = 0x3
475 };
476
477 /**
478 * Submission queue priority values for Create I/O Submission Queue Command.
479 *
480 * Only valid for weighted round robin arbitration method.
481 */
482 enum spdk_nvme_qprio {
483 SPDK_NVME_QPRIO_URGENT = 0x0,
484 SPDK_NVME_QPRIO_HIGH = 0x1,
485 SPDK_NVME_QPRIO_MEDIUM = 0x2,
486 SPDK_NVME_QPRIO_LOW = 0x3
487 };
488
489 #define SPDK_NVME_CREATE_IO_SQ_QPRIO_MASK 0x3
490
491 /**
492 * Optional Arbitration Mechanism Supported by the controller.
493 *
494 * Two bits for CAP.AMS (18:17) field are set to '1' when the controller supports.
495 * There is no bit for AMS_RR where all controllers support and set to 0x0 by default.
496 */
497 enum spdk_nvme_cap_ams {
498 SPDK_NVME_CAP_AMS_WRR = 0x1, /**< weighted round robin */
499 SPDK_NVME_CAP_AMS_VS = 0x2, /**< vendor specific */
500 };
501
502 /**
503 * Arbitration Mechanism Selected to the controller.
504 *
505 * Value 0x2 to 0x6 is reserved.
506 */
507 enum spdk_nvme_cc_ams {
508 SPDK_NVME_CC_AMS_RR = 0x0, /**< default round robin */
509 SPDK_NVME_CC_AMS_WRR = 0x1, /**< weighted round robin */
510 SPDK_NVME_CC_AMS_VS = 0x7, /**< vendor specific */
511 };
512
513 /**
514 * Fused Operation
515 */
516 enum spdk_nvme_cmd_fuse {
517 SPDK_NVME_CMD_FUSE_NONE = 0x0, /**< normal operation */
518 SPDK_NVME_CMD_FUSE_FIRST = 0x1, /**< fused operation, first command */
519 SPDK_NVME_CMD_FUSE_SECOND = 0x2, /**< fused operation, second command */
520 SPDK_NVME_CMD_FUSE_MASK = 0x3, /**< fused operation flags mask */
521 };
522
523 /**
524 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_ARBITRATION
525 */
526 union spdk_nvme_feat_arbitration {
527 uint32_t raw;
528 struct {
529 /** Arbitration Burst */
530 uint32_t ab : 3;
531
532 uint32_t reserved : 5;
533
534 /** Low Priority Weight */
535 uint32_t lpw : 8;
536
537 /** Medium Priority Weight */
538 uint32_t mpw : 8;
539
540 /** High Priority Weight */
541 uint32_t hpw : 8;
542 } bits;
543 };
544 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_arbitration) == 4, "Incorrect size");
545
546 #define SPDK_NVME_ARBITRATION_BURST_UNLIMITED 0x7
547
548 /**
549 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_POWER_MANAGEMENT
550 */
551 union spdk_nvme_feat_power_management {
552 uint32_t raw;
553 struct {
554 /** Power State */
555 uint32_t ps : 5;
556
557 /** Workload Hint */
558 uint32_t wh : 3;
559
560 uint32_t reserved : 24;
561 } bits;
562 };
563 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_power_management) == 4, "Incorrect size");
564
565 /**
566 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_LBA_RANGE_TYPE
567 */
568 union spdk_nvme_feat_lba_range_type {
569 uint32_t raw;
570 struct {
571 /** Number of LBA Ranges */
572 uint32_t num : 6;
573
574 uint32_t reserved : 26;
575 } bits;
576 };
577 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_lba_range_type) == 4, "Incorrect size");
578
579 /**
580 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD
581 */
582 union spdk_nvme_feat_temperature_threshold {
583 uint32_t raw;
584 struct {
585 /** Temperature Threshold */
586 uint32_t tmpth : 16;
587
588 /** Threshold Temperature Select */
589 uint32_t tmpsel : 4;
590
591 /** Threshold Type Select */
592 uint32_t thsel : 2;
593
594 uint32_t reserved : 10;
595 } bits;
596 };
597 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_temperature_threshold) == 4, "Incorrect size");
598
599 /**
600 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_ERROR_RECOVERY
601 */
602 union spdk_nvme_feat_error_recovery {
603 uint32_t raw;
604 struct {
605 /** Time Limited Error Recovery */
606 uint32_t tler : 16;
607
608 /** Deallocated or Unwritten Logical Block Error Enable */
609 uint32_t dulbe : 1;
610
611 uint32_t reserved : 15;
612 } bits;
613 };
614 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_error_recovery) == 4, "Incorrect size");
615
616 /**
617 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_VOLATILE_WRITE_CACHE
618 */
619 union spdk_nvme_feat_volatile_write_cache {
620 uint32_t raw;
621 struct {
622 /** Volatile Write Cache Enable */
623 uint32_t wce : 1;
624
625 uint32_t reserved : 31;
626 } bits;
627 };
628 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_volatile_write_cache) == 4, "Incorrect size");
629
630 /**
631 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_NUMBER_OF_QUEUES
632 */
633 union spdk_nvme_feat_number_of_queues {
634 uint32_t raw;
635 struct {
636 /** Number of I/O Submission Queues Requested */
637 uint32_t nsqr : 16;
638
639 /** Number of I/O Completion Queues Requested */
640 uint32_t ncqr : 16;
641 } bits;
642 };
643 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_number_of_queues) == 4, "Incorrect size");
644
645 /**
646 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_INTERRUPT_COALESCING
647 */
648 union spdk_nvme_feat_interrupt_coalescing {
649 uint32_t raw;
650 struct {
651 /** Aggregation Threshold */
652 uint32_t thr : 8;
653
654 /** Aggregration time */
655 uint32_t time : 8;
656
657 uint32_t reserved : 16;
658 } bits;
659 };
660 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_interrupt_coalescing) == 4, "Incorrect size");
661
662 /**
663 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION
664 */
665 union spdk_nvme_feat_interrupt_vector_configuration {
666 uint32_t raw;
667 struct {
668 /** Interrupt Vector */
669 uint32_t iv : 16;
670
671 /** Coalescing Disable */
672 uint32_t cd : 1;
673
674 uint32_t reserved : 15;
675 } bits;
676 };
677 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_interrupt_vector_configuration) == 4,
678 "Incorrect size");
679
680 /**
681 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_WRITE_ATOMICITY
682 */
683 union spdk_nvme_feat_write_atomicity {
684 uint32_t raw;
685 struct {
686 /** Disable Normal */
687 uint32_t dn : 1;
688
689 uint32_t reserved : 31;
690 } bits;
691 };
692 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_write_atomicity) == 4, "Incorrect size");
693
694 union spdk_nvme_critical_warning_state {
695 uint8_t raw;
696
697 struct {
698 uint8_t available_spare : 1;
699 uint8_t temperature : 1;
700 uint8_t device_reliability : 1;
701 uint8_t read_only : 1;
702 uint8_t volatile_memory_backup : 1;
703 uint8_t reserved : 3;
704 } bits;
705 };
706 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_critical_warning_state) == 1, "Incorrect size");
707
708 /**
709 * Data used by Set Features / Get Features \ref SPDK_NVME_FEAT_ASYNC_EVENT_CONFIGURATION
710 */
711 union spdk_nvme_feat_async_event_configuration {
712 uint32_t raw;
713 struct {
714 union spdk_nvme_critical_warning_state crit_warn;
715 uint32_t ns_attr_notice : 1;
716 uint32_t fw_activation_notice : 1;
717 uint32_t telemetry_log_notice : 1;
718 uint32_t reserved : 21;
719 } bits;
720 };
721 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_async_event_configuration) == 4, "Incorrect size");
722
723 /**
724 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION
725 */
726 union spdk_nvme_feat_autonomous_power_state_transition {
727 uint32_t raw;
728 struct {
729 /** Autonomous Power State Transition Enable */
730 uint32_t apste : 1;
731
732 uint32_t reserved : 31;
733 } bits;
734 };
735 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_autonomous_power_state_transition) == 4,
736 "Incorrect size");
737
738 /**
739 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_HOST_MEM_BUFFER
740 */
741 union spdk_nvme_feat_host_mem_buffer {
742 uint32_t raw;
743 struct {
744 /** Enable Host Memory */
745 uint32_t ehm : 1;
746
747 /** Memory Return */
748 uint32_t mr : 1;
749
750 uint32_t reserved : 30;
751 } bits;
752 };
753 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_host_mem_buffer) == 4, "Incorrect size");
754
755 /**
756 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_KEEP_ALIVE_TIMER
757 */
758 union spdk_nvme_feat_keep_alive_timer {
759 uint32_t raw;
760 struct {
761 /** Keep Alive Timeout */
762 uint32_t kato : 32;
763 } bits;
764 };
765 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_keep_alive_timer) == 4, "Incorrect size");
766
767 /**
768 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_HOST_CONTROLLED_THERMAL_MANAGEMENT
769 */
770 union spdk_nvme_feat_host_controlled_thermal_management {
771 uint32_t raw;
772 struct {
773 /** Thermal Management Temperature 2 */
774 uint32_t tmt2 : 16;
775
776 /** Thermal Management Temperature 1 */
777 uint32_t tmt1 : 16;
778 } bits;
779 };
780 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_host_controlled_thermal_management) == 4,
781 "Incorrect size");
782
783 /**
784 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_NON_OPERATIONAL_POWER_STATE_CONFIG
785 */
786 union spdk_nvme_feat_non_operational_power_state_config {
787 uint32_t raw;
788 struct {
789 /** Non-Operational Power State Permissive Mode Enable */
790 uint32_t noppme : 1;
791
792 uint32_t reserved : 31;
793 } bits;
794 };
795 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_non_operational_power_state_config) == 4,
796 "Incorrect size");
797
798 /**
799 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_SOFTWARE_PROGRESS_MARKER
800 */
801 union spdk_nvme_feat_software_progress_marker {
802 uint32_t raw;
803 struct {
804 /** Pre-boot Software Load Count */
805 uint32_t pbslc : 8;
806
807 uint32_t reserved : 24;
808 } bits;
809 };
810 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_software_progress_marker) == 4, "Incorrect size");
811
812 /**
813 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_HOST_IDENTIFIER
814 */
815 union spdk_nvme_feat_host_identifier {
816 uint32_t raw;
817 struct {
818 /** Enable Extended Host Identifier */
819 uint32_t exhid : 1;
820
821 uint32_t reserved : 31;
822 } bits;
823 };
824 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_host_identifier) == 4, "Incorrect size");
825
826 /**
827 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_HOST_RESERVE_MASK
828 */
829 union spdk_nvme_feat_reservation_notification_mask {
830 uint32_t raw;
831 struct {
832 uint32_t reserved1 : 1;
833 /* Mask Registration Preempted Notification */
834 uint32_t regpre : 1;
835 /* Mask Reservation Released Notification */
836 uint32_t resrel : 1;
837 /* Mask Reservation Preempted Notification */
838 uint32_t respre : 1;
839 uint32_t reserved2 : 28;
840 } bits;
841 };
842 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_reservation_notification_mask) == 4,
843 "Incorrect size");
844
845 /**
846 * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_HOST_RESERVE_PERSIST
847 */
848 union spdk_nvme_feat_reservation_persistence {
849 uint32_t raw;
850 struct {
851 /* Persist Through Power Loss */
852 uint32_t ptpl : 1;
853 uint32_t reserved : 31;
854 } bits;
855 };
856 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_reservation_persistence) == 4, "Incorrect size");
857
858 union spdk_nvme_cmd_cdw10 {
859 uint32_t raw;
860 struct {
861 /* Controller or Namespace Structure */
862 uint32_t cns : 8;
863 uint32_t reserved : 8;
864 /* Controller Identifier */
865 uint32_t cntid : 16;
866 } identify;
867
868 struct {
869 /* Log Page Identifier */
870 uint32_t lid : 8;
871 /* Log Specific Field */
872 uint32_t lsp : 4;
873 uint32_t reserved : 3;
874 /* Retain Asynchronous Event */
875 uint32_t rae : 1;
876 /* Number of Dwords Lower */
877 uint32_t numdl : 16;
878 } get_log_page;
879
880 struct {
881 /* Submission Queue Identifier */
882 uint32_t sqid : 16;
883 /* Command Identifier */
884 uint32_t cid : 16;
885 } abort;
886
887 struct {
888 /* NVMe Security Specific Field */
889 uint32_t nssf : 8;
890 /* SP Specific 0 */
891 uint32_t spsp0 : 8;
892 /* SP Specific 1 */
893 uint32_t spsp1 : 8;
894 /* Security Protocol */
895 uint32_t secp : 8;
896 } sec_send_recv;
897
898 struct {
899 /* Queue Identifier */
900 uint32_t qid : 16;
901 /* Queue Size */
902 uint32_t qsize : 16;
903 } create_io_q;
904
905 struct {
906 /* Queue Identifier */
907 uint32_t qid : 16;
908 uint32_t reserved : 16;
909 } delete_io_q;
910
911 struct {
912 /* Feature Identifier */
913 uint32_t fid : 8;
914 /* Select */
915 uint32_t sel : 3;
916 uint32_t reserved : 21;
917 } get_features;
918
919 struct {
920 /* Feature Identifier */
921 uint32_t fid : 8;
922 uint32_t reserved : 23;
923 /* Save */
924 uint32_t sv : 1;
925 } set_features;
926
927 struct {
928 /* Select */
929 uint32_t sel : 4;
930 uint32_t reserved : 28;
931 } ns_attach;
932
933 struct {
934 /* Select */
935 uint32_t sel : 4;
936 uint32_t reserved : 28;
937 } ns_manage;
938
939 struct {
940 /* Number of Ranges */
941 uint32_t nr : 8;
942 uint32_t reserved : 24;
943 } dsm;
944
945 struct {
946 /* Reservation Register Action */
947 uint32_t rrega : 3;
948 /* Ignore Existing Key */
949 uint32_t iekey : 1;
950 uint32_t reserved : 26;
951 /* Change Persist Through Power Loss State */
952 uint32_t cptpl : 2;
953 } resv_register;
954
955 struct {
956 /* Reservation Release Action */
957 uint32_t rrela : 3;
958 /* Ignore Existing Key */
959 uint32_t iekey : 1;
960 uint32_t reserved1 : 4;
961 /* Reservation Type */
962 uint32_t rtype : 8;
963 uint32_t reserved2 : 16;
964 } resv_release;
965
966 struct {
967 /* Reservation Acquire Action */
968 uint32_t racqa : 3;
969 /* Ignore Existing Key */
970 uint32_t iekey : 1;
971 uint32_t reserved1 : 4;
972 /* Reservation Type */
973 uint32_t rtype : 8;
974 uint32_t reserved2 : 16;
975 } resv_acquire;
976 };
977 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmd_cdw10) == 4, "Incorrect size");
978
979 union spdk_nvme_cmd_cdw11 {
980 uint32_t raw;
981
982 struct {
983 /* Physically Contiguous */
984 uint32_t pc : 1;
985 /* Queue Priority */
986 uint32_t qprio : 2;
987 uint32_t reserved : 13;
988 /* Completion Queue Identifier */
989 uint32_t cqid : 16;
990 } create_io_sq;
991
992 struct {
993 /* Physically Contiguous */
994 uint32_t pc : 1;
995 /* Interrupts Enabled */
996 uint32_t ien : 1;
997 uint32_t reserved : 14;
998 /* Interrupt Vector */
999 uint32_t iv : 16;
1000 } create_io_cq;
1001
1002 struct {
1003 /* Number of Dwords */
1004 uint32_t numdu : 16;
1005 /* Log Specific Identifier */
1006 uint32_t lsid : 16;
1007 } get_log_page;
1008
1009 struct {
1010 /* Extended Data Structure */
1011 uint32_t eds : 1;
1012 uint32_t reserved : 31;
1013 } resv_report;
1014
1015 union spdk_nvme_feat_arbitration feat_arbitration;
1016 union spdk_nvme_feat_power_management feat_power_management;
1017 union spdk_nvme_feat_lba_range_type feat_lba_range_type;
1018 union spdk_nvme_feat_temperature_threshold feat_temp_threshold;
1019 union spdk_nvme_feat_error_recovery feat_error_recovery;
1020 union spdk_nvme_feat_volatile_write_cache feat_volatile_write_cache;
1021 union spdk_nvme_feat_number_of_queues feat_num_of_queues;
1022 union spdk_nvme_feat_interrupt_coalescing feat_interrupt_coalescing;
1023 union spdk_nvme_feat_interrupt_vector_configuration feat_interrupt_vector_configuration;
1024 union spdk_nvme_feat_write_atomicity feat_write_atomicity;
1025 union spdk_nvme_feat_async_event_configuration feat_async_event_cfg;
1026 union spdk_nvme_feat_keep_alive_timer feat_keep_alive_timer;
1027 union spdk_nvme_feat_host_identifier feat_host_identifier;
1028 union spdk_nvme_feat_reservation_notification_mask feat_rsv_notification_mask;
1029 union spdk_nvme_feat_reservation_persistence feat_rsv_persistence;
1030
1031 struct {
1032 /* Attribute – Integral Dataset for Read */
1033 uint32_t idr : 1;
1034 /* Attribute – Integral Dataset for Write */
1035 uint32_t idw : 1;
1036 /* Attribute – Deallocate */
1037 uint32_t ad : 1;
1038 uint32_t reserved : 29;
1039 } dsm;
1040 };
1041 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmd_cdw11) == 4, "Incorrect size");
1042
1043 struct spdk_nvme_cmd {
1044 /* dword 0 */
1045 uint16_t opc : 8; /* opcode */
1046 uint16_t fuse : 2; /* fused operation */
1047 uint16_t rsvd1 : 4;
1048 uint16_t psdt : 2;
1049 uint16_t cid; /* command identifier */
1050
1051 /* dword 1 */
1052 uint32_t nsid; /* namespace identifier */
1053
1054 /* dword 2-3 */
1055 uint32_t rsvd2;
1056 uint32_t rsvd3;
1057
1058 /* dword 4-5 */
1059 uint64_t mptr; /* metadata pointer */
1060
1061 /* dword 6-9: data pointer */
1062 union {
1063 struct {
1064 uint64_t prp1; /* prp entry 1 */
1065 uint64_t prp2; /* prp entry 2 */
1066 } prp;
1067
1068 struct spdk_nvme_sgl_descriptor sgl1;
1069 } dptr;
1070
1071 /* command-specific */
1072 union {
1073 uint32_t cdw10;
1074 union spdk_nvme_cmd_cdw10 cdw10_bits;
1075 };
1076 /* command-specific */
1077 union {
1078 uint32_t cdw11;
1079 union spdk_nvme_cmd_cdw11 cdw11_bits;
1080 };
1081 /* dword 12-15 */
1082 uint32_t cdw12; /* command-specific */
1083 uint32_t cdw13; /* command-specific */
1084 uint32_t cdw14; /* command-specific */
1085 uint32_t cdw15; /* command-specific */
1086 };
1087 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_cmd) == 64, "Incorrect size");
1088
1089 struct spdk_nvme_status {
1090 uint16_t p : 1; /* phase tag */
1091 uint16_t sc : 8; /* status code */
1092 uint16_t sct : 3; /* status code type */
1093 uint16_t rsvd2 : 2;
1094 uint16_t m : 1; /* more */
1095 uint16_t dnr : 1; /* do not retry */
1096 };
1097 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_status) == 2, "Incorrect size");
1098
1099 /**
1100 * Completion queue entry
1101 */
1102 struct spdk_nvme_cpl {
1103 /* dword 0 */
1104 uint32_t cdw0; /* command-specific */
1105
1106 /* dword 1 */
1107 uint32_t rsvd1;
1108
1109 /* dword 2 */
1110 uint16_t sqhd; /* submission queue head pointer */
1111 uint16_t sqid; /* submission queue identifier */
1112
1113 /* dword 3 */
1114 uint16_t cid; /* command identifier */
1115 union {
1116 uint16_t status_raw;
1117 struct spdk_nvme_status status;
1118 };
1119 };
1120 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_cpl) == 16, "Incorrect size");
1121
1122 /**
1123 * Dataset Management range
1124 */
1125 struct spdk_nvme_dsm_range {
1126 union {
1127 struct {
1128 uint32_t af : 4; /**< access frequencey */
1129 uint32_t al : 2; /**< access latency */
1130 uint32_t reserved0 : 2;
1131
1132 uint32_t sr : 1; /**< sequential read range */
1133 uint32_t sw : 1; /**< sequential write range */
1134 uint32_t wp : 1; /**< write prepare */
1135 uint32_t reserved1 : 13;
1136
1137 uint32_t access_size : 8; /**< command access size */
1138 } bits;
1139
1140 uint32_t raw;
1141 } attributes;
1142
1143 uint32_t length;
1144 uint64_t starting_lba;
1145 };
1146 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_dsm_range) == 16, "Incorrect size");
1147
1148 /**
1149 * Status code types
1150 */
1151 enum spdk_nvme_status_code_type {
1152 SPDK_NVME_SCT_GENERIC = 0x0,
1153 SPDK_NVME_SCT_COMMAND_SPECIFIC = 0x1,
1154 SPDK_NVME_SCT_MEDIA_ERROR = 0x2,
1155 SPDK_NVME_SCT_PATH = 0x3,
1156 /* 0x4-0x6 - reserved */
1157 SPDK_NVME_SCT_VENDOR_SPECIFIC = 0x7,
1158 };
1159
1160 /**
1161 * Generic command status codes
1162 */
1163 enum spdk_nvme_generic_command_status_code {
1164 SPDK_NVME_SC_SUCCESS = 0x00,
1165 SPDK_NVME_SC_INVALID_OPCODE = 0x01,
1166 SPDK_NVME_SC_INVALID_FIELD = 0x02,
1167 SPDK_NVME_SC_COMMAND_ID_CONFLICT = 0x03,
1168 SPDK_NVME_SC_DATA_TRANSFER_ERROR = 0x04,
1169 SPDK_NVME_SC_ABORTED_POWER_LOSS = 0x05,
1170 SPDK_NVME_SC_INTERNAL_DEVICE_ERROR = 0x06,
1171 SPDK_NVME_SC_ABORTED_BY_REQUEST = 0x07,
1172 SPDK_NVME_SC_ABORTED_SQ_DELETION = 0x08,
1173 SPDK_NVME_SC_ABORTED_FAILED_FUSED = 0x09,
1174 SPDK_NVME_SC_ABORTED_MISSING_FUSED = 0x0a,
1175 SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT = 0x0b,
1176 SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR = 0x0c,
1177 SPDK_NVME_SC_INVALID_SGL_SEG_DESCRIPTOR = 0x0d,
1178 SPDK_NVME_SC_INVALID_NUM_SGL_DESCIRPTORS = 0x0e,
1179 SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID = 0x0f,
1180 SPDK_NVME_SC_METADATA_SGL_LENGTH_INVALID = 0x10,
1181 SPDK_NVME_SC_SGL_DESCRIPTOR_TYPE_INVALID = 0x11,
1182 SPDK_NVME_SC_INVALID_CONTROLLER_MEM_BUF = 0x12,
1183 SPDK_NVME_SC_INVALID_PRP_OFFSET = 0x13,
1184 SPDK_NVME_SC_ATOMIC_WRITE_UNIT_EXCEEDED = 0x14,
1185 SPDK_NVME_SC_OPERATION_DENIED = 0x15,
1186 SPDK_NVME_SC_INVALID_SGL_OFFSET = 0x16,
1187 /* 0x17 - reserved */
1188 SPDK_NVME_SC_HOSTID_INCONSISTENT_FORMAT = 0x18,
1189 SPDK_NVME_SC_KEEP_ALIVE_EXPIRED = 0x19,
1190 SPDK_NVME_SC_KEEP_ALIVE_INVALID = 0x1a,
1191 SPDK_NVME_SC_ABORTED_PREEMPT = 0x1b,
1192 SPDK_NVME_SC_SANITIZE_FAILED = 0x1c,
1193 SPDK_NVME_SC_SANITIZE_IN_PROGRESS = 0x1d,
1194 SPDK_NVME_SC_SGL_DATA_BLOCK_GRANULARITY_INVALID = 0x1e,
1195 SPDK_NVME_SC_COMMAND_INVALID_IN_CMB = 0x1f,
1196
1197 SPDK_NVME_SC_LBA_OUT_OF_RANGE = 0x80,
1198 SPDK_NVME_SC_CAPACITY_EXCEEDED = 0x81,
1199 SPDK_NVME_SC_NAMESPACE_NOT_READY = 0x82,
1200 SPDK_NVME_SC_RESERVATION_CONFLICT = 0x83,
1201 SPDK_NVME_SC_FORMAT_IN_PROGRESS = 0x84,
1202 };
1203
1204 /**
1205 * Command specific status codes
1206 */
1207 enum spdk_nvme_command_specific_status_code {
1208 SPDK_NVME_SC_COMPLETION_QUEUE_INVALID = 0x00,
1209 SPDK_NVME_SC_INVALID_QUEUE_IDENTIFIER = 0x01,
1210 SPDK_NVME_SC_INVALID_QUEUE_SIZE = 0x02,
1211 SPDK_NVME_SC_ABORT_COMMAND_LIMIT_EXCEEDED = 0x03,
1212 /* 0x04 - reserved */
1213 SPDK_NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED = 0x05,
1214 SPDK_NVME_SC_INVALID_FIRMWARE_SLOT = 0x06,
1215 SPDK_NVME_SC_INVALID_FIRMWARE_IMAGE = 0x07,
1216 SPDK_NVME_SC_INVALID_INTERRUPT_VECTOR = 0x08,
1217 SPDK_NVME_SC_INVALID_LOG_PAGE = 0x09,
1218 SPDK_NVME_SC_INVALID_FORMAT = 0x0a,
1219 SPDK_NVME_SC_FIRMWARE_REQ_CONVENTIONAL_RESET = 0x0b,
1220 SPDK_NVME_SC_INVALID_QUEUE_DELETION = 0x0c,
1221 SPDK_NVME_SC_FEATURE_ID_NOT_SAVEABLE = 0x0d,
1222 SPDK_NVME_SC_FEATURE_NOT_CHANGEABLE = 0x0e,
1223 SPDK_NVME_SC_FEATURE_NOT_NAMESPACE_SPECIFIC = 0x0f,
1224 SPDK_NVME_SC_FIRMWARE_REQ_NVM_RESET = 0x10,
1225 SPDK_NVME_SC_FIRMWARE_REQ_RESET = 0x11,
1226 SPDK_NVME_SC_FIRMWARE_REQ_MAX_TIME_VIOLATION = 0x12,
1227 SPDK_NVME_SC_FIRMWARE_ACTIVATION_PROHIBITED = 0x13,
1228 SPDK_NVME_SC_OVERLAPPING_RANGE = 0x14,
1229 SPDK_NVME_SC_NAMESPACE_INSUFFICIENT_CAPACITY = 0x15,
1230 SPDK_NVME_SC_NAMESPACE_ID_UNAVAILABLE = 0x16,
1231 /* 0x17 - reserved */
1232 SPDK_NVME_SC_NAMESPACE_ALREADY_ATTACHED = 0x18,
1233 SPDK_NVME_SC_NAMESPACE_IS_PRIVATE = 0x19,
1234 SPDK_NVME_SC_NAMESPACE_NOT_ATTACHED = 0x1a,
1235 SPDK_NVME_SC_THINPROVISIONING_NOT_SUPPORTED = 0x1b,
1236 SPDK_NVME_SC_CONTROLLER_LIST_INVALID = 0x1c,
1237 SPDK_NVME_SC_DEVICE_SELF_TEST_IN_PROGRESS = 0x1d,
1238 SPDK_NVME_SC_BOOT_PARTITION_WRITE_PROHIBITED = 0x1e,
1239 SPDK_NVME_SC_INVALID_CTRLR_ID = 0x1f,
1240 SPDK_NVME_SC_INVALID_SECONDARY_CTRLR_STATE = 0x20,
1241 SPDK_NVME_SC_INVALID_NUM_CTRLR_RESOURCES = 0x21,
1242 SPDK_NVME_SC_INVALID_RESOURCE_ID = 0x22,
1243
1244 SPDK_NVME_SC_IOCS_NOT_SUPPORTED = 0x29,
1245 SPDK_NVME_SC_IOCS_NOT_ENABLED = 0x2a,
1246 SPDK_NVME_SC_IOCS_COMBINATION_REJECTED = 0x2b,
1247 SPDK_NVME_SC_INVALID_IOCS = 0x2c,
1248
1249 SPDK_NVME_SC_CONFLICTING_ATTRIBUTES = 0x80,
1250 SPDK_NVME_SC_INVALID_PROTECTION_INFO = 0x81,
1251 SPDK_NVME_SC_ATTEMPTED_WRITE_TO_RO_RANGE = 0x82,
1252 };
1253
1254 /**
1255 * Media error status codes
1256 */
1257 enum spdk_nvme_media_error_status_code {
1258 SPDK_NVME_SC_WRITE_FAULTS = 0x80,
1259 SPDK_NVME_SC_UNRECOVERED_READ_ERROR = 0x81,
1260 SPDK_NVME_SC_GUARD_CHECK_ERROR = 0x82,
1261 SPDK_NVME_SC_APPLICATION_TAG_CHECK_ERROR = 0x83,
1262 SPDK_NVME_SC_REFERENCE_TAG_CHECK_ERROR = 0x84,
1263 SPDK_NVME_SC_COMPARE_FAILURE = 0x85,
1264 SPDK_NVME_SC_ACCESS_DENIED = 0x86,
1265 SPDK_NVME_SC_DEALLOCATED_OR_UNWRITTEN_BLOCK = 0x87,
1266 };
1267
1268 /**
1269 * Path related status codes
1270 */
1271 enum spdk_nvme_path_status_code {
1272 SPDK_NVME_SC_INTERNAL_PATH_ERROR = 0x00,
1273
1274 SPDK_NVME_SC_CONTROLLER_PATH_ERROR = 0x60,
1275
1276 SPDK_NVME_SC_HOST_PATH_ERROR = 0x70,
1277 SPDK_NVME_SC_ABORTED_BY_HOST = 0x71,
1278 };
1279
1280 #define SPDK_NVME_MAX_OPC 0xff
1281
1282 /**
1283 * Admin opcodes
1284 */
1285 enum spdk_nvme_admin_opcode {
1286 SPDK_NVME_OPC_DELETE_IO_SQ = 0x00,
1287 SPDK_NVME_OPC_CREATE_IO_SQ = 0x01,
1288 SPDK_NVME_OPC_GET_LOG_PAGE = 0x02,
1289 /* 0x03 - reserved */
1290 SPDK_NVME_OPC_DELETE_IO_CQ = 0x04,
1291 SPDK_NVME_OPC_CREATE_IO_CQ = 0x05,
1292 SPDK_NVME_OPC_IDENTIFY = 0x06,
1293 /* 0x07 - reserved */
1294 SPDK_NVME_OPC_ABORT = 0x08,
1295 SPDK_NVME_OPC_SET_FEATURES = 0x09,
1296 SPDK_NVME_OPC_GET_FEATURES = 0x0a,
1297 /* 0x0b - reserved */
1298 SPDK_NVME_OPC_ASYNC_EVENT_REQUEST = 0x0c,
1299 SPDK_NVME_OPC_NS_MANAGEMENT = 0x0d,
1300 /* 0x0e-0x0f - reserved */
1301 SPDK_NVME_OPC_FIRMWARE_COMMIT = 0x10,
1302 SPDK_NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD = 0x11,
1303
1304 SPDK_NVME_OPC_DEVICE_SELF_TEST = 0x14,
1305 SPDK_NVME_OPC_NS_ATTACHMENT = 0x15,
1306
1307 SPDK_NVME_OPC_KEEP_ALIVE = 0x18,
1308 SPDK_NVME_OPC_DIRECTIVE_SEND = 0x19,
1309 SPDK_NVME_OPC_DIRECTIVE_RECEIVE = 0x1a,
1310
1311 SPDK_NVME_OPC_VIRTUALIZATION_MANAGEMENT = 0x1c,
1312 SPDK_NVME_OPC_NVME_MI_SEND = 0x1d,
1313 SPDK_NVME_OPC_NVME_MI_RECEIVE = 0x1e,
1314
1315 SPDK_NVME_OPC_DOORBELL_BUFFER_CONFIG = 0x7c,
1316
1317 SPDK_NVME_OPC_FORMAT_NVM = 0x80,
1318 SPDK_NVME_OPC_SECURITY_SEND = 0x81,
1319 SPDK_NVME_OPC_SECURITY_RECEIVE = 0x82,
1320
1321 SPDK_NVME_OPC_SANITIZE = 0x84,
1322
1323 SPDK_NVME_OPC_GET_LBA_STATUS = 0x86,
1324 };
1325
1326 /**
1327 * NVM command set opcodes
1328 */
1329 enum spdk_nvme_nvm_opcode {
1330 SPDK_NVME_OPC_FLUSH = 0x00,
1331 SPDK_NVME_OPC_WRITE = 0x01,
1332 SPDK_NVME_OPC_READ = 0x02,
1333 /* 0x03 - reserved */
1334 SPDK_NVME_OPC_WRITE_UNCORRECTABLE = 0x04,
1335 SPDK_NVME_OPC_COMPARE = 0x05,
1336 /* 0x06-0x07 - reserved */
1337 SPDK_NVME_OPC_WRITE_ZEROES = 0x08,
1338 SPDK_NVME_OPC_DATASET_MANAGEMENT = 0x09,
1339
1340 SPDK_NVME_OPC_RESERVATION_REGISTER = 0x0d,
1341 SPDK_NVME_OPC_RESERVATION_REPORT = 0x0e,
1342
1343 SPDK_NVME_OPC_RESERVATION_ACQUIRE = 0x11,
1344 SPDK_NVME_OPC_RESERVATION_RELEASE = 0x15,
1345 };
1346
1347 /**
1348 * Data transfer (bits 1:0) of an NVMe opcode.
1349 *
1350 * \sa spdk_nvme_opc_get_data_transfer
1351 */
1352 enum spdk_nvme_data_transfer {
1353 /** Opcode does not transfer data */
1354 SPDK_NVME_DATA_NONE = 0,
1355 /** Opcode transfers data from host to controller (e.g. Write) */
1356 SPDK_NVME_DATA_HOST_TO_CONTROLLER = 1,
1357 /** Opcode transfers data from controller to host (e.g. Read) */
1358 SPDK_NVME_DATA_CONTROLLER_TO_HOST = 2,
1359 /** Opcode transfers data both directions */
1360 SPDK_NVME_DATA_BIDIRECTIONAL = 3
1361 };
1362
1363 /**
1364 * Extract the Data Transfer bits from an NVMe opcode.
1365 *
1366 * This determines whether a command requires a data buffer and
1367 * which direction (host to controller or controller to host) it is
1368 * transferred.
1369 */
1370 static inline enum spdk_nvme_data_transfer spdk_nvme_opc_get_data_transfer(uint8_t opc)
1371 {
1372 return (enum spdk_nvme_data_transfer)(opc & 3);
1373 }
1374
1375 enum spdk_nvme_feat {
1376 /* 0x00 - reserved */
1377
1378 /** cdw11 layout defined by \ref spdk_nvme_feat_arbitration */
1379 SPDK_NVME_FEAT_ARBITRATION = 0x01,
1380 /** cdw11 layout defined by \ref spdk_nvme_feat_power_management */
1381 SPDK_NVME_FEAT_POWER_MANAGEMENT = 0x02,
1382 /** cdw11 layout defined by \ref spdk_nvme_feat_lba_range_type */
1383 SPDK_NVME_FEAT_LBA_RANGE_TYPE = 0x03,
1384 /** cdw11 layout defined by \ref spdk_nvme_feat_temperature_threshold */
1385 SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD = 0x04,
1386 /** cdw11 layout defined by \ref spdk_nvme_feat_error_recovery */
1387 SPDK_NVME_FEAT_ERROR_RECOVERY = 0x05,
1388 /** cdw11 layout defined by \ref spdk_nvme_feat_volatile_write_cache */
1389 SPDK_NVME_FEAT_VOLATILE_WRITE_CACHE = 0x06,
1390 /** cdw11 layout defined by \ref spdk_nvme_feat_number_of_queues */
1391 SPDK_NVME_FEAT_NUMBER_OF_QUEUES = 0x07,
1392 /** cdw11 layout defined by \ref spdk_nvme_feat_interrupt_coalescing */
1393 SPDK_NVME_FEAT_INTERRUPT_COALESCING = 0x08,
1394 /** cdw11 layout defined by \ref spdk_nvme_feat_interrupt_vector_configuration */
1395 SPDK_NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION = 0x09,
1396 /** cdw11 layout defined by \ref spdk_nvme_feat_write_atomicity */
1397 SPDK_NVME_FEAT_WRITE_ATOMICITY = 0x0A,
1398 /** cdw11 layout defined by \ref spdk_nvme_feat_async_event_configuration */
1399 SPDK_NVME_FEAT_ASYNC_EVENT_CONFIGURATION = 0x0B,
1400 /** cdw11 layout defined by \ref spdk_nvme_feat_autonomous_power_state_transition */
1401 SPDK_NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION = 0x0C,
1402 /** cdw11 layout defined by \ref spdk_nvme_feat_host_mem_buffer */
1403 SPDK_NVME_FEAT_HOST_MEM_BUFFER = 0x0D,
1404 SPDK_NVME_FEAT_TIMESTAMP = 0x0E,
1405 /** cdw11 layout defined by \ref spdk_nvme_feat_keep_alive_timer */
1406 SPDK_NVME_FEAT_KEEP_ALIVE_TIMER = 0x0F,
1407 /** cdw11 layout defined by \ref spdk_nvme_feat_host_controlled_thermal_management */
1408 SPDK_NVME_FEAT_HOST_CONTROLLED_THERMAL_MANAGEMENT = 0x10,
1409 /** cdw11 layout defined by \ref spdk_nvme_feat_non_operational_power_state_config */
1410 SPDK_NVME_FEAT_NON_OPERATIONAL_POWER_STATE_CONFIG = 0x11,
1411
1412 /* 0x12-0x77 - reserved */
1413
1414 /* 0x78-0x7F - NVMe-MI features */
1415
1416 /** cdw11 layout defined by \ref spdk_nvme_feat_software_progress_marker */
1417 SPDK_NVME_FEAT_SOFTWARE_PROGRESS_MARKER = 0x80,
1418
1419 /** cdw11 layout defined by \ref spdk_nvme_feat_host_identifier */
1420 SPDK_NVME_FEAT_HOST_IDENTIFIER = 0x81,
1421 /** cdw11 layout defined by \ref spdk_nvme_feat_reservation_notification_mask */
1422 SPDK_NVME_FEAT_HOST_RESERVE_MASK = 0x82,
1423 /** cdw11 layout defined by \ref spdk_nvme_feat_reservation_persistence */
1424 SPDK_NVME_FEAT_HOST_RESERVE_PERSIST = 0x83,
1425
1426 /* 0x84-0xBF - command set specific (reserved) */
1427
1428 /* 0xC0-0xFF - vendor specific */
1429 };
1430
1431 /** Bit set of attributes for DATASET MANAGEMENT commands. */
1432 enum spdk_nvme_dsm_attribute {
1433 SPDK_NVME_DSM_ATTR_INTEGRAL_READ = 0x1,
1434 SPDK_NVME_DSM_ATTR_INTEGRAL_WRITE = 0x2,
1435 SPDK_NVME_DSM_ATTR_DEALLOCATE = 0x4,
1436 };
1437
1438 struct spdk_nvme_power_state {
1439 uint16_t mp; /* bits 15:00: maximum power */
1440
1441 uint8_t reserved1;
1442
1443 uint8_t mps : 1; /* bit 24: max power scale */
1444 uint8_t nops : 1; /* bit 25: non-operational state */
1445 uint8_t reserved2 : 6;
1446
1447 uint32_t enlat; /* bits 63:32: entry latency in microseconds */
1448 uint32_t exlat; /* bits 95:64: exit latency in microseconds */
1449
1450 uint8_t rrt : 5; /* bits 100:96: relative read throughput */
1451 uint8_t reserved3 : 3;
1452
1453 uint8_t rrl : 5; /* bits 108:104: relative read latency */
1454 uint8_t reserved4 : 3;
1455
1456 uint8_t rwt : 5; /* bits 116:112: relative write throughput */
1457 uint8_t reserved5 : 3;
1458
1459 uint8_t rwl : 5; /* bits 124:120: relative write latency */
1460 uint8_t reserved6 : 3;
1461
1462 uint8_t reserved7[16];
1463 };
1464 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_power_state) == 32, "Incorrect size");
1465
1466 /** Identify command CNS value */
1467 enum spdk_nvme_identify_cns {
1468 /** Identify namespace indicated in CDW1.NSID */
1469 SPDK_NVME_IDENTIFY_NS = 0x00,
1470
1471 /** Identify controller */
1472 SPDK_NVME_IDENTIFY_CTRLR = 0x01,
1473
1474 /** List active NSIDs greater than CDW1.NSID */
1475 SPDK_NVME_IDENTIFY_ACTIVE_NS_LIST = 0x02,
1476
1477 /** List namespace identification descriptors */
1478 SPDK_NVME_IDENTIFY_NS_ID_DESCRIPTOR_LIST = 0x03,
1479
1480 /** Identify namespace indicated in CDW1.NSID, specific to CWD11.CSI */
1481 SPDK_NVME_IDENTIFY_NS_IOCS = 0x05,
1482
1483 /** Identify controller, specific to CWD11.CSI */
1484 SPDK_NVME_IDENTIFY_CTRLR_IOCS = 0x06,
1485
1486 /** List active NSIDs greater than CDW1.NSID, specific to CWD11.CSI */
1487 SPDK_NVME_IDENTIFY_ACTIVE_NS_LIST_IOCS = 0x07,
1488
1489 /** List allocated NSIDs greater than CDW1.NSID */
1490 SPDK_NVME_IDENTIFY_ALLOCATED_NS_LIST = 0x10,
1491
1492 /** Identify namespace if CDW1.NSID is allocated */
1493 SPDK_NVME_IDENTIFY_NS_ALLOCATED = 0x11,
1494
1495 /** Get list of controllers starting at CDW10.CNTID that are attached to CDW1.NSID */
1496 SPDK_NVME_IDENTIFY_NS_ATTACHED_CTRLR_LIST = 0x12,
1497
1498 /** Get list of controllers starting at CDW10.CNTID */
1499 SPDK_NVME_IDENTIFY_CTRLR_LIST = 0x13,
1500
1501 /** Get primary controller capabilities structure */
1502 SPDK_NVME_IDENTIFY_PRIMARY_CTRLR_CAP = 0x14,
1503
1504 /** Get secondary controller list */
1505 SPDK_NVME_IDENTIFY_SECONDARY_CTRLR_LIST = 0x15,
1506
1507 /** List allocated NSIDs greater than CDW1.NSID, specific to CWD11.CSI */
1508 SPDK_NVME_IDENTIFY_ALLOCATED_NS_LIST_IOCS = 0x1a,
1509
1510 /** Identify namespace if CDW1.NSID is allocated, specific to CDWD11.CSI */
1511 SPDK_NVME_IDENTIFY_NS_ALLOCATED_IOCS = 0x1b,
1512
1513 /** Identify I/O Command Sets */
1514 SPDK_NVME_IDENTIFY_IOCS = 0x1c,
1515 };
1516
1517 /** NVMe over Fabrics controller model */
1518 enum spdk_nvmf_ctrlr_model {
1519 /** NVM subsystem uses dynamic controller model */
1520 SPDK_NVMF_CTRLR_MODEL_DYNAMIC = 0,
1521
1522 /** NVM subsystem uses static controller model */
1523 SPDK_NVMF_CTRLR_MODEL_STATIC = 1,
1524 };
1525
1526 #define SPDK_NVME_CTRLR_SN_LEN 20
1527 #define SPDK_NVME_CTRLR_MN_LEN 40
1528 #define SPDK_NVME_CTRLR_FR_LEN 8
1529
1530 /** Identify Controller data sgls.supported values */
1531 enum spdk_nvme_sgls_supported {
1532 /** SGLs are not supported */
1533 SPDK_NVME_SGLS_NOT_SUPPORTED = 0,
1534
1535 /** SGLs are supported with no alignment or granularity requirement. */
1536 SPDK_NVME_SGLS_SUPPORTED = 1,
1537
1538 /** SGLs are supported with a DWORD alignment and granularity requirement. */
1539 SPDK_NVME_SGLS_SUPPORTED_DWORD_ALIGNED = 2,
1540 };
1541
1542 /** Identify Controller data vwc.flush_broadcast values */
1543 enum spdk_nvme_flush_broadcast {
1544 /** Support for NSID=FFFFFFFFh with Flush is not indicated. */
1545 SPDK_NVME_FLUSH_BROADCAST_NOT_INDICATED = 0,
1546
1547 /* 01b: Reserved */
1548
1549 /** Flush does not support NSID set to FFFFFFFFh. */
1550 SPDK_NVME_FLUSH_BROADCAST_NOT_SUPPORTED = 2,
1551
1552 /** Flush supports NSID set to FFFFFFFFh. */
1553 SPDK_NVME_FLUSH_BROADCAST_SUPPORTED = 3
1554 };
1555
1556 #define SPDK_NVME_NQN_FIELD_SIZE 256
1557
1558 /** Identify Controller data NVMe over Fabrics-specific fields */
1559 struct spdk_nvme_cdata_nvmf_specific {
1560 /** I/O queue command capsule supported size (16-byte units) */
1561 uint32_t ioccsz;
1562
1563 /** I/O queue response capsule supported size (16-byte units) */
1564 uint32_t iorcsz;
1565
1566 /** In-capsule data offset (16-byte units) */
1567 uint16_t icdoff;
1568
1569 /** Controller attributes */
1570 struct {
1571 /** Controller model: \ref spdk_nvmf_ctrlr_model */
1572 uint8_t ctrlr_model : 1;
1573 uint8_t reserved : 7;
1574 } ctrattr;
1575
1576 /** Maximum SGL block descriptors (0 = no limit) */
1577 uint8_t msdbd;
1578
1579 uint8_t reserved[244];
1580 };
1581
1582 /** Identify Controller data SGL support */
1583 struct spdk_nvme_cdata_sgls {
1584 uint32_t supported : 2;
1585 uint32_t keyed_sgl : 1;
1586 uint32_t reserved1 : 13;
1587 uint32_t bit_bucket_descriptor : 1;
1588 uint32_t metadata_pointer : 1;
1589 uint32_t oversized_sgl : 1;
1590 uint32_t metadata_address : 1;
1591 uint32_t sgl_offset : 1;
1592 uint32_t transport_sgl : 1;
1593 uint32_t reserved2 : 10;
1594 };
1595
1596 struct __attribute__((packed)) __attribute__((aligned)) spdk_nvme_ctrlr_data {
1597 /* bytes 0-255: controller capabilities and features */
1598
1599 /** pci vendor id */
1600 uint16_t vid;
1601
1602 /** pci subsystem vendor id */
1603 uint16_t ssvid;
1604
1605 /** serial number */
1606 int8_t sn[SPDK_NVME_CTRLR_SN_LEN];
1607
1608 /** model number */
1609 int8_t mn[SPDK_NVME_CTRLR_MN_LEN];
1610
1611 /** firmware revision */
1612 uint8_t fr[SPDK_NVME_CTRLR_FR_LEN];
1613
1614 /** recommended arbitration burst */
1615 uint8_t rab;
1616
1617 /** ieee oui identifier */
1618 uint8_t ieee[3];
1619
1620 /** controller multi-path I/O and namespace sharing capabilities */
1621 struct {
1622 uint8_t multi_port : 1;
1623 uint8_t multi_host : 1;
1624 uint8_t sr_iov : 1;
1625 uint8_t reserved : 5;
1626 } cmic;
1627
1628 /** maximum data transfer size */
1629 uint8_t mdts;
1630
1631 /** controller id */
1632 uint16_t cntlid;
1633
1634 /** version */
1635 union spdk_nvme_vs_register ver;
1636
1637 /** RTD3 resume latency */
1638 uint32_t rtd3r;
1639
1640 /** RTD3 entry latency */
1641 uint32_t rtd3e;
1642
1643 /** optional asynchronous events supported */
1644 struct {
1645 uint32_t reserved1 : 8;
1646
1647 /** Supports sending Namespace Attribute Notices. */
1648 uint32_t ns_attribute_notices : 1;
1649
1650 /** Supports sending Firmware Activation Notices. */
1651 uint32_t fw_activation_notices : 1;
1652
1653 uint32_t reserved2 : 22;
1654 } oaes;
1655
1656 /** controller attributes */
1657 struct {
1658 /** Supports 128-bit host identifier */
1659 uint32_t host_id_exhid_supported: 1;
1660
1661 /** Supports non-operational power state permissive mode */
1662 uint32_t non_operational_power_state_permissive_mode: 1;
1663
1664 uint32_t reserved: 30;
1665 } ctratt;
1666
1667 uint8_t reserved_100[12];
1668
1669 /** FRU globally unique identifier */
1670 uint8_t fguid[16];
1671
1672 uint8_t reserved_128[128];
1673
1674 /* bytes 256-511: admin command set attributes */
1675
1676 /** optional admin command support */
1677 struct {
1678 /* supports security send/receive commands */
1679 uint16_t security : 1;
1680
1681 /* supports format nvm command */
1682 uint16_t format : 1;
1683
1684 /* supports firmware activate/download commands */
1685 uint16_t firmware : 1;
1686
1687 /* supports ns manage/ns attach commands */
1688 uint16_t ns_manage : 1;
1689
1690 /** Supports device self-test command (SPDK_NVME_OPC_DEVICE_SELF_TEST) */
1691 uint16_t device_self_test : 1;
1692
1693 /** Supports SPDK_NVME_OPC_DIRECTIVE_SEND and SPDK_NVME_OPC_DIRECTIVE_RECEIVE */
1694 uint16_t directives : 1;
1695
1696 /** Supports NVMe-MI (SPDK_NVME_OPC_NVME_MI_SEND, SPDK_NVME_OPC_NVME_MI_RECEIVE) */
1697 uint16_t nvme_mi : 1;
1698
1699 /** Supports SPDK_NVME_OPC_VIRTUALIZATION_MANAGEMENT */
1700 uint16_t virtualization_management : 1;
1701
1702 /** Supports SPDK_NVME_OPC_DOORBELL_BUFFER_CONFIG */
1703 uint16_t doorbell_buffer_config : 1;
1704
1705 /** Supports SPDK_NVME_OPC_GET_LBA_STATUS */
1706 uint16_t get_lba_status : 1;
1707
1708 uint16_t oacs_rsvd : 6;
1709 } oacs;
1710
1711 /** abort command limit */
1712 uint8_t acl;
1713
1714 /** asynchronous event request limit */
1715 uint8_t aerl;
1716
1717 /** firmware updates */
1718 struct {
1719 /* first slot is read-only */
1720 uint8_t slot1_ro : 1;
1721
1722 /* number of firmware slots */
1723 uint8_t num_slots : 3;
1724
1725 /* support activation without reset */
1726 uint8_t activation_without_reset : 1;
1727
1728 uint8_t frmw_rsvd : 3;
1729 } frmw;
1730
1731 /** log page attributes */
1732 struct {
1733 /* per namespace smart/health log page */
1734 uint8_t ns_smart : 1;
1735 /* command effects log page */
1736 uint8_t celp : 1;
1737 /* extended data for get log page */
1738 uint8_t edlp: 1;
1739 /** telemetry log pages and notices */
1740 uint8_t telemetry : 1;
1741 uint8_t lpa_rsvd : 4;
1742 } lpa;
1743
1744 /** error log page entries */
1745 uint8_t elpe;
1746
1747 /** number of power states supported */
1748 uint8_t npss;
1749
1750 /** admin vendor specific command configuration */
1751 struct {
1752 /* admin vendor specific commands use disk format */
1753 uint8_t spec_format : 1;
1754
1755 uint8_t avscc_rsvd : 7;
1756 } avscc;
1757
1758 /** autonomous power state transition attributes */
1759 struct {
1760 /** controller supports autonomous power state transitions */
1761 uint8_t supported : 1;
1762
1763 uint8_t apsta_rsvd : 7;
1764 } apsta;
1765
1766 /** warning composite temperature threshold */
1767 uint16_t wctemp;
1768
1769 /** critical composite temperature threshold */
1770 uint16_t cctemp;
1771
1772 /** maximum time for firmware activation */
1773 uint16_t mtfa;
1774
1775 /** host memory buffer preferred size */
1776 uint32_t hmpre;
1777
1778 /** host memory buffer minimum size */
1779 uint32_t hmmin;
1780
1781 /** total NVM capacity */
1782 uint64_t tnvmcap[2];
1783
1784 /** unallocated NVM capacity */
1785 uint64_t unvmcap[2];
1786
1787 /** replay protected memory block support */
1788 struct {
1789 uint8_t num_rpmb_units : 3;
1790 uint8_t auth_method : 3;
1791 uint8_t reserved1 : 2;
1792
1793 uint8_t reserved2;
1794
1795 uint8_t total_size;
1796 uint8_t access_size;
1797 } rpmbs;
1798
1799 /** extended device self-test time (in minutes) */
1800 uint16_t edstt;
1801
1802 /** device self-test options */
1803 union {
1804 uint8_t raw;
1805 struct {
1806 /** Device supports only one device self-test operation at a time */
1807 uint8_t one_only : 1;
1808
1809 uint8_t reserved : 7;
1810 } bits;
1811 } dsto;
1812
1813 /**
1814 * Firmware update granularity
1815 *
1816 * 4KB units
1817 * 0x00 = no information provided
1818 * 0xFF = no restriction
1819 */
1820 uint8_t fwug;
1821
1822 /**
1823 * Keep Alive Support
1824 *
1825 * Granularity of keep alive timer in 100 ms units
1826 * 0 = keep alive not supported
1827 */
1828 uint16_t kas;
1829
1830 /** Host controlled thermal management attributes */
1831 union {
1832 uint16_t raw;
1833 struct {
1834 uint16_t supported : 1;
1835 uint16_t reserved : 15;
1836 } bits;
1837 } hctma;
1838
1839 /** Minimum thermal management temperature */
1840 uint16_t mntmt;
1841
1842 /** Maximum thermal management temperature */
1843 uint16_t mxtmt;
1844
1845 /** Sanitize capabilities */
1846 union {
1847 uint32_t raw;
1848 struct {
1849 uint32_t crypto_erase : 1;
1850 uint32_t block_erase : 1;
1851 uint32_t overwrite : 1;
1852 uint32_t reserved : 29;
1853 } bits;
1854 } sanicap;
1855
1856 uint8_t reserved3[180];
1857
1858 /* bytes 512-703: nvm command set attributes */
1859
1860 /** submission queue entry size */
1861 struct {
1862 uint8_t min : 4;
1863 uint8_t max : 4;
1864 } sqes;
1865
1866 /** completion queue entry size */
1867 struct {
1868 uint8_t min : 4;
1869 uint8_t max : 4;
1870 } cqes;
1871
1872 uint16_t maxcmd;
1873
1874 /** number of namespaces */
1875 uint32_t nn;
1876
1877 /** optional nvm command support */
1878 struct {
1879 uint16_t compare : 1;
1880 uint16_t write_unc : 1;
1881 uint16_t dsm: 1;
1882 uint16_t write_zeroes: 1;
1883 uint16_t set_features_save: 1;
1884 uint16_t reservations: 1;
1885 uint16_t timestamp: 1;
1886 uint16_t reserved: 9;
1887 } oncs;
1888
1889 /** fused operation support */
1890 struct {
1891 uint16_t compare_and_write : 1;
1892 uint16_t reserved : 15;
1893 } fuses;
1894
1895 /** format nvm attributes */
1896 struct {
1897 uint8_t format_all_ns: 1;
1898 uint8_t erase_all_ns: 1;
1899 uint8_t crypto_erase_supported: 1;
1900 uint8_t reserved: 5;
1901 } fna;
1902
1903 /** volatile write cache */
1904 struct {
1905 uint8_t present : 1;
1906 uint8_t flush_broadcast : 2;
1907 uint8_t reserved : 5;
1908 } vwc;
1909
1910 /** atomic write unit normal */
1911 uint16_t awun;
1912
1913 /** atomic write unit power fail */
1914 uint16_t awupf;
1915
1916 /** NVM vendor specific command configuration */
1917 uint8_t nvscc;
1918
1919 uint8_t reserved531;
1920
1921 /** atomic compare & write unit */
1922 uint16_t acwu;
1923
1924 uint16_t reserved534;
1925
1926 struct spdk_nvme_cdata_sgls sgls;
1927
1928 uint8_t reserved4[228];
1929
1930 uint8_t subnqn[SPDK_NVME_NQN_FIELD_SIZE];
1931
1932 uint8_t reserved5[768];
1933
1934 struct spdk_nvme_cdata_nvmf_specific nvmf_specific;
1935
1936 /* bytes 2048-3071: power state descriptors */
1937 struct spdk_nvme_power_state psd[32];
1938
1939 /* bytes 3072-4095: vendor specific */
1940 uint8_t vs[1024];
1941 };
1942 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ctrlr_data) == 4096, "Incorrect size");
1943
1944 struct __attribute__((packed)) spdk_nvme_primary_ctrl_capabilities {
1945 /** controller id */
1946 uint16_t cntlid;
1947 /** port identifier */
1948 uint16_t portid;
1949 /** controller resource types */
1950 struct {
1951 uint8_t vq_supported : 1;
1952 uint8_t vi_supported : 1;
1953 uint8_t reserved : 6;
1954 } crt;
1955 uint8_t reserved[27];
1956 /** total number of VQ flexible resources */
1957 uint32_t vqfrt;
1958 /** total number of VQ flexible resources assigned to secondary controllers */
1959 uint32_t vqrfa;
1960 /** total number of VQ flexible resources allocated to primary controller */
1961 uint16_t vqrfap;
1962 /** total number of VQ Private resources for the primary controller */
1963 uint16_t vqprt;
1964 /** max number of VQ flexible Resources that may be assigned to a secondary controller */
1965 uint16_t vqfrsm;
1966 /** preferred granularity of assigning and removing VQ Flexible Resources */
1967 uint16_t vqgran;
1968 uint8_t reserved1[16];
1969 /** total number of VI flexible resources for the primary and its secondary controllers */
1970 uint32_t vifrt;
1971 /** total number of VI flexible resources assigned to the secondary controllers */
1972 uint32_t virfa;
1973 /** total number of VI flexible resources currently allocated to the primary controller */
1974 uint16_t virfap;
1975 /** total number of VI private resources for the primary controller */
1976 uint16_t viprt;
1977 /** max number of VI flexible resources that may be assigned to a secondary controller */
1978 uint16_t vifrsm;
1979 /** preferred granularity of assigning and removing VI flexible resources */
1980 uint16_t vigran;
1981 uint8_t reserved2[4016];
1982 };
1983 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_primary_ctrl_capabilities) == 4096, "Incorrect size");
1984
1985 struct __attribute__((packed)) spdk_nvme_secondary_ctrl_entry {
1986 /** controller identifier of the secondary controller */
1987 uint16_t scid;
1988 /** controller identifier of the associated primary controller */
1989 uint16_t pcid;
1990 /** indicates the state of the secondary controller */
1991 struct {
1992 uint8_t is_online : 1;
1993 uint8_t reserved : 7;
1994 } scs;
1995 uint8_t reserved[3];
1996 /** VF number if the secondary controller is an SR-IOV VF */
1997 uint16_t vfn;
1998 /** number of VQ flexible resources assigned to the indicated secondary controller */
1999 uint16_t nvq;
2000 /** number of VI flexible resources assigned to the indicated secondary controller */
2001 uint16_t nvi;
2002 uint8_t reserved1[18];
2003 };
2004 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_secondary_ctrl_entry) == 32, "Incorrect size");
2005
2006 struct __attribute__((packed)) spdk_nvme_secondary_ctrl_list {
2007 /** number of Secondary controller entries in the list */
2008 uint8_t number;
2009 uint8_t reserved[31];
2010 struct spdk_nvme_secondary_ctrl_entry entries[127];
2011 };
2012 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_secondary_ctrl_list) == 4096, "Incorrect size");
2013
2014 struct spdk_nvme_ns_data {
2015 /** namespace size */
2016 uint64_t nsze;
2017
2018 /** namespace capacity */
2019 uint64_t ncap;
2020
2021 /** namespace utilization */
2022 uint64_t nuse;
2023
2024 /** namespace features */
2025 struct {
2026 /** thin provisioning */
2027 uint8_t thin_prov : 1;
2028
2029 /** NAWUN, NAWUPF, and NACWU are defined for this namespace */
2030 uint8_t ns_atomic_write_unit : 1;
2031
2032 /** Supports Deallocated or Unwritten LBA error for this namespace */
2033 uint8_t dealloc_or_unwritten_error : 1;
2034
2035 /** Non-zero NGUID and EUI64 for namespace are never reused */
2036 uint8_t guid_never_reused : 1;
2037
2038 uint8_t reserved1 : 4;
2039 } nsfeat;
2040
2041 /** number of lba formats */
2042 uint8_t nlbaf;
2043
2044 /** formatted lba size */
2045 struct {
2046 uint8_t format : 4;
2047 uint8_t extended : 1;
2048 uint8_t reserved2 : 3;
2049 } flbas;
2050
2051 /** metadata capabilities */
2052 struct {
2053 /** metadata can be transferred as part of data prp list */
2054 uint8_t extended : 1;
2055
2056 /** metadata can be transferred with separate metadata pointer */
2057 uint8_t pointer : 1;
2058
2059 /** reserved */
2060 uint8_t reserved3 : 6;
2061 } mc;
2062
2063 /** end-to-end data protection capabilities */
2064 struct {
2065 /** protection information type 1 */
2066 uint8_t pit1 : 1;
2067
2068 /** protection information type 2 */
2069 uint8_t pit2 : 1;
2070
2071 /** protection information type 3 */
2072 uint8_t pit3 : 1;
2073
2074 /** first eight bytes of metadata */
2075 uint8_t md_start : 1;
2076
2077 /** last eight bytes of metadata */
2078 uint8_t md_end : 1;
2079 } dpc;
2080
2081 /** end-to-end data protection type settings */
2082 struct {
2083 /** protection information type */
2084 uint8_t pit : 3;
2085
2086 /** 1 == protection info transferred at start of metadata */
2087 /** 0 == protection info transferred at end of metadata */
2088 uint8_t md_start : 1;
2089
2090 uint8_t reserved4 : 4;
2091 } dps;
2092
2093 /** namespace multi-path I/O and namespace sharing capabilities */
2094 struct {
2095 uint8_t can_share : 1;
2096 uint8_t reserved : 7;
2097 } nmic;
2098
2099 /** reservation capabilities */
2100 union {
2101 struct {
2102 /** supports persist through power loss */
2103 uint8_t persist : 1;
2104
2105 /** supports write exclusive */
2106 uint8_t write_exclusive : 1;
2107
2108 /** supports exclusive access */
2109 uint8_t exclusive_access : 1;
2110
2111 /** supports write exclusive - registrants only */
2112 uint8_t write_exclusive_reg_only : 1;
2113
2114 /** supports exclusive access - registrants only */
2115 uint8_t exclusive_access_reg_only : 1;
2116
2117 /** supports write exclusive - all registrants */
2118 uint8_t write_exclusive_all_reg : 1;
2119
2120 /** supports exclusive access - all registrants */
2121 uint8_t exclusive_access_all_reg : 1;
2122
2123 /** supports ignore existing key */
2124 uint8_t ignore_existing_key : 1;
2125 } rescap;
2126 uint8_t raw;
2127 } nsrescap;
2128 /** format progress indicator */
2129 struct {
2130 uint8_t percentage_remaining : 7;
2131 uint8_t fpi_supported : 1;
2132 } fpi;
2133
2134 /** deallocate logical features */
2135 union {
2136 uint8_t raw;
2137 struct {
2138 /**
2139 * Value read from deallocated blocks
2140 *
2141 * 000b = not reported
2142 * 001b = all bytes 0x00
2143 * 010b = all bytes 0xFF
2144 *
2145 * \ref spdk_nvme_dealloc_logical_block_read_value
2146 */
2147 uint8_t read_value : 3;
2148
2149 /** Supports Deallocate bit in Write Zeroes */
2150 uint8_t write_zero_deallocate : 1;
2151
2152 /**
2153 * Guard field behavior for deallocated logical blocks
2154 * 0: contains 0xFFFF
2155 * 1: contains CRC for read value
2156 */
2157 uint8_t guard_value : 1;
2158
2159 uint8_t reserved : 3;
2160 } bits;
2161 } dlfeat;
2162
2163 /** namespace atomic write unit normal */
2164 uint16_t nawun;
2165
2166 /** namespace atomic write unit power fail */
2167 uint16_t nawupf;
2168
2169 /** namespace atomic compare & write unit */
2170 uint16_t nacwu;
2171
2172 /** namespace atomic boundary size normal */
2173 uint16_t nabsn;
2174
2175 /** namespace atomic boundary offset */
2176 uint16_t nabo;
2177
2178 /** namespace atomic boundary size power fail */
2179 uint16_t nabspf;
2180
2181 /** namespace optimal I/O boundary in logical blocks */
2182 uint16_t noiob;
2183
2184 /** NVM capacity */
2185 uint64_t nvmcap[2];
2186
2187 uint8_t reserved64[40];
2188
2189 /** namespace globally unique identifier */
2190 uint8_t nguid[16];
2191
2192 /** IEEE extended unique identifier */
2193 uint64_t eui64;
2194
2195 /** lba format support */
2196 struct {
2197 /** metadata size */
2198 uint32_t ms : 16;
2199
2200 /** lba data size */
2201 uint32_t lbads : 8;
2202
2203 /** relative performance */
2204 uint32_t rp : 2;
2205
2206 uint32_t reserved6 : 6;
2207 } lbaf[16];
2208
2209 uint8_t reserved6[192];
2210
2211 uint8_t vendor_specific[3712];
2212 };
2213 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_data) == 4096, "Incorrect size");
2214
2215 /**
2216 * Deallocated logical block features - read value
2217 */
2218 enum spdk_nvme_dealloc_logical_block_read_value {
2219 /** Not reported */
2220 SPDK_NVME_DEALLOC_NOT_REPORTED = 0,
2221
2222 /** Deallocated blocks read 0x00 */
2223 SPDK_NVME_DEALLOC_READ_00 = 1,
2224
2225 /** Deallocated blocks read 0xFF */
2226 SPDK_NVME_DEALLOC_READ_FF = 2,
2227 };
2228
2229 /**
2230 * Reservation Type Encoding
2231 */
2232 enum spdk_nvme_reservation_type {
2233 /* 0x00 - reserved */
2234
2235 /* Write Exclusive Reservation */
2236 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE = 0x1,
2237
2238 /* Exclusive Access Reservation */
2239 SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS = 0x2,
2240
2241 /* Write Exclusive - Registrants Only Reservation */
2242 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY = 0x3,
2243
2244 /* Exclusive Access - Registrants Only Reservation */
2245 SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY = 0x4,
2246
2247 /* Write Exclusive - All Registrants Reservation */
2248 SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS = 0x5,
2249
2250 /* Exclusive Access - All Registrants Reservation */
2251 SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_ALL_REGS = 0x6,
2252
2253 /* 0x7-0xFF - Reserved */
2254 };
2255
2256 struct spdk_nvme_reservation_acquire_data {
2257 /** current reservation key */
2258 uint64_t crkey;
2259 /** preempt reservation key */
2260 uint64_t prkey;
2261 };
2262 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_acquire_data) == 16, "Incorrect size");
2263
2264 /**
2265 * Reservation Acquire action
2266 */
2267 enum spdk_nvme_reservation_acquire_action {
2268 SPDK_NVME_RESERVE_ACQUIRE = 0x0,
2269 SPDK_NVME_RESERVE_PREEMPT = 0x1,
2270 SPDK_NVME_RESERVE_PREEMPT_ABORT = 0x2,
2271 };
2272
2273 struct __attribute__((packed)) spdk_nvme_reservation_status_data {
2274 /** reservation action generation counter */
2275 uint32_t gen;
2276 /** reservation type */
2277 uint8_t rtype;
2278 /** number of registered controllers */
2279 uint16_t regctl;
2280 uint16_t reserved1;
2281 /** persist through power loss state */
2282 uint8_t ptpls;
2283 uint8_t reserved[14];
2284 };
2285 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_status_data) == 24, "Incorrect size");
2286
2287 struct __attribute__((packed)) spdk_nvme_reservation_status_extended_data {
2288 struct spdk_nvme_reservation_status_data data;
2289 uint8_t reserved[40];
2290 };
2291 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_status_extended_data) == 64,
2292 "Incorrect size");
2293
2294 struct __attribute__((packed)) spdk_nvme_registered_ctrlr_data {
2295 /** controller id */
2296 uint16_t cntlid;
2297 /** reservation status */
2298 struct {
2299 uint8_t status : 1;
2300 uint8_t reserved1 : 7;
2301 } rcsts;
2302 uint8_t reserved2[5];
2303 /** 64-bit host identifier */
2304 uint64_t hostid;
2305 /** reservation key */
2306 uint64_t rkey;
2307 };
2308 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_registered_ctrlr_data) == 24, "Incorrect size");
2309
2310 struct __attribute__((packed)) spdk_nvme_registered_ctrlr_extended_data {
2311 /** controller id */
2312 uint16_t cntlid;
2313 /** reservation status */
2314 struct {
2315 uint8_t status : 1;
2316 uint8_t reserved1 : 7;
2317 } rcsts;
2318 uint8_t reserved2[5];
2319 /** reservation key */
2320 uint64_t rkey;
2321 /** 128-bit host identifier */
2322 uint8_t hostid[16];
2323 uint8_t reserved3[32];
2324 };
2325 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_registered_ctrlr_extended_data) == 64, "Incorrect size");
2326
2327 /**
2328 * Change persist through power loss state for
2329 * Reservation Register command
2330 */
2331 enum spdk_nvme_reservation_register_cptpl {
2332 SPDK_NVME_RESERVE_PTPL_NO_CHANGES = 0x0,
2333 SPDK_NVME_RESERVE_PTPL_CLEAR_POWER_ON = 0x2,
2334 SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS = 0x3,
2335 };
2336
2337 /**
2338 * Registration action for Reservation Register command
2339 */
2340 enum spdk_nvme_reservation_register_action {
2341 SPDK_NVME_RESERVE_REGISTER_KEY = 0x0,
2342 SPDK_NVME_RESERVE_UNREGISTER_KEY = 0x1,
2343 SPDK_NVME_RESERVE_REPLACE_KEY = 0x2,
2344 };
2345
2346 struct spdk_nvme_reservation_register_data {
2347 /** current reservation key */
2348 uint64_t crkey;
2349 /** new reservation key */
2350 uint64_t nrkey;
2351 };
2352 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_register_data) == 16, "Incorrect size");
2353
2354 struct spdk_nvme_reservation_key_data {
2355 /** current reservation key */
2356 uint64_t crkey;
2357 };
2358 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_key_data) == 8, "Incorrect size");
2359
2360 /**
2361 * Reservation Release action
2362 */
2363 enum spdk_nvme_reservation_release_action {
2364 SPDK_NVME_RESERVE_RELEASE = 0x0,
2365 SPDK_NVME_RESERVE_CLEAR = 0x1,
2366 };
2367
2368 /**
2369 * Reservation notification log page type
2370 */
2371 enum spdk_nvme_reservation_notification_log_page_type {
2372 SPDK_NVME_RESERVATION_LOG_PAGE_EMPTY = 0x0,
2373 SPDK_NVME_REGISTRATION_PREEMPTED = 0x1,
2374 SPDK_NVME_RESERVATION_RELEASED = 0x2,
2375 SPDK_NVME_RESERVATION_PREEMPTED = 0x3,
2376 };
2377
2378 /**
2379 * Reservation notification log
2380 */
2381 struct spdk_nvme_reservation_notification_log {
2382 /** 64-bit incrementing reservation notification log page count */
2383 uint64_t log_page_count;
2384 /** Reservation notification log page type */
2385 uint8_t type;
2386 /** Number of additional available reservation notification log pages */
2387 uint8_t num_avail_log_pages;
2388 uint8_t reserved[2];
2389 uint32_t nsid;
2390 uint8_t reserved1[48];
2391 };
2392 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_notification_log) == 64, "Incorrect size");
2393
2394 /* Mask Registration Preempted Notificaton */
2395 #define SPDK_NVME_REGISTRATION_PREEMPTED_MASK (1U << 1)
2396 /* Mask Reservation Released Notification */
2397 #define SPDK_NVME_RESERVATION_RELEASED_MASK (1U << 2)
2398 /* Mask Reservation Preempted Notification */
2399 #define SPDK_NVME_RESERVATION_PREEMPTED_MASK (1U << 3)
2400
2401 /**
2402 * Log page identifiers for SPDK_NVME_OPC_GET_LOG_PAGE
2403 */
2404 enum spdk_nvme_log_page {
2405 /* 0x00 - reserved */
2406
2407 /** Error information (mandatory) - \ref spdk_nvme_error_information_entry */
2408 SPDK_NVME_LOG_ERROR = 0x01,
2409
2410 /** SMART / health information (mandatory) - \ref spdk_nvme_health_information_page */
2411 SPDK_NVME_LOG_HEALTH_INFORMATION = 0x02,
2412
2413 /** Firmware slot information (mandatory) - \ref spdk_nvme_firmware_page */
2414 SPDK_NVME_LOG_FIRMWARE_SLOT = 0x03,
2415
2416 /** Changed namespace list (optional) */
2417 SPDK_NVME_LOG_CHANGED_NS_LIST = 0x04,
2418
2419 /** Command effects log (optional) */
2420 SPDK_NVME_LOG_COMMAND_EFFECTS_LOG = 0x05,
2421
2422 /** Device self test (optional) */
2423 SPDK_NVME_LOG_DEVICE_SELF_TEST = 0x06,
2424
2425 /** Host initiated telemetry log (optional) */
2426 SPDK_NVME_LOG_TELEMETRY_HOST_INITIATED = 0x07,
2427
2428 /** Controller initiated telemetry log (optional) */
2429 SPDK_NVME_LOG_TELEMETRY_CTRLR_INITIATED = 0x08,
2430
2431 /* 0x09-0x6F - reserved */
2432
2433 /** Discovery(refer to the NVMe over Fabrics specification) */
2434 SPDK_NVME_LOG_DISCOVERY = 0x70,
2435
2436 /* 0x71-0x7f - reserved for NVMe over Fabrics */
2437
2438 /** Reservation notification (optional) */
2439 SPDK_NVME_LOG_RESERVATION_NOTIFICATION = 0x80,
2440
2441 /** Sanitize status (optional) */
2442 SPDK_NVME_LOG_SANITIZE_STATUS = 0x81,
2443
2444 /* 0x81-0xBF - I/O command set specific */
2445
2446 /* 0xC0-0xFF - vendor specific */
2447 };
2448
2449 /**
2450 * Error information log page (\ref SPDK_NVME_LOG_ERROR)
2451 */
2452 struct spdk_nvme_error_information_entry {
2453 uint64_t error_count;
2454 uint16_t sqid;
2455 uint16_t cid;
2456 struct spdk_nvme_status status;
2457 uint16_t error_location;
2458 uint64_t lba;
2459 uint32_t nsid;
2460 uint8_t vendor_specific;
2461 uint8_t trtype;
2462 uint8_t reserved30[2];
2463 uint64_t command_specific;
2464 uint16_t trtype_specific;
2465 uint8_t reserved42[22];
2466 };
2467 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_error_information_entry) == 64, "Incorrect size");
2468
2469 /**
2470 * SMART / health information page (\ref SPDK_NVME_LOG_HEALTH_INFORMATION)
2471 */
2472 struct __attribute__((packed)) __attribute__((aligned)) spdk_nvme_health_information_page {
2473 union spdk_nvme_critical_warning_state critical_warning;
2474
2475 uint16_t temperature;
2476 uint8_t available_spare;
2477 uint8_t available_spare_threshold;
2478 uint8_t percentage_used;
2479
2480 uint8_t reserved[26];
2481
2482 /*
2483 * Note that the following are 128-bit values, but are
2484 * defined as an array of 2 64-bit values.
2485 */
2486 /* Data Units Read is always in 512-byte units. */
2487 uint64_t data_units_read[2];
2488 /* Data Units Written is always in 512-byte units. */
2489 uint64_t data_units_written[2];
2490 /* For NVM command set, this includes Compare commands. */
2491 uint64_t host_read_commands[2];
2492 uint64_t host_write_commands[2];
2493 /* Controller Busy Time is reported in minutes. */
2494 uint64_t controller_busy_time[2];
2495 uint64_t power_cycles[2];
2496 uint64_t power_on_hours[2];
2497 uint64_t unsafe_shutdowns[2];
2498 uint64_t media_errors[2];
2499 uint64_t num_error_info_log_entries[2];
2500 /* Controller temperature related. */
2501 uint32_t warning_temp_time;
2502 uint32_t critical_temp_time;
2503 uint16_t temp_sensor[8];
2504
2505 uint8_t reserved2[296];
2506 };
2507 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_health_information_page) == 512, "Incorrect size");
2508
2509 /* Commands Supported and Effects Data Structure */
2510 struct spdk_nvme_cmds_and_effect_entry {
2511 /** Command Supported */
2512 uint16_t csupp : 1;
2513
2514 /** Logic Block Content Change */
2515 uint16_t lbcc : 1;
2516
2517 /** Namespace Capability Change */
2518 uint16_t ncc : 1;
2519
2520 /** Namespace Inventory Change */
2521 uint16_t nic : 1;
2522
2523 /** Controller Capability Change */
2524 uint16_t ccc : 1;
2525
2526 uint16_t reserved1 : 11;
2527
2528 /* Command Submission and Execution recommendation
2529 * 000 - No command submission or execution restriction
2530 * 001 - Submitted when there is no outstanding command to same NS
2531 * 010 - Submitted when there is no outstanding command to any NS
2532 * others - Reserved
2533 * \ref command_submission_and_execution in section 5.14.1.5 NVMe Revision 1.3
2534 */
2535 uint16_t cse : 3;
2536
2537 uint16_t reserved2 : 13;
2538 };
2539
2540 /* Commands Supported and Effects Log Page */
2541 struct spdk_nvme_cmds_and_effect_log_page {
2542 /** Commands Supported and Effects Data Structure for the Admin Commands */
2543 struct spdk_nvme_cmds_and_effect_entry admin_cmds_supported[256];
2544
2545 /** Commands Supported and Effects Data Structure for the IO Commands */
2546 struct spdk_nvme_cmds_and_effect_entry io_cmds_supported[256];
2547
2548 uint8_t reserved0[2048];
2549 };
2550 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_cmds_and_effect_log_page) == 4096, "Incorrect size");
2551
2552 /*
2553 * Get Log Page – Telemetry Host/Controller Initiated Log (Log Identifiers 07h/08h)
2554 */
2555 struct spdk_nvme_telemetry_log_page_hdr {
2556 /* Log page identifier */
2557 uint8_t lpi;
2558 uint8_t rsvd[4];
2559 uint8_t ieee_oui[3];
2560 /* Data area 1 last block */
2561 uint16_t dalb1;
2562 /* Data area 2 last block */
2563 uint16_t dalb2;
2564 /* Data area 3 last block */
2565 uint16_t dalb3;
2566 uint8_t rsvd1[368];
2567 /* Controller initiated data avail */
2568 uint8_t ctrlr_avail;
2569 /* Controller initiated telemetry data generation */
2570 uint8_t ctrlr_gen;
2571 /* Reason identifier */
2572 uint8_t rsnident[128];
2573 uint8_t telemetry_datablock[0];
2574 };
2575 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_telemetry_log_page_hdr) == 512, "Incorrect size");
2576
2577 /**
2578 * Sanitize Status Type
2579 */
2580 enum spdk_nvme_sanitize_status_type {
2581 SPDK_NVME_NEVER_BEEN_SANITIZED = 0x0,
2582 SPDK_NVME_RECENT_SANITIZE_SUCCESSFUL = 0x1,
2583 SPDK_NVME_SANITIZE_IN_PROGRESS = 0x2,
2584 SPDK_NVME_SANITIZE_FAILED = 0x3,
2585 };
2586
2587 /**
2588 * Sanitize status sstat field
2589 */
2590 struct spdk_nvme_sanitize_status_sstat {
2591 uint16_t status : 3;
2592 uint16_t complete_pass : 5;
2593 uint16_t global_data_erase : 1;
2594 uint16_t reserved : 7;
2595 };
2596
2597 /**
2598 * Sanitize log page
2599 */
2600 struct spdk_nvme_sanitize_status_log_page {
2601 /* Sanitize progress */
2602 uint16_t sprog;
2603 /* Sanitize status */
2604 struct spdk_nvme_sanitize_status_sstat sstat;
2605 /* CDW10 of sanitize command */
2606 uint32_t scdw10;
2607 /* Estimated overwrite time in seconds */
2608 uint32_t et_overwrite;
2609 /* Estimated block erase time in seconds */
2610 uint32_t et_block_erase;
2611 /* Estimated crypto erase time in seconds */
2612 uint32_t et_crypto_erase;
2613 uint8_t reserved[492];
2614 };
2615 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_sanitize_status_log_page) == 512, "Incorrect size");
2616
2617 /**
2618 * Asynchronous Event Type
2619 */
2620 enum spdk_nvme_async_event_type {
2621 /* Error Status */
2622 SPDK_NVME_ASYNC_EVENT_TYPE_ERROR = 0x0,
2623 /* SMART/Health Status */
2624 SPDK_NVME_ASYNC_EVENT_TYPE_SMART = 0x1,
2625 /* Notice */
2626 SPDK_NVME_ASYNC_EVENT_TYPE_NOTICE = 0x2,
2627 /* 0x3 - 0x5 Reserved */
2628
2629 /* I/O Command Set Specific Status */
2630 SPDK_NVME_ASYNC_EVENT_TYPE_IO = 0x6,
2631 /* Vendor Specific */
2632 SPDK_NVME_ASYNC_EVENT_TYPE_VENDOR = 0x7,
2633 };
2634
2635 /**
2636 * Asynchronous Event Information for Error Status
2637 */
2638 enum spdk_nvme_async_event_info_error {
2639 /* Write to Invalid Doorbell Register */
2640 SPDK_NVME_ASYNC_EVENT_WRITE_INVALID_DB = 0x0,
2641 /* Invalid Doorbell Register Write Value */
2642 SPDK_NVME_ASYNC_EVENT_INVALID_DB_WRITE = 0x1,
2643 /* Diagnostic Failure */
2644 SPDK_NVME_ASYNC_EVENT_DIAGNOSTIC_FAILURE = 0x2,
2645 /* Persistent Internal Error */
2646 SPDK_NVME_ASYNC_EVENT_PERSISTENT_INTERNAL = 0x3,
2647 /* Transient Internal Error */
2648 SPDK_NVME_ASYNC_EVENT_TRANSIENT_INTERNAL = 0x4,
2649 /* Firmware Image Load Error */
2650 SPDK_NVME_ASYNC_EVENT_FW_IMAGE_LOAD = 0x5,
2651
2652 /* 0x6 - 0xFF Reserved */
2653 };
2654
2655 /**
2656 * Asynchronous Event Information for SMART/Health Status
2657 */
2658 enum spdk_nvme_async_event_info_smart {
2659 /* NVM Subsystem Reliability */
2660 SPDK_NVME_ASYNC_EVENT_SUBSYSTEM_RELIABILITY = 0x0,
2661 /* Temperature Threshold */
2662 SPDK_NVME_ASYNC_EVENT_TEMPERATURE_THRESHOLD = 0x1,
2663 /* Spare Below Threshold */
2664 SPDK_NVME_ASYNC_EVENT_SPARE_BELOW_THRESHOLD = 0x2,
2665
2666 /* 0x3 - 0xFF Reserved */
2667 };
2668
2669 /**
2670 * Asynchronous Event Information for Notice
2671 */
2672 enum spdk_nvme_async_event_info_notice {
2673 /* Namespace Attribute Changed */
2674 SPDK_NVME_ASYNC_EVENT_NS_ATTR_CHANGED = 0x0,
2675 /* Firmware Activation Starting */
2676 SPDK_NVME_ASYNC_EVENT_FW_ACTIVATION_START = 0x1,
2677 /* Telemetry Log Changed */
2678 SPDK_NVME_ASYNC_EVENT_TELEMETRY_LOG_CHANGED = 0x2,
2679
2680 /* 0x3 - 0xFF Reserved */
2681 };
2682
2683 /**
2684 * Asynchronous Event Information for NVM Command Set Specific Status
2685 */
2686 enum spdk_nvme_async_event_info_nvm_command_set {
2687 /* Reservation Log Page Avaiable */
2688 SPDK_NVME_ASYNC_EVENT_RESERVATION_LOG_AVAIL = 0x0,
2689 /* Sanitize Operation Completed */
2690 SPDK_NVME_ASYNC_EVENT_SANITIZE_COMPLETED = 0x1,
2691
2692 /* 0x2 - 0xFF Reserved */
2693 };
2694
2695 /**
2696 * Asynchronous Event Request Completion
2697 */
2698 union spdk_nvme_async_event_completion {
2699 uint32_t raw;
2700 struct {
2701 uint32_t async_event_type : 3;
2702 uint32_t reserved1 : 5;
2703 uint32_t async_event_info : 8;
2704 uint32_t log_page_identifier : 8;
2705 uint32_t reserved2 : 8;
2706 } bits;
2707 };
2708 SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_async_event_completion) == 4, "Incorrect size");
2709
2710 /**
2711 * Firmware slot information page (\ref SPDK_NVME_LOG_FIRMWARE_SLOT)
2712 */
2713 struct spdk_nvme_firmware_page {
2714 struct {
2715 uint8_t active_slot : 3; /**< Slot for current FW */
2716 uint8_t reserved3 : 1;
2717 uint8_t next_reset_slot : 3; /**< Slot that will be active at next controller reset */
2718 uint8_t reserved7 : 1;
2719 } afi;
2720
2721 uint8_t reserved[7];
2722 uint8_t revision[7][8]; /** Revisions for 7 slots (ASCII strings) */
2723 uint8_t reserved2[448];
2724 };
2725 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_firmware_page) == 512, "Incorrect size");
2726
2727 /**
2728 * Namespace attachment Type Encoding
2729 */
2730 enum spdk_nvme_ns_attach_type {
2731 /* Controller attach */
2732 SPDK_NVME_NS_CTRLR_ATTACH = 0x0,
2733
2734 /* Controller detach */
2735 SPDK_NVME_NS_CTRLR_DETACH = 0x1,
2736
2737 /* 0x2-0xF - Reserved */
2738 };
2739
2740 /**
2741 * Namespace management Type Encoding
2742 */
2743 enum spdk_nvme_ns_management_type {
2744 /* Create */
2745 SPDK_NVME_NS_MANAGEMENT_CREATE = 0x0,
2746
2747 /* Delete */
2748 SPDK_NVME_NS_MANAGEMENT_DELETE = 0x1,
2749
2750 /* 0x2-0xF - Reserved */
2751 };
2752
2753 struct spdk_nvme_ns_list {
2754 uint32_t ns_list[1024];
2755 };
2756 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_list) == 4096, "Incorrect size");
2757
2758 /**
2759 * Namespace identification descriptor type
2760 *
2761 * \sa spdk_nvme_ns_id_desc
2762 */
2763 enum spdk_nvme_nidt {
2764 /** IEEE Extended Unique Identifier */
2765 SPDK_NVME_NIDT_EUI64 = 0x01,
2766
2767 /** Namespace GUID */
2768 SPDK_NVME_NIDT_NGUID = 0x02,
2769
2770 /** Namespace UUID */
2771 SPDK_NVME_NIDT_UUID = 0x03,
2772 };
2773
2774 struct spdk_nvme_ns_id_desc {
2775 /** Namespace identifier type */
2776 uint8_t nidt;
2777
2778 /** Namespace identifier length (length of nid field) */
2779 uint8_t nidl;
2780
2781 uint8_t reserved2;
2782 uint8_t reserved3;
2783
2784 /** Namespace identifier */
2785 uint8_t nid[];
2786 };
2787 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_id_desc) == 4, "Incorrect size");
2788
2789 struct spdk_nvme_ctrlr_list {
2790 uint16_t ctrlr_count;
2791 uint16_t ctrlr_list[2047];
2792 };
2793 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ctrlr_list) == 4096, "Incorrect size");
2794
2795 enum spdk_nvme_secure_erase_setting {
2796 SPDK_NVME_FMT_NVM_SES_NO_SECURE_ERASE = 0x0,
2797 SPDK_NVME_FMT_NVM_SES_USER_DATA_ERASE = 0x1,
2798 SPDK_NVME_FMT_NVM_SES_CRYPTO_ERASE = 0x2,
2799 };
2800
2801 enum spdk_nvme_pi_location {
2802 SPDK_NVME_FMT_NVM_PROTECTION_AT_TAIL = 0x0,
2803 SPDK_NVME_FMT_NVM_PROTECTION_AT_HEAD = 0x1,
2804 };
2805
2806 enum spdk_nvme_pi_type {
2807 SPDK_NVME_FMT_NVM_PROTECTION_DISABLE = 0x0,
2808 SPDK_NVME_FMT_NVM_PROTECTION_TYPE1 = 0x1,
2809 SPDK_NVME_FMT_NVM_PROTECTION_TYPE2 = 0x2,
2810 SPDK_NVME_FMT_NVM_PROTECTION_TYPE3 = 0x3,
2811 };
2812
2813 enum spdk_nvme_metadata_setting {
2814 SPDK_NVME_FMT_NVM_METADATA_TRANSFER_AS_BUFFER = 0x0,
2815 SPDK_NVME_FMT_NVM_METADATA_TRANSFER_AS_LBA = 0x1,
2816 };
2817
2818 struct spdk_nvme_format {
2819 uint32_t lbaf : 4;
2820 uint32_t ms : 1;
2821 uint32_t pi : 3;
2822 uint32_t pil : 1;
2823 uint32_t ses : 3;
2824 uint32_t reserved : 20;
2825 };
2826 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_format) == 4, "Incorrect size");
2827
2828 struct spdk_nvme_protection_info {
2829 uint16_t guard;
2830 uint16_t app_tag;
2831 uint32_t ref_tag;
2832 };
2833 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_protection_info) == 8, "Incorrect size");
2834
2835 /* Data structures for sanitize command */
2836 /* Sanitize - Command Dword 10 */
2837 struct spdk_nvme_sanitize {
2838 /* Sanitize Action (SANACT) */
2839 uint32_t sanact : 3;
2840 /* Allow Unrestricted Sanitize Exit (AUSE) */
2841 uint32_t ause : 1;
2842 /* Overwrite Pass Count (OWPASS) */
2843 uint32_t owpass : 4;
2844 /* Overwrite Invert Pattern Between Passes */
2845 uint32_t oipbp : 1;
2846 /* No Deallocate after sanitize (NDAS) */
2847 uint32_t ndas : 1;
2848 /* reserved */
2849 uint32_t reserved : 22;
2850 };
2851 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_sanitize) == 4, "Incorrect size");
2852
2853 /* Sanitize Action */
2854 enum spdk_sanitize_action {
2855 /* Exit Failure Mode */
2856 SPDK_NVME_SANITIZE_EXIT_FAILURE_MODE = 0x1,
2857 /* Start a Block Erase sanitize operation */
2858 SPDK_NVME_SANITIZE_BLOCK_ERASE = 0x2,
2859 /* Start an Overwrite sanitize operation */
2860 SPDK_NVME_SANITIZE_OVERWRITE = 0x3,
2861 /* Start a Crypto Erase sanitize operation */
2862 SPDK_NVME_SANITIZE_CRYPTO_ERASE = 0x4,
2863 };
2864
2865 /** Parameters for SPDK_NVME_OPC_FIRMWARE_COMMIT cdw10: commit action */
2866 enum spdk_nvme_fw_commit_action {
2867 /**
2868 * Downloaded image replaces the image specified by
2869 * the Firmware Slot field. This image is not activated.
2870 */
2871 SPDK_NVME_FW_COMMIT_REPLACE_IMG = 0x0,
2872 /**
2873 * Downloaded image replaces the image specified by
2874 * the Firmware Slot field. This image is activated at the next reset.
2875 */
2876 SPDK_NVME_FW_COMMIT_REPLACE_AND_ENABLE_IMG = 0x1,
2877 /**
2878 * The image specified by the Firmware Slot field is
2879 * activated at the next reset.
2880 */
2881 SPDK_NVME_FW_COMMIT_ENABLE_IMG = 0x2,
2882 /**
2883 * The image specified by the Firmware Slot field is
2884 * requested to be activated immediately without reset.
2885 */
2886 SPDK_NVME_FW_COMMIT_RUN_IMG = 0x3,
2887 };
2888
2889 /** Parameters for SPDK_NVME_OPC_FIRMWARE_COMMIT cdw10 */
2890 struct spdk_nvme_fw_commit {
2891 /**
2892 * Firmware Slot. Specifies the firmware slot that shall be used for the
2893 * Commit Action. The controller shall choose the firmware slot (slot 1 - 7)
2894 * to use for the operation if the value specified is 0h.
2895 */
2896 uint32_t fs : 3;
2897 /**
2898 * Commit Action. Specifies the action that is taken on the image downloaded
2899 * with the Firmware Image Download command or on a previously downloaded and
2900 * placed image.
2901 */
2902 uint32_t ca : 3;
2903 uint32_t reserved : 26;
2904 };
2905 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fw_commit) == 4, "Incorrect size");
2906
2907 #define spdk_nvme_cpl_is_error(cpl) \
2908 ((cpl)->status.sc != SPDK_NVME_SC_SUCCESS || \
2909 (cpl)->status.sct != SPDK_NVME_SCT_GENERIC)
2910
2911 #define spdk_nvme_cpl_is_success(cpl) (!spdk_nvme_cpl_is_error(cpl))
2912
2913 #define spdk_nvme_cpl_is_pi_error(cpl) \
2914 ((cpl)->status.sct == SPDK_NVME_SCT_MEDIA_ERROR && \
2915 ((cpl)->status.sc == SPDK_NVME_SC_GUARD_CHECK_ERROR || \
2916 (cpl)->status.sc == SPDK_NVME_SC_APPLICATION_TAG_CHECK_ERROR || \
2917 (cpl)->status.sc == SPDK_NVME_SC_REFERENCE_TAG_CHECK_ERROR))
2918
2919 #define spdk_nvme_cpl_is_abort_success(cpl) \
2920 (spdk_nvme_cpl_is_success(cpl) && !((cpl)->cdw0 & 1U))
2921
2922 /** Set fused operation */
2923 #define SPDK_NVME_IO_FLAGS_FUSE_FIRST (SPDK_NVME_CMD_FUSE_FIRST << 0)
2924 #define SPDK_NVME_IO_FLAGS_FUSE_SECOND (SPDK_NVME_CMD_FUSE_SECOND << 0)
2925 #define SPDK_NVME_IO_FLAGS_FUSE_MASK (SPDK_NVME_CMD_FUSE_MASK << 0)
2926 /** Enable protection information checking of the Logical Block Reference Tag field */
2927 #define SPDK_NVME_IO_FLAGS_PRCHK_REFTAG (1U << 26)
2928 /** Enable protection information checking of the Application Tag field */
2929 #define SPDK_NVME_IO_FLAGS_PRCHK_APPTAG (1U << 27)
2930 /** Enable protection information checking of the Guard field */
2931 #define SPDK_NVME_IO_FLAGS_PRCHK_GUARD (1U << 28)
2932 /** The protection information is stripped or inserted when set this bit */
2933 #define SPDK_NVME_IO_FLAGS_PRACT (1U << 29)
2934 #define SPDK_NVME_IO_FLAGS_FORCE_UNIT_ACCESS (1U << 30)
2935 #define SPDK_NVME_IO_FLAGS_LIMITED_RETRY (1U << 31)
2936
2937 /** Mask of valid io flags mask */
2938 #define SPDK_NVME_IO_FLAGS_VALID_MASK 0xFFFF0003
2939 #define SPDK_NVME_IO_FLAGS_CDW12_MASK 0xFFFF0000
2940
2941 #ifdef __cplusplus
2942 }
2943 #endif
2944
2945 #endif