xref: /illumos-gate/usr/src/uts/common/sys/nvme.h (revision 046911eb)
13d9b1a2aSHans Rosenfeld /*
23d9b1a2aSHans Rosenfeld  * This file and its contents are supplied under the terms of the
33d9b1a2aSHans Rosenfeld  * Common Development and Distribution License ("CDDL"), version 1.0.
43d9b1a2aSHans Rosenfeld  * You may only use this file in accordance with the terms of version
53d9b1a2aSHans Rosenfeld  * 1.0 of the CDDL.
63d9b1a2aSHans Rosenfeld  *
73d9b1a2aSHans Rosenfeld  * A full copy of the text of the CDDL should have accompanied this
83d9b1a2aSHans Rosenfeld  * source.  A copy of the CDDL is also available via the Internet at
93d9b1a2aSHans Rosenfeld  * http://www.illumos.org/license/CDDL.
103d9b1a2aSHans Rosenfeld  */
113d9b1a2aSHans Rosenfeld 
123d9b1a2aSHans Rosenfeld /*
133d9b1a2aSHans Rosenfeld  * Copyright 2016 Nexenta Systems, Inc.
143c6ffbabSRob Johnston  * Copyright 2020 Joyent, Inc.
15cf840871SPaul Winder  * Copyright 2019 Western Digital Corporation
16533affcbSRobert Mustacchi  * Copyright 2024 Oxide Computer Company
1704be5853SAndy Fiddaman  * Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
183d9b1a2aSHans Rosenfeld  */
193d9b1a2aSHans Rosenfeld 
203d9b1a2aSHans Rosenfeld #ifndef _SYS_NVME_H
213d9b1a2aSHans Rosenfeld #define	_SYS_NVME_H
223d9b1a2aSHans Rosenfeld 
233d9b1a2aSHans Rosenfeld #include <sys/types.h>
24153f3212SHans Rosenfeld #include <sys/debug.h>
25*046911ebSRobert Mustacchi #include <sys/stddef.h>
263d9b1a2aSHans Rosenfeld 
273d9b1a2aSHans Rosenfeld #ifdef _KERNEL
283d9b1a2aSHans Rosenfeld #include <sys/types32.h>
293d9b1a2aSHans Rosenfeld #else
30153f3212SHans Rosenfeld #include <sys/uuid.h>
313d9b1a2aSHans Rosenfeld #include <stdint.h>
323d9b1a2aSHans Rosenfeld #endif
333d9b1a2aSHans Rosenfeld 
343d9b1a2aSHans Rosenfeld /*
35bbf21555SRichard Lowe  * Declarations used for communication between nvmeadm(8) and nvme(4D)
363d9b1a2aSHans Rosenfeld  */
373d9b1a2aSHans Rosenfeld 
383d9b1a2aSHans Rosenfeld #ifdef __cplusplus
393d9b1a2aSHans Rosenfeld extern "C" {
403d9b1a2aSHans Rosenfeld #endif
413d9b1a2aSHans Rosenfeld 
423d9b1a2aSHans Rosenfeld /*
433d9b1a2aSHans Rosenfeld  * NVMe ioctl definitions
443d9b1a2aSHans Rosenfeld  */
453d9b1a2aSHans Rosenfeld 
463d9b1a2aSHans Rosenfeld #define	NVME_IOC			(('N' << 24) | ('V' << 16) | ('M' << 8))
47533affcbSRobert Mustacchi #define	NVME_IOC_CTRL_INFO		(NVME_IOC | 0)
48153f3212SHans Rosenfeld #define	NVME_IOC_IDENTIFY		(NVME_IOC | 1)
49533affcbSRobert Mustacchi #define	NVME_IOC_GET_LOGPAGE		(NVME_IOC | 2)
50533affcbSRobert Mustacchi #define	NVME_IOC_GET_FEATURE		(NVME_IOC | 3)
51533affcbSRobert Mustacchi #define	NVME_IOC_FORMAT			(NVME_IOC | 4)
52533affcbSRobert Mustacchi #define	NVME_IOC_DETACH			(NVME_IOC | 5)
53533affcbSRobert Mustacchi #define	NVME_IOC_ATTACH			(NVME_IOC | 6)
54533affcbSRobert Mustacchi #define	NVME_IOC_FIRMWARE_DOWNLOAD	(NVME_IOC | 7)
55533affcbSRobert Mustacchi #define	NVME_IOC_FIRMWARE_COMMIT	(NVME_IOC | 8)
56533affcbSRobert Mustacchi #define	NVME_IOC_PASSTHRU		(NVME_IOC | 9)
57533affcbSRobert Mustacchi #define	NVME_IOC_NS_INFO		(NVME_IOC | 10)
58533affcbSRobert Mustacchi #define	NVME_IOC_LOCK			(NVME_IOC | 11)
59533affcbSRobert Mustacchi #define	NVME_IOC_UNLOCK			(NVME_IOC | 12)
60744642a2SRobert Mustacchi #define	NVME_IOC_MAX			NVME_IOC_NS_INFO
613d9b1a2aSHans Rosenfeld 
623d9b1a2aSHans Rosenfeld #define	IS_NVME_IOC(x)			((x) > NVME_IOC && (x) <= NVME_IOC_MAX)
633d9b1a2aSHans Rosenfeld #define	NVME_IOC_CMD(x)			((x) & 0xff)
643d9b1a2aSHans Rosenfeld 
65533affcbSRobert Mustacchi /*
66533affcbSRobert Mustacchi  * This represents the set of all possible errors that can be returned from an
67533affcbSRobert Mustacchi  * ioctl. Our general rule of thumb is that we only will use an errno value to
68533affcbSRobert Mustacchi  * indicate that certain processing failed: a lack of privileges, bad minor, or
69533affcbSRobert Mustacchi  * failure to copy in and out the initial ioctl structure. However, if we get
70533affcbSRobert Mustacchi  * far enough that there is any other failure (including a failure to copy in
71533affcbSRobert Mustacchi  * and out nested data such as the identify command payload) then we will issue
72533affcbSRobert Mustacchi  * an error here. Put differently, our basic promise is that there should be a
73533affcbSRobert Mustacchi  * single straightforward meaning for any errno returned and instead all the
74533affcbSRobert Mustacchi  * nuance is here. Our goal is that no one should guess what of two dozen things
75533affcbSRobert Mustacchi  * an EINVAL might have referred to.
76533affcbSRobert Mustacchi  *
77533affcbSRobert Mustacchi  * When we are dealing with field parameters, there are three general classes of
78533affcbSRobert Mustacchi  * errors that we define that are common across all request structures:
79533affcbSRobert Mustacchi  *
80533affcbSRobert Mustacchi  *   <REQ>_<FIELD>_RANGE	RANGE class errors indicate that the value
81533affcbSRobert Mustacchi  *				passed in is outside the range that the device
82533affcbSRobert Mustacchi  *				supports. The range may vary based on the
83533affcbSRobert Mustacchi  *				specification. This is used both for issues like
84533affcbSRobert Mustacchi  *				bad alignment in a value (e.g. not 4-byte
85533affcbSRobert Mustacchi  *				aligned) or a value that is larger than the
86533affcbSRobert Mustacchi  *				maximum possible size. Because the namespace ID
87533affcbSRobert Mustacchi  *				is shared in every request in the controller and
88533affcbSRobert Mustacchi  *				is part of our standard ioctl handling, we use a
89533affcbSRobert Mustacchi  *				single set of errors for that.
90533affcbSRobert Mustacchi  *
91533affcbSRobert Mustacchi  *   <REQ>_<FIELD>_UNSUP	This indicates that the controller cannot
92533affcbSRobert Mustacchi  *				support any value in the given field. This is
93533affcbSRobert Mustacchi  *				either because the field was introduced in an
94533affcbSRobert Mustacchi  *				NVMe specification later than the controller
95533affcbSRobert Mustacchi  *				supports or because there is an explicit feature
96533affcbSRobert Mustacchi  *				bit that indicates whether or not this field is
97533affcbSRobert Mustacchi  *				valid. Entries here may or may not have a
98533affcbSRobert Mustacchi  *				namespace unsupported entry due to the fact that
99533affcbSRobert Mustacchi  *				this is command specific.
100533affcbSRobert Mustacchi  *
101533affcbSRobert Mustacchi  *  <REQ>_<FIELD>_UNUSE		This class is perhaps the weirdest. This
102533affcbSRobert Mustacchi  *				represents a case where a given field cannot be
103533affcbSRobert Mustacchi  *				set because it is not used based on the
104533affcbSRobert Mustacchi  *				specifics of the request. For example, if you're
105533affcbSRobert Mustacchi  *				getting the health log page, you may not set the
106533affcbSRobert Mustacchi  *				LSP or LSI for that log page, even if you have
107533affcbSRobert Mustacchi  *				an NVMe 1.4 controller that supports both fields
108533affcbSRobert Mustacchi  *				because they have no meaning. A similar example
109533affcbSRobert Mustacchi  *				would be setting a controller ID when it has no
110533affcbSRobert Mustacchi  *				meaning in a particular identify request.
111533affcbSRobert Mustacchi  *
112533affcbSRobert Mustacchi  * While every field will have a RANGE class error, some fields will not have an
113533affcbSRobert Mustacchi  * UNSUP or UNUSE class error depending on the specifics. A field that has
114533affcbSRobert Mustacchi  * always been present since NVMe 1.0 and is always valid, such as say the log
115533affcbSRobert Mustacchi  * page ID field for a get log page request or the length of a firmware download
116533affcbSRobert Mustacchi  * request, currently are always valid. It is possible that future revisions to
117533affcbSRobert Mustacchi  * the specification or our logic may change this.
118533affcbSRobert Mustacchi  */
119533affcbSRobert Mustacchi typedef enum {
120533affcbSRobert Mustacchi 	/*
121533affcbSRobert Mustacchi 	 * Indicates that the command actually completed successfully.
122533affcbSRobert Mustacchi 	 */
123533affcbSRobert Mustacchi 	NVME_IOCTL_E_OK	= 0,
124533affcbSRobert Mustacchi 	/*
125533affcbSRobert Mustacchi 	 * Indicates that the controller failed the command and the controller
126533affcbSRobert Mustacchi 	 * specific (SC/SCT) are available. For all other errors, those fields
127533affcbSRobert Mustacchi 	 * are reserved.
128533affcbSRobert Mustacchi 	 */
129533affcbSRobert Mustacchi 	NVME_IOCTL_E_CTRL_ERROR,
130533affcbSRobert Mustacchi 	/*
131533affcbSRobert Mustacchi 	 * Indicates that the controller is considered "dead" by the system and
132533affcbSRobert Mustacchi 	 * therefore is unusable. Separately, the controller may have been
133533affcbSRobert Mustacchi 	 * removed from the system due to hotplug or related. In that case, the
134533affcbSRobert Mustacchi 	 * gone variant is used to distinguish this.
135533affcbSRobert Mustacchi 	 */
136533affcbSRobert Mustacchi 	NVME_IOCTL_E_CTRL_DEAD,
137533affcbSRobert Mustacchi 	NVME_IOCTL_E_CTRL_GONE,
138533affcbSRobert Mustacchi 	/*
139533affcbSRobert Mustacchi 	 * Indicates that a bad namespace was requested. This would generally
140533affcbSRobert Mustacchi 	 * happen when referring to a namespace that is outside of controller's
141533affcbSRobert Mustacchi 	 * range.
142533affcbSRobert Mustacchi 	 */
143533affcbSRobert Mustacchi 	NVME_IOCTL_E_NS_RANGE,
144533affcbSRobert Mustacchi 	/*
145533affcbSRobert Mustacchi 	 * Indicates that a namespace is not usable in this context.
146533affcbSRobert Mustacchi 	 */
147533affcbSRobert Mustacchi 	NVME_IOCTL_E_NS_UNUSE,
148533affcbSRobert Mustacchi 	/*
149533affcbSRobert Mustacchi 	 * Indicates that the requested namespace could not be used because we
150533affcbSRobert Mustacchi 	 * are operating on a namespace minor and asked to operate on a
151533affcbSRobert Mustacchi 	 * different namespace.
152533affcbSRobert Mustacchi 	 */
153533affcbSRobert Mustacchi 	NVME_IOCTL_E_MINOR_WRONG_NS,
154533affcbSRobert Mustacchi 	/*
155533affcbSRobert Mustacchi 	 * Indicates that the requested ioctl can only operate on the controller
156533affcbSRobert Mustacchi 	 * minor and we were on a namespace minor. This is not used for when a
157533affcbSRobert Mustacchi 	 * namespace is incorrectly requested otherwise.
158533affcbSRobert Mustacchi 	 */
159533affcbSRobert Mustacchi 	NVME_IOCTL_E_NOT_CTRL,
160533affcbSRobert Mustacchi 	/*
161533affcbSRobert Mustacchi 	 * Indicates that we were asked to operate on the broadcast namespace
162533affcbSRobert Mustacchi 	 * either because it was specified or that was how the request was
163533affcbSRobert Mustacchi 	 * transformed and the broadcast namespace is not supported for this
164533affcbSRobert Mustacchi 	 * operation.
165533affcbSRobert Mustacchi 	 */
166533affcbSRobert Mustacchi 	NVME_IOCTL_E_NO_BCAST_NS,
167533affcbSRobert Mustacchi 	/*
168533affcbSRobert Mustacchi 	 * Indicates that the operation failed because the operation requires a
169533affcbSRobert Mustacchi 	 * controller or namespace write lock and the caller did not have it.
170533affcbSRobert Mustacchi 	 */
171533affcbSRobert Mustacchi 	NVME_IOCTL_E_NEED_CTRL_WRLOCK,
172533affcbSRobert Mustacchi 	NVME_IOCTL_E_NEED_NS_WRLOCK,
173533affcbSRobert Mustacchi 	/*
174533affcbSRobert Mustacchi 	 * Indicates that the operation could not proceed because someone else
175533affcbSRobert Mustacchi 	 * has exclusive access currently to the controller or namespace and
176533affcbSRobert Mustacchi 	 * therefore this request (which does not require exclusive access)
177533affcbSRobert Mustacchi 	 * could not proceed.
178533affcbSRobert Mustacchi 	 */
179533affcbSRobert Mustacchi 	NVME_IOCTL_E_CTRL_LOCKED,
180533affcbSRobert Mustacchi 	NVME_IOCTL_E_NS_LOCKED,
181533affcbSRobert Mustacchi 	/*
182533affcbSRobert Mustacchi 	 * Indicates that a standard log page was requested that the kernel
183533affcbSRobert Mustacchi 	 * doesn't know about.
184533affcbSRobert Mustacchi 	 */
185533affcbSRobert Mustacchi 	NVME_IOCTL_E_UNKNOWN_LOG_PAGE,
186533affcbSRobert Mustacchi 	/*
187533affcbSRobert Mustacchi 	 * Indicates that the controller does not support the requested log
188533affcbSRobert Mustacchi 	 * page; however, the kernel knows about it.
189533affcbSRobert Mustacchi 	 */
190533affcbSRobert Mustacchi 	NVME_IOCTL_E_UNSUP_LOG_PAGE,
191533affcbSRobert Mustacchi 	/*
192533affcbSRobert Mustacchi 	 * Indicates that the log page's scope requires operating on something
193533affcbSRobert Mustacchi 	 * that isn't what was requested. For example, trying to request the
194533affcbSRobert Mustacchi 	 * firmware information page on a namespace.
195533affcbSRobert Mustacchi 	 */
196533affcbSRobert Mustacchi 	NVME_IOCTL_E_BAD_LOG_SCOPE,
197533affcbSRobert Mustacchi 	/*
198533affcbSRobert Mustacchi 	 * Log page fields with bad values.
199533affcbSRobert Mustacchi 	 */
200533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_CSI_RANGE,
201533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_LID_RANGE,
202533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_LSP_RANGE,
203533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_LSI_RANGE,
204533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_RAE_RANGE,
205533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_SIZE_RANGE,
206533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_OFFSET_RANGE,
207533affcbSRobert Mustacchi 	/*
208533affcbSRobert Mustacchi 	 * Log page fields that may not be supported.
209533affcbSRobert Mustacchi 	 */
210533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_CSI_UNSUP,
211533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_LSP_UNSUP,
212533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_LSI_UNSUP,
213533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_RAE_UNSUP,
214533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_OFFSET_UNSUP,
215533affcbSRobert Mustacchi 	/*
216533affcbSRobert Mustacchi 	 * Log page fields that may not be usable, depending on context.
217533affcbSRobert Mustacchi 	 */
218533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_LSP_UNUSE,
219533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_LSI_UNUSE,
220533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOG_RAE_UNUSE,
221533affcbSRobert Mustacchi 	/*
222533affcbSRobert Mustacchi 	 * Indicates that no DMA memory was available for a request.
223533affcbSRobert Mustacchi 	 */
224533affcbSRobert Mustacchi 	NVME_IOCTL_E_NO_DMA_MEM,
225533affcbSRobert Mustacchi 	/*
226533affcbSRobert Mustacchi 	 * Indicates that there was no kernel memory avilable for the request.
227533affcbSRobert Mustacchi 	 */
228533affcbSRobert Mustacchi 	NVME_IOCTL_E_NO_KERN_MEM,
229533affcbSRobert Mustacchi 	/*
230533affcbSRobert Mustacchi 	 * Indicates that an error occurred while trying to fill out the DMA PRP
231533affcbSRobert Mustacchi 	 */
232533affcbSRobert Mustacchi 	NVME_IOCTL_E_BAD_PRP,
233533affcbSRobert Mustacchi 	/*
234533affcbSRobert Mustacchi 	 * Indicates that a pointer to user data to read from or write to was
235533affcbSRobert Mustacchi 	 * not valid and generated a fault. Specifically this is for items that
236533affcbSRobert Mustacchi 	 * an ioctl structure points to.
237533affcbSRobert Mustacchi 	 */
238533affcbSRobert Mustacchi 	NVME_IOCTL_E_BAD_USER_DATA,
239533affcbSRobert Mustacchi 	/*
240533affcbSRobert Mustacchi 	 * Indicates that the kernel does not know about the requested identify
241533affcbSRobert Mustacchi 	 * command.
242533affcbSRobert Mustacchi 	 */
243533affcbSRobert Mustacchi 	NVME_IOCTL_E_UNKNOWN_IDENTIFY,
244533affcbSRobert Mustacchi 	/*
245533affcbSRobert Mustacchi 	 * Indicates that the controller does not support the requested identify
246533affcbSRobert Mustacchi 	 * command.
247533affcbSRobert Mustacchi 	 */
248533affcbSRobert Mustacchi 	NVME_IOCTL_E_UNSUP_IDENTIFY,
249533affcbSRobert Mustacchi 	/*
250533affcbSRobert Mustacchi 	 * The following errors indicate either a bad value for a given identify
251533affcbSRobert Mustacchi 	 * argument. This would happen because the value is outside the
252533affcbSRobert Mustacchi 	 * supported range. There is no CNS or below as those are the
253533affcbSRobert Mustacchi 	 * higher-level errors right above this.
254533affcbSRobert Mustacchi 	 */
255533affcbSRobert Mustacchi 	NVME_IOCTL_E_IDENTIFY_CTRLID_RANGE,
256533affcbSRobert Mustacchi 	/*
257533affcbSRobert Mustacchi 	 * Next, we have the unsupported and unusable pieces. The nsid was
258533affcbSRobert Mustacchi 	 * supported starting in NVMe 1.0, therefore it is never unsupported.
259533affcbSRobert Mustacchi 	 * However, the controller ID both requires controller support and is
260533affcbSRobert Mustacchi 	 * not usable in several requests.
261533affcbSRobert Mustacchi 	 */
262533affcbSRobert Mustacchi 	NVME_IOCTL_E_IDENTIFY_CTRLID_UNSUP,
263533affcbSRobert Mustacchi 	NVME_IOCTL_E_IDENTIFY_CTRLID_UNUSE,
264533affcbSRobert Mustacchi 	/*
265533affcbSRobert Mustacchi 	 * Indicates that the controller does not support the NVMe spec's
266533affcbSRobert Mustacchi 	 * general vendor unique command format.
267533affcbSRobert Mustacchi 	 */
268533affcbSRobert Mustacchi 	NVME_IOCTL_E_CTRL_VUC_UNSUP,
269533affcbSRobert Mustacchi 	/*
270533affcbSRobert Mustacchi 	 * The following indicate bad values for given NVMe vendor unique
271533affcbSRobert Mustacchi 	 * command fields. All of the cdw1[2-5] fields are not part of this
272533affcbSRobert Mustacchi 	 * because there is nothing that we can validate.
273533affcbSRobert Mustacchi 	 */
274533affcbSRobert Mustacchi 	NVME_IOCTL_E_VUC_TIMEOUT_RANGE,
275533affcbSRobert Mustacchi 	NVME_IOCTL_E_VUC_OPCODE_RANGE,
276533affcbSRobert Mustacchi 	NVME_IOCTL_E_VUC_FLAGS_RANGE,
277533affcbSRobert Mustacchi 	NVME_IOCTL_E_VUC_IMPACT_RANGE,
278533affcbSRobert Mustacchi 	NVME_IOCTL_E_VUC_NDT_RANGE,
279533affcbSRobert Mustacchi 	/*
280533affcbSRobert Mustacchi 	 * These indicate that the VUC data and that the corresponding pair of
281533affcbSRobert Mustacchi 	 * fields do not agree with each other.
282533affcbSRobert Mustacchi 	 */
283533affcbSRobert Mustacchi 	NVME_IOCTL_E_INCONSIST_VUC_FLAGS_NDT,
284533affcbSRobert Mustacchi 	NVME_IOCTL_E_INCONSIST_VUC_BUF_NDT,
285533affcbSRobert Mustacchi 	/*
286533affcbSRobert Mustacchi 	 * Indicates that the operation in question did not succeed because
287533affcbSRobert Mustacchi 	 * blkdev failed to detach. Most often this happens because the device
288533affcbSRobert Mustacchi 	 * node is busy. Reasons the device node could be busy include that the
289533affcbSRobert Mustacchi 	 * device is in a zpool, a file system is mounted, a process has the
290533affcbSRobert Mustacchi 	 * block device open, etc.
291533affcbSRobert Mustacchi 	 */
292533affcbSRobert Mustacchi 	NVME_IOCTL_E_BLKDEV_DETACH,
293533affcbSRobert Mustacchi 	/*
294533affcbSRobert Mustacchi 	 * Indicates that the operation in question failed because we were
295533affcbSRobert Mustacchi 	 * unable to create and online a new blkdev child.
296533affcbSRobert Mustacchi 	 */
297533affcbSRobert Mustacchi 	NVME_IOCTL_E_BLKDEV_ATTACH,
298533affcbSRobert Mustacchi 	/*
299533affcbSRobert Mustacchi 	 * Indicates that the namespace requested for an attach is not supported
300533affcbSRobert Mustacchi 	 * by the system. This would happen due to properties of the namespace
301533affcbSRobert Mustacchi 	 * itself (e.g. utilizing metadata sectors).
302533affcbSRobert Mustacchi 	 */
303533affcbSRobert Mustacchi 	NVME_IOCTL_E_UNSUP_ATTACH_NS,
304533affcbSRobert Mustacchi 	/*
305533affcbSRobert Mustacchi 	 * Indicates that the format operation is not supported by the
306533affcbSRobert Mustacchi 	 * controller at all.
307533affcbSRobert Mustacchi 	 */
308533affcbSRobert Mustacchi 	NVME_IOCTL_E_CTRL_FORMAT_UNSUP,
309533affcbSRobert Mustacchi 	/*
310533affcbSRobert Mustacchi 	 * Indicates that the controller does not support the ability to perform
311533affcbSRobert Mustacchi 	 * a cryptographic secure erase.
312533affcbSRobert Mustacchi 	 */
313533affcbSRobert Mustacchi 	NVME_IOCTL_E_CTRL_CRYPTO_SE_UNSUP,
314533affcbSRobert Mustacchi 	/*
315533affcbSRobert Mustacchi 	 * Indicates that a format operation is targeting a namespace, but
316533affcbSRobert Mustacchi 	 * cannot be performed because it does not support formatting an
317533affcbSRobert Mustacchi 	 * individual namespace or performing a secure-erase of an individual
318533affcbSRobert Mustacchi 	 * namespace respectively.
319533affcbSRobert Mustacchi 	 */
320533affcbSRobert Mustacchi 	NVME_IOCTL_E_CTRL_NS_FORMAT_UNSUP,
321533affcbSRobert Mustacchi 	NVME_IOCTL_E_CTRL_NS_SE_UNSUP,
322533affcbSRobert Mustacchi 	/*
323533affcbSRobert Mustacchi 	 * The following indicate bad values for a format NVM request.
324533affcbSRobert Mustacchi 	 */
325533affcbSRobert Mustacchi 	NVME_IOCTL_E_FORMAT_LBAF_RANGE,
326533affcbSRobert Mustacchi 	NVME_IOCTL_E_FORMAT_SES_RANGE,
327533affcbSRobert Mustacchi 	/*
328533affcbSRobert Mustacchi 	 * Indicates that the requested LBA format is not supported due to its
329533affcbSRobert Mustacchi 	 * use of metadata.
330533affcbSRobert Mustacchi 	 */
331533affcbSRobert Mustacchi 	NVME_IOCTL_E_UNSUP_LBAF_META,
332533affcbSRobert Mustacchi 	/*
333533affcbSRobert Mustacchi 	 * Indicates that the firmware commands are not supported by the
334533affcbSRobert Mustacchi 	 * controller at all.
335533affcbSRobert Mustacchi 	 */
336533affcbSRobert Mustacchi 	NVME_IOCTL_E_CTRL_FW_UNSUP,
337533affcbSRobert Mustacchi 	/*
338533affcbSRobert Mustacchi 	 * Indicates that the controller has reported a firmware update
339533affcbSRobert Mustacchi 	 * granularity that exceeds the calculated / driver supported maximum
340533affcbSRobert Mustacchi 	 * DMA transfer size. As such we cannot perform this operation.
341533affcbSRobert Mustacchi 	 */
342533affcbSRobert Mustacchi 	NVME_IOCTL_E_FW_LOAD_IMPOS_GRAN,
343533affcbSRobert Mustacchi 	/*
344533affcbSRobert Mustacchi 	 * The following indicate bad values for a firmware load's length and
345533affcbSRobert Mustacchi 	 * offset.
346533affcbSRobert Mustacchi 	 */
347533affcbSRobert Mustacchi 	NVME_IOCTL_E_FW_LOAD_LEN_RANGE,
348533affcbSRobert Mustacchi 	NVME_IOCTL_E_FW_LOAD_OFFSET_RANGE,
349533affcbSRobert Mustacchi 	/*
350533affcbSRobert Mustacchi 	 * The following indicate bad values for a firmware commit's slot and
351533affcbSRobert Mustacchi 	 * action.
352533affcbSRobert Mustacchi 	 */
353533affcbSRobert Mustacchi 	NVME_IOCTL_E_FW_COMMIT_SLOT_RANGE,
354533affcbSRobert Mustacchi 	NVME_IOCTL_E_FW_COMMIT_ACTION_RANGE,
355533affcbSRobert Mustacchi 	/*
356533affcbSRobert Mustacchi 	 * Indicates that an explicit attempt was made to download an image into
357533affcbSRobert Mustacchi 	 * a read-only slot. Note, some instances of this cannot be caught prior
358533affcbSRobert Mustacchi 	 * to issuing a command to the controller (commit action 0b11 as it can
359533affcbSRobert Mustacchi 	 * be used whether there is or isn't a staged image) and will result in
360533affcbSRobert Mustacchi 	 * a controller error.
361533affcbSRobert Mustacchi 	 */
362533affcbSRobert Mustacchi 	NVME_IOCTL_E_RO_FW_SLOT,
363533affcbSRobert Mustacchi 	/*
364533affcbSRobert Mustacchi 	 * Indicates that the kernel doesn't know about the NVMe feature in
365533affcbSRobert Mustacchi 	 * question and therefore cannot proceed.
366533affcbSRobert Mustacchi 	 */
367533affcbSRobert Mustacchi 	NVME_IOCTL_E_UNKNOWN_FEATURE,
368533affcbSRobert Mustacchi 	/*
369533affcbSRobert Mustacchi 	 * Indicates that while the system knows about the feature in question,
370533affcbSRobert Mustacchi 	 * it is not supported by the controller.
371533affcbSRobert Mustacchi 	 */
372533affcbSRobert Mustacchi 	NVME_IOCTL_E_UNSUP_FEATURE,
373533affcbSRobert Mustacchi 	/*
374533affcbSRobert Mustacchi 	 * The following errors indicate a bad value for a given get feature
375533affcbSRobert Mustacchi 	 * field. This would happen because the value is outside the supported
376533affcbSRobert Mustacchi 	 * range.
377533affcbSRobert Mustacchi 	 */
378533affcbSRobert Mustacchi 	NVME_IOCTL_E_GET_FEAT_SEL_RANGE,
379533affcbSRobert Mustacchi 	NVME_IOCTL_E_GET_FEAT_CDW11_RANGE,
380533affcbSRobert Mustacchi 	NVME_IOCTL_E_GET_FEAT_DATA_RANGE,
381533affcbSRobert Mustacchi 	/*
382533affcbSRobert Mustacchi 	 * This set of errors indicate that the field is not supported. This can
383533affcbSRobert Mustacchi 	 * happen because a given get feature command doesn't support setting
384533affcbSRobert Mustacchi 	 * this value, the field isn't supported in this revision of the
385533affcbSRobert Mustacchi 	 * controller, or similar issues.
386533affcbSRobert Mustacchi 	 */
387533affcbSRobert Mustacchi 	NVME_IOCTL_E_GET_FEAT_SEL_UNSUP,
388533affcbSRobert Mustacchi 	/*
389533affcbSRobert Mustacchi 	 * Fields that may be circumstantially unusable.
390533affcbSRobert Mustacchi 	 */
391533affcbSRobert Mustacchi 	NVME_IOCTL_E_GET_FEAT_CDW11_UNUSE,
392533affcbSRobert Mustacchi 	NVME_IOCTL_E_GET_FEAT_DATA_UNUSE,
393533affcbSRobert Mustacchi 	/*
394533affcbSRobert Mustacchi 	 * The following errors indicate a bad lock type.
395533affcbSRobert Mustacchi 	 */
396533affcbSRobert Mustacchi 	NVME_IOCTL_E_BAD_LOCK_ENTITY,
397533affcbSRobert Mustacchi 	NVME_IOCTL_E_BAD_LOCK_LEVEL,
398533affcbSRobert Mustacchi 	NVME_IOCTL_E_BAD_LOCK_FLAGS,
399533affcbSRobert Mustacchi 	/*
400533affcbSRobert Mustacchi 	 * Indicates that a namespace open cannot lock or unlock a controller.
401533affcbSRobert Mustacchi 	 */
402533affcbSRobert Mustacchi 	NVME_IOCTL_E_NS_CANNOT_LOCK_CTRL,
403533affcbSRobert Mustacchi 	NVME_IOCTL_E_NS_CANNOT_UNLOCK_CTRL,
404533affcbSRobert Mustacchi 	/*
405533affcbSRobert Mustacchi 	 * Indicates that this lock is already held by the caller.
406533affcbSRobert Mustacchi 	 */
407533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOCK_ALREADY_HELD,
408533affcbSRobert Mustacchi 	/*
409533affcbSRobert Mustacchi 	 * Indicates that we cannot take the controller lock, because the
410533affcbSRobert Mustacchi 	 * caller already has an active namespace lock.
411533affcbSRobert Mustacchi 	 */
412533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOCK_NO_CTRL_WITH_NS,
413533affcbSRobert Mustacchi 	/*
414533affcbSRobert Mustacchi 	 * Indicates that we cannot take a namespace lock because a controller
415533affcbSRobert Mustacchi 	 * write lock already exists.
416533affcbSRobert Mustacchi 	 */
417533affcbSRobert Mustacchi 	NVME_IOCTL_LOCK_NO_NS_WITH_CTRL_WRLOCK,
418533affcbSRobert Mustacchi 	/*
419533affcbSRobert Mustacchi 	 * Indicates that we cannot take a namespace lock because we already
420533affcbSRobert Mustacchi 	 * have one.
421533affcbSRobert Mustacchi 	 */
422533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOCK_NO_2ND_NS,
423533affcbSRobert Mustacchi 	/*
424533affcbSRobert Mustacchi 	 * Indicate that a blocking wait for a lock was interrupted due to a
425533affcbSRobert Mustacchi 	 * signal.
426533affcbSRobert Mustacchi 	 */
427533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOCK_WAIT_SIGNAL,
428533affcbSRobert Mustacchi 	/*
429533affcbSRobert Mustacchi 	 * Indicates that the lock could not be acquired because it was already
430533affcbSRobert Mustacchi 	 * held and we were asked not to block on the lock.
431533affcbSRobert Mustacchi 	 */
432533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOCK_WOULD_BLOCK,
433533affcbSRobert Mustacchi 	/*
434533affcbSRobert Mustacchi 	 * Indicates that the lock operation could not proceed because the minor
435533affcbSRobert Mustacchi 	 * is already blocking on another lock operation.
436533affcbSRobert Mustacchi 	 */
437533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOCK_PENDING,
438533affcbSRobert Mustacchi 	/*
439533affcbSRobert Mustacchi 	 * Indicates that the requested lock could not be unlocked because it is
440533affcbSRobert Mustacchi 	 * not held. The minor may not hold the lock or it may be blocking for
441533affcbSRobert Mustacchi 	 * acquisition.
442533affcbSRobert Mustacchi 	 */
443533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOCK_NOT_HELD,
444533affcbSRobert Mustacchi 	/*
445533affcbSRobert Mustacchi 	 * Indicates that the requested lock could not be unlocked because the
446533affcbSRobert Mustacchi 	 * namespace requested is not the namespace that is currently locked.
447533affcbSRobert Mustacchi 	 */
448533affcbSRobert Mustacchi 	NVME_IOCTL_E_LOCK_WRONG_NS,
449533affcbSRobert Mustacchi 	/*
450533affcbSRobert Mustacchi 	 * Indicates that the request could not proceed because a namespace is
451533affcbSRobert Mustacchi 	 * attached to blkdev. This would block a format operation, a vendor
452533affcbSRobert Mustacchi 	 * unique command that indicated that it would impact all namespaces,
453533affcbSRobert Mustacchi 	 * etc.
454533affcbSRobert Mustacchi 	 */
455533affcbSRobert Mustacchi 	NVME_IOCTL_E_NS_BLKDEV_ATTACH,
456533affcbSRobert Mustacchi 	/*
457533affcbSRobert Mustacchi 	 * Indicates that the blkdev address somehow would have overflowed our
458533affcbSRobert Mustacchi 	 * internal buffer.
459533affcbSRobert Mustacchi 	 */
460533affcbSRobert Mustacchi 	NVME_IOCTL_E_BD_ADDR_OVER
461533affcbSRobert Mustacchi } nvme_ioctl_errno_t;
4623d9b1a2aSHans Rosenfeld 
4633d9b1a2aSHans Rosenfeld /*
464533affcbSRobert Mustacchi  * This structure is embedded as the first item of every ioctl. It is also used
465533affcbSRobert Mustacchi  * directly for the attach (NVME_IOC_ATTACH) and detach (NVME_IOC_DETACH)
466533affcbSRobert Mustacchi  * ioctls.
4673d9b1a2aSHans Rosenfeld  */
4683d9b1a2aSHans Rosenfeld typedef struct {
469533affcbSRobert Mustacchi 	/*
470533affcbSRobert Mustacchi 	 * This allows one to specify the namespace ID that the ioctl may
471533affcbSRobert Mustacchi 	 * target, if it supports it. This field may be left to zero to indicate
472533affcbSRobert Mustacchi 	 * that the current open device (whether the controller or a namespace)
473533affcbSRobert Mustacchi 	 * should be targeted. If a namespace is open, a value other than 0 or
474533affcbSRobert Mustacchi 	 * the current namespace's ID is invalid.
475533affcbSRobert Mustacchi 	 */
476533affcbSRobert Mustacchi 	uint32_t nioc_nsid;
477533affcbSRobert Mustacchi 	/*
478533affcbSRobert Mustacchi 	 * These next three values represent a possible error that may have
479533affcbSRobert Mustacchi 	 * occurred. On every ioctl nioc_drv_err is set to a value from the
480533affcbSRobert Mustacchi 	 * nvme_ioctl_errno_t enumeration. Anything other than NVME_IOCTL_E_OK
481533affcbSRobert Mustacchi 	 * indicates a failure of some kind. Some error values will put
482533affcbSRobert Mustacchi 	 * supplemental information in sct and sc. For example,
483533affcbSRobert Mustacchi 	 * NVME_IOCTL_E_CTRL_ERROR uses that as a way to return the raw error
484533affcbSRobert Mustacchi 	 * values from the controller for someone to inspect. Others may use
485533affcbSRobert Mustacchi 	 * this for their own well-defined supplemental information.
486533affcbSRobert Mustacchi 	 */
487533affcbSRobert Mustacchi 	uint32_t nioc_drv_err;
488533affcbSRobert Mustacchi 	uint32_t nioc_ctrl_sct;
489533affcbSRobert Mustacchi 	uint32_t nioc_ctrl_sc;
490533affcbSRobert Mustacchi } nvme_ioctl_common_t;
491533affcbSRobert Mustacchi 
492533affcbSRobert Mustacchi /*
493533affcbSRobert Mustacchi  * NVMe Identify Command (NVME_IOC_IDENTIFY).
494533affcbSRobert Mustacchi  */
495533affcbSRobert Mustacchi typedef struct {
496533affcbSRobert Mustacchi 	nvme_ioctl_common_t nid_common;
497533affcbSRobert Mustacchi 	uint32_t nid_cns;
498533affcbSRobert Mustacchi 	uint32_t nid_ctrlid;
499533affcbSRobert Mustacchi 	uintptr_t nid_data;
500533affcbSRobert Mustacchi } nvme_ioctl_identify_t;
501533affcbSRobert Mustacchi 
502533affcbSRobert Mustacchi /*
503533affcbSRobert Mustacchi  * The following constants describe the maximum values that may be used in
504533affcbSRobert Mustacchi  * various identify requests.
505533affcbSRobert Mustacchi  */
506533affcbSRobert Mustacchi #define	NVME_IDENTIFY_MAX_CTRLID	0xffff
507533affcbSRobert Mustacchi #define	NVME_IDENTIFY_MAX_NSID		0xffffffff
508533affcbSRobert Mustacchi #define	NVME_IDENTIFY_MAX_CNS_1v2	0xff
509533affcbSRobert Mustacchi #define	NVME_IDENTIFY_MAX_CNS_1v1	0x3
510533affcbSRobert Mustacchi #define	NVME_IDENTIFY_MAX_CNS		0x1
511533affcbSRobert Mustacchi 
512533affcbSRobert Mustacchi /*
513533affcbSRobert Mustacchi  * Get a specific feature (NVME_IOC_GET_FEATURE).
514533affcbSRobert Mustacchi  */
515533affcbSRobert Mustacchi typedef struct {
516533affcbSRobert Mustacchi 	nvme_ioctl_common_t nigf_common;
517533affcbSRobert Mustacchi 	uint32_t nigf_fid;
518533affcbSRobert Mustacchi 	uint32_t nigf_sel;
519533affcbSRobert Mustacchi 	uint32_t nigf_cdw11;
520533affcbSRobert Mustacchi 	uintptr_t nigf_data;
521533affcbSRobert Mustacchi 	uint64_t nigf_len;
522533affcbSRobert Mustacchi 	uint32_t nigf_cdw0;
523533affcbSRobert Mustacchi } nvme_ioctl_get_feature_t;
524533affcbSRobert Mustacchi 
525533affcbSRobert Mustacchi /*
526533affcbSRobert Mustacchi  * Feature maximums.
527533affcbSRobert Mustacchi  */
528533affcbSRobert Mustacchi #define	NVME_FEAT_MAX_FID	0xff
529533affcbSRobert Mustacchi #define	NVME_FEAT_MAX_SEL	0x3
530533affcbSRobert Mustacchi 
531533affcbSRobert Mustacchi /*
532533affcbSRobert Mustacchi  * Get a specific log page (NVME_IOC_GET_LOGPAGE). By default, unused fields
533533affcbSRobert Mustacchi  * should be left at zero.  the input data length is specified by nigl_len, in
534533affcbSRobert Mustacchi  * bytes. The NVMe specification does not provide a way for a controller to
535533affcbSRobert Mustacchi  * write less bytes than requested for a log page. It is undefined behavior if a
536533affcbSRobert Mustacchi  * log page read requests more data than is supported. If this is successful,
537533affcbSRobert Mustacchi  * nigl_len bytes will be copied out.
538533affcbSRobert Mustacchi  */
539533affcbSRobert Mustacchi typedef struct {
540533affcbSRobert Mustacchi 	nvme_ioctl_common_t nigl_common;
541533affcbSRobert Mustacchi 	uint32_t nigl_csi;
542533affcbSRobert Mustacchi 	uint32_t nigl_lid;
543533affcbSRobert Mustacchi 	uint32_t nigl_lsp;
544533affcbSRobert Mustacchi 	uint32_t nigl_lsi;
545533affcbSRobert Mustacchi 	uint32_t nigl_rae;
546533affcbSRobert Mustacchi 	uint64_t nigl_len;
547533affcbSRobert Mustacchi 	uint64_t nigl_offset;
548533affcbSRobert Mustacchi 	uintptr_t nigl_data;
549533affcbSRobert Mustacchi } nvme_ioctl_get_logpage_t;
550533affcbSRobert Mustacchi 
551533affcbSRobert Mustacchi /*
552533affcbSRobert Mustacchi  * The following constants describe the maximum values for fields that used in
553533affcbSRobert Mustacchi  * the log page request. Note, some of these change with the version. These
554533affcbSRobert Mustacchi  * values are inclusive. The default max is the lowest common value. Larger
555533affcbSRobert Mustacchi  * values are included here. While these values are what the command set
556533affcbSRobert Mustacchi  * maximums are, the device driver may support smaller minimums (e.g. for size).
557533affcbSRobert Mustacchi  */
558533affcbSRobert Mustacchi #define	NVME_LOG_MAX_LID	0xff
559533affcbSRobert Mustacchi #define	NVME_LOG_MAX_LSP	0x0f
560533affcbSRobert Mustacchi #define	NVME_LOG_MAX_LSP_2v0	0x7f
561533affcbSRobert Mustacchi #define	NVME_LOG_MAX_LSI	0xffff
562533affcbSRobert Mustacchi #define	NVME_LOG_MAX_UUID	0x7f
563533affcbSRobert Mustacchi #define	NVME_LOG_MAX_CSI	0xff
564533affcbSRobert Mustacchi #define	NVME_LOG_MAX_RAE	0x1
565533affcbSRobert Mustacchi #define	NVME_LOG_MAX_OFFSET	UINT64_MAX
566533affcbSRobert Mustacchi 
567533affcbSRobert Mustacchi /*
568533affcbSRobert Mustacchi  * These maximum size values are inclusive like the others. The fields are 12
569533affcbSRobert Mustacchi  * and 32-bits wide respectively, but are zero based. That is accounted for by
570533affcbSRobert Mustacchi  * the shifts below.
571533affcbSRobert Mustacchi  */
572533affcbSRobert Mustacchi #define	NVME_LOG_MAX_SIZE	((1ULL << 12ULL) * 4ULL)
573533affcbSRobert Mustacchi #define	NVME_LOG_MAX_SIZE_1v2	((1ULL << 32ULL) * 4ULL)
574533affcbSRobert Mustacchi 
575533affcbSRobert Mustacchi /*
576533affcbSRobert Mustacchi  * Inject a vendor-specific admin command (NVME_IOC_PASSTHRU).
577533affcbSRobert Mustacchi  */
578533affcbSRobert Mustacchi typedef struct {
579533affcbSRobert Mustacchi 	nvme_ioctl_common_t npc_common;	/* NSID and status */
580533affcbSRobert Mustacchi 	uint32_t npc_opcode;	/* Command opcode. */
581533affcbSRobert Mustacchi 	uint32_t npc_timeout;	/* Command timeout, in seconds. */
582533affcbSRobert Mustacchi 	uint32_t npc_flags;	/* Flags for the command. */
583533affcbSRobert Mustacchi 	uint32_t npc_impact;	/* Impact information */
584533affcbSRobert Mustacchi 	uint32_t npc_cdw0;	/* Command-specific result DWord 0 */
585533affcbSRobert Mustacchi 	uint32_t npc_cdw12;	/* Command-specific DWord 12 */
586533affcbSRobert Mustacchi 	uint32_t npc_cdw13;	/* Command-specific DWord 13 */
587533affcbSRobert Mustacchi 	uint32_t npc_cdw14;	/* Command-specific DWord 14 */
588533affcbSRobert Mustacchi 	uint32_t npc_cdw15;	/* Command-specific DWord 15 */
589533affcbSRobert Mustacchi 	uint64_t npc_buflen;	/* Size of npc_buf. */
590533affcbSRobert Mustacchi 	uintptr_t npc_buf;	/* I/O source or destination */
591533affcbSRobert Mustacchi } nvme_ioctl_passthru_t;
592533affcbSRobert Mustacchi 
593533affcbSRobert Mustacchi /*
594533affcbSRobert Mustacchi  * Constants for the passthru admin commands. Because the timeout is a kernel
595533affcbSRobert Mustacchi  * property, we don't include that here.
596533affcbSRobert Mustacchi  */
597533affcbSRobert Mustacchi #define	NVME_PASSTHRU_MIN_ADMIN_OPC	0xc0
598533affcbSRobert Mustacchi #define	NVME_PASSTHRU_MAX_ADMIN_OPC	0xff
599533affcbSRobert Mustacchi 
600533affcbSRobert Mustacchi /* Flags for NVMe passthru commands. */
601533affcbSRobert Mustacchi #define	NVME_PASSTHRU_READ	0x1 /* Read from device */
602533affcbSRobert Mustacchi #define	NVME_PASSTHRU_WRITE	0x2 /* Write to device */
603533affcbSRobert Mustacchi 
604533affcbSRobert Mustacchi /*
605533affcbSRobert Mustacchi  * Impact information for NVMe passthru commands. The current impact flags are
606533affcbSRobert Mustacchi  * defined as follows:
607533affcbSRobert Mustacchi  *
608533affcbSRobert Mustacchi  * NVME_IMPACT_NS	This implies that one or all of the namespaces may be
609533affcbSRobert Mustacchi  *			changed. This command will rescan all namespace after
610533affcbSRobert Mustacchi  *			this occurs and update our state as a result. However,
611533affcbSRobert Mustacchi  *			this requires that all such namespaces not be attached
612533affcbSRobert Mustacchi  *			to blkdev to continue.
613533affcbSRobert Mustacchi  */
614533affcbSRobert Mustacchi #define	NVME_IMPACT_NS		0x01
615533affcbSRobert Mustacchi 
616533affcbSRobert Mustacchi 
617533affcbSRobert Mustacchi /*
618533affcbSRobert Mustacchi  * Firmware download (NVME_IOC_FIRMWARE_DOWNLOAD).
619533affcbSRobert Mustacchi  */
620533affcbSRobert Mustacchi typedef struct {
621533affcbSRobert Mustacchi 	nvme_ioctl_common_t fwl_common;
622533affcbSRobert Mustacchi 	uintptr_t fwl_buf;
623533affcbSRobert Mustacchi 	uint64_t fwl_len;
624533affcbSRobert Mustacchi 	uint64_t fwl_off;
625533affcbSRobert Mustacchi } nvme_ioctl_fw_load_t;
626533affcbSRobert Mustacchi 
627533affcbSRobert Mustacchi /*
628533affcbSRobert Mustacchi  * Firmware commit (NVME_IOC_FIRMWARE_COMMIT). This was previously called
629533affcbSRobert Mustacchi  * firmware activate in earlier specification revisions.
630533affcbSRobert Mustacchi  */
631533affcbSRobert Mustacchi typedef struct {
632533affcbSRobert Mustacchi 	nvme_ioctl_common_t fwc_common;
633533affcbSRobert Mustacchi 	uint32_t fwc_slot;
634533affcbSRobert Mustacchi 	uint32_t fwc_action;
635533affcbSRobert Mustacchi } nvme_ioctl_fw_commit_t;
636533affcbSRobert Mustacchi 
637533affcbSRobert Mustacchi /*
638533affcbSRobert Mustacchi  * Format NVM command (NVME_IOC_FORMAT)
639533affcbSRobert Mustacchi  */
640533affcbSRobert Mustacchi typedef struct {
641533affcbSRobert Mustacchi 	nvme_ioctl_common_t nif_common;
642533affcbSRobert Mustacchi 	uint32_t nif_lbaf;
643533affcbSRobert Mustacchi 	uint32_t nif_ses;
644533affcbSRobert Mustacchi } nvme_ioctl_format_t;
645533affcbSRobert Mustacchi 
646533affcbSRobert Mustacchi typedef enum {
647533affcbSRobert Mustacchi 	NVME_LOCK_E_CTRL = 1,
648533affcbSRobert Mustacchi 	NVME_LOCK_E_NS
649533affcbSRobert Mustacchi } nvme_lock_ent_t;
650533affcbSRobert Mustacchi 
651533affcbSRobert Mustacchi typedef enum {
652533affcbSRobert Mustacchi 	NVME_LOCK_L_READ	= 1,
653533affcbSRobert Mustacchi 	NVME_LOCK_L_WRITE
654533affcbSRobert Mustacchi } nvme_lock_level_t;
655533affcbSRobert Mustacchi 
656533affcbSRobert Mustacchi typedef enum {
657533affcbSRobert Mustacchi 	NVME_LOCK_F_DONT_BLOCK	= 1 << 0
658533affcbSRobert Mustacchi } nvme_lock_flags_t;
659533affcbSRobert Mustacchi 
660533affcbSRobert Mustacchi /*
661533affcbSRobert Mustacchi  * Lock structure (NVME_IOC_LOCK).
662533affcbSRobert Mustacchi  */
663533affcbSRobert Mustacchi typedef struct {
664533affcbSRobert Mustacchi 	nvme_ioctl_common_t nil_common;
665533affcbSRobert Mustacchi 	nvme_lock_ent_t nil_ent;
666533affcbSRobert Mustacchi 	nvme_lock_level_t nil_level;
667533affcbSRobert Mustacchi 	nvme_lock_flags_t nil_flags;
668533affcbSRobert Mustacchi } nvme_ioctl_lock_t;
669533affcbSRobert Mustacchi 
670533affcbSRobert Mustacchi /*
671533affcbSRobert Mustacchi  * Unlock structure (NVME_IOC_UNLOCK).
672533affcbSRobert Mustacchi  */
673533affcbSRobert Mustacchi typedef struct {
674533affcbSRobert Mustacchi 	nvme_ioctl_common_t niu_common;
675533affcbSRobert Mustacchi 	nvme_lock_ent_t niu_ent;
676533affcbSRobert Mustacchi } nvme_ioctl_unlock_t;
677533affcbSRobert Mustacchi 
678533affcbSRobert Mustacchi /*
679533affcbSRobert Mustacchi  * 32-bit ioctl structures. These must be packed to be 4 bytes to get the proper
680533affcbSRobert Mustacchi  * ILP32 sizing.
681533affcbSRobert Mustacchi  */
682533affcbSRobert Mustacchi #if defined(_KERNEL) && defined(_SYSCALL32)
683533affcbSRobert Mustacchi #pragma pack(4)
684533affcbSRobert Mustacchi typedef struct {
685533affcbSRobert Mustacchi 	nvme_ioctl_common_t nid_common;
686533affcbSRobert Mustacchi 	uint32_t nid_cns;
687533affcbSRobert Mustacchi 	uint32_t nid_ctrlid;
688533affcbSRobert Mustacchi 	uintptr32_t nid_data;
689533affcbSRobert Mustacchi } nvme_ioctl_identify32_t;
690533affcbSRobert Mustacchi 
691533affcbSRobert Mustacchi typedef struct {
692533affcbSRobert Mustacchi 	nvme_ioctl_common_t nigf_common;
693533affcbSRobert Mustacchi 	uint32_t nigf_fid;
694533affcbSRobert Mustacchi 	uint32_t nigf_sel;
695533affcbSRobert Mustacchi 	uint32_t nigf_cdw11;
696533affcbSRobert Mustacchi 	uintptr32_t nigf_data;
697533affcbSRobert Mustacchi 	uint64_t nigf_len;
698533affcbSRobert Mustacchi 	uint32_t nigf_cdw0;
699533affcbSRobert Mustacchi } nvme_ioctl_get_feature32_t;
700533affcbSRobert Mustacchi 
701533affcbSRobert Mustacchi typedef struct {
702533affcbSRobert Mustacchi 	nvme_ioctl_common_t nigl_common;
703533affcbSRobert Mustacchi 	uint32_t nigl_csi;
704533affcbSRobert Mustacchi 	uint32_t nigl_lid;
705533affcbSRobert Mustacchi 	uint32_t nigl_lsp;
706533affcbSRobert Mustacchi 	uint32_t nigl_lsi;
707533affcbSRobert Mustacchi 	uint32_t nigl_rae;
708533affcbSRobert Mustacchi 	uint64_t nigl_len;
709533affcbSRobert Mustacchi 	uint64_t nigl_offset;
710533affcbSRobert Mustacchi 	uintptr32_t nigl_data;
711533affcbSRobert Mustacchi } nvme_ioctl_get_logpage32_t;
712533affcbSRobert Mustacchi 
713533affcbSRobert Mustacchi typedef struct {
714533affcbSRobert Mustacchi 	nvme_ioctl_common_t npc_common;	/* NSID and status */
715533affcbSRobert Mustacchi 	uint32_t npc_opcode;	/* Command opcode. */
716533affcbSRobert Mustacchi 	uint32_t npc_timeout;	/* Command timeout, in seconds. */
717533affcbSRobert Mustacchi 	uint32_t npc_flags;	/* Flags for the command. */
718533affcbSRobert Mustacchi 	uint32_t npc_impact;	/* Impact information */
719533affcbSRobert Mustacchi 	uint32_t npc_cdw0;	/* Command-specific result DWord 0 */
720533affcbSRobert Mustacchi 	uint32_t npc_cdw12;	/* Command-specific DWord 12 */
721533affcbSRobert Mustacchi 	uint32_t npc_cdw13;	/* Command-specific DWord 13 */
722533affcbSRobert Mustacchi 	uint32_t npc_cdw14;	/* Command-specific DWord 14 */
723533affcbSRobert Mustacchi 	uint32_t npc_cdw15;	/* Command-specific DWord 15 */
724533affcbSRobert Mustacchi 	uint64_t npc_buflen;	/* Size of npc_buf. */
725533affcbSRobert Mustacchi 	uintptr32_t npc_buf;	/* I/O source or destination */
726533affcbSRobert Mustacchi } nvme_ioctl_passthru32_t;
727533affcbSRobert Mustacchi 
728533affcbSRobert Mustacchi typedef struct {
729533affcbSRobert Mustacchi 	nvme_ioctl_common_t fwl_common;
730533affcbSRobert Mustacchi 	uintptr32_t fwl_buf;
731533affcbSRobert Mustacchi 	uint64_t fwl_len;
732533affcbSRobert Mustacchi 	uint64_t fwl_off;
733533affcbSRobert Mustacchi } nvme_ioctl_fw_load32_t;
734533affcbSRobert Mustacchi #pragma pack()	/* pack(4) */
735533affcbSRobert Mustacchi #endif	/* _KERNEL && _SYSCALL32 */
736533affcbSRobert Mustacchi 
737533affcbSRobert Mustacchi /*
738533affcbSRobert Mustacchi  * NVMe capabilities. This is a set of fields that come from the controller's
739533affcbSRobert Mustacchi  * PCIe register space.
740533affcbSRobert Mustacchi  */
741533affcbSRobert Mustacchi typedef struct {
742533affcbSRobert Mustacchi 	uint32_t cap_mpsmax;		/* Memory Page Size Maximum */
743533affcbSRobert Mustacchi 	uint32_t cap_mpsmin;		/* Memory Page Size Minimum */
7443d9b1a2aSHans Rosenfeld } nvme_capabilities_t;
7453d9b1a2aSHans Rosenfeld 
7463d9b1a2aSHans Rosenfeld /*
7473d9b1a2aSHans Rosenfeld  * NVMe version
7483d9b1a2aSHans Rosenfeld  */
7493d9b1a2aSHans Rosenfeld typedef struct {
7503d9b1a2aSHans Rosenfeld 	uint16_t v_minor;
7513d9b1a2aSHans Rosenfeld 	uint16_t v_major;
7523d9b1a2aSHans Rosenfeld } nvme_version_t;
7533d9b1a2aSHans Rosenfeld 
7543d9b1a2aSHans Rosenfeld #define	NVME_VERSION_ATLEAST(v, maj, min) \
7553d9b1a2aSHans Rosenfeld 	(((v)->v_major) > (maj) || \
7563d9b1a2aSHans Rosenfeld 	((v)->v_major == (maj) && (v)->v_minor >= (min)))
7573d9b1a2aSHans Rosenfeld 
7583d9b1a2aSHans Rosenfeld #define	NVME_VERSION_HIGHER(v, maj, min) \
7593d9b1a2aSHans Rosenfeld 	(((v)->v_major) > (maj) || \
7603d9b1a2aSHans Rosenfeld 	((v)->v_major == (maj) && (v)->v_minor > (min)))
7613d9b1a2aSHans Rosenfeld 
762533affcbSRobert Mustacchi /*
763533affcbSRobert Mustacchi  * NVMe Namespace related constants. The maximum NSID is determined by the
764533affcbSRobert Mustacchi  * identify controller data structure.
765533affcbSRobert Mustacchi  */
766533affcbSRobert Mustacchi #define	NVME_NSID_MIN	1
767533affcbSRobert Mustacchi #define	NVME_NSID_BCAST	0xffffffff
7683d9b1a2aSHans Rosenfeld 
7693d9b1a2aSHans Rosenfeld #pragma pack(1)
7703d9b1a2aSHans Rosenfeld 
7718d5300d3SRobert Mustacchi typedef struct {
7728d5300d3SRobert Mustacchi 	uint64_t lo;
7738d5300d3SRobert Mustacchi 	uint64_t hi;
7748d5300d3SRobert Mustacchi } nvme_uint128_t;
7758d5300d3SRobert Mustacchi 
7763d9b1a2aSHans Rosenfeld /*
7773d9b1a2aSHans Rosenfeld  * NVMe Identify data structures
7783d9b1a2aSHans Rosenfeld  */
7793d9b1a2aSHans Rosenfeld 
7803d9b1a2aSHans Rosenfeld #define	NVME_IDENTIFY_BUFSIZE	4096	/* buffer size for Identify */
7813d9b1a2aSHans Rosenfeld 
782153f3212SHans Rosenfeld /* NVMe Identify parameters (cdw10) */
783153f3212SHans Rosenfeld #define	NVME_IDENTIFY_NSID		0x0	/* Identify Namespace */
784153f3212SHans Rosenfeld #define	NVME_IDENTIFY_CTRL		0x1	/* Identify Controller */
785153f3212SHans Rosenfeld #define	NVME_IDENTIFY_NSID_LIST		0x2	/* List Active Namespaces */
786153f3212SHans Rosenfeld #define	NVME_IDENTIFY_NSID_DESC		0x3	/* Namespace ID Descriptors */
787153f3212SHans Rosenfeld 
788153f3212SHans Rosenfeld #define	NVME_IDENTIFY_NSID_ALLOC_LIST	0x10	/* List Allocated NSID */
789153f3212SHans Rosenfeld #define	NVME_IDENTIFY_NSID_ALLOC	0x11	/* Identify Allocated NSID */
790153f3212SHans Rosenfeld #define	NVME_IDENTIFY_NSID_CTRL_LIST	0x12	/* List Controllers on NSID */
791153f3212SHans Rosenfeld #define	NVME_IDENTIFY_CTRL_LIST		0x13	/* Controller List */
792153f3212SHans Rosenfeld #define	NVME_IDENTIFY_PRIMARY_CAPS	0x14	/* Primary Controller Caps */
793153f3212SHans Rosenfeld 
794153f3212SHans Rosenfeld 
7953d9b1a2aSHans Rosenfeld /* NVMe Queue Entry Size bitfield */
7963d9b1a2aSHans Rosenfeld typedef struct {
7973d9b1a2aSHans Rosenfeld 	uint8_t qes_min:4;		/* minimum entry size */
7983d9b1a2aSHans Rosenfeld 	uint8_t qes_max:4;		/* maximum entry size */
7993d9b1a2aSHans Rosenfeld } nvme_idctl_qes_t;
8003d9b1a2aSHans Rosenfeld 
8013d9b1a2aSHans Rosenfeld /* NVMe Power State Descriptor */
8023d9b1a2aSHans Rosenfeld typedef struct {
8033d9b1a2aSHans Rosenfeld 	uint16_t psd_mp;		/* Maximum Power */
8043d9b1a2aSHans Rosenfeld 	uint8_t psd_rsvd1;
8053d9b1a2aSHans Rosenfeld 	uint8_t psd_mps:1;		/* Max Power Scale (1.1) */
8063d9b1a2aSHans Rosenfeld 	uint8_t psd_nops:1;		/* Non-Operational State (1.1) */
8073d9b1a2aSHans Rosenfeld 	uint8_t psd_rsvd2:6;
8083d9b1a2aSHans Rosenfeld 	uint32_t psd_enlat;		/* Entry Latency */
8093d9b1a2aSHans Rosenfeld 	uint32_t psd_exlat;		/* Exit Latency */
8103d9b1a2aSHans Rosenfeld 	uint8_t psd_rrt:5;		/* Relative Read Throughput */
8113d9b1a2aSHans Rosenfeld 	uint8_t psd_rsvd3:3;
8123d9b1a2aSHans Rosenfeld 	uint8_t psd_rrl:5;		/* Relative Read Latency */
8133d9b1a2aSHans Rosenfeld 	uint8_t psd_rsvd4:3;
8143d9b1a2aSHans Rosenfeld 	uint8_t psd_rwt:5;		/* Relative Write Throughput */
8153d9b1a2aSHans Rosenfeld 	uint8_t	psd_rsvd5:3;
8163d9b1a2aSHans Rosenfeld 	uint8_t psd_rwl:5;		/* Relative Write Latency */
8173d9b1a2aSHans Rosenfeld 	uint8_t psd_rsvd6:3;
81848d370f1SRobert Mustacchi 	uint16_t psd_idlp;		/* Idle Power (1.2) */
81948d370f1SRobert Mustacchi 	uint8_t psd_rsvd7:6;
82048d370f1SRobert Mustacchi 	uint8_t psd_ips:2;		/* Idle Power Scale (1.2) */
82148d370f1SRobert Mustacchi 	uint8_t psd_rsvd8;
82248d370f1SRobert Mustacchi 	uint16_t psd_actp;		/* Active Power (1.2) */
82348d370f1SRobert Mustacchi 	uint8_t psd_apw:3;		/* Active Power Workload (1.2) */
82448d370f1SRobert Mustacchi 	uint8_t psd_rsvd9:3;
82548d370f1SRobert Mustacchi 	uint8_t psd_aps:2;		/* Active Power Scale */
82648d370f1SRobert Mustacchi 	uint8_t psd_rsvd10[9];
8273d9b1a2aSHans Rosenfeld } nvme_idctl_psd_t;
8283d9b1a2aSHans Rosenfeld 
8293c6ffbabSRob Johnston #define	NVME_SERIAL_SZ	20
8303c6ffbabSRob Johnston #define	NVME_MODEL_SZ	40
831533affcbSRobert Mustacchi #define	NVME_FWVER_SZ	8
8323c6ffbabSRob Johnston 
8333d9b1a2aSHans Rosenfeld /* NVMe Identify Controller Data Structure */
8343d9b1a2aSHans Rosenfeld typedef struct {
8353d9b1a2aSHans Rosenfeld 	/* Controller Capabilities & Features */
8363d9b1a2aSHans Rosenfeld 	uint16_t id_vid;		/* PCI vendor ID */
8373d9b1a2aSHans Rosenfeld 	uint16_t id_ssvid;		/* PCI subsystem vendor ID */
8383c6ffbabSRob Johnston 	char id_serial[NVME_SERIAL_SZ];	/* Serial Number */
8393c6ffbabSRob Johnston 	char id_model[NVME_MODEL_SZ];	/* Model Number */
840533affcbSRobert Mustacchi 	char id_fwrev[NVME_FWVER_SZ];	/* Firmware Revision */
8413d9b1a2aSHans Rosenfeld 	uint8_t id_rab;			/* Recommended Arbitration Burst */
8423d9b1a2aSHans Rosenfeld 	uint8_t id_oui[3];		/* vendor IEEE OUI */
8433d9b1a2aSHans Rosenfeld 	struct {			/* Multi-Interface Capabilities */
8443d9b1a2aSHans Rosenfeld 		uint8_t m_multi_pci:1;	/* HW has multiple PCIe interfaces */
8453d9b1a2aSHans Rosenfeld 		uint8_t m_multi_ctrl:1; /* HW has multiple controllers (1.1) */
8468d5300d3SRobert Mustacchi 		uint8_t m_sr_iov:1;	/* Controller is SR-IOV virt fn (1.1) */
8478d5300d3SRobert Mustacchi 		uint8_t m_anar_sup:1;	/* ANA Reporting Supported (1.4) */
8488d5300d3SRobert Mustacchi 		uint8_t m_rsvd:4;
8493d9b1a2aSHans Rosenfeld 	} id_mic;
8503d9b1a2aSHans Rosenfeld 	uint8_t	id_mdts;		/* Maximum Data Transfer Size */
8513d9b1a2aSHans Rosenfeld 	uint16_t id_cntlid;		/* Unique Controller Identifier (1.1) */
85248d370f1SRobert Mustacchi 	/* Added in NVMe 1.2 */
8538d5300d3SRobert Mustacchi 	uint32_t id_ver;		/* Version (1.2) */
8548d5300d3SRobert Mustacchi 	uint32_t id_rtd3r;		/* RTD3 Resume Latency (1.2) */
8558d5300d3SRobert Mustacchi 	uint32_t id_rtd3e;		/* RTD3 Entry Latency (1.2) */
8568d5300d3SRobert Mustacchi 	struct {
8578d5300d3SRobert Mustacchi 		uint32_t oaes_rsvd0:8;
8588d5300d3SRobert Mustacchi 		uint32_t oaes_nsan:1;	/* Namespace Attribute Notices (1.2) */
8598d5300d3SRobert Mustacchi 		uint32_t oaes_fwact:1;	/* Firmware Activation Notices (1.2) */
8608d5300d3SRobert Mustacchi 		uint32_t oaes_rsvd1:1;
8618d5300d3SRobert Mustacchi 		uint32_t oaes_ansacn:1;	/* Asymmetric NS Access Change (1.4) */
8628d5300d3SRobert Mustacchi 		uint32_t oaes_plat:1;	/* Predictable Lat Event Agg. (1.4) */
8638d5300d3SRobert Mustacchi 		uint32_t oaes_lbasi:1;	/* LBA Status Information (1.4) */
8648d5300d3SRobert Mustacchi 		uint32_t oaes_egeal:1;	/* Endurance Group Event Agg. (1.4) */
8658d5300d3SRobert Mustacchi 		uint32_t oaes_rsvd2:17;
8668d5300d3SRobert Mustacchi 	} id_oaes;
8678d5300d3SRobert Mustacchi 	struct {
8688d5300d3SRobert Mustacchi 		uint32_t ctrat_hid:1;	/* 128-bit Host Identifier (1.2)  */
8698d5300d3SRobert Mustacchi 		uint32_t ctrat_nops:1;	/* Non-Operational Power State (1.3) */
8708d5300d3SRobert Mustacchi 		uint32_t ctrat_nvmset:1; /* NVMe Sets (1.4) */
8718d5300d3SRobert Mustacchi 		uint32_t ctrat_rrl:1;	/* Read Recovery Levels (1.4) */
8728d5300d3SRobert Mustacchi 		uint32_t ctrat_engrp:1; /* Endurance Groups (1.4) */
8738d5300d3SRobert Mustacchi 		uint32_t ctrat_plm:1;	/* Predictable Latency Mode (1.4) */
8748d5300d3SRobert Mustacchi 		uint32_t ctrat_tbkas:1;	/* Traffic Based Keep Alive (1.4) */
8758d5300d3SRobert Mustacchi 		uint32_t ctrat_nsg:1;	/* Namespace Granularity (1.4) */
8768d5300d3SRobert Mustacchi 		uint32_t ctrat_sqass:1;	/* SQ Associations (1.4) */
8778d5300d3SRobert Mustacchi 		uint32_t ctrat_uuid:1;	/* UUID List (1.4) */
8788d5300d3SRobert Mustacchi 		uint32_t ctrat_rsvd:22;
8798d5300d3SRobert Mustacchi 	} id_ctratt;
8808d5300d3SRobert Mustacchi 	uint16_t id_rrls;		/* Read Recovery Levels (1.4) */
8818d5300d3SRobert Mustacchi 	uint8_t id_rsvd_cc[111-102];
8828d5300d3SRobert Mustacchi 	uint8_t id_cntrltype;		/* Controller Type (1.4) */
8838d5300d3SRobert Mustacchi 	uint8_t id_frguid[16];		/* FRU GUID (1.3) */
8848d5300d3SRobert Mustacchi 	uint16_t id_crdt1;		/* Command Retry Delay Time 1 (1.4) */
8858d5300d3SRobert Mustacchi 	uint16_t id_crdt2;		/* Command Retry Delay Time 2 (1.4) */
8868d5300d3SRobert Mustacchi 	uint16_t id_crdt3;		/* Command Retry Delay Time 3 (1.4) */
8878d5300d3SRobert Mustacchi 	uint8_t id_rsvd2_cc[240 - 134];
8888d5300d3SRobert Mustacchi 	uint8_t id_rsvd_nvmemi[253 - 240];
8898d5300d3SRobert Mustacchi 	/* NVMe-MI region */
8908d5300d3SRobert Mustacchi 	struct {			/* NVMe Subsystem Report */
8918d5300d3SRobert Mustacchi 		uint8_t nvmsr_nvmesd:1;	/* NVMe Storage Device */
8928d5300d3SRobert Mustacchi 		uint8_t nvmsr_nvmee:1;	/* NVMe Enclosure */
8938d5300d3SRobert Mustacchi 		uint8_t nvmsr_rsvd:6;
8948d5300d3SRobert Mustacchi 	} id_nvmsr;
8958d5300d3SRobert Mustacchi 	struct {			/* VPD Write Cycle Information */
8968d5300d3SRobert Mustacchi 		uint8_t vwci_crem:7;	/* Write Cycles Remaining */
8978d5300d3SRobert Mustacchi 		uint8_t vwci_valid:1;	/* Write Cycles Remaining Valid */
8988d5300d3SRobert Mustacchi 	} id_vpdwc;
8998d5300d3SRobert Mustacchi 	struct {			/* Management Endpoint Capabilities */
9008d5300d3SRobert Mustacchi 		uint8_t mec_smbusme:1;	/* SMBus Port Management Endpoint */
9018d5300d3SRobert Mustacchi 		uint8_t mec_pcieme:1;	/* PCIe Port Management Endpoint */
9028d5300d3SRobert Mustacchi 		uint8_t mec_rsvd:6;
9038d5300d3SRobert Mustacchi 	} id_mec;
9043d9b1a2aSHans Rosenfeld 
9053d9b1a2aSHans Rosenfeld 	/* Admin Command Set Attributes */
9063d9b1a2aSHans Rosenfeld 	struct {			/* Optional Admin Command Support */
9073d9b1a2aSHans Rosenfeld 		uint16_t oa_security:1;	/* Security Send & Receive */
9083d9b1a2aSHans Rosenfeld 		uint16_t oa_format:1;	/* Format NVM */
9093d9b1a2aSHans Rosenfeld 		uint16_t oa_firmware:1;	/* Firmware Activate & Download */
9108d5300d3SRobert Mustacchi 		uint16_t oa_nsmgmt:1;	/* Namespace Management (1.2) */
9118d5300d3SRobert Mustacchi 		uint16_t oa_selftest:1;	/* Self Test (1.3) */
9128d5300d3SRobert Mustacchi 		uint16_t oa_direct:1;	/* Directives (1.3) */
9138d5300d3SRobert Mustacchi 		uint16_t oa_nvmemi:1;	/* MI-Send/Recv (1.3) */
9148d5300d3SRobert Mustacchi 		uint16_t oa_virtmgmt:1;	/* Virtualization Management (1.3) */
9158d5300d3SRobert Mustacchi 		uint16_t oa_doorbell:1;	/* Doorbell Buffer Config (1.3) */
9168d5300d3SRobert Mustacchi 		uint16_t oa_lbastat:1;	/* LBA Status (1.4) */
9178d5300d3SRobert Mustacchi 		uint16_t oa_rsvd:6;
9183d9b1a2aSHans Rosenfeld 	} id_oacs;
9193d9b1a2aSHans Rosenfeld 	uint8_t	id_acl;			/* Abort Command Limit */
9203d9b1a2aSHans Rosenfeld 	uint8_t id_aerl;		/* Asynchronous Event Request Limit */
9213d9b1a2aSHans Rosenfeld 	struct {			/* Firmware Updates */
9223d9b1a2aSHans Rosenfeld 		uint8_t fw_readonly:1;	/* Slot 1 is Read-Only */
9233d9b1a2aSHans Rosenfeld 		uint8_t	fw_nslot:3;	/* number of firmware slots */
9248d5300d3SRobert Mustacchi 		uint8_t fw_norst:1;	/* Activate w/o reset (1.2) */
9258d5300d3SRobert Mustacchi 		uint8_t fw_rsvd:3;
9263d9b1a2aSHans Rosenfeld 	} id_frmw;
9273d9b1a2aSHans Rosenfeld 	struct {			/* Log Page Attributes */
9283d9b1a2aSHans Rosenfeld 		uint8_t lp_smart:1;	/* SMART/Health information per NS */
9298d5300d3SRobert Mustacchi 		uint8_t lp_cmdeff:1;	/* Command Effects (1.2) */
9308d5300d3SRobert Mustacchi 		uint8_t lp_extsup:1;	/* Extended Get Log Page (1.2) */
9318d5300d3SRobert Mustacchi 		uint8_t lp_telemetry:1;	/* Telemetry Log Pages (1.3) */
9328d5300d3SRobert Mustacchi 		uint8_t lp_persist:1;	/* Persistent Log Page (1.4) */
9338d5300d3SRobert Mustacchi 		uint8_t lp_rsvd:3;
9343d9b1a2aSHans Rosenfeld 	} id_lpa;
9353d9b1a2aSHans Rosenfeld 	uint8_t id_elpe;		/* Error Log Page Entries */
9363d9b1a2aSHans Rosenfeld 	uint8_t	id_npss;		/* Number of Power States */
9373d9b1a2aSHans Rosenfeld 	struct {			/* Admin Vendor Specific Command Conf */
9383d9b1a2aSHans Rosenfeld 		uint8_t av_spec:1;	/* use format from spec */
9393d9b1a2aSHans Rosenfeld 		uint8_t av_rsvd:7;
9403d9b1a2aSHans Rosenfeld 	} id_avscc;
9413d9b1a2aSHans Rosenfeld 	struct {			/* Autonomous Power State Trans (1.1) */
9423d9b1a2aSHans Rosenfeld 		uint8_t ap_sup:1;	/* APST supported (1.1) */
9433d9b1a2aSHans Rosenfeld 		uint8_t ap_rsvd:7;
9443d9b1a2aSHans Rosenfeld 	} id_apsta;
9458d5300d3SRobert Mustacchi 	uint16_t ap_wctemp;		/* Warning Composite Temp. (1.2) */
9468d5300d3SRobert Mustacchi 	uint16_t ap_cctemp;		/* Critical Composite Temp. (1.2) */
9478d5300d3SRobert Mustacchi 	uint16_t ap_mtfa;		/* Maximum Firmware Activation (1.2) */
9488d5300d3SRobert Mustacchi 	uint32_t ap_hmpre;		/* Host Memory Buf Pref Size (1.2) */
9498d5300d3SRobert Mustacchi 	uint32_t ap_hmmin;		/* Host Memory Buf Min Size (1.2) */
9508d5300d3SRobert Mustacchi 	nvme_uint128_t ap_tnvmcap;	/* Total NVM Capacity in Bytes (1.2) */
9518d5300d3SRobert Mustacchi 	nvme_uint128_t ap_unvmcap;	/* Unallocated NVM Capacity (1.2) */
9528d5300d3SRobert Mustacchi 	struct {			/* Replay Protected Mem. Block (1.2) */
9538d5300d3SRobert Mustacchi 		uint32_t rpmbs_units:3;	/* Number of targets */
9548d5300d3SRobert Mustacchi 		uint32_t rpmbs_auth:3;	/* Auth method */
9558d5300d3SRobert Mustacchi 		uint32_t rpmbs_rsvd:10;
9568d5300d3SRobert Mustacchi 		uint32_t rpmbs_tot:8;	/* Total size in 128KB */
9578d5300d3SRobert Mustacchi 		uint32_t rpmbs_acc:8;	/* Access size in 512B */
9588d5300d3SRobert Mustacchi 	} ap_rpmbs;
95948d370f1SRobert Mustacchi 	/* Added in NVMe 1.3 */
9608d5300d3SRobert Mustacchi 	uint16_t ap_edstt;		/* Ext. Device Self-test time (1.3) */
9618d5300d3SRobert Mustacchi 	struct {			/* Device Self-test Options */
9628d5300d3SRobert Mustacchi 		uint8_t dsto_sub:1;	/* Subsystem level self-test (1.3) */
9638d5300d3SRobert Mustacchi 		uint8_t dsto_rsvd:7;
9648d5300d3SRobert Mustacchi 	} ap_dsto;
9658d5300d3SRobert Mustacchi 	uint8_t ap_fwug;		/* Firmware Update Granularity (1.3) */
9668d5300d3SRobert Mustacchi 	uint16_t ap_kas;		/* Keep Alive Support (1.2) */
9678d5300d3SRobert Mustacchi 	struct {			/* Host Thermal Management (1.3) */
9688d5300d3SRobert Mustacchi 		uint16_t hctma_hctm:1;	/* Host Controlled (1.3) */
9698d5300d3SRobert Mustacchi 		uint16_t hctma_rsvd:15;
9708d5300d3SRobert Mustacchi 	} ap_hctma;
9718d5300d3SRobert Mustacchi 	uint16_t ap_mntmt;		/* Minimum Thermal Temperature (1.3) */
9728d5300d3SRobert Mustacchi 	uint16_t ap_mxtmt;		/* Maximum Thermal Temperature (1.3) */
9738d5300d3SRobert Mustacchi 	struct {			/* Sanitize Caps */
9748d5300d3SRobert Mustacchi 		uint32_t san_ces:1;	/* Crypto Erase Support (1.3) */
9758d5300d3SRobert Mustacchi 		uint32_t san_bes:1;	/* Block Erase Support (1.3) */
9768d5300d3SRobert Mustacchi 		uint32_t san_ows:1;	/* Overwite Support (1.3) */
9778d5300d3SRobert Mustacchi 		uint32_t san_rsvd:26;
9788d5300d3SRobert Mustacchi 		uint32_t san_ndi:1;	/* No-deallocate Inhibited (1.4) */
9798d5300d3SRobert Mustacchi 		uint32_t san_nodmmas:2;	/* No-Deallocate Modifies Media (1.4) */
9808d5300d3SRobert Mustacchi 	} ap_sanitize;
9818d5300d3SRobert Mustacchi 	uint32_t ap_hmminds;		/* Host Mem Buf Min Desc Entry (1.4) */
9828d5300d3SRobert Mustacchi 	uint16_t ap_hmmaxd;		/* How Mem Max Desc Entries (1.4) */
9838d5300d3SRobert Mustacchi 	uint16_t ap_nsetidmax;		/* Max NVMe set identifier (1.4) */
9848d5300d3SRobert Mustacchi 	uint16_t ap_engidmax;		/* Max Endurance Group ID (1.4) */
9858d5300d3SRobert Mustacchi 	uint8_t ap_anatt;		/* ANA Transition Time (1.4) */
9868d5300d3SRobert Mustacchi 	struct {			/* Asymmetric Namespace Access Caps */
9878d5300d3SRobert Mustacchi 		uint8_t anacap_opt:1;	/* Optimized State (1.4) */
9888d5300d3SRobert Mustacchi 		uint8_t anacap_unopt:1;	/* Un-optimized State (1.4) */
9898d5300d3SRobert Mustacchi 		uint8_t anacap_inacc:1;	/* Inaccessible State (1.4) */
9908d5300d3SRobert Mustacchi 		uint8_t anacap_ploss:1;	/* Persistent Loss (1.4) */
9918d5300d3SRobert Mustacchi 		uint8_t anacap_chg:1;	/* Change State (1.4 ) */
9928d5300d3SRobert Mustacchi 		uint8_t anacap_rsvd:1;
9938d5300d3SRobert Mustacchi 		uint8_t anacap_grpns:1;	/* ID Changes with NS Attach (1.4) */
9948d5300d3SRobert Mustacchi 		uint8_t anacap_grpid:1;	/* Supports Group ID (1.4) */
9958d5300d3SRobert Mustacchi 	} ap_anacap;
9968d5300d3SRobert Mustacchi 	uint32_t ap_anagrpmax;		/* ANA Group ID Max (1.4) */
9978d5300d3SRobert Mustacchi 	uint32_t ap_nanagrpid;		/* Number of ANA Group IDs (1.4) */
9988d5300d3SRobert Mustacchi 	uint32_t ap_pels;		/* Persistent Event Log Size (1.4) */
9998d5300d3SRobert Mustacchi 	uint8_t id_rsvd_ac[512 - 356];
10003d9b1a2aSHans Rosenfeld 
10013d9b1a2aSHans Rosenfeld 	/* NVM Command Set Attributes */
10023d9b1a2aSHans Rosenfeld 	nvme_idctl_qes_t id_sqes;	/* Submission Queue Entry Size */
10033d9b1a2aSHans Rosenfeld 	nvme_idctl_qes_t id_cqes;	/* Completion Queue Entry Size */
100448d370f1SRobert Mustacchi 	uint16_t id_maxcmd;		/* Max Outstanding Commands (1.3) */
10053d9b1a2aSHans Rosenfeld 	uint32_t id_nn;			/* Number of Namespaces */
10063d9b1a2aSHans Rosenfeld 	struct {			/* Optional NVM Command Support */
10073d9b1a2aSHans Rosenfeld 		uint16_t on_compare:1;	/* Compare */
10083d9b1a2aSHans Rosenfeld 		uint16_t on_wr_unc:1;	/* Write Uncorrectable */
10093d9b1a2aSHans Rosenfeld 		uint16_t on_dset_mgmt:1; /* Dataset Management */
10103d9b1a2aSHans Rosenfeld 		uint16_t on_wr_zero:1;	/* Write Zeros (1.1) */
10113d9b1a2aSHans Rosenfeld 		uint16_t on_save:1;	/* Save/Select in Get/Set Feat (1.1) */
10123d9b1a2aSHans Rosenfeld 		uint16_t on_reserve:1;	/* Reservations (1.1) */
10138d5300d3SRobert Mustacchi 		uint16_t on_ts:1;	/* Timestamp (1.3) */
10148d5300d3SRobert Mustacchi 		uint16_t on_verify:1;	/* Verify (1.4) */
10158d5300d3SRobert Mustacchi 		uint16_t on_rsvd:8;
10163d9b1a2aSHans Rosenfeld 	} id_oncs;
10173d9b1a2aSHans Rosenfeld 	struct {			/* Fused Operation Support */
10183d9b1a2aSHans Rosenfeld 		uint16_t f_cmp_wr:1;	/* Compare and Write */
10193d9b1a2aSHans Rosenfeld 		uint16_t f_rsvd:15;
10203d9b1a2aSHans Rosenfeld 	} id_fuses;
10213d9b1a2aSHans Rosenfeld 	struct {			/* Format NVM Attributes */
10223d9b1a2aSHans Rosenfeld 		uint8_t fn_format:1;	/* Format applies to all NS */
10233d9b1a2aSHans Rosenfeld 		uint8_t fn_sec_erase:1;	/* Secure Erase applies to all NS */
10243d9b1a2aSHans Rosenfeld 		uint8_t fn_crypt_erase:1; /* Cryptographic Erase supported */
10253d9b1a2aSHans Rosenfeld 		uint8_t fn_rsvd:5;
10263d9b1a2aSHans Rosenfeld 	} id_fna;
10273d9b1a2aSHans Rosenfeld 	struct {			/* Volatile Write Cache */
10283d9b1a2aSHans Rosenfeld 		uint8_t vwc_present:1;	/* Volatile Write Cache present */
10298d5300d3SRobert Mustacchi 		uint8_t vwc_nsflush:2;	/* Flush with NS ffffffff (1.4) */
10308d5300d3SRobert Mustacchi 		uint8_t rsvd:5;
10313d9b1a2aSHans Rosenfeld 	} id_vwc;
10323d9b1a2aSHans Rosenfeld 	uint16_t id_awun;		/* Atomic Write Unit Normal */
10333d9b1a2aSHans Rosenfeld 	uint16_t id_awupf;		/* Atomic Write Unit Power Fail */
10343d9b1a2aSHans Rosenfeld 	struct {			/* NVM Vendor Specific Command Conf */
10353d9b1a2aSHans Rosenfeld 		uint8_t nv_spec:1;	/* use format from spec */
10363d9b1a2aSHans Rosenfeld 		uint8_t nv_rsvd:7;
10373d9b1a2aSHans Rosenfeld 	} id_nvscc;
10388d5300d3SRobert Mustacchi 	struct {			/* Namespace Write Protection Caps */
10398d5300d3SRobert Mustacchi 		uint8_t nwpc_base:1;	/* Base support (1.4) */
10408d5300d3SRobert Mustacchi 		uint8_t nwpc_wpupc:1;	/* Write prot until power cycle (1.4) */
10418d5300d3SRobert Mustacchi 		uint8_t nwpc_permwp:1;	/* Permanent write prot (1.4) */
10428d5300d3SRobert Mustacchi 		uint8_t nwpc_rsvd:5;
10438d5300d3SRobert Mustacchi 	} id_nwpc;
10443d9b1a2aSHans Rosenfeld 	uint16_t id_acwu;		/* Atomic Compare & Write Unit (1.1) */
10453d9b1a2aSHans Rosenfeld 	uint16_t id_rsvd_nc_3;
10463d9b1a2aSHans Rosenfeld 	struct {			/* SGL Support (1.1) */
10478d5300d3SRobert Mustacchi 		uint16_t sgl_sup:2;	/* SGL Supported in NVM cmds (1.3) */
10488d5300d3SRobert Mustacchi 		uint16_t sgl_keyed:1;	/* Keyed SGL Support (1.2) */
10498d5300d3SRobert Mustacchi 		uint16_t sgl_rsvd1:13;
10503d9b1a2aSHans Rosenfeld 		uint16_t sgl_bucket:1;	/* SGL Bit Bucket supported (1.1) */
10518d5300d3SRobert Mustacchi 		uint16_t sgl_balign:1;	/* SGL Byte Aligned (1.2) */
10528d5300d3SRobert Mustacchi 		uint16_t sgl_sglgtd:1;	/* SGL Length Longer than Data (1.2) */
10538d5300d3SRobert Mustacchi 		uint16_t sgl_mptr:1;	/* SGL MPTR w/ SGL (1.2) */
10548d5300d3SRobert Mustacchi 		uint16_t sgl_offset:1;	/* SGL Address is offset (1.2) */
10558d5300d3SRobert Mustacchi 		uint16_t sgl_tport:1;	/* Transport SGL Data Block (1.4) */
10568d5300d3SRobert Mustacchi 		uint16_t sgl_rsvd2:10;
10573d9b1a2aSHans Rosenfeld 	} id_sgls;
105898f586d7SAndy Fiddaman 	uint32_t id_mnan;		/* Maximum Number of Allowed NSes */
10598d5300d3SRobert Mustacchi 	uint8_t id_rsvd_nc_4[768 - 544];
10603d9b1a2aSHans Rosenfeld 
10613d9b1a2aSHans Rosenfeld 	/* I/O Command Set Attributes */
106248d370f1SRobert Mustacchi 	uint8_t id_subnqn[1024 - 768];	/* Subsystem Qualified Name (1.2.1+) */
106348d370f1SRobert Mustacchi 	uint8_t id_rsvd_ioc[1792 - 1024];
106448d370f1SRobert Mustacchi 	uint8_t id_nvmof[2048 - 1792];	/* NVMe over Fabrics */
10653d9b1a2aSHans Rosenfeld 
10663d9b1a2aSHans Rosenfeld 	/* Power State Descriptors */
10673d9b1a2aSHans Rosenfeld 	nvme_idctl_psd_t id_psd[32];
10683d9b1a2aSHans Rosenfeld 
10693d9b1a2aSHans Rosenfeld 	/* Vendor Specific */
10703d9b1a2aSHans Rosenfeld 	uint8_t id_vs[1024];
10713d9b1a2aSHans Rosenfeld } nvme_identify_ctrl_t;
10723d9b1a2aSHans Rosenfeld 
10738d5300d3SRobert Mustacchi /*
10748d5300d3SRobert Mustacchi  * NVMe Controller Types
10758d5300d3SRobert Mustacchi  */
10768d5300d3SRobert Mustacchi #define	NVME_CNTRLTYPE_RSVD	0
10778d5300d3SRobert Mustacchi #define	NVME_CNTRLTYPE_IO	1
10788d5300d3SRobert Mustacchi #define	NVME_CNTRLTYPE_DISC	2
10798d5300d3SRobert Mustacchi #define	NVME_CNTRLTYPE_ADMIN	3
10808d5300d3SRobert Mustacchi 
10818d5300d3SRobert Mustacchi /*
10828d5300d3SRobert Mustacchi  * RPMBS Authentication Types
10838d5300d3SRobert Mustacchi  */
10848d5300d3SRobert Mustacchi #define	NVME_RPMBS_AUTH_HMAC_SHA256	0
10858d5300d3SRobert Mustacchi 
10868d5300d3SRobert Mustacchi /*
10878d5300d3SRobert Mustacchi  * NODMMAS Values
10888d5300d3SRobert Mustacchi  */
10898d5300d3SRobert Mustacchi #define	NVME_NODMMAS_UNDEF	0x00
10908d5300d3SRobert Mustacchi #define	NVME_NODMMAS_NOMOD	0x01
10918d5300d3SRobert Mustacchi #define	NVME_NODMMAS_DOMOD	0x02
10928d5300d3SRobert Mustacchi 
10938d5300d3SRobert Mustacchi /*
10948d5300d3SRobert Mustacchi  * VWC NSID flushes
10958d5300d3SRobert Mustacchi  */
10968d5300d3SRobert Mustacchi #define	NVME_VWCNS_UNKNOWN	0x00
10978d5300d3SRobert Mustacchi #define	NVME_VWCNS_UNSUP	0x02
10988d5300d3SRobert Mustacchi #define	NVME_VWCNS_SUP		0x03
10998d5300d3SRobert Mustacchi 
11008d5300d3SRobert Mustacchi /*
11018d5300d3SRobert Mustacchi  * SGL Support Values
11028d5300d3SRobert Mustacchi  */
11038d5300d3SRobert Mustacchi #define	NVME_SGL_UNSUP		0x00
11048d5300d3SRobert Mustacchi #define	NVME_SGL_SUP_UNALIGN	0x01
11058d5300d3SRobert Mustacchi #define	NVME_SGL_SUP_ALIGN	0x02
11068d5300d3SRobert Mustacchi 
11073d9b1a2aSHans Rosenfeld /* NVMe Identify Namespace LBA Format */
11083d9b1a2aSHans Rosenfeld typedef struct {
11093d9b1a2aSHans Rosenfeld 	uint16_t lbaf_ms;		/* Metadata Size */
11103d9b1a2aSHans Rosenfeld 	uint8_t lbaf_lbads;		/* LBA Data Size */
11113d9b1a2aSHans Rosenfeld 	uint8_t lbaf_rp:2;		/* Relative Performance */
11123d9b1a2aSHans Rosenfeld 	uint8_t lbaf_rsvd1:6;
11133d9b1a2aSHans Rosenfeld } nvme_idns_lbaf_t;
11143d9b1a2aSHans Rosenfeld 
1115533affcbSRobert Mustacchi #define	NVME_MAX_LBAF	16
1116533affcbSRobert Mustacchi 
11173d9b1a2aSHans Rosenfeld /* NVMe Identify Namespace Data Structure */
11183d9b1a2aSHans Rosenfeld typedef struct {
11193d9b1a2aSHans Rosenfeld 	uint64_t id_nsize;		/* Namespace Size */
11203d9b1a2aSHans Rosenfeld 	uint64_t id_ncap;		/* Namespace Capacity */
11213d9b1a2aSHans Rosenfeld 	uint64_t id_nuse;		/* Namespace Utilization */
11223d9b1a2aSHans Rosenfeld 	struct {			/* Namespace Features */
11233d9b1a2aSHans Rosenfeld 		uint8_t f_thin:1;	/* Thin Provisioning */
11248d5300d3SRobert Mustacchi 		uint8_t f_nsabp:1;	/* Namespace atomics (1.2) */
11258d5300d3SRobert Mustacchi 		uint8_t f_dae:1;	/* Deallocated errors supported (1.2) */
11268d5300d3SRobert Mustacchi 		uint8_t f_uidreuse:1;	/* GUID reuse impossible (1.3) */
11278d5300d3SRobert Mustacchi 		uint8_t f_optperf:1;	/* Namespace I/O opt (1.4) */
11288d5300d3SRobert Mustacchi 		uint8_t f_rsvd:3;
11293d9b1a2aSHans Rosenfeld 	} id_nsfeat;
11303d9b1a2aSHans Rosenfeld 	uint8_t id_nlbaf;		/* Number of LBA formats */
11313d9b1a2aSHans Rosenfeld 	struct {			/* Formatted LBA size */
11323d9b1a2aSHans Rosenfeld 		uint8_t lba_format:4;	/* LBA format */
11333d9b1a2aSHans Rosenfeld 		uint8_t lba_extlba:1;	/* extended LBA (includes metadata) */
11343d9b1a2aSHans Rosenfeld 		uint8_t lba_rsvd:3;
11353d9b1a2aSHans Rosenfeld 	} id_flbas;
11363d9b1a2aSHans Rosenfeld 	struct {			/* Metadata Capabilities */
11373d9b1a2aSHans Rosenfeld 		uint8_t mc_extlba:1;	/* extended LBA transfers */
11383d9b1a2aSHans Rosenfeld 		uint8_t mc_separate:1;	/* separate metadata transfers */
11393d9b1a2aSHans Rosenfeld 		uint8_t mc_rsvd:6;
11403d9b1a2aSHans Rosenfeld 	} id_mc;
11413d9b1a2aSHans Rosenfeld 	struct {			/* Data Protection Capabilities */
11423d9b1a2aSHans Rosenfeld 		uint8_t dp_type1:1;	/* Protection Information Type 1 */
11433d9b1a2aSHans Rosenfeld 		uint8_t dp_type2:1;	/* Protection Information Type 2 */
11443d9b1a2aSHans Rosenfeld 		uint8_t dp_type3:1;	/* Protection Information Type 3 */
11453d9b1a2aSHans Rosenfeld 		uint8_t dp_first:1;	/* first 8 bytes of metadata */
11463d9b1a2aSHans Rosenfeld 		uint8_t dp_last:1;	/* last 8 bytes of metadata */
11473d9b1a2aSHans Rosenfeld 		uint8_t dp_rsvd:3;
11483d9b1a2aSHans Rosenfeld 	} id_dpc;
11493d9b1a2aSHans Rosenfeld 	struct {			/* Data Protection Settings */
11503d9b1a2aSHans Rosenfeld 		uint8_t dp_pinfo:3;	/* Protection Information enabled */
11513d9b1a2aSHans Rosenfeld 		uint8_t dp_first:1;	/* first 8 bytes of metadata */
11523d9b1a2aSHans Rosenfeld 		uint8_t dp_rsvd:4;
11533d9b1a2aSHans Rosenfeld 	} id_dps;
11543d9b1a2aSHans Rosenfeld 	struct {			/* NS Multi-Path/Sharing Cap (1.1) */
11553d9b1a2aSHans Rosenfeld 		uint8_t nm_shared:1;	/* NS is shared (1.1) */
11563d9b1a2aSHans Rosenfeld 		uint8_t nm_rsvd:7;
11573d9b1a2aSHans Rosenfeld 	} id_nmic;
11583d9b1a2aSHans Rosenfeld 	struct {			/* Reservation Capabilities (1.1) */
11593d9b1a2aSHans Rosenfeld 		uint8_t rc_persist:1;	/* Persist Through Power Loss (1.1) */
11603d9b1a2aSHans Rosenfeld 		uint8_t rc_wr_excl:1;	/* Write Exclusive (1.1) */
11613d9b1a2aSHans Rosenfeld 		uint8_t rc_excl:1;	/* Exclusive Access (1.1) */
11623d9b1a2aSHans Rosenfeld 		uint8_t rc_wr_excl_r:1;	/* Wr Excl - Registrants Only (1.1) */
11633d9b1a2aSHans Rosenfeld 		uint8_t rc_excl_r:1;	/* Excl Acc - Registrants Only (1.1) */
11643d9b1a2aSHans Rosenfeld 		uint8_t rc_wr_excl_a:1;	/* Wr Excl - All Registrants (1.1) */
11653d9b1a2aSHans Rosenfeld 		uint8_t rc_excl_a:1;	/* Excl Acc - All Registrants (1.1) */
11668d5300d3SRobert Mustacchi 		uint8_t rc_ign_ekey:1;	/* Ignore Existing Key (1.3) */
11673d9b1a2aSHans Rosenfeld 	} id_rescap;
11688d5300d3SRobert Mustacchi 	struct {			/* Format Progress Indicator (1.2) */
11698d5300d3SRobert Mustacchi 		uint8_t fpi_remp:7;	/* Percent NVM Format Remaining (1.2) */
11708d5300d3SRobert Mustacchi 		uint8_t fpi_sup:1;	/* Supported (1.2) */
11718d5300d3SRobert Mustacchi 	} id_fpi;
117248d370f1SRobert Mustacchi 	uint8_t id_dfleat;		/* Deallocate Log. Block (1.3) */
117348d370f1SRobert Mustacchi 	uint16_t id_nawun;		/* Atomic Write Unit Normal (1.2) */
117448d370f1SRobert Mustacchi 	uint16_t id_nawupf;		/* Atomic Write Unit Power Fail (1.2) */
117548d370f1SRobert Mustacchi 	uint16_t id_nacwu;		/* Atomic Compare & Write Unit (1.2) */
117648d370f1SRobert Mustacchi 	uint16_t id_nabsn;		/* Atomic Boundary Size Normal (1.2) */
117748d370f1SRobert Mustacchi 	uint16_t id_nbao;		/* Atomic Boundary Offset (1.2) */
117848d370f1SRobert Mustacchi 	uint16_t id_nabspf;		/* Atomic Boundary Size Fail (1.2) */
117948d370f1SRobert Mustacchi 	uint16_t id_noiob;		/* Optimal I/O Bondary (1.3) */
11808d5300d3SRobert Mustacchi 	nvme_uint128_t id_nvmcap;	/* NVM Capacity */
11818d5300d3SRobert Mustacchi 	uint16_t id_npwg;		/* NS Pref. Write Gran. (1.4) */
11828d5300d3SRobert Mustacchi 	uint16_t id_npwa;		/* NS Pref. Write Align. (1.4) */
11838d5300d3SRobert Mustacchi 	uint16_t id_npdg;		/* NS Pref. Deallocate Gran. (1.4) */
11848d5300d3SRobert Mustacchi 	uint16_t id_npda;		/* NS Pref. Deallocate Align. (1.4) */
11858d5300d3SRobert Mustacchi 	uint16_t id_nows;		/* NS. Optimal Write Size (1.4) */
11868d5300d3SRobert Mustacchi 	uint8_t id_rsvd1[92 - 74];
11878d5300d3SRobert Mustacchi 	uint32_t id_anagrpid;		/* ANA Group Identifier (1.4) */
11888d5300d3SRobert Mustacchi 	uint8_t id_rsvd2[99 - 96];
11898d5300d3SRobert Mustacchi 	struct {
11908d5300d3SRobert Mustacchi 		uint8_t nsa_wprot:1;	/* Write Protected (1.4) */
11918d5300d3SRobert Mustacchi 		uint8_t nsa_rsvd:7;
11928d5300d3SRobert Mustacchi 	} id_nsattr;
11938d5300d3SRobert Mustacchi 	uint16_t id_nvmsetid;		/* NVM Set Identifier (1.4) */
11948d5300d3SRobert Mustacchi 	uint16_t id_endgid;		/* Endurance Group Identifier (1.4) */
119548d370f1SRobert Mustacchi 	uint8_t id_nguid[16];		/* Namespace GUID (1.2) */
11963d9b1a2aSHans Rosenfeld 	uint8_t id_eui64[8];		/* IEEE Extended Unique Id (1.1) */
1197533affcbSRobert Mustacchi 	nvme_idns_lbaf_t id_lbaf[NVME_MAX_LBAF];	/* LBA Formats */
11983d9b1a2aSHans Rosenfeld 
11998d5300d3SRobert Mustacchi 	uint8_t id_rsvd3[384 - 192];
12003d9b1a2aSHans Rosenfeld 
120148d370f1SRobert Mustacchi 	uint8_t id_vs[4096 - 384];	/* Vendor Specific */
12023d9b1a2aSHans Rosenfeld } nvme_identify_nsid_t;
12033d9b1a2aSHans Rosenfeld 
1204153f3212SHans Rosenfeld /* NVMe Identify Namespace ID List */
1205153f3212SHans Rosenfeld typedef struct {
1206153f3212SHans Rosenfeld 					/* Ordered list of Namespace IDs */
1207153f3212SHans Rosenfeld 	uint32_t nl_nsid[NVME_IDENTIFY_BUFSIZE / sizeof (uint32_t)];
1208153f3212SHans Rosenfeld } nvme_identify_nsid_list_t;
1209153f3212SHans Rosenfeld 
1210153f3212SHans Rosenfeld /* NVME Identify Controller ID List */
1211153f3212SHans Rosenfeld typedef struct {
1212153f3212SHans Rosenfeld 	uint16_t	cl_nid;		/* Number of controller entries */
1213153f3212SHans Rosenfeld 					/* unique controller identifiers */
1214153f3212SHans Rosenfeld 	uint16_t	cl_ctlid[NVME_IDENTIFY_BUFSIZE / sizeof (uint16_t) - 1];
1215153f3212SHans Rosenfeld } nvme_identify_ctrl_list_t;
1216153f3212SHans Rosenfeld 
1217153f3212SHans Rosenfeld /* NVMe Identify Namespace Descriptor */
1218153f3212SHans Rosenfeld typedef struct {
1219153f3212SHans Rosenfeld 	uint8_t nd_nidt;		/* Namespace Identifier Type */
1220153f3212SHans Rosenfeld 	uint8_t nd_nidl;		/* Namespace Identifier Length */
1221153f3212SHans Rosenfeld 	uint8_t nd_resv[2];
1222153f3212SHans Rosenfeld 	uint8_t nd_nid[];		/* Namespace Identifier */
1223153f3212SHans Rosenfeld } nvme_identify_nsid_desc_t;
1224153f3212SHans Rosenfeld 
1225153f3212SHans Rosenfeld #define	NVME_NSID_DESC_EUI64	1
1226153f3212SHans Rosenfeld #define	NVME_NSID_DESC_NGUID	2
1227153f3212SHans Rosenfeld #define	NVME_NSID_DESC_NUUID	3
1228153f3212SHans Rosenfeld #define	NVME_NSID_DESC_MIN	NVME_NSID_DESC_EUI64
1229153f3212SHans Rosenfeld #define	NVME_NSID_DESC_MAX	NVME_NSID_DESC_NUUID
1230153f3212SHans Rosenfeld 
1231153f3212SHans Rosenfeld #define	NVME_NSID_DESC_LEN_EUI64	8
1232153f3212SHans Rosenfeld #define	NVME_NSID_DESC_LEN_NGUID	16
1233153f3212SHans Rosenfeld #define	NVME_NSID_DESC_LEN_NUUID	UUID_LEN
1234153f3212SHans Rosenfeld 
123548d370f1SRobert Mustacchi /* NVMe Identify Primary Controller Capabilities */
123648d370f1SRobert Mustacchi typedef struct {
123748d370f1SRobert Mustacchi 	uint16_t	nipc_cntlid;	/* Controller ID */
123848d370f1SRobert Mustacchi 	uint16_t	nipc_portid;	/* Port Identifier */
123948d370f1SRobert Mustacchi 	uint8_t		nipc_crt;	/* Controller Resource Types */
124048d370f1SRobert Mustacchi 	uint8_t		nipc_rsvd0[32 - 5];
124148d370f1SRobert Mustacchi 	uint32_t	nipc_vqfrt;	/* VQ Resources Flexible Total */
124248d370f1SRobert Mustacchi 	uint32_t	nipc_vqrfa;	/* VQ Resources Flexible Assigned */
124348d370f1SRobert Mustacchi 	uint16_t	nipc_vqrfap;	/* VQ Resources to Primary */
124448d370f1SRobert Mustacchi 	uint16_t	nipc_vqprt;	/* VQ Resources Private Total */
124548d370f1SRobert Mustacchi 	uint16_t	nipc_vqfrsm;	/* VQ Resources Secondary Max */
124648d370f1SRobert Mustacchi 	uint16_t	nipc_vqgran;	/* VQ Flexible Resource Gran */
124748d370f1SRobert Mustacchi 	uint8_t		nipc_rvsd1[64 - 48];
124848d370f1SRobert Mustacchi 	uint32_t	nipc_vifrt;	/* VI Flexible total */
124948d370f1SRobert Mustacchi 	uint32_t	nipc_virfa;	/* VI Flexible Assigned */
12508d5300d3SRobert Mustacchi 	uint16_t	nipc_virfap;	/* VI Flexible Allocated to Primary */
125148d370f1SRobert Mustacchi 	uint16_t	nipc_viprt;	/* VI Resources Private Total */
125248d370f1SRobert Mustacchi 	uint16_t	nipc_vifrsm;	/* VI Resources Secondary Max */
125348d370f1SRobert Mustacchi 	uint16_t	nipc_vigran;	/* VI Flexible Granularity */
125448d370f1SRobert Mustacchi 	uint8_t		nipc_rsvd2[4096 - 80];
125548d370f1SRobert Mustacchi } nvme_identify_primary_caps_t;
12563d9b1a2aSHans Rosenfeld 
12573d9b1a2aSHans Rosenfeld /*
12583d9b1a2aSHans Rosenfeld  * NVMe completion queue entry status field
12593d9b1a2aSHans Rosenfeld  */
12603d9b1a2aSHans Rosenfeld typedef struct {
12613d9b1a2aSHans Rosenfeld 	uint16_t sf_p:1;		/* Phase Tag */
12623d9b1a2aSHans Rosenfeld 	uint16_t sf_sc:8;		/* Status Code */
12633d9b1a2aSHans Rosenfeld 	uint16_t sf_sct:3;		/* Status Code Type */
12643d9b1a2aSHans Rosenfeld 	uint16_t sf_rsvd2:2;
12653d9b1a2aSHans Rosenfeld 	uint16_t sf_m:1;		/* More */
12663d9b1a2aSHans Rosenfeld 	uint16_t sf_dnr:1;		/* Do Not Retry */
12673d9b1a2aSHans Rosenfeld } nvme_cqe_sf_t;
12683d9b1a2aSHans Rosenfeld 
12693d9b1a2aSHans Rosenfeld 
12703d9b1a2aSHans Rosenfeld /*
12713d9b1a2aSHans Rosenfeld  * NVMe Get Log Page
12723d9b1a2aSHans Rosenfeld  */
1273533affcbSRobert Mustacchi #define	NVME_LOGPAGE_SUP	0x00	/* Supported Logs (2.0) */
1274533affcbSRobert Mustacchi #define	NVME_LOGPAGE_ERROR	0x01	/* Error Information */
1275533affcbSRobert Mustacchi #define	NVME_LOGPAGE_HEALTH	0x02	/* SMART/Health Information */
1276533affcbSRobert Mustacchi #define	NVME_LOGPAGE_FWSLOT	0x03	/* Firmware Slot Information */
1277533affcbSRobert Mustacchi #define	NVME_LOGPAGE_NSCHANGE	0x04	/* Changed namespace (1.2) */
1278533affcbSRobert Mustacchi #define	NVME_LOGPAGE_CMDSUP	0x05	/* Cmds. Supported and Effects (1.3) */
1279533affcbSRobert Mustacchi #define	NVME_LOGPAGE_SELFTEST	0x06	/* Device self-test (1.3) */
1280533affcbSRobert Mustacchi #define	NVME_LOGPAGE_TELMHOST	0x07	/* Telemetry Host-Initiated */
1281533affcbSRobert Mustacchi #define	NVME_LOGPAGE_TELMCTRL	0x08	/* Telemetry Controller-Initiated */
1282533affcbSRobert Mustacchi #define	NVME_LOGPAGE_ENDGRP	0x09	/* Endurance Group Information (1.4) */
1283533affcbSRobert Mustacchi #define	NVME_LOGPAGE_PLATSET	0x0a	/* Predictable Lat. per NVM Set (1.4) */
1284533affcbSRobert Mustacchi #define	NVME_LOGPAGE_PLATAGG	0x0b	/* Predictable Lat. Event Agg (1.4) */
1285533affcbSRobert Mustacchi #define	NVME_LOGPAGE_ASYMNS	0x0c	/* Asymmetric Namespace Access (1.4) */
1286533affcbSRobert Mustacchi #define	NVME_LOGPAGE_PEVLOG	0x0d	/* Persistent Event Log (1.4) */
1287533affcbSRobert Mustacchi #define	NVME_LOGPAGE_LBASTS	0x0e	/* LBA Status Information (1.4) */
1288533affcbSRobert Mustacchi #define	NVME_LOGPAGE_ENDAGG	0x0f	/* Endurance Group Event Agg. (1.4) */
1289533affcbSRobert Mustacchi 
1290533affcbSRobert Mustacchi #define	NVME_LOGPAGE_VEND_MIN	0xc0
1291533affcbSRobert Mustacchi #define	NVME_LOGPAGE_VEND_MAX	0xff
12923d9b1a2aSHans Rosenfeld 
1293*046911ebSRobert Mustacchi /*
1294*046911ebSRobert Mustacchi  * Supported Log Pages (2.0). There is one entry of an nvme_logsup_t that then
1295*046911ebSRobert Mustacchi  * exists on a per-log basis.
1296*046911ebSRobert Mustacchi  */
1297*046911ebSRobert Mustacchi 
1298*046911ebSRobert Mustacchi /*
1299*046911ebSRobert Mustacchi  * The NVMe Log Identifier specific parameter field. Currently there is only one
1300*046911ebSRobert Mustacchi  * defined field for the persistent event log (pel).
1301*046911ebSRobert Mustacchi  */
1302*046911ebSRobert Mustacchi typedef union {
1303*046911ebSRobert Mustacchi 	uint16_t nsl_lidsp;		/* Raw Value */
1304*046911ebSRobert Mustacchi 	struct {			/* Persistent Event Log */
1305*046911ebSRobert Mustacchi 		uint16_t nsl_ec512:1;
1306*046911ebSRobert Mustacchi 		uint16_t nsl_pel_rsvd0p1:15;
1307*046911ebSRobert Mustacchi 	} nsl_pel;
1308*046911ebSRobert Mustacchi } nvme_suplog_lidsp_t;
1309*046911ebSRobert Mustacchi 
1310*046911ebSRobert Mustacchi typedef struct {
1311*046911ebSRobert Mustacchi 	uint16_t ns_lsupp:1;
1312*046911ebSRobert Mustacchi 	uint16_t ns_ios:1;
1313*046911ebSRobert Mustacchi 	uint16_t ns_rsvd0p2:14;
1314*046911ebSRobert Mustacchi 	nvme_suplog_lidsp_t ns_lidsp;
1315*046911ebSRobert Mustacchi } nvme_suplog_t;
1316*046911ebSRobert Mustacchi 
1317*046911ebSRobert Mustacchi CTASSERT(sizeof (nvme_suplog_lidsp_t) == 2);
1318*046911ebSRobert Mustacchi CTASSERT(sizeof (nvme_suplog_t) == 4);
1319*046911ebSRobert Mustacchi 
1320*046911ebSRobert Mustacchi typedef struct {
1321*046911ebSRobert Mustacchi 	nvme_suplog_t	nl_logs[256];
1322*046911ebSRobert Mustacchi } nvme_suplog_log_t;
1323*046911ebSRobert Mustacchi 
1324*046911ebSRobert Mustacchi CTASSERT(sizeof (nvme_suplog_log_t) == 1024);
1325*046911ebSRobert Mustacchi 
1326*046911ebSRobert Mustacchi /*
1327*046911ebSRobert Mustacchi  * SMART / Health information
1328*046911ebSRobert Mustacchi  */
13293d9b1a2aSHans Rosenfeld typedef struct {
13303d9b1a2aSHans Rosenfeld 	uint64_t el_count;		/* Error Count */
13313d9b1a2aSHans Rosenfeld 	uint16_t el_sqid;		/* Submission Queue ID */
13323d9b1a2aSHans Rosenfeld 	uint16_t el_cid;		/* Command ID */
13333d9b1a2aSHans Rosenfeld 	nvme_cqe_sf_t el_sf;		/* Status Field */
13343d9b1a2aSHans Rosenfeld 	uint8_t	el_byte;		/* Parameter Error Location byte */
13353d9b1a2aSHans Rosenfeld 	uint8_t	el_bit:3;		/* Parameter Error Location bit */
13363d9b1a2aSHans Rosenfeld 	uint8_t el_rsvd1:5;
13373d9b1a2aSHans Rosenfeld 	uint64_t el_lba;		/* Logical Block Address */
13383d9b1a2aSHans Rosenfeld 	uint32_t el_nsid;		/* Namespace ID */
13393d9b1a2aSHans Rosenfeld 	uint8_t	el_vendor;		/* Vendor Specific Information avail */
13403d9b1a2aSHans Rosenfeld 	uint8_t el_rsvd2[64 - 29];
13413d9b1a2aSHans Rosenfeld } nvme_error_log_entry_t;
13423d9b1a2aSHans Rosenfeld 
13433d9b1a2aSHans Rosenfeld typedef struct {
13443d9b1a2aSHans Rosenfeld 	struct {			/* Critical Warning */
13453d9b1a2aSHans Rosenfeld 		uint8_t cw_avail:1;	/* available space too low */
13463d9b1a2aSHans Rosenfeld 		uint8_t cw_temp:1;	/* temperature too high */
13473d9b1a2aSHans Rosenfeld 		uint8_t cw_reliab:1;	/* degraded reliability */
13483d9b1a2aSHans Rosenfeld 		uint8_t cw_readonly:1;	/* media is read-only */
13493d9b1a2aSHans Rosenfeld 		uint8_t cw_volatile:1;	/* volatile memory backup failed */
13503d9b1a2aSHans Rosenfeld 		uint8_t cw_rsvd:3;
13513d9b1a2aSHans Rosenfeld 	} hl_crit_warn;
13523d9b1a2aSHans Rosenfeld 	uint16_t hl_temp;		/* Temperature */
13533d9b1a2aSHans Rosenfeld 	uint8_t hl_avail_spare;		/* Available Spare */
13543d9b1a2aSHans Rosenfeld 	uint8_t hl_avail_spare_thr;	/* Available Spare Threshold */
13553d9b1a2aSHans Rosenfeld 	uint8_t hl_used;		/* Percentage Used */
13563d9b1a2aSHans Rosenfeld 	uint8_t hl_rsvd1[32 - 6];
13573d9b1a2aSHans Rosenfeld 	nvme_uint128_t hl_data_read;	/* Data Units Read */
13583d9b1a2aSHans Rosenfeld 	nvme_uint128_t hl_data_write;	/* Data Units Written */
13593d9b1a2aSHans Rosenfeld 	nvme_uint128_t hl_host_read;	/* Host Read Commands */
13603d9b1a2aSHans Rosenfeld 	nvme_uint128_t hl_host_write;	/* Host Write Commands */
13613d9b1a2aSHans Rosenfeld 	nvme_uint128_t hl_ctrl_busy;	/* Controller Busy Time */
13623d9b1a2aSHans Rosenfeld 	nvme_uint128_t hl_power_cycles;	/* Power Cycles */
13633d9b1a2aSHans Rosenfeld 	nvme_uint128_t hl_power_on_hours; /* Power On Hours */
13643d9b1a2aSHans Rosenfeld 	nvme_uint128_t hl_unsafe_shutdn; /* Unsafe Shutdowns */
13653d9b1a2aSHans Rosenfeld 	nvme_uint128_t hl_media_errors;	/* Media Errors */
13663d9b1a2aSHans Rosenfeld 	nvme_uint128_t hl_errors_logged; /* Number of errors logged */
13674a663bacSRobert Mustacchi 	/* Added in NVMe 1.2 */
13684a663bacSRobert Mustacchi 	uint32_t hl_warn_temp_time;	/* Warning Composite Temp Time */
13694a663bacSRobert Mustacchi 	uint32_t hl_crit_temp_time;	/* Critical Composite Temp Time */
13704a663bacSRobert Mustacchi 	uint16_t hl_temp_sensor_1;	/* Temperature Sensor 1 */
13714a663bacSRobert Mustacchi 	uint16_t hl_temp_sensor_2;	/* Temperature Sensor 2 */
13724a663bacSRobert Mustacchi 	uint16_t hl_temp_sensor_3;	/* Temperature Sensor 3 */
13734a663bacSRobert Mustacchi 	uint16_t hl_temp_sensor_4;	/* Temperature Sensor 4 */
13744a663bacSRobert Mustacchi 	uint16_t hl_temp_sensor_5;	/* Temperature Sensor 5 */
13754a663bacSRobert Mustacchi 	uint16_t hl_temp_sensor_6;	/* Temperature Sensor 6 */
13764a663bacSRobert Mustacchi 	uint16_t hl_temp_sensor_7;	/* Temperature Sensor 7 */
13774a663bacSRobert Mustacchi 	uint16_t hl_temp_sensor_8;	/* Temperature Sensor 8 */
13784a663bacSRobert Mustacchi 	/* Added in NVMe 1.3 */
13794a663bacSRobert Mustacchi 	uint32_t hl_tmtemp_1_tc;	/* Thermal Mgmt Temp 1 Transition # */
13804a663bacSRobert Mustacchi 	uint32_t hl_tmtemp_2_tc;	/* Thermal Mgmt Temp 1 Transition # */
13814a663bacSRobert Mustacchi 	uint32_t hl_tmtemp_1_time;	/* Time in Thermal Mgmt Temp 1 */
13824a663bacSRobert Mustacchi 	uint32_t hl_tmtemp_2_time;	/* Time in Thermal Mgmt Temp 2 */
13834a663bacSRobert Mustacchi 	uint8_t hl_rsvd2[512 - 232];
13843d9b1a2aSHans Rosenfeld } nvme_health_log_t;
13853d9b1a2aSHans Rosenfeld 
1386e89be50aSRob Johnston /*
1387e89be50aSRob Johnston  * The NVMe spec allows for up to seven firmware slots.
1388e89be50aSRob Johnston  */
1389e89be50aSRob Johnston #define	NVME_MAX_FWSLOTS	7
1390e89be50aSRob Johnston 
13913d9b1a2aSHans Rosenfeld typedef struct {
1392e89be50aSRob Johnston 	/* Active Firmware Slot */
1393e89be50aSRob Johnston 	uint8_t fw_afi:3;
1394cf840871SPaul Winder 	uint8_t fw_rsvd1:1;
1395e89be50aSRob Johnston 	/* Next Active Firmware Slot */
1396e89be50aSRob Johnston 	uint8_t fw_next:3;
1397cf840871SPaul Winder 	uint8_t fw_rsvd2:1;
1398cf840871SPaul Winder 	uint8_t fw_rsvd3[7];
1399e89be50aSRob Johnston 	/* Firmware Revision / Slot */
1400e89be50aSRob Johnston 	char fw_frs[NVME_MAX_FWSLOTS][NVME_FWVER_SZ];
1401cf840871SPaul Winder 	uint8_t fw_rsvd4[512 - 64];
14023d9b1a2aSHans Rosenfeld } nvme_fwslot_log_t;
14033d9b1a2aSHans Rosenfeld 
140404be5853SAndy Fiddaman /*
140504be5853SAndy Fiddaman  * The NVMe spec specifies that the changed namespace list contains up to
140604be5853SAndy Fiddaman  * 1024 entries.
140704be5853SAndy Fiddaman  */
140804be5853SAndy Fiddaman #define	NVME_NSCHANGE_LIST_SIZE	1024
140904be5853SAndy Fiddaman 
141004be5853SAndy Fiddaman typedef struct {
141104be5853SAndy Fiddaman 	uint32_t	nscl_ns[NVME_NSCHANGE_LIST_SIZE];
1412153f3212SHans Rosenfeld } nvme_nschange_list_t;
14133d9b1a2aSHans Rosenfeld 
14143d9b1a2aSHans Rosenfeld /*
1415*046911ebSRobert Mustacchi  * Commands Supported and Effects log page and information structure. This was
1416*046911ebSRobert Mustacchi  * an optional log page added in NVMe 1.2.
1417*046911ebSRobert Mustacchi  */
1418*046911ebSRobert Mustacchi typedef struct {
1419*046911ebSRobert Mustacchi 	uint8_t cmd_csupp:1;	/* Command supported */
1420*046911ebSRobert Mustacchi 	uint8_t cmd_lbcc:1;	/* Logical block content change */
1421*046911ebSRobert Mustacchi 	uint8_t cmd_ncc:1;	/* Namespace capability change */
1422*046911ebSRobert Mustacchi 	uint8_t cmd_nic:1;	/* Namespace inventory change */
1423*046911ebSRobert Mustacchi 	uint8_t cmd_ccc:1;	/* Controller capability change */
1424*046911ebSRobert Mustacchi 	uint8_t cmd_rsvd0p5:3;
1425*046911ebSRobert Mustacchi 	uint8_t cmd_rsvd1;
1426*046911ebSRobert Mustacchi 	uint16_t cmd_cse:3;	/* Command submission and execution */
1427*046911ebSRobert Mustacchi 	uint16_t cmd_uuid:1;	/* UUID select supported, 1.4 */
1428*046911ebSRobert Mustacchi 	uint16_t cmd_csp:12;	/* Command Scope, 2.0 */
1429*046911ebSRobert Mustacchi } nvme_cmdeff_t;
1430*046911ebSRobert Mustacchi 
1431*046911ebSRobert Mustacchi CTASSERT(sizeof (nvme_cmdeff_t) == 4);
1432*046911ebSRobert Mustacchi 
1433*046911ebSRobert Mustacchi typedef enum {
1434*046911ebSRobert Mustacchi 	NVME_CMDEFF_CSP_NS		= 1 << 0,
1435*046911ebSRobert Mustacchi 	NVME_CMDEFF_CSP_CTRL		= 1 << 1,
1436*046911ebSRobert Mustacchi 	NVME_CMDEFF_CSP_SET		= 1 << 2,
1437*046911ebSRobert Mustacchi 	NVME_CMDEFF_CSP_ENDURANCE	= 1 << 3,
1438*046911ebSRobert Mustacchi 	NVME_CMDEFF_CSP_DOMAIN		= 1 << 4,
1439*046911ebSRobert Mustacchi 	NVME_CMDEFF_CSP_NVM		= 1 << 5
1440*046911ebSRobert Mustacchi } nvme_cmdeff_csp_t;
1441*046911ebSRobert Mustacchi 
1442*046911ebSRobert Mustacchi typedef enum {
1443*046911ebSRobert Mustacchi 	NVME_CMDEFF_CSE_NONE	= 0,
1444*046911ebSRobert Mustacchi 	NVME_CMDEFF_CSE_NS,
1445*046911ebSRobert Mustacchi 	NVME_CMDEFF_CSE_CTRL
1446*046911ebSRobert Mustacchi } nvme_cmdeff_cse_t;
1447*046911ebSRobert Mustacchi 
1448*046911ebSRobert Mustacchi typedef struct {
1449*046911ebSRobert Mustacchi 	nvme_cmdeff_t	cme_admin[256];
1450*046911ebSRobert Mustacchi 	nvme_cmdeff_t	cme_io[256];
1451*046911ebSRobert Mustacchi 	uint8_t		cme_rsvd2048[2048];
1452*046911ebSRobert Mustacchi } nvme_cmdeff_log_t;
1453*046911ebSRobert Mustacchi 
1454*046911ebSRobert Mustacchi CTASSERT(sizeof (nvme_cmdeff_log_t) == 4096);
1455*046911ebSRobert Mustacchi CTASSERT(offsetof(nvme_cmdeff_log_t, cme_rsvd2048) == 2048);
1456*046911ebSRobert Mustacchi 
1457*046911ebSRobert Mustacchi /*
14583d9b1a2aSHans Rosenfeld  * NVMe Format NVM
14593d9b1a2aSHans Rosenfeld  */
14603d9b1a2aSHans Rosenfeld #define	NVME_FRMT_SES_NONE	0
14613d9b1a2aSHans Rosenfeld #define	NVME_FRMT_SES_USER	1
14623d9b1a2aSHans Rosenfeld #define	NVME_FRMT_SES_CRYPTO	2
14633d9b1a2aSHans Rosenfeld #define	NVME_FRMT_MAX_SES	2
14643d9b1a2aSHans Rosenfeld 
14653d9b1a2aSHans Rosenfeld #define	NVME_FRMT_MAX_LBAF	15
14663d9b1a2aSHans Rosenfeld 
14673d9b1a2aSHans Rosenfeld typedef union {
14683d9b1a2aSHans Rosenfeld 	struct {
14693d9b1a2aSHans Rosenfeld 		uint32_t fm_lbaf:4;		/* LBA Format */
14703d9b1a2aSHans Rosenfeld 		uint32_t fm_ms:1;		/* Metadata Settings */
14713d9b1a2aSHans Rosenfeld 		uint32_t fm_pi:3;		/* Protection Information */
14723d9b1a2aSHans Rosenfeld 		uint32_t fm_pil:1;		/* Prot. Information Location */
14733d9b1a2aSHans Rosenfeld 		uint32_t fm_ses:3;		/* Secure Erase Settings */
14743d9b1a2aSHans Rosenfeld 		uint32_t fm_resvd:20;
14753d9b1a2aSHans Rosenfeld 	} b;
14763d9b1a2aSHans Rosenfeld 	uint32_t r;
14773d9b1a2aSHans Rosenfeld } nvme_format_nvm_t;
14783d9b1a2aSHans Rosenfeld 
14793d9b1a2aSHans Rosenfeld 
14803d9b1a2aSHans Rosenfeld /*
14813d9b1a2aSHans Rosenfeld  * NVMe Get / Set Features
14823d9b1a2aSHans Rosenfeld  */
14833d9b1a2aSHans Rosenfeld #define	NVME_FEAT_ARBITRATION	0x1	/* Command Arbitration */
14843d9b1a2aSHans Rosenfeld #define	NVME_FEAT_POWER_MGMT	0x2	/* Power Management */
14853d9b1a2aSHans Rosenfeld #define	NVME_FEAT_LBA_RANGE	0x3	/* LBA Range Type */
14863d9b1a2aSHans Rosenfeld #define	NVME_FEAT_TEMPERATURE	0x4	/* Temperature Threshold */
14873d9b1a2aSHans Rosenfeld #define	NVME_FEAT_ERROR		0x5	/* Error Recovery */
14883d9b1a2aSHans Rosenfeld #define	NVME_FEAT_WRITE_CACHE	0x6	/* Volatile Write Cache */
14893d9b1a2aSHans Rosenfeld #define	NVME_FEAT_NQUEUES	0x7	/* Number of Queues */
14903d9b1a2aSHans Rosenfeld #define	NVME_FEAT_INTR_COAL	0x8	/* Interrupt Coalescing */
14913d9b1a2aSHans Rosenfeld #define	NVME_FEAT_INTR_VECT	0x9	/* Interrupt Vector Configuration */
14923d9b1a2aSHans Rosenfeld #define	NVME_FEAT_WRITE_ATOM	0xa	/* Write Atomicity */
14933d9b1a2aSHans Rosenfeld #define	NVME_FEAT_ASYNC_EVENT	0xb	/* Asynchronous Event Configuration */
14943d9b1a2aSHans Rosenfeld #define	NVME_FEAT_AUTO_PST	0xc	/* Autonomous Power State Transition */
14953d9b1a2aSHans Rosenfeld 					/* (1.1) */
14963d9b1a2aSHans Rosenfeld 
14973d9b1a2aSHans Rosenfeld #define	NVME_FEAT_PROGRESS	0x80	/* Software Progress Marker */
14983d9b1a2aSHans Rosenfeld 
1499533affcbSRobert Mustacchi /*
1500533affcbSRobert Mustacchi  * This enumeration represents the capabilities in the Get Features select / Set
1501533affcbSRobert Mustacchi  * Features save options. This was introduced in NVMe 1.1 and the values below
1502533affcbSRobert Mustacchi  * match the specification. An optional feature in the identify controller data
1503533affcbSRobert Mustacchi  * structure is set to indicate that this is supported (id_oncs.on_save).
1504533affcbSRobert Mustacchi  */
1505533affcbSRobert Mustacchi typedef enum {
1506533affcbSRobert Mustacchi 	NVME_FEATURE_SEL_CURRENT	= 0,
1507533affcbSRobert Mustacchi 	NVME_FEATURE_SEL_DEFAULT,
1508533affcbSRobert Mustacchi 	NVME_FEATURE_SEL_SAVED,
1509533affcbSRobert Mustacchi 	NVME_FEATURE_SEL_SUPPORTED
1510533affcbSRobert Mustacchi } nvme_feature_sel_t;
1511533affcbSRobert Mustacchi 
1512533affcbSRobert Mustacchi typedef union {
1513533affcbSRobert Mustacchi 	struct {
1514533affcbSRobert Mustacchi 		uint32_t gt_fid:8;	/* Feature ID */
1515533affcbSRobert Mustacchi 		uint32_t gt_sel:3;	/* Select */
1516533affcbSRobert Mustacchi 		uint32_t gt_rsvd:21;
1517533affcbSRobert Mustacchi 	} b;
1518533affcbSRobert Mustacchi 	uint32_t r;
1519533affcbSRobert Mustacchi } nvme_get_features_dw10_t;
1520533affcbSRobert Mustacchi 
15213d9b1a2aSHans Rosenfeld /* Arbitration Feature */
15223d9b1a2aSHans Rosenfeld typedef union {
15233d9b1a2aSHans Rosenfeld 	struct {
15243d9b1a2aSHans Rosenfeld 		uint8_t arb_ab:3;	/* Arbitration Burst */
15253d9b1a2aSHans Rosenfeld 		uint8_t arb_rsvd:5;
15263d9b1a2aSHans Rosenfeld 		uint8_t arb_lpw;	/* Low Priority Weight */
15273d9b1a2aSHans Rosenfeld 		uint8_t arb_mpw;	/* Medium Priority Weight */
15283d9b1a2aSHans Rosenfeld 		uint8_t arb_hpw;	/* High Priority Weight */
15293d9b1a2aSHans Rosenfeld 	} b;
15303d9b1a2aSHans Rosenfeld 	uint32_t r;
15313d9b1a2aSHans Rosenfeld } nvme_arbitration_t;
15323d9b1a2aSHans Rosenfeld 
15333d9b1a2aSHans Rosenfeld /* Power Management Feature */
15343d9b1a2aSHans Rosenfeld typedef union {
15353d9b1a2aSHans Rosenfeld 	struct {
15363d9b1a2aSHans Rosenfeld 		uint32_t pm_ps:5;	/* Power State */
15373d9b1a2aSHans Rosenfeld 		uint32_t pm_rsvd:27;
15383d9b1a2aSHans Rosenfeld 	} b;
15393d9b1a2aSHans Rosenfeld 	uint32_t r;
15403d9b1a2aSHans Rosenfeld } nvme_power_mgmt_t;
15413d9b1a2aSHans Rosenfeld 
15423d9b1a2aSHans Rosenfeld /* LBA Range Type Feature */
15433d9b1a2aSHans Rosenfeld typedef union {
15443d9b1a2aSHans Rosenfeld 	struct {
15453d9b1a2aSHans Rosenfeld 		uint32_t lr_num:6;	/* Number of LBA ranges */
15463d9b1a2aSHans Rosenfeld 		uint32_t lr_rsvd:26;
15473d9b1a2aSHans Rosenfeld 	} b;
15483d9b1a2aSHans Rosenfeld 	uint32_t r;
15493d9b1a2aSHans Rosenfeld } nvme_lba_range_type_t;
15503d9b1a2aSHans Rosenfeld 
15513d9b1a2aSHans Rosenfeld typedef struct {
15523d9b1a2aSHans Rosenfeld 	uint8_t lr_type;		/* Type */
15533d9b1a2aSHans Rosenfeld 	struct {			/* Attributes */
15543d9b1a2aSHans Rosenfeld 		uint8_t lr_write:1;	/* may be overwritten */
15553d9b1a2aSHans Rosenfeld 		uint8_t lr_hidden:1;	/* hidden from OS/EFI/BIOS */
15563d9b1a2aSHans Rosenfeld 		uint8_t lr_rsvd1:6;
15573d9b1a2aSHans Rosenfeld 	} lr_attr;
15583d9b1a2aSHans Rosenfeld 	uint8_t lr_rsvd2[14];
15593d9b1a2aSHans Rosenfeld 	uint64_t lr_slba;		/* Starting LBA */
15603d9b1a2aSHans Rosenfeld 	uint64_t lr_nlb;		/* Number of Logical Blocks */
15613d9b1a2aSHans Rosenfeld 	uint8_t lr_guid[16];		/* Unique Identifier */
15623d9b1a2aSHans Rosenfeld 	uint8_t lr_rsvd3[16];
15633d9b1a2aSHans Rosenfeld } nvme_lba_range_t;
15643d9b1a2aSHans Rosenfeld 
15653d9b1a2aSHans Rosenfeld #define	NVME_LBA_RANGE_BUFSIZE	4096
15663d9b1a2aSHans Rosenfeld 
15673d9b1a2aSHans Rosenfeld /* Temperature Threshold Feature */
15683d9b1a2aSHans Rosenfeld typedef union {
15693d9b1a2aSHans Rosenfeld 	struct {
15703d9b1a2aSHans Rosenfeld 		uint16_t tt_tmpth;	/* Temperature Threshold */
15714a663bacSRobert Mustacchi 		uint16_t tt_tmpsel:4;	/* Temperature Select */
15724a663bacSRobert Mustacchi 		uint16_t tt_thsel:2;	/* Temperature Type */
15734a663bacSRobert Mustacchi 		uint16_t tt_resv:10;
15743d9b1a2aSHans Rosenfeld 	} b;
15753d9b1a2aSHans Rosenfeld 	uint32_t r;
15763d9b1a2aSHans Rosenfeld } nvme_temp_threshold_t;
15773d9b1a2aSHans Rosenfeld 
15784a663bacSRobert Mustacchi #define	NVME_TEMP_THRESH_MAX_SENSOR	8
15794a663bacSRobert Mustacchi #define	NVME_TEMP_THRESH_ALL	0xf
15804a663bacSRobert Mustacchi #define	NVME_TEMP_THRESH_OVER	0x00
15814a663bacSRobert Mustacchi #define	NVME_TEMP_THRESH_UNDER	0x01
15824a663bacSRobert Mustacchi 
15833d9b1a2aSHans Rosenfeld /* Error Recovery Feature */
15843d9b1a2aSHans Rosenfeld typedef union {
15853d9b1a2aSHans Rosenfeld 	struct {
15863d9b1a2aSHans Rosenfeld 		uint16_t er_tler;	/* Time-Limited Error Recovery */
15873d9b1a2aSHans Rosenfeld 		uint16_t er_rsvd;
15883d9b1a2aSHans Rosenfeld 	} b;
15893d9b1a2aSHans Rosenfeld 	uint32_t r;
15903d9b1a2aSHans Rosenfeld } nvme_error_recovery_t;
15913d9b1a2aSHans Rosenfeld 
15923d9b1a2aSHans Rosenfeld /* Volatile Write Cache Feature */
15933d9b1a2aSHans Rosenfeld typedef union {
15943d9b1a2aSHans Rosenfeld 	struct {
15953d9b1a2aSHans Rosenfeld 		uint32_t wc_wce:1;	/* Volatile Write Cache Enable */
15963d9b1a2aSHans Rosenfeld 		uint32_t wc_rsvd:31;
15973d9b1a2aSHans Rosenfeld 	} b;
15983d9b1a2aSHans Rosenfeld 	uint32_t r;
15993d9b1a2aSHans Rosenfeld } nvme_write_cache_t;
16003d9b1a2aSHans Rosenfeld 
16013d9b1a2aSHans Rosenfeld /* Number of Queues Feature */
16023d9b1a2aSHans Rosenfeld typedef union {
16033d9b1a2aSHans Rosenfeld 	struct {
16043d9b1a2aSHans Rosenfeld 		uint16_t nq_nsq;	/* Number of Submission Queues */
16053d9b1a2aSHans Rosenfeld 		uint16_t nq_ncq;	/* Number of Completion Queues */
16063d9b1a2aSHans Rosenfeld 	} b;
16073d9b1a2aSHans Rosenfeld 	uint32_t r;
16083d9b1a2aSHans Rosenfeld } nvme_nqueues_t;
16093d9b1a2aSHans Rosenfeld 
16103d9b1a2aSHans Rosenfeld /* Interrupt Coalescing Feature */
16113d9b1a2aSHans Rosenfeld typedef union {
16123d9b1a2aSHans Rosenfeld 	struct {
16133d9b1a2aSHans Rosenfeld 		uint8_t ic_thr;		/* Aggregation Threshold */
16143d9b1a2aSHans Rosenfeld 		uint8_t ic_time;	/* Aggregation Time */
16153d9b1a2aSHans Rosenfeld 		uint16_t ic_rsvd;
16163d9b1a2aSHans Rosenfeld 	} b;
16173d9b1a2aSHans Rosenfeld 	uint32_t r;
16183d9b1a2aSHans Rosenfeld } nvme_intr_coal_t;
16193d9b1a2aSHans Rosenfeld 
16203d9b1a2aSHans Rosenfeld /* Interrupt Configuration Features */
16213d9b1a2aSHans Rosenfeld typedef union {
16223d9b1a2aSHans Rosenfeld 	struct {
16233d9b1a2aSHans Rosenfeld 		uint16_t iv_iv;		/* Interrupt Vector */
16243d9b1a2aSHans Rosenfeld 		uint16_t iv_cd:1;	/* Coalescing Disable */
16253d9b1a2aSHans Rosenfeld 		uint16_t iv_rsvd:15;
16263d9b1a2aSHans Rosenfeld 	} b;
16273d9b1a2aSHans Rosenfeld 	uint32_t r;
16283d9b1a2aSHans Rosenfeld } nvme_intr_vect_t;
16293d9b1a2aSHans Rosenfeld 
16303d9b1a2aSHans Rosenfeld /* Write Atomicity Feature */
16313d9b1a2aSHans Rosenfeld typedef union {
16323d9b1a2aSHans Rosenfeld 	struct {
16333d9b1a2aSHans Rosenfeld 		uint32_t wa_dn:1;	/* Disable Normal */
16343d9b1a2aSHans Rosenfeld 		uint32_t wa_rsvd:31;
16353d9b1a2aSHans Rosenfeld 	} b;
16363d9b1a2aSHans Rosenfeld 	uint32_t r;
16373d9b1a2aSHans Rosenfeld } nvme_write_atomicity_t;
16383d9b1a2aSHans Rosenfeld 
16393d9b1a2aSHans Rosenfeld /* Asynchronous Event Configuration Feature */
16403d9b1a2aSHans Rosenfeld typedef union {
16413d9b1a2aSHans Rosenfeld 	struct {
164204be5853SAndy Fiddaman 		uint8_t aec_avail:1;	/* Available space too low */
164304be5853SAndy Fiddaman 		uint8_t aec_temp:1;	/* Temperature too high */
164404be5853SAndy Fiddaman 		uint8_t aec_reliab:1;	/* Degraded reliability */
164504be5853SAndy Fiddaman 		uint8_t aec_readonly:1;	/* Media is read-only */
164604be5853SAndy Fiddaman 		uint8_t aec_volatile:1;	/* Volatile memory backup failed */
16473d9b1a2aSHans Rosenfeld 		uint8_t aec_rsvd1:3;
164804be5853SAndy Fiddaman 		uint8_t aec_nsan:1;	/* Namespace attribute notices (1.2) */
164904be5853SAndy Fiddaman 		uint8_t aec_fwact:1;	/* Firmware activation notices (1.2) */
165004be5853SAndy Fiddaman 		uint8_t aec_telln:1;	/* Telemetry log notices (1.3) */
165104be5853SAndy Fiddaman 		uint8_t aec_ansacn:1;	/* Asymm. NS access change (1.4) */
165204be5853SAndy Fiddaman 		uint8_t aec_plat:1;	/* Predictable latency ev. agg. (1.4) */
165304be5853SAndy Fiddaman 		uint8_t aec_lbasi:1;	/* LBA status information (1.4) */
165404be5853SAndy Fiddaman 		uint8_t aec_egeal:1;	/* Endurance group ev. agg. (1.4) */
165504be5853SAndy Fiddaman 		uint8_t aec_rsvd2:1;
165604be5853SAndy Fiddaman 		uint8_t aec_rsvd3[2];
16573d9b1a2aSHans Rosenfeld 	} b;
16583d9b1a2aSHans Rosenfeld 	uint32_t r;
16593d9b1a2aSHans Rosenfeld } nvme_async_event_conf_t;
16603d9b1a2aSHans Rosenfeld 
16613d9b1a2aSHans Rosenfeld /* Autonomous Power State Transition Feature (1.1) */
16623d9b1a2aSHans Rosenfeld typedef union {
16633d9b1a2aSHans Rosenfeld 	struct {
1664533affcbSRobert Mustacchi 		uint32_t apst_apste:1;	/* APST enabled */
1665533affcbSRobert Mustacchi 		uint32_t apst_rsvd:31;
16663d9b1a2aSHans Rosenfeld 	} b;
1667533affcbSRobert Mustacchi 	uint32_t r;
16683d9b1a2aSHans Rosenfeld } nvme_auto_power_state_trans_t;
16693d9b1a2aSHans Rosenfeld 
16703d9b1a2aSHans Rosenfeld typedef struct {
16713d9b1a2aSHans Rosenfeld 	uint32_t apst_rsvd1:3;
16723d9b1a2aSHans Rosenfeld 	uint32_t apst_itps:5;	/* Idle Transition Power State */
16733d9b1a2aSHans Rosenfeld 	uint32_t apst_itpt:24;	/* Idle Time Prior to Transition */
16743d9b1a2aSHans Rosenfeld 	uint32_t apst_rsvd2;
16753d9b1a2aSHans Rosenfeld } nvme_auto_power_state_t;
16763d9b1a2aSHans Rosenfeld 
16773d9b1a2aSHans Rosenfeld #define	NVME_AUTO_PST_BUFSIZE	256
16783d9b1a2aSHans Rosenfeld 
16793d9b1a2aSHans Rosenfeld /* Software Progress Marker Feature */
16803d9b1a2aSHans Rosenfeld typedef union {
16813d9b1a2aSHans Rosenfeld 	struct {
16823d9b1a2aSHans Rosenfeld 		uint8_t spm_pbslc;	/* Pre-Boot Software Load Count */
16833d9b1a2aSHans Rosenfeld 		uint8_t spm_rsvd[3];
16843d9b1a2aSHans Rosenfeld 	} b;
16853d9b1a2aSHans Rosenfeld 	uint32_t r;
16863d9b1a2aSHans Rosenfeld } nvme_software_progress_marker_t;
16873d9b1a2aSHans Rosenfeld 
1688cf840871SPaul Winder /*
1689cf840871SPaul Winder  * Firmware Commit - Command Dword 10
1690cf840871SPaul Winder  */
1691cf840871SPaul Winder #define	NVME_FWC_SAVE		0x0	/* Save image only */
1692cf840871SPaul Winder #define	NVME_FWC_SAVE_ACTIVATE	0x1	/* Save and activate at next reset */
1693cf840871SPaul Winder #define	NVME_FWC_ACTIVATE	0x2	/* Activate slot at next reset */
1694cf840871SPaul Winder #define	NVME_FWC_ACTIVATE_IMMED	0x3	/* Activate slot immediately */
1695cf840871SPaul Winder 
1696cf840871SPaul Winder /*
1697cf840871SPaul Winder  * Firmware slot number is only 3 bits, and zero is not allowed.
1698cf840871SPaul Winder  * Valid range is 1 to 7.
1699cf840871SPaul Winder  */
1700533affcbSRobert Mustacchi #define	NVME_FW_SLOT_MIN	1U	/* lowest allowable slot number ... */
1701533affcbSRobert Mustacchi #define	NVME_FW_SLOT_MAX	7U	/* ... and highest */
1702cf840871SPaul Winder 
1703cf840871SPaul Winder /*
1704cf840871SPaul Winder  * Some constants to make verification of DWORD variables and arguments easier.
1705cf840871SPaul Winder  * A DWORD is 4 bytes.
1706cf840871SPaul Winder  */
1707cf840871SPaul Winder #define	NVME_DWORD_SHIFT	2
1708cf840871SPaul Winder #define	NVME_DWORD_SIZE		(1 << NVME_DWORD_SHIFT)
1709cf840871SPaul Winder #define	NVME_DWORD_MASK		(NVME_DWORD_SIZE - 1)
1710cf840871SPaul Winder 
1711cf840871SPaul Winder /*
1712cf840871SPaul Winder  * Maximum offset a firmware image can be load at is the number of
1713cf840871SPaul Winder  * DWORDS in a 32 bit field. Expressed in bytes its is:
1714cf840871SPaul Winder  */
1715cf840871SPaul Winder #define	NVME_FW_OFFSETB_MAX	((u_longlong_t)UINT32_MAX << NVME_DWORD_SHIFT)
1716cf840871SPaul Winder 
1717cf840871SPaul Winder typedef union {
1718cf840871SPaul Winder 	struct {
1719cf840871SPaul Winder 		uint32_t fc_slot:3;	/* Firmware slot */
1720cf840871SPaul Winder 		uint32_t fc_action:3;	/* Commit action */
1721cf840871SPaul Winder 		uint32_t fc_rsvd:26;
1722cf840871SPaul Winder 	} b;
1723cf840871SPaul Winder 	uint32_t r;
1724cf840871SPaul Winder } nvme_firmware_commit_dw10_t;
1725cf840871SPaul Winder 
17263d9b1a2aSHans Rosenfeld #pragma pack() /* pack(1) */
17273d9b1a2aSHans Rosenfeld 
1728cf840871SPaul Winder /* NVMe completion status code type */
1729cf840871SPaul Winder #define	NVME_CQE_SCT_GENERIC	0	/* Generic Command Status */
1730cf840871SPaul Winder #define	NVME_CQE_SCT_SPECIFIC	1	/* Command Specific Status */
1731cf840871SPaul Winder #define	NVME_CQE_SCT_INTEGRITY	2	/* Media and Data Integrity Errors */
1732e7efdd31SRobert Mustacchi #define	NVME_CQE_SCT_PATH	3	/* Path Related Status (1.4) */
1733cf840871SPaul Winder #define	NVME_CQE_SCT_VENDOR	7	/* Vendor Specific */
1734cf840871SPaul Winder 
1735533affcbSRobert Mustacchi /*
1736533affcbSRobert Mustacchi  * Status code ranges
1737533affcbSRobert Mustacchi  */
1738533affcbSRobert Mustacchi #define	NVME_CQE_SC_GEN_MIN		0x00
1739533affcbSRobert Mustacchi #define	NVME_CQE_SC_GEN_MAX		0x7f
1740533affcbSRobert Mustacchi #define	NVME_CQE_SC_CSI_MIN		0x80
1741533affcbSRobert Mustacchi #define	NVME_CQE_SC_CSI_MAX		0xbf
1742533affcbSRobert Mustacchi #define	NVME_CQE_SC_VEND_MIN		0xc0
1743533affcbSRobert Mustacchi #define	NVME_CQE_SC_VEND_MAX		0xff
1744533affcbSRobert Mustacchi 
1745cf840871SPaul Winder /* NVMe completion status code (generic) */
1746cf840871SPaul Winder #define	NVME_CQE_SC_GEN_SUCCESS		0x0	/* Successful Completion */
1747cf840871SPaul Winder #define	NVME_CQE_SC_GEN_INV_OPC		0x1	/* Invalid Command Opcode */
1748cf840871SPaul Winder #define	NVME_CQE_SC_GEN_INV_FLD		0x2	/* Invalid Field in Command */
1749cf840871SPaul Winder #define	NVME_CQE_SC_GEN_ID_CNFL		0x3	/* Command ID Conflict */
1750cf840871SPaul Winder #define	NVME_CQE_SC_GEN_DATA_XFR_ERR	0x4	/* Data Transfer Error */
1751cf840871SPaul Winder #define	NVME_CQE_SC_GEN_ABORT_PWRLOSS	0x5	/* Cmds Aborted / Pwr Loss */
1752cf840871SPaul Winder #define	NVME_CQE_SC_GEN_INTERNAL_ERR	0x6	/* Internal Error */
1753cf840871SPaul Winder #define	NVME_CQE_SC_GEN_ABORT_REQUEST	0x7	/* Command Abort Requested */
1754cf840871SPaul Winder #define	NVME_CQE_SC_GEN_ABORT_SQ_DEL	0x8	/* Cmd Aborted / SQ deletion */
1755cf840871SPaul Winder #define	NVME_CQE_SC_GEN_ABORT_FUSE_FAIL	0x9	/* Cmd Aborted / Failed Fused */
1756cf840871SPaul Winder #define	NVME_CQE_SC_GEN_ABORT_FUSE_MISS	0xa	/* Cmd Aborted / Missing Fusd */
1757cf840871SPaul Winder #define	NVME_CQE_SC_GEN_INV_NS		0xb	/* Inval Namespace or Format */
1758cf840871SPaul Winder #define	NVME_CQE_SC_GEN_CMD_SEQ_ERR	0xc	/* Command Sequence Error */
1759cf840871SPaul Winder #define	NVME_CQE_SC_GEN_INV_SGL_LAST	0xd	/* Inval SGL Last Seg Desc */
1760cf840871SPaul Winder #define	NVME_CQE_SC_GEN_INV_SGL_NUM	0xe	/* Inval Number of SGL Desc */
1761cf840871SPaul Winder #define	NVME_CQE_SC_GEN_INV_DSGL_LEN	0xf	/* Data SGL Length Invalid */
1762cf840871SPaul Winder #define	NVME_CQE_SC_GEN_INV_MSGL_LEN	0x10	/* Metadata SGL Length Inval */
1763cf840871SPaul Winder #define	NVME_CQE_SC_GEN_INV_SGL_DESC	0x11	/* SGL Descriptor Type Inval */
1764e7efdd31SRobert Mustacchi /* Added in NVMe 1.2 */
1765cf840871SPaul Winder #define	NVME_CQE_SC_GEN_INV_USE_CMB	0x12	/* Inval use of Ctrl Mem Buf */
1766cf840871SPaul Winder #define	NVME_CQE_SC_GEN_INV_PRP_OFF	0x13	/* PRP Offset Invalid */
1767cf840871SPaul Winder #define	NVME_CQE_SC_GEN_AWU_EXCEEDED	0x14	/* Atomic Write Unit Exceeded */
1768e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_OP_DENIED	0x15	/* Operation Denied */
1769e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_INV_SGL_OFF	0x16	/* SGL Offset Invalid */
1770e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_INV_SGL_ST	0x17	/* SGL Sub type Invalid */
1771e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_INCON_HOSTID	0x18	/* Host ID Inconsistent fmt */
1772e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_KA_EXP		0x19	/* Keep Alive Timer Expired */
1773e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_INV_KA_TO	0x1a	/* Keep Alive Timeout Invalid */
1774e7efdd31SRobert Mustacchi /* Added in NVMe 1.3 */
1775e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_ABORT_PREEMPT	0x1b	/* Cmd aborted due to preempt */
1776e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_SANITIZE_FAIL	0x1c	/* Sanitize Failed */
1777e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_SANITIZING	0x1d	/* Sanitize in Progress */
1778e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_INV_SGL_GRAN	0x1e	/* SGL Data Block Gran. Inval */
1779e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_NO_CMD_Q_CMD	0x1f	/* Command not sup for CMB Q */
1780e7efdd31SRobert Mustacchi /* Added in NVMe 1.4 */
1781e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_NS_RDONLY	0x20	/* Namespace is write prot. */
1782e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_CMD_INTR	0x21	/* Command Interrupted */
1783e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_TRANSIENT	0x22	/* Transient Transport Error */
1784e7efdd31SRobert Mustacchi /* Added in NVMe 2.0 */
1785e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_CMD_LOCK	0x23	/* Command/Feature Lockdown */
1786e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_ADM_MEDIA_NR	0x24	/* Admin Cmd Media Not Ready */
1787cf840871SPaul Winder 
1788cf840871SPaul Winder /* NVMe completion status code (generic NVM commands) */
1789cf840871SPaul Winder #define	NVME_CQE_SC_GEN_NVM_LBA_RANGE	0x80	/* LBA Out Of Range */
1790cf840871SPaul Winder #define	NVME_CQE_SC_GEN_NVM_CAP_EXC	0x81	/* Capacity Exceeded */
1791cf840871SPaul Winder #define	NVME_CQE_SC_GEN_NVM_NS_NOTRDY	0x82	/* Namespace Not Ready */
1792cf840871SPaul Winder #define	NVME_CQE_SC_GEN_NVM_RSV_CNFLCT	0x83	/* Reservation Conflict */
17933eaaeb3dSAndy Fiddaman #define	NVME_CQE_SC_GEN_NVM_FORMATTING	0x84	/* Format in progress (1.2) */
1794e7efdd31SRobert Mustacchi /* Added in NVMe 2.0 */
1795e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_KEY_INV_VAL	0x85	/* Invalid value size */
1796e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_KEY_INV_KEY	0x86	/* Invalid key size */
1797e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_KEY_ENOENT	0x87	/* KV Key Does Not Exist */
1798e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_KEY_UNRECOV	0x88	/* Unrecovered Error */
1799e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_GEN_KEY_EXISTS	0x89	/* Key already exists */
1800cf840871SPaul Winder 
1801cf840871SPaul Winder /* NVMe completion status code (command specific) */
1802cf840871SPaul Winder #define	NVME_CQE_SC_SPC_INV_CQ		0x0	/* Completion Queue Invalid */
1803cf840871SPaul Winder #define	NVME_CQE_SC_SPC_INV_QID		0x1	/* Invalid Queue Identifier */
1804cf840871SPaul Winder #define	NVME_CQE_SC_SPC_MAX_QSZ_EXC	0x2	/* Max Queue Size Exceeded */
1805cf840871SPaul Winder #define	NVME_CQE_SC_SPC_ABRT_CMD_EXC	0x3	/* Abort Cmd Limit Exceeded */
1806cf840871SPaul Winder #define	NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC	0x5	/* Async Event Request Limit */
1807cf840871SPaul Winder #define	NVME_CQE_SC_SPC_INV_FW_SLOT	0x6	/* Invalid Firmware Slot */
1808cf840871SPaul Winder #define	NVME_CQE_SC_SPC_INV_FW_IMG	0x7	/* Invalid Firmware Image */
1809cf840871SPaul Winder #define	NVME_CQE_SC_SPC_INV_INT_VECT	0x8	/* Invalid Interrupt Vector */
1810cf840871SPaul Winder #define	NVME_CQE_SC_SPC_INV_LOG_PAGE	0x9	/* Invalid Log Page */
1811cf840871SPaul Winder #define	NVME_CQE_SC_SPC_INV_FORMAT	0xa	/* Invalid Format */
1812cf840871SPaul Winder #define	NVME_CQE_SC_SPC_FW_RESET	0xb	/* FW Application Reset Reqd */
1813cf840871SPaul Winder #define	NVME_CQE_SC_SPC_INV_Q_DEL	0xc	/* Invalid Queue Deletion */
1814cf840871SPaul Winder #define	NVME_CQE_SC_SPC_FEAT_SAVE	0xd	/* Feature Id Not Saveable */
1815cf840871SPaul Winder #define	NVME_CQE_SC_SPC_FEAT_CHG	0xe	/* Feature Not Changeable */
1816cf840871SPaul Winder #define	NVME_CQE_SC_SPC_FEAT_NS_SPEC	0xf	/* Feature Not Namespace Spec */
1817e7efdd31SRobert Mustacchi /* Added in NVMe 1.2 */
1818cf840871SPaul Winder #define	NVME_CQE_SC_SPC_FW_NSSR		0x10	/* FW Application NSSR Reqd */
1819cf840871SPaul Winder #define	NVME_CQE_SC_SPC_FW_NEXT_RESET	0x11	/* FW Application Next Reqd */
1820cf840871SPaul Winder #define	NVME_CQE_SC_SPC_FW_MTFA		0x12	/* FW Application Exceed MTFA */
1821cf840871SPaul Winder #define	NVME_CQE_SC_SPC_FW_PROHIBITED	0x13	/* FW Application Prohibited */
1822cf840871SPaul Winder #define	NVME_CQE_SC_SPC_FW_OVERLAP	0x14	/* Overlapping FW ranges */
1823e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_NS_INSUF_CAP	0x15	/* NS Insufficient Capacity */
1824e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_NS_NO_ID	0x16	/* NS ID Unavailable */
1825e7efdd31SRobert Mustacchi /* 0x17 is reserved */
1826e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_NS_ATTACHED	0x18	/* NS Already Attached */
1827e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_NS_PRIV		0x19	/* NS is private */
1828e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_NS_NOT_ATTACH	0x1a	/* NS Not Attached */
1829e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_THIN_ENOTSUP	0x1b	/* Thin Provisioning ENOTSUP */
1830e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_INV_CTRL_LIST	0x1c	/* Controller list invalid */
1831e7efdd31SRobert Mustacchi /* Added in NVMe 1.3 */
1832e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_SELF_TESTING	0x1d	/* Self-test in progress */
1833e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_NO_BP_WRITE	0x1e	/* No Boot Partition Write */
1834e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_INV_CTRL_ID	0x1f	/* Invalid Controller Id */
1835e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_INV_SEC_CTRL	0x20	/* Invalid Sec. Ctrl state */
1836e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_INV_CTRL_NRSRC	0x21	/* Inv. # Ctrl Resources */
1837e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_INV_RSRC_ID	0x22	/* Inv. Resource ID */
1838e7efdd31SRobert Mustacchi /* Added in NVMe 1.4 */
1839e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_NO_SAN_PMR	0x23	/* Sanitize prohib. w/ pmem */
1840e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_INV_ANA_GID	0x24	/* Invalid ANA group ID */
1841e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_ANA_ATTACH	0x25	/* ANA Attach Failed */
1842e7efdd31SRobert Mustacchi /* Added in NVMe 2.0 */
1843e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_INSUF_CAP	0x26	/* Insufficient Capacity */
1844e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_NS_ATTACH_LIM	0x27	/* NS Attach Limit Exceeded */
1845e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_LOCKDOWN_UNSUP	0x28	/* Prohib Cmd Exec Not Sup */
1846e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_UNSUP_IO_CMD	0x29	/* I/O Command set not sup */
1847e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_DIS_IO_CMD	0x2a	/* I/O Command set not enab */
1848e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_INV_CMD_COMBO	0x2b	/* I/O command set combo rej */
1849e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_INV_IO_CMD	0x2c	/* Invalid I/O command set */
1850e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_UNAVAIL_ID	0x2d	/* Unavailable ID */
1851cf840871SPaul Winder 
1852e7efdd31SRobert Mustacchi 
1853e7efdd31SRobert Mustacchi /* NVMe completion status code (I/O command specific) */
1854cf840871SPaul Winder #define	NVME_CQE_SC_SPC_NVM_CNFL_ATTR	0x80	/* Conflicting Attributes */
1855cf840871SPaul Winder #define	NVME_CQE_SC_SPC_NVM_INV_PROT	0x81	/* Invalid Protection */
1856cf840871SPaul Winder #define	NVME_CQE_SC_SPC_NVM_READONLY	0x82	/* Write to Read Only Range */
1857e7efdd31SRobert Mustacchi /* Added in 2.0 */
1858e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_IO_LIMIT	0x83	/* Cmd Size Limit Exceeded */
1859e7efdd31SRobert Mustacchi /* 0x84 to 0xb7 are reserved */
1860e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_ZONE_BDRY_ERR	0xb8	/* Zoned Boundary Error */
1861e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_ZONE_FULL	0xb9	/* Zone is Full */
1862e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_ZONE_RDONLY	0xba	/* Zone is Read Only */
1863e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_ZONE_OFFLINE	0xbb	/* Zone is Offline */
1864e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_ZONE_INV_WRITE	0xbc	/* Zone Invalid Write */
1865e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_ZONE_ACT	0xbd	/* Too May Active Zones */
1866e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_ZONE_OPEN	0xbe	/* Too May Open Zones */
1867e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_SPC_INV_ZONE_TRANS	0xbf	/* Invalid Zone State Trans */
1868cf840871SPaul Winder 
1869cf840871SPaul Winder /* NVMe completion status code (data / metadata integrity) */
1870cf840871SPaul Winder #define	NVME_CQE_SC_INT_NVM_WRITE	0x80	/* Write Fault */
1871cf840871SPaul Winder #define	NVME_CQE_SC_INT_NVM_READ	0x81	/* Unrecovered Read Error */
1872cf840871SPaul Winder #define	NVME_CQE_SC_INT_NVM_GUARD	0x82	/* Guard Check Error */
1873cf840871SPaul Winder #define	NVME_CQE_SC_INT_NVM_APPL_TAG	0x83	/* Application Tag Check Err */
1874cf840871SPaul Winder #define	NVME_CQE_SC_INT_NVM_REF_TAG	0x84	/* Reference Tag Check Err */
1875cf840871SPaul Winder #define	NVME_CQE_SC_INT_NVM_COMPARE	0x85	/* Compare Failure */
1876cf840871SPaul Winder #define	NVME_CQE_SC_INT_NVM_ACCESS	0x86	/* Access Denied */
1877e7efdd31SRobert Mustacchi /* Added in 1.2 */
1878e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_INT_NVM_DEALLOC	0x87	/* Dealloc Log Block */
1879e7efdd31SRobert Mustacchi /* Added in 2.0 */
1880e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_INT_NVM_TAG		0x88	/* End-to-End Storage Tag Err */
1881e7efdd31SRobert Mustacchi 
1882e7efdd31SRobert Mustacchi /* NVMe completion status code (path related) */
1883e7efdd31SRobert Mustacchi /* Added in NVMe 1.4 */
1884e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_PATH_INT_ERR	0x00	/* Internal Path Error */
1885e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_PATH_AA_PLOSS	0x01	/* Asym Access Pers Loss */
1886e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_PATH_AA_INACC	0x02	/* Asym Access Inaccessible */
1887e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_PATH_AA_TRANS	0x03	/* Asym Access Transition */
1888e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_PATH_CTRL_ERR	0x60	/* Controller Path Error */
1889e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_PATH_HOST_ERR	0x70	/* Host Path Error */
1890e7efdd31SRobert Mustacchi #define	NVME_CQE_SC_PATH_HOST_ABRT	0x71	/* Cmd aborted by host */
18913d9b1a2aSHans Rosenfeld 
1892eb7b3ff7SBenjamin Naecker /*
1893533affcbSRobert Mustacchi  * Controller information (NVME_IOC_CTRL_INFO). This is a consolidation of misc.
1894533affcbSRobert Mustacchi  * information that we want to know about a controller.
1895eb7b3ff7SBenjamin Naecker  */
1896eb7b3ff7SBenjamin Naecker typedef struct {
1897533affcbSRobert Mustacchi 	nvme_ioctl_common_t nci_common;
1898533affcbSRobert Mustacchi 	nvme_identify_ctrl_t nci_ctrl_id;
1899533affcbSRobert Mustacchi 	nvme_identify_nsid_t nci_common_ns;
1900533affcbSRobert Mustacchi 	nvme_version_t nci_vers;
1901533affcbSRobert Mustacchi 	nvme_capabilities_t nci_caps;
1902533affcbSRobert Mustacchi 	uint32_t nci_nintrs;
1903533affcbSRobert Mustacchi } nvme_ioctl_ctrl_info_t;
1904eb7b3ff7SBenjamin Naecker 
1905baf9a850SHans Rosenfeld /*
1906744642a2SRobert Mustacchi  * NVME namespace state flags.
1907baf9a850SHans Rosenfeld  *
1908baf9a850SHans Rosenfeld  * The values are defined entirely by the driver. Some states correspond to
1909baf9a850SHans Rosenfeld  * namespace states described by the NVMe specification r1.3 section 6.1, others
1910744642a2SRobert Mustacchi  * are specific to the implementation of this driver. These are present in the
1911533affcbSRobert Mustacchi  * nvme_ns_kinfo_t that is used with the NVME_IOC_NS_INFO ioctl.
1912baf9a850SHans Rosenfeld  *
1913baf9a850SHans Rosenfeld  * The states are as follows:
1914baf9a850SHans Rosenfeld  * - ALLOCATED: the namespace exists in the controller as per the NVMe spec
1915baf9a850SHans Rosenfeld  * - ACTIVE: the namespace exists and is attached to this controller as per the
1916baf9a850SHans Rosenfeld  *   NVMe spec. Any namespace that is ACTIVE is also ALLOCATED. This must not be
1917baf9a850SHans Rosenfeld  *   confused with the ATTACHED state.
1918baf9a850SHans Rosenfeld  * - ATTACHED: the driver has attached a blkdev(4D) instance to this namespace.
1919baf9a850SHans Rosenfeld  *   This state can be changed by userspace with the ioctls NVME_IOC_ATTACH and
1920baf9a850SHans Rosenfeld  *   NVME_IOC_DETACH. A namespace can only be ATTACHED when it is not IGNORED.
1921baf9a850SHans Rosenfeld  * - IGNORED: the driver ignores this namespace, it never attaches a blkdev(4D).
1922baf9a850SHans Rosenfeld  *   Namespaces are IGNORED when they are not ACTIVE, or if they are ACTIVE but
1923baf9a850SHans Rosenfeld  *   have certain properties that the driver cannot handle.
1924baf9a850SHans Rosenfeld  */
1925744642a2SRobert Mustacchi typedef enum {
1926744642a2SRobert Mustacchi 	NVME_NS_STATE_ALLOCATED	=	1 << 0,
1927744642a2SRobert Mustacchi 	NVME_NS_STATE_ACTIVE	=	1 << 1,
1928744642a2SRobert Mustacchi 	NVME_NS_STATE_ATTACHED	=	1 << 2,
1929744642a2SRobert Mustacchi 	NVME_NS_STATE_IGNORED	=	1 << 3
1930744642a2SRobert Mustacchi } nvme_ns_state_t;
1931744642a2SRobert Mustacchi 
1932744642a2SRobert Mustacchi /*
1933744642a2SRobert Mustacchi  * This is the maximum length of the NVMe namespace's blkdev address. This is
1934744642a2SRobert Mustacchi  * only valid in the structure with the NVME_NS_STATE_ATTACHED flag is set.
1935744642a2SRobert Mustacchi  * Otherwise the entry will be all zeros. This is useful when you need to
1936744642a2SRobert Mustacchi  * determine what the corresponding blkdev instance in libdevinfo for the
1937744642a2SRobert Mustacchi  * device.
1938744642a2SRobert Mustacchi  */
1939744642a2SRobert Mustacchi #define	NVME_BLKDEV_NAMELEN	128
1940744642a2SRobert Mustacchi 
1941533affcbSRobert Mustacchi /*
1942533affcbSRobert Mustacchi  * Namespace Information (NVME_IOC_NS_INFO).
1943533affcbSRobert Mustacchi  */
1944744642a2SRobert Mustacchi typedef struct {
1945533affcbSRobert Mustacchi 	nvme_ioctl_common_t nni_common;
1946744642a2SRobert Mustacchi 	nvme_ns_state_t	nni_state;
1947744642a2SRobert Mustacchi 	char nni_addr[NVME_BLKDEV_NAMELEN];
1948744642a2SRobert Mustacchi 	nvme_identify_nsid_t nni_id;
1949533affcbSRobert Mustacchi } nvme_ioctl_ns_info_t;
1950533affcbSRobert Mustacchi 
1951533affcbSRobert Mustacchi /*
1952533affcbSRobert Mustacchi  * NVMe Command Set Identifiers. This was added in NVMe 2.0, but in all the
1953533affcbSRobert Mustacchi  * places it was required to be specified, the default value of 0 indicates the
1954533affcbSRobert Mustacchi  * traditional NVM command set.
1955533affcbSRobert Mustacchi  */
1956533affcbSRobert Mustacchi typedef enum {
1957533affcbSRobert Mustacchi 	NVME_CSI_NVM	= 0,
1958533affcbSRobert Mustacchi 	NVME_CSI_KV,
1959533affcbSRobert Mustacchi 	NVME_CSI_ZNS
1960533affcbSRobert Mustacchi } nvme_csi_t;
1961baf9a850SHans Rosenfeld 
19623d9b1a2aSHans Rosenfeld #ifdef __cplusplus
19633d9b1a2aSHans Rosenfeld }
19643d9b1a2aSHans Rosenfeld #endif
19653d9b1a2aSHans Rosenfeld 
19663d9b1a2aSHans Rosenfeld #endif /* _SYS_NVME_H */
1967