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