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 nlb : 16;
1307 : uint32_t reserved : 4;
1308 : /* Directive Type */
1309 : uint32_t dtype : 4;
1310 : /* Storage Tag Check */
1311 : uint32_t stc : 1;
1312 : uint32_t reserved2 : 1;
1313 : /* Protection Information Check */
1314 : uint32_t prchk : 3;
1315 : /* Protection Information Action */
1316 : uint32_t pract : 1;
1317 : /* Force Unit Access */
1318 : uint32_t fua : 1;
1319 : /* Limited Retry */
1320 : uint32_t lr : 1;
1321 : } write;
1322 :
1323 : struct {
1324 : /* Number of Ranges */
1325 : uint32_t nr : 8;
1326 : /* Desciptor Format */
1327 : uint32_t df : 4;
1328 : /* Protection Information Field Read */
1329 : uint32_t prinfor : 4;
1330 : uint32_t reserved : 4;
1331 : /* Directive Type */
1332 : uint32_t dtype : 4;
1333 : /* Storage Tag Check Write */
1334 : uint32_t stcw : 1;
1335 : uint32_t reserved2 : 1;
1336 : /* Protection Information Field Write */
1337 : uint32_t prinfow : 4;
1338 : /* Force Unit Access */
1339 : uint32_t fua : 1;
1340 : /* Limited Retry */
1341 : uint32_t lr : 1;
1342 : } copy;
1343 :
1344 : struct {
1345 : /* Number of Logical Blocks */
1346 : uint32_t nlb : 16;
1347 : uint32_t reserved : 8;
1348 : /* Storage Tag Check */
1349 : uint32_t stc : 1;
1350 : /* Deallocate */
1351 : uint32_t deac : 1;
1352 : /* Protection Information Check */
1353 : uint32_t prchk : 3;
1354 : /* Protection Information Action */
1355 : uint32_t pract : 1;
1356 : /* Force Unit Access */
1357 : uint32_t fua : 1;
1358 : /* Limited Retry */
1359 : uint32_t lr : 1;
1360 : } write_zeroes;
1361 :
1362 : union spdk_nvme_feat_fdp_cdw12 feat_fdp_cdw12;
1363 : union spdk_nvme_feat_fdp_events_cdw12 feat_fdp_events_cdw12;
1364 : };
1365 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmd_cdw12) == 4, "Incorrect size");
1366 :
1367 : union spdk_nvme_cmd_cdw13 {
1368 : uint32_t raw;
1369 :
1370 : struct {
1371 : /* Dataset Management */
1372 : uint32_t dsm : 8;
1373 : uint32_t reserved : 8;
1374 : /* Directive Specific */
1375 : uint32_t dspec : 16;
1376 : } write;
1377 : };
1378 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmd_cdw13) == 4, "Incorrect size");
1379 :
1380 : struct spdk_nvme_cmd {
1381 : /* dword 0 */
1382 : uint16_t opc : 8; /* opcode */
1383 : uint16_t fuse : 2; /* fused operation */
1384 : uint16_t rsvd1 : 4;
1385 : uint16_t psdt : 2;
1386 : uint16_t cid; /* command identifier */
1387 :
1388 : /* dword 1 */
1389 : uint32_t nsid; /* namespace identifier */
1390 :
1391 : /* dword 2-3 */
1392 : uint32_t rsvd2;
1393 : uint32_t rsvd3;
1394 :
1395 : /* dword 4-5 */
1396 : uint64_t mptr; /* metadata pointer */
1397 :
1398 : /* dword 6-9: data pointer */
1399 : union {
1400 : struct {
1401 : uint64_t prp1; /* prp entry 1 */
1402 : uint64_t prp2; /* prp entry 2 */
1403 : } prp;
1404 :
1405 : struct spdk_nvme_sgl_descriptor sgl1;
1406 : } dptr;
1407 :
1408 : /* command-specific */
1409 : union {
1410 : uint32_t cdw10;
1411 : union spdk_nvme_cmd_cdw10 cdw10_bits;
1412 : };
1413 : /* command-specific */
1414 : union {
1415 : uint32_t cdw11;
1416 : union spdk_nvme_cmd_cdw11 cdw11_bits;
1417 : };
1418 : /* command-specific */
1419 : union {
1420 : uint32_t cdw12;
1421 : union spdk_nvme_cmd_cdw12 cdw12_bits;
1422 : };
1423 : /* command-specific */
1424 : union {
1425 : uint32_t cdw13;
1426 : union spdk_nvme_cmd_cdw13 cdw13_bits;
1427 : };
1428 : /* dword 14-15 */
1429 : uint32_t cdw14; /* command-specific */
1430 : uint32_t cdw15; /* command-specific */
1431 : };
1432 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_cmd) == 64, "Incorrect size");
1433 :
1434 : struct spdk_nvme_status {
1435 : uint16_t p : 1; /* phase tag */
1436 : uint16_t sc : 8; /* status code */
1437 : uint16_t sct : 3; /* status code type */
1438 : uint16_t crd : 2; /* command retry delay */
1439 : uint16_t m : 1; /* more */
1440 : uint16_t dnr : 1; /* do not retry */
1441 : };
1442 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_status) == 2, "Incorrect size");
1443 :
1444 : /**
1445 : * Completion queue entry
1446 : */
1447 : struct spdk_nvme_cpl {
1448 : /* dword 0 */
1449 : uint32_t cdw0; /* command-specific */
1450 :
1451 : /* dword 1 */
1452 : uint32_t cdw1; /* command-specific */
1453 :
1454 : /* dword 2 */
1455 : uint16_t sqhd; /* submission queue head pointer */
1456 : uint16_t sqid; /* submission queue identifier */
1457 :
1458 : /* dword 3 */
1459 : uint16_t cid; /* command identifier */
1460 : union {
1461 : uint16_t status_raw;
1462 : struct spdk_nvme_status status;
1463 : };
1464 : };
1465 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_cpl) == 16, "Incorrect size");
1466 :
1467 : /**
1468 : * Dataset Management range
1469 : */
1470 : struct spdk_nvme_dsm_range {
1471 : union {
1472 : struct {
1473 : uint32_t af : 4; /**< access frequency */
1474 : uint32_t al : 2; /**< access latency */
1475 : uint32_t reserved0 : 2;
1476 :
1477 : uint32_t sr : 1; /**< sequential read range */
1478 : uint32_t sw : 1; /**< sequential write range */
1479 : uint32_t wp : 1; /**< write prepare */
1480 : uint32_t reserved1 : 13;
1481 :
1482 : uint32_t access_size : 8; /**< command access size */
1483 : } bits;
1484 :
1485 : uint32_t raw;
1486 : } attributes;
1487 :
1488 : uint32_t length;
1489 : uint64_t starting_lba;
1490 : };
1491 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_dsm_range) == 16, "Incorrect size");
1492 :
1493 : /**
1494 : * Simple Copy Command source range
1495 : */
1496 : struct spdk_nvme_scc_source_range {
1497 : uint64_t reserved0;
1498 : uint64_t slba;
1499 : uint16_t nlb;
1500 : uint16_t reserved18;
1501 : uint32_t reserved20;
1502 : uint32_t eilbrt;
1503 : uint16_t elbat;
1504 : uint16_t elbatm;
1505 : };
1506 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_scc_source_range) == 32, "Incorrect size");
1507 :
1508 : /**
1509 : * Status code types
1510 : */
1511 : enum spdk_nvme_status_code_type {
1512 : SPDK_NVME_SCT_GENERIC = 0x0,
1513 : SPDK_NVME_SCT_COMMAND_SPECIFIC = 0x1,
1514 : SPDK_NVME_SCT_MEDIA_ERROR = 0x2,
1515 : SPDK_NVME_SCT_PATH = 0x3,
1516 : /* 0x4-0x6 - reserved */
1517 : SPDK_NVME_SCT_VENDOR_SPECIFIC = 0x7,
1518 : };
1519 :
1520 : /**
1521 : * Generic command status codes
1522 : */
1523 : enum spdk_nvme_generic_command_status_code {
1524 : SPDK_NVME_SC_SUCCESS = 0x00,
1525 : SPDK_NVME_SC_INVALID_OPCODE = 0x01,
1526 : SPDK_NVME_SC_INVALID_FIELD = 0x02,
1527 : SPDK_NVME_SC_COMMAND_ID_CONFLICT = 0x03,
1528 : SPDK_NVME_SC_DATA_TRANSFER_ERROR = 0x04,
1529 : SPDK_NVME_SC_ABORTED_POWER_LOSS = 0x05,
1530 : SPDK_NVME_SC_INTERNAL_DEVICE_ERROR = 0x06,
1531 : SPDK_NVME_SC_ABORTED_BY_REQUEST = 0x07,
1532 : SPDK_NVME_SC_ABORTED_SQ_DELETION = 0x08,
1533 : SPDK_NVME_SC_ABORTED_FAILED_FUSED = 0x09,
1534 : SPDK_NVME_SC_ABORTED_MISSING_FUSED = 0x0a,
1535 : SPDK_NVME_SC_INVALID_NAMESPACE_OR_FORMAT = 0x0b,
1536 : SPDK_NVME_SC_COMMAND_SEQUENCE_ERROR = 0x0c,
1537 : SPDK_NVME_SC_INVALID_SGL_SEG_DESCRIPTOR = 0x0d,
1538 : SPDK_NVME_SC_INVALID_NUM_SGL_DESCIRPTORS = 0x0e,
1539 : SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID = 0x0f,
1540 : SPDK_NVME_SC_METADATA_SGL_LENGTH_INVALID = 0x10,
1541 : SPDK_NVME_SC_SGL_DESCRIPTOR_TYPE_INVALID = 0x11,
1542 : SPDK_NVME_SC_INVALID_CONTROLLER_MEM_BUF = 0x12,
1543 : SPDK_NVME_SC_INVALID_PRP_OFFSET = 0x13,
1544 : SPDK_NVME_SC_ATOMIC_WRITE_UNIT_EXCEEDED = 0x14,
1545 : SPDK_NVME_SC_OPERATION_DENIED = 0x15,
1546 : SPDK_NVME_SC_INVALID_SGL_OFFSET = 0x16,
1547 : /* 0x17 - reserved */
1548 : SPDK_NVME_SC_HOSTID_INCONSISTENT_FORMAT = 0x18,
1549 : SPDK_NVME_SC_KEEP_ALIVE_EXPIRED = 0x19,
1550 : SPDK_NVME_SC_KEEP_ALIVE_INVALID = 0x1a,
1551 : SPDK_NVME_SC_ABORTED_PREEMPT = 0x1b,
1552 : SPDK_NVME_SC_SANITIZE_FAILED = 0x1c,
1553 : SPDK_NVME_SC_SANITIZE_IN_PROGRESS = 0x1d,
1554 : SPDK_NVME_SC_SGL_DATA_BLOCK_GRANULARITY_INVALID = 0x1e,
1555 : SPDK_NVME_SC_COMMAND_INVALID_IN_CMB = 0x1f,
1556 : SPDK_NVME_SC_COMMAND_NAMESPACE_IS_PROTECTED = 0x20,
1557 : SPDK_NVME_SC_COMMAND_INTERRUPTED = 0x21,
1558 : SPDK_NVME_SC_COMMAND_TRANSIENT_TRANSPORT_ERROR = 0x22,
1559 : SPDK_NVME_SC_COMMAND_PROHIBITED_BY_LOCKDOWN = 0x23,
1560 : SPDK_NVME_SC_ADMIN_COMMAND_MEDIA_NOT_READY = 0x24,
1561 :
1562 : SPDK_NVME_SC_FDP_DISABLED = 0x29,
1563 : SPDK_NVME_SC_INVALID_PLACEMENT_HANDLE_LIST = 0x2A,
1564 :
1565 : SPDK_NVME_SC_LBA_OUT_OF_RANGE = 0x80,
1566 : SPDK_NVME_SC_CAPACITY_EXCEEDED = 0x81,
1567 : SPDK_NVME_SC_NAMESPACE_NOT_READY = 0x82,
1568 : SPDK_NVME_SC_RESERVATION_CONFLICT = 0x83,
1569 : SPDK_NVME_SC_FORMAT_IN_PROGRESS = 0x84,
1570 : SPDK_NVME_SC_INVALID_VALUE_SIZE = 0x85,
1571 : SPDK_NVME_SC_INVALID_KEY_SIZE = 0x86,
1572 : SPDK_NVME_SC_KV_KEY_DOES_NOT_EXIST = 0x87,
1573 : SPDK_NVME_SC_UNRECOVERED_ERROR = 0x88,
1574 : SPDK_NVME_SC_KEY_EXISTS = 0x89,
1575 : };
1576 :
1577 : /**
1578 : * Command specific status codes
1579 : */
1580 : enum spdk_nvme_command_specific_status_code {
1581 : SPDK_NVME_SC_COMPLETION_QUEUE_INVALID = 0x00,
1582 : SPDK_NVME_SC_INVALID_QUEUE_IDENTIFIER = 0x01,
1583 : SPDK_NVME_SC_INVALID_QUEUE_SIZE = 0x02,
1584 : SPDK_NVME_SC_ABORT_COMMAND_LIMIT_EXCEEDED = 0x03,
1585 : /* 0x04 - reserved */
1586 : SPDK_NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED = 0x05,
1587 : SPDK_NVME_SC_INVALID_FIRMWARE_SLOT = 0x06,
1588 : SPDK_NVME_SC_INVALID_FIRMWARE_IMAGE = 0x07,
1589 : SPDK_NVME_SC_INVALID_INTERRUPT_VECTOR = 0x08,
1590 : SPDK_NVME_SC_INVALID_LOG_PAGE = 0x09,
1591 : SPDK_NVME_SC_INVALID_FORMAT = 0x0a,
1592 : SPDK_NVME_SC_FIRMWARE_REQ_CONVENTIONAL_RESET = 0x0b,
1593 : SPDK_NVME_SC_INVALID_QUEUE_DELETION = 0x0c,
1594 : SPDK_NVME_SC_FEATURE_ID_NOT_SAVEABLE = 0x0d,
1595 : SPDK_NVME_SC_FEATURE_NOT_CHANGEABLE = 0x0e,
1596 : SPDK_NVME_SC_FEATURE_NOT_NAMESPACE_SPECIFIC = 0x0f,
1597 : SPDK_NVME_SC_FIRMWARE_REQ_NVM_RESET = 0x10,
1598 : SPDK_NVME_SC_FIRMWARE_REQ_RESET = 0x11,
1599 : SPDK_NVME_SC_FIRMWARE_REQ_MAX_TIME_VIOLATION = 0x12,
1600 : SPDK_NVME_SC_FIRMWARE_ACTIVATION_PROHIBITED = 0x13,
1601 : SPDK_NVME_SC_OVERLAPPING_RANGE = 0x14,
1602 : SPDK_NVME_SC_NAMESPACE_INSUFFICIENT_CAPACITY = 0x15,
1603 : SPDK_NVME_SC_NAMESPACE_ID_UNAVAILABLE = 0x16,
1604 : /* 0x17 - reserved */
1605 : SPDK_NVME_SC_NAMESPACE_ALREADY_ATTACHED = 0x18,
1606 : SPDK_NVME_SC_NAMESPACE_IS_PRIVATE = 0x19,
1607 : SPDK_NVME_SC_NAMESPACE_NOT_ATTACHED = 0x1a,
1608 : SPDK_NVME_SC_THINPROVISIONING_NOT_SUPPORTED = 0x1b,
1609 : SPDK_NVME_SC_CONTROLLER_LIST_INVALID = 0x1c,
1610 : SPDK_NVME_SC_DEVICE_SELF_TEST_IN_PROGRESS = 0x1d,
1611 : SPDK_NVME_SC_BOOT_PARTITION_WRITE_PROHIBITED = 0x1e,
1612 : SPDK_NVME_SC_INVALID_CTRLR_ID = 0x1f,
1613 : SPDK_NVME_SC_INVALID_SECONDARY_CTRLR_STATE = 0x20,
1614 : SPDK_NVME_SC_INVALID_NUM_CTRLR_RESOURCES = 0x21,
1615 : SPDK_NVME_SC_INVALID_RESOURCE_ID = 0x22,
1616 : SPDK_NVME_SC_SANITIZE_PROHIBITED = 0x23,
1617 : SPDK_NVME_SC_ANA_GROUP_IDENTIFIER_INVALID = 0x24,
1618 : SPDK_NVME_SC_ANA_ATTACH_FAILED = 0x25,
1619 : SPDK_NVME_SC_INSUFFICIENT_CAPACITY = 0x26,
1620 : SPDK_NVME_SC_NAMESPACE_ATTACH_LIMIT_EXCEEDED = 0x27,
1621 : SPDK_NVME_SC_PROHIBIT_CMD_EXEC_NOT_SUPPORTED = 0x28,
1622 : SPDK_NVME_SC_IOCS_NOT_SUPPORTED = 0x29,
1623 : SPDK_NVME_SC_IOCS_NOT_ENABLED = 0x2a,
1624 : SPDK_NVME_SC_IOCS_COMBINATION_REJECTED = 0x2b,
1625 : SPDK_NVME_SC_INVALID_IOCS = 0x2c,
1626 : SPDK_NVME_SC_IDENTIFIER_UNAVAILABLE = 0x2d,
1627 :
1628 : SPDK_NVME_SC_STREAM_RESOURCE_ALLOCATION_FAILED = 0x7f,
1629 : SPDK_NVME_SC_CONFLICTING_ATTRIBUTES = 0x80,
1630 : SPDK_NVME_SC_INVALID_PROTECTION_INFO = 0x81,
1631 : SPDK_NVME_SC_ATTEMPTED_WRITE_TO_RO_RANGE = 0x82,
1632 : SPDK_NVME_SC_CMD_SIZE_LIMIT_SIZE_EXCEEDED = 0x83,
1633 :
1634 : SPDK_NVME_SC_ZONED_BOUNDARY_ERROR = 0xb8,
1635 : SPDK_NVME_SC_ZONE_IS_FULL = 0xb9,
1636 : SPDK_NVME_SC_ZONE_IS_READ_ONLY = 0xba,
1637 : SPDK_NVME_SC_ZONE_IS_OFFLINE = 0xbb,
1638 : SPDK_NVME_SC_ZONE_INVALID_WRITE = 0xbc,
1639 : SPDK_NVME_SC_TOO_MANY_ACTIVE_ZONES = 0xbd,
1640 : SPDK_NVME_SC_TOO_MANY_OPEN_ZONES = 0xbe,
1641 : SPDK_NVME_SC_INVALID_ZONE_STATE_TRANSITION = 0xbf,
1642 : };
1643 :
1644 : /**
1645 : * Media error status codes
1646 : */
1647 : enum spdk_nvme_media_error_status_code {
1648 : SPDK_NVME_SC_WRITE_FAULTS = 0x80,
1649 : SPDK_NVME_SC_UNRECOVERED_READ_ERROR = 0x81,
1650 : SPDK_NVME_SC_GUARD_CHECK_ERROR = 0x82,
1651 : SPDK_NVME_SC_APPLICATION_TAG_CHECK_ERROR = 0x83,
1652 : SPDK_NVME_SC_REFERENCE_TAG_CHECK_ERROR = 0x84,
1653 : SPDK_NVME_SC_COMPARE_FAILURE = 0x85,
1654 : SPDK_NVME_SC_ACCESS_DENIED = 0x86,
1655 : SPDK_NVME_SC_DEALLOCATED_OR_UNWRITTEN_BLOCK = 0x87,
1656 : SPDK_NVME_SC_END_TO_END_STORAGE_TAG_CHECK_ERROR = 0x88,
1657 : };
1658 :
1659 : /**
1660 : * Path related status codes
1661 : */
1662 : enum spdk_nvme_path_status_code {
1663 : SPDK_NVME_SC_INTERNAL_PATH_ERROR = 0x00,
1664 : SPDK_NVME_SC_ASYMMETRIC_ACCESS_PERSISTENT_LOSS = 0x01,
1665 : SPDK_NVME_SC_ASYMMETRIC_ACCESS_INACCESSIBLE = 0x02,
1666 : SPDK_NVME_SC_ASYMMETRIC_ACCESS_TRANSITION = 0x03,
1667 :
1668 : SPDK_NVME_SC_CONTROLLER_PATH_ERROR = 0x60,
1669 :
1670 : SPDK_NVME_SC_HOST_PATH_ERROR = 0x70,
1671 : SPDK_NVME_SC_ABORTED_BY_HOST = 0x71,
1672 : };
1673 :
1674 : #define SPDK_NVME_MAX_OPC 0xff
1675 :
1676 : /**
1677 : * Admin opcodes
1678 : */
1679 : enum spdk_nvme_admin_opcode {
1680 : SPDK_NVME_OPC_DELETE_IO_SQ = 0x00,
1681 : SPDK_NVME_OPC_CREATE_IO_SQ = 0x01,
1682 : SPDK_NVME_OPC_GET_LOG_PAGE = 0x02,
1683 : /* 0x03 - reserved */
1684 : SPDK_NVME_OPC_DELETE_IO_CQ = 0x04,
1685 : SPDK_NVME_OPC_CREATE_IO_CQ = 0x05,
1686 : SPDK_NVME_OPC_IDENTIFY = 0x06,
1687 : /* 0x07 - reserved */
1688 : SPDK_NVME_OPC_ABORT = 0x08,
1689 : SPDK_NVME_OPC_SET_FEATURES = 0x09,
1690 : SPDK_NVME_OPC_GET_FEATURES = 0x0a,
1691 : /* 0x0b - reserved */
1692 : SPDK_NVME_OPC_ASYNC_EVENT_REQUEST = 0x0c,
1693 : SPDK_NVME_OPC_NS_MANAGEMENT = 0x0d,
1694 : /* 0x0e-0x0f - reserved */
1695 : SPDK_NVME_OPC_FIRMWARE_COMMIT = 0x10,
1696 : SPDK_NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD = 0x11,
1697 :
1698 : SPDK_NVME_OPC_DEVICE_SELF_TEST = 0x14,
1699 : SPDK_NVME_OPC_NS_ATTACHMENT = 0x15,
1700 :
1701 : SPDK_NVME_OPC_KEEP_ALIVE = 0x18,
1702 : SPDK_NVME_OPC_DIRECTIVE_SEND = 0x19,
1703 : SPDK_NVME_OPC_DIRECTIVE_RECEIVE = 0x1a,
1704 :
1705 : SPDK_NVME_OPC_VIRTUALIZATION_MANAGEMENT = 0x1c,
1706 : SPDK_NVME_OPC_NVME_MI_SEND = 0x1d,
1707 : SPDK_NVME_OPC_NVME_MI_RECEIVE = 0x1e,
1708 :
1709 : SPDK_NVME_OPC_DOORBELL_BUFFER_CONFIG = 0x7c,
1710 :
1711 : SPDK_NVME_OPC_FORMAT_NVM = 0x80,
1712 : SPDK_NVME_OPC_SECURITY_SEND = 0x81,
1713 : SPDK_NVME_OPC_SECURITY_RECEIVE = 0x82,
1714 :
1715 : SPDK_NVME_OPC_SANITIZE = 0x84,
1716 :
1717 : SPDK_NVME_OPC_GET_LBA_STATUS = 0x86,
1718 : };
1719 :
1720 : /**
1721 : * NVM command set opcodes
1722 : */
1723 : enum spdk_nvme_nvm_opcode {
1724 : SPDK_NVME_OPC_FLUSH = 0x00,
1725 : SPDK_NVME_OPC_WRITE = 0x01,
1726 : SPDK_NVME_OPC_READ = 0x02,
1727 : /* 0x03 - reserved */
1728 : SPDK_NVME_OPC_WRITE_UNCORRECTABLE = 0x04,
1729 : SPDK_NVME_OPC_COMPARE = 0x05,
1730 : /* 0x06-0x07 - reserved */
1731 : SPDK_NVME_OPC_WRITE_ZEROES = 0x08,
1732 : SPDK_NVME_OPC_DATASET_MANAGEMENT = 0x09,
1733 :
1734 : SPDK_NVME_OPC_VERIFY = 0x0c,
1735 : SPDK_NVME_OPC_RESERVATION_REGISTER = 0x0d,
1736 : SPDK_NVME_OPC_RESERVATION_REPORT = 0x0e,
1737 :
1738 : SPDK_NVME_OPC_RESERVATION_ACQUIRE = 0x11,
1739 : SPDK_NVME_OPC_IO_MANAGEMENT_RECEIVE = 0x12,
1740 : SPDK_NVME_OPC_RESERVATION_RELEASE = 0x15,
1741 :
1742 : SPDK_NVME_OPC_COPY = 0x19,
1743 : SPDK_NVME_OPC_IO_MANAGEMENT_SEND = 0x1D,
1744 : };
1745 :
1746 : /**
1747 : * Zoned Namespace command set opcodes
1748 : *
1749 : * In addition to the opcodes of the NVM command set, the Zoned Namespace
1750 : * command set supports the following opcodes.
1751 : */
1752 : enum spdk_nvme_zns_opcode {
1753 : SPDK_NVME_OPC_ZONE_MGMT_SEND = 0x79,
1754 : SPDK_NVME_OPC_ZONE_MGMT_RECV = 0x7a,
1755 : SPDK_NVME_OPC_ZONE_APPEND = 0x7d,
1756 : };
1757 :
1758 : /**
1759 : * Data transfer (bits 1:0) of an NVMe opcode.
1760 : *
1761 : * \sa spdk_nvme_opc_get_data_transfer
1762 : */
1763 : enum spdk_nvme_data_transfer {
1764 : /** Opcode does not transfer data */
1765 : SPDK_NVME_DATA_NONE = 0,
1766 : /** Opcode transfers data from host to controller (e.g. Write) */
1767 : SPDK_NVME_DATA_HOST_TO_CONTROLLER = 1,
1768 : /** Opcode transfers data from controller to host (e.g. Read) */
1769 : SPDK_NVME_DATA_CONTROLLER_TO_HOST = 2,
1770 : /** Opcode transfers data both directions */
1771 : SPDK_NVME_DATA_BIDIRECTIONAL = 3
1772 : };
1773 :
1774 : /**
1775 : * Extract the Data Transfer bits from an NVMe opcode.
1776 : *
1777 : * This determines whether a command requires a data buffer and
1778 : * which direction (host to controller or controller to host) it is
1779 : * transferred.
1780 : */
1781 42 : static inline enum spdk_nvme_data_transfer spdk_nvme_opc_get_data_transfer(uint8_t opc)
1782 : {
1783 42 : return (enum spdk_nvme_data_transfer)(opc & 3);
1784 : }
1785 :
1786 : static inline uint32_t
1787 16 : spdk_nvme_bytes_to_numd(uint32_t len)
1788 : {
1789 16 : return (len >> 2) - 1;
1790 : }
1791 :
1792 : #pragma pack(push, 1)
1793 : struct spdk_nvme_host_behavior {
1794 : uint8_t acre;
1795 : uint8_t reserved[511];
1796 : };
1797 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_host_behavior) == 512, "Incorrect size");
1798 : #pragma pack(pop)
1799 :
1800 : /**
1801 : * Supported FDP event descriptor
1802 : */
1803 : struct spdk_nvme_fdp_event_desc {
1804 : /* FDP Event type */
1805 : uint8_t fdp_etype;
1806 :
1807 : /* FDP event type attributes */
1808 : union {
1809 : uint8_t raw;
1810 : struct {
1811 : /* FDP event enabled */
1812 : uint8_t fdp_ee : 1;
1813 : uint8_t reserved : 7;
1814 : } bits;
1815 : } fdpeta;
1816 : };
1817 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_event_desc) == 2, "Incorrect size");
1818 :
1819 : /**
1820 : * Reclaim unit handle status descriptor
1821 : */
1822 : struct spdk_nvme_fdp_ruhs_desc {
1823 : /* Placement Identifier */
1824 : uint16_t pid;
1825 :
1826 : /* Reclaim Unit Handle Identifier */
1827 : uint16_t ruhid;
1828 :
1829 : /* Estimated Active Reclaim Unit Time Remaining */
1830 : uint32_t earutr;
1831 :
1832 : /* Reclaim Unit Available Media Writes */
1833 : uint64_t ruamw;
1834 :
1835 : uint8_t reserved[16];
1836 : };
1837 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_ruhs_desc) == 32, "Incorrect size");
1838 :
1839 : /**
1840 : * Reclaim unit handle status
1841 : */
1842 : struct spdk_nvme_fdp_ruhs {
1843 : uint8_t reserved[14];
1844 :
1845 : /* Number of Reclaim Unit Handle Status Descriptors */
1846 : uint16_t nruhsd;
1847 :
1848 : struct spdk_nvme_fdp_ruhs_desc ruhs_desc[];
1849 : };
1850 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_ruhs) == 16, "Incorrect size");
1851 :
1852 : /**
1853 : * Management operation to perform for IO management receive
1854 : */
1855 : enum spdk_nvme_fdp_mgmt_recv_mo {
1856 : SPDK_NVME_FDP_IO_MGMT_RECV_NA = 0x00,
1857 : SPDK_NVME_FDP_IO_MGMT_RECV_RUHS = 0x01,
1858 : /* 0x02-0xFE - reserved */
1859 : SPDK_NVME_FDP_IO_MGMT_RECV_VS = 0xFF,
1860 : };
1861 :
1862 : /**
1863 : * Management operation to perform for IO management send
1864 : */
1865 : enum spdk_nvme_fdp_mgmt_send_mo {
1866 : SPDK_NVME_FDP_IO_MGMT_SEND_NA = 0x00,
1867 : SPDK_NVME_FDP_IO_MGMT_SEND_RUHU = 0x01,
1868 : /* 0x02-0xFE - reserved */
1869 : SPDK_NVME_FDP_IO_MGMT_SEND_VS = 0xFF,
1870 : };
1871 :
1872 : enum spdk_nvme_feat {
1873 : /* 0x00 - reserved */
1874 :
1875 : /** cdw11 layout defined by \ref spdk_nvme_feat_arbitration */
1876 : SPDK_NVME_FEAT_ARBITRATION = 0x01,
1877 : /** cdw11 layout defined by \ref spdk_nvme_feat_power_management */
1878 : SPDK_NVME_FEAT_POWER_MANAGEMENT = 0x02,
1879 : /** cdw11 layout defined by \ref spdk_nvme_feat_lba_range_type */
1880 : SPDK_NVME_FEAT_LBA_RANGE_TYPE = 0x03,
1881 : /** cdw11 layout defined by \ref spdk_nvme_feat_temperature_threshold */
1882 : SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD = 0x04,
1883 : /** cdw11 layout defined by \ref spdk_nvme_feat_error_recovery */
1884 : SPDK_NVME_FEAT_ERROR_RECOVERY = 0x05,
1885 : /** cdw11 layout defined by \ref spdk_nvme_feat_volatile_write_cache */
1886 : SPDK_NVME_FEAT_VOLATILE_WRITE_CACHE = 0x06,
1887 : /** cdw11 layout defined by \ref spdk_nvme_feat_number_of_queues */
1888 : SPDK_NVME_FEAT_NUMBER_OF_QUEUES = 0x07,
1889 : /** cdw11 layout defined by \ref spdk_nvme_feat_interrupt_coalescing */
1890 : SPDK_NVME_FEAT_INTERRUPT_COALESCING = 0x08,
1891 : /** cdw11 layout defined by \ref spdk_nvme_feat_interrupt_vector_configuration */
1892 : SPDK_NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION = 0x09,
1893 : /** cdw11 layout defined by \ref spdk_nvme_feat_write_atomicity */
1894 : SPDK_NVME_FEAT_WRITE_ATOMICITY = 0x0A,
1895 : /** cdw11 layout defined by \ref spdk_nvme_feat_async_event_configuration */
1896 : SPDK_NVME_FEAT_ASYNC_EVENT_CONFIGURATION = 0x0B,
1897 : /** cdw11 layout defined by \ref spdk_nvme_feat_autonomous_power_state_transition */
1898 : SPDK_NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION = 0x0C,
1899 : /** cdw11 layout defined by \ref spdk_nvme_feat_host_mem_buffer */
1900 : SPDK_NVME_FEAT_HOST_MEM_BUFFER = 0x0D,
1901 : SPDK_NVME_FEAT_TIMESTAMP = 0x0E,
1902 : /** cdw11 layout defined by \ref spdk_nvme_feat_keep_alive_timer */
1903 : SPDK_NVME_FEAT_KEEP_ALIVE_TIMER = 0x0F,
1904 : /** cdw11 layout defined by \ref spdk_nvme_feat_host_controlled_thermal_management */
1905 : SPDK_NVME_FEAT_HOST_CONTROLLED_THERMAL_MANAGEMENT = 0x10,
1906 : /** cdw11 layout defined by \ref spdk_nvme_feat_non_operational_power_state_config */
1907 : SPDK_NVME_FEAT_NON_OPERATIONAL_POWER_STATE_CONFIG = 0x11,
1908 :
1909 : SPDK_NVME_FEAT_READ_RECOVERY_LEVEL_CONFIG = 0x12,
1910 : SPDK_NVME_FEAT_PREDICTABLE_LATENCY_MODE_CONFIG = 0x13,
1911 : SPDK_NVME_FEAT_PREDICTABLE_LATENCY_MODE_WINDOW = 0x14,
1912 : SPDK_NVME_FEAT_LBA_STATUS_INFORMATION_ATTRIBUTES = 0x15,
1913 : /** data buffer layout defined by \ref spdk_nvme_host_behavior */
1914 : SPDK_NVME_FEAT_HOST_BEHAVIOR_SUPPORT = 0x16,
1915 : SPDK_NVME_FEAT_SANITIZE_CONFIG = 0x17,
1916 : SPDK_NVME_FEAT_ENDURANCE_GROUP_EVENT = 0x18,
1917 : SPDK_NVME_FEAT_IO_COMMAND_SET_PROFILE = 0x19,
1918 : SPDK_NVME_FEAT_SPINUP_CONTROL = 0x1A,
1919 : /* 0x1B-0x1C - reserved */
1920 :
1921 : /**
1922 : * cdw11 layout defined by \ref spdk_nvme_feat_fdp_cdw11
1923 : * cdw12 layout defined by \ref spdk_nvme_feat_fdp_cdw12
1924 : */
1925 : SPDK_NVME_FEAT_FDP = 0x1D,
1926 :
1927 : /**
1928 : * cdw11 layout defined by \ref spdk_nvme_feat_fdp_events_cdw11
1929 : * cdw12 layout defined by \ref spdk_nvme_feat_fdp_events_cdw12
1930 : * data layout defined by \ref spdk_nvme_fdp_event_desc
1931 : */
1932 : SPDK_NVME_FEAT_FDP_EVENTS = 0x1E,
1933 :
1934 : /* 0x1F-0x77 - reserved */
1935 : /* 0x78-0x7C - NVMe-MI features */
1936 : SPDK_NVME_FEAT_ENHANCED_CONTROLLER_METADATA = 0x7D,
1937 : SPDK_NVME_FEAT_CONTROLLER_METADATA = 0x7E,
1938 : SPDK_NVME_FEAT_NAMESPACE_METADATA = 0x7F,
1939 :
1940 : /** cdw11 layout defined by \ref spdk_nvme_feat_software_progress_marker */
1941 : SPDK_NVME_FEAT_SOFTWARE_PROGRESS_MARKER = 0x80,
1942 :
1943 : /** cdw11 layout defined by \ref spdk_nvme_feat_host_identifier */
1944 : SPDK_NVME_FEAT_HOST_IDENTIFIER = 0x81,
1945 : /** cdw11 layout defined by \ref spdk_nvme_feat_reservation_notification_mask */
1946 : SPDK_NVME_FEAT_HOST_RESERVE_MASK = 0x82,
1947 : /** cdw11 layout defined by \ref spdk_nvme_feat_reservation_persistence */
1948 : SPDK_NVME_FEAT_HOST_RESERVE_PERSIST = 0x83,
1949 : SPDK_NVME_FEAT_NAMESPACE_WRITE_PROTECTION_CONFIG = 0x84,
1950 :
1951 : /* 0x85-0xBF - command set specific (reserved) */
1952 :
1953 : /* 0xC0-0xFF - vendor specific */
1954 : };
1955 :
1956 : /** Bit set of attributes for DATASET MANAGEMENT commands. */
1957 : enum spdk_nvme_dsm_attribute {
1958 : SPDK_NVME_DSM_ATTR_INTEGRAL_READ = 0x1,
1959 : SPDK_NVME_DSM_ATTR_INTEGRAL_WRITE = 0x2,
1960 : SPDK_NVME_DSM_ATTR_DEALLOCATE = 0x4,
1961 : };
1962 :
1963 : struct spdk_nvme_power_state {
1964 : uint16_t mp; /* bits 15:00: maximum power */
1965 :
1966 : uint8_t reserved1;
1967 :
1968 : uint8_t mps : 1; /* bit 24: max power scale */
1969 : uint8_t nops : 1; /* bit 25: non-operational state */
1970 : uint8_t reserved2 : 6;
1971 :
1972 : uint32_t enlat; /* bits 63:32: entry latency in microseconds */
1973 : uint32_t exlat; /* bits 95:64: exit latency in microseconds */
1974 :
1975 : uint8_t rrt : 5; /* bits 100:96: relative read throughput */
1976 : uint8_t reserved3 : 3;
1977 :
1978 : uint8_t rrl : 5; /* bits 108:104: relative read latency */
1979 : uint8_t reserved4 : 3;
1980 :
1981 : uint8_t rwt : 5; /* bits 116:112: relative write throughput */
1982 : uint8_t reserved5 : 3;
1983 :
1984 : uint8_t rwl : 5; /* bits 124:120: relative write latency */
1985 : uint8_t reserved6 : 3;
1986 :
1987 : uint16_t idlp; /* bits 143:128: idle power */
1988 :
1989 : uint8_t reserved7 : 6;
1990 : uint8_t ips : 2; /* bits 151:150: idle power scale */
1991 :
1992 : uint8_t reserved8;
1993 :
1994 : uint16_t actp; /* bits 175:160: active power */
1995 :
1996 : uint8_t apw : 3; /* bits 178:176: active power workload */
1997 : uint8_t reserved9 : 3;
1998 : uint8_t aps : 2; /* bits 183:182: active power scale */
1999 :
2000 : uint8_t reserved10[9];
2001 : };
2002 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_power_state) == 32, "Incorrect size");
2003 :
2004 : /** Identify command CNS value */
2005 : enum spdk_nvme_identify_cns {
2006 : /** Identify namespace indicated in CDW1.NSID */
2007 : SPDK_NVME_IDENTIFY_NS = 0x00,
2008 :
2009 : /** Identify controller */
2010 : SPDK_NVME_IDENTIFY_CTRLR = 0x01,
2011 :
2012 : /** List active NSIDs greater than CDW1.NSID */
2013 : SPDK_NVME_IDENTIFY_ACTIVE_NS_LIST = 0x02,
2014 :
2015 : /** List namespace identification descriptors */
2016 : SPDK_NVME_IDENTIFY_NS_ID_DESCRIPTOR_LIST = 0x03,
2017 :
2018 : /** Identify namespace indicated in CDW1.NSID, specific to CWD11.CSI */
2019 : SPDK_NVME_IDENTIFY_NS_IOCS = 0x05,
2020 :
2021 : /** Identify controller, specific to CWD11.CSI */
2022 : SPDK_NVME_IDENTIFY_CTRLR_IOCS = 0x06,
2023 :
2024 : /** List active NSIDs greater than CDW1.NSID, specific to CWD11.CSI */
2025 : SPDK_NVME_IDENTIFY_ACTIVE_NS_LIST_IOCS = 0x07,
2026 :
2027 : /** List allocated NSIDs greater than CDW1.NSID */
2028 : SPDK_NVME_IDENTIFY_ALLOCATED_NS_LIST = 0x10,
2029 :
2030 : /** Identify namespace if CDW1.NSID is allocated */
2031 : SPDK_NVME_IDENTIFY_NS_ALLOCATED = 0x11,
2032 :
2033 : /** Get list of controllers starting at CDW10.CNTID that are attached to CDW1.NSID */
2034 : SPDK_NVME_IDENTIFY_NS_ATTACHED_CTRLR_LIST = 0x12,
2035 :
2036 : /** Get list of controllers starting at CDW10.CNTID */
2037 : SPDK_NVME_IDENTIFY_CTRLR_LIST = 0x13,
2038 :
2039 : /** Get primary controller capabilities structure */
2040 : SPDK_NVME_IDENTIFY_PRIMARY_CTRLR_CAP = 0x14,
2041 :
2042 : /** Get secondary controller list */
2043 : SPDK_NVME_IDENTIFY_SECONDARY_CTRLR_LIST = 0x15,
2044 :
2045 : /** List allocated NSIDs greater than CDW1.NSID, specific to CWD11.CSI */
2046 : SPDK_NVME_IDENTIFY_ALLOCATED_NS_LIST_IOCS = 0x1a,
2047 :
2048 : /** Identify namespace if CDW1.NSID is allocated, specific to CDWD11.CSI */
2049 : SPDK_NVME_IDENTIFY_NS_ALLOCATED_IOCS = 0x1b,
2050 :
2051 : /** Identify I/O Command Sets */
2052 : SPDK_NVME_IDENTIFY_IOCS = 0x1c,
2053 : };
2054 :
2055 : /** NVMe over Fabrics controller model */
2056 : enum spdk_nvmf_ctrlr_model {
2057 : /** NVM subsystem uses dynamic controller model */
2058 : SPDK_NVMF_CTRLR_MODEL_DYNAMIC = 0,
2059 :
2060 : /** NVM subsystem uses static controller model */
2061 : SPDK_NVMF_CTRLR_MODEL_STATIC = 1,
2062 : };
2063 :
2064 : #define SPDK_NVME_CTRLR_SN_LEN 20
2065 : #define SPDK_NVME_CTRLR_MN_LEN 40
2066 : #define SPDK_NVME_CTRLR_FR_LEN 8
2067 : #define SPDK_NVME_CTRLR_MEGCAP_LEN 16
2068 :
2069 : /** Identify Controller data sgls.supported values */
2070 : enum spdk_nvme_sgls_supported {
2071 : /** SGLs are not supported */
2072 : SPDK_NVME_SGLS_NOT_SUPPORTED = 0,
2073 :
2074 : /** SGLs are supported with no alignment or granularity requirement. */
2075 : SPDK_NVME_SGLS_SUPPORTED = 1,
2076 :
2077 : /** SGLs are supported with a DWORD alignment and granularity requirement. */
2078 : SPDK_NVME_SGLS_SUPPORTED_DWORD_ALIGNED = 2,
2079 : };
2080 :
2081 : /** Identify Controller data vwc.flush_broadcast values */
2082 : enum spdk_nvme_flush_broadcast {
2083 : /** Support for NSID=FFFFFFFFh with Flush is not indicated. */
2084 : SPDK_NVME_FLUSH_BROADCAST_NOT_INDICATED = 0,
2085 :
2086 : /* 01b: Reserved */
2087 :
2088 : /** Flush does not support NSID set to FFFFFFFFh. */
2089 : SPDK_NVME_FLUSH_BROADCAST_NOT_SUPPORTED = 2,
2090 :
2091 : /** Flush supports NSID set to FFFFFFFFh. */
2092 : SPDK_NVME_FLUSH_BROADCAST_SUPPORTED = 3
2093 : };
2094 :
2095 : #define SPDK_NVME_MAXDNA_FIELD_SIZE 16
2096 : #define SPDK_NVME_NQN_FIELD_SIZE 256
2097 :
2098 : /** Identify Controller data NVMe over Fabrics-specific fields */
2099 : struct spdk_nvme_cdata_nvmf_specific {
2100 : /** I/O queue command capsule supported size (16-byte units) */
2101 : uint32_t ioccsz;
2102 :
2103 : /** I/O queue response capsule supported size (16-byte units) */
2104 : uint32_t iorcsz;
2105 :
2106 : /** In-capsule data offset (16-byte units) */
2107 : uint16_t icdoff;
2108 :
2109 : /** Controller attributes */
2110 : struct {
2111 : /** Controller model: \ref spdk_nvmf_ctrlr_model */
2112 : uint8_t ctrlr_model : 1;
2113 : uint8_t reserved : 7;
2114 : } ctrattr;
2115 :
2116 : /** Maximum SGL block descriptors (0 = no limit) */
2117 : uint8_t msdbd;
2118 :
2119 : /** Optional fabric commands supported */
2120 : struct {
2121 : /** Support disconnect command and individual I/O queue deletion */
2122 : uint16_t disconnect : 1;
2123 : uint16_t reserved : 15;
2124 : } ofcs;
2125 :
2126 : uint8_t reserved[242];
2127 : };
2128 :
2129 : /** Identify Controller data SGL support */
2130 : struct spdk_nvme_cdata_sgls {
2131 : uint32_t supported : 2;
2132 : uint32_t keyed_sgl : 1;
2133 : uint32_t reserved1 : 13;
2134 : uint32_t bit_bucket_descriptor : 1;
2135 : uint32_t metadata_pointer : 1;
2136 : uint32_t oversized_sgl : 1;
2137 : uint32_t metadata_address : 1;
2138 : uint32_t sgl_offset : 1;
2139 : uint32_t transport_sgl : 1;
2140 : uint32_t reserved2 : 10;
2141 : };
2142 :
2143 : /** Identify Controller data Optional NVM Command Support */
2144 : struct spdk_nvme_cdata_oncs {
2145 : uint16_t compare : 1;
2146 : uint16_t write_unc : 1;
2147 : uint16_t dsm: 1;
2148 : uint16_t write_zeroes: 1;
2149 : uint16_t set_features_save: 1;
2150 : uint16_t reservations: 1;
2151 : uint16_t timestamp: 1;
2152 : uint16_t verify: 1;
2153 : uint16_t copy: 1;
2154 : uint16_t reserved9: 7;
2155 : };
2156 :
2157 : struct spdk_nvme_cdata_oacs {
2158 : /* supports security send/receive commands */
2159 : uint16_t security : 1;
2160 :
2161 : /* supports format nvm command */
2162 : uint16_t format : 1;
2163 :
2164 : /* supports firmware activate/download commands */
2165 : uint16_t firmware : 1;
2166 :
2167 : /* supports ns manage/ns attach commands */
2168 : uint16_t ns_manage : 1;
2169 :
2170 : /** Supports device self-test command (SPDK_NVME_OPC_DEVICE_SELF_TEST) */
2171 : uint16_t device_self_test : 1;
2172 :
2173 : /** Supports SPDK_NVME_OPC_DIRECTIVE_SEND and SPDK_NVME_OPC_DIRECTIVE_RECEIVE */
2174 : uint16_t directives : 1;
2175 :
2176 : /** Supports NVMe-MI (SPDK_NVME_OPC_NVME_MI_SEND, SPDK_NVME_OPC_NVME_MI_RECEIVE) */
2177 : uint16_t nvme_mi : 1;
2178 :
2179 : /** Supports SPDK_NVME_OPC_VIRTUALIZATION_MANAGEMENT */
2180 : uint16_t virtualization_management : 1;
2181 :
2182 : /** Supports SPDK_NVME_OPC_DOORBELL_BUFFER_CONFIG */
2183 : uint16_t doorbell_buffer_config : 1;
2184 :
2185 : /** Supports SPDK_NVME_OPC_GET_LBA_STATUS */
2186 : uint16_t get_lba_status : 1;
2187 :
2188 : /** Supports command and feature lockdown capability */
2189 : uint16_t command_feature_lockdown : 1;
2190 :
2191 : uint16_t oacs_rsvd : 5;
2192 : };
2193 :
2194 : struct spdk_nvme_cdata_fuses {
2195 : uint16_t compare_and_write : 1;
2196 : uint16_t reserved : 15;
2197 : };
2198 :
2199 : struct spdk_nvme_cdata_oaes {
2200 : uint32_t reserved1 : 8;
2201 :
2202 : /* Supports sending Namespace Attribute Notices. */
2203 : uint32_t ns_attribute_notices : 1;
2204 :
2205 : /* Supports sending Firmware Activation Notices. */
2206 : uint32_t fw_activation_notices : 1;
2207 :
2208 : uint32_t reserved2 : 1;
2209 :
2210 : /* Supports Asymmetric Namespace Access Change Notices. */
2211 : uint32_t ana_change_notices : 1;
2212 :
2213 : /* Supports Predictable Latency Event Aggregate Log Change Notices. */
2214 : uint32_t pleal_change_notices : 1;
2215 :
2216 : /* Supports LBA Status Information Alert Notices. */
2217 : uint32_t lba_sia_notices : 1;
2218 :
2219 : /* Supports Endurance Group Event Aggregate Log Page Change Notices. */
2220 : uint32_t egealp_change_notices : 1;
2221 :
2222 : /* Supports Normal NVM Subsystem Shutdown event. */
2223 : uint32_t nnvm_sse : 1;
2224 :
2225 : uint32_t reserved3 : 11;
2226 :
2227 : /* Supports Zone Descriptor Change Notices (refer to the ZNS Command Set specification) */
2228 : uint32_t zdes_change_notices : 1;
2229 :
2230 : uint32_t reserved4 : 3;
2231 :
2232 : /* Supports Discovery log change notices (refer to the NVMe over Fabrics specification) */
2233 : uint32_t discovery_log_change_notices : 1;
2234 : };
2235 :
2236 : union spdk_nvme_cdata_ctratt {
2237 : uint32_t raw;
2238 : struct {
2239 : /* Supports 128-bit host identifier */
2240 : uint32_t host_id_exhid_supported: 1;
2241 :
2242 : /* Supports non-operational power state permissive mode */
2243 : uint32_t non_operational_power_state_permissive_mode: 1;
2244 :
2245 : /* Supports NVM sets */
2246 : uint32_t nvm_sets: 1;
2247 :
2248 : /* Supports read recovery levels */
2249 : uint32_t read_recovery_levels: 1;
2250 :
2251 : /* Supports endurance groups */
2252 : uint32_t endurance_groups: 1;
2253 :
2254 : /* Supports predictable latency mode */
2255 : uint32_t predictable_latency_mode: 1;
2256 :
2257 : /* Supports traffic based keep alive */
2258 : uint32_t tbkas: 1;
2259 :
2260 : /* Supports reporting of namespace granularity */
2261 : uint32_t namespace_granularity: 1;
2262 :
2263 : /* Supports SQ associations */
2264 : uint32_t sq_associations: 1;
2265 :
2266 : /* Supports reporting of UUID list */
2267 : uint32_t uuid_list: 1;
2268 :
2269 : /* NVM subsystem supports multiple domains */
2270 : uint32_t mds: 1;
2271 :
2272 : /* Supports fixed capacity management */
2273 : uint32_t fixed_capacity_management: 1;
2274 :
2275 : /* Supports variable capacity management */
2276 : uint32_t variable_capacity_management: 1;
2277 :
2278 : /* Supports delete endurance group operation */
2279 : uint32_t delete_endurance_group: 1;
2280 :
2281 : /* Supports delete NVM set */
2282 : uint32_t delete_nvm_set: 1;
2283 :
2284 : /* Supports I/O command set specific extended PI formats */
2285 : uint32_t elbas: 1;
2286 :
2287 : uint32_t reserved1: 3;
2288 :
2289 : /* Supports flexible data placement */
2290 : uint32_t fdps: 1;
2291 :
2292 : uint32_t reserved2: 12;
2293 : } bits;
2294 : };
2295 :
2296 : #pragma pack(push, 1)
2297 : struct spdk_nvme_ctrlr_data {
2298 : /* bytes 0-255: controller capabilities and features */
2299 :
2300 : /** pci vendor id */
2301 : uint16_t vid;
2302 :
2303 : /** pci subsystem vendor id */
2304 : uint16_t ssvid;
2305 :
2306 : /** serial number */
2307 : int8_t sn[SPDK_NVME_CTRLR_SN_LEN];
2308 :
2309 : /** model number */
2310 : int8_t mn[SPDK_NVME_CTRLR_MN_LEN];
2311 :
2312 : /** firmware revision */
2313 : uint8_t fr[SPDK_NVME_CTRLR_FR_LEN];
2314 :
2315 : /** recommended arbitration burst */
2316 : uint8_t rab;
2317 :
2318 : /** ieee oui identifier */
2319 : uint8_t ieee[3];
2320 :
2321 : /** controller multi-path I/O and namespace sharing capabilities */
2322 : struct {
2323 : uint8_t multi_port : 1;
2324 : uint8_t multi_ctrlr : 1;
2325 : uint8_t sr_iov : 1;
2326 : uint8_t ana_reporting : 1;
2327 : uint8_t reserved : 4;
2328 : } cmic;
2329 :
2330 : /** maximum data transfer size */
2331 : uint8_t mdts;
2332 :
2333 : /** controller id */
2334 : uint16_t cntlid;
2335 :
2336 : /** version */
2337 : union spdk_nvme_vs_register ver;
2338 :
2339 : /** RTD3 resume latency */
2340 : uint32_t rtd3r;
2341 :
2342 : /** RTD3 entry latency */
2343 : uint32_t rtd3e;
2344 :
2345 : /** optional asynchronous events supported */
2346 : struct spdk_nvme_cdata_oaes oaes;
2347 :
2348 : /** controller attributes */
2349 : union spdk_nvme_cdata_ctratt ctratt;
2350 :
2351 : /** Read Recovery Levels Supported */
2352 : uint16_t rrls;
2353 :
2354 : uint8_t reserved_102[9];
2355 :
2356 : /** Controller Type */
2357 : uint8_t cntrltype;
2358 :
2359 : /** FRU globally unique identifier */
2360 : uint8_t fguid[16];
2361 :
2362 : /** Command Retry Delay Time 1, 2 and 3 */
2363 : uint16_t crdt[3];
2364 :
2365 : uint8_t reserved_134[119];
2366 :
2367 : /** NVM Subsystem Report */
2368 : struct {
2369 : /* NVM Subsystem part of NVMe storage device */
2370 : uint8_t nvmesd : 1;
2371 :
2372 : /* NVM Subsystem part of NVMe enclosure */
2373 : uint8_t nvmee : 1;
2374 :
2375 : uint8_t nvmsr_rsvd : 6;
2376 : } nvmsr;
2377 :
2378 : /** VPD Write Cycle Information */
2379 : struct {
2380 : /* VPD write cycles remaining */
2381 : uint8_t vwcr : 7;
2382 :
2383 : /* VPD write cycles remaining valid */
2384 : uint8_t vwcrv : 1;
2385 : } vwci;
2386 :
2387 : /** Management Endpoint Capabilities */
2388 : struct {
2389 : /* SMBus/I2C Port management endpoint */
2390 : uint8_t smbusme : 1;
2391 :
2392 : /* PCIe port management endpoint */
2393 : uint8_t pcieme : 1;
2394 :
2395 : uint8_t mec_rsvd : 6;
2396 : } mec;
2397 :
2398 : /* bytes 256-511: admin command set attributes */
2399 :
2400 : /** optional admin command support */
2401 : struct spdk_nvme_cdata_oacs oacs;
2402 :
2403 : /** abort command limit */
2404 : uint8_t acl;
2405 :
2406 : /** asynchronous event request limit */
2407 : uint8_t aerl;
2408 :
2409 : /** firmware updates */
2410 : struct {
2411 : /* first slot is read-only */
2412 : uint8_t slot1_ro : 1;
2413 :
2414 : /* number of firmware slots */
2415 : uint8_t num_slots : 3;
2416 :
2417 : /* support activation without reset */
2418 : uint8_t activation_without_reset : 1;
2419 :
2420 : /* Support multiple update detection */
2421 : uint8_t multiple_update_detection : 1;
2422 :
2423 : uint8_t frmw_rsvd : 2;
2424 : } frmw;
2425 :
2426 : /** log page attributes */
2427 : struct {
2428 : /* per namespace smart/health log page */
2429 : uint8_t ns_smart : 1;
2430 : /* command effects log page */
2431 : uint8_t celp : 1;
2432 : /* extended data for get log page */
2433 : uint8_t edlp: 1;
2434 : /* telemetry log pages and notices */
2435 : uint8_t telemetry : 1;
2436 : /* Persistent event log */
2437 : uint8_t pelp : 1;
2438 : /* Log pages log page */
2439 : uint8_t lplp : 1;
2440 : /* Data Area 4 for telemetry */
2441 : uint8_t da4_telemetry : 1;
2442 : uint8_t lpa_rsvd : 1;
2443 : } lpa;
2444 :
2445 : /** error log page entries */
2446 : uint8_t elpe;
2447 :
2448 : /** number of power states supported */
2449 : uint8_t npss;
2450 :
2451 : /** admin vendor specific command configuration */
2452 : struct {
2453 : /* admin vendor specific commands use disk format */
2454 : uint8_t spec_format : 1;
2455 :
2456 : uint8_t avscc_rsvd : 7;
2457 : } avscc;
2458 :
2459 : /** autonomous power state transition attributes */
2460 : struct {
2461 : /** controller supports autonomous power state transitions */
2462 : uint8_t supported : 1;
2463 :
2464 : uint8_t apsta_rsvd : 7;
2465 : } apsta;
2466 :
2467 : /** warning composite temperature threshold */
2468 : uint16_t wctemp;
2469 :
2470 : /** critical composite temperature threshold */
2471 : uint16_t cctemp;
2472 :
2473 : /** maximum time for firmware activation */
2474 : uint16_t mtfa;
2475 :
2476 : /** host memory buffer preferred size */
2477 : uint32_t hmpre;
2478 :
2479 : /** host memory buffer minimum size */
2480 : uint32_t hmmin;
2481 :
2482 : /** total NVM capacity */
2483 : uint64_t tnvmcap[2];
2484 :
2485 : /** unallocated NVM capacity */
2486 : uint64_t unvmcap[2];
2487 :
2488 : /** replay protected memory block support */
2489 : struct {
2490 : uint8_t num_rpmb_units : 3;
2491 : uint8_t auth_method : 3;
2492 : uint8_t reserved1 : 2;
2493 :
2494 : uint8_t reserved2;
2495 :
2496 : uint8_t total_size;
2497 : uint8_t access_size;
2498 : } rpmbs;
2499 :
2500 : /** extended device self-test time (in minutes) */
2501 : uint16_t edstt;
2502 :
2503 : /** device self-test options */
2504 : union {
2505 : uint8_t raw;
2506 : struct {
2507 : /** Device supports only one device self-test operation at a time */
2508 : uint8_t one_only : 1;
2509 :
2510 : uint8_t reserved : 7;
2511 : } bits;
2512 : } dsto;
2513 :
2514 : /**
2515 : * Firmware update granularity
2516 : *
2517 : * 4KB units
2518 : * 0x00 = no information provided
2519 : * 0xFF = no restriction
2520 : */
2521 : uint8_t fwug;
2522 :
2523 : /**
2524 : * Keep Alive Support
2525 : *
2526 : * Granularity of keep alive timer in 100 ms units
2527 : * 0 = keep alive not supported
2528 : */
2529 : uint16_t kas;
2530 :
2531 : /** Host controlled thermal management attributes */
2532 : union {
2533 : uint16_t raw;
2534 : struct {
2535 : uint16_t supported : 1;
2536 : uint16_t reserved : 15;
2537 : } bits;
2538 : } hctma;
2539 :
2540 : /** Minimum thermal management temperature */
2541 : uint16_t mntmt;
2542 :
2543 : /** Maximum thermal management temperature */
2544 : uint16_t mxtmt;
2545 :
2546 : /** Sanitize capabilities */
2547 : union {
2548 : uint32_t raw;
2549 : struct {
2550 : uint32_t crypto_erase : 1;
2551 : uint32_t block_erase : 1;
2552 : uint32_t overwrite : 1;
2553 : uint32_t reserved : 29;
2554 : } bits;
2555 : } sanicap;
2556 :
2557 : /** Host memory buffer minimum descriptor entry size */
2558 : uint32_t hmminds;
2559 :
2560 : /** Host memory maximum descriptor entries */
2561 : uint16_t hmmaxd;
2562 :
2563 : /** NVM set identifier maximum */
2564 : uint16_t nsetidmax;
2565 :
2566 : /** Endurance group identifier maximum */
2567 : uint16_t endgidmax;
2568 :
2569 : /** ANA transition time */
2570 : uint8_t anatt;
2571 :
2572 : /* bytes 343: Asymmetric namespace access capabilities */
2573 : struct {
2574 : uint8_t ana_optimized_state : 1;
2575 : uint8_t ana_non_optimized_state : 1;
2576 : uint8_t ana_inaccessible_state : 1;
2577 : uint8_t ana_persistent_loss_state : 1;
2578 : uint8_t ana_change_state : 1;
2579 : uint8_t reserved : 1;
2580 : uint8_t no_change_anagrpid : 1;
2581 : uint8_t non_zero_anagrpid : 1;
2582 : } anacap;
2583 :
2584 : /* bytes 344-347: ANA group identifier maximum */
2585 : uint32_t anagrpmax;
2586 : /* bytes 348-351: number of ANA group identifiers */
2587 : uint32_t nanagrpid;
2588 :
2589 : /* bytes 352-355: persistent event log size */
2590 : uint32_t pels;
2591 :
2592 : /* Domain identifier that contains this controller */
2593 : uint16_t domain_identifier;
2594 :
2595 : uint8_t reserved3[10];
2596 :
2597 : /* Maximum capacity of a single endurance group */
2598 : uint8_t megcap[SPDK_NVME_CTRLR_MEGCAP_LEN];
2599 :
2600 : /* bytes 384-511 */
2601 : uint8_t reserved384[128];
2602 :
2603 : /* bytes 512-703: nvm command set attributes */
2604 :
2605 : /** submission queue entry size */
2606 : struct {
2607 : uint8_t min : 4;
2608 : uint8_t max : 4;
2609 : } sqes;
2610 :
2611 : /** completion queue entry size */
2612 : struct {
2613 : uint8_t min : 4;
2614 : uint8_t max : 4;
2615 : } cqes;
2616 :
2617 : uint16_t maxcmd;
2618 :
2619 : /** number of namespaces */
2620 : uint32_t nn;
2621 :
2622 : /** optional nvm command support */
2623 : struct spdk_nvme_cdata_oncs oncs;
2624 :
2625 : /** fused operation support */
2626 : struct spdk_nvme_cdata_fuses fuses;
2627 :
2628 : /** format nvm attributes */
2629 : struct {
2630 : uint8_t format_all_ns: 1;
2631 : uint8_t erase_all_ns: 1;
2632 : uint8_t crypto_erase_supported: 1;
2633 : uint8_t reserved: 5;
2634 : } fna;
2635 :
2636 : /** volatile write cache */
2637 : struct {
2638 : uint8_t present : 1;
2639 : uint8_t flush_broadcast : 2;
2640 : uint8_t reserved : 5;
2641 : } vwc;
2642 :
2643 : /** atomic write unit normal */
2644 : uint16_t awun;
2645 :
2646 : /** atomic write unit power fail */
2647 : uint16_t awupf;
2648 :
2649 : /** NVM vendor specific command configuration */
2650 : uint8_t nvscc;
2651 :
2652 : /** Namespace Write Protection Capabilities */
2653 : uint8_t nwpc;
2654 :
2655 : /** atomic compare & write unit */
2656 : uint16_t acwu;
2657 :
2658 : /** optional copy formats supported */
2659 : struct {
2660 : uint16_t copy_format0 : 1;
2661 : uint16_t reserved1: 15;
2662 : } ocfs;
2663 :
2664 :
2665 : struct spdk_nvme_cdata_sgls sgls;
2666 :
2667 : /* maximum number of allowed namespaces */
2668 : uint32_t mnan;
2669 :
2670 : /* maximum domain namespace attachments */
2671 : uint8_t maxdna[SPDK_NVME_MAXDNA_FIELD_SIZE];
2672 :
2673 : /* maximum I/O controller namespace attachments */
2674 : uint32_t maxcna;
2675 :
2676 : uint8_t reserved4[204];
2677 :
2678 : uint8_t subnqn[SPDK_NVME_NQN_FIELD_SIZE];
2679 :
2680 : uint8_t reserved5[768];
2681 :
2682 : struct spdk_nvme_cdata_nvmf_specific nvmf_specific;
2683 :
2684 : /* bytes 2048-3071: power state descriptors */
2685 : struct spdk_nvme_power_state psd[32];
2686 :
2687 : /* bytes 3072-4095: vendor specific */
2688 : uint8_t vs[1024];
2689 : };
2690 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ctrlr_data) == 4096, "Incorrect size");
2691 : #pragma pack(pop)
2692 :
2693 : struct spdk_nvme_zns_ctrlr_data {
2694 : /** zone append size limit */
2695 : uint8_t zasl;
2696 :
2697 : uint8_t reserved1[4095];
2698 : };
2699 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_zns_ctrlr_data) == 4096, "Incorrect size");
2700 :
2701 : #pragma pack(push, 1)
2702 : struct spdk_nvme_primary_ctrl_capabilities {
2703 : /** controller id */
2704 : uint16_t cntlid;
2705 : /** port identifier */
2706 : uint16_t portid;
2707 : /** controller resource types */
2708 : struct {
2709 : uint8_t vq_supported : 1;
2710 : uint8_t vi_supported : 1;
2711 : uint8_t reserved : 6;
2712 : } crt;
2713 : uint8_t reserved[27];
2714 : /** total number of VQ flexible resources */
2715 : uint32_t vqfrt;
2716 : /** total number of VQ flexible resources assigned to secondary controllers */
2717 : uint32_t vqrfa;
2718 : /** total number of VQ flexible resources allocated to primary controller */
2719 : uint16_t vqrfap;
2720 : /** total number of VQ Private resources for the primary controller */
2721 : uint16_t vqprt;
2722 : /** max number of VQ flexible Resources that may be assigned to a secondary controller */
2723 : uint16_t vqfrsm;
2724 : /** preferred granularity of assigning and removing VQ Flexible Resources */
2725 : uint16_t vqgran;
2726 : uint8_t reserved1[16];
2727 : /** total number of VI flexible resources for the primary and its secondary controllers */
2728 : uint32_t vifrt;
2729 : /** total number of VI flexible resources assigned to the secondary controllers */
2730 : uint32_t virfa;
2731 : /** total number of VI flexible resources currently allocated to the primary controller */
2732 : uint16_t virfap;
2733 : /** total number of VI private resources for the primary controller */
2734 : uint16_t viprt;
2735 : /** max number of VI flexible resources that may be assigned to a secondary controller */
2736 : uint16_t vifrsm;
2737 : /** preferred granularity of assigning and removing VI flexible resources */
2738 : uint16_t vigran;
2739 : uint8_t reserved2[4016];
2740 : };
2741 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_primary_ctrl_capabilities) == 4096, "Incorrect size");
2742 :
2743 : struct spdk_nvme_secondary_ctrl_entry {
2744 : /** controller identifier of the secondary controller */
2745 : uint16_t scid;
2746 : /** controller identifier of the associated primary controller */
2747 : uint16_t pcid;
2748 : /** indicates the state of the secondary controller */
2749 : struct {
2750 : uint8_t is_online : 1;
2751 : uint8_t reserved : 7;
2752 : } scs;
2753 : uint8_t reserved[3];
2754 : /** VF number if the secondary controller is an SR-IOV VF */
2755 : uint16_t vfn;
2756 : /** number of VQ flexible resources assigned to the indicated secondary controller */
2757 : uint16_t nvq;
2758 : /** number of VI flexible resources assigned to the indicated secondary controller */
2759 : uint16_t nvi;
2760 : uint8_t reserved1[18];
2761 : };
2762 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_secondary_ctrl_entry) == 32, "Incorrect size");
2763 :
2764 : struct spdk_nvme_secondary_ctrl_list {
2765 : /** number of Secondary controller entries in the list */
2766 : uint8_t number;
2767 : uint8_t reserved[31];
2768 : struct spdk_nvme_secondary_ctrl_entry entries[127];
2769 : };
2770 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_secondary_ctrl_list) == 4096, "Incorrect size");
2771 : #pragma pack(pop)
2772 :
2773 : struct spdk_nvme_ns_data {
2774 : /** namespace size */
2775 : uint64_t nsze;
2776 :
2777 : /** namespace capacity */
2778 : uint64_t ncap;
2779 :
2780 : /** namespace utilization */
2781 : uint64_t nuse;
2782 :
2783 : /** namespace features */
2784 : struct {
2785 : /** thin provisioning */
2786 : uint8_t thin_prov : 1;
2787 :
2788 : /** NAWUN, NAWUPF, and NACWU are defined for this namespace */
2789 : uint8_t ns_atomic_write_unit : 1;
2790 :
2791 : /** Supports Deallocated or Unwritten LBA error for this namespace */
2792 : uint8_t dealloc_or_unwritten_error : 1;
2793 :
2794 : /** Non-zero NGUID and EUI64 for namespace are never reused */
2795 : uint8_t guid_never_reused : 1;
2796 :
2797 : /** Optimal Performance field */
2798 : uint8_t optperf : 1;
2799 :
2800 : uint8_t reserved1 : 3;
2801 : } nsfeat;
2802 :
2803 : /** number of lba formats */
2804 : uint8_t nlbaf;
2805 :
2806 : /** formatted lba size */
2807 : struct {
2808 : /** LSB for Format index */
2809 : uint8_t format : 4;
2810 : uint8_t extended : 1;
2811 : /** MSB for Format index, to be ignored if nlbaf <= 16 */
2812 : uint8_t msb_format : 2;
2813 : uint8_t reserved2 : 1;
2814 : } flbas;
2815 :
2816 : /** metadata capabilities */
2817 : struct {
2818 : /** metadata can be transferred as part of data prp list */
2819 : uint8_t extended : 1;
2820 :
2821 : /** metadata can be transferred with separate metadata pointer */
2822 : uint8_t pointer : 1;
2823 :
2824 : /** reserved */
2825 : uint8_t reserved3 : 6;
2826 : } mc;
2827 :
2828 : /** end-to-end data protection capabilities */
2829 : struct {
2830 : /** protection information type 1 */
2831 : uint8_t pit1 : 1;
2832 :
2833 : /** protection information type 2 */
2834 : uint8_t pit2 : 1;
2835 :
2836 : /** protection information type 3 */
2837 : uint8_t pit3 : 1;
2838 :
2839 : /** first eight bytes of metadata */
2840 : uint8_t md_start : 1;
2841 :
2842 : /** last eight bytes of metadata */
2843 : uint8_t md_end : 1;
2844 : } dpc;
2845 :
2846 : /** end-to-end data protection type settings */
2847 : struct {
2848 : /** protection information type */
2849 : uint8_t pit : 3;
2850 :
2851 : /** 1 == protection info transferred at start of metadata */
2852 : /** 0 == protection info transferred at end of metadata */
2853 : uint8_t md_start : 1;
2854 :
2855 : uint8_t reserved4 : 4;
2856 : } dps;
2857 :
2858 : /** namespace multi-path I/O and namespace sharing capabilities */
2859 : struct {
2860 : uint8_t can_share : 1;
2861 : uint8_t reserved : 7;
2862 : } nmic;
2863 :
2864 : /** reservation capabilities */
2865 : union {
2866 : struct {
2867 : /** supports persist through power loss */
2868 : uint8_t persist : 1;
2869 :
2870 : /** supports write exclusive */
2871 : uint8_t write_exclusive : 1;
2872 :
2873 : /** supports exclusive access */
2874 : uint8_t exclusive_access : 1;
2875 :
2876 : /** supports write exclusive - registrants only */
2877 : uint8_t write_exclusive_reg_only : 1;
2878 :
2879 : /** supports exclusive access - registrants only */
2880 : uint8_t exclusive_access_reg_only : 1;
2881 :
2882 : /** supports write exclusive - all registrants */
2883 : uint8_t write_exclusive_all_reg : 1;
2884 :
2885 : /** supports exclusive access - all registrants */
2886 : uint8_t exclusive_access_all_reg : 1;
2887 :
2888 : /** supports ignore existing key */
2889 : uint8_t ignore_existing_key : 1;
2890 : } rescap;
2891 : uint8_t raw;
2892 : } nsrescap;
2893 : /** format progress indicator */
2894 : struct {
2895 : uint8_t percentage_remaining : 7;
2896 : uint8_t fpi_supported : 1;
2897 : } fpi;
2898 :
2899 : /** deallocate logical features */
2900 : union {
2901 : uint8_t raw;
2902 : struct {
2903 : /**
2904 : * Value read from deallocated blocks
2905 : *
2906 : * 000b = not reported
2907 : * 001b = all bytes 0x00
2908 : * 010b = all bytes 0xFF
2909 : *
2910 : * \ref spdk_nvme_dealloc_logical_block_read_value
2911 : */
2912 : uint8_t read_value : 3;
2913 :
2914 : /** Supports Deallocate bit in Write Zeroes */
2915 : uint8_t write_zero_deallocate : 1;
2916 :
2917 : /**
2918 : * Guard field behavior for deallocated logical blocks
2919 : * 0: contains 0xFFFF
2920 : * 1: contains CRC for read value
2921 : */
2922 : uint8_t guard_value : 1;
2923 :
2924 : uint8_t reserved : 3;
2925 : } bits;
2926 : } dlfeat;
2927 :
2928 : /** namespace atomic write unit normal */
2929 : uint16_t nawun;
2930 :
2931 : /** namespace atomic write unit power fail */
2932 : uint16_t nawupf;
2933 :
2934 : /** namespace atomic compare & write unit */
2935 : uint16_t nacwu;
2936 :
2937 : /** namespace atomic boundary size normal */
2938 : uint16_t nabsn;
2939 :
2940 : /** namespace atomic boundary offset */
2941 : uint16_t nabo;
2942 :
2943 : /** namespace atomic boundary size power fail */
2944 : uint16_t nabspf;
2945 :
2946 : /** namespace optimal I/O boundary in logical blocks */
2947 : uint16_t noiob;
2948 :
2949 : /** NVM capacity */
2950 : uint64_t nvmcap[2];
2951 :
2952 : /** Namespace Preferred Write Granularity */
2953 : uint16_t npwg;
2954 :
2955 : /** Namespace Preferred Write Alignment */
2956 : uint16_t npwa;
2957 :
2958 : /** Namespace Preferred Deallocate Granularity */
2959 : uint16_t npdg;
2960 :
2961 : /** Namespace Preferred Deallocate Alignment */
2962 : uint16_t npda;
2963 :
2964 : /** Namespace Optimal Write Size */
2965 : uint16_t nows;
2966 :
2967 : /** Maximum Single Source Range Length */
2968 : uint16_t mssrl;
2969 :
2970 : /** Maximum Copy Length */
2971 : uint32_t mcl;
2972 :
2973 : /** Maximum Source Range Count */
2974 : uint8_t msrc;
2975 :
2976 : uint8_t reserved81[11];
2977 :
2978 : /** ANA group identifier */
2979 : uint32_t anagrpid;
2980 :
2981 : uint8_t reserved96[3];
2982 :
2983 : /** namespace attributes */
2984 : struct {
2985 : /** Namespace write protected */
2986 : uint8_t write_protected : 1;
2987 : uint8_t reserved : 7;
2988 : } nsattr;
2989 :
2990 : /** NVM Set Identifier */
2991 : uint16_t nvmsetid;
2992 :
2993 : /** Endurance group identifier */
2994 : uint16_t endgid;
2995 :
2996 : /** namespace globally unique identifier */
2997 : uint8_t nguid[16];
2998 :
2999 : /** IEEE extended unique identifier */
3000 : uint64_t eui64;
3001 :
3002 : /** lba format support */
3003 : struct {
3004 : /** metadata size */
3005 : uint32_t ms : 16;
3006 :
3007 : /** lba data size */
3008 : uint32_t lbads : 8;
3009 :
3010 : /** relative performance */
3011 : uint32_t rp : 2;
3012 :
3013 : uint32_t reserved6 : 6;
3014 : } lbaf[64];
3015 :
3016 : uint8_t vendor_specific[3712];
3017 : };
3018 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_data) == 4096, "Incorrect size");
3019 :
3020 : struct spdk_nvme_nvm_ctrlr_data {
3021 : /* verify size limit */
3022 : uint8_t vsl;
3023 :
3024 : /* write zeroes size limit */
3025 : uint8_t wzsl;
3026 :
3027 : /* write uncorrectable size limit */
3028 : uint8_t wusl;
3029 :
3030 : /* dataset management ranges limit */
3031 : uint8_t dmrl;
3032 :
3033 : /* dataset management range size limit */
3034 : uint32_t dmrsl;
3035 :
3036 : /* dataset management size limit */
3037 : uint64_t dmsl;
3038 :
3039 : uint8_t rsvd16[4080];
3040 : };
3041 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_nvm_ctrlr_data) == 4096, "Incorrect size");
3042 :
3043 : struct spdk_nvme_zns_ns_data {
3044 : /** zone operation characteristics */
3045 : struct {
3046 : uint16_t variable_zone_capacity : 1;
3047 : uint16_t zone_active_excursions : 1;
3048 : uint16_t reserved0 : 14;
3049 : } zoc;
3050 :
3051 : /** optional zoned command support */
3052 : struct {
3053 : uint16_t read_across_zone_boundaries : 1;
3054 : uint16_t reserved0 : 15;
3055 : } ozcs;
3056 :
3057 : /** maximum active resources */
3058 : uint32_t mar;
3059 :
3060 : /** maximum open resources */
3061 : uint32_t mor;
3062 :
3063 : /** reset recommended limit */
3064 : uint32_t rrl;
3065 :
3066 : /** finish recommended limit */
3067 : uint32_t frl;
3068 :
3069 : /** reset recommended limit 1 */
3070 : uint32_t rrl1;
3071 :
3072 : /** reset recommended limit 2 */
3073 : uint32_t rrl2;
3074 :
3075 : /** reset recommended limit 3 */
3076 : uint32_t rrl3;
3077 :
3078 : /** finish recommended limit 1 */
3079 : uint32_t frl1;
3080 :
3081 : /** finish recommended limit 2 */
3082 : uint32_t frl2;
3083 :
3084 : /** finish recommended limit 3 */
3085 : uint32_t frl3;
3086 :
3087 : uint8_t reserved44[2772];
3088 :
3089 : /** zns lba format extension support */
3090 : struct {
3091 : /** zone size */
3092 : uint64_t zsze;
3093 :
3094 : /** zone descriptor extension size */
3095 : uint64_t zdes : 8;
3096 :
3097 : uint64_t reserved15 : 56;
3098 : } lbafe[64];
3099 :
3100 : uint8_t vendor_specific[256];
3101 : };
3102 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_zns_ns_data) == 4096, "Incorrect size");
3103 :
3104 : /**
3105 : * IO command set vector for IDENTIFY_IOCS
3106 : */
3107 : struct spdk_nvme_iocs_vector {
3108 : uint8_t nvm : 1;
3109 : uint8_t kv : 1;
3110 : uint8_t zns : 1;
3111 : uint8_t rsvd : 5;
3112 : uint8_t rsvd2[7];
3113 : };
3114 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_iocs_vector) == 8, "Incorrect size");
3115 :
3116 : /**
3117 : * Deallocated logical block features - read value
3118 : */
3119 : enum spdk_nvme_dealloc_logical_block_read_value {
3120 : /** Not reported */
3121 : SPDK_NVME_DEALLOC_NOT_REPORTED = 0,
3122 :
3123 : /** Deallocated blocks read 0x00 */
3124 : SPDK_NVME_DEALLOC_READ_00 = 1,
3125 :
3126 : /** Deallocated blocks read 0xFF */
3127 : SPDK_NVME_DEALLOC_READ_FF = 2,
3128 : };
3129 :
3130 : /**
3131 : * Reservation Type Encoding
3132 : */
3133 : enum spdk_nvme_reservation_type {
3134 : /* 0x00 - reserved */
3135 :
3136 : /* Write Exclusive Reservation */
3137 : SPDK_NVME_RESERVE_WRITE_EXCLUSIVE = 0x1,
3138 :
3139 : /* Exclusive Access Reservation */
3140 : SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS = 0x2,
3141 :
3142 : /* Write Exclusive - Registrants Only Reservation */
3143 : SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_REG_ONLY = 0x3,
3144 :
3145 : /* Exclusive Access - Registrants Only Reservation */
3146 : SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_REG_ONLY = 0x4,
3147 :
3148 : /* Write Exclusive - All Registrants Reservation */
3149 : SPDK_NVME_RESERVE_WRITE_EXCLUSIVE_ALL_REGS = 0x5,
3150 :
3151 : /* Exclusive Access - All Registrants Reservation */
3152 : SPDK_NVME_RESERVE_EXCLUSIVE_ACCESS_ALL_REGS = 0x6,
3153 :
3154 : /* 0x7-0xFF - Reserved */
3155 : };
3156 :
3157 : struct spdk_nvme_reservation_acquire_data {
3158 : /** current reservation key */
3159 : uint64_t crkey;
3160 : /** preempt reservation key */
3161 : uint64_t prkey;
3162 : };
3163 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_acquire_data) == 16, "Incorrect size");
3164 :
3165 : /**
3166 : * Reservation Acquire action
3167 : */
3168 : enum spdk_nvme_reservation_acquire_action {
3169 : SPDK_NVME_RESERVE_ACQUIRE = 0x0,
3170 : SPDK_NVME_RESERVE_PREEMPT = 0x1,
3171 : SPDK_NVME_RESERVE_PREEMPT_ABORT = 0x2,
3172 : };
3173 :
3174 : #pragma pack(push, 1)
3175 : struct spdk_nvme_reservation_status_data {
3176 : /** reservation action generation counter */
3177 : uint32_t gen;
3178 : /** reservation type */
3179 : uint8_t rtype;
3180 : /** number of registered controllers */
3181 : uint16_t regctl;
3182 : uint16_t reserved1;
3183 : /** persist through power loss state */
3184 : uint8_t ptpls;
3185 : uint8_t reserved[14];
3186 : };
3187 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_status_data) == 24, "Incorrect size");
3188 :
3189 : struct spdk_nvme_reservation_status_extended_data {
3190 : struct spdk_nvme_reservation_status_data data;
3191 : uint8_t reserved[40];
3192 : };
3193 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_status_extended_data) == 64,
3194 : "Incorrect size");
3195 :
3196 : struct spdk_nvme_registered_ctrlr_data {
3197 : /** controller id */
3198 : uint16_t cntlid;
3199 : /** reservation status */
3200 : struct {
3201 : uint8_t status : 1;
3202 : uint8_t reserved1 : 7;
3203 : } rcsts;
3204 : uint8_t reserved2[5];
3205 : /** 64-bit host identifier */
3206 : uint64_t hostid;
3207 : /** reservation key */
3208 : uint64_t rkey;
3209 : };
3210 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_registered_ctrlr_data) == 24, "Incorrect size");
3211 :
3212 : struct spdk_nvme_registered_ctrlr_extended_data {
3213 : /** controller id */
3214 : uint16_t cntlid;
3215 : /** reservation status */
3216 : struct {
3217 : uint8_t status : 1;
3218 : uint8_t reserved1 : 7;
3219 : } rcsts;
3220 : uint8_t reserved2[5];
3221 : /** reservation key */
3222 : uint64_t rkey;
3223 : /** 128-bit host identifier */
3224 : uint8_t hostid[16];
3225 : uint8_t reserved3[32];
3226 : };
3227 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_registered_ctrlr_extended_data) == 64, "Incorrect size");
3228 : #pragma pack(pop)
3229 :
3230 : /**
3231 : * Change persist through power loss state for
3232 : * Reservation Register command
3233 : */
3234 : enum spdk_nvme_reservation_register_cptpl {
3235 : SPDK_NVME_RESERVE_PTPL_NO_CHANGES = 0x0,
3236 : SPDK_NVME_RESERVE_PTPL_CLEAR_POWER_ON = 0x2,
3237 : SPDK_NVME_RESERVE_PTPL_PERSIST_POWER_LOSS = 0x3,
3238 : };
3239 :
3240 : /**
3241 : * Registration action for Reservation Register command
3242 : */
3243 : enum spdk_nvme_reservation_register_action {
3244 : SPDK_NVME_RESERVE_REGISTER_KEY = 0x0,
3245 : SPDK_NVME_RESERVE_UNREGISTER_KEY = 0x1,
3246 : SPDK_NVME_RESERVE_REPLACE_KEY = 0x2,
3247 : };
3248 :
3249 : struct spdk_nvme_reservation_register_data {
3250 : /** current reservation key */
3251 : uint64_t crkey;
3252 : /** new reservation key */
3253 : uint64_t nrkey;
3254 : };
3255 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_register_data) == 16, "Incorrect size");
3256 :
3257 : struct spdk_nvme_reservation_key_data {
3258 : /** current reservation key */
3259 : uint64_t crkey;
3260 : };
3261 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_key_data) == 8, "Incorrect size");
3262 :
3263 : /**
3264 : * Reservation Release action
3265 : */
3266 : enum spdk_nvme_reservation_release_action {
3267 : SPDK_NVME_RESERVE_RELEASE = 0x0,
3268 : SPDK_NVME_RESERVE_CLEAR = 0x1,
3269 : };
3270 :
3271 : /**
3272 : * Reservation notification log page type
3273 : */
3274 : enum spdk_nvme_reservation_notification_log_page_type {
3275 : SPDK_NVME_RESERVATION_LOG_PAGE_EMPTY = 0x0,
3276 : SPDK_NVME_REGISTRATION_PREEMPTED = 0x1,
3277 : SPDK_NVME_RESERVATION_RELEASED = 0x2,
3278 : SPDK_NVME_RESERVATION_PREEMPTED = 0x3,
3279 : };
3280 :
3281 : /**
3282 : * Reservation notification log
3283 : */
3284 : struct spdk_nvme_reservation_notification_log {
3285 : /** 64-bit incrementing reservation notification log page count */
3286 : uint64_t log_page_count;
3287 : /** Reservation notification log page type */
3288 : uint8_t type;
3289 : /** Number of additional available reservation notification log pages */
3290 : uint8_t num_avail_log_pages;
3291 : uint8_t reserved[2];
3292 : uint32_t nsid;
3293 : uint8_t reserved1[48];
3294 : };
3295 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_reservation_notification_log) == 64, "Incorrect size");
3296 :
3297 : /* Mask Registration Preempted Notification */
3298 : #define SPDK_NVME_REGISTRATION_PREEMPTED_MASK (1U << 1)
3299 : /* Mask Reservation Released Notification */
3300 : #define SPDK_NVME_RESERVATION_RELEASED_MASK (1U << 2)
3301 : /* Mask Reservation Preempted Notification */
3302 : #define SPDK_NVME_RESERVATION_PREEMPTED_MASK (1U << 3)
3303 :
3304 : /**
3305 : * Log page identifiers for SPDK_NVME_OPC_GET_LOG_PAGE
3306 : */
3307 : enum spdk_nvme_log_page {
3308 : /** Supported log pages (optional) */
3309 : SPDK_NVME_LOG_SUPPORTED_LOG_PAGES = 0x00,
3310 :
3311 : /** Error information (mandatory) - \ref spdk_nvme_error_information_entry */
3312 : SPDK_NVME_LOG_ERROR = 0x01,
3313 :
3314 : /** SMART / health information (mandatory) - \ref spdk_nvme_health_information_page */
3315 : SPDK_NVME_LOG_HEALTH_INFORMATION = 0x02,
3316 :
3317 : /** Firmware slot information (mandatory) - \ref spdk_nvme_firmware_page */
3318 : SPDK_NVME_LOG_FIRMWARE_SLOT = 0x03,
3319 :
3320 : /** Changed namespace list (optional) */
3321 : SPDK_NVME_LOG_CHANGED_NS_LIST = 0x04,
3322 :
3323 : /** Command effects log (optional) */
3324 : SPDK_NVME_LOG_COMMAND_EFFECTS_LOG = 0x05,
3325 :
3326 : /** Device self test (optional) */
3327 : SPDK_NVME_LOG_DEVICE_SELF_TEST = 0x06,
3328 :
3329 : /** Host initiated telemetry log (optional) */
3330 : SPDK_NVME_LOG_TELEMETRY_HOST_INITIATED = 0x07,
3331 :
3332 : /** Controller initiated telemetry log (optional) */
3333 : SPDK_NVME_LOG_TELEMETRY_CTRLR_INITIATED = 0x08,
3334 :
3335 : /** Endurance group Information (optional) */
3336 : SPDK_NVME_LOG_ENDURANCE_GROUP_INFORMATION = 0x09,
3337 :
3338 : /** Predictable latency per NVM set (optional) */
3339 : SPDK_NVME_LOG_PREDICATBLE_LATENCY = 0x0A,
3340 :
3341 : /** Predictable latency event aggregrate (optional) */
3342 : SPDK_NVME_LOG_PREDICTABLE_LATENCY_EVENT = 0x0B,
3343 :
3344 : /** Asymmetric namespace access log (optional) */
3345 : SPDK_NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS = 0x0C,
3346 :
3347 : /** Persistent event log (optional) */
3348 : SPDK_NVME_LOG_PERSISTENT_EVENT_LOG = 0x0D,
3349 :
3350 : /* 0x0E NVM command set specific */
3351 :
3352 : /** Endurance group event aggregate (optional) */
3353 : SPDK_NVME_LOG_ENDURANCE_GROUP_EVENT = 0x0F,
3354 :
3355 : /** Media unit status (optional) */
3356 : SPDK_NVME_LOG_MEDIA_UNIT_STATUS = 0x10,
3357 :
3358 : /** Supported capacity configuration list (optional) */
3359 : SPDK_NVME_LOG_CAPACITY_CONFIGURATION_LIST = 0x11,
3360 :
3361 : /** Feature identifiers supported and effects (optional) */
3362 : SPDK_NVME_LOG_FEATURE_IDS_EFFECTS = 0x12,
3363 :
3364 : /** NVMe-MI commands supported and effects (optional) */
3365 : SPDK_NVME_LOG_NVME_MI_COMMANDS_EFFECTS = 0x13,
3366 :
3367 : /** Command and feature lockdown (optional) */
3368 : SPDK_NVME_LOG_COMMAND_FEATURE_LOCKDOWN = 0x14,
3369 :
3370 : /** Boot partition (optional) */
3371 : SPDK_NVME_LOG_BOOT_PARTITION = 0x15,
3372 :
3373 : /** Rotational media information (optional) */
3374 : SPDK_NVME_LOG_ROTATIONAL_MEDIA_INFORMATION = 0x16,
3375 :
3376 : /* 0x17-0x1f - reserved */
3377 :
3378 : /** FDP configurations (optional) */
3379 : SPDK_NVME_LOG_FDP_CONFIGURATIONS = 0x20,
3380 :
3381 : /** Reclaim unit handle usage (optional) */
3382 : SPDK_NVME_LOG_RECLAIM_UNIT_HANDLE_USAGE = 0x21,
3383 :
3384 : /** FDP statistics (optional) */
3385 : SPDK_NVME_LOG_FDP_STATISTICS = 0x22,
3386 :
3387 : /** FDP events (optional) */
3388 : SPDK_NVME_LOG_FDP_EVENTS = 0x23,
3389 :
3390 : /* 0x24-0x6f - reserved */
3391 :
3392 : /** Discovery(refer to the NVMe over Fabrics specification) */
3393 : SPDK_NVME_LOG_DISCOVERY = 0x70,
3394 :
3395 : /* 0x71-0x7f - reserved for NVMe over Fabrics */
3396 :
3397 : /** Reservation notification (optional) */
3398 : SPDK_NVME_LOG_RESERVATION_NOTIFICATION = 0x80,
3399 :
3400 : /** Sanitize status (optional) */
3401 : SPDK_NVME_LOG_SANITIZE_STATUS = 0x81,
3402 :
3403 : /* 0x82-0xBE - I/O command set specific */
3404 :
3405 : /** Changed zone list (refer to Zoned Namespace command set) */
3406 : SPDK_NVME_LOG_CHANGED_ZONE_LIST = 0xBF,
3407 :
3408 : /* 0xC0-0xFF - vendor specific */
3409 : SPDK_NVME_LOG_VENDOR_SPECIFIC_START = 0xc0,
3410 : SPDK_NVME_LOG_VENDOR_SPECIFIC_END = 0xff,
3411 : };
3412 :
3413 : #define spdk_nvme_log_page_is_vendor_specific(lid) ((lid) >= SPDK_NVME_LOG_VENDOR_SPECIFIC_START)
3414 :
3415 : /**
3416 : * Error information log page (\ref SPDK_NVME_LOG_ERROR)
3417 : */
3418 : struct spdk_nvme_error_information_entry {
3419 : uint64_t error_count;
3420 : uint16_t sqid;
3421 : uint16_t cid;
3422 : struct spdk_nvme_status status;
3423 : uint16_t error_location;
3424 : uint64_t lba;
3425 : uint32_t nsid;
3426 : uint8_t vendor_specific;
3427 : uint8_t trtype;
3428 : uint8_t reserved30[2];
3429 : uint64_t command_specific;
3430 : uint16_t trtype_specific;
3431 : uint8_t reserved42[22];
3432 : };
3433 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_error_information_entry) == 64, "Incorrect size");
3434 :
3435 : /**
3436 : * SMART / health information page (\ref SPDK_NVME_LOG_HEALTH_INFORMATION)
3437 : */
3438 : #pragma pack(push, 1)
3439 : struct spdk_nvme_health_information_page {
3440 : union spdk_nvme_critical_warning_state critical_warning;
3441 :
3442 : uint16_t temperature;
3443 : uint8_t available_spare;
3444 : uint8_t available_spare_threshold;
3445 : uint8_t percentage_used;
3446 :
3447 : uint8_t reserved[26];
3448 :
3449 : /*
3450 : * Note that the following are 128-bit values, but are
3451 : * defined as an array of 2 64-bit values.
3452 : */
3453 : /* Data Units Read is always in 512-byte units. */
3454 : uint64_t data_units_read[2];
3455 : /* Data Units Written is always in 512-byte units. */
3456 : uint64_t data_units_written[2];
3457 : /* For NVM command set, this includes Compare commands. */
3458 : uint64_t host_read_commands[2];
3459 : uint64_t host_write_commands[2];
3460 : /* Controller Busy Time is reported in minutes. */
3461 : uint64_t controller_busy_time[2];
3462 : uint64_t power_cycles[2];
3463 : uint64_t power_on_hours[2];
3464 : uint64_t unsafe_shutdowns[2];
3465 : uint64_t media_errors[2];
3466 : uint64_t num_error_info_log_entries[2];
3467 : /* Controller temperature related. */
3468 : uint32_t warning_temp_time;
3469 : uint32_t critical_temp_time;
3470 : uint16_t temp_sensor[8];
3471 :
3472 : uint8_t reserved2[296];
3473 : };
3474 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_health_information_page) == 512, "Incorrect size");
3475 : #pragma pack(pop)
3476 :
3477 : /* Commands Supported and Effects Data Structure */
3478 : struct spdk_nvme_cmds_and_effect_entry {
3479 : /** Command Supported */
3480 : uint16_t csupp : 1;
3481 :
3482 : /** Logic Block Content Change */
3483 : uint16_t lbcc : 1;
3484 :
3485 : /** Namespace Capability Change */
3486 : uint16_t ncc : 1;
3487 :
3488 : /** Namespace Inventory Change */
3489 : uint16_t nic : 1;
3490 :
3491 : /** Controller Capability Change */
3492 : uint16_t ccc : 1;
3493 :
3494 : uint16_t reserved1 : 11;
3495 :
3496 : /* Command Submission and Execution recommendation
3497 : * 000 - No command submission or execution restriction
3498 : * 001 - Submitted when there is no outstanding command to same NS
3499 : * 010 - Submitted when there is no outstanding command to any NS
3500 : * others - Reserved
3501 : * \ref command_submission_and_execution in section 5.14.1.5 NVMe Revision 1.3
3502 : */
3503 : uint16_t cse : 3;
3504 :
3505 : uint16_t reserved2 : 13;
3506 : };
3507 :
3508 : /* Commands Supported and Effects Log Page */
3509 : struct spdk_nvme_cmds_and_effect_log_page {
3510 : /** Commands Supported and Effects Data Structure for the Admin Commands */
3511 : struct spdk_nvme_cmds_and_effect_entry admin_cmds_supported[256];
3512 :
3513 : /** Commands Supported and Effects Data Structure for the IO Commands */
3514 : struct spdk_nvme_cmds_and_effect_entry io_cmds_supported[256];
3515 :
3516 : uint8_t reserved0[2048];
3517 : };
3518 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_cmds_and_effect_log_page) == 4096, "Incorrect size");
3519 :
3520 : /*
3521 : * Get Log Page – Telemetry Host/Controller Initiated Log (Log Identifiers 07h/08h)
3522 : */
3523 : struct spdk_nvme_telemetry_log_page_hdr {
3524 : /* Log page identifier */
3525 : uint8_t lpi;
3526 : uint8_t rsvd[4];
3527 : uint8_t ieee_oui[3];
3528 : /* Data area 1 last block */
3529 : uint16_t dalb1;
3530 : /* Data area 2 last block */
3531 : uint16_t dalb2;
3532 : /* Data area 3 last block */
3533 : uint16_t dalb3;
3534 : uint8_t rsvd1[368];
3535 : /* Controller initiated data avail */
3536 : uint8_t ctrlr_avail;
3537 : /* Controller initiated telemetry data generation */
3538 : uint8_t ctrlr_gen;
3539 : /* Reason identifier */
3540 : uint8_t rsnident[128];
3541 : uint8_t telemetry_datablock[0];
3542 : };
3543 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_telemetry_log_page_hdr) == 512, "Incorrect size");
3544 :
3545 : /**
3546 : * Sanitize Status Type
3547 : */
3548 : enum spdk_nvme_sanitize_status_type {
3549 : SPDK_NVME_NEVER_BEEN_SANITIZED = 0x0,
3550 : SPDK_NVME_RECENT_SANITIZE_SUCCESSFUL = 0x1,
3551 : SPDK_NVME_SANITIZE_IN_PROGRESS = 0x2,
3552 : SPDK_NVME_SANITIZE_FAILED = 0x3,
3553 : };
3554 :
3555 : /**
3556 : * Sanitize status sstat field
3557 : */
3558 : struct spdk_nvme_sanitize_status_sstat {
3559 : uint16_t status : 3;
3560 : uint16_t complete_pass : 5;
3561 : uint16_t global_data_erase : 1;
3562 : uint16_t reserved : 7;
3563 : };
3564 :
3565 : /**
3566 : * Sanitize log page
3567 : */
3568 : struct spdk_nvme_sanitize_status_log_page {
3569 : /* Sanitize progress */
3570 : uint16_t sprog;
3571 : /* Sanitize status */
3572 : struct spdk_nvme_sanitize_status_sstat sstat;
3573 : /* CDW10 of sanitize command */
3574 : uint32_t scdw10;
3575 : /* Estimated overwrite time in seconds */
3576 : uint32_t et_overwrite;
3577 : /* Estimated block erase time in seconds */
3578 : uint32_t et_block_erase;
3579 : /* Estimated crypto erase time in seconds */
3580 : uint32_t et_crypto_erase;
3581 : uint8_t reserved[492];
3582 : };
3583 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_sanitize_status_log_page) == 512, "Incorrect size");
3584 :
3585 : /**
3586 : * Asynchronous Event Type
3587 : */
3588 : enum spdk_nvme_async_event_type {
3589 : /* Error Status */
3590 : SPDK_NVME_ASYNC_EVENT_TYPE_ERROR = 0x0,
3591 : /* SMART/Health Status */
3592 : SPDK_NVME_ASYNC_EVENT_TYPE_SMART = 0x1,
3593 : /* Notice */
3594 : SPDK_NVME_ASYNC_EVENT_TYPE_NOTICE = 0x2,
3595 : /* 0x3 - 0x5 Reserved */
3596 :
3597 : /* I/O Command Set Specific Status */
3598 : SPDK_NVME_ASYNC_EVENT_TYPE_IO = 0x6,
3599 : /* Vendor Specific */
3600 : SPDK_NVME_ASYNC_EVENT_TYPE_VENDOR = 0x7,
3601 : };
3602 :
3603 : /**
3604 : * Asynchronous Event Information for Error Status
3605 : */
3606 : enum spdk_nvme_async_event_info_error {
3607 : /* Write to Invalid Doorbell Register */
3608 : SPDK_NVME_ASYNC_EVENT_WRITE_INVALID_DB = 0x0,
3609 : /* Invalid Doorbell Register Write Value */
3610 : SPDK_NVME_ASYNC_EVENT_INVALID_DB_WRITE = 0x1,
3611 : /* Diagnostic Failure */
3612 : SPDK_NVME_ASYNC_EVENT_DIAGNOSTIC_FAILURE = 0x2,
3613 : /* Persistent Internal Error */
3614 : SPDK_NVME_ASYNC_EVENT_PERSISTENT_INTERNAL = 0x3,
3615 : /* Transient Internal Error */
3616 : SPDK_NVME_ASYNC_EVENT_TRANSIENT_INTERNAL = 0x4,
3617 : /* Firmware Image Load Error */
3618 : SPDK_NVME_ASYNC_EVENT_FW_IMAGE_LOAD = 0x5,
3619 :
3620 : /* 0x6 - 0xFF Reserved */
3621 : };
3622 :
3623 : /**
3624 : * Asynchronous Event Information for SMART/Health Status
3625 : */
3626 : enum spdk_nvme_async_event_info_smart {
3627 : /* NVM Subsystem Reliability */
3628 : SPDK_NVME_ASYNC_EVENT_SUBSYSTEM_RELIABILITY = 0x0,
3629 : /* Temperature Threshold */
3630 : SPDK_NVME_ASYNC_EVENT_TEMPERATURE_THRESHOLD = 0x1,
3631 : /* Spare Below Threshold */
3632 : SPDK_NVME_ASYNC_EVENT_SPARE_BELOW_THRESHOLD = 0x2,
3633 :
3634 : /* 0x3 - 0xFF Reserved */
3635 : };
3636 :
3637 : /**
3638 : * Asynchronous Event Information for Notice
3639 : */
3640 : enum spdk_nvme_async_event_info_notice {
3641 : /* Namespace Attribute Changed */
3642 : SPDK_NVME_ASYNC_EVENT_NS_ATTR_CHANGED = 0x0,
3643 : /* Firmware Activation Starting */
3644 : SPDK_NVME_ASYNC_EVENT_FW_ACTIVATION_START = 0x1,
3645 : /* Telemetry Log Changed */
3646 : SPDK_NVME_ASYNC_EVENT_TELEMETRY_LOG_CHANGED = 0x2,
3647 : /* Asymmetric Namespace Access Change */
3648 : SPDK_NVME_ASYNC_EVENT_ANA_CHANGE = 0x3,
3649 :
3650 : /* 0x4 - 0xEF Reserved */
3651 :
3652 : /** Discovery log change event(refer to the NVMe over Fabrics specification) */
3653 : SPDK_NVME_ASYNC_EVENT_DISCOVERY_LOG_CHANGE = 0xF0,
3654 :
3655 : /* 0xF1 - 0xFF Reserved */
3656 : };
3657 :
3658 : /**
3659 : * Asynchronous Event Information for NVM Command Set Specific Status
3660 : */
3661 : enum spdk_nvme_async_event_info_nvm_command_set {
3662 : /* Reservation Log Page Available */
3663 : SPDK_NVME_ASYNC_EVENT_RESERVATION_LOG_AVAIL = 0x0,
3664 : /* Sanitize Operation Completed */
3665 : SPDK_NVME_ASYNC_EVENT_SANITIZE_COMPLETED = 0x1,
3666 :
3667 : /* 0x2 - 0xFF Reserved */
3668 : };
3669 :
3670 : /**
3671 : * Asynchronous Event Request Completion
3672 : */
3673 : union spdk_nvme_async_event_completion {
3674 : uint32_t raw;
3675 : struct {
3676 : uint32_t async_event_type : 3;
3677 : uint32_t reserved1 : 5;
3678 : uint32_t async_event_info : 8;
3679 : uint32_t log_page_identifier : 8;
3680 : uint32_t reserved2 : 8;
3681 : } bits;
3682 : };
3683 : SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_async_event_completion) == 4, "Incorrect size");
3684 :
3685 : /**
3686 : * Firmware slot information page (\ref SPDK_NVME_LOG_FIRMWARE_SLOT)
3687 : */
3688 : struct spdk_nvme_firmware_page {
3689 : struct {
3690 : uint8_t active_slot : 3; /**< Slot for current FW */
3691 : uint8_t reserved3 : 1;
3692 : uint8_t next_reset_slot : 3; /**< Slot that will be active at next controller reset */
3693 : uint8_t reserved7 : 1;
3694 : } afi;
3695 :
3696 : uint8_t reserved[7];
3697 : uint8_t revision[7][8]; /** Revisions for 7 slots (ASCII strings) */
3698 : uint8_t reserved2[448];
3699 : };
3700 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_firmware_page) == 512, "Incorrect size");
3701 :
3702 : /**
3703 : * Asymmetric Namespace Access page (\ref SPDK_NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS)
3704 : */
3705 : struct spdk_nvme_ana_page {
3706 : uint64_t change_count;
3707 : uint16_t num_ana_group_desc;
3708 : uint8_t reserved[6];
3709 : };
3710 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ana_page) == 16, "Incorrect size");
3711 :
3712 : /* Asymmetric namespace access state */
3713 : enum spdk_nvme_ana_state {
3714 : SPDK_NVME_ANA_OPTIMIZED_STATE = 0x1,
3715 : SPDK_NVME_ANA_NON_OPTIMIZED_STATE = 0x2,
3716 : SPDK_NVME_ANA_INACCESSIBLE_STATE = 0x3,
3717 : SPDK_NVME_ANA_PERSISTENT_LOSS_STATE = 0x4,
3718 : SPDK_NVME_ANA_CHANGE_STATE = 0xF,
3719 : };
3720 :
3721 : /* ANA group descriptor */
3722 : struct spdk_nvme_ana_group_descriptor {
3723 : uint32_t ana_group_id;
3724 : uint32_t num_of_nsid;
3725 : uint64_t change_count;
3726 :
3727 : uint8_t ana_state : 4;
3728 : uint8_t reserved0 : 4;
3729 :
3730 : uint8_t reserved1[15];
3731 :
3732 : uint32_t nsid[];
3733 : };
3734 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ana_group_descriptor) == 32, "Incorrect size");
3735 :
3736 : /* Reclaim unit handle type */
3737 : enum spdk_nvme_fdp_ruh_type {
3738 : /* 0x0 Reserved */
3739 :
3740 : /* Reclaim unit handle type initially isolated */
3741 : SPDK_NVME_FDP_RUHT_INITIALLY_ISOLATED = 0x1,
3742 : /* Reclaim unit handle type persistently isolated */
3743 : SPDK_NVME_FDP_RUHT_PERSISTENTLY_ISOLATED = 0x2,
3744 :
3745 : /* 0x3 - 0xBF Reserved */
3746 :
3747 : /* 0xC0 - 0xFF Vendor specific */
3748 : };
3749 :
3750 : /* Reclaim unit handle descriptor */
3751 : struct spdk_nvme_fdp_ruh_descriptor {
3752 : /* Reclaim unit handle type */
3753 : uint8_t ruht;
3754 : uint8_t reserved[3];
3755 : };
3756 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_ruh_descriptor) == 4, "Incorrect size");
3757 :
3758 : /* FDP configuration descriptor */
3759 : struct spdk_nvme_fdp_cfg_descriptor {
3760 : /* Descriptor size */
3761 : uint16_t ds;
3762 :
3763 : /* FDP attributes */
3764 : union {
3765 : uint8_t raw;
3766 : struct {
3767 : /* Reclaim group identifier format */
3768 : uint8_t rgif : 4;
3769 : /* FDP volatile write cache */
3770 : uint8_t fdpvwc : 1;
3771 : uint8_t rsvd1 : 2;
3772 : /* FDP configuration valid */
3773 : uint8_t fdpcv : 1;
3774 : } bits;
3775 : } fdpa;
3776 :
3777 : /* Vendor specific size */
3778 : uint8_t vss;
3779 : /* Number of reclaim groups */
3780 : uint32_t nrg;
3781 : /* Number of reclaim unit handles */
3782 : uint16_t nruh;
3783 : /* Max placement identifiers */
3784 : uint16_t maxpids;
3785 : /* Number of namespaces supported */
3786 : uint32_t nns;
3787 : /* Reclaim unit nominal size */
3788 : uint64_t runs;
3789 : /* Estimated reclaim unit time limit */
3790 : uint32_t erutl;
3791 : uint8_t rsvd28[36];
3792 : struct spdk_nvme_fdp_ruh_descriptor ruh_desc[];
3793 : };
3794 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_cfg_descriptor) == 64, "Incorrect size");
3795 :
3796 : /* FDP configurations log page (\ref SPDK_NVME_LOG_FDP_CONFIGURATIONS) */
3797 : struct spdk_nvme_fdp_cfg_log_page {
3798 : /* Number of FDP configurations */
3799 : uint16_t ncfg;
3800 : /* Version of log page */
3801 : uint8_t version;
3802 : uint8_t reserved1;
3803 : /* Size of this log page in bytes */
3804 : uint32_t size;
3805 : uint8_t reserved2[8];
3806 : struct spdk_nvme_fdp_cfg_descriptor cfg_desc[];
3807 : };
3808 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_cfg_log_page) == 16, "Incorrect size");
3809 :
3810 : /* Reclaim unit handle attributes */
3811 : enum spdk_nvme_fdp_ruh_attributes {
3812 : /* Not used by a namespace */
3813 : SPDK_NVME_FDP_RUHA_UNUSED = 0x0,
3814 : /* Use a specific reclaim unit handle */
3815 : SPDK_NVME_FDP_RUHA_HOST_SPECIFIED = 0x1,
3816 : /* Use the only default reclaim unit handle */
3817 : SPDK_NVME_FDP_RUHA_CTRLR_SPECIFIED = 0x2,
3818 :
3819 : /* 0x3 - 0xFF Reserved */
3820 : };
3821 :
3822 : /* Reclaim unit handle usage descriptor */
3823 : struct spdk_nvme_fdp_ruhu_descriptor {
3824 : /* Reclaim unit handle attributes */
3825 : uint8_t ruha;
3826 : uint8_t reserved[7];
3827 : };
3828 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_ruhu_descriptor) == 8, "Incorrect size");
3829 :
3830 : /* Reclaim unit handle usage log page (\ref SPDK_NVME_LOG_RECLAIM_UNIT_HANDLE_USAGE) */
3831 : struct spdk_nvme_fdp_ruhu_log_page {
3832 : /* Number of Reclaim Unit Handles */
3833 : uint16_t nruh;
3834 : uint8_t reserved[6];
3835 : struct spdk_nvme_fdp_ruhu_descriptor ruhu_desc[];
3836 : };
3837 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_ruhu_log_page) == 8, "Incorrect size");
3838 :
3839 : /* FDP statistics log page (\ref SPDK_NVME_LOG_FDP_STATISTICS) */
3840 : struct spdk_nvme_fdp_stats_log_page {
3841 : /* Host bytes with metadata written */
3842 : uint64_t hbmw[2];
3843 : /* Media bytes with metadata written */
3844 : uint64_t mbmw[2];
3845 : /* Media bytes erased */
3846 : uint64_t mbe[2];
3847 : uint8_t rsvd48[16];
3848 : };
3849 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_stats_log_page) == 64, "Incorrect size");
3850 :
3851 : /* FDP report event types (cdw10 log specific parameter) */
3852 : enum spdk_nvme_fdp_report_event_type {
3853 : /* Report FDP controller events */
3854 : SPDK_NVME_FDP_REPORT_CTRL_EVENTS = 0x0,
3855 : /* Report FDP host events */
3856 : SPDK_NVME_FDP_REPORT_HOST_EVENTS = 0x1,
3857 : };
3858 :
3859 : /* FDP event type */
3860 : enum spdk_nvme_fdp_event_type {
3861 : /* FDP host events */
3862 : /* Reclaim unit not fully written to capacity */
3863 : SPDK_NVME_FDP_EVENT_RU_NOT_WRITTEN_CAPACITY = 0x0,
3864 : /* Reclaim unit time limit exceeded */
3865 : SPDK_NVME_FDP_EVENT_RU_TIME_LIMIT_EXCEEDED = 0x1,
3866 : /* Controller reset modified reclaim unit handles */
3867 : SPDK_NVME_FDP_EVENT_CTRLR_RESET_MODIFY_RUH = 0x2,
3868 : /* Invalid placement identifier */
3869 : SPDK_NVME_FDP_EVENT_INVALID_PLACEMENT_ID = 0x3,
3870 :
3871 : /* 0x4 - 0x6F Reserved */
3872 :
3873 : /* 0x70 - 0x7F Vendor specific */
3874 :
3875 : /* FDP controller events */
3876 : /* Media reallocated */
3877 : SPDK_NVME_FDP_EVENT_MEDIA_REALLOCATED = 0x80,
3878 : /* Implicitly modified reclaim unit handle */
3879 : SPDK_NVME_FDP_EVENT_IMPLICIT_MODIFIED_RUH = 0x81,
3880 :
3881 : /* 0x82 - 0xEF Reserved */
3882 :
3883 : /* 0xF0 - 0xFF Vendor specific */
3884 : };
3885 :
3886 : /* Media reallocated */
3887 : #pragma pack(push, 1)
3888 : struct spdk_nvme_fdp_event_media_reallocated {
3889 : /* Specific event flags */
3890 : union {
3891 : uint8_t raw;
3892 : struct {
3893 : /* LBA valid */
3894 : uint8_t lbav : 1;
3895 : uint8_t reserved : 7;
3896 : } bits;
3897 : } sef;
3898 :
3899 : uint8_t reserved1;
3900 : /* Number of LBAs moved */
3901 : uint16_t nlbam;
3902 : /* Logical block address */
3903 : uint64_t lba;
3904 : uint8_t reserved2[4];
3905 : };
3906 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_event_media_reallocated) == 16, "Incorrect size");
3907 :
3908 : /* FDP event */
3909 : struct spdk_nvme_fdp_event {
3910 : /* Event type */
3911 : uint8_t etype;
3912 :
3913 : /* FDP event flags */
3914 : union {
3915 : uint8_t raw;
3916 : struct {
3917 : /* Placement identifier valid */
3918 : uint8_t piv : 1;
3919 : /* NSID valid */
3920 : uint8_t nsidv : 1;
3921 : /* Location valid */
3922 : uint8_t lv : 1;
3923 : uint8_t reserved : 5;
3924 : } bits;
3925 : } fdpef;
3926 :
3927 : /* Placement identifier */
3928 : uint16_t pid;
3929 : /* Event timestamp */
3930 : uint64_t timestamp;
3931 : /* Namespace identifier */
3932 : uint32_t nsid;
3933 : /* Event type specific */
3934 : uint64_t event_type_specific[2];
3935 : /* Reclaim group identifier */
3936 : uint16_t rgid;
3937 : /* Reclaim unit handle identifier */
3938 : uint16_t ruhid;
3939 : uint8_t reserved[4];
3940 : uint8_t vs[24];
3941 : };
3942 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_event) == 64, "Incorrect size");
3943 : #pragma pack(pop)
3944 :
3945 : /* FDP events log page (\ref SPDK_NVME_LOG_FDP_EVENTS) */
3946 : struct spdk_nvme_fdp_events_log_page {
3947 : /* Number of FDP events */
3948 : uint32_t nevents;
3949 : uint8_t reserved[60];
3950 : struct spdk_nvme_fdp_event event[];
3951 : };
3952 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_events_log_page) == 64, "Incorrect size");
3953 :
3954 : /**
3955 : * Namespace attachment Type Encoding
3956 : */
3957 : enum spdk_nvme_ns_attach_type {
3958 : /* Controller attach */
3959 : SPDK_NVME_NS_CTRLR_ATTACH = 0x0,
3960 :
3961 : /* Controller detach */
3962 : SPDK_NVME_NS_CTRLR_DETACH = 0x1,
3963 :
3964 : /* 0x2-0xF - Reserved */
3965 : };
3966 :
3967 : /**
3968 : * Namespace management Type Encoding
3969 : */
3970 : enum spdk_nvme_ns_management_type {
3971 : /* Create */
3972 : SPDK_NVME_NS_MANAGEMENT_CREATE = 0x0,
3973 :
3974 : /* Delete */
3975 : SPDK_NVME_NS_MANAGEMENT_DELETE = 0x1,
3976 :
3977 : /* 0x2-0xF - Reserved */
3978 : };
3979 :
3980 : struct spdk_nvme_ns_list {
3981 : uint32_t ns_list[1024];
3982 : };
3983 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_list) == 4096, "Incorrect size");
3984 :
3985 : /**
3986 : * Namespace identification descriptor type
3987 : *
3988 : * \sa spdk_nvme_ns_id_desc
3989 : */
3990 : enum spdk_nvme_nidt {
3991 : /** IEEE Extended Unique Identifier */
3992 : SPDK_NVME_NIDT_EUI64 = 0x01,
3993 :
3994 : /** Namespace GUID */
3995 : SPDK_NVME_NIDT_NGUID = 0x02,
3996 :
3997 : /** Namespace UUID */
3998 : SPDK_NVME_NIDT_UUID = 0x03,
3999 :
4000 : /** Namespace Command Set Identifier */
4001 : SPDK_NVME_NIDT_CSI = 0x04,
4002 : };
4003 :
4004 : struct spdk_nvme_ns_id_desc {
4005 : /** Namespace identifier type */
4006 : uint8_t nidt;
4007 :
4008 : /** Namespace identifier length (length of nid field) */
4009 : uint8_t nidl;
4010 :
4011 : uint8_t reserved2;
4012 : uint8_t reserved3;
4013 :
4014 : /** Namespace identifier */
4015 : uint8_t nid[];
4016 : };
4017 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_id_desc) == 4, "Incorrect size");
4018 :
4019 : struct spdk_nvme_ctrlr_list {
4020 : uint16_t ctrlr_count;
4021 : uint16_t ctrlr_list[2047];
4022 : };
4023 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ctrlr_list) == 4096, "Incorrect size");
4024 :
4025 : enum spdk_nvme_csi {
4026 : SPDK_NVME_CSI_NVM = 0x0,
4027 : SPDK_NVME_CSI_KV = 0x1,
4028 : SPDK_NVME_CSI_ZNS = 0x2,
4029 : };
4030 :
4031 : enum spdk_nvme_secure_erase_setting {
4032 : SPDK_NVME_FMT_NVM_SES_NO_SECURE_ERASE = 0x0,
4033 : SPDK_NVME_FMT_NVM_SES_USER_DATA_ERASE = 0x1,
4034 : SPDK_NVME_FMT_NVM_SES_CRYPTO_ERASE = 0x2,
4035 : };
4036 :
4037 : enum spdk_nvme_pi_location {
4038 : SPDK_NVME_FMT_NVM_PROTECTION_AT_TAIL = 0x0,
4039 : SPDK_NVME_FMT_NVM_PROTECTION_AT_HEAD = 0x1,
4040 : };
4041 :
4042 : enum spdk_nvme_pi_type {
4043 : SPDK_NVME_FMT_NVM_PROTECTION_DISABLE = 0x0,
4044 : SPDK_NVME_FMT_NVM_PROTECTION_TYPE1 = 0x1,
4045 : SPDK_NVME_FMT_NVM_PROTECTION_TYPE2 = 0x2,
4046 : SPDK_NVME_FMT_NVM_PROTECTION_TYPE3 = 0x3,
4047 : };
4048 :
4049 : enum spdk_nvme_metadata_setting {
4050 : SPDK_NVME_FMT_NVM_METADATA_TRANSFER_AS_BUFFER = 0x0,
4051 : SPDK_NVME_FMT_NVM_METADATA_TRANSFER_AS_LBA = 0x1,
4052 : };
4053 :
4054 : /* Format - Command Dword 10 */
4055 : struct spdk_nvme_format {
4056 : /* LBA format lower (LSB 4 bits of format index), also called lbafl in 2.0 spec */
4057 : uint32_t lbaf : 4;
4058 : /* Metadata settings, also called mset in 2.0 spec */
4059 : uint32_t ms : 1;
4060 : /* Protection information */
4061 : uint32_t pi : 3;
4062 : /* Protection information location */
4063 : uint32_t pil : 1;
4064 : /* Secure erase settings */
4065 : uint32_t ses : 3;
4066 : /* LBA format upper (MSB 2 bits of format index) */
4067 : uint32_t lbafu : 2;
4068 : uint32_t reserved : 18;
4069 : };
4070 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_format) == 4, "Incorrect size");
4071 :
4072 : struct spdk_nvme_protection_info {
4073 : uint16_t guard;
4074 : uint16_t app_tag;
4075 : uint32_t ref_tag;
4076 : };
4077 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_protection_info) == 8, "Incorrect size");
4078 :
4079 : /* Data structures for sanitize command */
4080 : /* Sanitize - Command Dword 10 */
4081 : struct spdk_nvme_sanitize {
4082 : /* Sanitize Action (SANACT) */
4083 : uint32_t sanact : 3;
4084 : /* Allow Unrestricted Sanitize Exit (AUSE) */
4085 : uint32_t ause : 1;
4086 : /* Overwrite Pass Count (OWPASS) */
4087 : uint32_t owpass : 4;
4088 : /* Overwrite Invert Pattern Between Passes */
4089 : uint32_t oipbp : 1;
4090 : /* No Deallocate after sanitize (NDAS) */
4091 : uint32_t ndas : 1;
4092 : /* reserved */
4093 : uint32_t reserved : 22;
4094 : };
4095 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_sanitize) == 4, "Incorrect size");
4096 :
4097 : /* Sanitize Action */
4098 : enum spdk_sanitize_action {
4099 : /* Exit Failure Mode */
4100 : SPDK_NVME_SANITIZE_EXIT_FAILURE_MODE = 0x1,
4101 : /* Start a Block Erase sanitize operation */
4102 : SPDK_NVME_SANITIZE_BLOCK_ERASE = 0x2,
4103 : /* Start an Overwrite sanitize operation */
4104 : SPDK_NVME_SANITIZE_OVERWRITE = 0x3,
4105 : /* Start a Crypto Erase sanitize operation */
4106 : SPDK_NVME_SANITIZE_CRYPTO_ERASE = 0x4,
4107 : };
4108 :
4109 : /** Parameters for SPDK_NVME_OPC_FIRMWARE_COMMIT cdw10: commit action */
4110 : enum spdk_nvme_fw_commit_action {
4111 : /**
4112 : * Downloaded image replaces the image specified by
4113 : * the Firmware Slot field. This image is not activated.
4114 : */
4115 : SPDK_NVME_FW_COMMIT_REPLACE_IMG = 0x0,
4116 : /**
4117 : * Downloaded image replaces the image specified by
4118 : * the Firmware Slot field. This image is activated at the next reset.
4119 : */
4120 : SPDK_NVME_FW_COMMIT_REPLACE_AND_ENABLE_IMG = 0x1,
4121 : /**
4122 : * The image specified by the Firmware Slot field is
4123 : * activated at the next reset.
4124 : */
4125 : SPDK_NVME_FW_COMMIT_ENABLE_IMG = 0x2,
4126 : /**
4127 : * The image specified by the Firmware Slot field is
4128 : * requested to be activated immediately without reset.
4129 : */
4130 : SPDK_NVME_FW_COMMIT_RUN_IMG = 0x3,
4131 : /**
4132 : * Downloaded image replaces the Boot Partition specified by
4133 : * the Boot Partition ID field.
4134 : */
4135 : SPDK_NVME_FW_COMMIT_REPLACE_BOOT_PARTITION = 0x6,
4136 : /**
4137 : * Mark the Boot Partition specified in the BPID field as Active
4138 : * and update BPINFO.ABPID.
4139 : */
4140 : SPDK_NVME_FW_COMMIT_ACTIVATE_BOOT_PARTITION = 0x7,
4141 : };
4142 :
4143 : /** Parameters for SPDK_NVME_OPC_FIRMWARE_COMMIT cdw10 */
4144 : struct spdk_nvme_fw_commit {
4145 : /**
4146 : * Firmware Slot. Specifies the firmware slot that shall be used for the
4147 : * Commit Action. The controller shall choose the firmware slot (slot 1 - 7)
4148 : * to use for the operation if the value specified is 0h.
4149 : */
4150 : uint32_t fs : 3;
4151 : /**
4152 : * Commit Action. Specifies the action that is taken on the image downloaded
4153 : * with the Firmware Image Download command or on a previously downloaded and
4154 : * placed image.
4155 : */
4156 : uint32_t ca : 3;
4157 : uint32_t reserved : 25;
4158 : /**
4159 : * Boot Partition ID. Specifies the boot partition that shall be used for the
4160 : * Commit Action.
4161 : */
4162 : uint32_t bpid : 1;
4163 : };
4164 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fw_commit) == 4, "Incorrect size");
4165 :
4166 : /* ZNS Zone Send Action (ZSA) cdw13 */
4167 : enum spdk_nvme_zns_zone_send_action {
4168 : SPDK_NVME_ZONE_CLOSE = 0x1,
4169 : SPDK_NVME_ZONE_FINISH = 0x2,
4170 : SPDK_NVME_ZONE_OPEN = 0x3,
4171 : SPDK_NVME_ZONE_RESET = 0x4,
4172 : SPDK_NVME_ZONE_OFFLINE = 0x5,
4173 : SPDK_NVME_ZONE_SET_ZDE = 0x10,
4174 : };
4175 :
4176 : /* ZNS Zone Receive Action (ZRA) cdw13 */
4177 : enum spdk_nvme_zns_zone_receive_action {
4178 : SPDK_NVME_ZONE_REPORT = 0x0,
4179 : SPDK_NVME_ZONE_EXTENDED_REPORT = 0x1,
4180 : };
4181 :
4182 : enum spdk_nvme_zns_zra_report_opts {
4183 : SPDK_NVME_ZRA_LIST_ALL = 0x0,
4184 : SPDK_NVME_ZRA_LIST_ZSE = 0x1,
4185 : SPDK_NVME_ZRA_LIST_ZSIO = 0x2,
4186 : SPDK_NVME_ZRA_LIST_ZSEO = 0x3,
4187 : SPDK_NVME_ZRA_LIST_ZSC = 0x4,
4188 : SPDK_NVME_ZRA_LIST_ZSF = 0x5,
4189 : SPDK_NVME_ZRA_LIST_ZSRO = 0x6,
4190 : SPDK_NVME_ZRA_LIST_ZSO = 0x7,
4191 : };
4192 :
4193 : enum spdk_nvme_zns_zone_type {
4194 : SPDK_NVME_ZONE_TYPE_SEQWR = 0x2,
4195 : };
4196 :
4197 : enum spdk_nvme_zns_zone_state {
4198 : SPDK_NVME_ZONE_STATE_EMPTY = 0x1,
4199 : SPDK_NVME_ZONE_STATE_IOPEN = 0x2,
4200 : SPDK_NVME_ZONE_STATE_EOPEN = 0x3,
4201 : SPDK_NVME_ZONE_STATE_CLOSED = 0x4,
4202 : SPDK_NVME_ZONE_STATE_RONLY = 0xD,
4203 : SPDK_NVME_ZONE_STATE_FULL = 0xE,
4204 : SPDK_NVME_ZONE_STATE_OFFLINE = 0xF,
4205 : };
4206 :
4207 : struct spdk_nvme_zns_zone_desc {
4208 : /** Zone Type */
4209 : uint8_t zt : 4;
4210 :
4211 : uint8_t rsvd0 : 4;
4212 :
4213 : uint8_t rsvd1 : 4;
4214 :
4215 : /** Zone State */
4216 : uint8_t zs : 4;
4217 :
4218 : /**
4219 : * Zone Attributes
4220 : */
4221 : union {
4222 : uint8_t raw;
4223 :
4224 : struct {
4225 : /** Zone Finished by controller */
4226 : uint8_t zfc: 1;
4227 :
4228 : /** Finish Zone Recommended */
4229 : uint8_t fzr: 1;
4230 :
4231 : /** Reset Zone Recommended */
4232 : uint8_t rzr: 1;
4233 :
4234 : uint8_t rsvd3 : 4;
4235 :
4236 : /** Zone Descriptor Extension Valid */
4237 : uint8_t zdev: 1;
4238 : } bits;
4239 : } za;
4240 :
4241 : uint8_t reserved[5];
4242 :
4243 : /** Zone Capacity (in number of LBAs) */
4244 : uint64_t zcap;
4245 :
4246 : /** Zone Start LBA */
4247 : uint64_t zslba;
4248 :
4249 : /** Write Pointer (LBA) */
4250 : uint64_t wp;
4251 :
4252 : uint8_t reserved32[32];
4253 : };
4254 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_zns_zone_desc) == 64, "Incorrect size");
4255 :
4256 : struct spdk_nvme_zns_zone_report {
4257 : uint64_t nr_zones;
4258 : uint8_t reserved8[56];
4259 : struct spdk_nvme_zns_zone_desc descs[];
4260 : };
4261 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_zns_zone_report) == 64, "Incorrect size");
4262 :
4263 : /* Directives field */
4264 : enum spdk_nvme_directive_type {
4265 : SPDK_NVME_DIRECTIVE_TYPE_IDENTIFY = 0x0,
4266 : SPDK_NVME_DIRECTIVE_TYPE_STREAMS = 0x1,
4267 : SPDK_NVME_DIRECTIVE_TYPE_DATA_PLACEMENT = 0x2,
4268 : };
4269 :
4270 : enum spdk_nvme_identify_directive_send_operation {
4271 : SPDK_NVME_IDENTIFY_DIRECTIVE_SEND_ENABLED = 0x1,
4272 : };
4273 :
4274 : enum spdk_nvme_identify_directive_receive_operation {
4275 : SPDK_NVME_IDENTIFY_DIRECTIVE_RECEIVE_RETURN_PARAM = 0x1,
4276 : };
4277 :
4278 : struct spdk_nvme_ns_identify_directive_param {
4279 : struct {
4280 : /* set to 1b to indicate that the Identify Directive is supported */
4281 : uint8_t identify : 1;
4282 : /* set to 1b if the Streams Directive is supported */
4283 : uint8_t streams : 1;
4284 : /* set to 1b if the Data Placement Directive is supported */
4285 : uint8_t data_pd : 1;
4286 : uint8_t reserved1 : 5;
4287 : uint8_t reserved2[31];
4288 : } directives_supported;
4289 : struct {
4290 : /* set to 1b to indicate that the Identify Directive is enabled */
4291 : uint8_t identify : 1;
4292 : /* set to 1b if the Streams Directive is enabled */
4293 : uint8_t streams : 1;
4294 : /* set to 1b if the Data Placement Directive is enabled */
4295 : uint8_t data_pd : 1;
4296 : uint8_t reserved1 : 5;
4297 : uint8_t reserved2[31];
4298 : } directives_enabled;
4299 : struct {
4300 : /**
4301 : * cleared to 0b as the host is not able to change the state of
4302 : * Identify Directive
4303 : */
4304 : uint8_t identify : 1;
4305 : /**
4306 : * cleared to 0b to indicate that the Streams Directive state
4307 : * is not preserved across ctrl reset
4308 : */
4309 : uint8_t streams : 1;
4310 : /**
4311 : * set to 1b if the Data Placement Directive is supported to
4312 : * indicate that the host specified Data Placement Directive
4313 : * state is preserved across ctrl reset
4314 : */
4315 : uint8_t data_pd : 1;
4316 : uint8_t reserved1 : 5;
4317 : uint8_t reserved2[31];
4318 : } directives_persistence;
4319 :
4320 : uint32_t reserved[1000];
4321 : };
4322 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_identify_directive_param) == 4096, "Incorrect size");
4323 :
4324 : enum spdk_nvme_streams_directive_receive_operation {
4325 : SPDK_NVME_STREAMS_DIRECTIVE_RECEIVE_RETURN_PARAM = 0x1,
4326 : SPDK_NVME_STREAMS_DIRECTIVE_RECEIVE_GET_STATUS = 0x2,
4327 : SPDK_NVME_STREAMS_DIRECTIVE_RECEIVE_ALLOCATE_RESOURCE = 0x3,
4328 : };
4329 :
4330 : enum spdk_nvme_streams_directive_send_operation {
4331 : SPDK_NVME_STREAMS_DIRECTIVE_SEND_RELEASE_ID = 0x1,
4332 : SPDK_NVME_STREAMS_DIRECTIVE_SEND_RELEASE_RESOURCE = 0x2,
4333 : };
4334 :
4335 : struct spdk_nvme_ns_streams_data {
4336 : /* MAX Streams Limit */
4337 : uint16_t msl;
4338 : /* NVM Subsystem Streams Available */
4339 : uint16_t nssa;
4340 : /* NVM Subsystem Streams Open */
4341 : uint16_t nsso;
4342 : /* NVM Subsystem Stream Capability */
4343 : struct {
4344 : /* Stream ID may be shared by multiple host IDs if set to 1. */
4345 : uint8_t ssid : 1;
4346 : uint8_t reserved : 7;
4347 : } nssc;
4348 : uint8_t reserved1[9];
4349 : /* Namespace Specific Fields
4350 : * Stream Write Size */
4351 : uint32_t sws;
4352 : /* Stream Granularity Size */
4353 : uint16_t sgs;
4354 : /* Namespace and Host Identifier Specific Fields
4355 : * Namespace Streams Allocated */
4356 : uint16_t nsa;
4357 : /* Namespace Streams Open */
4358 : uint16_t nso;
4359 : uint8_t reserved2[6];
4360 : };
4361 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_streams_data) == 32, "Incorrect size");
4362 :
4363 : struct spdk_nvme_ns_streams_status {
4364 : /* Open Stream Count, this field specifies the number of streams that are currently open */
4365 : uint16_t open_streams_count;
4366 :
4367 : /* Stream Identifier, this field specifies the open stream identifier */
4368 : uint16_t stream_id[65535];
4369 : };
4370 : SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ns_streams_status) == 131072, "Incorrect size");
4371 :
4372 : #define spdk_nvme_cpl_is_error(cpl) \
4373 : ((cpl)->status.sc != SPDK_NVME_SC_SUCCESS || \
4374 : (cpl)->status.sct != SPDK_NVME_SCT_GENERIC)
4375 :
4376 : #define spdk_nvme_cpl_is_success(cpl) (!spdk_nvme_cpl_is_error(cpl))
4377 :
4378 : #define spdk_nvme_cpl_is_pi_error(cpl) \
4379 : ((cpl)->status.sct == SPDK_NVME_SCT_MEDIA_ERROR && \
4380 : ((cpl)->status.sc == SPDK_NVME_SC_GUARD_CHECK_ERROR || \
4381 : (cpl)->status.sc == SPDK_NVME_SC_APPLICATION_TAG_CHECK_ERROR || \
4382 : (cpl)->status.sc == SPDK_NVME_SC_REFERENCE_TAG_CHECK_ERROR))
4383 :
4384 : #define spdk_nvme_cpl_is_abort_success(cpl) \
4385 : (spdk_nvme_cpl_is_success(cpl) && !((cpl)->cdw0 & 1U))
4386 :
4387 : #define spdk_nvme_cpl_is_path_error(cpl) \
4388 : ((cpl)->status.sct == SPDK_NVME_SCT_PATH)
4389 :
4390 : #define spdk_nvme_cpl_is_ana_error(cpl) \
4391 : ((cpl)->status.sct == SPDK_NVME_SCT_PATH && \
4392 : ((cpl)->status.sc == SPDK_NVME_SC_ASYMMETRIC_ACCESS_PERSISTENT_LOSS || \
4393 : (cpl)->status.sc == SPDK_NVME_SC_ASYMMETRIC_ACCESS_INACCESSIBLE || \
4394 : (cpl)->status.sc == SPDK_NVME_SC_ASYMMETRIC_ACCESS_TRANSITION))
4395 :
4396 : #define spdk_nvme_cpl_is_aborted_sq_deletion(cpl) \
4397 : ((cpl)->status.sct == SPDK_NVME_SCT_GENERIC && \
4398 : (cpl)->status.sc == SPDK_NVME_SC_ABORTED_SQ_DELETION)
4399 :
4400 : #define spdk_nvme_cpl_is_aborted_by_request(cpl) \
4401 : ((cpl)->status.sct == SPDK_NVME_SCT_GENERIC && \
4402 : (cpl)->status.sc == SPDK_NVME_SC_ABORTED_BY_REQUEST)
4403 :
4404 : /** Set fused operation */
4405 : #define SPDK_NVME_IO_FLAGS_FUSE_FIRST (SPDK_NVME_CMD_FUSE_FIRST << 0)
4406 : #define SPDK_NVME_IO_FLAGS_FUSE_SECOND (SPDK_NVME_CMD_FUSE_SECOND << 0)
4407 : #define SPDK_NVME_IO_FLAGS_FUSE_MASK (SPDK_NVME_CMD_FUSE_MASK << 0)
4408 :
4409 : /* Bits 20-31 of SPDK_NVME_IO_FLAGS map directly to their associated bits in
4410 : * cdw12 for NVMe IO commands
4411 : */
4412 : /** For enabling directive types on write-oriented commands */
4413 : #define SPDK_NVME_IO_FLAGS_DIRECTIVE(dtype) (dtype << 20)
4414 : #define SPDK_NVME_IO_FLAGS_STREAMS_DIRECTIVE \
4415 : SPDK_NVME_IO_FLAGS_DIRECTIVE(SPDK_NVME_DIRECTIVE_TYPE_STREAMS)
4416 : #define SPDK_NVME_IO_FLAGS_DATA_PLACEMENT_DIRECTIVE \
4417 : SPDK_NVME_IO_FLAGS_DIRECTIVE(SPDK_NVME_DIRECTIVE_TYPE_DATA_PLACEMENT)
4418 : /** Zone append specific, determines the contents of the reference tag written to the media */
4419 : #define SPDK_NVME_IO_FLAGS_ZONE_APPEND_PIREMAP (1U << 25)
4420 : /** Enable protection information checking of the Logical Block Reference Tag field */
4421 : #define SPDK_NVME_IO_FLAGS_PRCHK_REFTAG (1U << 26)
4422 : /** Enable protection information checking of the Application Tag field */
4423 : #define SPDK_NVME_IO_FLAGS_PRCHK_APPTAG (1U << 27)
4424 : /** Enable protection information checking of the Guard field */
4425 : #define SPDK_NVME_IO_FLAGS_PRCHK_GUARD (1U << 28)
4426 : /** The protection information is stripped or inserted when set this bit */
4427 : #define SPDK_NVME_IO_FLAGS_PRACT (1U << 29)
4428 : #define SPDK_NVME_IO_FLAGS_FORCE_UNIT_ACCESS (1U << 30)
4429 : #define SPDK_NVME_IO_FLAGS_LIMITED_RETRY (1U << 31)
4430 :
4431 : /** Mask of valid io flags mask */
4432 : #define SPDK_NVME_IO_FLAGS_VALID_MASK 0xFFFF0003
4433 : #define SPDK_NVME_IO_FLAGS_CDW12_MASK 0xFFFF0000
4434 :
4435 : /** Identify command buffer response size */
4436 : #define SPDK_NVME_IDENTIFY_BUFLEN 4096
4437 :
4438 : #ifdef __cplusplus
4439 : }
4440 : #endif
4441 :
4442 : #endif
|