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