xref: /illumos-gate/usr/src/uts/common/io/nvme/nvme_reg.h (revision 48edc7cf07b5dccc3ad84bf2dafe4150bd666d60)
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  */
15 
16 /*
17  * NVMe hardware interface
18  */
19 
20 #ifndef _NVME_REG_H
21 #define	_NVME_REG_H
22 
23 #pragma pack(1)
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 
30 /*
31  * NVMe constants
32  */
33 #define	NVME_MAX_ADMIN_QUEUE_LEN	4096
34 
35 /*
36  * NVMe version
37  */
38 typedef struct {
39 	uint16_t v_minor;
40 	uint16_t v_major;
41 } nvme_version_t;
42 
43 #define	NVME_VERSION_ATLEAST(v, maj, min) \
44 	(((v)->v_major) > (maj) || \
45 	((v)->v_major == (maj) && (v)->v_minor >= (min)))
46 
47 #define	NVME_VERSION_HIGHER(v, maj, min) \
48 	(((v)->v_major) > (maj) || \
49 	((v)->v_major == (maj) && (v)->v_minor > (min)))
50 
51 /*
52  * NVMe registers and register fields
53  */
54 #define	NVME_REG_CAP	0x0		/* Controller Capabilities */
55 #define	NVME_REG_VS	0x8		/* Version */
56 #define	NVME_REG_INTMS	0xc		/* Interrupt Mask Set */
57 #define	NVME_REG_INTMC	0x10		/* Interrupt Mask Clear */
58 #define	NVME_REG_CC	0x14		/* Controller Configuration */
59 #define	NVME_REG_CSTS	0x1c		/* Controller Status */
60 #define	NVME_REG_NSSR	0x20		/* NVM Subsystem Reset */
61 #define	NVME_REG_AQA	0x24		/* Admin Queue Attributes */
62 #define	NVME_REG_ASQ	0x28		/* Admin Submission Queue */
63 #define	NVME_REG_ACQ	0x30		/* Admin Completion Qeueu */
64 #define	NVME_REG_SQTDBL(nvme, n) \
65 	(0x1000 + ((2 * (n)) * nvme->n_doorbell_stride))
66 #define	NVME_REG_CQHDBL(nvme, n) \
67 	(0x1000 + ((2 * (n) + 1) * nvme->n_doorbell_stride))
68 
69 #define	 NVME_CAP_CSS_NVM	1	/* NVM Command Set */
70 #define	 NVME_CAP_AMS_WRR	1	/* Weighted Round-Robin */
71 
72 /* CAP -- Controller Capabilities */
73 typedef union {
74 	struct {
75 		uint16_t cap_mqes;	/* Maximum Queue Entries Supported */
76 		uint8_t cap_cqr:1;	/* Contiguous Queues Required */
77 		uint8_t cap_ams:2;	/* Arbitration Mechanisms Supported */
78 		uint8_t cap_rsvd1:5;
79 		uint8_t cap_to;		/* Timeout */
80 		uint16_t cap_dstrd:4;	/* Doorbell Stride */
81 		uint16_t cap_nssrs:1;	/* NVM Subsystem Reset Supported */
82 		uint16_t cap_css:8;	/* Command Sets Supported */
83 		uint16_t cap_rsvd2:3;
84 		uint8_t cap_mpsmin:4;	/* Memory Page Size Minimum */
85 		uint8_t cap_mpsmax:4;	/* Memory Page Size Maximum */
86 		uint8_t cap_rsvd3;
87 	} b;
88 	uint64_t r;
89 } nvme_reg_cap_t;
90 
91 /* VS -- Version */
92 typedef union {
93 	struct {
94 		uint8_t vs_rsvd;
95 		uint8_t vs_mnr;		/* Minor Version Number */
96 		uint16_t vs_mjr;	/* Major Version Number */
97 	} b;
98 	uint32_t r;
99 } nvme_reg_vs_t;
100 
101 /* CC -- Controller Configuration */
102 #define	NVME_CC_SHN_NORMAL	1	/* Normal Shutdown Notification */
103 #define	NVME_CC_SHN_ABRUPT	2	/* Abrupt Shutdown Notification */
104 
105 typedef union {
106 	struct {
107 		uint16_t cc_en:1;	/* Enable */
108 		uint16_t cc_rsvd1:3;
109 		uint16_t cc_css:3;	/* I/O Command Set Selected */
110 		uint16_t cc_mps:4;	/* Memory Page Size */
111 		uint16_t cc_ams:3;	/* Arbitration Mechanism Selected */
112 		uint16_t cc_shn:2;	/* Shutdown Notification */
113 		uint8_t cc_iosqes:4;	/* I/O Submission Queue Entry Size */
114 		uint8_t cc_iocqes:4;	/* I/O Completion Queue Entry Size */
115 		uint8_t cc_rsvd2;
116 	} b;
117 	uint32_t r;
118 } nvme_reg_cc_t;
119 
120 /* CSTS -- Controller Status */
121 #define	NVME_CSTS_SHN_OCCURING	1	/* Shutdown Processing Occuring */
122 #define	NVME_CSTS_SHN_COMPLETE	2	/* Shutdown Processing Complete */
123 
124 typedef union {
125 	struct {
126 		uint32_t csts_rdy:1;	/* Ready */
127 		uint32_t csts_cfs:1;	/* Controller Fatal Status */
128 		uint32_t csts_shst:2;	/* Shutdown Status */
129 		uint32_t csts_nssro:1;	/* NVM Subsystem Reset Occured */
130 		uint32_t csts_rsvd:27;
131 	} b;
132 	uint32_t r;
133 } nvme_reg_csts_t;
134 
135 /* NSSR -- NVM Subsystem Reset */
136 #define	NVME_NSSR_NSSRC	0x4e564d65	/* NSSR magic value */
137 typedef uint32_t nvme_reg_nssr_t;
138 
139 /* AQA -- Admin Queue Attributes */
140 typedef union {
141 	struct {
142 		uint16_t aqa_asqs:12;	/* Admin Submission Queue Size */
143 		uint16_t aqa_rsvd1:4;
144 		uint16_t aqa_acqs:12;	/* Admin Completion Queue Size */
145 		uint16_t aqa_rsvd2:4;
146 	} b;
147 	uint32_t r;
148 } nvme_reg_aqa_t;
149 
150 /*
151  * The spec specifies the lower 12 bits of ASQ and ACQ as reserved, which is
152  * probably a specification bug. The full 64bit regs are used as base address,
153  * and the lower bits must be zero to ensure alignment on the page size
154  * specified in CC.MPS.
155  */
156 /* ASQ -- Admin Submission Queue Base Address */
157 typedef uint64_t nvme_reg_asq_t;	/* Admin Submission Queue Base */
158 
159 /* ACQ -- Admin Completion Queue Base Address */
160 typedef uint64_t nvme_reg_acq_t;	/* Admin Completion Queue Base */
161 
162 /* SQyTDBL -- Submission Queue y Tail Doorbell */
163 typedef union {
164 	struct {
165 		uint16_t sqtdbl_sqt;	/* Submission Queue Tail */
166 		uint16_t sqtdbl_rsvd;
167 	} b;
168 	uint32_t r;
169 } nvme_reg_sqtdbl_t;
170 
171 /* CQyHDBL -- Completion Queue y Head Doorbell */
172 typedef union {
173 	struct {
174 		uint16_t cqhdbl_cqh;	/* Completion Queue Head */
175 		uint16_t cqhdbl_rsvd;
176 	} b;
177 	uint32_t r;
178 } nvme_reg_cqhdbl_t;
179 
180 /*
181  * NVMe submission queue entries
182  */
183 
184 /* NVMe scatter/gather list descriptor */
185 typedef struct {
186 	uint64_t sgl_addr;		/* Address */
187 	uint32_t sgl_len;		/* Length */
188 	uint8_t sgl_rsvd[3];
189 	uint8_t sgl_zero:4;
190 	uint8_t sgl_type:4;		/* SGL descriptor type */
191 } nvme_sgl_t;
192 
193 /* NVMe SGL descriptor type */
194 #define	NVME_SGL_DATA_BLOCK	0
195 #define	NVME_SGL_BIT_BUCKET	1
196 #define	NVME_SGL_SEGMENT	2
197 #define	NVME_SGL_LAST_SEGMENT	3
198 #define	NVME_SGL_VENDOR		0xf
199 
200 /* NVMe submission queue entry */
201 typedef struct {
202 	uint8_t sqe_opc;		/* Opcode */
203 	uint8_t sqe_fuse:2;		/* Fused Operation */
204 	uint8_t sqe_rsvd:5;
205 	uint8_t sqe_psdt:1;		/* PRP or SGL for Data Transfer */
206 	uint16_t sqe_cid;		/* Command Identifier */
207 	uint32_t sqe_nsid;		/* Namespace Identifier */
208 	uint64_t sqe_rsvd1;
209 	union {
210 		uint64_t m_ptr;		/* Metadata Pointer */
211 		uint64_t m_sglp;	/* Metadata SGL Segment Pointer */
212 	} sqe_m;
213 	union {
214 		uint64_t d_prp[2];	/* Physical Page Region Entries 1 & 2 */
215 		nvme_sgl_t d_sgl;	/* SGL Entry 1 */
216 	} sqe_dptr;			/* Data Pointer */
217 	uint32_t sqe_cdw10;		/* Number of Dwords in Data Transfer */
218 	uint32_t sqe_cdw11;		/* Number of Dwords in Metadata Xfer */
219 	uint32_t sqe_cdw12;
220 	uint32_t sqe_cdw13;
221 	uint32_t sqe_cdw14;
222 	uint32_t sqe_cdw15;
223 } nvme_sqe_t;
224 
225 /* NVMe admin command opcodes */
226 #define	NVME_OPC_DELETE_SQUEUE	0x0
227 #define	NVME_OPC_CREATE_SQUEUE	0x1
228 #define	NVME_OPC_GET_LOG_PAGE	0x2
229 #define	NVME_OPC_DELETE_CQUEUE	0x4
230 #define	NVME_OPC_CREATE_CQUEUE	0x5
231 #define	NVME_OPC_IDENTIFY	0x6
232 #define	NVME_OPC_ABORT		0x8
233 #define	NVME_OPC_SET_FEATURES	0x9
234 #define	NVME_OPC_GET_FEATURES	0xa
235 #define	NVME_OPC_ASYNC_EVENT	0xc
236 #define	NVME_OPC_FW_ACTIVATE	0x10
237 #define	NVME_OPC_FW_IMAGE_LOAD	0x11
238 
239 /* NVMe NVM command set specific admin command opcodes */
240 #define	NVME_OPC_NVM_FORMAT	0x80
241 #define	NVME_OPC_NVM_SEC_SEND	0x81
242 #define	NVME_OPC_NVM_SEC_RECV	0x82
243 
244 /* NVMe NVM command opcodes */
245 #define	NVME_OPC_NVM_FLUSH	0x0
246 #define	NVME_OPC_NVM_WRITE	0x1
247 #define	NVME_OPC_NVM_READ	0x2
248 #define	NVME_OPC_NVM_WRITE_UNC	0x4
249 #define	NVME_OPC_NVM_COMPARE	0x5
250 #define	NVME_OPC_NVM_WRITE_ZERO	0x8
251 #define	NVME_OPC_NVM_DSET_MGMT	0x9
252 #define	NVME_OPC_NVM_RESV_REG	0xd
253 #define	NVME_OPC_NVM_RESV_REPRT	0xe
254 #define	NVME_OPC_NVM_RESV_ACQ	0x11
255 #define	NVME_OPC_NVM_RESV_REL	0x12
256 
257 /*
258  * NVMe completion queue entry
259  */
260 typedef struct {
261 	uint16_t sf_p:1;		/* Phase Tag */
262 	uint16_t sf_sc:8;		/* Status Code */
263 	uint16_t sf_sct:3;		/* Status Code Type */
264 	uint16_t sf_rsvd2:2;
265 	uint16_t sf_m:1;		/* More */
266 	uint16_t sf_dnr:1;		/* Do Not Retry */
267 } nvme_cqe_sf_t;
268 
269 typedef struct {
270 	uint32_t cqe_dw0;		/* Command Specific */
271 	uint32_t cqe_rsvd1;
272 	uint16_t cqe_sqhd;		/* SQ Head Pointer */
273 	uint16_t cqe_sqid;		/* SQ Identifier */
274 	uint16_t cqe_cid;		/* Command Identifier */
275 	nvme_cqe_sf_t cqe_sf;		/* Status Field */
276 } nvme_cqe_t;
277 
278 /* NVMe completion status code type */
279 #define	NVME_CQE_SCT_GENERIC	0	/* Generic Command Status */
280 #define	NVME_CQE_SCT_SPECIFIC	1	/* Command Specific Status */
281 #define	NVME_CQE_SCT_INTEGRITY	2	/* Media and Data Integrity Errors */
282 #define	NVME_CQE_SCT_VENDOR	7	/* Vendor Specific */
283 
284 /* NVMe completion status code (generic) */
285 #define	NVME_CQE_SC_GEN_SUCCESS		0x0	/* Successful Completion */
286 #define	NVME_CQE_SC_GEN_INV_OPC		0x1	/* Invalid Command Opcode */
287 #define	NVME_CQE_SC_GEN_INV_FLD		0x2	/* Invalid Field in Command */
288 #define	NVME_CQE_SC_GEN_ID_CNFL		0x3	/* Command ID Conflict */
289 #define	NVME_CQE_SC_GEN_DATA_XFR_ERR	0x4	/* Data Transfer Error */
290 #define	NVME_CQE_SC_GEN_ABORT_PWRLOSS	0x5	/* Cmds Aborted / Pwr Loss */
291 #define	NVME_CQE_SC_GEN_INTERNAL_ERR	0x6	/* Internal Error */
292 #define	NVME_CQE_SC_GEN_ABORT_REQUEST	0x7	/* Command Abort Requested */
293 #define	NVME_CQE_SC_GEN_ABORT_SQ_DEL	0x8	/* Cmd Aborted / SQ deletion */
294 #define	NVME_CQE_SC_GEN_ABORT_FUSE_FAIL	0x9	/* Cmd Aborted / Failed Fused */
295 #define	NVME_CQE_SC_GEN_ABORT_FUSE_MISS	0xa	/* Cmd Aborted / Missing Fusd */
296 #define	NVME_CQE_SC_GEN_INV_NS		0xb	/* Inval Namespace or Format */
297 #define	NVME_CQE_SC_GEN_CMD_SEQ_ERR	0xc	/* Command Sequence Error */
298 #define	NVME_CQE_SC_GEN_INV_SGL_LAST	0xd	/* Inval SGL Last Seg Desc */
299 #define	NVME_CQE_SC_GEN_INV_SGL_NUM	0xe	/* Inval Number of SGL Desc */
300 #define	NVME_CQE_SC_GEN_INV_DSGL_LEN	0xf	/* Data SGL Length Invalid */
301 #define	NVME_CQE_SC_GEN_INV_MSGL_LEN	0x10	/* Metadata SGL Length Inval */
302 #define	NVME_CQE_SC_GEN_INV_SGL_DESC	0x11	/* SGL Descriptor Type Inval */
303 
304 /* NVMe completion status code (generic NVM commands) */
305 #define	NVME_CQE_SC_GEN_NVM_LBA_RANGE	0x80	/* LBA Out Of Range */
306 #define	NVME_CQE_SC_GEN_NVM_CAP_EXC	0x81	/* Capacity Exceeded */
307 #define	NVME_CQE_SC_GEN_NVM_NS_NOTRDY	0x82	/* Namespace Not Ready */
308 #define	NVME_CQE_SC_GEN_NVM_RSV_CNFLCT	0x83	/* Reservation Conflict */
309 
310 /* NVMe completion status code (command specific) */
311 #define	NVME_CQE_SC_SPC_INV_CQ		0x0	/* Completion Queue Invalid */
312 #define	NVME_CQE_SC_SPC_INV_QID		0x1	/* Invalid Queue Identifier */
313 #define	NVME_CQE_SC_SPC_MAX_QSZ_EXC	0x2	/* Max Queue Size Exceeded */
314 #define	NVME_CQE_SC_SPC_ABRT_CMD_EXC	0x3	/* Abort Cmd Limit Exceeded */
315 #define	NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC	0x5	/* Async Event Request Limit */
316 #define	NVME_CQE_SC_SPC_INV_FW_SLOT	0x6	/* Invalid Firmware Slot */
317 #define	NVME_CQE_SC_SPC_INV_FW_IMG	0x7	/* Invalid Firmware Image */
318 #define	NVME_CQE_SC_SPC_INV_INT_VECT	0x8	/* Invalid Interrupt Vector */
319 #define	NVME_CQE_SC_SPC_INV_LOG_PAGE	0x9	/* Invalid Log Page */
320 #define	NVME_CQE_SC_SPC_INV_FORMAT	0xa	/* Invalid Format */
321 #define	NVME_CQE_SC_SPC_FW_RESET	0xb	/* FW Application Reset Reqd */
322 #define	NVME_CQE_SC_SPC_INV_Q_DEL	0xc	/* Invalid Queue Deletion */
323 #define	NVME_CQE_SC_SPC_FEAT_SAVE	0xd	/* Feature Id Not Saveable */
324 #define	NVME_CQE_SC_SPC_FEAT_CHG	0xe	/* Feature Not Changeable */
325 #define	NVME_CQE_SC_SPC_FEAT_NS_SPEC	0xf	/* Feature Not Namespace Spec */
326 #define	NVME_CQE_SC_SPC_FW_NSSR		0x10	/* FW Application NSSR Reqd */
327 
328 /* NVMe completion status code (NVM command specific */
329 #define	NVME_CQE_SC_SPC_NVM_CNFL_ATTR	0x80	/* Conflicting Attributes */
330 #define	NVME_CQE_SC_SPC_NVM_INV_PROT	0x81	/* Invalid Protection */
331 #define	NVME_CQE_SC_SPC_NVM_READONLY	0x82	/* Write to Read Only Range */
332 
333 /* NVMe completion status code (data / metadata integrity) */
334 #define	NVME_CQE_SC_INT_NVM_WRITE	0x80	/* Write Fault */
335 #define	NVME_CQE_SC_INT_NVM_READ	0x81	/* Unrecovered Read Error */
336 #define	NVME_CQE_SC_INT_NVM_GUARD	0x82	/* Guard Check Error */
337 #define	NVME_CQE_SC_INT_NVM_APPL_TAG	0x83	/* Application Tag Check Err */
338 #define	NVME_CQE_SC_INT_NVM_REF_TAG	0x84	/* Reference Tag Check Err */
339 #define	NVME_CQE_SC_INT_NVM_COMPARE	0x85	/* Compare Failure */
340 #define	NVME_CQE_SC_INT_NVM_ACCESS	0x86	/* Access Denied */
341 
342 /*
343  * NVMe Asynchronous Event Request
344  */
345 #define	NVME_ASYNC_TYPE_ERROR		0x0	/* Error Status */
346 #define	NVME_ASYNC_TYPE_HEALTH		0x1	/* SMART/Health Status */
347 #define	NVME_ASYNC_TYPE_VENDOR		0x7	/* vendor specific */
348 
349 #define	NVME_ASYNC_ERROR_INV_SQ		0x0	/* Invalid Submission Queue */
350 #define	NVME_ASYNC_ERROR_INV_DBL	0x1	/* Invalid Doorbell Write */
351 #define	NVME_ASYNC_ERROR_DIAGFAIL	0x2	/* Diagnostic Failure */
352 #define	NVME_ASYNC_ERROR_PERSISTENT	0x3	/* Persistent Internal Error */
353 #define	NVME_ASYNC_ERROR_TRANSIENT	0x4	/* Transient Internal Error */
354 #define	NVME_ASYNC_ERROR_FW_LOAD	0x5	/* Firmware Image Load Error */
355 
356 #define	NVME_ASYNC_HEALTH_RELIABILITY	0x0	/* Device Reliability */
357 #define	NVME_ASYNC_HEALTH_TEMPERATURE	0x1	/* Temp. Above Threshold */
358 #define	NVME_ASYNC_HEALTH_SPARE		0x2	/* Spare Below Threshold */
359 
360 typedef union {
361 	struct {
362 		uint8_t ae_type:3;		/* Asynchronous Event Type */
363 		uint8_t ae_rsvd1:5;
364 		uint8_t ae_info;		/* Asynchronous Event Info */
365 		uint8_t ae_logpage;		/* Associated Log Page */
366 		uint8_t ae_rsvd2;
367 	} b;
368 	uint32_t r;
369 } nvme_async_event_t;
370 
371 /*
372  * NVMe Create Completion/Submission Queue
373  */
374 typedef union {
375 	struct {
376 		uint16_t q_qid;			/* Queue Identifier */
377 		uint16_t q_qsize; 		/* Queue Size */
378 	} b;
379 	uint32_t r;
380 } nvme_create_queue_dw10_t;
381 
382 typedef union {
383 	struct {
384 		uint16_t cq_pc:1;		/* Physically Contiguous */
385 		uint16_t cq_ien:1;		/* Interrupts Enabled */
386 		uint16_t cq_rsvd:14;
387 		uint16_t cq_iv;			/* Interrupt Vector */
388 	} b;
389 	uint32_t r;
390 } nvme_create_cq_dw11_t;
391 
392 typedef union {
393 	struct {
394 		uint16_t sq_pc:1;		/* Physically Contiguous */
395 		uint16_t sq_qprio:2;		/* Queue Priority */
396 		uint16_t sq_rsvd:13;
397 		uint16_t sq_cqid;		/* Completion Queue ID */
398 	} b;
399 	uint32_t r;
400 } nvme_create_sq_dw11_t;
401 
402 /*
403  * NVMe Identify
404  */
405 
406 /* NVMe Identify parameters (cdw10) */
407 #define	NVME_IDENTIFY_NSID	0x0	/* Identify Namespace */
408 #define	NVME_IDENTIFY_CTRL	0x1	/* Identify Controller */
409 #define	NVME_IDENTIFY_LIST	0x2	/* Identify List Namespaces */
410 
411 #define	NVME_IDENTIFY_BUFSIZE	4096	/* buffer size for Identify */
412 
413 /* NVMe Queue Entry Size bitfield */
414 typedef struct {
415 	uint8_t qes_min:4;		/* minimum entry size */
416 	uint8_t qes_max:4;		/* maximum entry size */
417 } nvme_idctl_qes_t;
418 
419 /* NVMe Power State Descriptor */
420 typedef struct {
421 	uint16_t psd_mp;		/* Maximum Power */
422 	uint8_t psd_rsvd1;
423 	uint8_t psd_mps:1;		/* Max Power Scale (1.1) */
424 	uint8_t psd_nops:1;		/* Non-Operational State (1.1) */
425 	uint8_t psd_rsvd2:6;
426 	uint32_t psd_enlat;		/* Entry Latency */
427 	uint32_t psd_exlat;		/* Exit Latency */
428 	uint8_t psd_rrt:5;		/* Relative Read Throughput */
429 	uint8_t psd_rsvd3:3;
430 	uint8_t psd_rrl:5;		/* Relative Read Latency */
431 	uint8_t psd_rsvd4:3;
432 	uint8_t psd_rwt:5;		/* Relative Write Throughput */
433 	uint8_t	psd_rsvd5:3;
434 	uint8_t psd_rwl:5;		/* Relative Write Latency */
435 	uint8_t psd_rsvd6:3;
436 	uint8_t psd_rsvd7[16];
437 } nvme_idctl_psd_t;
438 
439 /* NVMe Identify Controller Data Structure */
440 typedef struct {
441 	/* Controller Capabilities & Features */
442 	uint16_t id_vid;		/* PCI vendor ID */
443 	uint16_t id_ssvid; 		/* PCI subsystem vendor ID */
444 	char id_serial[20];		/* Serial Number */
445 	char id_model[40];		/* Model Number */
446 	char id_fwrev[8];		/* Firmware Revision */
447 	uint8_t id_rab;			/* Recommended Arbitration Burst */
448 	uint8_t id_oui[3];		/* vendor IEEE OUI */
449 	struct {			/* Multi-Interface Capabilities */
450 		uint8_t m_multi_pci:1;	/* HW has multiple PCIe interfaces */
451 		uint8_t m_multi_ctrl:1; /* HW has multiple controllers (1.1) */
452 		uint8_t m_sr_iov:1;	/* controller is SR-IOV virt fn (1.1) */
453 		uint8_t m_rsvd:5;
454 	} id_mic;
455 	uint8_t	id_mdts;		/* Maximum Data Transfer Size */
456 	uint16_t id_cntlid;		/* Unique Controller Identifier (1.1) */
457 	uint8_t id_rsvd_cc[256 - 80];
458 
459 	/* Admin Command Set Attributes */
460 	struct {			/* Optional Admin Command Support */
461 		uint16_t oa_security:1;	/* Security Send & Receive */
462 		uint16_t oa_format:1;	/* Format NVM */
463 		uint16_t oa_firmare:1;	/* Firmware Activate & Download */
464 		uint16_t oa_rsvd:13;
465 	} id_oacs;
466 	uint8_t	id_acl;			/* Abort Command Limit */
467 	uint8_t id_aerl;		/* Asynchronous Event Request Limit */
468 	struct {			/* Firmware Updates */
469 		uint8_t fw_readonly:1;	/* Slot 1 is Read-Only */
470 		uint8_t	fw_nslot:3;	/* number of firmware slots */
471 		uint8_t fw_rsvd:4;
472 	} id_frmw;
473 	struct {			/* Log Page Attributes */
474 		uint8_t lp_smart:1;	/* SMART/Health information per NS */
475 		uint8_t lp_rsvd:7;
476 	} id_lpa;
477 	uint8_t id_elpe;		/* Error Log Page Entries */
478 	uint8_t	id_npss;		/* Number of Power States */
479 	struct {			/* Admin Vendor Specific Command Conf */
480 		uint8_t av_spec:1;	/* use format from spec */
481 		uint8_t av_rsvd:7;
482 	} id_avscc;
483 	struct {			/* Autonomous Power State Trans (1.1) */
484 		uint8_t ap_sup:1;	/* APST supported (1.1) */
485 		uint8_t ap_rsvd:7;
486 	} id_apsta;
487 	uint8_t id_rsvd_ac[256 - 10];
488 
489 	/* NVM Command Set Attributes */
490 	nvme_idctl_qes_t id_sqes;	/* Submission Queue Entry Size */
491 	nvme_idctl_qes_t id_cqes;	/* Completion Queue Entry Size */
492 	uint16_t id_rsvd_nc_1;
493 	uint32_t id_nn;			/* Number of Namespaces */
494 	struct {			/* Optional NVM Command Support */
495 		uint16_t on_compare:1;	/* Compare */
496 		uint16_t on_wr_unc:1;	/* Write Uncorrectable */
497 		uint16_t on_dset_mgmt:1; /* Dataset Management */
498 		uint16_t on_wr_zero:1;	/* Write Zeros (1.1) */
499 		uint16_t on_save:1;	/* Save/Select in Get/Set Feat (1.1) */
500 		uint16_t on_reserve:1;	/* Reservations (1.1) */
501 		uint16_t on_rsvd:10;
502 	} id_oncs;
503 	struct {			/* Fused Operation Support */
504 		uint16_t f_cmp_wr:1;	/* Compare and Write */
505 		uint16_t f_rsvd:15;
506 	} id_fuses;
507 	struct {			/* Format NVM Attributes */
508 		uint8_t fn_format:1;	/* Format applies to all NS */
509 		uint8_t fn_sec_erase:1;	/* Secure Erase applies to all NS */
510 		uint8_t fn_crypt_erase:1; /* Cryptographic Erase supported */
511 		uint8_t fn_rsvd:5;
512 	} id_fna;
513 	struct {			/* Volatile Write Cache */
514 		uint8_t vwc_present:1;	/* Volatile Write Cache present */
515 		uint8_t rsvd:7;
516 	} id_vwc;
517 	uint16_t id_awun;		/* Atomic Write Unit Normal */
518 	uint16_t id_awupf;		/* Atomic Write Unit Power Fail */
519 	struct {			/* NVM Vendor Specific Command Conf */
520 		uint8_t nv_spec:1;	/* use format from spec */
521 		uint8_t nv_rsvd:7;
522 	} id_nvscc;
523 	uint8_t id_rsvd_nc_2;
524 	uint16_t id_acwu;		/* Atomic Compare & Write Unit (1.1) */
525 	uint16_t id_rsvd_nc_3;
526 	struct {			/* SGL Support (1.1) */
527 		uint16_t sgl_sup:1;	/* SGL Supported in NVM cmds (1.1) */
528 		uint16_t sgl_rsvd1:15;
529 		uint16_t sgl_bucket:1;	/* SGL Bit Bucket supported (1.1) */
530 		uint16_t sgl_rsvd2:15;
531 	} id_sgls;
532 	uint8_t id_rsvd_nc_4[192 - 28];
533 
534 	/* I/O Command Set Attributes */
535 	uint8_t id_rsvd_ioc[1344];
536 
537 	/* Power State Descriptors */
538 	nvme_idctl_psd_t id_psd[32];
539 
540 	/* Vendor Specific */
541 	uint8_t id_vs[1024];
542 } nvme_identify_ctrl_t;
543 
544 /* NVMe Identify Namespace LBA Format */
545 typedef struct {
546 	uint16_t lbaf_ms;		/* Metadata Size */
547 	uint8_t lbaf_lbads;		/* LBA Data Size */
548 	uint8_t lbaf_rp:2;		/* Relative Performance */
549 	uint8_t lbaf_rsvd1:6;
550 } nvme_idns_lbaf_t;
551 
552 /* NVMe Identify Namespace Data Structure */
553 typedef struct {
554 	uint64_t id_nsize;		/* Namespace Size */
555 	uint64_t id_ncap;		/* Namespace Capacity */
556 	uint64_t id_nuse;		/* Namespace Utilization */
557 	struct {			/* Namespace Features */
558 		uint8_t f_thin:1;	/* Thin Provisioning */
559 		uint8_t f_rsvd:7;
560 	} id_nsfeat;
561 	uint8_t id_nlbaf;		/* Number of LBA formats */
562 	struct {			/* Formatted LBA size */
563 		uint8_t lba_format:4;	/* LBA format */
564 		uint8_t lba_extlba:1;	/* extended LBA (includes metadata) */
565 		uint8_t lba_rsvd:3;
566 	} id_flbas;
567 	struct {			/* Metadata Capabilities */
568 		uint8_t mc_extlba:1;	/* extended LBA transfers */
569 		uint8_t mc_separate:1;	/* separate metadata transfers */
570 		uint8_t mc_rsvd:6;
571 	} id_mc;
572 	struct {			/* Data Protection Capabilities */
573 		uint8_t dp_type1:1;	/* Protection Information Type 1 */
574 		uint8_t dp_type2:1;	/* Protection Information Type 2 */
575 		uint8_t dp_type3:1;	/* Protection Information Type 3 */
576 		uint8_t dp_first:1;	/* first 8 bytes of metadata */
577 		uint8_t dp_last:1;	/* last 8 bytes of metadata */
578 		uint8_t dp_rsvd:3;
579 	} id_dpc;
580 	struct {			/* Data Protection Settings */
581 		uint8_t dp_pinfo:3;	/* Protection Information enabled */
582 		uint8_t dp_first:1;	/* first 8 bytes of metadata */
583 		uint8_t dp_rsvd:4;
584 	} id_dps;
585 	struct {			/* NS Multi-Path/Sharing Cap (1.1) */
586 		uint8_t nm_shared:1;	/* NS is shared (1.1) */
587 		uint8_t nm_rsvd:7;
588 	} id_nmic;
589 	struct {			/* Reservation Capabilities (1.1) */
590 		uint8_t rc_persist:1;	/* Persist Through Power Loss (1.1) */
591 		uint8_t rc_wr_excl:1;	/* Write Exclusive (1.1) */
592 		uint8_t rc_excl:1;	/* Exclusive Access (1.1) */
593 		uint8_t rc_wr_excl_r:1;	/* Wr Excl - Registrants Only (1.1) */
594 		uint8_t rc_excl_r:1;	/* Excl Acc - Registrants Only (1.1) */
595 		uint8_t rc_wr_excl_a:1;	/* Wr Excl - All Registrants (1.1) */
596 		uint8_t rc_excl_a:1;	/* Excl Acc - All Registrants (1.1) */
597 		uint8_t rc_rsvd:1;
598 	} id_rescap;
599 	uint8_t id_rsvd1[120 - 32];
600 	uint8_t id_eui64[8];		/* IEEE Extended Unique Id (1.1) */
601 	nvme_idns_lbaf_t id_lbaf[16];	/* LBA Formats */
602 
603 	uint8_t id_rsvd2[192];
604 
605 	uint8_t id_vs[3712];		/* Vendor Specific */
606 } nvme_identify_nsid_t;
607 
608 
609 /*
610  * NVMe Abort Command
611  */
612 typedef union {
613 	struct {
614 		uint16_t ac_sqid;	/* Submission Queue ID */
615 		uint16_t ac_cid;	/* Command ID */
616 	} b;
617 	uint32_t r;
618 } nvme_abort_cmd_t;
619 
620 
621 /*
622  * NVMe Get / Set Features
623  */
624 #define	NVME_FEAT_ARBITRATION	0x1	/* Command Arbitration */
625 #define	NVME_FEAT_POWER_MGMT	0x2	/* Power Management */
626 #define	NVME_FEAT_LBA_RANGE	0x3	/* LBA Range Type */
627 #define	NVME_FEAT_TEMPERATURE	0x4	/* Temperature Threshold */
628 #define	NVME_FEAT_ERROR		0x5	/* Error Recovery */
629 #define	NVME_FEAT_WRITE_CACHE	0x6	/* Volatile Write Cache */
630 #define	NVME_FEAT_NQUEUES	0x7	/* Number of Queues */
631 #define	NVME_FEAT_INTR_COAL	0x8	/* Interrupt Coalescing */
632 #define	NVME_FEAT_INTR_VECT	0x9	/* Interrupt Vector Configuration */
633 #define	NVME_FEAT_WRITE_ATOM	0xa	/* Write Atomicity */
634 #define	NVME_FEAT_ASYNC_EVENT	0xb	/* Asynchronous Event Configuration */
635 #define	NVME_FEAT_AUTO_PST	0xc	/* Autonomous Power State Transition */
636 					/* (1.1) */
637 
638 #define	NVME_FEAT_PROGRESS	0x80	/* Software Progress Marker */
639 
640 /* Arbitration Feature */
641 typedef struct {
642 	uint8_t arb_ab:3;		/* Arbitration Burst */
643 	uint8_t arb_rsvd:5;
644 	uint8_t arb_lpw;		/* Low Priority Weight */
645 	uint8_t arb_mpw;		/* Medium Priority Weight */
646 	uint8_t arb_hpw;		/* High Priority Weight */
647 } nvme_arbitration_dw11_t;
648 
649 /* LBA Range Type Feature */
650 typedef struct {
651 	uint32_t lr_num:6;		/* Number of LBA ranges */
652 	uint32_t lr_rsvd:26;
653 } nvme_lba_range_type_dw11_t;
654 
655 typedef struct {
656 	uint8_t lr_type;		/* Type */
657 	struct {			/* Attributes */
658 		uint8_t lr_write:1;	/* may be overwritten */
659 		uint8_t lr_hidden:1;	/* hidden from OS/EFI/BIOS */
660 		uint8_t lr_rsvd1:6;
661 	} lr_attr;
662 	uint8_t lr_rsvd2[14];
663 	uint64_t lr_slba;		/* Starting LBA */
664 	uint64_t lr_nlb;		/* Number of Logical Blocks */
665 	uint8_t lr_guid[16];		/* Unique Identifier */
666 	uint8_t lr_rsvd3[16];
667 } nvme_lba_range_type_t;
668 
669 /* Volatile Write Cache Feature */
670 typedef union {
671 	struct {
672 		uint32_t wc_wce:1;	/* Volatile Write Cache Enable */
673 		uint32_t wc_rsvd:31;
674 	} b;
675 	uint32_t r;
676 } nvme_write_cache_t;
677 
678 /* Number of Queues */
679 typedef union {
680 	struct {
681 		uint16_t nq_nsq;	/* Number of Submission Queues */
682 		uint16_t nq_ncq;	/* Number of Completion Queues */
683 	} b;
684 	uint32_t r;
685 } nvme_nqueue_t;
686 
687 
688 /*
689  * NVMe Get Log Page
690  */
691 #define	NVME_LOGPAGE_ERROR	0x1	/* Error Information */
692 #define	NVME_LOGPAGE_HEALTH	0x2	/* SMART/Health Information */
693 #define	NVME_LOGPAGE_FWSLOT	0x3	/* Firmware Slot Information */
694 
695 typedef union {
696 	struct {
697 		uint8_t lp_lid;		/* Log Page Identifier */
698 		uint8_t lp_rsvd1;
699 		uint16_t lp_numd:12;	/* Number of Dwords */
700 		uint16_t lp_rsvd2:4;
701 	} b;
702 	uint32_t r;
703 } nvme_getlogpage_t;
704 
705 typedef struct {
706 	uint64_t el_count;		/* Error Count */
707 	uint16_t el_sqid;		/* Submission Queue ID */
708 	uint16_t el_cid;		/* Command ID */
709 	nvme_cqe_sf_t el_sf;		/* Status Field */
710 	uint8_t	el_byte;		/* Parameter Error Location byte */
711 	uint8_t	el_bit:3;		/* Parameter Error Location bit */
712 	uint8_t el_rsvd1:5;
713 	uint64_t el_lba;		/* Logical Block Address */
714 	uint32_t el_nsid;		/* Namespace ID */
715 	uint8_t	el_vendor;		/* Vendor Specific Information avail */
716 	uint8_t el_rsvd2[64 - 29];
717 } nvme_error_log_entry_t;
718 
719 typedef struct {
720 	uint64_t lo;
721 	uint64_t hi;
722 } nvme_uint128_t;
723 
724 typedef struct {
725 	uint8_t hl_crit_warn;		/* Critical Warning */
726 	uint16_t hl_temp;		/* Temperature */
727 	uint8_t hl_avail_spare;		/* Available Spare */
728 	uint8_t hl_avail_spare_thr;	/* Available Spare Threshold */
729 	uint8_t hl_used;		/* Percentage Used */
730 	uint8_t hl_rsvd1[32 - 6];
731 	nvme_uint128_t hl_data_read;	/* Data Units Read */
732 	nvme_uint128_t hl_data_write;	/* Data Units Written */
733 	nvme_uint128_t hl_host_read;	/* Host Read Commands */
734 	nvme_uint128_t hl_host_write;	/* Host Write Commands */
735 	nvme_uint128_t hl_ctrl_busy;	/* Controller Busy Time */
736 	nvme_uint128_t hl_power_cycles;	/* Power Cycles */
737 	nvme_uint128_t hl_power_on_hours; /* Power On Hours */
738 	nvme_uint128_t hl_unsafe_shutdn; /* Unsafe Shutdowns */
739 	nvme_uint128_t hl_media_errors;	/* Media Errors */
740 	nvme_uint128_t hl_errors_logged; /* Number of errors logged */
741 	uint8_t hl_rsvd2[512 - 192];
742 } nvme_health_log_t;
743 
744 typedef struct {
745 	uint8_t fw_afi:3;		/* Active Firmware Slot */
746 	uint8_t fw_rsvd1:5;
747 	uint8_t fw_rsvd2[7];
748 	char fw_frs[7][8];		/* Firmware Revision / Slot */
749 	uint8_t fw_rsvd3[512 - 64];
750 } nvme_fwslot_log_t;
751 
752 #ifdef __cplusplus
753 }
754 #endif
755 
756 #pragma pack() /* pack(1) */
757 
758 #endif /* _NVME_REG_H */
759