xref: /illumos-gate/usr/src/lib/libnvme/common/libnvme.h (revision e8d3efa1c56e5f2b5368600a2baeb7b1d54a07f8)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2026 Oxide Computer Company
14  */
15 
16 #ifndef _LIBNVME_H
17 #define	_LIBNVME_H
18 
19 /*
20  * This contains an evolving set of interfaces for more programmatically
21  * interfacing with NVMe devices. For more information on why the library looks
22  * this way, please see lib/libnvme/common/libnvme.c.
23  */
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 #include <stdint.h>
30 #include <stdbool.h>
31 #include <libdevinfo.h>
32 #include <sys/nvme/discovery.h>
33 
34 /*
35  * Right now everything relies on seeing various pieces that are in sys/nvme.h,
36  * unfortunately. This includes things like the identify, log page, and
37  * structure data structures, various constants, and other things that have
38  * accumulated. This must all be rejiggered prior to making this a committed
39  * interface as we're leaking through many things that software needs.
40  * Directionally splitting this out into headers that relate to the spec as
41  * <sys/nvme/identify.h>, etc. would be useful and would address several of the
42  * places that we're passing in raw uint32_t's for items that come from the spec
43  * and could be a little more specific to help out consumers.
44  */
45 #include <sys/nvme.h>
46 
47 /*
48  * General error classes that may be returned when operating on non-information
49  * snapshots.
50  */
51 typedef enum {
52 	NVME_ERR_OK	 = 0,
53 	/*
54 	 * Indicates that a command failed due to a controller-specific error.
55 	 * The controller's SCT/SC are valid in the corresponding objects error
56 	 * data.
57 	 */
58 	NVME_ERR_CONTROLLER,
59 	/*
60 	 * Indicates that there was a memory allocation error. The system error
61 	 * contains the specific errno.
62 	 */
63 	NVME_ERR_NO_MEM,
64 	/*
65 	 * Indicates that an operation could not complete because the kernel did
66 	 * not have DMA resources available for us.
67 	 */
68 	NVME_ERR_NO_DMA_MEM,
69 	/*
70 	 * Indicates that an error occurred while trying to use the devinfo
71 	 * library.
72 	 */
73 	NVME_ERR_LIBDEVINFO,
74 	/*
75 	 * Indicates that an internal error condition occurred.
76 	 */
77 	NVME_ERR_INTERNAL,
78 	/*
79 	 * Indicates that the function was given an invalid pointer argument.
80 	 */
81 	NVME_ERR_BAD_PTR,
82 	/*
83 	 * Indicates that an unknown flag argument was given to us.
84 	 */
85 	NVME_ERR_BAD_FLAG,
86 	/*
87 	 * Indicates that the devinfo node we were given doesn't correspond to
88 	 * an NVMe controller.
89 	 */
90 	NVME_ERR_BAD_DEVI,
91 	/*
92 	 * Indicates that while we found a devinfo property successfully,
93 	 * something about it does not match our expectations. This could be the
94 	 * type, number of values, range, etc.
95 	 */
96 	NVME_ERR_BAD_DEVI_PROP,
97 	/*
98 	 * Indicates that we were given an illegal instance (i.e. a negative
99 	 * instance).
100 	 */
101 	NVME_ERR_ILLEGAL_INSTANCE,
102 	/*
103 	 * Indicates that a means of identifying a controller (name, instance,
104 	 * etc.) does not match any known NVMe device.
105 	 */
106 	NVME_ERR_BAD_CONTROLLER,
107 	/*
108 	 * Indicates that a request could not proceed due to missing privileges.
109 	 */
110 	NVME_ERR_PRIVS,
111 	/*
112 	 * Indicates a failure to open a device file.
113 	 */
114 	NVME_ERR_OPEN_DEV,
115 	/*
116 	 * Indicates that the given restore data is not valid.
117 	 */
118 	NVME_ERR_BAD_RESTORE,
119 	/*
120 	 * Indicates that a namespace (name, ID, etc.) passed in is not valid on
121 	 * the controller. This may be because it's outside the valid range or
122 	 * there was an attempt to use the broadcast namespace when it's not
123 	 * supported.
124 	 */
125 	NVME_ERR_NS_RANGE,
126 	/*
127 	 * Indicates that a namespace ID is not usable in this context. For
128 	 * example, attempting to specify a namespace to an identify or log page
129 	 * that does not support them.
130 	 */
131 	NVME_ERR_NS_UNUSE,
132 	/*
133 	 * Indicates that the value for a get log page field is invalid. This
134 	 * may happened due to alignment, just being too large, or something
135 	 * else.
136 	 */
137 	NVME_ERR_LOG_CSI_RANGE,
138 	NVME_ERR_LOG_LID_RANGE,
139 	NVME_ERR_LOG_LSP_RANGE,
140 	NVME_ERR_LOG_LSI_RANGE,
141 	NVME_ERR_LOG_RAE_RANGE,
142 	NVME_ERR_LOG_SIZE_RANGE,
143 	NVME_ERR_LOG_OFFSET_RANGE,
144 	/*
145 	 * Indicates that the log field value given is not supported because the
146 	 * controller is not of a sufficient version or does not indicate that
147 	 * it is supported in the LPA field.
148 	 */
149 	NVME_ERR_LOG_CSI_UNSUP,
150 	NVME_ERR_LOG_LSP_UNSUP,
151 	NVME_ERR_LOG_LSI_UNSUP,
152 	NVME_ERR_LOG_RAE_UNSUP,
153 	NVME_ERR_LOG_OFFSET_UNSUP,
154 	/*
155 	 * Indicates that the log field value is unusable. The specifics of our
156 	 * request indicate that this cannot be set.
157 	 */
158 	NVME_ERR_LOG_LSP_UNUSE,
159 	NVME_ERR_LOG_LSI_UNUSE,
160 	NVME_ERR_LOG_RAE_UNUSE,
161 	/*
162 	 * Indicates that the log page's scope requires operating on something
163 	 * that isn't what was requested. This would happen if manually
164 	 * constructing a log page that operates on the controller, but passed a
165 	 * namespace (e.g. the firmware log page).
166 	 */
167 	NVME_ERR_LOG_SCOPE_MISMATCH,
168 	/*
169 	 * Indicates that a log request can't be executed because required
170 	 * fields have not been set.
171 	 */
172 	NVME_ERR_LOG_REQ_MISSING_FIELDS,
173 	/*
174 	 * Indicates that the named log is unknown to the library.
175 	 */
176 	NVME_ERR_LOG_NAME_UNKNOWN,
177 	/*
178 	 * Indicates that the named log is not supported by the device.
179 	 */
180 	NVME_ERR_LOG_UNSUP_BY_DEV,
181 	/*
182 	 * Indicates that the IDENTIFY command requested is unknown.
183 	 */
184 	NVME_ERR_IDENTIFY_UNKNOWN,
185 	/*
186 	 * Indicates that the requested identify command is not supported by the
187 	 * device.
188 	 */
189 	NVME_ERR_IDENTIFY_UNSUP_BY_DEV,
190 	/*
191 	 * Indicates that the identify command parameter is outside of the valid
192 	 * range for the field.
193 	 */
194 	NVME_ERR_IDENTIFY_CTRLID_RANGE,
195 	NVME_ERR_IDENTIFY_OUTPUT_RANGE,
196 	/*
197 	 * Indicates that the parameter given is not supported because the
198 	 * controller is not of a sufficient version or does not indicate that
199 	 * it is supported.
200 	 */
201 	NVME_ERR_IDENTIFY_CTRLID_UNSUP,
202 	/*
203 	 * Indicates that the parameter given is not supported in the context of
204 	 * a given identify command. Namespaces are handled with the
205 	 * cross-command error code.
206 	 */
207 	NVME_ERR_IDENTIFY_CTRLID_UNUSE,
208 	/*
209 	 * Indicates that an identify request can't be executed because required
210 	 * fields have not been set.
211 	 */
212 	NVME_ERR_IDENTIFY_REQ_MISSING_FIELDS,
213 	/*
214 	 * Indicates that the controller doesn't support the NVMe standard
215 	 * vendor unique command.
216 	 */
217 	NVME_ERR_VUC_UNSUP_BY_DEV,
218 	/*
219 	 * Indicates that the vendor unique command parameter is outside of the
220 	 * valid range for the field.
221 	 */
222 	NVME_ERR_VUC_TIMEOUT_RANGE,
223 	NVME_ERR_VUC_OPCODE_RANGE,
224 	NVME_ERR_VUC_IMPACT_RANGE,
225 	NVME_ERR_VUC_NDT_RANGE,
226 	/*
227 	 * Indicates that a vendor unique command already has an input or output
228 	 * buffer set and is being asked to set a separate one.
229 	 */
230 	NVME_ERR_VUC_CANNOT_RW,
231 	/*
232 	 * Indicates that the vendor unique request does not have valid
233 	 * execution context. This may be because the command was never executed
234 	 * or the exec failed in a way such that the controller never exercised
235 	 * the command.
236 	 */
237 	NVME_ERR_VUC_NO_RESULTS,
238 	/*
239 	 * Indicates that the named vendor unique command is not known to the
240 	 * library.
241 	 */
242 	NVME_ERR_VUC_UNKNOWN,
243 	/*
244 	 * Indicates that a vendor unique command can't be executed because
245 	 * required fields have not been set.
246 	 */
247 	NVME_ERR_VUC_REQ_MISSING_FIELDS,
248 	/*
249 	 * Indicates that the vendor-specific library operation could not
250 	 * proceed because it is not supported by the given device.
251 	 */
252 	NVME_ERR_VU_FUNC_UNSUP_BY_DEV,
253 	/*
254 	 * WDC e6 dump specific invalid values
255 	 */
256 	NVME_ERR_WDC_E6_OFFSET_RANGE,
257 	/*
258 	 * Indicates that the controller does not support firmware related
259 	 * operations.
260 	 */
261 	NVME_ERR_FW_UNSUP_BY_DEV,
262 	/*
263 	 * Indicates that the constraints of the device and what the kernel can
264 	 * do make the firmware upgrade non-tenable.
265 	 */
266 	NVME_ERR_KERN_FW_IMPOS,
267 	/*
268 	 * Indicates that a firmware download parameter is invalid.
269 	 */
270 	NVME_ERR_FW_LOAD_LEN_RANGE,
271 	NVME_ERR_FW_LOAD_OFFSET_RANGE,
272 	/*
273 	 * Indicates that the firmware commit command parameter is outside of
274 	 * the valid range for the field.
275 	 */
276 	NVME_ERR_FW_COMMIT_SLOT_RANGE,
277 	NVME_ERR_FW_COMMIT_ACTION_RANGE,
278 	/*
279 	 * Indicates that a firmware commit command can't be executed because
280 	 * required fields have not been set.
281 	 */
282 	NVME_ERR_FW_COMMIT_REQ_MISSING_FIELDS,
283 	/*
284 	 * Indicates that the firmware commit could not occur because the
285 	 * requested slot is read-only.
286 	 */
287 	NVME_ERR_FW_SLOT_RO,
288 	/*
289 	 * Indicates that the controller does not support NVM format operations.
290 	 */
291 	NVME_ERR_FORMAT_UNSUP_BY_DEV,
292 	/*
293 	 * Indicates that the controller does not support cryptographic secure
294 	 * erase.
295 	 */
296 	NVME_ERR_CRYPTO_SE_UNSUP_BY_DEV,
297 	/*
298 	 * Indicates that the NVM format command cannot be executed because it
299 	 * would target a specific namespace; however, the device does not allow
300 	 * a secure erase or a format to target an individual namespace.
301 	 */
302 	NVME_ERR_NS_FORMAT_UNSUP_BY_DEV,
303 	/*
304 	 * Indicates that the kernel does not support formatting with the
305 	 * specified LBA format, generally due to something like the use of
306 	 * metadata in the namespace.
307 	 */
308 	NVME_ERR_KERN_FORMAT_UNSUP,
309 	/*
310 	 * Indicates that the NVM format command parameter is outside of
311 	 * the valid range for the field.
312 	 */
313 	NVME_ERR_FORMAT_LBAF_RANGE,
314 	NVME_ERR_FORMAT_SES_RANGE,
315 	/*
316 	 * Indicates that the parameter and/or its value is not supported for a
317 	 * NVM format command.
318 	 */
319 	NVME_ERR_FORMAT_PARAM_UNSUP,
320 	/*
321 	 * Indicates that a NVM format command can't be executed because
322 	 * required fields have not been set.
323 	 */
324 	NVME_ERR_FORMAT_REQ_MISSING_FIELDS,
325 	/*
326 	 * Indicates that the WDC e6 log dump request could not be executed due
327 	 * to fields not being set.
328 	 */
329 	NVME_ERR_WDC_E6_REQ_MISSING_FIELDS,
330 	/*
331 	 * Indicates that the named feature is unknown to the library.
332 	 */
333 	NVME_ERR_FEAT_NAME_UNKNOWN,
334 	/*
335 	 * Indicates that the named feature is not supported by the device.
336 	 */
337 	NVME_ERR_FEAT_UNSUP_BY_DEV,
338 	/*
339 	 * Indicates that the feature parameter is outside of the valid range
340 	 * for the field.
341 	 */
342 	NVME_ERR_FEAT_FID_RANGE,
343 	NVME_ERR_FEAT_SEL_RANGE,
344 	NVME_ERR_FEAT_CDW11_RANGE,
345 	NVME_ERR_FEAT_DATA_RANGE,
346 	/*
347 	 * Indicates that the feature parameter given is not supported because
348 	 * the controller is not of a sufficient version.
349 	 */
350 	NVME_ERR_FEAT_SEL_UNSUP,
351 	/*
352 	 * Indicates that the get feature parameter given is not supported for
353 	 * the given feature. For example, passing in a cdw11 argument that is
354 	 * not needed.
355 	 */
356 	NVME_ERR_FEAT_CDW11_UNUSE,
357 	NVME_ERR_FEAT_DATA_UNUSE,
358 	/*
359 	 * Indicates that a feature request does not have valid output data.
360 	 * This may be because the command was never executed or it did not
361 	 * execute successfully.
362 	 */
363 	NVME_ERR_FEAT_NO_RESULTS,
364 	/*
365 	 * Indicates that a get features request can't be executed because
366 	 * required fields have not been set.
367 	 */
368 	NVME_ERR_GET_FEAT_REQ_MISSING_FIELDS,
369 	/*
370 	 * These indicate that the operation could not be executed because they
371 	 * require holding either a controller or namespace write lock and one
372 	 * is not held by the corresponding controller handle.
373 	 */
374 	NVME_ERR_NEED_CTRL_WRLOCK,
375 	NVME_ERR_NEED_NS_WRLOCK,
376 	/*
377 	 * These indicate that the operation could not be executed because the
378 	 * controller or namespace respectively currently have an exclusive
379 	 * write lock (or an equivalent future form) that blocks execution from
380 	 * others.
381 	 */
382 	NVME_ERR_CTRL_LOCKED,
383 	NVME_ERR_NS_LOCKED,
384 	/*
385 	 * Indicates that a fatal locking operation occurred that will terminate
386 	 * the process. This includes cases such as recursive enters on the same
387 	 * lock, attempting to unlock a lock that isn't owned, etc.
388 	 */
389 	NVME_ERR_LOCK_PROG,
390 	/*
391 	 * Indicates that a lock order violation was attempted. This includes
392 	 * things like taking the controller lock while holding the namespace
393 	 * lock, attempting to take a second namespace lock, holding a
394 	 * controller write lock and trying to get a namespace lock, etc.
395 	 */
396 	NVME_ERR_LOCK_ORDER,
397 	/*
398 	 * Indicates that a signal was encountered while attempting to take a
399 	 * lock.
400 	 */
401 	NVME_ERR_LOCK_WAIT_INTR,
402 	/*
403 	 * Indicates that attempting to take the lock failed because the thread
404 	 * would be required to block, but it asked not to.
405 	 */
406 	NVME_ERR_LOCK_WOULD_BLOCK,
407 	/*
408 	 * These indicate that the respective blkdev attach and detach
409 	 * operations failed to complete due to an error in the underlying
410 	 * kernel subsystems. For detach this might happen because of a disk
411 	 * being open, busy in a zpool, or something else. For attach, it may
412 	 * suggest an NDI or other issue.
413 	 */
414 	NVME_ERR_DETACH_KERN,
415 	NVME_ERR_ATTACH_KERN,
416 	/*
417 	 * Indicates that the kernel driver does not support some property of
418 	 * the requested namespace.
419 	 */
420 	NVME_ERR_ATTACH_UNSUP_KERN,
421 	/*
422 	 * Indicates that the operation cannot proceed because a namespace is
423 	 * attached to blkdev and it must be detached to proceed.
424 	 */
425 	NVME_ERR_NS_BLKDEV_ATTACH,
426 	/*
427 	 * Indicates that non-DMA kernel memory was not available for this
428 	 * request.
429 	 */
430 	NVME_ERR_NO_KERN_MEM,
431 	/*
432 	 * These two codes represent internal device conditions that indicate
433 	 * the device is unusable or that it was physically removed (usually due
434 	 * to hotplug).
435 	 */
436 	NVME_ERR_CTRL_DEAD,
437 	NVME_ERR_CTRL_GONE,
438 	/*
439 	 * Indicates that the controller does not support namespace management
440 	 * operations including controller attach/detach and namespace
441 	 * create/delete.
442 	 */
443 	NVME_ERR_NS_MGMT_UNSUP_BY_DEV,
444 	/*
445 	 * Indicates that the controller does not support thin provisioning.
446 	 */
447 	NVME_ERR_THIN_PROV_UNSUP_BY_DEV,
448 	/*
449 	 * These indicate that the corresponding requests cannot be executed due
450 	 * to missing fields.
451 	 */
452 	NVME_ERR_NS_ATTACH_REQ_MISSING_FIELDS,
453 	NVME_ERR_NS_CREATE_REQ_MISSING_FIELDS,
454 	NVME_ERR_NS_DELETE_REQ_MISSING_FIELDS,
455 	/*
456 	 * This specifically is used by the namespace creation functions to
457 	 * indicate that a requested CSI is not supported. Currently this could
458 	 * be because the CSI is invalid, the device doesn't support it, the
459 	 * kernel doesn't support it, etc.
460 	 *
461 	 * The namespace attach variant is the same logic, just applied to the
462 	 * selector. Both of these are phrased differently as the set of fields
463 	 * that may or may not be valid for a given request of these types can
464 	 * vary based on the type.
465 	 */
466 	NVME_ERR_NS_CREATE_BAD_CSI,
467 	NVME_ERR_NS_ATTACH_BAD_SEL,
468 	/*
469 	 * Indicates that the NSID result value is not valid because we have not
470 	 * yet executed a namespace create request.
471 	 */
472 	NVME_ERR_NS_CREATE_NO_RESULTS,
473 	/*
474 	 * Indicates that the create namespace field is outside of the valid
475 	 * range for the field.
476 	 */
477 	NVME_ERR_NS_CREATE_NCAP_RANGE,
478 	NVME_ERR_NS_CREATE_NSZE_RANGE,
479 	NVME_ERR_NS_CREATE_NMIC_RANGE,
480 	NVME_ERR_NS_CREATE_FLBAS_RANGE,
481 	/*
482 	 * Indicates that the operation cannot proceed because the namespace is
483 	 * already attached or not attached to a controller respectively.
484 	 */
485 	NVME_ERR_NS_CTRL_ATTACHED,
486 	NVME_ERR_NS_CTRL_NOT_ATTACHED,
487 	/*
488 	 * Indicates that the namespace is unallocated and therefore the
489 	 * operation cannot proceed.
490 	 */
491 	NVME_ERR_NS_UNALLOC,
492 	/*
493 	 * Indicates that a library function was referring to a PCIe lane number
494 	 * that is not valid for the device.
495 	 */
496 	NVME_ERR_PCIE_LANE_RANGE,
497 	/*
498 	 * Indicates that a PCIe eye diagram buffer size was too small.
499 	 */
500 	NVME_ERR_PCIE_EYE_BUF_RANGE,
501 	/*
502 	 * The system does not allow this particular feature to be set by users.
503 	 */
504 	NVME_ERR_SET_FEAT_USER_UNSUP,
505 	/*
506 	 * Additional feature fields that are outside the range.
507 	 */
508 	NVME_ERR_FEAT_SAVE_RANGE,
509 	NVME_ERR_FEAT_CDW12_RANGE,
510 	NVME_ERR_FEAT_CDW13_RANGE,
511 	NVME_ERR_FEAT_CDW15_RANGE,
512 	NVME_ERR_FEAT_IMPACT_RANGE,
513 	/*
514 	 * Additional feature fields that are unusable on certain controllers.
515 	 */
516 	NVME_ERR_FEAT_SAVE_UNSUP,
517 	NVME_ERR_FEAT_CDW12_UNSUP,
518 	NVME_ERR_FEAT_CDW13_UNSUP,
519 	NVME_ERR_FEAT_CDW15_UNSUP,
520 	/*
521 	 * Additional feature fields that are not unusable in certain
522 	 * circumstances.
523 	 */
524 	NVME_ERR_FEAT_CDW12_UNUSE,
525 	NVME_ERR_FEAT_CDW13_UNUSE,
526 	NVME_ERR_FEAT_CDW15_UNUSE,
527 	/*
528 	 * Indicates that a set features request can't be executed because
529 	 * required fields have not been set.
530 	 */
531 	NVME_ERR_SET_FEAT_REQ_MISSING_FIELDS,
532 	/*
533 	 * Indicates that the vendor-specific library operation could not
534 	 * proceed because the underlying feature is not supported by the given
535 	 * device.
536 	 */
537 	NVME_ERR_VU_FEAT_UNSUP_BY_DEV,
538 	/*
539 	 * OCP Error Injection specific errors.
540 	 */
541 	NVME_ERR_OCP_ERRINJ_TYPE_RANGE,
542 	NVME_ERR_OCP_ERRINJ_NRTDE_RANGE,
543 	NVME_ERR_OCP_ERRINJ_LD_RANGE,
544 	NVME_ERR_OCP_ERRINJ_LD_UNSUP,
545 	NVME_ERR_OCP_ERRINJ_LD_UNUSE,
546 	NVME_ERR_OCP_ERRINJ_REQ_MISSING_FIELDS
547 } nvme_err_t;
548 
549 /*
550  * Errors used for the various information errors. This is shared between both
551  * controller and namespace information structures.
552  */
553 typedef enum {
554 	NVME_INFO_ERR_OK,
555 	/*
556 	 * Indicates that the item is not supported because this is the wrong
557 	 * controller transport. For example, asking about a PCI ID for
558 	 * something that is not PCI-based.
559 	 */
560 	NVME_INFO_ERR_TRANSPORT,
561 	/*
562 	 * Indicates that the item is not supported because the device version
563 	 * is too old to get this.
564 	 */
565 	NVME_INFO_ERR_VERSION,
566 	/*
567 	 * Indicates that we could not get certain information because the
568 	 * device does not support a given capability.
569 	 */
570 	NVME_INFO_ERR_MISSING_CAP,
571 	/*
572 	 * Indicates that the specified format value is unknown.
573 	 */
574 	NVME_INFO_ERR_BAD_LBA_FMT,
575 	/*
576 	 * These errors only occur during attempts to persist information and
577 	 * indicate challenges allocating memory or otherwise challenges with
578 	 * libnvpair.
579 	 */
580 	NVME_INFO_ERR_PERSIST_NVL,
581 	/*
582 	 * The first indicates that the index is invalid or if it is technically
583 	 * within the valid LBA format range, but there is no data size. The
584 	 * second indicates that we can't actually fully represent the data
585 	 * here. This happens because say the LBA size can't be represented by a
586 	 * uint64_t.
587 	 */
588 	NVME_INFO_ERR_BAD_FMT,
589 	NVME_INFO_ERR_BAD_FMT_DATA,
590 	/*
591 	 * Indicates that the information cannot be returned because the
592 	 * namespace's state does not allow us to answer this question. This may
593 	 * be because it's inactive as below or because blkdev is not attached.
594 	 */
595 	NVME_INFO_ERR_NS_INACTIVE,
596 	NVME_INFO_ERR_NS_NO_BLKDEV
597 } nvme_info_err_t;
598 
599 typedef struct nvme nvme_t;
600 typedef struct nvme_ctrl nvme_ctrl_t;
601 typedef struct nvme_ctrl_iter nvme_ctrl_iter_t;
602 typedef struct nvme_ctrl_disc nvme_ctrl_disc_t;
603 typedef struct nvme_ctrl_info nvme_ctrl_info_t;
604 typedef struct nvme_ns nvme_ns_t;
605 typedef struct nvme_ns_iter nvme_ns_iter_t;
606 typedef struct nvme_ns_disc nvme_ns_disc_t;
607 typedef struct nvme_ns_info nvme_ns_info_t;
608 typedef struct nvme_nvm_lba_fmt nvme_nvm_lba_fmt_t;
609 typedef struct nvme_log_iter nvme_log_iter_t;
610 typedef struct nvme_log_disc nvme_log_disc_t;
611 typedef struct nvme_log_req nvme_log_req_t;
612 typedef struct nvme_id_req nvme_id_req_t;
613 typedef struct nvme_vuc_iter nvme_vuc_iter_t;
614 typedef struct nvme_vuc_disc nvme_vuc_disc_t;
615 typedef struct nvme_vuc_req nvme_vuc_req_t;
616 typedef struct nvme_fw_commit_req nvme_fw_commit_req_t;
617 typedef struct nvme_format_req nvme_format_req_t;
618 typedef struct nvme_feat_disc nvme_feat_disc_t;
619 typedef struct nvme_feat_iter nvme_feat_iter_t;
620 typedef struct nvme_get_feat_req nvme_get_feat_req_t;
621 typedef struct nvme_set_feat_req nvme_set_feat_req_t;
622 typedef struct nvme_ns_attach_req nvme_ns_attach_req_t;
623 typedef struct nvme_ns_create_req nvme_ns_create_req_t;
624 typedef struct nvme_ns_delete_req nvme_ns_delete_req_t;
625 
626 /*
627  * Vendor-specific forwards.
628  */
629 typedef struct nvme_wdc_e6_req nvme_wdc_e6_req_t;
630 typedef struct nvme_ocp_errinj_req nvme_ocp_errinj_req_t;
631 
632 extern nvme_t *nvme_init(void);
633 extern void nvme_fini(nvme_t *);
634 
635 /*
636  * Error information. Operations that take an nvme_t, always set error
637  * information on the nvme_t. Operations that operate on a controller or are
638  * related to a request object or iterator that starts from the controller
639  * set error information on the nvme_ctrl_t.
640  */
641 extern nvme_err_t nvme_err(nvme_t *);
642 extern int32_t nvme_syserr(nvme_t *);
643 extern const char *nvme_errmsg(nvme_t *);
644 extern size_t nvme_errlen(nvme_t *);
645 extern const char *nvme_errtostr(nvme_t *, nvme_err_t);
646 
647 extern nvme_err_t nvme_ctrl_err(nvme_ctrl_t *);
648 extern int32_t nvme_ctrl_syserr(nvme_ctrl_t *);
649 extern const char *nvme_ctrl_errmsg(nvme_ctrl_t *);
650 extern size_t nvme_ctrl_errlen(nvme_ctrl_t *);
651 extern void nvme_ctrl_deverr(nvme_ctrl_t *, uint32_t *, uint32_t *);
652 extern const char *nvme_ctrl_errtostr(nvme_ctrl_t *, nvme_err_t);
653 
654 /*
655  * Translations for NVMe spec error constants. These end up taking the
656  * nvme_ctrl_t so that way they can potentially translate vendor-specific errors
657  * if they are defined. A NULL controller is allowed, which will skip all such
658  * processing altogether. Both functions will always a return a string so there
659  * is no need to check for NULL (though it may just be a variant of "unknown
660  * ...").
661  *
662  * If NULL is passed for the controller in nvme_sctostr(), we will assume that
663  * the controller's type is a traditional PCI I/O controller and not a fabric
664  * based controller, which further changes the way that command-specific status
665  * codes are interpreted. Due to the lack of support in the system for
666  * different controller types, this function will always assume a PCI I/O
667  * controller currently.
668  */
669 extern const char *nvme_scttostr(nvme_ctrl_t *, uint32_t);
670 extern const char *nvme_sctostr(nvme_ctrl_t *, nvme_csi_t, uint32_t, uint32_t);
671 
672 typedef enum nvme_iter {
673 	NVME_ITER_VALID,
674 	NVME_ITER_DONE,
675 	NVME_ITER_ERROR
676 } nvme_iter_t;
677 
678 /*
679  * NVMe Controller discovery.
680  */
681 extern di_node_t nvme_ctrl_disc_devi(const nvme_ctrl_disc_t *);
682 extern di_minor_t nvme_ctrl_disc_minor(const nvme_ctrl_disc_t *);
683 
684 extern bool nvme_ctrl_discover_init(nvme_t *, nvme_ctrl_iter_t **);
685 extern nvme_iter_t nvme_ctrl_discover_step(nvme_ctrl_iter_t *,
686     const nvme_ctrl_disc_t **);
687 extern void nvme_ctrl_discover_fini(nvme_ctrl_iter_t *);
688 
689 typedef bool (*nvme_ctrl_disc_f)(nvme_t *, const nvme_ctrl_disc_t *, void *);
690 extern bool nvme_ctrl_discover(nvme_t *, nvme_ctrl_disc_f, void *);
691 
692 extern bool nvme_ctrl_init(nvme_t *, di_node_t, nvme_ctrl_t **);
693 extern bool nvme_ctrl_init_by_instance(nvme_t *, int32_t, nvme_ctrl_t **);
694 extern bool nvme_ctrl_devi(nvme_ctrl_t *, di_node_t *);
695 extern void nvme_ctrl_fini(nvme_ctrl_t *);
696 
697 /*
698  * Get information about a controller. This information about a controller is
699  * separate from the lifetime of the controller itself. This is done to
700  * facilitate the ability of saving and using this information on another
701  * system and make the management a bit easier. Errors appear on this object and
702  * not the nmve_t.
703  */
704 extern bool nvme_ctrl_info_snap(nvme_ctrl_t *, nvme_ctrl_info_t **);
705 extern bool nvme_ctrl_info_restore(nvme_t *, nvlist_t *, nvme_ctrl_info_t **);
706 extern bool nvme_ctrl_info_persist(nvme_ctrl_info_t *, nvlist_t **);
707 extern void nvme_ctrl_info_free(nvme_ctrl_info_t *);
708 
709 extern nvme_info_err_t nvme_ctrl_info_err(nvme_ctrl_info_t *);
710 extern int32_t nvme_ctrl_info_syserr(nvme_ctrl_info_t *);
711 extern const char *nvme_ctrl_info_errmsg(nvme_ctrl_info_t *);
712 extern size_t nvme_ctrl_info_errlen(nvme_ctrl_info_t *);
713 extern const char *nvme_ctrl_info_errtostr(nvme_ctrl_info_t *, nvme_info_err_t);
714 
715 /*
716  * Information about an NVMe controller. This information is a combination of
717  * the identify data structure which can be retrieved directly by folks who
718  * would prefer to use it. Common fields that are used in something like nvmeadm
719  * or other utilities who would rather not need to know about the specifics of
720  * the data structure or have to think about the version can use that instead.
721  *
722  * NVMe 2.x has kept the identify controller data structure backwards
723  * compatible. If a future version were to invalidate that, then this could
724  * possibly return NULL.
725  */
726 extern uint16_t nvme_ctrl_info_vendor(nvme_ctrl_info_t *);
727 extern const nvme_identify_ctrl_t *nvme_ctrl_info_identify(nvme_ctrl_info_t *);
728 extern const nvme_version_t *nvme_ctrl_info_version(nvme_ctrl_info_t *);
729 extern const char *nvme_ctrl_info_model(nvme_ctrl_info_t *);
730 extern const char *nvme_ctrl_info_serial(nvme_ctrl_info_t *);
731 extern uint32_t nvme_ctrl_info_fwgran(nvme_ctrl_info_t *);
732 extern const char *nvme_ctrl_info_fwrev(nvme_ctrl_info_t *);
733 extern uint32_t nvme_ctrl_info_nns(nvme_ctrl_info_t *);
734 
735 typedef enum {
736 	NVME_CTRL_TRANSPORT_PCI,
737 	NVME_CTRL_TRANSPORT_TCP,
738 	NVME_CTRL_TRANSPORT_RDMA,
739 } nvme_ctrl_transport_t;
740 
741 typedef enum {
742 	NVME_CTRL_TYPE_UNKNOWN,
743 	NVME_CTRL_TYPE_IO,
744 	NVME_CTRL_TYPE_ADMIN,
745 	NVME_CTRL_TYPE_DISCOVERY,
746 } nvme_ctrl_type_t;
747 
748 /*
749  * Controller types were explicitly added in the NVMe 1.4 specification. Prior
750  * to that all controllers were required to support issuing I/O, hence we return
751  * them as NVME_CTRL_TYPE_IO, even though this isn't quite by the spec. In 1.4
752  * this was added to the identify controller information. The 'UNKNOWN' type is
753  * for cases where we don't recognize the value based upon the standard.
754  */
755 extern nvme_ctrl_type_t nvme_ctrl_info_type(nvme_ctrl_info_t *);
756 extern nvme_ctrl_transport_t nvme_ctrl_info_transport(nvme_ctrl_info_t *);
757 
758 /*
759  * The following pieces of information are specific to PCI NVMe controllers and
760  * are not from the common identify controller data structure. As such they are
761  * fallible. The first group come from configuration space while the others are
762  * information that comes from the actual controller capability registers.
763  */
764 extern bool nvme_ctrl_info_pci_vid(nvme_ctrl_info_t *, uint16_t *);
765 extern bool nvme_ctrl_info_pci_did(nvme_ctrl_info_t *, uint16_t *);
766 extern bool nvme_ctrl_info_pci_rev(nvme_ctrl_info_t *, uint8_t *);
767 extern bool nvme_ctrl_info_pci_subvid(nvme_ctrl_info_t *, uint16_t *);
768 extern bool nvme_ctrl_info_pci_subsys(nvme_ctrl_info_t *, uint16_t *);
769 
770 extern bool nvme_ctrl_info_pci_mps_min(nvme_ctrl_info_t *, uint32_t *);
771 extern bool nvme_ctrl_info_pci_mps_max(nvme_ctrl_info_t *, uint32_t *);
772 
773 extern bool nvme_ctrl_info_pci_nintrs(nvme_ctrl_info_t *, uint32_t *);
774 
775 /*
776  * These three items are only present if the device supports Namespace
777  * Management.
778  */
779 extern bool nvme_ctrl_info_cap(nvme_ctrl_info_t *, nvme_uint128_t *);
780 extern bool nvme_ctrl_info_unalloc_cap(nvme_ctrl_info_t *, nvme_uint128_t *);
781 extern bool nvme_ctrl_info_common_ns(nvme_ctrl_info_t *,
782     const nvme_identify_nsid_t **);
783 
784 /*
785  * The following information is specific to the NVM command set for controllers.
786  */
787 extern uint32_t nvme_ctrl_info_nformats(nvme_ctrl_info_t *);
788 extern bool nvme_ctrl_info_format(nvme_ctrl_info_t *, uint32_t,
789     const nvme_nvm_lba_fmt_t **);
790 extern uint32_t nvme_nvm_lba_fmt_id(const nvme_nvm_lba_fmt_t *);
791 extern uint32_t nvme_nvm_lba_fmt_meta_size(const nvme_nvm_lba_fmt_t *);
792 extern uint64_t nvme_nvm_lba_fmt_data_size(const nvme_nvm_lba_fmt_t *);
793 extern uint32_t nvme_nvm_lba_fmt_rel_perf(const nvme_nvm_lba_fmt_t *);
794 
795 /*
796  * Identify Operations
797  *
798  * The basic controller and namespace identify operations are a part of the
799  * controller and namespace snapshot facilities. These functions are designed to
800  * help enumerate and iterate lists of active and inactive namespaces,
801  * controllers, and related. The initial interface is a basic form that allows
802  * folks to create a request based on one that the library knows about as the
803  * kernel doesn't allow unknown requests.
804  *
805  * Eventually, when the kernel allows for arbitrary identify commands to be
806  * issued we can add an nvme_id_req_init() and the ability to set the CSI and
807  * CNS.
808  */
809 extern bool nvme_id_req_init_by_cns(nvme_ctrl_t *, nvme_csi_t, uint32_t,
810     nvme_id_req_t **);
811 extern void nvme_id_req_fini(nvme_id_req_t *);
812 
813 extern bool nvme_id_req_set_nsid(nvme_id_req_t *, uint32_t);
814 extern bool nvme_id_req_set_ctrlid(nvme_id_req_t *, uint32_t);
815 extern bool nvme_id_req_set_output(nvme_id_req_t *, void *, size_t);
816 extern bool nvme_id_req_clear_output(nvme_id_req_t *);
817 extern bool nvme_id_req_exec(nvme_id_req_t *);
818 
819 /*
820  * NVMe Namespace Discovery
821  *
822  * Namespaces come in various states. While the controller has a list of
823  * namespace IDs. The following enumeration describes namespace information with
824  * increasing specificity.
825  */
826 typedef enum {
827 	/*
828 	 * This returns all namespaces that are present on the device. This
829 	 * includes ones that may be ignored by the kernel or more.
830 	 */
831 	NVME_NS_DISC_F_ALL = 0,
832 	/*
833 	 * Only return namespaces that the controller considers to be allocated.
834 	 */
835 	NVME_NS_DISC_F_ALLOCATED,
836 	/*
837 	 * Only return namespaces that are active. If the controller does not
838 	 * support namespace management then all namespaces are considered
839 	 * active.
840 	 */
841 	NVME_NS_DISC_F_ACTIVE,
842 	/*
843 	 * The kernel has a notion of a namespace is ignored or not. In general,
844 	 * this is a subset of active namespaces that can actually be supported.
845 	 * They may or may not have a blkdev instance attached.
846 	 */
847 	NVME_NS_DISC_F_NOT_IGNORED,
848 	/*
849 	 * Only return namespaces that have blkdev actively attached. In other
850 	 * words these are disks that the OS can use.
851 	 */
852 	NVME_NS_DISC_F_BLKDEV
853 } nvme_ns_disc_level_t;
854 
855 typedef enum nvme_ns_disc_flags {
856 	NVME_NS_DISC_F_EUI64_VALID	= 1 << 0,
857 	NVME_NS_DISC_F_NGUID_VALID	= 1 << 1
858 } nvme_ns_disc_flags_t;
859 
860 extern uint32_t nvme_ns_disc_nsid(const nvme_ns_disc_t *);
861 extern nvme_ns_disc_level_t nvme_ns_disc_level(const nvme_ns_disc_t *);
862 extern nvme_ns_disc_flags_t nvme_ns_disc_flags(const nvme_ns_disc_t *);
863 extern const uint8_t *nvme_ns_disc_eui64(const nvme_ns_disc_t *);
864 extern const uint8_t *nvme_ns_disc_nguid(const nvme_ns_disc_t *);
865 
866 extern bool nvme_ns_discover_init(nvme_ctrl_t *, nvme_ns_disc_level_t,
867     nvme_ns_iter_t **);
868 extern nvme_iter_t nvme_ns_discover_step(nvme_ns_iter_t *,
869     const nvme_ns_disc_t **);
870 extern void nvme_ns_discover_fini(nvme_ns_iter_t *);
871 
872 typedef bool (*nvme_ns_disc_f)(nvme_ctrl_t *, const nvme_ns_disc_t *, void *);
873 extern bool nvme_ns_discover(nvme_ctrl_t *, nvme_ns_disc_level_t,
874     nvme_ns_disc_f, void *);
875 
876 extern bool nvme_ns_init(nvme_ctrl_t *, uint32_t, nvme_ns_t **);
877 extern bool nvme_ns_init_by_name(nvme_ctrl_t *, const char *, nvme_ns_t **);
878 extern void nvme_ns_fini(nvme_ns_t *);
879 
880 /*
881  * This is a convenience routine for opening up an NVMe controller and/or
882  * namespace. Many utilities refer to things as <controller>/<namespace>. As
883  * such, this will parse that apart. If no namespace is specified, it will be
884  * left as NULL. If the specified controller or namespace cannot be found, then
885  * the function will fail.
886  *
887  * Currently the only supported controller name is nvmeX, though we should
888  * support GUIDs at some point. The namespace id, EUI64, and NGUID are all
889  * supported for the namespace.
890  */
891 extern bool nvme_ctrl_ns_init(nvme_t *, const char *, nvme_ctrl_t **,
892     nvme_ns_t **);
893 
894 /*
895  * NVMe Namespace Information.
896  *
897  * Namespace information is broken into a few groups. There is basic information
898  * about the LBA formats and capacities (which are provided in block sizes).
899  * There is information about the IDs. Note the NGUID/EUI64 are fallible
900  * because they are optional.
901  */
902 extern bool nvme_ns_info_snap(nvme_ns_t *, nvme_ns_info_t **);
903 extern bool nvme_ctrl_ns_info_snap(nvme_ctrl_t *, uint32_t, nvme_ns_info_t **);
904 extern void nvme_ns_info_free(nvme_ns_info_t *);
905 
906 extern nvme_info_err_t nvme_ns_info_err(nvme_ns_info_t *);
907 extern int32_t nvme_ns_info_syserr(nvme_ns_info_t *);
908 extern const char *nvme_ns_info_errmsg(nvme_ns_info_t *);
909 extern size_t nvme_ns_info_errlen(nvme_ns_info_t *);
910 extern const char *nvme_ns_info_errtostr(nvme_ns_info_t *, nvme_info_err_t);
911 
912 extern uint32_t nvme_ns_info_nsid(nvme_ns_info_t *);
913 extern nvme_ns_disc_level_t nvme_ns_info_level(nvme_ns_info_t *);
914 extern const nvme_identify_nsid_t *nvme_ns_info_identify(nvme_ns_info_t *);
915 
916 extern bool nvme_ns_info_nguid(nvme_ns_info_t *, uint8_t [16]);
917 extern bool nvme_ns_info_eui64(nvme_ns_info_t *, uint8_t [8]);
918 
919 extern bool nvme_ns_info_size(nvme_ns_info_t *, uint64_t *);
920 extern bool nvme_ns_info_cap(nvme_ns_info_t *, uint64_t *);
921 extern bool nvme_ns_info_use(nvme_ns_info_t *, uint64_t *);
922 
923 extern bool nvme_ns_info_curformat(nvme_ns_info_t *,
924     const nvme_nvm_lba_fmt_t **);
925 extern bool nvme_ns_info_nformats(nvme_ns_info_t *, uint32_t *);
926 extern bool nvme_ns_info_format(nvme_ns_info_t *, uint32_t,
927     const nvme_nvm_lba_fmt_t **);
928 
929 extern bool nvme_ns_info_bd_addr(nvme_ns_info_t *, const char **);
930 
931 /*
932  * Controller and Namespace Locking
933  *
934  * A given controller can be active by several different parallel consumers.
935  */
936 extern bool nvme_ctrl_lock(nvme_ctrl_t *, nvme_lock_level_t, nvme_lock_flags_t);
937 extern void nvme_ctrl_unlock(nvme_ctrl_t *);
938 extern bool nvme_ns_lock(nvme_ns_t *, nvme_lock_level_t, nvme_lock_flags_t);
939 extern void nvme_ns_unlock(nvme_ns_t *);
940 
941 /*
942  * Namespace Attach and Detach
943  *
944  * These operations are used to attach and detach a blkdev device from a given
945  * namespace.
946  */
947 extern bool nvme_ns_bd_attach(nvme_ns_t *);
948 extern bool nvme_ns_bd_detach(nvme_ns_t *);
949 
950 /*
951  * NVMe Log Page Discovery
952  *
953  * NVMe Log Pages provide some complications around discovery. There are
954  * standard log pages, which are either mandatory or optional. There are also
955  * vendor-specific log pages that we may know about. While NVMe 2.0 introduced a
956  * way to list all of the supported log pages a device implements, that is not
957  * true for most devices. Pre 2.x devices sometimes have a vendor-specific way
958  * to list all the available logs. The NVMe 2.0 based mechanism also does not
959  * provide a means of getting additional information such as required fields, so
960  * we'll end up always needing the additional information this interface
961  * provides.
962  *
963  * The log page discovery functions here allow a caller to just ask for all the
964  * known IDs that exist for something. The discovery callback will fire once for
965  * each log page that may be implemented. Log pages we know that aren't
966  * implemented are never called back for.
967  */
968 extern const char *nvme_log_disc_name(const nvme_log_disc_t *);
969 extern const char *nvme_log_disc_desc(const nvme_log_disc_t *);
970 extern const char *const *nvme_log_disc_aliases(const nvme_log_disc_t *);
971 extern size_t nvme_log_disc_naliases(const nvme_log_disc_t *);
972 extern nvme_csi_t nvme_log_disc_csi(const nvme_log_disc_t *);
973 extern uint32_t nvme_log_disc_lid(const nvme_log_disc_t *);
974 extern nvme_log_disc_kind_t nvme_log_disc_kind(const nvme_log_disc_t *);
975 extern nvme_log_disc_source_t nvme_log_disc_sources(const nvme_log_disc_t *);
976 extern nvme_log_disc_fields_t nvme_log_disc_fields(const nvme_log_disc_t *);
977 extern nvme_log_disc_scope_t nvme_log_disc_scopes(const nvme_log_disc_t *);
978 extern bool nvme_log_disc_impl(const nvme_log_disc_t *);
979 
980 typedef enum {
981 	/*
982 	 * This indicates that the size of a log page is unknown. Instead, we
983 	 * will return a size that is reasonable enough to hopefully cover most
984 	 * things.
985 	 */
986 	NVME_LOG_SIZE_K_UNKNOWN	= 0,
987 	/*
988 	 * This indicates that there is a known fixed size for the log page and
989 	 * we have indicated what that is.
990 	 */
991 	NVME_LOG_SIZE_K_FIXED,
992 	/*
993 	 * This indicates that the total log size is variable; however, it can
994 	 * be determined by reading the specified following number of bytes.
995 	 * Once that number of bytes has been read, that can be passed to the
996 	 * nvme_log_disc_cal_size() function, which will attempt to determine
997 	 * the actual number of bytes based on the returned data.
998 	 */
999 	NVME_LOG_SIZE_K_VAR
1000 } nvme_log_size_kind_t;
1001 extern nvme_log_size_kind_t nvme_log_disc_size(const nvme_log_disc_t *,
1002     uint64_t *);
1003 extern bool nvme_log_disc_calc_size(const nvme_log_disc_t *, uint64_t *,
1004     const void *, size_t);
1005 
1006 /*
1007  * Duplicate and free log discovery information. The free function should only
1008  * be used when it is explicitly duplicated or obtained through something like
1009  * nvme_log_req_init_by_name(). It must not be used on the constant data
1010  * provided as part of the nvme_log_discover family of functions.
1011  */
1012 extern bool nvme_log_disc_dup(nvme_ctrl_t *, const nvme_log_disc_t *,
1013     nvme_log_disc_t **);
1014 extern void nvme_log_disc_free(nvme_log_disc_t *);
1015 
1016 extern bool nvme_log_discover_init(nvme_ctrl_t *, nvme_log_disc_scope_t,
1017     uint32_t, nvme_log_iter_t **);
1018 extern nvme_iter_t nvme_log_discover_step(nvme_log_iter_t *,
1019     const nvme_log_disc_t **);
1020 extern void nvme_log_discover_fini(nvme_log_iter_t *);
1021 
1022 typedef bool (*nvme_log_disc_f)(nvme_ctrl_t *, const nvme_log_disc_t *,
1023     void *);
1024 extern bool nvme_log_discover(nvme_ctrl_t *, nvme_log_disc_scope_t,
1025     uint32_t, nvme_log_disc_f, void *);
1026 
1027 /*
1028  * One does not simply request a log page. There are a lot of parameters that
1029  * are used to get a log page and these have been evolving over time. For
1030  * example, the size has changed between 1.2 and 1.3, NVMe 1.0 never had UUIDs,
1031  * LSP, LSIs, there are optional features around supporting offsets, etc.
1032  *
1033  * To deal with the fact that this keeps changing and an attempt to create a
1034  * stable ABI, we instead have an opaque structure that allows various fields to
1035  * be set and changed. To speed this up, this can be bootstrapped from the
1036  * discovery information directly or indirectly by the log page short name.
1037  *
1038  * Once all of the appropriate fields are set on a log page request then it can
1039  * be executed. A given request may be executed multiple times.
1040  *
1041  * When creating a raw log request, it will be up to the caller to fill in and
1042  * set up the log ID (lid) and the output information. It is assumed that by
1043  * default a log request should specify the NVM CSI. When using
1044  * nvme_log_req_init_by_disc(), the log ID and command set will be filled in
1045  * automatically. The discovery flags will indicate what other fields are still
1046  * required.
1047  */
1048 extern bool nvme_log_req_init(nvme_ctrl_t *, nvme_log_req_t **);
1049 extern bool nvme_log_req_init_by_disc(nvme_ctrl_t *, const nvme_log_disc_t *,
1050     nvme_log_req_t **);
1051 extern bool nvme_log_req_init_by_name(nvme_ctrl_t *, const char *,
1052     uint32_t, nvme_log_disc_t **, nvme_log_req_t **);
1053 extern void nvme_log_req_fini(nvme_log_req_t *);
1054 
1055 extern bool nvme_log_req_set_lid(nvme_log_req_t *, uint32_t);
1056 extern bool nvme_log_req_set_lsp(nvme_log_req_t *, uint32_t);
1057 extern bool nvme_log_req_set_lsi(nvme_log_req_t *, uint32_t);
1058 extern bool nvme_log_req_set_uuid(nvme_log_req_t *, uint32_t);
1059 extern bool nvme_log_req_set_nsid(nvme_log_req_t *, uint32_t);
1060 extern bool nvme_log_req_set_output(nvme_log_req_t *, void *, size_t);
1061 extern bool nvme_log_req_clear_output(nvme_log_req_t *);
1062 extern bool nvme_log_req_set_offset(nvme_log_req_t *, uint64_t);
1063 extern bool nvme_log_req_set_rae(nvme_log_req_t *, bool);
1064 extern bool nvme_log_req_set_csi(nvme_log_req_t *, nvme_csi_t);
1065 extern bool nvme_log_req_exec(nvme_log_req_t *);
1066 
1067 /*
1068  * Feature Discovery and Management
1069  *
1070  * Features are parts of the NVMe specification that can both be retrieved and
1071  * set. Features are often either a uint32_t or a larger data payload. In
1072  * addition, there are additional modifiers that are required to select
1073  * information about features. For example, when getting or setting a
1074  * temperature threshold feature, a temperature sensor ID is required. Much like
1075  * with log pages this has changed and added new arguments to getting and
1076  * setting a feature at the command level and the individual features have grown
1077  * support for more configuration as well.
1078  *
1079  * We currently provide information in discovery to determine what is required
1080  * to get a feature as well as the ability to fast path that. Currently we
1081  * provide the raw feature getting API that works at the low level. There is no
1082  * higher level API for specific features. This works okay for an nvmeadm(8)
1083  * style implementation, but we should consider adding more here based on
1084  * feedback from consumers.
1085  */
1086 extern const char *nvme_feat_disc_short(const nvme_feat_disc_t *);
1087 extern const char *nvme_feat_disc_spec(const nvme_feat_disc_t *);
1088 extern uint32_t nvme_feat_disc_fid(const nvme_feat_disc_t *);
1089 extern nvme_feat_scope_t nvme_feat_disc_scope(const nvme_feat_disc_t *);
1090 extern nvme_feat_kind_t nvme_feat_disc_kind(const nvme_feat_disc_t *);
1091 extern nvme_feat_csi_t nvme_feat_disc_csi(const nvme_feat_disc_t *);
1092 extern nvme_feat_flags_t nvme_feat_disc_flags(const nvme_feat_disc_t *);
1093 extern nvme_get_feat_fields_t nvme_feat_disc_fields_get(
1094     const nvme_feat_disc_t *);
1095 extern nvme_set_feat_fields_t nvme_feat_disc_fields_set(
1096     const nvme_feat_disc_t *);
1097 extern nvme_feat_output_t nvme_feat_disc_output_get(const nvme_feat_disc_t *);
1098 extern nvme_feat_output_t nvme_feat_disc_output_set(const nvme_feat_disc_t *);
1099 extern uint64_t nvme_feat_disc_data_size(const nvme_feat_disc_t *);
1100 extern nvme_feat_impl_t nvme_feat_disc_impl(const nvme_feat_disc_t *);
1101 extern nvme_disc_impact_t nvme_feat_disc_impact_set(const nvme_feat_disc_t *);
1102 
1103 extern bool nvme_feat_discover_init(nvme_ctrl_t *, nvme_feat_scope_t, uint32_t,
1104     nvme_feat_iter_t **);
1105 extern nvme_iter_t nvme_feat_discover_step(nvme_feat_iter_t *,
1106     const nvme_feat_disc_t **);
1107 extern void nvme_feat_discover_fini(nvme_feat_iter_t *);
1108 
1109 extern bool nvme_feat_disc_dup(nvme_ctrl_t *, const nvme_feat_disc_t *,
1110     nvme_feat_disc_t **);
1111 extern void nvme_feat_disc_free(nvme_feat_disc_t *);
1112 
1113 typedef bool (*nvme_feat_disc_f)(nvme_ctrl_t *, const nvme_feat_disc_t *,
1114     void *);
1115 extern bool nvme_feat_discover(nvme_ctrl_t *, nvme_feat_scope_t, uint32_t,
1116     nvme_feat_disc_f, void *);
1117 
1118 /*
1119  * Get Feature Request
1120  *
1121  * The get feature request allows one to build up a get feature command. It is
1122  * recommended to initiate a request based on discovery information or a
1123  * feature's name. That will allow the system to perform better validation, know
1124  * what fields are required or not, and pre-set parameters like the feature id
1125  * (fid). By default, a get features request will always ask for the current
1126  * value. Unless you want a saved or default value (and the controller is new
1127  * enough), then there is no need to set the selector. The only required field
1128  * when not using discovery information is the fid.
1129  */
1130 extern bool nvme_get_feat_req_init(nvme_ctrl_t *, nvme_get_feat_req_t **);
1131 extern bool nvme_get_feat_req_init_by_disc(nvme_ctrl_t *,
1132     const nvme_feat_disc_t *, nvme_get_feat_req_t **);
1133 extern bool nvme_get_feat_req_init_by_name(nvme_ctrl_t *, const char *,
1134     uint32_t, nvme_feat_disc_t **, nvme_get_feat_req_t **);
1135 extern void nvme_get_feat_req_fini(nvme_get_feat_req_t *);
1136 
1137 extern bool nvme_get_feat_req_set_fid(nvme_get_feat_req_t *, uint32_t);
1138 extern bool nvme_get_feat_req_set_sel(nvme_get_feat_req_t *, uint32_t);
1139 extern bool nvme_get_feat_req_set_nsid(nvme_get_feat_req_t *, uint32_t);
1140 extern bool nvme_get_feat_req_set_cdw11(nvme_get_feat_req_t *, uint32_t);
1141 extern bool nvme_get_feat_req_set_output(nvme_get_feat_req_t *, void *, size_t);
1142 extern bool nvme_get_feat_req_clear_output(nvme_get_feat_req_t *);
1143 extern bool nvme_get_feat_req_exec(nvme_get_feat_req_t *);
1144 extern bool nvme_get_feat_req_get_cdw0(nvme_get_feat_req_t *, uint32_t *);
1145 
1146 /*
1147  * Set Feature Request
1148  *
1149  * This allows one to set the value of a feature in a similar fashion to get
1150  * feature. Currently only vendor-specific features are supported by the kernel.
1151  * By default, a set feature will not save its value. The set of required fields
1152  * and the impact will be determined automatically if creating a request from a
1153  * discovery object. Otherwise, this must be specified.
1154  */
1155 extern bool nvme_set_feat_req_init(nvme_ctrl_t *, nvme_set_feat_req_t **);
1156 extern bool nvme_set_feat_req_init_by_disc(nvme_ctrl_t *,
1157     const nvme_feat_disc_t *, nvme_set_feat_req_t **);
1158 extern bool nvme_set_feat_req_init_by_name(nvme_ctrl_t *, const char *,
1159     uint32_t, nvme_feat_disc_t **, nvme_set_feat_req_t **);
1160 extern void nvme_set_feat_req_fini(nvme_set_feat_req_t *);
1161 
1162 extern bool nvme_set_feat_req_set_fid(nvme_set_feat_req_t *, uint32_t);
1163 extern bool nvme_set_feat_req_set_save(nvme_set_feat_req_t *, bool);
1164 extern bool nvme_set_feat_req_set_nsid(nvme_set_feat_req_t *, uint32_t);
1165 extern bool nvme_set_feat_req_set_cdw11(nvme_set_feat_req_t *, uint32_t);
1166 extern bool nvme_set_feat_req_set_cdw12(nvme_set_feat_req_t *, uint32_t);
1167 extern bool nvme_set_feat_req_set_cdw13(nvme_set_feat_req_t *, uint32_t);
1168 extern bool nvme_set_feat_req_set_cdw15(nvme_set_feat_req_t *, uint32_t);
1169 extern bool nvme_set_feat_req_set_input(nvme_set_feat_req_t *, const void *,
1170     size_t);
1171 extern bool nvme_set_feat_req_clear_input(nvme_set_feat_req_t *);
1172 extern bool nvme_set_feat_req_set_impact(nvme_set_feat_req_t *,
1173     nvme_disc_impact_t);
1174 extern bool nvme_set_feat_req_exec(nvme_set_feat_req_t *);
1175 extern bool nvme_set_feat_req_get_cdw0(nvme_set_feat_req_t *, uint32_t *);
1176 
1177 /*
1178  * NVMe Vendor Unique Command Discovery and Execution
1179  *
1180  * There is a standard form of vendor unique commands which are indicated in the
1181  * identify controller datasheet. The first set of pieces here allows one to
1182  * discover which vendor-specific commands are supported by a device that are
1183  * known to the library. These generally have their own implementation
1184  * function; however, that isn't really linked to from the discovery function.
1185  * Tied into this is also asking if a given controller supports a given command
1186  * and getting information about it.
1187  *
1188  * The second set of functions here is all around allocating a vendor unique
1189  * command then executing it. Currently only admin commands are supported
1190  * through this interface.
1191  */
1192 extern bool nvme_vuc_discover_init(nvme_ctrl_t *, uint32_t,
1193     nvme_vuc_iter_t **);
1194 extern nvme_iter_t nvme_vuc_discover_step(nvme_vuc_iter_t *,
1195     const nvme_vuc_disc_t **);
1196 extern void nvme_vuc_discover_fini(nvme_vuc_iter_t *);
1197 
1198 typedef bool (*nvme_vuc_disc_f)(nvme_ctrl_t *, const nvme_vuc_disc_t *, void *);
1199 extern bool nvme_vuc_discover(nvme_ctrl_t *, uint32_t, nvme_vuc_disc_f, void *);
1200 
1201 extern bool nvme_vuc_discover_by_name(nvme_ctrl_t *, const char *, uint32_t,
1202     nvme_vuc_disc_t **);
1203 extern bool nvme_vuc_disc_dup(nvme_ctrl_t *, const nvme_vuc_disc_t *,
1204     nvme_vuc_disc_t **);
1205 extern void nvme_vuc_disc_free(nvme_vuc_disc_t *);
1206 
1207 extern const char *nvme_vuc_disc_name(const nvme_vuc_disc_t *);
1208 extern const char *nvme_vuc_disc_desc(const nvme_vuc_disc_t *);
1209 extern uint32_t nvme_vuc_disc_opcode(const nvme_vuc_disc_t *);
1210 extern nvme_disc_impact_t nvme_vuc_disc_impact(const nvme_vuc_disc_t *);
1211 
1212 typedef enum {
1213 	NVME_VUC_DISC_IO_NONE	= 0,
1214 	/*
1215 	 * Indicates that this command needs additional data provided as input
1216 	 * to the command.
1217 	 */
1218 	NVME_VUC_DISC_IO_INPUT	= 1 << 0,
1219 	/*
1220 	 * Indicates that this command writes output back to the host from the
1221 	 * controller and a data buffer is required.
1222 	 */
1223 	NVME_VUC_DISC_IO_OUTPUT	= 1 << 1
1224 } nvme_vuc_disc_io_t;
1225 extern nvme_vuc_disc_io_t nvme_vuc_disc_dt(const nvme_vuc_disc_t *);
1226 
1227 typedef enum {
1228 	/*
1229 	 * Indicates that the library has no opinion on whether a lock should be
1230 	 * taken or not.
1231 	 */
1232 	NVME_VUC_DISC_LOCK_NONE	= 0,
1233 	/*
1234 	 * Indicates that a controller or namespace level read lock is
1235 	 * recommended for this operation.
1236 	 */
1237 	NVME_VUC_DISC_LOCK_READ,
1238 	/*
1239 	 * Indicates that a controller or namespace level write lock is
1240 	 * recommended for this operation.
1241 	 */
1242 	NVME_VUC_DISC_LOCK_WRITE
1243 } nvme_vuc_disc_lock_t;
1244 extern nvme_vuc_disc_lock_t nvme_vuc_disc_lock(const nvme_vuc_disc_t *);
1245 
1246 extern bool nvme_vuc_req_init(nvme_ctrl_t *, nvme_vuc_req_t **);
1247 extern void nvme_vuc_req_fini(nvme_vuc_req_t *);
1248 
1249 extern bool nvme_vuc_req_set_opcode(nvme_vuc_req_t *, uint32_t);
1250 extern bool nvme_vuc_req_set_nsid(nvme_vuc_req_t *, uint32_t);
1251 extern bool nvme_vuc_req_set_timeout(nvme_vuc_req_t *, uint32_t);
1252 extern bool nvme_vuc_req_set_cdw12(nvme_vuc_req_t *, uint32_t);
1253 extern bool nvme_vuc_req_set_cdw13(nvme_vuc_req_t *, uint32_t);
1254 extern bool nvme_vuc_req_set_cdw14(nvme_vuc_req_t *, uint32_t);
1255 extern bool nvme_vuc_req_set_cdw15(nvme_vuc_req_t *, uint32_t);
1256 extern bool nvme_vuc_req_set_impact(nvme_vuc_req_t *, nvme_disc_impact_t);
1257 extern bool nvme_vuc_req_set_input(nvme_vuc_req_t *, const void *, size_t);
1258 extern bool nvme_vuc_req_set_output(nvme_vuc_req_t *, void *, size_t);
1259 extern bool nvme_vuc_req_clear_output(nvme_vuc_req_t *);
1260 
1261 /*
1262  * Execute a request. After a request is executed, the status information
1263  * becomes available. A call to exec will invalidate any prior results. If the
1264  * request does not make it to the controller for some reason or some other
1265  * error occurs, then getting the results will fail. If the controller fails the
1266  * command, that will set the NVME_ERR_CONTROLLER error and the corresponding
1267  * SCT/SC values can be retrieved from the controller's error information for
1268  * inspection.
1269  */
1270 extern bool nvme_vuc_req_exec(nvme_vuc_req_t *);
1271 extern bool nvme_vuc_req_get_cdw0(nvme_vuc_req_t *, uint32_t *);
1272 
1273 /*
1274  * Firmware Download and Commit (Activation)
1275  *
1276  * NVMe devices have a buffer that is used to receive a firmware download. This
1277  * can then be committed into a firmware slot or a boot slot through the commit
1278  * action. The commit action may also change which firmware slot is activated on
1279  * the next boot at the same time as installing an image or a commit can be used
1280  * to just change the active image. The optional bootloader features will have a
1281  * similar shape as to the firmware commit routines, but ultimately be different
1282  * ones to make it more obvious what is being done.
1283  *
1284  * The firmware download command has to date not really changed through the NVMe
1285  * 1.x and 2.0 standards, which is why it is not broken into a request and
1286  * execution format like others at this time.
1287  *
1288  * Firmware must be loaded with a particular granularity and if blocks do not
1289  * conform to that, nvme_fw_load() will return an error.
1290  */
1291 extern bool nvme_fw_load(nvme_ctrl_t *, const void *, size_t, uint64_t);
1292 
1293 extern bool nvme_fw_commit_req_init(nvme_ctrl_t *, nvme_fw_commit_req_t **);
1294 extern void nvme_fw_commit_req_fini(nvme_fw_commit_req_t *);
1295 extern bool nvme_fw_commit_req_set_slot(nvme_fw_commit_req_t *, uint32_t);
1296 extern bool nvme_fw_commit_req_set_action(nvme_fw_commit_req_t *, uint32_t);
1297 extern bool nvme_fw_commit_req_exec(nvme_fw_commit_req_t *);
1298 
1299 /*
1300  * Format NVM
1301  *
1302  * This is used to erase and reformat either all namespaces or a specific one.
1303  * We currently do not support setting metadata or protection information for
1304  * namespaces in the kernel which is why this is not present in the library.
1305  */
1306 extern bool nvme_format_req_init(nvme_ctrl_t *, nvme_format_req_t **);
1307 extern void nvme_format_req_fini(nvme_format_req_t *);
1308 extern bool nvme_format_req_set_lbaf(nvme_format_req_t *, uint32_t);
1309 extern bool nvme_format_req_set_ses(nvme_format_req_t *, uint32_t);
1310 extern bool nvme_format_req_set_nsid(nvme_format_req_t *, uint32_t);
1311 extern bool nvme_format_req_exec(nvme_format_req_t *);
1312 
1313 /*
1314  * NVMe Namespace Attach
1315  *
1316  * This is used to attach or detach a collection of controllers to a namespace.
1317  * Currently the only way to specify a controller is to use the self flag on
1318  * here. In the future, we will likely have support for listing the explicit
1319  * controllers to specify here.
1320  */
1321 extern bool nvme_ns_attach_req_init_by_sel(nvme_ctrl_t *, uint32_t,
1322     nvme_ns_attach_req_t **);
1323 extern void nvme_ns_attach_req_fini(nvme_ns_attach_req_t *);
1324 extern bool nvme_ns_attach_req_set_nsid(nvme_ns_attach_req_t *, uint32_t);
1325 extern bool nvme_ns_attach_req_set_ctrlid_self(nvme_ns_attach_req_t *);
1326 extern bool nvme_ns_attach_req_exec(nvme_ns_attach_req_t *);
1327 
1328 /*
1329  * NVMe Namesapce Create and Delete
1330  */
1331 extern bool nvme_ns_create_req_init_by_csi(nvme_ctrl_t *, nvme_csi_t,
1332     nvme_ns_create_req_t **);
1333 extern void nvme_ns_create_req_fini(nvme_ns_create_req_t *);
1334 extern bool nvme_ns_create_req_set_flbas(nvme_ns_create_req_t *, uint32_t);
1335 extern bool nvme_ns_create_req_set_nsze(nvme_ns_create_req_t *, uint64_t);
1336 extern bool nvme_ns_create_req_set_ncap(nvme_ns_create_req_t *, uint64_t);
1337 extern bool nvme_ns_create_req_set_nmic(nvme_ns_create_req_t *, uint32_t);
1338 extern bool nvme_ns_create_req_exec(nvme_ns_create_req_t *);
1339 extern bool nvme_ns_create_req_get_nsid(nvme_ns_create_req_t *, uint32_t *);
1340 
1341 extern bool nvme_ns_delete_req_init(nvme_ctrl_t *, nvme_ns_delete_req_t **);
1342 extern void nvme_ns_delete_req_fini(nvme_ns_delete_req_t *);
1343 extern bool nvme_ns_delete_req_set_nsid(nvme_ns_delete_req_t *, uint32_t);
1344 extern bool nvme_ns_delete_req_exec(nvme_ns_delete_req_t *);
1345 
1346 /*
1347  * Vendor-specific interfaces.
1348  */
1349 
1350 /*
1351  * WDC resizing functions. These are interfaces supported in the SN840, SN650,
1352  * SN655, etc. These end up allowing one to adjust the overprovisioning ratio,
1353  * though this ends up reformatting the device and all namespaces in the
1354  * process. The values passed and returned are in GB (not GiB).
1355  */
1356 extern bool nvme_wdc_resize_set(nvme_ctrl_t *, uint32_t);
1357 extern bool nvme_wdc_resize_get(nvme_ctrl_t *, uint32_t *);
1358 
1359 /*
1360  * WDC e6 diagnostic log. The e6 log is a WDC-specific diagnostic log which
1361  * contains information about the device itself.
1362  */
1363 extern bool nvme_wdc_e6_req_init(nvme_ctrl_t *, nvme_wdc_e6_req_t **);
1364 extern void nvme_wdc_e6_req_fini(nvme_wdc_e6_req_t *);
1365 extern bool nvme_wdc_e6_req_set_offset(nvme_wdc_e6_req_t *, uint64_t);
1366 extern bool nvme_wdc_e6_req_set_output(nvme_wdc_e6_req_t *, void *,
1367     size_t);
1368 extern bool nvme_wdc_e6_req_clear_output(nvme_wdc_e6_req_t *);
1369 extern bool nvme_wdc_e6_req_exec(nvme_wdc_e6_req_t *);
1370 
1371 /*
1372  * WDC assert injection and removal.
1373  */
1374 extern bool nvme_wdc_assert_clear(nvme_ctrl_t *);
1375 extern bool nvme_wdc_assert_inject(nvme_ctrl_t *);
1376 
1377 /*
1378  * Sandisk commands to get PCI eye diagrams and the hardware revision.
1379  */
1380 extern bool nvme_sndk_pci_eye(nvme_ctrl_t *, uint8_t, void *, size_t);
1381 extern bool nvme_sndk_hw_rev(nvme_ctrl_t *, uint8_t *, uint8_t *);
1382 
1383 /*
1384  * OCP Error Injection.
1385  */
1386 extern bool nvme_ocp_errinj_req_init(nvme_ctrl_t *, nvme_ocp_errinj_req_t **);
1387 extern void nvme_ocp_errinj_req_fini(nvme_ocp_errinj_req_t *);
1388 extern bool nvme_ocp_errinj_req_set_type(nvme_ocp_errinj_req_t *, uint32_t);
1389 extern bool nvme_ocp_errinj_req_set_nrtde(nvme_ocp_errinj_req_t *, uint32_t);
1390 extern bool nvme_ocp_errinj_req_set_ld(nvme_ocp_errinj_req_t *, uint32_t);
1391 extern bool nvme_ocp_errinj_req_exec(nvme_ocp_errinj_req_t *);
1392 
1393 extern bool nvme_ocp_errinj_clear(nvme_ctrl_t *);
1394 
1395 #ifdef __cplusplus
1396 }
1397 #endif
1398 
1399 #endif /* _LIBNVME_H */
1400