xref: /illumos-gate/usr/src/uts/common/sys/nvme.h (revision ec6d8ca621f19d1cd1a46117b9b0fde4831c5794)
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  * Copyright 2021 Oxide Computer Company
17  * Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
18  */
19 
20 #ifndef _SYS_NVME_H
21 #define	_SYS_NVME_H
22 
23 #include <sys/types.h>
24 
25 #ifdef _KERNEL
26 #include <sys/types32.h>
27 #else
28 #include <stdint.h>
29 #endif
30 
31 /*
32  * Declarations used for communication between nvmeadm(8) and nvme(4D)
33  */
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 /*
40  * NVMe ioctl definitions
41  */
42 
43 #define	NVME_IOC			(('N' << 24) | ('V' << 16) | ('M' << 8))
44 #define	NVME_IOC_IDENTIFY_CTRL		(NVME_IOC | 1)
45 #define	NVME_IOC_IDENTIFY_NSID		(NVME_IOC | 2)
46 #define	NVME_IOC_CAPABILITIES		(NVME_IOC | 3)
47 #define	NVME_IOC_GET_LOGPAGE		(NVME_IOC | 4)
48 #define	NVME_IOC_GET_FEATURES		(NVME_IOC | 5)
49 #define	NVME_IOC_INTR_CNT		(NVME_IOC | 6)
50 #define	NVME_IOC_VERSION		(NVME_IOC | 7)
51 #define	NVME_IOC_FORMAT			(NVME_IOC | 8)
52 #define	NVME_IOC_DETACH			(NVME_IOC | 9)
53 #define	NVME_IOC_ATTACH			(NVME_IOC | 10)
54 #define	NVME_IOC_FIRMWARE_DOWNLOAD	(NVME_IOC | 11)
55 #define	NVME_IOC_FIRMWARE_COMMIT	(NVME_IOC | 12)
56 #define	NVME_IOC_PASSTHRU		(NVME_IOC | 13)
57 #define	NVME_IOC_NS_STATE		(NVME_IOC | 14)
58 #define	NVME_IOC_MAX			NVME_IOC_NS_STATE
59 
60 #define	IS_NVME_IOC(x)			((x) > NVME_IOC && (x) <= NVME_IOC_MAX)
61 #define	NVME_IOC_CMD(x)			((x) & 0xff)
62 
63 typedef struct {
64 	size_t		n_len;
65 	uintptr_t	n_buf;
66 	uint64_t	n_arg;
67 } nvme_ioctl_t;
68 
69 #ifdef _KERNEL
70 typedef struct {
71 	size32_t	n_len;
72 	uintptr32_t	n_buf;
73 	uint64_t	n_arg;
74 } nvme_ioctl32_t;
75 #endif
76 
77 /*
78  * NVMe capabilities
79  */
80 typedef struct {
81 	uint32_t mpsmax;		/* Memory Page Size Maximum */
82 	uint32_t mpsmin;		/* Memory Page Size Minimum */
83 } nvme_capabilities_t;
84 
85 /*
86  * NVMe version
87  */
88 typedef struct {
89 	uint16_t v_minor;
90 	uint16_t v_major;
91 } nvme_version_t;
92 
93 #define	NVME_VERSION_ATLEAST(v, maj, min) \
94 	(((v)->v_major) > (maj) || \
95 	((v)->v_major == (maj) && (v)->v_minor >= (min)))
96 
97 #define	NVME_VERSION_HIGHER(v, maj, min) \
98 	(((v)->v_major) > (maj) || \
99 	((v)->v_major == (maj) && (v)->v_minor > (min)))
100 
101 
102 #pragma pack(1)
103 
104 typedef struct {
105 	uint64_t lo;
106 	uint64_t hi;
107 } nvme_uint128_t;
108 
109 /*
110  * NVMe Identify data structures
111  */
112 
113 #define	NVME_IDENTIFY_BUFSIZE	4096	/* buffer size for Identify */
114 
115 /* NVMe Queue Entry Size bitfield */
116 typedef struct {
117 	uint8_t qes_min:4;		/* minimum entry size */
118 	uint8_t qes_max:4;		/* maximum entry size */
119 } nvme_idctl_qes_t;
120 
121 /* NVMe Power State Descriptor */
122 typedef struct {
123 	uint16_t psd_mp;		/* Maximum Power */
124 	uint8_t psd_rsvd1;
125 	uint8_t psd_mps:1;		/* Max Power Scale (1.1) */
126 	uint8_t psd_nops:1;		/* Non-Operational State (1.1) */
127 	uint8_t psd_rsvd2:6;
128 	uint32_t psd_enlat;		/* Entry Latency */
129 	uint32_t psd_exlat;		/* Exit Latency */
130 	uint8_t psd_rrt:5;		/* Relative Read Throughput */
131 	uint8_t psd_rsvd3:3;
132 	uint8_t psd_rrl:5;		/* Relative Read Latency */
133 	uint8_t psd_rsvd4:3;
134 	uint8_t psd_rwt:5;		/* Relative Write Throughput */
135 	uint8_t	psd_rsvd5:3;
136 	uint8_t psd_rwl:5;		/* Relative Write Latency */
137 	uint8_t psd_rsvd6:3;
138 	uint16_t psd_idlp;		/* Idle Power (1.2) */
139 	uint8_t psd_rsvd7:6;
140 	uint8_t psd_ips:2;		/* Idle Power Scale (1.2) */
141 	uint8_t psd_rsvd8;
142 	uint16_t psd_actp;		/* Active Power (1.2) */
143 	uint8_t psd_apw:3;		/* Active Power Workload (1.2) */
144 	uint8_t psd_rsvd9:3;
145 	uint8_t psd_aps:2;		/* Active Power Scale */
146 	uint8_t psd_rsvd10[9];
147 } nvme_idctl_psd_t;
148 
149 #define	NVME_SERIAL_SZ	20
150 #define	NVME_MODEL_SZ	40
151 
152 /* NVMe Identify Controller Data Structure */
153 typedef struct {
154 	/* Controller Capabilities & Features */
155 	uint16_t id_vid;		/* PCI vendor ID */
156 	uint16_t id_ssvid;		/* PCI subsystem vendor ID */
157 	char id_serial[NVME_SERIAL_SZ];	/* Serial Number */
158 	char id_model[NVME_MODEL_SZ];	/* Model Number */
159 	char id_fwrev[8];		/* Firmware Revision */
160 	uint8_t id_rab;			/* Recommended Arbitration Burst */
161 	uint8_t id_oui[3];		/* vendor IEEE OUI */
162 	struct {			/* Multi-Interface Capabilities */
163 		uint8_t m_multi_pci:1;	/* HW has multiple PCIe interfaces */
164 		uint8_t m_multi_ctrl:1; /* HW has multiple controllers (1.1) */
165 		uint8_t m_sr_iov:1;	/* Controller is SR-IOV virt fn (1.1) */
166 		uint8_t m_anar_sup:1;	/* ANA Reporting Supported (1.4) */
167 		uint8_t m_rsvd:4;
168 	} id_mic;
169 	uint8_t	id_mdts;		/* Maximum Data Transfer Size */
170 	uint16_t id_cntlid;		/* Unique Controller Identifier (1.1) */
171 	/* Added in NVMe 1.2 */
172 	uint32_t id_ver;		/* Version (1.2) */
173 	uint32_t id_rtd3r;		/* RTD3 Resume Latency (1.2) */
174 	uint32_t id_rtd3e;		/* RTD3 Entry Latency (1.2) */
175 	struct {
176 		uint32_t oaes_rsvd0:8;
177 		uint32_t oaes_nsan:1;	/* Namespace Attribute Notices (1.2) */
178 		uint32_t oaes_fwact:1;	/* Firmware Activation Notices (1.2) */
179 		uint32_t oaes_rsvd1:1;
180 		uint32_t oaes_ansacn:1;	/* Asymmetric NS Access Change (1.4) */
181 		uint32_t oaes_plat:1;	/* Predictable Lat Event Agg. (1.4) */
182 		uint32_t oaes_lbasi:1;	/* LBA Status Information (1.4) */
183 		uint32_t oaes_egeal:1;	/* Endurance Group Event Agg. (1.4) */
184 		uint32_t oaes_rsvd2:17;
185 	} id_oaes;
186 	struct {
187 		uint32_t ctrat_hid:1;	/* 128-bit Host Identifier (1.2)  */
188 		uint32_t ctrat_nops:1;	/* Non-Operational Power State (1.3) */
189 		uint32_t ctrat_nvmset:1; /* NVMe Sets (1.4) */
190 		uint32_t ctrat_rrl:1;	/* Read Recovery Levels (1.4) */
191 		uint32_t ctrat_engrp:1; /* Endurance Groups (1.4) */
192 		uint32_t ctrat_plm:1;	/* Predictable Latency Mode (1.4) */
193 		uint32_t ctrat_tbkas:1;	/* Traffic Based Keep Alive (1.4) */
194 		uint32_t ctrat_nsg:1;	/* Namespace Granularity (1.4) */
195 		uint32_t ctrat_sqass:1;	/* SQ Associations (1.4) */
196 		uint32_t ctrat_uuid:1;	/* UUID List (1.4) */
197 		uint32_t ctrat_rsvd:22;
198 	} id_ctratt;
199 	uint16_t id_rrls;		/* Read Recovery Levels (1.4) */
200 	uint8_t id_rsvd_cc[111-102];
201 	uint8_t id_cntrltype;		/* Controller Type (1.4) */
202 	uint8_t id_frguid[16];		/* FRU GUID (1.3) */
203 	uint16_t id_crdt1;		/* Command Retry Delay Time 1 (1.4) */
204 	uint16_t id_crdt2;		/* Command Retry Delay Time 2 (1.4) */
205 	uint16_t id_crdt3;		/* Command Retry Delay Time 3 (1.4) */
206 	uint8_t id_rsvd2_cc[240 - 134];
207 	uint8_t id_rsvd_nvmemi[253 - 240];
208 	/* NVMe-MI region */
209 	struct {			/* NVMe Subsystem Report */
210 		uint8_t nvmsr_nvmesd:1;	/* NVMe Storage Device */
211 		uint8_t nvmsr_nvmee:1;	/* NVMe Enclosure */
212 		uint8_t nvmsr_rsvd:6;
213 	} id_nvmsr;
214 	struct {			/* VPD Write Cycle Information */
215 		uint8_t vwci_crem:7;	/* Write Cycles Remaining */
216 		uint8_t vwci_valid:1;	/* Write Cycles Remaining Valid */
217 	} id_vpdwc;
218 	struct {			/* Management Endpoint Capabilities */
219 		uint8_t mec_smbusme:1;	/* SMBus Port Management Endpoint */
220 		uint8_t mec_pcieme:1;	/* PCIe Port Management Endpoint */
221 		uint8_t mec_rsvd:6;
222 	} id_mec;
223 
224 	/* Admin Command Set Attributes */
225 	struct {			/* Optional Admin Command Support */
226 		uint16_t oa_security:1;	/* Security Send & Receive */
227 		uint16_t oa_format:1;	/* Format NVM */
228 		uint16_t oa_firmware:1;	/* Firmware Activate & Download */
229 		uint16_t oa_nsmgmt:1;	/* Namespace Management (1.2) */
230 		uint16_t oa_selftest:1;	/* Self Test (1.3) */
231 		uint16_t oa_direct:1;	/* Directives (1.3) */
232 		uint16_t oa_nvmemi:1;	/* MI-Send/Recv (1.3) */
233 		uint16_t oa_virtmgmt:1;	/* Virtualization Management (1.3) */
234 		uint16_t oa_doorbell:1;	/* Doorbell Buffer Config (1.3) */
235 		uint16_t oa_lbastat:1;	/* LBA Status (1.4) */
236 		uint16_t oa_rsvd:6;
237 	} id_oacs;
238 	uint8_t	id_acl;			/* Abort Command Limit */
239 	uint8_t id_aerl;		/* Asynchronous Event Request Limit */
240 	struct {			/* Firmware Updates */
241 		uint8_t fw_readonly:1;	/* Slot 1 is Read-Only */
242 		uint8_t	fw_nslot:3;	/* number of firmware slots */
243 		uint8_t fw_norst:1;	/* Activate w/o reset (1.2) */
244 		uint8_t fw_rsvd:3;
245 	} id_frmw;
246 	struct {			/* Log Page Attributes */
247 		uint8_t lp_smart:1;	/* SMART/Health information per NS */
248 		uint8_t lp_cmdeff:1;	/* Command Effects (1.2) */
249 		uint8_t lp_extsup:1;	/* Extended Get Log Page (1.2) */
250 		uint8_t lp_telemetry:1;	/* Telemetry Log Pages (1.3) */
251 		uint8_t lp_persist:1;	/* Persistent Log Page (1.4) */
252 		uint8_t lp_rsvd:3;
253 	} id_lpa;
254 	uint8_t id_elpe;		/* Error Log Page Entries */
255 	uint8_t	id_npss;		/* Number of Power States */
256 	struct {			/* Admin Vendor Specific Command Conf */
257 		uint8_t av_spec:1;	/* use format from spec */
258 		uint8_t av_rsvd:7;
259 	} id_avscc;
260 	struct {			/* Autonomous Power State Trans (1.1) */
261 		uint8_t ap_sup:1;	/* APST supported (1.1) */
262 		uint8_t ap_rsvd:7;
263 	} id_apsta;
264 	uint16_t ap_wctemp;		/* Warning Composite Temp. (1.2) */
265 	uint16_t ap_cctemp;		/* Critical Composite Temp. (1.2) */
266 	uint16_t ap_mtfa;		/* Maximum Firmware Activation (1.2) */
267 	uint32_t ap_hmpre;		/* Host Memory Buf Pref Size (1.2) */
268 	uint32_t ap_hmmin;		/* Host Memory Buf Min Size (1.2) */
269 	nvme_uint128_t ap_tnvmcap;	/* Total NVM Capacity in Bytes (1.2) */
270 	nvme_uint128_t ap_unvmcap;	/* Unallocated NVM Capacity (1.2) */
271 	struct {			/* Replay Protected Mem. Block (1.2) */
272 		uint32_t rpmbs_units:3;	/* Number of targets */
273 		uint32_t rpmbs_auth:3;	/* Auth method */
274 		uint32_t rpmbs_rsvd:10;
275 		uint32_t rpmbs_tot:8;	/* Total size in 128KB */
276 		uint32_t rpmbs_acc:8;	/* Access size in 512B */
277 	} ap_rpmbs;
278 	/* Added in NVMe 1.3 */
279 	uint16_t ap_edstt;		/* Ext. Device Self-test time (1.3) */
280 	struct {			/* Device Self-test Options */
281 		uint8_t dsto_sub:1;	/* Subsystem level self-test (1.3) */
282 		uint8_t dsto_rsvd:7;
283 	} ap_dsto;
284 	uint8_t ap_fwug;		/* Firmware Update Granularity (1.3) */
285 	uint16_t ap_kas;		/* Keep Alive Support (1.2) */
286 	struct {			/* Host Thermal Management (1.3) */
287 		uint16_t hctma_hctm:1;	/* Host Controlled (1.3) */
288 		uint16_t hctma_rsvd:15;
289 	} ap_hctma;
290 	uint16_t ap_mntmt;		/* Minimum Thermal Temperature (1.3) */
291 	uint16_t ap_mxtmt;		/* Maximum Thermal Temperature (1.3) */
292 	struct {			/* Sanitize Caps */
293 		uint32_t san_ces:1;	/* Crypto Erase Support (1.3) */
294 		uint32_t san_bes:1;	/* Block Erase Support (1.3) */
295 		uint32_t san_ows:1;	/* Overwite Support (1.3) */
296 		uint32_t san_rsvd:26;
297 		uint32_t san_ndi:1;	/* No-deallocate Inhibited (1.4) */
298 		uint32_t san_nodmmas:2;	/* No-Deallocate Modifies Media (1.4) */
299 	} ap_sanitize;
300 	uint32_t ap_hmminds;		/* Host Mem Buf Min Desc Entry (1.4) */
301 	uint16_t ap_hmmaxd;		/* How Mem Max Desc Entries (1.4) */
302 	uint16_t ap_nsetidmax;		/* Max NVMe set identifier (1.4) */
303 	uint16_t ap_engidmax;		/* Max Endurance Group ID (1.4) */
304 	uint8_t ap_anatt;		/* ANA Transition Time (1.4) */
305 	struct {			/* Asymmetric Namespace Access Caps */
306 		uint8_t anacap_opt:1;	/* Optimized State (1.4) */
307 		uint8_t anacap_unopt:1;	/* Un-optimized State (1.4) */
308 		uint8_t anacap_inacc:1;	/* Inaccessible State (1.4) */
309 		uint8_t anacap_ploss:1;	/* Persistent Loss (1.4) */
310 		uint8_t anacap_chg:1;	/* Change State (1.4 ) */
311 		uint8_t anacap_rsvd:1;
312 		uint8_t anacap_grpns:1;	/* ID Changes with NS Attach (1.4) */
313 		uint8_t anacap_grpid:1;	/* Supports Group ID (1.4) */
314 	} ap_anacap;
315 	uint32_t ap_anagrpmax;		/* ANA Group ID Max (1.4) */
316 	uint32_t ap_nanagrpid;		/* Number of ANA Group IDs (1.4) */
317 	uint32_t ap_pels;		/* Persistent Event Log Size (1.4) */
318 	uint8_t id_rsvd_ac[512 - 356];
319 
320 	/* NVM Command Set Attributes */
321 	nvme_idctl_qes_t id_sqes;	/* Submission Queue Entry Size */
322 	nvme_idctl_qes_t id_cqes;	/* Completion Queue Entry Size */
323 	uint16_t id_maxcmd;		/* Max Outstanding Commands (1.3) */
324 	uint32_t id_nn;			/* Number of Namespaces */
325 	struct {			/* Optional NVM Command Support */
326 		uint16_t on_compare:1;	/* Compare */
327 		uint16_t on_wr_unc:1;	/* Write Uncorrectable */
328 		uint16_t on_dset_mgmt:1; /* Dataset Management */
329 		uint16_t on_wr_zero:1;	/* Write Zeros (1.1) */
330 		uint16_t on_save:1;	/* Save/Select in Get/Set Feat (1.1) */
331 		uint16_t on_reserve:1;	/* Reservations (1.1) */
332 		uint16_t on_ts:1;	/* Timestamp (1.3) */
333 		uint16_t on_verify:1;	/* Verify (1.4) */
334 		uint16_t on_rsvd:8;
335 	} id_oncs;
336 	struct {			/* Fused Operation Support */
337 		uint16_t f_cmp_wr:1;	/* Compare and Write */
338 		uint16_t f_rsvd:15;
339 	} id_fuses;
340 	struct {			/* Format NVM Attributes */
341 		uint8_t fn_format:1;	/* Format applies to all NS */
342 		uint8_t fn_sec_erase:1;	/* Secure Erase applies to all NS */
343 		uint8_t fn_crypt_erase:1; /* Cryptographic Erase supported */
344 		uint8_t fn_rsvd:5;
345 	} id_fna;
346 	struct {			/* Volatile Write Cache */
347 		uint8_t vwc_present:1;	/* Volatile Write Cache present */
348 		uint8_t vwc_nsflush:2;	/* Flush with NS ffffffff (1.4) */
349 		uint8_t rsvd:5;
350 	} id_vwc;
351 	uint16_t id_awun;		/* Atomic Write Unit Normal */
352 	uint16_t id_awupf;		/* Atomic Write Unit Power Fail */
353 	struct {			/* NVM Vendor Specific Command Conf */
354 		uint8_t nv_spec:1;	/* use format from spec */
355 		uint8_t nv_rsvd:7;
356 	} id_nvscc;
357 	struct {			/* Namespace Write Protection Caps */
358 		uint8_t nwpc_base:1;	/* Base support (1.4) */
359 		uint8_t nwpc_wpupc:1;	/* Write prot until power cycle (1.4) */
360 		uint8_t nwpc_permwp:1;	/* Permanent write prot (1.4) */
361 		uint8_t nwpc_rsvd:5;
362 	} id_nwpc;
363 	uint16_t id_acwu;		/* Atomic Compare & Write Unit (1.1) */
364 	uint16_t id_rsvd_nc_3;
365 	struct {			/* SGL Support (1.1) */
366 		uint16_t sgl_sup:2;	/* SGL Supported in NVM cmds (1.3) */
367 		uint16_t sgl_keyed:1;	/* Keyed SGL Support (1.2) */
368 		uint16_t sgl_rsvd1:13;
369 		uint16_t sgl_bucket:1;	/* SGL Bit Bucket supported (1.1) */
370 		uint16_t sgl_balign:1;	/* SGL Byte Aligned (1.2) */
371 		uint16_t sgl_sglgtd:1;	/* SGL Length Longer than Data (1.2) */
372 		uint16_t sgl_mptr:1;	/* SGL MPTR w/ SGL (1.2) */
373 		uint16_t sgl_offset:1;	/* SGL Address is offset (1.2) */
374 		uint16_t sgl_tport:1;	/* Transport SGL Data Block (1.4) */
375 		uint16_t sgl_rsvd2:10;
376 	} id_sgls;
377 	uint32_t id_mnam;		/* Maximum Number of Allowed NSes */
378 	uint8_t id_rsvd_nc_4[768 - 544];
379 
380 	/* I/O Command Set Attributes */
381 	uint8_t id_subnqn[1024 - 768];	/* Subsystem Qualified Name (1.2.1+) */
382 	uint8_t id_rsvd_ioc[1792 - 1024];
383 	uint8_t id_nvmof[2048 - 1792];	/* NVMe over Fabrics */
384 
385 	/* Power State Descriptors */
386 	nvme_idctl_psd_t id_psd[32];
387 
388 	/* Vendor Specific */
389 	uint8_t id_vs[1024];
390 } nvme_identify_ctrl_t;
391 
392 /*
393  * NVMe Controller Types
394  */
395 #define	NVME_CNTRLTYPE_RSVD	0
396 #define	NVME_CNTRLTYPE_IO	1
397 #define	NVME_CNTRLTYPE_DISC	2
398 #define	NVME_CNTRLTYPE_ADMIN	3
399 
400 /*
401  * RPMBS Authentication Types
402  */
403 #define	NVME_RPMBS_AUTH_HMAC_SHA256	0
404 
405 /*
406  * NODMMAS Values
407  */
408 #define	NVME_NODMMAS_UNDEF	0x00
409 #define	NVME_NODMMAS_NOMOD	0x01
410 #define	NVME_NODMMAS_DOMOD	0x02
411 
412 /*
413  * VWC NSID flushes
414  */
415 #define	NVME_VWCNS_UNKNOWN	0x00
416 #define	NVME_VWCNS_UNSUP	0x02
417 #define	NVME_VWCNS_SUP		0x03
418 
419 /*
420  * SGL Support Values
421  */
422 #define	NVME_SGL_UNSUP		0x00
423 #define	NVME_SGL_SUP_UNALIGN	0x01
424 #define	NVME_SGL_SUP_ALIGN	0x02
425 
426 /* NVMe Identify Namespace LBA Format */
427 typedef struct {
428 	uint16_t lbaf_ms;		/* Metadata Size */
429 	uint8_t lbaf_lbads;		/* LBA Data Size */
430 	uint8_t lbaf_rp:2;		/* Relative Performance */
431 	uint8_t lbaf_rsvd1:6;
432 } nvme_idns_lbaf_t;
433 
434 /* NVMe Identify Namespace Data Structure */
435 typedef struct {
436 	uint64_t id_nsize;		/* Namespace Size */
437 	uint64_t id_ncap;		/* Namespace Capacity */
438 	uint64_t id_nuse;		/* Namespace Utilization */
439 	struct {			/* Namespace Features */
440 		uint8_t f_thin:1;	/* Thin Provisioning */
441 		uint8_t f_nsabp:1;	/* Namespace atomics (1.2) */
442 		uint8_t f_dae:1;	/* Deallocated errors supported (1.2) */
443 		uint8_t f_uidreuse:1;	/* GUID reuse impossible (1.3) */
444 		uint8_t f_optperf:1;	/* Namespace I/O opt (1.4) */
445 		uint8_t f_rsvd:3;
446 	} id_nsfeat;
447 	uint8_t id_nlbaf;		/* Number of LBA formats */
448 	struct {			/* Formatted LBA size */
449 		uint8_t lba_format:4;	/* LBA format */
450 		uint8_t lba_extlba:1;	/* extended LBA (includes metadata) */
451 		uint8_t lba_rsvd:3;
452 	} id_flbas;
453 	struct {			/* Metadata Capabilities */
454 		uint8_t mc_extlba:1;	/* extended LBA transfers */
455 		uint8_t mc_separate:1;	/* separate metadata transfers */
456 		uint8_t mc_rsvd:6;
457 	} id_mc;
458 	struct {			/* Data Protection Capabilities */
459 		uint8_t dp_type1:1;	/* Protection Information Type 1 */
460 		uint8_t dp_type2:1;	/* Protection Information Type 2 */
461 		uint8_t dp_type3:1;	/* Protection Information Type 3 */
462 		uint8_t dp_first:1;	/* first 8 bytes of metadata */
463 		uint8_t dp_last:1;	/* last 8 bytes of metadata */
464 		uint8_t dp_rsvd:3;
465 	} id_dpc;
466 	struct {			/* Data Protection Settings */
467 		uint8_t dp_pinfo:3;	/* Protection Information enabled */
468 		uint8_t dp_first:1;	/* first 8 bytes of metadata */
469 		uint8_t dp_rsvd:4;
470 	} id_dps;
471 	struct {			/* NS Multi-Path/Sharing Cap (1.1) */
472 		uint8_t nm_shared:1;	/* NS is shared (1.1) */
473 		uint8_t nm_rsvd:7;
474 	} id_nmic;
475 	struct {			/* Reservation Capabilities (1.1) */
476 		uint8_t rc_persist:1;	/* Persist Through Power Loss (1.1) */
477 		uint8_t rc_wr_excl:1;	/* Write Exclusive (1.1) */
478 		uint8_t rc_excl:1;	/* Exclusive Access (1.1) */
479 		uint8_t rc_wr_excl_r:1;	/* Wr Excl - Registrants Only (1.1) */
480 		uint8_t rc_excl_r:1;	/* Excl Acc - Registrants Only (1.1) */
481 		uint8_t rc_wr_excl_a:1;	/* Wr Excl - All Registrants (1.1) */
482 		uint8_t rc_excl_a:1;	/* Excl Acc - All Registrants (1.1) */
483 		uint8_t rc_ign_ekey:1;	/* Ignore Existing Key (1.3) */
484 	} id_rescap;
485 	struct {			/* Format Progress Indicator (1.2) */
486 		uint8_t fpi_remp:7;	/* Percent NVM Format Remaining (1.2) */
487 		uint8_t fpi_sup:1;	/* Supported (1.2) */
488 	} id_fpi;
489 	uint8_t id_dfleat;		/* Deallocate Log. Block (1.3) */
490 	uint16_t id_nawun;		/* Atomic Write Unit Normal (1.2) */
491 	uint16_t id_nawupf;		/* Atomic Write Unit Power Fail (1.2) */
492 	uint16_t id_nacwu;		/* Atomic Compare & Write Unit (1.2) */
493 	uint16_t id_nabsn;		/* Atomic Boundary Size Normal (1.2) */
494 	uint16_t id_nbao;		/* Atomic Boundary Offset (1.2) */
495 	uint16_t id_nabspf;		/* Atomic Boundary Size Fail (1.2) */
496 	uint16_t id_noiob;		/* Optimal I/O Bondary (1.3) */
497 	nvme_uint128_t id_nvmcap;	/* NVM Capacity */
498 	uint16_t id_npwg;		/* NS Pref. Write Gran. (1.4) */
499 	uint16_t id_npwa;		/* NS Pref. Write Align. (1.4) */
500 	uint16_t id_npdg;		/* NS Pref. Deallocate Gran. (1.4) */
501 	uint16_t id_npda;		/* NS Pref. Deallocate Align. (1.4) */
502 	uint16_t id_nows;		/* NS. Optimal Write Size (1.4) */
503 	uint8_t id_rsvd1[92 - 74];
504 	uint32_t id_anagrpid;		/* ANA Group Identifier (1.4) */
505 	uint8_t id_rsvd2[99 - 96];
506 	struct {
507 		uint8_t nsa_wprot:1;	/* Write Protected (1.4) */
508 		uint8_t nsa_rsvd:7;
509 	} id_nsattr;
510 	uint16_t id_nvmsetid;		/* NVM Set Identifier (1.4) */
511 	uint16_t id_endgid;		/* Endurance Group Identifier (1.4) */
512 	uint8_t id_nguid[16];		/* Namespace GUID (1.2) */
513 	uint8_t id_eui64[8];		/* IEEE Extended Unique Id (1.1) */
514 	nvme_idns_lbaf_t id_lbaf[16];	/* LBA Formats */
515 
516 	uint8_t id_rsvd3[384 - 192];
517 
518 	uint8_t id_vs[4096 - 384];	/* Vendor Specific */
519 } nvme_identify_nsid_t;
520 
521 /* NVMe Identify Primary Controller Capabilities */
522 typedef struct {
523 	uint16_t	nipc_cntlid;	/* Controller ID */
524 	uint16_t	nipc_portid;	/* Port Identifier */
525 	uint8_t		nipc_crt;	/* Controller Resource Types */
526 	uint8_t		nipc_rsvd0[32 - 5];
527 	uint32_t	nipc_vqfrt;	/* VQ Resources Flexible Total */
528 	uint32_t	nipc_vqrfa;	/* VQ Resources Flexible Assigned */
529 	uint16_t	nipc_vqrfap;	/* VQ Resources to Primary */
530 	uint16_t	nipc_vqprt;	/* VQ Resources Private Total */
531 	uint16_t	nipc_vqfrsm;	/* VQ Resources Secondary Max */
532 	uint16_t	nipc_vqgran;	/* VQ Flexible Resource Gran */
533 	uint8_t		nipc_rvsd1[64 - 48];
534 	uint32_t	nipc_vifrt;	/* VI Flexible total */
535 	uint32_t	nipc_virfa;	/* VI Flexible Assigned */
536 	uint16_t	nipc_virfap;	/* VI Flexible Allocated to Primary */
537 	uint16_t	nipc_viprt;	/* VI Resources Private Total */
538 	uint16_t	nipc_vifrsm;	/* VI Resources Secondary Max */
539 	uint16_t	nipc_vigran;	/* VI Flexible Granularity */
540 	uint8_t		nipc_rsvd2[4096 - 80];
541 } nvme_identify_primary_caps_t;
542 
543 /*
544  * NVMe completion queue entry status field
545  */
546 typedef struct {
547 	uint16_t sf_p:1;		/* Phase Tag */
548 	uint16_t sf_sc:8;		/* Status Code */
549 	uint16_t sf_sct:3;		/* Status Code Type */
550 	uint16_t sf_rsvd2:2;
551 	uint16_t sf_m:1;		/* More */
552 	uint16_t sf_dnr:1;		/* Do Not Retry */
553 } nvme_cqe_sf_t;
554 
555 
556 /*
557  * NVMe Get Log Page
558  */
559 #define	NVME_LOGPAGE_ERROR	0x1	/* Error Information */
560 #define	NVME_LOGPAGE_HEALTH	0x2	/* SMART/Health Information */
561 #define	NVME_LOGPAGE_FWSLOT	0x3	/* Firmware Slot Information */
562 #define	NVME_LOGPAGE_NSCHANGE	0x4	/* Changed namespace (1.2) */
563 
564 typedef struct {
565 	uint64_t el_count;		/* Error Count */
566 	uint16_t el_sqid;		/* Submission Queue ID */
567 	uint16_t el_cid;		/* Command ID */
568 	nvme_cqe_sf_t el_sf;		/* Status Field */
569 	uint8_t	el_byte;		/* Parameter Error Location byte */
570 	uint8_t	el_bit:3;		/* Parameter Error Location bit */
571 	uint8_t el_rsvd1:5;
572 	uint64_t el_lba;		/* Logical Block Address */
573 	uint32_t el_nsid;		/* Namespace ID */
574 	uint8_t	el_vendor;		/* Vendor Specific Information avail */
575 	uint8_t el_rsvd2[64 - 29];
576 } nvme_error_log_entry_t;
577 
578 typedef struct {
579 	struct {			/* Critical Warning */
580 		uint8_t cw_avail:1;	/* available space too low */
581 		uint8_t cw_temp:1;	/* temperature too high */
582 		uint8_t cw_reliab:1;	/* degraded reliability */
583 		uint8_t cw_readonly:1;	/* media is read-only */
584 		uint8_t cw_volatile:1;	/* volatile memory backup failed */
585 		uint8_t cw_rsvd:3;
586 	} hl_crit_warn;
587 	uint16_t hl_temp;		/* Temperature */
588 	uint8_t hl_avail_spare;		/* Available Spare */
589 	uint8_t hl_avail_spare_thr;	/* Available Spare Threshold */
590 	uint8_t hl_used;		/* Percentage Used */
591 	uint8_t hl_rsvd1[32 - 6];
592 	nvme_uint128_t hl_data_read;	/* Data Units Read */
593 	nvme_uint128_t hl_data_write;	/* Data Units Written */
594 	nvme_uint128_t hl_host_read;	/* Host Read Commands */
595 	nvme_uint128_t hl_host_write;	/* Host Write Commands */
596 	nvme_uint128_t hl_ctrl_busy;	/* Controller Busy Time */
597 	nvme_uint128_t hl_power_cycles;	/* Power Cycles */
598 	nvme_uint128_t hl_power_on_hours; /* Power On Hours */
599 	nvme_uint128_t hl_unsafe_shutdn; /* Unsafe Shutdowns */
600 	nvme_uint128_t hl_media_errors;	/* Media Errors */
601 	nvme_uint128_t hl_errors_logged; /* Number of errors logged */
602 	/* Added in NVMe 1.2 */
603 	uint32_t hl_warn_temp_time;	/* Warning Composite Temp Time */
604 	uint32_t hl_crit_temp_time;	/* Critical Composite Temp Time */
605 	uint16_t hl_temp_sensor_1;	/* Temperature Sensor 1 */
606 	uint16_t hl_temp_sensor_2;	/* Temperature Sensor 2 */
607 	uint16_t hl_temp_sensor_3;	/* Temperature Sensor 3 */
608 	uint16_t hl_temp_sensor_4;	/* Temperature Sensor 4 */
609 	uint16_t hl_temp_sensor_5;	/* Temperature Sensor 5 */
610 	uint16_t hl_temp_sensor_6;	/* Temperature Sensor 6 */
611 	uint16_t hl_temp_sensor_7;	/* Temperature Sensor 7 */
612 	uint16_t hl_temp_sensor_8;	/* Temperature Sensor 8 */
613 	/* Added in NVMe 1.3 */
614 	uint32_t hl_tmtemp_1_tc;	/* Thermal Mgmt Temp 1 Transition # */
615 	uint32_t hl_tmtemp_2_tc;	/* Thermal Mgmt Temp 1 Transition # */
616 	uint32_t hl_tmtemp_1_time;	/* Time in Thermal Mgmt Temp 1 */
617 	uint32_t hl_tmtemp_2_time;	/* Time in Thermal Mgmt Temp 2 */
618 	uint8_t hl_rsvd2[512 - 232];
619 } nvme_health_log_t;
620 
621 /*
622  * The NVMe spec allows for up to seven firmware slots.
623  */
624 #define	NVME_MAX_FWSLOTS	7
625 #define	NVME_FWVER_SZ		8
626 
627 typedef struct {
628 	/* Active Firmware Slot */
629 	uint8_t fw_afi:3;
630 	uint8_t fw_rsvd1:1;
631 	/* Next Active Firmware Slot */
632 	uint8_t fw_next:3;
633 	uint8_t fw_rsvd2:1;
634 	uint8_t fw_rsvd3[7];
635 	/* Firmware Revision / Slot */
636 	char fw_frs[NVME_MAX_FWSLOTS][NVME_FWVER_SZ];
637 	uint8_t fw_rsvd4[512 - 64];
638 } nvme_fwslot_log_t;
639 
640 /*
641  * The NVMe spec specifies that the changed namespace list contains up to
642  * 1024 entries.
643  */
644 #define	NVME_NSCHANGE_LIST_SIZE	1024
645 
646 typedef struct {
647 	uint32_t	nscl_ns[NVME_NSCHANGE_LIST_SIZE];
648 } __packed nvme_nschange_list_t;
649 
650 /* CSTYLED */
651 _Static_assert(sizeof (nvme_nschange_list_t) == 4096, "bad size for nvme_nschange_list_t");
652 
653 /*
654  * NVMe Format NVM
655  */
656 #define	NVME_FRMT_SES_NONE	0
657 #define	NVME_FRMT_SES_USER	1
658 #define	NVME_FRMT_SES_CRYPTO	2
659 #define	NVME_FRMT_MAX_SES	2
660 
661 #define	NVME_FRMT_MAX_LBAF	15
662 
663 typedef union {
664 	struct {
665 		uint32_t fm_lbaf:4;		/* LBA Format */
666 		uint32_t fm_ms:1;		/* Metadata Settings */
667 		uint32_t fm_pi:3;		/* Protection Information */
668 		uint32_t fm_pil:1;		/* Prot. Information Location */
669 		uint32_t fm_ses:3;		/* Secure Erase Settings */
670 		uint32_t fm_resvd:20;
671 	} b;
672 	uint32_t r;
673 } nvme_format_nvm_t;
674 
675 
676 /*
677  * NVMe Get / Set Features
678  */
679 #define	NVME_FEAT_ARBITRATION	0x1	/* Command Arbitration */
680 #define	NVME_FEAT_POWER_MGMT	0x2	/* Power Management */
681 #define	NVME_FEAT_LBA_RANGE	0x3	/* LBA Range Type */
682 #define	NVME_FEAT_TEMPERATURE	0x4	/* Temperature Threshold */
683 #define	NVME_FEAT_ERROR		0x5	/* Error Recovery */
684 #define	NVME_FEAT_WRITE_CACHE	0x6	/* Volatile Write Cache */
685 #define	NVME_FEAT_NQUEUES	0x7	/* Number of Queues */
686 #define	NVME_FEAT_INTR_COAL	0x8	/* Interrupt Coalescing */
687 #define	NVME_FEAT_INTR_VECT	0x9	/* Interrupt Vector Configuration */
688 #define	NVME_FEAT_WRITE_ATOM	0xa	/* Write Atomicity */
689 #define	NVME_FEAT_ASYNC_EVENT	0xb	/* Asynchronous Event Configuration */
690 #define	NVME_FEAT_AUTO_PST	0xc	/* Autonomous Power State Transition */
691 					/* (1.1) */
692 
693 #define	NVME_FEAT_PROGRESS	0x80	/* Software Progress Marker */
694 
695 /* Arbitration Feature */
696 typedef union {
697 	struct {
698 		uint8_t arb_ab:3;	/* Arbitration Burst */
699 		uint8_t arb_rsvd:5;
700 		uint8_t arb_lpw;	/* Low Priority Weight */
701 		uint8_t arb_mpw;	/* Medium Priority Weight */
702 		uint8_t arb_hpw;	/* High Priority Weight */
703 	} b;
704 	uint32_t r;
705 } nvme_arbitration_t;
706 
707 /* Power Management Feature */
708 typedef union {
709 	struct {
710 		uint32_t pm_ps:5;	/* Power State */
711 		uint32_t pm_rsvd:27;
712 	} b;
713 	uint32_t r;
714 } nvme_power_mgmt_t;
715 
716 /* LBA Range Type Feature */
717 typedef union {
718 	struct {
719 		uint32_t lr_num:6;	/* Number of LBA ranges */
720 		uint32_t lr_rsvd:26;
721 	} b;
722 	uint32_t r;
723 } nvme_lba_range_type_t;
724 
725 typedef struct {
726 	uint8_t lr_type;		/* Type */
727 	struct {			/* Attributes */
728 		uint8_t lr_write:1;	/* may be overwritten */
729 		uint8_t lr_hidden:1;	/* hidden from OS/EFI/BIOS */
730 		uint8_t lr_rsvd1:6;
731 	} lr_attr;
732 	uint8_t lr_rsvd2[14];
733 	uint64_t lr_slba;		/* Starting LBA */
734 	uint64_t lr_nlb;		/* Number of Logical Blocks */
735 	uint8_t lr_guid[16];		/* Unique Identifier */
736 	uint8_t lr_rsvd3[16];
737 } nvme_lba_range_t;
738 
739 #define	NVME_LBA_RANGE_BUFSIZE	4096
740 
741 /* Temperature Threshold Feature */
742 typedef union {
743 	struct {
744 		uint16_t tt_tmpth;	/* Temperature Threshold */
745 		uint16_t tt_tmpsel:4;	/* Temperature Select */
746 		uint16_t tt_thsel:2;	/* Temperature Type */
747 		uint16_t tt_resv:10;
748 	} b;
749 	uint32_t r;
750 } nvme_temp_threshold_t;
751 
752 #define	NVME_TEMP_THRESH_MAX_SENSOR	8
753 #define	NVME_TEMP_THRESH_ALL	0xf
754 #define	NVME_TEMP_THRESH_OVER	0x00
755 #define	NVME_TEMP_THRESH_UNDER	0x01
756 
757 /* Error Recovery Feature */
758 typedef union {
759 	struct {
760 		uint16_t er_tler;	/* Time-Limited Error Recovery */
761 		uint16_t er_rsvd;
762 	} b;
763 	uint32_t r;
764 } nvme_error_recovery_t;
765 
766 /* Volatile Write Cache Feature */
767 typedef union {
768 	struct {
769 		uint32_t wc_wce:1;	/* Volatile Write Cache Enable */
770 		uint32_t wc_rsvd:31;
771 	} b;
772 	uint32_t r;
773 } nvme_write_cache_t;
774 
775 /* Number of Queues Feature */
776 typedef union {
777 	struct {
778 		uint16_t nq_nsq;	/* Number of Submission Queues */
779 		uint16_t nq_ncq;	/* Number of Completion Queues */
780 	} b;
781 	uint32_t r;
782 } nvme_nqueues_t;
783 
784 /* Interrupt Coalescing Feature */
785 typedef union {
786 	struct {
787 		uint8_t ic_thr;		/* Aggregation Threshold */
788 		uint8_t ic_time;	/* Aggregation Time */
789 		uint16_t ic_rsvd;
790 	} b;
791 	uint32_t r;
792 } nvme_intr_coal_t;
793 
794 /* Interrupt Configuration Features */
795 typedef union {
796 	struct {
797 		uint16_t iv_iv;		/* Interrupt Vector */
798 		uint16_t iv_cd:1;	/* Coalescing Disable */
799 		uint16_t iv_rsvd:15;
800 	} b;
801 	uint32_t r;
802 } nvme_intr_vect_t;
803 
804 /* Write Atomicity Feature */
805 typedef union {
806 	struct {
807 		uint32_t wa_dn:1;	/* Disable Normal */
808 		uint32_t wa_rsvd:31;
809 	} b;
810 	uint32_t r;
811 } nvme_write_atomicity_t;
812 
813 /* Asynchronous Event Configuration Feature */
814 typedef union {
815 	struct {
816 		uint8_t aec_avail:1;	/* Available space too low */
817 		uint8_t aec_temp:1;	/* Temperature too high */
818 		uint8_t aec_reliab:1;	/* Degraded reliability */
819 		uint8_t aec_readonly:1;	/* Media is read-only */
820 		uint8_t aec_volatile:1;	/* Volatile memory backup failed */
821 		uint8_t aec_rsvd1:3;
822 		uint8_t aec_nsan:1;	/* Namespace attribute notices (1.2) */
823 		uint8_t aec_fwact:1;	/* Firmware activation notices (1.2) */
824 		uint8_t aec_telln:1;	/* Telemetry log notices (1.3) */
825 		uint8_t aec_ansacn:1;	/* Asymm. NS access change (1.4) */
826 		uint8_t aec_plat:1;	/* Predictable latency ev. agg. (1.4) */
827 		uint8_t aec_lbasi:1;	/* LBA status information (1.4) */
828 		uint8_t aec_egeal:1;	/* Endurance group ev. agg. (1.4) */
829 		uint8_t aec_rsvd2:1;
830 		uint8_t aec_rsvd3[2];
831 	} b;
832 	uint32_t r;
833 } nvme_async_event_conf_t;
834 
835 /* Autonomous Power State Transition Feature (1.1) */
836 typedef union {
837 	struct {
838 		uint8_t	apst_apste:1;	/* APST enabled */
839 		uint8_t apst_rsvd:7;
840 	} b;
841 	uint8_t r;
842 } nvme_auto_power_state_trans_t;
843 
844 typedef struct {
845 	uint32_t apst_rsvd1:3;
846 	uint32_t apst_itps:5;	/* Idle Transition Power State */
847 	uint32_t apst_itpt:24;	/* Idle Time Prior to Transition */
848 	uint32_t apst_rsvd2;
849 } nvme_auto_power_state_t;
850 
851 #define	NVME_AUTO_PST_BUFSIZE	256
852 
853 /* Software Progress Marker Feature */
854 typedef union {
855 	struct {
856 		uint8_t spm_pbslc;	/* Pre-Boot Software Load Count */
857 		uint8_t spm_rsvd[3];
858 	} b;
859 	uint32_t r;
860 } nvme_software_progress_marker_t;
861 
862 /*
863  * Firmware Commit - Command Dword 10
864  */
865 #define	NVME_FWC_SAVE		0x0	/* Save image only */
866 #define	NVME_FWC_SAVE_ACTIVATE	0x1	/* Save and activate at next reset */
867 #define	NVME_FWC_ACTIVATE	0x2	/* Activate slot at next reset */
868 #define	NVME_FWC_ACTIVATE_IMMED	0x3	/* Activate slot immediately */
869 
870 /*
871  * Firmware slot number is only 3 bits, and zero is not allowed.
872  * Valid range is 1 to 7.
873  */
874 #define	NVME_FW_SLOT_MIN	1	/* lowest allowable slot number ... */
875 #define	NVME_FW_SLOT_MAX	7	/* ... and highest */
876 
877 /*
878  * Some constants to make verification of DWORD variables and arguments easier.
879  * A DWORD is 4 bytes.
880  */
881 #define	NVME_DWORD_SHIFT	2
882 #define	NVME_DWORD_SIZE		(1 << NVME_DWORD_SHIFT)
883 #define	NVME_DWORD_MASK		(NVME_DWORD_SIZE - 1)
884 
885 /*
886  * Maximum offset a firmware image can be load at is the number of
887  * DWORDS in a 32 bit field. Expressed in bytes its is:
888  */
889 #define	NVME_FW_OFFSETB_MAX	((u_longlong_t)UINT32_MAX << NVME_DWORD_SHIFT)
890 
891 typedef union {
892 	struct {
893 		uint32_t fc_slot:3;	/* Firmware slot */
894 		uint32_t fc_action:3;	/* Commit action */
895 		uint32_t fc_rsvd:26;
896 	} b;
897 	uint32_t r;
898 } nvme_firmware_commit_dw10_t;
899 
900 #pragma pack() /* pack(1) */
901 
902 /* NVMe completion status code type */
903 #define	NVME_CQE_SCT_GENERIC	0	/* Generic Command Status */
904 #define	NVME_CQE_SCT_SPECIFIC	1	/* Command Specific Status */
905 #define	NVME_CQE_SCT_INTEGRITY	2	/* Media and Data Integrity Errors */
906 #define	NVME_CQE_SCT_VENDOR	7	/* Vendor Specific */
907 
908 /* NVMe completion status code (generic) */
909 #define	NVME_CQE_SC_GEN_SUCCESS		0x0	/* Successful Completion */
910 #define	NVME_CQE_SC_GEN_INV_OPC		0x1	/* Invalid Command Opcode */
911 #define	NVME_CQE_SC_GEN_INV_FLD		0x2	/* Invalid Field in Command */
912 #define	NVME_CQE_SC_GEN_ID_CNFL		0x3	/* Command ID Conflict */
913 #define	NVME_CQE_SC_GEN_DATA_XFR_ERR	0x4	/* Data Transfer Error */
914 #define	NVME_CQE_SC_GEN_ABORT_PWRLOSS	0x5	/* Cmds Aborted / Pwr Loss */
915 #define	NVME_CQE_SC_GEN_INTERNAL_ERR	0x6	/* Internal Error */
916 #define	NVME_CQE_SC_GEN_ABORT_REQUEST	0x7	/* Command Abort Requested */
917 #define	NVME_CQE_SC_GEN_ABORT_SQ_DEL	0x8	/* Cmd Aborted / SQ deletion */
918 #define	NVME_CQE_SC_GEN_ABORT_FUSE_FAIL	0x9	/* Cmd Aborted / Failed Fused */
919 #define	NVME_CQE_SC_GEN_ABORT_FUSE_MISS	0xa	/* Cmd Aborted / Missing Fusd */
920 #define	NVME_CQE_SC_GEN_INV_NS		0xb	/* Inval Namespace or Format */
921 #define	NVME_CQE_SC_GEN_CMD_SEQ_ERR	0xc	/* Command Sequence Error */
922 #define	NVME_CQE_SC_GEN_INV_SGL_LAST	0xd	/* Inval SGL Last Seg Desc */
923 #define	NVME_CQE_SC_GEN_INV_SGL_NUM	0xe	/* Inval Number of SGL Desc */
924 #define	NVME_CQE_SC_GEN_INV_DSGL_LEN	0xf	/* Data SGL Length Invalid */
925 #define	NVME_CQE_SC_GEN_INV_MSGL_LEN	0x10	/* Metadata SGL Length Inval */
926 #define	NVME_CQE_SC_GEN_INV_SGL_DESC	0x11	/* SGL Descriptor Type Inval */
927 #define	NVME_CQE_SC_GEN_INV_USE_CMB	0x12	/* Inval use of Ctrl Mem Buf */
928 #define	NVME_CQE_SC_GEN_INV_PRP_OFF	0x13	/* PRP Offset Invalid */
929 #define	NVME_CQE_SC_GEN_AWU_EXCEEDED	0x14	/* Atomic Write Unit Exceeded */
930 
931 /* NVMe completion status code (generic NVM commands) */
932 #define	NVME_CQE_SC_GEN_NVM_LBA_RANGE	0x80	/* LBA Out Of Range */
933 #define	NVME_CQE_SC_GEN_NVM_CAP_EXC	0x81	/* Capacity Exceeded */
934 #define	NVME_CQE_SC_GEN_NVM_NS_NOTRDY	0x82	/* Namespace Not Ready */
935 #define	NVME_CQE_SC_GEN_NVM_RSV_CNFLCT	0x83	/* Reservation Conflict */
936 
937 /* NVMe completion status code (command specific) */
938 #define	NVME_CQE_SC_SPC_INV_CQ		0x0	/* Completion Queue Invalid */
939 #define	NVME_CQE_SC_SPC_INV_QID		0x1	/* Invalid Queue Identifier */
940 #define	NVME_CQE_SC_SPC_MAX_QSZ_EXC	0x2	/* Max Queue Size Exceeded */
941 #define	NVME_CQE_SC_SPC_ABRT_CMD_EXC	0x3	/* Abort Cmd Limit Exceeded */
942 #define	NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC	0x5	/* Async Event Request Limit */
943 #define	NVME_CQE_SC_SPC_INV_FW_SLOT	0x6	/* Invalid Firmware Slot */
944 #define	NVME_CQE_SC_SPC_INV_FW_IMG	0x7	/* Invalid Firmware Image */
945 #define	NVME_CQE_SC_SPC_INV_INT_VECT	0x8	/* Invalid Interrupt Vector */
946 #define	NVME_CQE_SC_SPC_INV_LOG_PAGE	0x9	/* Invalid Log Page */
947 #define	NVME_CQE_SC_SPC_INV_FORMAT	0xa	/* Invalid Format */
948 #define	NVME_CQE_SC_SPC_FW_RESET	0xb	/* FW Application Reset Reqd */
949 #define	NVME_CQE_SC_SPC_INV_Q_DEL	0xc	/* Invalid Queue Deletion */
950 #define	NVME_CQE_SC_SPC_FEAT_SAVE	0xd	/* Feature Id Not Saveable */
951 #define	NVME_CQE_SC_SPC_FEAT_CHG	0xe	/* Feature Not Changeable */
952 #define	NVME_CQE_SC_SPC_FEAT_NS_SPEC	0xf	/* Feature Not Namespace Spec */
953 #define	NVME_CQE_SC_SPC_FW_NSSR		0x10	/* FW Application NSSR Reqd */
954 #define	NVME_CQE_SC_SPC_FW_NEXT_RESET	0x11	/* FW Application Next Reqd */
955 #define	NVME_CQE_SC_SPC_FW_MTFA		0x12	/* FW Application Exceed MTFA */
956 #define	NVME_CQE_SC_SPC_FW_PROHIBITED	0x13	/* FW Application Prohibited */
957 #define	NVME_CQE_SC_SPC_FW_OVERLAP	0x14	/* Overlapping FW ranges */
958 
959 /* NVMe completion status code (NVM command specific */
960 #define	NVME_CQE_SC_SPC_NVM_CNFL_ATTR	0x80	/* Conflicting Attributes */
961 #define	NVME_CQE_SC_SPC_NVM_INV_PROT	0x81	/* Invalid Protection */
962 #define	NVME_CQE_SC_SPC_NVM_READONLY	0x82	/* Write to Read Only Range */
963 
964 /* NVMe completion status code (data / metadata integrity) */
965 #define	NVME_CQE_SC_INT_NVM_WRITE	0x80	/* Write Fault */
966 #define	NVME_CQE_SC_INT_NVM_READ	0x81	/* Unrecovered Read Error */
967 #define	NVME_CQE_SC_INT_NVM_GUARD	0x82	/* Guard Check Error */
968 #define	NVME_CQE_SC_INT_NVM_APPL_TAG	0x83	/* Application Tag Check Err */
969 #define	NVME_CQE_SC_INT_NVM_REF_TAG	0x84	/* Reference Tag Check Err */
970 #define	NVME_CQE_SC_INT_NVM_COMPARE	0x85	/* Compare Failure */
971 #define	NVME_CQE_SC_INT_NVM_ACCESS	0x86	/* Access Denied */
972 
973 /* Flags for NVMe passthru commands. */
974 #define	NVME_PASSTHRU_READ	0x1 /* Read from device */
975 #define	NVME_PASSTHRU_WRITE	0x2 /* Write to device */
976 
977 /* Error codes for NVMe passthru command validation. */
978 /* Must be sizeof(nvme_passthru_cmd_t) */
979 #define	NVME_PASSTHRU_ERR_CMD_SIZE	0x01
980 #define	NVME_PASSTHRU_ERR_NOT_SUPPORTED	0x02	/* Not supported on device */
981 #define	NVME_PASSTHRU_ERR_INVALID_OPCODE	0x03
982 #define	NVME_PASSTHRU_ERR_READ_AND_WRITE	0x04	/* Must read ^ write */
983 #define	NVME_PASSTHRU_ERR_INVALID_TIMEOUT	0x05
984 
985 /*
986  * Must be
987  * - multiple of 4 bytes in length
988  * - non-null iff length is non-zero
989  * - null if neither reading nor writing
990  * - non-null if either reading or writing
991  * - <= `nvme_vendor_specific_admin_cmd_size` in length, 16 MiB
992  * - <= UINT32_MAX in length
993  */
994 #define	NVME_PASSTHRU_ERR_INVALID_BUFFER	0x06
995 
996 
997 /* Generic struct for passing through vendor-unique commands to a device. */
998 typedef struct {
999 	uint8_t npc_opcode;	/* Command opcode. */
1000 	uint8_t npc_status;	/* Command completion status code. */
1001 	uint8_t npc_err;	/* Error-code if validation fails. */
1002 	uint8_t npc_rsvd0;	/* Align to 4 bytes */
1003 	uint32_t npc_timeout;	/* Command timeout, in seconds. */
1004 	uint32_t npc_flags;	/* Flags for the command. */
1005 	uint32_t npc_cdw0;	/* Command-specific result DWord 0 */
1006 	uint32_t npc_cdw12;	/* Command-specific DWord 12 */
1007 	uint32_t npc_cdw13;	/* Command-specific DWord 13 */
1008 	uint32_t npc_cdw14;	/* Command-specific DWord 14 */
1009 	uint32_t npc_cdw15;	/* Command-specific DWord 15 */
1010 	size_t npc_buflen;	/* Size of npc_buf. */
1011 	uintptr_t npc_buf;	/* I/O source or destination */
1012 } nvme_passthru_cmd_t;
1013 
1014 #ifdef _KERNEL
1015 typedef struct {
1016 	uint8_t npc_opcode;	/* Command opcode. */
1017 	uint8_t npc_status;	/* Command completion status code. */
1018 	uint8_t npc_err;	/* Error-code if validation fails. */
1019 	uint8_t npc_rsvd0;	/* Align to 4 bytes */
1020 	uint32_t npc_timeout;	/* Command timeout, in seconds. */
1021 	uint32_t npc_flags;	/* Flags for the command. */
1022 	uint32_t npc_cdw0;	/* Command-specific result DWord 0 */
1023 	uint32_t npc_cdw12;	/* Command-specific DWord 12 */
1024 	uint32_t npc_cdw13;	/* Command-specific DWord 13 */
1025 	uint32_t npc_cdw14;	/* Command-specific DWord 14 */
1026 	uint32_t npc_cdw15;	/* Command-specific DWord 15 */
1027 	size32_t npc_buflen;	/* Size of npc_buf. */
1028 	uintptr32_t npc_buf;	/* I/O source or destination */
1029 } nvme_passthru_cmd32_t;
1030 #endif
1031 
1032 /*
1033  * NVME namespace state flags for NVME_IOC_NS_STATE ioctl
1034  *
1035  * The values are defined entirely by the driver. Some states correspond to
1036  * namespace states described by the NVMe specification r1.3 section 6.1, others
1037  * are specific to the implementation of this driver.
1038  *
1039  * The states are as follows:
1040  * - ALLOCATED: the namespace exists in the controller as per the NVMe spec
1041  * - ACTIVE: the namespace exists and is attached to this controller as per the
1042  *   NVMe spec. Any namespace that is ACTIVE is also ALLOCATED. This must not be
1043  *   confused with the ATTACHED state.
1044  * - ATTACHED: the driver has attached a blkdev(4D) instance to this namespace.
1045  *   This state can be changed by userspace with the ioctls NVME_IOC_ATTACH and
1046  *   NVME_IOC_DETACH. A namespace can only be ATTACHED when it is not IGNORED.
1047  * - IGNORED: the driver ignores this namespace, it never attaches a blkdev(4D).
1048  *   Namespaces are IGNORED when they are not ACTIVE, or if they are ACTIVE but
1049  *   have certain properties that the driver cannot handle.
1050  */
1051 #define	NVME_NS_STATE_ALLOCATED		0x1
1052 #define	NVME_NS_STATE_ACTIVE		0x2
1053 #define	NVME_NS_STATE_ATTACHED		0x4
1054 #define	NVME_NS_STATE_IGNORED		0x8
1055 
1056 #ifdef __cplusplus
1057 }
1058 #endif
1059 
1060 #endif /* _SYS_NVME_H */
1061