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