xref: /illumos-gate/usr/src/lib/libnvme/common/libnvme.h (revision 1c02c6c85edfeb48df1fe18511a8779bf9d6c6ed)
1533affcbSRobert Mustacchi /*
2533affcbSRobert Mustacchi  * This file and its contents are supplied under the terms of the
3533affcbSRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4533affcbSRobert Mustacchi  * You may only use this file in accordance with the terms of version
5533affcbSRobert Mustacchi  * 1.0 of the CDDL.
6533affcbSRobert Mustacchi  *
7533affcbSRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8533affcbSRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9533affcbSRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10533affcbSRobert Mustacchi  */
11533affcbSRobert Mustacchi 
12533affcbSRobert Mustacchi /*
13533affcbSRobert Mustacchi  * Copyright 2024 Oxide Computer Company
14533affcbSRobert Mustacchi  */
15533affcbSRobert Mustacchi 
16533affcbSRobert Mustacchi #ifndef _LIBNVME_H
17533affcbSRobert Mustacchi #define	_LIBNVME_H
18533affcbSRobert Mustacchi 
19533affcbSRobert Mustacchi /*
20533affcbSRobert Mustacchi  * This contains an evolving set of interfaces for more programmatically
21533affcbSRobert Mustacchi  * interfacing with NVMe devices. For more information on why the library looks
22533affcbSRobert Mustacchi  * this way, please see lib/libnvme/common/libnvme.c.
23533affcbSRobert Mustacchi  */
24533affcbSRobert Mustacchi 
25533affcbSRobert Mustacchi #ifdef __cplusplus
26533affcbSRobert Mustacchi extern "C" {
27533affcbSRobert Mustacchi #endif
28533affcbSRobert Mustacchi 
29533affcbSRobert Mustacchi #include <stdint.h>
30533affcbSRobert Mustacchi #include <stdbool.h>
31533affcbSRobert Mustacchi #include <libdevinfo.h>
32533affcbSRobert Mustacchi #include <sys/nvme/discovery.h>
33533affcbSRobert Mustacchi 
34533affcbSRobert Mustacchi /*
35533affcbSRobert Mustacchi  * Right now everything relies on seeing various pieces that are in sys/nvme.h,
36533affcbSRobert Mustacchi  * unfortunately. This includes things like the identify, log page, and
37533affcbSRobert Mustacchi  * structure data structures, various constants, and other things that have
38533affcbSRobert Mustacchi  * accumulated. This must all be rejiggered prior to making this a committed
39533affcbSRobert Mustacchi  * interface as we're leaking through many things that software needs.
40533affcbSRobert Mustacchi  * Directionally splitting this out into headers that relate to the spec as
41533affcbSRobert Mustacchi  * <sys/nvme/identify.h>, etc. would be useful and would address several of the
42533affcbSRobert Mustacchi  * places that we're passing in raw uint32_t's for items that come from the spec
43533affcbSRobert Mustacchi  * and could be a little more specific to help out consumers.
44533affcbSRobert Mustacchi  */
45533affcbSRobert Mustacchi #include <sys/nvme.h>
46533affcbSRobert Mustacchi 
47533affcbSRobert Mustacchi /*
48533affcbSRobert Mustacchi  * General error classes that may be returned when operating on non-information
49533affcbSRobert Mustacchi  * snapshots.
50533affcbSRobert Mustacchi  */
51533affcbSRobert Mustacchi typedef enum {
52533affcbSRobert Mustacchi 	NVME_ERR_OK	 = 0,
53533affcbSRobert Mustacchi 	/*
54533affcbSRobert Mustacchi 	 * Indicates that a command failed due to a controller-specific error.
55533affcbSRobert Mustacchi 	 * The controller's SCT/SC are valid in the corresponding objects error
56533affcbSRobert Mustacchi 	 * data.
57533affcbSRobert Mustacchi 	 */
58533affcbSRobert Mustacchi 	NVME_ERR_CONTROLLER,
59533affcbSRobert Mustacchi 	/*
60533affcbSRobert Mustacchi 	 * Indicates that there was a memory allocation error. The system error
61533affcbSRobert Mustacchi 	 * contains the specific errno.
62533affcbSRobert Mustacchi 	 */
63533affcbSRobert Mustacchi 	NVME_ERR_NO_MEM,
64533affcbSRobert Mustacchi 	/*
65533affcbSRobert Mustacchi 	 * Indicates that an operation could not complete because the kernel did
66533affcbSRobert Mustacchi 	 * not have DMA resources available for us.
67533affcbSRobert Mustacchi 	 */
68533affcbSRobert Mustacchi 	NVME_ERR_NO_DMA_MEM,
69533affcbSRobert Mustacchi 	/*
70533affcbSRobert Mustacchi 	 * Indicates that an error occurred while trying to use the devinfo
71533affcbSRobert Mustacchi 	 * library.
72533affcbSRobert Mustacchi 	 */
73533affcbSRobert Mustacchi 	NVME_ERR_LIBDEVINFO,
74533affcbSRobert Mustacchi 	/*
75533affcbSRobert Mustacchi 	 * Indicates that an internal error condition occurred.
76533affcbSRobert Mustacchi 	 */
77533affcbSRobert Mustacchi 	NVME_ERR_INTERNAL,
78533affcbSRobert Mustacchi 	/*
79533affcbSRobert Mustacchi 	 * Indicates that the function was given an invalid pointer argument.
80533affcbSRobert Mustacchi 	 */
81533affcbSRobert Mustacchi 	NVME_ERR_BAD_PTR,
82533affcbSRobert Mustacchi 	/*
83533affcbSRobert Mustacchi 	 * Indicates that an unknown flag argument was given to us.
84533affcbSRobert Mustacchi 	 */
85533affcbSRobert Mustacchi 	NVME_ERR_BAD_FLAG,
86533affcbSRobert Mustacchi 	/*
87533affcbSRobert Mustacchi 	 * Indicates that the devinfo node we were given doesn't correspond to
88533affcbSRobert Mustacchi 	 * an NVMe controller.
89533affcbSRobert Mustacchi 	 */
90533affcbSRobert Mustacchi 	NVME_ERR_BAD_DEVI,
91533affcbSRobert Mustacchi 	/*
92533affcbSRobert Mustacchi 	 * Indicates that while we found a devinfo property successfully,
93533affcbSRobert Mustacchi 	 * something about it does not match our expectations. This could be the
94533affcbSRobert Mustacchi 	 * type, number of values, range, etc.
95533affcbSRobert Mustacchi 	 */
96533affcbSRobert Mustacchi 	NVME_ERR_BAD_DEVI_PROP,
97533affcbSRobert Mustacchi 	/*
98533affcbSRobert Mustacchi 	 * Indicates that we were given an illegal instance (i.e. a negative
99533affcbSRobert Mustacchi 	 * instance).
100533affcbSRobert Mustacchi 	 */
101533affcbSRobert Mustacchi 	NVME_ERR_ILLEGAL_INSTANCE,
102533affcbSRobert Mustacchi 	/*
103533affcbSRobert Mustacchi 	 * Indicates that a means of identifying a controller (name, instance,
104533affcbSRobert Mustacchi 	 * etc.) does not match any known NVMe device.
105533affcbSRobert Mustacchi 	 */
106533affcbSRobert Mustacchi 	NVME_ERR_BAD_CONTROLLER,
107533affcbSRobert Mustacchi 	/*
108533affcbSRobert Mustacchi 	 * Indicates that a request could not proceed due to missing privileges.
109533affcbSRobert Mustacchi 	 */
110533affcbSRobert Mustacchi 	NVME_ERR_PRIVS,
111533affcbSRobert Mustacchi 	/*
112533affcbSRobert Mustacchi 	 * Indicates a failure to open a device file.
113533affcbSRobert Mustacchi 	 */
114533affcbSRobert Mustacchi 	NVME_ERR_OPEN_DEV,
115533affcbSRobert Mustacchi 	/*
116533affcbSRobert Mustacchi 	 * Indicates that the given restore data is not valid.
117533affcbSRobert Mustacchi 	 */
118533affcbSRobert Mustacchi 	NVME_ERR_BAD_RESTORE,
119533affcbSRobert Mustacchi 	/*
120533affcbSRobert Mustacchi 	 * Indicates that a namespace (name, ID, etc.) passed in is not valid on
121533affcbSRobert Mustacchi 	 * the controller. This may be because it's outside the valid range or
122533affcbSRobert Mustacchi 	 * there was an attempt to use the broadcast namespace when it's not
123533affcbSRobert Mustacchi 	 * supported.
124533affcbSRobert Mustacchi 	 */
125533affcbSRobert Mustacchi 	NVME_ERR_NS_RANGE,
126533affcbSRobert Mustacchi 	/*
127533affcbSRobert Mustacchi 	 * Indicates that a namespace ID is not usable in this context. For
128533affcbSRobert Mustacchi 	 * example, attempting to specify a namespace to an identify or log page
129533affcbSRobert Mustacchi 	 * that does not support them.
130533affcbSRobert Mustacchi 	 */
131533affcbSRobert Mustacchi 	NVME_ERR_NS_UNUSE,
132533affcbSRobert Mustacchi 	/*
133533affcbSRobert Mustacchi 	 * Indicates that the value for a get log page field is invalid. This
134533affcbSRobert Mustacchi 	 * may happened due to alignment, just being too large, or something
135533affcbSRobert Mustacchi 	 * else.
136533affcbSRobert Mustacchi 	 */
137533affcbSRobert Mustacchi 	NVME_ERR_LOG_CSI_RANGE,
138533affcbSRobert Mustacchi 	NVME_ERR_LOG_LID_RANGE,
139533affcbSRobert Mustacchi 	NVME_ERR_LOG_LSP_RANGE,
140533affcbSRobert Mustacchi 	NVME_ERR_LOG_LSI_RANGE,
141533affcbSRobert Mustacchi 	NVME_ERR_LOG_RAE_RANGE,
142533affcbSRobert Mustacchi 	NVME_ERR_LOG_SIZE_RANGE,
143533affcbSRobert Mustacchi 	NVME_ERR_LOG_OFFSET_RANGE,
144533affcbSRobert Mustacchi 	/*
145533affcbSRobert Mustacchi 	 * Indicates that the log field value given is not supported because the
146533affcbSRobert Mustacchi 	 * controller is not of a sufficient version or does not indicate that
147533affcbSRobert Mustacchi 	 * it is supported in the LPA field.
148533affcbSRobert Mustacchi 	 */
149533affcbSRobert Mustacchi 	NVME_ERR_LOG_CSI_UNSUP,
150533affcbSRobert Mustacchi 	NVME_ERR_LOG_LSP_UNSUP,
151533affcbSRobert Mustacchi 	NVME_ERR_LOG_LSI_UNSUP,
152533affcbSRobert Mustacchi 	NVME_ERR_LOG_RAE_UNSUP,
153533affcbSRobert Mustacchi 	NVME_ERR_LOG_OFFSET_UNSUP,
154533affcbSRobert Mustacchi 	/*
155533affcbSRobert Mustacchi 	 * Indicates that the log field value is unusable. The specifics of our
156533affcbSRobert Mustacchi 	 * request indicate that this cannot be set.
157533affcbSRobert Mustacchi 	 */
158533affcbSRobert Mustacchi 	NVME_ERR_LOG_LSP_UNUSE,
159533affcbSRobert Mustacchi 	NVME_ERR_LOG_LSI_UNUSE,
160533affcbSRobert Mustacchi 	NVME_ERR_LOG_RAE_UNUSE,
161533affcbSRobert Mustacchi 	/*
162533affcbSRobert Mustacchi 	 * Indicates that the log page's scope requires operating on something
163533affcbSRobert Mustacchi 	 * that isn't what was requested. This would happen if manually
164533affcbSRobert Mustacchi 	 * constructing a log page that operates on the controller, but passed a
165533affcbSRobert Mustacchi 	 * namespace (e.g. the firmware log page).
166533affcbSRobert Mustacchi 	 */
167533affcbSRobert Mustacchi 	NVME_ERR_LOG_SCOPE_MISMATCH,
168533affcbSRobert Mustacchi 	/*
169533affcbSRobert Mustacchi 	 * Indicates that a log request can't be executed because required
170533affcbSRobert Mustacchi 	 * fields have not been set.
171533affcbSRobert Mustacchi 	 */
172533affcbSRobert Mustacchi 	NVME_ERR_LOG_REQ_MISSING_FIELDS,
173533affcbSRobert Mustacchi 	/*
174533affcbSRobert Mustacchi 	 * Indicates that the named log is unknown to the library.
175533affcbSRobert Mustacchi 	 */
176533affcbSRobert Mustacchi 	NVME_ERR_LOG_NAME_UNKNOWN,
177533affcbSRobert Mustacchi 	/*
178533affcbSRobert Mustacchi 	 * Indicates that the named log is not supported by the device.
179533affcbSRobert Mustacchi 	 */
180533affcbSRobert Mustacchi 	NVME_ERR_LOG_UNSUP_BY_DEV,
181533affcbSRobert Mustacchi 	/*
182533affcbSRobert Mustacchi 	 * Indicates that the IDENTIFY command requested is unknown.
183533affcbSRobert Mustacchi 	 */
184533affcbSRobert Mustacchi 	NVME_ERR_IDENTIFY_UNKNOWN,
185533affcbSRobert Mustacchi 	/*
186533affcbSRobert Mustacchi 	 * Indicates that the requested identify command is not supported by the
187533affcbSRobert Mustacchi 	 * device.
188533affcbSRobert Mustacchi 	 */
189533affcbSRobert Mustacchi 	NVME_ERR_IDENTIFY_UNSUP_BY_DEV,
190533affcbSRobert Mustacchi 	/*
191533affcbSRobert Mustacchi 	 * Indicates that the identify command parameter is outside of the valid
192533affcbSRobert Mustacchi 	 * range for the field.
193533affcbSRobert Mustacchi 	 */
194533affcbSRobert Mustacchi 	NVME_ERR_IDENTIFY_CTRLID_RANGE,
195533affcbSRobert Mustacchi 	NVME_ERR_IDENTIFY_OUTPUT_RANGE,
196533affcbSRobert Mustacchi 	/*
197533affcbSRobert Mustacchi 	 * Indicates that the parameter given is not supported because the
198533affcbSRobert Mustacchi 	 * controller is not of a sufficient version or does not indicate that
199533affcbSRobert Mustacchi 	 * it is supported.
200533affcbSRobert Mustacchi 	 */
201533affcbSRobert Mustacchi 	NVME_ERR_IDENTIFY_CTRLID_UNSUP,
202533affcbSRobert Mustacchi 	/*
203533affcbSRobert Mustacchi 	 * Indicates that the parameter given is not supported in the context of
204533affcbSRobert Mustacchi 	 * a given identify command. Namespaces are handled with the
205533affcbSRobert Mustacchi 	 * cross-command error code.
206533affcbSRobert Mustacchi 	 */
207533affcbSRobert Mustacchi 	NVME_ERR_IDENTIFY_CTRLID_UNUSE,
208533affcbSRobert Mustacchi 	/*
209533affcbSRobert Mustacchi 	 * Indicates that an identify request can't be executed because required
210533affcbSRobert Mustacchi 	 * fields have not been set.
211533affcbSRobert Mustacchi 	 */
212533affcbSRobert Mustacchi 	NVME_ERR_IDENTIFY_REQ_MISSING_FIELDS,
213533affcbSRobert Mustacchi 	/*
214533affcbSRobert Mustacchi 	 * Indicates that the controller doesn't support the NVMe standard
215533affcbSRobert Mustacchi 	 * vendor unique command.
216533affcbSRobert Mustacchi 	 */
217533affcbSRobert Mustacchi 	NVME_ERR_VUC_UNSUP_BY_DEV,
218533affcbSRobert Mustacchi 	/*
219533affcbSRobert Mustacchi 	 * Indicates that the vendor unique command parameter is outside of the
220533affcbSRobert Mustacchi 	 * valid range for the field.
221533affcbSRobert Mustacchi 	 */
222533affcbSRobert Mustacchi 	NVME_ERR_VUC_TIMEOUT_RANGE,
223533affcbSRobert Mustacchi 	NVME_ERR_VUC_OPCODE_RANGE,
224533affcbSRobert Mustacchi 	NVME_ERR_VUC_IMPACT_RANGE,
225533affcbSRobert Mustacchi 	NVME_ERR_VUC_NDT_RANGE,
226533affcbSRobert Mustacchi 	/*
227533affcbSRobert Mustacchi 	 * Indicates that a vendor unique command already has an input or output
228533affcbSRobert Mustacchi 	 * buffer set and is being asked to set a separate one.
229533affcbSRobert Mustacchi 	 */
230533affcbSRobert Mustacchi 	NVME_ERR_VUC_CANNOT_RW,
231533affcbSRobert Mustacchi 	/*
232533affcbSRobert Mustacchi 	 * Indicates that the vendor unique request does not have valid
233533affcbSRobert Mustacchi 	 * execution context. This may be because the command was never executed
234533affcbSRobert Mustacchi 	 * or the exec failed in a way such that the controller never exercised
235533affcbSRobert Mustacchi 	 * the command.
236533affcbSRobert Mustacchi 	 */
237533affcbSRobert Mustacchi 	NVME_ERR_VUC_NO_RESULTS,
238533affcbSRobert Mustacchi 	/*
239533affcbSRobert Mustacchi 	 * Indicates that the named vendor unique command is not known to the
240533affcbSRobert Mustacchi 	 * library.
241533affcbSRobert Mustacchi 	 */
242533affcbSRobert Mustacchi 	NVME_ERR_VUC_UNKNOWN,
243533affcbSRobert Mustacchi 	/*
244533affcbSRobert Mustacchi 	 * Indicates that a vendor unique command can't be executed because
245533affcbSRobert Mustacchi 	 * required fields have not been set.
246533affcbSRobert Mustacchi 	 */
247533affcbSRobert Mustacchi 	NVME_ERR_VUC_REQ_MISSING_FIELDS,
248533affcbSRobert Mustacchi 	/*
249533affcbSRobert Mustacchi 	 * Indicates that the vendor-specific library operation could not
250533affcbSRobert Mustacchi 	 * proceed because it is not supported by the given device.
251533affcbSRobert Mustacchi 	 */
252533affcbSRobert Mustacchi 	NVME_ERR_VU_FUNC_UNSUP_BY_DEV,
253533affcbSRobert Mustacchi 	/*
254533affcbSRobert Mustacchi 	 * WDC e6 dump specific invalid values
255533affcbSRobert Mustacchi 	 */
256533affcbSRobert Mustacchi 	NVME_ERR_WDC_E6_OFFSET_RANGE,
257533affcbSRobert Mustacchi 	/*
258533affcbSRobert Mustacchi 	 * Indicates that the controller does not support firmware related
259533affcbSRobert Mustacchi 	 * operations.
260533affcbSRobert Mustacchi 	 */
261533affcbSRobert Mustacchi 	NVME_ERR_FW_UNSUP_BY_DEV,
262533affcbSRobert Mustacchi 	/*
263533affcbSRobert Mustacchi 	 * Indicates that the constraints of the device and what the kernel can
264533affcbSRobert Mustacchi 	 * do make the firmware upgrade non-tenable.
265533affcbSRobert Mustacchi 	 */
266533affcbSRobert Mustacchi 	NVME_ERR_KERN_FW_IMPOS,
267533affcbSRobert Mustacchi 	/*
268533affcbSRobert Mustacchi 	 * Indicates that a firmware download parameter is invalid.
269533affcbSRobert Mustacchi 	 */
270533affcbSRobert Mustacchi 	NVME_ERR_FW_LOAD_LEN_RANGE,
271533affcbSRobert Mustacchi 	NVME_ERR_FW_LOAD_OFFSET_RANGE,
272533affcbSRobert Mustacchi 	/*
273533affcbSRobert Mustacchi 	 * Indicates that the firmware commit command parameter is outside of
274533affcbSRobert Mustacchi 	 * the valid range for the field.
275533affcbSRobert Mustacchi 	 */
276533affcbSRobert Mustacchi 	NVME_ERR_FW_COMMIT_SLOT_RANGE,
277533affcbSRobert Mustacchi 	NVME_ERR_FW_COMMIT_ACTION_RANGE,
278533affcbSRobert Mustacchi 	/*
279533affcbSRobert Mustacchi 	 * Indicates that a firmware commit command can't be executed because
280533affcbSRobert Mustacchi 	 * required fields have not been set.
281533affcbSRobert Mustacchi 	 */
282533affcbSRobert Mustacchi 	NVME_ERR_FW_COMMIT_REQ_MISSING_FIELDS,
283533affcbSRobert Mustacchi 	/*
284533affcbSRobert Mustacchi 	 * Indicates that the firmware commit could not occur because the
285533affcbSRobert Mustacchi 	 * requested slot is read-only.
286533affcbSRobert Mustacchi 	 */
287533affcbSRobert Mustacchi 	NVME_ERR_FW_SLOT_RO,
288533affcbSRobert Mustacchi 	/*
289533affcbSRobert Mustacchi 	 * Indicates that the controller does not support NVM format operations.
290533affcbSRobert Mustacchi 	 */
291533affcbSRobert Mustacchi 	NVME_ERR_FORMAT_UNSUP_BY_DEV,
292533affcbSRobert Mustacchi 	/*
293533affcbSRobert Mustacchi 	 * Indicates that the controller does not support cryptographic secure
294533affcbSRobert Mustacchi 	 * erase.
295533affcbSRobert Mustacchi 	 */
296533affcbSRobert Mustacchi 	NVME_ERR_CRYPTO_SE_UNSUP_BY_DEV,
297533affcbSRobert Mustacchi 	/*
298533affcbSRobert Mustacchi 	 * Indicates that the NVM format command cannot be executed because it
299533affcbSRobert Mustacchi 	 * would target a specific namespace; however, the device does not allow
300533affcbSRobert Mustacchi 	 * a secure erase or a format to target an individual namespace.
301533affcbSRobert Mustacchi 	 */
302533affcbSRobert Mustacchi 	NVME_ERR_NS_FORMAT_UNSUP_BY_DEV,
303533affcbSRobert Mustacchi 	/*
304533affcbSRobert Mustacchi 	 * Indicates that the kernel does not support formatting with the
305533affcbSRobert Mustacchi 	 * specified LBA format, generally due to something like the use of
306533affcbSRobert Mustacchi 	 * metadata in the namespace.
307533affcbSRobert Mustacchi 	 */
308533affcbSRobert Mustacchi 	NVME_ERR_KERN_FORMAT_UNSUP,
309533affcbSRobert Mustacchi 	/*
310533affcbSRobert Mustacchi 	 * Indicates that the NVM format command parameter is outside of
311533affcbSRobert Mustacchi 	 * the valid range for the field.
312533affcbSRobert Mustacchi 	 */
313533affcbSRobert Mustacchi 	NVME_ERR_FORMAT_LBAF_RANGE,
314533affcbSRobert Mustacchi 	NVME_ERR_FORMAT_SES_RANGE,
315533affcbSRobert Mustacchi 	/*
316533affcbSRobert Mustacchi 	 * Indicates that the parameter and/or its value is not supported for a
317533affcbSRobert Mustacchi 	 * NVM format command.
318533affcbSRobert Mustacchi 	 */
319533affcbSRobert Mustacchi 	NVME_ERR_FORMAT_PARAM_UNSUP,
320533affcbSRobert Mustacchi 	/*
321533affcbSRobert Mustacchi 	 * Indicates that a NVM format command can't be executed because
322533affcbSRobert Mustacchi 	 * required fields have not been set.
323533affcbSRobert Mustacchi 	 */
324533affcbSRobert Mustacchi 	NVME_ERR_FORMAT_REQ_MISSING_FIELDS,
325533affcbSRobert Mustacchi 	/*
326533affcbSRobert Mustacchi 	 * Indicates that the WDC e6 log dump request could not be executed due
327533affcbSRobert Mustacchi 	 * to fields not being set.
328533affcbSRobert Mustacchi 	 */
329533affcbSRobert Mustacchi 	NVME_ERR_WDC_E6_REQ_MISSING_FIELDS,
330533affcbSRobert Mustacchi 	/*
331533affcbSRobert Mustacchi 	 * Indicates that the named feature is unknown to the library.
332533affcbSRobert Mustacchi 	 */
333533affcbSRobert Mustacchi 	NVME_ERR_FEAT_NAME_UNKNOWN,
334533affcbSRobert Mustacchi 	/*
335533affcbSRobert Mustacchi 	 * Indicates that the named feature is not supported by the device.
336533affcbSRobert Mustacchi 	 */
337533affcbSRobert Mustacchi 	NVME_ERR_FEAT_UNSUP_BY_DEV,
338533affcbSRobert Mustacchi 	/*
339533affcbSRobert Mustacchi 	 * Indicates that the feature parameter is outside of the valid range
340533affcbSRobert Mustacchi 	 * for the field.
341533affcbSRobert Mustacchi 	 */
342533affcbSRobert Mustacchi 	NVME_ERR_FEAT_FID_RANGE,
343533affcbSRobert Mustacchi 	NVME_ERR_FEAT_SEL_RANGE,
344533affcbSRobert Mustacchi 	NVME_ERR_FEAT_CDW11_RANGE,
345533affcbSRobert Mustacchi 	NVME_ERR_FEAT_DATA_RANGE,
346533affcbSRobert Mustacchi 	/*
347533affcbSRobert Mustacchi 	 * Indicates that the feature parameter given is not supported because
348533affcbSRobert Mustacchi 	 * the controller is not of a sufficient version.
349533affcbSRobert Mustacchi 	 */
350533affcbSRobert Mustacchi 	NVME_ERR_FEAT_SEL_UNSUP,
351533affcbSRobert Mustacchi 	/*
352533affcbSRobert Mustacchi 	 * Indicates that the get feature parameter given is not supported for
353533affcbSRobert Mustacchi 	 * the given feature. For example, passing in a cdw11 argument that is
354533affcbSRobert Mustacchi 	 * not needed.
355533affcbSRobert Mustacchi 	 */
356533affcbSRobert Mustacchi 	NVME_ERR_FEAT_CDW11_UNUSE,
357533affcbSRobert Mustacchi 	NVME_ERR_FEAT_DATA_UNUSE,
358533affcbSRobert Mustacchi 	/*
359533affcbSRobert Mustacchi 	 * Indicates that a feature request does not have valid output data.
360533affcbSRobert Mustacchi 	 * This may be because the command was never executed or it did not
361533affcbSRobert Mustacchi 	 * execute successfully.
362533affcbSRobert Mustacchi 	 */
363533affcbSRobert Mustacchi 	NVME_ERR_FEAT_NO_RESULTS,
364533affcbSRobert Mustacchi 	/*
365533affcbSRobert Mustacchi 	 * Indicates that a get features request can't be executed because
366533affcbSRobert Mustacchi 	 * required fields have not been set.
367533affcbSRobert Mustacchi 	 */
368533affcbSRobert Mustacchi 	NVME_ERR_GET_FEAT_REQ_MISSING_FIELDS,
369533affcbSRobert Mustacchi 	/*
370533affcbSRobert Mustacchi 	 * These indicate that the operation could not be executed because they
371533affcbSRobert Mustacchi 	 * require holding either a controller or namespace write lock and one
372533affcbSRobert Mustacchi 	 * is not held by the corresponding controller handle.
373533affcbSRobert Mustacchi 	 */
374533affcbSRobert Mustacchi 	NVME_ERR_NEED_CTRL_WRLOCK,
375533affcbSRobert Mustacchi 	NVME_ERR_NEED_NS_WRLOCK,
376533affcbSRobert Mustacchi 	/*
377533affcbSRobert Mustacchi 	 * These indicate that the operation could not be executed because the
378533affcbSRobert Mustacchi 	 * controller or namespace respectively currently have an exclusive
379533affcbSRobert Mustacchi 	 * write lock (or an equivalent future form) that blocks execution from
380533affcbSRobert Mustacchi 	 * others.
381533affcbSRobert Mustacchi 	 */
382533affcbSRobert Mustacchi 	NVME_ERR_CTRL_LOCKED,
383533affcbSRobert Mustacchi 	NVME_ERR_NS_LOCKED,
384533affcbSRobert Mustacchi 	/*
385533affcbSRobert Mustacchi 	 * Indicates that a fatal locking operation occurred that will terminate
386533affcbSRobert Mustacchi 	 * the process. This includes cases such as recursive enters on the same
387533affcbSRobert Mustacchi 	 * lock, attempting to unlock a lock that isn't owned, etc.
388533affcbSRobert Mustacchi 	 */
389533affcbSRobert Mustacchi 	NVME_ERR_LOCK_PROG,
390533affcbSRobert Mustacchi 	/*
391533affcbSRobert Mustacchi 	 * Indicates that a lock order violation was attempted. This includes
392533affcbSRobert Mustacchi 	 * things like taking the controller lock while holding the namespace
393533affcbSRobert Mustacchi 	 * lock, attempting to take a second namespace lock, holding a
394533affcbSRobert Mustacchi 	 * controller write lock and trying to get a namespace lock, etc.
395533affcbSRobert Mustacchi 	 */
396533affcbSRobert Mustacchi 	NVME_ERR_LOCK_ORDER,
397533affcbSRobert Mustacchi 	/*
398533affcbSRobert Mustacchi 	 * Indicates that a signal was encountered while attempting to take a
399533affcbSRobert Mustacchi 	 * lock.
400533affcbSRobert Mustacchi 	 */
401533affcbSRobert Mustacchi 	NVME_ERR_LOCK_WAIT_INTR,
402533affcbSRobert Mustacchi 	/*
403533affcbSRobert Mustacchi 	 * Indicates that attempting to take the lock failed because the thread
404533affcbSRobert Mustacchi 	 * would be required to block, but it asked not to.
405533affcbSRobert Mustacchi 	 */
406533affcbSRobert Mustacchi 	NVME_ERR_LOCK_WOULD_BLOCK,
407533affcbSRobert Mustacchi 	/*
408533affcbSRobert Mustacchi 	 * These indicate that the respective attach and detach operations
409533affcbSRobert Mustacchi 	 * failed to complete due to an error in the underlying kernel
410533affcbSRobert Mustacchi 	 * subsystems. For detach this might happen because of a disk being
411533affcbSRobert Mustacchi 	 * open, busy in a zpool, or something else. For attach, it may suggest
412533affcbSRobert Mustacchi 	 * and NDI or other issue.
413533affcbSRobert Mustacchi 	 */
414533affcbSRobert Mustacchi 	NVME_ERR_DETACH_KERN,
415533affcbSRobert Mustacchi 	NVME_ERR_ATTACH_KERN,
416533affcbSRobert Mustacchi 	/*
417533affcbSRobert Mustacchi 	 * Indicates that the kernel driver does not support some property of
418533affcbSRobert Mustacchi 	 * the requested namespace.
419533affcbSRobert Mustacchi 	 */
420533affcbSRobert Mustacchi 	NVME_ERR_ATTACH_UNSUP_KERN,
421533affcbSRobert Mustacchi 	/*
422533affcbSRobert Mustacchi 	 * Indicates that the operation cannot proceed because a namespace is
423533affcbSRobert Mustacchi 	 * attached to blkdev and it must be detached to proceed.
424533affcbSRobert Mustacchi 	 */
425533affcbSRobert Mustacchi 	NVME_ERR_NS_BLKDEV_ATTACH,
426533affcbSRobert Mustacchi 	/*
427533affcbSRobert Mustacchi 	 * Indicates that non-DMA kernel memory was not available for this
428533affcbSRobert Mustacchi 	 * request.
429533affcbSRobert Mustacchi 	 */
430533affcbSRobert Mustacchi 	NVME_ERR_NO_KERN_MEM,
431533affcbSRobert Mustacchi 	/*
432533affcbSRobert Mustacchi 	 * These two codes represent internal device conditions that indicate
433533affcbSRobert Mustacchi 	 * the device is unusable or that it was physically removed (usually due
434533affcbSRobert Mustacchi 	 * to hotplug).
435533affcbSRobert Mustacchi 	 */
436533affcbSRobert Mustacchi 	NVME_ERR_CTRL_DEAD,
437533affcbSRobert Mustacchi 	NVME_ERR_CTRL_GONE
438533affcbSRobert Mustacchi } nvme_err_t;
439533affcbSRobert Mustacchi 
440533affcbSRobert Mustacchi /*
441533affcbSRobert Mustacchi  * Errors used for the various information errors. This is shared between both
442533affcbSRobert Mustacchi  * controller and namespace information structures.
443533affcbSRobert Mustacchi  */
444533affcbSRobert Mustacchi typedef enum {
445533affcbSRobert Mustacchi 	NVME_INFO_ERR_OK,
446533affcbSRobert Mustacchi 	/*
447533affcbSRobert Mustacchi 	 * Indicates that the item is not supported because this is the wrong
448533affcbSRobert Mustacchi 	 * controller transport. For example, asking about a PCI ID for
449533affcbSRobert Mustacchi 	 * something that is not PCI-based.
450533affcbSRobert Mustacchi 	 */
451533affcbSRobert Mustacchi 	NVME_INFO_ERR_TRANSPORT,
452533affcbSRobert Mustacchi 	/*
453533affcbSRobert Mustacchi 	 * Indicates that the item is not supported because the device version
454533affcbSRobert Mustacchi 	 * is too old to get this.
455533affcbSRobert Mustacchi 	 */
456533affcbSRobert Mustacchi 	NVME_INFO_ERR_VERSION,
457533affcbSRobert Mustacchi 	/*
458533affcbSRobert Mustacchi 	 * Indicates that we could not get certain information because the
459533affcbSRobert Mustacchi 	 * device does not support a given capability.
460533affcbSRobert Mustacchi 	 */
461533affcbSRobert Mustacchi 	NVME_INFO_ERR_MISSING_CAP,
462533affcbSRobert Mustacchi 	/*
463533affcbSRobert Mustacchi 	 * Indicates that the specified format value is unknown.
464533affcbSRobert Mustacchi 	 */
465533affcbSRobert Mustacchi 	NVME_INFO_ERR_BAD_LBA_FMT,
466533affcbSRobert Mustacchi 	/*
467533affcbSRobert Mustacchi 	 * These errors only occur during attempts to persist information and
468533affcbSRobert Mustacchi 	 * indicate challenges allocating memory or otherwise challenges with
469533affcbSRobert Mustacchi 	 * libnvpair.
470533affcbSRobert Mustacchi 	 */
471533affcbSRobert Mustacchi 	NVME_INFO_ERR_PERSIST_NVL,
472533affcbSRobert Mustacchi 	/*
473533affcbSRobert Mustacchi 	 * The first indicates that the index is invalid or if it is technically
474533affcbSRobert Mustacchi 	 * within the valid LBA format range, but there is no data size. The
475533affcbSRobert Mustacchi 	 * second indicates that we can't actually fully represent the data
476533affcbSRobert Mustacchi 	 * here. This happens because say the LBA size can't be represented by a
477533affcbSRobert Mustacchi 	 * uint64_t.
478533affcbSRobert Mustacchi 	 */
479533affcbSRobert Mustacchi 	NVME_INFO_ERR_BAD_FMT,
480533affcbSRobert Mustacchi 	NVME_INFO_ERR_BAD_FMT_DATA,
481533affcbSRobert Mustacchi 	/*
482533affcbSRobert Mustacchi 	 * Indicates that the information cannot be returned because the
483533affcbSRobert Mustacchi 	 * namespace's state does not allow us to answer this question. This may
484533affcbSRobert Mustacchi 	 * be because it's inactive as below or because blkdev is not attached.
485533affcbSRobert Mustacchi 	 */
486533affcbSRobert Mustacchi 	NVME_INFO_ERR_NS_INACTIVE,
487533affcbSRobert Mustacchi 	NVME_INFO_ERR_NS_NO_BLKDEV
488533affcbSRobert Mustacchi } nvme_info_err_t;
489533affcbSRobert Mustacchi 
490533affcbSRobert Mustacchi typedef struct nvme nvme_t;
491533affcbSRobert Mustacchi typedef struct nvme_ctrl nvme_ctrl_t;
492533affcbSRobert Mustacchi typedef struct nvme_ctrl_iter nvme_ctrl_iter_t;
493533affcbSRobert Mustacchi typedef struct nvme_ctrl_disc nvme_ctrl_disc_t;
494533affcbSRobert Mustacchi typedef struct nvme_ctrl_info nvme_ctrl_info_t;
495533affcbSRobert Mustacchi typedef struct nvme_ns nvme_ns_t;
496533affcbSRobert Mustacchi typedef struct nvme_ns_iter nvme_ns_iter_t;
497533affcbSRobert Mustacchi typedef struct nvme_ns_disc nvme_ns_disc_t;
498533affcbSRobert Mustacchi typedef struct nvme_ns_info nvme_ns_info_t;
499533affcbSRobert Mustacchi typedef struct nvme_nvm_lba_fmt nvme_nvm_lba_fmt_t;
500533affcbSRobert Mustacchi typedef struct nvme_log_iter nvme_log_iter_t;
501533affcbSRobert Mustacchi typedef struct nvme_log_disc nvme_log_disc_t;
502533affcbSRobert Mustacchi typedef struct nvme_log_req nvme_log_req_t;
503533affcbSRobert Mustacchi typedef struct nvme_id_req nvme_id_req_t;
504533affcbSRobert Mustacchi typedef struct nvme_vuc_iter nvme_vuc_iter_t;
505533affcbSRobert Mustacchi typedef struct nvme_vuc_disc nvme_vuc_disc_t;
506533affcbSRobert Mustacchi typedef struct nvme_vuc_req nvme_vuc_req_t;
507533affcbSRobert Mustacchi typedef struct nvme_fw_commit_req nvme_fw_commit_req_t;
508533affcbSRobert Mustacchi typedef struct nvme_format_req nvme_format_req_t;
509533affcbSRobert Mustacchi typedef struct nvme_feat_disc nvme_feat_disc_t;
510533affcbSRobert Mustacchi typedef struct nvme_feat_iter nvme_feat_iter_t;
511533affcbSRobert Mustacchi typedef struct nvme_get_feat_req nvme_get_feat_req_t;
512533affcbSRobert Mustacchi 
513533affcbSRobert Mustacchi /*
514533affcbSRobert Mustacchi  * Vendor-specific forwards.
515533affcbSRobert Mustacchi  */
516533affcbSRobert Mustacchi typedef struct nvme_wdc_e6_req nvme_wdc_e6_req_t;
517533affcbSRobert Mustacchi 
518533affcbSRobert Mustacchi extern nvme_t *nvme_init(void);
519533affcbSRobert Mustacchi extern void nvme_fini(nvme_t *);
520533affcbSRobert Mustacchi 
521533affcbSRobert Mustacchi /*
522533affcbSRobert Mustacchi  * Error information. Operations that take an nvme_t, always set error
523533affcbSRobert Mustacchi  * information on the nvme_t. Operations that operate on a controller or are
524533affcbSRobert Mustacchi  * related to a request object or iterator that starts from the controller
525533affcbSRobert Mustacchi  * set error information on the nvme_ctrl_t.
526533affcbSRobert Mustacchi  */
527533affcbSRobert Mustacchi extern nvme_err_t nvme_err(nvme_t *);
528533affcbSRobert Mustacchi extern int32_t nvme_syserr(nvme_t *);
529533affcbSRobert Mustacchi extern const char *nvme_errmsg(nvme_t *);
530533affcbSRobert Mustacchi extern size_t nvme_errlen(nvme_t *);
531533affcbSRobert Mustacchi extern const char *nvme_errtostr(nvme_t *, nvme_err_t);
532533affcbSRobert Mustacchi 
533533affcbSRobert Mustacchi extern nvme_err_t nvme_ctrl_err(nvme_ctrl_t *);
534533affcbSRobert Mustacchi extern int32_t nvme_ctrl_syserr(nvme_ctrl_t *);
535533affcbSRobert Mustacchi extern const char *nvme_ctrl_errmsg(nvme_ctrl_t *);
536533affcbSRobert Mustacchi extern size_t nvme_ctrl_errlen(nvme_ctrl_t *);
537533affcbSRobert Mustacchi extern void nvme_ctrl_deverr(nvme_ctrl_t *, uint32_t *, uint32_t *);
538533affcbSRobert Mustacchi extern const char *nvme_ctrl_errtostr(nvme_ctrl_t *, nvme_err_t);
539533affcbSRobert Mustacchi 
540533affcbSRobert Mustacchi /*
541533affcbSRobert Mustacchi  * Translations for NVMe spec error constants. These end up taking the
542533affcbSRobert Mustacchi  * nvme_ctrl_t so that way they can potentially translate vendor-specific errors
543533affcbSRobert Mustacchi  * if they are defined. A NULL controller is allowed, which will skip all such
544533affcbSRobert Mustacchi  * processing altogether. Both functions will always a return a string so there
545533affcbSRobert Mustacchi  * is no need to check for NULL (though it may just be a variant of "unknown
546533affcbSRobert Mustacchi  * ...").
547533affcbSRobert Mustacchi  *
548533affcbSRobert Mustacchi  * If NULL is passed for the controller in nvme_sctostr(), we will assume that
549533affcbSRobert Mustacchi  * the controller's type is a traditional PCI I/O controller and not a fabric
550533affcbSRobert Mustacchi  * based controller, which further changes the way that command-specific status
551533affcbSRobert Mustacchi  * codes are interpreted. Due to the lack of support in the system for
552533affcbSRobert Mustacchi  * different controller types, this function will always assume a PCI I/O
553533affcbSRobert Mustacchi  * controller currently.
554533affcbSRobert Mustacchi  */
555533affcbSRobert Mustacchi extern const char *nvme_scttostr(nvme_ctrl_t *, uint32_t);
556533affcbSRobert Mustacchi extern const char *nvme_sctostr(nvme_ctrl_t *, nvme_csi_t, uint32_t, uint32_t);
557533affcbSRobert Mustacchi 
558533affcbSRobert Mustacchi typedef enum nvme_iter {
559533affcbSRobert Mustacchi 	NVME_ITER_VALID,
560533affcbSRobert Mustacchi 	NVME_ITER_DONE,
561533affcbSRobert Mustacchi 	NVME_ITER_ERROR
562533affcbSRobert Mustacchi } nvme_iter_t;
563533affcbSRobert Mustacchi 
564533affcbSRobert Mustacchi /*
565533affcbSRobert Mustacchi  * NVMe Controller discovery.
566533affcbSRobert Mustacchi  */
567533affcbSRobert Mustacchi extern di_node_t nvme_ctrl_disc_devi(const nvme_ctrl_disc_t *);
568533affcbSRobert Mustacchi extern di_minor_t nvme_ctrl_disc_minor(const nvme_ctrl_disc_t *);
569533affcbSRobert Mustacchi 
570533affcbSRobert Mustacchi extern bool nvme_ctrl_discover_init(nvme_t *, nvme_ctrl_iter_t **);
571533affcbSRobert Mustacchi extern nvme_iter_t nvme_ctrl_discover_step(nvme_ctrl_iter_t *,
572533affcbSRobert Mustacchi     const nvme_ctrl_disc_t **);
573533affcbSRobert Mustacchi extern void nvme_ctrl_discover_fini(nvme_ctrl_iter_t *);
574533affcbSRobert Mustacchi 
575533affcbSRobert Mustacchi typedef bool (*nvme_ctrl_disc_f)(nvme_t *, const nvme_ctrl_disc_t *, void *);
576533affcbSRobert Mustacchi extern bool nvme_ctrl_discover(nvme_t *, nvme_ctrl_disc_f, void *);
577533affcbSRobert Mustacchi 
578533affcbSRobert Mustacchi extern bool nvme_ctrl_init(nvme_t *, di_node_t, nvme_ctrl_t **);
579533affcbSRobert Mustacchi extern bool nvme_ctrl_init_by_instance(nvme_t *, int32_t, nvme_ctrl_t **);
580533affcbSRobert Mustacchi extern bool nvme_ctrl_devi(nvme_ctrl_t *, di_node_t *);
581533affcbSRobert Mustacchi extern void nvme_ctrl_fini(nvme_ctrl_t *);
582533affcbSRobert Mustacchi 
583533affcbSRobert Mustacchi /*
584533affcbSRobert Mustacchi  * Get information about a controller. This information about a controller is
585533affcbSRobert Mustacchi  * separate from the lifetime of the controller itself. This is done to
586533affcbSRobert Mustacchi  * facilitate the ability of saving and using this information on another
587533affcbSRobert Mustacchi  * system and make the management a bit easier. Errors appear on this object and
588533affcbSRobert Mustacchi  * not the nmve_t.
589533affcbSRobert Mustacchi  */
590533affcbSRobert Mustacchi extern bool nvme_ctrl_info_snap(nvme_ctrl_t *, nvme_ctrl_info_t **);
591533affcbSRobert Mustacchi extern bool nvme_ctrl_info_restore(nvme_t *, nvlist_t *, nvme_ctrl_info_t **);
592533affcbSRobert Mustacchi extern bool nvme_ctrl_info_persist(nvme_ctrl_info_t *, nvlist_t **);
593533affcbSRobert Mustacchi extern void nvme_ctrl_info_free(nvme_ctrl_info_t *);
594533affcbSRobert Mustacchi 
595533affcbSRobert Mustacchi extern nvme_info_err_t nvme_ctrl_info_err(nvme_ctrl_info_t *);
596533affcbSRobert Mustacchi extern int32_t nvme_ctrl_info_syserr(nvme_ctrl_info_t *);
597533affcbSRobert Mustacchi extern const char *nvme_ctrl_info_errmsg(nvme_ctrl_info_t *);
598533affcbSRobert Mustacchi extern size_t nvme_ctrl_info_errlen(nvme_ctrl_info_t *);
599533affcbSRobert Mustacchi extern const char *nvme_ctrl_info_errtostr(nvme_ctrl_info_t *, nvme_info_err_t);
600533affcbSRobert Mustacchi 
601533affcbSRobert Mustacchi /*
602533affcbSRobert Mustacchi  * Information about an NVMe controller. This information is a combination of
603533affcbSRobert Mustacchi  * the identify data structure which can be retrieved directly by folks who
604533affcbSRobert Mustacchi  * would prefer to use it. Common fields that are used in something like nvmeadm
605533affcbSRobert Mustacchi  * or other utilities who would rather not need to know about the specifics of
606533affcbSRobert Mustacchi  * the data structure or have to think about the version can use that instead.
607533affcbSRobert Mustacchi  *
608533affcbSRobert Mustacchi  * NVMe 2.x has kept the identify controller data structure backwards
609533affcbSRobert Mustacchi  * compatible. If a future version were to invalidate that, then this could
610533affcbSRobert Mustacchi  * possibly return NULL.
611533affcbSRobert Mustacchi  */
612533affcbSRobert Mustacchi extern uint16_t nvme_ctrl_info_vendor(nvme_ctrl_info_t *);
613533affcbSRobert Mustacchi extern const nvme_identify_ctrl_t *nvme_ctrl_info_identify(nvme_ctrl_info_t *);
614533affcbSRobert Mustacchi extern const nvme_version_t *nvme_ctrl_info_version(nvme_ctrl_info_t *);
615533affcbSRobert Mustacchi extern const char *nvme_ctrl_info_model(nvme_ctrl_info_t *);
616533affcbSRobert Mustacchi extern const char *nvme_ctrl_info_serial(nvme_ctrl_info_t *);
6173dd3cd66SAndy Fiddaman extern uint32_t nvme_ctrl_info_fwgran(nvme_ctrl_info_t *);
618533affcbSRobert Mustacchi extern const char *nvme_ctrl_info_fwrev(nvme_ctrl_info_t *);
619533affcbSRobert Mustacchi extern uint32_t nvme_ctrl_info_nns(nvme_ctrl_info_t *);
620533affcbSRobert Mustacchi 
621533affcbSRobert Mustacchi typedef enum {
622533affcbSRobert Mustacchi 	NVME_CTRL_TRANSPORT_PCI,
623533affcbSRobert Mustacchi 	NVME_CTRL_TRANSPORT_TCP,
624533affcbSRobert Mustacchi 	NVME_CTRL_TRANSPORT_RDMA,
625533affcbSRobert Mustacchi } nvme_ctrl_transport_t;
626533affcbSRobert Mustacchi 
627533affcbSRobert Mustacchi typedef enum {
628533affcbSRobert Mustacchi 	NVME_CTRL_TYPE_UNKNOWN,
629533affcbSRobert Mustacchi 	NVME_CTRL_TYPE_IO,
630533affcbSRobert Mustacchi 	NVME_CTRL_TYPE_ADMIN,
631533affcbSRobert Mustacchi 	NVME_CTRL_TYPE_DISCOVERY,
632533affcbSRobert Mustacchi } nvme_ctrl_type_t;
633533affcbSRobert Mustacchi 
634533affcbSRobert Mustacchi /*
635533affcbSRobert Mustacchi  * Controller types were explicitly added in the NVMe 1.4 specification. Prior
636533affcbSRobert Mustacchi  * to that all controllers were required to support issuing I/O, hence we return
637533affcbSRobert Mustacchi  * them as NVME_CTRL_TYPE_IO, even though this isn't quite by the spec. In 1.4
638533affcbSRobert Mustacchi  * this was added to the identify controller information. The 'UNKNOWN' type is
639533affcbSRobert Mustacchi  * for cases where we don't recognize the value based upon the standard.
640533affcbSRobert Mustacchi  */
641533affcbSRobert Mustacchi extern nvme_ctrl_type_t nvme_ctrl_info_type(nvme_ctrl_info_t *);
642533affcbSRobert Mustacchi extern nvme_ctrl_transport_t nvme_ctrl_info_transport(nvme_ctrl_info_t *);
643533affcbSRobert Mustacchi 
644533affcbSRobert Mustacchi /*
645533affcbSRobert Mustacchi  * The following pieces of information are specific to PCI NVMe controllers and
646533affcbSRobert Mustacchi  * are not from the common identify controller data structure. As such they are
647533affcbSRobert Mustacchi  * fallible. The first group come from configuration space while the others are
648533affcbSRobert Mustacchi  * information that comes from the actual controller capability registers.
649533affcbSRobert Mustacchi  */
650533affcbSRobert Mustacchi extern bool nvme_ctrl_info_pci_vid(nvme_ctrl_info_t *, uint16_t *);
651533affcbSRobert Mustacchi extern bool nvme_ctrl_info_pci_did(nvme_ctrl_info_t *, uint16_t *);
652533affcbSRobert Mustacchi extern bool nvme_ctrl_info_pci_rev(nvme_ctrl_info_t *, uint8_t *);
653533affcbSRobert Mustacchi extern bool nvme_ctrl_info_pci_subvid(nvme_ctrl_info_t *, uint16_t *);
654533affcbSRobert Mustacchi extern bool nvme_ctrl_info_pci_subsys(nvme_ctrl_info_t *, uint16_t *);
655533affcbSRobert Mustacchi 
656533affcbSRobert Mustacchi extern bool nvme_ctrl_info_pci_mps_min(nvme_ctrl_info_t *, uint32_t *);
657533affcbSRobert Mustacchi extern bool nvme_ctrl_info_pci_mps_max(nvme_ctrl_info_t *, uint32_t *);
658533affcbSRobert Mustacchi 
659533affcbSRobert Mustacchi extern bool nvme_ctrl_info_pci_nintrs(nvme_ctrl_info_t *, uint32_t *);
660533affcbSRobert Mustacchi 
661533affcbSRobert Mustacchi /*
662533affcbSRobert Mustacchi  * These three items are only present if the device supports Namespace
663533affcbSRobert Mustacchi  * Management.
664533affcbSRobert Mustacchi  */
665533affcbSRobert Mustacchi extern bool nvme_ctrl_info_cap(nvme_ctrl_info_t *, nvme_uint128_t *);
666533affcbSRobert Mustacchi extern bool nvme_ctrl_info_unalloc_cap(nvme_ctrl_info_t *, nvme_uint128_t *);
667533affcbSRobert Mustacchi extern bool nvme_ctrl_info_common_ns(nvme_ctrl_info_t *,
668533affcbSRobert Mustacchi     const nvme_identify_nsid_t **);
669533affcbSRobert Mustacchi 
670533affcbSRobert Mustacchi /*
671533affcbSRobert Mustacchi  * The following information is specific to the NVM command set for controllers.
672533affcbSRobert Mustacchi  */
673533affcbSRobert Mustacchi extern uint32_t nvme_ctrl_info_nformats(nvme_ctrl_info_t *);
674533affcbSRobert Mustacchi extern bool nvme_ctrl_info_format(nvme_ctrl_info_t *, uint32_t,
675533affcbSRobert Mustacchi     const nvme_nvm_lba_fmt_t **);
676533affcbSRobert Mustacchi extern uint32_t nvme_nvm_lba_fmt_id(const nvme_nvm_lba_fmt_t *);
677533affcbSRobert Mustacchi extern uint32_t nvme_nvm_lba_fmt_meta_size(const nvme_nvm_lba_fmt_t *);
678533affcbSRobert Mustacchi extern uint64_t nvme_nvm_lba_fmt_data_size(const nvme_nvm_lba_fmt_t *);
679533affcbSRobert Mustacchi extern uint32_t nvme_nvm_lba_fmt_rel_perf(const nvme_nvm_lba_fmt_t *);
680533affcbSRobert Mustacchi 
681533affcbSRobert Mustacchi /*
682533affcbSRobert Mustacchi  * Identify Operations
683533affcbSRobert Mustacchi  *
684533affcbSRobert Mustacchi  * The basic controller and namespace identify operations are a part of the
685533affcbSRobert Mustacchi  * controller and namespace snapshot facilities. These functions are designed to
686533affcbSRobert Mustacchi  * help enumerate and iterate lists of active and inactive namespaces,
687533affcbSRobert Mustacchi  * controllers, and related. The initial interface is a basic form that allows
688533affcbSRobert Mustacchi  * folks to create a request based on one that the library knows about as the
689533affcbSRobert Mustacchi  * kernel doesn't allow unknown requests.
690533affcbSRobert Mustacchi  *
691533affcbSRobert Mustacchi  * Eventually, when the kernel allows for arbitrary identify commands to be
692533affcbSRobert Mustacchi  * issued we can add an nvme_id_req_init() and the ability to set the CSI and
693533affcbSRobert Mustacchi  * CNS.
694533affcbSRobert Mustacchi  */
695533affcbSRobert Mustacchi extern bool nvme_id_req_init_by_cns(nvme_ctrl_t *, nvme_csi_t, uint32_t,
696533affcbSRobert Mustacchi     nvme_id_req_t **);
697533affcbSRobert Mustacchi extern void nvme_id_req_fini(nvme_id_req_t *);
698533affcbSRobert Mustacchi 
699533affcbSRobert Mustacchi extern bool nvme_id_req_set_nsid(nvme_id_req_t *, uint32_t);
700533affcbSRobert Mustacchi extern bool nvme_id_req_set_ctrlid(nvme_id_req_t *, uint32_t);
701533affcbSRobert Mustacchi extern bool nvme_id_req_set_output(nvme_id_req_t *, void *, size_t);
702*1c02c6c8SRobert Mustacchi extern bool nvme_id_req_clear_output(nvme_id_req_t *);
703533affcbSRobert Mustacchi extern bool nvme_id_req_exec(nvme_id_req_t *);
704533affcbSRobert Mustacchi 
705533affcbSRobert Mustacchi /*
706533affcbSRobert Mustacchi  * NVMe Namespace Discovery
707533affcbSRobert Mustacchi  *
708533affcbSRobert Mustacchi  * Namespaces come in various states. While the controller has a list of
709533affcbSRobert Mustacchi  * namespace IDs. The following enumeration describes namespace information with
710533affcbSRobert Mustacchi  * increasing specificity.
711533affcbSRobert Mustacchi  */
712533affcbSRobert Mustacchi typedef enum {
713533affcbSRobert Mustacchi 	/*
714533affcbSRobert Mustacchi 	 * This returns all namespaces that are present on the device. This
715533affcbSRobert Mustacchi 	 * includes ones that may be ignored by the kernel or more.
716533affcbSRobert Mustacchi 	 */
717533affcbSRobert Mustacchi 	NVME_NS_DISC_F_ALL = 0,
718533affcbSRobert Mustacchi 	/*
719533affcbSRobert Mustacchi 	 * Only return namespaces that the controller considers to be allocated.
720533affcbSRobert Mustacchi 	 */
721533affcbSRobert Mustacchi 	NVME_NS_DISC_F_ALLOCATED,
722533affcbSRobert Mustacchi 	/*
723533affcbSRobert Mustacchi 	 * Only return namespaces that are active. If the controller does not
724533affcbSRobert Mustacchi 	 * support namespace management then all namespaces are considered
725533affcbSRobert Mustacchi 	 * active.
726533affcbSRobert Mustacchi 	 */
727533affcbSRobert Mustacchi 	NVME_NS_DISC_F_ACTIVE,
728533affcbSRobert Mustacchi 	/*
729533affcbSRobert Mustacchi 	 * The kernel has a notion of a namespace is ignored or not. In general,
730533affcbSRobert Mustacchi 	 * this is a subset of active namespaces that can actually be supported.
731533affcbSRobert Mustacchi 	 * They may or may not have a blkdev instance attached.
732533affcbSRobert Mustacchi 	 */
733533affcbSRobert Mustacchi 	NVME_NS_DISC_F_NOT_IGNORED,
734533affcbSRobert Mustacchi 	/*
735533affcbSRobert Mustacchi 	 * Only return namespaces that have blkdev actively attached. In other
736533affcbSRobert Mustacchi 	 * words these are disks that the OS can use.
737533affcbSRobert Mustacchi 	 */
738533affcbSRobert Mustacchi 	NVME_NS_DISC_F_BLKDEV
739533affcbSRobert Mustacchi } nvme_ns_disc_level_t;
740533affcbSRobert Mustacchi 
741533affcbSRobert Mustacchi typedef enum nvme_ns_disc_flags {
742533affcbSRobert Mustacchi 	NVME_NS_DISC_F_EUI64_VALID	= 1 << 0,
743533affcbSRobert Mustacchi 	NVME_NS_DISC_F_NGUID_VALID	= 1 << 1
744533affcbSRobert Mustacchi } nvme_ns_disc_flags_t;
745533affcbSRobert Mustacchi 
746533affcbSRobert Mustacchi extern uint32_t nvme_ns_disc_nsid(const nvme_ns_disc_t *);
747533affcbSRobert Mustacchi extern nvme_ns_disc_level_t nvme_ns_disc_level(const nvme_ns_disc_t *);
748533affcbSRobert Mustacchi extern nvme_ns_disc_flags_t nvme_ns_disc_flags(const nvme_ns_disc_t *);
749533affcbSRobert Mustacchi extern const uint8_t *nvme_ns_disc_eui64(const nvme_ns_disc_t *);
750533affcbSRobert Mustacchi extern const uint8_t *nvme_ns_disc_nguid(const nvme_ns_disc_t *);
751533affcbSRobert Mustacchi 
752533affcbSRobert Mustacchi extern bool nvme_ns_discover_init(nvme_ctrl_t *, nvme_ns_disc_level_t,
753533affcbSRobert Mustacchi     nvme_ns_iter_t **);
754533affcbSRobert Mustacchi extern nvme_iter_t nvme_ns_discover_step(nvme_ns_iter_t *,
755533affcbSRobert Mustacchi     const nvme_ns_disc_t **);
756533affcbSRobert Mustacchi extern void nvme_ns_discover_fini(nvme_ns_iter_t *);
757533affcbSRobert Mustacchi 
758533affcbSRobert Mustacchi typedef bool (*nvme_ns_disc_f)(nvme_ctrl_t *, const nvme_ns_disc_t *, void *);
759533affcbSRobert Mustacchi extern bool nvme_ns_discover(nvme_ctrl_t *, nvme_ns_disc_level_t,
760533affcbSRobert Mustacchi     nvme_ns_disc_f, void *);
761533affcbSRobert Mustacchi 
762533affcbSRobert Mustacchi extern bool nvme_ns_init(nvme_ctrl_t *, uint32_t, nvme_ns_t **);
763533affcbSRobert Mustacchi extern bool nvme_ns_init_by_name(nvme_ctrl_t *, const char *, nvme_ns_t **);
764533affcbSRobert Mustacchi extern void nvme_ns_fini(nvme_ns_t *);
765533affcbSRobert Mustacchi 
766533affcbSRobert Mustacchi /*
767533affcbSRobert Mustacchi  * This is a convenience routine for opening up an NVMe controller and/or
768533affcbSRobert Mustacchi  * namespace. Many utilities refer to things as <controller>/<namespace>. As
769533affcbSRobert Mustacchi  * such, this will parse that apart. If no namespace is specified, it will be
770533affcbSRobert Mustacchi  * left as NULL. If the specified controller or namespace cannot be found, then
771533affcbSRobert Mustacchi  * the function will fail.
772533affcbSRobert Mustacchi  *
773533affcbSRobert Mustacchi  * Currently the only supported controller name is nvmeX, though we should
774533affcbSRobert Mustacchi  * support GUIDs at some point. The namespace id, EUI64, and NGUID are all
775533affcbSRobert Mustacchi  * supported for the namespace.
776533affcbSRobert Mustacchi  */
777533affcbSRobert Mustacchi extern bool nvme_ctrl_ns_init(nvme_t *, const char *, nvme_ctrl_t **,
778533affcbSRobert Mustacchi     nvme_ns_t **);
779533affcbSRobert Mustacchi 
780533affcbSRobert Mustacchi /*
781533affcbSRobert Mustacchi  * NVMe Namespace Information.
782533affcbSRobert Mustacchi  *
783533affcbSRobert Mustacchi  * Namespace information is broken into a few groups. There is basic information
784533affcbSRobert Mustacchi  * about the LBA formats and capacities (which are provided in block sizes).
785533affcbSRobert Mustacchi  * There is information about the IDs. Note the NGUID/EUI64 are fallible
786533affcbSRobert Mustacchi  * because they are optional.
787533affcbSRobert Mustacchi  */
788533affcbSRobert Mustacchi extern bool nvme_ns_info_snap(nvme_ns_t *, nvme_ns_info_t **);
789533affcbSRobert Mustacchi extern bool nvme_ctrl_ns_info_snap(nvme_ctrl_t *, uint32_t, nvme_ns_info_t **);
790533affcbSRobert Mustacchi extern void nvme_ns_info_free(nvme_ns_info_t *);
791533affcbSRobert Mustacchi 
792533affcbSRobert Mustacchi extern nvme_info_err_t nvme_ns_info_err(nvme_ns_info_t *);
793533affcbSRobert Mustacchi extern int32_t nvme_ns_info_syserr(nvme_ns_info_t *);
794533affcbSRobert Mustacchi extern const char *nvme_ns_info_errmsg(nvme_ns_info_t *);
795533affcbSRobert Mustacchi extern size_t nvme_ns_info_errlen(nvme_ns_info_t *);
796533affcbSRobert Mustacchi extern const char *nvme_ns_info_errtostr(nvme_ns_info_t *, nvme_info_err_t);
797533affcbSRobert Mustacchi 
798533affcbSRobert Mustacchi extern uint32_t nvme_ns_info_nsid(nvme_ns_info_t *);
799533affcbSRobert Mustacchi extern nvme_ns_disc_level_t nvme_ns_info_level(nvme_ns_info_t *);
800533affcbSRobert Mustacchi extern const nvme_identify_nsid_t *nvme_ns_info_identify(nvme_ns_info_t *);
801533affcbSRobert Mustacchi 
802533affcbSRobert Mustacchi extern bool nvme_ns_info_nguid(nvme_ns_info_t *, uint8_t [16]);
803533affcbSRobert Mustacchi extern bool nvme_ns_info_eui64(nvme_ns_info_t *, uint8_t [8]);
804533affcbSRobert Mustacchi 
805533affcbSRobert Mustacchi extern bool nvme_ns_info_size(nvme_ns_info_t *, uint64_t *);
806533affcbSRobert Mustacchi extern bool nvme_ns_info_cap(nvme_ns_info_t *, uint64_t *);
807533affcbSRobert Mustacchi extern bool nvme_ns_info_use(nvme_ns_info_t *, uint64_t *);
808533affcbSRobert Mustacchi 
809533affcbSRobert Mustacchi extern bool nvme_ns_info_curformat(nvme_ns_info_t *,
810533affcbSRobert Mustacchi     const nvme_nvm_lba_fmt_t **);
811533affcbSRobert Mustacchi extern bool nvme_ns_info_nformats(nvme_ns_info_t *, uint32_t *);
812533affcbSRobert Mustacchi extern bool nvme_ns_info_format(nvme_ns_info_t *, uint32_t,
813533affcbSRobert Mustacchi     const nvme_nvm_lba_fmt_t **);
814533affcbSRobert Mustacchi 
815533affcbSRobert Mustacchi extern bool nvme_ns_info_bd_addr(nvme_ns_info_t *, const char **);
816533affcbSRobert Mustacchi 
817533affcbSRobert Mustacchi /*
818533affcbSRobert Mustacchi  * Controller and Namespace Locking
819533affcbSRobert Mustacchi  *
820533affcbSRobert Mustacchi  * A given controller can be active by several different parallel consumers.
821533affcbSRobert Mustacchi  */
822533affcbSRobert Mustacchi extern bool nvme_ctrl_lock(nvme_ctrl_t *, nvme_lock_level_t, nvme_lock_flags_t);
823533affcbSRobert Mustacchi extern void nvme_ctrl_unlock(nvme_ctrl_t *);
824533affcbSRobert Mustacchi extern bool nvme_ns_lock(nvme_ns_t *, nvme_lock_level_t, nvme_lock_flags_t);
825533affcbSRobert Mustacchi extern void nvme_ns_unlock(nvme_ns_t *);
826533affcbSRobert Mustacchi 
827533affcbSRobert Mustacchi /*
828533affcbSRobert Mustacchi  * Namespace Attach and Detach
829533affcbSRobert Mustacchi  *
830533affcbSRobert Mustacchi  * These operations are used to attach and detach a blkdev device from a given
831533affcbSRobert Mustacchi  * namespace.
832533affcbSRobert Mustacchi  */
833533affcbSRobert Mustacchi extern bool nvme_ns_bd_attach(nvme_ns_t *);
834533affcbSRobert Mustacchi extern bool nvme_ns_bd_detach(nvme_ns_t *);
835533affcbSRobert Mustacchi 
836533affcbSRobert Mustacchi /*
837533affcbSRobert Mustacchi  * NVMe Log Page Discovery
838533affcbSRobert Mustacchi  *
839533affcbSRobert Mustacchi  * NVMe Log Pages provide some complications around discovery. There are
840533affcbSRobert Mustacchi  * standard log pages, which are either mandatory or optional. There are also
841533affcbSRobert Mustacchi  * vendor-specific log pages that we may know about. While NVMe 2.0 introduced a
842533affcbSRobert Mustacchi  * way to list all of the supported log pages a device implements, that is not
843533affcbSRobert Mustacchi  * true for most devices. Pre 2.x devices sometimes have a vendor-specific way
844533affcbSRobert Mustacchi  * to list all the available logs. The NVMe 2.0 based mechanism also does not
845533affcbSRobert Mustacchi  * provide a means of getting additional information such as required fields, so
846533affcbSRobert Mustacchi  * we'll end up always needing the additional information this interface
847533affcbSRobert Mustacchi  * provides.
848533affcbSRobert Mustacchi  *
849533affcbSRobert Mustacchi  * The log page discovery functions here allow a caller to just ask for all the
850533affcbSRobert Mustacchi  * known IDs that exist for something. The discovery callback will fire once for
851533affcbSRobert Mustacchi  * each log page that may be implemented. Log pages we know that aren't
852533affcbSRobert Mustacchi  * implemented are never called back for.
853533affcbSRobert Mustacchi  */
854533affcbSRobert Mustacchi extern const char *nvme_log_disc_name(const nvme_log_disc_t *);
855533affcbSRobert Mustacchi extern const char *nvme_log_disc_desc(const nvme_log_disc_t *);
856533affcbSRobert Mustacchi extern nvme_csi_t nvme_log_disc_csi(const nvme_log_disc_t *);
857533affcbSRobert Mustacchi extern uint32_t nvme_log_disc_lid(const nvme_log_disc_t *);
858533affcbSRobert Mustacchi extern nvme_log_disc_kind_t nvme_log_disc_kind(const nvme_log_disc_t *);
859533affcbSRobert Mustacchi extern nvme_log_disc_source_t nvme_log_disc_sources(const nvme_log_disc_t *);
860533affcbSRobert Mustacchi extern nvme_log_disc_fields_t nvme_log_disc_fields(const nvme_log_disc_t *);
861533affcbSRobert Mustacchi extern nvme_log_disc_scope_t nvme_log_disc_scopes(const nvme_log_disc_t *);
862533affcbSRobert Mustacchi extern bool nvme_log_disc_impl(const nvme_log_disc_t *);
863533affcbSRobert Mustacchi 
864533affcbSRobert Mustacchi typedef enum {
865533affcbSRobert Mustacchi 	/*
866533affcbSRobert Mustacchi 	 * This indicates that the size of a log page is unknown. Instead, we
867533affcbSRobert Mustacchi 	 * will return a size that is reasonable enough to hopefully cover most
868533affcbSRobert Mustacchi 	 * things.
869533affcbSRobert Mustacchi 	 */
870533affcbSRobert Mustacchi 	NVME_LOG_SIZE_K_UNKNOWN	= 0,
871533affcbSRobert Mustacchi 	/*
872533affcbSRobert Mustacchi 	 * This indicates that there is a known fixed size for the log page and
873533affcbSRobert Mustacchi 	 * we have indicated what that is.
874533affcbSRobert Mustacchi 	 */
875533affcbSRobert Mustacchi 	NVME_LOG_SIZE_K_FIXED,
876533affcbSRobert Mustacchi 	/*
877533affcbSRobert Mustacchi 	 * This indicates that the total log size is variable; however, it can
878533affcbSRobert Mustacchi 	 * be determined by reading the specified following number of bytes.
879533affcbSRobert Mustacchi 	 * Once that number of bytes has been read, that can be passed to the
880533affcbSRobert Mustacchi 	 * nvme_log_disc_cal_size() function, which will attempt to determine
881533affcbSRobert Mustacchi 	 * the actual number of bytes based on the returned data.
882533affcbSRobert Mustacchi 	 */
883533affcbSRobert Mustacchi 	NVME_LOG_SIZE_K_VAR
884533affcbSRobert Mustacchi } nvme_log_size_kind_t;
885533affcbSRobert Mustacchi extern nvme_log_size_kind_t nvme_log_disc_size(const nvme_log_disc_t *,
886533affcbSRobert Mustacchi     uint64_t *);
887533affcbSRobert Mustacchi extern bool nvme_log_disc_calc_size(const nvme_log_disc_t *, uint64_t *,
888533affcbSRobert Mustacchi     const void *, size_t);
889533affcbSRobert Mustacchi 
890533affcbSRobert Mustacchi /*
891533affcbSRobert Mustacchi  * Duplicate and free log discovery information. The free function should only
892533affcbSRobert Mustacchi  * be used when it is explicitly duplicated or obtained through something like
893533affcbSRobert Mustacchi  * nvme_log_req_init_by_name(). It must not be used on the constant data
894533affcbSRobert Mustacchi  * provided as part of the nvme_log_discover family of functions.
895533affcbSRobert Mustacchi  */
896533affcbSRobert Mustacchi extern bool nvme_log_disc_dup(nvme_ctrl_t *, const nvme_log_disc_t *,
897533affcbSRobert Mustacchi     nvme_log_disc_t **);
898533affcbSRobert Mustacchi extern void nvme_log_disc_free(nvme_log_disc_t *);
899533affcbSRobert Mustacchi 
900533affcbSRobert Mustacchi extern bool nvme_log_discover_init(nvme_ctrl_t *, nvme_log_disc_scope_t,
901533affcbSRobert Mustacchi     uint32_t, nvme_log_iter_t **);
902533affcbSRobert Mustacchi extern nvme_iter_t nvme_log_discover_step(nvme_log_iter_t *,
903533affcbSRobert Mustacchi     const nvme_log_disc_t **);
904533affcbSRobert Mustacchi extern void nvme_log_discover_fini(nvme_log_iter_t *);
905533affcbSRobert Mustacchi 
906533affcbSRobert Mustacchi typedef bool (*nvme_log_disc_f)(nvme_ctrl_t *, const nvme_log_disc_t *,
907533affcbSRobert Mustacchi     void *);
908533affcbSRobert Mustacchi extern bool nvme_log_discover(nvme_ctrl_t *, nvme_log_disc_scope_t,
909533affcbSRobert Mustacchi     uint32_t, nvme_log_disc_f, void *);
910533affcbSRobert Mustacchi 
911533affcbSRobert Mustacchi /*
912533affcbSRobert Mustacchi  * One does not simply request a log page. There are a lot of parameters that
913533affcbSRobert Mustacchi  * are used to get a log page and these have been evolving over time. For
914533affcbSRobert Mustacchi  * example, the size has changed between 1.2 and 1.3, NVMe 1.0 never had UUIDs,
915533affcbSRobert Mustacchi  * LSP, LSIs, there are optional features around supporting offsets, etc.
916533affcbSRobert Mustacchi  *
917533affcbSRobert Mustacchi  * To deal with the fact that this keeps changing and an attempt to create a
918533affcbSRobert Mustacchi  * stable ABI, we instead have an opaque structure that allows various fields to
919533affcbSRobert Mustacchi  * be set and changed. To speed this up, this can be bootstrapped from the
920533affcbSRobert Mustacchi  * discovery information directly or indirectly by the log page short name.
921533affcbSRobert Mustacchi  *
922533affcbSRobert Mustacchi  * Once all of the appropriate fields are set on a log page request then it can
923533affcbSRobert Mustacchi  * be executed. A given request may be executed multiple times.
924533affcbSRobert Mustacchi  *
925533affcbSRobert Mustacchi  * When creating a raw log request, it will be up to the caller to fill in and
926533affcbSRobert Mustacchi  * set up the log ID (lid) and the output information. It is assumed that by
927533affcbSRobert Mustacchi  * default a log request should specify the NVM CSI. When using
928533affcbSRobert Mustacchi  * nvme_log_req_init_by_disc(), the log ID and command set will be filled in
929533affcbSRobert Mustacchi  * automatically. The discovery flags will indicate what other fields are still
930533affcbSRobert Mustacchi  * required.
931533affcbSRobert Mustacchi  */
932533affcbSRobert Mustacchi extern bool nvme_log_req_init(nvme_ctrl_t *, nvme_log_req_t **);
933533affcbSRobert Mustacchi extern bool nvme_log_req_init_by_disc(nvme_ctrl_t *, const nvme_log_disc_t *,
934533affcbSRobert Mustacchi     nvme_log_req_t **);
935533affcbSRobert Mustacchi extern bool nvme_log_req_init_by_name(nvme_ctrl_t *, const char *,
936533affcbSRobert Mustacchi     uint32_t, nvme_log_disc_t **, nvme_log_req_t **);
937533affcbSRobert Mustacchi extern void nvme_log_req_fini(nvme_log_req_t *);
938533affcbSRobert Mustacchi 
939533affcbSRobert Mustacchi extern bool nvme_log_req_set_lid(nvme_log_req_t *, uint32_t);
940533affcbSRobert Mustacchi extern bool nvme_log_req_set_lsp(nvme_log_req_t *, uint32_t);
941533affcbSRobert Mustacchi extern bool nvme_log_req_set_lsi(nvme_log_req_t *, uint32_t);
942533affcbSRobert Mustacchi extern bool nvme_log_req_set_uuid(nvme_log_req_t *, uint32_t);
943533affcbSRobert Mustacchi extern bool nvme_log_req_set_nsid(nvme_log_req_t *, uint32_t);
944533affcbSRobert Mustacchi extern bool nvme_log_req_set_output(nvme_log_req_t *, void *, size_t);
945*1c02c6c8SRobert Mustacchi extern bool nvme_log_req_clear_output(nvme_log_req_t *);
946533affcbSRobert Mustacchi extern bool nvme_log_req_set_offset(nvme_log_req_t *, uint64_t);
947533affcbSRobert Mustacchi extern bool nvme_log_req_set_rae(nvme_log_req_t *, bool);
948533affcbSRobert Mustacchi extern bool nvme_log_req_set_csi(nvme_log_req_t *, nvme_csi_t);
949533affcbSRobert Mustacchi extern bool nvme_log_req_exec(nvme_log_req_t *);
950533affcbSRobert Mustacchi 
951533affcbSRobert Mustacchi /*
952533affcbSRobert Mustacchi  * Feature Discovery and Management
953533affcbSRobert Mustacchi  *
954533affcbSRobert Mustacchi  * Features are parts of the NVMe specification that can both be retrieved and
955533affcbSRobert Mustacchi  * set. Features are often either a uint32_t or a larger data payload. In
956533affcbSRobert Mustacchi  * addition, there are additional modifiers that are required to select
957533affcbSRobert Mustacchi  * information about features. For example, when getting or setting a
958533affcbSRobert Mustacchi  * temperature threshold feature, a temperature sensor ID is required. Much like
959533affcbSRobert Mustacchi  * with log pages this has changed and added new arguments to getting and
960533affcbSRobert Mustacchi  * setting a feature at the command level and the individual features have grown
961533affcbSRobert Mustacchi  * support for more configuration as well.
962533affcbSRobert Mustacchi  *
963533affcbSRobert Mustacchi  * We currently provide information in discovery to determine what is required
964533affcbSRobert Mustacchi  * to get a feature as well as the ability to fast path that. Currently we
965533affcbSRobert Mustacchi  * provide the raw feature getting API that works at the low level. There is no
966533affcbSRobert Mustacchi  * higher level API for specific features. This works okay for an nvmeadm(8)
967533affcbSRobert Mustacchi  * style implementation, but we should consider adding more here based on
968533affcbSRobert Mustacchi  * feedback from consumers.
969533affcbSRobert Mustacchi  *
970533affcbSRobert Mustacchi  * Currently the kernel does not support setting features, which is why there is
971533affcbSRobert Mustacchi  * not a set feature API exposed through here. When it is, there will be an
972533affcbSRobert Mustacchi  * analogues set feature API to the get feature API that allows for one to
973533affcbSRobert Mustacchi  * build this up generically.
974533affcbSRobert Mustacchi  */
975533affcbSRobert Mustacchi extern const char *nvme_feat_disc_short(const nvme_feat_disc_t *);
976533affcbSRobert Mustacchi extern const char *nvme_feat_disc_spec(const nvme_feat_disc_t *);
977533affcbSRobert Mustacchi extern uint32_t nvme_feat_disc_fid(const nvme_feat_disc_t *);
978533affcbSRobert Mustacchi extern nvme_feat_scope_t nvme_feat_disc_scope(const nvme_feat_disc_t *);
979533affcbSRobert Mustacchi extern nvme_feat_kind_t nvme_feat_disc_kind(const nvme_feat_disc_t *);
980533affcbSRobert Mustacchi extern nvme_feat_csi_t nvme_feat_disc_csi(const nvme_feat_disc_t *);
981533affcbSRobert Mustacchi extern nvme_feat_flags_t nvme_feat_disc_flags(const nvme_feat_disc_t *);
982533affcbSRobert Mustacchi extern nvme_get_feat_fields_t nvme_feat_disc_fields_get(
983533affcbSRobert Mustacchi     const nvme_feat_disc_t *);
984533affcbSRobert Mustacchi extern nvme_set_feat_fields_t nvme_feat_disc_fields_set(
985533affcbSRobert Mustacchi     const nvme_feat_disc_t *);
986533affcbSRobert Mustacchi extern nvme_feat_output_t nvme_feat_disc_output_get(const nvme_feat_disc_t *);
987533affcbSRobert Mustacchi extern nvme_feat_output_t nvme_feat_disc_output_set(const nvme_feat_disc_t *);
988533affcbSRobert Mustacchi extern uint64_t nvme_feat_disc_data_size(const nvme_feat_disc_t *);
989533affcbSRobert Mustacchi extern nvme_feat_impl_t nvme_feat_disc_impl(const nvme_feat_disc_t *);
990533affcbSRobert Mustacchi 
991533affcbSRobert Mustacchi extern bool nvme_feat_discover_init(nvme_ctrl_t *, nvme_feat_scope_t, uint32_t,
992533affcbSRobert Mustacchi     nvme_feat_iter_t **);
993533affcbSRobert Mustacchi extern nvme_iter_t nvme_feat_discover_step(nvme_feat_iter_t *,
994533affcbSRobert Mustacchi     const nvme_feat_disc_t **);
995533affcbSRobert Mustacchi extern void nvme_feat_discover_fini(nvme_feat_iter_t *);
996533affcbSRobert Mustacchi 
997533affcbSRobert Mustacchi extern bool nvme_feat_disc_dup(nvme_ctrl_t *, const nvme_feat_disc_t *,
998533affcbSRobert Mustacchi     nvme_feat_disc_t **);
999533affcbSRobert Mustacchi extern void nvme_feat_disc_free(nvme_feat_disc_t *);
1000533affcbSRobert Mustacchi 
1001533affcbSRobert Mustacchi typedef bool (*nvme_feat_disc_f)(nvme_ctrl_t *, const nvme_feat_disc_t *,
1002533affcbSRobert Mustacchi     void *);
1003533affcbSRobert Mustacchi extern bool nvme_feat_discover(nvme_ctrl_t *, nvme_feat_scope_t, uint32_t,
1004533affcbSRobert Mustacchi     nvme_feat_disc_f, void *);
1005533affcbSRobert Mustacchi 
1006533affcbSRobert Mustacchi /*
1007533affcbSRobert Mustacchi  * Get Feature Request
1008533affcbSRobert Mustacchi  *
1009533affcbSRobert Mustacchi  * The get feature request allows one to build up a get feature command. It is
1010533affcbSRobert Mustacchi  * recommended to initiate a request based on discovery information or a
1011533affcbSRobert Mustacchi  * feature's name. That will allow the system to perform better validation, know
1012533affcbSRobert Mustacchi  * what fields are required or not, and pre-set parameters like the feature id
1013533affcbSRobert Mustacchi  * (fid). By default, a get features request will always ask for the current
1014533affcbSRobert Mustacchi  * value. Unless you want a saved or default value (and the controller is new
1015533affcbSRobert Mustacchi  * enough), then there is no need to set the selector. The only required field
1016533affcbSRobert Mustacchi  * when not using discovery information is the fid.
1017533affcbSRobert Mustacchi  */
1018533affcbSRobert Mustacchi extern bool nvme_get_feat_req_init(nvme_ctrl_t *, nvme_get_feat_req_t **);
1019533affcbSRobert Mustacchi extern bool nvme_get_feat_req_init_by_disc(nvme_ctrl_t *,
1020533affcbSRobert Mustacchi     const nvme_feat_disc_t *, nvme_get_feat_req_t **);
1021533affcbSRobert Mustacchi extern bool nvme_get_feat_req_init_by_name(nvme_ctrl_t *, const char *,
1022533affcbSRobert Mustacchi     uint32_t, nvme_feat_disc_t **, nvme_get_feat_req_t **);
1023533affcbSRobert Mustacchi extern void nvme_get_feat_req_fini(nvme_get_feat_req_t *);
1024533affcbSRobert Mustacchi 
1025533affcbSRobert Mustacchi extern bool nvme_get_feat_req_set_fid(nvme_get_feat_req_t *, uint32_t);
1026533affcbSRobert Mustacchi extern bool nvme_get_feat_req_set_sel(nvme_get_feat_req_t *, uint32_t);
1027533affcbSRobert Mustacchi extern bool nvme_get_feat_req_set_nsid(nvme_get_feat_req_t *, uint32_t);
1028533affcbSRobert Mustacchi extern bool nvme_get_feat_req_set_cdw11(nvme_get_feat_req_t *, uint32_t);
1029533affcbSRobert Mustacchi extern bool nvme_get_feat_req_set_output(nvme_get_feat_req_t *, void *, size_t);
1030*1c02c6c8SRobert Mustacchi extern bool nvme_get_feat_req_clear_output(nvme_get_feat_req_t *);
1031533affcbSRobert Mustacchi extern bool nvme_get_feat_req_exec(nvme_get_feat_req_t *);
1032533affcbSRobert Mustacchi extern bool nvme_get_feat_req_get_cdw0(nvme_get_feat_req_t *, uint32_t *);
1033533affcbSRobert Mustacchi 
1034533affcbSRobert Mustacchi /*
1035533affcbSRobert Mustacchi  * NVMe Vendor Unique Command Discovery and Execution
1036533affcbSRobert Mustacchi  *
1037533affcbSRobert Mustacchi  * There is a standard form of vendor unique commands which are indicated in the
1038533affcbSRobert Mustacchi  * identify controller datasheet. The first set of pieces here allows one to
1039533affcbSRobert Mustacchi  * discover which vendor-specific commands are supported by a device that are
1040533affcbSRobert Mustacchi  * known to the library. These generally have their own implementation
1041533affcbSRobert Mustacchi  * function; however, that isn't really linked to from the discovery function.
1042533affcbSRobert Mustacchi  * Tied into this is also asking if a given controller supports a given command
1043533affcbSRobert Mustacchi  * and getting information about it.
1044533affcbSRobert Mustacchi  *
1045533affcbSRobert Mustacchi  * The second set of functions here is all around allocating a vendor unique
1046533affcbSRobert Mustacchi  * command then executing it. Currently only admin commands are supported
1047533affcbSRobert Mustacchi  * through this interface.
1048533affcbSRobert Mustacchi  */
1049533affcbSRobert Mustacchi extern bool nvme_vuc_discover_init(nvme_ctrl_t *, uint32_t,
1050533affcbSRobert Mustacchi     nvme_vuc_iter_t **);
1051533affcbSRobert Mustacchi extern nvme_iter_t nvme_vuc_discover_step(nvme_vuc_iter_t *,
1052533affcbSRobert Mustacchi     const nvme_vuc_disc_t **);
1053533affcbSRobert Mustacchi extern void nvme_vuc_discover_fini(nvme_vuc_iter_t *);
1054533affcbSRobert Mustacchi 
1055533affcbSRobert Mustacchi typedef bool (*nvme_vuc_disc_f)(nvme_ctrl_t *, const nvme_vuc_disc_t *, void *);
1056533affcbSRobert Mustacchi extern bool nvme_vuc_discover(nvme_ctrl_t *, uint32_t, nvme_vuc_disc_f, void *);
1057533affcbSRobert Mustacchi 
1058533affcbSRobert Mustacchi extern bool nvme_vuc_discover_by_name(nvme_ctrl_t *, const char *, uint32_t,
1059533affcbSRobert Mustacchi     nvme_vuc_disc_t **);
1060533affcbSRobert Mustacchi extern bool nvme_vuc_disc_dup(nvme_ctrl_t *, const nvme_vuc_disc_t *,
1061533affcbSRobert Mustacchi     nvme_vuc_disc_t **);
1062533affcbSRobert Mustacchi extern void nvme_vuc_disc_free(nvme_vuc_disc_t *);
1063533affcbSRobert Mustacchi 
1064533affcbSRobert Mustacchi extern const char *nvme_vuc_disc_name(const nvme_vuc_disc_t *);
1065533affcbSRobert Mustacchi extern const char *nvme_vuc_disc_desc(const nvme_vuc_disc_t *);
1066533affcbSRobert Mustacchi extern uint32_t nvme_vuc_disc_opcode(const nvme_vuc_disc_t *);
1067533affcbSRobert Mustacchi 
1068533affcbSRobert Mustacchi typedef enum {
1069533affcbSRobert Mustacchi 	/*
1070533affcbSRobert Mustacchi 	 * Indicates that when this command is run, one should assume that all
1071533affcbSRobert Mustacchi 	 * data is potentially erased.
1072533affcbSRobert Mustacchi 	 */
1073533affcbSRobert Mustacchi 	NVME_VUC_DISC_IMPACT_DATA	= 1 << 0,
1074533affcbSRobert Mustacchi 	/*
1075533affcbSRobert Mustacchi 	 * Indicates that when this command is run, one should assume that the
1076533affcbSRobert Mustacchi 	 * list of namespaces and their attributes will change.
1077533affcbSRobert Mustacchi 	 */
1078533affcbSRobert Mustacchi 	NVME_VUC_DISC_IMPACT_NS		= 1 << 1
1079533affcbSRobert Mustacchi } nvme_vuc_disc_impact_t;
1080533affcbSRobert Mustacchi extern nvme_vuc_disc_impact_t nvme_vuc_disc_impact(const nvme_vuc_disc_t *);
1081533affcbSRobert Mustacchi 
1082533affcbSRobert Mustacchi typedef enum {
1083533affcbSRobert Mustacchi 	NVME_VUC_DISC_IO_NONE	= 0,
1084533affcbSRobert Mustacchi 	/*
1085533affcbSRobert Mustacchi 	 * Indicates that this command needs additional data provided as input
1086533affcbSRobert Mustacchi 	 * to the command.
1087533affcbSRobert Mustacchi 	 */
1088533affcbSRobert Mustacchi 	NVME_VUC_DISC_IO_INPUT	= 1 << 0,
1089533affcbSRobert Mustacchi 	/*
1090533affcbSRobert Mustacchi 	 * Indicates that this command writes output back to the host from the
1091533affcbSRobert Mustacchi 	 * controller and a data buffer is required.
1092533affcbSRobert Mustacchi 	 */
1093533affcbSRobert Mustacchi 	NVME_VUC_DISC_IO_OUTPUT	= 1 << 1
1094533affcbSRobert Mustacchi } nvme_vuc_disc_io_t;
1095533affcbSRobert Mustacchi extern nvme_vuc_disc_io_t nvme_vuc_disc_dt(const nvme_vuc_disc_t *);
1096533affcbSRobert Mustacchi 
1097533affcbSRobert Mustacchi typedef enum {
1098533affcbSRobert Mustacchi 	/*
1099533affcbSRobert Mustacchi 	 * Indicates that the library has no opinion on whether a lock should be
1100533affcbSRobert Mustacchi 	 * taken or not.
1101533affcbSRobert Mustacchi 	 */
1102533affcbSRobert Mustacchi 	NVME_VUC_DISC_LOCK_NONE	= 0,
1103533affcbSRobert Mustacchi 	/*
1104533affcbSRobert Mustacchi 	 * Indicates that a controller or namespace level read lock is
1105533affcbSRobert Mustacchi 	 * recommended for this operation.
1106533affcbSRobert Mustacchi 	 */
1107533affcbSRobert Mustacchi 	NVME_VUC_DISC_LOCK_READ,
1108533affcbSRobert Mustacchi 	/*
1109533affcbSRobert Mustacchi 	 * Indicates that a controller or namespace level write lock is
1110533affcbSRobert Mustacchi 	 * recommended for this operation.
1111533affcbSRobert Mustacchi 	 */
1112533affcbSRobert Mustacchi 	NVME_VUC_DISC_LOCK_WRITE
1113533affcbSRobert Mustacchi } nvme_vuc_disc_lock_t;
1114533affcbSRobert Mustacchi extern nvme_vuc_disc_lock_t nvme_vuc_disc_lock(const nvme_vuc_disc_t *);
1115533affcbSRobert Mustacchi 
1116533affcbSRobert Mustacchi extern bool nvme_vuc_req_init(nvme_ctrl_t *, nvme_vuc_req_t **);
1117533affcbSRobert Mustacchi extern void nvme_vuc_req_fini(nvme_vuc_req_t *);
1118533affcbSRobert Mustacchi 
1119533affcbSRobert Mustacchi extern bool nvme_vuc_req_set_opcode(nvme_vuc_req_t *, uint32_t);
1120533affcbSRobert Mustacchi extern bool nvme_vuc_req_set_nsid(nvme_vuc_req_t *, uint32_t);
1121533affcbSRobert Mustacchi extern bool nvme_vuc_req_set_timeout(nvme_vuc_req_t *, uint32_t);
1122533affcbSRobert Mustacchi extern bool nvme_vuc_req_set_cdw12(nvme_vuc_req_t *, uint32_t);
1123533affcbSRobert Mustacchi extern bool nvme_vuc_req_set_cdw13(nvme_vuc_req_t *, uint32_t);
1124533affcbSRobert Mustacchi extern bool nvme_vuc_req_set_cdw14(nvme_vuc_req_t *, uint32_t);
1125533affcbSRobert Mustacchi extern bool nvme_vuc_req_set_cdw15(nvme_vuc_req_t *, uint32_t);
1126533affcbSRobert Mustacchi extern bool nvme_vuc_req_set_impact(nvme_vuc_req_t *, nvme_vuc_disc_impact_t);
1127533affcbSRobert Mustacchi extern bool nvme_vuc_req_set_input(nvme_vuc_req_t *, const void *, size_t);
1128533affcbSRobert Mustacchi extern bool nvme_vuc_req_set_output(nvme_vuc_req_t *, void *, size_t);
1129*1c02c6c8SRobert Mustacchi extern bool nvme_vuc_req_clear_output(nvme_vuc_req_t *);
1130533affcbSRobert Mustacchi 
1131533affcbSRobert Mustacchi /*
1132533affcbSRobert Mustacchi  * Execute a request. After a request is executed, the status information
1133533affcbSRobert Mustacchi  * becomes available. A call to exec will invalidate any prior results. If the
1134533affcbSRobert Mustacchi  * request does not make it to the controller for some reason or some other
1135533affcbSRobert Mustacchi  * error occurs, then getting the results will fail. If the controller fails the
1136533affcbSRobert Mustacchi  * command, that will set the NVME_ERR_CONTROLLER error and the corresponding
1137533affcbSRobert Mustacchi  * SCT/SC values can be retrieved from the controller's error information for
1138533affcbSRobert Mustacchi  * inspection.
1139533affcbSRobert Mustacchi  */
1140533affcbSRobert Mustacchi extern bool nvme_vuc_req_exec(nvme_vuc_req_t *);
1141533affcbSRobert Mustacchi extern bool nvme_vuc_req_get_cdw0(nvme_vuc_req_t *, uint32_t *);
1142533affcbSRobert Mustacchi 
1143533affcbSRobert Mustacchi /*
1144533affcbSRobert Mustacchi  * Firmware Download and Commit (Activation)
1145533affcbSRobert Mustacchi  *
1146533affcbSRobert Mustacchi  * NVMe devices have a buffer that is used to receive a firmware download. This
1147533affcbSRobert Mustacchi  * can then be committed into a firmware slot or a boot slot through the commit
1148533affcbSRobert Mustacchi  * action. The commit action may also change which firmware slot is activated on
1149533affcbSRobert Mustacchi  * the next boot at the same time as installing an image or a commit can be used
1150533affcbSRobert Mustacchi  * to just change the active image. The optional bootloader features will have a
1151533affcbSRobert Mustacchi  * similar shape as to the firmware commit routines, but ultimately be different
1152533affcbSRobert Mustacchi  * ones to make it more obvious what is being done.
1153533affcbSRobert Mustacchi  *
1154533affcbSRobert Mustacchi  * The firmware download command has to date not really changed through the NVMe
1155533affcbSRobert Mustacchi  * 1.x and 2.0 standards, which is why it is not broken into a request and
1156533affcbSRobert Mustacchi  * execution format like others at this time.
11573dd3cd66SAndy Fiddaman  *
11583dd3cd66SAndy Fiddaman  * Firmware must be loaded with a particular granularity and if blocks do not
11593dd3cd66SAndy Fiddaman  * conform to that, nvme_fw_load() will return an error.
1160533affcbSRobert Mustacchi  */
1161533affcbSRobert Mustacchi extern bool nvme_fw_load(nvme_ctrl_t *, const void *, size_t, uint64_t);
1162533affcbSRobert Mustacchi 
1163533affcbSRobert Mustacchi extern bool nvme_fw_commit_req_init(nvme_ctrl_t *, nvme_fw_commit_req_t **);
1164533affcbSRobert Mustacchi extern void nvme_fw_commit_req_fini(nvme_fw_commit_req_t *);
1165533affcbSRobert Mustacchi extern bool nvme_fw_commit_req_set_slot(nvme_fw_commit_req_t *, uint32_t);
1166533affcbSRobert Mustacchi extern bool nvme_fw_commit_req_set_action(nvme_fw_commit_req_t *, uint32_t);
1167533affcbSRobert Mustacchi extern bool nvme_fw_commit_req_exec(nvme_fw_commit_req_t *);
1168533affcbSRobert Mustacchi 
1169533affcbSRobert Mustacchi /*
1170533affcbSRobert Mustacchi  * Format NVM
1171533affcbSRobert Mustacchi  *
1172533affcbSRobert Mustacchi  * This is used to erase and reformat either all namespaces or a specific one.
1173533affcbSRobert Mustacchi  * We currently do not support setting metadata or protection information for
1174533affcbSRobert Mustacchi  * namespaces in the kernel which is why this is not present in the library.
1175533affcbSRobert Mustacchi  */
1176533affcbSRobert Mustacchi extern bool nvme_format_req_init(nvme_ctrl_t *, nvme_format_req_t **);
1177533affcbSRobert Mustacchi extern void nvme_format_req_fini(nvme_format_req_t *);
1178533affcbSRobert Mustacchi extern bool nvme_format_req_set_lbaf(nvme_format_req_t *, uint32_t);
1179533affcbSRobert Mustacchi extern bool nvme_format_req_set_ses(nvme_format_req_t *, uint32_t);
1180533affcbSRobert Mustacchi extern bool nvme_format_req_set_nsid(nvme_format_req_t *, uint32_t);
1181533affcbSRobert Mustacchi extern bool nvme_format_req_exec(nvme_format_req_t *);
1182533affcbSRobert Mustacchi 
1183533affcbSRobert Mustacchi /*
1184533affcbSRobert Mustacchi  * Vendor-specific interfaces.
1185533affcbSRobert Mustacchi  */
1186533affcbSRobert Mustacchi 
1187533affcbSRobert Mustacchi /*
1188533affcbSRobert Mustacchi  * WDC resizing functions. These are interfaces supported in the SN840, SN650,
1189533affcbSRobert Mustacchi  * SN655, etc. These end up allowing one to adjust the overprovisioning ratio,
1190533affcbSRobert Mustacchi  * though this ends up reformatting the device and all namespaces in the
1191533affcbSRobert Mustacchi  * process. The values passed and returned are in GB (not GiB).
1192533affcbSRobert Mustacchi  */
1193533affcbSRobert Mustacchi extern bool nvme_wdc_resize_set(nvme_ctrl_t *, uint32_t);
1194533affcbSRobert Mustacchi extern bool nvme_wdc_resize_get(nvme_ctrl_t *, uint32_t *);
1195533affcbSRobert Mustacchi 
1196533affcbSRobert Mustacchi /*
1197533affcbSRobert Mustacchi  * WDC e6 diagnostic log. The e6 log is a WDC-specific diagnostic log which
1198533affcbSRobert Mustacchi  * contains information about the device itself.
1199533affcbSRobert Mustacchi  */
1200533affcbSRobert Mustacchi extern bool nvme_wdc_e6_req_init(nvme_ctrl_t *, nvme_wdc_e6_req_t **);
1201533affcbSRobert Mustacchi extern void nvme_wdc_e6_req_fini(nvme_wdc_e6_req_t *);
1202533affcbSRobert Mustacchi extern bool nvme_wdc_e6_req_set_offset(nvme_wdc_e6_req_t *, uint64_t);
1203533affcbSRobert Mustacchi extern bool nvme_wdc_e6_req_set_output(nvme_wdc_e6_req_t *, void *,
1204533affcbSRobert Mustacchi     size_t);
1205*1c02c6c8SRobert Mustacchi extern bool nvme_wdc_e6_req_clear_output(nvme_wdc_e6_req_t *);
1206533affcbSRobert Mustacchi extern bool nvme_wdc_e6_req_exec(nvme_wdc_e6_req_t *);
1207533affcbSRobert Mustacchi 
12087a27a99aSRobert Mustacchi /*
12097a27a99aSRobert Mustacchi  * WDC assert injection and removal.
12107a27a99aSRobert Mustacchi  */
12117a27a99aSRobert Mustacchi extern bool nvme_wdc_assert_clear(nvme_ctrl_t *);
12127a27a99aSRobert Mustacchi extern bool nvme_wdc_assert_inject(nvme_ctrl_t *);
12137a27a99aSRobert Mustacchi 
1214533affcbSRobert Mustacchi #ifdef __cplusplus
1215533affcbSRobert Mustacchi }
1216533affcbSRobert Mustacchi #endif
1217533affcbSRobert Mustacchi 
1218533affcbSRobert Mustacchi #endif /* _LIBNVME_H */
1219