xref: /dragonfly/sys/dev/disk/nvme/nvme_chipset.h (revision 43844926a802f7ff6676984ccfee74fdf16a8670)
1 /*
2  * Copyright (c) 2016 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
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  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. 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  * 3. Neither the name of The DragonFly Project 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
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 /*
36  * Misc limits
37  */
38 #define NVME_MAX_ADMIN_BUFFER 4096U
39 
40 /*
41  * NVME chipset register and structural definitions
42  *
43  * NOTE! Firmware related commands and responses are in nvme_fw.h
44  */
45 #define NVME_REG_CAP                    0x0000    /* Capabilities */
46 #define NVME_REG_VERS                   0x0008    /* Version */
47 #define NVME_REG_INTSET                 0x000C    /* Set interrupt mask bits */
48 #define NVME_REG_INTCLR                 0x0010    /* Clr interrupt mask bits */
49 #define NVME_REG_CONFIG                 0x0014    /* Configuration */
50 #define NVME_REG_RESERVED_18  0x0018
51 #define NVME_REG_STATUS                 0x001C
52 #define NVME_REG_SUBRESET     0x0020
53 #define NVME_REG_ADM_ATTR     0x0024
54 #define NVME_REG_ADM_SUBADR   0x0028
55 #define NVME_REG_ADM_COMADR   0x0030
56 #define NVME_REG_MEMBUF                 0x0038
57 #define NVME_REG_MEMSIZE      0x003C
58 #define NVME_REG_RESERVED_40  0x0040
59 #define NVME_REG_CSS                    0x0F00    /* Command-set specific area */
60 
61 /*
62  * Doorbell area for queues.  Queue 0 is the admin queue.  The number of
63  * queues supported is specified in the capabilities.
64  */
65 #define NVME_REG_SUBQ_BELL(n, dstrd4)   (0x1000 + ((n) * 2 + 0) * (dstrd4))
66 #define NVME_REG_COMQ_BELL(n, dstrd4)   (0x1000 + ((n) * 2 + 1) * (dstrd4))
67 
68 /*
69  * NVME_REG_CAP               - Capabilities (64 bits)
70  *
71  * DSTRD- Doorbell stride (0=4 bytes, in multiples of 4 bytes)
72  * AMS  - Arbitration mechanisms supported.  WRRUP means weighted round robin
73  *          with urgent priority feature.
74  * CQR  - Indicates that submission and completion queues must be physically
75  *          contiguous.
76  * MQES   - Maximum queue entries (0 means a maximum of 1, 1 is 2, etc)
77  */
78 #define NVME_CAP_CSS_63                 (0x8000000000000000LLU)
79 #define NVME_CAP_CSS_62                 (0x4000000000000000LLU)
80 #define NVME_CAP_CSS_61                 (0x2000000000000000LLU)
81 #define NVME_CAP_CSS_60                 (0x1000000000000000LLU)
82 #define NVME_CAP_CSS_59                 (0x0800000000000000LLU)
83 #define NVME_CAP_CSS_58                 (0x0400000000000000LLU)
84 #define NVME_CAP_CSS_57                 (0x0200000000000000LLU)
85 #define NVME_CAP_CSS_56                 (0x0100000000000000LLU)
86 #define NVME_CAP_MEMPG_MAX    (0x00F0000000000000LLU)
87 #define NVME_CAP_MEMPG_MIN    (0x000F000000000000LLU)
88 #define NVME_CAP_RESERVED_47  (0x0000800000000000LLU)
89 #define NVME_CAP_RESERVED_46  (0x0000400000000000LLU)
90 #define NVME_CAP_RESERVED_45  (0x0000200000000000LLU)
91 #define NVME_CAP_CSS_44                 (0x0000100000000000LLU)
92 #define NVME_CAP_CSS_43                 (0x0000080000000000LLU)
93 #define NVME_CAP_CSS_42                 (0x0000040000000000LLU)
94 #define NVME_CAP_CSS_41                 (0x0000020000000000LLU)
95 #define NVME_CAP_CSS_40                 (0x0000010000000000LLU)
96 #define NVME_CAP_CSS_39                 (0x0000008000000000LLU)
97 #define NVME_CAP_CSS_38                 (0x0000004000000000LLU)
98 #define NVME_CAP_CSS_NVM      (0x0000002000000000LLU)
99 #define NVME_CAP_SUBRESET     (0x0000001000000000LLU)
100 #define NVME_CAP_DSTRD_MASK   (0x0000000F00000000LLU)
101 #define NVME_CAP_TIMEOUT      (0x00000000FF000000LLU)
102 #define NVME_CAP_RESERVED_19  (0x0000000000F80000LLU)
103 #define NVME_CAP_AMS_VENDOR   (0x0000000000040000LLU)
104 #define NVME_CAP_AMS_WRRUP    (0x0000000000020000LLU)
105 #define NVME_CAP_CQR                    (0x0000000000010000LLU)
106 #define NVME_CAP_MQES                   (0x000000000000FFFFLLU)
107 
108 #define NVME_CAP_MEMPG_MAX_GET(data)    \
109                     (1 << (12 + (((data) & NVME_CAP_MEMPG_MAX) >> 52)))
110 #define NVME_CAP_MEMPG_MIN_GET(data)    \
111                     (1 << (12 + (((data) & NVME_CAP_MEMPG_MIN) >> 48)))
112 #define NVME_CAP_DSTRD_GET(data)        \
113                     (4 << ((((data) & NVME_CAP_DSTRD_MASK) >> 32)))
114 #define NVME_CAP_TIMEOUT_GET(data)      \
115                     (((data) & NVME_CAP_TIMEOUT) >> 24)     /* 500ms incr */
116 #define NVME_CAP_MQES_GET(data)                   \
117                     (((data) & NVME_CAP_MQES) + 1)                    /* 0-based 0=1, min 2 */
118 
119 /*
120  * NVME_REG_VERS    - Version register (32 bits)
121  *
122  * Just extract and shift the fields, 1=1, e.g. '1.2' has MAJOR=1, MINOR=2
123  */
124 #define NVME_VERS_MAJOR                 (0xFFFF0000U)
125 #define NVME_VERS_MINOR                 (0x0000FF00U)
126 #define NVME_VERS_RESERVED_00 (0x00000000U)
127 
128 #define NVME_VERS_MAJOR_GET(data)       \
129                     (((data) & NVME_VERS_MAJOR) >> 16)
130 #define NVME_VERS_MINOR_GET(data)       \
131                     (((data) & NVME_VERS_MINOR) >> 8)
132 
133 /*
134  * NVME_REG_INTSET  (32 bits)
135  * NVME_REG_INTCLR  (32 bits)
136  *
137  * Set and clear interrupt mask bits (up to 32 interrupt sources).
138  * Writing a 1 to the appropriate bits in the appropriate register sets
139  * or clears that interrupt source.  Writing a 0 has no effect.  Reading
140  * either register returns the current interrupt mask.
141  *
142  * Setting an interrupt mask bit via INTSET masks the interrupt so it
143  * cannot occur.
144  */
145 
146 /*
147  * NVME_REG_CONFIG  (32 bits)
148  *
149  * Controller configuration, set by the host prior to enabling the
150  * controller.
151  *
152  * IOCOM_ES         - I/O completion queue entry size, 1<<n
153  * IOSUB_ES         - I/O submission queue entry size, 1<<n
154  * SHUT*  - Set while controller enabled to indicate shutdown pending.
155  *
156  * ENABLE (EN):
157  *        Works as expected.  On the 1->0 transition the controller state
158  *        is reset except for PCI registers and the Admin Queue registers.
159  *        When clearing to 0, poll the CSTS RDY bit until it becomes 0.
160  *        Similarly, when enabling EN, poll CSTS RDY until it becomes 1.
161  */
162 #define NVME_CONFIG_RESERVED_24         0xFF000000U
163 #define NVME_CONFIG_IOCOM_ES  0x00F00000U
164 #define NVME_CONFIG_IOSUB_ES  0x000F0000U
165 
166 #define NVME_CONFIG_IOCOM_ES_SET(pwr)   ((pwr) << 20)
167 #define NVME_CONFIG_IOSUB_ES_SET(pwr)   ((pwr) << 16)
168 
169 #define NVME_CONFIG_SHUT_MASK 0x0000C000U
170 #define NVME_CONFIG_SHUT_NONE 0x00000000U
171 #define NVME_CONFIG_SHUT_NORM 0x00004000U         /* normal shutdown */
172 #define NVME_CONFIG_SHUT_EMERG          0x00008000U         /* emergency shutdown */
173 #define NVME_CONFIG_SHUT_RES3 0x0000C000U
174 
175 #define NVME_CONFIG_AMS_DEF   0x00000000U         /* default (round-robin) */
176 #define NVME_CONFIG_AMS_WRRUP 0x00000800U         /* weighted round-robin */
177 #define NVME_CONFIG_AMS_2     0x00001000U
178 #define NVME_CONFIG_AMS_3     0x00001800U
179 #define NVME_CONFIG_AMS_4     0x00002000U
180 #define NVME_CONFIG_AMS_5     0x00002800U
181 #define NVME_CONFIG_AMS_6     0x00003000U
182 #define NVME_CONFIG_AMS_VENDOR          0x00003800U
183 
184 #define NVME_CONFIG_MEMPG     0x00000780U         /* MPS register */
185 #define NVME_CONFIG_CSS_MASK  0x00000070U
186 #define NVME_CONFIG_3                   0x00000008U
187 #define NVME_CONFIG_2                   0x00000004U
188 #define NVME_CONFIG_1                   0x00000002U
189 #define NVME_CONFIG_EN                  0x00000001U
190 
191 #define NVME_CONFIG_CSS_NVM   (0U << 4) /* NVM command set */
192 #define NVME_CONFIG_CSS_1     (1U << 4) /* these are reserved */
193 #define NVME_CONFIG_CSS_2     (2U << 4)
194 #define NVME_CONFIG_CSS_3     (3U << 4)
195 #define NVME_CONFIG_CSS_4     (4U << 4)
196 #define NVME_CONFIG_CSS_5     (5U << 4)
197 #define NVME_CONFIG_CSS_6     (6U << 4)
198 #define NVME_CONFIG_CSS_7     (7U << 4)
199 
200 #define NVME_CONFIG_MEMPG_SET(pwr)      \
201                     (uint32_t)(((pwr) - 12) << 7)
202 
203 
204 /*
205  * NVME_REG_STATUS  (32 bits)
206  *
207  * PAUSED - Set to 1 if the controller is paused, 0 if normal operation.
208  * SUBRESET         - Set to 1 if a subsystem reset occurred (if available).
209  * SHUT*  - Shutdown state for poller
210  * FATAL  - Indicates a fatal controller error ocurred.
211  * RDY              - Controller ready/disable response to ENABLE.
212  */
213 #define NVME_STATUS_RESERVED  0xFFFFFFC0U
214 #define NVME_STATUS_PAUSED    0x00000020U
215 #define NVME_STATUS_SUBRESET  0x00000010U
216 #define NVME_STATUS_SHUT_MASK 0x0000000CU
217 #define NVME_STATUS_FATAL     0x00000002U
218 #define NVME_STATUS_RDY                 0x00000001U
219 
220 #define NVME_STATUS_SHUT_NORM 0x00000000U
221 #define NVME_STATUS_SHUT_INPROG         0x00000004U
222 #define NVME_STATUS_SHUT_DONE 0x00000008U
223 #define NVME_STATUS_SHUT_11   0x0000000CU
224 
225 /*
226  * NVME_REG_SUBRESET
227  *
228  * Allows for the initiation of a subsystem reset, if available (see caps).
229  * Writing the value 0x4E565D65 ('NVMe') initiates the reset.
230  */
231 
232 /*
233  * NVME_REG_ADM_ATTR
234  *
235  * Specifies the completion and submission queue size in #entries.  Values
236  * between 2 and 4096 are valid.  COM and SUB are a 0's based value (0=1).
237  */
238 #define NVME_ATTR_RESERVED_31 0x80000000U
239 #define NVME_ATTR_RESERVED_30 0x40000000U
240 #define NVME_ATTR_RESERVED_29 0x20000000U
241 #define NVME_ATTR_RESERVED_28 0x10000000U
242 #define NVME_ATTR_COM                   0x0FFF0000U
243 #define NVME_ATTR_RESERVED_15 0x00008000U
244 #define NVME_ATTR_RESERVED_14 0x00004000U
245 #define NVME_ATTR_RESERVED_13 0x00002000U
246 #define NVME_ATTR_RESERVED_12 0x00001000U
247 #define NVME_ATTR_SUB                   0x00000FFFU
248 
249 #define NVME_ATTR_COM_SET(nqe)          (((nqe - 1) << 16) & NVME_ATTR_COM)
250 #define NVME_ATTR_SUB_SET(nqe)          ((nqe - 1) & NVME_ATTR_SUB)
251 
252 /*
253  * NVME_REG_ADM_SUBADR (64 bits)
254  * NVME_REG_ADM_COMADR (64 bits)
255  *
256  * Specify the admin submission and completion queue physical base
257  * address.  These are 64-bit addresses, 4K aligned.  Bits 11:00 must
258  * be 0.
259  */
260 
261 /*
262  * NVME_REG_MEMBUF  (RO, 32 bits)
263  * NVME_REG_MEMSIZE (RO, 32 bits)
264  *
265  * These are optional registers which specify the location and extent
266  * of the controller memory buffer.  The offset is specified in multipleps
267  * of CMBSZ and must be 4K aligned.  The BIR tells us which BAR controls
268  * MEMBUF/MEMSIZE.
269  *
270  * The SIZE field in MEMSIZE is in multiple of the UNITS field.
271  *
272  * WDS - If set to 1, data and meta-data for commands may be placed in
273  *         the memory buffer.
274  * RDS - (same)
275  * LISTS - PRP and SGL lists can be in controller memory.
276  * CQS - completion queues can be in controller memory.
277  * SQS - submission queues can be in controller memory.
278  *
279  * Implementation note: We can ignore this entire register.  We will always
280  * use host memory for data and meta-data transfers.
281  */
282 #define NVME_MEMBUF_OFFSET    0xFFFFF000U         /* 0, 2, 3, 4, or 5 only */
283 #define NVME_MEMBUF_BAR                 0x00000007U         /* 0, 2, 3, 4, or 5 only */
284 
285 #define NVME_MEMSIZE_SIZE     0xFFFFF000U
286 #define NVME_MEMSIZE_UNITS_MASK         0x00000F00U
287 #define NVME_MEMSIZE_UNITS_4K 0x00000000U
288 #define NVME_MEMSIZE_UNITS_64K          0x00000100U
289 #define NVME_MEMSIZE_UNITS_1M 0x00000200U
290 #define NVME_MEMSIZE_UNITS_16M          0x00000300U
291 #define NVME_MEMSIZE_UNITS_256M         0x00000400U
292 #define NVME_MEMSIZE_UNITS_4G 0x00000500U
293 #define NVME_MEMSIZE_UNITS_64G          0x00000600U
294                                         /* 7-F are reserved */
295 
296 #define NVME_MEMSIZE_WDS      0x00000010U
297 #define NVME_MEMSIZE_RDS      0x00000008U
298 #define NVME_MEMSIZE_LISTS    0x00000004U
299 #define NVME_MEMSIZE_CQS      0x00000002U
300 #define NVME_MEMSIZE_SQS      0x00000001U
301 
302 /*
303  * NVME_REG_SUBQ*_BELL                  Submission queue doorbell register (WO)
304  * NVME_REG_COMQ*_BELL                  Completion queue doorbell register (WO)
305  *
306  * The low 16 bits specify the index of the submission queue tail or
307  * completion queue head.  Only write to this register, do not read.
308  * Writing to the register passes control of the related command block(s)
309  * to/from the controller.  For example, if the submission queue is
310  * at index 4 and empty the host can setup N command blocks and then
311  * doorbell 4+N.  Each command block does not need to be independently
312  * doorbelled.  The doorbell is managing a circular queue.
313  *
314  * NOTE: A full queue is N-1 entries.  The last entry cannot be in-play
315  *         to distinguish between an empty queue and a full queue.
316  */
317 #define NVME_BELL_MASK                  0x0000FFFFU
318 
319 /*
320  * Submission Queue Entry Header (40 bytes, full entry is 64 bytes)
321  *
322  * This is just the header for the entry, see the opcode section later
323  * on for the full entry structure (which we will define as a union).
324  *
325  * NOTE: prp1/prp2 format depends on config and use cases also depend on
326  *         the command.
327  *
328  *         PRP - Basically a 4-byte-aligned 64-bit address.  The first PRP
329  *               can offset into a page, subsequent PRPs must be page-aligned.
330  *               If pointing to a PRP list, must be 8-byte aligned and each
331  *               PRP in the PRP list must be page-aligned.
332  *
333  * NOTE: For optional admin and nvm vendor specific commands
334  *
335  * NOTE: PRP data target vs PRP to PRP list.  Typically prp1 represents
336  *         the starting point in the target data space and prp2, if needed,
337  *         is a PRP list entry.  In our driver implementation we limit the
338  *         data transfer size such that we do not have to chain PRP lists.
339  *         That is, 4096 / 8 = 512 x 4K pages (2MB).  So 2MB is the maximum
340  *         transfer size we will support.
341  */
342 typedef struct {
343 #if _BYTE_ORDER == _LITTLE_ENDIAN
344           uint8_t   opcode;
345           uint8_t   flags;
346           uint16_t cid;
347 #else
348           uint16_t cid;
349           uint8_t   flags;
350           uint8_t   opcode;
351 #endif
352           uint32_t nsid;                /* namespace id. 0=not used, -1=apply all */
353           uint32_t dw2;
354           uint32_t dw3;
355           uint64_t mptr;
356           uint64_t prp1;                /* prp or sgl depending on config */
357           uint64_t prp2;                /* prp or sgl depending on config */
358 } __packed nvme_subq_head_t;
359 
360 /*
361  * NOTE: SGL1 - buffer can be byte aligned
362  *         SGL2 - buffer containing single SGL desc must be 8-byte aligned
363  */
364 #define NVME_SUBQFLG_PRP      0x00
365 #define NVME_SUBQFLG_SGL1     0x40      /* MPTR -> single contig buffer */
366 #define NVME_SUBQFLG_SGL2     0x80      /* MPTR -> &SGL seg w/one SGL desc */
367 #define NVME_SUBQFLG_RESERVEDS          0xC0
368 
369 #define NVME_SUBQFLG_NORM     0x00
370 #define NVME_SUBQFLG_FUSED0   0x01
371 #define NVME_SUBQFLG_FUSED1   0x02
372 #define NVME_SUBQFLG_RESERVEDF          0x03
373 
374 /*
375  * Submission queue full generic entry (64 bytes)
376  *
377  * NOTE: nvme_subq_item_t is used as part of the nvme_allcmd_t union later
378  *         on.  Do not use the generic item structure to construct nominal
379  *         commands.
380  */
381 typedef struct {
382           nvme_subq_head_t head;
383           /*
384            * command specific fields
385            */
386           union {
387                     uint32_t dw10;
388                     uint32_t ndt;       /* number of dwords in data xfer */
389           };
390           union {
391                     uint32_t dw11;
392                     uint32_t ndm;       /* number of dwords in meta-data xfer */
393           };
394           uint32_t dw12;
395           uint32_t dw13;
396           uint32_t dw14;
397           uint32_t dw15;
398 } __packed nvme_subq_item_t;
399 
400 /*
401  * Completion Queue Entry Trailer (8 bytes, full entry is 16 bytes)
402  */
403 typedef struct {
404 #if _BYTE_ORDER == _LITTLE_ENDIAN
405           uint16_t  subq_head_ptr;
406           uint16_t  subq_id;
407           uint16_t  cmd_id;
408           uint16_t  status;
409 #else
410           uint16_t  subq_id;
411           uint16_t  subq_head_ptr;
412           uint16_t  status;
413           uint16_t  cmd_id;
414 #endif
415 } __packed nvme_comq_tail_t;
416 
417 /*
418  * Completion queue full generic entry (16 bytes)
419  *
420  * subq_head_ptr    - Current submission queue head pointer
421  * subq_id                    - Submission queue the command came from
422  * cmd_id;                    - Command identifier
423  * status;                    - Result status
424  *
425  * NOTE: nvme_comq_item_t is used as part of the nvme_allres_t union later
426  *         on.  Do not use the generic item structure to parse nominal
427  *         results.
428  */
429 typedef struct {
430           uint32_t  dw0;                /* command-specific status */
431           uint32_t  dw1;                /* (typically reserved) */
432           nvme_comq_tail_t tail;
433 } __packed nvme_comq_item_t;
434 
435 #define NVME_COMQ_STATUS_DNR  0x8000U
436 #define NVME_COMQ_STATUS_MORE 0x4000U
437 #define NVME_COMQ_STATUS_29   0x2000U
438 #define NVME_COMQ_STATUS_28   0x1000U
439 #define NVME_COMQ_STATUS_TYPE 0x0E00U
440 #define NVME_COMQ_STATUS_CODE 0x01FEU
441 #define NVME_COMQ_STATUS_PHASE          0x0001U
442 
443 #define NVME_COMQ_STATUS_TYPE_GET(data) \
444                     (((data) & NVME_COMQ_STATUS_TYPE) >> 9)
445 #define NVME_COMQ_STATUS_CODE_GET(data) \
446                     (((data) & NVME_COMQ_STATUS_CODE) >> 1)
447 
448 #define NVME_STATUS_TYPE_GENERIC        0         /* generic status code */
449 #define NVME_STATUS_TYPE_SPECIFIC       1         /* opcode-specific code */
450 #define NVME_STATUS_TYPE_MEDIA                    2         /* media & data errors */
451 #define NVME_STATUS_TYPE_3              3
452 #define NVME_STATUS_TYPE_4              4
453 #define NVME_STATUS_TYPE_5              5
454 #define NVME_STATUS_TYPE_6              6
455 #define NVME_STATUS_TYPE_VENDOR                   7
456 
457 /*
458  * Generic status (NVME_STATUS_TYPE_GENERIC)
459  *
460  * Status codes 0x00-0x7F are applicable to the admin command set or
461  * are generic across multiple command sets.
462  *
463  * Status codes 0x80-0xBF are applicable to the I/O command set.
464  *
465  * Status codes 0xC0-0xFF are vendor-specific
466  */
467 #define NVME_CODE_SUCCESS               0x00
468 #define NVME_CODE_BADOP                           0x01
469 #define NVME_CODE_BADFIELD              0x02
470 #define NVME_CODE_IDCONFLICT            0x03
471 #define NVME_CODE_BADXFER               0x04
472 #define NVME_CODE_ABORTED_PWRLOSS       0x05
473 #define NVME_CODE_INTERNAL              0x06
474 #define NVME_CODE_ABORTED_ONREQ                   0x07
475 #define NVME_CODE_ABORTED_SQDEL                   0x08
476 #define NVME_CODE_ABORTED_FUSEFAIL      0x09
477 #define NVME_CODE_ABORTED_FUSEMISSING   0x0A
478 #define NVME_CODE_BADNAMESPACE                    0x0B
479 #define NVME_CODE_SEQERROR              0x0C
480 #define NVME_CODE_BADSGLSEG             0x0D
481 #define NVME_CODE_BADSGLCNT             0x0E
482 #define NVME_CODE_BADSGLLEN             0x0F
483 #define NVME_CODE_BADSGLMLEN            0x10
484 #define NVME_CODE_BADSGLTYPE            0x11
485 #define NVME_CODE_BADMEMBUFUSE                    0x12
486 #define NVME_CODE_BADPRPOFF             0x13
487 #define NVME_CODE_ATOMICWUOVFL                    0x14
488                                                   /* 15-7f reserved */
489 
490 #define NVME_CODE_LBA_RANGE             0x80
491 #define NVME_CODE_CAP_EXCEEDED                    0x81
492 #define NVME_CODE_NAM_NOT_READY                   0x82
493 #define NVME_CODE_RSV_CONFLICT                    0x83
494 #define NVME_CODE_FMT_IN_PROG           0x84
495                                                   /* 85-bf reserved */
496 
497 /*
498  * Command specific status codes (NVME_STATUS_TYPE_SPECIFIC)
499  */
500 #define NVME_CSSCODE_BADCOMQ                      0x00
501 #define NVME_CSSCODE_BADQID                       0x01
502 #define NVME_CSSCODE_BADQSIZE                     0x02
503 #define NVME_CSSCODE_ABORTLIM                     0x03
504 #define NVME_CSSCODE_RESERVED04                             0x04
505 #define NVME_CSSCODE_ASYNCEVENTLIM                0x05
506 #define NVME_CSSCODE_BADFWSLOT                              0x06
507 #define NVME_CSSCODE_BADFWIMAGE                             0x07
508 #define NVME_CSSCODE_BADINTRVECT                  0x08
509 #define NVME_CSSCODE_BADLOGPAGE                             0x09
510 #define NVME_CSSCODE_BADFORMAT                              0x0A
511 #define NVME_CSSCODE_FW_NEEDSCONVRESET            0x0B
512 #define NVME_CSSCODE_BADQDELETE                             0x0C
513 #define NVME_CSSCODE_FEAT_NOT_SAVEABLE            0x0D
514 #define NVME_CSSCODE_FEAT_NOT_CHGABLE             0x0E
515 #define NVME_CSSCODE_FEAT_NOT_NSSPEC              0x0F
516 #define NVME_CSSCODE_FW_NEEDSSUBRESET             0x10
517 #define NVME_CSSCODE_FW_NEEDSRESET                0x11
518 #define NVME_CSSCODE_FW_NEEDSMAXTVIOLATE          0x12
519 #define NVME_CSSCODE_FW_PROHIBITED                0x13
520 #define NVME_CSSCODE_RANGE_OVERLAP                0x14
521 #define NVME_CSSCODE_NAM_INSUFF_CAP               0x15
522 #define NVME_CSSCODE_NAM_ID_UNAVAIL               0x16
523 #define NVME_CSSCODE_RESERVED17                             0x17
524 #define NVME_CSSCODE_NAM_ALREADY_ATT              0x18
525 #define NVME_CSSCODE_NAM_IS_PRIVATE               0x19
526 #define NVME_CSSCODE_NAM_NOT_ATT                  0x1A
527 #define NVME_CSSCODE_NO_THIN_PROVISION            0x1B
528 #define NVME_CSSCODE_CTLR_LIST_INVALID            0x1C
529                                                             /* 1D-7F reserved */
530 
531 #define NVME_CSSCODE_ATTR_CONFLICT                0x80
532 #define NVME_CSSCODE_BADPROTINFO                  0x81
533 #define NVME_CSSCODE_WRITE_TO_RDONLY              0x82
534                                                   /* 83-BF reserved */
535 
536 /*
537  * Media and Data Integrity (NVME_STATUS_TYPE_MEDIA)
538  */
539 #define NVME_MEDCODE_WRITE_FAULT                  0x80
540 #define NVME_MEDCODE_UNRECOV_READ_ERROR           0x81
541 #define NVME_MEDCODE_ETOE_GUARD_CHK               0x82
542 #define NVME_MEDCODE_ETOE_APPTAG_CHK              0x83
543 #define NVME_MEDCODE_ETOE_REFTAG_CHK              0x84
544 #define NVME_MEDCODE_COMPARE_FAILURE              0x85
545 #define NVME_MEDCODE_ACCESS_DENIED                0x86
546 #define NVME_MEDCODE_UNALLOCATED                  0x87
547                                                   /* 88-BF reserved */
548 
549 /*
550  * OPCODES:
551  *        7:        1=IO Command set or vendor specific
552  *        6:2       Function
553  *        1         Data XFer R
554  *        0         Data XFer W         (note: both R and W cannot be specified)
555  *
556  * Admin commands
557  */
558 #define NVME_OP_DELETE_SUBQ   0x00
559 #define NVME_OP_CREATE_SUBQ   0x01
560 #define NVME_OP_GET_LOG_PAGE  0x02      /* (needs namid) */
561 #define NVME_OP_DELETE_COMQ   0x04
562 #define NVME_OP_CREATE_COMQ   0x05
563 #define NVME_OP_IDENTIFY      0x06      /* (needs namid) */
564 #define NVME_OP_ABORT                   0x08
565 #define NVME_OP_SET_FEATURES  0x09      /* (needs namid) */
566 #define NVME_OP_GET_FEATURES  0x0A      /* (needs namid) */
567 #define NVME_OP_ASY_EVENT_REQ 0x0C
568 #define NVME_OP_NAM_MANAGE    0x0D      /* (optional, needs namid) */
569 #define NVME_OP_FW_COMMIT     0x10      /* (optional) */
570 #define NVME_OP_FW_DOWNLOAD   0x11      /* (optional) */
571 #define NVME_OP_NAM_ATTACH    0x15      /* (optional, needs namid) */
572 
573 #define NVME_OP_FORMATNVM     0x80      /* (optional, needs namid) */
574 #define NVME_OP_SEC_SEND      0x81      /* (optional, needs namid) */
575 #define NVME_OP_SEC_RECV      0x82      /* (optional, needs namid) */
576 
577 /*
578  * Abort command
579  *
580  * Error status possible: NVM_CSSCODE_ABORTLIM
581  */
582 typedef struct {
583           nvme_subq_head_t head;
584 #if _BYTE_ORDER == _LITTLE_ENDIAN
585           uint16_t  subq_id;  /* subq to abort */
586           uint16_t  cmd_id;             /* cmdid to abort */
587 #else
588           uint16_t  cmd_id;
589           uint16_t  subq_id;
590 #endif
591           uint32_t  reserved11;
592           uint32_t  reserved12;
593           uint32_t  reserved13;
594           uint32_t  reserved14;
595           uint32_t  reserved15;
596 } __packed nvme_abort_cmd_t;
597 
598 typedef struct {
599           uint32_t dw0;
600           uint32_t dw1;
601           nvme_comq_tail_t tail;
602 } __packed nvme_abort_res_t;
603 
604 /*
605  * Asynchronous Event Request Command
606  *
607  * Error status possible: NVM_CSSCODE_ASYNCEVENTLIM
608  *
609  * NOTE: Should be posted to an independent queue, with no timeout.  Async
610  *         events are returned when they occur and so might not be returned
611  *         for a very long time (like hours, or longer).
612  */
613 typedef struct {
614           nvme_subq_head_t head;
615           uint32_t  reserved10;
616           uint32_t  reserved11;
617           uint32_t  reserved12;
618           uint32_t  reserved13;
619           uint32_t  reserved14;
620           uint32_t  reserved15;
621 } __packed nvme_async_cmd_t;
622 
623 typedef struct {
624 #if _BYTE_ORDER == _LITTLE_ENDIAN
625           uint8_t             type;
626           uint8_t             info;
627           uint8_t             lid;
628           uint8_t             reserved03;
629 #else
630           uint8_t             reserved03;
631           uint8_t             lid;
632           uint8_t             info;
633           uint8_t             type;
634 #endif
635           uint32_t  dw1;
636           nvme_comq_tail_t tail;
637 } __packed nvme_async_res_t;
638 
639 #define NVME_ASYNC_TYPE_MASK            0x07
640 #define NVME_ASYNC_TYPE_ERROR           0x00      /* error status */
641 #define NVME_ASYNC_TYPE_SMART           0x01      /* smart status */
642 #define NVME_ASYNC_TYPE_NOTICE                    0x02
643 #define NVME_ASYNC_TYPE_RESERVED3       0x03
644 #define NVME_ASYNC_TYPE_RESERVED4       0x04
645 #define NVME_ASYNC_TYPE_RESERVED5       0x05
646 #define NVME_ASYNC_TYPE_CSS             0x06      /* cmd-specific status */
647 #define NVME_ASYNC_TYPE_VENDOR                    0x07
648 
649 /* TYPE_ERROR */
650 #define NVME_ASYNC_INFO_INVDOORBELL     0x00
651 #define NVME_ASYNC_INFO_INVDOORVALUE    0x01
652 #define NVME_ASYNC_INFO_DIAGFAIL        0x02
653 #define NVME_ASYNC_INFO_INTRNL_FATAL    0x03      /* persistent internal error */
654 #define NVME_ASYNC_INFO_INTRNL_TRANS    0x04      /* transient internal error */
655 #define NVME_ASYNC_INFO_FIRMLOADERR     0x05
656                                                   /* 06-FF reserved */
657 
658 /* TYPE_SMART */
659 #define NVME_ASYNC_INFO_UNRELIABLE      0x00
660 #define NVME_ASYNC_INFO_TEMP_THR        0x01
661 #define NVME_ASYNC_INFO_SPARE_BELOW_THR 0x02
662                                                   /* 03-FF reserved */
663 
664 /* TYPE_NOTICE */
665 #define NVME_ASYNC_INFO_NAM_ATTR_CHG    0x00
666 #define NVME_ASYNC_INFO_FW_ACT_START    0x01
667                                                   /* 02-FF reserved */
668 
669 /* TYPE_CSS */
670 #define NVME_ASYNC_INFO_RES_LOGPG_AVAIL 0x00
671                                                   /* 01-FF reserved */
672 
673 /*
674  * Create I/O Completion Queue Command
675  *
676  * NOTE: PRP1 depends on the PC (physically contiguous) config bit.
677  *         If set (which we do), points to a single physically contiguous
678  *         array.
679  *
680  * NOTE: XXX IV specification associated with msix PCI space ?
681  */
682 typedef struct {
683           nvme_subq_head_t head;
684 #if _BYTE_ORDER == _LITTLE_ENDIAN
685           uint16_t  comq_id;  /* create w/unique id */
686           uint16_t  comq_size;          /* in entries */
687           uint16_t  flags;
688           uint16_t  ivect;              /* multiple MSI or MSI-X only */
689 #else
690           uint16_t  comq_size;
691           uint16_t  comq_id;
692           uint16_t  ivect;
693           uint16_t  flags;
694 #endif
695           uint32_t  reserved12;
696           uint32_t  reserved13;
697           uint32_t  reserved14;
698           uint32_t  reserved15;
699 } __packed nvme_createcomq_cmd_t;
700 
701 #define NVME_CREATECOM_IEN    0x0002
702 #define NVME_CREATECOM_PC     0x0001
703 
704 typedef struct {
705           uint32_t  dw0;
706           uint32_t  dw1;
707           nvme_comq_tail_t tail;
708 } __packed nvme_createcomq_res_t;
709 
710 /*
711  * Create I/O Completion Queue Command
712  *
713  * NOTE: PRP1 depends on the PC (physically contiguous) config bit.
714  *         If set (which we do), points to a single physically contiguous
715  *         array.
716  *
717  * NOTE: XXX IV specification associated with msix PCI space ?
718  */
719 typedef struct {
720           nvme_subq_head_t head;
721 #if _BYTE_ORDER == _LITTLE_ENDIAN
722           uint16_t  subq_id;  /* create w/unique id */
723           uint16_t  subq_size;          /* in entries */
724           uint16_t  flags;
725           uint16_t  comq_id;  /* completion queue to use */
726 #else
727           uint16_t  subq_size;
728           uint16_t  subq_id;
729           uint16_t  comq_id;
730           uint16_t  flags;
731 #endif
732           uint32_t  reserved12;
733           uint32_t  reserved13;
734           uint32_t  reserved14;
735           uint32_t  reserved15;
736 } __packed nvme_createsubq_cmd_t;
737 
738 #define NVME_CREATESUB_PRI    0x0006
739 #define NVME_CREATESUB_PRI_LOW          0x0006
740 #define NVME_CREATESUB_PRI_MED          0x0004
741 #define NVME_CREATESUB_PRI_HIG          0x0002
742 #define NVME_CREATESUB_PRI_URG          0x0000
743 
744 #define NVME_CREATESUB_PC     0x0001
745 
746 typedef struct {
747           uint32_t  dw0;
748           uint32_t  dw1;
749           nvme_comq_tail_t tail;
750 } __packed nvme_createsubq_res_t;
751 
752 /*
753  * Delete I/O Completion Queue Command
754  * Delete I/O Submission Queue Command
755  *
756  * Both commands use the same structures.
757  */
758 typedef struct {
759           nvme_subq_head_t head;
760 #if _BYTE_ORDER == _LITTLE_ENDIAN
761           uint16_t  qid;                /* queue id to delete */
762           uint16_t  reserved02;
763 #else
764           uint16_t  reserved02;
765           uint16_t  qid;                /* queue id to delete */
766 #endif
767           uint32_t  reserved11;
768           uint32_t  reserved12;
769           uint32_t  reserved13;
770           uint32_t  reserved14;
771           uint32_t  reserved15;
772 } __packed nvme_deleteq_cmd_t;
773 
774 typedef struct {
775           uint32_t  dw0;
776           uint32_t  dw1;
777           nvme_comq_tail_t tail;
778 } __packed nvme_deleteq_res_t;
779 
780 /*
781  * Get Features Command
782  */
783 typedef struct {
784           nvme_subq_head_t head;
785           uint32_t  flags;
786           uint32_t  reserved11;
787           uint32_t  reserved12;
788           uint32_t  reserved13;
789           uint32_t  reserved14;
790           uint32_t  reserved15;
791 } __packed nvme_getfeat_cmd_t;
792 
793 #define NVME_GETFEAT_ID_MASK  0x000000FFU
794 #define NVME_GETFEAT_SEL_MASK 0x00000700U         /* NOTE: optional support */
795 
796 #define NVME_GETFEAT_SEL_CUR  0x00000000U         /* current */
797 #define NVME_GETFEAT_SEL_DEF  0x00000100U         /* default */
798 #define NVME_GETFEAT_SEL_SAV  0x00000200U         /* saved */
799 #define NVME_GETFEAT_SEL_SUP  0x00000300U         /* supported */
800 #define NVME_GETFEAT_SEL_4    0x00000400U
801 #define NVME_GETFEAT_SEL_5    0x00000500U
802 #define NVME_GETFEAT_SEL_6    0x00000600U
803 #define NVME_GETFEAT_SEL_7    0x00000700U
804 
805 typedef struct {
806           uint32_t  cap;      /* SEL_SUP select only */
807           uint32_t  dw1;
808           nvme_comq_tail_t tail;
809 } __packed nvme_getfeat_res_t;
810 
811 #define NVME_GETFEAT_CAP_SAVEABLE       0x00000001U
812 #define NVME_GETFEAT_CAP_NAM_SPECIFIC   0x00000002U
813 #define NVME_GETFEAT_CAP_CHANGEABLE     0x00000004U
814 
815 /*
816  * Get Log Page Command
817  *
818  * See nvme_log.h for returned data content
819  */
820 typedef struct {
821           nvme_subq_head_t head;
822 #if _BYTE_ORDER == _LITTLE_ENDIAN
823           uint8_t             lid;
824           uint8_t             reserved01;
825           uint16_t  numdl;              /* 0's based value */
826           uint16_t  numdu;              /* msb (NVMe 1.2.1 or later) */
827           uint16_t  reserved02;
828 #else
829           uint16_t  numdl;
830           uint8_t             reserved01;
831           uint8_t             lid;
832           uint16_t  reserved02;
833           uint16_t  numdu;
834 #endif
835                                                   /* NOTE: must be 4-byte aligned */
836           uint32_t  lpol;               /* NVME 1.2.1+ logpg offset low */
837           uint32_t  lpou;               /* NVME 1.2.1+ logpg offset high */
838           uint32_t  reserved14;
839           uint32_t  reserved15;
840 } __packed nvme_getlog_cmd_t;
841 
842 #define NVME_GETLOGPG_NUMD_MASK         0x0FFF
843 
844 #define NVME_LID_00           0x00
845 #define NVME_LID_ERROR                  0x01      /* error information */
846 #define NVME_LID_SMART                  0x02      /* smart/health information */
847 #define NVME_LID_FWSLOT                 0x03      /* firmware slot information */
848 #define NVME_LID_NAM_CHG_LIST 0x04      /* (optional) changed ns list */
849 #define NVME_LID_CMDEFF                 0x05      /* (optional) command effects log */
850                                         /* 06-7F reserved */
851 #define NVME_LID_RES_NOTIFY   0x80      /* (optional) Reservation notify */
852                                         /* 81-BF I/O command set specific */
853                                         /* C0-FF Vendor specific */
854 
855 typedef struct {
856           uint32_t  dw0;
857           uint32_t  dw1;
858           nvme_comq_tail_t tail;
859 } __packed nvme_getlog_res_t;
860 
861 /*
862  * Identify Command
863  *
864  * See nvme_ident.h for the returned data structure(s)
865  */
866 typedef struct {
867           nvme_subq_head_t head;
868 #if _BYTE_ORDER == _LITTLE_ENDIAN
869           uint8_t             cns;
870           uint8_t             reserved01;
871           uint16_t  cntid;
872 #else
873           uint16_t  cntid;
874           uint8_t             reserved01;
875           uint8_t             cns;
876 #endif
877           uint32_t  reserved11;
878           uint32_t  reserved12;
879           uint32_t  reserved13;
880           uint32_t  reserved14;
881           uint32_t  reserved15;
882 } __packed nvme_identify_cmd_t;
883 
884 #define NVME_CNS_ACT_NS                 0x00      /* Identify Namespace Structure */
885 #define NVME_CNS_CTLR                   0x01      /* Identify Controller Structure */
886 #define NVME_CNS_ACT_NSLIST   0x02      /* List of 1024 ACTIVE nsids > nsid */
887                                         /* 03-0F reserved */
888 
889 #define NVME_CNS_ALO_NSLIST   0x10      /* List of1024 ALLOCATED nsids >nsid*/
890 #define NVME_CNS_ALO_NS                 0x11      /* Identify Namespace Structure */
891 #define NVME_CNS_ATT_CTLR_LIST          0x12      /* up to 2047 ctlr ids >= cntid */
892                                                   /* (that are attached to nsid) */
893 #define NVME_CNS_ANY_CTLR_LIST          0x13      /* same, but may/maynot be attached */
894                                         /* 14-1F reserved */
895                                         /* 20-FF reserved */
896 
897 typedef struct {
898           uint32_t dw0;
899           uint32_t dw1;
900           nvme_comq_tail_t tail;
901 } __packed nvme_identify_res_t;
902 
903 /*
904  * Namespace Attachment Command
905  */
906 typedef struct {
907           nvme_subq_head_t head;
908           uint32_t  sel;
909           uint32_t  reserved11;
910           uint32_t  reserved12;
911           uint32_t  reserved13;
912           uint32_t  reserved14;
913           uint32_t  reserved15;
914 } __packed nvme_nsatt_cmd_t;
915 
916 #define NVME_NSATT_SEL_MASK   0x0000000FU
917 
918 #define NVME_NSATT_SEL_GET(data)        \
919                     ((data) & NVME_NSATT_SEL_MASK)
920 #define NVME_NSATT_SEL_ATTACH 0
921 #define NVME_NSATT_SEL_DETACH 1
922                                         /* 2-F reserved */
923 
924 typedef struct {
925           uint32_t dw0;
926           uint32_t dw1;
927           nvme_comq_tail_t tail;
928 } __packed nvme_nsatt_res_t;
929 
930 /*
931  * Namespace Management Command
932  *
933  * See nvme_ns.h for transfered data structures
934  */
935 typedef struct {
936           nvme_subq_head_t head;
937           uint32_t  sel;
938           uint32_t  reserved11;
939           uint32_t  reserved12;
940           uint32_t  reserved13;
941           uint32_t  reserved14;
942           uint32_t  reserved15;
943 } __packed nvme_nsmgmt_cmd_t;
944 
945 #define NVME_NSMGMT_SEL_MASK  0x0000000FU
946 
947 #define NVME_NSMGMT_SEL_GET(data)       \
948                     ((data) & NVME_NSMGMT_SEL_MASK)
949 #define NVME_NSMGMT_SEL_CREATE          0
950 #define NVME_NSMGMT_SEL_DELETE          1
951                                         /* 2-F reserved */
952 
953 typedef struct {
954           uint32_t  nsid;     /* nsid created in a CREATE op only */
955           uint32_t  dw1;
956           nvme_comq_tail_t tail;
957 } __packed nvme_nsmgmt_res_t;
958 
959 /*
960  * NVME Set Features Command
961  *
962  * NOTE: PRP2 cannot point to a PRP list.  It exists in case the data area
963  *         crosses a page boundary and has a direct PRP.  Our driver
964  *         implementation page-aligns requests and will only use PRP1.
965  *
966  * NOTE: I decided to embed the sub-commands in the main structure, and
967  *         place the related #define's nearby.  This is the only place where
968  *         I try to embed #defines because doing so normally makes things hard
969  *         to read.
970  */
971 typedef struct {
972           nvme_subq_head_t head;
973           uint32_t flags;               /* dw10 */
974           union {
975                     /*
976                      * (Generic)
977                      */
978                     struct {
979                               uint32_t dw11;
980                               uint32_t dw12;
981                               uint32_t dw13;
982                               uint32_t dw14;
983                               uint32_t dw15;
984                     };
985 
986                     /*
987                      * NVME_FID_ARB
988                      */
989                     struct {
990                               uint8_t   burst;    /* arb burst 2^n n=0-7 */
991                               uint8_t lpw;        /* N 0-255 (0=1) low pri weight */
992                               uint8_t mpw;        /* N 0-255 (0=1) med pri weight */
993                               uint8_t   hpw;      /* N 0-255 (0=1) high pri weight */
994                     } arb;
995 #define NVME_ARB_BURST_MASK   0x07
996 #define NVME_ARB_BURST_MAX    0x07
997 
998                     /*
999                      * NVME_FID_PWRMGMT
1000                      */
1001                     struct {
1002                               uint8_t xflags;
1003                               uint8_t   reserved01;
1004                               uint8_t   reserved02;
1005                               uint8_t   reserved03;
1006                     } pwrmgmt;
1007 #define NVME_PWRMGMT_PS_MASK  0x1F;
1008 #define NVME_PWRMGMT_WH_MASK  0xE0;
1009 #define NVME_PWRMGMT_PS_SET(data)       ((data) & NVME_PWRMGMT_PS_MASK)
1010 #define NVME_PWRMGMT_WH_SET(data)       (((data) << 5) & NVME_PWRMGMT_WH_MASK)
1011 
1012                     /*
1013                      * NVME_FID_LBARNGTYPE (requires Host Memory Buffer)
1014                      */
1015                     struct {
1016                               uint32_t xflags;
1017                               uint32_t dw12;
1018                               uint32_t dw13;
1019                               uint32_t dw14;
1020                               uint32_t dw15;
1021                     } lbarng;
1022 #define NVME_LBARNG_NUM_MASK  0x0000003FU
1023 
1024                     /*
1025                      * NVME_FID_TEMPTHRESH
1026                      */
1027                     struct {
1028 #if _BYTE_ORDER == _LITTLE_ENDIAN
1029                               uint16_t tmpth;
1030                               uint16_t xflags;
1031 #else
1032                               uint16_t xflags;
1033                               uint16_t tmpth;
1034 #endif
1035                               uint32_t dw12;
1036                               uint32_t dw13;
1037                               uint32_t dw14;
1038                               uint32_t dw15;
1039                     } tempth;
1040 #define NVME_TEMPTH_SEL_MASK  0x000FU
1041 #define NVME_TEMPTH_TYPE_MASK 0x0030U
1042 #define NVME_TEMPTH_TYPE_OVER 0x0000U
1043 #define NVME_TEMPTH_TYPE_UNDER          0x0010U
1044 #define NVME_TEMPTH_TYPE_2    0x0020U
1045 #define NVME_TEMPTH_TYPE_3    0x0030U
1046 
1047                     /*
1048                      * NVME_FID_ERRORRECOVERY
1049                      */
1050                     struct {
1051 #if _BYTE_ORDER == _LITTLE_ENDIAN
1052                               uint16_t tler;
1053                               uint16_t xflags;
1054 #else
1055                               uint16_t xflags;
1056                               uint16_t tler;
1057 #endif
1058                               uint32_t dw12;
1059                               uint32_t dw13;
1060                               uint32_t dw14;
1061                               uint32_t dw15;
1062                     } errrec;
1063 #define NVME_ERRREC_DEALLOCERR          0x0001U   /* enable deallo/unwritten blk error */
1064 
1065                     /*
1066                      * NVME_FID_VOLATILEWC
1067                      */
1068                     struct {
1069                               uint32_t xflags;
1070                               uint32_t dw12;
1071                               uint32_t dw13;
1072                               uint32_t dw14;
1073                               uint32_t dw15;
1074                     } volatilewc;
1075 #define NVME_VOLATILEWC_ENABLE          0x0001U
1076 
1077                     /*
1078                      * NVME_FID_NUMQUEUES
1079                      *
1080                      * (dw0 in completion block contains the number of submission
1081                      *  and completion queues allocated).
1082                      */
1083                     struct {
1084 #if _BYTE_ORDER == _LITTLE_ENDIAN
1085                               uint16_t nsqr;                /* #submissions qus requested */
1086                               uint16_t ncqr;                /* #completion qus requested */
1087 #else
1088                               uint16_t ncqr;
1089                               uint16_t nsqr;
1090 #endif
1091                               uint32_t dw12;
1092                               uint32_t dw13;
1093                               uint32_t dw14;
1094                               uint32_t dw15;
1095                     } numqs;
1096 
1097                     /*
1098                      * NVME_FID_INTCOALESCE
1099                      *
1100                      * NOTE: default upon reset is 0 (no coalescing)
1101                      */
1102                     struct {
1103 #if _BYTE_ORDER == _LITTLE_ENDIAN
1104                               uint8_t   thr;                /* 0's based value, 0=1 */
1105                               uint8_t   time;               /* 0's based value, 0=1 */
1106                               uint16_t reserved02;
1107 #else
1108                               uint16_t reserved02;
1109                               uint8_t   time;
1110                               uint8_t   thr;
1111 #endif
1112                               uint32_t dw12;
1113                               uint32_t dw13;
1114                               uint32_t dw14;
1115                               uint32_t dw15;
1116                     } intcoal;
1117 
1118                     /*
1119                      * NVME_FID_INTVECTOR
1120                      */
1121                     struct {
1122 #if _BYTE_ORDER == _LITTLE_ENDIAN
1123                               uint16_t iv;
1124                               uint16_t xflags;
1125 #else
1126                               uint16_t xflags;
1127                               uint16_t iv;
1128 #endif
1129                               uint32_t dw12;
1130                               uint32_t dw13;
1131                               uint32_t dw14;
1132                               uint32_t dw15;
1133                     } intvect;
1134 #define NVME_INTVECT_CD                 0x0001U             /* disable coalescing */
1135 
1136                     /*
1137                      * NVME_FID_WRATOMICYNRM
1138                      */
1139                     struct {
1140                               uint32_t xflags;
1141                               uint32_t dw12;
1142                               uint32_t dw13;
1143                               uint32_t dw14;
1144                               uint32_t dw15;
1145                     } wratom;
1146 #define NVME_WRATOM_DN                  0x00000001U         /* disables AWUN/NAWUN */
1147 
1148                     /*
1149                      * NVME_FID_ASYNCEVCFG
1150                      */
1151                     struct {
1152                               uint32_t xflags;
1153                               uint32_t dw12;
1154                               uint32_t dw13;
1155                               uint32_t dw14;
1156                               uint32_t dw15;
1157                     } asyncev;
1158 #define NVME_ASYNCEV_SMART_MASK         0x000000FFU         /* bits same as SMART bits */
1159 #define NVME_ASYNCEV_NS_ATTR  0x00000100U         /* ns attr change */
1160 #define NVME_ASYNCEV_FW_ACTVTE          0x00000200U         /* fw activation notice */
1161 
1162                     /*
1163                      * NVME_FID_AUTOPS  (requires Host Memory Buffer)
1164                      */
1165                     struct {
1166                               uint32_t xflags;
1167                               uint32_t dw12;
1168                               uint32_t dw13;
1169                               uint32_t dw14;
1170                               uint32_t dw15;
1171                     } autops;
1172 #define NVME_AUTOPS_ENABLE    0x00000001U         /* enable autonomous ps trans */
1173 
1174                     /*
1175                      * NVME_FID_HOSTMEMBUF
1176                      */
1177                     struct {
1178                               uint32_t xflags;
1179                               uint32_t sizepgs;   /* buffer size in mps units */
1180                               uint32_t hmdlla;    /* desclist lower address */
1181                               uint32_t hmdlua;    /* desclist upper address */
1182                               uint32_t count;               /* list entry count */
1183                     } hostmem;
1184 #define NVME_HOSTMEM_RETURN   0x00000002U         /* same memory after reset */
1185 #define NVME_HOSTMEM_ENABLE   0x00000001U
1186 
1187                     /*
1188                      * NVME_FID_SFTPROGRESS
1189                      */
1190                     struct {
1191 #if _BYTE_ORDER == _LITTLE_ENDIAN
1192                               uint8_t pbslc;                /* pre-boot software load cnt */
1193                               uint8_t reserved01;
1194                               uint8_t reserved02;
1195                               uint8_t reserved03;
1196 #else
1197                               uint8_t reserved03;
1198                               uint8_t reserved02;
1199                               uint8_t reserved01;
1200                               uint8_t pbslc;
1201 #endif
1202                               uint32_t dw12;
1203                               uint32_t dw13;
1204                               uint32_t dw14;
1205                               uint32_t dw15;
1206                     } sftprog;
1207 
1208                     /*
1209                      * NVME_FID_HOSTID
1210                      */
1211                     struct {
1212                               uint32_t dw11;
1213                               uint32_t dw12;
1214                               uint32_t dw13;
1215                               uint32_t dw14;
1216                               uint32_t dw15;
1217                     } hostid;
1218 
1219                     /*
1220                      * NVME_FID_RESERVENOTMASK
1221                      */
1222                     struct {
1223                               uint32_t xflags;
1224                               uint32_t dw12;
1225                               uint32_t dw13;
1226                               uint32_t dw14;
1227                               uint32_t dw15;
1228                     } resnotify;
1229 #define NVME_RESNOTIFY_RESPRE 0x00000008U
1230 #define NVME_RESNOTIFY_RESREL 0x00000004U
1231 #define NVME_RESNOTIFY_REGPRE 0x00000002U
1232 
1233                     /*
1234                      * NVME_FID_RESERVEPERSIST
1235                      */
1236                     struct {
1237                               uint32_t xflags;
1238                               uint32_t dw12;
1239                               uint32_t dw13;
1240                               uint32_t dw14;
1241                               uint32_t dw15;
1242                     } respersist;
1243 #define NVME_RESPERSIST_PTPL  0x00000001U         /* persist thru power loss */
1244           };
1245 } __packed nvme_setfeat_cmd_t;
1246 
1247 #define NVME_SETFEAT_SAVE     0x80000000U
1248 #define NVME_FID_MASK                   0x000000FFU
1249 
1250 #define NVME_FID_GET(data)    \
1251                     ((data) & NVME_FID_MASK)
1252 #define NVME_FID_SET(fid)     \
1253                     ((fid) & NVME_FID_MASK)
1254 
1255 #define NVME_FID_00           0x00
1256 #define NVME_FID_ARB                    0x01      /* Aribtration */
1257 #define NVME_FID_PWRMGMT      0x02      /* Power Management */
1258 #define NVME_FID_LBARNGTYPE   0x03      /* (opt) LBA Range Type */
1259 #define NVME_FID_TEMPTHRESH   0x04      /* Temp Threshold */
1260 #define NVME_FID_ERRORRECOVERY          0x05      /* Error Recovery */
1261 #define NVME_FID_VOLATILEWC   0x06      /* (opt) Volatile Write Cache */
1262 #define NVME_FID_NUMQUEUES    0x07      /* Number of Queues */
1263 #define NVME_FID_INTCOALESCE  0x08      /* Interrupt Coalescing */
1264 #define NVME_FID_INTVECTOR    0x09      /* Interrupt Vector Config */
1265 #define NVME_FID_WRATOMICYNRM 0x0A      /* Write Atomicy Normal */
1266 #define NVME_FID_ASYNCEVCFG   0x0B      /* Async Event Config */
1267 #define NVME_FID_AUTOPS                 0x0C      /* (opt) Autonomous pwr state */
1268 #define NVME_FID_HOSTMEMBUF   0x0D      /* (opt) Host memory buffer */
1269                                         /* 0E-77 reserved */
1270                                         /* 78-7F see NVMe management ifc spec */
1271                                         /* 80-BF cmd set specific (reserved) */
1272 #define NVME_FID_SFTPROGRESS  0x80      /* (opt) Software Progress Marker */
1273 #define NVME_FID_HOSTID                 0x81      /* (opt) Host Identifier */
1274 #define NVME_FID_RESERVENOTMASK         0x82      /* (opt) Reservation Notify Marker */
1275 #define NVME_FID_RESERVEPERSIST         0x83      /* (opt) Reservation Persistance */
1276 
1277 typedef struct {
1278           uint32_t dw0;
1279           uint32_t dw1;
1280           nvme_comq_tail_t tail;
1281 } __packed nvme_setfeat_res_t;
1282 
1283 /*
1284  * Format NVM Command
1285  */
1286 typedef struct {
1287           nvme_subq_head_t head;
1288           uint32_t  flags;
1289           uint32_t  reserved11;
1290           uint32_t  reserved12;
1291           uint32_t  reserved13;
1292           uint32_t  reserved14;
1293           uint32_t  reserved15;
1294 } __packed nvme_format_cmd_t;
1295 
1296 #define NVME_FORMAT_SES_MASK            0x00000E00U
1297 #define NVME_FORMAT_SES_NONE            0x00000000U
1298 #define NVME_FORMAT_SES_NORM            0x00000200U
1299 #define NVME_FORMAT_SES_CRYPTO                    0x00000400U
1300                                                   /* remainint ids reserved */
1301 
1302 #define NVME_FORMAT_PROT_FIRST                    0x00000100U         /* first-8 of meta */
1303                                                                       /* (else last-8) */
1304 
1305 #define NVME_FORMAT_PROT_MASK           0x000000E0U
1306 #define NVME_FORMAT_PROT_NONE           0x00000000U
1307 #define NVME_FORMAT_PROT_TYPE1                    0x00000020U
1308 #define NVME_FORMAT_PROT_TYPE2                    0x00000040U
1309 #define NVME_FORMAT_PROT_TYPE3                    0x00000060U
1310                                                   /* remaining ids reserved */
1311 
1312 #define NVME_FORMAT_MS                            0x00000010U         /* metadata 1=inline */
1313 #define NVME_FORMAT_LBA_FMT_MASK        0x0000000FU
1314 #define NVME_FORMAT_LBA_FMT_SET(data)   \
1315           ((data) & NVME_FORMAT_LBA_FMT_MASK)
1316 
1317 typedef struct {
1318           uint32_t dw0;
1319           uint32_t dw1;
1320           nvme_comq_tail_t tail;
1321 } __packed nvme_format_res_t;
1322 
1323 /*
1324  * Security Receive Command
1325  */
1326 typedef struct {
1327           nvme_subq_head_t head;
1328 #if _BYTE_ORDER == _LITTLE_ENDIAN
1329           uint8_t             nssf;
1330           uint8_t             spsp0;
1331           uint8_t             spsp1;
1332           uint8_t             secp;
1333 #else
1334           uint8_t             secp;
1335           uint8_t             spsp1;
1336           uint8_t             spsp0;
1337           uint8_t             nssf;
1338 #endif
1339           uint32_t  alloc_len;          /* allocation length */
1340           uint32_t  reserved12;
1341           uint32_t  reserved13;
1342           uint32_t  reserved14;
1343           uint32_t  reserved15;
1344 } __packed nvme_secrecv_cmd_t;
1345 
1346 typedef struct {
1347           uint32_t dw0;
1348           uint32_t dw1;
1349           nvme_comq_tail_t tail;
1350 } __packed nvme_secrecv_res_t;
1351 
1352 /*
1353  * Security Send Command
1354  */
1355 typedef struct {
1356           nvme_subq_head_t head;
1357 #if _BYTE_ORDER == _LITTLE_ENDIAN
1358           uint8_t             nssf;
1359           uint8_t             spsp0;
1360           uint8_t             spsp1;
1361           uint8_t             secp;
1362 #else
1363           uint8_t             secp;
1364           uint8_t             spsp1;
1365           uint8_t             spsp0;
1366           uint8_t             nssf;
1367 #endif
1368           uint32_t  xfer_len; /* xfer length */
1369           uint32_t  reserved12;
1370           uint32_t  reserved13;
1371           uint32_t  reserved14;
1372           uint32_t  reserved15;
1373 } __packed nvme_secsend_cmd_t;
1374 
1375 typedef struct {
1376           uint32_t dw0;
1377           uint32_t dw1;
1378           nvme_comq_tail_t tail;
1379 } __packed nvme_secsend_res_t;
1380 
1381 
1382 /************************************************************************
1383  * NVM I/O COMMANDS - Core I/O Commands, NVM command set              *
1384  ************************************************************************
1385  *
1386  * The nsid field is required for all of these commands.
1387  */
1388 
1389 #define NVME_IOCMD_FLUSH      0x00
1390 #define NVME_IOCMD_WRITE      0x01
1391 #define NVME_IOCMD_READ                 0x02
1392 #define NVME_IOCMD_WRITEUC    0x04
1393 #define NVME_IOCMD_COMPARE    0x05
1394 #define NVME_IOCMD_WRITEZ     0x08
1395 #define NVME_IOCMD_DATAMGMT   0x09
1396 #define NVME_IOCMD_RESREG     0x0D
1397 #define NVME_IOCMD_RESREP     0x0E
1398 #define NVME_IOCMD_RESACQ     0x11
1399 #define NVME_IOCMD_RESREL     0x15
1400 
1401 /*
1402  * ioflags (16 bits) is similar across many NVM commands, make
1403  * those definitions generic.
1404  */
1405 #define NVME_IOFLG_LR                   0x8000U   /* limited retry */
1406 #define NVME_IOFLG_FUA                  0x4000U   /* force unit access */
1407 #define NVME_IOFLG_PRINFO_MASK          0x3C00U   /* prot info mask */
1408 #define NVME_IOFLG_RESV_MASK  0x03FFU
1409 
1410 /*
1411  * dsm (32 bits) exists in the read and write commands.
1412  */
1413 #define NVME_DSM_INCOMPRESSIBLE         0x00000080U
1414 #define NVME_DSM_SEQREQ                 0x00000040U
1415 
1416 #define NVME_DSM_ACCLAT_MASK  0x00000030U
1417 #define NVME_DSM_ACCLAT_UNSPEC          0x00000000U
1418 #define NVME_DSM_ACCLAT_IDLE  0x00000010U
1419 #define NVME_DSM_ACCLAT_NORM  0x00000020U
1420 #define NVME_DSM_ACCLAT_LOW   0x00000030U
1421 
1422 #define NVME_DSM_ACCFREQ_MASK 0x0000000FU
1423 #define NVME_DSM_ACCFREQ_UNSPEC         0x00000000U         /* unspecified */
1424 #define NVME_DSM_ACCFREQ_WRTYP          0x00000001U         /* typical reads & writes */
1425 #define NVME_DSM_ACCFREQ_WRLOW          0x00000002U         /* few writes, few reads */
1426 #define NVME_DSM_ACCFREQ_WLORHI         0x00000003U         /* few writes, many reads */
1427 #define NVME_DSM_ACCFREQ_WHIRLO         0x00000004U         /* many writes, few reads */
1428 #define NVME_DSM_ACCFREQ_WHIRHI         0x00000005U         /* many writes, many reads */
1429 #define NVME_DSM_ACCFREQ_RONETM         0x00000006U         /* one-time read */
1430 #define NVME_DSM_ACCFREQ_RSPECU         0x00000007U         /* speculative read */
1431 #define NVME_DSM_ACCFREQ_OVERWR         0x00000008U         /* will be overwritten soon */
1432                                         /* 9-F reserved */
1433 
1434 
1435 /*
1436  * NVM Flush Command                              NVME_IOCMD_FLUSH
1437  *
1438  * For entire nsid, dw10-15 are reserved and should be zerod.
1439  */
1440 typedef struct {
1441           nvme_subq_head_t head;
1442           uint32_t  reserved10;
1443           uint32_t  reserved11;
1444           uint32_t  reserved12;
1445           uint32_t  reserved13;
1446           uint32_t  reserved14;
1447           uint32_t  reserved15;
1448 } __packed nvme_flush_cmd_t;
1449 
1450 typedef struct {
1451           uint32_t dw0;
1452           uint32_t dw1;
1453           nvme_comq_tail_t tail;
1454 } __packed nvme_flush_res_t;
1455 
1456 /*
1457  * NVM Write Command                              NVME_IOCMD_WRITE
1458  */
1459 typedef struct {
1460           nvme_subq_head_t head;
1461           uint64_t  start_lba;
1462 #if _BYTE_ORDER == _LITTLE_ENDIAN
1463           uint16_t  count_lba;
1464           uint16_t  ioflags;
1465 #else
1466           uint16_t  ioflags;
1467           uint16_t  count_lba;
1468 #endif
1469           uint32_t  dsm;
1470           uint32_t  iilbrt;             /* expected initial logblk ref tag */
1471 #if _BYTE_ORDER == _LITTLE_ENDIAN
1472           uint16_t  lbat;               /* expected log blk app tag */
1473           uint16_t  lbatm;              /* expected log blk app tag mask */
1474 #else
1475           uint16_t  lbatm;
1476           uint16_t  lbat;
1477 #endif
1478 } __packed nvme_write_cmd_t;
1479 
1480 typedef struct {
1481           uint32_t dw0;
1482           uint32_t dw1;
1483           nvme_comq_tail_t tail;
1484 } __packed nvme_write_res_t;
1485 
1486 /*
1487  * NVM Read Command                     NVME_IOCMD_READ
1488  */
1489 typedef struct {
1490           nvme_subq_head_t head;
1491           uint64_t  start_lba;
1492 #if _BYTE_ORDER == _LITTLE_ENDIAN
1493           uint16_t  count_lba;
1494           uint16_t  ioflags;
1495 #else
1496           uint16_t  ioflags;
1497           uint16_t  count_lba;
1498 #endif
1499           uint32_t  dsm;
1500           uint32_t  eilbrt;             /* expected initial logblk ref tag */
1501 #if _BYTE_ORDER == _LITTLE_ENDIAN
1502           uint16_t  elbat;              /* expected log blk app tag */
1503           uint16_t  elbatm;             /* expected log blk app tag mask */
1504 #else
1505           uint16_t  elbatm;
1506           uint16_t  elbat;
1507 #endif
1508 } __packed nvme_read_cmd_t;
1509 
1510 typedef struct {
1511           uint32_t dw0;
1512           uint32_t dw1;
1513           nvme_comq_tail_t tail;
1514 } __packed nvme_read_res_t;
1515 
1516 /*
1517  * NVM Write Uncorrectable Command      NVME_IOCMD_WRITEUC
1518  */
1519 typedef struct {
1520           nvme_subq_head_t head;
1521           uint64_t  start_lba;
1522 #if _BYTE_ORDER == _LITTLE_ENDIAN
1523           uint16_t  count_lba;
1524           uint16_t  reserved12l;
1525 #else
1526           uint16_t  reserved12l;
1527           uint16_t  count_lba;
1528 #endif
1529           uint32_t  reserved13;
1530           uint32_t  reserved14;
1531           uint32_t  reserved15;
1532 } __packed nvme_writeuc_cmd_t;
1533 
1534 typedef struct {
1535           uint32_t dw0;
1536           uint32_t dw1;
1537           nvme_comq_tail_t tail;
1538 } __packed nvme_writeuc_res_t;
1539 
1540 /*
1541  * NVM Compare Command                            NVME_IOCMD_COMPARE
1542  */
1543 typedef struct {
1544           nvme_subq_head_t head;
1545           uint64_t  start_lba;
1546 #if _BYTE_ORDER == _LITTLE_ENDIAN
1547           uint16_t  count_lba;
1548           uint16_t  ioflags;
1549 #else
1550           uint16_t  ioflags;
1551           uint16_t  count_lba;
1552 #endif
1553           uint32_t  reserved13;
1554           uint32_t  eilbrt;             /* expected initial logblk ref tag */
1555 #if _BYTE_ORDER == _LITTLE_ENDIAN
1556           uint16_t  elbat;              /* expected log blk app tag */
1557           uint16_t  elbatm;             /* expected log blk app tag mask */
1558 #else
1559           uint16_t  elbatm;
1560           uint16_t  elbat;
1561 #endif
1562 } __packed nvme_cmp_cmd_t;
1563 
1564 typedef struct {
1565           uint32_t dw0;
1566           uint32_t dw1;
1567           nvme_comq_tail_t tail;
1568 } __packed nvme_cmp_res_t;
1569 
1570 /*
1571  * NVM Write Zeros Command              NVME_IOCMD_WRITEZ
1572  */
1573 typedef struct {
1574           nvme_subq_head_t head;
1575           uint64_t  start_lba;
1576 #if _BYTE_ORDER == _LITTLE_ENDIAN
1577           uint16_t  count_lba;
1578           uint16_t  ioflags;
1579 #else
1580           uint16_t  ioflags;
1581           uint16_t  count_lba;
1582 #endif
1583           uint32_t  dsm;
1584           uint32_t  iilbrt;             /* expected initial logblk ref tag */
1585 #if _BYTE_ORDER == _LITTLE_ENDIAN
1586           uint16_t  lbat;               /* expected log blk app tag */
1587           uint16_t  lbatm;              /* expected log blk app tag mask */
1588 #else
1589           uint16_t  lbatm;
1590           uint16_t  lbat;
1591 #endif
1592 } __packed nvme_writez_cmd_t;
1593 
1594 typedef struct {
1595           uint32_t dw0;
1596           uint32_t dw1;
1597           nvme_comq_tail_t tail;
1598 } __packed nvme_writez_res_t;
1599 
1600 /*
1601  * NVM Dataset Management Command       NVME_IOCMD_DATAMGMT
1602  *
1603  * See nvme_datamgmt.h for range and context attributes
1604  */
1605 typedef struct {
1606           nvme_subq_head_t head;
1607 #if _BYTE_ORDER == _LITTLE_ENDIAN
1608           uint8_t             nr;       /* number of 16-byte ranges 0's based (0=1) */
1609           uint8_t             reserved01;
1610           uint8_t             reserved02;
1611           uint8_t             reserved03;
1612 #else
1613           uint8_t             reserved03;
1614           uint8_t             reserved02;
1615           uint8_t             reserved01;
1616           uint8_t             nr;       /* number of 16-byte ranges 0's based (0=1) */
1617 #endif
1618           uint32_t  flags;
1619           uint32_t  reserved12;
1620           uint32_t  reserved13;
1621           uint32_t  reserved14;
1622           uint32_t  reserved15;
1623 } __packed nvme_datamgmt_cmd_t;
1624 
1625 /* flags field */
1626 #define NVME_DATAMGT_AD                 0x00000004U         /* 1=deallocate ranges */
1627 #define NVME_DATAMGT_IDW      0x00000002U         /* 1=hint for write acc */
1628 #define NVME_DATAMGT_IDR      0x00000001U         /* 1=hint for read acc */
1629 
1630 typedef struct {
1631           uint32_t dw0;
1632           uint32_t dw1;
1633           nvme_comq_tail_t tail;
1634 } __packed nvme_datamgmt_res_t;
1635 
1636 /*
1637  * NVM Reservation Register Command     NVME_IOCMD_RESREG (TOD)
1638  */
1639 typedef struct {
1640           nvme_subq_head_t head;
1641           uint32_t  dw10;
1642           uint32_t  dw11;
1643           uint32_t  dw12;
1644           uint32_t  dw13;
1645           uint32_t  dw14;
1646           uint32_t  dw15;
1647 } __packed nvme_resreg_cmd_t;
1648 
1649 typedef struct {
1650           uint32_t dw0;
1651           uint32_t dw1;
1652           nvme_comq_tail_t tail;
1653 } __packed nvme_resreg_res_t;
1654 
1655 /*
1656  * NVM Reservation Report Command       NVME_IOCMD_RESREP (TODO)
1657  */
1658 typedef struct {
1659           nvme_subq_head_t head;
1660           uint32_t  dw10;
1661           uint32_t  dw11;
1662           uint32_t  dw12;
1663           uint32_t  dw13;
1664           uint32_t  dw14;
1665           uint32_t  dw15;
1666 } __packed nvme_resrep_cmd_t;
1667 
1668 typedef struct {
1669           uint32_t dw0;
1670           uint32_t dw1;
1671           nvme_comq_tail_t tail;
1672 } __packed nvme_resrep_res_t;
1673 
1674 /*
1675  * NVM Reservation Acquire Command      NVME_IOCMD_RESACQ (TODO)
1676  */
1677 typedef struct {
1678           nvme_subq_head_t head;
1679           uint32_t  dw10;
1680           uint32_t  dw11;
1681           uint32_t  dw12;
1682           uint32_t  dw13;
1683           uint32_t  dw14;
1684           uint32_t  dw15;
1685 } __packed nvme_resacq_cmd_t;
1686 
1687 typedef struct {
1688           uint32_t dw0;
1689           uint32_t dw1;
1690           nvme_comq_tail_t tail;
1691 } __packed nvme_resacq_res_t;
1692 
1693 /*
1694  * NVM Reservation Release Command      NVME_IOCMD_RESREL (TODO)
1695  */
1696 typedef struct {
1697           nvme_subq_head_t head;
1698           uint32_t  dw10;
1699           uint32_t  dw11;
1700           uint32_t  dw12;
1701           uint32_t  dw13;
1702           uint32_t  dw14;
1703           uint32_t  dw15;
1704 } __packed nvme_resrel_cmd_t;
1705 
1706 typedef struct {
1707           uint32_t dw0;
1708           uint32_t dw1;
1709           nvme_comq_tail_t tail;
1710 } __packed nvme_resrel_res_t;
1711 
1712 
1713 /*
1714  * SUBMISSION AND COMPLETION QUEUE ALL-COMMAND UNIONS (primary API)
1715  *
1716  * Union of all submission queue commands (64 bytes)
1717  */
1718 typedef union {
1719           struct {            /* convenient accessors */
1720                     nvme_subq_head_t head;
1721                     uint32_t dw10;
1722                     uint32_t dw11;
1723                     uint32_t dw12;
1724                     uint32_t dw13;
1725                     uint32_t dw14;
1726                     uint32_t dw15;
1727           };
1728           nvme_subq_item_t    item;
1729           nvme_abort_cmd_t    abort;
1730           nvme_async_cmd_t    async;
1731           nvme_createcomq_cmd_t         crcom;
1732           nvme_createsubq_cmd_t         crsub;
1733           nvme_deleteq_cmd_t  delete;
1734           nvme_getfeat_cmd_t  getfeat;
1735           nvme_getlog_cmd_t   getlog;
1736           nvme_identify_cmd_t identify;
1737           nvme_nsatt_cmd_t    nsatt;
1738           nvme_nsmgmt_cmd_t   nsmgmt;
1739           nvme_setfeat_cmd_t  setfeat;
1740           nvme_format_cmd_t   format;
1741           nvme_secrecv_cmd_t  secrecv;
1742           nvme_secsend_cmd_t  secsend;
1743           nvme_flush_cmd_t    flush;
1744           nvme_write_cmd_t    write;
1745           nvme_read_cmd_t               read;
1746           nvme_writeuc_cmd_t  writeuc;
1747           nvme_cmp_cmd_t                cmp;
1748           nvme_writez_cmd_t   writez;
1749           nvme_datamgmt_cmd_t datamgmt;
1750           nvme_resreg_cmd_t   resreg;
1751           nvme_resrep_cmd_t   resrep;
1752           nvme_resacq_cmd_t   resacq;
1753           nvme_resrel_cmd_t   resrel;
1754 } __packed nvme_allcmd_t;
1755 
1756 /*
1757  * Union of all completion queue responses (16 bytes)
1758  */
1759 typedef union {
1760           struct {            /* convenient accessors */
1761                     uint32_t dw0;
1762                     uint32_t dw1;
1763                     nvme_comq_tail_t tail;
1764           };
1765           nvme_comq_item_t    item;
1766           nvme_async_res_t    async;
1767           nvme_createcomq_res_t         crcom;
1768           nvme_createsubq_res_t         crsub;
1769           nvme_deleteq_res_t  delete;
1770           nvme_getfeat_res_t  getfeat;
1771           nvme_getlog_res_t   getlog;
1772           nvme_identify_res_t identify;
1773           nvme_nsatt_res_t    nsatt;
1774           nvme_nsmgmt_res_t   nsmgmt;
1775           nvme_setfeat_res_t  setfeat;
1776           nvme_format_res_t   format;
1777           nvme_secrecv_res_t  secrecv;
1778           nvme_secsend_res_t  secsend;
1779           nvme_flush_res_t    flush;
1780           nvme_write_res_t    write;
1781           nvme_read_res_t               read;
1782           nvme_writeuc_res_t  writeuc;
1783           nvme_cmp_res_t                cmp;
1784           nvme_writez_res_t   writez;
1785           nvme_datamgmt_res_t datamgmt;
1786           nvme_resreg_res_t   resreg;
1787           nvme_resrep_res_t   resrep;
1788           nvme_resacq_res_t   resacq;
1789           nvme_resrel_res_t   resrel;
1790 } __packed nvme_allres_t;
1791 
1792 /*
1793  * Union of all administrative data buffers (does not exceed 4KB)
1794  */
1795 typedef union {
1796           nvme_pwstate_data_t pwstate;
1797           nvme_lba_fmt_data_t lbafmt;
1798           nvme_ident_ctlr_data_t        idctlr;
1799           nvme_ident_ns_data_t          idns;
1800           nvme_ident_ns_list_t          nslist;
1801           nvme_ident_ctlr_list_t        ctlrlist;
1802           nvme_log_error_data_t         logerr[64];
1803           nvme_log_smart_data_t         logsmart;
1804           nvme_fw_slot_data_t fwslot;
1805           nvme_nsmgmt_create_data_t nsmgmt;
1806           nvme_cmdeff_data_t  cmdeff;
1807           nvme_resnotify_data_t         resnotify;
1808 } __packed nvme_admin_data_t;
1809 
1810 /*
1811  * MISC STRUCTURES SENT OR RECEIVED AS DATA
1812  */
1813