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 2024 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 * 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 * 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 default: 101 return ("unknown status code"); 102 } 103 } 104 105 static const char * 106 nvme_sctostr_gen_csi(nvme_csi_t csi, uint32_t sct) 107 { 108 if (csi != NVME_CSI_NVM) { 109 return ("unknown command set specific general status code"); 110 } 111 112 switch (sct) { 113 case NVME_CQE_SC_GEN_NVM_LBA_RANGE: 114 return ("lba out of range"); 115 case NVME_CQE_SC_GEN_NVM_CAP_EXC: 116 return ("capacity exceeded"); 117 case NVME_CQE_SC_GEN_NVM_NS_NOTRDY: 118 return ("namespace not ready"); 119 case NVME_CQE_SC_GEN_NVM_RSV_CNFLCT: 120 return ("reservation conflict"); 121 case NVME_CQE_SC_GEN_NVM_FORMATTING: 122 return ("format in progress"); 123 default: 124 return ("unknown command set specific general status code"); 125 } 126 } 127 128 static const char * 129 nvme_sctostr_cmd_gen(uint32_t sct) 130 { 131 switch (sct) { 132 case NVME_CQE_SC_SPC_INV_CQ : 133 return ("completion queue invalid"); 134 case NVME_CQE_SC_SPC_INV_QID : 135 return ("invalid queue identifier"); 136 case NVME_CQE_SC_SPC_MAX_QSZ_EXC: 137 return ("max queue size exceeded"); 138 case NVME_CQE_SC_SPC_ABRT_CMD_EXC: 139 return ("abort command limit exceeded"); 140 case NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC: 141 return ("asynchronous event request limit"); 142 case NVME_CQE_SC_SPC_INV_FW_SLOT: 143 return ("invalid firmware slot"); 144 case NVME_CQE_SC_SPC_INV_FW_IMG: 145 return ("invalid firmware image"); 146 case NVME_CQE_SC_SPC_INV_INT_VECT: 147 return ("invalid interrupt vector"); 148 case NVME_CQE_SC_SPC_INV_LOG_PAGE: 149 return ("invalid log page"); 150 case NVME_CQE_SC_SPC_INV_FORMAT: 151 return ("invalid format"); 152 case NVME_CQE_SC_SPC_FW_RESET: 153 return ("firmware activation requires conventional reset"); 154 case NVME_CQE_SC_SPC_INV_Q_DEL: 155 return ("invalid queue deletion"); 156 case NVME_CQE_SC_SPC_FEAT_SAVE: 157 return ("feature identifier not saveable"); 158 case NVME_CQE_SC_SPC_FEAT_CHG: 159 return ("feature not changeable"); 160 case NVME_CQE_SC_SPC_FEAT_NS_SPEC: 161 return ("feature not namespace spec"); 162 case NVME_CQE_SC_SPC_FW_NSSR : 163 return ("firmware activation requires nvm subsystem reset"); 164 case NVME_CQE_SC_SPC_FW_NEXT_RESET: 165 return ("firmware activation requires controller level reset"); 166 case NVME_CQE_SC_SPC_FW_MTFA : 167 return ("firmware activation requires maximum time violation"); 168 case NVME_CQE_SC_SPC_FW_PROHIBITED: 169 return ("firmware activation prohibited"); 170 case NVME_CQE_SC_SPC_FW_OVERLAP: 171 return ("overlapping range"); 172 default: 173 return ("unknown generic command status code"); 174 } 175 } 176 177 static const char * 178 nvme_sctostr_cmd_csi(nvme_csi_t csi, uint32_t sct) 179 { 180 if (csi != NVME_CSI_NVM) { 181 return ("unknown command specific, I/O command set specific " 182 "status code"); 183 } 184 185 switch (sct) { 186 case NVME_CQE_SC_SPC_NVM_CNFL_ATTR: 187 return ("conflicting attributes"); 188 case NVME_CQE_SC_SPC_NVM_INV_PROT: 189 return ("invalid protection"); 190 case NVME_CQE_SC_SPC_NVM_READONLY: 191 return ("write to read only range"); 192 default: 193 return ("unknown command specific, I/O command set specific " 194 "status code"); 195 } 196 } 197 198 static const char * 199 nvme_sctostr_media(nvme_csi_t csi, uint32_t sct) 200 { 201 if (sct >= NVME_CQE_SC_VEND_MIN) { 202 return ("vendor specific media and data integrity status code"); 203 } 204 205 /* 206 * Unlike NVMe 1.x, NVMe 2.x declares the following command set 207 * independent. 208 */ 209 switch (sct) { 210 case NVME_CQE_SC_INT_NVM_WRITE: 211 return ("write fault"); 212 case NVME_CQE_SC_INT_NVM_READ: 213 return ("unrecovered read error"); 214 case NVME_CQE_SC_INT_NVM_GUARD: 215 return ("guard check error"); 216 case NVME_CQE_SC_INT_NVM_APPL_TAG: 217 return ("application tag check err"); 218 case NVME_CQE_SC_INT_NVM_REF_TAG: 219 return ("reference tag check err"); 220 case NVME_CQE_SC_INT_NVM_ACCESS: 221 return ("access denied"); 222 } 223 224 /* 225 * The only command-set specific values are currently defined for the 226 * NVM command set. 227 */ 228 if (csi != NVME_CSI_NVM) { 229 return ("unknown media and data integrity status code"); 230 } 231 232 switch (sct) { 233 case NVME_CQE_SC_INT_NVM_COMPARE: 234 return ("compare failure"); 235 default: 236 return ("unknown media and data integrity status code"); 237 } 238 } 239 240 const char * 241 nvme_sctostr(nvme_ctrl_t *ctrl __unused, nvme_csi_t csi, uint32_t sct, 242 uint32_t sc) 243 { 244 switch (sct) { 245 case NVME_CQE_SCT_GENERIC: 246 if (sc <= NVME_CQE_SC_GEN_MAX) { 247 return (nvme_sctostr_gen_gen(sc)); 248 } else if (sc <= NVME_CQE_SC_CSI_MAX) { 249 return (nvme_sctostr_gen_csi(csi, sc)); 250 } else { 251 return ("generic vendor specific status code"); 252 } 253 case NVME_CQE_SCT_SPECIFIC: 254 if (sc <= NVME_CQE_SC_GEN_MAX) { 255 return (nvme_sctostr_cmd_gen(sc)); 256 } else if (sc <= NVME_CQE_SC_CSI_MAX) { 257 return (nvme_sctostr_cmd_csi(csi, sc)); 258 } else { 259 return ("command specific vendor specific status code"); 260 } 261 case NVME_CQE_SCT_INTEGRITY: 262 return (nvme_sctostr_media(csi, sc)); 263 case NVME_CQE_SCT_VENDOR: 264 return ("vendor specific"); 265 default: 266 return ("unknown status code"); 267 } 268 } 269 270 nvme_err_t 271 nvme_err(nvme_t *nvme) 272 { 273 return (nvme->nh_err.ne_err); 274 } 275 276 int32_t 277 nvme_syserr(nvme_t *nvme) 278 { 279 return (nvme->nh_err.ne_syserr); 280 } 281 282 const char * 283 nvme_errmsg(nvme_t *nvme) 284 { 285 return (nvme->nh_err.ne_errmsg); 286 } 287 288 size_t 289 nvme_errlen(nvme_t *nvme) 290 { 291 return (nvme->nh_err.ne_errlen); 292 } 293 294 const char * 295 nvme_errtostr(nvme_t *nvme, nvme_err_t err) 296 { 297 switch (err) { 298 case NVME_ERR_OK: 299 return ("NVME_ERR_OK"); 300 case NVME_ERR_CONTROLLER: 301 return ("NVME_ERR_CONTROLLER"); 302 case NVME_ERR_NO_MEM: 303 return ("NVME_ERR_NO_MEM"); 304 case NVME_ERR_NO_DMA_MEM: 305 return ("NVME_ERR_NO_DMA_MEM"); 306 case NVME_ERR_LIBDEVINFO: 307 return ("NVME_ERR_LIBDEVINFO"); 308 case NVME_ERR_INTERNAL: 309 return ("NVME_ERR_INTERNAL"); 310 case NVME_ERR_BAD_PTR: 311 return ("NVME_ERR_BAD_PTR"); 312 case NVME_ERR_BAD_FLAG: 313 return ("NVME_ERR_BAD_FLAG"); 314 case NVME_ERR_BAD_DEVI: 315 return ("NVME_ERR_BAD_DEVI"); 316 case NVME_ERR_BAD_DEVI_PROP: 317 return ("NVME_ERR_BAD_DEVI_PROP"); 318 case NVME_ERR_ILLEGAL_INSTANCE: 319 return ("NVME_ERR_ILLEGAL_INSTANCE"); 320 case NVME_ERR_BAD_CONTROLLER: 321 return ("NVME_ERR_BAD_CONTROLLER"); 322 case NVME_ERR_PRIVS: 323 return ("NVME_ERR_PRIVS"); 324 case NVME_ERR_OPEN_DEV: 325 return ("NVME_ERR_OPEN_DEV"); 326 case NVME_ERR_BAD_RESTORE: 327 return ("NVME_ERR_BAD_RESTORE"); 328 case NVME_ERR_NS_RANGE: 329 return ("NVME_ERR_NS_RANGE"); 330 case NVME_ERR_NS_UNUSE: 331 return ("NVME_ERR_NS_UNUSE"); 332 case NVME_ERR_LOG_CSI_RANGE: 333 return ("NVME_ERR_LOG_CSI_RANGE"); 334 case NVME_ERR_LOG_LID_RANGE: 335 return ("NVME_ERR_LOG_LID_RANGE"); 336 case NVME_ERR_LOG_LSP_RANGE: 337 return ("NVME_ERR_LOG_LSP_RANGE"); 338 case NVME_ERR_LOG_LSI_RANGE: 339 return ("NVME_ERR_LOG_LSI_RANGE"); 340 case NVME_ERR_LOG_RAE_RANGE: 341 return ("NVME_ERR_LOG_RAE_RANGE"); 342 case NVME_ERR_LOG_SIZE_RANGE: 343 return ("NVME_ERR_LOG_SIZE_RANGE"); 344 case NVME_ERR_LOG_OFFSET_RANGE: 345 return ("NVME_ERR_LOG_OFFSET_RANGE"); 346 case NVME_ERR_LOG_CSI_UNSUP: 347 return ("NVME_ERR_LOG_CSI_UNSUP"); 348 case NVME_ERR_LOG_LSP_UNSUP: 349 return ("NVME_ERR_LOG_LSP_UNSUP"); 350 case NVME_ERR_LOG_LSI_UNSUP: 351 return ("NVME_ERR_LOG_LSI_UNSUP"); 352 case NVME_ERR_LOG_RAE_UNSUP: 353 return ("NVME_ERR_LOG_RAE_UNSUP"); 354 case NVME_ERR_LOG_OFFSET_UNSUP: 355 return ("NVME_ERR_LOG_OFFSET_UNSUP"); 356 case NVME_ERR_LOG_LSP_UNUSE: 357 return ("NVME_ERR_LOG_LSP_UNUSE"); 358 case NVME_ERR_LOG_LSI_UNUSE: 359 return ("NVME_ERR_LOG_LSI_UNUSE"); 360 case NVME_ERR_LOG_RAE_UNUSE: 361 return ("NVME_ERR_LOG_RAE_UNUSE"); 362 case NVME_ERR_LOG_SCOPE_MISMATCH: 363 return ("NVME_ERR_LOG_SCOPE_MISMATCH"); 364 case NVME_ERR_LOG_REQ_MISSING_FIELDS: 365 return ("NVME_ERR_LOG_REQ_MISSING_FIELDS"); 366 case NVME_ERR_LOG_NAME_UNKNOWN: 367 return ("NVME_ERR_LOG_NAME_UNKNOWN"); 368 case NVME_ERR_LOG_UNSUP_BY_DEV: 369 return ("NVME_ERR_LOG_UNSUP_BY_DEV"); 370 case NVME_ERR_IDENTIFY_UNKNOWN: 371 return ("NVME_ERR_IDENTIFY_UNKNOWN"); 372 case NVME_ERR_IDENTIFY_UNSUP_BY_DEV: 373 return ("NVME_ERR_IDENTIFY_UNSUP_BY_DEV"); 374 case NVME_ERR_IDENTIFY_CTRLID_RANGE: 375 return ("NVME_ERR_IDENTIFY_CTRLID_RANGE"); 376 case NVME_ERR_IDENTIFY_OUTPUT_RANGE: 377 return ("NVME_ERR_IDENTIFY_OUTPUT_RANGE"); 378 case NVME_ERR_IDENTIFY_CTRLID_UNSUP: 379 return ("NVME_ERR_IDENTIFY_CTRLID_UNSUP"); 380 case NVME_ERR_IDENTIFY_CTRLID_UNUSE: 381 return ("NVME_ERR_IDENTIFY_CTRLID_UNUSE"); 382 case NVME_ERR_IDENTIFY_REQ_MISSING_FIELDS: 383 return ("NVME_ERR_IDENTIFY_REQ_MISSING_FIELDS"); 384 case NVME_ERR_VUC_UNSUP_BY_DEV: 385 return ("NVME_ERR_VUC_UNSUP_BY_DEV"); 386 case NVME_ERR_VUC_TIMEOUT_RANGE: 387 return ("NVME_ERR_VUC_TIMEOUT_RANGE"); 388 case NVME_ERR_VUC_OPCODE_RANGE: 389 return ("NVME_ERR_VUC_OPCODE_RANGE"); 390 case NVME_ERR_VUC_IMPACT_RANGE: 391 return ("NVME_ERR_VUC_IMPACT_RANGE"); 392 case NVME_ERR_VUC_NDT_RANGE: 393 return ("NVME_ERR_VUC_NDT_RANGE"); 394 case NVME_ERR_VUC_CANNOT_RW: 395 return ("NVME_ERR_VUC_CANNOT_RW"); 396 case NVME_ERR_VUC_NO_RESULTS: 397 return ("NVME_ERR_VUC_NO_RESULTS"); 398 case NVME_ERR_VUC_UNKNOWN: 399 return ("NVME_ERR_VUC_UNKNOWN"); 400 case NVME_ERR_VUC_REQ_MISSING_FIELDS: 401 return ("NVME_ERR_VUC_REQ_MISSING_FIELDS"); 402 case NVME_ERR_VU_FUNC_UNSUP_BY_DEV: 403 return ("NVME_ERR_VU_FUNC_UNSUP_BY_DEV"); 404 case NVME_ERR_WDC_E6_OFFSET_RANGE: 405 return ("NVME_ERR_WDC_E6_OFFSET_RANGE"); 406 case NVME_ERR_FW_UNSUP_BY_DEV: 407 return ("NVME_ERR_FW_UNSUP_BY_DEV"); 408 case NVME_ERR_KERN_FW_IMPOS: 409 return ("NVME_ERR_KERN_FW_IMPOS"); 410 case NVME_ERR_FW_LOAD_LEN_RANGE: 411 return ("NVME_ERR_FW_LOAD_LEN_RANGE"); 412 case NVME_ERR_FW_LOAD_OFFSET_RANGE: 413 return ("NVME_ERR_FW_LOAD_OFFSET_RANGE"); 414 case NVME_ERR_FW_COMMIT_SLOT_RANGE: 415 return ("NVME_ERR_FW_COMMIT_SLOT_RANGE"); 416 case NVME_ERR_FW_COMMIT_ACTION_RANGE: 417 return ("NVME_ERR_FW_COMMIT_ACTION_RANGE"); 418 case NVME_ERR_FW_COMMIT_REQ_MISSING_FIELDS: 419 return ("NVME_ERR_FW_COMMIT_REQ_MISSING_FIELDS"); 420 case NVME_ERR_FW_SLOT_RO: 421 return ("NVME_ERR_FW_SLOT_RO"); 422 case NVME_ERR_FORMAT_UNSUP_BY_DEV: 423 return ("NVME_ERR_FORMAT_UNSUP_BY_DEV"); 424 case NVME_ERR_CRYPTO_SE_UNSUP_BY_DEV: 425 return ("NVME_ERR_CRYPTO_SE_UNSUP_BY_DEV"); 426 case NVME_ERR_NS_FORMAT_UNSUP_BY_DEV: 427 return ("NVME_ERR_NS_FORMAT_UNSUP_BY_DEV"); 428 case NVME_ERR_KERN_FORMAT_UNSUP: 429 return ("NVME_ERR_KERN_FORMAT_UNSUP"); 430 case NVME_ERR_FORMAT_LBAF_RANGE: 431 return ("NVME_ERR_FORMAT_LBAF_RANGE"); 432 case NVME_ERR_FORMAT_SES_RANGE: 433 return ("NVME_ERR_FORMAT_SES_RANGE"); 434 case NVME_ERR_FORMAT_PARAM_UNSUP: 435 return ("NVME_ERR_FORMAT_PARAM_UNSUP"); 436 case NVME_ERR_FORMAT_REQ_MISSING_FIELDS: 437 return ("NVME_ERR_FORMAT_REQ_MISSING_FIELDS"); 438 case NVME_ERR_WDC_E6_REQ_MISSING_FIELDS: 439 return ("NVME_ERR_WDC_E6_REQ_MISSING_FIELDS"); 440 case NVME_ERR_FEAT_NAME_UNKNOWN: 441 return ("NVME_ERR_FEAT_NAME_UNKNOWN"); 442 case NVME_ERR_FEAT_UNSUP_BY_DEV: 443 return ("NVME_ERR_FEAT_UNSUP_BY_DEV"); 444 case NVME_ERR_FEAT_FID_RANGE: 445 return ("NVME_ERR_FEAT_FID_RANGE"); 446 case NVME_ERR_FEAT_SEL_RANGE: 447 return ("NVME_ERR_FEAT_SEL_RANGE"); 448 case NVME_ERR_FEAT_CDW11_RANGE: 449 return ("NVME_ERR_FEAT_CDW11_RANGE"); 450 case NVME_ERR_FEAT_DATA_RANGE: 451 return ("NVME_ERR_FEAT_DATA_RANGE"); 452 case NVME_ERR_FEAT_SEL_UNSUP: 453 return ("NVME_ERR_FEAT_SEL_UNSUP"); 454 case NVME_ERR_FEAT_CDW11_UNUSE: 455 return ("NVME_ERR_FEAT_CDW11_UNUSE"); 456 case NVME_ERR_FEAT_DATA_UNUSE: 457 return ("NVME_ERR_FEAT_DATA_UNUSE"); 458 case NVME_ERR_FEAT_NO_RESULTS: 459 return ("NVME_ERR_FEAT_NO_RESULTS"); 460 case NVME_ERR_GET_FEAT_REQ_MISSING_FIELDS: 461 return ("NVME_ERR_GET_FEAT_REQ_MISSING_FIELDS"); 462 case NVME_ERR_NEED_CTRL_WRLOCK: 463 return ("NVME_ERR_NEED_CTRL_WRLOCK"); 464 case NVME_ERR_NEED_NS_WRLOCK: 465 return ("NVME_ERR_NEED_NS_WRLOCK"); 466 case NVME_ERR_CTRL_LOCKED: 467 return ("NVME_ERR_CTRL_LOCKED"); 468 case NVME_ERR_NS_LOCKED: 469 return ("NVME_ERR_NS_LOCKED"); 470 case NVME_ERR_LOCK_PROG: 471 return ("NVME_ERR_LOCK_PROG"); 472 case NVME_ERR_LOCK_ORDER: 473 return ("NVME_ERR_LOCK_ORDER"); 474 case NVME_ERR_LOCK_WAIT_INTR: 475 return ("NVME_ERR_LOCK_WAIT_INTR"); 476 case NVME_ERR_LOCK_WOULD_BLOCK: 477 return ("NVME_ERR_LOCK_WOULD_BLOCK"); 478 case NVME_ERR_DETACH_KERN: 479 return ("NVME_ERR_DETACH_KERN"); 480 case NVME_ERR_ATTACH_KERN: 481 return ("NVME_ERR_ATTACH_KERN"); 482 case NVME_ERR_ATTACH_UNSUP_KERN: 483 return ("NVME_ERR_ATTACH_UNSUP_KERN"); 484 case NVME_ERR_NS_BLKDEV_ATTACH: 485 return ("NVME_ERR_NS_BLKDEV_ATTACH"); 486 case NVME_ERR_NO_KERN_MEM: 487 return ("NVME_ERR_NO_KERN_MEM"); 488 case NVME_ERR_CTRL_DEAD: 489 return ("NVME_ERR_CTRL_DEAD"); 490 case NVME_ERR_CTRL_GONE: 491 return ("NVME_ERR_CTRL_GONE"); 492 default: 493 return ("unknown error"); 494 } 495 } 496 497 nvme_err_t 498 nvme_ctrl_err(nvme_ctrl_t *ctrl) 499 { 500 return (ctrl->nc_err.ne_err); 501 } 502 503 int32_t 504 nvme_ctrl_syserr(nvme_ctrl_t *ctrl) 505 { 506 return (ctrl->nc_err.ne_syserr); 507 } 508 509 const char * 510 nvme_ctrl_errmsg(nvme_ctrl_t *ctrl) 511 { 512 return (ctrl->nc_err.ne_errmsg); 513 } 514 515 size_t 516 nvme_ctrl_errlen(nvme_ctrl_t *ctrl) 517 { 518 return (ctrl->nc_err.ne_errlen); 519 } 520 521 void 522 nvme_ctrl_deverr(nvme_ctrl_t *ctrl, uint32_t *sct, uint32_t *sc) 523 { 524 if (sct != NULL) { 525 *sct = ctrl->nc_err.ne_ctrl_sct; 526 } 527 528 if (sc != NULL) { 529 *sc = ctrl->nc_err.ne_ctrl_sc; 530 } 531 } 532 533 const char * 534 nvme_ctrl_errtostr(nvme_ctrl_t *ctrl, nvme_err_t err) 535 { 536 return (nvme_errtostr(ctrl->nc_nvme, err)); 537 } 538 539 static void 540 nvme_error_common(nvme_err_data_t *ep, nvme_err_t err, int32_t sys, 541 const char *fmt, va_list ap) 542 { 543 int ret; 544 545 ep->ne_err = err; 546 ep->ne_syserr = sys; 547 ep->ne_ctrl_sct = 0; 548 ep->ne_ctrl_sc = 0; 549 ret = vsnprintf(ep->ne_errmsg, 550 sizeof (ep->ne_errmsg), fmt, ap); 551 if (ret >= sizeof (ep->ne_errmsg)) { 552 ep->ne_errlen = sizeof (ep->ne_errmsg) - 1; 553 } else if (ret <= 0) { 554 ep->ne_errlen = 0; 555 ep->ne_errmsg[0] = '\0'; 556 } else { 557 ep->ne_errlen = (size_t)ret; 558 } 559 } 560 561 bool 562 nvme_error(nvme_t *nvme, nvme_err_t err, int32_t sys, const char *fmt, ...) 563 { 564 va_list ap; 565 566 va_start(ap, fmt); 567 nvme_error_common(&nvme->nh_err, err, sys, fmt, ap); 568 va_end(ap); 569 570 return (false); 571 } 572 573 bool 574 nvme_ctrl_error(nvme_ctrl_t *ctrl, nvme_err_t err, int32_t sys, 575 const char *fmt, ...) 576 { 577 va_list ap; 578 579 va_start(ap, fmt); 580 nvme_error_common(&ctrl->nc_err, err, sys, fmt, ap); 581 va_end(ap); 582 583 return (false); 584 } 585 586 static bool 587 nvme_success_common(nvme_err_data_t *err) 588 { 589 err->ne_err = NVME_ERR_OK; 590 err->ne_syserr = 0; 591 err->ne_ctrl_sct = 0; 592 err->ne_ctrl_sc = 0; 593 err->ne_errmsg[0] = '\0'; 594 err->ne_errlen = 0; 595 596 return (true); 597 } 598 599 bool 600 nvme_success(nvme_t *nvme) 601 { 602 return (nvme_success_common(&nvme->nh_err)); 603 } 604 605 bool 606 nvme_ctrl_success(nvme_ctrl_t *ctrl) 607 { 608 return (nvme_success_common(&ctrl->nc_err)); 609 } 610 611 void 612 nvme_err_save(const nvme_t *nvme, nvme_err_data_t *out) 613 { 614 *out = nvme->nh_err; 615 } 616 617 void 618 nvme_err_set(nvme_t *nvme, const nvme_err_data_t *err) 619 { 620 nvme->nh_err = *err; 621 } 622 623 void 624 nvme_ctrl_err_save(const nvme_ctrl_t *ctrl, nvme_err_data_t *out) 625 { 626 *out = ctrl->nc_err; 627 } 628 629 void 630 nvme_ctrl_err_set(nvme_ctrl_t *ctrl, const nvme_err_data_t *err) 631 { 632 ctrl->nc_err = *err; 633 } 634 635 /* 636 * This table deals with mapping a kernel error to a library error and provides 637 * a short description of what it is. Note, we do not expect all kernel errors 638 * to occur and we may want to revisit which of these end up indicating a 639 * programmer error that we caused somehow. 640 */ 641 typedef struct { 642 nvme_ioctl_errno_t kl_kern; 643 nvme_err_t kl_lib; 644 const char *kl_desc; 645 } nvme_ktolmap_t; 646 647 /* 648 * Please keep this table ordered based on the nvme_ioctl_error_t enumeration 649 * order. This is not required for correctness, but helps when scanning for 650 * missing entries. Please document why certain entries are skipped. 651 */ 652 static const nvme_ktolmap_t nvme_ktolmap[] = { 653 /* 654 * NVME_IOCTL_E_OK and NVME_IOCTL_E_CTRL_ERROR should already have been 655 * dealt with and shouldn't be included here. 656 */ 657 { NVME_IOCTL_E_CTRL_DEAD, NVME_ERR_CTRL_DEAD, "the controller is no " 658 "longer usable by the system" }, 659 { NVME_IOCTL_E_CTRL_GONE, NVME_ERR_CTRL_GONE, "the controller has been " 660 "physically removed from the system" }, 661 { NVME_IOCTL_E_NS_RANGE, NVME_ERR_NS_RANGE, "invalid namespace " 662 "requested" }, 663 { NVME_IOCTL_E_NS_UNUSE, NVME_ERR_NS_UNUSE, "a namespace ID may not be " 664 "specified in this context" }, 665 /* 666 * We have purposefully skipped NVME_IOCTL_E_MINOR_WRONG_NS and 667 * NVME_IOCTL_E_NOT_CTRL as the library should not ever use the 668 * namespace minor. 669 */ 670 { NVME_IOCTL_E_NO_BCAST_NS, NVME_ERR_NS_RANGE, "the broadcast " 671 "namespace may not be used in this context" }, 672 { NVME_IOCTL_E_NEED_CTRL_WRLOCK, NVME_ERR_NEED_CTRL_WRLOCK, "operation " 673 "requires a controller write lock, but it is not owned" }, 674 { NVME_IOCTL_E_NEED_NS_WRLOCK, NVME_ERR_NEED_NS_WRLOCK, "operation " 675 "requires a namespace write lock, but it is not owned" }, 676 { NVME_IOCTL_E_CTRL_LOCKED, NVME_ERR_CTRL_LOCKED, "controller locked" }, 677 { NVME_IOCTL_E_NS_LOCKED, NVME_ERR_NS_LOCKED, "namespace locked" }, 678 /* 679 * We have purposefully skipped NVME_IOCTL_E_UNKNOWN_LOG_PAGE as in 680 * theory the library and kernel should be in sync with the set of known 681 * log pages. If it is out of sync due to someone distributing the two 682 * weirdly or a bad build, we'd rather that end up as an internal error 683 * rather than a first class error for users. 684 */ 685 { NVME_IOCTL_E_UNSUP_LOG_PAGE, NVME_ERR_LOG_UNSUP_BY_DEV, "controller " 686 "does not support the specified log page" }, 687 { NVME_IOCTL_E_BAD_LOG_SCOPE, NVME_ERR_LOG_SCOPE_MISMATCH, "log page " 688 "does not work with the requested scope" }, 689 { NVME_IOCTL_E_LOG_CSI_RANGE, NVME_ERR_LOG_CSI_RANGE, "invalid command " 690 "set interface value" }, 691 { NVME_IOCTL_E_LOG_LID_RANGE, NVME_ERR_LOG_LID_RANGE, "invalid log " 692 "identifier value" }, 693 { NVME_IOCTL_E_LOG_LSP_RANGE, NVME_ERR_LOG_LSP_RANGE, "invalid log " 694 "specific parameter value" }, 695 { NVME_IOCTL_E_LOG_LSI_RANGE, NVME_ERR_LOG_LSI_RANGE, "invalid log " 696 "specific identifier value" }, 697 { NVME_IOCTL_E_LOG_RAE_RANGE, NVME_ERR_LOG_SIZE_RANGE, "invalid retain " 698 "asynchronous event value" }, 699 { NVME_IOCTL_E_LOG_SIZE_RANGE, NVME_ERR_LOG_SIZE_RANGE, "invalid log " 700 "length value" }, 701 { NVME_IOCTL_E_LOG_OFFSET_RANGE, NVME_ERR_LOG_OFFSET_RANGE, "invalid " 702 "log offset value" }, 703 { NVME_IOCTL_E_LOG_CSI_UNSUP, NVME_ERR_LOG_CSI_UNSUP, 704 "the controller does not support specifying the csi" }, 705 { NVME_IOCTL_E_LOG_LSP_UNSUP, NVME_ERR_LOG_LSP_UNSUP, 706 "the controller does not support specifying the lsp" }, 707 { NVME_IOCTL_E_LOG_LSI_UNSUP, NVME_ERR_LOG_LSI_UNSUP, 708 "or controller do not support specifying the lsi" }, 709 { NVME_IOCTL_E_LOG_RAE_UNSUP, NVME_ERR_LOG_RAE_UNSUP, 710 "the controller does not support retaining an asynchronous event" }, 711 { NVME_IOCTL_E_LOG_OFFSET_UNSUP, NVME_ERR_LOG_OFFSET_UNSUP, 712 "the controller do not support specifying a a read offset" }, 713 { NVME_IOCTL_E_LOG_LSP_UNUSE, NVME_ERR_LOG_LSP_UNUSE, "the log page " 714 "does not allow the lsp to be used" }, 715 { NVME_IOCTL_E_LOG_LSI_UNUSE, NVME_ERR_LOG_LSI_UNUSE, "the log page " 716 "does not allow the lsi to be used" }, 717 { NVME_IOCTL_E_LOG_RAE_UNUSE, NVME_ERR_LOG_RAE_UNUSE, "the log page " 718 "does not allow rae to be set" }, 719 { NVME_IOCTL_E_NO_DMA_MEM, NVME_ERR_NO_DMA_MEM, "the kernel failed to " 720 "allocate sufficient DMA resources" }, 721 { NVME_IOCTL_E_NO_KERN_MEM, NVME_ERR_NO_KERN_MEM, "the kernel failed " 722 "to allocate sufficient memory for this operation" }, 723 { NVME_IOCTL_E_BAD_PRP, NVME_ERR_INTERNAL, "a driver error occurred " 724 "while filling out the command's DMA resources" }, 725 { NVME_IOCTL_E_BAD_USER_DATA, NVME_ERR_BAD_PTR, "the kernel " 726 "detected an invalid user buffer while trying to read/write the " 727 "passed in data buffer" }, 728 { NVME_IOCTL_E_UNKNOWN_IDENTIFY, NVME_ERR_IDENTIFY_UNKNOWN, "unknown " 729 "identify command requested" }, 730 { NVME_IOCTL_E_UNSUP_IDENTIFY, NVME_ERR_IDENTIFY_UNSUP_BY_DEV, 731 "controller does not support the requested identify command" }, 732 { NVME_IOCTL_E_IDENTIFY_CTRLID_RANGE, NVME_ERR_IDENTIFY_CTRLID_RANGE, 733 "invalid controller id value" }, 734 { NVME_IOCTL_E_IDENTIFY_CTRLID_UNSUP, NVME_ERR_IDENTIFY_CTRLID_UNSUP, 735 "the controller does not support specifying the controller ID" }, 736 { NVME_IOCTL_E_IDENTIFY_CTRLID_UNUSE, NVME_ERR_IDENTIFY_CTRLID_UNUSE, 737 "this specific identify request does not allow setting the " 738 "controller id" }, 739 { NVME_IOCTL_E_CTRL_VUC_UNSUP, NVME_ERR_VUC_UNSUP_BY_DEV, 740 "the controller does not support standard NVMe vendor unique " 741 "commands" }, 742 /* 743 * The following indicate bad values for given NVMe vendor unique 744 * command fields. Note, we do not include an entry for 745 * NVME_IOCTL_E_VUC_FLAGS_RANGE because these flags are entirely owned 746 * by the library. 747 */ 748 { NVME_IOCTL_E_VUC_TIMEOUT_RANGE, NVME_ERR_VUC_TIMEOUT_RANGE, "invalid " 749 "command timeout value" }, 750 { NVME_IOCTL_E_VUC_OPCODE_RANGE, NVME_ERR_VUC_OPCODE_RANGE, "invalid " 751 "vendor unique opcode specified" }, 752 { NVME_IOCTL_E_VUC_IMPACT_RANGE, NVME_ERR_VUC_IMPACT_RANGE, "invalid " 753 "vendor unique impact specified" }, 754 { NVME_IOCTL_E_VUC_NDT_RANGE, NVME_ERR_VUC_NDT_RANGE, "invalid " 755 "data transfer size specified" }, 756 /* 757 * We skip NVME_IOCTL_E_INCONSIST_VUC_FLAGS_NDT and 758 * NVME_IOCTL_E_INCONSIST_VUC_BUF_NDT because these are solely under the 759 * library control and would indicate a programming error at our end. 760 * The user shouldn't be able to cause this. 761 */ 762 { NVME_IOCTL_E_BLKDEV_DETACH, NVME_ERR_DETACH_KERN, "the kernel failed " 763 "to detach the requested namespace" }, 764 { NVME_IOCTL_E_BLKDEV_ATTACH, NVME_ERR_ATTACH_KERN, "the kernel failed " 765 "to attach the requested namespace" }, 766 { NVME_IOCTL_E_UNSUP_ATTACH_NS, NVME_ERR_ATTACH_UNSUP_KERN, 767 "the namespace is not supported by the kernel" }, 768 { NVME_IOCTL_E_CTRL_FORMAT_UNSUP, NVME_ERR_FORMAT_UNSUP_BY_DEV, "the " 769 "controller does not support formatting namespaces" }, 770 { NVME_IOCTL_E_CTRL_CRYPTO_SE_UNSUP, NVME_ERR_CRYPTO_SE_UNSUP_BY_DEV, 771 "the controller does not support cryptographic secure erase" }, 772 { NVME_IOCTL_E_CTRL_NS_FORMAT_UNSUP, NVME_ERR_NS_FORMAT_UNSUP_BY_DEV, 773 "the controller cannot format a single namespace" }, 774 { NVME_IOCTL_E_CTRL_NS_SE_UNSUP, NVME_ERR_NS_FORMAT_UNSUP_BY_DEV, 775 "the controller cannot secure erase a single namespace" }, 776 { NVME_IOCTL_E_FORMAT_LBAF_RANGE, NVME_ERR_FORMAT_LBAF_RANGE, 777 "invalid LBA format value" }, 778 { NVME_IOCTL_E_FORMAT_SES_RANGE, NVME_ERR_FORMAT_SES_RANGE, 779 "invalid secure erase settings value" }, 780 { NVME_IOCTL_E_UNSUP_LBAF_META, NVME_ERR_KERN_FORMAT_UNSUP, "cannot " 781 "format due to the use of unsupported metadata sectors" }, 782 { NVME_IOCTL_E_CTRL_FW_UNSUP, NVME_ERR_FW_UNSUP_BY_DEV, "the " 783 "controller does not support firmware commands" }, 784 { NVME_IOCTL_E_FW_LOAD_IMPOS_GRAN, NVME_ERR_KERN_FW_IMPOS, "controller " 785 "reported firmware upgrade granularity does not work with the " 786 "calculated maximum DMA transfer size" }, 787 { NVME_IOCTL_E_FW_LOAD_LEN_RANGE, NVME_ERR_FW_LOAD_LEN_RANGE, 788 "invalid firmware load length value" }, 789 { NVME_IOCTL_E_FW_LOAD_OFFSET_RANGE, NVME_ERR_FW_LOAD_OFFSET_RANGE, 790 "invalid firmware load offset value" }, 791 { NVME_IOCTL_E_FW_COMMIT_SLOT_RANGE, NVME_ERR_FW_COMMIT_SLOT_RANGE, 792 "invalid firmware commit slot value" }, 793 { NVME_IOCTL_E_FW_COMMIT_ACTION_RANGE, NVME_ERR_FW_COMMIT_ACTION_RANGE, 794 "invalid firmware commit action value" }, 795 { NVME_IOCTL_E_RO_FW_SLOT, NVME_ERR_FW_SLOT_RO, "cannot write to read-" 796 "only slot" }, 797 /* 798 * We have purposefully skipped NVME_IOCTL_E_UNKNOWN_FEATURE for the 799 * same reasons we did with NVME_IOCTL_E_UNKNOWN_LOG above. 800 */ 801 { NVME_IOCTL_E_UNSUP_FEATURE, NVME_ERR_FEAT_UNSUP_BY_DEV, "the " 802 "controller does not supported the requested feature" }, 803 { NVME_IOCTL_E_GET_FEAT_SEL_RANGE, NVME_ERR_FEAT_SEL_RANGE, "invalid " 804 "feature selector value" }, 805 { NVME_IOCTL_E_GET_FEAT_CDW11_RANGE, NVME_ERR_FEAT_CDW11_RANGE, 806 "invalid feature-specific cdw11 value" }, 807 { NVME_IOCTL_E_GET_FEAT_DATA_RANGE, NVME_ERR_FEAT_DATA_RANGE, "invalid " 808 "feature data, likely a size mismatch" }, 809 { NVME_IOCTL_E_GET_FEAT_SEL_UNSUP, NVME_ERR_FEAT_SEL_UNSUP, "the " 810 "controller does not support specifying a feature selector" }, 811 { NVME_IOCTL_E_GET_FEAT_CDW11_UNUSE, NVME_ERR_FEAT_CDW11_UNUSE, 812 "the feature does not support specifying a cdw11 argument" }, 813 { NVME_IOCTL_E_GET_FEAT_DATA_UNUSE, NVME_ERR_FEAT_DATA_UNUSE, 814 "the feature does not support specifying a data buffer" }, 815 /* 816 * We skip the NVME_IOCTL_E_BAD_LOCK_ENTITY, 817 * NVME_IOCTL_E_BAD_LOCK_LEVEL, and NVME_IOCTL_E_BAD_LOCK_FLAGS 818 * arguments as these are all generally passed by the library and not 819 * really under direct user control. Therefore if there is a problem, 820 * that should be an internal error. 821 * 822 * Similarly we skip NVME_IOCTL_E_NS_CANNOT_LOCK_CTRL and 823 * NVME_IOCTL_E_NS_CANNOT_UNLOCK_CTRL because the library does not 824 * utilize namespace minors and these can only apply to those. 825 */ 826 { NVME_IOCTL_E_LOCK_ALREADY_HELD, NVME_ERR_LOCK_PROG, "fatal " 827 "programmer error: recursive lock attempt" }, 828 { NVME_IOCTL_E_LOCK_NO_CTRL_WITH_NS, NVME_ERR_LOCK_ORDER, 829 "control locks cannot be acquired while holding a namespace lock" }, 830 { NVME_IOCTL_LOCK_NO_NS_WITH_CTRL_WRLOCK, NVME_ERR_LOCK_ORDER, 831 "no namespace locks may be acquired while holding a controller " 832 "write lock" }, 833 { NVME_IOCTL_E_LOCK_NO_2ND_NS, NVME_ERR_LOCK_ORDER, "only a single " 834 "namespace lock can be held at any time" }, 835 { NVME_IOCTL_E_LOCK_WAIT_SIGNAL, NVME_ERR_LOCK_WAIT_INTR, "signal " 836 "received while blocking" }, 837 { NVME_IOCTL_E_LOCK_WOULD_BLOCK, NVME_ERR_LOCK_WOULD_BLOCK, "lock not " 838 "available and no blocking allowed" }, 839 { NVME_IOCTL_E_LOCK_PENDING, NVME_ERR_LOCK_ORDER, "a handle may only " 840 "block on one lock at a time" }, 841 { NVME_IOCTL_E_LOCK_NOT_HELD, NVME_ERR_LOCK_PROG, "fatal " 842 "programmer error: asked to unlock lock that was not held" }, 843 /* 844 * This error is almost a can't happen due to the library construction 845 * and should result in the above error, but if this does happen, we 846 * treat this as a fatal lock error regardless. 847 */ 848 { NVME_IOCTL_E_LOCK_WRONG_NS, NVME_ERR_LOCK_PROG, "fatal " 849 "programmer error: asked to unlock namespace lock that was not " 850 "held" }, 851 { NVME_IOCTL_E_NS_BLKDEV_ATTACH, NVME_ERR_NS_BLKDEV_ATTACH, "cannot " 852 "execute request while namespace is attached" }, 853 /* 854 * We purposefully skip NVME_IOCTL_E_BD_ADDR_OVER right now because 855 * there is nothing that a user can do about this. This is a 856 * libnvme/kernel interface issue. 857 */ 858 }; 859 860 /* 861 * Translate a kernel ioctl error into the library's error. We handle the 862 * controller error separately. Otherwise, everything else is done based upon 863 * our translation table. 864 */ 865 bool 866 nvme_ioctl_error(nvme_ctrl_t *ctrl, const nvme_ioctl_common_t *ioc, 867 const char *desc) 868 { 869 int ret; 870 nvme_err_data_t *err = &ctrl->nc_err; 871 VERIFY3U(ioc->nioc_drv_err, !=, NVME_IOCTL_E_OK); 872 873 err->ne_syserr = 0; 874 err->ne_ctrl_sct = 0; 875 err->ne_ctrl_sc = 0; 876 877 if (ioc->nioc_drv_err == NVME_IOCTL_E_CTRL_ERROR) { 878 const char *sct, *sc; 879 err->ne_err = NVME_ERR_CONTROLLER; 880 err->ne_ctrl_sct = ioc->nioc_ctrl_sct; 881 err->ne_ctrl_sc = ioc->nioc_ctrl_sc; 882 sct = nvme_scttostr(ctrl, ioc->nioc_ctrl_sct); 883 sc = nvme_sctostr(ctrl, NVME_CSI_NVM, ioc->nioc_ctrl_sct, 884 ioc->nioc_ctrl_sc); 885 ret = snprintf(err->ne_errmsg, sizeof (err->ne_errmsg), 886 "failed to execute %s command: received controller error " 887 "sct/sc %s/%s (0x%x/0x%x)", desc, sct, sc, 888 ioc->nioc_ctrl_sct, ioc->nioc_ctrl_sc); 889 } else { 890 const nvme_ktolmap_t *map = NULL; 891 for (size_t i = 0; i < ARRAY_SIZE(nvme_ktolmap); i++) { 892 if (nvme_ktolmap[i].kl_kern == ioc->nioc_drv_err) { 893 map = &nvme_ktolmap[i]; 894 break; 895 } 896 } 897 898 if (map != NULL) { 899 err->ne_err = map->kl_lib; 900 ret = snprintf(err->ne_errmsg, sizeof (err->ne_errmsg), 901 "failed to execute %s command: %s", desc, 902 map->kl_desc); 903 } else { 904 err->ne_err = NVME_ERR_INTERNAL; 905 ret = snprintf(err->ne_errmsg, sizeof (err->ne_errmsg), 906 "failed to execute %s command: failed to map " 907 "kernel error 0x%x to a known cause", desc, 908 ioc->nioc_drv_err); 909 } 910 } 911 912 if (ret >= sizeof (err->ne_errmsg)) { 913 err->ne_errlen = sizeof (err->ne_errmsg) - 1; 914 } else if (ret <= 0) { 915 err->ne_errlen = 0; 916 err->ne_errmsg[0] = '\0'; 917 } else { 918 err->ne_errlen = (size_t)ret; 919 } 920 921 return (false); 922 } 923 924 /* 925 * Evaluate the set of ioctl errors that we see and translate and/or abort a few 926 * of the expected values. Most things will end up being translated into a 927 * generic internal error as we expect a rather tight error set at this point. 928 * 929 * We choose to panic on EFAULT because we are responsible for all such EFAULT 930 * errors. These are structure that are coming from the library. This is not 931 * something that the user could have passed us (their buffers will trigger 932 * an explicit nvme_ioctl_errno_t). Therefore, something has gone very wrong 933 * with our stack or we just corrupted some memory. 934 * 935 * The same is true with EBADF. In this case, that'd happen either because our 936 * controller fd was bandit'd away by someone or somehow we lost FREAD or FWRITE 937 * on the fd. That should not be possible assuming everyone is acting in good 938 * faith, so we treat this as a sign that something quite bad has happened and 939 * we shouldn't continue. 940 */ 941 bool 942 nvme_ioctl_syserror(nvme_ctrl_t *ctrl, int err, const char *desc) 943 { 944 switch (err) { 945 case EFAULT: 946 case EBADF: { 947 const char *base = "fatal libnvme internal programming error: " 948 "failed to issue ioctl"; 949 char msg[1024]; 950 int ret; 951 const char *up; 952 size_t ulen; 953 954 ret = snprintf(msg, sizeof (msg), "%s %s: %s (controller %p)", 955 base, desc, strerror(err), ctrl); 956 if (ret >= sizeof (msg)) { 957 ulen = sizeof (msg); 958 up = msg; 959 } else if (ret <= 0) { 960 up = base; 961 ulen = strlen(base) + 1; 962 } else { 963 ulen = (size_t)ret; 964 up = msg; 965 } 966 967 upanic(up, ulen); 968 } 969 case EPERM: 970 return (nvme_ctrl_error(ctrl, NVME_ERR_PRIVS, err, 971 "failed to issue %s ioctl due to missing privileges", 972 desc)); 973 default: 974 return (nvme_ctrl_error(ctrl, NVME_ERR_INTERNAL, err, 975 "failed to issue %s ioctl due to unexpected system " 976 "error: %s", desc, strerror(err))); 977 } 978 } 979 980 /* 981 * Generate the standard warning about which fields are unused. 982 */ 983 bool 984 nvme_field_miss_err(nvme_ctrl_t *ctrl, const nvme_field_info_t *fields, 985 size_t nfields, nvme_err_t err, const char *desc, uint32_t val) 986 { 987 char buf[512]; 988 bool comma = false; 989 990 VERIFY3U(val, !=, 0); 991 buf[0] = '\0'; 992 for (size_t i = 0; i < nfields; i++) { 993 if ((val & (1 << i)) == 0) { 994 continue; 995 } 996 997 if (comma) { 998 (void) strlcat(buf, ",", sizeof (buf)); 999 } 1000 (void) strlcat(buf, fields[i].nlfi_spec, sizeof (buf)); 1001 comma = true; 1002 } 1003 1004 return (nvme_ctrl_error(ctrl, err, 0, "cannot execute %s request due " 1005 "to missing fields: %s", desc, buf)); 1006 } 1007 1008 bool 1009 nvme_field_check_one(nvme_ctrl_t *ctrl, uint64_t val, const char *req, 1010 const nvme_field_check_t *check, uint32_t allow) 1011 { 1012 const nvme_field_info_t *field = &check->chk_fields[check->chk_index]; 1013 nvme_valid_ctrl_data_t data; 1014 nvme_field_error_t err; 1015 char msg[256]; 1016 1017 if (allow != 0 && (allow & (1 << check->chk_index)) == 0) { 1018 VERIFY3U(check->chk_field_unuse, !=, 0); 1019 return (nvme_ctrl_error(ctrl, check->chk_field_unuse, 0, 1020 "field %s (%s) cannot be set in this %s request", 1021 field->nlfi_human, field->nlfi_spec, req)); 1022 } 1023 1024 data.vcd_vers = &ctrl->nc_vers; 1025 data.vcd_id = &ctrl->nc_info; 1026 1027 err = nvme_field_validate(field, &data, val, msg, sizeof (msg)); 1028 switch (err) { 1029 case NVME_FIELD_ERR_OK: 1030 break; 1031 case NVME_FIELD_ERR_UNSUP_VERSION: 1032 case NVME_FIELD_ERR_UNSUP_FIELD: 1033 VERIFY3U(check->chk_field_unsup, !=, 0); 1034 return (nvme_ctrl_error(ctrl, check->chk_field_unsup, 0, "%s", 1035 msg)); 1036 case NVME_FIELD_ERR_BAD_VALUE: 1037 VERIFY3U(check->chk_field_range, !=, 0); 1038 return (nvme_ctrl_error(ctrl, check->chk_field_range, 0, "%s", 1039 msg)); 1040 } 1041 1042 return (true); 1043 } 1044