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 /*
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.
22 */
23
24 #include <string.h>
25 #include <stdarg.h>
26 #include <sys/debug.h>
27 #include <sys/sysmacros.h>
28 #include <upanic.h>
29
30 #include "libnvme_impl.h"
31
32 /*
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.
36 */
37 const char *
nvme_scttostr(nvme_ctrl_t * ctrl __unused,uint32_t sc)38 nvme_scttostr(nvme_ctrl_t *ctrl __unused, uint32_t sc)
39 {
40 switch (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");
49 default:
50 return ("unknown status type");
51 }
52 }
53
54 static const char *
nvme_sctostr_gen_gen(uint32_t sct)55 nvme_sctostr_gen_gen(uint32_t sct)
56 {
57 switch (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_GEN_ADM_MEDIA_NR:
131 return ("admin command media not ready");
132 case NVME_CQE_SC_GEN_INV_KEY:
133 return ("invalid key tag");
134 case NVME_CQE_SC_GEN_HOST_DISPNS_DIS:
135 return ("host dispersed namespace support not enabled");
136 case NVME_CQE_SC_GEN_HOSTID_UNINIT:
137 return ("host identifier not initialized");
138 case NVME_CQE_SC_GEN_WRONG_KEY:
139 return ("incorrect key");
140 case NVME_CQE_SC_GEN_FDP_DIS:
141 return ("FDP disabled");
142 case NVME_CQE_SC_GEN_INV_PHL:
143 return ("invalid placement handle list");
144 case NVME_CQE_SC_GEN_SAN_NS_FAIL:
145 return ("sanitize namespace failed");
146 case NVME_CQE_SC_GEN_SAN_NS_PROG:
147 return ("sanitize namespace in progress");
148 default:
149 return ("unknown status code");
150 }
151 }
152
153 static const char *
nvme_sctostr_gen_csi(nvme_csi_t csi,uint32_t sct)154 nvme_sctostr_gen_csi(nvme_csi_t csi, uint32_t sct)
155 {
156 /*
157 * These errors are allowed for all command sets.
158 */
159 switch (sct) {
160 case NVME_CQE_SC_GEN_NVM_CAP_EXC:
161 return ("capacity exceeded");
162 case NVME_CQE_SC_GEN_NVM_NS_NOTRDY:
163 return ("namespace not ready");
164 case NVME_CQE_SC_GEN_NVM_RSV_CNFLCT:
165 return ("reservation conflict");
166 default:
167 break;
168 }
169
170 switch (csi) {
171 case NVME_CSI_NVM:
172 case NVME_CSI_ZNS:
173 switch (sct) {
174 case NVME_CQE_SC_GEN_NVM_LBA_RANGE:
175 return ("lba out of range");
176 case NVME_CQE_SC_GEN_NVM_FORMATTING:
177 return ("format in progress");
178 default:
179 break;
180 }
181 break;
182 case NVME_CSI_KV:
183 switch (sct) {
184 case NVME_CQE_SC_GEN_KEY_INV_VAL:
185 return ("invalid value size");
186 case NVME_CQE_SC_GEN_KEY_INV_KEY:
187 return ("invalid key size");
188 case NVME_CQE_SC_GEN_KEY_ENOENT:
189 return ("kv key does not exist");
190 case NVME_CQE_SC_GEN_KEY_UNRECOV:
191 return ("unrecovered error");
192 case NVME_CQE_SC_GEN_KEY_EXISTS:
193 return ("key exists");
194 default:
195 break;
196 }
197 break;
198 default:
199 break;
200 }
201
202 return ("unknown command set specific general status code");
203 }
204
205 static const char *
nvme_sctostr_cmd_gen(uint32_t sct)206 nvme_sctostr_cmd_gen(uint32_t sct)
207 {
208 switch (sct) {
209 case NVME_CQE_SC_SPC_INV_CQ:
210 return ("completion queue invalid");
211 case NVME_CQE_SC_SPC_INV_QID:
212 return ("invalid queue identifier");
213 case NVME_CQE_SC_SPC_MAX_QSZ_EXC:
214 return ("max queue size exceeded");
215 case NVME_CQE_SC_SPC_ABRT_CMD_EXC:
216 return ("abort command limit exceeded");
217 case NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC:
218 return ("asynchronous event request limit");
219 case NVME_CQE_SC_SPC_INV_FW_SLOT:
220 return ("invalid firmware slot");
221 case NVME_CQE_SC_SPC_INV_FW_IMG:
222 return ("invalid firmware image");
223 case NVME_CQE_SC_SPC_INV_INT_VECT:
224 return ("invalid interrupt vector");
225 case NVME_CQE_SC_SPC_INV_LOG_PAGE:
226 return ("invalid log page");
227 case NVME_CQE_SC_SPC_INV_FORMAT:
228 return ("invalid format");
229 case NVME_CQE_SC_SPC_FW_RESET:
230 return ("firmware activation requires conventional reset");
231 case NVME_CQE_SC_SPC_INV_Q_DEL:
232 return ("invalid queue deletion");
233 case NVME_CQE_SC_SPC_FEAT_SAVE:
234 return ("feature identifier not saveable");
235 case NVME_CQE_SC_SPC_FEAT_CHG:
236 return ("feature not changeable");
237 case NVME_CQE_SC_SPC_FEAT_NS_SPEC:
238 return ("feature not namespace spec");
239 case NVME_CQE_SC_SPC_FW_NSSR:
240 return ("firmware activation requires nvm subsystem reset");
241 case NVME_CQE_SC_SPC_FW_NEXT_RESET:
242 return ("firmware activation requires controller level reset");
243 case NVME_CQE_SC_SPC_FW_MTFA:
244 return ("firmware activation requires maximum time violation");
245 case NVME_CQE_SC_SPC_FW_PROHIBITED:
246 return ("firmware activation prohibited");
247 case NVME_CQE_SC_SPC_FW_OVERLAP:
248 return ("overlapping range");
249 case NVME_CQE_SC_SPC_NS_INSUF_CAP:
250 return ("namespace insufficient capacity");
251 case NVME_CQE_SC_SPC_NS_NO_ID:
252 return ("namespace identifier unavailable");
253 case NVME_CQE_SC_SPC_NS_ATTACHED:
254 return ("namespace already attached");
255 case NVME_CQE_SC_SPC_NS_PRIV:
256 return ("namespace is private");
257 case NVME_CQE_SC_SPC_NS_NOT_ATTACH:
258 return ("namespace is not attached");
259 case NVME_CQE_SC_SPC_THIN_ENOTSUP:
260 return ("thin provisioning not supported");
261 case NVME_CQE_SC_SPC_INV_CTRL_LIST:
262 return ("controller list invalid");
263 case NVME_CQE_SC_SPC_SELF_TESTING:
264 return ("device self-test in progress");
265 case NVME_CQE_SC_SPC_NO_BP_WRITE:
266 return ("boot partition write protected");
267 case NVME_CQE_SC_SPC_INV_CTRL_ID:
268 return ("invalid controller identifier");
269 case NVME_CQE_SC_SPC_INV_SEC_CTRL:
270 return ("invalid secondary controller state");
271 case NVME_CQE_SC_SPC_INV_CTRL_NRSRC:
272 return ("invalid number of controller resources");
273 case NVME_CQE_SC_SPC_INV_RSRC_ID:
274 return ("Invalid resource identifier");
275 case NVME_CQE_SC_SPC_NO_SAN_PMR:
276 return ("sanitize prohibited while persistent memory region "
277 "is enabled");
278 case NVME_CQE_SC_SPC_INV_ANA_GID:
279 return ("ana group identifier invalid");
280 case NVME_CQE_SC_SPC_ANA_ATTACH:
281 return ("ana attach failed");
282 case NVME_CQE_SC_SPC_INSUF_CAP:
283 return ("insufficient capacity");
284 case NVME_CQE_SC_SPC_NS_ATTACH_LIM:
285 return ("namespace attachment limit exceeded");
286 case NVME_CQE_SC_SPC_LOCKDOWN_UNSUP:
287 return ("prohibition of command execution not supported");
288 case NVME_CQE_SC_SPC_UNSUP_IO_CMD:
289 return ("I/O command set not supported");
290 case NVME_CQE_SC_SPC_DIS_IO_CMD:
291 return ("I/O command set not enabled");
292 case NVME_CQE_SC_SPC_INV_CMD_COMBO:
293 return ("I/O command set combination rejected");
294 case NVME_CQE_SC_SPC_INV_IO_CMD:
295 return ("Invalid I/O command set");
296 case NVME_CQE_SC_SPC_UNAVAIL_ID:
297 return ("identifier unavailable");
298 case NVME_CQE_SC_SPC_DISPERSE_NS:
299 return ("namespace is dispersed");
300 case NVME_CQE_SC_SPC_INV_DISC:
301 return ("invalid discovery information");
302 case NVME_CQE_SC_SPC_ZONE_LOCKED:
303 return ("zoning data structure locked");
304 case NVME_CQE_SC_SPC_ZONE_ENOENT:
305 return ("zoning data structure not found");
306 case NVME_CQE_SC_SPC_DISC_RSRCS:
307 return ("insufficient discovery resources");
308 case NVME_CQE_SC_SPC_FUNC_DIS:
309 return ("requested function disabled");
310 case NVME_CQE_SC_SPC_INV_ZGRP_ORIG:
311 return ("zonegroup originator invalid");
312 case NVME_CQE_SC_SPC_INV_HOST:
313 return ("invalid host");
314 case NVME_CQE_SC_SPC_INV_NVM_SYS:
315 return ("invalid nvm subsystem");
316 case NVME_CQE_SC_SPC_INV_CTL_DQ:
317 return ("invalid controller data queue");
318 case NVME_CQE_SC_SPC_ERSRC:
319 return ("not enough resources");
320 case NVME_CQE_SC_SPC_CTL_SUSPEND:
321 return ("controller suspended");
322 case NVME_CQE_SC_SPC_CTL_NOT_SUSPEND:
323 return ("controller not suspended");
324 case NVME_CQE_SC_SPC_CTL_DQ_FULL:
325 return ("controller data queue full");
326 case NVME_CQE_SC_SPC_MAX_NS_SAN:
327 return ("request exceeds maximum namespace sanitize operations "
328 "in progress");
329 case NVME_CQE_SC_SPC_REQ_DEF_PERS:
330 return ("manufacturing default personality required");
331 case NVME_CQE_SC_SPC_INV_PLIMIT:
332 return ("invalid power limit");
333 case NVME_CQE_SC_SPC_XCTL_RST_PROG:
334 return ("cross-controller reset in progress");
335 case NVME_CQE_SC_SPC_XCTL_RST_LPF:
336 return ("cross-controller reset log page full");
337 case NVME_CQE_SC_SPC_XCTL_RST_LIM:
338 return ("cross-controller reset limit exceeded");
339 default:
340 return ("unknown generic command status code");
341 }
342 }
343
344 /*
345 * The NVMe 2.0c spec that introduces many of the zoned related errors has
346 * footnotes to suggest some of these are command set specific, but does not
347 * mark any of them. For the moment we basically assume that they're valid
348 * everywhere due to the fact that they don't overlap.
349 */
350 static const char *
nvme_sctostr_cmd_csi(nvme_csi_t csi,uint32_t sct)351 nvme_sctostr_cmd_csi(nvme_csi_t csi, uint32_t sct)
352 {
353 switch (sct) {
354 case NVME_CQE_SC_SPC_NVM_CNFL_ATTR:
355 return ("conflicting attributes");
356 case NVME_CQE_SC_SPC_NVM_INV_PROT:
357 return ("invalid protection");
358 case NVME_CQE_SC_SPC_NVM_READONLY:
359 return ("write to read only range");
360 case NVME_CQE_SC_SPC_INV_CID:
361 return ("invalid command id");
362 case NVME_CQE_SC_SPC_INCOMPAT_NS:
363 return ("incompatible namespace or format");
364 case NVME_CQE_SC_SPC_NO_FAST_COPY:
365 return ("fast copy not possible");
366 case NVME_CQE_SC_SPC_OVLP_IO:
367 return ("overlapping i/o range");
368 case NVME_CQE_SC_SPC_NS_UNREACH:
369 return ("namespace not reachable");
370 case NVME_CQE_SC_SPC_INSUF_RSRC:
371 return ("insufficient resources");
372 case NVME_CQE_SC_SPC_INSUF_PROG:
373 return ("insufficient program resources");
374 case NVME_CQE_SC_SPC_INV_MEM_NS:
375 return ("invalid memory namespace");
376 case NVME_CQE_SC_SPC_INV_MEM_RANGE:
377 return ("invalid memory range set");
378 case NVME_CQE_SC_SPC_INV_MEM_SETID:
379 return ("invalid memory range set identifier");
380 case NVME_CQE_SC_SPC_INV_PROG_DATA:
381 return ("invalid program data");
382 case NVME_CQE_SC_SPC_INV_PROG_IDX:
383 return ("invalid program index");
384 case NVME_CQE_SC_SPC_INV_PROG_TYPE:
385 return ("invalid program type");
386 case NVME_CQE_SC_SPC_MAX_MEM_RANGE:
387 return ("maximum memory ranges exceeded");
388 case NVME_CQE_SC_SPC_MAX_MEM_SETIDS:
389 return ("maximum memory range sets exceeded");
390 case NVME_CQE_SC_SPC_MAX_PROG_ACT:
391 return ("maximum programs activated");
392 case NVME_CQE_SC_SPC_MAX_PROG_BYTES:
393 return ("maximum program bytes exceeded");
394 case NVME_CQE_SC_SPC_MEM_SET_IN_USE:
395 return ("memory range set in use");
396 case NVME_CQE_SC_SPC_NO_PROG:
397 return ("no program");
398 case NVME_CQE_SC_SPC_OVLP_MEM_RANGE:
399 return ("overlapping memory ranges");
400 case NVME_CQE_SC_SPC_PROG_NOT_ACT:
401 return ("program not activated");
402 case NVME_CQE_SC_SPC_PROG_IN_USE:
403 return ("program in use");
404 case NVME_CQE_SC_SPC_PROG_IDX_NO_DL:
405 return ("program index not downloadable");
406 case NVME_CQE_SC_SPC_PROG_2BIG:
407 return ("program too big");
408 case NVME_CQE_SC_SPC_MEDIA_VERIF:
409 return ("successful media verification read");
410 case NVME_CQE_SC_SPC_ZONE_BDRY_ERR:
411 return ("zoned boundary error");
412 case NVME_CQE_SC_SPC_ZONE_FULL:
413 return ("zone is full");
414 case NVME_CQE_SC_SPC_ZONE_RDONLY:
415 return ("zone is read only");
416 case NVME_CQE_SC_SPC_ZONE_OFFLINE:
417 return ("zone is offline");
418 case NVME_CQE_SC_SPC_ZONE_INV_WRITE:
419 return ("zone invalid write");
420 case NVME_CQE_SC_SPC_ZONE_ACT:
421 return ("too many active zones");
422 case NVME_CQE_SC_SPC_ZONE_OPEN:
423 return ("too many open zones");
424 case NVME_CQE_SC_SPC_INV_ZONE_TRANS:
425 return ("invalid zone state transition");
426 default:
427 return ("unknown command specific, I/O command set specific "
428 "status code");
429 }
430 }
431
432 static const char *
nvme_sctostr_media(nvme_csi_t csi,uint32_t sct)433 nvme_sctostr_media(nvme_csi_t csi, uint32_t sct)
434 {
435 if (sct >= NVME_CQE_SC_VEND_MIN) {
436 return ("vendor specific media and data integrity status code");
437 }
438
439 /*
440 * Unlike NVMe 1.x, NVMe 2.x declares the following command set
441 * independent.
442 */
443 switch (sct) {
444 case NVME_CQE_SC_INT_NVM_WRITE:
445 return ("write fault");
446 case NVME_CQE_SC_INT_NVM_READ:
447 return ("unrecovered read error");
448 case NVME_CQE_SC_INT_NVM_GUARD:
449 return ("guard check error");
450 case NVME_CQE_SC_INT_NVM_APPL_TAG:
451 return ("application tag check err");
452 case NVME_CQE_SC_INT_NVM_REF_TAG:
453 return ("reference tag check err");
454 case NVME_CQE_SC_INT_NVM_ACCESS:
455 return ("access denied");
456 case NVME_CQE_SC_INT_NVM_TAG:
457 return ("end-to-end storage tag check error");
458 default:
459 break;
460 }
461
462 /*
463 * The only command-set specific values are currently defined for the
464 * NVM command set.
465 */
466 if (csi != NVME_CSI_NVM) {
467 return ("unknown media and data integrity status code");
468 }
469
470 switch (sct) {
471 case NVME_CQE_SC_INT_NVM_COMPARE:
472 return ("compare failure");
473 case NVME_CQE_SC_INT_NVM_DEALLOC:
474 return ("deallocated or unwritten logical block");
475 default:
476 return ("unknown media and data integrity status code");
477 }
478 }
479
480 static const char *
nvme_sctostr_path(uint32_t sct)481 nvme_sctostr_path(uint32_t sct)
482 {
483 switch (sct) {
484 case NVME_CQE_SC_PATH_INT_ERR:
485 return ("internal path error");
486 case NVME_CQE_SC_PATH_AA_PLOSS:
487 return ("asymmetric access persistent loss");
488 case NVME_CQE_SC_PATH_AA_INACC:
489 return ("asymmetric access inaccessible");
490 case NVME_CQE_SC_PATH_AA_TRANS:
491 return ("asymmetric access transition");
492 case NVME_CQE_SC_PATH_CTRL_ERR:
493 return ("controller pathing error");
494 case NVME_CQE_SC_PATH_HOST_ERR:
495 return ("host pathing error");
496 case NVME_CQE_SC_PATH_HOST_ABRT:
497 return ("command aborted by host");
498 default:
499 return ("unknown path related status code");
500 }
501 }
502
503 const char *
nvme_sctostr(nvme_ctrl_t * ctrl __unused,nvme_csi_t csi,uint32_t sct,uint32_t sc)504 nvme_sctostr(nvme_ctrl_t *ctrl __unused, nvme_csi_t csi, uint32_t sct,
505 uint32_t sc)
506 {
507 switch (sct) {
508 case NVME_CQE_SCT_GENERIC:
509 if (sc <= NVME_CQE_SC_GEN_MAX) {
510 return (nvme_sctostr_gen_gen(sc));
511 } else if (sc <= NVME_CQE_SC_CSI_MAX) {
512 return (nvme_sctostr_gen_csi(csi, sc));
513 } else {
514 return ("generic vendor specific status code");
515 }
516 case NVME_CQE_SCT_SPECIFIC:
517 if (sc <= NVME_CQE_SC_GEN_MAX) {
518 return (nvme_sctostr_cmd_gen(sc));
519 } else if (sc <= NVME_CQE_SC_CSI_MAX) {
520 return (nvme_sctostr_cmd_csi(csi, sc));
521 } else {
522 return ("command specific vendor specific status code");
523 }
524 case NVME_CQE_SCT_INTEGRITY:
525 return (nvme_sctostr_media(csi, sc));
526 case NVME_CQE_SCT_PATH:
527 return (nvme_sctostr_path(sc));
528 case NVME_CQE_SCT_VENDOR:
529 return ("vendor specific");
530 default:
531 return ("unknown status code");
532 }
533 }
534
535 nvme_err_t
nvme_err(nvme_t * nvme)536 nvme_err(nvme_t *nvme)
537 {
538 return (nvme->nh_err.ne_err);
539 }
540
541 int32_t
nvme_syserr(nvme_t * nvme)542 nvme_syserr(nvme_t *nvme)
543 {
544 return (nvme->nh_err.ne_syserr);
545 }
546
547 const char *
nvme_errmsg(nvme_t * nvme)548 nvme_errmsg(nvme_t *nvme)
549 {
550 return (nvme->nh_err.ne_errmsg);
551 }
552
553 size_t
nvme_errlen(nvme_t * nvme)554 nvme_errlen(nvme_t *nvme)
555 {
556 return (nvme->nh_err.ne_errlen);
557 }
558
559 const char *
nvme_errtostr(nvme_t * nvme,nvme_err_t err)560 nvme_errtostr(nvme_t *nvme, nvme_err_t err)
561 {
562 switch (err) {
563 case NVME_ERR_OK:
564 return ("NVME_ERR_OK");
565 case NVME_ERR_CONTROLLER:
566 return ("NVME_ERR_CONTROLLER");
567 case NVME_ERR_NO_MEM:
568 return ("NVME_ERR_NO_MEM");
569 case NVME_ERR_NO_DMA_MEM:
570 return ("NVME_ERR_NO_DMA_MEM");
571 case NVME_ERR_LIBDEVINFO:
572 return ("NVME_ERR_LIBDEVINFO");
573 case NVME_ERR_INTERNAL:
574 return ("NVME_ERR_INTERNAL");
575 case NVME_ERR_BAD_PTR:
576 return ("NVME_ERR_BAD_PTR");
577 case NVME_ERR_BAD_FLAG:
578 return ("NVME_ERR_BAD_FLAG");
579 case NVME_ERR_BAD_DEVI:
580 return ("NVME_ERR_BAD_DEVI");
581 case NVME_ERR_BAD_DEVI_PROP:
582 return ("NVME_ERR_BAD_DEVI_PROP");
583 case NVME_ERR_ILLEGAL_INSTANCE:
584 return ("NVME_ERR_ILLEGAL_INSTANCE");
585 case NVME_ERR_BAD_CONTROLLER:
586 return ("NVME_ERR_BAD_CONTROLLER");
587 case NVME_ERR_PRIVS:
588 return ("NVME_ERR_PRIVS");
589 case NVME_ERR_OPEN_DEV:
590 return ("NVME_ERR_OPEN_DEV");
591 case NVME_ERR_BAD_RESTORE:
592 return ("NVME_ERR_BAD_RESTORE");
593 case NVME_ERR_NS_RANGE:
594 return ("NVME_ERR_NS_RANGE");
595 case NVME_ERR_NS_UNUSE:
596 return ("NVME_ERR_NS_UNUSE");
597 case NVME_ERR_LOG_CSI_RANGE:
598 return ("NVME_ERR_LOG_CSI_RANGE");
599 case NVME_ERR_LOG_LID_RANGE:
600 return ("NVME_ERR_LOG_LID_RANGE");
601 case NVME_ERR_LOG_LSP_RANGE:
602 return ("NVME_ERR_LOG_LSP_RANGE");
603 case NVME_ERR_LOG_LSI_RANGE:
604 return ("NVME_ERR_LOG_LSI_RANGE");
605 case NVME_ERR_LOG_RAE_RANGE:
606 return ("NVME_ERR_LOG_RAE_RANGE");
607 case NVME_ERR_LOG_SIZE_RANGE:
608 return ("NVME_ERR_LOG_SIZE_RANGE");
609 case NVME_ERR_LOG_OFFSET_RANGE:
610 return ("NVME_ERR_LOG_OFFSET_RANGE");
611 case NVME_ERR_LOG_CSI_UNSUP:
612 return ("NVME_ERR_LOG_CSI_UNSUP");
613 case NVME_ERR_LOG_LSP_UNSUP:
614 return ("NVME_ERR_LOG_LSP_UNSUP");
615 case NVME_ERR_LOG_LSI_UNSUP:
616 return ("NVME_ERR_LOG_LSI_UNSUP");
617 case NVME_ERR_LOG_RAE_UNSUP:
618 return ("NVME_ERR_LOG_RAE_UNSUP");
619 case NVME_ERR_LOG_OFFSET_UNSUP:
620 return ("NVME_ERR_LOG_OFFSET_UNSUP");
621 case NVME_ERR_LOG_LSP_UNUSE:
622 return ("NVME_ERR_LOG_LSP_UNUSE");
623 case NVME_ERR_LOG_LSI_UNUSE:
624 return ("NVME_ERR_LOG_LSI_UNUSE");
625 case NVME_ERR_LOG_RAE_UNUSE:
626 return ("NVME_ERR_LOG_RAE_UNUSE");
627 case NVME_ERR_LOG_SCOPE_MISMATCH:
628 return ("NVME_ERR_LOG_SCOPE_MISMATCH");
629 case NVME_ERR_LOG_REQ_MISSING_FIELDS:
630 return ("NVME_ERR_LOG_REQ_MISSING_FIELDS");
631 case NVME_ERR_LOG_NAME_UNKNOWN:
632 return ("NVME_ERR_LOG_NAME_UNKNOWN");
633 case NVME_ERR_LOG_UNSUP_BY_DEV:
634 return ("NVME_ERR_LOG_UNSUP_BY_DEV");
635 case NVME_ERR_IDENTIFY_UNKNOWN:
636 return ("NVME_ERR_IDENTIFY_UNKNOWN");
637 case NVME_ERR_IDENTIFY_UNSUP_BY_DEV:
638 return ("NVME_ERR_IDENTIFY_UNSUP_BY_DEV");
639 case NVME_ERR_IDENTIFY_CTRLID_RANGE:
640 return ("NVME_ERR_IDENTIFY_CTRLID_RANGE");
641 case NVME_ERR_IDENTIFY_OUTPUT_RANGE:
642 return ("NVME_ERR_IDENTIFY_OUTPUT_RANGE");
643 case NVME_ERR_IDENTIFY_CTRLID_UNSUP:
644 return ("NVME_ERR_IDENTIFY_CTRLID_UNSUP");
645 case NVME_ERR_IDENTIFY_CTRLID_UNUSE:
646 return ("NVME_ERR_IDENTIFY_CTRLID_UNUSE");
647 case NVME_ERR_IDENTIFY_REQ_MISSING_FIELDS:
648 return ("NVME_ERR_IDENTIFY_REQ_MISSING_FIELDS");
649 case NVME_ERR_VUC_UNSUP_BY_DEV:
650 return ("NVME_ERR_VUC_UNSUP_BY_DEV");
651 case NVME_ERR_VUC_TIMEOUT_RANGE:
652 return ("NVME_ERR_VUC_TIMEOUT_RANGE");
653 case NVME_ERR_VUC_OPCODE_RANGE:
654 return ("NVME_ERR_VUC_OPCODE_RANGE");
655 case NVME_ERR_VUC_IMPACT_RANGE:
656 return ("NVME_ERR_VUC_IMPACT_RANGE");
657 case NVME_ERR_VUC_NDT_RANGE:
658 return ("NVME_ERR_VUC_NDT_RANGE");
659 case NVME_ERR_VUC_CANNOT_RW:
660 return ("NVME_ERR_VUC_CANNOT_RW");
661 case NVME_ERR_VUC_NO_RESULTS:
662 return ("NVME_ERR_VUC_NO_RESULTS");
663 case NVME_ERR_VUC_UNKNOWN:
664 return ("NVME_ERR_VUC_UNKNOWN");
665 case NVME_ERR_VUC_REQ_MISSING_FIELDS:
666 return ("NVME_ERR_VUC_REQ_MISSING_FIELDS");
667 case NVME_ERR_VU_FUNC_UNSUP_BY_DEV:
668 return ("NVME_ERR_VU_FUNC_UNSUP_BY_DEV");
669 case NVME_ERR_WDC_E6_OFFSET_RANGE:
670 return ("NVME_ERR_WDC_E6_OFFSET_RANGE");
671 case NVME_ERR_FW_UNSUP_BY_DEV:
672 return ("NVME_ERR_FW_UNSUP_BY_DEV");
673 case NVME_ERR_KERN_FW_IMPOS:
674 return ("NVME_ERR_KERN_FW_IMPOS");
675 case NVME_ERR_FW_LOAD_LEN_RANGE:
676 return ("NVME_ERR_FW_LOAD_LEN_RANGE");
677 case NVME_ERR_FW_LOAD_OFFSET_RANGE:
678 return ("NVME_ERR_FW_LOAD_OFFSET_RANGE");
679 case NVME_ERR_FW_COMMIT_SLOT_RANGE:
680 return ("NVME_ERR_FW_COMMIT_SLOT_RANGE");
681 case NVME_ERR_FW_COMMIT_ACTION_RANGE:
682 return ("NVME_ERR_FW_COMMIT_ACTION_RANGE");
683 case NVME_ERR_FW_COMMIT_REQ_MISSING_FIELDS:
684 return ("NVME_ERR_FW_COMMIT_REQ_MISSING_FIELDS");
685 case NVME_ERR_FW_SLOT_RO:
686 return ("NVME_ERR_FW_SLOT_RO");
687 case NVME_ERR_FORMAT_UNSUP_BY_DEV:
688 return ("NVME_ERR_FORMAT_UNSUP_BY_DEV");
689 case NVME_ERR_CRYPTO_SE_UNSUP_BY_DEV:
690 return ("NVME_ERR_CRYPTO_SE_UNSUP_BY_DEV");
691 case NVME_ERR_NS_FORMAT_UNSUP_BY_DEV:
692 return ("NVME_ERR_NS_FORMAT_UNSUP_BY_DEV");
693 case NVME_ERR_KERN_FORMAT_UNSUP:
694 return ("NVME_ERR_KERN_FORMAT_UNSUP");
695 case NVME_ERR_FORMAT_LBAF_RANGE:
696 return ("NVME_ERR_FORMAT_LBAF_RANGE");
697 case NVME_ERR_FORMAT_SES_RANGE:
698 return ("NVME_ERR_FORMAT_SES_RANGE");
699 case NVME_ERR_FORMAT_PARAM_UNSUP:
700 return ("NVME_ERR_FORMAT_PARAM_UNSUP");
701 case NVME_ERR_FORMAT_REQ_MISSING_FIELDS:
702 return ("NVME_ERR_FORMAT_REQ_MISSING_FIELDS");
703 case NVME_ERR_WDC_E6_REQ_MISSING_FIELDS:
704 return ("NVME_ERR_WDC_E6_REQ_MISSING_FIELDS");
705 case NVME_ERR_FEAT_NAME_UNKNOWN:
706 return ("NVME_ERR_FEAT_NAME_UNKNOWN");
707 case NVME_ERR_FEAT_UNSUP_BY_DEV:
708 return ("NVME_ERR_FEAT_UNSUP_BY_DEV");
709 case NVME_ERR_FEAT_FID_RANGE:
710 return ("NVME_ERR_FEAT_FID_RANGE");
711 case NVME_ERR_FEAT_SEL_RANGE:
712 return ("NVME_ERR_FEAT_SEL_RANGE");
713 case NVME_ERR_FEAT_CDW11_RANGE:
714 return ("NVME_ERR_FEAT_CDW11_RANGE");
715 case NVME_ERR_FEAT_DATA_RANGE:
716 return ("NVME_ERR_FEAT_DATA_RANGE");
717 case NVME_ERR_FEAT_SEL_UNSUP:
718 return ("NVME_ERR_FEAT_SEL_UNSUP");
719 case NVME_ERR_FEAT_CDW11_UNUSE:
720 return ("NVME_ERR_FEAT_CDW11_UNUSE");
721 case NVME_ERR_FEAT_DATA_UNUSE:
722 return ("NVME_ERR_FEAT_DATA_UNUSE");
723 case NVME_ERR_FEAT_NO_RESULTS:
724 return ("NVME_ERR_FEAT_NO_RESULTS");
725 case NVME_ERR_GET_FEAT_REQ_MISSING_FIELDS:
726 return ("NVME_ERR_GET_FEAT_REQ_MISSING_FIELDS");
727 case NVME_ERR_NEED_CTRL_WRLOCK:
728 return ("NVME_ERR_NEED_CTRL_WRLOCK");
729 case NVME_ERR_NEED_NS_WRLOCK:
730 return ("NVME_ERR_NEED_NS_WRLOCK");
731 case NVME_ERR_CTRL_LOCKED:
732 return ("NVME_ERR_CTRL_LOCKED");
733 case NVME_ERR_NS_LOCKED:
734 return ("NVME_ERR_NS_LOCKED");
735 case NVME_ERR_LOCK_PROG:
736 return ("NVME_ERR_LOCK_PROG");
737 case NVME_ERR_LOCK_ORDER:
738 return ("NVME_ERR_LOCK_ORDER");
739 case NVME_ERR_LOCK_WAIT_INTR:
740 return ("NVME_ERR_LOCK_WAIT_INTR");
741 case NVME_ERR_LOCK_WOULD_BLOCK:
742 return ("NVME_ERR_LOCK_WOULD_BLOCK");
743 case NVME_ERR_DETACH_KERN:
744 return ("NVME_ERR_DETACH_KERN");
745 case NVME_ERR_ATTACH_KERN:
746 return ("NVME_ERR_ATTACH_KERN");
747 case NVME_ERR_ATTACH_UNSUP_KERN:
748 return ("NVME_ERR_ATTACH_UNSUP_KERN");
749 case NVME_ERR_NS_BLKDEV_ATTACH:
750 return ("NVME_ERR_NS_BLKDEV_ATTACH");
751 case NVME_ERR_NO_KERN_MEM:
752 return ("NVME_ERR_NO_KERN_MEM");
753 case NVME_ERR_CTRL_DEAD:
754 return ("NVME_ERR_CTRL_DEAD");
755 case NVME_ERR_CTRL_GONE:
756 return ("NVME_ERR_CTRL_GONE");
757 case NVME_ERR_NS_MGMT_UNSUP_BY_DEV:
758 return ("NVME_ERR_NS_MGMT_UNSUP_BY_DEV");
759 case NVME_ERR_THIN_PROV_UNSUP_BY_DEV:
760 return ("NVME_ERR_THIN_PROV_UNSUP_BY_DEV");
761 case NVME_ERR_NS_ATTACH_REQ_MISSING_FIELDS:
762 return ("NVME_ERR_NS_ATTACH_REQ_MISSING_FIELDS");
763 case NVME_ERR_NS_CREATE_REQ_MISSING_FIELDS:
764 return ("NVME_ERR_NS_CREATE_REQ_MISSING_FIELDS");
765 case NVME_ERR_NS_DELETE_REQ_MISSING_FIELDS:
766 return ("NVME_ERR_NS_DELETE_REQ_MISSING_FIELDS");
767 case NVME_ERR_NS_CREATE_BAD_CSI:
768 return ("NVME_ERR_NS_CREATE_BAD_CSI");
769 case NVME_ERR_NS_ATTACH_BAD_SEL:
770 return ("NVME_ERR_NS_ATTACH_BAD_SEL");
771 case NVME_ERR_NS_CREATE_NO_RESULTS:
772 return ("NVME_ERR_NS_CREATE_NO_RESULTS");
773 case NVME_ERR_NS_CREATE_NCAP_RANGE:
774 return ("NVME_ERR_NS_CREATE_NCAP_RANGE");
775 case NVME_ERR_NS_CREATE_NSZE_RANGE:
776 return ("NVME_ERR_NS_CREATE_NSZE_RANGE");
777 case NVME_ERR_NS_CREATE_NMIC_RANGE:
778 return ("NVME_ERR_NS_CREATE_NMIC_RANGE");
779 case NVME_ERR_NS_CREATE_FLBAS_RANGE:
780 return ("NVME_ERR_NS_CREATE_FLBAS_RANGE");
781 case NVME_ERR_NS_CTRL_ATTACHED:
782 return ("NVME_ERR_NS_CTRL_ATTACHED");
783 case NVME_ERR_NS_CTRL_NOT_ATTACHED:
784 return ("NVME_ERR_NS_CTRL_NOT_ATTACHED");
785 case NVME_ERR_NS_UNALLOC:
786 return ("NVME_ERR_NS_UNALLOC");
787 case NVME_ERR_PCIE_LANE_RANGE:
788 return ("NVME_ERR_PCIE_LANE_RANGE");
789 case NVME_ERR_PCIE_EYE_BUF_RANGE:
790 return ("NVME_ERR_PCIE_EYE_BUF_RANGE");
791 default:
792 return ("unknown error");
793 }
794 }
795
796 nvme_err_t
nvme_ctrl_err(nvme_ctrl_t * ctrl)797 nvme_ctrl_err(nvme_ctrl_t *ctrl)
798 {
799 return (ctrl->nc_err.ne_err);
800 }
801
802 int32_t
nvme_ctrl_syserr(nvme_ctrl_t * ctrl)803 nvme_ctrl_syserr(nvme_ctrl_t *ctrl)
804 {
805 return (ctrl->nc_err.ne_syserr);
806 }
807
808 const char *
nvme_ctrl_errmsg(nvme_ctrl_t * ctrl)809 nvme_ctrl_errmsg(nvme_ctrl_t *ctrl)
810 {
811 return (ctrl->nc_err.ne_errmsg);
812 }
813
814 size_t
nvme_ctrl_errlen(nvme_ctrl_t * ctrl)815 nvme_ctrl_errlen(nvme_ctrl_t *ctrl)
816 {
817 return (ctrl->nc_err.ne_errlen);
818 }
819
820 void
nvme_ctrl_deverr(nvme_ctrl_t * ctrl,uint32_t * sct,uint32_t * sc)821 nvme_ctrl_deverr(nvme_ctrl_t *ctrl, uint32_t *sct, uint32_t *sc)
822 {
823 if (sct != NULL) {
824 *sct = ctrl->nc_err.ne_ctrl_sct;
825 }
826
827 if (sc != NULL) {
828 *sc = ctrl->nc_err.ne_ctrl_sc;
829 }
830 }
831
832 const char *
nvme_ctrl_errtostr(nvme_ctrl_t * ctrl,nvme_err_t err)833 nvme_ctrl_errtostr(nvme_ctrl_t *ctrl, nvme_err_t err)
834 {
835 return (nvme_errtostr(ctrl->nc_nvme, err));
836 }
837
838 static void
nvme_error_common(nvme_err_data_t * ep,nvme_err_t err,int32_t sys,const char * fmt,va_list ap)839 nvme_error_common(nvme_err_data_t *ep, nvme_err_t err, int32_t sys,
840 const char *fmt, va_list ap)
841 {
842 int ret;
843
844 ep->ne_err = err;
845 ep->ne_syserr = sys;
846 ep->ne_ctrl_sct = 0;
847 ep->ne_ctrl_sc = 0;
848 ret = vsnprintf(ep->ne_errmsg,
849 sizeof (ep->ne_errmsg), fmt, ap);
850 if (ret >= sizeof (ep->ne_errmsg)) {
851 ep->ne_errlen = sizeof (ep->ne_errmsg) - 1;
852 } else if (ret <= 0) {
853 ep->ne_errlen = 0;
854 ep->ne_errmsg[0] = '\0';
855 } else {
856 ep->ne_errlen = (size_t)ret;
857 }
858 }
859
860 bool
nvme_error(nvme_t * nvme,nvme_err_t err,int32_t sys,const char * fmt,...)861 nvme_error(nvme_t *nvme, nvme_err_t err, int32_t sys, const char *fmt, ...)
862 {
863 va_list ap;
864
865 va_start(ap, fmt);
866 nvme_error_common(&nvme->nh_err, err, sys, fmt, ap);
867 va_end(ap);
868
869 return (false);
870 }
871
872 bool
nvme_ctrl_error(nvme_ctrl_t * ctrl,nvme_err_t err,int32_t sys,const char * fmt,...)873 nvme_ctrl_error(nvme_ctrl_t *ctrl, nvme_err_t err, int32_t sys,
874 const char *fmt, ...)
875 {
876 va_list ap;
877
878 va_start(ap, fmt);
879 nvme_error_common(&ctrl->nc_err, err, sys, fmt, ap);
880 va_end(ap);
881
882 return (false);
883 }
884
885 static bool
nvme_success_common(nvme_err_data_t * err)886 nvme_success_common(nvme_err_data_t *err)
887 {
888 err->ne_err = NVME_ERR_OK;
889 err->ne_syserr = 0;
890 err->ne_ctrl_sct = 0;
891 err->ne_ctrl_sc = 0;
892 err->ne_errmsg[0] = '\0';
893 err->ne_errlen = 0;
894
895 return (true);
896 }
897
898 bool
nvme_success(nvme_t * nvme)899 nvme_success(nvme_t *nvme)
900 {
901 return (nvme_success_common(&nvme->nh_err));
902 }
903
904 bool
nvme_ctrl_success(nvme_ctrl_t * ctrl)905 nvme_ctrl_success(nvme_ctrl_t *ctrl)
906 {
907 return (nvme_success_common(&ctrl->nc_err));
908 }
909
910 void
nvme_err_save(const nvme_t * nvme,nvme_err_data_t * out)911 nvme_err_save(const nvme_t *nvme, nvme_err_data_t *out)
912 {
913 *out = nvme->nh_err;
914 }
915
916 void
nvme_err_set(nvme_t * nvme,const nvme_err_data_t * err)917 nvme_err_set(nvme_t *nvme, const nvme_err_data_t *err)
918 {
919 nvme->nh_err = *err;
920 }
921
922 void
nvme_ctrl_err_save(const nvme_ctrl_t * ctrl,nvme_err_data_t * out)923 nvme_ctrl_err_save(const nvme_ctrl_t *ctrl, nvme_err_data_t *out)
924 {
925 *out = ctrl->nc_err;
926 }
927
928 void
nvme_ctrl_err_set(nvme_ctrl_t * ctrl,const nvme_err_data_t * err)929 nvme_ctrl_err_set(nvme_ctrl_t *ctrl, const nvme_err_data_t *err)
930 {
931 ctrl->nc_err = *err;
932 }
933
934 /*
935 * This table deals with mapping a kernel error to a library error and provides
936 * a short description of what it is. Note, we do not expect all kernel errors
937 * to occur and we may want to revisit which of these end up indicating a
938 * programmer error that we caused somehow.
939 */
940 typedef struct {
941 nvme_ioctl_errno_t kl_kern;
942 nvme_err_t kl_lib;
943 const char *kl_desc;
944 } nvme_ktolmap_t;
945
946 /*
947 * Please keep this table ordered based on the nvme_ioctl_error_t enumeration
948 * order. This is not required for correctness, but helps when scanning for
949 * missing entries. Please document why certain entries are skipped.
950 */
951 static const nvme_ktolmap_t nvme_ktolmap[] = {
952 /*
953 * NVME_IOCTL_E_OK and NVME_IOCTL_E_CTRL_ERROR should already have been
954 * dealt with and shouldn't be included here.
955 */
956 { NVME_IOCTL_E_CTRL_DEAD, NVME_ERR_CTRL_DEAD, "the controller is no "
957 "longer usable by the system" },
958 { NVME_IOCTL_E_CTRL_GONE, NVME_ERR_CTRL_GONE, "the controller has been "
959 "physically removed from the system" },
960 { NVME_IOCTL_E_NS_RANGE, NVME_ERR_NS_RANGE, "invalid namespace "
961 "requested" },
962 { NVME_IOCTL_E_NS_UNUSE, NVME_ERR_NS_UNUSE, "a namespace ID may not be "
963 "specified in this context" },
964 /*
965 * We have purposefully skipped NVME_IOCTL_E_MINOR_WRONG_NS and
966 * NVME_IOCTL_E_NOT_CTRL as the library should not ever use the
967 * namespace minor.
968 */
969 { NVME_IOCTL_E_NO_BCAST_NS, NVME_ERR_NS_RANGE, "the broadcast "
970 "namespace may not be used in this context" },
971 { NVME_IOCTL_E_NEED_CTRL_WRLOCK, NVME_ERR_NEED_CTRL_WRLOCK, "operation "
972 "requires a controller write lock, but it is not owned" },
973 { NVME_IOCTL_E_NEED_NS_WRLOCK, NVME_ERR_NEED_NS_WRLOCK, "operation "
974 "requires a namespace write lock, but it is not owned" },
975 { NVME_IOCTL_E_CTRL_LOCKED, NVME_ERR_CTRL_LOCKED, "controller locked" },
976 { NVME_IOCTL_E_NS_LOCKED, NVME_ERR_NS_LOCKED, "namespace locked" },
977 /*
978 * We have purposefully skipped NVME_IOCTL_E_UNKNOWN_LOG_PAGE as in
979 * theory the library and kernel should be in sync with the set of known
980 * log pages. If it is out of sync due to someone distributing the two
981 * weirdly or a bad build, we'd rather that end up as an internal error
982 * rather than a first class error for users.
983 */
984 { NVME_IOCTL_E_UNSUP_LOG_PAGE, NVME_ERR_LOG_UNSUP_BY_DEV, "controller "
985 "does not support the specified log page" },
986 { NVME_IOCTL_E_BAD_LOG_SCOPE, NVME_ERR_LOG_SCOPE_MISMATCH, "log page "
987 "does not work with the requested scope" },
988 { NVME_IOCTL_E_LOG_CSI_RANGE, NVME_ERR_LOG_CSI_RANGE, "invalid command "
989 "set interface value" },
990 { NVME_IOCTL_E_LOG_LID_RANGE, NVME_ERR_LOG_LID_RANGE, "invalid log "
991 "identifier value" },
992 { NVME_IOCTL_E_LOG_LSP_RANGE, NVME_ERR_LOG_LSP_RANGE, "invalid log "
993 "specific parameter value" },
994 { NVME_IOCTL_E_LOG_LSI_RANGE, NVME_ERR_LOG_LSI_RANGE, "invalid log "
995 "specific identifier value" },
996 { NVME_IOCTL_E_LOG_RAE_RANGE, NVME_ERR_LOG_SIZE_RANGE, "invalid retain "
997 "asynchronous event value" },
998 { NVME_IOCTL_E_LOG_SIZE_RANGE, NVME_ERR_LOG_SIZE_RANGE, "invalid log "
999 "length value" },
1000 { NVME_IOCTL_E_LOG_OFFSET_RANGE, NVME_ERR_LOG_OFFSET_RANGE, "invalid "
1001 "log offset value" },
1002 { NVME_IOCTL_E_LOG_CSI_UNSUP, NVME_ERR_LOG_CSI_UNSUP,
1003 "the controller does not support specifying the csi" },
1004 { NVME_IOCTL_E_LOG_LSP_UNSUP, NVME_ERR_LOG_LSP_UNSUP,
1005 "the controller does not support specifying the lsp" },
1006 { NVME_IOCTL_E_LOG_LSI_UNSUP, NVME_ERR_LOG_LSI_UNSUP,
1007 "or controller do not support specifying the lsi" },
1008 { NVME_IOCTL_E_LOG_RAE_UNSUP, NVME_ERR_LOG_RAE_UNSUP,
1009 "the controller does not support retaining an asynchronous event" },
1010 { NVME_IOCTL_E_LOG_OFFSET_UNSUP, NVME_ERR_LOG_OFFSET_UNSUP,
1011 "the controller do not support specifying a a read offset" },
1012 { NVME_IOCTL_E_LOG_LSP_UNUSE, NVME_ERR_LOG_LSP_UNUSE, "the log page "
1013 "does not allow the lsp to be used" },
1014 { NVME_IOCTL_E_LOG_LSI_UNUSE, NVME_ERR_LOG_LSI_UNUSE, "the log page "
1015 "does not allow the lsi to be used" },
1016 { NVME_IOCTL_E_LOG_RAE_UNUSE, NVME_ERR_LOG_RAE_UNUSE, "the log page "
1017 "does not allow rae to be set" },
1018 { NVME_IOCTL_E_NO_DMA_MEM, NVME_ERR_NO_DMA_MEM, "the kernel failed to "
1019 "allocate sufficient DMA resources" },
1020 { NVME_IOCTL_E_NO_KERN_MEM, NVME_ERR_NO_KERN_MEM, "the kernel failed "
1021 "to allocate sufficient memory for this operation" },
1022 { NVME_IOCTL_E_BAD_PRP, NVME_ERR_INTERNAL, "a driver error occurred "
1023 "while filling out the command's DMA resources" },
1024 { NVME_IOCTL_E_BAD_USER_DATA, NVME_ERR_BAD_PTR, "the kernel "
1025 "detected an invalid user buffer while trying to read/write the "
1026 "passed in data buffer" },
1027 { NVME_IOCTL_E_UNKNOWN_IDENTIFY, NVME_ERR_IDENTIFY_UNKNOWN, "unknown "
1028 "identify command requested" },
1029 { NVME_IOCTL_E_UNSUP_IDENTIFY, NVME_ERR_IDENTIFY_UNSUP_BY_DEV,
1030 "controller does not support the requested identify command" },
1031 { NVME_IOCTL_E_IDENTIFY_CTRLID_RANGE, NVME_ERR_IDENTIFY_CTRLID_RANGE,
1032 "invalid controller id value" },
1033 { NVME_IOCTL_E_IDENTIFY_CTRLID_UNSUP, NVME_ERR_IDENTIFY_CTRLID_UNSUP,
1034 "the controller does not support specifying the controller ID" },
1035 { NVME_IOCTL_E_IDENTIFY_CTRLID_UNUSE, NVME_ERR_IDENTIFY_CTRLID_UNUSE,
1036 "this specific identify request does not allow setting the "
1037 "controller id" },
1038 { NVME_IOCTL_E_CTRL_VUC_UNSUP, NVME_ERR_VUC_UNSUP_BY_DEV,
1039 "the controller does not support standard NVMe vendor unique "
1040 "commands" },
1041 /*
1042 * The following indicate bad values for given NVMe vendor unique
1043 * command fields. Note, we do not include an entry for
1044 * NVME_IOCTL_E_VUC_FLAGS_RANGE because these flags are entirely owned
1045 * by the library.
1046 */
1047 { NVME_IOCTL_E_VUC_TIMEOUT_RANGE, NVME_ERR_VUC_TIMEOUT_RANGE, "invalid "
1048 "command timeout value" },
1049 { NVME_IOCTL_E_VUC_OPCODE_RANGE, NVME_ERR_VUC_OPCODE_RANGE, "invalid "
1050 "vendor unique opcode specified" },
1051 { NVME_IOCTL_E_VUC_IMPACT_RANGE, NVME_ERR_VUC_IMPACT_RANGE, "invalid "
1052 "vendor unique impact specified" },
1053 { NVME_IOCTL_E_VUC_NDT_RANGE, NVME_ERR_VUC_NDT_RANGE, "invalid "
1054 "data transfer size specified" },
1055 /*
1056 * We skip NVME_IOCTL_E_INCONSIST_VUC_FLAGS_NDT and
1057 * NVME_IOCTL_E_INCONSIST_VUC_BUF_NDT because these are solely under the
1058 * library control and would indicate a programming error at our end.
1059 * The user shouldn't be able to cause this.
1060 */
1061 { NVME_IOCTL_E_BLKDEV_DETACH, NVME_ERR_DETACH_KERN, "the kernel failed "
1062 "to detach the requested namespace" },
1063 { NVME_IOCTL_E_BLKDEV_ATTACH, NVME_ERR_ATTACH_KERN, "the kernel failed "
1064 "to attach the requested namespace" },
1065 { NVME_IOCTL_E_UNSUP_ATTACH_NS, NVME_ERR_ATTACH_UNSUP_KERN,
1066 "the namespace is not supported by the kernel" },
1067 { NVME_IOCTL_E_CTRL_FORMAT_UNSUP, NVME_ERR_FORMAT_UNSUP_BY_DEV, "the "
1068 "controller does not support formatting namespaces" },
1069 { NVME_IOCTL_E_CTRL_CRYPTO_SE_UNSUP, NVME_ERR_CRYPTO_SE_UNSUP_BY_DEV,
1070 "the controller does not support cryptographic secure erase" },
1071 { NVME_IOCTL_E_CTRL_NS_FORMAT_UNSUP, NVME_ERR_NS_FORMAT_UNSUP_BY_DEV,
1072 "the controller cannot format a single namespace" },
1073 { NVME_IOCTL_E_CTRL_NS_SE_UNSUP, NVME_ERR_NS_FORMAT_UNSUP_BY_DEV,
1074 "the controller cannot secure erase a single namespace" },
1075 { NVME_IOCTL_E_FORMAT_LBAF_RANGE, NVME_ERR_FORMAT_LBAF_RANGE,
1076 "invalid LBA format value" },
1077 { NVME_IOCTL_E_FORMAT_SES_RANGE, NVME_ERR_FORMAT_SES_RANGE,
1078 "invalid secure erase settings value" },
1079 { NVME_IOCTL_E_UNSUP_LBAF_META, NVME_ERR_KERN_FORMAT_UNSUP, "cannot "
1080 "format due to the use of unsupported metadata sectors" },
1081 { NVME_IOCTL_E_CTRL_FW_UNSUP, NVME_ERR_FW_UNSUP_BY_DEV, "the "
1082 "controller does not support firmware commands" },
1083 { NVME_IOCTL_E_FW_LOAD_IMPOS_GRAN, NVME_ERR_KERN_FW_IMPOS, "controller "
1084 "reported firmware upgrade granularity does not work with the "
1085 "calculated maximum DMA transfer size" },
1086 { NVME_IOCTL_E_FW_LOAD_LEN_RANGE, NVME_ERR_FW_LOAD_LEN_RANGE,
1087 "invalid firmware load length value" },
1088 { NVME_IOCTL_E_FW_LOAD_OFFSET_RANGE, NVME_ERR_FW_LOAD_OFFSET_RANGE,
1089 "invalid firmware load offset value" },
1090 { NVME_IOCTL_E_FW_COMMIT_SLOT_RANGE, NVME_ERR_FW_COMMIT_SLOT_RANGE,
1091 "invalid firmware commit slot value" },
1092 { NVME_IOCTL_E_FW_COMMIT_ACTION_RANGE, NVME_ERR_FW_COMMIT_ACTION_RANGE,
1093 "invalid firmware commit action value" },
1094 { NVME_IOCTL_E_RO_FW_SLOT, NVME_ERR_FW_SLOT_RO, "cannot write to read-"
1095 "only slot" },
1096 /*
1097 * We have purposefully skipped NVME_IOCTL_E_UNKNOWN_FEATURE for the
1098 * same reasons we did with NVME_IOCTL_E_UNKNOWN_LOG above.
1099 */
1100 { NVME_IOCTL_E_UNSUP_FEATURE, NVME_ERR_FEAT_UNSUP_BY_DEV, "the "
1101 "controller does not supported the requested feature" },
1102 { NVME_IOCTL_E_GET_FEAT_SEL_RANGE, NVME_ERR_FEAT_SEL_RANGE, "invalid "
1103 "feature selector value" },
1104 { NVME_IOCTL_E_GET_FEAT_CDW11_RANGE, NVME_ERR_FEAT_CDW11_RANGE,
1105 "invalid feature-specific cdw11 value" },
1106 { NVME_IOCTL_E_GET_FEAT_DATA_RANGE, NVME_ERR_FEAT_DATA_RANGE, "invalid "
1107 "feature data, likely a size mismatch" },
1108 { NVME_IOCTL_E_GET_FEAT_SEL_UNSUP, NVME_ERR_FEAT_SEL_UNSUP, "the "
1109 "controller does not support specifying a feature selector" },
1110 { NVME_IOCTL_E_GET_FEAT_CDW11_UNUSE, NVME_ERR_FEAT_CDW11_UNUSE,
1111 "the feature does not support specifying a cdw11 argument" },
1112 { NVME_IOCTL_E_GET_FEAT_DATA_UNUSE, NVME_ERR_FEAT_DATA_UNUSE,
1113 "the feature does not support specifying a data buffer" },
1114 /*
1115 * We skip the NVME_IOCTL_E_BAD_LOCK_ENTITY,
1116 * NVME_IOCTL_E_BAD_LOCK_LEVEL, and NVME_IOCTL_E_BAD_LOCK_FLAGS
1117 * arguments as these are all generally passed by the library and not
1118 * really under direct user control. Therefore if there is a problem,
1119 * that should be an internal error.
1120 *
1121 * Similarly we skip NVME_IOCTL_E_NS_CANNOT_LOCK_CTRL and
1122 * NVME_IOCTL_E_NS_CANNOT_UNLOCK_CTRL because the library does not
1123 * utilize namespace minors and these can only apply to those.
1124 */
1125 { NVME_IOCTL_E_LOCK_ALREADY_HELD, NVME_ERR_LOCK_PROG, "fatal "
1126 "programmer error: recursive lock attempt" },
1127 { NVME_IOCTL_E_LOCK_NO_CTRL_WITH_NS, NVME_ERR_LOCK_ORDER,
1128 "control locks cannot be acquired while holding a namespace lock" },
1129 { NVME_IOCTL_LOCK_NO_NS_WITH_CTRL_WRLOCK, NVME_ERR_LOCK_ORDER,
1130 "no namespace locks may be acquired while holding a controller "
1131 "write lock" },
1132 { NVME_IOCTL_E_LOCK_NO_2ND_NS, NVME_ERR_LOCK_ORDER, "only a single "
1133 "namespace lock can be held at any time" },
1134 { NVME_IOCTL_E_LOCK_WAIT_SIGNAL, NVME_ERR_LOCK_WAIT_INTR, "signal "
1135 "received while blocking" },
1136 { NVME_IOCTL_E_LOCK_WOULD_BLOCK, NVME_ERR_LOCK_WOULD_BLOCK, "lock not "
1137 "available and no blocking allowed" },
1138 { NVME_IOCTL_E_LOCK_PENDING, NVME_ERR_LOCK_ORDER, "a handle may only "
1139 "block on one lock at a time" },
1140 { NVME_IOCTL_E_LOCK_NOT_HELD, NVME_ERR_LOCK_PROG, "fatal "
1141 "programmer error: asked to unlock lock that was not held" },
1142 /*
1143 * This error is almost a can't happen due to the library construction
1144 * and should result in the above error, but if this does happen, we
1145 * treat this as a fatal lock error regardless.
1146 */
1147 { NVME_IOCTL_E_LOCK_WRONG_NS, NVME_ERR_LOCK_PROG, "fatal "
1148 "programmer error: asked to unlock namespace lock that was not "
1149 "held" },
1150 { NVME_IOCTL_E_NS_BLKDEV_ATTACH, NVME_ERR_NS_BLKDEV_ATTACH, "cannot "
1151 "execute request while blkdev is attached to the namespace" },
1152 /*
1153 * We purposefully skip NVME_IOCTL_E_BD_ADDR_OVER right now because
1154 * there is nothing that a user can do about this. This is a
1155 * libnvme/kernel interface issue.
1156 */
1157 { NVME_IOCTL_E_CTRL_NS_MGMT_UNSUP, NVME_ERR_NS_MGMT_UNSUP_BY_DEV,
1158 "controller does not support namespace management" },
1159 { NVME_IOCTL_E_NS_CTRL_ATTACHED, NVME_ERR_NS_CTRL_ATTACHED,
1160 "cannot execute request against an attached namespace" },
1161 { NVME_IOCTL_E_NS_CTRL_NOT_ATTACHED, NVME_ERR_NS_CTRL_NOT_ATTACHED,
1162 "cannot execute request against an unattached namespace" },
1163 { NVME_IOCTL_E_NS_NO_NS, NVME_ERR_NS_UNALLOC, "cannot execute request "
1164 "against an unallocated namespace" },
1165 { NVME_IOCTL_E_NS_CREATE_NSZE_RANGE, NVME_ERR_NS_CREATE_NSZE_RANGE,
1166 "invalid namespace create size specified" },
1167 { NVME_IOCTL_E_NS_CREATE_NCAP_RANGE, NVME_ERR_NS_CREATE_NCAP_RANGE,
1168 "invalid namespace create capacity specified" },
1169 /*
1170 * Right now the library only has a single error for an invalid CSI on
1171 * namespace create regardless of the reason.
1172 */
1173 { NVME_IOCTL_E_NS_CREATE_CSI_RANGE, NVME_ERR_NS_CREATE_BAD_CSI,
1174 "invalid namespace create command set identifier specified" },
1175 { NVME_IOCTL_E_NS_CREATE_FLBAS_RANGE, NVME_ERR_NS_CREATE_FLBAS_RANGE,
1176 "invalid namespace create LBA format specified" },
1177 { NVME_IOCTL_E_NS_CREATE_NMIC_RANGE, NVME_ERR_NS_CREATE_NMIC_RANGE,
1178 "invalid namespace multi-path and sharing capability specified" },
1179 { NVME_IOCTL_E_NS_CREATE_CSI_UNSUP, NVME_ERR_NS_CREATE_BAD_CSI, "the "
1180 "controller does not support specifying a CSI when creating "
1181 "namespaces" },
1182 { NVME_IOCTL_E_DRV_CSI_UNSUP, NVME_ERR_NS_CREATE_BAD_CSI, "the nvme "
1183 "driver does not supporting CSIs with that value" },
1184 { NVME_IOCTL_E_CTRL_THIN_PROV_UNSUP, NVME_ERR_THIN_PROV_UNSUP_BY_DEV,
1185 "controller does not support thin provisioning of namespaces" },
1186 };
1187
1188 /*
1189 * Translate a kernel ioctl error into the library's error. We handle the
1190 * controller error separately. Otherwise, everything else is done based upon
1191 * our translation table.
1192 */
1193 bool
nvme_ioctl_error(nvme_ctrl_t * ctrl,const nvme_ioctl_common_t * ioc,const char * desc)1194 nvme_ioctl_error(nvme_ctrl_t *ctrl, const nvme_ioctl_common_t *ioc,
1195 const char *desc)
1196 {
1197 int ret;
1198 nvme_err_data_t *err = &ctrl->nc_err;
1199 VERIFY3U(ioc->nioc_drv_err, !=, NVME_IOCTL_E_OK);
1200
1201 err->ne_syserr = 0;
1202 err->ne_ctrl_sct = 0;
1203 err->ne_ctrl_sc = 0;
1204
1205 if (ioc->nioc_drv_err == NVME_IOCTL_E_CTRL_ERROR) {
1206 const char *sct, *sc;
1207 err->ne_err = NVME_ERR_CONTROLLER;
1208 err->ne_ctrl_sct = ioc->nioc_ctrl_sct;
1209 err->ne_ctrl_sc = ioc->nioc_ctrl_sc;
1210 sct = nvme_scttostr(ctrl, ioc->nioc_ctrl_sct);
1211 sc = nvme_sctostr(ctrl, NVME_CSI_NVM, ioc->nioc_ctrl_sct,
1212 ioc->nioc_ctrl_sc);
1213 ret = snprintf(err->ne_errmsg, sizeof (err->ne_errmsg),
1214 "failed to execute %s command: received controller error "
1215 "sct/sc %s/%s (0x%x/0x%x)", desc, sct, sc,
1216 ioc->nioc_ctrl_sct, ioc->nioc_ctrl_sc);
1217 } else {
1218 const nvme_ktolmap_t *map = NULL;
1219 for (size_t i = 0; i < ARRAY_SIZE(nvme_ktolmap); i++) {
1220 if (nvme_ktolmap[i].kl_kern == ioc->nioc_drv_err) {
1221 map = &nvme_ktolmap[i];
1222 break;
1223 }
1224 }
1225
1226 if (map != NULL) {
1227 err->ne_err = map->kl_lib;
1228 ret = snprintf(err->ne_errmsg, sizeof (err->ne_errmsg),
1229 "failed to execute %s command: %s", desc,
1230 map->kl_desc);
1231 } else {
1232 err->ne_err = NVME_ERR_INTERNAL;
1233 ret = snprintf(err->ne_errmsg, sizeof (err->ne_errmsg),
1234 "failed to execute %s command: failed to map "
1235 "kernel error 0x%x to a known cause", desc,
1236 ioc->nioc_drv_err);
1237 }
1238 }
1239
1240 if (ret >= sizeof (err->ne_errmsg)) {
1241 err->ne_errlen = sizeof (err->ne_errmsg) - 1;
1242 } else if (ret <= 0) {
1243 err->ne_errlen = 0;
1244 err->ne_errmsg[0] = '\0';
1245 } else {
1246 err->ne_errlen = (size_t)ret;
1247 }
1248
1249 return (false);
1250 }
1251
1252 /*
1253 * Evaluate the set of ioctl errors that we see and translate and/or abort a few
1254 * of the expected values. Most things will end up being translated into a
1255 * generic internal error as we expect a rather tight error set at this point.
1256 *
1257 * We choose to panic on EFAULT because we are responsible for all such EFAULT
1258 * errors. These are structure that are coming from the library. This is not
1259 * something that the user could have passed us (their buffers will trigger
1260 * an explicit nvme_ioctl_errno_t). Therefore, something has gone very wrong
1261 * with our stack or we just corrupted some memory.
1262 *
1263 * The same is true with EBADF. In this case, that'd happen either because our
1264 * controller fd was bandit'd away by someone or somehow we lost FREAD or FWRITE
1265 * on the fd. That should not be possible assuming everyone is acting in good
1266 * faith, so we treat this as a sign that something quite bad has happened and
1267 * we shouldn't continue.
1268 */
1269 bool
nvme_ioctl_syserror(nvme_ctrl_t * ctrl,int err,const char * desc)1270 nvme_ioctl_syserror(nvme_ctrl_t *ctrl, int err, const char *desc)
1271 {
1272 switch (err) {
1273 case EFAULT:
1274 case EBADF: {
1275 const char *base = "fatal libnvme internal programming error: "
1276 "failed to issue ioctl";
1277 char msg[1024];
1278 int ret;
1279 const char *up;
1280 size_t ulen;
1281
1282 ret = snprintf(msg, sizeof (msg), "%s %s: %s (controller %p)",
1283 base, desc, strerror(err), ctrl);
1284 if (ret >= sizeof (msg)) {
1285 ulen = sizeof (msg);
1286 up = msg;
1287 } else if (ret <= 0) {
1288 up = base;
1289 ulen = strlen(base) + 1;
1290 } else {
1291 ulen = (size_t)ret;
1292 up = msg;
1293 }
1294
1295 upanic(up, ulen);
1296 }
1297 case EPERM:
1298 return (nvme_ctrl_error(ctrl, NVME_ERR_PRIVS, err,
1299 "failed to issue %s ioctl due to missing privileges",
1300 desc));
1301 default:
1302 return (nvme_ctrl_error(ctrl, NVME_ERR_INTERNAL, err,
1303 "failed to issue %s ioctl due to unexpected system "
1304 "error: %s", desc, strerror(err)));
1305 }
1306 }
1307
1308 /*
1309 * Generate the standard warning about which fields are unused.
1310 */
1311 bool
nvme_field_miss_err(nvme_ctrl_t * ctrl,const nvme_field_info_t * fields,size_t nfields,nvme_err_t err,const char * desc,uint32_t val)1312 nvme_field_miss_err(nvme_ctrl_t *ctrl, const nvme_field_info_t *fields,
1313 size_t nfields, nvme_err_t err, const char *desc, uint32_t val)
1314 {
1315 char buf[512];
1316 bool comma = false;
1317
1318 VERIFY3U(val, !=, 0);
1319 buf[0] = '\0';
1320 for (size_t i = 0; i < nfields; i++) {
1321 if ((val & (1 << i)) == 0) {
1322 continue;
1323 }
1324
1325 if (comma) {
1326 (void) strlcat(buf, ",", sizeof (buf));
1327 }
1328 (void) strlcat(buf, fields[i].nlfi_spec, sizeof (buf));
1329 comma = true;
1330 }
1331
1332 return (nvme_ctrl_error(ctrl, err, 0, "cannot execute %s request due "
1333 "to missing fields: %s", desc, buf));
1334 }
1335
1336 bool
nvme_field_check_one(nvme_ctrl_t * ctrl,uint64_t val,const char * req,const nvme_field_check_t * check,uint32_t allow)1337 nvme_field_check_one(nvme_ctrl_t *ctrl, uint64_t val, const char *req,
1338 const nvme_field_check_t *check, uint32_t allow)
1339 {
1340 const nvme_field_info_t *field = &check->chk_fields[check->chk_index];
1341 nvme_valid_ctrl_data_t data;
1342 nvme_field_error_t err;
1343 char msg[256];
1344
1345 if (allow != 0 && (allow & (1 << check->chk_index)) == 0) {
1346 VERIFY3U(check->chk_field_unuse, !=, 0);
1347 return (nvme_ctrl_error(ctrl, check->chk_field_unuse, 0,
1348 "field %s (%s) cannot be set in this %s request",
1349 field->nlfi_human, field->nlfi_spec, req));
1350 }
1351
1352 data.vcd_vers = &ctrl->nc_vers;
1353 data.vcd_id = &ctrl->nc_info;
1354
1355 err = nvme_field_validate(field, &data, val, msg, sizeof (msg));
1356 switch (err) {
1357 case NVME_FIELD_ERR_OK:
1358 break;
1359 case NVME_FIELD_ERR_UNSUP_VERSION:
1360 case NVME_FIELD_ERR_UNSUP_FIELD:
1361 VERIFY3U(check->chk_field_unsup, !=, 0);
1362 return (nvme_ctrl_error(ctrl, check->chk_field_unsup, 0, "%s",
1363 msg));
1364 case NVME_FIELD_ERR_BAD_VALUE:
1365 VERIFY3U(check->chk_field_range, !=, 0);
1366 return (nvme_ctrl_error(ctrl, check->chk_field_range, 0, "%s",
1367 msg));
1368 }
1369
1370 return (true);
1371 }
1372