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