xref: /titanic_50/usr/src/uts/common/sys/nvme.h (revision 1188b15922ed58bf45acc792330e9649bd3166cf)
1ecee5a1fSHans Rosenfeld /*
2ecee5a1fSHans Rosenfeld  * This file and its contents are supplied under the terms of the
3ecee5a1fSHans Rosenfeld  * Common Development and Distribution License ("CDDL"), version 1.0.
4ecee5a1fSHans Rosenfeld  * You may only use this file in accordance with the terms of version
5ecee5a1fSHans Rosenfeld  * 1.0 of the CDDL.
6ecee5a1fSHans Rosenfeld  *
7ecee5a1fSHans Rosenfeld  * A full copy of the text of the CDDL should have accompanied this
8ecee5a1fSHans Rosenfeld  * source.  A copy of the CDDL is also available via the Internet at
9ecee5a1fSHans Rosenfeld  * http://www.illumos.org/license/CDDL.
10ecee5a1fSHans Rosenfeld  */
11ecee5a1fSHans Rosenfeld 
12ecee5a1fSHans Rosenfeld /*
13ecee5a1fSHans Rosenfeld  * Copyright 2016 Nexenta Systems, Inc.
14*1188b159SRobert Mustacchi  * Copyright (c) 2018, Joyent, Inc.
15ecee5a1fSHans Rosenfeld  */
16ecee5a1fSHans Rosenfeld 
17ecee5a1fSHans Rosenfeld #ifndef _SYS_NVME_H
18ecee5a1fSHans Rosenfeld #define	_SYS_NVME_H
19ecee5a1fSHans Rosenfeld 
20ecee5a1fSHans Rosenfeld #include <sys/types.h>
21ecee5a1fSHans Rosenfeld 
22ecee5a1fSHans Rosenfeld #ifdef _KERNEL
23ecee5a1fSHans Rosenfeld #include <sys/types32.h>
24ecee5a1fSHans Rosenfeld #else
25ecee5a1fSHans Rosenfeld #include <stdint.h>
26ecee5a1fSHans Rosenfeld #endif
27ecee5a1fSHans Rosenfeld 
28ecee5a1fSHans Rosenfeld /*
29ecee5a1fSHans Rosenfeld  * Declarations used for communication between nvmeadm(1M) and nvme(7D)
30ecee5a1fSHans Rosenfeld  */
31ecee5a1fSHans Rosenfeld 
32ecee5a1fSHans Rosenfeld #ifdef __cplusplus
33ecee5a1fSHans Rosenfeld extern "C" {
34ecee5a1fSHans Rosenfeld #endif
35ecee5a1fSHans Rosenfeld 
36ecee5a1fSHans Rosenfeld /*
37ecee5a1fSHans Rosenfeld  * NVMe ioctl definitions
38ecee5a1fSHans Rosenfeld  */
39ecee5a1fSHans Rosenfeld 
40ecee5a1fSHans Rosenfeld #define	NVME_IOC			(('N' << 24) | ('V' << 16) | ('M' << 8))
41ecee5a1fSHans Rosenfeld #define	NVME_IOC_IDENTIFY_CTRL		(NVME_IOC | 1)
42ecee5a1fSHans Rosenfeld #define	NVME_IOC_IDENTIFY_NSID		(NVME_IOC | 2)
43ecee5a1fSHans Rosenfeld #define	NVME_IOC_CAPABILITIES		(NVME_IOC | 3)
44ecee5a1fSHans Rosenfeld #define	NVME_IOC_GET_LOGPAGE		(NVME_IOC | 4)
45ecee5a1fSHans Rosenfeld #define	NVME_IOC_GET_FEATURES		(NVME_IOC | 5)
46ecee5a1fSHans Rosenfeld #define	NVME_IOC_INTR_CNT		(NVME_IOC | 6)
47ecee5a1fSHans Rosenfeld #define	NVME_IOC_VERSION		(NVME_IOC | 7)
48ecee5a1fSHans Rosenfeld #define	NVME_IOC_FORMAT			(NVME_IOC | 8)
49ecee5a1fSHans Rosenfeld #define	NVME_IOC_DETACH			(NVME_IOC | 9)
50ecee5a1fSHans Rosenfeld #define	NVME_IOC_ATTACH			(NVME_IOC | 10)
51ecee5a1fSHans Rosenfeld #define	NVME_IOC_MAX			NVME_IOC_ATTACH
52ecee5a1fSHans Rosenfeld 
53ecee5a1fSHans Rosenfeld #define	IS_NVME_IOC(x)			((x) > NVME_IOC && (x) <= NVME_IOC_MAX)
54ecee5a1fSHans Rosenfeld #define	NVME_IOC_CMD(x)			((x) & 0xff)
55ecee5a1fSHans Rosenfeld 
56ecee5a1fSHans Rosenfeld typedef struct {
57ecee5a1fSHans Rosenfeld 	size_t		n_len;
58ecee5a1fSHans Rosenfeld 	uintptr_t	n_buf;
59ecee5a1fSHans Rosenfeld 	uint64_t	n_arg;
60ecee5a1fSHans Rosenfeld } nvme_ioctl_t;
61ecee5a1fSHans Rosenfeld 
62ecee5a1fSHans Rosenfeld #ifdef _KERNEL
63ecee5a1fSHans Rosenfeld typedef struct {
64ecee5a1fSHans Rosenfeld 	size32_t	n_len;
65ecee5a1fSHans Rosenfeld 	uintptr32_t	n_buf;
66ecee5a1fSHans Rosenfeld 	uint64_t	n_arg;
67ecee5a1fSHans Rosenfeld } nvme_ioctl32_t;
68ecee5a1fSHans Rosenfeld #endif
69ecee5a1fSHans Rosenfeld 
70ecee5a1fSHans Rosenfeld /*
71ecee5a1fSHans Rosenfeld  * NVMe capabilities
72ecee5a1fSHans Rosenfeld  */
73ecee5a1fSHans Rosenfeld typedef struct {
74ecee5a1fSHans Rosenfeld 	uint32_t mpsmax;		/* Memory Page Size Maximum */
75ecee5a1fSHans Rosenfeld 	uint32_t mpsmin;		/* Memory Page Size Minimum */
76ecee5a1fSHans Rosenfeld } nvme_capabilities_t;
77ecee5a1fSHans Rosenfeld 
78ecee5a1fSHans Rosenfeld /*
79ecee5a1fSHans Rosenfeld  * NVMe version
80ecee5a1fSHans Rosenfeld  */
81ecee5a1fSHans Rosenfeld typedef struct {
82ecee5a1fSHans Rosenfeld 	uint16_t v_minor;
83ecee5a1fSHans Rosenfeld 	uint16_t v_major;
84ecee5a1fSHans Rosenfeld } nvme_version_t;
85ecee5a1fSHans Rosenfeld 
86ecee5a1fSHans Rosenfeld #define	NVME_VERSION_ATLEAST(v, maj, min) \
87ecee5a1fSHans Rosenfeld 	(((v)->v_major) > (maj) || \
88ecee5a1fSHans Rosenfeld 	((v)->v_major == (maj) && (v)->v_minor >= (min)))
89ecee5a1fSHans Rosenfeld 
90ecee5a1fSHans Rosenfeld #define	NVME_VERSION_HIGHER(v, maj, min) \
91ecee5a1fSHans Rosenfeld 	(((v)->v_major) > (maj) || \
92ecee5a1fSHans Rosenfeld 	((v)->v_major == (maj) && (v)->v_minor > (min)))
93ecee5a1fSHans Rosenfeld 
94ecee5a1fSHans Rosenfeld 
95ecee5a1fSHans Rosenfeld #pragma pack(1)
96ecee5a1fSHans Rosenfeld 
97ecee5a1fSHans Rosenfeld /*
98ecee5a1fSHans Rosenfeld  * NVMe Identify data structures
99ecee5a1fSHans Rosenfeld  */
100ecee5a1fSHans Rosenfeld 
101ecee5a1fSHans Rosenfeld #define	NVME_IDENTIFY_BUFSIZE	4096	/* buffer size for Identify */
102ecee5a1fSHans Rosenfeld 
103ecee5a1fSHans Rosenfeld /* NVMe Queue Entry Size bitfield */
104ecee5a1fSHans Rosenfeld typedef struct {
105ecee5a1fSHans Rosenfeld 	uint8_t qes_min:4;		/* minimum entry size */
106ecee5a1fSHans Rosenfeld 	uint8_t qes_max:4;		/* maximum entry size */
107ecee5a1fSHans Rosenfeld } nvme_idctl_qes_t;
108ecee5a1fSHans Rosenfeld 
109ecee5a1fSHans Rosenfeld /* NVMe Power State Descriptor */
110ecee5a1fSHans Rosenfeld typedef struct {
111ecee5a1fSHans Rosenfeld 	uint16_t psd_mp;		/* Maximum Power */
112ecee5a1fSHans Rosenfeld 	uint8_t psd_rsvd1;
113ecee5a1fSHans Rosenfeld 	uint8_t psd_mps:1;		/* Max Power Scale (1.1) */
114ecee5a1fSHans Rosenfeld 	uint8_t psd_nops:1;		/* Non-Operational State (1.1) */
115ecee5a1fSHans Rosenfeld 	uint8_t psd_rsvd2:6;
116ecee5a1fSHans Rosenfeld 	uint32_t psd_enlat;		/* Entry Latency */
117ecee5a1fSHans Rosenfeld 	uint32_t psd_exlat;		/* Exit Latency */
118ecee5a1fSHans Rosenfeld 	uint8_t psd_rrt:5;		/* Relative Read Throughput */
119ecee5a1fSHans Rosenfeld 	uint8_t psd_rsvd3:3;
120ecee5a1fSHans Rosenfeld 	uint8_t psd_rrl:5;		/* Relative Read Latency */
121ecee5a1fSHans Rosenfeld 	uint8_t psd_rsvd4:3;
122ecee5a1fSHans Rosenfeld 	uint8_t psd_rwt:5;		/* Relative Write Throughput */
123ecee5a1fSHans Rosenfeld 	uint8_t	psd_rsvd5:3;
124ecee5a1fSHans Rosenfeld 	uint8_t psd_rwl:5;		/* Relative Write Latency */
125ecee5a1fSHans Rosenfeld 	uint8_t psd_rsvd6:3;
126*1188b159SRobert Mustacchi 	uint16_t psd_idlp;		/* Idle Power (1.2) */
127*1188b159SRobert Mustacchi 	uint8_t psd_rsvd7:6;
128*1188b159SRobert Mustacchi 	uint8_t psd_ips:2;		/* Idle Power Scale (1.2) */
129*1188b159SRobert Mustacchi 	uint8_t psd_rsvd8;
130*1188b159SRobert Mustacchi 	uint16_t psd_actp;		/* Active Power (1.2) */
131*1188b159SRobert Mustacchi 	uint8_t psd_apw:3;		/* Active Power Workload (1.2) */
132*1188b159SRobert Mustacchi 	uint8_t psd_rsvd9:3;
133*1188b159SRobert Mustacchi 	uint8_t psd_aps:2;		/* Active Power Scale */
134*1188b159SRobert Mustacchi 	uint8_t psd_rsvd10[9];
135ecee5a1fSHans Rosenfeld } nvme_idctl_psd_t;
136ecee5a1fSHans Rosenfeld 
137ecee5a1fSHans Rosenfeld /* NVMe Identify Controller Data Structure */
138ecee5a1fSHans Rosenfeld typedef struct {
139ecee5a1fSHans Rosenfeld 	/* Controller Capabilities & Features */
140ecee5a1fSHans Rosenfeld 	uint16_t id_vid;		/* PCI vendor ID */
141ecee5a1fSHans Rosenfeld 	uint16_t id_ssvid;		/* PCI subsystem vendor ID */
142ecee5a1fSHans Rosenfeld 	char id_serial[20];		/* Serial Number */
143ecee5a1fSHans Rosenfeld 	char id_model[40];		/* Model Number */
144ecee5a1fSHans Rosenfeld 	char id_fwrev[8];		/* Firmware Revision */
145ecee5a1fSHans Rosenfeld 	uint8_t id_rab;			/* Recommended Arbitration Burst */
146ecee5a1fSHans Rosenfeld 	uint8_t id_oui[3];		/* vendor IEEE OUI */
147ecee5a1fSHans Rosenfeld 	struct {			/* Multi-Interface Capabilities */
148ecee5a1fSHans Rosenfeld 		uint8_t m_multi_pci:1;	/* HW has multiple PCIe interfaces */
149ecee5a1fSHans Rosenfeld 		uint8_t m_multi_ctrl:1; /* HW has multiple controllers (1.1) */
150ecee5a1fSHans Rosenfeld 		uint8_t m_sr_iov:1;	/* controller is SR-IOV virt fn (1.1) */
151ecee5a1fSHans Rosenfeld 		uint8_t m_rsvd:5;
152ecee5a1fSHans Rosenfeld 	} id_mic;
153ecee5a1fSHans Rosenfeld 	uint8_t	id_mdts;		/* Maximum Data Transfer Size */
154ecee5a1fSHans Rosenfeld 	uint16_t id_cntlid;		/* Unique Controller Identifier (1.1) */
155*1188b159SRobert Mustacchi 	/* Added in NVMe 1.2 */
156*1188b159SRobert Mustacchi 	uint32_t id_ver;		/* Version */
157*1188b159SRobert Mustacchi 	uint32_t id_rtd3r;		/* RTD3 Resume Latency */
158*1188b159SRobert Mustacchi 	uint32_t id_rtd3e;		/* RTD3 Entry Latency */
159*1188b159SRobert Mustacchi 	uint32_t id_oaes;		/* Optional Asynchronous Events */
160*1188b159SRobert Mustacchi 	/* Added in NVMe 1.3 */
161*1188b159SRobert Mustacchi 	uint32_t id_ctratt;		/* Controller Attributes */
162*1188b159SRobert Mustacchi 	uint8_t id_rsvd_cc[12];
163*1188b159SRobert Mustacchi 	uint8_t id_frguid[16];		/* FRU GUID */
164*1188b159SRobert Mustacchi 	uint8_t id_rsvd2_cc[240 - 128];
165*1188b159SRobert Mustacchi 	uint8_t id_rsvd_nvmemi[255 - 240];
166*1188b159SRobert Mustacchi 	uint8_t id_mec;			/* Management Endpiont Capabilities */
167ecee5a1fSHans Rosenfeld 
168ecee5a1fSHans Rosenfeld 	/* Admin Command Set Attributes */
169ecee5a1fSHans Rosenfeld 	struct {			/* Optional Admin Command Support */
170ecee5a1fSHans Rosenfeld 		uint16_t oa_security:1;	/* Security Send & Receive */
171ecee5a1fSHans Rosenfeld 		uint16_t oa_format:1;	/* Format NVM */
172ecee5a1fSHans Rosenfeld 		uint16_t oa_firmware:1;	/* Firmware Activate & Download */
173ecee5a1fSHans Rosenfeld 		uint16_t oa_rsvd:13;
174ecee5a1fSHans Rosenfeld 	} id_oacs;
175ecee5a1fSHans Rosenfeld 	uint8_t	id_acl;			/* Abort Command Limit */
176ecee5a1fSHans Rosenfeld 	uint8_t id_aerl;		/* Asynchronous Event Request Limit */
177ecee5a1fSHans Rosenfeld 	struct {			/* Firmware Updates */
178ecee5a1fSHans Rosenfeld 		uint8_t fw_readonly:1;	/* Slot 1 is Read-Only */
179ecee5a1fSHans Rosenfeld 		uint8_t	fw_nslot:3;	/* number of firmware slots */
180ecee5a1fSHans Rosenfeld 		uint8_t fw_rsvd:4;
181ecee5a1fSHans Rosenfeld 	} id_frmw;
182ecee5a1fSHans Rosenfeld 	struct {			/* Log Page Attributes */
183ecee5a1fSHans Rosenfeld 		uint8_t lp_smart:1;	/* SMART/Health information per NS */
184ecee5a1fSHans Rosenfeld 		uint8_t lp_rsvd:7;
185ecee5a1fSHans Rosenfeld 	} id_lpa;
186ecee5a1fSHans Rosenfeld 	uint8_t id_elpe;		/* Error Log Page Entries */
187ecee5a1fSHans Rosenfeld 	uint8_t	id_npss;		/* Number of Power States */
188ecee5a1fSHans Rosenfeld 	struct {			/* Admin Vendor Specific Command Conf */
189ecee5a1fSHans Rosenfeld 		uint8_t av_spec:1;	/* use format from spec */
190ecee5a1fSHans Rosenfeld 		uint8_t av_rsvd:7;
191ecee5a1fSHans Rosenfeld 	} id_avscc;
192ecee5a1fSHans Rosenfeld 	struct {			/* Autonomous Power State Trans (1.1) */
193ecee5a1fSHans Rosenfeld 		uint8_t ap_sup:1;	/* APST supported (1.1) */
194ecee5a1fSHans Rosenfeld 		uint8_t ap_rsvd:7;
195ecee5a1fSHans Rosenfeld 	} id_apsta;
196*1188b159SRobert Mustacchi 	/* Added in NVMe 1.2 */
197*1188b159SRobert Mustacchi 	uint16_t ap_wctemp;		/* Warning Composite Temperature */
198*1188b159SRobert Mustacchi 	uint16_t ap_cctemp;		/* Critical Composite Temperature */
199*1188b159SRobert Mustacchi 	uint16_t ap_mtfa;		/* Maximum Firmware Activation Time */
200*1188b159SRobert Mustacchi 	uint32_t ap_hmpre;		/* Host Memory Buffer Preferred Size */
201*1188b159SRobert Mustacchi 	uint32_t ap_hmmin;		/* Host Memory Buffer Min Size */
202*1188b159SRobert Mustacchi 	uint8_t ap_tnvmcap[16];		/* Total NVM Capacity in Bytes */
203*1188b159SRobert Mustacchi 	uint8_t ap_unvmcap[16];		/* Unallocated NVM Capacity */
204*1188b159SRobert Mustacchi 	uint32_t ap_rpmbs;		/* Replay Protected Memory Block */
205*1188b159SRobert Mustacchi 	/* Added in NVMe 1.3 */
206*1188b159SRobert Mustacchi 	uint16_t ap_edstt;		/* Extended Device Self-test time */
207*1188b159SRobert Mustacchi 	uint8_t ap_dsto;		/* Device Self-test Options */
208*1188b159SRobert Mustacchi 	uint8_t ap_fwug;		/* Firmware Update Granularity */
209*1188b159SRobert Mustacchi 	uint16_t ap_kas;		/* Keep Alive Support */
210*1188b159SRobert Mustacchi 	uint16_t ap_hctma;		/* Host Thermal Management */
211*1188b159SRobert Mustacchi 	uint16_t ap_mntmt;		/* Minimum Thermal Temperature */
212*1188b159SRobert Mustacchi 	uint16_t ap_mxtmt;		/* Maximum Thermal Temperature */
213*1188b159SRobert Mustacchi 	uint32_t ap_sanitize;		/* Sanitize Caps */
214*1188b159SRobert Mustacchi 	uint8_t id_rsvd_ac[512 - 332];
215ecee5a1fSHans Rosenfeld 
216ecee5a1fSHans Rosenfeld 	/* NVM Command Set Attributes */
217ecee5a1fSHans Rosenfeld 	nvme_idctl_qes_t id_sqes;	/* Submission Queue Entry Size */
218ecee5a1fSHans Rosenfeld 	nvme_idctl_qes_t id_cqes;	/* Completion Queue Entry Size */
219*1188b159SRobert Mustacchi 	uint16_t id_maxcmd;		/* Max Outstanding Commands (1.3) */
220ecee5a1fSHans Rosenfeld 	uint32_t id_nn;			/* Number of Namespaces */
221ecee5a1fSHans Rosenfeld 	struct {			/* Optional NVM Command Support */
222ecee5a1fSHans Rosenfeld 		uint16_t on_compare:1;	/* Compare */
223ecee5a1fSHans Rosenfeld 		uint16_t on_wr_unc:1;	/* Write Uncorrectable */
224ecee5a1fSHans Rosenfeld 		uint16_t on_dset_mgmt:1; /* Dataset Management */
225ecee5a1fSHans Rosenfeld 		uint16_t on_wr_zero:1;	/* Write Zeros (1.1) */
226ecee5a1fSHans Rosenfeld 		uint16_t on_save:1;	/* Save/Select in Get/Set Feat (1.1) */
227ecee5a1fSHans Rosenfeld 		uint16_t on_reserve:1;	/* Reservations (1.1) */
228ecee5a1fSHans Rosenfeld 		uint16_t on_rsvd:10;
229ecee5a1fSHans Rosenfeld 	} id_oncs;
230ecee5a1fSHans Rosenfeld 	struct {			/* Fused Operation Support */
231ecee5a1fSHans Rosenfeld 		uint16_t f_cmp_wr:1;	/* Compare and Write */
232ecee5a1fSHans Rosenfeld 		uint16_t f_rsvd:15;
233ecee5a1fSHans Rosenfeld 	} id_fuses;
234ecee5a1fSHans Rosenfeld 	struct {			/* Format NVM Attributes */
235ecee5a1fSHans Rosenfeld 		uint8_t fn_format:1;	/* Format applies to all NS */
236ecee5a1fSHans Rosenfeld 		uint8_t fn_sec_erase:1;	/* Secure Erase applies to all NS */
237ecee5a1fSHans Rosenfeld 		uint8_t fn_crypt_erase:1; /* Cryptographic Erase supported */
238ecee5a1fSHans Rosenfeld 		uint8_t fn_rsvd:5;
239ecee5a1fSHans Rosenfeld 	} id_fna;
240ecee5a1fSHans Rosenfeld 	struct {			/* Volatile Write Cache */
241ecee5a1fSHans Rosenfeld 		uint8_t vwc_present:1;	/* Volatile Write Cache present */
242ecee5a1fSHans Rosenfeld 		uint8_t rsvd:7;
243ecee5a1fSHans Rosenfeld 	} id_vwc;
244ecee5a1fSHans Rosenfeld 	uint16_t id_awun;		/* Atomic Write Unit Normal */
245ecee5a1fSHans Rosenfeld 	uint16_t id_awupf;		/* Atomic Write Unit Power Fail */
246ecee5a1fSHans Rosenfeld 	struct {			/* NVM Vendor Specific Command Conf */
247ecee5a1fSHans Rosenfeld 		uint8_t nv_spec:1;	/* use format from spec */
248ecee5a1fSHans Rosenfeld 		uint8_t nv_rsvd:7;
249ecee5a1fSHans Rosenfeld 	} id_nvscc;
250ecee5a1fSHans Rosenfeld 	uint8_t id_rsvd_nc_2;
251ecee5a1fSHans Rosenfeld 	uint16_t id_acwu;		/* Atomic Compare & Write Unit (1.1) */
252ecee5a1fSHans Rosenfeld 	uint16_t id_rsvd_nc_3;
253ecee5a1fSHans Rosenfeld 	struct {			/* SGL Support (1.1) */
254ecee5a1fSHans Rosenfeld 		uint16_t sgl_sup:1;	/* SGL Supported in NVM cmds (1.1) */
255ecee5a1fSHans Rosenfeld 		uint16_t sgl_rsvd1:15;
256ecee5a1fSHans Rosenfeld 		uint16_t sgl_bucket:1;	/* SGL Bit Bucket supported (1.1) */
257ecee5a1fSHans Rosenfeld 		uint16_t sgl_rsvd2:15;
258ecee5a1fSHans Rosenfeld 	} id_sgls;
259*1188b159SRobert Mustacchi 	uint8_t id_rsvd_nc_4[768 - 540];
260ecee5a1fSHans Rosenfeld 
261ecee5a1fSHans Rosenfeld 	/* I/O Command Set Attributes */
262*1188b159SRobert Mustacchi 	uint8_t id_subnqn[1024 - 768];	/* Subsystem Qualified Name (1.2.1+) */
263*1188b159SRobert Mustacchi 	uint8_t id_rsvd_ioc[1792 - 1024];
264*1188b159SRobert Mustacchi 	uint8_t id_nvmof[2048 - 1792];	/* NVMe over Fabrics */
265ecee5a1fSHans Rosenfeld 
266ecee5a1fSHans Rosenfeld 	/* Power State Descriptors */
267ecee5a1fSHans Rosenfeld 	nvme_idctl_psd_t id_psd[32];
268ecee5a1fSHans Rosenfeld 
269ecee5a1fSHans Rosenfeld 	/* Vendor Specific */
270ecee5a1fSHans Rosenfeld 	uint8_t id_vs[1024];
271ecee5a1fSHans Rosenfeld } nvme_identify_ctrl_t;
272ecee5a1fSHans Rosenfeld 
273ecee5a1fSHans Rosenfeld /* NVMe Identify Namespace LBA Format */
274ecee5a1fSHans Rosenfeld typedef struct {
275ecee5a1fSHans Rosenfeld 	uint16_t lbaf_ms;		/* Metadata Size */
276ecee5a1fSHans Rosenfeld 	uint8_t lbaf_lbads;		/* LBA Data Size */
277ecee5a1fSHans Rosenfeld 	uint8_t lbaf_rp:2;		/* Relative Performance */
278ecee5a1fSHans Rosenfeld 	uint8_t lbaf_rsvd1:6;
279ecee5a1fSHans Rosenfeld } nvme_idns_lbaf_t;
280ecee5a1fSHans Rosenfeld 
281ecee5a1fSHans Rosenfeld /* NVMe Identify Namespace Data Structure */
282ecee5a1fSHans Rosenfeld typedef struct {
283ecee5a1fSHans Rosenfeld 	uint64_t id_nsize;		/* Namespace Size */
284ecee5a1fSHans Rosenfeld 	uint64_t id_ncap;		/* Namespace Capacity */
285ecee5a1fSHans Rosenfeld 	uint64_t id_nuse;		/* Namespace Utilization */
286ecee5a1fSHans Rosenfeld 	struct {			/* Namespace Features */
287ecee5a1fSHans Rosenfeld 		uint8_t f_thin:1;	/* Thin Provisioning */
288ecee5a1fSHans Rosenfeld 		uint8_t f_rsvd:7;
289ecee5a1fSHans Rosenfeld 	} id_nsfeat;
290ecee5a1fSHans Rosenfeld 	uint8_t id_nlbaf;		/* Number of LBA formats */
291ecee5a1fSHans Rosenfeld 	struct {			/* Formatted LBA size */
292ecee5a1fSHans Rosenfeld 		uint8_t lba_format:4;	/* LBA format */
293ecee5a1fSHans Rosenfeld 		uint8_t lba_extlba:1;	/* extended LBA (includes metadata) */
294ecee5a1fSHans Rosenfeld 		uint8_t lba_rsvd:3;
295ecee5a1fSHans Rosenfeld 	} id_flbas;
296ecee5a1fSHans Rosenfeld 	struct {			/* Metadata Capabilities */
297ecee5a1fSHans Rosenfeld 		uint8_t mc_extlba:1;	/* extended LBA transfers */
298ecee5a1fSHans Rosenfeld 		uint8_t mc_separate:1;	/* separate metadata transfers */
299ecee5a1fSHans Rosenfeld 		uint8_t mc_rsvd:6;
300ecee5a1fSHans Rosenfeld 	} id_mc;
301ecee5a1fSHans Rosenfeld 	struct {			/* Data Protection Capabilities */
302ecee5a1fSHans Rosenfeld 		uint8_t dp_type1:1;	/* Protection Information Type 1 */
303ecee5a1fSHans Rosenfeld 		uint8_t dp_type2:1;	/* Protection Information Type 2 */
304ecee5a1fSHans Rosenfeld 		uint8_t dp_type3:1;	/* Protection Information Type 3 */
305ecee5a1fSHans Rosenfeld 		uint8_t dp_first:1;	/* first 8 bytes of metadata */
306ecee5a1fSHans Rosenfeld 		uint8_t dp_last:1;	/* last 8 bytes of metadata */
307ecee5a1fSHans Rosenfeld 		uint8_t dp_rsvd:3;
308ecee5a1fSHans Rosenfeld 	} id_dpc;
309ecee5a1fSHans Rosenfeld 	struct {			/* Data Protection Settings */
310ecee5a1fSHans Rosenfeld 		uint8_t dp_pinfo:3;	/* Protection Information enabled */
311ecee5a1fSHans Rosenfeld 		uint8_t dp_first:1;	/* first 8 bytes of metadata */
312ecee5a1fSHans Rosenfeld 		uint8_t dp_rsvd:4;
313ecee5a1fSHans Rosenfeld 	} id_dps;
314ecee5a1fSHans Rosenfeld 	struct {			/* NS Multi-Path/Sharing Cap (1.1) */
315ecee5a1fSHans Rosenfeld 		uint8_t nm_shared:1;	/* NS is shared (1.1) */
316ecee5a1fSHans Rosenfeld 		uint8_t nm_rsvd:7;
317ecee5a1fSHans Rosenfeld 	} id_nmic;
318ecee5a1fSHans Rosenfeld 	struct {			/* Reservation Capabilities (1.1) */
319ecee5a1fSHans Rosenfeld 		uint8_t rc_persist:1;	/* Persist Through Power Loss (1.1) */
320ecee5a1fSHans Rosenfeld 		uint8_t rc_wr_excl:1;	/* Write Exclusive (1.1) */
321ecee5a1fSHans Rosenfeld 		uint8_t rc_excl:1;	/* Exclusive Access (1.1) */
322ecee5a1fSHans Rosenfeld 		uint8_t rc_wr_excl_r:1;	/* Wr Excl - Registrants Only (1.1) */
323ecee5a1fSHans Rosenfeld 		uint8_t rc_excl_r:1;	/* Excl Acc - Registrants Only (1.1) */
324ecee5a1fSHans Rosenfeld 		uint8_t rc_wr_excl_a:1;	/* Wr Excl - All Registrants (1.1) */
325ecee5a1fSHans Rosenfeld 		uint8_t rc_excl_a:1;	/* Excl Acc - All Registrants (1.1) */
326ecee5a1fSHans Rosenfeld 		uint8_t rc_rsvd:1;
327ecee5a1fSHans Rosenfeld 	} id_rescap;
328*1188b159SRobert Mustacchi 	uint8_t id_fpi;			/* Format Progress Indicator (1.2) */
329*1188b159SRobert Mustacchi 	uint8_t id_dfleat;		/* Deallocate Log. Block (1.3) */
330*1188b159SRobert Mustacchi 	uint16_t id_nawun;		/* Atomic Write Unit Normal (1.2) */
331*1188b159SRobert Mustacchi 	uint16_t id_nawupf;		/* Atomic Write Unit Power Fail (1.2) */
332*1188b159SRobert Mustacchi 	uint16_t id_nacwu;		/* Atomic Compare & Write Unit (1.2) */
333*1188b159SRobert Mustacchi 	uint16_t id_nabsn;		/* Atomic Boundary Size Normal (1.2) */
334*1188b159SRobert Mustacchi 	uint16_t id_nbao;		/* Atomic Boundary Offset (1.2) */
335*1188b159SRobert Mustacchi 	uint16_t id_nabspf;		/* Atomic Boundary Size Fail (1.2) */
336*1188b159SRobert Mustacchi 	uint16_t id_noiob;		/* Optimal I/O Bondary (1.3) */
337*1188b159SRobert Mustacchi 	uint8_t id_nvmcap[16];		/* NVM Capacity */
338*1188b159SRobert Mustacchi 	uint8_t id_rsvd1[104 - 64];
339*1188b159SRobert Mustacchi 	uint8_t id_nguid[16];		/* Namespace GUID (1.2) */
340ecee5a1fSHans Rosenfeld 	uint8_t id_eui64[8];		/* IEEE Extended Unique Id (1.1) */
341ecee5a1fSHans Rosenfeld 	nvme_idns_lbaf_t id_lbaf[16];	/* LBA Formats */
342ecee5a1fSHans Rosenfeld 
343*1188b159SRobert Mustacchi 	uint8_t id_rsvd2[384 - 192];
344ecee5a1fSHans Rosenfeld 
345*1188b159SRobert Mustacchi 	uint8_t id_vs[4096 - 384];	/* Vendor Specific */
346ecee5a1fSHans Rosenfeld } nvme_identify_nsid_t;
347ecee5a1fSHans Rosenfeld 
348*1188b159SRobert Mustacchi /* NVMe Identify Primary Controller Capabilities */
349*1188b159SRobert Mustacchi typedef struct {
350*1188b159SRobert Mustacchi 	uint16_t	nipc_cntlid;	/* Controller ID */
351*1188b159SRobert Mustacchi 	uint16_t	nipc_portid;	/* Port Identifier */
352*1188b159SRobert Mustacchi 	uint8_t		nipc_crt;	/* Controller Resource Types */
353*1188b159SRobert Mustacchi 	uint8_t		nipc_rsvd0[32 - 5];
354*1188b159SRobert Mustacchi 	uint32_t	nipc_vqfrt;	/* VQ Resources Flexible Total */
355*1188b159SRobert Mustacchi 	uint32_t	nipc_vqrfa;	/* VQ Resources Flexible Assigned */
356*1188b159SRobert Mustacchi 	uint16_t	nipc_vqrfap;	/* VQ Resources to Primary */
357*1188b159SRobert Mustacchi 	uint16_t	nipc_vqprt;	/* VQ Resources Private Total */
358*1188b159SRobert Mustacchi 	uint16_t	nipc_vqfrsm;	/* VQ Resources Secondary Max */
359*1188b159SRobert Mustacchi 	uint16_t	nipc_vqgran;	/* VQ Flexible Resource Gran */
360*1188b159SRobert Mustacchi 	uint8_t		nipc_rvsd1[64 - 48];
361*1188b159SRobert Mustacchi 	uint32_t	nipc_vifrt;	/* VI Flexible total */
362*1188b159SRobert Mustacchi 	uint32_t	nipc_virfa;	/* VI Flexible Assigned */
363*1188b159SRobert Mustacchi 	uint16_t	nipc_virfap;	/* VI Flexible Allocatd to Primary */
364*1188b159SRobert Mustacchi 	uint16_t	nipc_viprt;	/* VI Resources Private Total */
365*1188b159SRobert Mustacchi 	uint16_t	nipc_vifrsm;	/* VI Resources Secondary Max */
366*1188b159SRobert Mustacchi 	uint16_t	nipc_vigran;	/* VI Flexible Granularity */
367*1188b159SRobert Mustacchi 	uint8_t		nipc_rsvd2[4096 - 80];
368*1188b159SRobert Mustacchi } nvme_identify_primary_caps_t;
369ecee5a1fSHans Rosenfeld 
370ecee5a1fSHans Rosenfeld /*
371ecee5a1fSHans Rosenfeld  * NVMe completion queue entry status field
372ecee5a1fSHans Rosenfeld  */
373ecee5a1fSHans Rosenfeld typedef struct {
374ecee5a1fSHans Rosenfeld 	uint16_t sf_p:1;		/* Phase Tag */
375ecee5a1fSHans Rosenfeld 	uint16_t sf_sc:8;		/* Status Code */
376ecee5a1fSHans Rosenfeld 	uint16_t sf_sct:3;		/* Status Code Type */
377ecee5a1fSHans Rosenfeld 	uint16_t sf_rsvd2:2;
378ecee5a1fSHans Rosenfeld 	uint16_t sf_m:1;		/* More */
379ecee5a1fSHans Rosenfeld 	uint16_t sf_dnr:1;		/* Do Not Retry */
380ecee5a1fSHans Rosenfeld } nvme_cqe_sf_t;
381ecee5a1fSHans Rosenfeld 
382ecee5a1fSHans Rosenfeld 
383ecee5a1fSHans Rosenfeld /*
384ecee5a1fSHans Rosenfeld  * NVMe Get Log Page
385ecee5a1fSHans Rosenfeld  */
386ecee5a1fSHans Rosenfeld #define	NVME_LOGPAGE_ERROR	0x1	/* Error Information */
387ecee5a1fSHans Rosenfeld #define	NVME_LOGPAGE_HEALTH	0x2	/* SMART/Health Information */
388ecee5a1fSHans Rosenfeld #define	NVME_LOGPAGE_FWSLOT	0x3	/* Firmware Slot Information */
389ecee5a1fSHans Rosenfeld 
390ecee5a1fSHans Rosenfeld typedef struct {
391ecee5a1fSHans Rosenfeld 	uint64_t el_count;		/* Error Count */
392ecee5a1fSHans Rosenfeld 	uint16_t el_sqid;		/* Submission Queue ID */
393ecee5a1fSHans Rosenfeld 	uint16_t el_cid;		/* Command ID */
394ecee5a1fSHans Rosenfeld 	nvme_cqe_sf_t el_sf;		/* Status Field */
395ecee5a1fSHans Rosenfeld 	uint8_t	el_byte;		/* Parameter Error Location byte */
396ecee5a1fSHans Rosenfeld 	uint8_t	el_bit:3;		/* Parameter Error Location bit */
397ecee5a1fSHans Rosenfeld 	uint8_t el_rsvd1:5;
398ecee5a1fSHans Rosenfeld 	uint64_t el_lba;		/* Logical Block Address */
399ecee5a1fSHans Rosenfeld 	uint32_t el_nsid;		/* Namespace ID */
400ecee5a1fSHans Rosenfeld 	uint8_t	el_vendor;		/* Vendor Specific Information avail */
401ecee5a1fSHans Rosenfeld 	uint8_t el_rsvd2[64 - 29];
402ecee5a1fSHans Rosenfeld } nvme_error_log_entry_t;
403ecee5a1fSHans Rosenfeld 
404ecee5a1fSHans Rosenfeld typedef struct {
405ecee5a1fSHans Rosenfeld 	uint64_t lo;
406ecee5a1fSHans Rosenfeld 	uint64_t hi;
407ecee5a1fSHans Rosenfeld } nvme_uint128_t;
408ecee5a1fSHans Rosenfeld 
409ecee5a1fSHans Rosenfeld typedef struct {
410ecee5a1fSHans Rosenfeld 	struct {			/* Critical Warning */
411ecee5a1fSHans Rosenfeld 		uint8_t cw_avail:1;	/* available space too low */
412ecee5a1fSHans Rosenfeld 		uint8_t cw_temp:1;	/* temperature too high */
413ecee5a1fSHans Rosenfeld 		uint8_t cw_reliab:1;	/* degraded reliability */
414ecee5a1fSHans Rosenfeld 		uint8_t cw_readonly:1;	/* media is read-only */
415ecee5a1fSHans Rosenfeld 		uint8_t cw_volatile:1;	/* volatile memory backup failed */
416ecee5a1fSHans Rosenfeld 		uint8_t cw_rsvd:3;
417ecee5a1fSHans Rosenfeld 	} hl_crit_warn;
418ecee5a1fSHans Rosenfeld 	uint16_t hl_temp;		/* Temperature */
419ecee5a1fSHans Rosenfeld 	uint8_t hl_avail_spare;		/* Available Spare */
420ecee5a1fSHans Rosenfeld 	uint8_t hl_avail_spare_thr;	/* Available Spare Threshold */
421ecee5a1fSHans Rosenfeld 	uint8_t hl_used;		/* Percentage Used */
422ecee5a1fSHans Rosenfeld 	uint8_t hl_rsvd1[32 - 6];
423ecee5a1fSHans Rosenfeld 	nvme_uint128_t hl_data_read;	/* Data Units Read */
424ecee5a1fSHans Rosenfeld 	nvme_uint128_t hl_data_write;	/* Data Units Written */
425ecee5a1fSHans Rosenfeld 	nvme_uint128_t hl_host_read;	/* Host Read Commands */
426ecee5a1fSHans Rosenfeld 	nvme_uint128_t hl_host_write;	/* Host Write Commands */
427ecee5a1fSHans Rosenfeld 	nvme_uint128_t hl_ctrl_busy;	/* Controller Busy Time */
428ecee5a1fSHans Rosenfeld 	nvme_uint128_t hl_power_cycles;	/* Power Cycles */
429ecee5a1fSHans Rosenfeld 	nvme_uint128_t hl_power_on_hours; /* Power On Hours */
430ecee5a1fSHans Rosenfeld 	nvme_uint128_t hl_unsafe_shutdn; /* Unsafe Shutdowns */
431ecee5a1fSHans Rosenfeld 	nvme_uint128_t hl_media_errors;	/* Media Errors */
432ecee5a1fSHans Rosenfeld 	nvme_uint128_t hl_errors_logged; /* Number of errors logged */
433ecee5a1fSHans Rosenfeld 	uint8_t hl_rsvd2[512 - 192];
434ecee5a1fSHans Rosenfeld } nvme_health_log_t;
435ecee5a1fSHans Rosenfeld 
436ecee5a1fSHans Rosenfeld typedef struct {
437ecee5a1fSHans Rosenfeld 	uint8_t fw_afi:3;		/* Active Firmware Slot */
438ecee5a1fSHans Rosenfeld 	uint8_t fw_rsvd1:5;
439ecee5a1fSHans Rosenfeld 	uint8_t fw_rsvd2[7];
440ecee5a1fSHans Rosenfeld 	char fw_frs[7][8];		/* Firmware Revision / Slot */
441ecee5a1fSHans Rosenfeld 	uint8_t fw_rsvd3[512 - 64];
442ecee5a1fSHans Rosenfeld } nvme_fwslot_log_t;
443ecee5a1fSHans Rosenfeld 
444ecee5a1fSHans Rosenfeld 
445ecee5a1fSHans Rosenfeld /*
446ecee5a1fSHans Rosenfeld  * NVMe Format NVM
447ecee5a1fSHans Rosenfeld  */
448ecee5a1fSHans Rosenfeld #define	NVME_FRMT_SES_NONE	0
449ecee5a1fSHans Rosenfeld #define	NVME_FRMT_SES_USER	1
450ecee5a1fSHans Rosenfeld #define	NVME_FRMT_SES_CRYPTO	2
451ecee5a1fSHans Rosenfeld #define	NVME_FRMT_MAX_SES	2
452ecee5a1fSHans Rosenfeld 
453ecee5a1fSHans Rosenfeld #define	NVME_FRMT_MAX_LBAF	15
454ecee5a1fSHans Rosenfeld 
455ecee5a1fSHans Rosenfeld typedef union {
456ecee5a1fSHans Rosenfeld 	struct {
457ecee5a1fSHans Rosenfeld 		uint32_t fm_lbaf:4;		/* LBA Format */
458ecee5a1fSHans Rosenfeld 		uint32_t fm_ms:1;		/* Metadata Settings */
459ecee5a1fSHans Rosenfeld 		uint32_t fm_pi:3;		/* Protection Information */
460ecee5a1fSHans Rosenfeld 		uint32_t fm_pil:1;		/* Prot. Information Location */
461ecee5a1fSHans Rosenfeld 		uint32_t fm_ses:3;		/* Secure Erase Settings */
462ecee5a1fSHans Rosenfeld 		uint32_t fm_resvd:20;
463ecee5a1fSHans Rosenfeld 	} b;
464ecee5a1fSHans Rosenfeld 	uint32_t r;
465ecee5a1fSHans Rosenfeld } nvme_format_nvm_t;
466ecee5a1fSHans Rosenfeld 
467ecee5a1fSHans Rosenfeld 
468ecee5a1fSHans Rosenfeld /*
469ecee5a1fSHans Rosenfeld  * NVMe Get / Set Features
470ecee5a1fSHans Rosenfeld  */
471ecee5a1fSHans Rosenfeld #define	NVME_FEAT_ARBITRATION	0x1	/* Command Arbitration */
472ecee5a1fSHans Rosenfeld #define	NVME_FEAT_POWER_MGMT	0x2	/* Power Management */
473ecee5a1fSHans Rosenfeld #define	NVME_FEAT_LBA_RANGE	0x3	/* LBA Range Type */
474ecee5a1fSHans Rosenfeld #define	NVME_FEAT_TEMPERATURE	0x4	/* Temperature Threshold */
475ecee5a1fSHans Rosenfeld #define	NVME_FEAT_ERROR		0x5	/* Error Recovery */
476ecee5a1fSHans Rosenfeld #define	NVME_FEAT_WRITE_CACHE	0x6	/* Volatile Write Cache */
477ecee5a1fSHans Rosenfeld #define	NVME_FEAT_NQUEUES	0x7	/* Number of Queues */
478ecee5a1fSHans Rosenfeld #define	NVME_FEAT_INTR_COAL	0x8	/* Interrupt Coalescing */
479ecee5a1fSHans Rosenfeld #define	NVME_FEAT_INTR_VECT	0x9	/* Interrupt Vector Configuration */
480ecee5a1fSHans Rosenfeld #define	NVME_FEAT_WRITE_ATOM	0xa	/* Write Atomicity */
481ecee5a1fSHans Rosenfeld #define	NVME_FEAT_ASYNC_EVENT	0xb	/* Asynchronous Event Configuration */
482ecee5a1fSHans Rosenfeld #define	NVME_FEAT_AUTO_PST	0xc	/* Autonomous Power State Transition */
483ecee5a1fSHans Rosenfeld 					/* (1.1) */
484ecee5a1fSHans Rosenfeld 
485ecee5a1fSHans Rosenfeld #define	NVME_FEAT_PROGRESS	0x80	/* Software Progress Marker */
486ecee5a1fSHans Rosenfeld 
487ecee5a1fSHans Rosenfeld /* Arbitration Feature */
488ecee5a1fSHans Rosenfeld typedef union {
489ecee5a1fSHans Rosenfeld 	struct {
490ecee5a1fSHans Rosenfeld 		uint8_t arb_ab:3;	/* Arbitration Burst */
491ecee5a1fSHans Rosenfeld 		uint8_t arb_rsvd:5;
492ecee5a1fSHans Rosenfeld 		uint8_t arb_lpw;	/* Low Priority Weight */
493ecee5a1fSHans Rosenfeld 		uint8_t arb_mpw;	/* Medium Priority Weight */
494ecee5a1fSHans Rosenfeld 		uint8_t arb_hpw;	/* High Priority Weight */
495ecee5a1fSHans Rosenfeld 	} b;
496ecee5a1fSHans Rosenfeld 	uint32_t r;
497ecee5a1fSHans Rosenfeld } nvme_arbitration_t;
498ecee5a1fSHans Rosenfeld 
499ecee5a1fSHans Rosenfeld /* Power Management Feature */
500ecee5a1fSHans Rosenfeld typedef union {
501ecee5a1fSHans Rosenfeld 	struct {
502ecee5a1fSHans Rosenfeld 		uint32_t pm_ps:5;	/* Power State */
503ecee5a1fSHans Rosenfeld 		uint32_t pm_rsvd:27;
504ecee5a1fSHans Rosenfeld 	} b;
505ecee5a1fSHans Rosenfeld 	uint32_t r;
506ecee5a1fSHans Rosenfeld } nvme_power_mgmt_t;
507ecee5a1fSHans Rosenfeld 
508ecee5a1fSHans Rosenfeld /* LBA Range Type Feature */
509ecee5a1fSHans Rosenfeld typedef union {
510ecee5a1fSHans Rosenfeld 	struct {
511ecee5a1fSHans Rosenfeld 		uint32_t lr_num:6;	/* Number of LBA ranges */
512ecee5a1fSHans Rosenfeld 		uint32_t lr_rsvd:26;
513ecee5a1fSHans Rosenfeld 	} b;
514ecee5a1fSHans Rosenfeld 	uint32_t r;
515ecee5a1fSHans Rosenfeld } nvme_lba_range_type_t;
516ecee5a1fSHans Rosenfeld 
517ecee5a1fSHans Rosenfeld typedef struct {
518ecee5a1fSHans Rosenfeld 	uint8_t lr_type;		/* Type */
519ecee5a1fSHans Rosenfeld 	struct {			/* Attributes */
520ecee5a1fSHans Rosenfeld 		uint8_t lr_write:1;	/* may be overwritten */
521ecee5a1fSHans Rosenfeld 		uint8_t lr_hidden:1;	/* hidden from OS/EFI/BIOS */
522ecee5a1fSHans Rosenfeld 		uint8_t lr_rsvd1:6;
523ecee5a1fSHans Rosenfeld 	} lr_attr;
524ecee5a1fSHans Rosenfeld 	uint8_t lr_rsvd2[14];
525ecee5a1fSHans Rosenfeld 	uint64_t lr_slba;		/* Starting LBA */
526ecee5a1fSHans Rosenfeld 	uint64_t lr_nlb;		/* Number of Logical Blocks */
527ecee5a1fSHans Rosenfeld 	uint8_t lr_guid[16];		/* Unique Identifier */
528ecee5a1fSHans Rosenfeld 	uint8_t lr_rsvd3[16];
529ecee5a1fSHans Rosenfeld } nvme_lba_range_t;
530ecee5a1fSHans Rosenfeld 
531ecee5a1fSHans Rosenfeld #define	NVME_LBA_RANGE_BUFSIZE	4096
532ecee5a1fSHans Rosenfeld 
533ecee5a1fSHans Rosenfeld /* Temperature Threshold Feature */
534ecee5a1fSHans Rosenfeld typedef union {
535ecee5a1fSHans Rosenfeld 	struct {
536ecee5a1fSHans Rosenfeld 		uint16_t tt_tmpth;	/* Temperature Threshold */
537ecee5a1fSHans Rosenfeld 		uint16_t tt_rsvd;
538ecee5a1fSHans Rosenfeld 	} b;
539ecee5a1fSHans Rosenfeld 	uint32_t r;
540ecee5a1fSHans Rosenfeld } nvme_temp_threshold_t;
541ecee5a1fSHans Rosenfeld 
542ecee5a1fSHans Rosenfeld /* Error Recovery Feature */
543ecee5a1fSHans Rosenfeld typedef union {
544ecee5a1fSHans Rosenfeld 	struct {
545ecee5a1fSHans Rosenfeld 		uint16_t er_tler;	/* Time-Limited Error Recovery */
546ecee5a1fSHans Rosenfeld 		uint16_t er_rsvd;
547ecee5a1fSHans Rosenfeld 	} b;
548ecee5a1fSHans Rosenfeld 	uint32_t r;
549ecee5a1fSHans Rosenfeld } nvme_error_recovery_t;
550ecee5a1fSHans Rosenfeld 
551ecee5a1fSHans Rosenfeld /* Volatile Write Cache Feature */
552ecee5a1fSHans Rosenfeld typedef union {
553ecee5a1fSHans Rosenfeld 	struct {
554ecee5a1fSHans Rosenfeld 		uint32_t wc_wce:1;	/* Volatile Write Cache Enable */
555ecee5a1fSHans Rosenfeld 		uint32_t wc_rsvd:31;
556ecee5a1fSHans Rosenfeld 	} b;
557ecee5a1fSHans Rosenfeld 	uint32_t r;
558ecee5a1fSHans Rosenfeld } nvme_write_cache_t;
559ecee5a1fSHans Rosenfeld 
560ecee5a1fSHans Rosenfeld /* Number of Queues Feature */
561ecee5a1fSHans Rosenfeld typedef union {
562ecee5a1fSHans Rosenfeld 	struct {
563ecee5a1fSHans Rosenfeld 		uint16_t nq_nsq;	/* Number of Submission Queues */
564ecee5a1fSHans Rosenfeld 		uint16_t nq_ncq;	/* Number of Completion Queues */
565ecee5a1fSHans Rosenfeld 	} b;
566ecee5a1fSHans Rosenfeld 	uint32_t r;
567ecee5a1fSHans Rosenfeld } nvme_nqueues_t;
568ecee5a1fSHans Rosenfeld 
569ecee5a1fSHans Rosenfeld /* Interrupt Coalescing Feature */
570ecee5a1fSHans Rosenfeld typedef union {
571ecee5a1fSHans Rosenfeld 	struct {
572ecee5a1fSHans Rosenfeld 		uint8_t ic_thr;		/* Aggregation Threshold */
573ecee5a1fSHans Rosenfeld 		uint8_t ic_time;	/* Aggregation Time */
574ecee5a1fSHans Rosenfeld 		uint16_t ic_rsvd;
575ecee5a1fSHans Rosenfeld 	} b;
576ecee5a1fSHans Rosenfeld 	uint32_t r;
577ecee5a1fSHans Rosenfeld } nvme_intr_coal_t;
578ecee5a1fSHans Rosenfeld 
579ecee5a1fSHans Rosenfeld /* Interrupt Configuration Features */
580ecee5a1fSHans Rosenfeld typedef union {
581ecee5a1fSHans Rosenfeld 	struct {
582ecee5a1fSHans Rosenfeld 		uint16_t iv_iv;		/* Interrupt Vector */
583ecee5a1fSHans Rosenfeld 		uint16_t iv_cd:1;	/* Coalescing Disable */
584ecee5a1fSHans Rosenfeld 		uint16_t iv_rsvd:15;
585ecee5a1fSHans Rosenfeld 	} b;
586ecee5a1fSHans Rosenfeld 	uint32_t r;
587ecee5a1fSHans Rosenfeld } nvme_intr_vect_t;
588ecee5a1fSHans Rosenfeld 
589ecee5a1fSHans Rosenfeld /* Write Atomicity Feature */
590ecee5a1fSHans Rosenfeld typedef union {
591ecee5a1fSHans Rosenfeld 	struct {
592ecee5a1fSHans Rosenfeld 		uint32_t wa_dn:1;	/* Disable Normal */
593ecee5a1fSHans Rosenfeld 		uint32_t wa_rsvd:31;
594ecee5a1fSHans Rosenfeld 	} b;
595ecee5a1fSHans Rosenfeld 	uint32_t r;
596ecee5a1fSHans Rosenfeld } nvme_write_atomicity_t;
597ecee5a1fSHans Rosenfeld 
598ecee5a1fSHans Rosenfeld /* Asynchronous Event Configuration Feature */
599ecee5a1fSHans Rosenfeld typedef union {
600ecee5a1fSHans Rosenfeld 	struct {
601ecee5a1fSHans Rosenfeld 		uint8_t aec_avail:1;	/* available space too low */
602ecee5a1fSHans Rosenfeld 		uint8_t aec_temp:1;	/* temperature too high */
603ecee5a1fSHans Rosenfeld 		uint8_t aec_reliab:1;	/* degraded reliability */
604ecee5a1fSHans Rosenfeld 		uint8_t aec_readonly:1;	/* media is read-only */
605ecee5a1fSHans Rosenfeld 		uint8_t aec_volatile:1;	/* volatile memory backup failed */
606ecee5a1fSHans Rosenfeld 		uint8_t aec_rsvd1:3;
607ecee5a1fSHans Rosenfeld 		uint8_t aec_rsvd2[3];
608ecee5a1fSHans Rosenfeld 	} b;
609ecee5a1fSHans Rosenfeld 	uint32_t r;
610ecee5a1fSHans Rosenfeld } nvme_async_event_conf_t;
611ecee5a1fSHans Rosenfeld 
612ecee5a1fSHans Rosenfeld /* Autonomous Power State Transition Feature (1.1) */
613ecee5a1fSHans Rosenfeld typedef union {
614ecee5a1fSHans Rosenfeld 	struct {
615ecee5a1fSHans Rosenfeld 		uint8_t	apst_apste:1;	/* APST enabled */
616ecee5a1fSHans Rosenfeld 		uint8_t apst_rsvd:7;
617ecee5a1fSHans Rosenfeld 	} b;
618ecee5a1fSHans Rosenfeld 	uint8_t r;
619ecee5a1fSHans Rosenfeld } nvme_auto_power_state_trans_t;
620ecee5a1fSHans Rosenfeld 
621ecee5a1fSHans Rosenfeld typedef struct {
622ecee5a1fSHans Rosenfeld 	uint32_t apst_rsvd1:3;
623ecee5a1fSHans Rosenfeld 	uint32_t apst_itps:5;	/* Idle Transition Power State */
624ecee5a1fSHans Rosenfeld 	uint32_t apst_itpt:24;	/* Idle Time Prior to Transition */
625ecee5a1fSHans Rosenfeld 	uint32_t apst_rsvd2;
626ecee5a1fSHans Rosenfeld } nvme_auto_power_state_t;
627ecee5a1fSHans Rosenfeld 
628ecee5a1fSHans Rosenfeld #define	NVME_AUTO_PST_BUFSIZE	256
629ecee5a1fSHans Rosenfeld 
630ecee5a1fSHans Rosenfeld /* Software Progress Marker Feature */
631ecee5a1fSHans Rosenfeld typedef union {
632ecee5a1fSHans Rosenfeld 	struct {
633ecee5a1fSHans Rosenfeld 		uint8_t spm_pbslc;	/* Pre-Boot Software Load Count */
634ecee5a1fSHans Rosenfeld 		uint8_t spm_rsvd[3];
635ecee5a1fSHans Rosenfeld 	} b;
636ecee5a1fSHans Rosenfeld 	uint32_t r;
637ecee5a1fSHans Rosenfeld } nvme_software_progress_marker_t;
638ecee5a1fSHans Rosenfeld 
639ecee5a1fSHans Rosenfeld #pragma pack() /* pack(1) */
640ecee5a1fSHans Rosenfeld 
641ecee5a1fSHans Rosenfeld 
642ecee5a1fSHans Rosenfeld #ifdef __cplusplus
643ecee5a1fSHans Rosenfeld }
644ecee5a1fSHans Rosenfeld #endif
645ecee5a1fSHans Rosenfeld 
646ecee5a1fSHans Rosenfeld #endif /* _SYS_NVME_H */
647