xref: /illumos-gate/usr/src/uts/common/sys/nvme.h (revision 4a663bac9c5f9f82a5f633bc9639bbee3c2317ff)
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.
14  * Copyright 2020 Joyent, Inc.
15  * Copyright 2019 Western Digital Corporation
16  */
17 
18 #ifndef _SYS_NVME_H
19 #define	_SYS_NVME_H
20 
21 #include <sys/types.h>
22 
23 #ifdef _KERNEL
24 #include <sys/types32.h>
25 #else
26 #include <stdint.h>
27 #endif
28 
29 /*
30  * Declarations used for communication between nvmeadm(1M) and nvme(7D)
31  */
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 /*
38  * NVMe ioctl definitions
39  */
40 
41 #define	NVME_IOC			(('N' << 24) | ('V' << 16) | ('M' << 8))
42 #define	NVME_IOC_IDENTIFY_CTRL		(NVME_IOC | 1)
43 #define	NVME_IOC_IDENTIFY_NSID		(NVME_IOC | 2)
44 #define	NVME_IOC_CAPABILITIES		(NVME_IOC | 3)
45 #define	NVME_IOC_GET_LOGPAGE		(NVME_IOC | 4)
46 #define	NVME_IOC_GET_FEATURES		(NVME_IOC | 5)
47 #define	NVME_IOC_INTR_CNT		(NVME_IOC | 6)
48 #define	NVME_IOC_VERSION		(NVME_IOC | 7)
49 #define	NVME_IOC_FORMAT			(NVME_IOC | 8)
50 #define	NVME_IOC_DETACH			(NVME_IOC | 9)
51 #define	NVME_IOC_ATTACH			(NVME_IOC | 10)
52 #define	NVME_IOC_FIRMWARE_DOWNLOAD	(NVME_IOC | 11)
53 #define	NVME_IOC_FIRMWARE_COMMIT	(NVME_IOC | 12)
54 #define	NVME_IOC_MAX			NVME_IOC_FIRMWARE_COMMIT
55 
56 #define	IS_NVME_IOC(x)			((x) > NVME_IOC && (x) <= NVME_IOC_MAX)
57 #define	NVME_IOC_CMD(x)			((x) & 0xff)
58 
59 typedef struct {
60 	size_t		n_len;
61 	uintptr_t	n_buf;
62 	uint64_t	n_arg;
63 } nvme_ioctl_t;
64 
65 #ifdef _KERNEL
66 typedef struct {
67 	size32_t	n_len;
68 	uintptr32_t	n_buf;
69 	uint64_t	n_arg;
70 } nvme_ioctl32_t;
71 #endif
72 
73 /*
74  * NVMe capabilities
75  */
76 typedef struct {
77 	uint32_t mpsmax;		/* Memory Page Size Maximum */
78 	uint32_t mpsmin;		/* Memory Page Size Minimum */
79 } nvme_capabilities_t;
80 
81 /*
82  * NVMe version
83  */
84 typedef struct {
85 	uint16_t v_minor;
86 	uint16_t v_major;
87 } nvme_version_t;
88 
89 #define	NVME_VERSION_ATLEAST(v, maj, min) \
90 	(((v)->v_major) > (maj) || \
91 	((v)->v_major == (maj) && (v)->v_minor >= (min)))
92 
93 #define	NVME_VERSION_HIGHER(v, maj, min) \
94 	(((v)->v_major) > (maj) || \
95 	((v)->v_major == (maj) && (v)->v_minor > (min)))
96 
97 
98 #pragma pack(1)
99 
100 /*
101  * NVMe Identify data structures
102  */
103 
104 #define	NVME_IDENTIFY_BUFSIZE	4096	/* buffer size for Identify */
105 
106 /* NVMe Queue Entry Size bitfield */
107 typedef struct {
108 	uint8_t qes_min:4;		/* minimum entry size */
109 	uint8_t qes_max:4;		/* maximum entry size */
110 } nvme_idctl_qes_t;
111 
112 /* NVMe Power State Descriptor */
113 typedef struct {
114 	uint16_t psd_mp;		/* Maximum Power */
115 	uint8_t psd_rsvd1;
116 	uint8_t psd_mps:1;		/* Max Power Scale (1.1) */
117 	uint8_t psd_nops:1;		/* Non-Operational State (1.1) */
118 	uint8_t psd_rsvd2:6;
119 	uint32_t psd_enlat;		/* Entry Latency */
120 	uint32_t psd_exlat;		/* Exit Latency */
121 	uint8_t psd_rrt:5;		/* Relative Read Throughput */
122 	uint8_t psd_rsvd3:3;
123 	uint8_t psd_rrl:5;		/* Relative Read Latency */
124 	uint8_t psd_rsvd4:3;
125 	uint8_t psd_rwt:5;		/* Relative Write Throughput */
126 	uint8_t	psd_rsvd5:3;
127 	uint8_t psd_rwl:5;		/* Relative Write Latency */
128 	uint8_t psd_rsvd6:3;
129 	uint16_t psd_idlp;		/* Idle Power (1.2) */
130 	uint8_t psd_rsvd7:6;
131 	uint8_t psd_ips:2;		/* Idle Power Scale (1.2) */
132 	uint8_t psd_rsvd8;
133 	uint16_t psd_actp;		/* Active Power (1.2) */
134 	uint8_t psd_apw:3;		/* Active Power Workload (1.2) */
135 	uint8_t psd_rsvd9:3;
136 	uint8_t psd_aps:2;		/* Active Power Scale */
137 	uint8_t psd_rsvd10[9];
138 } nvme_idctl_psd_t;
139 
140 #define	NVME_SERIAL_SZ	20
141 #define	NVME_MODEL_SZ	40
142 
143 /* NVMe Identify Controller Data Structure */
144 typedef struct {
145 	/* Controller Capabilities & Features */
146 	uint16_t id_vid;		/* PCI vendor ID */
147 	uint16_t id_ssvid;		/* PCI subsystem vendor ID */
148 	char id_serial[NVME_SERIAL_SZ];	/* Serial Number */
149 	char id_model[NVME_MODEL_SZ];	/* Model Number */
150 	char id_fwrev[8];		/* Firmware Revision */
151 	uint8_t id_rab;			/* Recommended Arbitration Burst */
152 	uint8_t id_oui[3];		/* vendor IEEE OUI */
153 	struct {			/* Multi-Interface Capabilities */
154 		uint8_t m_multi_pci:1;	/* HW has multiple PCIe interfaces */
155 		uint8_t m_multi_ctrl:1; /* HW has multiple controllers (1.1) */
156 		uint8_t m_sr_iov:1;	/* controller is SR-IOV virt fn (1.1) */
157 		uint8_t m_rsvd:5;
158 	} id_mic;
159 	uint8_t	id_mdts;		/* Maximum Data Transfer Size */
160 	uint16_t id_cntlid;		/* Unique Controller Identifier (1.1) */
161 	/* Added in NVMe 1.2 */
162 	uint32_t id_ver;		/* Version */
163 	uint32_t id_rtd3r;		/* RTD3 Resume Latency */
164 	uint32_t id_rtd3e;		/* RTD3 Entry Latency */
165 	uint32_t id_oaes;		/* Optional Asynchronous Events */
166 	/* Added in NVMe 1.3 */
167 	uint32_t id_ctratt;		/* Controller Attributes */
168 	uint8_t id_rsvd_cc[12];
169 	uint8_t id_frguid[16];		/* FRU GUID */
170 	uint8_t id_rsvd2_cc[240 - 128];
171 	uint8_t id_rsvd_nvmemi[255 - 240];
172 	uint8_t id_mec;			/* Management Endpiont Capabilities */
173 
174 	/* Admin Command Set Attributes */
175 	struct {			/* Optional Admin Command Support */
176 		uint16_t oa_security:1;	/* Security Send & Receive */
177 		uint16_t oa_format:1;	/* Format NVM */
178 		uint16_t oa_firmware:1;	/* Firmware Activate & Download */
179 		uint16_t oa_rsvd:13;
180 	} id_oacs;
181 	uint8_t	id_acl;			/* Abort Command Limit */
182 	uint8_t id_aerl;		/* Asynchronous Event Request Limit */
183 	struct {			/* Firmware Updates */
184 		uint8_t fw_readonly:1;	/* Slot 1 is Read-Only */
185 		uint8_t	fw_nslot:3;	/* number of firmware slots */
186 		uint8_t fw_rsvd:4;
187 	} id_frmw;
188 	struct {			/* Log Page Attributes */
189 		uint8_t lp_smart:1;	/* SMART/Health information per NS */
190 		uint8_t lp_rsvd:7;
191 	} id_lpa;
192 	uint8_t id_elpe;		/* Error Log Page Entries */
193 	uint8_t	id_npss;		/* Number of Power States */
194 	struct {			/* Admin Vendor Specific Command Conf */
195 		uint8_t av_spec:1;	/* use format from spec */
196 		uint8_t av_rsvd:7;
197 	} id_avscc;
198 	struct {			/* Autonomous Power State Trans (1.1) */
199 		uint8_t ap_sup:1;	/* APST supported (1.1) */
200 		uint8_t ap_rsvd:7;
201 	} id_apsta;
202 	/* Added in NVMe 1.2 */
203 	uint16_t ap_wctemp;		/* Warning Composite Temperature */
204 	uint16_t ap_cctemp;		/* Critical Composite Temperature */
205 	uint16_t ap_mtfa;		/* Maximum Firmware Activation Time */
206 	uint32_t ap_hmpre;		/* Host Memory Buffer Preferred Size */
207 	uint32_t ap_hmmin;		/* Host Memory Buffer Min Size */
208 	uint8_t ap_tnvmcap[16];		/* Total NVM Capacity in Bytes */
209 	uint8_t ap_unvmcap[16];		/* Unallocated NVM Capacity */
210 	uint32_t ap_rpmbs;		/* Replay Protected Memory Block */
211 	/* Added in NVMe 1.3 */
212 	uint16_t ap_edstt;		/* Extended Device Self-test time */
213 	uint8_t ap_dsto;		/* Device Self-test Options */
214 	uint8_t ap_fwug;		/* Firmware Update Granularity */
215 	uint16_t ap_kas;		/* Keep Alive Support */
216 	uint16_t ap_hctma;		/* Host Thermal Management */
217 	uint16_t ap_mntmt;		/* Minimum Thermal Temperature */
218 	uint16_t ap_mxtmt;		/* Maximum Thermal Temperature */
219 	uint32_t ap_sanitize;		/* Sanitize Caps */
220 	uint8_t id_rsvd_ac[512 - 332];
221 
222 	/* NVM Command Set Attributes */
223 	nvme_idctl_qes_t id_sqes;	/* Submission Queue Entry Size */
224 	nvme_idctl_qes_t id_cqes;	/* Completion Queue Entry Size */
225 	uint16_t id_maxcmd;		/* Max Outstanding Commands (1.3) */
226 	uint32_t id_nn;			/* Number of Namespaces */
227 	struct {			/* Optional NVM Command Support */
228 		uint16_t on_compare:1;	/* Compare */
229 		uint16_t on_wr_unc:1;	/* Write Uncorrectable */
230 		uint16_t on_dset_mgmt:1; /* Dataset Management */
231 		uint16_t on_wr_zero:1;	/* Write Zeros (1.1) */
232 		uint16_t on_save:1;	/* Save/Select in Get/Set Feat (1.1) */
233 		uint16_t on_reserve:1;	/* Reservations (1.1) */
234 		uint16_t on_rsvd:10;
235 	} id_oncs;
236 	struct {			/* Fused Operation Support */
237 		uint16_t f_cmp_wr:1;	/* Compare and Write */
238 		uint16_t f_rsvd:15;
239 	} id_fuses;
240 	struct {			/* Format NVM Attributes */
241 		uint8_t fn_format:1;	/* Format applies to all NS */
242 		uint8_t fn_sec_erase:1;	/* Secure Erase applies to all NS */
243 		uint8_t fn_crypt_erase:1; /* Cryptographic Erase supported */
244 		uint8_t fn_rsvd:5;
245 	} id_fna;
246 	struct {			/* Volatile Write Cache */
247 		uint8_t vwc_present:1;	/* Volatile Write Cache present */
248 		uint8_t rsvd:7;
249 	} id_vwc;
250 	uint16_t id_awun;		/* Atomic Write Unit Normal */
251 	uint16_t id_awupf;		/* Atomic Write Unit Power Fail */
252 	struct {			/* NVM Vendor Specific Command Conf */
253 		uint8_t nv_spec:1;	/* use format from spec */
254 		uint8_t nv_rsvd:7;
255 	} id_nvscc;
256 	uint8_t id_rsvd_nc_2;
257 	uint16_t id_acwu;		/* Atomic Compare & Write Unit (1.1) */
258 	uint16_t id_rsvd_nc_3;
259 	struct {			/* SGL Support (1.1) */
260 		uint16_t sgl_sup:1;	/* SGL Supported in NVM cmds (1.1) */
261 		uint16_t sgl_rsvd1:15;
262 		uint16_t sgl_bucket:1;	/* SGL Bit Bucket supported (1.1) */
263 		uint16_t sgl_rsvd2:15;
264 	} id_sgls;
265 	uint8_t id_rsvd_nc_4[768 - 540];
266 
267 	/* I/O Command Set Attributes */
268 	uint8_t id_subnqn[1024 - 768];	/* Subsystem Qualified Name (1.2.1+) */
269 	uint8_t id_rsvd_ioc[1792 - 1024];
270 	uint8_t id_nvmof[2048 - 1792];	/* NVMe over Fabrics */
271 
272 	/* Power State Descriptors */
273 	nvme_idctl_psd_t id_psd[32];
274 
275 	/* Vendor Specific */
276 	uint8_t id_vs[1024];
277 } nvme_identify_ctrl_t;
278 
279 /* NVMe Identify Namespace LBA Format */
280 typedef struct {
281 	uint16_t lbaf_ms;		/* Metadata Size */
282 	uint8_t lbaf_lbads;		/* LBA Data Size */
283 	uint8_t lbaf_rp:2;		/* Relative Performance */
284 	uint8_t lbaf_rsvd1:6;
285 } nvme_idns_lbaf_t;
286 
287 /* NVMe Identify Namespace Data Structure */
288 typedef struct {
289 	uint64_t id_nsize;		/* Namespace Size */
290 	uint64_t id_ncap;		/* Namespace Capacity */
291 	uint64_t id_nuse;		/* Namespace Utilization */
292 	struct {			/* Namespace Features */
293 		uint8_t f_thin:1;	/* Thin Provisioning */
294 		uint8_t f_rsvd:7;
295 	} id_nsfeat;
296 	uint8_t id_nlbaf;		/* Number of LBA formats */
297 	struct {			/* Formatted LBA size */
298 		uint8_t lba_format:4;	/* LBA format */
299 		uint8_t lba_extlba:1;	/* extended LBA (includes metadata) */
300 		uint8_t lba_rsvd:3;
301 	} id_flbas;
302 	struct {			/* Metadata Capabilities */
303 		uint8_t mc_extlba:1;	/* extended LBA transfers */
304 		uint8_t mc_separate:1;	/* separate metadata transfers */
305 		uint8_t mc_rsvd:6;
306 	} id_mc;
307 	struct {			/* Data Protection Capabilities */
308 		uint8_t dp_type1:1;	/* Protection Information Type 1 */
309 		uint8_t dp_type2:1;	/* Protection Information Type 2 */
310 		uint8_t dp_type3:1;	/* Protection Information Type 3 */
311 		uint8_t dp_first:1;	/* first 8 bytes of metadata */
312 		uint8_t dp_last:1;	/* last 8 bytes of metadata */
313 		uint8_t dp_rsvd:3;
314 	} id_dpc;
315 	struct {			/* Data Protection Settings */
316 		uint8_t dp_pinfo:3;	/* Protection Information enabled */
317 		uint8_t dp_first:1;	/* first 8 bytes of metadata */
318 		uint8_t dp_rsvd:4;
319 	} id_dps;
320 	struct {			/* NS Multi-Path/Sharing Cap (1.1) */
321 		uint8_t nm_shared:1;	/* NS is shared (1.1) */
322 		uint8_t nm_rsvd:7;
323 	} id_nmic;
324 	struct {			/* Reservation Capabilities (1.1) */
325 		uint8_t rc_persist:1;	/* Persist Through Power Loss (1.1) */
326 		uint8_t rc_wr_excl:1;	/* Write Exclusive (1.1) */
327 		uint8_t rc_excl:1;	/* Exclusive Access (1.1) */
328 		uint8_t rc_wr_excl_r:1;	/* Wr Excl - Registrants Only (1.1) */
329 		uint8_t rc_excl_r:1;	/* Excl Acc - Registrants Only (1.1) */
330 		uint8_t rc_wr_excl_a:1;	/* Wr Excl - All Registrants (1.1) */
331 		uint8_t rc_excl_a:1;	/* Excl Acc - All Registrants (1.1) */
332 		uint8_t rc_rsvd:1;
333 	} id_rescap;
334 	uint8_t id_fpi;			/* Format Progress Indicator (1.2) */
335 	uint8_t id_dfleat;		/* Deallocate Log. Block (1.3) */
336 	uint16_t id_nawun;		/* Atomic Write Unit Normal (1.2) */
337 	uint16_t id_nawupf;		/* Atomic Write Unit Power Fail (1.2) */
338 	uint16_t id_nacwu;		/* Atomic Compare & Write Unit (1.2) */
339 	uint16_t id_nabsn;		/* Atomic Boundary Size Normal (1.2) */
340 	uint16_t id_nbao;		/* Atomic Boundary Offset (1.2) */
341 	uint16_t id_nabspf;		/* Atomic Boundary Size Fail (1.2) */
342 	uint16_t id_noiob;		/* Optimal I/O Bondary (1.3) */
343 	uint8_t id_nvmcap[16];		/* NVM Capacity */
344 	uint8_t id_rsvd1[104 - 64];
345 	uint8_t id_nguid[16];		/* Namespace GUID (1.2) */
346 	uint8_t id_eui64[8];		/* IEEE Extended Unique Id (1.1) */
347 	nvme_idns_lbaf_t id_lbaf[16];	/* LBA Formats */
348 
349 	uint8_t id_rsvd2[384 - 192];
350 
351 	uint8_t id_vs[4096 - 384];	/* Vendor Specific */
352 } nvme_identify_nsid_t;
353 
354 /* NVMe Identify Primary Controller Capabilities */
355 typedef struct {
356 	uint16_t	nipc_cntlid;	/* Controller ID */
357 	uint16_t	nipc_portid;	/* Port Identifier */
358 	uint8_t		nipc_crt;	/* Controller Resource Types */
359 	uint8_t		nipc_rsvd0[32 - 5];
360 	uint32_t	nipc_vqfrt;	/* VQ Resources Flexible Total */
361 	uint32_t	nipc_vqrfa;	/* VQ Resources Flexible Assigned */
362 	uint16_t	nipc_vqrfap;	/* VQ Resources to Primary */
363 	uint16_t	nipc_vqprt;	/* VQ Resources Private Total */
364 	uint16_t	nipc_vqfrsm;	/* VQ Resources Secondary Max */
365 	uint16_t	nipc_vqgran;	/* VQ Flexible Resource Gran */
366 	uint8_t		nipc_rvsd1[64 - 48];
367 	uint32_t	nipc_vifrt;	/* VI Flexible total */
368 	uint32_t	nipc_virfa;	/* VI Flexible Assigned */
369 	uint16_t	nipc_virfap;	/* VI Flexible Allocatd to Primary */
370 	uint16_t	nipc_viprt;	/* VI Resources Private Total */
371 	uint16_t	nipc_vifrsm;	/* VI Resources Secondary Max */
372 	uint16_t	nipc_vigran;	/* VI Flexible Granularity */
373 	uint8_t		nipc_rsvd2[4096 - 80];
374 } nvme_identify_primary_caps_t;
375 
376 /*
377  * NVMe completion queue entry status field
378  */
379 typedef struct {
380 	uint16_t sf_p:1;		/* Phase Tag */
381 	uint16_t sf_sc:8;		/* Status Code */
382 	uint16_t sf_sct:3;		/* Status Code Type */
383 	uint16_t sf_rsvd2:2;
384 	uint16_t sf_m:1;		/* More */
385 	uint16_t sf_dnr:1;		/* Do Not Retry */
386 } nvme_cqe_sf_t;
387 
388 
389 /*
390  * NVMe Get Log Page
391  */
392 #define	NVME_LOGPAGE_ERROR	0x1	/* Error Information */
393 #define	NVME_LOGPAGE_HEALTH	0x2	/* SMART/Health Information */
394 #define	NVME_LOGPAGE_FWSLOT	0x3	/* Firmware Slot Information */
395 
396 typedef struct {
397 	uint64_t el_count;		/* Error Count */
398 	uint16_t el_sqid;		/* Submission Queue ID */
399 	uint16_t el_cid;		/* Command ID */
400 	nvme_cqe_sf_t el_sf;		/* Status Field */
401 	uint8_t	el_byte;		/* Parameter Error Location byte */
402 	uint8_t	el_bit:3;		/* Parameter Error Location bit */
403 	uint8_t el_rsvd1:5;
404 	uint64_t el_lba;		/* Logical Block Address */
405 	uint32_t el_nsid;		/* Namespace ID */
406 	uint8_t	el_vendor;		/* Vendor Specific Information avail */
407 	uint8_t el_rsvd2[64 - 29];
408 } nvme_error_log_entry_t;
409 
410 typedef struct {
411 	uint64_t lo;
412 	uint64_t hi;
413 } nvme_uint128_t;
414 
415 typedef struct {
416 	struct {			/* Critical Warning */
417 		uint8_t cw_avail:1;	/* available space too low */
418 		uint8_t cw_temp:1;	/* temperature too high */
419 		uint8_t cw_reliab:1;	/* degraded reliability */
420 		uint8_t cw_readonly:1;	/* media is read-only */
421 		uint8_t cw_volatile:1;	/* volatile memory backup failed */
422 		uint8_t cw_rsvd:3;
423 	} hl_crit_warn;
424 	uint16_t hl_temp;		/* Temperature */
425 	uint8_t hl_avail_spare;		/* Available Spare */
426 	uint8_t hl_avail_spare_thr;	/* Available Spare Threshold */
427 	uint8_t hl_used;		/* Percentage Used */
428 	uint8_t hl_rsvd1[32 - 6];
429 	nvme_uint128_t hl_data_read;	/* Data Units Read */
430 	nvme_uint128_t hl_data_write;	/* Data Units Written */
431 	nvme_uint128_t hl_host_read;	/* Host Read Commands */
432 	nvme_uint128_t hl_host_write;	/* Host Write Commands */
433 	nvme_uint128_t hl_ctrl_busy;	/* Controller Busy Time */
434 	nvme_uint128_t hl_power_cycles;	/* Power Cycles */
435 	nvme_uint128_t hl_power_on_hours; /* Power On Hours */
436 	nvme_uint128_t hl_unsafe_shutdn; /* Unsafe Shutdowns */
437 	nvme_uint128_t hl_media_errors;	/* Media Errors */
438 	nvme_uint128_t hl_errors_logged; /* Number of errors logged */
439 	/* Added in NVMe 1.2 */
440 	uint32_t hl_warn_temp_time;	/* Warning Composite Temp Time */
441 	uint32_t hl_crit_temp_time;	/* Critical Composite Temp Time */
442 	uint16_t hl_temp_sensor_1;	/* Temperature Sensor 1 */
443 	uint16_t hl_temp_sensor_2;	/* Temperature Sensor 2 */
444 	uint16_t hl_temp_sensor_3;	/* Temperature Sensor 3 */
445 	uint16_t hl_temp_sensor_4;	/* Temperature Sensor 4 */
446 	uint16_t hl_temp_sensor_5;	/* Temperature Sensor 5 */
447 	uint16_t hl_temp_sensor_6;	/* Temperature Sensor 6 */
448 	uint16_t hl_temp_sensor_7;	/* Temperature Sensor 7 */
449 	uint16_t hl_temp_sensor_8;	/* Temperature Sensor 8 */
450 	/* Added in NVMe 1.3 */
451 	uint32_t hl_tmtemp_1_tc;	/* Thermal Mgmt Temp 1 Transition # */
452 	uint32_t hl_tmtemp_2_tc;	/* Thermal Mgmt Temp 1 Transition # */
453 	uint32_t hl_tmtemp_1_time;	/* Time in Thermal Mgmt Temp 1 */
454 	uint32_t hl_tmtemp_2_time;	/* Time in Thermal Mgmt Temp 2 */
455 	uint8_t hl_rsvd2[512 - 232];
456 } nvme_health_log_t;
457 
458 /*
459  * The NVMe spec allows for up to seven firmware slots.
460  */
461 #define	NVME_MAX_FWSLOTS	7
462 #define	NVME_FWVER_SZ		8
463 
464 typedef struct {
465 	/* Active Firmware Slot */
466 	uint8_t fw_afi:3;
467 	uint8_t fw_rsvd1:1;
468 	/* Next Active Firmware Slot */
469 	uint8_t fw_next:3;
470 	uint8_t fw_rsvd2:1;
471 	uint8_t fw_rsvd3[7];
472 	/* Firmware Revision / Slot */
473 	char fw_frs[NVME_MAX_FWSLOTS][NVME_FWVER_SZ];
474 	uint8_t fw_rsvd4[512 - 64];
475 } nvme_fwslot_log_t;
476 
477 
478 /*
479  * NVMe Format NVM
480  */
481 #define	NVME_FRMT_SES_NONE	0
482 #define	NVME_FRMT_SES_USER	1
483 #define	NVME_FRMT_SES_CRYPTO	2
484 #define	NVME_FRMT_MAX_SES	2
485 
486 #define	NVME_FRMT_MAX_LBAF	15
487 
488 typedef union {
489 	struct {
490 		uint32_t fm_lbaf:4;		/* LBA Format */
491 		uint32_t fm_ms:1;		/* Metadata Settings */
492 		uint32_t fm_pi:3;		/* Protection Information */
493 		uint32_t fm_pil:1;		/* Prot. Information Location */
494 		uint32_t fm_ses:3;		/* Secure Erase Settings */
495 		uint32_t fm_resvd:20;
496 	} b;
497 	uint32_t r;
498 } nvme_format_nvm_t;
499 
500 
501 /*
502  * NVMe Get / Set Features
503  */
504 #define	NVME_FEAT_ARBITRATION	0x1	/* Command Arbitration */
505 #define	NVME_FEAT_POWER_MGMT	0x2	/* Power Management */
506 #define	NVME_FEAT_LBA_RANGE	0x3	/* LBA Range Type */
507 #define	NVME_FEAT_TEMPERATURE	0x4	/* Temperature Threshold */
508 #define	NVME_FEAT_ERROR		0x5	/* Error Recovery */
509 #define	NVME_FEAT_WRITE_CACHE	0x6	/* Volatile Write Cache */
510 #define	NVME_FEAT_NQUEUES	0x7	/* Number of Queues */
511 #define	NVME_FEAT_INTR_COAL	0x8	/* Interrupt Coalescing */
512 #define	NVME_FEAT_INTR_VECT	0x9	/* Interrupt Vector Configuration */
513 #define	NVME_FEAT_WRITE_ATOM	0xa	/* Write Atomicity */
514 #define	NVME_FEAT_ASYNC_EVENT	0xb	/* Asynchronous Event Configuration */
515 #define	NVME_FEAT_AUTO_PST	0xc	/* Autonomous Power State Transition */
516 					/* (1.1) */
517 
518 #define	NVME_FEAT_PROGRESS	0x80	/* Software Progress Marker */
519 
520 /* Arbitration Feature */
521 typedef union {
522 	struct {
523 		uint8_t arb_ab:3;	/* Arbitration Burst */
524 		uint8_t arb_rsvd:5;
525 		uint8_t arb_lpw;	/* Low Priority Weight */
526 		uint8_t arb_mpw;	/* Medium Priority Weight */
527 		uint8_t arb_hpw;	/* High Priority Weight */
528 	} b;
529 	uint32_t r;
530 } nvme_arbitration_t;
531 
532 /* Power Management Feature */
533 typedef union {
534 	struct {
535 		uint32_t pm_ps:5;	/* Power State */
536 		uint32_t pm_rsvd:27;
537 	} b;
538 	uint32_t r;
539 } nvme_power_mgmt_t;
540 
541 /* LBA Range Type Feature */
542 typedef union {
543 	struct {
544 		uint32_t lr_num:6;	/* Number of LBA ranges */
545 		uint32_t lr_rsvd:26;
546 	} b;
547 	uint32_t r;
548 } nvme_lba_range_type_t;
549 
550 typedef struct {
551 	uint8_t lr_type;		/* Type */
552 	struct {			/* Attributes */
553 		uint8_t lr_write:1;	/* may be overwritten */
554 		uint8_t lr_hidden:1;	/* hidden from OS/EFI/BIOS */
555 		uint8_t lr_rsvd1:6;
556 	} lr_attr;
557 	uint8_t lr_rsvd2[14];
558 	uint64_t lr_slba;		/* Starting LBA */
559 	uint64_t lr_nlb;		/* Number of Logical Blocks */
560 	uint8_t lr_guid[16];		/* Unique Identifier */
561 	uint8_t lr_rsvd3[16];
562 } nvme_lba_range_t;
563 
564 #define	NVME_LBA_RANGE_BUFSIZE	4096
565 
566 /* Temperature Threshold Feature */
567 typedef union {
568 	struct {
569 		uint16_t tt_tmpth;	/* Temperature Threshold */
570 		uint16_t tt_tmpsel:4;	/* Temperature Select */
571 		uint16_t tt_thsel:2;	/* Temperature Type */
572 		uint16_t tt_resv:10;
573 	} b;
574 	uint32_t r;
575 } nvme_temp_threshold_t;
576 
577 #define	NVME_TEMP_THRESH_MAX_SENSOR	8
578 #define	NVME_TEMP_THRESH_ALL	0xf
579 #define	NVME_TEMP_THRESH_OVER	0x00
580 #define	NVME_TEMP_THRESH_UNDER	0x01
581 
582 /* Error Recovery Feature */
583 typedef union {
584 	struct {
585 		uint16_t er_tler;	/* Time-Limited Error Recovery */
586 		uint16_t er_rsvd;
587 	} b;
588 	uint32_t r;
589 } nvme_error_recovery_t;
590 
591 /* Volatile Write Cache Feature */
592 typedef union {
593 	struct {
594 		uint32_t wc_wce:1;	/* Volatile Write Cache Enable */
595 		uint32_t wc_rsvd:31;
596 	} b;
597 	uint32_t r;
598 } nvme_write_cache_t;
599 
600 /* Number of Queues Feature */
601 typedef union {
602 	struct {
603 		uint16_t nq_nsq;	/* Number of Submission Queues */
604 		uint16_t nq_ncq;	/* Number of Completion Queues */
605 	} b;
606 	uint32_t r;
607 } nvme_nqueues_t;
608 
609 /* Interrupt Coalescing Feature */
610 typedef union {
611 	struct {
612 		uint8_t ic_thr;		/* Aggregation Threshold */
613 		uint8_t ic_time;	/* Aggregation Time */
614 		uint16_t ic_rsvd;
615 	} b;
616 	uint32_t r;
617 } nvme_intr_coal_t;
618 
619 /* Interrupt Configuration Features */
620 typedef union {
621 	struct {
622 		uint16_t iv_iv;		/* Interrupt Vector */
623 		uint16_t iv_cd:1;	/* Coalescing Disable */
624 		uint16_t iv_rsvd:15;
625 	} b;
626 	uint32_t r;
627 } nvme_intr_vect_t;
628 
629 /* Write Atomicity Feature */
630 typedef union {
631 	struct {
632 		uint32_t wa_dn:1;	/* Disable Normal */
633 		uint32_t wa_rsvd:31;
634 	} b;
635 	uint32_t r;
636 } nvme_write_atomicity_t;
637 
638 /* Asynchronous Event Configuration Feature */
639 typedef union {
640 	struct {
641 		uint8_t aec_avail:1;	/* available space too low */
642 		uint8_t aec_temp:1;	/* temperature too high */
643 		uint8_t aec_reliab:1;	/* degraded reliability */
644 		uint8_t aec_readonly:1;	/* media is read-only */
645 		uint8_t aec_volatile:1;	/* volatile memory backup failed */
646 		uint8_t aec_rsvd1:3;
647 		uint8_t aec_rsvd2[3];
648 	} b;
649 	uint32_t r;
650 } nvme_async_event_conf_t;
651 
652 /* Autonomous Power State Transition Feature (1.1) */
653 typedef union {
654 	struct {
655 		uint8_t	apst_apste:1;	/* APST enabled */
656 		uint8_t apst_rsvd:7;
657 	} b;
658 	uint8_t r;
659 } nvme_auto_power_state_trans_t;
660 
661 typedef struct {
662 	uint32_t apst_rsvd1:3;
663 	uint32_t apst_itps:5;	/* Idle Transition Power State */
664 	uint32_t apst_itpt:24;	/* Idle Time Prior to Transition */
665 	uint32_t apst_rsvd2;
666 } nvme_auto_power_state_t;
667 
668 #define	NVME_AUTO_PST_BUFSIZE	256
669 
670 /* Software Progress Marker Feature */
671 typedef union {
672 	struct {
673 		uint8_t spm_pbslc;	/* Pre-Boot Software Load Count */
674 		uint8_t spm_rsvd[3];
675 	} b;
676 	uint32_t r;
677 } nvme_software_progress_marker_t;
678 
679 /*
680  * Firmware Commit - Command Dword 10
681  */
682 #define	NVME_FWC_SAVE		0x0	/* Save image only */
683 #define	NVME_FWC_SAVE_ACTIVATE	0x1	/* Save and activate at next reset */
684 #define	NVME_FWC_ACTIVATE	0x2	/* Activate slot at next reset */
685 #define	NVME_FWC_ACTIVATE_IMMED	0x3	/* Activate slot immediately */
686 
687 /*
688  * Firmware slot number is only 3 bits, and zero is not allowed.
689  * Valid range is 1 to 7.
690  */
691 #define	NVME_FW_SLOT_MIN	1	/* lowest allowable slot number ... */
692 #define	NVME_FW_SLOT_MAX	7	/* ... and highest */
693 
694 /*
695  * Some constants to make verification of DWORD variables and arguments easier.
696  * A DWORD is 4 bytes.
697  */
698 #define	NVME_DWORD_SHIFT	2
699 #define	NVME_DWORD_SIZE		(1 << NVME_DWORD_SHIFT)
700 #define	NVME_DWORD_MASK		(NVME_DWORD_SIZE - 1)
701 
702 /*
703  * Maximum offset a firmware image can be load at is the number of
704  * DWORDS in a 32 bit field. Expressed in bytes its is:
705  */
706 #define	NVME_FW_OFFSETB_MAX	((u_longlong_t)UINT32_MAX << NVME_DWORD_SHIFT)
707 
708 typedef union {
709 	struct {
710 		uint32_t fc_slot:3;	/* Firmware slot */
711 		uint32_t fc_action:3;	/* Commit action */
712 		uint32_t fc_rsvd:26;
713 	} b;
714 	uint32_t r;
715 } nvme_firmware_commit_dw10_t;
716 
717 #pragma pack() /* pack(1) */
718 
719 /* NVMe completion status code type */
720 #define	NVME_CQE_SCT_GENERIC	0	/* Generic Command Status */
721 #define	NVME_CQE_SCT_SPECIFIC	1	/* Command Specific Status */
722 #define	NVME_CQE_SCT_INTEGRITY	2	/* Media and Data Integrity Errors */
723 #define	NVME_CQE_SCT_VENDOR	7	/* Vendor Specific */
724 
725 /* NVMe completion status code (generic) */
726 #define	NVME_CQE_SC_GEN_SUCCESS		0x0	/* Successful Completion */
727 #define	NVME_CQE_SC_GEN_INV_OPC		0x1	/* Invalid Command Opcode */
728 #define	NVME_CQE_SC_GEN_INV_FLD		0x2	/* Invalid Field in Command */
729 #define	NVME_CQE_SC_GEN_ID_CNFL		0x3	/* Command ID Conflict */
730 #define	NVME_CQE_SC_GEN_DATA_XFR_ERR	0x4	/* Data Transfer Error */
731 #define	NVME_CQE_SC_GEN_ABORT_PWRLOSS	0x5	/* Cmds Aborted / Pwr Loss */
732 #define	NVME_CQE_SC_GEN_INTERNAL_ERR	0x6	/* Internal Error */
733 #define	NVME_CQE_SC_GEN_ABORT_REQUEST	0x7	/* Command Abort Requested */
734 #define	NVME_CQE_SC_GEN_ABORT_SQ_DEL	0x8	/* Cmd Aborted / SQ deletion */
735 #define	NVME_CQE_SC_GEN_ABORT_FUSE_FAIL	0x9	/* Cmd Aborted / Failed Fused */
736 #define	NVME_CQE_SC_GEN_ABORT_FUSE_MISS	0xa	/* Cmd Aborted / Missing Fusd */
737 #define	NVME_CQE_SC_GEN_INV_NS		0xb	/* Inval Namespace or Format */
738 #define	NVME_CQE_SC_GEN_CMD_SEQ_ERR	0xc	/* Command Sequence Error */
739 #define	NVME_CQE_SC_GEN_INV_SGL_LAST	0xd	/* Inval SGL Last Seg Desc */
740 #define	NVME_CQE_SC_GEN_INV_SGL_NUM	0xe	/* Inval Number of SGL Desc */
741 #define	NVME_CQE_SC_GEN_INV_DSGL_LEN	0xf	/* Data SGL Length Invalid */
742 #define	NVME_CQE_SC_GEN_INV_MSGL_LEN	0x10	/* Metadata SGL Length Inval */
743 #define	NVME_CQE_SC_GEN_INV_SGL_DESC	0x11	/* SGL Descriptor Type Inval */
744 #define	NVME_CQE_SC_GEN_INV_USE_CMB	0x12	/* Inval use of Ctrl Mem Buf */
745 #define	NVME_CQE_SC_GEN_INV_PRP_OFF	0x13	/* PRP Offset Invalid */
746 #define	NVME_CQE_SC_GEN_AWU_EXCEEDED	0x14	/* Atomic Write Unit Exceeded */
747 
748 /* NVMe completion status code (generic NVM commands) */
749 #define	NVME_CQE_SC_GEN_NVM_LBA_RANGE	0x80	/* LBA Out Of Range */
750 #define	NVME_CQE_SC_GEN_NVM_CAP_EXC	0x81	/* Capacity Exceeded */
751 #define	NVME_CQE_SC_GEN_NVM_NS_NOTRDY	0x82	/* Namespace Not Ready */
752 #define	NVME_CQE_SC_GEN_NVM_RSV_CNFLCT	0x83	/* Reservation Conflict */
753 
754 /* NVMe completion status code (command specific) */
755 #define	NVME_CQE_SC_SPC_INV_CQ		0x0	/* Completion Queue Invalid */
756 #define	NVME_CQE_SC_SPC_INV_QID		0x1	/* Invalid Queue Identifier */
757 #define	NVME_CQE_SC_SPC_MAX_QSZ_EXC	0x2	/* Max Queue Size Exceeded */
758 #define	NVME_CQE_SC_SPC_ABRT_CMD_EXC	0x3	/* Abort Cmd Limit Exceeded */
759 #define	NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC	0x5	/* Async Event Request Limit */
760 #define	NVME_CQE_SC_SPC_INV_FW_SLOT	0x6	/* Invalid Firmware Slot */
761 #define	NVME_CQE_SC_SPC_INV_FW_IMG	0x7	/* Invalid Firmware Image */
762 #define	NVME_CQE_SC_SPC_INV_INT_VECT	0x8	/* Invalid Interrupt Vector */
763 #define	NVME_CQE_SC_SPC_INV_LOG_PAGE	0x9	/* Invalid Log Page */
764 #define	NVME_CQE_SC_SPC_INV_FORMAT	0xa	/* Invalid Format */
765 #define	NVME_CQE_SC_SPC_FW_RESET	0xb	/* FW Application Reset Reqd */
766 #define	NVME_CQE_SC_SPC_INV_Q_DEL	0xc	/* Invalid Queue Deletion */
767 #define	NVME_CQE_SC_SPC_FEAT_SAVE	0xd	/* Feature Id Not Saveable */
768 #define	NVME_CQE_SC_SPC_FEAT_CHG	0xe	/* Feature Not Changeable */
769 #define	NVME_CQE_SC_SPC_FEAT_NS_SPEC	0xf	/* Feature Not Namespace Spec */
770 #define	NVME_CQE_SC_SPC_FW_NSSR		0x10	/* FW Application NSSR Reqd */
771 #define	NVME_CQE_SC_SPC_FW_NEXT_RESET	0x11	/* FW Application Next Reqd */
772 #define	NVME_CQE_SC_SPC_FW_MTFA		0x12	/* FW Application Exceed MTFA */
773 #define	NVME_CQE_SC_SPC_FW_PROHIBITED	0x13	/* FW Application Prohibited */
774 #define	NVME_CQE_SC_SPC_FW_OVERLAP	0x14	/* Overlapping FW ranges */
775 
776 /* NVMe completion status code (NVM command specific */
777 #define	NVME_CQE_SC_SPC_NVM_CNFL_ATTR	0x80	/* Conflicting Attributes */
778 #define	NVME_CQE_SC_SPC_NVM_INV_PROT	0x81	/* Invalid Protection */
779 #define	NVME_CQE_SC_SPC_NVM_READONLY	0x82	/* Write to Read Only Range */
780 
781 /* NVMe completion status code (data / metadata integrity) */
782 #define	NVME_CQE_SC_INT_NVM_WRITE	0x80	/* Write Fault */
783 #define	NVME_CQE_SC_INT_NVM_READ	0x81	/* Unrecovered Read Error */
784 #define	NVME_CQE_SC_INT_NVM_GUARD	0x82	/* Guard Check Error */
785 #define	NVME_CQE_SC_INT_NVM_APPL_TAG	0x83	/* Application Tag Check Err */
786 #define	NVME_CQE_SC_INT_NVM_REF_TAG	0x84	/* Reference Tag Check Err */
787 #define	NVME_CQE_SC_INT_NVM_COMPARE	0x85	/* Compare Failure */
788 #define	NVME_CQE_SC_INT_NVM_ACCESS	0x86	/* Access Denied */
789 
790 #ifdef __cplusplus
791 }
792 #endif
793 
794 #endif /* _SYS_NVME_H */
795