Line data Source code
1 : /* SPDX-License-Identifier: BSD-3-Clause
2 : * Copyright (C) 2015 Intel Corporation.
3 : * All rights reserved.
4 : */
5 :
6 : /**
7 : * \file
8 : * NVMe specification definitions
9 : */
10 :
11 : #ifndef SPDK_NVME_SPEC_H
12 : #define SPDK_NVME_SPEC_H
13 :
14 : #include "spdk/stdinc.h"
15 :
16 : #ifdef __cplusplus
17 : extern "C" {
18 : #endif
19 :
20 : #include "spdk/assert.h"
21 :
22 : /**
23 : * Use to mark a command to apply to all namespaces, or to retrieve global
24 : * log pages.
25 : */
26 : #define SPDK_NVME_GLOBAL_NS_TAG ((uint32_t)0xFFFFFFFF)
27 :
28 : #define SPDK_NVME_MAX_IO_QUEUES (65535)
29 :
30 : #define SPDK_NVME_QUEUE_MIN_ENTRIES (2)
31 :
32 : #define SPDK_NVME_ADMIN_QUEUE_MIN_ENTRIES SPDK_NVME_QUEUE_MIN_ENTRIES
33 : #define SPDK_NVME_ADMIN_QUEUE_MAX_ENTRIES 4096
34 :
35 : /* Controllers with quirk NVME_QUIRK_MINIMUM_ADMIN_QUEUE_SIZE must have
36 : * admin queue size entries that are an even multiple of this number.
37 : */
38 : #define SPDK_NVME_ADMIN_QUEUE_QUIRK_ENTRIES_MULTIPLE 64
39 :
40 : #define SPDK_NVME_IO_QUEUE_MIN_ENTRIES SPDK_NVME_QUEUE_MIN_ENTRIES
41 : #define SPDK_NVME_IO_QUEUE_MAX_ENTRIES 65536
42 :
43 : /**
44 : * Indicates the maximum number of range sets that may be specified
45 : * in the dataset management command.
46 : */
47 : #define SPDK_NVME_DATASET_MANAGEMENT_MAX_RANGES 256
48 :
49 : /**
50 : * Maximum number of blocks that may be specified in a single dataset management range.
51 : */
52 : #define SPDK_NVME_DATASET_MANAGEMENT_RANGE_MAX_BLOCKS 0xFFFFFFFFu
53 :
54 : /**
55 : * Maximum number of entries in the log page of Changed Namespace List.
56 : */
57 : #define SPDK_NVME_MAX_CHANGED_NAMESPACES 1024
58 :
59 : #define SPDK_NVME_DOORBELL_REGISTER_SIZE 4
60 :
61 : union spdk_nvme_cap_register {
62 : uint64_t raw;
63 : struct {
64 : /** maximum queue entries supported */
65 : uint32_t mqes : 16;
66 :
67 : /** contiguous queues required */
68 : uint32_t cqr : 1;
69 :
70 : /** arbitration mechanism supported */
71 : uint32_t ams : 2;
72 :
73 : uint32_t reserved1 : 5;
74 :
75 : /** timeout */
76 : uint32_t to : 8;
77 :
78 : /** doorbell stride */
79 : uint32_t dstrd : 4;
80 :
81 : /** NVM subsystem reset supported */
82 : uint32_t nssrs : 1;
83 :
84 : /** command sets supported */
85 : uint32_t css : 8;
86 :
87 : /** boot partition support */
88 : uint32_t bps : 1;
89 :
90 : uint32_t reserved2 : 2;
91 :
92 : /** memory page size minimum */
93 : uint32_t mpsmin : 4;
94 :
95 : /** memory page size maximum */
96 : uint32_t mpsmax : 4;
97 :
98 : /** persistent memory region supported */
99 : uint32_t pmrs : 1;
100 :
101 : /** controller memory buffer supported */
102 : uint32_t cmbs : 1;
103 :
104 : uint32_t reserved3 : 6;
105 : } bits;
106 : };
107 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cap_register) == 8, "Incorrect size");
108 :
109 : /**
110 : * I/O Command Set Selected
111 : *
112 : * Only a single command set is defined as of NVMe 1.3 (NVM). Later, it became
113 : * possible to disable I/O Command Sets, that is, configuring it to only use the
114 : * Admin Command Set. With 1.4c and Namespace Types, additional I/O Command Sets
115 : * are available.
116 : */
117 : enum spdk_nvme_cc_css {
118 : SPDK_NVME_CC_CSS_NVM = 0x0, /**< NVM command set */
119 : SPDK_NVME_CC_CSS_IOCS = 0x6, /**< One or more I/O command sets */
120 : SPDK_NVME_CC_CSS_NOIO = 0x7, /**< No I/O, only admin */
121 : };
122 :
123 : #define SPDK_NVME_CAP_CSS_NVM (1u << SPDK_NVME_CC_CSS_NVM) /**< NVM command set supported */
124 : #define SPDK_NVME_CAP_CSS_IOCS (1u << SPDK_NVME_CC_CSS_IOCS) /**< One or more I/O Command sets supported */
125 : #define SPDK_NVME_CAP_CSS_NOIO (1u << SPDK_NVME_CC_CSS_NOIO) /**< No I/O, only admin */
126 :
127 : union spdk_nvme_cc_register {
128 : uint32_t raw;
129 : struct {
130 : /** enable */
131 : uint32_t en : 1;
132 :
133 : uint32_t reserved1 : 3;
134 :
135 : /** i/o command set selected */
136 : uint32_t css : 3;
137 :
138 : /** memory page size */
139 : uint32_t mps : 4;
140 :
141 : /** arbitration mechanism selected */
142 : uint32_t ams : 3;
143 :
144 : /** shutdown notification */
145 : uint32_t shn : 2;
146 :
147 : /** i/o submission queue entry size */
148 : uint32_t iosqes : 4;
149 :
150 : /** i/o completion queue entry size */
151 : uint32_t iocqes : 4;
152 :
153 : uint32_t reserved2 : 8;
154 : } bits;
155 : };
156 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cc_register) == 4, "Incorrect size");
157 :
158 : enum spdk_nvme_shn_value {
159 : SPDK_NVME_SHN_NORMAL = 0x1,
160 : SPDK_NVME_SHN_ABRUPT = 0x2,
161 : };
162 :
163 : union spdk_nvme_csts_register {
164 : uint32_t raw;
165 : struct {
166 : /** ready */
167 : uint32_t rdy : 1;
168 :
169 : /** controller fatal status */
170 : uint32_t cfs : 1;
171 :
172 : /** shutdown status */
173 : uint32_t shst : 2;
174 :
175 : /** NVM subsystem reset occurred */
176 : uint32_t nssro : 1;
177 :
178 : /** Processing paused */
179 : uint32_t pp : 1;
180 :
181 : uint32_t reserved1 : 26;
182 : } bits;
183 : };
184 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_csts_register) == 4, "Incorrect size");
185 :
186 : enum spdk_nvme_shst_value {
187 : SPDK_NVME_SHST_NORMAL = 0x0,
188 : SPDK_NVME_SHST_OCCURRING = 0x1,
189 : SPDK_NVME_SHST_COMPLETE = 0x2,
190 : };
191 :
192 : union spdk_nvme_aqa_register {
193 : uint32_t raw;
194 : struct {
195 : /** admin submission queue size */
196 : uint32_t asqs : 12;
197 :
198 : uint32_t reserved1 : 4;
199 :
200 : /** admin completion queue size */
201 : uint32_t acqs : 12;
202 :
203 : uint32_t reserved2 : 4;
204 : } bits;
205 : };
206 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_aqa_register) == 4, "Incorrect size");
207 :
208 : union spdk_nvme_vs_register {
209 : uint32_t raw;
210 : struct {
211 : /** indicates the tertiary version */
212 : uint32_t ter : 8;
213 : /** indicates the minor version */
214 : uint32_t mnr : 8;
215 : /** indicates the major version */
216 : uint32_t mjr : 16;
217 : } bits;
218 : };
219 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_vs_register) == 4, "Incorrect size");
220 :
221 : /** Generate raw version in the same format as \ref spdk_nvme_vs_register for comparison. */
222 : #define SPDK_NVME_VERSION(mjr, mnr, ter) \
223 : (((uint32_t)(mjr) << 16) | \
224 : ((uint32_t)(mnr) << 8) | \
225 : (uint32_t)(ter))
226 :
227 : /* Test that the shifts are correct */
228 : SPDK_STATIC_ASSERT(SPDK_NVME_VERSION(1, 0, 0) == 0x00010000, "version macro error");
229 : SPDK_STATIC_ASSERT(SPDK_NVME_VERSION(1, 2, 1) == 0x00010201, "version macro error");
230 :
231 : union spdk_nvme_cmbloc_register {
232 : uint32_t raw;
233 : struct {
234 : /** indicator of BAR which contains controller memory buffer(CMB) */
235 : uint32_t bir : 3;
236 : uint32_t reserved1 : 9;
237 : /** offset of CMB in multiples of the size unit */
238 : uint32_t ofst : 20;
239 : } bits;
240 : };
241 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmbloc_register) == 4, "Incorrect size");
242 :
243 : union spdk_nvme_cmbsz_register {
244 : uint32_t raw;
245 : struct {
246 : /** support submission queues in CMB */
247 : uint32_t sqs : 1;
248 : /** support completion queues in CMB */
249 : uint32_t cqs : 1;
250 : /** support PRP and SGLs lists in CMB */
251 : uint32_t lists : 1;
252 : /** support read data and metadata in CMB */
253 : uint32_t rds : 1;
254 : /** support write data and metadata in CMB */
255 : uint32_t wds : 1;
256 : uint32_t reserved1 : 3;
257 : /** indicates the granularity of the size unit */
258 : uint32_t szu : 4;
259 : /** size of CMB in multiples of the size unit */
260 : uint32_t sz : 20;
261 : } bits;
262 : };
263 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmbsz_register) == 4, "Incorrect size");
264 :
265 : union spdk_nvme_cmbmsc_register {
266 : uint64_t raw;
267 : struct {
268 : /** capability registers enabled */
269 : uint64_t cre : 1;
270 :
271 : /** controller memory space enable */
272 : uint64_t cmse : 1;
273 :
274 : uint64_t reserved : 10;
275 :
276 : /** controller base address */
277 : uint64_t cba : 52;
278 : } bits;
279 :
280 : };
281 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmbmsc_register) == 8, "Incorrect size");
282 :
283 : union spdk_nvme_cmbsts_register {
284 : uint32_t raw;
285 : struct {
286 : /** controller base address invalid */
287 : uint32_t cbai : 1;
288 :
289 : uint32_t reserved : 31;
290 : } bits;
291 : };
292 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmbsts_register) == 4, "Incorrect size");
293 :
294 : union spdk_nvme_pmrcap_register {
295 : uint32_t raw;
296 : struct {
297 : uint32_t reserved1 : 3;
298 :
299 : /** read data support */
300 : uint32_t rds : 1;
301 :
302 : /** write data support */
303 : uint32_t wds : 1;
304 :
305 : /** base indicator register */
306 : uint32_t bir : 3;
307 :
308 : /**
309 : * persistent memory region time units
310 : * 00b: 500 milliseconds
311 : * 01b: minutes
312 : */
313 : uint32_t pmrtu : 2;
314 :
315 : /** persistent memory region write barrier mechanisms */
316 : uint32_t pmrwbm : 4;
317 :
318 : uint32_t reserved2 : 2;
319 :
320 : /** persistent memory region timeout */
321 : uint32_t pmrto : 8;
322 :
323 : /** controller memory space supported */
324 : uint32_t cmss : 1;
325 :
326 : uint32_t reserved3 : 7;
327 : } bits;
328 : };
329 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_pmrcap_register) == 4, "Incorrect size");
330 :
331 : union spdk_nvme_pmrctl_register {
332 : uint32_t raw;
333 : struct {
334 : /** enable */
335 : uint32_t en : 1;
336 :
337 : uint32_t reserved : 31;
338 : } bits;
339 : };
340 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_pmrctl_register) == 4, "Incorrect size");
341 :
342 : union spdk_nvme_pmrsts_register {
343 : uint32_t raw;
344 : struct {
345 : /** err */
346 : uint32_t err : 8;
347 :
348 : /** not ready */
349 : uint32_t nrdy : 1;
350 :
351 : /**
352 : * health status
353 : * 000b: Normal Operation
354 : * 001b: Restore Error
355 : * 010b: Read Only
356 : * 011b: Unreliable
357 : */
358 : uint32_t hsts : 3;
359 :
360 : /** controller base address invalid */
361 : uint32_t cbai : 1;
362 :
363 : uint32_t reserved : 19;
364 : } bits;
365 : };
366 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_pmrsts_register) == 4, "Incorrect size");
367 :
368 : union spdk_nvme_pmrebs_register {
369 : uint32_t raw;
370 : struct {
371 : /**
372 : * pmr elasticity buffer size units
373 : * 0h: Bytes
374 : * 1h: 1 KiB
375 : * 2h: 1 MiB
376 : * 3h: 1 GiB
377 : */
378 : uint32_t pmrszu : 4;
379 :
380 : /** read bypass behavior */
381 : uint32_t rbb : 1;
382 :
383 : uint32_t reserved : 3;
384 :
385 : /** pmr elasticity buffer size base */
386 : uint32_t pmrwbz : 24;
387 : } bits;
388 : };
389 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_pmrebs_register) == 4, "Incorrect size");
390 :
391 : union spdk_nvme_pmrswtp_register {
392 : uint32_t raw;
393 : struct {
394 : /**
395 : * pmr sustained write throughput units
396 : * 0h: Bytes per second
397 : * 1h: 1 KiB / s
398 : * 2h: 1 MiB / s
399 : * 3h: 1 GiB / s
400 : */
401 : uint32_t pmrswtu : 4;
402 :
403 : uint32_t reserved : 4;
404 :
405 : /** pmr sustained write throughput */
406 : uint32_t pmrswtv : 24;
407 : } bits;
408 : };
409 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_pmrswtp_register) == 4, "Incorrect size");
410 :
411 : union spdk_nvme_pmrmscl_register {
412 : uint32_t raw;
413 : struct {
414 : uint32_t reserved1 : 1;
415 :
416 : /** controller memory space enable */
417 : uint32_t cmse : 1;
418 :
419 : uint32_t reserved2 : 10;
420 :
421 : /** controller base address */
422 : uint32_t cba : 20;
423 : } bits;
424 : };
425 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_pmrmscl_register) == 4, "Incorrect size");
426 :
427 : /** Boot partition information */
428 : union spdk_nvme_bpinfo_register {
429 : uint32_t raw;
430 : struct {
431 : /** Boot partition size in 128KB multiples */
432 : uint32_t bpsz : 15;
433 :
434 : uint32_t reserved1 : 9;
435 :
436 : /**
437 : * Boot read status
438 : * 00b: No Boot Partition read operation requested
439 : * 01b: Boot Partition read in progress
440 : * 10b: Boot Partition read completed successfully
441 : * 11b: Error completing Boot Partition read
442 : */
443 : uint32_t brs : 2;
444 :
445 : uint32_t reserved2 : 5;
446 :
447 : /** Active Boot Partition ID */
448 : uint32_t abpid : 1;
449 : } bits;
450 : };
451 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_bpinfo_register) == 4, "Incorrect size");
452 :
453 : /** Boot read status values */
454 : enum spdk_nvme_brs_value {
455 : SPDK_NVME_BRS_NO_READ = 0x0,
456 : SPDK_NVME_BRS_READ_IN_PROGRESS = 0x1,
457 : SPDK_NVME_BRS_READ_SUCCESS = 0x2,
458 : SPDK_NVME_BRS_READ_ERROR = 0x3,
459 : };
460 :
461 : /** Boot partition read select */
462 : union spdk_nvme_bprsel_register {
463 : uint32_t raw;
464 : struct {
465 : /** Boot partition read size in multiples of 4KB */
466 : uint32_t bprsz : 10;
467 :
468 : /** Boot partition read offset in multiples of 4KB */
469 : uint32_t bprof : 20;
470 :
471 : uint32_t reserved : 1;
472 :
473 : /** Boot Partition Identifier */
474 : uint32_t bpid : 1;
475 : } bits;
476 : };
477 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_bprsel_register) == 4, "Incorrect size");
478 :
479 : /** Value to write to NSSR to indicate a NVM subsystem reset ("NVMe") */
480 : #define SPDK_NVME_NSSR_VALUE 0x4E564D65
481 :
482 : struct spdk_nvme_registers {
483 : /** controller capabilities */
484 : union spdk_nvme_cap_register cap;
485 :
486 : /** version of NVMe specification */
487 : union spdk_nvme_vs_register vs;
488 : uint32_t intms; /* interrupt mask set */
489 : uint32_t intmc; /* interrupt mask clear */
490 :
491 : /** controller configuration */
492 : union spdk_nvme_cc_register cc;
493 :
494 : uint32_t reserved1;
495 : union spdk_nvme_csts_register csts; /* controller status */
496 : uint32_t nssr; /* NVM subsystem reset */
497 :
498 : /** admin queue attributes */
499 : union spdk_nvme_aqa_register aqa;
500 :
501 : uint64_t asq; /* admin submission queue base addr */
502 : uint64_t acq; /* admin completion queue base addr */
503 : /** controller memory buffer location */
504 : union spdk_nvme_cmbloc_register cmbloc;
505 : /** controller memory buffer size */
506 : union spdk_nvme_cmbsz_register cmbsz;
507 :
508 : /** boot partition information */
509 : union spdk_nvme_bpinfo_register bpinfo;
510 :
511 : /** boot partition read select */
512 : union spdk_nvme_bprsel_register bprsel;
513 :
514 : /** boot partition memory buffer location (must be 4KB aligned) */
515 : uint64_t bpmbl;
516 :
517 : /** controller memory buffer memory space control */
518 : union spdk_nvme_cmbmsc_register cmbmsc;
519 :
520 : /** controller memory buffer status */
521 : union spdk_nvme_cmbsts_register cmbsts;
522 :
523 : uint32_t reserved2[0x369];
524 :
525 : /** persistent memory region capabilities */
526 : union spdk_nvme_pmrcap_register pmrcap;
527 :
528 : /** persistent memory region control */
529 : union spdk_nvme_pmrctl_register pmrctl;
530 :
531 : /** persistent memory region status */
532 : union spdk_nvme_pmrsts_register pmrsts;
533 :
534 : /** persistent memory region elasticity buffer size */
535 : union spdk_nvme_pmrebs_register pmrebs;
536 :
537 : /** persistent memory region sustained write throughput */
538 : union spdk_nvme_pmrswtp_register pmrswtp;
539 :
540 : /** persistent memory region memory space control lower */
541 : union spdk_nvme_pmrmscl_register pmrmscl;
542 :
543 : uint32_t pmrmscu; /* persistent memory region memory space control upper */
544 :
545 : uint32_t reserved3[0x79];
546 :
547 : struct {
548 : uint32_t sq_tdbl; /* submission queue tail doorbell */
549 : uint32_t cq_hdbl; /* completion queue head doorbell */
550 : } doorbell[1];
551 : };
552 :
553 : /* NVMe controller register space offsets */
554 : SPDK_STATIC_ASSERT(0x00 == offsetof(struct spdk_nvme_registers, cap),
555 : "Incorrect register offset");
556 : SPDK_STATIC_ASSERT(0x08 == offsetof(struct spdk_nvme_registers, vs), "Incorrect register offset");
557 : SPDK_STATIC_ASSERT(0x0C == offsetof(struct spdk_nvme_registers, intms),
558 : "Incorrect register offset");
559 : SPDK_STATIC_ASSERT(0x10 == offsetof(struct spdk_nvme_registers, intmc),
560 : "Incorrect register offset");
561 : SPDK_STATIC_ASSERT(0x14 == offsetof(struct spdk_nvme_registers, cc), "Incorrect register offset");
562 : SPDK_STATIC_ASSERT(0x1C == offsetof(struct spdk_nvme_registers, csts), "Incorrect register offset");
563 : SPDK_STATIC_ASSERT(0x20 == offsetof(struct spdk_nvme_registers, nssr), "Incorrect register offset");
564 : SPDK_STATIC_ASSERT(0x24 == offsetof(struct spdk_nvme_registers, aqa), "Incorrect register offset");
565 : SPDK_STATIC_ASSERT(0x28 == offsetof(struct spdk_nvme_registers, asq), "Incorrect register offset");
566 : SPDK_STATIC_ASSERT(0x30 == offsetof(struct spdk_nvme_registers, acq), "Incorrect register offset");
567 : SPDK_STATIC_ASSERT(0x38 == offsetof(struct spdk_nvme_registers, cmbloc),
568 : "Incorrect register offset");
569 : SPDK_STATIC_ASSERT(0x3C == offsetof(struct spdk_nvme_registers, cmbsz),
570 : "Incorrect register offset");
571 : SPDK_STATIC_ASSERT(0x40 == offsetof(struct spdk_nvme_registers, bpinfo),
572 : "Incorrect register offset");
573 : SPDK_STATIC_ASSERT(0x44 == offsetof(struct spdk_nvme_registers, bprsel),
574 : "Incorrect register offset");
575 : SPDK_STATIC_ASSERT(0x48 == offsetof(struct spdk_nvme_registers, bpmbl),
576 : "Incorrect register offset");
577 : SPDK_STATIC_ASSERT(0x50 == offsetof(struct spdk_nvme_registers, cmbmsc),
578 : "Incorrect register offset");
579 : SPDK_STATIC_ASSERT(0x58 == offsetof(struct spdk_nvme_registers, cmbsts),
580 : "Incorrect register offset");
581 : SPDK_STATIC_ASSERT(0xE00 == offsetof(struct spdk_nvme_registers, pmrcap),
582 : "Incorrect register offset");
583 : SPDK_STATIC_ASSERT(0xE04 == offsetof(struct spdk_nvme_registers, pmrctl),
584 : "Incorrect register offset");
585 : SPDK_STATIC_ASSERT(0xE08 == offsetof(struct spdk_nvme_registers, pmrsts),
586 : "Incorrect register offset");
587 : SPDK_STATIC_ASSERT(0xE0C == offsetof(struct spdk_nvme_registers, pmrebs),
588 : "Incorrect register offset");
589 : SPDK_STATIC_ASSERT(0xE10 == offsetof(struct spdk_nvme_registers, pmrswtp),
590 : "Incorrect register offset");
591 : SPDK_STATIC_ASSERT(0xE14 == offsetof(struct spdk_nvme_registers, pmrmscl),
592 : "Incorrect register offset");
593 : SPDK_STATIC_ASSERT(0xE18 == offsetof(struct spdk_nvme_registers, pmrmscu),
594 : "Incorrect register offset");
595 :
596 : enum spdk_nvme_sgl_descriptor_type {
597 : SPDK_NVME_SGL_TYPE_DATA_BLOCK = 0x0,
598 : SPDK_NVME_SGL_TYPE_BIT_BUCKET = 0x1,
599 : SPDK_NVME_SGL_TYPE_SEGMENT = 0x2,
600 : SPDK_NVME_SGL_TYPE_LAST_SEGMENT = 0x3,
601 : SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK = 0x4,
602 : SPDK_NVME_SGL_TYPE_TRANSPORT_DATA_BLOCK = 0x5,
603 : /* 0x6 - 0xE reserved */
604 : SPDK_NVME_SGL_TYPE_VENDOR_SPECIFIC = 0xF
605 : };
606 :
607 : enum spdk_nvme_sgl_descriptor_subtype {
608 : SPDK_NVME_SGL_SUBTYPE_ADDRESS = 0x0,
609 : SPDK_NVME_SGL_SUBTYPE_OFFSET = 0x1,
610 : SPDK_NVME_SGL_SUBTYPE_TRANSPORT = 0xa,
611 : };
612 :
613 : #pragma pack(push, 1)
614 : struct spdk_nvme_sgl_descriptor {
615 : uint64_t address;
616 : union {
617 : struct {
618 : uint8_t reserved[7];
619 : uint8_t subtype : 4;
620 : uint8_t type : 4;
621 : } generic;
622 :
623 : struct {
624 : uint32_t length;
625 : uint8_t reserved[3];
626 : uint8_t subtype : 4;
627 : uint8_t type : 4;
628 : } unkeyed;
629 :
630 : struct {
631 : uint64_t length : 24;
632 : uint64_t key : 32;
633 : uint64_t subtype : 4;
634 : uint64_t type : 4;
635 : } keyed;
636 : };
637 : };
638 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_sgl_descriptor) == 16, "Incorrect size");
639 : #pragma pack(pop)
640 :
641 : enum spdk_nvme_psdt_value {
642 : SPDK_NVME_PSDT_PRP = 0x0,
643 : SPDK_NVME_PSDT_SGL_MPTR_CONTIG = 0x1,
644 : SPDK_NVME_PSDT_SGL_MPTR_SGL = 0x2,
645 : SPDK_NVME_PSDT_RESERVED = 0x3
646 : };
647 :
648 : /**
649 : * Submission queue priority values for Create I/O Submission Queue Command.
650 : *
651 : * Only valid for weighted round robin arbitration method.
652 : */
653 : enum spdk_nvme_qprio {
654 : SPDK_NVME_QPRIO_URGENT = 0x0,
655 : SPDK_NVME_QPRIO_HIGH = 0x1,
656 : SPDK_NVME_QPRIO_MEDIUM = 0x2,
657 : SPDK_NVME_QPRIO_LOW = 0x3
658 : };
659 :
660 : #define SPDK_NVME_CREATE_IO_SQ_QPRIO_MASK 0x3
661 :
662 : /**
663 : * Optional Arbitration Mechanism Supported by the controller.
664 : *
665 : * Two bits for CAP.AMS (18:17) field are set to '1' when the controller supports.
666 : * There is no bit for AMS_RR where all controllers support and set to 0x0 by default.
667 : */
668 : enum spdk_nvme_cap_ams {
669 : SPDK_NVME_CAP_AMS_WRR = 0x1, /**< weighted round robin */
670 : SPDK_NVME_CAP_AMS_VS = 0x2, /**< vendor specific */
671 : };
672 :
673 : /**
674 : * Arbitration Mechanism Selected to the controller.
675 : *
676 : * Value 0x2 to 0x6 is reserved.
677 : */
678 : enum spdk_nvme_cc_ams {
679 : SPDK_NVME_CC_AMS_RR = 0x0, /**< default round robin */
680 : SPDK_NVME_CC_AMS_WRR = 0x1, /**< weighted round robin */
681 : SPDK_NVME_CC_AMS_VS = 0x7, /**< vendor specific */
682 : };
683 :
684 : /**
685 : * Fused Operation
686 : */
687 : enum spdk_nvme_cmd_fuse {
688 : SPDK_NVME_CMD_FUSE_NONE = 0x0, /**< normal operation */
689 : SPDK_NVME_CMD_FUSE_FIRST = 0x1, /**< fused operation, first command */
690 : SPDK_NVME_CMD_FUSE_SECOND = 0x2, /**< fused operation, second command */
691 : SPDK_NVME_CMD_FUSE_MASK = 0x3, /**< fused operation flags mask */
692 : };
693 :
694 : /**
695 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_ARBITRATION
696 : */
697 : union spdk_nvme_feat_arbitration {
698 : uint32_t raw;
699 : struct {
700 : /** Arbitration Burst */
701 : uint32_t ab : 3;
702 :
703 : uint32_t reserved : 5;
704 :
705 : /** Low Priority Weight */
706 : uint32_t lpw : 8;
707 :
708 : /** Medium Priority Weight */
709 : uint32_t mpw : 8;
710 :
711 : /** High Priority Weight */
712 : uint32_t hpw : 8;
713 : } bits;
714 : };
715 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_arbitration) == 4, "Incorrect size");
716 :
717 : #define SPDK_NVME_ARBITRATION_BURST_UNLIMITED 0x7
718 :
719 : /**
720 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_POWER_MANAGEMENT
721 : */
722 : union spdk_nvme_feat_power_management {
723 : uint32_t raw;
724 : struct {
725 : /** Power State */
726 : uint32_t ps : 5;
727 :
728 : /** Workload Hint */
729 : uint32_t wh : 3;
730 :
731 : uint32_t reserved : 24;
732 : } bits;
733 : };
734 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_power_management) == 4, "Incorrect size");
735 :
736 : /**
737 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_LBA_RANGE_TYPE
738 : */
739 : union spdk_nvme_feat_lba_range_type {
740 : uint32_t raw;
741 : struct {
742 : /** Number of LBA Ranges */
743 : uint32_t num : 6;
744 :
745 : uint32_t reserved : 26;
746 : } bits;
747 : };
748 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_lba_range_type) == 4, "Incorrect size");
749 :
750 : /**
751 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD
752 : */
753 : union spdk_nvme_feat_temperature_threshold {
754 : uint32_t raw;
755 : struct {
756 : /** Temperature Threshold */
757 : uint32_t tmpth : 16;
758 :
759 : /** Threshold Temperature Select */
760 : uint32_t tmpsel : 4;
761 :
762 : /** Threshold Type Select */
763 : uint32_t thsel : 2;
764 :
765 : uint32_t reserved : 10;
766 : } bits;
767 : };
768 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_temperature_threshold) == 4, "Incorrect size");
769 :
770 : /**
771 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_ERROR_RECOVERY
772 : */
773 : union spdk_nvme_feat_error_recovery {
774 : uint32_t raw;
775 : struct {
776 : /** Time Limited Error Recovery */
777 : uint32_t tler : 16;
778 :
779 : /** Deallocated or Unwritten Logical Block Error Enable */
780 : uint32_t dulbe : 1;
781 :
782 : uint32_t reserved : 15;
783 : } bits;
784 : };
785 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_error_recovery) == 4, "Incorrect size");
786 :
787 : /**
788 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_VOLATILE_WRITE_CACHE
789 : */
790 : union spdk_nvme_feat_volatile_write_cache {
791 : uint32_t raw;
792 : struct {
793 : /** Volatile Write Cache Enable */
794 : uint32_t wce : 1;
795 :
796 : uint32_t reserved : 31;
797 : } bits;
798 : };
799 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_volatile_write_cache) == 4, "Incorrect size");
800 :
801 : /**
802 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_NUMBER_OF_QUEUES
803 : */
804 : union spdk_nvme_feat_number_of_queues {
805 : uint32_t raw;
806 : struct {
807 : /** Number of I/O Submission Queues Requested */
808 : uint32_t nsqr : 16;
809 :
810 : /** Number of I/O Completion Queues Requested */
811 : uint32_t ncqr : 16;
812 : } bits;
813 : };
814 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_number_of_queues) == 4, "Incorrect size");
815 :
816 : /**
817 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_INTERRUPT_COALESCING
818 : */
819 : union spdk_nvme_feat_interrupt_coalescing {
820 : uint32_t raw;
821 : struct {
822 : /** Aggregation Threshold */
823 : uint32_t thr : 8;
824 :
825 : /** Aggregation time */
826 : uint32_t time : 8;
827 :
828 : uint32_t reserved : 16;
829 : } bits;
830 : };
831 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_interrupt_coalescing) == 4, "Incorrect size");
832 :
833 : /**
834 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION
835 : */
836 : union spdk_nvme_feat_interrupt_vector_configuration {
837 : uint32_t raw;
838 : struct {
839 : /** Interrupt Vector */
840 : uint32_t iv : 16;
841 :
842 : /** Coalescing Disable */
843 : uint32_t cd : 1;
844 :
845 : uint32_t reserved : 15;
846 : } bits;
847 : };
848 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_interrupt_vector_configuration) == 4,
849 : "Incorrect size");
850 :
851 : /**
852 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_WRITE_ATOMICITY
853 : */
854 : union spdk_nvme_feat_write_atomicity {
855 : uint32_t raw;
856 : struct {
857 : /** Disable Normal */
858 : uint32_t dn : 1;
859 :
860 : uint32_t reserved : 31;
861 : } bits;
862 : };
863 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_write_atomicity) == 4, "Incorrect size");
864 :
865 : union spdk_nvme_critical_warning_state {
866 : uint8_t raw;
867 :
868 : struct {
869 : uint8_t available_spare : 1;
870 : uint8_t temperature : 1;
871 : uint8_t device_reliability : 1;
872 : uint8_t read_only : 1;
873 : uint8_t volatile_memory_backup : 1;
874 : uint8_t reserved : 3;
875 : } bits;
876 : };
877 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_critical_warning_state) == 1, "Incorrect size");
878 :
879 : /**
880 : * Data used by Set Features / Get Features \ref SPDK_NVME_FEAT_ASYNC_EVENT_CONFIGURATION
881 : */
882 : union spdk_nvme_feat_async_event_configuration {
883 : uint32_t raw;
884 : struct {
885 : union spdk_nvme_critical_warning_state crit_warn;
886 : uint8_t ns_attr_notice : 1;
887 : uint8_t fw_activation_notice : 1;
888 : uint8_t telemetry_log_notice : 1;
889 : uint8_t ana_change_notice : 1;
890 : uint8_t reserved1 : 4;
891 : uint16_t reserved2 : 15;
892 : /** Discovery log change (refer to the NVMe over Fabrics specification) */
893 : uint16_t discovery_log_change_notice : 1;
894 : } bits;
895 : };
896 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_async_event_configuration) == 4, "Incorrect size");
897 :
898 : /**
899 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION
900 : */
901 : union spdk_nvme_feat_autonomous_power_state_transition {
902 : uint32_t raw;
903 : struct {
904 : /** Autonomous Power State Transition Enable */
905 : uint32_t apste : 1;
906 :
907 : uint32_t reserved : 31;
908 : } bits;
909 : };
910 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_autonomous_power_state_transition) == 4,
911 : "Incorrect size");
912 :
913 : /**
914 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_HOST_MEM_BUFFER
915 : */
916 : union spdk_nvme_feat_host_mem_buffer {
917 : uint32_t raw;
918 : struct {
919 : /** Enable Host Memory */
920 : uint32_t ehm : 1;
921 :
922 : /** Memory Return */
923 : uint32_t mr : 1;
924 :
925 : uint32_t reserved : 30;
926 : } bits;
927 : };
928 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_host_mem_buffer) == 4, "Incorrect size");
929 :
930 : /**
931 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_KEEP_ALIVE_TIMER
932 : */
933 : union spdk_nvme_feat_keep_alive_timer {
934 : uint32_t raw;
935 : struct {
936 : /** Keep Alive Timeout */
937 : uint32_t kato : 32;
938 : } bits;
939 : };
940 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_keep_alive_timer) == 4, "Incorrect size");
941 :
942 : /**
943 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_HOST_CONTROLLED_THERMAL_MANAGEMENT
944 : */
945 : union spdk_nvme_feat_host_controlled_thermal_management {
946 : uint32_t raw;
947 : struct {
948 : /** Thermal Management Temperature 2 */
949 : uint32_t tmt2 : 16;
950 :
951 : /** Thermal Management Temperature 1 */
952 : uint32_t tmt1 : 16;
953 : } bits;
954 : };
955 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_host_controlled_thermal_management) == 4,
956 : "Incorrect size");
957 :
958 : /**
959 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_NON_OPERATIONAL_POWER_STATE_CONFIG
960 : */
961 : union spdk_nvme_feat_non_operational_power_state_config {
962 : uint32_t raw;
963 : struct {
964 : /** Non-Operational Power State Permissive Mode Enable */
965 : uint32_t noppme : 1;
966 :
967 : uint32_t reserved : 31;
968 : } bits;
969 : };
970 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_non_operational_power_state_config) == 4,
971 : "Incorrect size");
972 :
973 : /**
974 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_SOFTWARE_PROGRESS_MARKER
975 : */
976 : union spdk_nvme_feat_software_progress_marker {
977 : uint32_t raw;
978 : struct {
979 : /** Pre-boot Software Load Count */
980 : uint32_t pbslc : 8;
981 :
982 : uint32_t reserved : 24;
983 : } bits;
984 : };
985 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_software_progress_marker) == 4, "Incorrect size");
986 :
987 : /**
988 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_HOST_IDENTIFIER
989 : */
990 : union spdk_nvme_feat_host_identifier {
991 : uint32_t raw;
992 : struct {
993 : /** Enable Extended Host Identifier */
994 : uint32_t exhid : 1;
995 :
996 : uint32_t reserved : 31;
997 : } bits;
998 : };
999 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_host_identifier) == 4, "Incorrect size");
1000 :
1001 : /**
1002 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_HOST_RESERVE_MASK
1003 : */
1004 : union spdk_nvme_feat_reservation_notification_mask {
1005 : uint32_t raw;
1006 : struct {
1007 : uint32_t reserved1 : 1;
1008 : /* Mask Registration Preempted Notification */
1009 : uint32_t regpre : 1;
1010 : /* Mask Reservation Released Notification */
1011 : uint32_t resrel : 1;
1012 : /* Mask Reservation Preempted Notification */
1013 : uint32_t respre : 1;
1014 : uint32_t reserved2 : 28;
1015 : } bits;
1016 : };
1017 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_reservation_notification_mask) == 4,
1018 : "Incorrect size");
1019 :
1020 : /**
1021 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_HOST_RESERVE_PERSIST
1022 : */
1023 : union spdk_nvme_feat_reservation_persistence {
1024 : uint32_t raw;
1025 : struct {
1026 : /* Persist Through Power Loss */
1027 : uint32_t ptpl : 1;
1028 : uint32_t reserved : 31;
1029 : } bits;
1030 : };
1031 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_reservation_persistence) == 4, "Incorrect size");
1032 :
1033 : /**
1034 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_FDP
1035 : */
1036 : union spdk_nvme_feat_fdp_cdw11 {
1037 : uint32_t raw;
1038 : struct {
1039 : /* Endurance Group Identifier */
1040 : uint32_t endgid : 16;
1041 : uint32_t reserved : 16;
1042 : } bits;
1043 : };
1044 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_fdp_cdw11) == 4, "Incorrect size");
1045 :
1046 : /**
1047 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_FDP
1048 : */
1049 : union spdk_nvme_feat_fdp_cdw12 {
1050 : uint32_t raw;
1051 : struct {
1052 : /* Flexible Data Placement Enable */
1053 : uint32_t fdpe : 1;
1054 : uint32_t reserved1 : 7;
1055 : /* Flexible Data Placement Configuration Index */
1056 : uint32_t fdpci : 8;
1057 : uint32_t reserved2 : 16;
1058 : } bits;
1059 : };
1060 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_fdp_cdw12) == 4, "Incorrect size");
1061 :
1062 : /**
1063 : * Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_FDP_EVENTS
1064 : */
1065 : union spdk_nvme_feat_fdp_events_cdw11 {
1066 : uint32_t raw;
1067 : struct {
1068 : /* Placement Handle associated with RUH */
1069 : uint32_t phndl : 16;
1070 : /* Number of FDP event types in data buffer */
1071 : uint32_t noet : 8;
1072 : uint32_t reserved : 8;
1073 : } bits;
1074 : };
1075 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_fdp_events_cdw11) == 4, "Incorrect size");
1076 :
1077 : /**
1078 : * Data used by Set Feature \ref SPDK_NVME_FEAT_FDP_EVENTS
1079 : */
1080 : union spdk_nvme_feat_fdp_events_cdw12 {
1081 : uint32_t raw;
1082 : struct {
1083 : /* FDP Event Enable */
1084 : uint32_t fdpee : 1;
1085 : uint32_t reserved1 : 31;
1086 : } bits;
1087 : };
1088 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_feat_fdp_events_cdw12) == 4, "Incorrect size");
1089 :
1090 : union spdk_nvme_cmd_cdw10 {
1091 : uint32_t raw;
1092 : struct {
1093 : /* Controller or Namespace Structure */
1094 : uint32_t cns : 8;
1095 : uint32_t reserved : 8;
1096 : /* Controller Identifier */
1097 : uint32_t cntid : 16;
1098 : } identify;
1099 :
1100 : struct {
1101 : /* Log Page Identifier */
1102 : uint32_t lid : 8;
1103 : /* Log Specific Field */
1104 : uint32_t lsp : 7;
1105 : /* Retain Asynchronous Event */
1106 : uint32_t rae : 1;
1107 : /* Number of Dwords Lower */
1108 : uint32_t numdl : 16;
1109 : } get_log_page;
1110 :
1111 : struct {
1112 : /* Submission Queue Identifier */
1113 : uint32_t sqid : 16;
1114 : /* Command Identifier */
1115 : uint32_t cid : 16;
1116 : } abort;
1117 :
1118 : struct {
1119 : /* NVMe Security Specific Field */
1120 : uint32_t nssf : 8;
1121 : /* SP Specific 0 */
1122 : uint32_t spsp0 : 8;
1123 : /* SP Specific 1 */
1124 : uint32_t spsp1 : 8;
1125 : /* Security Protocol */
1126 : uint32_t secp : 8;
1127 : } sec_send_recv;
1128 :
1129 : struct {
1130 : /* Queue Identifier */
1131 : uint32_t qid : 16;
1132 : /* Queue Size */
1133 : uint32_t qsize : 16;
1134 : } create_io_q;
1135 :
1136 : struct {
1137 : /* Queue Identifier */
1138 : uint32_t qid : 16;
1139 : uint32_t reserved : 16;
1140 : } delete_io_q;
1141 :
1142 : struct {
1143 : /* Feature Identifier */
1144 : uint32_t fid : 8;
1145 : /* Select */
1146 : uint32_t sel : 3;
1147 : uint32_t reserved : 21;
1148 : } get_features;
1149 :
1150 : struct {
1151 : /* Feature Identifier */
1152 : uint32_t fid : 8;
1153 : uint32_t reserved : 23;
1154 : /* Save */
1155 : uint32_t sv : 1;
1156 : } set_features;
1157 :
1158 : struct {
1159 : /* Select */
1160 : uint32_t sel : 4;
1161 : uint32_t reserved : 28;
1162 : } ns_attach;
1163 :
1164 : struct {
1165 : /* Select */
1166 : uint32_t sel : 4;
1167 : uint32_t reserved : 28;
1168 : } ns_manage;
1169 :
1170 : struct {
1171 : /* Number of Ranges */
1172 : uint32_t nr : 8;
1173 : uint32_t reserved : 24;
1174 : } dsm;
1175 :
1176 : struct {
1177 : /* Reservation Register Action */
1178 : uint32_t rrega : 3;
1179 : /* Ignore Existing Key */
1180 : uint32_t iekey : 1;
1181 : uint32_t reserved : 26;
1182 : /* Change Persist Through Power Loss State */
1183 : uint32_t cptpl : 2;
1184 : } resv_register;
1185 :
1186 : struct {
1187 : /* Reservation Release Action */
1188 : uint32_t rrela : 3;
1189 : /* Ignore Existing Key */
1190 : uint32_t iekey : 1;
1191 : uint32_t reserved1 : 4;
1192 : /* Reservation Type */
1193 : uint32_t rtype : 8;
1194 : uint32_t reserved2 : 16;
1195 : } resv_release;
1196 :
1197 : struct {
1198 : /* Reservation Acquire Action */
1199 : uint32_t racqa : 3;
1200 : /* Ignore Existing Key */
1201 : uint32_t iekey : 1;
1202 : uint32_t reserved1 : 4;
1203 : /* Reservation Type */
1204 : uint32_t rtype : 8;
1205 : uint32_t reserved2 : 16;
1206 : } resv_acquire;
1207 :
1208 : struct {
1209 : /* Management Operation */
1210 : uint32_t mo : 8;
1211 : uint32_t reserved : 8;
1212 : /* Management Operation Specific */
1213 : uint32_t mos : 16;
1214 : } mgmt_send_recv;
1215 : };
1216 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmd_cdw10) == 4, "Incorrect size");
1217 :
1218 : union spdk_nvme_cmd_cdw11 {
1219 : uint32_t raw;
1220 :
1221 : struct {
1222 : /* NVM Set Identifier */
1223 : uint32_t nvmsetid : 16;
1224 : uint32_t reserved : 8;
1225 : /* Command Set Identifier */
1226 : uint32_t csi : 8;
1227 : } identify;
1228 :
1229 : struct {
1230 : /* Physically Contiguous */
1231 : uint32_t pc : 1;
1232 : /* Queue Priority */
1233 : uint32_t qprio : 2;
1234 : uint32_t reserved : 13;
1235 : /* Completion Queue Identifier */
1236 : uint32_t cqid : 16;
1237 : } create_io_sq;
1238 :
1239 : struct {
1240 : /* Physically Contiguous */
1241 : uint32_t pc : 1;
1242 : /* Interrupts Enabled */
1243 : uint32_t ien : 1;
1244 : uint32_t reserved : 14;
1245 : /* Interrupt Vector */
1246 : uint32_t iv : 16;
1247 : } create_io_cq;
1248 :
1249 : struct {
1250 : /* Directive Operation */
1251 : uint32_t doper : 8;
1252 : /* Directive Type */
1253 : uint32_t dtype : 8;
1254 : /* Directive Specific */
1255 : uint32_t dspec : 16;
1256 : } directive;
1257 :
1258 : struct {
1259 : /* Number of Dwords */
1260 : uint32_t numdu : 16;
1261 : /* Log Specific Identifier */
1262 : uint32_t lsid : 16;
1263 : } get_log_page;
1264 :
1265 : struct {
1266 : /* Extended Data Structure */
1267 : uint32_t eds : 1;
1268 : uint32_t reserved : 31;
1269 : } resv_report;
1270 :
1271 : union spdk_nvme_feat_arbitration feat_arbitration;
1272 : union spdk_nvme_feat_power_management feat_power_management;
1273 : union spdk_nvme_feat_lba_range_type feat_lba_range_type;
1274 : union spdk_nvme_feat_temperature_threshold feat_temp_threshold;
1275 : union spdk_nvme_feat_error_recovery feat_error_recovery;
1276 : union spdk_nvme_feat_volatile_write_cache feat_volatile_write_cache;
1277 : union spdk_nvme_feat_number_of_queues feat_num_of_queues;
1278 : union spdk_nvme_feat_interrupt_coalescing feat_interrupt_coalescing;
1279 : union spdk_nvme_feat_interrupt_vector_configuration feat_interrupt_vector_configuration;
1280 : union spdk_nvme_feat_write_atomicity feat_write_atomicity;
1281 : union spdk_nvme_feat_async_event_configuration feat_async_event_cfg;
1282 : union spdk_nvme_feat_keep_alive_timer feat_keep_alive_timer;
1283 : union spdk_nvme_feat_host_identifier feat_host_identifier;
1284 : union spdk_nvme_feat_reservation_notification_mask feat_rsv_notification_mask;
1285 : union spdk_nvme_feat_reservation_persistence feat_rsv_persistence;
1286 : union spdk_nvme_feat_fdp_cdw11 feat_fdp_cdw11;
1287 : union spdk_nvme_feat_fdp_events_cdw11 feat_fdp_events_cdw11;
1288 :
1289 : struct {
1290 : /* Attribute – Integral Dataset for Read */
1291 : uint32_t idr : 1;
1292 : /* Attribute – Integral Dataset for Write */
1293 : uint32_t idw : 1;
1294 : /* Attribute – Deallocate */
1295 : uint32_t ad : 1;
1296 : uint32_t reserved : 29;
1297 : } dsm;
1298 : };
1299 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmd_cdw11) == 4, "Incorrect size");
1300 :
1301 : union spdk_nvme_cmd_cdw12 {
1302 : uint32_t raw;
1303 :
1304 : struct {
1305 : /* Number of Ranges */
1306 : uint32_t nr : 8;
1307 : /* Desciptor Format */
1308 : uint32_t df : 4;
1309 : /* Protection Information Field Read */
1310 : uint32_t prinfor : 4;
1311 : uint32_t reserved : 4;
1312 : /* Directive Type */
1313 : uint32_t dtype : 4;
1314 : /* Storage Tag Check Write */
1315 : uint32_t stcw : 1;
1316 : uint32_t reserved2 : 1;
1317 : /* Protection Information Field Write */
1318 : uint32_t prinfow : 4;
1319 : /* Force Unit Access */
1320 : uint32_t fua : 1;
1321 : /* Limited Retry */
1322 : uint32_t lr : 1;
1323 : } copy;
1324 :
1325 : union spdk_nvme_feat_fdp_cdw12 feat_fdp_cdw12;
1326 : union spdk_nvme_feat_fdp_events_cdw12 feat_fdp_events_cdw12;
1327 : };
1328 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmd_cdw12) == 4, "Incorrect size");
1329 :
1330 : struct spdk_nvme_cmd {
1331 : /* dword 0 */
1332 : uint16_t opc : 8; /* opcode */
1333 : uint16_t fuse : 2; /* fused operation */
1334 : uint16_t rsvd1 : 4;
1335 : uint16_t psdt : 2;
1336 : uint16_t cid; /* command identifier */
1337 :
1338 : /* dword 1 */
1339 : uint32_t nsid; /* namespace identifier */
1340 :
1341 : /* dword 2-3 */
1342 : uint32_t rsvd2;
1343 : uint32_t rsvd3;
1344 :
1345 : /* dword 4-5 */
1346 : uint64_t mptr; /* metadata pointer */
1347 :
1348 : /* dword 6-9: data pointer */
1349 : union {
1350 : struct {
1351 : uint64_t prp1; /* prp entry 1 */
1352 : uint64_t prp2; /* prp entry 2 */
1353 : } prp;
1354 :
1355 : struct spdk_nvme_sgl_descriptor sgl1;
1356 : } dptr;
1357 :
1358 : /* command-specific */
1359 : union {
1360 : uint32_t cdw10;
1361 : union spdk_nvme_cmd_cdw10 cdw10_bits;
1362 : };
1363 : /* command-specific */
1364 : union {
1365 : uint32_t cdw11;
1366 : union spdk_nvme_cmd_cdw11 cdw11_bits;
1367 : };
1368 : /* command-specific */
1369 : union {
1370 : uint32_t cdw12;
1371 : union spdk_nvme_cmd_cdw12 cdw12_bits;
1372 : };
1373 : /* dword 13-15 */
1374 : uint32_t cdw13; /* command-specific */
1375 : uint32_t cdw14; /* command-specific */
1376 : uint32_t cdw15; /* command-specific */
1377 : };
1378 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_cmd) == 64, "Incorrect size");
1379 :
1380 : struct spdk_nvme_status {
1381 : uint16_t p : 1; /* phase tag */
1382 : uint16_t sc : 8; /* status code */
1383 : uint16_t sct : 3; /* status code type */
1384 : uint16_t crd : 2; /* command retry delay */
1385 : uint16_t m : 1; /* more */
1386 : uint16_t dnr : 1; /* do not retry */
1387 : };
1388 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_status) == 2, "Incorrect size");
1389 :
1390 : /**
1391 : * Completion queue entry
1392 : */
1393 : struct spdk_nvme_cpl {
1394 : /* dword 0 */
1395 : uint32_t cdw0; /* command-specific */
1396 :
1397 : /* dword 1 */
1398 : uint32_t cdw1; /* command-specific */
1399 :
1400 : /* dword 2 */
1401 : uint16_t sqhd; /* submission queue head pointer */
1402 : uint16_t sqid; /* submission queue identifier */
1403 :
1404 : /* dword 3 */
1405 : uint16_t cid; /* command identifier */
1406 : union {
1407 : uint16_t status_raw;
1408 : struct spdk_nvme_status status;
1409 : };
1410 : };
1411 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_cpl) == 16, "Incorrect size");
1412 :
1413 : /**
1414 : * Dataset Management range
1415 : */
1416 : struct spdk_nvme_dsm_range {
1417 : union {
1418 : struct {
1419 : uint32_t af : 4; /**< access frequency */
1420 : uint32_t al : 2; /**< access latency */
1421 : uint32_t reserved0 : 2;
1422 :
1423 : uint32_t sr : 1; /**< sequential read range */
1424 : uint32_t sw : 1; /**< sequential write range */
1425 : uint32_t wp : 1; /**< write prepare */
1426 : uint32_t reserved1 : 13;
1427 :
1428 : uint32_t access_size : 8; /**< command access size */
1429 : } bits;
1430 :
1431 : uint32_t raw;
1432 : } attributes;
1433 :
1434 : uint32_t length;
1435 : uint64_t starting_lba;
1436 : };
1437 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_dsm_range) == 16, "Incorrect size");
1438 :
1439 : /**
1440 : * Simple Copy Command source range
1441 : */
1442 : struct spdk_nvme_scc_source_range {
1443 : uint64_t reserved0;
1444 : uint64_t slba;
1445 : uint16_t nlb;
1446 : uint16_t reserved18;
1447 : uint32_t reserved20;
1448 : uint32_t eilbrt;
1449 : uint16_t elbat;
1450 : uint16_t elbatm;
1451 : };
1452 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_scc_source_range) == 32, "Incorrect size");
1453 :
1454 : /**
1455 : * Status code types
1456 : */
1457 : enum spdk_nvme_status_code_type {
1458 : SPDK_NVME_SCT_GENERIC = 0x0,
1459 : SPDK_NVME_SCT_COMMAND_SPECIFIC = 0x1,
1460 : SPDK_NVME_SCT_MEDIA_ERROR = 0x2,
1461 : SPDK_NVME_SCT_PATH = 0x3,
1462 : /* 0x4-0x6 - reserved */
1463 : SPDK_NVME_SCT_VENDOR_SPECIFIC = 0x7,
1464 : };
1465 :
1466 : /**
1467 : * Generic command status codes
1468 : */
1469 : enum spdk_nvme_generic_command_status_code {
1470 : SPDK_NVME_SC_SUCCESS = 0x00,
1471 : SPDK_NVME_SC_INVALID_OPCODE = 0x01,
1472 : SPDK_NVME_SC_INVALID_FIELD = 0x02,
1473 : SPDK_NVME_SC_COMMAND_ID_CONFLICT = 0x03,
1474 : SPDK_NVME_SC_DATA_TRANSFER_ERROR = 0x04,
1475 : SPDK_NVME_SC_ABORTED_POWER_LOSS = 0x05,
1476 : SPDK_NVME_SC_INTERNAL_DEVICE_ERROR = 0x06,
1477 : SPDK_NVME_SC_ABORTED_BY_REQUEST = 0x07,
1478 : SPDK_NVME_SC_ABORTED_SQ_DELETION = 0x08,
1479 : SPDK_NVME_SC_ABORTED_FAILED_FUSED = 0x09,
1480 : SPDK_NVME_SC_ABORTED_MISSING_FUSED = 0x0a,
1481 : SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT = 0x0b,
1482 : SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR = 0x0c,
1483 : SPDK_NVME_SC_INVALID_SGL_SEG_DESCRIPTOR = 0x0d,
1484 : SPDK_NVME_SC_INVALID_NUM_SGL_DESCIRPTORS = 0x0e,
1485 : SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID = 0x0f,
1486 : SPDK_NVME_SC_METADATA_SGL_LENGTH_INVALID = 0x10,
1487 : SPDK_NVME_SC_SGL_DESCRIPTOR_TYPE_INVALID = 0x11,
1488 : SPDK_NVME_SC_INVALID_CONTROLLER_MEM_BUF = 0x12,
1489 : SPDK_NVME_SC_INVALID_PRP_OFFSET = 0x13,
1490 : SPDK_NVME_SC_ATOMIC_WRITE_UNIT_EXCEEDED = 0x14,
1491 : SPDK_NVME_SC_OPERATION_DENIED = 0x15,
1492 : SPDK_NVME_SC_INVALID_SGL_OFFSET = 0x16,
1493 : /* 0x17 - reserved */
1494 : SPDK_NVME_SC_HOSTID_INCONSISTENT_FORMAT = 0x18,
1495 : SPDK_NVME_SC_KEEP_ALIVE_EXPIRED = 0x19,
1496 : SPDK_NVME_SC_KEEP_ALIVE_INVALID = 0x1a,
1497 : SPDK_NVME_SC_ABORTED_PREEMPT = 0x1b,
1498 : SPDK_NVME_SC_SANITIZE_FAILED = 0x1c,
1499 : SPDK_NVME_SC_SANITIZE_IN_PROGRESS = 0x1d,
1500 : SPDK_NVME_SC_SGL_DATA_BLOCK_GRANULARITY_INVALID = 0x1e,
1501 : SPDK_NVME_SC_COMMAND_INVALID_IN_CMB = 0x1f,
1502 : SPDK_NVME_SC_COMMAND_NAMESPACE_IS_PROTECTED = 0x20,
1503 : SPDK_NVME_SC_COMMAND_INTERRUPTED = 0x21,
1504 : SPDK_NVME_SC_COMMAND_TRANSIENT_TRANSPORT_ERROR = 0x22,
1505 : SPDK_NVME_SC_COMMAND_PROHIBITED_BY_LOCKDOWN = 0x23,
1506 : SPDK_NVME_SC_ADMIN_COMMAND_MEDIA_NOT_READY = 0x24,
1507 :
1508 : SPDK_NVME_SC_FDP_DISABLED = 0x29,
1509 : SPDK_NVME_SC_INVALID_PLACEMENT_HANDLE_LIST = 0x2A,
1510 :
1511 : SPDK_NVME_SC_LBA_OUT_OF_RANGE = 0x80,
1512 : SPDK_NVME_SC_CAPACITY_EXCEEDED = 0x81,
1513 : SPDK_NVME_SC_NAMESPACE_NOT_READY = 0x82,
1514 : SPDK_NVME_SC_RESERVATION_CONFLICT = 0x83,
1515 : SPDK_NVME_SC_FORMAT_IN_PROGRESS = 0x84,
1516 : SPDK_NVME_SC_INVALID_VALUE_SIZE = 0x85,
1517 : SPDK_NVME_SC_INVALID_KEY_SIZE = 0x86,
1518 : SPDK_NVME_SC_KV_KEY_DOES_NOT_EXIST = 0x87,
1519 : SPDK_NVME_SC_UNRECOVERED_ERROR = 0x88,
1520 : SPDK_NVME_SC_KEY_EXISTS = 0x89,
1521 : };
1522 :
1523 : /**
1524 : * Command specific status codes
1525 : */
1526 : enum spdk_nvme_command_specific_status_code {
1527 : SPDK_NVME_SC_COMPLETION_QUEUE_INVALID = 0x00,
1528 : SPDK_NVME_SC_INVALID_QUEUE_IDENTIFIER = 0x01,
1529 : SPDK_NVME_SC_INVALID_QUEUE_SIZE = 0x02,
1530 : SPDK_NVME_SC_ABORT_COMMAND_LIMIT_EXCEEDED = 0x03,
1531 : /* 0x04 - reserved */
1532 : SPDK_NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED = 0x05,
1533 : SPDK_NVME_SC_INVALID_FIRMWARE_SLOT = 0x06,
1534 : SPDK_NVME_SC_INVALID_FIRMWARE_IMAGE = 0x07,
1535 : SPDK_NVME_SC_INVALID_INTERRUPT_VECTOR = 0x08,
1536 : SPDK_NVME_SC_INVALID_LOG_PAGE = 0x09,
1537 : SPDK_NVME_SC_INVALID_FORMAT = 0x0a,
1538 : SPDK_NVME_SC_FIRMWARE_REQ_CONVENTIONAL_RESET = 0x0b,
1539 : SPDK_NVME_SC_INVALID_QUEUE_DELETION = 0x0c,
1540 : SPDK_NVME_SC_FEATURE_ID_NOT_SAVEABLE = 0x0d,
1541 : SPDK_NVME_SC_FEATURE_NOT_CHANGEABLE = 0x0e,
1542 : SPDK_NVME_SC_FEATURE_NOT_NAMESPACE_SPECIFIC = 0x0f,
1543 : SPDK_NVME_SC_FIRMWARE_REQ_NVM_RESET = 0x10,
1544 : SPDK_NVME_SC_FIRMWARE_REQ_RESET = 0x11,
1545 : SPDK_NVME_SC_FIRMWARE_REQ_MAX_TIME_VIOLATION = 0x12,
1546 : SPDK_NVME_SC_FIRMWARE_ACTIVATION_PROHIBITED = 0x13,
1547 : SPDK_NVME_SC_OVERLAPPING_RANGE = 0x14,
1548 : SPDK_NVME_SC_NAMESPACE_INSUFFICIENT_CAPACITY = 0x15,
1549 : SPDK_NVME_SC_NAMESPACE_ID_UNAVAILABLE = 0x16,
1550 : /* 0x17 - reserved */
1551 : SPDK_NVME_SC_NAMESPACE_ALREADY_ATTACHED = 0x18,
1552 : SPDK_NVME_SC_NAMESPACE_IS_PRIVATE = 0x19,
1553 : SPDK_NVME_SC_NAMESPACE_NOT_ATTACHED = 0x1a,
1554 : SPDK_NVME_SC_THINPROVISIONING_NOT_SUPPORTED = 0x1b,
1555 : SPDK_NVME_SC_CONTROLLER_LIST_INVALID = 0x1c,
1556 : SPDK_NVME_SC_DEVICE_SELF_TEST_IN_PROGRESS = 0x1d,
1557 : SPDK_NVME_SC_BOOT_PARTITION_WRITE_PROHIBITED = 0x1e,
1558 : SPDK_NVME_SC_INVALID_CTRLR_ID = 0x1f,
1559 : SPDK_NVME_SC_INVALID_SECONDARY_CTRLR_STATE = 0x20,
1560 : SPDK_NVME_SC_INVALID_NUM_CTRLR_RESOURCES = 0x21,
1561 : SPDK_NVME_SC_INVALID_RESOURCE_ID = 0x22,
1562 : SPDK_NVME_SC_SANITIZE_PROHIBITED = 0x23,
1563 : SPDK_NVME_SC_ANA_GROUP_IDENTIFIER_INVALID = 0x24,
1564 : SPDK_NVME_SC_ANA_ATTACH_FAILED = 0x25,
1565 : SPDK_NVME_SC_INSUFFICIENT_CAPACITY = 0x26,
1566 : SPDK_NVME_SC_NAMESPACE_ATTACH_LIMIT_EXCEEDED = 0x27,
1567 : SPDK_NVME_SC_PROHIBIT_CMD_EXEC_NOT_SUPPORTED = 0x28,
1568 : SPDK_NVME_SC_IOCS_NOT_SUPPORTED = 0x29,
1569 : SPDK_NVME_SC_IOCS_NOT_ENABLED = 0x2a,
1570 : SPDK_NVME_SC_IOCS_COMBINATION_REJECTED = 0x2b,
1571 : SPDK_NVME_SC_INVALID_IOCS = 0x2c,
1572 : SPDK_NVME_SC_IDENTIFIER_UNAVAILABLE = 0x2d,
1573 :
1574 : SPDK_NVME_SC_STREAM_RESOURCE_ALLOCATION_FAILED = 0x7f,
1575 : SPDK_NVME_SC_CONFLICTING_ATTRIBUTES = 0x80,
1576 : SPDK_NVME_SC_INVALID_PROTECTION_INFO = 0x81,
1577 : SPDK_NVME_SC_ATTEMPTED_WRITE_TO_RO_RANGE = 0x82,
1578 : SPDK_NVME_SC_CMD_SIZE_LIMIT_SIZE_EXCEEDED = 0x83,
1579 :
1580 : SPDK_NVME_SC_ZONED_BOUNDARY_ERROR = 0xb8,
1581 : SPDK_NVME_SC_ZONE_IS_FULL = 0xb9,
1582 : SPDK_NVME_SC_ZONE_IS_READ_ONLY = 0xba,
1583 : SPDK_NVME_SC_ZONE_IS_OFFLINE = 0xbb,
1584 : SPDK_NVME_SC_ZONE_INVALID_WRITE = 0xbc,
1585 : SPDK_NVME_SC_TOO_MANY_ACTIVE_ZONES = 0xbd,
1586 : SPDK_NVME_SC_TOO_MANY_OPEN_ZONES = 0xbe,
1587 : SPDK_NVME_SC_INVALID_ZONE_STATE_TRANSITION = 0xbf,
1588 : };
1589 :
1590 : /**
1591 : * Media error status codes
1592 : */
1593 : enum spdk_nvme_media_error_status_code {
1594 : SPDK_NVME_SC_WRITE_FAULTS = 0x80,
1595 : SPDK_NVME_SC_UNRECOVERED_READ_ERROR = 0x81,
1596 : SPDK_NVME_SC_GUARD_CHECK_ERROR = 0x82,
1597 : SPDK_NVME_SC_APPLICATION_TAG_CHECK_ERROR = 0x83,
1598 : SPDK_NVME_SC_REFERENCE_TAG_CHECK_ERROR = 0x84,
1599 : SPDK_NVME_SC_COMPARE_FAILURE = 0x85,
1600 : SPDK_NVME_SC_ACCESS_DENIED = 0x86,
1601 : SPDK_NVME_SC_DEALLOCATED_OR_UNWRITTEN_BLOCK = 0x87,
1602 : SPDK_NVME_SC_END_TO_END_STORAGE_TAG_CHECK_ERROR = 0x88,
1603 : };
1604 :
1605 : /**
1606 : * Path related status codes
1607 : */
1608 : enum spdk_nvme_path_status_code {
1609 : SPDK_NVME_SC_INTERNAL_PATH_ERROR = 0x00,
1610 : SPDK_NVME_SC_ASYMMETRIC_ACCESS_PERSISTENT_LOSS = 0x01,
1611 : SPDK_NVME_SC_ASYMMETRIC_ACCESS_INACCESSIBLE = 0x02,
1612 : SPDK_NVME_SC_ASYMMETRIC_ACCESS_TRANSITION = 0x03,
1613 :
1614 : SPDK_NVME_SC_CONTROLLER_PATH_ERROR = 0x60,
1615 :
1616 : SPDK_NVME_SC_HOST_PATH_ERROR = 0x70,
1617 : SPDK_NVME_SC_ABORTED_BY_HOST = 0x71,
1618 : };
1619 :
1620 : #define SPDK_NVME_MAX_OPC 0xff
1621 :
1622 : /**
1623 : * Admin opcodes
1624 : */
1625 : enum spdk_nvme_admin_opcode {
1626 : SPDK_NVME_OPC_DELETE_IO_SQ = 0x00,
1627 : SPDK_NVME_OPC_CREATE_IO_SQ = 0x01,
1628 : SPDK_NVME_OPC_GET_LOG_PAGE = 0x02,
1629 : /* 0x03 - reserved */
1630 : SPDK_NVME_OPC_DELETE_IO_CQ = 0x04,
1631 : SPDK_NVME_OPC_CREATE_IO_CQ = 0x05,
1632 : SPDK_NVME_OPC_IDENTIFY = 0x06,
1633 : /* 0x07 - reserved */
1634 : SPDK_NVME_OPC_ABORT = 0x08,
1635 : SPDK_NVME_OPC_SET_FEATURES = 0x09,
1636 : SPDK_NVME_OPC_GET_FEATURES = 0x0a,
1637 : /* 0x0b - reserved */
1638 : SPDK_NVME_OPC_ASYNC_EVENT_REQUEST = 0x0c,
1639 : SPDK_NVME_OPC_NS_MANAGEMENT = 0x0d,
1640 : /* 0x0e-0x0f - reserved */
1641 : SPDK_NVME_OPC_FIRMWARE_COMMIT = 0x10,
1642 : SPDK_NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD = 0x11,
1643 :
1644 : SPDK_NVME_OPC_DEVICE_SELF_TEST = 0x14,
1645 : SPDK_NVME_OPC_NS_ATTACHMENT = 0x15,
1646 :
1647 : SPDK_NVME_OPC_KEEP_ALIVE = 0x18,
1648 : SPDK_NVME_OPC_DIRECTIVE_SEND = 0x19,
1649 : SPDK_NVME_OPC_DIRECTIVE_RECEIVE = 0x1a,
1650 :
1651 : SPDK_NVME_OPC_VIRTUALIZATION_MANAGEMENT = 0x1c,
1652 : SPDK_NVME_OPC_NVME_MI_SEND = 0x1d,
1653 : SPDK_NVME_OPC_NVME_MI_RECEIVE = 0x1e,
1654 :
1655 : SPDK_NVME_OPC_DOORBELL_BUFFER_CONFIG = 0x7c,
1656 :
1657 : SPDK_NVME_OPC_FORMAT_NVM = 0x80,
1658 : SPDK_NVME_OPC_SECURITY_SEND = 0x81,
1659 : SPDK_NVME_OPC_SECURITY_RECEIVE = 0x82,
1660 :
1661 : SPDK_NVME_OPC_SANITIZE = 0x84,
1662 :
1663 : SPDK_NVME_OPC_GET_LBA_STATUS = 0x86,
1664 : };
1665 :
1666 : /**
1667 : * NVM command set opcodes
1668 : */
1669 : enum spdk_nvme_nvm_opcode {
1670 : SPDK_NVME_OPC_FLUSH = 0x00,
1671 : SPDK_NVME_OPC_WRITE = 0x01,
1672 : SPDK_NVME_OPC_READ = 0x02,
1673 : /* 0x03 - reserved */
1674 : SPDK_NVME_OPC_WRITE_UNCORRECTABLE = 0x04,
1675 : SPDK_NVME_OPC_COMPARE = 0x05,
1676 : /* 0x06-0x07 - reserved */
1677 : SPDK_NVME_OPC_WRITE_ZEROES = 0x08,
1678 : SPDK_NVME_OPC_DATASET_MANAGEMENT = 0x09,
1679 :
1680 : SPDK_NVME_OPC_VERIFY = 0x0c,
1681 : SPDK_NVME_OPC_RESERVATION_REGISTER = 0x0d,
1682 : SPDK_NVME_OPC_RESERVATION_REPORT = 0x0e,
1683 :
1684 : SPDK_NVME_OPC_RESERVATION_ACQUIRE = 0x11,
1685 : SPDK_NVME_OPC_IO_MANAGEMENT_RECEIVE = 0x12,
1686 : SPDK_NVME_OPC_RESERVATION_RELEASE = 0x15,
1687 :
1688 : SPDK_NVME_OPC_COPY = 0x19,
1689 : SPDK_NVME_OPC_IO_MANAGEMENT_SEND = 0x1D,
1690 : };
1691 :
1692 : /**
1693 : * Zoned Namespace command set opcodes
1694 : *
1695 : * In addition to the opcodes of the NVM command set, the Zoned Namespace
1696 : * command set supports the following opcodes.
1697 : */
1698 : enum spdk_nvme_zns_opcode {
1699 : SPDK_NVME_OPC_ZONE_MGMT_SEND = 0x79,
1700 : SPDK_NVME_OPC_ZONE_MGMT_RECV = 0x7a,
1701 : SPDK_NVME_OPC_ZONE_APPEND = 0x7d,
1702 : };
1703 :
1704 : /**
1705 : * Data transfer (bits 1:0) of an NVMe opcode.
1706 : *
1707 : * \sa spdk_nvme_opc_get_data_transfer
1708 : */
1709 : enum spdk_nvme_data_transfer {
1710 : /** Opcode does not transfer data */
1711 : SPDK_NVME_DATA_NONE = 0,
1712 : /** Opcode transfers data from host to controller (e.g. Write) */
1713 : SPDK_NVME_DATA_HOST_TO_CONTROLLER = 1,
1714 : /** Opcode transfers data from controller to host (e.g. Read) */
1715 : SPDK_NVME_DATA_CONTROLLER_TO_HOST = 2,
1716 : /** Opcode transfers data both directions */
1717 : SPDK_NVME_DATA_BIDIRECTIONAL = 3
1718 : };
1719 :
1720 : /**
1721 : * Extract the Data Transfer bits from an NVMe opcode.
1722 : *
1723 : * This determines whether a command requires a data buffer and
1724 : * which direction (host to controller or controller to host) it is
1725 : * transferred.
1726 : */
1727 40 : static inline enum spdk_nvme_data_transfer spdk_nvme_opc_get_data_transfer(uint8_t opc)
1728 : {
1729 40 : return (enum spdk_nvme_data_transfer)(opc & 3);
1730 : }
1731 :
1732 : static inline uint32_t
1733 16 : spdk_nvme_bytes_to_numd(uint32_t len)
1734 : {
1735 16 : return (len >> 2) - 1;
1736 : }
1737 :
1738 : #pragma pack(push, 1)
1739 : struct spdk_nvme_host_behavior {
1740 : uint8_t acre;
1741 : uint8_t reserved[511];
1742 : };
1743 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_host_behavior) == 512, "Incorrect size");
1744 : #pragma pack(pop)
1745 :
1746 : /**
1747 : * Supported FDP event descriptor
1748 : */
1749 : struct spdk_nvme_fdp_event_desc {
1750 : /* FDP Event type */
1751 : uint8_t fdp_etype;
1752 :
1753 : /* FDP event type attributes */
1754 : union {
1755 : uint8_t raw;
1756 : struct {
1757 : /* FDP event enabled */
1758 : uint8_t fdp_ee : 1;
1759 : uint8_t reserved : 7;
1760 : } bits;
1761 : } fdpeta;
1762 : };
1763 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_event_desc) == 2, "Incorrect size");
1764 :
1765 : /**
1766 : * Reclaim unit handle status descriptor
1767 : */
1768 : struct spdk_nvme_fdp_ruhs_desc {
1769 : /* Placement Identifier */
1770 : uint16_t pid;
1771 :
1772 : /* Reclaim Unit Handle Identifier */
1773 : uint16_t ruhid;
1774 :
1775 : /* Estimated Active Reclaim Unit Time Remaining */
1776 : uint32_t earutr;
1777 :
1778 : /* Reclaim Unit Available Media Writes */
1779 : uint64_t ruamw;
1780 :
1781 : uint8_t reserved[16];
1782 : };
1783 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_ruhs_desc) == 32, "Incorrect size");
1784 :
1785 : /**
1786 : * Reclaim unit handle status
1787 : */
1788 : struct spdk_nvme_fdp_ruhs {
1789 : uint8_t reserved[14];
1790 :
1791 : /* Number of Reclaim Unit Handle Status Descriptors */
1792 : uint16_t nruhsd;
1793 :
1794 : struct spdk_nvme_fdp_ruhs_desc ruhs_desc[];
1795 : };
1796 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_ruhs) == 16, "Incorrect size");
1797 :
1798 : /**
1799 : * Management operation to perform for IO management receive
1800 : */
1801 : enum spdk_nvme_fdp_mgmt_recv_mo {
1802 : SPDK_NVME_FDP_IO_MGMT_RECV_NA = 0x00,
1803 : SPDK_NVME_FDP_IO_MGMT_RECV_RUHS = 0x01,
1804 : /* 0x02-0xFE - reserved */
1805 : SPDK_NVME_FDP_IO_MGMT_RECV_VS = 0xFF,
1806 : };
1807 :
1808 : /**
1809 : * Management operation to perform for IO management send
1810 : */
1811 : enum spdk_nvme_fdp_mgmt_send_mo {
1812 : SPDK_NVME_FDP_IO_MGMT_SEND_NA = 0x00,
1813 : SPDK_NVME_FDP_IO_MGMT_SEND_RUHU = 0x01,
1814 : /* 0x02-0xFE - reserved */
1815 : SPDK_NVME_FDP_IO_MGMT_SEND_VS = 0xFF,
1816 : };
1817 :
1818 : enum spdk_nvme_feat {
1819 : /* 0x00 - reserved */
1820 :
1821 : /** cdw11 layout defined by \ref spdk_nvme_feat_arbitration */
1822 : SPDK_NVME_FEAT_ARBITRATION = 0x01,
1823 : /** cdw11 layout defined by \ref spdk_nvme_feat_power_management */
1824 : SPDK_NVME_FEAT_POWER_MANAGEMENT = 0x02,
1825 : /** cdw11 layout defined by \ref spdk_nvme_feat_lba_range_type */
1826 : SPDK_NVME_FEAT_LBA_RANGE_TYPE = 0x03,
1827 : /** cdw11 layout defined by \ref spdk_nvme_feat_temperature_threshold */
1828 : SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD = 0x04,
1829 : /** cdw11 layout defined by \ref spdk_nvme_feat_error_recovery */
1830 : SPDK_NVME_FEAT_ERROR_RECOVERY = 0x05,
1831 : /** cdw11 layout defined by \ref spdk_nvme_feat_volatile_write_cache */
1832 : SPDK_NVME_FEAT_VOLATILE_WRITE_CACHE = 0x06,
1833 : /** cdw11 layout defined by \ref spdk_nvme_feat_number_of_queues */
1834 : SPDK_NVME_FEAT_NUMBER_OF_QUEUES = 0x07,
1835 : /** cdw11 layout defined by \ref spdk_nvme_feat_interrupt_coalescing */
1836 : SPDK_NVME_FEAT_INTERRUPT_COALESCING = 0x08,
1837 : /** cdw11 layout defined by \ref spdk_nvme_feat_interrupt_vector_configuration */
1838 : SPDK_NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION = 0x09,
1839 : /** cdw11 layout defined by \ref spdk_nvme_feat_write_atomicity */
1840 : SPDK_NVME_FEAT_WRITE_ATOMICITY = 0x0A,
1841 : /** cdw11 layout defined by \ref spdk_nvme_feat_async_event_configuration */
1842 : SPDK_NVME_FEAT_ASYNC_EVENT_CONFIGURATION = 0x0B,
1843 : /** cdw11 layout defined by \ref spdk_nvme_feat_autonomous_power_state_transition */
1844 : SPDK_NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION = 0x0C,
1845 : /** cdw11 layout defined by \ref spdk_nvme_feat_host_mem_buffer */
1846 : SPDK_NVME_FEAT_HOST_MEM_BUFFER = 0x0D,
1847 : SPDK_NVME_FEAT_TIMESTAMP = 0x0E,
1848 : /** cdw11 layout defined by \ref spdk_nvme_feat_keep_alive_timer */
1849 : SPDK_NVME_FEAT_KEEP_ALIVE_TIMER = 0x0F,
1850 : /** cdw11 layout defined by \ref spdk_nvme_feat_host_controlled_thermal_management */
1851 : SPDK_NVME_FEAT_HOST_CONTROLLED_THERMAL_MANAGEMENT = 0x10,
1852 : /** cdw11 layout defined by \ref spdk_nvme_feat_non_operational_power_state_config */
1853 : SPDK_NVME_FEAT_NON_OPERATIONAL_POWER_STATE_CONFIG = 0x11,
1854 :
1855 : SPDK_NVME_FEAT_READ_RECOVERY_LEVEL_CONFIG = 0x12,
1856 : SPDK_NVME_FEAT_PREDICTABLE_LATENCY_MODE_CONFIG = 0x13,
1857 : SPDK_NVME_FEAT_PREDICTABLE_LATENCY_MODE_WINDOW = 0x14,
1858 : SPDK_NVME_FEAT_LBA_STATUS_INFORMATION_ATTRIBUTES = 0x15,
1859 : /** data buffer layout defined by \ref spdk_nvme_host_behavior */
1860 : SPDK_NVME_FEAT_HOST_BEHAVIOR_SUPPORT = 0x16,
1861 : SPDK_NVME_FEAT_SANITIZE_CONFIG = 0x17,
1862 : SPDK_NVME_FEAT_ENDURANCE_GROUP_EVENT = 0x18,
1863 : SPDK_NVME_FEAT_IO_COMMAND_SET_PROFILE = 0x19,
1864 : SPDK_NVME_FEAT_SPINUP_CONTROL = 0x1A,
1865 : /* 0x1B-0x1C - reserved */
1866 :
1867 : /**
1868 : * cdw11 layout defined by \ref spdk_nvme_feat_fdp_cdw11
1869 : * cdw12 layout defined by \ref spdk_nvme_feat_fdp_cdw12
1870 : */
1871 : SPDK_NVME_FEAT_FDP = 0x1D,
1872 :
1873 : /**
1874 : * cdw11 layout defined by \ref spdk_nvme_feat_fdp_events_cdw11
1875 : * cdw12 layout defined by \ref spdk_nvme_feat_fdp_events_cdw12
1876 : * data layout defined by \ref spdk_nvme_fdp_event_desc
1877 : */
1878 : SPDK_NVME_FEAT_FDP_EVENTS = 0x1E,
1879 :
1880 : /* 0x1F-0x77 - reserved */
1881 : /* 0x78-0x7C - NVMe-MI features */
1882 : SPDK_NVME_FEAT_ENHANCED_CONTROLLER_METADATA = 0x7D,
1883 : SPDK_NVME_FEAT_CONTROLLER_METADATA = 0x7E,
1884 : SPDK_NVME_FEAT_NAMESPACE_METADATA = 0x7F,
1885 :
1886 : /** cdw11 layout defined by \ref spdk_nvme_feat_software_progress_marker */
1887 : SPDK_NVME_FEAT_SOFTWARE_PROGRESS_MARKER = 0x80,
1888 :
1889 : /** cdw11 layout defined by \ref spdk_nvme_feat_host_identifier */
1890 : SPDK_NVME_FEAT_HOST_IDENTIFIER = 0x81,
1891 : /** cdw11 layout defined by \ref spdk_nvme_feat_reservation_notification_mask */
1892 : SPDK_NVME_FEAT_HOST_RESERVE_MASK = 0x82,
1893 : /** cdw11 layout defined by \ref spdk_nvme_feat_reservation_persistence */
1894 : SPDK_NVME_FEAT_HOST_RESERVE_PERSIST = 0x83,
1895 : SPDK_NVME_FEAT_NAMESPACE_WRITE_PROTECTION_CONFIG = 0x84,
1896 :
1897 : /* 0x85-0xBF - command set specific (reserved) */
1898 :
1899 : /* 0xC0-0xFF - vendor specific */
1900 : };
1901 :
1902 : /** Bit set of attributes for DATASET MANAGEMENT commands. */
1903 : enum spdk_nvme_dsm_attribute {
1904 : SPDK_NVME_DSM_ATTR_INTEGRAL_READ = 0x1,
1905 : SPDK_NVME_DSM_ATTR_INTEGRAL_WRITE = 0x2,
1906 : SPDK_NVME_DSM_ATTR_DEALLOCATE = 0x4,
1907 : };
1908 :
1909 : struct spdk_nvme_power_state {
1910 : uint16_t mp; /* bits 15:00: maximum power */
1911 :
1912 : uint8_t reserved1;
1913 :
1914 : uint8_t mps : 1; /* bit 24: max power scale */
1915 : uint8_t nops : 1; /* bit 25: non-operational state */
1916 : uint8_t reserved2 : 6;
1917 :
1918 : uint32_t enlat; /* bits 63:32: entry latency in microseconds */
1919 : uint32_t exlat; /* bits 95:64: exit latency in microseconds */
1920 :
1921 : uint8_t rrt : 5; /* bits 100:96: relative read throughput */
1922 : uint8_t reserved3 : 3;
1923 :
1924 : uint8_t rrl : 5; /* bits 108:104: relative read latency */
1925 : uint8_t reserved4 : 3;
1926 :
1927 : uint8_t rwt : 5; /* bits 116:112: relative write throughput */
1928 : uint8_t reserved5 : 3;
1929 :
1930 : uint8_t rwl : 5; /* bits 124:120: relative write latency */
1931 : uint8_t reserved6 : 3;
1932 :
1933 : uint16_t idlp; /* bits 143:128: idle power */
1934 :
1935 : uint8_t reserved7 : 6;
1936 : uint8_t ips : 2; /* bits 151:150: idle power scale */
1937 :
1938 : uint8_t reserved8;
1939 :
1940 : uint16_t actp; /* bits 175:160: active power */
1941 :
1942 : uint8_t apw : 3; /* bits 178:176: active power workload */
1943 : uint8_t reserved9 : 3;
1944 : uint8_t aps : 2; /* bits 183:182: active power scale */
1945 :
1946 : uint8_t reserved10[9];
1947 : };
1948 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_power_state) == 32, "Incorrect size");
1949 :
1950 : /** Identify command CNS value */
1951 : enum spdk_nvme_identify_cns {
1952 : /** Identify namespace indicated in CDW1.NSID */
1953 : SPDK_NVME_IDENTIFY_NS = 0x00,
1954 :
1955 : /** Identify controller */
1956 : SPDK_NVME_IDENTIFY_CTRLR = 0x01,
1957 :
1958 : /** List active NSIDs greater than CDW1.NSID */
1959 : SPDK_NVME_IDENTIFY_ACTIVE_NS_LIST = 0x02,
1960 :
1961 : /** List namespace identification descriptors */
1962 : SPDK_NVME_IDENTIFY_NS_ID_DESCRIPTOR_LIST = 0x03,
1963 :
1964 : /** Identify namespace indicated in CDW1.NSID, specific to CWD11.CSI */
1965 : SPDK_NVME_IDENTIFY_NS_IOCS = 0x05,
1966 :
1967 : /** Identify controller, specific to CWD11.CSI */
1968 : SPDK_NVME_IDENTIFY_CTRLR_IOCS = 0x06,
1969 :
1970 : /** List active NSIDs greater than CDW1.NSID, specific to CWD11.CSI */
1971 : SPDK_NVME_IDENTIFY_ACTIVE_NS_LIST_IOCS = 0x07,
1972 :
1973 : /** List allocated NSIDs greater than CDW1.NSID */
1974 : SPDK_NVME_IDENTIFY_ALLOCATED_NS_LIST = 0x10,
1975 :
1976 : /** Identify namespace if CDW1.NSID is allocated */
1977 : SPDK_NVME_IDENTIFY_NS_ALLOCATED = 0x11,
1978 :
1979 : /** Get list of controllers starting at CDW10.CNTID that are attached to CDW1.NSID */
1980 : SPDK_NVME_IDENTIFY_NS_ATTACHED_CTRLR_LIST = 0x12,
1981 :
1982 : /** Get list of controllers starting at CDW10.CNTID */
1983 : SPDK_NVME_IDENTIFY_CTRLR_LIST = 0x13,
1984 :
1985 : /** Get primary controller capabilities structure */
1986 : SPDK_NVME_IDENTIFY_PRIMARY_CTRLR_CAP = 0x14,
1987 :
1988 : /** Get secondary controller list */
1989 : SPDK_NVME_IDENTIFY_SECONDARY_CTRLR_LIST = 0x15,
1990 :
1991 : /** List allocated NSIDs greater than CDW1.NSID, specific to CWD11.CSI */
1992 : SPDK_NVME_IDENTIFY_ALLOCATED_NS_LIST_IOCS = 0x1a,
1993 :
1994 : /** Identify namespace if CDW1.NSID is allocated, specific to CDWD11.CSI */
1995 : SPDK_NVME_IDENTIFY_NS_ALLOCATED_IOCS = 0x1b,
1996 :
1997 : /** Identify I/O Command Sets */
1998 : SPDK_NVME_IDENTIFY_IOCS = 0x1c,
1999 : };
2000 :
2001 : /** NVMe over Fabrics controller model */
2002 : enum spdk_nvmf_ctrlr_model {
2003 : /** NVM subsystem uses dynamic controller model */
2004 : SPDK_NVMF_CTRLR_MODEL_DYNAMIC = 0,
2005 :
2006 : /** NVM subsystem uses static controller model */
2007 : SPDK_NVMF_CTRLR_MODEL_STATIC = 1,
2008 : };
2009 :
2010 : #define SPDK_NVME_CTRLR_SN_LEN 20
2011 : #define SPDK_NVME_CTRLR_MN_LEN 40
2012 : #define SPDK_NVME_CTRLR_FR_LEN 8
2013 : #define SPDK_NVME_CTRLR_MEGCAP_LEN 16
2014 :
2015 : /** Identify Controller data sgls.supported values */
2016 : enum spdk_nvme_sgls_supported {
2017 : /** SGLs are not supported */
2018 : SPDK_NVME_SGLS_NOT_SUPPORTED = 0,
2019 :
2020 : /** SGLs are supported with no alignment or granularity requirement. */
2021 : SPDK_NVME_SGLS_SUPPORTED = 1,
2022 :
2023 : /** SGLs are supported with a DWORD alignment and granularity requirement. */
2024 : SPDK_NVME_SGLS_SUPPORTED_DWORD_ALIGNED = 2,
2025 : };
2026 :
2027 : /** Identify Controller data vwc.flush_broadcast values */
2028 : enum spdk_nvme_flush_broadcast {
2029 : /** Support for NSID=FFFFFFFFh with Flush is not indicated. */
2030 : SPDK_NVME_FLUSH_BROADCAST_NOT_INDICATED = 0,
2031 :
2032 : /* 01b: Reserved */
2033 :
2034 : /** Flush does not support NSID set to FFFFFFFFh. */
2035 : SPDK_NVME_FLUSH_BROADCAST_NOT_SUPPORTED = 2,
2036 :
2037 : /** Flush supports NSID set to FFFFFFFFh. */
2038 : SPDK_NVME_FLUSH_BROADCAST_SUPPORTED = 3
2039 : };
2040 :
2041 : #define SPDK_NVME_MAXDNA_FIELD_SIZE 16
2042 : #define SPDK_NVME_NQN_FIELD_SIZE 256
2043 :
2044 : /** Identify Controller data NVMe over Fabrics-specific fields */
2045 : struct spdk_nvme_cdata_nvmf_specific {
2046 : /** I/O queue command capsule supported size (16-byte units) */
2047 : uint32_t ioccsz;
2048 :
2049 : /** I/O queue response capsule supported size (16-byte units) */
2050 : uint32_t iorcsz;
2051 :
2052 : /** In-capsule data offset (16-byte units) */
2053 : uint16_t icdoff;
2054 :
2055 : /** Controller attributes */
2056 : struct {
2057 : /** Controller model: \ref spdk_nvmf_ctrlr_model */
2058 : uint8_t ctrlr_model : 1;
2059 : uint8_t reserved : 7;
2060 : } ctrattr;
2061 :
2062 : /** Maximum SGL block descriptors (0 = no limit) */
2063 : uint8_t msdbd;
2064 :
2065 : /** Optional fabric commands supported */
2066 : struct {
2067 : /** Support disconnect command and individual I/O queue deletion */
2068 : uint16_t disconnect : 1;
2069 : uint16_t reserved : 15;
2070 : } ofcs;
2071 :
2072 : uint8_t reserved[242];
2073 : };
2074 :
2075 : /** Identify Controller data SGL support */
2076 : struct spdk_nvme_cdata_sgls {
2077 : uint32_t supported : 2;
2078 : uint32_t keyed_sgl : 1;
2079 : uint32_t reserved1 : 13;
2080 : uint32_t bit_bucket_descriptor : 1;
2081 : uint32_t metadata_pointer : 1;
2082 : uint32_t oversized_sgl : 1;
2083 : uint32_t metadata_address : 1;
2084 : uint32_t sgl_offset : 1;
2085 : uint32_t transport_sgl : 1;
2086 : uint32_t reserved2 : 10;
2087 : };
2088 :
2089 : /** Identify Controller data Optional NVM Command Support */
2090 : struct spdk_nvme_cdata_oncs {
2091 : uint16_t compare : 1;
2092 : uint16_t write_unc : 1;
2093 : uint16_t dsm: 1;
2094 : uint16_t write_zeroes: 1;
2095 : uint16_t set_features_save: 1;
2096 : uint16_t reservations: 1;
2097 : uint16_t timestamp: 1;
2098 : uint16_t verify: 1;
2099 : uint16_t copy: 1;
2100 : uint16_t reserved9: 7;
2101 : };
2102 :
2103 : struct spdk_nvme_cdata_oacs {
2104 : /* supports security send/receive commands */
2105 : uint16_t security : 1;
2106 :
2107 : /* supports format nvm command */
2108 : uint16_t format : 1;
2109 :
2110 : /* supports firmware activate/download commands */
2111 : uint16_t firmware : 1;
2112 :
2113 : /* supports ns manage/ns attach commands */
2114 : uint16_t ns_manage : 1;
2115 :
2116 : /** Supports device self-test command (SPDK_NVME_OPC_DEVICE_SELF_TEST) */
2117 : uint16_t device_self_test : 1;
2118 :
2119 : /** Supports SPDK_NVME_OPC_DIRECTIVE_SEND and SPDK_NVME_OPC_DIRECTIVE_RECEIVE */
2120 : uint16_t directives : 1;
2121 :
2122 : /** Supports NVMe-MI (SPDK_NVME_OPC_NVME_MI_SEND, SPDK_NVME_OPC_NVME_MI_RECEIVE) */
2123 : uint16_t nvme_mi : 1;
2124 :
2125 : /** Supports SPDK_NVME_OPC_VIRTUALIZATION_MANAGEMENT */
2126 : uint16_t virtualization_management : 1;
2127 :
2128 : /** Supports SPDK_NVME_OPC_DOORBELL_BUFFER_CONFIG */
2129 : uint16_t doorbell_buffer_config : 1;
2130 :
2131 : /** Supports SPDK_NVME_OPC_GET_LBA_STATUS */
2132 : uint16_t get_lba_status : 1;
2133 :
2134 : /** Supports command and feature lockdown capability */
2135 : uint16_t command_feature_lockdown : 1;
2136 :
2137 : uint16_t oacs_rsvd : 5;
2138 : };
2139 :
2140 : struct spdk_nvme_cdata_fuses {
2141 : uint16_t compare_and_write : 1;
2142 : uint16_t reserved : 15;
2143 : };
2144 :
2145 : struct spdk_nvme_cdata_oaes {
2146 : uint32_t reserved1 : 8;
2147 :
2148 : /* Supports sending Namespace Attribute Notices. */
2149 : uint32_t ns_attribute_notices : 1;
2150 :
2151 : /* Supports sending Firmware Activation Notices. */
2152 : uint32_t fw_activation_notices : 1;
2153 :
2154 : uint32_t reserved2 : 1;
2155 :
2156 : /* Supports Asymmetric Namespace Access Change Notices. */
2157 : uint32_t ana_change_notices : 1;
2158 :
2159 : /* Supports Predictable Latency Event Aggregate Log Change Notices. */
2160 : uint32_t pleal_change_notices : 1;
2161 :
2162 : /* Supports LBA Status Information Alert Notices. */
2163 : uint32_t lba_sia_notices : 1;
2164 :
2165 : /* Supports Endurance Group Event Aggregate Log Page Change Notices. */
2166 : uint32_t egealp_change_notices : 1;
2167 :
2168 : /* Supports Normal NVM Subsystem Shutdown event. */
2169 : uint32_t nnvm_sse : 1;
2170 :
2171 : uint32_t reserved3 : 11;
2172 :
2173 : /* Supports Zone Descriptor Change Notices (refer to the ZNS Command Set specification) */
2174 : uint32_t zdes_change_notices : 1;
2175 :
2176 : uint32_t reserved4 : 3;
2177 :
2178 : /* Supports Discovery log change notices (refer to the NVMe over Fabrics specification) */
2179 : uint32_t discovery_log_change_notices : 1;
2180 : };
2181 :
2182 : struct spdk_nvme_cdata_ctratt {
2183 : /* Supports 128-bit host identifier */
2184 : uint32_t host_id_exhid_supported: 1;
2185 :
2186 : /* Supports non-operational power state permissive mode */
2187 : uint32_t non_operational_power_state_permissive_mode: 1;
2188 :
2189 : /* Supports NVM sets */
2190 : uint32_t nvm_sets: 1;
2191 :
2192 : /* Supports read recovery levels */
2193 : uint32_t read_recovery_levels: 1;
2194 :
2195 : /* Supports endurance groups */
2196 : uint32_t endurance_groups: 1;
2197 :
2198 : /* Supports predictable latency mode */
2199 : uint32_t predictable_latency_mode: 1;
2200 :
2201 : /* Supports traffic based keep alive */
2202 : uint32_t tbkas: 1;
2203 :
2204 : /* Supports reporting of namespace granularity */
2205 : uint32_t namespace_granularity: 1;
2206 :
2207 : /* Supports SQ associations */
2208 : uint32_t sq_associations: 1;
2209 :
2210 : /* Supports reporting of UUID list */
2211 : uint32_t uuid_list: 1;
2212 :
2213 : /* NVM subsystem supports multiple domains */
2214 : uint32_t mds: 1;
2215 :
2216 : /* Supports fixed capacity management */
2217 : uint32_t fixed_capacity_management: 1;
2218 :
2219 : /* Supports variable capacity management */
2220 : uint32_t variable_capacity_management: 1;
2221 :
2222 : /* Supports delete endurance group operation */
2223 : uint32_t delete_endurance_group: 1;
2224 :
2225 : /* Supports delete NVM set */
2226 : uint32_t delete_nvm_set: 1;
2227 :
2228 : /* Supports I/O command set specific extended PI formats */
2229 : uint32_t elbas: 1;
2230 :
2231 : uint32_t reserved1: 3;
2232 :
2233 : /* Supports flexible data placement */
2234 : uint32_t fdps: 1;
2235 :
2236 : uint32_t reserved2: 12;
2237 : };
2238 :
2239 : #pragma pack(push, 1)
2240 : struct spdk_nvme_ctrlr_data {
2241 : /* bytes 0-255: controller capabilities and features */
2242 :
2243 : /** pci vendor id */
2244 : uint16_t vid;
2245 :
2246 : /** pci subsystem vendor id */
2247 : uint16_t ssvid;
2248 :
2249 : /** serial number */
2250 : int8_t sn[SPDK_NVME_CTRLR_SN_LEN];
2251 :
2252 : /** model number */
2253 : int8_t mn[SPDK_NVME_CTRLR_MN_LEN];
2254 :
2255 : /** firmware revision */
2256 : uint8_t fr[SPDK_NVME_CTRLR_FR_LEN];
2257 :
2258 : /** recommended arbitration burst */
2259 : uint8_t rab;
2260 :
2261 : /** ieee oui identifier */
2262 : uint8_t ieee[3];
2263 :
2264 : /** controller multi-path I/O and namespace sharing capabilities */
2265 : struct {
2266 : uint8_t multi_port : 1;
2267 : uint8_t multi_ctrlr : 1;
2268 : uint8_t sr_iov : 1;
2269 : uint8_t ana_reporting : 1;
2270 : uint8_t reserved : 4;
2271 : } cmic;
2272 :
2273 : /** maximum data transfer size */
2274 : uint8_t mdts;
2275 :
2276 : /** controller id */
2277 : uint16_t cntlid;
2278 :
2279 : /** version */
2280 : union spdk_nvme_vs_register ver;
2281 :
2282 : /** RTD3 resume latency */
2283 : uint32_t rtd3r;
2284 :
2285 : /** RTD3 entry latency */
2286 : uint32_t rtd3e;
2287 :
2288 : /** optional asynchronous events supported */
2289 : struct spdk_nvme_cdata_oaes oaes;
2290 :
2291 : /** controller attributes */
2292 : struct spdk_nvme_cdata_ctratt ctratt;
2293 :
2294 : /** Read Recovery Levels Supported */
2295 : uint16_t rrls;
2296 :
2297 : uint8_t reserved_102[9];
2298 :
2299 : /** Controller Type */
2300 : uint8_t cntrltype;
2301 :
2302 : /** FRU globally unique identifier */
2303 : uint8_t fguid[16];
2304 :
2305 : /** Command Retry Delay Time 1, 2 and 3 */
2306 : uint16_t crdt[3];
2307 :
2308 : uint8_t reserved_134[119];
2309 :
2310 : /** NVM Subsystem Report */
2311 : struct {
2312 : /* NVM Subsystem part of NVMe storage device */
2313 : uint8_t nvmesd : 1;
2314 :
2315 : /* NVM Subsystem part of NVMe enclosure */
2316 : uint8_t nvmee : 1;
2317 :
2318 : uint8_t nvmsr_rsvd : 6;
2319 : } nvmsr;
2320 :
2321 : /** VPD Write Cycle Information */
2322 : struct {
2323 : /* VPD write cycles remaining */
2324 : uint8_t vwcr : 7;
2325 :
2326 : /* VPD write cycles remaining valid */
2327 : uint8_t vwcrv : 1;
2328 : } vwci;
2329 :
2330 : /** Management Endpoint Capabilities */
2331 : struct {
2332 : /* SMBus/I2C Port management endpoint */
2333 : uint8_t smbusme : 1;
2334 :
2335 : /* PCIe port management endpoint */
2336 : uint8_t pcieme : 1;
2337 :
2338 : uint8_t mec_rsvd : 6;
2339 : } mec;
2340 :
2341 : /* bytes 256-511: admin command set attributes */
2342 :
2343 : /** optional admin command support */
2344 : struct spdk_nvme_cdata_oacs oacs;
2345 :
2346 : /** abort command limit */
2347 : uint8_t acl;
2348 :
2349 : /** asynchronous event request limit */
2350 : uint8_t aerl;
2351 :
2352 : /** firmware updates */
2353 : struct {
2354 : /* first slot is read-only */
2355 : uint8_t slot1_ro : 1;
2356 :
2357 : /* number of firmware slots */
2358 : uint8_t num_slots : 3;
2359 :
2360 : /* support activation without reset */
2361 : uint8_t activation_without_reset : 1;
2362 :
2363 : /* Support multiple update detection */
2364 : uint8_t multiple_update_detection : 1;
2365 :
2366 : uint8_t frmw_rsvd : 2;
2367 : } frmw;
2368 :
2369 : /** log page attributes */
2370 : struct {
2371 : /* per namespace smart/health log page */
2372 : uint8_t ns_smart : 1;
2373 : /* command effects log page */
2374 : uint8_t celp : 1;
2375 : /* extended data for get log page */
2376 : uint8_t edlp: 1;
2377 : /* telemetry log pages and notices */
2378 : uint8_t telemetry : 1;
2379 : /* Persistent event log */
2380 : uint8_t pelp : 1;
2381 : /* Log pages log page */
2382 : uint8_t lplp : 1;
2383 : /* Data Area 4 for telemetry */
2384 : uint8_t da4_telemetry : 1;
2385 : uint8_t lpa_rsvd : 1;
2386 : } lpa;
2387 :
2388 : /** error log page entries */
2389 : uint8_t elpe;
2390 :
2391 : /** number of power states supported */
2392 : uint8_t npss;
2393 :
2394 : /** admin vendor specific command configuration */
2395 : struct {
2396 : /* admin vendor specific commands use disk format */
2397 : uint8_t spec_format : 1;
2398 :
2399 : uint8_t avscc_rsvd : 7;
2400 : } avscc;
2401 :
2402 : /** autonomous power state transition attributes */
2403 : struct {
2404 : /** controller supports autonomous power state transitions */
2405 : uint8_t supported : 1;
2406 :
2407 : uint8_t apsta_rsvd : 7;
2408 : } apsta;
2409 :
2410 : /** warning composite temperature threshold */
2411 : uint16_t wctemp;
2412 :
2413 : /** critical composite temperature threshold */
2414 : uint16_t cctemp;
2415 :
2416 : /** maximum time for firmware activation */
2417 : uint16_t mtfa;
2418 :
2419 : /** host memory buffer preferred size */
2420 : uint32_t hmpre;
2421 :
2422 : /** host memory buffer minimum size */
2423 : uint32_t hmmin;
2424 :
2425 : /** total NVM capacity */
2426 : uint64_t tnvmcap[2];
2427 :
2428 : /** unallocated NVM capacity */
2429 : uint64_t unvmcap[2];
2430 :
2431 : /** replay protected memory block support */
2432 : struct {
2433 : uint8_t num_rpmb_units : 3;
2434 : uint8_t auth_method : 3;
2435 : uint8_t reserved1 : 2;
2436 :
2437 : uint8_t reserved2;
2438 :
2439 : uint8_t total_size;
2440 : uint8_t access_size;
2441 : } rpmbs;
2442 :
2443 : /** extended device self-test time (in minutes) */
2444 : uint16_t edstt;
2445 :
2446 : /** device self-test options */
2447 : union {
2448 : uint8_t raw;
2449 : struct {
2450 : /** Device supports only one device self-test operation at a time */
2451 : uint8_t one_only : 1;
2452 :
2453 : uint8_t reserved : 7;
2454 : } bits;
2455 : } dsto;
2456 :
2457 : /**
2458 : * Firmware update granularity
2459 : *
2460 : * 4KB units
2461 : * 0x00 = no information provided
2462 : * 0xFF = no restriction
2463 : */
2464 : uint8_t fwug;
2465 :
2466 : /**
2467 : * Keep Alive Support
2468 : *
2469 : * Granularity of keep alive timer in 100 ms units
2470 : * 0 = keep alive not supported
2471 : */
2472 : uint16_t kas;
2473 :
2474 : /** Host controlled thermal management attributes */
2475 : union {
2476 : uint16_t raw;
2477 : struct {
2478 : uint16_t supported : 1;
2479 : uint16_t reserved : 15;
2480 : } bits;
2481 : } hctma;
2482 :
2483 : /** Minimum thermal management temperature */
2484 : uint16_t mntmt;
2485 :
2486 : /** Maximum thermal management temperature */
2487 : uint16_t mxtmt;
2488 :
2489 : /** Sanitize capabilities */
2490 : union {
2491 : uint32_t raw;
2492 : struct {
2493 : uint32_t crypto_erase : 1;
2494 : uint32_t block_erase : 1;
2495 : uint32_t overwrite : 1;
2496 : uint32_t reserved : 29;
2497 : } bits;
2498 : } sanicap;
2499 :
2500 : /** Host memory buffer minimum descriptor entry size */
2501 : uint32_t hmminds;
2502 :
2503 : /** Host memory maximum descriptor entries */
2504 : uint16_t hmmaxd;
2505 :
2506 : /** NVM set identifier maximum */
2507 : uint16_t nsetidmax;
2508 :
2509 : /** Endurance group identifier maximum */
2510 : uint16_t endgidmax;
2511 :
2512 : /** ANA transition time */
2513 : uint8_t anatt;
2514 :
2515 : /* bytes 343: Asymmetric namespace access capabilities */
2516 : struct {
2517 : uint8_t ana_optimized_state : 1;
2518 : uint8_t ana_non_optimized_state : 1;
2519 : uint8_t ana_inaccessible_state : 1;
2520 : uint8_t ana_persistent_loss_state : 1;
2521 : uint8_t ana_change_state : 1;
2522 : uint8_t reserved : 1;
2523 : uint8_t no_change_anagrpid : 1;
2524 : uint8_t non_zero_anagrpid : 1;
2525 : } anacap;
2526 :
2527 : /* bytes 344-347: ANA group identifier maximum */
2528 : uint32_t anagrpmax;
2529 : /* bytes 348-351: number of ANA group identifiers */
2530 : uint32_t nanagrpid;
2531 :
2532 : /* bytes 352-355: persistent event log size */
2533 : uint32_t pels;
2534 :
2535 : /* Domain identifier that contains this controller */
2536 : uint16_t domain_identifier;
2537 :
2538 : uint8_t reserved3[10];
2539 :
2540 : /* Maximum capacity of a single endurance group */
2541 : uint8_t megcap[SPDK_NVME_CTRLR_MEGCAP_LEN];
2542 :
2543 : /* bytes 384-511 */
2544 : uint8_t reserved384[128];
2545 :
2546 : /* bytes 512-703: nvm command set attributes */
2547 :
2548 : /** submission queue entry size */
2549 : struct {
2550 : uint8_t min : 4;
2551 : uint8_t max : 4;
2552 : } sqes;
2553 :
2554 : /** completion queue entry size */
2555 : struct {
2556 : uint8_t min : 4;
2557 : uint8_t max : 4;
2558 : } cqes;
2559 :
2560 : uint16_t maxcmd;
2561 :
2562 : /** number of namespaces */
2563 : uint32_t nn;
2564 :
2565 : /** optional nvm command support */
2566 : struct spdk_nvme_cdata_oncs oncs;
2567 :
2568 : /** fused operation support */
2569 : struct spdk_nvme_cdata_fuses fuses;
2570 :
2571 : /** format nvm attributes */
2572 : struct {
2573 : uint8_t format_all_ns: 1;
2574 : uint8_t erase_all_ns: 1;
2575 : uint8_t crypto_erase_supported: 1;
2576 : uint8_t reserved: 5;
2577 : } fna;
2578 :
2579 : /** volatile write cache */
2580 : struct {
2581 : uint8_t present : 1;
2582 : uint8_t flush_broadcast : 2;
2583 : uint8_t reserved : 5;
2584 : } vwc;
2585 :
2586 : /** atomic write unit normal */
2587 : uint16_t awun;
2588 :
2589 : /** atomic write unit power fail */
2590 : uint16_t awupf;
2591 :
2592 : /** NVM vendor specific command configuration */
2593 : uint8_t nvscc;
2594 :
2595 : /** Namespace Write Protection Capabilities */
2596 : uint8_t nwpc;
2597 :
2598 : /** atomic compare & write unit */
2599 : uint16_t acwu;
2600 :
2601 : /** optional copy formats supported */
2602 : struct {
2603 : uint16_t copy_format0 : 1;
2604 : uint16_t reserved1: 15;
2605 : } ocfs;
2606 :
2607 :
2608 : struct spdk_nvme_cdata_sgls sgls;
2609 :
2610 : /* maximum number of allowed namespaces */
2611 : uint32_t mnan;
2612 :
2613 : /* maximum domain namespace attachments */
2614 : uint8_t maxdna[SPDK_NVME_MAXDNA_FIELD_SIZE];
2615 :
2616 : /* maximum I/O controller namespace attachments */
2617 : uint32_t maxcna;
2618 :
2619 : uint8_t reserved4[204];
2620 :
2621 : uint8_t subnqn[SPDK_NVME_NQN_FIELD_SIZE];
2622 :
2623 : uint8_t reserved5[768];
2624 :
2625 : struct spdk_nvme_cdata_nvmf_specific nvmf_specific;
2626 :
2627 : /* bytes 2048-3071: power state descriptors */
2628 : struct spdk_nvme_power_state psd[32];
2629 :
2630 : /* bytes 3072-4095: vendor specific */
2631 : uint8_t vs[1024];
2632 : };
2633 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ctrlr_data) == 4096, "Incorrect size");
2634 : #pragma pack(pop)
2635 :
2636 : struct spdk_nvme_zns_ctrlr_data {
2637 : /** zone append size limit */
2638 : uint8_t zasl;
2639 :
2640 : uint8_t reserved1[4095];
2641 : };
2642 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_zns_ctrlr_data) == 4096, "Incorrect size");
2643 :
2644 : #pragma pack(push, 1)
2645 : struct spdk_nvme_primary_ctrl_capabilities {
2646 : /** controller id */
2647 : uint16_t cntlid;
2648 : /** port identifier */
2649 : uint16_t portid;
2650 : /** controller resource types */
2651 : struct {
2652 : uint8_t vq_supported : 1;
2653 : uint8_t vi_supported : 1;
2654 : uint8_t reserved : 6;
2655 : } crt;
2656 : uint8_t reserved[27];
2657 : /** total number of VQ flexible resources */
2658 : uint32_t vqfrt;
2659 : /** total number of VQ flexible resources assigned to secondary controllers */
2660 : uint32_t vqrfa;
2661 : /** total number of VQ flexible resources allocated to primary controller */
2662 : uint16_t vqrfap;
2663 : /** total number of VQ Private resources for the primary controller */
2664 : uint16_t vqprt;
2665 : /** max number of VQ flexible Resources that may be assigned to a secondary controller */
2666 : uint16_t vqfrsm;
2667 : /** preferred granularity of assigning and removing VQ Flexible Resources */
2668 : uint16_t vqgran;
2669 : uint8_t reserved1[16];
2670 : /** total number of VI flexible resources for the primary and its secondary controllers */
2671 : uint32_t vifrt;
2672 : /** total number of VI flexible resources assigned to the secondary controllers */
2673 : uint32_t virfa;
2674 : /** total number of VI flexible resources currently allocated to the primary controller */
2675 : uint16_t virfap;
2676 : /** total number of VI private resources for the primary controller */
2677 : uint16_t viprt;
2678 : /** max number of VI flexible resources that may be assigned to a secondary controller */
2679 : uint16_t vifrsm;
2680 : /** preferred granularity of assigning and removing VI flexible resources */
2681 : uint16_t vigran;
2682 : uint8_t reserved2[4016];
2683 : };
2684 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_primary_ctrl_capabilities) == 4096, "Incorrect size");
2685 :
2686 : struct spdk_nvme_secondary_ctrl_entry {
2687 : /** controller identifier of the secondary controller */
2688 : uint16_t scid;
2689 : /** controller identifier of the associated primary controller */
2690 : uint16_t pcid;
2691 : /** indicates the state of the secondary controller */
2692 : struct {
2693 : uint8_t is_online : 1;
2694 : uint8_t reserved : 7;
2695 : } scs;
2696 : uint8_t reserved[3];
2697 : /** VF number if the secondary controller is an SR-IOV VF */
2698 : uint16_t vfn;
2699 : /** number of VQ flexible resources assigned to the indicated secondary controller */
2700 : uint16_t nvq;
2701 : /** number of VI flexible resources assigned to the indicated secondary controller */
2702 : uint16_t nvi;
2703 : uint8_t reserved1[18];
2704 : };
2705 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_secondary_ctrl_entry) == 32, "Incorrect size");
2706 :
2707 : struct spdk_nvme_secondary_ctrl_list {
2708 : /** number of Secondary controller entries in the list */
2709 : uint8_t number;
2710 : uint8_t reserved[31];
2711 : struct spdk_nvme_secondary_ctrl_entry entries[127];
2712 : };
2713 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_secondary_ctrl_list) == 4096, "Incorrect size");
2714 : #pragma pack(pop)
2715 :
2716 : struct spdk_nvme_ns_data {
2717 : /** namespace size */
2718 : uint64_t nsze;
2719 :
2720 : /** namespace capacity */
2721 : uint64_t ncap;
2722 :
2723 : /** namespace utilization */
2724 : uint64_t nuse;
2725 :
2726 : /** namespace features */
2727 : struct {
2728 : /** thin provisioning */
2729 : uint8_t thin_prov : 1;
2730 :
2731 : /** NAWUN, NAWUPF, and NACWU are defined for this namespace */
2732 : uint8_t ns_atomic_write_unit : 1;
2733 :
2734 : /** Supports Deallocated or Unwritten LBA error for this namespace */
2735 : uint8_t dealloc_or_unwritten_error : 1;
2736 :
2737 : /** Non-zero NGUID and EUI64 for namespace are never reused */
2738 : uint8_t guid_never_reused : 1;
2739 :
2740 : /** Optimal Performance field */
2741 : uint8_t optperf : 1;
2742 :
2743 : uint8_t reserved1 : 3;
2744 : } nsfeat;
2745 :
2746 : /** number of lba formats */
2747 : uint8_t nlbaf;
2748 :
2749 : /** formatted lba size */
2750 : struct {
2751 : /** LSB for Format index */
2752 : uint8_t format : 4;
2753 : uint8_t extended : 1;
2754 : /** MSB for Format index, to be ignored if nlbaf <= 16 */
2755 : uint8_t msb_format : 2;
2756 : uint8_t reserved2 : 1;
2757 : } flbas;
2758 :
2759 : /** metadata capabilities */
2760 : struct {
2761 : /** metadata can be transferred as part of data prp list */
2762 : uint8_t extended : 1;
2763 :
2764 : /** metadata can be transferred with separate metadata pointer */
2765 : uint8_t pointer : 1;
2766 :
2767 : /** reserved */
2768 : uint8_t reserved3 : 6;
2769 : } mc;
2770 :
2771 : /** end-to-end data protection capabilities */
2772 : struct {
2773 : /** protection information type 1 */
2774 : uint8_t pit1 : 1;
2775 :
2776 : /** protection information type 2 */
2777 : uint8_t pit2 : 1;
2778 :
2779 : /** protection information type 3 */
2780 : uint8_t pit3 : 1;
2781 :
2782 : /** first eight bytes of metadata */
2783 : uint8_t md_start : 1;
2784 :
2785 : /** last eight bytes of metadata */
2786 : uint8_t md_end : 1;
2787 : } dpc;
2788 :
2789 : /** end-to-end data protection type settings */
2790 : struct {
2791 : /** protection information type */
2792 : uint8_t pit : 3;
2793 :
2794 : /** 1 == protection info transferred at start of metadata */
2795 : /** 0 == protection info transferred at end of metadata */
2796 : uint8_t md_start : 1;
2797 :
2798 : uint8_t reserved4 : 4;
2799 : } dps;
2800 :
2801 : /** namespace multi-path I/O and namespace sharing capabilities */
2802 : struct {
2803 : uint8_t can_share : 1;
2804 : uint8_t reserved : 7;
2805 : } nmic;
2806 :
2807 : /** reservation capabilities */
2808 : union {
2809 : struct {
2810 : /** supports persist through power loss */
2811 : uint8_t persist : 1;
2812 :
2813 : /** supports write exclusive */
2814 : uint8_t write_exclusive : 1;
2815 :
2816 : /** supports exclusive access */
2817 : uint8_t exclusive_access : 1;
2818 :
2819 : /** supports write exclusive - registrants only */
2820 : uint8_t write_exclusive_reg_only : 1;
2821 :
2822 : /** supports exclusive access - registrants only */
2823 : uint8_t exclusive_access_reg_only : 1;
2824 :
2825 : /** supports write exclusive - all registrants */
2826 : uint8_t write_exclusive_all_reg : 1;
2827 :
2828 : /** supports exclusive access - all registrants */
2829 : uint8_t exclusive_access_all_reg : 1;
2830 :
2831 : /** supports ignore existing key */
2832 : uint8_t ignore_existing_key : 1;
2833 : } rescap;
2834 : uint8_t raw;
2835 : } nsrescap;
2836 : /** format progress indicator */
2837 : struct {
2838 : uint8_t percentage_remaining : 7;
2839 : uint8_t fpi_supported : 1;
2840 : } fpi;
2841 :
2842 : /** deallocate logical features */
2843 : union {
2844 : uint8_t raw;
2845 : struct {
2846 : /**
2847 : * Value read from deallocated blocks
2848 : *
2849 : * 000b = not reported
2850 : * 001b = all bytes 0x00
2851 : * 010b = all bytes 0xFF
2852 : *
2853 : * \ref spdk_nvme_dealloc_logical_block_read_value
2854 : */
2855 : uint8_t read_value : 3;
2856 :
2857 : /** Supports Deallocate bit in Write Zeroes */
2858 : uint8_t write_zero_deallocate : 1;
2859 :
2860 : /**
2861 : * Guard field behavior for deallocated logical blocks
2862 : * 0: contains 0xFFFF
2863 : * 1: contains CRC for read value
2864 : */
2865 : uint8_t guard_value : 1;
2866 :
2867 : uint8_t reserved : 3;
2868 : } bits;
2869 : } dlfeat;
2870 :
2871 : /** namespace atomic write unit normal */
2872 : uint16_t nawun;
2873 :
2874 : /** namespace atomic write unit power fail */
2875 : uint16_t nawupf;
2876 :
2877 : /** namespace atomic compare & write unit */
2878 : uint16_t nacwu;
2879 :
2880 : /** namespace atomic boundary size normal */
2881 : uint16_t nabsn;
2882 :
2883 : /** namespace atomic boundary offset */
2884 : uint16_t nabo;
2885 :
2886 : /** namespace atomic boundary size power fail */
2887 : uint16_t nabspf;
2888 :
2889 : /** namespace optimal I/O boundary in logical blocks */
2890 : uint16_t noiob;
2891 :
2892 : /** NVM capacity */
2893 : uint64_t nvmcap[2];
2894 :
2895 : /** Namespace Preferred Write Granularity */
2896 : uint16_t npwg;
2897 :
2898 : /** Namespace Preferred Write Alignment */
2899 : uint16_t npwa;
2900 :
2901 : /** Namespace Preferred Deallocate Granularity */
2902 : uint16_t npdg;
2903 :
2904 : /** Namespace Preferred Deallocate Alignment */
2905 : uint16_t npda;
2906 :
2907 : /** Namespace Optimal Write Size */
2908 : uint16_t nows;
2909 :
2910 : /** Maximum Single Source Range Length */
2911 : uint16_t mssrl;
2912 :
2913 : /** Maximum Copy Length */
2914 : uint32_t mcl;
2915 :
2916 : /** Maximum Source Range Count */
2917 : uint8_t msrc;
2918 :
2919 : uint8_t reserved81[11];
2920 :
2921 : /** ANA group identifier */
2922 : uint32_t anagrpid;
2923 :
2924 : uint8_t reserved96[3];
2925 :
2926 : /** namespace attributes */
2927 : struct {
2928 : /** Namespace write protected */
2929 : uint8_t write_protected : 1;
2930 : uint8_t reserved : 7;
2931 : } nsattr;
2932 :
2933 : /** NVM Set Identifier */
2934 : uint16_t nvmsetid;
2935 :
2936 : /** Endurance group identifier */
2937 : uint16_t endgid;
2938 :
2939 : /** namespace globally unique identifier */
2940 : uint8_t nguid[16];
2941 :
2942 : /** IEEE extended unique identifier */
2943 : uint64_t eui64;
2944 :
2945 : /** lba format support */
2946 : struct {
2947 : /** metadata size */
2948 : uint32_t ms : 16;
2949 :
2950 : /** lba data size */
2951 : uint32_t lbads : 8;
2952 :
2953 : /** relative performance */
2954 : uint32_t rp : 2;
2955 :
2956 : uint32_t reserved6 : 6;
2957 : } lbaf[64];
2958 :
2959 : uint8_t vendor_specific[3712];
2960 : };
2961 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_data) == 4096, "Incorrect size");
2962 :
2963 : struct spdk_nvme_nvm_ctrlr_data {
2964 : /* verify size limit */
2965 : uint8_t vsl;
2966 :
2967 : /* write zeroes size limit */
2968 : uint8_t wzsl;
2969 :
2970 : /* write uncorrectable size limit */
2971 : uint8_t wusl;
2972 :
2973 : /* dataset management ranges limit */
2974 : uint8_t dmrl;
2975 :
2976 : /* dataset management range size limit */
2977 : uint32_t dmrsl;
2978 :
2979 : /* dataset management size limit */
2980 : uint64_t dmsl;
2981 :
2982 : uint8_t rsvd16[4080];
2983 : };
2984 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_nvm_ctrlr_data) == 4096, "Incorrect size");
2985 :
2986 : struct spdk_nvme_zns_ns_data {
2987 : /** zone operation characteristics */
2988 : struct {
2989 : uint16_t variable_zone_capacity : 1;
2990 : uint16_t zone_active_excursions : 1;
2991 : uint16_t reserved0 : 14;
2992 : } zoc;
2993 :
2994 : /** optional zoned command support */
2995 : struct {
2996 : uint16_t read_across_zone_boundaries : 1;
2997 : uint16_t reserved0 : 15;
2998 : } ozcs;
2999 :
3000 : /** maximum active resources */
3001 : uint32_t mar;
3002 :
3003 : /** maximum open resources */
3004 : uint32_t mor;
3005 :
3006 : /** reset recommended limit */
3007 : uint32_t rrl;
3008 :
3009 : /** finish recommended limit */
3010 : uint32_t frl;
3011 :
3012 : /** reset recommended limit 1 */
3013 : uint32_t rrl1;
3014 :
3015 : /** reset recommended limit 2 */
3016 : uint32_t rrl2;
3017 :
3018 : /** reset recommended limit 3 */
3019 : uint32_t rrl3;
3020 :
3021 : /** finish recommended limit 1 */
3022 : uint32_t frl1;
3023 :
3024 : /** finish recommended limit 2 */
3025 : uint32_t frl2;
3026 :
3027 : /** finish recommended limit 3 */
3028 : uint32_t frl3;
3029 :
3030 : uint8_t reserved44[2772];
3031 :
3032 : /** zns lba format extension support */
3033 : struct {
3034 : /** zone size */
3035 : uint64_t zsze;
3036 :
3037 : /** zone descriptor extension size */
3038 : uint64_t zdes : 8;
3039 :
3040 : uint64_t reserved15 : 56;
3041 : } lbafe[64];
3042 :
3043 : uint8_t vendor_specific[256];
3044 : };
3045 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_zns_ns_data) == 4096, "Incorrect size");
3046 :
3047 : /**
3048 : * IO command set vector for IDENTIFY_IOCS
3049 : */
3050 : struct spdk_nvme_iocs_vector {
3051 : uint8_t nvm : 1;
3052 : uint8_t kv : 1;
3053 : uint8_t zns : 1;
3054 : uint8_t rsvd : 5;
3055 : uint8_t rsvd2[7];
3056 : };
3057 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_iocs_vector) == 8, "Incorrect size");
3058 :
3059 : /**
3060 : * Deallocated logical block features - read value
3061 : */
3062 : enum spdk_nvme_dealloc_logical_block_read_value {
3063 : /** Not reported */
3064 : SPDK_NVME_DEALLOC_NOT_REPORTED = 0,
3065 :
3066 : /** Deallocated blocks read 0x00 */
3067 : SPDK_NVME_DEALLOC_READ_00 = 1,
3068 :
3069 : /** Deallocated blocks read 0xFF */
3070 : SPDK_NVME_DEALLOC_READ_FF = 2,
3071 : };
3072 :
3073 : /**
3074 : * Reservation Type Encoding
3075 : */
3076 : enum spdk_nvme_reservation_type {
3077 : /* 0x00 - reserved */
3078 :
3079 : /* Write Exclusive Reservation */
3080 : SPDK_NVME_RESERVE_WRITE_EXCLUSIVE = 0x1,
3081 :
3082 : /* Exclusive Access Reservation */
3083 : SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS = 0x2,
3084 :
3085 : /* Write Exclusive - Registrants Only Reservation */
3086 : SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY = 0x3,
3087 :
3088 : /* Exclusive Access - Registrants Only Reservation */
3089 : SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY = 0x4,
3090 :
3091 : /* Write Exclusive - All Registrants Reservation */
3092 : SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS = 0x5,
3093 :
3094 : /* Exclusive Access - All Registrants Reservation */
3095 : SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_ALL_REGS = 0x6,
3096 :
3097 : /* 0x7-0xFF - Reserved */
3098 : };
3099 :
3100 : struct spdk_nvme_reservation_acquire_data {
3101 : /** current reservation key */
3102 : uint64_t crkey;
3103 : /** preempt reservation key */
3104 : uint64_t prkey;
3105 : };
3106 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_acquire_data) == 16, "Incorrect size");
3107 :
3108 : /**
3109 : * Reservation Acquire action
3110 : */
3111 : enum spdk_nvme_reservation_acquire_action {
3112 : SPDK_NVME_RESERVE_ACQUIRE = 0x0,
3113 : SPDK_NVME_RESERVE_PREEMPT = 0x1,
3114 : SPDK_NVME_RESERVE_PREEMPT_ABORT = 0x2,
3115 : };
3116 :
3117 : #pragma pack(push, 1)
3118 : struct spdk_nvme_reservation_status_data {
3119 : /** reservation action generation counter */
3120 : uint32_t gen;
3121 : /** reservation type */
3122 : uint8_t rtype;
3123 : /** number of registered controllers */
3124 : uint16_t regctl;
3125 : uint16_t reserved1;
3126 : /** persist through power loss state */
3127 : uint8_t ptpls;
3128 : uint8_t reserved[14];
3129 : };
3130 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_status_data) == 24, "Incorrect size");
3131 :
3132 : struct spdk_nvme_reservation_status_extended_data {
3133 : struct spdk_nvme_reservation_status_data data;
3134 : uint8_t reserved[40];
3135 : };
3136 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_status_extended_data) == 64,
3137 : "Incorrect size");
3138 :
3139 : struct spdk_nvme_registered_ctrlr_data {
3140 : /** controller id */
3141 : uint16_t cntlid;
3142 : /** reservation status */
3143 : struct {
3144 : uint8_t status : 1;
3145 : uint8_t reserved1 : 7;
3146 : } rcsts;
3147 : uint8_t reserved2[5];
3148 : /** 64-bit host identifier */
3149 : uint64_t hostid;
3150 : /** reservation key */
3151 : uint64_t rkey;
3152 : };
3153 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_registered_ctrlr_data) == 24, "Incorrect size");
3154 :
3155 : struct spdk_nvme_registered_ctrlr_extended_data {
3156 : /** controller id */
3157 : uint16_t cntlid;
3158 : /** reservation status */
3159 : struct {
3160 : uint8_t status : 1;
3161 : uint8_t reserved1 : 7;
3162 : } rcsts;
3163 : uint8_t reserved2[5];
3164 : /** reservation key */
3165 : uint64_t rkey;
3166 : /** 128-bit host identifier */
3167 : uint8_t hostid[16];
3168 : uint8_t reserved3[32];
3169 : };
3170 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_registered_ctrlr_extended_data) == 64, "Incorrect size");
3171 : #pragma pack(pop)
3172 :
3173 : /**
3174 : * Change persist through power loss state for
3175 : * Reservation Register command
3176 : */
3177 : enum spdk_nvme_reservation_register_cptpl {
3178 : SPDK_NVME_RESERVE_PTPL_NO_CHANGES = 0x0,
3179 : SPDK_NVME_RESERVE_PTPL_CLEAR_POWER_ON = 0x2,
3180 : SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS = 0x3,
3181 : };
3182 :
3183 : /**
3184 : * Registration action for Reservation Register command
3185 : */
3186 : enum spdk_nvme_reservation_register_action {
3187 : SPDK_NVME_RESERVE_REGISTER_KEY = 0x0,
3188 : SPDK_NVME_RESERVE_UNREGISTER_KEY = 0x1,
3189 : SPDK_NVME_RESERVE_REPLACE_KEY = 0x2,
3190 : };
3191 :
3192 : struct spdk_nvme_reservation_register_data {
3193 : /** current reservation key */
3194 : uint64_t crkey;
3195 : /** new reservation key */
3196 : uint64_t nrkey;
3197 : };
3198 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_register_data) == 16, "Incorrect size");
3199 :
3200 : struct spdk_nvme_reservation_key_data {
3201 : /** current reservation key */
3202 : uint64_t crkey;
3203 : };
3204 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_key_data) == 8, "Incorrect size");
3205 :
3206 : /**
3207 : * Reservation Release action
3208 : */
3209 : enum spdk_nvme_reservation_release_action {
3210 : SPDK_NVME_RESERVE_RELEASE = 0x0,
3211 : SPDK_NVME_RESERVE_CLEAR = 0x1,
3212 : };
3213 :
3214 : /**
3215 : * Reservation notification log page type
3216 : */
3217 : enum spdk_nvme_reservation_notification_log_page_type {
3218 : SPDK_NVME_RESERVATION_LOG_PAGE_EMPTY = 0x0,
3219 : SPDK_NVME_REGISTRATION_PREEMPTED = 0x1,
3220 : SPDK_NVME_RESERVATION_RELEASED = 0x2,
3221 : SPDK_NVME_RESERVATION_PREEMPTED = 0x3,
3222 : };
3223 :
3224 : /**
3225 : * Reservation notification log
3226 : */
3227 : struct spdk_nvme_reservation_notification_log {
3228 : /** 64-bit incrementing reservation notification log page count */
3229 : uint64_t log_page_count;
3230 : /** Reservation notification log page type */
3231 : uint8_t type;
3232 : /** Number of additional available reservation notification log pages */
3233 : uint8_t num_avail_log_pages;
3234 : uint8_t reserved[2];
3235 : uint32_t nsid;
3236 : uint8_t reserved1[48];
3237 : };
3238 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_notification_log) == 64, "Incorrect size");
3239 :
3240 : /* Mask Registration Preempted Notification */
3241 : #define SPDK_NVME_REGISTRATION_PREEMPTED_MASK (1U << 1)
3242 : /* Mask Reservation Released Notification */
3243 : #define SPDK_NVME_RESERVATION_RELEASED_MASK (1U << 2)
3244 : /* Mask Reservation Preempted Notification */
3245 : #define SPDK_NVME_RESERVATION_PREEMPTED_MASK (1U << 3)
3246 :
3247 : /**
3248 : * Log page identifiers for SPDK_NVME_OPC_GET_LOG_PAGE
3249 : */
3250 : enum spdk_nvme_log_page {
3251 : /** Supported log pages (optional) */
3252 : SPDK_NVME_LOG_SUPPORTED_LOG_PAGES = 0x00,
3253 :
3254 : /** Error information (mandatory) - \ref spdk_nvme_error_information_entry */
3255 : SPDK_NVME_LOG_ERROR = 0x01,
3256 :
3257 : /** SMART / health information (mandatory) - \ref spdk_nvme_health_information_page */
3258 : SPDK_NVME_LOG_HEALTH_INFORMATION = 0x02,
3259 :
3260 : /** Firmware slot information (mandatory) - \ref spdk_nvme_firmware_page */
3261 : SPDK_NVME_LOG_FIRMWARE_SLOT = 0x03,
3262 :
3263 : /** Changed namespace list (optional) */
3264 : SPDK_NVME_LOG_CHANGED_NS_LIST = 0x04,
3265 :
3266 : /** Command effects log (optional) */
3267 : SPDK_NVME_LOG_COMMAND_EFFECTS_LOG = 0x05,
3268 :
3269 : /** Device self test (optional) */
3270 : SPDK_NVME_LOG_DEVICE_SELF_TEST = 0x06,
3271 :
3272 : /** Host initiated telemetry log (optional) */
3273 : SPDK_NVME_LOG_TELEMETRY_HOST_INITIATED = 0x07,
3274 :
3275 : /** Controller initiated telemetry log (optional) */
3276 : SPDK_NVME_LOG_TELEMETRY_CTRLR_INITIATED = 0x08,
3277 :
3278 : /** Endurance group Information (optional) */
3279 : SPDK_NVME_LOG_ENDURANCE_GROUP_INFORMATION = 0x09,
3280 :
3281 : /** Predictable latency per NVM set (optional) */
3282 : SPDK_NVME_LOG_PREDICATBLE_LATENCY = 0x0A,
3283 :
3284 : /** Predictable latency event aggregrate (optional) */
3285 : SPDK_NVME_LOG_PREDICTABLE_LATENCY_EVENT = 0x0B,
3286 :
3287 : /** Asymmetric namespace access log (optional) */
3288 : SPDK_NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS = 0x0C,
3289 :
3290 : /** Persistent event log (optional) */
3291 : SPDK_NVME_LOG_PERSISTENT_EVENT_LOG = 0x0D,
3292 :
3293 : /* 0x0E NVM command set specific */
3294 :
3295 : /** Endurance group event aggregate (optional) */
3296 : SPDK_NVME_LOG_ENDURANCE_GROUP_EVENT = 0x0F,
3297 :
3298 : /** Media unit status (optional) */
3299 : SPDK_NVME_LOG_MEDIA_UNIT_STATUS = 0x10,
3300 :
3301 : /** Supported capacity configuration list (optional) */
3302 : SPDK_NVME_LOG_CAPACITY_CONFIGURATION_LIST = 0x11,
3303 :
3304 : /** Feature identifiers supported and effects (optional) */
3305 : SPDK_NVME_LOG_FEATURE_IDS_EFFECTS = 0x12,
3306 :
3307 : /** NVMe-MI commands supported and effects (optional) */
3308 : SPDK_NVME_LOG_NVME_MI_COMMANDS_EFFECTS = 0x13,
3309 :
3310 : /** Command and feature lockdown (optional) */
3311 : SPDK_NVME_LOG_COMMAND_FEATURE_LOCKDOWN = 0x14,
3312 :
3313 : /** Boot partition (optional) */
3314 : SPDK_NVME_LOG_BOOT_PARTITION = 0x15,
3315 :
3316 : /** Rotational media information (optional) */
3317 : SPDK_NVME_LOG_ROTATIONAL_MEDIA_INFORMATION = 0x16,
3318 :
3319 : /* 0x17-0x1f - reserved */
3320 :
3321 : /** FDP configurations (optional) */
3322 : SPDK_NVME_LOG_FDP_CONFIGURATIONS = 0x20,
3323 :
3324 : /** Reclaim unit handle usage (optional) */
3325 : SPDK_NVME_LOG_RECLAIM_UNIT_HANDLE_USAGE = 0x21,
3326 :
3327 : /** FDP statistics (optional) */
3328 : SPDK_NVME_LOG_FDP_STATISTICS = 0x22,
3329 :
3330 : /** FDP events (optional) */
3331 : SPDK_NVME_LOG_FDP_EVENTS = 0x23,
3332 :
3333 : /* 0x24-0x6f - reserved */
3334 :
3335 : /** Discovery(refer to the NVMe over Fabrics specification) */
3336 : SPDK_NVME_LOG_DISCOVERY = 0x70,
3337 :
3338 : /* 0x71-0x7f - reserved for NVMe over Fabrics */
3339 :
3340 : /** Reservation notification (optional) */
3341 : SPDK_NVME_LOG_RESERVATION_NOTIFICATION = 0x80,
3342 :
3343 : /** Sanitize status (optional) */
3344 : SPDK_NVME_LOG_SANITIZE_STATUS = 0x81,
3345 :
3346 : /* 0x82-0xBE - I/O command set specific */
3347 :
3348 : /** Changed zone list (refer to Zoned Namespace command set) */
3349 : SPDK_NVME_LOG_CHANGED_ZONE_LIST = 0xBF,
3350 :
3351 : /* 0xC0-0xFF - vendor specific */
3352 : SPDK_NVME_LOG_VENDOR_SPECIFIC_START = 0xc0,
3353 : SPDK_NVME_LOG_VENDOR_SPECIFIC_END = 0xff,
3354 : };
3355 :
3356 : #define spdk_nvme_log_page_is_vendor_specific(lid) ((lid) >= SPDK_NVME_LOG_VENDOR_SPECIFIC_START)
3357 :
3358 : /**
3359 : * Error information log page (\ref SPDK_NVME_LOG_ERROR)
3360 : */
3361 : struct spdk_nvme_error_information_entry {
3362 : uint64_t error_count;
3363 : uint16_t sqid;
3364 : uint16_t cid;
3365 : struct spdk_nvme_status status;
3366 : uint16_t error_location;
3367 : uint64_t lba;
3368 : uint32_t nsid;
3369 : uint8_t vendor_specific;
3370 : uint8_t trtype;
3371 : uint8_t reserved30[2];
3372 : uint64_t command_specific;
3373 : uint16_t trtype_specific;
3374 : uint8_t reserved42[22];
3375 : };
3376 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_error_information_entry) == 64, "Incorrect size");
3377 :
3378 : /**
3379 : * SMART / health information page (\ref SPDK_NVME_LOG_HEALTH_INFORMATION)
3380 : */
3381 : #pragma pack(push, 1)
3382 : struct spdk_nvme_health_information_page {
3383 : union spdk_nvme_critical_warning_state critical_warning;
3384 :
3385 : uint16_t temperature;
3386 : uint8_t available_spare;
3387 : uint8_t available_spare_threshold;
3388 : uint8_t percentage_used;
3389 :
3390 : uint8_t reserved[26];
3391 :
3392 : /*
3393 : * Note that the following are 128-bit values, but are
3394 : * defined as an array of 2 64-bit values.
3395 : */
3396 : /* Data Units Read is always in 512-byte units. */
3397 : uint64_t data_units_read[2];
3398 : /* Data Units Written is always in 512-byte units. */
3399 : uint64_t data_units_written[2];
3400 : /* For NVM command set, this includes Compare commands. */
3401 : uint64_t host_read_commands[2];
3402 : uint64_t host_write_commands[2];
3403 : /* Controller Busy Time is reported in minutes. */
3404 : uint64_t controller_busy_time[2];
3405 : uint64_t power_cycles[2];
3406 : uint64_t power_on_hours[2];
3407 : uint64_t unsafe_shutdowns[2];
3408 : uint64_t media_errors[2];
3409 : uint64_t num_error_info_log_entries[2];
3410 : /* Controller temperature related. */
3411 : uint32_t warning_temp_time;
3412 : uint32_t critical_temp_time;
3413 : uint16_t temp_sensor[8];
3414 :
3415 : uint8_t reserved2[296];
3416 : };
3417 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_health_information_page) == 512, "Incorrect size");
3418 : #pragma pack(pop)
3419 :
3420 : /* Commands Supported and Effects Data Structure */
3421 : struct spdk_nvme_cmds_and_effect_entry {
3422 : /** Command Supported */
3423 : uint16_t csupp : 1;
3424 :
3425 : /** Logic Block Content Change */
3426 : uint16_t lbcc : 1;
3427 :
3428 : /** Namespace Capability Change */
3429 : uint16_t ncc : 1;
3430 :
3431 : /** Namespace Inventory Change */
3432 : uint16_t nic : 1;
3433 :
3434 : /** Controller Capability Change */
3435 : uint16_t ccc : 1;
3436 :
3437 : uint16_t reserved1 : 11;
3438 :
3439 : /* Command Submission and Execution recommendation
3440 : * 000 - No command submission or execution restriction
3441 : * 001 - Submitted when there is no outstanding command to same NS
3442 : * 010 - Submitted when there is no outstanding command to any NS
3443 : * others - Reserved
3444 : * \ref command_submission_and_execution in section 5.14.1.5 NVMe Revision 1.3
3445 : */
3446 : uint16_t cse : 3;
3447 :
3448 : uint16_t reserved2 : 13;
3449 : };
3450 :
3451 : /* Commands Supported and Effects Log Page */
3452 : struct spdk_nvme_cmds_and_effect_log_page {
3453 : /** Commands Supported and Effects Data Structure for the Admin Commands */
3454 : struct spdk_nvme_cmds_and_effect_entry admin_cmds_supported[256];
3455 :
3456 : /** Commands Supported and Effects Data Structure for the IO Commands */
3457 : struct spdk_nvme_cmds_and_effect_entry io_cmds_supported[256];
3458 :
3459 : uint8_t reserved0[2048];
3460 : };
3461 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_cmds_and_effect_log_page) == 4096, "Incorrect size");
3462 :
3463 : /*
3464 : * Get Log Page – Telemetry Host/Controller Initiated Log (Log Identifiers 07h/08h)
3465 : */
3466 : struct spdk_nvme_telemetry_log_page_hdr {
3467 : /* Log page identifier */
3468 : uint8_t lpi;
3469 : uint8_t rsvd[4];
3470 : uint8_t ieee_oui[3];
3471 : /* Data area 1 last block */
3472 : uint16_t dalb1;
3473 : /* Data area 2 last block */
3474 : uint16_t dalb2;
3475 : /* Data area 3 last block */
3476 : uint16_t dalb3;
3477 : uint8_t rsvd1[368];
3478 : /* Controller initiated data avail */
3479 : uint8_t ctrlr_avail;
3480 : /* Controller initiated telemetry data generation */
3481 : uint8_t ctrlr_gen;
3482 : /* Reason identifier */
3483 : uint8_t rsnident[128];
3484 : uint8_t telemetry_datablock[0];
3485 : };
3486 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_telemetry_log_page_hdr) == 512, "Incorrect size");
3487 :
3488 : /**
3489 : * Sanitize Status Type
3490 : */
3491 : enum spdk_nvme_sanitize_status_type {
3492 : SPDK_NVME_NEVER_BEEN_SANITIZED = 0x0,
3493 : SPDK_NVME_RECENT_SANITIZE_SUCCESSFUL = 0x1,
3494 : SPDK_NVME_SANITIZE_IN_PROGRESS = 0x2,
3495 : SPDK_NVME_SANITIZE_FAILED = 0x3,
3496 : };
3497 :
3498 : /**
3499 : * Sanitize status sstat field
3500 : */
3501 : struct spdk_nvme_sanitize_status_sstat {
3502 : uint16_t status : 3;
3503 : uint16_t complete_pass : 5;
3504 : uint16_t global_data_erase : 1;
3505 : uint16_t reserved : 7;
3506 : };
3507 :
3508 : /**
3509 : * Sanitize log page
3510 : */
3511 : struct spdk_nvme_sanitize_status_log_page {
3512 : /* Sanitize progress */
3513 : uint16_t sprog;
3514 : /* Sanitize status */
3515 : struct spdk_nvme_sanitize_status_sstat sstat;
3516 : /* CDW10 of sanitize command */
3517 : uint32_t scdw10;
3518 : /* Estimated overwrite time in seconds */
3519 : uint32_t et_overwrite;
3520 : /* Estimated block erase time in seconds */
3521 : uint32_t et_block_erase;
3522 : /* Estimated crypto erase time in seconds */
3523 : uint32_t et_crypto_erase;
3524 : uint8_t reserved[492];
3525 : };
3526 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_sanitize_status_log_page) == 512, "Incorrect size");
3527 :
3528 : /**
3529 : * Asynchronous Event Type
3530 : */
3531 : enum spdk_nvme_async_event_type {
3532 : /* Error Status */
3533 : SPDK_NVME_ASYNC_EVENT_TYPE_ERROR = 0x0,
3534 : /* SMART/Health Status */
3535 : SPDK_NVME_ASYNC_EVENT_TYPE_SMART = 0x1,
3536 : /* Notice */
3537 : SPDK_NVME_ASYNC_EVENT_TYPE_NOTICE = 0x2,
3538 : /* 0x3 - 0x5 Reserved */
3539 :
3540 : /* I/O Command Set Specific Status */
3541 : SPDK_NVME_ASYNC_EVENT_TYPE_IO = 0x6,
3542 : /* Vendor Specific */
3543 : SPDK_NVME_ASYNC_EVENT_TYPE_VENDOR = 0x7,
3544 : };
3545 :
3546 : /**
3547 : * Asynchronous Event Information for Error Status
3548 : */
3549 : enum spdk_nvme_async_event_info_error {
3550 : /* Write to Invalid Doorbell Register */
3551 : SPDK_NVME_ASYNC_EVENT_WRITE_INVALID_DB = 0x0,
3552 : /* Invalid Doorbell Register Write Value */
3553 : SPDK_NVME_ASYNC_EVENT_INVALID_DB_WRITE = 0x1,
3554 : /* Diagnostic Failure */
3555 : SPDK_NVME_ASYNC_EVENT_DIAGNOSTIC_FAILURE = 0x2,
3556 : /* Persistent Internal Error */
3557 : SPDK_NVME_ASYNC_EVENT_PERSISTENT_INTERNAL = 0x3,
3558 : /* Transient Internal Error */
3559 : SPDK_NVME_ASYNC_EVENT_TRANSIENT_INTERNAL = 0x4,
3560 : /* Firmware Image Load Error */
3561 : SPDK_NVME_ASYNC_EVENT_FW_IMAGE_LOAD = 0x5,
3562 :
3563 : /* 0x6 - 0xFF Reserved */
3564 : };
3565 :
3566 : /**
3567 : * Asynchronous Event Information for SMART/Health Status
3568 : */
3569 : enum spdk_nvme_async_event_info_smart {
3570 : /* NVM Subsystem Reliability */
3571 : SPDK_NVME_ASYNC_EVENT_SUBSYSTEM_RELIABILITY = 0x0,
3572 : /* Temperature Threshold */
3573 : SPDK_NVME_ASYNC_EVENT_TEMPERATURE_THRESHOLD = 0x1,
3574 : /* Spare Below Threshold */
3575 : SPDK_NVME_ASYNC_EVENT_SPARE_BELOW_THRESHOLD = 0x2,
3576 :
3577 : /* 0x3 - 0xFF Reserved */
3578 : };
3579 :
3580 : /**
3581 : * Asynchronous Event Information for Notice
3582 : */
3583 : enum spdk_nvme_async_event_info_notice {
3584 : /* Namespace Attribute Changed */
3585 : SPDK_NVME_ASYNC_EVENT_NS_ATTR_CHANGED = 0x0,
3586 : /* Firmware Activation Starting */
3587 : SPDK_NVME_ASYNC_EVENT_FW_ACTIVATION_START = 0x1,
3588 : /* Telemetry Log Changed */
3589 : SPDK_NVME_ASYNC_EVENT_TELEMETRY_LOG_CHANGED = 0x2,
3590 : /* Asymmetric Namespace Access Change */
3591 : SPDK_NVME_ASYNC_EVENT_ANA_CHANGE = 0x3,
3592 :
3593 : /* 0x4 - 0xEF Reserved */
3594 :
3595 : /** Discovery log change event(refer to the NVMe over Fabrics specification) */
3596 : SPDK_NVME_ASYNC_EVENT_DISCOVERY_LOG_CHANGE = 0xF0,
3597 :
3598 : /* 0xF1 - 0xFF Reserved */
3599 : };
3600 :
3601 : /**
3602 : * Asynchronous Event Information for NVM Command Set Specific Status
3603 : */
3604 : enum spdk_nvme_async_event_info_nvm_command_set {
3605 : /* Reservation Log Page Available */
3606 : SPDK_NVME_ASYNC_EVENT_RESERVATION_LOG_AVAIL = 0x0,
3607 : /* Sanitize Operation Completed */
3608 : SPDK_NVME_ASYNC_EVENT_SANITIZE_COMPLETED = 0x1,
3609 :
3610 : /* 0x2 - 0xFF Reserved */
3611 : };
3612 :
3613 : /**
3614 : * Asynchronous Event Request Completion
3615 : */
3616 : union spdk_nvme_async_event_completion {
3617 : uint32_t raw;
3618 : struct {
3619 : uint32_t async_event_type : 3;
3620 : uint32_t reserved1 : 5;
3621 : uint32_t async_event_info : 8;
3622 : uint32_t log_page_identifier : 8;
3623 : uint32_t reserved2 : 8;
3624 : } bits;
3625 : };
3626 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_async_event_completion) == 4, "Incorrect size");
3627 :
3628 : /**
3629 : * Firmware slot information page (\ref SPDK_NVME_LOG_FIRMWARE_SLOT)
3630 : */
3631 : struct spdk_nvme_firmware_page {
3632 : struct {
3633 : uint8_t active_slot : 3; /**< Slot for current FW */
3634 : uint8_t reserved3 : 1;
3635 : uint8_t next_reset_slot : 3; /**< Slot that will be active at next controller reset */
3636 : uint8_t reserved7 : 1;
3637 : } afi;
3638 :
3639 : uint8_t reserved[7];
3640 : uint8_t revision[7][8]; /** Revisions for 7 slots (ASCII strings) */
3641 : uint8_t reserved2[448];
3642 : };
3643 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_firmware_page) == 512, "Incorrect size");
3644 :
3645 : /**
3646 : * Asymmetric Namespace Access page (\ref SPDK_NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS)
3647 : */
3648 : struct spdk_nvme_ana_page {
3649 : uint64_t change_count;
3650 : uint16_t num_ana_group_desc;
3651 : uint8_t reserved[6];
3652 : };
3653 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ana_page) == 16, "Incorrect size");
3654 :
3655 : /* Asymmetric namespace access state */
3656 : enum spdk_nvme_ana_state {
3657 : SPDK_NVME_ANA_OPTIMIZED_STATE = 0x1,
3658 : SPDK_NVME_ANA_NON_OPTIMIZED_STATE = 0x2,
3659 : SPDK_NVME_ANA_INACCESSIBLE_STATE = 0x3,
3660 : SPDK_NVME_ANA_PERSISTENT_LOSS_STATE = 0x4,
3661 : SPDK_NVME_ANA_CHANGE_STATE = 0xF,
3662 : };
3663 :
3664 : /* ANA group descriptor */
3665 : struct spdk_nvme_ana_group_descriptor {
3666 : uint32_t ana_group_id;
3667 : uint32_t num_of_nsid;
3668 : uint64_t change_count;
3669 :
3670 : uint8_t ana_state : 4;
3671 : uint8_t reserved0 : 4;
3672 :
3673 : uint8_t reserved1[15];
3674 :
3675 : uint32_t nsid[];
3676 : };
3677 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ana_group_descriptor) == 32, "Incorrect size");
3678 :
3679 : /* Reclaim unit handle type */
3680 : enum spdk_nvme_fdp_ruh_type {
3681 : /* 0x0 Reserved */
3682 :
3683 : /* Reclaim unit handle type initially isolated */
3684 : SPDK_NVME_FDP_RUHT_INITIALLY_ISOLATED = 0x1,
3685 : /* Reclaim unit handle type persistently isolated */
3686 : SPDK_NVME_FDP_RUHT_PERSISTENTLY_ISOLATED = 0x2,
3687 :
3688 : /* 0x3 - 0xBF Reserved */
3689 :
3690 : /* 0xC0 - 0xFF Vendor specific */
3691 : };
3692 :
3693 : /* Reclaim unit handle descriptor */
3694 : struct spdk_nvme_fdp_ruh_descriptor {
3695 : /* Reclaim unit handle type */
3696 : uint8_t ruht;
3697 : uint8_t reserved[3];
3698 : };
3699 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_ruh_descriptor) == 4, "Incorrect size");
3700 :
3701 : /* FDP configuration descriptor */
3702 : struct spdk_nvme_fdp_cfg_descriptor {
3703 : /* Descriptor size */
3704 : uint16_t ds;
3705 :
3706 : /* FDP attributes */
3707 : union {
3708 : uint8_t raw;
3709 : struct {
3710 : /* Reclaim group identifier format */
3711 : uint8_t rgif : 4;
3712 : /* FDP volatile write cache */
3713 : uint8_t fdpvwc : 1;
3714 : uint8_t rsvd1 : 2;
3715 : /* FDP configuration valid */
3716 : uint8_t fdpcv : 1;
3717 : } bits;
3718 : } fdpa;
3719 :
3720 : /* Vendor specific size */
3721 : uint8_t vss;
3722 : /* Number of reclaim groups */
3723 : uint32_t nrg;
3724 : /* Number of reclaim unit handles */
3725 : uint16_t nruh;
3726 : /* Max placement identifiers */
3727 : uint16_t maxpids;
3728 : /* Number of namespaces supported */
3729 : uint32_t nns;
3730 : /* Reclaim unit nominal size */
3731 : uint64_t runs;
3732 : /* Estimated reclaim unit time limit */
3733 : uint32_t erutl;
3734 : uint8_t rsvd28[36];
3735 : struct spdk_nvme_fdp_ruh_descriptor ruh_desc[];
3736 : };
3737 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_cfg_descriptor) == 64, "Incorrect size");
3738 :
3739 : /* FDP configurations log page (\ref SPDK_NVME_LOG_FDP_CONFIGURATIONS) */
3740 : struct spdk_nvme_fdp_cfg_log_page {
3741 : /* Number of FDP configurations */
3742 : uint16_t ncfg;
3743 : /* Version of log page */
3744 : uint8_t version;
3745 : uint8_t reserved1;
3746 : /* Size of this log page in bytes */
3747 : uint32_t size;
3748 : uint8_t reserved2[8];
3749 : struct spdk_nvme_fdp_cfg_descriptor cfg_desc[];
3750 : };
3751 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_cfg_log_page) == 16, "Incorrect size");
3752 :
3753 : /* Reclaim unit handle attributes */
3754 : enum spdk_nvme_fdp_ruh_attributes {
3755 : /* Not used by a namespace */
3756 : SPDK_NVME_FDP_RUHA_UNUSED = 0x0,
3757 : /* Use a specific reclaim unit handle */
3758 : SPDK_NVME_FDP_RUHA_HOST_SPECIFIED = 0x1,
3759 : /* Use the only default reclaim unit handle */
3760 : SPDK_NVME_FDP_RUHA_CTRLR_SPECIFIED = 0x2,
3761 :
3762 : /* 0x3 - 0xFF Reserved */
3763 : };
3764 :
3765 : /* Reclaim unit handle usage descriptor */
3766 : struct spdk_nvme_fdp_ruhu_descriptor {
3767 : /* Reclaim unit handle attributes */
3768 : uint8_t ruha;
3769 : uint8_t reserved[7];
3770 : };
3771 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_ruhu_descriptor) == 8, "Incorrect size");
3772 :
3773 : /* Reclaim unit handle usage log page (\ref SPDK_NVME_LOG_RECLAIM_UNIT_HANDLE_USAGE) */
3774 : struct spdk_nvme_fdp_ruhu_log_page {
3775 : /* Number of Reclaim Unit Handles */
3776 : uint16_t nruh;
3777 : uint8_t reserved[6];
3778 : struct spdk_nvme_fdp_ruhu_descriptor ruhu_desc[];
3779 : };
3780 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_ruhu_log_page) == 8, "Incorrect size");
3781 :
3782 : /* FDP statistics log page (\ref SPDK_NVME_LOG_FDP_STATISTICS) */
3783 : struct spdk_nvme_fdp_stats_log_page {
3784 : /* Host bytes with metadata written */
3785 : uint64_t hbmw[2];
3786 : /* Media bytes with metadata written */
3787 : uint64_t mbmw[2];
3788 : /* Media bytes erased */
3789 : uint64_t mbe[2];
3790 : uint8_t rsvd48[16];
3791 : };
3792 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_stats_log_page) == 64, "Incorrect size");
3793 :
3794 : /* FDP report event types (cdw10 log specific parameter) */
3795 : enum spdk_nvme_fdp_report_event_type {
3796 : /* Report FDP controller events */
3797 : SPDK_NVME_FDP_REPORT_CTRL_EVENTS = 0x0,
3798 : /* Report FDP host events */
3799 : SPDK_NVME_FDP_REPORT_HOST_EVENTS = 0x1,
3800 : };
3801 :
3802 : /* FDP event type */
3803 : enum spdk_nvme_fdp_event_type {
3804 : /* FDP host events */
3805 : /* Reclaim unit not fully written to capacity */
3806 : SPDK_NVME_FDP_EVENT_RU_NOT_WRITTEN_CAPACITY = 0x0,
3807 : /* Reclaim unit time limit exceeded */
3808 : SPDK_NVME_FDP_EVENT_RU_TIME_LIMIT_EXCEEDED = 0x1,
3809 : /* Controller reset modified reclaim unit handles */
3810 : SPDK_NVME_FDP_EVENT_CTRLR_RESET_MODIFY_RUH = 0x2,
3811 : /* Invalid placement identifier */
3812 : SPDK_NVME_FDP_EVENT_INVALID_PLACEMENT_ID = 0x3,
3813 :
3814 : /* 0x4 - 0x6F Reserved */
3815 :
3816 : /* 0x70 - 0x7F Vendor specific */
3817 :
3818 : /* FDP controller events */
3819 : /* Media reallocated */
3820 : SPDK_NVME_FDP_EVENT_MEDIA_REALLOCATED = 0x80,
3821 : /* Implicitly modified reclaim unit handle */
3822 : SPDK_NVME_FDP_EVENT_IMPLICIT_MODIFIED_RUH = 0x81,
3823 :
3824 : /* 0x82 - 0xEF Reserved */
3825 :
3826 : /* 0xF0 - 0xFF Vendor specific */
3827 : };
3828 :
3829 : /* Media reallocated */
3830 : #pragma pack(push, 1)
3831 : struct spdk_nvme_fdp_event_media_reallocated {
3832 : /* Specific event flags */
3833 : union {
3834 : uint8_t raw;
3835 : struct {
3836 : /* LBA valid */
3837 : uint8_t lbav : 1;
3838 : uint8_t reserved : 7;
3839 : } bits;
3840 : } sef;
3841 :
3842 : uint8_t reserved1;
3843 : /* Number of LBAs moved */
3844 : uint16_t nlbam;
3845 : /* Logical block address */
3846 : uint64_t lba;
3847 : uint8_t reserved2[4];
3848 : };
3849 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_event_media_reallocated) == 16, "Incorrect size");
3850 :
3851 : /* FDP event */
3852 : struct spdk_nvme_fdp_event {
3853 : /* Event type */
3854 : uint8_t etype;
3855 :
3856 : /* FDP event flags */
3857 : union {
3858 : uint8_t raw;
3859 : struct {
3860 : /* Placement identifier valid */
3861 : uint8_t piv : 1;
3862 : /* NSID valid */
3863 : uint8_t nsidv : 1;
3864 : /* Location valid */
3865 : uint8_t lv : 1;
3866 : uint8_t reserved : 5;
3867 : } bits;
3868 : } fdpef;
3869 :
3870 : /* Placement identifier */
3871 : uint16_t pid;
3872 : /* Event timestamp */
3873 : uint64_t timestamp;
3874 : /* Namespace identifier */
3875 : uint32_t nsid;
3876 : /* Event type specific */
3877 : uint64_t event_type_specific[2];
3878 : /* Reclaim group identifier */
3879 : uint16_t rgid;
3880 : /* Reclaim unit handle identifier */
3881 : uint16_t ruhid;
3882 : uint8_t reserved[4];
3883 : uint8_t vs[24];
3884 : };
3885 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_event) == 64, "Incorrect size");
3886 : #pragma pack(pop)
3887 :
3888 : /* FDP events log page (\ref SPDK_NVME_LOG_FDP_EVENTS) */
3889 : struct spdk_nvme_fdp_events_log_page {
3890 : /* Number of FDP events */
3891 : uint32_t nevents;
3892 : uint8_t reserved[60];
3893 : struct spdk_nvme_fdp_event event[];
3894 : };
3895 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_events_log_page) == 64, "Incorrect size");
3896 :
3897 : /**
3898 : * Namespace attachment Type Encoding
3899 : */
3900 : enum spdk_nvme_ns_attach_type {
3901 : /* Controller attach */
3902 : SPDK_NVME_NS_CTRLR_ATTACH = 0x0,
3903 :
3904 : /* Controller detach */
3905 : SPDK_NVME_NS_CTRLR_DETACH = 0x1,
3906 :
3907 : /* 0x2-0xF - Reserved */
3908 : };
3909 :
3910 : /**
3911 : * Namespace management Type Encoding
3912 : */
3913 : enum spdk_nvme_ns_management_type {
3914 : /* Create */
3915 : SPDK_NVME_NS_MANAGEMENT_CREATE = 0x0,
3916 :
3917 : /* Delete */
3918 : SPDK_NVME_NS_MANAGEMENT_DELETE = 0x1,
3919 :
3920 : /* 0x2-0xF - Reserved */
3921 : };
3922 :
3923 : struct spdk_nvme_ns_list {
3924 : uint32_t ns_list[1024];
3925 : };
3926 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_list) == 4096, "Incorrect size");
3927 :
3928 : /**
3929 : * Namespace identification descriptor type
3930 : *
3931 : * \sa spdk_nvme_ns_id_desc
3932 : */
3933 : enum spdk_nvme_nidt {
3934 : /** IEEE Extended Unique Identifier */
3935 : SPDK_NVME_NIDT_EUI64 = 0x01,
3936 :
3937 : /** Namespace GUID */
3938 : SPDK_NVME_NIDT_NGUID = 0x02,
3939 :
3940 : /** Namespace UUID */
3941 : SPDK_NVME_NIDT_UUID = 0x03,
3942 :
3943 : /** Namespace Command Set Identifier */
3944 : SPDK_NVME_NIDT_CSI = 0x04,
3945 : };
3946 :
3947 : struct spdk_nvme_ns_id_desc {
3948 : /** Namespace identifier type */
3949 : uint8_t nidt;
3950 :
3951 : /** Namespace identifier length (length of nid field) */
3952 : uint8_t nidl;
3953 :
3954 : uint8_t reserved2;
3955 : uint8_t reserved3;
3956 :
3957 : /** Namespace identifier */
3958 : uint8_t nid[];
3959 : };
3960 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_id_desc) == 4, "Incorrect size");
3961 :
3962 : struct spdk_nvme_ctrlr_list {
3963 : uint16_t ctrlr_count;
3964 : uint16_t ctrlr_list[2047];
3965 : };
3966 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ctrlr_list) == 4096, "Incorrect size");
3967 :
3968 : enum spdk_nvme_csi {
3969 : SPDK_NVME_CSI_NVM = 0x0,
3970 : SPDK_NVME_CSI_KV = 0x1,
3971 : SPDK_NVME_CSI_ZNS = 0x2,
3972 : };
3973 :
3974 : enum spdk_nvme_secure_erase_setting {
3975 : SPDK_NVME_FMT_NVM_SES_NO_SECURE_ERASE = 0x0,
3976 : SPDK_NVME_FMT_NVM_SES_USER_DATA_ERASE = 0x1,
3977 : SPDK_NVME_FMT_NVM_SES_CRYPTO_ERASE = 0x2,
3978 : };
3979 :
3980 : enum spdk_nvme_pi_location {
3981 : SPDK_NVME_FMT_NVM_PROTECTION_AT_TAIL = 0x0,
3982 : SPDK_NVME_FMT_NVM_PROTECTION_AT_HEAD = 0x1,
3983 : };
3984 :
3985 : enum spdk_nvme_pi_type {
3986 : SPDK_NVME_FMT_NVM_PROTECTION_DISABLE = 0x0,
3987 : SPDK_NVME_FMT_NVM_PROTECTION_TYPE1 = 0x1,
3988 : SPDK_NVME_FMT_NVM_PROTECTION_TYPE2 = 0x2,
3989 : SPDK_NVME_FMT_NVM_PROTECTION_TYPE3 = 0x3,
3990 : };
3991 :
3992 : enum spdk_nvme_metadata_setting {
3993 : SPDK_NVME_FMT_NVM_METADATA_TRANSFER_AS_BUFFER = 0x0,
3994 : SPDK_NVME_FMT_NVM_METADATA_TRANSFER_AS_LBA = 0x1,
3995 : };
3996 :
3997 : /* Format - Command Dword 10 */
3998 : struct spdk_nvme_format {
3999 : /* LBA format lower (LSB 4 bits of format index), also called lbafl in 2.0 spec */
4000 : uint32_t lbaf : 4;
4001 : /* Metadata settings, also called mset in 2.0 spec */
4002 : uint32_t ms : 1;
4003 : /* Protection information */
4004 : uint32_t pi : 3;
4005 : /* Protection information location */
4006 : uint32_t pil : 1;
4007 : /* Secure erase settings */
4008 : uint32_t ses : 3;
4009 : /* LBA format upper (MSB 2 bits of format index) */
4010 : uint32_t lbafu : 2;
4011 : uint32_t reserved : 18;
4012 : };
4013 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_format) == 4, "Incorrect size");
4014 :
4015 : struct spdk_nvme_protection_info {
4016 : uint16_t guard;
4017 : uint16_t app_tag;
4018 : uint32_t ref_tag;
4019 : };
4020 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_protection_info) == 8, "Incorrect size");
4021 :
4022 : /* Data structures for sanitize command */
4023 : /* Sanitize - Command Dword 10 */
4024 : struct spdk_nvme_sanitize {
4025 : /* Sanitize Action (SANACT) */
4026 : uint32_t sanact : 3;
4027 : /* Allow Unrestricted Sanitize Exit (AUSE) */
4028 : uint32_t ause : 1;
4029 : /* Overwrite Pass Count (OWPASS) */
4030 : uint32_t owpass : 4;
4031 : /* Overwrite Invert Pattern Between Passes */
4032 : uint32_t oipbp : 1;
4033 : /* No Deallocate after sanitize (NDAS) */
4034 : uint32_t ndas : 1;
4035 : /* reserved */
4036 : uint32_t reserved : 22;
4037 : };
4038 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_sanitize) == 4, "Incorrect size");
4039 :
4040 : /* Sanitize Action */
4041 : enum spdk_sanitize_action {
4042 : /* Exit Failure Mode */
4043 : SPDK_NVME_SANITIZE_EXIT_FAILURE_MODE = 0x1,
4044 : /* Start a Block Erase sanitize operation */
4045 : SPDK_NVME_SANITIZE_BLOCK_ERASE = 0x2,
4046 : /* Start an Overwrite sanitize operation */
4047 : SPDK_NVME_SANITIZE_OVERWRITE = 0x3,
4048 : /* Start a Crypto Erase sanitize operation */
4049 : SPDK_NVME_SANITIZE_CRYPTO_ERASE = 0x4,
4050 : };
4051 :
4052 : /** Parameters for SPDK_NVME_OPC_FIRMWARE_COMMIT cdw10: commit action */
4053 : enum spdk_nvme_fw_commit_action {
4054 : /**
4055 : * Downloaded image replaces the image specified by
4056 : * the Firmware Slot field. This image is not activated.
4057 : */
4058 : SPDK_NVME_FW_COMMIT_REPLACE_IMG = 0x0,
4059 : /**
4060 : * Downloaded image replaces the image specified by
4061 : * the Firmware Slot field. This image is activated at the next reset.
4062 : */
4063 : SPDK_NVME_FW_COMMIT_REPLACE_AND_ENABLE_IMG = 0x1,
4064 : /**
4065 : * The image specified by the Firmware Slot field is
4066 : * activated at the next reset.
4067 : */
4068 : SPDK_NVME_FW_COMMIT_ENABLE_IMG = 0x2,
4069 : /**
4070 : * The image specified by the Firmware Slot field is
4071 : * requested to be activated immediately without reset.
4072 : */
4073 : SPDK_NVME_FW_COMMIT_RUN_IMG = 0x3,
4074 : /**
4075 : * Downloaded image replaces the Boot Partition specified by
4076 : * the Boot Partition ID field.
4077 : */
4078 : SPDK_NVME_FW_COMMIT_REPLACE_BOOT_PARTITION = 0x6,
4079 : /**
4080 : * Mark the Boot Partition specified in the BPID field as Active
4081 : * and update BPINFO.ABPID.
4082 : */
4083 : SPDK_NVME_FW_COMMIT_ACTIVATE_BOOT_PARTITION = 0x7,
4084 : };
4085 :
4086 : /** Parameters for SPDK_NVME_OPC_FIRMWARE_COMMIT cdw10 */
4087 : struct spdk_nvme_fw_commit {
4088 : /**
4089 : * Firmware Slot. Specifies the firmware slot that shall be used for the
4090 : * Commit Action. The controller shall choose the firmware slot (slot 1 - 7)
4091 : * to use for the operation if the value specified is 0h.
4092 : */
4093 : uint32_t fs : 3;
4094 : /**
4095 : * Commit Action. Specifies the action that is taken on the image downloaded
4096 : * with the Firmware Image Download command or on a previously downloaded and
4097 : * placed image.
4098 : */
4099 : uint32_t ca : 3;
4100 : uint32_t reserved : 25;
4101 : /**
4102 : * Boot Partition ID. Specifies the boot partition that shall be used for the
4103 : * Commit Action.
4104 : */
4105 : uint32_t bpid : 1;
4106 : };
4107 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fw_commit) == 4, "Incorrect size");
4108 :
4109 : /* ZNS Zone Send Action (ZSA) cdw13 */
4110 : enum spdk_nvme_zns_zone_send_action {
4111 : SPDK_NVME_ZONE_CLOSE = 0x1,
4112 : SPDK_NVME_ZONE_FINISH = 0x2,
4113 : SPDK_NVME_ZONE_OPEN = 0x3,
4114 : SPDK_NVME_ZONE_RESET = 0x4,
4115 : SPDK_NVME_ZONE_OFFLINE = 0x5,
4116 : SPDK_NVME_ZONE_SET_ZDE = 0x10,
4117 : };
4118 :
4119 : /* ZNS Zone Receive Action (ZRA) cdw13 */
4120 : enum spdk_nvme_zns_zone_receive_action {
4121 : SPDK_NVME_ZONE_REPORT = 0x0,
4122 : SPDK_NVME_ZONE_EXTENDED_REPORT = 0x1,
4123 : };
4124 :
4125 : enum spdk_nvme_zns_zra_report_opts {
4126 : SPDK_NVME_ZRA_LIST_ALL = 0x0,
4127 : SPDK_NVME_ZRA_LIST_ZSE = 0x1,
4128 : SPDK_NVME_ZRA_LIST_ZSIO = 0x2,
4129 : SPDK_NVME_ZRA_LIST_ZSEO = 0x3,
4130 : SPDK_NVME_ZRA_LIST_ZSC = 0x4,
4131 : SPDK_NVME_ZRA_LIST_ZSF = 0x5,
4132 : SPDK_NVME_ZRA_LIST_ZSRO = 0x6,
4133 : SPDK_NVME_ZRA_LIST_ZSO = 0x7,
4134 : };
4135 :
4136 : enum spdk_nvme_zns_zone_type {
4137 : SPDK_NVME_ZONE_TYPE_SEQWR = 0x2,
4138 : };
4139 :
4140 : enum spdk_nvme_zns_zone_state {
4141 : SPDK_NVME_ZONE_STATE_EMPTY = 0x1,
4142 : SPDK_NVME_ZONE_STATE_IOPEN = 0x2,
4143 : SPDK_NVME_ZONE_STATE_EOPEN = 0x3,
4144 : SPDK_NVME_ZONE_STATE_CLOSED = 0x4,
4145 : SPDK_NVME_ZONE_STATE_RONLY = 0xD,
4146 : SPDK_NVME_ZONE_STATE_FULL = 0xE,
4147 : SPDK_NVME_ZONE_STATE_OFFLINE = 0xF,
4148 : };
4149 :
4150 : struct spdk_nvme_zns_zone_desc {
4151 : /** Zone Type */
4152 : uint8_t zt : 4;
4153 :
4154 : uint8_t rsvd0 : 4;
4155 :
4156 : uint8_t rsvd1 : 4;
4157 :
4158 : /** Zone State */
4159 : uint8_t zs : 4;
4160 :
4161 : /**
4162 : * Zone Attributes
4163 : */
4164 : union {
4165 : uint8_t raw;
4166 :
4167 : struct {
4168 : /** Zone Finished by controller */
4169 : uint8_t zfc: 1;
4170 :
4171 : /** Finish Zone Recommended */
4172 : uint8_t fzr: 1;
4173 :
4174 : /** Reset Zone Recommended */
4175 : uint8_t rzr: 1;
4176 :
4177 : uint8_t rsvd3 : 4;
4178 :
4179 : /** Zone Descriptor Extension Valid */
4180 : uint8_t zdev: 1;
4181 : } bits;
4182 : } za;
4183 :
4184 : uint8_t reserved[5];
4185 :
4186 : /** Zone Capacity (in number of LBAs) */
4187 : uint64_t zcap;
4188 :
4189 : /** Zone Start LBA */
4190 : uint64_t zslba;
4191 :
4192 : /** Write Pointer (LBA) */
4193 : uint64_t wp;
4194 :
4195 : uint8_t reserved32[32];
4196 : };
4197 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_zns_zone_desc) == 64, "Incorrect size");
4198 :
4199 : struct spdk_nvme_zns_zone_report {
4200 : uint64_t nr_zones;
4201 : uint8_t reserved8[56];
4202 : struct spdk_nvme_zns_zone_desc descs[];
4203 : };
4204 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_zns_zone_report) == 64, "Incorrect size");
4205 :
4206 : /* Directives field */
4207 : enum spdk_nvme_directive_type {
4208 : SPDK_NVME_DIRECTIVE_TYPE_IDENTIFY = 0x0,
4209 : SPDK_NVME_DIRECTIVE_TYPE_STREAMS = 0x1,
4210 : SPDK_NVME_DIRECTIVE_TYPE_DATA_PLACEMENT = 0x2,
4211 : };
4212 :
4213 : enum spdk_nvme_identify_directive_send_operation {
4214 : SPDK_NVME_IDENTIFY_DIRECTIVE_SEND_ENABLED = 0x1,
4215 : };
4216 :
4217 : enum spdk_nvme_identify_directive_receive_operation {
4218 : SPDK_NVME_IDENTIFY_DIRECTIVE_RECEIVE_RETURN_PARAM = 0x1,
4219 : };
4220 :
4221 : struct spdk_nvme_ns_identify_directive_param {
4222 : struct {
4223 : /* set to 1b to indicate that the Identify Directive is supported */
4224 : uint8_t identify : 1;
4225 : /* set to 1b if the Streams Directive is supported */
4226 : uint8_t streams : 1;
4227 : /* set to 1b if the Data Placement Directive is supported */
4228 : uint8_t data_pd : 1;
4229 : uint8_t reserved1 : 5;
4230 : uint8_t reserved2[31];
4231 : } directives_supported;
4232 : struct {
4233 : /* set to 1b to indicate that the Identify Directive is enabled */
4234 : uint8_t identify : 1;
4235 : /* set to 1b if the Streams Directive is enabled */
4236 : uint8_t streams : 1;
4237 : /* set to 1b if the Data Placement Directive is enabled */
4238 : uint8_t data_pd : 1;
4239 : uint8_t reserved1 : 5;
4240 : uint8_t reserved2[31];
4241 : } directives_enabled;
4242 : struct {
4243 : /**
4244 : * cleared to 0b as the host is not able to change the state of
4245 : * Identify Directive
4246 : */
4247 : uint8_t identify : 1;
4248 : /**
4249 : * cleared to 0b to indicate that the Streams Directive state
4250 : * is not preserved across ctrl reset
4251 : */
4252 : uint8_t streams : 1;
4253 : /**
4254 : * set to 1b if the Data Placement Directive is supported to
4255 : * indicate that the host specified Data Placement Directive
4256 : * state is preserved across ctrl reset
4257 : */
4258 : uint8_t data_pd : 1;
4259 : uint8_t reserved1 : 5;
4260 : uint8_t reserved2[31];
4261 : } directives_persistence;
4262 :
4263 : uint32_t reserved[1000];
4264 : };
4265 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_identify_directive_param) == 4096, "Incorrect size");
4266 :
4267 : enum spdk_nvme_streams_directive_receive_operation {
4268 : SPDK_NVME_STREAMS_DIRECTIVE_RECEIVE_RETURN_PARAM = 0x1,
4269 : SPDK_NVME_STREAMS_DIRECTIVE_RECEIVE_GET_STATUS = 0x2,
4270 : SPDK_NVME_STREAMS_DIRECTIVE_RECEIVE_ALLOCATE_RESOURCE = 0x3,
4271 : };
4272 :
4273 : enum spdk_nvme_streams_directive_send_operation {
4274 : SPDK_NVME_STREAMS_DIRECTIVE_SEND_RELEASE_ID = 0x1,
4275 : SPDK_NVME_STREAMS_DIRECTIVE_SEND_RELEASE_RESOURCE = 0x2,
4276 : };
4277 :
4278 : struct spdk_nvme_ns_streams_data {
4279 : /* MAX Streams Limit */
4280 : uint16_t msl;
4281 : /* NVM Subsystem Streams Available */
4282 : uint16_t nssa;
4283 : /* NVM Subsystem Streams Open */
4284 : uint16_t nsso;
4285 : /* NVM Subsystem Stream Capability */
4286 : struct {
4287 : /* Stream ID may be shared by multiple host IDs if set to 1. */
4288 : uint8_t ssid : 1;
4289 : uint8_t reserved : 7;
4290 : } nssc;
4291 : uint8_t reserved1[9];
4292 : /* Namespace Specific Fields
4293 : * Stream Write Size */
4294 : uint32_t sws;
4295 : /* Stream Granularity Size */
4296 : uint16_t sgs;
4297 : /* Namespace and Host Identifier Specific Fields
4298 : * Namespace Streams Allocated */
4299 : uint16_t nsa;
4300 : /* Namespace Streams Open */
4301 : uint16_t nso;
4302 : uint8_t reserved2[6];
4303 : };
4304 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_streams_data) == 32, "Incorrect size");
4305 :
4306 : struct spdk_nvme_ns_streams_status {
4307 : /* Open Stream Count, this field specifies the number of streams that are currently open */
4308 : uint16_t open_streams_count;
4309 :
4310 : /* Stream Identifier, this field specifies the open stream identifier */
4311 : uint16_t stream_id[65535];
4312 : };
4313 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_streams_status) == 131072, "Incorrect size");
4314 :
4315 : #define spdk_nvme_cpl_is_error(cpl) \
4316 : ((cpl)->status.sc != SPDK_NVME_SC_SUCCESS || \
4317 : (cpl)->status.sct != SPDK_NVME_SCT_GENERIC)
4318 :
4319 : #define spdk_nvme_cpl_is_success(cpl) (!spdk_nvme_cpl_is_error(cpl))
4320 :
4321 : #define spdk_nvme_cpl_is_pi_error(cpl) \
4322 : ((cpl)->status.sct == SPDK_NVME_SCT_MEDIA_ERROR && \
4323 : ((cpl)->status.sc == SPDK_NVME_SC_GUARD_CHECK_ERROR || \
4324 : (cpl)->status.sc == SPDK_NVME_SC_APPLICATION_TAG_CHECK_ERROR || \
4325 : (cpl)->status.sc == SPDK_NVME_SC_REFERENCE_TAG_CHECK_ERROR))
4326 :
4327 : #define spdk_nvme_cpl_is_abort_success(cpl) \
4328 : (spdk_nvme_cpl_is_success(cpl) && !((cpl)->cdw0 & 1U))
4329 :
4330 : #define spdk_nvme_cpl_is_path_error(cpl) \
4331 : ((cpl)->status.sct == SPDK_NVME_SCT_PATH)
4332 :
4333 : #define spdk_nvme_cpl_is_ana_error(cpl) \
4334 : ((cpl)->status.sct == SPDK_NVME_SCT_PATH && \
4335 : ((cpl)->status.sc == SPDK_NVME_SC_ASYMMETRIC_ACCESS_PERSISTENT_LOSS || \
4336 : (cpl)->status.sc == SPDK_NVME_SC_ASYMMETRIC_ACCESS_INACCESSIBLE || \
4337 : (cpl)->status.sc == SPDK_NVME_SC_ASYMMETRIC_ACCESS_TRANSITION))
4338 :
4339 : #define spdk_nvme_cpl_is_aborted_sq_deletion(cpl) \
4340 : ((cpl)->status.sct == SPDK_NVME_SCT_GENERIC && \
4341 : (cpl)->status.sc == SPDK_NVME_SC_ABORTED_SQ_DELETION)
4342 :
4343 : #define spdk_nvme_cpl_is_aborted_by_request(cpl) \
4344 : ((cpl)->status.sct == SPDK_NVME_SCT_GENERIC && \
4345 : (cpl)->status.sc == SPDK_NVME_SC_ABORTED_BY_REQUEST)
4346 :
4347 : /** Set fused operation */
4348 : #define SPDK_NVME_IO_FLAGS_FUSE_FIRST (SPDK_NVME_CMD_FUSE_FIRST << 0)
4349 : #define SPDK_NVME_IO_FLAGS_FUSE_SECOND (SPDK_NVME_CMD_FUSE_SECOND << 0)
4350 : #define SPDK_NVME_IO_FLAGS_FUSE_MASK (SPDK_NVME_CMD_FUSE_MASK << 0)
4351 : /** Enable Directive type as streams */
4352 : #define SPDK_NVME_IO_FLAGS_STREAMS_DIRECTIVE (1U << 20)
4353 : /** Enable Directive type as data placement */
4354 : #define SPDK_NVME_IO_FLAGS_DATA_PLACEMENT_DIRECTIVE (2U << 20)
4355 : /** Zone append specific, determines the contents of the reference tag written to the media */
4356 : #define SPDK_NVME_IO_FLAGS_ZONE_APPEND_PIREMAP (1U << 25)
4357 : /** Enable protection information checking of the Logical Block Reference Tag field */
4358 : #define SPDK_NVME_IO_FLAGS_PRCHK_REFTAG (1U << 26)
4359 : /** Enable protection information checking of the Application Tag field */
4360 : #define SPDK_NVME_IO_FLAGS_PRCHK_APPTAG (1U << 27)
4361 : /** Enable protection information checking of the Guard field */
4362 : #define SPDK_NVME_IO_FLAGS_PRCHK_GUARD (1U << 28)
4363 : /** The protection information is stripped or inserted when set this bit */
4364 : #define SPDK_NVME_IO_FLAGS_PRACT (1U << 29)
4365 : #define SPDK_NVME_IO_FLAGS_FORCE_UNIT_ACCESS (1U << 30)
4366 : #define SPDK_NVME_IO_FLAGS_LIMITED_RETRY (1U << 31)
4367 :
4368 : /** Mask of valid io flags mask */
4369 : #define SPDK_NVME_IO_FLAGS_VALID_MASK 0xFFFF0003
4370 : #define SPDK_NVME_IO_FLAGS_CDW12_MASK 0xFFFF0000
4371 :
4372 : /** Identify command buffer response size */
4373 : #define SPDK_NVME_IDENTIFY_BUFLEN 4096
4374 :
4375 : #ifdef __cplusplus
4376 : }
4377 : #endif
4378 :
4379 : #endif
|