xref: /illumos-gate/usr/src/uts/common/io/nvme/nvme_reg.h (revision bc1f688b4872ace323eaddbb1a6365d054e7bf56)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
14  * Copyright (c) 2018, Joyent, Inc.
15  */
16 
17 /*
18  * NVMe hardware interface
19  */
20 
21 #ifndef _NVME_REG_H
22 #define	_NVME_REG_H
23 
24 #include <sys/nvme.h>
25 
26 #pragma pack(1)
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 
33 /*
34  * NVMe constants
35  */
36 #define	NVME_MAX_ADMIN_QUEUE_LEN	4096
37 
38 /*
39  * NVMe registers and register fields
40  */
41 #define	NVME_REG_CAP	0x0		/* Controller Capabilities */
42 #define	NVME_REG_VS	0x8		/* Version */
43 #define	NVME_REG_INTMS	0xc		/* Interrupt Mask Set */
44 #define	NVME_REG_INTMC	0x10		/* Interrupt Mask Clear */
45 #define	NVME_REG_CC	0x14		/* Controller Configuration */
46 #define	NVME_REG_CSTS	0x1c		/* Controller Status */
47 #define	NVME_REG_NSSR	0x20		/* NVM Subsystem Reset */
48 #define	NVME_REG_AQA	0x24		/* Admin Queue Attributes */
49 #define	NVME_REG_ASQ	0x28		/* Admin Submission Queue */
50 #define	NVME_REG_ACQ	0x30		/* Admin Completion Qeueu */
51 #define	NVME_REG_CMBLOC	0x38		/* Controller Memory Buffer Location */
52 #define	NVME_REG_CMBSZ	0x3C		/* Controller Memory Buffer Size */
53 #define	NVME_REG_BPINFO	0x40		/* Boot Partition Information */
54 #define	NVME_REG_BPRSEL	0x44		/* Boot Partition Read Select */
55 #define	NVME_REG_BPMBL	0x48		/* Boot Partition Memory Buffer Loc */
56 #define	NVME_REG_SQTDBL(nvme, n) \
57 	(0x1000 + ((2 * (n)) * nvme->n_doorbell_stride))
58 #define	NVME_REG_CQHDBL(nvme, n) \
59 	(0x1000 + ((2 * (n) + 1) * nvme->n_doorbell_stride))
60 
61 #define	 NVME_CAP_CSS_NVM	1	/* NVM Command Set */
62 #define	 NVME_CAP_AMS_WRR	1	/* Weighted Round-Robin */
63 
64 /* CAP -- Controller Capabilities */
65 typedef union {
66 	struct {
67 		uint16_t cap_mqes;	/* Maximum Queue Entries Supported */
68 		uint8_t cap_cqr:1;	/* Contiguous Queues Required */
69 		uint8_t cap_ams:2;	/* Arbitration Mechanisms Supported */
70 		uint8_t cap_rsvd1:5;
71 		uint8_t cap_to;		/* Timeout */
72 		uint16_t cap_dstrd:4;	/* Doorbell Stride */
73 		uint16_t cap_nssrs:1;	/* NVM Subsystem Reset Supported */
74 		uint16_t cap_css:8;	/* Command Sets Supported */
75 		uint16_t cap_rsvd2:2;
76 		uint8_t cap_bps:1;	/* Boot Partition Support */
77 		uint8_t cap_mpsmin:4;	/* Memory Page Size Minimum */
78 		uint8_t cap_mpsmax:4;	/* Memory Page Size Maximum */
79 		uint8_t cap_rsvd3;
80 	} b;
81 	uint64_t r;
82 } nvme_reg_cap_t;
83 
84 /* VS -- Version */
85 typedef union {
86 	struct {
87 		uint8_t vs_rsvd;
88 		uint8_t vs_mnr;		/* Minor Version Number */
89 		uint16_t vs_mjr;	/* Major Version Number */
90 	} b;
91 	uint32_t r;
92 } nvme_reg_vs_t;
93 
94 /* CC -- Controller Configuration */
95 #define	NVME_CC_SHN_NORMAL	1	/* Normal Shutdown Notification */
96 #define	NVME_CC_SHN_ABRUPT	2	/* Abrupt Shutdown Notification */
97 
98 typedef union {
99 	struct {
100 		uint16_t cc_en:1;	/* Enable */
101 		uint16_t cc_rsvd1:3;
102 		uint16_t cc_css:3;	/* I/O Command Set Selected */
103 		uint16_t cc_mps:4;	/* Memory Page Size */
104 		uint16_t cc_ams:3;	/* Arbitration Mechanism Selected */
105 		uint16_t cc_shn:2;	/* Shutdown Notification */
106 		uint8_t cc_iosqes:4;	/* I/O Submission Queue Entry Size */
107 		uint8_t cc_iocqes:4;	/* I/O Completion Queue Entry Size */
108 		uint8_t cc_rsvd2;
109 	} b;
110 	uint32_t r;
111 } nvme_reg_cc_t;
112 
113 /* CSTS -- Controller Status */
114 #define	NVME_CSTS_SHN_OCCURING	1	/* Shutdown Processing Occuring */
115 #define	NVME_CSTS_SHN_COMPLETE	2	/* Shutdown Processing Complete */
116 
117 typedef union {
118 	struct {
119 		uint32_t csts_rdy:1;	/* Ready */
120 		uint32_t csts_cfs:1;	/* Controller Fatal Status */
121 		uint32_t csts_shst:2;	/* Shutdown Status */
122 		uint32_t csts_nssro:1;	/* NVM Subsystem Reset Occured */
123 		uint32_t csts_pp:1;	/* Processing Paused */
124 		uint32_t csts_rsvd:26;
125 	} b;
126 	uint32_t r;
127 } nvme_reg_csts_t;
128 
129 /* NSSR -- NVM Subsystem Reset */
130 #define	NVME_NSSR_NSSRC	0x4e564d65	/* NSSR magic value */
131 typedef uint32_t nvme_reg_nssr_t;
132 
133 /* AQA -- Admin Queue Attributes */
134 typedef union {
135 	struct {
136 		uint16_t aqa_asqs:12;	/* Admin Submission Queue Size */
137 		uint16_t aqa_rsvd1:4;
138 		uint16_t aqa_acqs:12;	/* Admin Completion Queue Size */
139 		uint16_t aqa_rsvd2:4;
140 	} b;
141 	uint32_t r;
142 } nvme_reg_aqa_t;
143 
144 /*
145  * The spec specifies the lower 12 bits of ASQ and ACQ as reserved, which is
146  * probably a specification bug. The full 64bit regs are used as base address,
147  * and the lower bits must be zero to ensure alignment on the page size
148  * specified in CC.MPS.
149  */
150 /* ASQ -- Admin Submission Queue Base Address */
151 typedef uint64_t nvme_reg_asq_t;	/* Admin Submission Queue Base */
152 
153 /* ACQ -- Admin Completion Queue Base Address */
154 typedef uint64_t nvme_reg_acq_t;	/* Admin Completion Queue Base */
155 
156 /* CMBLOC - Controller Memory Buffer Location */
157 typedef union {
158 	struct {
159 		uint32_t cmbloc_bir:3;		/* Base Indicator Register */
160 		uint32_t cmbloc_rsvd:9;
161 		uint32_t cmbloc_ofst:20;	/* Offset */
162 	} b;
163 	uint32_t r;
164 } nvme_reg_cmbloc_t;
165 
166 /* CMBSZ - Controller Memory Buffer Size */
167 typedef union {
168 	struct {
169 		uint32_t cmbsz_sqs:1;	/* Submission Queue Support */
170 		uint32_t cmbsz_cqs:1;	/* Completion Queue Support */
171 		uint32_t cmbsz_lists:1;	/* PRP SGL List Support */
172 		uint32_t cmbsz_rds:1;	/* Read Data Support */
173 		uint32_t cmbsz_wds:1;	/* Write Data Support */
174 		uint32_t cmbsz_rsvd:3;
175 		uint32_t cmbsz_szu:4;	/* Size Units */
176 		uint32_t cmbsz_sz:20;	/* Size */
177 	} b;
178 	uint32_t r;
179 } nvme_reg_cmbsz_t;
180 
181 /* BPINFO - Boot Partition Information */
182 typedef union {
183 	struct {
184 		uint32_t bpinfo_bpsz:15;	/* Boot Partition Size */
185 		uint32_t bpinfo_rsvd:9;
186 		uint32_t bpinfo_brs:2;		/* Boot Read Status */
187 		uint32_t bpinfo_rsvd2:5;
188 		uint32_t bpinfo_abpid:1;	/* Active Boot Partition ID */
189 	} b;
190 	uint32_t r;
191 } nvme_reg_bpinfo_t;
192 
193 /* BPRSEL - Boot Partition Read Select */
194 typedef union {
195 	struct {
196 		uint32_t bprsel_bprsz:10;	/* Boot Partition Read Size */
197 		uint32_t bprsel_bprof:20;	/* Boot Partition Read Offset */
198 		uint32_t bprsel_rsvd:1;
199 		uint32_t bprsel_bpid:1;		/* Boot Partition Identifier */
200 	} b;
201 	uint32_t r;
202 } nvme_reg_bprsel_t;
203 
204 /* BPMBL - Boot Partition Memory Location Buffer Location */
205 typedef uint64_t nvme_reg_bpbml_t;	/* Memory Buffer Base Address */
206 
207 /* SQyTDBL -- Submission Queue y Tail Doorbell */
208 typedef union {
209 	struct {
210 		uint16_t sqtdbl_sqt;	/* Submission Queue Tail */
211 		uint16_t sqtdbl_rsvd;
212 	} b;
213 	uint32_t r;
214 } nvme_reg_sqtdbl_t;
215 
216 /* CQyHDBL -- Completion Queue y Head Doorbell */
217 typedef union {
218 	struct {
219 		uint16_t cqhdbl_cqh;	/* Completion Queue Head */
220 		uint16_t cqhdbl_rsvd;
221 	} b;
222 	uint32_t r;
223 } nvme_reg_cqhdbl_t;
224 
225 /*
226  * NVMe submission queue entries
227  */
228 
229 /* NVMe scatter/gather list descriptor */
230 typedef struct {
231 	uint64_t sgl_addr;		/* Address */
232 	uint32_t sgl_len;		/* Length */
233 	uint8_t sgl_rsvd[3];
234 	uint8_t sgl_zero:4;
235 	uint8_t sgl_type:4;		/* SGL descriptor type */
236 } nvme_sgl_t;
237 
238 /* NVMe SGL descriptor type */
239 #define	NVME_SGL_DATA_BLOCK	0
240 #define	NVME_SGL_BIT_BUCKET	1
241 #define	NVME_SGL_SEGMENT	2
242 #define	NVME_SGL_LAST_SEGMENT	3
243 #define	NVME_SGL_VENDOR		0xf
244 
245 /* NVMe submission queue entry */
246 typedef struct {
247 	uint8_t sqe_opc;		/* Opcode */
248 	uint8_t sqe_fuse:2;		/* Fused Operation */
249 	uint8_t sqe_rsvd:5;
250 	uint8_t sqe_psdt:1;		/* PRP or SGL for Data Transfer */
251 	uint16_t sqe_cid;		/* Command Identifier */
252 	uint32_t sqe_nsid;		/* Namespace Identifier */
253 	uint64_t sqe_rsvd1;
254 	union {
255 		uint64_t m_ptr;		/* Metadata Pointer */
256 		uint64_t m_sglp;	/* Metadata SGL Segment Pointer */
257 	} sqe_m;
258 	union {
259 		uint64_t d_prp[2];	/* Physical Page Region Entries 1 & 2 */
260 		nvme_sgl_t d_sgl;	/* SGL Entry 1 */
261 	} sqe_dptr;			/* Data Pointer */
262 	uint32_t sqe_cdw10;		/* Number of Dwords in Data Transfer */
263 	uint32_t sqe_cdw11;		/* Number of Dwords in Metadata Xfer */
264 	uint32_t sqe_cdw12;
265 	uint32_t sqe_cdw13;
266 	uint32_t sqe_cdw14;
267 	uint32_t sqe_cdw15;
268 } nvme_sqe_t;
269 
270 /* NVMe admin command opcodes */
271 #define	NVME_OPC_DELETE_SQUEUE	0x0
272 #define	NVME_OPC_CREATE_SQUEUE	0x1
273 #define	NVME_OPC_GET_LOG_PAGE	0x2
274 #define	NVME_OPC_DELETE_CQUEUE	0x4
275 #define	NVME_OPC_CREATE_CQUEUE	0x5
276 #define	NVME_OPC_IDENTIFY	0x6
277 #define	NVME_OPC_ABORT		0x8
278 #define	NVME_OPC_SET_FEATURES	0x9
279 #define	NVME_OPC_GET_FEATURES	0xa
280 #define	NVME_OPC_ASYNC_EVENT	0xc
281 #define	NVME_OPC_NS_MGMT	0xd	/* 1.2 */
282 #define	NVME_OPC_FW_ACTIVATE	0x10
283 #define	NVME_OPC_FW_IMAGE_LOAD	0x11
284 #define	NVME_OPC_SELF_TEST	0x14	/* 1.3 */
285 #define	NVME_OPC_NS_ATTACH	0x15	/* 1.2 */
286 #define	NVME_OPC_KEEP_ALIVE	0x18	/* 1.3 */
287 #define	NVME_OPC_DIRECTIVE_SEND	0x19	/* 1.3 */
288 #define	NVME_OPC_DIRECTIVE_RECV	0x1A	/* 1.3 */
289 #define	NVME_OPC_VIRT_MGMT	0x1C	/* 1.3 */
290 #define	NVME_OPC_NVMEMI_SEND	0x1D	/* 1.3 */
291 #define	NVME_OPC_NVMEMI_RECV	0x1E	/* 1.3 */
292 #define	NVME_OPC_DB_CONFIG	0x7C	/* 1.3 */
293 
294 /* NVMe NVM command set specific admin command opcodes */
295 #define	NVME_OPC_NVM_FORMAT	0x80
296 #define	NVME_OPC_NVM_SEC_SEND	0x81
297 #define	NVME_OPC_NVM_SEC_RECV	0x82
298 
299 /* NVMe NVM command opcodes */
300 #define	NVME_OPC_NVM_FLUSH	0x0
301 #define	NVME_OPC_NVM_WRITE	0x1
302 #define	NVME_OPC_NVM_READ	0x2
303 #define	NVME_OPC_NVM_WRITE_UNC	0x4
304 #define	NVME_OPC_NVM_COMPARE	0x5
305 #define	NVME_OPC_NVM_WRITE_ZERO	0x8
306 #define	NVME_OPC_NVM_DSET_MGMT	0x9
307 #define	NVME_OPC_NVM_RESV_REG	0xd
308 #define	NVME_OPC_NVM_RESV_REPRT	0xe
309 #define	NVME_OPC_NVM_RESV_ACQ	0x11
310 #define	NVME_OPC_NVM_RESV_REL	0x12
311 
312 /*
313  * NVMe completion queue entry
314  */
315 typedef struct {
316 	uint32_t cqe_dw0;		/* Command Specific */
317 	uint32_t cqe_rsvd1;
318 	uint16_t cqe_sqhd;		/* SQ Head Pointer */
319 	uint16_t cqe_sqid;		/* SQ Identifier */
320 	uint16_t cqe_cid;		/* Command Identifier */
321 	nvme_cqe_sf_t cqe_sf;		/* Status Field */
322 } nvme_cqe_t;
323 
324 /* NVMe completion status code type */
325 #define	NVME_CQE_SCT_GENERIC	0	/* Generic Command Status */
326 #define	NVME_CQE_SCT_SPECIFIC	1	/* Command Specific Status */
327 #define	NVME_CQE_SCT_INTEGRITY	2	/* Media and Data Integrity Errors */
328 #define	NVME_CQE_SCT_VENDOR	7	/* Vendor Specific */
329 
330 /* NVMe completion status code (generic) */
331 #define	NVME_CQE_SC_GEN_SUCCESS		0x0	/* Successful Completion */
332 #define	NVME_CQE_SC_GEN_INV_OPC		0x1	/* Invalid Command Opcode */
333 #define	NVME_CQE_SC_GEN_INV_FLD		0x2	/* Invalid Field in Command */
334 #define	NVME_CQE_SC_GEN_ID_CNFL		0x3	/* Command ID Conflict */
335 #define	NVME_CQE_SC_GEN_DATA_XFR_ERR	0x4	/* Data Transfer Error */
336 #define	NVME_CQE_SC_GEN_ABORT_PWRLOSS	0x5	/* Cmds Aborted / Pwr Loss */
337 #define	NVME_CQE_SC_GEN_INTERNAL_ERR	0x6	/* Internal Error */
338 #define	NVME_CQE_SC_GEN_ABORT_REQUEST	0x7	/* Command Abort Requested */
339 #define	NVME_CQE_SC_GEN_ABORT_SQ_DEL	0x8	/* Cmd Aborted / SQ deletion */
340 #define	NVME_CQE_SC_GEN_ABORT_FUSE_FAIL	0x9	/* Cmd Aborted / Failed Fused */
341 #define	NVME_CQE_SC_GEN_ABORT_FUSE_MISS	0xa	/* Cmd Aborted / Missing Fusd */
342 #define	NVME_CQE_SC_GEN_INV_NS		0xb	/* Inval Namespace or Format */
343 #define	NVME_CQE_SC_GEN_CMD_SEQ_ERR	0xc	/* Command Sequence Error */
344 #define	NVME_CQE_SC_GEN_INV_SGL_LAST	0xd	/* Inval SGL Last Seg Desc */
345 #define	NVME_CQE_SC_GEN_INV_SGL_NUM	0xe	/* Inval Number of SGL Desc */
346 #define	NVME_CQE_SC_GEN_INV_DSGL_LEN	0xf	/* Data SGL Length Invalid */
347 #define	NVME_CQE_SC_GEN_INV_MSGL_LEN	0x10	/* Metadata SGL Length Inval */
348 #define	NVME_CQE_SC_GEN_INV_SGL_DESC	0x11	/* SGL Descriptor Type Inval */
349 
350 /* NVMe completion status code (generic NVM commands) */
351 #define	NVME_CQE_SC_GEN_NVM_LBA_RANGE	0x80	/* LBA Out Of Range */
352 #define	NVME_CQE_SC_GEN_NVM_CAP_EXC	0x81	/* Capacity Exceeded */
353 #define	NVME_CQE_SC_GEN_NVM_NS_NOTRDY	0x82	/* Namespace Not Ready */
354 #define	NVME_CQE_SC_GEN_NVM_RSV_CNFLCT	0x83	/* Reservation Conflict */
355 
356 /* NVMe completion status code (command specific) */
357 #define	NVME_CQE_SC_SPC_INV_CQ		0x0	/* Completion Queue Invalid */
358 #define	NVME_CQE_SC_SPC_INV_QID		0x1	/* Invalid Queue Identifier */
359 #define	NVME_CQE_SC_SPC_MAX_QSZ_EXC	0x2	/* Max Queue Size Exceeded */
360 #define	NVME_CQE_SC_SPC_ABRT_CMD_EXC	0x3	/* Abort Cmd Limit Exceeded */
361 #define	NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC	0x5	/* Async Event Request Limit */
362 #define	NVME_CQE_SC_SPC_INV_FW_SLOT	0x6	/* Invalid Firmware Slot */
363 #define	NVME_CQE_SC_SPC_INV_FW_IMG	0x7	/* Invalid Firmware Image */
364 #define	NVME_CQE_SC_SPC_INV_INT_VECT	0x8	/* Invalid Interrupt Vector */
365 #define	NVME_CQE_SC_SPC_INV_LOG_PAGE	0x9	/* Invalid Log Page */
366 #define	NVME_CQE_SC_SPC_INV_FORMAT	0xa	/* Invalid Format */
367 #define	NVME_CQE_SC_SPC_FW_RESET	0xb	/* FW Application Reset Reqd */
368 #define	NVME_CQE_SC_SPC_INV_Q_DEL	0xc	/* Invalid Queue Deletion */
369 #define	NVME_CQE_SC_SPC_FEAT_SAVE	0xd	/* Feature Id Not Saveable */
370 #define	NVME_CQE_SC_SPC_FEAT_CHG	0xe	/* Feature Not Changeable */
371 #define	NVME_CQE_SC_SPC_FEAT_NS_SPEC	0xf	/* Feature Not Namespace Spec */
372 #define	NVME_CQE_SC_SPC_FW_NSSR		0x10	/* FW Application NSSR Reqd */
373 
374 /* NVMe completion status code (NVM command specific */
375 #define	NVME_CQE_SC_SPC_NVM_CNFL_ATTR	0x80	/* Conflicting Attributes */
376 #define	NVME_CQE_SC_SPC_NVM_INV_PROT	0x81	/* Invalid Protection */
377 #define	NVME_CQE_SC_SPC_NVM_READONLY	0x82	/* Write to Read Only Range */
378 
379 /* NVMe completion status code (data / metadata integrity) */
380 #define	NVME_CQE_SC_INT_NVM_WRITE	0x80	/* Write Fault */
381 #define	NVME_CQE_SC_INT_NVM_READ	0x81	/* Unrecovered Read Error */
382 #define	NVME_CQE_SC_INT_NVM_GUARD	0x82	/* Guard Check Error */
383 #define	NVME_CQE_SC_INT_NVM_APPL_TAG	0x83	/* Application Tag Check Err */
384 #define	NVME_CQE_SC_INT_NVM_REF_TAG	0x84	/* Reference Tag Check Err */
385 #define	NVME_CQE_SC_INT_NVM_COMPARE	0x85	/* Compare Failure */
386 #define	NVME_CQE_SC_INT_NVM_ACCESS	0x86	/* Access Denied */
387 
388 /*
389  * NVMe Asynchronous Event Request
390  */
391 #define	NVME_ASYNC_TYPE_ERROR		0x0	/* Error Status */
392 #define	NVME_ASYNC_TYPE_HEALTH		0x1	/* SMART/Health Status */
393 #define	NVME_ASYNC_TYPE_VENDOR		0x7	/* vendor specific */
394 
395 #define	NVME_ASYNC_ERROR_INV_SQ		0x0	/* Invalid Submission Queue */
396 #define	NVME_ASYNC_ERROR_INV_DBL	0x1	/* Invalid Doorbell Write */
397 #define	NVME_ASYNC_ERROR_DIAGFAIL	0x2	/* Diagnostic Failure */
398 #define	NVME_ASYNC_ERROR_PERSISTENT	0x3	/* Persistent Internal Error */
399 #define	NVME_ASYNC_ERROR_TRANSIENT	0x4	/* Transient Internal Error */
400 #define	NVME_ASYNC_ERROR_FW_LOAD	0x5	/* Firmware Image Load Error */
401 
402 #define	NVME_ASYNC_HEALTH_RELIABILITY	0x0	/* Device Reliability */
403 #define	NVME_ASYNC_HEALTH_TEMPERATURE	0x1	/* Temp. Above Threshold */
404 #define	NVME_ASYNC_HEALTH_SPARE		0x2	/* Spare Below Threshold */
405 
406 typedef union {
407 	struct {
408 		uint8_t ae_type:3;		/* Asynchronous Event Type */
409 		uint8_t ae_rsvd1:5;
410 		uint8_t ae_info;		/* Asynchronous Event Info */
411 		uint8_t ae_logpage;		/* Associated Log Page */
412 		uint8_t ae_rsvd2;
413 	} b;
414 	uint32_t r;
415 } nvme_async_event_t;
416 
417 /*
418  * NVMe Create Completion/Submission Queue
419  */
420 typedef union {
421 	struct {
422 		uint16_t q_qid;			/* Queue Identifier */
423 		uint16_t q_qsize;		/* Queue Size */
424 	} b;
425 	uint32_t r;
426 } nvme_create_queue_dw10_t;
427 
428 typedef union {
429 	struct {
430 		uint16_t cq_pc:1;		/* Physically Contiguous */
431 		uint16_t cq_ien:1;		/* Interrupts Enabled */
432 		uint16_t cq_rsvd:14;
433 		uint16_t cq_iv;			/* Interrupt Vector */
434 	} b;
435 	uint32_t r;
436 } nvme_create_cq_dw11_t;
437 
438 typedef union {
439 	struct {
440 		uint16_t sq_pc:1;		/* Physically Contiguous */
441 		uint16_t sq_qprio:2;		/* Queue Priority */
442 		uint16_t sq_rsvd:13;
443 		uint16_t sq_cqid;		/* Completion Queue ID */
444 	} b;
445 	uint32_t r;
446 } nvme_create_sq_dw11_t;
447 
448 /*
449  * NVMe Identify
450  */
451 
452 /* NVMe Identify parameters (cdw10) */
453 #define	NVME_IDENTIFY_NSID	0x0	/* Identify Namespace */
454 #define	NVME_IDENTIFY_CTRL	0x1	/* Identify Controller */
455 #define	NVME_IDENTIFY_LIST	0x2	/* Identify List Namespaces */
456 
457 #define	NVME_IDENTIFY_NSID_ALLOC_LIST	0x10	/* List Allocated NSID */
458 #define	NVME_IDENTIFY_NSID_ALLOC	0x11	/* Identify Allocated NSID */
459 #define	NVME_IDENTIFY_NSID_CTRL_LIST	0x12	/* List Controllers on NSID */
460 #define	NVME_IDENTIFY_CTRL_LIST		0x13	/* Controller List */
461 #define	NVME_IDENTIFY_PRIMARY_CAPS	0x14	/* Primary Controller Caps */
462 
463 /*
464  * NVMe Abort Command
465  */
466 typedef union {
467 	struct {
468 		uint16_t ac_sqid;	/* Submission Queue ID */
469 		uint16_t ac_cid;	/* Command ID */
470 	} b;
471 	uint32_t r;
472 } nvme_abort_cmd_t;
473 
474 
475 /*
476  * NVMe Get Log Page
477  */
478 typedef union {
479 	struct {
480 		uint8_t lp_lid;		/* Log Page Identifier */
481 		uint8_t lp_rsvd1;
482 		uint16_t lp_numd:12;	/* Number of Dwords */
483 		uint16_t lp_rsvd2:4;
484 	} b;
485 	uint32_t r;
486 } nvme_getlogpage_t;
487 
488 
489 #ifdef __cplusplus
490 }
491 #endif
492 
493 #pragma pack() /* pack(1) */
494 
495 #endif /* _NVME_REG_H */
496