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 2016 Nexenta Systems, Inc. 14 * Copyright 2019 Western Digital Corporation 15 */ 16 17 /* 18 * functions for printing of NVMe data structures and their members 19 */ 20 21 #include <sys/byteorder.h> 22 #include <sys/types.h> 23 #include <inttypes.h> 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <strings.h> 27 #include <stdarg.h> 28 #include <err.h> 29 #include <assert.h> 30 31 #include "nvmeadm.h" 32 33 static int nvme_strlen(const char *, int); 34 35 static void nvme_print_str(int, char *, int, const char *, int); 36 static void nvme_print_double(int, char *, double, int, char *); 37 static void nvme_print_uint64(int, char *, uint64_t, const char *, char *); 38 static void nvme_print_uint128(int, char *, nvme_uint128_t, char *, int, int); 39 static void nvme_print_bit(int, char *, int, char *, char *); 40 41 #define ARRAYSIZE(x) (sizeof (x) / sizeof (*(x))) 42 43 static const char *generic_status_codes[] = { 44 "Successful Completion", 45 "Invalid Command Opcode", 46 "Invalid Field in Command", 47 "Command ID Conflict", 48 "Data Transfer Error", 49 "Commands Aborted due to Power Loss Notification", 50 "Internal Error", 51 "Command Abort Requested", 52 "Command Aborted due to SQ Deletion", 53 "Command Aborted due to Failed Fused Command", 54 "Command Aborted due to Missing Fused Command", 55 "Invalid Namespace or Format", 56 "Command Sequence Error", 57 /* NVMe 1.1 */ 58 "Invalid SGL Segment Descriptor", 59 "Invalid Number of SGL Descriptors", 60 "Data SGL Length Invalid", 61 "Metadata SGL Length Invalid", 62 "SGL Descriptor Type Invalid", 63 /* NVMe 1.2 */ 64 "Invalid Use of Controller Memory Buffer", 65 "PRP Offset Invalid", 66 "Atomic Write Unit Exceeded" 67 }; 68 69 static const char *specific_status_codes[] = { 70 "Completion Queue Invalid", 71 "Invalid Queue Identifier", 72 "Invalid Queue Size", 73 "Abort Command Limit Exceeded", 74 "Reserved", 75 "Asynchronous Event Request Limit Exceeded", 76 "Invalid Firmware Slot", 77 "Invalid Firmware Image", 78 "Invalid Interrupt Vector", 79 "Invalid Log Page", 80 "Invalid Format", 81 "Firmware Activation Requires Conventional Reset", 82 "Invalid Queue Deletion", 83 /* NVMe 1.1 */ 84 "Feature Identifier Not Saveable", 85 "Feature Not Changeable", 86 "Feature Not Namespace Specific", 87 "Firmware Activation Requires NVM Subsystem Reset", 88 /* NVMe 1.2 */ 89 "Firmware Activation Requires Reset", 90 "Firmware Activation Requires Maximum Time Violation", 91 "Firmware Activation Prohibited", 92 "Overlapping Range", 93 "Namespace Insufficient Capacity", 94 "Namespace Identifier Unavailable", 95 "Reserved", 96 "Namespace Already Attached", 97 "Namespace Is Private", 98 "Namespace Not Attached", 99 "Thin Provisioning Not Supported", 100 "Controller List Invalid" 101 }; 102 103 static const char *generic_nvm_status_codes[] = { 104 "LBA Out Of Range", 105 "Capacity Exceeded", 106 "Namespace Not Ready", 107 /* NVMe 1.1 */ 108 "Reservation Conflict", 109 /* NVMe 1.2 */ 110 "Format In Progress", 111 }; 112 113 static const char *specific_nvm_status_codes[] = { 114 "Conflicting Attributes", 115 "Invalid Protection Information", 116 "Attempted Write to Read Only Range" 117 }; 118 119 static const char *media_nvm_status_codes[] = { 120 "Write Fault", 121 "Unrecovered Read Error", 122 "End-to-End Guard Check Error", 123 "End-to-End Application Tag Check Error", 124 "End-to-End Reference Tag Check Error", 125 "Compare Failure", 126 "Access Denied", 127 /* NVMe 1.2 */ 128 "Deallocated or Unwritten Logical Block" 129 }; 130 131 static const char *status_code_types[] = { 132 "Generic Command Status", 133 "Command Specific Status", 134 "Media Errors", 135 "Reserved", 136 "Reserved", 137 "Reserved", 138 "Reserved", 139 "Vendor Specific" 140 }; 141 142 static const char *lbaf_relative_performance[] = { 143 "Best", "Better", "Good", "Degraded" 144 }; 145 146 static const char *lba_range_types[] = { 147 "Reserved", "Filesystem", "RAID", "Cache", "Page/Swap File" 148 }; 149 150 /* 151 * nvme_print 152 * 153 * This function prints a string indented by the specified number of spaces, 154 * optionally followed by the specified index if it is >= 0. If a format string 155 * is specified, a single colon and the required number of spaces for alignment 156 * are printed before the format string and any remaining arguments are passed 157 * vprintf. 158 * 159 * NVME_PRINT_ALIGN was chosen so that all values will be lined up nicely even 160 * for the longest name at its default indentation. 161 */ 162 163 #define NVME_PRINT_ALIGN 43 164 165 void 166 nvme_print(int indent, char *name, int index, const char *fmt, ...) 167 { 168 int align = NVME_PRINT_ALIGN - (indent + strlen(name) + 1); 169 va_list ap; 170 171 if (index >= 0) 172 align -= snprintf(NULL, 0, " %d", index); 173 174 if (align < 0) 175 align = 0; 176 177 va_start(ap, fmt); 178 179 (void) printf("%*s%s", indent, "", name); 180 181 if (index >= 0) 182 (void) printf(" %d", index); 183 184 if (fmt != NULL) { 185 (void) printf(": %*s", align, ""); 186 (void) vprintf(fmt, ap); 187 } 188 189 (void) printf("\n"); 190 va_end(ap); 191 } 192 193 /* 194 * nvme_strlen -- return length of string without trailing whitespace 195 */ 196 static int 197 nvme_strlen(const char *str, int len) 198 { 199 if (len < 0) 200 return (0); 201 202 while (str[--len] == ' ') 203 ; 204 205 return (++len); 206 } 207 208 /* 209 * nvme_print_str -- print a string up to the specified length 210 */ 211 static void 212 nvme_print_str(int indent, char *name, int index, const char *value, int len) 213 { 214 if (len == 0) 215 len = strlen(value); 216 217 nvme_print(indent, name, index, "%.*s", nvme_strlen(value, len), value); 218 } 219 220 /* 221 * nvme_print_double -- print a double up to a specified number of places with 222 * optional unit 223 */ 224 static void 225 nvme_print_double(int indent, char *name, double value, int places, char *unit) 226 { 227 if (unit == NULL) 228 unit = ""; 229 230 nvme_print(indent, name, -1, "%.*g%s", places, value, unit); 231 } 232 233 /* 234 * nvme_print_uint64 -- print uint64_t with optional unit in decimal or another 235 * format specified 236 */ 237 static void 238 nvme_print_uint64(int indent, char *name, uint64_t value, const char *fmt, 239 char *unit) 240 { 241 char *tmp_fmt; 242 243 if (unit == NULL) 244 unit = ""; 245 246 if (fmt == NULL) 247 fmt = "%"PRId64; 248 249 if (asprintf(&tmp_fmt, "%s%%s", fmt) < 0) 250 err(-1, "nvme_print_uint64()"); 251 252 nvme_print(indent, name, -1, tmp_fmt, value, unit); 253 254 free(tmp_fmt); 255 } 256 257 /* 258 * nvme_print_uint128 -- print a 128bit uint with optional unit, after applying 259 * binary and/or decimal shifting 260 */ 261 static void 262 nvme_print_uint128(int indent, char *name, nvme_uint128_t value, char *unit, 263 int scale_bits, int scale_tens) 264 { 265 const char hex[] = "0123456789abcdef"; 266 uint8_t o[(128 + scale_bits) / 3]; 267 char p[sizeof (o) * 2]; 268 char *pp = &p[0]; 269 int i, x; 270 uint64_t rem = 0; 271 272 if (unit == NULL) 273 unit = ""; 274 275 /* 276 * Don't allow binary shifting by more than 64 bits to keep the 277 * arithmetic simple. Also limit decimal shifting based on the size 278 * of any possible remainder from binary shifting. 279 */ 280 assert(scale_bits <= 64); 281 assert(scale_tens <= (64 - scale_bits) / 3); 282 283 bzero(o, sizeof (o)); 284 bzero(p, sizeof (p)); 285 286 /* 287 * Convert the two 64-bit numbers into a series of BCD digits using 288 * a double-dabble algorithm. By using more or less iterations than 289 * 128 we can do a binary shift in either direction. 290 */ 291 for (x = 0; x != 128 - scale_bits; x++) { 292 for (i = 0; i != sizeof (o); i++) { 293 if ((o[i] & 0xf0) > 0x40) 294 o[i] += 0x30; 295 296 if ((o[i] & 0xf) > 4) 297 o[i] += 3; 298 } 299 300 for (i = 0; i != sizeof (o) - 1; i++) 301 o[i] = (o[i] << 1) + (o[i+1] >> 7); 302 303 o[i] = (o[i] << 1) + (value.hi >> 63); 304 305 value.hi = (value.hi << 1) + (value.lo >> 63); 306 value.lo = (value.lo << 1); 307 } 308 309 /* 310 * If we're supposed to do a decimal left shift (* 10^x), too, 311 * calculate the remainder of the previous binary shift operation. 312 */ 313 if (scale_tens > 0) { 314 rem = value.hi >> (64 - scale_bits); 315 316 for (i = 0; i != scale_tens; i++) 317 rem *= 10; 318 319 rem >>= scale_bits; 320 } 321 322 /* 323 * Construct the decimal number for printing. Skip leading zeros. 324 */ 325 for (i = 0; i < sizeof (o); i++) 326 if (o[i] != 0) 327 break; 328 329 if (i == sizeof (o)) { 330 /* 331 * The converted number is 0. Just print the calculated 332 * remainder and return. 333 */ 334 nvme_print(indent, name, -1, "%"PRId64"%s", rem, unit); 335 return; 336 } else { 337 if (o[i] > 0xf) 338 *pp++ = hex[o[i] >> 4]; 339 340 *pp++ = hex[o[i] & 0xf]; 341 342 for (i++; i < sizeof (o); i++) { 343 *pp++ = hex[o[i] >> 4]; 344 *pp++ = hex[o[i] & 0xf]; 345 } 346 } 347 348 /* 349 * For negative decimal scaling, use the printf precision specifier to 350 * truncate the results according to the requested decimal scaling. For 351 * positive decimal scaling we print the remainder padded with 0. 352 */ 353 nvme_print(indent, name, -1, "%.*s%0.*"PRId64"%s", 354 strlen(p) + scale_tens, p, 355 scale_tens > 0 ? scale_tens : 0, rem, 356 unit); 357 } 358 359 /* 360 * nvme_print_bit -- print a bit with optional names for both states 361 */ 362 static void 363 nvme_print_bit(int indent, char *name, int value, char *s_true, char *s_false) 364 { 365 if (s_true == NULL) 366 s_true = "supported"; 367 if (s_false == NULL) 368 s_false = "unsupported"; 369 370 nvme_print(indent, name, -1, "%s", value ? s_true : s_false); 371 } 372 373 /* 374 * nvme_print_ctrl_summary -- print a 1-line summary of the IDENTIFY CONTROLLER 375 * data structure 376 */ 377 void 378 nvme_print_ctrl_summary(nvme_identify_ctrl_t *idctl, nvme_version_t *version) 379 { 380 (void) printf("model: %.*s, serial: %.*s, FW rev: %.*s, NVMe v%d.%d\n", 381 nvme_strlen(idctl->id_model, sizeof (idctl->id_model)), 382 idctl->id_model, 383 nvme_strlen(idctl->id_serial, sizeof (idctl->id_serial)), 384 idctl->id_serial, 385 nvme_strlen(idctl->id_fwrev, sizeof (idctl->id_fwrev)), 386 idctl->id_fwrev, 387 version->v_major, version->v_minor); 388 } 389 390 /* 391 * nvme_print_nsid_summary -- print a 1-line summary of the IDENTIFY NAMESPACE 392 * data structure 393 */ 394 void 395 nvme_print_nsid_summary(nvme_identify_nsid_t *idns) 396 { 397 int bsize = 1 << idns->id_lbaf[idns->id_flbas.lba_format].lbaf_lbads; 398 399 (void) printf("Size = %"PRId64" MB, " 400 "Capacity = %"PRId64" MB, " 401 "Used = %"PRId64" MB\n", 402 idns->id_nsize * bsize / 1024 / 1024, 403 idns->id_ncap * bsize / 1024 / 1024, 404 idns->id_nuse * bsize / 1024 / 1024); 405 406 } 407 408 /* 409 * nvme_print_identify_ctrl 410 * 411 * This function pretty-prints the structure returned by the IDENTIFY CONTROLLER 412 * command. 413 */ 414 void 415 nvme_print_identify_ctrl(nvme_identify_ctrl_t *idctl, 416 nvme_capabilities_t *cap, nvme_version_t *version) 417 { 418 int i; 419 420 nvme_print(0, "Identify Controller", -1, NULL); 421 nvme_print(2, "Controller Capabilities and Features", -1, NULL); 422 nvme_print_str(4, "Model", -1, 423 idctl->id_model, sizeof (idctl->id_model)); 424 nvme_print_str(4, "Serial", -1, 425 idctl->id_serial, sizeof (idctl->id_serial)); 426 nvme_print_str(4, "Firmware Revision", -1, 427 idctl->id_fwrev, sizeof (idctl->id_fwrev)); 428 if (verbose) { 429 nvme_print_uint64(4, "PCI vendor ID", 430 idctl->id_vid, "0x%0.4"PRIx64, NULL); 431 nvme_print_uint64(4, "subsystem vendor ID", 432 idctl->id_ssvid, "0x%0.4"PRIx64, NULL); 433 nvme_print_uint64(4, "Recommended Arbitration Burst", 434 idctl->id_rab, NULL, NULL); 435 nvme_print(4, "Vendor IEEE OUI", -1, "%0.2X-%0.2X-%0.2X", 436 idctl->id_oui[0], idctl->id_oui[1], idctl->id_oui[2]); 437 } 438 nvme_print(4, "Multi-Interface Capabilities", -1, NULL); 439 nvme_print_bit(6, "Multiple PCI Express ports", 440 idctl->id_mic.m_multi_pci, NULL, NULL); 441 442 if (NVME_VERSION_ATLEAST(version, 1, 1)) { 443 nvme_print_bit(6, "Multiple Controllers", 444 idctl->id_mic.m_multi_ctrl, NULL, NULL); 445 nvme_print_bit(6, "Is SR-IOV virtual function", 446 idctl->id_mic.m_sr_iov, "yes", "no"); 447 } 448 if (idctl->id_mdts > 0) 449 nvme_print_uint64(4, "Maximum Data Transfer Size", 450 (1 << idctl->id_mdts) * cap->mpsmin / 1024, NULL, "kB"); 451 else 452 nvme_print_str(4, "Maximum Data Transfer Size", -1, 453 "unlimited", 0); 454 455 if (NVME_VERSION_ATLEAST(version, 1, 1)) { 456 nvme_print_uint64(4, "Unique Controller Identifier", 457 idctl->id_cntlid, "0x%0.4"PRIx64, NULL); 458 } 459 460 nvme_print(2, "Admin Command Set Attributes", -1, NULL); 461 nvme_print(4, "Optional Admin Command Support", -1, NULL); 462 nvme_print_bit(6, "Security Send & Receive", 463 idctl->id_oacs.oa_security, NULL, NULL); 464 nvme_print_bit(6, "Format NVM", 465 idctl->id_oacs.oa_format, NULL, NULL); 466 nvme_print_bit(6, "Firmware Activate & Download", 467 idctl->id_oacs.oa_firmware, NULL, NULL); 468 if (verbose) { 469 nvme_print_uint64(4, "Abort Command Limit", 470 (uint16_t)idctl->id_acl + 1, NULL, NULL); 471 nvme_print_uint64(4, "Asynchronous Event Request Limit", 472 (uint16_t)idctl->id_aerl + 1, NULL, NULL); 473 } 474 nvme_print(4, "Firmware Updates", -1, NULL); 475 nvme_print_bit(6, "Firmware Slot 1", 476 idctl->id_frmw.fw_readonly, "read-only", "writable"); 477 nvme_print_uint64(6, "No. of Firmware Slots", 478 idctl->id_frmw.fw_nslot, NULL, NULL); 479 nvme_print(2, "Log Page Attributes", -1, NULL); 480 nvme_print_bit(6, "per Namespace SMART/Health info", 481 idctl->id_lpa.lp_smart, NULL, NULL); 482 nvme_print_uint64(4, "Error Log Page Entries", 483 (uint16_t)idctl->id_elpe + 1, NULL, NULL); 484 nvme_print_uint64(4, "Number of Power States", 485 (uint16_t)idctl->id_npss + 1, NULL, NULL); 486 if (verbose) { 487 nvme_print_bit(4, "Admin Vendor-specific Command Format", 488 idctl->id_avscc.av_spec, "standard", "vendor-specific"); 489 } 490 491 if (NVME_VERSION_ATLEAST(version, 1, 1)) { 492 nvme_print_bit(4, "Autonomous Power State Transitions", 493 idctl->id_apsta.ap_sup, NULL, NULL); 494 } 495 496 nvme_print(2, "NVM Command Set Attributes", -1, NULL); 497 if (verbose) { 498 nvme_print(4, "Submission Queue Entry Size", -1, 499 "min %d, max %d", 500 1 << idctl->id_sqes.qes_min, 1 << idctl->id_sqes.qes_max); 501 nvme_print(4, "Completion Queue Entry Size", -1, 502 "min %d, max %d", 503 1 << idctl->id_cqes.qes_min, 1 << idctl->id_cqes.qes_max); 504 } 505 nvme_print_uint64(4, "Number of Namespaces", 506 idctl->id_nn, NULL, NULL); 507 nvme_print(4, "Optional NVM Command Support", -1, NULL); 508 nvme_print_bit(6, "Compare", 509 idctl->id_oncs.on_compare, NULL, NULL); 510 nvme_print_bit(6, "Write Uncorrectable", 511 idctl->id_oncs.on_wr_unc, NULL, NULL); 512 nvme_print_bit(6, "Dataset Management", 513 idctl->id_oncs.on_dset_mgmt, NULL, NULL); 514 515 if (NVME_VERSION_ATLEAST(version, 1, 1)) { 516 nvme_print_bit(6, "Write Zeros", 517 idctl->id_oncs.on_wr_zero, NULL, NULL); 518 nvme_print_bit(6, "Save/Select in Get/Set Features", 519 idctl->id_oncs.on_save, NULL, NULL); 520 nvme_print_bit(6, "Reservations", 521 idctl->id_oncs.on_reserve, NULL, NULL); 522 } 523 524 nvme_print(4, "Fused Operation Support", -1, NULL); 525 nvme_print_bit(6, "Compare and Write", 526 idctl->id_fuses.f_cmp_wr, NULL, NULL); 527 nvme_print(4, "Format NVM Attributes", -1, NULL); 528 nvme_print_bit(6, "per Namespace Format", 529 idctl->id_fna.fn_format == 0, NULL, NULL); 530 nvme_print_bit(6, "per Namespace Secure Erase", 531 idctl->id_fna.fn_sec_erase == 0, NULL, NULL); 532 nvme_print_bit(6, "Cryptographic Erase", 533 idctl->id_fna.fn_crypt_erase, NULL, NULL); 534 nvme_print_bit(4, "Volatile Write Cache", 535 idctl->id_vwc.vwc_present, "present", "not present"); 536 nvme_print_uint64(4, "Atomic Write Unit Normal", 537 (uint32_t)idctl->id_awun + 1, NULL, 538 idctl->id_awun == 0 ? " block" : " blocks"); 539 nvme_print_uint64(4, "Atomic Write Unit Power Fail", 540 (uint32_t)idctl->id_awupf + 1, NULL, 541 idctl->id_awupf == 0 ? " block" : " blocks"); 542 543 if (verbose != 0) 544 nvme_print_bit(4, "NVM Vendor-specific Command Format", 545 idctl->id_nvscc.nv_spec, "standard", "vendor-specific"); 546 547 if (NVME_VERSION_ATLEAST(version, 1, 1)) { 548 nvme_print_uint64(4, "Atomic Compare & Write Size", 549 (uint32_t)idctl->id_acwu + 1, NULL, 550 idctl->id_acwu == 0 ? " block" : " blocks"); 551 nvme_print(4, "SGL Support", -1, NULL); 552 nvme_print_bit(6, "SGLs in NVM commands", 553 idctl->id_sgls.sgl_sup, NULL, NULL); 554 nvme_print_bit(6, "SGL Bit Bucket Descriptor", 555 idctl->id_sgls.sgl_bucket, NULL, NULL); 556 } 557 558 for (i = 0; i != idctl->id_npss + 1; i++) { 559 double scale = 0.01; 560 double power = 0; 561 int places = 2; 562 char *unit = "W"; 563 564 if (NVME_VERSION_ATLEAST(version, 1, 1) && 565 idctl->id_psd[i].psd_mps == 1) { 566 scale = 0.0001; 567 places = 4; 568 } 569 570 power = (double)idctl->id_psd[i].psd_mp * scale; 571 if (power < 1.0) { 572 power *= 1000.0; 573 unit = "mW"; 574 } 575 576 nvme_print(4, "Power State Descriptor", i, NULL); 577 nvme_print_double(6, "Maximum Power", power, places, unit); 578 nvme_print_bit(6, "Non-Operational State", 579 idctl->id_psd[i].psd_nops, "yes", "no"); 580 nvme_print_uint64(6, "Entry Latency", 581 idctl->id_psd[i].psd_enlat, NULL, "us"); 582 nvme_print_uint64(6, "Exit Latency", 583 idctl->id_psd[i].psd_exlat, NULL, "us"); 584 nvme_print_uint64(6, "Relative Read Throughput (0 = best)", 585 idctl->id_psd[i].psd_rrt, NULL, NULL); 586 nvme_print_uint64(6, "Relative Read Latency (0 = best)", 587 idctl->id_psd[i].psd_rrl, NULL, NULL); 588 nvme_print_uint64(6, "Relative Write Throughput (0 = best)", 589 idctl->id_psd[i].psd_rwt, NULL, NULL); 590 nvme_print_uint64(6, "Relative Write Latency (0 = best)", 591 idctl->id_psd[i].psd_rwl, NULL, NULL); 592 } 593 } 594 595 /* 596 * nvme_print_identify_nsid 597 * 598 * This function pretty-prints the structure returned by the IDENTIFY NAMESPACE 599 * command. 600 */ 601 void 602 nvme_print_identify_nsid(nvme_identify_nsid_t *idns, nvme_version_t *version) 603 { 604 int bsize = 1 << idns->id_lbaf[idns->id_flbas.lba_format].lbaf_lbads; 605 int i; 606 607 nvme_print(0, "Identify Namespace", -1, NULL); 608 nvme_print(2, "Namespace Capabilities and Features", -1, NULL); 609 nvme_print_uint64(4, "Namespace Size", 610 idns->id_nsize * bsize / 1024 / 1024, NULL, "MB"); 611 nvme_print_uint64(4, "Namespace Capacity", 612 idns->id_ncap * bsize / 1024 / 1024, NULL, "MB"); 613 nvme_print_uint64(4, "Namespace Utilization", 614 idns->id_nuse * bsize / 1024 / 1024, NULL, "MB"); 615 nvme_print(4, "Namespace Features", -1, NULL); 616 nvme_print_bit(6, "Thin Provisioning", 617 idns->id_nsfeat.f_thin, NULL, NULL); 618 nvme_print_uint64(4, "Number of LBA Formats", 619 (uint16_t)idns->id_nlbaf + 1, NULL, NULL); 620 nvme_print(4, "Formatted LBA Size", -1, NULL); 621 nvme_print_uint64(6, "LBA Format", 622 (uint16_t)idns->id_flbas.lba_format, NULL, NULL); 623 nvme_print_bit(6, "Extended Data LBA", 624 idns->id_flbas.lba_extlba, "yes", "no"); 625 nvme_print(4, "Metadata Capabilities", -1, NULL); 626 nvme_print_bit(6, "Extended Data LBA", 627 idns->id_mc.mc_extlba, NULL, NULL); 628 nvme_print_bit(6, "Separate Metadata", 629 idns->id_mc.mc_separate, NULL, NULL); 630 nvme_print(4, "End-to-End Data Protection Capabilities", -1, NULL); 631 nvme_print_bit(6, "Protection Information Type 1", 632 idns->id_dpc.dp_type1, NULL, NULL); 633 nvme_print_bit(6, "Protection Information Type 2", 634 idns->id_dpc.dp_type2, NULL, NULL); 635 nvme_print_bit(6, "Protection Information Type 3", 636 idns->id_dpc.dp_type3, NULL, NULL); 637 nvme_print_bit(6, "Protection Information first", 638 idns->id_dpc.dp_first, NULL, NULL); 639 nvme_print_bit(6, "Protection Information last", 640 idns->id_dpc.dp_last, NULL, NULL); 641 nvme_print(4, "End-to-End Data Protection Settings", -1, NULL); 642 if (idns->id_dps.dp_pinfo == 0) 643 nvme_print_str(6, "Protection Information", -1, 644 "disabled", 0); 645 else 646 nvme_print_uint64(6, "Protection Information Type", 647 idns->id_dps.dp_pinfo, NULL, NULL); 648 nvme_print_bit(6, "Protection Information in Metadata", 649 idns->id_dps.dp_first, "first 8 bytes", "last 8 bytes"); 650 651 if (NVME_VERSION_ATLEAST(version, 1, 1)) { 652 nvme_print(4, "Namespace Multi-Path I/O and Namespace Sharing " 653 "Capabilities", -1, NULL); 654 nvme_print_bit(6, "Namespace is shared", 655 idns->id_nmic.nm_shared, "yes", "no"); 656 nvme_print(2, "Reservation Capabilities", -1, NULL); 657 nvme_print_bit(6, "Persist Through Power Loss", 658 idns->id_rescap.rc_persist, NULL, NULL); 659 nvme_print_bit(6, "Write Exclusive", 660 idns->id_rescap.rc_wr_excl, NULL, NULL); 661 nvme_print_bit(6, "Exclusive Access", 662 idns->id_rescap.rc_excl, NULL, NULL); 663 nvme_print_bit(6, "Write Exclusive - Registrants Only", 664 idns->id_rescap.rc_wr_excl_r, NULL, NULL); 665 nvme_print_bit(6, "Exclusive Access - Registrants Only", 666 idns->id_rescap.rc_excl_r, NULL, NULL); 667 nvme_print_bit(6, "Write Exclusive - All Registrants", 668 idns->id_rescap.rc_wr_excl_a, NULL, NULL); 669 nvme_print_bit(6, "Exclusive Access - All Registrants", 670 idns->id_rescap.rc_excl_a, NULL, NULL); 671 672 nvme_print(4, "IEEE Extended Unique Identifier", -1, 673 "%0.2X%0.2X%0.2X%0.2X%0.2X%0.2X%0.2X%0.2X", 674 idns->id_eui64[0], idns->id_eui64[1], 675 idns->id_eui64[2], idns->id_eui64[3], 676 idns->id_eui64[4], idns->id_eui64[5], 677 idns->id_eui64[6], idns->id_eui64[7]); 678 } 679 680 for (i = 0; i <= idns->id_nlbaf; i++) { 681 if (verbose == 0 && idns->id_lbaf[i].lbaf_ms != 0) 682 continue; 683 684 nvme_print(4, "LBA Format", i, NULL); 685 nvme_print_uint64(6, "Metadata Size", 686 idns->id_lbaf[i].lbaf_ms, NULL, " bytes"); 687 nvme_print_uint64(6, "LBA Data Size", 688 1 << idns->id_lbaf[i].lbaf_lbads, NULL, " bytes"); 689 nvme_print_str(6, "Relative Performance", -1, 690 lbaf_relative_performance[idns->id_lbaf[i].lbaf_rp], 0); 691 } 692 } 693 694 /* 695 * nvme_print_error_log 696 * 697 * This function pretty-prints all non-zero error log entries, or all entries 698 * if verbose is set. 699 */ 700 void 701 nvme_print_error_log(int nlog, nvme_error_log_entry_t *elog) 702 { 703 int i; 704 705 nvme_print(0, "Error Log", -1, NULL); 706 for (i = 0; i != nlog; i++) 707 if (elog[i].el_count == 0) 708 break; 709 nvme_print_uint64(2, "Number of Error Log Entries", i, NULL, NULL); 710 711 for (i = 0; i != nlog; i++) { 712 int sc = elog[i].el_sf.sf_sc; 713 const char *sc_str = ""; 714 715 if (elog[i].el_count == 0 && verbose == 0) 716 break; 717 718 switch (elog[i].el_sf.sf_sct) { 719 case 0: /* Generic Command Status */ 720 if (sc < ARRAYSIZE(generic_status_codes)) 721 sc_str = generic_status_codes[sc]; 722 else if (sc >= 0x80 && 723 sc - 0x80 < ARRAYSIZE(generic_nvm_status_codes)) 724 sc_str = generic_nvm_status_codes[sc - 0x80]; 725 break; 726 case 1: /* Specific Command Status */ 727 if (sc < ARRAYSIZE(specific_status_codes)) 728 sc_str = specific_status_codes[sc]; 729 else if (sc >= 0x80 && 730 sc - 0x80 < ARRAYSIZE(specific_nvm_status_codes)) 731 sc_str = specific_nvm_status_codes[sc - 0x80]; 732 break; 733 case 2: /* Media Errors */ 734 if (sc >= 0x80 && 735 sc - 0x80 < ARRAYSIZE(media_nvm_status_codes)) 736 sc_str = media_nvm_status_codes[sc - 0x80]; 737 break; 738 case 7: /* Vendor Specific */ 739 sc_str = "Unknown Vendor Specific"; 740 break; 741 default: 742 sc_str = "Reserved"; 743 break; 744 } 745 746 nvme_print(2, "Entry", i, NULL); 747 nvme_print_uint64(4, "Error Count", 748 elog[i].el_count, NULL, NULL); 749 nvme_print_uint64(4, "Submission Queue ID", 750 elog[i].el_sqid, NULL, NULL); 751 nvme_print_uint64(4, "Command ID", 752 elog[i].el_cid, NULL, NULL); 753 nvme_print(4, "Status Field", -1, NULL); 754 nvme_print_uint64(6, "Phase Tag", 755 elog[i].el_sf.sf_p, NULL, NULL); 756 nvme_print(6, "Status Code", -1, "0x%0.2x (%s)", 757 sc, sc_str); 758 nvme_print(6, "Status Code Type", -1, "0x%x (%s)", 759 elog[i].el_sf.sf_sct, 760 status_code_types[elog[i].el_sf.sf_sct]); 761 nvme_print_bit(6, "More", 762 elog[i].el_sf.sf_m, "yes", "no"); 763 nvme_print_bit(6, "Do Not Retry", 764 elog[i].el_sf.sf_m, "yes", "no"); 765 nvme_print_uint64(4, "Parameter Error Location byte", 766 elog[i].el_byte, "0x%0.2"PRIx64, NULL); 767 nvme_print_uint64(4, "Parameter Error Location bit", 768 elog[i].el_bit, NULL, NULL); 769 nvme_print_uint64(4, "Logical Block Address", 770 elog[i].el_lba, NULL, NULL); 771 nvme_print(4, "Namespace ID", -1, "%d", 772 elog[i].el_nsid == 0xffffffff ? 773 0 : elog[i].el_nsid); 774 nvme_print_uint64(4, 775 "Vendor Specifc Information Available", 776 elog[i].el_vendor, NULL, NULL); 777 } 778 } 779 780 /* 781 * nvme_print_health_log 782 * 783 * This function pretty-prints a summary of the SMART/Health log, or all 784 * of the log if verbose is set. 785 */ 786 void 787 nvme_print_health_log(nvme_health_log_t *hlog, nvme_identify_ctrl_t *idctl) 788 { 789 nvme_print(0, "SMART/Health Information", -1, NULL); 790 nvme_print(2, "Critical Warnings", -1, NULL); 791 nvme_print_bit(4, "Available Space", 792 hlog->hl_crit_warn.cw_avail, "low", "OK"); 793 nvme_print_bit(4, "Temperature", 794 hlog->hl_crit_warn.cw_temp, "too high", "OK"); 795 nvme_print_bit(4, "Device Reliability", 796 hlog->hl_crit_warn.cw_reliab, "degraded", "OK"); 797 nvme_print_bit(4, "Media", 798 hlog->hl_crit_warn.cw_readonly, "read-only", "OK"); 799 if (idctl->id_vwc.vwc_present != 0) 800 nvme_print_bit(4, "Volatile Memory Backup", 801 hlog->hl_crit_warn.cw_volatile, "failed", "OK"); 802 803 nvme_print_uint64(2, "Temperature", 804 hlog->hl_temp - 273, NULL, "C"); 805 nvme_print_uint64(2, "Available Spare Capacity", 806 hlog->hl_avail_spare, NULL, "%"); 807 808 if (verbose != 0) 809 nvme_print_uint64(2, "Available Spare Threshold", 810 hlog->hl_avail_spare_thr, NULL, "%"); 811 812 nvme_print_uint64(2, "Device Life Used", 813 hlog->hl_used, NULL, "%"); 814 815 if (verbose == 0) 816 return; 817 818 /* 819 * The following two fields are in 1000 512 byte units. Convert that to 820 * GB by doing binary shifts (9 left and 30 right) and muliply by 10^3. 821 */ 822 nvme_print_uint128(2, "Data Read", 823 hlog->hl_data_read, "GB", 30 - 9, 3); 824 nvme_print_uint128(2, "Data Written", 825 hlog->hl_data_write, "GB", 30 - 9, 3); 826 827 nvme_print_uint128(2, "Read Commands", 828 hlog->hl_host_read, NULL, 0, 0); 829 nvme_print_uint128(2, "Write Commands", 830 hlog->hl_host_write, NULL, 0, 0); 831 nvme_print_uint128(2, "Controller Busy", 832 hlog->hl_ctrl_busy, "min", 0, 0); 833 nvme_print_uint128(2, "Power Cycles", 834 hlog->hl_power_cycles, NULL, 0, 0); 835 nvme_print_uint128(2, "Power On", 836 hlog->hl_power_on_hours, "h", 0, 0); 837 nvme_print_uint128(2, "Unsafe Shutdowns", 838 hlog->hl_unsafe_shutdn, NULL, 0, 0); 839 nvme_print_uint128(2, "Uncorrectable Media Errors", 840 hlog->hl_media_errors, NULL, 0, 0); 841 nvme_print_uint128(2, "Errors Logged", 842 hlog->hl_errors_logged, NULL, 0, 0); 843 } 844 845 /* 846 * nvme_print_fwslot_log 847 * 848 * This function pretty-prints the firmware slot information. 849 */ 850 void 851 nvme_print_fwslot_log(nvme_fwslot_log_t *fwlog) 852 { 853 int i; 854 855 nvme_print(0, "Firmware Slot Information", -1, NULL); 856 nvme_print_uint64(2, "Active Firmware Slot", fwlog->fw_afi, NULL, NULL); 857 if (fwlog->fw_next != 0) 858 nvme_print_uint64(2, "Next Firmware Slot", fwlog->fw_next, 859 NULL, NULL); 860 861 for (i = 0; i != ARRAYSIZE(fwlog->fw_frs); i++) { 862 nvme_print_str(2, "Firmware Revision for Slot", i + 1, 863 fwlog->fw_frs[i][0] == '\0' ? "<Unused>" : 864 fwlog->fw_frs[i], sizeof (fwlog->fw_frs[i])); 865 } 866 } 867 868 /* 869 * nvme_print_feat_* 870 * 871 * These functions pretty-print the data structures returned by GET FEATURES. 872 */ 873 void 874 nvme_print_feat_arbitration(uint64_t res, void *b, size_t s, 875 nvme_identify_ctrl_t *id) 876 { 877 _NOTE(ARGUNUSED(b)); 878 _NOTE(ARGUNUSED(s)); 879 _NOTE(ARGUNUSED(id)); 880 nvme_arbitration_t arb; 881 882 arb.r = (uint32_t)res; 883 if (arb.b.arb_ab != 7) 884 nvme_print_uint64(4, "Arbitration Burst", 885 1 << arb.b.arb_ab, NULL, NULL); 886 else 887 nvme_print_str(4, "Arbitration Burst", 0, 888 "no limit", 0); 889 nvme_print_uint64(4, "Low Priority Weight", 890 (uint16_t)arb.b.arb_lpw + 1, NULL, NULL); 891 nvme_print_uint64(4, "Medium Priority Weight", 892 (uint16_t)arb.b.arb_mpw + 1, NULL, NULL); 893 nvme_print_uint64(4, "High Priority Weight", 894 (uint16_t)arb.b.arb_hpw + 1, NULL, NULL); 895 } 896 897 void 898 nvme_print_feat_power_mgmt(uint64_t res, void *b, size_t s, 899 nvme_identify_ctrl_t *id) 900 { 901 _NOTE(ARGUNUSED(b)); 902 _NOTE(ARGUNUSED(s)); 903 _NOTE(ARGUNUSED(id)); 904 nvme_power_mgmt_t pm; 905 906 pm.r = (uint32_t)res; 907 nvme_print_uint64(4, "Power State", (uint8_t)pm.b.pm_ps, 908 NULL, NULL); 909 } 910 911 void 912 nvme_print_feat_lba_range(uint64_t res, void *buf, size_t bufsize, 913 nvme_identify_ctrl_t *id) 914 { 915 _NOTE(ARGUNUSED(id)); 916 917 nvme_lba_range_type_t lrt; 918 nvme_lba_range_t *lr; 919 size_t n_lr; 920 int i; 921 922 if (buf == NULL) 923 return; 924 925 lrt.r = res; 926 lr = buf; 927 928 n_lr = bufsize / sizeof (nvme_lba_range_t); 929 if (n_lr > lrt.b.lr_num + 1) 930 n_lr = lrt.b.lr_num + 1; 931 932 nvme_print_uint64(4, "Number of LBA Ranges", 933 (uint8_t)lrt.b.lr_num + 1, NULL, NULL); 934 935 for (i = 0; i != n_lr; i++) { 936 if (verbose == 0 && lr[i].lr_nlb == 0) 937 continue; 938 939 nvme_print(4, "LBA Range", i, NULL); 940 if (lr[i].lr_type < ARRAYSIZE(lba_range_types)) 941 nvme_print_str(6, "Type", -1, 942 lba_range_types[lr[i].lr_type], 0); 943 else 944 nvme_print_uint64(6, "Type", 945 lr[i].lr_type, NULL, NULL); 946 nvme_print(6, "Attributes", -1, NULL); 947 nvme_print_bit(8, "Writable", 948 lr[i].lr_attr.lr_write, "yes", "no"); 949 nvme_print_bit(8, "Hidden", 950 lr[i].lr_attr.lr_hidden, "yes", "no"); 951 nvme_print_uint64(6, "Starting LBA", 952 lr[i].lr_slba, NULL, NULL); 953 nvme_print_uint64(6, "Number of Logical Blocks", 954 lr[i].lr_nlb, NULL, NULL); 955 nvme_print(6, "Unique Identifier", -1, 956 "%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x" 957 "%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", 958 lr[i].lr_guid[0], lr[i].lr_guid[1], 959 lr[i].lr_guid[2], lr[i].lr_guid[3], 960 lr[i].lr_guid[4], lr[i].lr_guid[5], 961 lr[i].lr_guid[6], lr[i].lr_guid[7], 962 lr[i].lr_guid[8], lr[i].lr_guid[9], 963 lr[i].lr_guid[10], lr[i].lr_guid[11], 964 lr[i].lr_guid[12], lr[i].lr_guid[13], 965 lr[i].lr_guid[14], lr[i].lr_guid[15]); 966 } 967 } 968 969 void 970 nvme_print_feat_temperature(uint64_t res, void *b, size_t s, 971 nvme_identify_ctrl_t *id) 972 { 973 _NOTE(ARGUNUSED(b)); 974 _NOTE(ARGUNUSED(s)); 975 _NOTE(ARGUNUSED(id)); 976 nvme_temp_threshold_t tt; 977 978 tt.r = (uint32_t)res; 979 nvme_print_uint64(4, "Temperature Threshold", tt.b.tt_tmpth - 273, 980 NULL, "C"); 981 } 982 983 void 984 nvme_print_feat_error(uint64_t res, void *b, size_t s, 985 nvme_identify_ctrl_t *id) 986 { 987 _NOTE(ARGUNUSED(b)); 988 _NOTE(ARGUNUSED(s)); 989 _NOTE(ARGUNUSED(id)); 990 nvme_error_recovery_t er; 991 992 er.r = (uint32_t)res; 993 if (er.b.er_tler > 0) 994 nvme_print_uint64(4, "Time Limited Error Recovery", 995 (uint32_t)er.b.er_tler * 100, NULL, "ms"); 996 else 997 nvme_print_str(4, "Time Limited Error Recovery", -1, 998 "no time limit", 0); 999 } 1000 1001 void 1002 nvme_print_feat_write_cache(uint64_t res, void *b, size_t s, 1003 nvme_identify_ctrl_t *id) 1004 { 1005 _NOTE(ARGUNUSED(b)); 1006 _NOTE(ARGUNUSED(s)); 1007 _NOTE(ARGUNUSED(id)); 1008 nvme_write_cache_t wc; 1009 1010 wc.r = (uint32_t)res; 1011 nvme_print_bit(4, "Volatile Write Cache", 1012 wc.b.wc_wce, "enabled", "disabled"); 1013 } 1014 1015 void 1016 nvme_print_feat_nqueues(uint64_t res, void *b, size_t s, 1017 nvme_identify_ctrl_t *id) 1018 { 1019 _NOTE(ARGUNUSED(b)); 1020 _NOTE(ARGUNUSED(s)); 1021 _NOTE(ARGUNUSED(id)); 1022 nvme_nqueues_t nq; 1023 1024 nq.r = (uint32_t)res; 1025 nvme_print_uint64(4, "Number of Submission Queues", 1026 nq.b.nq_nsq + 1, NULL, NULL); 1027 nvme_print_uint64(4, "Number of Completion Queues", 1028 nq.b.nq_ncq + 1, NULL, NULL); 1029 } 1030 1031 void 1032 nvme_print_feat_intr_coal(uint64_t res, void *b, size_t s, 1033 nvme_identify_ctrl_t *id) 1034 { 1035 _NOTE(ARGUNUSED(b)); 1036 _NOTE(ARGUNUSED(s)); 1037 _NOTE(ARGUNUSED(id)); 1038 nvme_intr_coal_t ic; 1039 1040 ic.r = (uint32_t)res; 1041 nvme_print_uint64(4, "Aggregation Threshold", 1042 ic.b.ic_thr + 1, NULL, NULL); 1043 nvme_print_uint64(4, "Aggregation Time", 1044 (uint16_t)ic.b.ic_time * 100, NULL, "us"); 1045 } 1046 void 1047 nvme_print_feat_intr_vect(uint64_t res, void *b, size_t s, 1048 nvme_identify_ctrl_t *id) 1049 { 1050 _NOTE(ARGUNUSED(b)); 1051 _NOTE(ARGUNUSED(s)); 1052 _NOTE(ARGUNUSED(id)); 1053 nvme_intr_vect_t iv; 1054 char *tmp; 1055 1056 iv.r = (uint32_t)res; 1057 if (asprintf(&tmp, "Vector %d Coalescing Disable", iv.b.iv_iv) < 0) 1058 err(-1, "nvme_print_feat_common()"); 1059 1060 nvme_print_bit(4, tmp, iv.b.iv_cd, "yes", "no"); 1061 } 1062 1063 void 1064 nvme_print_feat_write_atom(uint64_t res, void *b, size_t s, 1065 nvme_identify_ctrl_t *id) 1066 { 1067 _NOTE(ARGUNUSED(b)); 1068 _NOTE(ARGUNUSED(s)); 1069 _NOTE(ARGUNUSED(id)); 1070 nvme_write_atomicity_t wa; 1071 1072 wa.r = (uint32_t)res; 1073 nvme_print_bit(4, "Disable Normal", wa.b.wa_dn, "yes", "no"); 1074 } 1075 1076 void 1077 nvme_print_feat_async_event(uint64_t res, void *b, size_t s, 1078 nvme_identify_ctrl_t *idctl) 1079 { 1080 _NOTE(ARGUNUSED(b)); 1081 _NOTE(ARGUNUSED(s)); 1082 nvme_async_event_conf_t aec; 1083 1084 aec.r = (uint32_t)res; 1085 nvme_print_bit(4, "Available Space below threshold", 1086 aec.b.aec_avail, "enabled", "disabled"); 1087 nvme_print_bit(4, "Temperature above threshold", 1088 aec.b.aec_temp, "enabled", "disabled"); 1089 nvme_print_bit(4, "Device Reliability compromised", 1090 aec.b.aec_reliab, "enabled", "disabled"); 1091 nvme_print_bit(4, "Media read-only", 1092 aec.b.aec_readonly, "enabled", "disabled"); 1093 if (idctl->id_vwc.vwc_present != 0) 1094 nvme_print_bit(4, "Volatile Memory Backup failed", 1095 aec.b.aec_volatile, "enabled", "disabled"); 1096 } 1097 1098 void 1099 nvme_print_feat_auto_pst(uint64_t res, void *buf, size_t bufsize, 1100 nvme_identify_ctrl_t *id) 1101 { 1102 _NOTE(ARGUNUSED(id)); 1103 1104 nvme_auto_power_state_trans_t apst; 1105 nvme_auto_power_state_t *aps; 1106 int i; 1107 int cnt = bufsize / sizeof (nvme_auto_power_state_t); 1108 1109 if (buf == NULL) 1110 return; 1111 1112 apst.r = res; 1113 aps = buf; 1114 1115 nvme_print_bit(4, "Autonomous Power State Transition", 1116 apst.b.apst_apste, "enabled", "disabled"); 1117 for (i = 0; i != cnt; i++) { 1118 if (aps[i].apst_itps == 0 && aps[i].apst_itpt == 0) 1119 break; 1120 1121 nvme_print(4, "Power State", i, NULL); 1122 nvme_print_uint64(6, "Idle Transition Power State", 1123 (uint16_t)aps[i].apst_itps, NULL, NULL); 1124 nvme_print_uint64(6, "Idle Time Prior to Transition", 1125 aps[i].apst_itpt, NULL, "ms"); 1126 } 1127 } 1128 1129 void 1130 nvme_print_feat_progress(uint64_t res, void *b, size_t s, 1131 nvme_identify_ctrl_t *id) 1132 { 1133 _NOTE(ARGUNUSED(b)); 1134 _NOTE(ARGUNUSED(s)); 1135 _NOTE(ARGUNUSED(id)); 1136 nvme_software_progress_marker_t spm; 1137 1138 spm.r = (uint32_t)res; 1139 nvme_print_uint64(4, "Pre-Boot Software Load Count", 1140 spm.b.spm_pbslc, NULL, NULL); 1141 } 1142 1143 static const char * 1144 nvme_str_generic_error(int sc) 1145 { 1146 switch (sc) { 1147 case NVME_CQE_SC_GEN_SUCCESS: 1148 return ("Success"); 1149 default: 1150 return ("See message log (usually /var/adm/messages) " 1151 "for details"); 1152 } 1153 } 1154 1155 static const char * 1156 nvme_str_specific_error(int sc) 1157 { 1158 switch (sc) { 1159 case NVME_CQE_SC_SPC_INV_FW_SLOT: 1160 return ("Invalid firmware slot"); 1161 case NVME_CQE_SC_SPC_INV_FW_IMG: 1162 return ("Invalid firmware image"); 1163 case NVME_CQE_SC_SPC_FW_RESET: 1164 return ("Conventional reset required - use " 1165 "'reboot -p' or similar"); 1166 case NVME_CQE_SC_SPC_FW_NSSR: 1167 return ("NVM subsystem reset required - power cycle " 1168 "your system"); 1169 case NVME_CQE_SC_SPC_FW_NEXT_RESET: 1170 return ("Image will be activated at next reset"); 1171 case NVME_CQE_SC_SPC_FW_MTFA: 1172 return ("Activation requires maxmimum time violation"); 1173 case NVME_CQE_SC_SPC_FW_PROHIBITED: 1174 return ("Activation prohibited"); 1175 default: 1176 return ("See message log (usually /var/adm/messages) " 1177 "for details"); 1178 } 1179 } 1180 1181 const char * 1182 nvme_str_error(int sct, int sc) 1183 { 1184 switch (sct) { 1185 case NVME_CQE_SCT_GENERIC: 1186 return (nvme_str_generic_error(sc)); 1187 1188 case NVME_CQE_SCT_SPECIFIC: 1189 return (nvme_str_specific_error(sc)); 1190 1191 default: 1192 return ("See message log (usually /var/adm/messages) " 1193 "for details"); 1194 } 1195 } 1196