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
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.
13 * Copyright 2024 Oxide Computer Company
17 * libnvme error manipulation and translation. This maintains the error objects
18 * that we have on handles and provides translations between the kernel's errors
19 * and those that we might generate ourselves. Information errors are instead
20 * contained in the corresponding files that own controller and namespace
21 * information libnvme_ctrl_info.c and libnvme_ns_info.c respectively.
26 #include <sys/debug.h>
27 #include <sys/sysmacros.h>
30 #include "libnvme_impl.h"
33 * The following sets of functions provide translations of error types. Note,
34 * the kernel headers need to be updated for newer NVMe specs at which point
35 * these should be updated.
38 nvme_scttostr(nvme_ctrl_t
*ctrl __unused
, uint32_t sc
)
41 case NVME_CQE_SCT_GENERIC
:
42 return ("generic command status");
43 case NVME_CQE_SCT_SPECIFIC
:
44 return ("command specific status");
45 case NVME_CQE_SCT_INTEGRITY
:
46 return ("media and data integrity errors");
47 case NVME_CQE_SCT_VENDOR
:
48 return ("vendor specific");
50 return ("unknown status type");
55 nvme_sctostr_gen_gen(uint32_t sct
)
58 case NVME_CQE_SC_GEN_SUCCESS
:
59 return ("successful completion");
60 case NVME_CQE_SC_GEN_INV_OPC
:
61 return ("invalid command opcode");
62 case NVME_CQE_SC_GEN_INV_FLD
:
63 return ("invalid field in command");
64 case NVME_CQE_SC_GEN_ID_CNFL
:
65 return ("command id conflict");
66 case NVME_CQE_SC_GEN_DATA_XFR_ERR
:
67 return ("data transfer error");
68 case NVME_CQE_SC_GEN_ABORT_PWRLOSS
:
69 return ("commands aborted due to power loss notification");
70 case NVME_CQE_SC_GEN_INTERNAL_ERR
:
71 return ("internal error");
72 case NVME_CQE_SC_GEN_ABORT_REQUEST
:
73 return ("command abort requested");
74 case NVME_CQE_SC_GEN_ABORT_SQ_DEL
:
75 return ("command aborted due to sq deletion");
76 case NVME_CQE_SC_GEN_ABORT_FUSE_FAIL
:
77 return ("command aborted due to failed fused command");
78 case NVME_CQE_SC_GEN_ABORT_FUSE_MISS
:
79 return ("command aborted due to missing fused command");
80 case NVME_CQE_SC_GEN_INV_NS
:
81 return ("invalid namespace or format");
82 case NVME_CQE_SC_GEN_CMD_SEQ_ERR
:
83 return ("command sequence error");
84 case NVME_CQE_SC_GEN_INV_SGL_LAST
:
85 return ("invalid sgl last segment descriptor");
86 case NVME_CQE_SC_GEN_INV_SGL_NUM
:
87 return ("invalid number of sgl descriptors");
88 case NVME_CQE_SC_GEN_INV_DSGL_LEN
:
89 return ("data sgl length invalid");
90 case NVME_CQE_SC_GEN_INV_MSGL_LEN
:
91 return ("metadata sgl length invalid");
92 case NVME_CQE_SC_GEN_INV_SGL_DESC
:
93 return ("sgl descriptor type invalid");
94 case NVME_CQE_SC_GEN_INV_USE_CMB
:
95 return ("invalid use of controller memory buffer");
96 case NVME_CQE_SC_GEN_INV_PRP_OFF
:
97 return ("prp offset invalid");
98 case NVME_CQE_SC_GEN_AWU_EXCEEDED
:
99 return ("atomic write unit exceeded");
100 case NVME_CQE_SC_GEN_OP_DENIED
:
101 return ("operation denied");
102 case NVME_CQE_SC_GEN_INV_SGL_OFF
:
103 return ("sgl offset invalid");
104 case NVME_CQE_SC_GEN_INV_SGL_ST
:
105 return ("sgl sub type invalid");
106 case NVME_CQE_SC_GEN_INCON_HOSTID
:
107 return ("host identifier inconsistent format");
108 case NVME_CQE_SC_GEN_KA_EXP
:
109 return ("keep alive timer expired");
110 case NVME_CQE_SC_GEN_INV_KA_TO
:
111 return ("keep alive timeout invalid");
112 case NVME_CQE_SC_GEN_ABORT_PREEMPT
:
113 return ("command aborted due to preempt and abort");
114 case NVME_CQE_SC_GEN_SANITIZE_FAIL
:
115 return ("sanitize failed");
116 case NVME_CQE_SC_GEN_SANITIZING
:
117 return ("sanitize in progress");
118 case NVME_CQE_SC_GEN_INV_SGL_GRAN
:
119 return ("sgl data block granularity invalid");
120 case NVME_CQE_SC_GEN_NO_CMD_Q_CMD
:
121 return ("command not supported for queue in cmb");
122 case NVME_CQE_SC_GEN_NS_RDONLY
:
123 return ("namespace is write protected");
124 case NVME_CQE_SC_GEN_CMD_INTR
:
125 return ("command interrupted");
126 case NVME_CQE_SC_GEN_TRANSIENT
:
127 return ("transient transport error");
128 case NVME_CQE_SC_GEN_CMD_LOCK
:
129 return ("command prohibited by command and feature lockdown");
130 case NVME_CQE_SC_ADM_MEDIA_NR
:
131 return ("admin command media not ready");
133 return ("unknown status code");
138 nvme_sctostr_gen_csi(nvme_csi_t csi
, uint32_t sct
)
141 * These errors are allowed for all command sets.
144 case NVME_CQE_SC_GEN_NVM_CAP_EXC
:
145 return ("capacity exceeded");
146 case NVME_CQE_SC_GEN_NVM_NS_NOTRDY
:
147 return ("namespace not ready");
148 case NVME_CQE_SC_GEN_NVM_RSV_CNFLCT
:
149 return ("reservation conflict");
158 case NVME_CQE_SC_GEN_NVM_LBA_RANGE
:
159 return ("lba out of range");
160 case NVME_CQE_SC_GEN_NVM_FORMATTING
:
161 return ("format in progress");
168 case NVME_CQE_SC_GEN_KEY_INV_VAL
:
169 return ("invalid value size");
170 case NVME_CQE_SC_GEN_KEY_INV_KEY
:
171 return ("invalid key size");
172 case NVME_CQE_SC_GEN_KEY_ENOENT
:
173 return ("kv key does not exist");
174 case NVME_CQE_SC_GEN_KEY_UNRECOV
:
175 return ("unrecovered error");
176 case NVME_CQE_SC_GEN_KEY_EXISTS
:
177 return ("key exists");
186 return ("unknown command set specific general status code");
190 nvme_sctostr_cmd_gen(uint32_t sct
)
193 case NVME_CQE_SC_SPC_INV_CQ
:
194 return ("completion queue invalid");
195 case NVME_CQE_SC_SPC_INV_QID
:
196 return ("invalid queue identifier");
197 case NVME_CQE_SC_SPC_MAX_QSZ_EXC
:
198 return ("max queue size exceeded");
199 case NVME_CQE_SC_SPC_ABRT_CMD_EXC
:
200 return ("abort command limit exceeded");
201 case NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC
:
202 return ("asynchronous event request limit");
203 case NVME_CQE_SC_SPC_INV_FW_SLOT
:
204 return ("invalid firmware slot");
205 case NVME_CQE_SC_SPC_INV_FW_IMG
:
206 return ("invalid firmware image");
207 case NVME_CQE_SC_SPC_INV_INT_VECT
:
208 return ("invalid interrupt vector");
209 case NVME_CQE_SC_SPC_INV_LOG_PAGE
:
210 return ("invalid log page");
211 case NVME_CQE_SC_SPC_INV_FORMAT
:
212 return ("invalid format");
213 case NVME_CQE_SC_SPC_FW_RESET
:
214 return ("firmware activation requires conventional reset");
215 case NVME_CQE_SC_SPC_INV_Q_DEL
:
216 return ("invalid queue deletion");
217 case NVME_CQE_SC_SPC_FEAT_SAVE
:
218 return ("feature identifier not saveable");
219 case NVME_CQE_SC_SPC_FEAT_CHG
:
220 return ("feature not changeable");
221 case NVME_CQE_SC_SPC_FEAT_NS_SPEC
:
222 return ("feature not namespace spec");
223 case NVME_CQE_SC_SPC_FW_NSSR
:
224 return ("firmware activation requires nvm subsystem reset");
225 case NVME_CQE_SC_SPC_FW_NEXT_RESET
:
226 return ("firmware activation requires controller level reset");
227 case NVME_CQE_SC_SPC_FW_MTFA
:
228 return ("firmware activation requires maximum time violation");
229 case NVME_CQE_SC_SPC_FW_PROHIBITED
:
230 return ("firmware activation prohibited");
231 case NVME_CQE_SC_SPC_FW_OVERLAP
:
232 return ("overlapping range");
233 case NVME_CQE_SC_SPC_NS_INSUF_CAP
:
234 return ("namespace insufficient capacity");
235 case NVME_CQE_SC_SPC_NS_NO_ID
:
236 return ("namespace identifier unavailable");
237 case NVME_CQE_SC_SPC_NS_ATTACHED
:
238 return ("namespace already attached");
239 case NVME_CQE_SC_SPC_NS_PRIV
:
240 return ("namespace is private");
241 case NVME_CQE_SC_SPC_NS_NOT_ATTACH
:
242 return ("namespace is not attached");
243 case NVME_CQE_SC_SPC_THIN_ENOTSUP
:
244 return ("thin provisioning not supported");
245 case NVME_CQE_SC_SPC_INV_CTRL_LIST
:
246 return ("controller list invalid");
247 case NVME_CQE_SC_SPC_SELF_TESTING
:
248 return ("device self-test in progress");
249 case NVME_CQE_SC_SPC_NO_BP_WRITE
:
250 return ("boot partition write protected");
251 case NVME_CQE_SC_SPC_INV_CTRL_ID
:
252 return ("invalid controller identifier");
253 case NVME_CQE_SC_SPC_INV_SEC_CTRL
:
254 return ("invalid secondary controller state");
255 case NVME_CQE_SC_SPC_INV_CTRL_NRSRC
:
256 return ("invalid number of controller resources");
257 case NVME_CQE_SC_SPC_INV_RSRC_ID
:
258 return ("Invalid resource identifier");
259 case NVME_CQE_SC_SPC_NO_SAN_PMR
:
260 return ("sanitize prohibited while persistent memory region "
262 case NVME_CQE_SC_SPC_INV_ANA_GID
:
263 return ("ana group identifier invalid");
264 case NVME_CQE_SC_SPC_ANA_ATTACH
:
265 return ("ana attach failed");
266 case NVME_CQE_SC_SPC_INSUF_CAP
:
267 return ("insufficient capacity");
268 case NVME_CQE_SC_SPC_NS_ATTACH_LIM
:
269 return ("namespace attachment limit exceeded");
270 case NVME_CQE_SC_SPC_LOCKDOWN_UNSUP
:
271 return ("prohibition of command execution not supported");
272 case NVME_CQE_SC_SPC_UNSUP_IO_CMD
:
273 return ("I/O command set not supported");
274 case NVME_CQE_SC_SPC_DIS_IO_CMD
:
275 return ("I/O command set not enabled");
276 case NVME_CQE_SC_SPC_INV_CMD_COMBO
:
277 return ("I/O command set combination rejected");
278 case NVME_CQE_SC_SPC_INV_IO_CMD
:
279 return ("Invalid I/O command set");
280 case NVME_CQE_SC_SPC_UNAVAIL_ID
:
281 return ("identifier unavailable");
283 return ("unknown generic command status code");
288 * The NVMe 2.0c spec that introduces many of the zoned related errors has
289 * footnotes to suggest some of these are command set specific, but does not
290 * mark any of them. For the moment we basically assume that they're valid
291 * everywhere due to the fact that they don't overlap.
294 nvme_sctostr_cmd_csi(nvme_csi_t csi
, uint32_t sct
)
297 case NVME_CQE_SC_SPC_NVM_CNFL_ATTR
:
298 return ("conflicting attributes");
299 case NVME_CQE_SC_SPC_NVM_INV_PROT
:
300 return ("invalid protection");
301 case NVME_CQE_SC_SPC_NVM_READONLY
:
302 return ("write to read only range");
303 case NVME_CQE_SC_SPC_ZONE_BDRY_ERR
:
304 return ("zoned boundary error");
305 case NVME_CQE_SC_SPC_ZONE_FULL
:
306 return ("zone is full");
307 case NVME_CQE_SC_SPC_ZONE_RDONLY
:
308 return ("zone is read only");
309 case NVME_CQE_SC_SPC_ZONE_OFFLINE
:
310 return ("zone is offline");
311 case NVME_CQE_SC_SPC_ZONE_INV_WRITE
:
312 return ("zone invalid write");
313 case NVME_CQE_SC_SPC_ZONE_ACT
:
314 return ("too many active zones");
315 case NVME_CQE_SC_SPC_ZONE_OPEN
:
316 return ("too many open zones");
317 case NVME_CQE_SC_SPC_INV_ZONE_TRANS
:
318 return ("invalid zone state transition");
320 return ("unknown command specific, I/O command set specific "
326 nvme_sctostr_media(nvme_csi_t csi
, uint32_t sct
)
328 if (sct
>= NVME_CQE_SC_VEND_MIN
) {
329 return ("vendor specific media and data integrity status code");
333 * Unlike NVMe 1.x, NVMe 2.x declares the following command set
337 case NVME_CQE_SC_INT_NVM_WRITE
:
338 return ("write fault");
339 case NVME_CQE_SC_INT_NVM_READ
:
340 return ("unrecovered read error");
341 case NVME_CQE_SC_INT_NVM_GUARD
:
342 return ("guard check error");
343 case NVME_CQE_SC_INT_NVM_APPL_TAG
:
344 return ("application tag check err");
345 case NVME_CQE_SC_INT_NVM_REF_TAG
:
346 return ("reference tag check err");
347 case NVME_CQE_SC_INT_NVM_ACCESS
:
348 return ("access denied");
349 case NVME_CQE_SC_INT_NVM_TAG
:
350 return ("end-to-end storage tag check error");
356 * The only command-set specific values are currently defined for the
359 if (csi
!= NVME_CSI_NVM
) {
360 return ("unknown media and data integrity status code");
364 case NVME_CQE_SC_INT_NVM_COMPARE
:
365 return ("compare failure");
366 case NVME_CQE_SC_INT_NVM_DEALLOC
:
367 return ("deallocated or unwritten logical block");
369 return ("unknown media and data integrity status code");
374 nvme_sctostr_path(uint32_t sct
)
377 case NVME_CQE_SC_PATH_INT_ERR
:
378 return ("internal path error");
379 case NVME_CQE_SC_PATH_AA_PLOSS
:
380 return ("asymmetric access persistent loss");
381 case NVME_CQE_SC_PATH_AA_INACC
:
382 return ("asymmetric access inaccessible");
383 case NVME_CQE_SC_PATH_AA_TRANS
:
384 return ("asymmetric access transition");
385 case NVME_CQE_SC_PATH_CTRL_ERR
:
386 return ("controller pathing error");
387 case NVME_CQE_SC_PATH_HOST_ERR
:
388 return ("host pathing error");
389 case NVME_CQE_SC_PATH_HOST_ABRT
:
390 return ("command aborted by host");
392 return ("unknown path related status code");
397 nvme_sctostr(nvme_ctrl_t
*ctrl __unused
, nvme_csi_t csi
, uint32_t sct
,
401 case NVME_CQE_SCT_GENERIC
:
402 if (sc
<= NVME_CQE_SC_GEN_MAX
) {
403 return (nvme_sctostr_gen_gen(sc
));
404 } else if (sc
<= NVME_CQE_SC_CSI_MAX
) {
405 return (nvme_sctostr_gen_csi(csi
, sc
));
407 return ("generic vendor specific status code");
409 case NVME_CQE_SCT_SPECIFIC
:
410 if (sc
<= NVME_CQE_SC_GEN_MAX
) {
411 return (nvme_sctostr_cmd_gen(sc
));
412 } else if (sc
<= NVME_CQE_SC_CSI_MAX
) {
413 return (nvme_sctostr_cmd_csi(csi
, sc
));
415 return ("command specific vendor specific status code");
417 case NVME_CQE_SCT_INTEGRITY
:
418 return (nvme_sctostr_media(csi
, sc
));
419 case NVME_CQE_SCT_PATH
:
420 return (nvme_sctostr_path(sc
));
421 case NVME_CQE_SCT_VENDOR
:
422 return ("vendor specific");
424 return ("unknown status code");
429 nvme_err(nvme_t
*nvme
)
431 return (nvme
->nh_err
.ne_err
);
435 nvme_syserr(nvme_t
*nvme
)
437 return (nvme
->nh_err
.ne_syserr
);
441 nvme_errmsg(nvme_t
*nvme
)
443 return (nvme
->nh_err
.ne_errmsg
);
447 nvme_errlen(nvme_t
*nvme
)
449 return (nvme
->nh_err
.ne_errlen
);
453 nvme_errtostr(nvme_t
*nvme
, nvme_err_t err
)
457 return ("NVME_ERR_OK");
458 case NVME_ERR_CONTROLLER
:
459 return ("NVME_ERR_CONTROLLER");
460 case NVME_ERR_NO_MEM
:
461 return ("NVME_ERR_NO_MEM");
462 case NVME_ERR_NO_DMA_MEM
:
463 return ("NVME_ERR_NO_DMA_MEM");
464 case NVME_ERR_LIBDEVINFO
:
465 return ("NVME_ERR_LIBDEVINFO");
466 case NVME_ERR_INTERNAL
:
467 return ("NVME_ERR_INTERNAL");
468 case NVME_ERR_BAD_PTR
:
469 return ("NVME_ERR_BAD_PTR");
470 case NVME_ERR_BAD_FLAG
:
471 return ("NVME_ERR_BAD_FLAG");
472 case NVME_ERR_BAD_DEVI
:
473 return ("NVME_ERR_BAD_DEVI");
474 case NVME_ERR_BAD_DEVI_PROP
:
475 return ("NVME_ERR_BAD_DEVI_PROP");
476 case NVME_ERR_ILLEGAL_INSTANCE
:
477 return ("NVME_ERR_ILLEGAL_INSTANCE");
478 case NVME_ERR_BAD_CONTROLLER
:
479 return ("NVME_ERR_BAD_CONTROLLER");
481 return ("NVME_ERR_PRIVS");
482 case NVME_ERR_OPEN_DEV
:
483 return ("NVME_ERR_OPEN_DEV");
484 case NVME_ERR_BAD_RESTORE
:
485 return ("NVME_ERR_BAD_RESTORE");
486 case NVME_ERR_NS_RANGE
:
487 return ("NVME_ERR_NS_RANGE");
488 case NVME_ERR_NS_UNUSE
:
489 return ("NVME_ERR_NS_UNUSE");
490 case NVME_ERR_LOG_CSI_RANGE
:
491 return ("NVME_ERR_LOG_CSI_RANGE");
492 case NVME_ERR_LOG_LID_RANGE
:
493 return ("NVME_ERR_LOG_LID_RANGE");
494 case NVME_ERR_LOG_LSP_RANGE
:
495 return ("NVME_ERR_LOG_LSP_RANGE");
496 case NVME_ERR_LOG_LSI_RANGE
:
497 return ("NVME_ERR_LOG_LSI_RANGE");
498 case NVME_ERR_LOG_RAE_RANGE
:
499 return ("NVME_ERR_LOG_RAE_RANGE");
500 case NVME_ERR_LOG_SIZE_RANGE
:
501 return ("NVME_ERR_LOG_SIZE_RANGE");
502 case NVME_ERR_LOG_OFFSET_RANGE
:
503 return ("NVME_ERR_LOG_OFFSET_RANGE");
504 case NVME_ERR_LOG_CSI_UNSUP
:
505 return ("NVME_ERR_LOG_CSI_UNSUP");
506 case NVME_ERR_LOG_LSP_UNSUP
:
507 return ("NVME_ERR_LOG_LSP_UNSUP");
508 case NVME_ERR_LOG_LSI_UNSUP
:
509 return ("NVME_ERR_LOG_LSI_UNSUP");
510 case NVME_ERR_LOG_RAE_UNSUP
:
511 return ("NVME_ERR_LOG_RAE_UNSUP");
512 case NVME_ERR_LOG_OFFSET_UNSUP
:
513 return ("NVME_ERR_LOG_OFFSET_UNSUP");
514 case NVME_ERR_LOG_LSP_UNUSE
:
515 return ("NVME_ERR_LOG_LSP_UNUSE");
516 case NVME_ERR_LOG_LSI_UNUSE
:
517 return ("NVME_ERR_LOG_LSI_UNUSE");
518 case NVME_ERR_LOG_RAE_UNUSE
:
519 return ("NVME_ERR_LOG_RAE_UNUSE");
520 case NVME_ERR_LOG_SCOPE_MISMATCH
:
521 return ("NVME_ERR_LOG_SCOPE_MISMATCH");
522 case NVME_ERR_LOG_REQ_MISSING_FIELDS
:
523 return ("NVME_ERR_LOG_REQ_MISSING_FIELDS");
524 case NVME_ERR_LOG_NAME_UNKNOWN
:
525 return ("NVME_ERR_LOG_NAME_UNKNOWN");
526 case NVME_ERR_LOG_UNSUP_BY_DEV
:
527 return ("NVME_ERR_LOG_UNSUP_BY_DEV");
528 case NVME_ERR_IDENTIFY_UNKNOWN
:
529 return ("NVME_ERR_IDENTIFY_UNKNOWN");
530 case NVME_ERR_IDENTIFY_UNSUP_BY_DEV
:
531 return ("NVME_ERR_IDENTIFY_UNSUP_BY_DEV");
532 case NVME_ERR_IDENTIFY_CTRLID_RANGE
:
533 return ("NVME_ERR_IDENTIFY_CTRLID_RANGE");
534 case NVME_ERR_IDENTIFY_OUTPUT_RANGE
:
535 return ("NVME_ERR_IDENTIFY_OUTPUT_RANGE");
536 case NVME_ERR_IDENTIFY_CTRLID_UNSUP
:
537 return ("NVME_ERR_IDENTIFY_CTRLID_UNSUP");
538 case NVME_ERR_IDENTIFY_CTRLID_UNUSE
:
539 return ("NVME_ERR_IDENTIFY_CTRLID_UNUSE");
540 case NVME_ERR_IDENTIFY_REQ_MISSING_FIELDS
:
541 return ("NVME_ERR_IDENTIFY_REQ_MISSING_FIELDS");
542 case NVME_ERR_VUC_UNSUP_BY_DEV
:
543 return ("NVME_ERR_VUC_UNSUP_BY_DEV");
544 case NVME_ERR_VUC_TIMEOUT_RANGE
:
545 return ("NVME_ERR_VUC_TIMEOUT_RANGE");
546 case NVME_ERR_VUC_OPCODE_RANGE
:
547 return ("NVME_ERR_VUC_OPCODE_RANGE");
548 case NVME_ERR_VUC_IMPACT_RANGE
:
549 return ("NVME_ERR_VUC_IMPACT_RANGE");
550 case NVME_ERR_VUC_NDT_RANGE
:
551 return ("NVME_ERR_VUC_NDT_RANGE");
552 case NVME_ERR_VUC_CANNOT_RW
:
553 return ("NVME_ERR_VUC_CANNOT_RW");
554 case NVME_ERR_VUC_NO_RESULTS
:
555 return ("NVME_ERR_VUC_NO_RESULTS");
556 case NVME_ERR_VUC_UNKNOWN
:
557 return ("NVME_ERR_VUC_UNKNOWN");
558 case NVME_ERR_VUC_REQ_MISSING_FIELDS
:
559 return ("NVME_ERR_VUC_REQ_MISSING_FIELDS");
560 case NVME_ERR_VU_FUNC_UNSUP_BY_DEV
:
561 return ("NVME_ERR_VU_FUNC_UNSUP_BY_DEV");
562 case NVME_ERR_WDC_E6_OFFSET_RANGE
:
563 return ("NVME_ERR_WDC_E6_OFFSET_RANGE");
564 case NVME_ERR_FW_UNSUP_BY_DEV
:
565 return ("NVME_ERR_FW_UNSUP_BY_DEV");
566 case NVME_ERR_KERN_FW_IMPOS
:
567 return ("NVME_ERR_KERN_FW_IMPOS");
568 case NVME_ERR_FW_LOAD_LEN_RANGE
:
569 return ("NVME_ERR_FW_LOAD_LEN_RANGE");
570 case NVME_ERR_FW_LOAD_OFFSET_RANGE
:
571 return ("NVME_ERR_FW_LOAD_OFFSET_RANGE");
572 case NVME_ERR_FW_COMMIT_SLOT_RANGE
:
573 return ("NVME_ERR_FW_COMMIT_SLOT_RANGE");
574 case NVME_ERR_FW_COMMIT_ACTION_RANGE
:
575 return ("NVME_ERR_FW_COMMIT_ACTION_RANGE");
576 case NVME_ERR_FW_COMMIT_REQ_MISSING_FIELDS
:
577 return ("NVME_ERR_FW_COMMIT_REQ_MISSING_FIELDS");
578 case NVME_ERR_FW_SLOT_RO
:
579 return ("NVME_ERR_FW_SLOT_RO");
580 case NVME_ERR_FORMAT_UNSUP_BY_DEV
:
581 return ("NVME_ERR_FORMAT_UNSUP_BY_DEV");
582 case NVME_ERR_CRYPTO_SE_UNSUP_BY_DEV
:
583 return ("NVME_ERR_CRYPTO_SE_UNSUP_BY_DEV");
584 case NVME_ERR_NS_FORMAT_UNSUP_BY_DEV
:
585 return ("NVME_ERR_NS_FORMAT_UNSUP_BY_DEV");
586 case NVME_ERR_KERN_FORMAT_UNSUP
:
587 return ("NVME_ERR_KERN_FORMAT_UNSUP");
588 case NVME_ERR_FORMAT_LBAF_RANGE
:
589 return ("NVME_ERR_FORMAT_LBAF_RANGE");
590 case NVME_ERR_FORMAT_SES_RANGE
:
591 return ("NVME_ERR_FORMAT_SES_RANGE");
592 case NVME_ERR_FORMAT_PARAM_UNSUP
:
593 return ("NVME_ERR_FORMAT_PARAM_UNSUP");
594 case NVME_ERR_FORMAT_REQ_MISSING_FIELDS
:
595 return ("NVME_ERR_FORMAT_REQ_MISSING_FIELDS");
596 case NVME_ERR_WDC_E6_REQ_MISSING_FIELDS
:
597 return ("NVME_ERR_WDC_E6_REQ_MISSING_FIELDS");
598 case NVME_ERR_FEAT_NAME_UNKNOWN
:
599 return ("NVME_ERR_FEAT_NAME_UNKNOWN");
600 case NVME_ERR_FEAT_UNSUP_BY_DEV
:
601 return ("NVME_ERR_FEAT_UNSUP_BY_DEV");
602 case NVME_ERR_FEAT_FID_RANGE
:
603 return ("NVME_ERR_FEAT_FID_RANGE");
604 case NVME_ERR_FEAT_SEL_RANGE
:
605 return ("NVME_ERR_FEAT_SEL_RANGE");
606 case NVME_ERR_FEAT_CDW11_RANGE
:
607 return ("NVME_ERR_FEAT_CDW11_RANGE");
608 case NVME_ERR_FEAT_DATA_RANGE
:
609 return ("NVME_ERR_FEAT_DATA_RANGE");
610 case NVME_ERR_FEAT_SEL_UNSUP
:
611 return ("NVME_ERR_FEAT_SEL_UNSUP");
612 case NVME_ERR_FEAT_CDW11_UNUSE
:
613 return ("NVME_ERR_FEAT_CDW11_UNUSE");
614 case NVME_ERR_FEAT_DATA_UNUSE
:
615 return ("NVME_ERR_FEAT_DATA_UNUSE");
616 case NVME_ERR_FEAT_NO_RESULTS
:
617 return ("NVME_ERR_FEAT_NO_RESULTS");
618 case NVME_ERR_GET_FEAT_REQ_MISSING_FIELDS
:
619 return ("NVME_ERR_GET_FEAT_REQ_MISSING_FIELDS");
620 case NVME_ERR_NEED_CTRL_WRLOCK
:
621 return ("NVME_ERR_NEED_CTRL_WRLOCK");
622 case NVME_ERR_NEED_NS_WRLOCK
:
623 return ("NVME_ERR_NEED_NS_WRLOCK");
624 case NVME_ERR_CTRL_LOCKED
:
625 return ("NVME_ERR_CTRL_LOCKED");
626 case NVME_ERR_NS_LOCKED
:
627 return ("NVME_ERR_NS_LOCKED");
628 case NVME_ERR_LOCK_PROG
:
629 return ("NVME_ERR_LOCK_PROG");
630 case NVME_ERR_LOCK_ORDER
:
631 return ("NVME_ERR_LOCK_ORDER");
632 case NVME_ERR_LOCK_WAIT_INTR
:
633 return ("NVME_ERR_LOCK_WAIT_INTR");
634 case NVME_ERR_LOCK_WOULD_BLOCK
:
635 return ("NVME_ERR_LOCK_WOULD_BLOCK");
636 case NVME_ERR_DETACH_KERN
:
637 return ("NVME_ERR_DETACH_KERN");
638 case NVME_ERR_ATTACH_KERN
:
639 return ("NVME_ERR_ATTACH_KERN");
640 case NVME_ERR_ATTACH_UNSUP_KERN
:
641 return ("NVME_ERR_ATTACH_UNSUP_KERN");
642 case NVME_ERR_NS_BLKDEV_ATTACH
:
643 return ("NVME_ERR_NS_BLKDEV_ATTACH");
644 case NVME_ERR_NO_KERN_MEM
:
645 return ("NVME_ERR_NO_KERN_MEM");
646 case NVME_ERR_CTRL_DEAD
:
647 return ("NVME_ERR_CTRL_DEAD");
648 case NVME_ERR_CTRL_GONE
:
649 return ("NVME_ERR_CTRL_GONE");
651 return ("unknown error");
656 nvme_ctrl_err(nvme_ctrl_t
*ctrl
)
658 return (ctrl
->nc_err
.ne_err
);
662 nvme_ctrl_syserr(nvme_ctrl_t
*ctrl
)
664 return (ctrl
->nc_err
.ne_syserr
);
668 nvme_ctrl_errmsg(nvme_ctrl_t
*ctrl
)
670 return (ctrl
->nc_err
.ne_errmsg
);
674 nvme_ctrl_errlen(nvme_ctrl_t
*ctrl
)
676 return (ctrl
->nc_err
.ne_errlen
);
680 nvme_ctrl_deverr(nvme_ctrl_t
*ctrl
, uint32_t *sct
, uint32_t *sc
)
683 *sct
= ctrl
->nc_err
.ne_ctrl_sct
;
687 *sc
= ctrl
->nc_err
.ne_ctrl_sc
;
692 nvme_ctrl_errtostr(nvme_ctrl_t
*ctrl
, nvme_err_t err
)
694 return (nvme_errtostr(ctrl
->nc_nvme
, err
));
698 nvme_error_common(nvme_err_data_t
*ep
, nvme_err_t err
, int32_t sys
,
699 const char *fmt
, va_list ap
)
707 ret
= vsnprintf(ep
->ne_errmsg
,
708 sizeof (ep
->ne_errmsg
), fmt
, ap
);
709 if (ret
>= sizeof (ep
->ne_errmsg
)) {
710 ep
->ne_errlen
= sizeof (ep
->ne_errmsg
) - 1;
711 } else if (ret
<= 0) {
713 ep
->ne_errmsg
[0] = '\0';
715 ep
->ne_errlen
= (size_t)ret
;
720 nvme_error(nvme_t
*nvme
, nvme_err_t err
, int32_t sys
, const char *fmt
, ...)
725 nvme_error_common(&nvme
->nh_err
, err
, sys
, fmt
, ap
);
732 nvme_ctrl_error(nvme_ctrl_t
*ctrl
, nvme_err_t err
, int32_t sys
,
733 const char *fmt
, ...)
738 nvme_error_common(&ctrl
->nc_err
, err
, sys
, fmt
, ap
);
745 nvme_success_common(nvme_err_data_t
*err
)
747 err
->ne_err
= NVME_ERR_OK
;
749 err
->ne_ctrl_sct
= 0;
751 err
->ne_errmsg
[0] = '\0';
758 nvme_success(nvme_t
*nvme
)
760 return (nvme_success_common(&nvme
->nh_err
));
764 nvme_ctrl_success(nvme_ctrl_t
*ctrl
)
766 return (nvme_success_common(&ctrl
->nc_err
));
770 nvme_err_save(const nvme_t
*nvme
, nvme_err_data_t
*out
)
776 nvme_err_set(nvme_t
*nvme
, const nvme_err_data_t
*err
)
782 nvme_ctrl_err_save(const nvme_ctrl_t
*ctrl
, nvme_err_data_t
*out
)
788 nvme_ctrl_err_set(nvme_ctrl_t
*ctrl
, const nvme_err_data_t
*err
)
794 * This table deals with mapping a kernel error to a library error and provides
795 * a short description of what it is. Note, we do not expect all kernel errors
796 * to occur and we may want to revisit which of these end up indicating a
797 * programmer error that we caused somehow.
800 nvme_ioctl_errno_t kl_kern
;
806 * Please keep this table ordered based on the nvme_ioctl_error_t enumeration
807 * order. This is not required for correctness, but helps when scanning for
808 * missing entries. Please document why certain entries are skipped.
810 static const nvme_ktolmap_t nvme_ktolmap
[] = {
812 * NVME_IOCTL_E_OK and NVME_IOCTL_E_CTRL_ERROR should already have been
813 * dealt with and shouldn't be included here.
815 { NVME_IOCTL_E_CTRL_DEAD
, NVME_ERR_CTRL_DEAD
, "the controller is no "
816 "longer usable by the system" },
817 { NVME_IOCTL_E_CTRL_GONE
, NVME_ERR_CTRL_GONE
, "the controller has been "
818 "physically removed from the system" },
819 { NVME_IOCTL_E_NS_RANGE
, NVME_ERR_NS_RANGE
, "invalid namespace "
821 { NVME_IOCTL_E_NS_UNUSE
, NVME_ERR_NS_UNUSE
, "a namespace ID may not be "
822 "specified in this context" },
824 * We have purposefully skipped NVME_IOCTL_E_MINOR_WRONG_NS and
825 * NVME_IOCTL_E_NOT_CTRL as the library should not ever use the
828 { NVME_IOCTL_E_NO_BCAST_NS
, NVME_ERR_NS_RANGE
, "the broadcast "
829 "namespace may not be used in this context" },
830 { NVME_IOCTL_E_NEED_CTRL_WRLOCK
, NVME_ERR_NEED_CTRL_WRLOCK
, "operation "
831 "requires a controller write lock, but it is not owned" },
832 { NVME_IOCTL_E_NEED_NS_WRLOCK
, NVME_ERR_NEED_NS_WRLOCK
, "operation "
833 "requires a namespace write lock, but it is not owned" },
834 { NVME_IOCTL_E_CTRL_LOCKED
, NVME_ERR_CTRL_LOCKED
, "controller locked" },
835 { NVME_IOCTL_E_NS_LOCKED
, NVME_ERR_NS_LOCKED
, "namespace locked" },
837 * We have purposefully skipped NVME_IOCTL_E_UNKNOWN_LOG_PAGE as in
838 * theory the library and kernel should be in sync with the set of known
839 * log pages. If it is out of sync due to someone distributing the two
840 * weirdly or a bad build, we'd rather that end up as an internal error
841 * rather than a first class error for users.
843 { NVME_IOCTL_E_UNSUP_LOG_PAGE
, NVME_ERR_LOG_UNSUP_BY_DEV
, "controller "
844 "does not support the specified log page" },
845 { NVME_IOCTL_E_BAD_LOG_SCOPE
, NVME_ERR_LOG_SCOPE_MISMATCH
, "log page "
846 "does not work with the requested scope" },
847 { NVME_IOCTL_E_LOG_CSI_RANGE
, NVME_ERR_LOG_CSI_RANGE
, "invalid command "
848 "set interface value" },
849 { NVME_IOCTL_E_LOG_LID_RANGE
, NVME_ERR_LOG_LID_RANGE
, "invalid log "
850 "identifier value" },
851 { NVME_IOCTL_E_LOG_LSP_RANGE
, NVME_ERR_LOG_LSP_RANGE
, "invalid log "
852 "specific parameter value" },
853 { NVME_IOCTL_E_LOG_LSI_RANGE
, NVME_ERR_LOG_LSI_RANGE
, "invalid log "
854 "specific identifier value" },
855 { NVME_IOCTL_E_LOG_RAE_RANGE
, NVME_ERR_LOG_SIZE_RANGE
, "invalid retain "
856 "asynchronous event value" },
857 { NVME_IOCTL_E_LOG_SIZE_RANGE
, NVME_ERR_LOG_SIZE_RANGE
, "invalid log "
859 { NVME_IOCTL_E_LOG_OFFSET_RANGE
, NVME_ERR_LOG_OFFSET_RANGE
, "invalid "
860 "log offset value" },
861 { NVME_IOCTL_E_LOG_CSI_UNSUP
, NVME_ERR_LOG_CSI_UNSUP
,
862 "the controller does not support specifying the csi" },
863 { NVME_IOCTL_E_LOG_LSP_UNSUP
, NVME_ERR_LOG_LSP_UNSUP
,
864 "the controller does not support specifying the lsp" },
865 { NVME_IOCTL_E_LOG_LSI_UNSUP
, NVME_ERR_LOG_LSI_UNSUP
,
866 "or controller do not support specifying the lsi" },
867 { NVME_IOCTL_E_LOG_RAE_UNSUP
, NVME_ERR_LOG_RAE_UNSUP
,
868 "the controller does not support retaining an asynchronous event" },
869 { NVME_IOCTL_E_LOG_OFFSET_UNSUP
, NVME_ERR_LOG_OFFSET_UNSUP
,
870 "the controller do not support specifying a a read offset" },
871 { NVME_IOCTL_E_LOG_LSP_UNUSE
, NVME_ERR_LOG_LSP_UNUSE
, "the log page "
872 "does not allow the lsp to be used" },
873 { NVME_IOCTL_E_LOG_LSI_UNUSE
, NVME_ERR_LOG_LSI_UNUSE
, "the log page "
874 "does not allow the lsi to be used" },
875 { NVME_IOCTL_E_LOG_RAE_UNUSE
, NVME_ERR_LOG_RAE_UNUSE
, "the log page "
876 "does not allow rae to be set" },
877 { NVME_IOCTL_E_NO_DMA_MEM
, NVME_ERR_NO_DMA_MEM
, "the kernel failed to "
878 "allocate sufficient DMA resources" },
879 { NVME_IOCTL_E_NO_KERN_MEM
, NVME_ERR_NO_KERN_MEM
, "the kernel failed "
880 "to allocate sufficient memory for this operation" },
881 { NVME_IOCTL_E_BAD_PRP
, NVME_ERR_INTERNAL
, "a driver error occurred "
882 "while filling out the command's DMA resources" },
883 { NVME_IOCTL_E_BAD_USER_DATA
, NVME_ERR_BAD_PTR
, "the kernel "
884 "detected an invalid user buffer while trying to read/write the "
885 "passed in data buffer" },
886 { NVME_IOCTL_E_UNKNOWN_IDENTIFY
, NVME_ERR_IDENTIFY_UNKNOWN
, "unknown "
887 "identify command requested" },
888 { NVME_IOCTL_E_UNSUP_IDENTIFY
, NVME_ERR_IDENTIFY_UNSUP_BY_DEV
,
889 "controller does not support the requested identify command" },
890 { NVME_IOCTL_E_IDENTIFY_CTRLID_RANGE
, NVME_ERR_IDENTIFY_CTRLID_RANGE
,
891 "invalid controller id value" },
892 { NVME_IOCTL_E_IDENTIFY_CTRLID_UNSUP
, NVME_ERR_IDENTIFY_CTRLID_UNSUP
,
893 "the controller does not support specifying the controller ID" },
894 { NVME_IOCTL_E_IDENTIFY_CTRLID_UNUSE
, NVME_ERR_IDENTIFY_CTRLID_UNUSE
,
895 "this specific identify request does not allow setting the "
897 { NVME_IOCTL_E_CTRL_VUC_UNSUP
, NVME_ERR_VUC_UNSUP_BY_DEV
,
898 "the controller does not support standard NVMe vendor unique "
901 * The following indicate bad values for given NVMe vendor unique
902 * command fields. Note, we do not include an entry for
903 * NVME_IOCTL_E_VUC_FLAGS_RANGE because these flags are entirely owned
906 { NVME_IOCTL_E_VUC_TIMEOUT_RANGE
, NVME_ERR_VUC_TIMEOUT_RANGE
, "invalid "
907 "command timeout value" },
908 { NVME_IOCTL_E_VUC_OPCODE_RANGE
, NVME_ERR_VUC_OPCODE_RANGE
, "invalid "
909 "vendor unique opcode specified" },
910 { NVME_IOCTL_E_VUC_IMPACT_RANGE
, NVME_ERR_VUC_IMPACT_RANGE
, "invalid "
911 "vendor unique impact specified" },
912 { NVME_IOCTL_E_VUC_NDT_RANGE
, NVME_ERR_VUC_NDT_RANGE
, "invalid "
913 "data transfer size specified" },
915 * We skip NVME_IOCTL_E_INCONSIST_VUC_FLAGS_NDT and
916 * NVME_IOCTL_E_INCONSIST_VUC_BUF_NDT because these are solely under the
917 * library control and would indicate a programming error at our end.
918 * The user shouldn't be able to cause this.
920 { NVME_IOCTL_E_BLKDEV_DETACH
, NVME_ERR_DETACH_KERN
, "the kernel failed "
921 "to detach the requested namespace" },
922 { NVME_IOCTL_E_BLKDEV_ATTACH
, NVME_ERR_ATTACH_KERN
, "the kernel failed "
923 "to attach the requested namespace" },
924 { NVME_IOCTL_E_UNSUP_ATTACH_NS
, NVME_ERR_ATTACH_UNSUP_KERN
,
925 "the namespace is not supported by the kernel" },
926 { NVME_IOCTL_E_CTRL_FORMAT_UNSUP
, NVME_ERR_FORMAT_UNSUP_BY_DEV
, "the "
927 "controller does not support formatting namespaces" },
928 { NVME_IOCTL_E_CTRL_CRYPTO_SE_UNSUP
, NVME_ERR_CRYPTO_SE_UNSUP_BY_DEV
,
929 "the controller does not support cryptographic secure erase" },
930 { NVME_IOCTL_E_CTRL_NS_FORMAT_UNSUP
, NVME_ERR_NS_FORMAT_UNSUP_BY_DEV
,
931 "the controller cannot format a single namespace" },
932 { NVME_IOCTL_E_CTRL_NS_SE_UNSUP
, NVME_ERR_NS_FORMAT_UNSUP_BY_DEV
,
933 "the controller cannot secure erase a single namespace" },
934 { NVME_IOCTL_E_FORMAT_LBAF_RANGE
, NVME_ERR_FORMAT_LBAF_RANGE
,
935 "invalid LBA format value" },
936 { NVME_IOCTL_E_FORMAT_SES_RANGE
, NVME_ERR_FORMAT_SES_RANGE
,
937 "invalid secure erase settings value" },
938 { NVME_IOCTL_E_UNSUP_LBAF_META
, NVME_ERR_KERN_FORMAT_UNSUP
, "cannot "
939 "format due to the use of unsupported metadata sectors" },
940 { NVME_IOCTL_E_CTRL_FW_UNSUP
, NVME_ERR_FW_UNSUP_BY_DEV
, "the "
941 "controller does not support firmware commands" },
942 { NVME_IOCTL_E_FW_LOAD_IMPOS_GRAN
, NVME_ERR_KERN_FW_IMPOS
, "controller "
943 "reported firmware upgrade granularity does not work with the "
944 "calculated maximum DMA transfer size" },
945 { NVME_IOCTL_E_FW_LOAD_LEN_RANGE
, NVME_ERR_FW_LOAD_LEN_RANGE
,
946 "invalid firmware load length value" },
947 { NVME_IOCTL_E_FW_LOAD_OFFSET_RANGE
, NVME_ERR_FW_LOAD_OFFSET_RANGE
,
948 "invalid firmware load offset value" },
949 { NVME_IOCTL_E_FW_COMMIT_SLOT_RANGE
, NVME_ERR_FW_COMMIT_SLOT_RANGE
,
950 "invalid firmware commit slot value" },
951 { NVME_IOCTL_E_FW_COMMIT_ACTION_RANGE
, NVME_ERR_FW_COMMIT_ACTION_RANGE
,
952 "invalid firmware commit action value" },
953 { NVME_IOCTL_E_RO_FW_SLOT
, NVME_ERR_FW_SLOT_RO
, "cannot write to read-"
956 * We have purposefully skipped NVME_IOCTL_E_UNKNOWN_FEATURE for the
957 * same reasons we did with NVME_IOCTL_E_UNKNOWN_LOG above.
959 { NVME_IOCTL_E_UNSUP_FEATURE
, NVME_ERR_FEAT_UNSUP_BY_DEV
, "the "
960 "controller does not supported the requested feature" },
961 { NVME_IOCTL_E_GET_FEAT_SEL_RANGE
, NVME_ERR_FEAT_SEL_RANGE
, "invalid "
962 "feature selector value" },
963 { NVME_IOCTL_E_GET_FEAT_CDW11_RANGE
, NVME_ERR_FEAT_CDW11_RANGE
,
964 "invalid feature-specific cdw11 value" },
965 { NVME_IOCTL_E_GET_FEAT_DATA_RANGE
, NVME_ERR_FEAT_DATA_RANGE
, "invalid "
966 "feature data, likely a size mismatch" },
967 { NVME_IOCTL_E_GET_FEAT_SEL_UNSUP
, NVME_ERR_FEAT_SEL_UNSUP
, "the "
968 "controller does not support specifying a feature selector" },
969 { NVME_IOCTL_E_GET_FEAT_CDW11_UNUSE
, NVME_ERR_FEAT_CDW11_UNUSE
,
970 "the feature does not support specifying a cdw11 argument" },
971 { NVME_IOCTL_E_GET_FEAT_DATA_UNUSE
, NVME_ERR_FEAT_DATA_UNUSE
,
972 "the feature does not support specifying a data buffer" },
974 * We skip the NVME_IOCTL_E_BAD_LOCK_ENTITY,
975 * NVME_IOCTL_E_BAD_LOCK_LEVEL, and NVME_IOCTL_E_BAD_LOCK_FLAGS
976 * arguments as these are all generally passed by the library and not
977 * really under direct user control. Therefore if there is a problem,
978 * that should be an internal error.
980 * Similarly we skip NVME_IOCTL_E_NS_CANNOT_LOCK_CTRL and
981 * NVME_IOCTL_E_NS_CANNOT_UNLOCK_CTRL because the library does not
982 * utilize namespace minors and these can only apply to those.
984 { NVME_IOCTL_E_LOCK_ALREADY_HELD
, NVME_ERR_LOCK_PROG
, "fatal "
985 "programmer error: recursive lock attempt" },
986 { NVME_IOCTL_E_LOCK_NO_CTRL_WITH_NS
, NVME_ERR_LOCK_ORDER
,
987 "control locks cannot be acquired while holding a namespace lock" },
988 { NVME_IOCTL_LOCK_NO_NS_WITH_CTRL_WRLOCK
, NVME_ERR_LOCK_ORDER
,
989 "no namespace locks may be acquired while holding a controller "
991 { NVME_IOCTL_E_LOCK_NO_2ND_NS
, NVME_ERR_LOCK_ORDER
, "only a single "
992 "namespace lock can be held at any time" },
993 { NVME_IOCTL_E_LOCK_WAIT_SIGNAL
, NVME_ERR_LOCK_WAIT_INTR
, "signal "
994 "received while blocking" },
995 { NVME_IOCTL_E_LOCK_WOULD_BLOCK
, NVME_ERR_LOCK_WOULD_BLOCK
, "lock not "
996 "available and no blocking allowed" },
997 { NVME_IOCTL_E_LOCK_PENDING
, NVME_ERR_LOCK_ORDER
, "a handle may only "
998 "block on one lock at a time" },
999 { NVME_IOCTL_E_LOCK_NOT_HELD
, NVME_ERR_LOCK_PROG
, "fatal "
1000 "programmer error: asked to unlock lock that was not held" },
1002 * This error is almost a can't happen due to the library construction
1003 * and should result in the above error, but if this does happen, we
1004 * treat this as a fatal lock error regardless.
1006 { NVME_IOCTL_E_LOCK_WRONG_NS
, NVME_ERR_LOCK_PROG
, "fatal "
1007 "programmer error: asked to unlock namespace lock that was not "
1009 { NVME_IOCTL_E_NS_BLKDEV_ATTACH
, NVME_ERR_NS_BLKDEV_ATTACH
, "cannot "
1010 "execute request while namespace is attached" },
1012 * We purposefully skip NVME_IOCTL_E_BD_ADDR_OVER right now because
1013 * there is nothing that a user can do about this. This is a
1014 * libnvme/kernel interface issue.
1019 * Translate a kernel ioctl error into the library's error. We handle the
1020 * controller error separately. Otherwise, everything else is done based upon
1021 * our translation table.
1024 nvme_ioctl_error(nvme_ctrl_t
*ctrl
, const nvme_ioctl_common_t
*ioc
,
1028 nvme_err_data_t
*err
= &ctrl
->nc_err
;
1029 VERIFY3U(ioc
->nioc_drv_err
, !=, NVME_IOCTL_E_OK
);
1032 err
->ne_ctrl_sct
= 0;
1033 err
->ne_ctrl_sc
= 0;
1035 if (ioc
->nioc_drv_err
== NVME_IOCTL_E_CTRL_ERROR
) {
1036 const char *sct
, *sc
;
1037 err
->ne_err
= NVME_ERR_CONTROLLER
;
1038 err
->ne_ctrl_sct
= ioc
->nioc_ctrl_sct
;
1039 err
->ne_ctrl_sc
= ioc
->nioc_ctrl_sc
;
1040 sct
= nvme_scttostr(ctrl
, ioc
->nioc_ctrl_sct
);
1041 sc
= nvme_sctostr(ctrl
, NVME_CSI_NVM
, ioc
->nioc_ctrl_sct
,
1043 ret
= snprintf(err
->ne_errmsg
, sizeof (err
->ne_errmsg
),
1044 "failed to execute %s command: received controller error "
1045 "sct/sc %s/%s (0x%x/0x%x)", desc
, sct
, sc
,
1046 ioc
->nioc_ctrl_sct
, ioc
->nioc_ctrl_sc
);
1048 const nvme_ktolmap_t
*map
= NULL
;
1049 for (size_t i
= 0; i
< ARRAY_SIZE(nvme_ktolmap
); i
++) {
1050 if (nvme_ktolmap
[i
].kl_kern
== ioc
->nioc_drv_err
) {
1051 map
= &nvme_ktolmap
[i
];
1057 err
->ne_err
= map
->kl_lib
;
1058 ret
= snprintf(err
->ne_errmsg
, sizeof (err
->ne_errmsg
),
1059 "failed to execute %s command: %s", desc
,
1062 err
->ne_err
= NVME_ERR_INTERNAL
;
1063 ret
= snprintf(err
->ne_errmsg
, sizeof (err
->ne_errmsg
),
1064 "failed to execute %s command: failed to map "
1065 "kernel error 0x%x to a known cause", desc
,
1070 if (ret
>= sizeof (err
->ne_errmsg
)) {
1071 err
->ne_errlen
= sizeof (err
->ne_errmsg
) - 1;
1072 } else if (ret
<= 0) {
1074 err
->ne_errmsg
[0] = '\0';
1076 err
->ne_errlen
= (size_t)ret
;
1083 * Evaluate the set of ioctl errors that we see and translate and/or abort a few
1084 * of the expected values. Most things will end up being translated into a
1085 * generic internal error as we expect a rather tight error set at this point.
1087 * We choose to panic on EFAULT because we are responsible for all such EFAULT
1088 * errors. These are structure that are coming from the library. This is not
1089 * something that the user could have passed us (their buffers will trigger
1090 * an explicit nvme_ioctl_errno_t). Therefore, something has gone very wrong
1091 * with our stack or we just corrupted some memory.
1093 * The same is true with EBADF. In this case, that'd happen either because our
1094 * controller fd was bandit'd away by someone or somehow we lost FREAD or FWRITE
1095 * on the fd. That should not be possible assuming everyone is acting in good
1096 * faith, so we treat this as a sign that something quite bad has happened and
1097 * we shouldn't continue.
1100 nvme_ioctl_syserror(nvme_ctrl_t
*ctrl
, int err
, const char *desc
)
1105 const char *base
= "fatal libnvme internal programming error: "
1106 "failed to issue ioctl";
1112 ret
= snprintf(msg
, sizeof (msg
), "%s %s: %s (controller %p)",
1113 base
, desc
, strerror(err
), ctrl
);
1114 if (ret
>= sizeof (msg
)) {
1115 ulen
= sizeof (msg
);
1117 } else if (ret
<= 0) {
1119 ulen
= strlen(base
) + 1;
1128 return (nvme_ctrl_error(ctrl
, NVME_ERR_PRIVS
, err
,
1129 "failed to issue %s ioctl due to missing privileges",
1132 return (nvme_ctrl_error(ctrl
, NVME_ERR_INTERNAL
, err
,
1133 "failed to issue %s ioctl due to unexpected system "
1134 "error: %s", desc
, strerror(err
)));
1139 * Generate the standard warning about which fields are unused.
1142 nvme_field_miss_err(nvme_ctrl_t
*ctrl
, const nvme_field_info_t
*fields
,
1143 size_t nfields
, nvme_err_t err
, const char *desc
, uint32_t val
)
1148 VERIFY3U(val
, !=, 0);
1150 for (size_t i
= 0; i
< nfields
; i
++) {
1151 if ((val
& (1 << i
)) == 0) {
1156 (void) strlcat(buf
, ",", sizeof (buf
));
1158 (void) strlcat(buf
, fields
[i
].nlfi_spec
, sizeof (buf
));
1162 return (nvme_ctrl_error(ctrl
, err
, 0, "cannot execute %s request due "
1163 "to missing fields: %s", desc
, buf
));
1167 nvme_field_check_one(nvme_ctrl_t
*ctrl
, uint64_t val
, const char *req
,
1168 const nvme_field_check_t
*check
, uint32_t allow
)
1170 const nvme_field_info_t
*field
= &check
->chk_fields
[check
->chk_index
];
1171 nvme_valid_ctrl_data_t data
;
1172 nvme_field_error_t err
;
1175 if (allow
!= 0 && (allow
& (1 << check
->chk_index
)) == 0) {
1176 VERIFY3U(check
->chk_field_unuse
, !=, 0);
1177 return (nvme_ctrl_error(ctrl
, check
->chk_field_unuse
, 0,
1178 "field %s (%s) cannot be set in this %s request",
1179 field
->nlfi_human
, field
->nlfi_spec
, req
));
1182 data
.vcd_vers
= &ctrl
->nc_vers
;
1183 data
.vcd_id
= &ctrl
->nc_info
;
1185 err
= nvme_field_validate(field
, &data
, val
, msg
, sizeof (msg
));
1187 case NVME_FIELD_ERR_OK
:
1189 case NVME_FIELD_ERR_UNSUP_VERSION
:
1190 case NVME_FIELD_ERR_UNSUP_FIELD
:
1191 VERIFY3U(check
->chk_field_unsup
, !=, 0);
1192 return (nvme_ctrl_error(ctrl
, check
->chk_field_unsup
, 0, "%s",
1194 case NVME_FIELD_ERR_BAD_VALUE
:
1195 VERIFY3U(check
->chk_field_range
, !=, 0);
1196 return (nvme_ctrl_error(ctrl
, check
->chk_field_range
, 0, "%s",