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 * Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
15 * Copyright 2022 Tintri by DDN, Inc. All rights reserved.
16 */
17
18 /*
19 * functions for printing of NVMe data structures and their members
20 */
21
22 #include <sys/sysmacros.h>
23 #include <sys/byteorder.h>
24 #include <sys/types.h>
25 #include <inttypes.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <strings.h>
29 #include <stdarg.h>
30 #include <err.h>
31 #include <assert.h>
32 #include <libcmdutils.h>
33 #include <ctype.h>
34
35 #include "nvmeadm.h"
36
37 static void nvme_print_str(int, const char *, int, const char *, int);
38 static void nvme_print_double(int, const char *, double, int, const char *);
39 static void nvme_print_int64(int, const char *, uint64_t, const char *,
40 const char *);
41 static void nvme_print_uint64(int, const char *, uint64_t, const char *,
42 const char *);
43 static void nvme_print_uint128(int, const char *, nvme_uint128_t, const char *,
44 int, int);
45 static void nvme_print_bit(int, const char *, boolean_t, uint_t, const char *,
46 const char *);
47 static void nvme_print_hexbuf(int, const char *, const uint8_t *, size_t);
48 static void nvme_print_eui64(int, const char *, const uint8_t *);
49 static void nvme_print_guid(int, const char *, const uint8_t *);
50 static void nvme_print_uuid(int, const char *, const uint8_t *);
51
52 static const char *generic_status_codes[] = {
53 "Successful Completion",
54 "Invalid Command Opcode",
55 "Invalid Field in Command",
56 "Command ID Conflict",
57 "Data Transfer Error",
58 "Commands Aborted due to Power Loss Notification",
59 "Internal Error",
60 "Command Abort Requested",
61 "Command Aborted due to SQ Deletion",
62 "Command Aborted due to Failed Fused Command",
63 "Command Aborted due to Missing Fused Command",
64 "Invalid Namespace or Format",
65 "Command Sequence Error",
66 /* NVMe 1.1 -- 0xd */
67 "Invalid SGL Segment Descriptor",
68 "Invalid Number of SGL Descriptors",
69 "Data SGL Length Invalid",
70 "Metadata SGL Length Invalid",
71 "SGL Descriptor Type Invalid",
72 /* NVMe 1.2 -- 0x12 */
73 "Invalid Use of Controller Memory Buffer",
74 "PRP Offset Invalid",
75 "Atomic Write Unit Exceeded",
76 /* NVMe 1.3 -- 0x15 */
77 "Operation Denied",
78 "SGL Offset Invalid",
79 "Reserved",
80 "Host Identifier Inconsistent Format",
81 "Keep Alive Timeout Expired",
82 "Keep Alive Timeout Invalid",
83 "Command Aborted due to Preempt and Abort",
84 "Sanitize Failed",
85 "Sanitize in Progress",
86 "SGL Data Block Granularity Invalid",
87 "Command Not Supported for Queue in CMB",
88 /* NVMe 1.4 -- 0x20 */
89 "Namespace is Write Protected",
90 "Command Interrupted",
91 "Transient Transport Error"
92 };
93
94 static const char *specific_status_codes[] = {
95 "Completion Queue Invalid",
96 "Invalid Queue Identifier",
97 "Invalid Queue Size",
98 "Abort Command Limit Exceeded",
99 "Reserved",
100 "Asynchronous Event Request Limit Exceeded",
101 "Invalid Firmware Slot",
102 "Invalid Firmware Image",
103 "Invalid Interrupt Vector",
104 "Invalid Log Page",
105 "Invalid Format",
106 "Firmware Activation Requires Conventional Reset",
107 "Invalid Queue Deletion",
108 /* NVMe 1.1 -- 0xd */
109 "Feature Identifier Not Saveable",
110 "Feature Not Changeable",
111 "Feature Not Namespace Specific",
112 "Firmware Activation Requires NVM Subsystem Reset",
113 /* NVMe 1.2 -- 0x12 */
114 "Firmware Activation Requires Reset",
115 "Firmware Activation Requires Maximum Time Violation",
116 "Firmware Activation Prohibited",
117 "Overlapping Range",
118 "Namespace Insufficient Capacity",
119 "Namespace Identifier Unavailable",
120 "Reserved",
121 "Namespace Already Attached",
122 "Namespace Is Private",
123 "Namespace Not Attached",
124 "Thin Provisioning Not Supported",
125 "Controller List Invalid",
126 /* NVMe 1.3 -- 0x1e */
127 "Boot Partition Write Prohibited",
128 "Invalid Controller Identifier",
129 "Invalid Secondary Controller State",
130 "Invalid Number of Controller Resources",
131 "Invalid Resource Identifier",
132 /* NVMe 1.4 -- 0x23 */
133 "Sanitize Prohibited While Persistent Memory Region is Enabled",
134 "ANA Group Identifier Invalid",
135 "ANA Attach Failed"
136 };
137
138 static const char *generic_nvm_status_codes[] = {
139 "LBA Out Of Range",
140 "Capacity Exceeded",
141 "Namespace Not Ready",
142 /* NVMe 1.1 */
143 "Reservation Conflict",
144 /* NVMe 1.2 */
145 "Format In Progress",
146 };
147
148 static const char *specific_nvm_status_codes[] = {
149 "Conflicting Attributes",
150 "Invalid Protection Information",
151 "Attempted Write to Read Only Range"
152 };
153
154 static const char *media_nvm_status_codes[] = {
155 "Write Fault",
156 "Unrecovered Read Error",
157 "End-to-End Guard Check Error",
158 "End-to-End Application Tag Check Error",
159 "End-to-End Reference Tag Check Error",
160 "Compare Failure",
161 "Access Denied",
162 /* NVMe 1.2 -- 0x87 (0x7) */
163 "Deallocated or Unwritten Logical Block"
164 };
165
166 static const char *path_status_codes[] = {
167 /* NVMe 1.4 -- 0x00 */
168 "Internal Path Error",
169 "Asymmetric Access Persistent Loss",
170 "Asymmetric Access Inaccessible",
171 "Asymmetric Access Transition"
172 };
173
174 static const char *path_controller_codes[] = {
175 /* NVMe 1.4 -- 0x60 */
176 "Controller Pathing Error"
177 };
178
179 static const char *path_host_codes[] = {
180 /* NVMe 1.4 -- 0x70 */
181 "Host Pathing Error",
182 "Command Aborted by Host"
183 };
184
185 static const char *status_code_types[] = {
186 "Generic Command Status",
187 "Command Specific Status",
188 "Media and Data Integrity Errors",
189 "Path Related Status",
190 "Reserved",
191 "Reserved",
192 "Reserved",
193 "Vendor Specific"
194 };
195
196 static const char *lbaf_relative_performance[] = {
197 "Best", "Better", "Good", "Degraded"
198 };
199
200 static const char *lba_range_types[] = {
201 "Reserved", "Filesystem", "RAID", "Cache", "Page/Swap File"
202 };
203
204 static const char *ns_identifier_type[] = {
205 "Reserved", "IEEE Extended Unique Identifier", "Namespace GUID", "UUID"
206 };
207
208 /*
209 * nvme_print
210 *
211 * This function prints a string indented by the specified number of spaces,
212 * optionally followed by the specified index if it is >= 0. If a format string
213 * is specified, a single colon and the required number of spaces for alignment
214 * are printed before the format string and any remaining arguments are passed
215 * vprintf.
216 *
217 * NVME_PRINT_ALIGN was chosen so that all values will be lined up nicely even
218 * for the longest name at its default indentation.
219 */
220
221 #define NVME_PRINT_ALIGN 43
222
223 void
nvme_print(int indent,const char * name,int index,const char * fmt,...)224 nvme_print(int indent, const char *name, int index, const char *fmt, ...)
225 {
226 int align = NVME_PRINT_ALIGN - (indent + 1);
227 va_list ap;
228
229 if (name != NULL)
230 align -= strlen(name);
231
232 if (index >= 0)
233 align -= snprintf(NULL, 0, " %d", index);
234
235 if (align < 0)
236 align = 0;
237
238 va_start(ap, fmt);
239
240 (void) printf("%*s%s", indent, "", name != NULL ? name : "");
241
242 if (index >= 0)
243 (void) printf(" %d", index);
244
245 if (fmt != NULL) {
246 if (name != NULL || index >= 0)
247 (void) printf(": ");
248 else
249 (void) printf(" ");
250 (void) printf("%*s", align, "");
251 (void) vprintf(fmt, ap);
252 }
253
254 (void) printf("\n");
255 va_end(ap);
256 }
257
258 /*
259 * nvme_strlen -- return length of string without trailing whitespace
260 */
261 int
nvme_strlen(const char * str,int len)262 nvme_strlen(const char *str, int len)
263 {
264 if (len <= 0)
265 return (0);
266
267 while (str[--len] == ' ')
268 ;
269
270 return (++len);
271 }
272
273 /*
274 * nvme_print_str -- print a string up to the specified length
275 */
276 static void
nvme_print_str(int indent,const char * name,int index,const char * value,int len)277 nvme_print_str(int indent, const char *name, int index, const char *value,
278 int len)
279 {
280 if (len == 0)
281 len = strlen(value);
282
283 nvme_print(indent, name, index, "%.*s", nvme_strlen(value, len), value);
284 }
285
286 /*
287 * nvme_print_double -- print a double up to a specified number of places with
288 * optional unit
289 */
290 static void
nvme_print_double(int indent,const char * name,double value,int places,const char * unit)291 nvme_print_double(int indent, const char *name, double value, int places,
292 const char *unit)
293 {
294 if (unit == NULL)
295 unit = "";
296
297 nvme_print(indent, name, -1, "%.*g%s", places, value, unit);
298 }
299
300 /*
301 * nvme_print_int64 -- print int64_t with optional unit in decimal or another
302 * format specified
303 */
304 static void
nvme_print_int64(int indent,const char * name,uint64_t value,const char * fmt,const char * unit)305 nvme_print_int64(int indent, const char *name, uint64_t value, const char *fmt,
306 const char *unit)
307 {
308 char *tmp_fmt;
309
310 if (unit == NULL)
311 unit = "";
312
313 if (fmt == NULL)
314 fmt = "%"PRId64;
315
316 if (asprintf(&tmp_fmt, "%s%%s", fmt) < 0)
317 err(-1, "nvme_print_int64()");
318
319 nvme_print(indent, name, -1, tmp_fmt, value, unit);
320
321 free(tmp_fmt);
322 }
323
324 /*
325 * nvme_print_temp -- The NVMe specification passes most temperature values as
326 * uint16_t values that are encoded in kelvin. This converts them in one place
327 * to Celsius.
328 */
329 static void
nvme_print_temp(int indent,const char * name,uint16_t value)330 nvme_print_temp(int indent, const char *name, uint16_t value)
331 {
332 int64_t temp = (int64_t)value;
333 temp -= 273;
334 nvme_print_int64(indent, name, temp, NULL, "C");
335 }
336
337 /*
338 * nvme_print_uint64 -- print uint64_t with optional unit in decimal or another
339 * format specified
340 */
341 static void
nvme_print_uint64(int indent,const char * name,uint64_t value,const char * fmt,const char * unit)342 nvme_print_uint64(int indent, const char *name, uint64_t value, const char *fmt,
343 const char *unit)
344 {
345 char *tmp_fmt;
346
347 if (unit == NULL)
348 unit = "";
349
350 if (fmt == NULL)
351 fmt = "%"PRIu64;
352
353 if (asprintf(&tmp_fmt, "%s%%s", fmt) < 0)
354 err(-1, "nvme_print_uint64()");
355
356 nvme_print(indent, name, -1, tmp_fmt, value, unit);
357
358 free(tmp_fmt);
359 }
360
361 /*
362 * nvme_snprint_uint128 -- format a 128bit uint with optional unit, after
363 * applying binary and/or decimal shifting
364 */
365 int
nvme_snprint_uint128(char * buf,size_t buflen,nvme_uint128_t value,int scale_bits,int scale_tens)366 nvme_snprint_uint128(char *buf, size_t buflen, nvme_uint128_t value,
367 int scale_bits, int scale_tens)
368 {
369 const char hex[] = "0123456789abcdef";
370 uint8_t o[(128 + scale_bits) / 3];
371 char p[sizeof (o) * 2];
372 char *pp = &p[0];
373 int i, x;
374 uint64_t rem = 0;
375
376 /*
377 * Don't allow binary shifting by more than 64 bits to keep the
378 * arithmetic simple. Also limit decimal shifting based on the size
379 * of any possible remainder from binary shifting.
380 */
381 assert(scale_bits <= 64);
382 assert(scale_tens <= (64 - scale_bits) / 3);
383
384 bzero(o, sizeof (o));
385 bzero(p, sizeof (p));
386
387 /*
388 * Convert the two 64-bit numbers into a series of BCD digits using
389 * a double-dabble algorithm. By using more or less iterations than
390 * 128 we can do a binary shift in either direction.
391 */
392 for (x = 0; x != 128 - scale_bits; x++) {
393 for (i = 0; i != sizeof (o); i++) {
394 if ((o[i] & 0xf0) > 0x40)
395 o[i] += 0x30;
396
397 if ((o[i] & 0xf) > 4)
398 o[i] += 3;
399 }
400
401 for (i = 0; i != sizeof (o) - 1; i++)
402 o[i] = (o[i] << 1) + (o[i+1] >> 7);
403
404 o[i] = (o[i] << 1) + (value.hi >> 63);
405
406 value.hi = (value.hi << 1) + (value.lo >> 63);
407 value.lo = (value.lo << 1);
408 }
409
410 /*
411 * If we're supposed to do a decimal left shift (* 10^x), too,
412 * calculate the remainder of the previous binary shift operation.
413 */
414 if (scale_tens > 0) {
415 rem = value.hi >> (64 - scale_bits);
416
417 for (i = 0; i != scale_tens; i++)
418 rem *= 10;
419
420 rem >>= scale_bits;
421 }
422
423 /*
424 * Construct the decimal number for printing. Skip leading zeros.
425 */
426 for (i = 0; i < sizeof (o); i++)
427 if (o[i] != 0)
428 break;
429
430 if (i == sizeof (o)) {
431 /*
432 * The converted number is 0. Just print the calculated
433 * remainder and return.
434 */
435 return (snprintf(buf, buflen, "%"PRId64, rem));
436 } else {
437 if (o[i] > 0xf)
438 *pp++ = hex[o[i] >> 4];
439
440 *pp++ = hex[o[i] & 0xf];
441
442 for (i++; i < sizeof (o); i++) {
443 *pp++ = hex[o[i] >> 4];
444 *pp++ = hex[o[i] & 0xf];
445 }
446 }
447
448 /*
449 * For negative decimal scaling, use the snprintf precision specifier to
450 * truncate the results according to the requested decimal scaling. For
451 * positive decimal scaling we print the remainder padded with 0.
452 */
453 return (snprintf(buf, buflen, "%.*s%0.*"PRId64,
454 strlen(p) + scale_tens, p,
455 scale_tens > 0 ? scale_tens : 0, rem));
456 }
457
458 /*
459 * nvme_print_uint128 -- print a 128bit uint with optional unit, after applying
460 * binary and/or decimal shifting
461 */
462 static void
nvme_print_uint128(int indent,const char * name,nvme_uint128_t value,const char * unit,int scale_bits,int scale_tens)463 nvme_print_uint128(int indent, const char *name, nvme_uint128_t value,
464 const char *unit, int scale_bits, int scale_tens)
465 {
466 char buf[64];
467
468 if (unit == NULL)
469 unit = "";
470
471 (void) nvme_snprint_uint128(buf, sizeof (buf), value, scale_bits,
472 scale_tens);
473
474 nvme_print(indent, name, -1, "%s%s", buf, unit);
475 }
476
477 /*
478 * nvme_print_bit -- print a bit with optional names for both states
479 */
480 static void
nvme_print_bit(int indent,const char * name,boolean_t valid_vers,uint_t value,const char * s_true,const char * s_false)481 nvme_print_bit(int indent, const char *name, boolean_t valid_vers, uint_t value,
482 const char *s_true, const char *s_false)
483 {
484 if (s_true == NULL)
485 s_true = "supported";
486 if (s_false == NULL)
487 s_false = "unsupported";
488
489 if (!valid_vers)
490 value = 0;
491
492 nvme_print(indent, name, -1, "%s", value ? s_true : s_false);
493 }
494
495 /*
496 * nvme_print_hexbuf -- print a buffer of bytes as a hex dump
497 */
498 static void
nvme_print_hexbuf(int indent,const char * name,const uint8_t * buf,size_t len)499 nvme_print_hexbuf(int indent, const char *name, const uint8_t *buf, size_t len)
500 {
501 /*
502 * The format string is kept in this variable so it can be cut
503 * short to print the remainder after the loop.
504 */
505 char fmt[] = { "%02x %02x %02x %02x %02x %02x %02x %02x" };
506 size_t lines = len / 8;
507 size_t rem = len % 8;
508 size_t i;
509
510 for (i = 0; i < lines; i++) {
511 nvme_print(indent, name, -1, fmt,
512 buf[i*8 + 0], buf[i*8 + 1], buf[i*8 + 2], buf[i*8 + 3],
513 buf[i*8 + 4], buf[i*8 + 5], buf[i*8 + 6], buf[i*8 + 7]);
514 name = NULL;
515 }
516
517 if (rem > 0) {
518 fmt[rem * 5] = '\0';
519
520 nvme_print(indent, name, -1, fmt,
521 buf[i*8 + 0], buf[i*8 + 1], buf[i*8 + 2], buf[i*8 + 3],
522 buf[i*8 + 4], buf[i*8 + 5], buf[i*8 + 6], buf[i*8 + 7]);
523 }
524 }
525
526 /*
527 * nvme_print_uuid -- print a UUID in canonical form
528 */
529 static void
nvme_print_uuid(int indent,const char * name,const uint8_t * uuid)530 nvme_print_uuid(int indent, const char *name, const uint8_t *uuid)
531 {
532 nvme_print(indent, name, -1,
533 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
534 "%02x%02x%02x%02x%02x%02x",
535 uuid[0], uuid[1], uuid[2], uuid[3],
536 uuid[4], uuid[5], uuid[6], uuid[7],
537 uuid[8], uuid[9], uuid[10], uuid[11],
538 uuid[12], uuid[13], uuid[14], uuid[15]);
539 }
540
541 /*
542 * nvme_print_guid -- print a namespace GUID
543 */
544 static void
nvme_print_guid(int indent,const char * name,const uint8_t * guid)545 nvme_print_guid(int indent, const char *name, const uint8_t *guid)
546 {
547 nvme_print(indent, name, -1,
548 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
549 guid[0], guid[1], guid[2], guid[3],
550 guid[4], guid[5], guid[6], guid[7],
551 guid[8], guid[9], guid[10], guid[11],
552 guid[12], guid[13], guid[14], guid[15]);
553 }
554
555 /*
556 * nvme_print_eui64 -- print a namespace EUI64
557 */
558 static void
nvme_print_eui64(int indent,const char * name,const uint8_t * eui64)559 nvme_print_eui64(int indent, const char *name, const uint8_t *eui64)
560 {
561 nvme_print(indent, name, -1,
562 "%02X%02X%02X%02X%02X%02X%02X%02X",
563 eui64[0], eui64[1], eui64[2], eui64[3],
564 eui64[4], eui64[5], eui64[6], eui64[7]);
565 }
566
567 /*
568 * nvme_print_version -- print a uint32_t encoded nvme version
569 */
570 static void
nvme_print_version(int indent,const char * name,uint32_t value)571 nvme_print_version(int indent, const char *name, uint32_t value)
572 {
573 nvme_reg_vs_t vers;
574
575 vers.r = value;
576 nvme_print(indent, name, -1, "%u.%u", vers.b.vs_mjr, vers.b.vs_mnr);
577 }
578
579 /*
580 * nvme_print_ctrl_summary -- print a 1-line summary of the IDENTIFY CONTROLLER
581 * data structure
582 */
583 void
nvme_print_ctrl_summary(nvme_ctrl_info_t * info)584 nvme_print_ctrl_summary(nvme_ctrl_info_t *info)
585 {
586 nvme_uint128_t u128;
587 char buf[64];
588
589 const nvme_version_t *version = nvme_ctrl_info_version(info);
590
591 (void) printf("model: %s, serial: %s, FW rev: %s, NVMe v%u.%u",
592 nvme_ctrl_info_model(info), nvme_ctrl_info_serial(info),
593 nvme_ctrl_info_fwrev(info), version->v_major, version->v_minor);
594
595 /*
596 * This can fail because a device isn't at NVMe version 1.2 or it
597 * doesn't support namespace management.
598 */
599 if (nvme_ctrl_info_cap(info, &u128)) {
600 (void) nvme_snprint_uint128(buf, sizeof (buf), u128, 20, 0);
601 (void) printf(", Capacity = %s MB", buf);
602 }
603
604 if (nvme_ctrl_info_unalloc_cap(info, &u128) && (u128.lo != 0 ||
605 u128.hi != 0)) {
606 (void) nvme_snprint_uint128(buf, sizeof (buf), u128, 20, 0);
607 (void) printf(", Unallocated = %s MB", buf);
608 }
609
610 (void) printf("\n");
611 }
612
613 /*
614 * nvme_print_nsid_summary -- print a 1-line summary of the IDENTIFY NAMESPACE
615 * data structure
616 */
617 void
nvme_print_nsid_summary(nvme_ns_info_t * ns)618 nvme_print_nsid_summary(nvme_ns_info_t *ns)
619 {
620 const nvme_nvm_lba_fmt_t *fmt = NULL;
621 const char *comma = "";
622 uint64_t val;
623 char numbuf[40];
624
625 (void) nvme_ns_info_curformat(ns, &fmt);
626
627 if (nvme_ns_info_size(ns, &val) && fmt != NULL) {
628 nicenum_scale(val, nvme_nvm_lba_fmt_data_size(fmt), numbuf,
629 sizeof (numbuf), NN_UNIT_SPACE);
630 (void) printf("Size = %sB", numbuf);
631 comma = ", ";
632 }
633
634 if (nvme_ns_info_cap(ns, &val) && fmt != NULL) {
635 nicenum_scale(val, nvme_nvm_lba_fmt_data_size(fmt), numbuf,
636 sizeof (numbuf), NN_UNIT_SPACE);
637 (void) printf("%sCapacity = %sB", comma, numbuf);
638 comma = ", ";
639 }
640
641 if (nvme_ns_info_use(ns, &val) && fmt != NULL) {
642 nicenum_scale(val, nvme_nvm_lba_fmt_data_size(fmt), numbuf,
643 sizeof (numbuf), NN_UNIT_SPACE);
644 (void) printf("%sUsed = %sB", comma, numbuf);
645 }
646 (void) printf("\n");
647 }
648
649 /*
650 * nvme_print_identify_ctrl
651 *
652 * This function pretty-prints the structure returned by the IDENTIFY CONTROLLER
653 * command.
654 */
655 void
nvme_print_identify_ctrl(const nvme_identify_ctrl_t * idctl,uint32_t mpsmin,const nvme_version_t * version)656 nvme_print_identify_ctrl(const nvme_identify_ctrl_t *idctl, uint32_t mpsmin,
657 const nvme_version_t *version)
658 {
659 int i;
660
661 nvme_print(0, "Identify Controller", -1, NULL);
662 nvme_print(2, "Controller Capabilities and Features", -1, NULL);
663 nvme_print_str(4, "Model", -1,
664 idctl->id_model, sizeof (idctl->id_model));
665 nvme_print_str(4, "Serial", -1,
666 idctl->id_serial, sizeof (idctl->id_serial));
667 nvme_print_str(4, "Firmware Revision", -1,
668 idctl->id_fwrev, sizeof (idctl->id_fwrev));
669 if (verbose) {
670 nvme_print_uint64(4, "PCI vendor ID",
671 idctl->id_vid, "0x%0.4"PRIx64, NULL);
672 nvme_print_uint64(4, "subsystem vendor ID",
673 idctl->id_ssvid, "0x%0.4"PRIx64, NULL);
674 nvme_print_uint64(4, "Recommended Arbitration Burst",
675 idctl->id_rab, NULL, NULL);
676 nvme_print(4, "Vendor IEEE OUI", -1, "%0.2X-%0.2X-%0.2X",
677 idctl->id_oui[0], idctl->id_oui[1], idctl->id_oui[2]);
678 }
679 nvme_print(4, "Multi-Interface Capabilities", -1, NULL);
680 nvme_print_bit(6, "Multiple PCI Express ports",
681 nvme_vers_atleast(version, &nvme_vers_1v0),
682 idctl->id_mic.m_multi_pci, NULL, NULL);
683 nvme_print_bit(6, "Multiple Controller Support",
684 nvme_vers_atleast(version, &nvme_vers_1v0),
685 idctl->id_mic.m_multi_ctrl, NULL, NULL);
686 nvme_print_bit(6, "Controller is an SR-IOV Virtual Function",
687 nvme_vers_atleast(version, &nvme_vers_1v0),
688 idctl->id_mic.m_sr_iov, NULL, NULL);
689 nvme_print_bit(6, "Asymmetric Namespace Access Reporting",
690 nvme_vers_atleast(version, &nvme_vers_1v4),
691 idctl->id_mic.m_anar_sup, NULL, NULL);
692
693 if (idctl->id_mdts > 0)
694 nvme_print_uint64(4, "Maximum Data Transfer Size",
695 (1 << idctl->id_mdts) * mpsmin / 1024, NULL, "kB");
696 else
697 nvme_print_str(4, "Maximum Data Transfer Size", -1,
698 "unlimited", 0);
699
700 if (nvme_vers_atleast(version, &nvme_vers_1v1)) {
701 nvme_print_uint64(4, "Unique Controller Identifier",
702 idctl->id_cntlid, NULL, NULL);
703 }
704
705 if (nvme_vers_atleast(version, &nvme_vers_1v2)) {
706 nvme_print_version(4, "NVMe Version",
707 idctl->id_ver);
708
709 if (idctl->id_rtd3r != 0) {
710 nvme_print_uint64(4, "RTD3 Resume Latency",
711 idctl->id_rtd3r, NULL, "us");
712 }
713
714 if (idctl->id_rtd3e != 0) {
715 nvme_print_uint64(4, "RTD3 Entry Latency",
716 idctl->id_rtd3e, NULL, "us");
717 }
718 }
719
720 if (verbose) {
721 nvme_print(4, "Optional Asynchronous Events Supported", -1,
722 NULL);
723 nvme_print_bit(6, "Namespace Attribute Notices",
724 nvme_vers_atleast(version, &nvme_vers_1v2),
725 idctl->id_oaes.oaes_nsan, NULL, NULL);
726 nvme_print_bit(6, "Firmware Activation Notices",
727 nvme_vers_atleast(version, &nvme_vers_1v2),
728 idctl->id_oaes.oaes_fwact, NULL, NULL);
729 nvme_print_bit(6, "Asynchronous Namespace Access Change "
730 "Notices",
731 nvme_vers_atleast(version, &nvme_vers_1v4),
732 idctl->id_oaes.oaes_ansacn, NULL, NULL);
733 nvme_print_bit(6, "Predictable Latency Event Aggregation",
734 nvme_vers_atleast(version, &nvme_vers_1v4),
735 idctl->id_oaes.oaes_plat, NULL, NULL);
736 nvme_print_bit(6, "LBA Status Information Notices",
737 nvme_vers_atleast(version, &nvme_vers_1v4),
738 idctl->id_oaes.oaes_lbasi, NULL, NULL);
739 nvme_print_bit(6, "Endurance Group Event Aggregate Log Page "
740 "Change Notices",
741 nvme_vers_atleast(version, &nvme_vers_1v4),
742 idctl->id_oaes.oaes_egeal, NULL, NULL);
743
744 nvme_print(4, "Controller Attributes", -1,
745 NULL);
746 nvme_print_bit(6, "128-bit Host Identifier",
747 nvme_vers_atleast(version, &nvme_vers_1v2),
748 idctl->id_ctratt.ctrat_hid, NULL, NULL);
749 nvme_print_bit(6, "Non-Operational Power State Permissive Mode",
750 nvme_vers_atleast(version, &nvme_vers_1v3),
751 idctl->id_ctratt.ctrat_nops, NULL, NULL);
752 nvme_print_bit(6, "NVM Sets",
753 nvme_vers_atleast(version, &nvme_vers_1v4),
754 idctl->id_ctratt.ctrat_nvmset, NULL, NULL);
755 nvme_print_bit(6, "Read Recovery Levels",
756 nvme_vers_atleast(version, &nvme_vers_1v4),
757 idctl->id_ctratt.ctrat_rrl, NULL, NULL);
758 nvme_print_bit(6, "Endurance Groups",
759 nvme_vers_atleast(version, &nvme_vers_1v4),
760 idctl->id_ctratt.ctrat_engrp, NULL, NULL);
761 nvme_print_bit(6, "Predictable Latency Mode",
762 nvme_vers_atleast(version, &nvme_vers_1v4),
763 idctl->id_ctratt.ctrat_plm, NULL, NULL);
764 nvme_print_bit(6, "Traffic Based Keep Alive",
765 nvme_vers_atleast(version, &nvme_vers_1v4),
766 idctl->id_ctratt.ctrat_tbkas, NULL, NULL);
767 nvme_print_bit(6, "Namespace Granularity",
768 nvme_vers_atleast(version, &nvme_vers_1v4),
769 idctl->id_ctratt.ctrat_nsg, NULL, NULL);
770 nvme_print_bit(6, "SQ Associations",
771 nvme_vers_atleast(version, &nvme_vers_1v4),
772 idctl->id_ctratt.ctrat_sqass, NULL, NULL);
773 nvme_print_bit(6, "UUID List",
774 nvme_vers_atleast(version, &nvme_vers_1v4),
775 idctl->id_ctratt.ctrat_uuid, NULL, NULL);
776
777 nvme_print(4, "Read Recovery Levels", -1,
778 NULL);
779 nvme_print_bit(6, "Read Recovery Level 0",
780 nvme_vers_atleast(version, &nvme_vers_1v4),
781 idctl->id_rrls & (1 << 0), NULL, NULL);
782 nvme_print_bit(6, "Read Recovery Level 1",
783 nvme_vers_atleast(version, &nvme_vers_1v4),
784 idctl->id_rrls & (1 << 1), NULL, NULL);
785 nvme_print_bit(6, "Read Recovery Level 2",
786 nvme_vers_atleast(version, &nvme_vers_1v4),
787 idctl->id_rrls & (1 << 2), NULL, NULL);
788 nvme_print_bit(6, "Read Recovery Level 3",
789 nvme_vers_atleast(version, &nvme_vers_1v4),
790 idctl->id_rrls & (1 << 3), NULL, NULL);
791 nvme_print_bit(6, "Read Recovery Level 4 - Default",
792 nvme_vers_atleast(version, &nvme_vers_1v4),
793 idctl->id_rrls & (1 << 4), NULL, NULL);
794 nvme_print_bit(6, "Read Recovery Level 5",
795 nvme_vers_atleast(version, &nvme_vers_1v4),
796 idctl->id_rrls & (1 << 5), NULL, NULL);
797 nvme_print_bit(6, "Read Recovery Level 6",
798 nvme_vers_atleast(version, &nvme_vers_1v4),
799 idctl->id_rrls & (1 << 6), NULL, NULL);
800 nvme_print_bit(6, "Read Recovery Level 7",
801 nvme_vers_atleast(version, &nvme_vers_1v4),
802 idctl->id_rrls & (1 << 7), NULL, NULL);
803 nvme_print_bit(6, "Read Recovery Level 8",
804 nvme_vers_atleast(version, &nvme_vers_1v4),
805 idctl->id_rrls & (1 << 8), NULL, NULL);
806 nvme_print_bit(6, "Read Recovery Level 9",
807 nvme_vers_atleast(version, &nvme_vers_1v4),
808 idctl->id_rrls & (1 << 9), NULL, NULL);
809 nvme_print_bit(6, "Read Recovery Level 10",
810 nvme_vers_atleast(version, &nvme_vers_1v4),
811 idctl->id_rrls & (1 << 10), NULL, NULL);
812 nvme_print_bit(6, "Read Recovery Level 11",
813 nvme_vers_atleast(version, &nvme_vers_1v4),
814 idctl->id_rrls & (1 << 11), NULL, NULL);
815 nvme_print_bit(6, "Read Recovery Level 12",
816 nvme_vers_atleast(version, &nvme_vers_1v4),
817 idctl->id_rrls & (1 << 12), NULL, NULL);
818 nvme_print_bit(6, "Read Recovery Level 13",
819 nvme_vers_atleast(version, &nvme_vers_1v4),
820 idctl->id_rrls & (1 << 13), NULL, NULL);
821 nvme_print_bit(6, "Read Recovery Level 14",
822 nvme_vers_atleast(version, &nvme_vers_1v4),
823 idctl->id_rrls & (1 << 14), NULL, NULL);
824 nvme_print_bit(6, "Read Recovery Level 15 - Fast Fail",
825 nvme_vers_atleast(version, &nvme_vers_1v4),
826 idctl->id_rrls & (1 << 15), NULL, NULL);
827 }
828
829 if (nvme_vers_atleast(version, &nvme_vers_1v4)) {
830 switch (idctl->id_cntrltype) {
831 case NVME_CNTRLTYPE_RSVD:
832 nvme_print_str(4, "Controller Type", -1,
833 "not reported", 0);
834 break;
835 case NVME_CNTRLTYPE_IO:
836 nvme_print_str(4, "Controller Type", -1, "I/O", 0);
837 break;
838 case NVME_CNTRLTYPE_DISC:
839 nvme_print_str(4, "Controller Type", -1, "discovery",
840 0);
841 break;
842 case NVME_CNTRLTYPE_ADMIN:
843 nvme_print_str(4, "Controller Type", -1,
844 "administrative", 0);
845 break;
846 default:
847 nvme_print(4, "Controller Type", -1,
848 "unknown reserved value: %u", idctl->id_cntrltype);
849 break;
850 }
851 } else {
852 nvme_print_str(4, "Controller Type", -1, "not reported", 0);
853 }
854
855 if (nvme_vers_atleast(version, &nvme_vers_1v3)) {
856 uint8_t zguid[16] = { 0 };
857
858 if (memcmp(zguid, idctl->id_frguid, sizeof (zguid)) != 0) {
859 nvme_print_guid(4, "FRU GUID", idctl->id_frguid);
860 } else {
861 nvme_print_str(4, "FRU GUID", -1, "unsupported", 0);
862 }
863 } else {
864 nvme_print_str(4, "FRU GUID", -1, "unsupported", 0);
865 }
866
867 if (nvme_vers_atleast(version, &nvme_vers_1v4)) {
868 nvme_print_uint64(4, "Command Retry Delay Time 1",
869 idctl->id_crdt1 * 100, NULL, "ms");
870 nvme_print_uint64(4, "Command Retry Delay Time 2",
871 idctl->id_crdt2 * 100, NULL, "ms");
872 nvme_print_uint64(4, "Command Retry Delay Time 3",
873 idctl->id_crdt3 * 100, NULL, "ms");
874 } else {
875 nvme_print_str(4, "Command Retry Delay Time 1", -1,
876 "unsupported", 0);
877 nvme_print_str(4, "Command Retry Delay Time 2", -1,
878 "unsupported", 0);
879 nvme_print_str(4, "Command Retry Delay Time 3", -1,
880 "unsupported", 0);
881 }
882
883 /*
884 * The NVMe-MI spec claimed a portion of the identify controller data;
885 * however, there's no way to actually figure out if this data is valid
886 * or not. We basically have to rely on the NVMe spec's initialized to
887 * zero behavior for this region. Unfortunately, there's no way to get
888 * the NVMe-MI version to know when fields were added here so we
889 * basically treat the minimum version required as that of when the
890 * NVMe-MI region was reserved in the NVMe spec, which is 1.2. Note,
891 * these bytes go in reverse order because they're allocating them in
892 * reverse order.
893 */
894 if (verbose) {
895 nvme_print(2, "NVMe Management Interface", -1, NULL);
896 nvme_print(4, "Management Endpoint Capabilities", -1, NULL);
897 nvme_print_bit(6, "SMBus/I2C Port Management Endpoint",
898 nvme_vers_atleast(version, &nvme_vers_1v2),
899 idctl->id_mec.mec_smbusme, NULL, NULL);
900 nvme_print_bit(6, "PCIe Port Management Endpoint",
901 nvme_vers_atleast(version, &nvme_vers_1v2),
902 idctl->id_mec.mec_pcieme, NULL, NULL);
903
904 if (idctl->id_vpdwc.vwci_valid != 0) {
905 nvme_print_uint64(4, "VPD Write Cycles Remaining",
906 idctl->id_vpdwc.vwci_crem, NULL, NULL);
907 } else {
908 nvme_print_str(4, "VPD Write Cycles Remaining", -1,
909 "invalid or unsupported", 0);
910 }
911
912 if (idctl->id_nvmsr.nvmsr_nvmesd == 0 &&
913 idctl->id_nvmsr.nvmsr_nvmee == 0 &&
914 idctl->id_nvmsr.nvmsr_rsvd == 0) {
915 nvme_print_str(4, "NVM Subsystem Report", -1,
916 "unsupported", 0);
917 } else {
918 nvme_print(4, "NVM Subsystem Report", -1, NULL);
919 nvme_print_bit(6, "NVMe Storage Device",
920 nvme_vers_atleast(version, &nvme_vers_1v2),
921 idctl->id_nvmsr.nvmsr_nvmesd, NULL, NULL);
922 nvme_print_bit(6, "NVMe Enclosure",
923 nvme_vers_atleast(version, &nvme_vers_1v2),
924 idctl->id_nvmsr.nvmsr_nvmee, NULL, NULL);
925 }
926 }
927
928 nvme_print(2, "Admin Command Set Attributes", -1, NULL);
929 nvme_print(4, "Optional Admin Command Support", -1, NULL);
930 nvme_print_bit(6, "Security Send & Receive",
931 nvme_vers_atleast(version, &nvme_vers_1v0),
932 idctl->id_oacs.oa_security, NULL, NULL);
933 nvme_print_bit(6, "Format NVM",
934 nvme_vers_atleast(version, &nvme_vers_1v0),
935 idctl->id_oacs.oa_format, NULL, NULL);
936 nvme_print_bit(6, "Firmware Activate & Download",
937 nvme_vers_atleast(version, &nvme_vers_1v0),
938 idctl->id_oacs.oa_firmware, NULL, NULL);
939 nvme_print_bit(6, "Namespace Management",
940 nvme_vers_atleast(version, &nvme_vers_1v2),
941 idctl->id_oacs.oa_nsmgmt, NULL, NULL);
942 nvme_print_bit(6, "Device Self-test",
943 nvme_vers_atleast(version, &nvme_vers_1v3),
944 idctl->id_oacs.oa_selftest, NULL, NULL);
945 nvme_print_bit(6, "Directives",
946 nvme_vers_atleast(version, &nvme_vers_1v3),
947 idctl->id_oacs.oa_direct, NULL, NULL);
948 nvme_print_bit(6, "NVME-MI Send and Receive",
949 nvme_vers_atleast(version, &nvme_vers_1v3),
950 idctl->id_oacs.oa_nvmemi, NULL, NULL);
951 nvme_print_bit(6, "Virtualization Management",
952 nvme_vers_atleast(version, &nvme_vers_1v3),
953 idctl->id_oacs.oa_virtmgmt, NULL, NULL);
954 nvme_print_bit(6, "Doorbell Buffer Config",
955 nvme_vers_atleast(version, &nvme_vers_1v3),
956 idctl->id_oacs.oa_doorbell, NULL, NULL);
957 nvme_print_bit(6, "Get LBA Status",
958 nvme_vers_atleast(version, &nvme_vers_1v4),
959 idctl->id_oacs.oa_lbastat, NULL, NULL);
960 if (verbose) {
961 nvme_print_uint64(4, "Abort Command Limit",
962 (uint16_t)idctl->id_acl + 1, NULL, NULL);
963 nvme_print_uint64(4, "Asynchronous Event Request Limit",
964 (uint16_t)idctl->id_aerl + 1, NULL, NULL);
965 }
966 nvme_print(4, "Firmware Updates", -1, NULL);
967 nvme_print_bit(6, "Firmware Slot 1",
968 nvme_vers_atleast(version, &nvme_vers_1v0),
969 idctl->id_frmw.fw_readonly, "read-only", "writable");
970 nvme_print_uint64(6, "No. of Firmware Slots",
971 idctl->id_frmw.fw_nslot, NULL, NULL);
972 nvme_print_bit(6, "Activate Without Reset",
973 nvme_vers_atleast(version, &nvme_vers_1v2),
974 idctl->id_frmw.fw_norst, NULL, NULL);
975
976 nvme_print(2, "Log Page Attributes", -1, NULL);
977 nvme_print_bit(6, "Per Namespace SMART/Health info",
978 nvme_vers_atleast(version, &nvme_vers_1v0),
979 idctl->id_lpa.lp_smart, NULL, NULL);
980 nvme_print_bit(6, "Commands Supported and Effects",
981 nvme_vers_atleast(version, &nvme_vers_1v2),
982 idctl->id_lpa.lp_cmdeff, NULL, NULL);
983 nvme_print_bit(6, "Get Log Page Extended Data",
984 nvme_vers_atleast(version, &nvme_vers_1v2),
985 idctl->id_lpa.lp_extsup, NULL, NULL);
986 nvme_print_bit(6, "Telemetry Log Pages",
987 nvme_vers_atleast(version, &nvme_vers_1v3),
988 idctl->id_lpa.lp_telemetry, NULL, NULL);
989 nvme_print_bit(6, "Persistent Event Log",
990 nvme_vers_atleast(version, &nvme_vers_1v4),
991 idctl->id_lpa.lp_persist, NULL, NULL);
992
993 nvme_print_uint64(4, "Error Log Page Entries",
994 (uint16_t)idctl->id_elpe + 1, NULL, NULL);
995 nvme_print_uint64(4, "Number of Power States",
996 (uint16_t)idctl->id_npss + 1, NULL, NULL);
997 if (verbose) {
998 nvme_print_bit(4, "Admin Vendor-specific Command Format",
999 nvme_vers_atleast(version, &nvme_vers_1v0),
1000 idctl->id_avscc.av_spec, "standard", "vendor-specific");
1001 }
1002
1003 nvme_print_bit(4, "Autonomous Power State Transitions",
1004 nvme_vers_atleast(version, &nvme_vers_1v1),
1005 idctl->id_apsta.ap_sup, NULL, NULL);
1006
1007 if (nvme_vers_atleast(version, &nvme_vers_1v2)) {
1008 nvme_print_temp(4, "Warning Composite Temperature Threshold",
1009 idctl->ap_wctemp);
1010 nvme_print_temp(4, "Critical Composite Temperature Threshold",
1011 idctl->ap_cctemp);
1012 } else {
1013 nvme_print_str(4, "Warning Composite Temperature Threshold",
1014 -1, "unspecified", 0);
1015 nvme_print_str(4, "Critical Composite Temperature Threshold",
1016 -1, "unspecified", 0);
1017 }
1018
1019 if (verbose) {
1020 if (idctl->ap_mtfa != 0) {
1021 nvme_print_uint64(4, "Maximum Firmware Activation Time",
1022 idctl->ap_mtfa * 100, NULL, "ms");
1023 } else {
1024 nvme_print_str(4, "Maximum Firmware Activation Time",
1025 -1, "unknown", 0);
1026 }
1027
1028 if (idctl->ap_hmpre != 0) {
1029 nvme_print_uint64(4, "Host Memory Buffer Preferred "
1030 "Size", idctl->ap_hmpre * 4, NULL, "KiB");
1031 } else {
1032 nvme_print_str(4, "Host Memory Buffer Preferred "
1033 "Size", -1, "unsupported", 0);
1034 }
1035
1036 if (idctl->ap_hmmin != 0) {
1037 nvme_print_uint64(4, "Host Memory Buffer Minimum Size",
1038 idctl->ap_hmmin * 4, NULL, "KiB");
1039 } else {
1040 nvme_print_str(4, "Host Memory Buffer Minimum Size",
1041 -1, "unsupported", 0);
1042 }
1043 }
1044
1045 if (idctl->id_oacs.oa_nsmgmt != 0) {
1046 nvme_print_uint128(4, "Total NVM Capacity",
1047 idctl->ap_tnvmcap, "B", 0, 0);
1048 nvme_print_uint128(4, "Unallocated NVM Capacity",
1049 idctl->ap_unvmcap, "B", 0, 0);
1050 } else if (verbose) {
1051 nvme_print_str(4, "Total NVM Capacity", -1,
1052 "unsupported", 0);
1053 nvme_print_str(4, "Unallocated NVM Capacity", -1,
1054 "unsupported", 0);
1055 }
1056
1057 if (verbose) {
1058 if (idctl->ap_rpmbs.rpmbs_units != 0) {
1059 nvme_print(4, "Replay Protected Memory Block", -1,
1060 NULL);
1061 nvme_print_uint64(6, "Number of RPMB Units",
1062 idctl->ap_rpmbs.rpmbs_units, NULL, NULL);
1063 switch (idctl->ap_rpmbs.rpmbs_auth) {
1064 case NVME_RPMBS_AUTH_HMAC_SHA256:
1065 nvme_print_str(6, "Authentication Method", -1,
1066 "HMAC SHA-256", 0);
1067 break;
1068 default:
1069 nvme_print(6, "Authentication Method", -1,
1070 "unknown reserved value: %u",
1071 idctl->ap_rpmbs.rpmbs_auth);
1072 break;
1073 }
1074 nvme_print_uint64(6, "Total Size",
1075 (idctl->ap_rpmbs.rpmbs_tot + 1) * 128, NULL, "KiB");
1076 nvme_print_uint64(6, "Access Size",
1077 (idctl->ap_rpmbs.rpmbs_acc + 1) * 512, NULL, "KiB");
1078 } else {
1079 nvme_print_str(4, "Replay Protected Memory Block", -1,
1080 "unsupported", 0);
1081 }
1082
1083 if (idctl->id_oacs.oa_selftest != 0) {
1084 nvme_print_uint64(4, "Extended Device Self-test Time",
1085 idctl->ap_edstt, NULL, "min");
1086 nvme_print(4, "Device Self-test Options", -1, NULL);
1087 nvme_print_bit(6, "Self-test operation granularity",
1088 nvme_vers_atleast(version, &nvme_vers_1v3),
1089 idctl->ap_dsto.dsto_sub, "subsystem", "controller");
1090 } else {
1091 nvme_print_str(4, "Extended Device Self-test Time", -1,
1092 "unsupported", 0);
1093 nvme_print_str(4, "Device Self-test Options", -1,
1094 "unsupported", 0);
1095 }
1096 }
1097
1098 switch (idctl->ap_fwug) {
1099 case 0x00:
1100 nvme_print_str(4, "Firmware Update Granularity", -1, "unknown",
1101 0);
1102 break;
1103 case 0xff:
1104 nvme_print_str(4, "Firmware Update Granularity", -1,
1105 "unrestricted", 0);
1106 break;
1107 default:
1108 nvme_print_uint64(4, "Firmware Update Granularity",
1109 idctl->ap_fwug * 4, NULL, "KiB");
1110 break;
1111 }
1112
1113 if (verbose) {
1114 if (idctl->ap_kas != 0) {
1115 nvme_print_uint64(4, "Keep Alive Support",
1116 idctl->ap_kas * 100, NULL, "ms");
1117 } else {
1118 nvme_print_str(4, "Keep Alive Support", -1,
1119 "unsupported", 0);
1120 }
1121
1122 nvme_print(4, "Host Controlled Thermal Management Attributes",
1123 -1, NULL);
1124 nvme_print_bit(6, "Host Controlled Thermal Management",
1125 nvme_vers_atleast(version, &nvme_vers_1v3),
1126 idctl->ap_hctma.hctma_hctm, NULL, NULL);
1127 if (idctl->ap_mntmt != 0 && nvme_vers_atleast(version,
1128 &nvme_vers_1v3)) {
1129 nvme_print_temp(6, "Minimum Thermal Management "
1130 "Temperature", idctl->ap_mntmt);
1131 } else {
1132 nvme_print_str(6, "Minimum Thermal Management "
1133 "Temperature", -1, "unsupported", -1);
1134 }
1135
1136 if (idctl->ap_mxtmt != 0 && nvme_vers_atleast(version,
1137 &nvme_vers_1v3)) {
1138 nvme_print_temp(6, "Maximum Thermal Management "
1139 "Temperature", idctl->ap_mxtmt);
1140 } else {
1141 nvme_print_str(6, "Maximum Thermal Management "
1142 "Temperature", -1, "unsupported", -1);
1143 }
1144
1145 nvme_print(4, "Sanitize Capabilities", -1, NULL);
1146 nvme_print_bit(6, "Crypto Erase Support",
1147 nvme_vers_atleast(version, &nvme_vers_1v3),
1148 idctl->ap_sanitize.san_ces, NULL, NULL);
1149 nvme_print_bit(6, "Block Erase Support",
1150 nvme_vers_atleast(version, &nvme_vers_1v3),
1151 idctl->ap_sanitize.san_bes, NULL, NULL);
1152 nvme_print_bit(6, "Overwrite Support",
1153 nvme_vers_atleast(version, &nvme_vers_1v3),
1154 idctl->ap_sanitize.san_ows, NULL, NULL);
1155 nvme_print_bit(6, "No-Deallocate Inhibited",
1156 nvme_vers_atleast(version, &nvme_vers_1v4),
1157 idctl->ap_sanitize.san_ndi, NULL, NULL);
1158 if (nvme_vers_atleast(version, &nvme_vers_1v4)) {
1159 uint_t val = idctl->ap_sanitize.san_nodmmas;
1160 switch (val) {
1161 case NVME_NODMMAS_UNDEF:
1162 nvme_print_str(6, "No-Deallocate Modifies "
1163 "Media after Sanitize", -1,
1164 "undefined", 0);
1165 break;
1166 case NVME_NODMMAS_NOMOD:
1167 nvme_print_str(6, "No-Deallocate Modifies "
1168 "Media after Sanitize", -1,
1169 "no modification", 0);
1170 break;
1171 case NVME_NODMMAS_DOMOD:
1172 nvme_print_str(6, "No-Deallocate Modifies "
1173 "Media after Sanitize", -1,
1174 "modification required", 0);
1175 break;
1176 default:
1177 nvme_print(6, "No-Deallocate Modifies "
1178 "Media after Sanitize", -1,
1179 "unknown reserved value: %u", val);
1180 break;
1181 }
1182 } else {
1183 nvme_print_str(6, "No-Deallocate Modifies Media after "
1184 "Sanitize", -1, "undefined", 0);
1185 }
1186
1187 if (idctl->ap_hmminds != 0) {
1188 nvme_print_uint64(4, "Host Memory Buffer Minimum "
1189 "Descriptor Entry Size", idctl->ap_hmminds * 4,
1190 NULL, "KiB");
1191 } else {
1192 nvme_print_str(4, "Host Memory Buffer Minimum "
1193 "Descriptor Entry Size", -1, "unsupported", 0);
1194 }
1195
1196 if (idctl->ap_hmmaxd != 0) {
1197 nvme_print_uint64(4, "Host Memory Buffer Maximum "
1198 "Descriptor Entries", idctl->ap_hmmaxd,
1199 NULL, NULL);
1200 } else {
1201 nvme_print_str(4, "Host Memory Buffer Maximum "
1202 "Descriptor Entries", -1, "unsupported", 0);
1203 }
1204
1205 if (idctl->id_ctratt.ctrat_engrp != 0) {
1206 nvme_print_uint64(4, "Max Endurance Group Identifier",
1207 idctl->ap_engidmax, NULL, NULL);
1208 } else {
1209 nvme_print_str(4, "Max Endurance Group Identifier",
1210 -1, "unsupported", 0);
1211 }
1212
1213 if (idctl->id_mic.m_anar_sup != 0) {
1214 nvme_print_uint64(4, "ANA Transition Time",
1215 idctl->ap_anatt, NULL, "secs");
1216 } else {
1217 nvme_print_str(4, "ANA Transition Time", -1,
1218 "unsupported", 0);
1219 }
1220
1221 nvme_print(4, "Asymmetric Namespace Access Capabilities",
1222 -1, NULL);
1223 nvme_print_bit(6, "ANA Optimized state",
1224 nvme_vers_atleast(version, &nvme_vers_1v4),
1225 idctl->ap_anacap.anacap_opt, NULL, NULL);
1226 nvme_print_bit(6, "ANA Non-Optimized state",
1227 nvme_vers_atleast(version, &nvme_vers_1v4),
1228 idctl->ap_anacap.anacap_unopt, NULL, NULL);
1229 nvme_print_bit(6, "ANA Inaccessible state",
1230 nvme_vers_atleast(version, &nvme_vers_1v4),
1231 idctl->ap_anacap.anacap_inacc, NULL, NULL);
1232 nvme_print_bit(6, "ANA Persistent Loss state",
1233 nvme_vers_atleast(version, &nvme_vers_1v4),
1234 idctl->ap_anacap.anacap_ploss, NULL, NULL);
1235 nvme_print_bit(6, "ANA Persistent Change state",
1236 nvme_vers_atleast(version, &nvme_vers_1v4),
1237 idctl->ap_anacap.anacap_chg, NULL, NULL);
1238 nvme_print_bit(6, "ANAGRPID doesn't change with attached NS",
1239 nvme_vers_atleast(version, &nvme_vers_1v4),
1240 idctl->ap_anacap.anacap_grpns, "yes", "no");
1241 nvme_print_bit(6, "Non-zero ANAGRPID in Namespace Management",
1242 nvme_vers_atleast(version, &nvme_vers_1v4),
1243 idctl->ap_anacap.anacap_grpid, NULL, NULL);
1244
1245 if (idctl->id_mic.m_anar_sup != 0) {
1246 nvme_print_uint64(4, "Max ANA Group Identifier",
1247 idctl->ap_anagrpmax, NULL, NULL);
1248 nvme_print_uint64(4, "Number of ANA Group Identifiers",
1249 idctl->ap_nanagrpid, NULL, NULL);
1250 } else {
1251 nvme_print_str(4, "Max ANA Group Identifier",
1252 -1, "unsupported", 0);
1253 nvme_print_str(4, "Number of ANA Group Identifiers",
1254 -1, "unsupported", 0);
1255 }
1256
1257 if (idctl->id_lpa.lp_persist != 0) {
1258 nvme_print_uint64(4, "Persistent Event Log Size",
1259 idctl->ap_pels * 64, NULL, "KiB");
1260 } else {
1261 nvme_print_str(4, "Persistent Event Log Size",
1262 -1, "unsupported", 0);
1263 }
1264 }
1265
1266
1267 nvme_print(2, "NVM Command Set Attributes", -1, NULL);
1268 if (verbose) {
1269 nvme_print(4, "Submission Queue Entry Size", -1,
1270 "min %d, max %d",
1271 1 << idctl->id_sqes.qes_min, 1 << idctl->id_sqes.qes_max);
1272 nvme_print(4, "Completion Queue Entry Size", -1,
1273 "min %d, max %d",
1274 1 << idctl->id_cqes.qes_min, 1 << idctl->id_cqes.qes_max);
1275
1276 if (nvme_vers_atleast(version, &nvme_vers_1v2)) {
1277 nvme_print_uint64(4, "Maximum Outstanding Commands",
1278 idctl->id_maxcmd, NULL, NULL);
1279 } else {
1280 nvme_print_str(4, "Maximum Outstanding Commands",
1281 -1, "unknown", 0);
1282 }
1283 }
1284 nvme_print_uint64(4, "Number of Namespaces",
1285 idctl->id_nn, NULL, NULL);
1286 nvme_print(4, "Optional NVM Command Support", -1, NULL);
1287 nvme_print_bit(6, "Compare",
1288 nvme_vers_atleast(version, &nvme_vers_1v0),
1289 idctl->id_oncs.on_compare, NULL, NULL);
1290 nvme_print_bit(6, "Write Uncorrectable",
1291 nvme_vers_atleast(version, &nvme_vers_1v0),
1292 idctl->id_oncs.on_wr_unc, NULL, NULL);
1293 nvme_print_bit(6, "Dataset Management",
1294 nvme_vers_atleast(version, &nvme_vers_1v0),
1295 idctl->id_oncs.on_dset_mgmt, NULL, NULL);
1296 nvme_print_bit(6, "Write Zeros",
1297 nvme_vers_atleast(version, &nvme_vers_1v1),
1298 idctl->id_oncs.on_wr_zero, NULL, NULL);
1299 nvme_print_bit(6, "Save/Select in Get/Set Features",
1300 nvme_vers_atleast(version, &nvme_vers_1v1),
1301 idctl->id_oncs.on_save, NULL, NULL);
1302 nvme_print_bit(6, "Reservations",
1303 nvme_vers_atleast(version, &nvme_vers_1v1),
1304 idctl->id_oncs.on_reserve, NULL, NULL);
1305 nvme_print_bit(6, "Timestamp Feature",
1306 nvme_vers_atleast(version, &nvme_vers_1v3),
1307 idctl->id_oncs.on_ts, NULL, NULL);
1308 nvme_print_bit(6, "Verify",
1309 nvme_vers_atleast(version, &nvme_vers_1v4),
1310 idctl->id_oncs.on_verify, NULL, NULL);
1311
1312 nvme_print(4, "Fused Operation Support", -1, NULL);
1313 nvme_print_bit(6, "Compare and Write",
1314 nvme_vers_atleast(version, &nvme_vers_1v0),
1315 idctl->id_fuses.f_cmp_wr, NULL, NULL);
1316 nvme_print(4, "Format NVM Attributes", -1, NULL);
1317 nvme_print_bit(6, "Per Namespace Format",
1318 nvme_vers_atleast(version, &nvme_vers_1v0),
1319 idctl->id_fna.fn_format == 0, NULL, NULL);
1320 nvme_print_bit(6, "Per Namespace Secure Erase",
1321 nvme_vers_atleast(version, &nvme_vers_1v0),
1322 idctl->id_fna.fn_sec_erase == 0, NULL, NULL);
1323 nvme_print_bit(6, "Cryptographic Erase",
1324 nvme_vers_atleast(version, &nvme_vers_1v0),
1325 idctl->id_fna.fn_crypt_erase, NULL, NULL);
1326 nvme_print(4, "Volatile Write Cache", -1, NULL);
1327 nvme_print_bit(6, "Present",
1328 nvme_vers_atleast(version, &nvme_vers_1v0),
1329 idctl->id_vwc.vwc_present, "yes", "no");
1330 if (verbose) {
1331 switch (idctl->id_vwc.vwc_nsflush) {
1332 case NVME_VWCNS_UNKNOWN:
1333 nvme_print_str(6, "Flush with NSID 0xFFFFFFFF",
1334 -1, "unknown", 0);
1335 break;
1336 case NVME_VWCNS_UNSUP:
1337 nvme_print_str(6, "Flush with NSID 0xFFFFFFFF",
1338 -1, "unsupported", 0);
1339 break;
1340 case NVME_VWCNS_SUP:
1341 nvme_print_str(6, "Flush with NSID 0xFFFFFFFF",
1342 -1, "supported", 0);
1343 break;
1344 default:
1345 nvme_print(6, "Flush with NSID 0xFFFFFFFF",
1346 -1, "unknown reserved value: %u",
1347 idctl->id_vwc.vwc_nsflush);
1348 break;
1349 }
1350 }
1351 nvme_print_uint64(4, "Atomic Write Unit Normal",
1352 (uint32_t)idctl->id_awun + 1, NULL,
1353 idctl->id_awun == 0 ? " block" : " blocks");
1354 nvme_print_uint64(4, "Atomic Write Unit Power Fail",
1355 (uint32_t)idctl->id_awupf + 1, NULL,
1356 idctl->id_awupf == 0 ? " block" : " blocks");
1357
1358 if (verbose != 0) {
1359 nvme_print_bit(4, "NVM Vendor-specific Command Format",
1360 nvme_vers_atleast(version, &nvme_vers_1v0),
1361 idctl->id_nvscc.nv_spec, "standard", "vendor-specific");
1362
1363 nvme_print(4, "Namespace Write Protection Capabilities",
1364 -1, NULL);
1365 nvme_print_bit(6, "Core Support",
1366 nvme_vers_atleast(version, &nvme_vers_1v4),
1367 idctl->id_nwpc.nwpc_base, NULL, NULL);
1368 nvme_print_bit(6, "Write Protect Until Power Cycle",
1369 nvme_vers_atleast(version, &nvme_vers_1v4),
1370 idctl->id_nwpc.nwpc_wpupc, NULL, NULL);
1371 nvme_print_bit(6, "Permanent Write Protect",
1372 nvme_vers_atleast(version, &nvme_vers_1v4),
1373 idctl->id_nwpc.nwpc_permwp, NULL, NULL);
1374 }
1375
1376 if (idctl->id_fuses.f_cmp_wr && nvme_vers_atleast(version,
1377 &nvme_vers_1v1)) {
1378 nvme_print_uint64(4, "Atomic Compare & Write Size",
1379 (uint32_t)idctl->id_acwu + 1, NULL,
1380 idctl->id_acwu == 0 ? " block" : " blocks");
1381 } else {
1382 nvme_print_str(4, "Atomic Compare & Write Size", -1,
1383 "unsupported", 0);
1384 }
1385
1386 nvme_print(4, "SGL Support", -1, NULL);
1387 switch (idctl->id_sgls.sgl_sup) {
1388 case NVME_SGL_UNSUP:
1389 nvme_print_str(6, "Command Set", -1, "unsupported", 0);
1390 break;
1391 case NVME_SGL_SUP_UNALIGN:
1392 nvme_print_str(6, "Command Set", -1, "supported, "
1393 "no restrictions", 0);
1394 break;
1395 case NVME_SGL_SUP_ALIGN:
1396 nvme_print_str(6, "Command Set", -1, "supported, "
1397 "alignment restrictions", 0);
1398 break;
1399 default:
1400 nvme_print(6, "Command Set", -1, "unknown reserved value: %u",
1401 idctl->id_sgls.sgl_sup);
1402 break;
1403 }
1404 nvme_print_bit(6, "Keyed SGL Block Descriptor",
1405 nvme_vers_atleast(version, &nvme_vers_1v2),
1406 idctl->id_sgls.sgl_keyed, NULL, NULL);
1407 nvme_print_bit(6, "SGL Bit Bucket Descriptor",
1408 nvme_vers_atleast(version, &nvme_vers_1v1),
1409 idctl->id_sgls.sgl_bucket, NULL, NULL);
1410 nvme_print_bit(6, "Byte Aligned Contiguous Metadata",
1411 nvme_vers_atleast(version, &nvme_vers_1v2),
1412 idctl->id_sgls.sgl_balign, NULL, NULL);
1413 nvme_print_bit(6, "SGL Longer than Data Transferred",
1414 nvme_vers_atleast(version, &nvme_vers_1v2),
1415 idctl->id_sgls.sgl_sglgtd, NULL, NULL);
1416 nvme_print_bit(6, "MPTR with SGL",
1417 nvme_vers_atleast(version, &nvme_vers_1v2),
1418 idctl->id_sgls.sgl_mptr, NULL, NULL);
1419 nvme_print_bit(6, "SGL Address as Offset",
1420 nvme_vers_atleast(version, &nvme_vers_1v2),
1421 idctl->id_sgls.sgl_offset, NULL, NULL);
1422 nvme_print_bit(6, "Transport SGL Data Block",
1423 nvme_vers_atleast(version, &nvme_vers_1v4),
1424 idctl->id_sgls.sgl_tport, NULL, NULL);
1425 if (verbose) {
1426 if (idctl->id_mnan != 0) {
1427 nvme_print_uint64(4, "Maximum Number of Allowed "
1428 "Namespaces", idctl->id_mnan, NULL, NULL);
1429 } else {
1430 nvme_print(4, "Maximum Number of Allowed "
1431 "Namespaces", -1, "at most %u", idctl->id_nn);
1432 }
1433 }
1434
1435 if (nvme_vers_atleast(version, &nvme_vers_1v2) &&
1436 idctl->id_subnqn[0] != '\0') {
1437 nvme_print_str(4, "NVMe Subsystem Qualified Name", -1,
1438 (char *)idctl->id_subnqn, sizeof (idctl->id_subnqn));
1439 } else {
1440 nvme_print_str(4, "NVMe Subsystem Qualified Name", -1,
1441 "unknown", 0);
1442 }
1443
1444 for (i = 0; i != idctl->id_npss + 1; i++) {
1445 double scale = 0.01;
1446 double power = 0;
1447 int places = 2;
1448 char *unit = "W";
1449
1450 if (nvme_vers_atleast(version, &nvme_vers_1v1) &&
1451 idctl->id_psd[i].psd_mps == 1) {
1452 scale = 0.0001;
1453 places = 4;
1454 }
1455
1456 power = (double)idctl->id_psd[i].psd_mp * scale;
1457 if (power < 1.0) {
1458 power *= 1000.0;
1459 unit = "mW";
1460 }
1461
1462 nvme_print(4, "Power State Descriptor", i, NULL);
1463 nvme_print_double(6, "Maximum Power", power, places, unit);
1464 nvme_print_bit(6, "Non-Operational State",
1465 nvme_vers_atleast(version, &nvme_vers_1v1),
1466 idctl->id_psd[i].psd_nops, "yes", "no");
1467 nvme_print_uint64(6, "Entry Latency",
1468 idctl->id_psd[i].psd_enlat, NULL, "us");
1469 nvme_print_uint64(6, "Exit Latency",
1470 idctl->id_psd[i].psd_exlat, NULL, "us");
1471 nvme_print_uint64(6, "Relative Read Throughput (0 = best)",
1472 idctl->id_psd[i].psd_rrt, NULL, NULL);
1473 nvme_print_uint64(6, "Relative Read Latency (0 = best)",
1474 idctl->id_psd[i].psd_rrl, NULL, NULL);
1475 nvme_print_uint64(6, "Relative Write Throughput (0 = best)",
1476 idctl->id_psd[i].psd_rwt, NULL, NULL);
1477 nvme_print_uint64(6, "Relative Write Latency (0 = best)",
1478 idctl->id_psd[i].psd_rwl, NULL, NULL);
1479 }
1480 }
1481
1482 /*
1483 * nvme_print_identify_nsid
1484 *
1485 * This function pretty-prints the structure returned by the IDENTIFY NAMESPACE
1486 * command.
1487 */
1488 void
nvme_print_identify_nsid(const nvme_identify_nsid_t * idns,const nvme_version_t * version)1489 nvme_print_identify_nsid(const nvme_identify_nsid_t *idns,
1490 const nvme_version_t *version)
1491 {
1492 int bsize = 1 << idns->id_lbaf[idns->id_flbas.lba_format].lbaf_lbads;
1493 int i;
1494
1495 nvme_print(0, "Identify Namespace", -1, NULL);
1496 nvme_print(2, "Namespace Capabilities and Features", -1, NULL);
1497 nvme_print_uint64(4, "Namespace Size",
1498 idns->id_nsize * bsize / 1024 / 1024, NULL, "MB");
1499 nvme_print_uint64(4, "Namespace Capacity",
1500 idns->id_ncap * bsize / 1024 / 1024, NULL, "MB");
1501 nvme_print_uint64(4, "Namespace Utilization",
1502 idns->id_nuse * bsize / 1024 / 1024, NULL, "MB");
1503 nvme_print(4, "Namespace Features", -1, NULL);
1504 nvme_print_bit(6, "Thin Provisioning",
1505 nvme_vers_atleast(version, &nvme_vers_1v0),
1506 idns->id_nsfeat.f_thin, NULL, NULL);
1507 nvme_print_bit(6, "Namespace-specific Atomic Units",
1508 nvme_vers_atleast(version, &nvme_vers_1v2),
1509 idns->id_nsfeat.f_nsabp, NULL, NULL);
1510 nvme_print_bit(6, "Deallocate errors",
1511 nvme_vers_atleast(version, &nvme_vers_1v2),
1512 idns->id_nsfeat.f_dae, NULL, NULL);
1513 nvme_print_bit(6, "Namespace GUID Reuse",
1514 nvme_vers_atleast(version, &nvme_vers_1v2),
1515 idns->id_nsfeat.f_uidreuse, "impossible", "possible");
1516 nvme_print_bit(6, "Namespace-specific I/O Optimized Sizes",
1517 nvme_vers_atleast(version, &nvme_vers_1v4),
1518 idns->id_nsfeat.f_optperf, NULL, NULL);
1519
1520 nvme_print_uint64(4, "Number of LBA Formats",
1521 (uint16_t)idns->id_nlbaf + 1, NULL, NULL);
1522 nvme_print(4, "Formatted LBA Size", -1, NULL);
1523 nvme_print_uint64(6, "LBA Format",
1524 (uint16_t)idns->id_flbas.lba_format, NULL, NULL);
1525 nvme_print_bit(6, "Extended Data LBA",
1526 nvme_vers_atleast(version, &nvme_vers_1v0),
1527 idns->id_flbas.lba_extlba, "yes", "no");
1528
1529 nvme_print(4, "Metadata Capabilities", -1, NULL);
1530 nvme_print_bit(6, "Extended Data LBA",
1531 nvme_vers_atleast(version, &nvme_vers_1v0),
1532 idns->id_mc.mc_extlba, NULL, NULL);
1533 nvme_print_bit(6, "Separate Metadata",
1534 nvme_vers_atleast(version, &nvme_vers_1v0),
1535 idns->id_mc.mc_separate, NULL, NULL);
1536
1537 nvme_print(4, "End-to-End Data Protection Capabilities", -1, NULL);
1538 nvme_print_bit(6, "Protection Information Type 1",
1539 nvme_vers_atleast(version, &nvme_vers_1v0),
1540 idns->id_dpc.dp_type1, NULL, NULL);
1541 nvme_print_bit(6, "Protection Information Type 2",
1542 nvme_vers_atleast(version, &nvme_vers_1v0),
1543 idns->id_dpc.dp_type2, NULL, NULL);
1544 nvme_print_bit(6, "Protection Information Type 3",
1545 nvme_vers_atleast(version, &nvme_vers_1v0),
1546 idns->id_dpc.dp_type3, NULL, NULL);
1547 nvme_print_bit(6, "Protection Information first",
1548 nvme_vers_atleast(version, &nvme_vers_1v0),
1549 idns->id_dpc.dp_first, NULL, NULL);
1550 nvme_print_bit(6, "Protection Information last",
1551 nvme_vers_atleast(version, &nvme_vers_1v0),
1552 idns->id_dpc.dp_last, NULL, NULL);
1553 nvme_print(4, "End-to-End Data Protection Settings", -1, NULL);
1554 if (idns->id_dps.dp_pinfo == 0) {
1555 nvme_print_str(6, "Protection Information", -1,
1556 "disabled", 0);
1557 } else {
1558 nvme_print_uint64(6, "Protection Information Type",
1559 idns->id_dps.dp_pinfo, NULL, NULL);
1560 }
1561 nvme_print_bit(6, "Protection Information in Metadata",
1562 nvme_vers_atleast(version, &nvme_vers_1v0),
1563 idns->id_dps.dp_first, "first 8 bytes", "last 8 bytes");
1564
1565 nvme_print(4, "Namespace Multi-Path I/O and Namespace Sharing "
1566 "Capabilities", -1, NULL);
1567
1568 nvme_print_bit(6, "Namespace is shared",
1569 nvme_vers_atleast(version, &nvme_vers_1v1),
1570 idns->id_nmic.nm_shared, "yes", "no");
1571 nvme_print(2, "Reservation Capabilities", -1, NULL);
1572 nvme_print_bit(6, "Persist Through Power Loss",
1573 nvme_vers_atleast(version, &nvme_vers_1v1),
1574 idns->id_rescap.rc_persist, NULL, NULL);
1575 nvme_print_bit(6, "Write Exclusive",
1576 nvme_vers_atleast(version, &nvme_vers_1v1),
1577 idns->id_rescap.rc_wr_excl, NULL, NULL);
1578 nvme_print_bit(6, "Exclusive Access",
1579 nvme_vers_atleast(version, &nvme_vers_1v1),
1580 idns->id_rescap.rc_excl, NULL, NULL);
1581 nvme_print_bit(6, "Write Exclusive - Registrants Only",
1582 nvme_vers_atleast(version, &nvme_vers_1v1),
1583 idns->id_rescap.rc_wr_excl_r, NULL, NULL);
1584 nvme_print_bit(6, "Exclusive Access - Registrants Only",
1585 nvme_vers_atleast(version, &nvme_vers_1v1),
1586 idns->id_rescap.rc_excl_r, NULL, NULL);
1587 nvme_print_bit(6, "Write Exclusive - All Registrants",
1588 nvme_vers_atleast(version, &nvme_vers_1v1),
1589 idns->id_rescap.rc_wr_excl_a, NULL, NULL);
1590 nvme_print_bit(6, "Exclusive Access - All Registrants",
1591 nvme_vers_atleast(version, &nvme_vers_1v1),
1592 idns->id_rescap.rc_excl_a, NULL, NULL);
1593 nvme_print_bit(6, "Ignore Existing Key Behavior",
1594 nvme_vers_atleast(version, &nvme_vers_1v3),
1595 idns->id_rescap.rc_ign_ekey, "NVMe 1.3 behavior", "pre-NVMe 1.3");
1596
1597 if (idns->id_fpi.fpi_sup != 0) {
1598 nvme_print_uint64(4, "NVM Format Remaining",
1599 idns->id_fpi.fpi_remp, NULL, "%");
1600 } else {
1601 nvme_print_str(4, "NVM Format Remaining", -1, "unsupported", 0);
1602 }
1603
1604 if (verbose) {
1605 if (idns->id_nawun != 0) {
1606 nvme_print_uint64(4, "Namespace Atomic Write Unit "
1607 "Normal", idns->id_nawun + 1, NULL, " blocks");
1608 } else {
1609 nvme_print_str(4, "Namespace Atomic Write Unit "
1610 "Normal", -1, "unspecified", 0);
1611 }
1612
1613 if (idns->id_nawupf != 0) {
1614 nvme_print_uint64(4, "Namespace Atomic Write Unit "
1615 "Power Fail", idns->id_nawupf + 1, NULL, " blocks");
1616 } else {
1617 nvme_print_str(4, "Namespace Atomic Write Unit "
1618 "Power Fail", -1, "unspecified", 0);
1619 }
1620
1621 if (idns->id_nacwu != 0) {
1622 nvme_print_uint64(4, "Namespace Atomic Compare & Write "
1623 "Unit", idns->id_nacwu + 1, NULL, " blocks");
1624 } else {
1625 nvme_print_str(4, "Namespace Atomic Compare & Write "
1626 "Unit", -1, "unspecified", 0);
1627 }
1628
1629 if (idns->id_nabsn != 0) {
1630 nvme_print_uint64(4, "Namespace Atomic Boundary Size "
1631 "Normal", idns->id_nabsn + 1, NULL, " blocks");
1632 } else {
1633 nvme_print_str(4, "Namespace Atomic Boundary Size "
1634 "Normal", -1, "unspecified", 0);
1635 }
1636
1637 if (idns->id_nbao != 0) {
1638 nvme_print(4, "Namespace Atomic Boundary Offset", -1,
1639 "LBA %u", idns->id_nbao);
1640 } else {
1641 nvme_print_str(4, "Namespace Atomic Boundary Offset",
1642 -1, "unspecified", 0);
1643 }
1644
1645 if (idns->id_nabspf != 0) {
1646 nvme_print_uint64(4, "Namespace Atomic Boundary Size "
1647 "Power Fail", idns->id_nabspf + 1, NULL,
1648 idns->id_nabspf == 0 ? " block" : " blocks");
1649 } else {
1650 nvme_print_str(4, "Namespace Atomic Boundary Size "
1651 "Power Fail", -1, "unspecified", 0);
1652 }
1653
1654 if (idns->id_noiob != 0) {
1655 nvme_print_uint64(4, "Namespace Optional I/O Boundary",
1656 idns->id_noiob, NULL,
1657 idns->id_noiob == 1 ? " block" : " blocks");
1658 } else {
1659 nvme_print_str(4, "Namespace Optimal I/O Boundary",
1660 -1, "unspecified", 0);
1661 }
1662 }
1663
1664 if (idns->id_nvmcap.lo != 0 || idns->id_nvmcap.hi != 0) {
1665 nvme_print_uint128(4, "NVM Capacity", idns->id_nvmcap,
1666 "B", 0, 0);
1667 } else {
1668 nvme_print_str(4, "NVM Capacity", -1, "unknown", 0);
1669 }
1670
1671 if (verbose) {
1672 if (idns->id_npwg != 0) {
1673 nvme_print_uint64(4, "Namespace Preferred Write "
1674 "Granularity", idns->id_npwg + 1, NULL, " blocks");
1675 } else {
1676 nvme_print_str(4, "Namespace Preferred Write "
1677 "Granularity", -1, "unspecified", 0);
1678 }
1679
1680 if (idns->id_npwa != 0) {
1681 nvme_print_uint64(4, "Namespace Preferred Write "
1682 "Alignment", idns->id_npwa + 1, NULL, " blocks");
1683 } else {
1684 nvme_print_str(4, "Namespace Preferred Write "
1685 "Alignment", -1, "unspecified", 0);
1686 }
1687
1688 if (idns->id_npdg != 0) {
1689 nvme_print_uint64(4, "Namespace Preferred Deallocate "
1690 "Granularity", idns->id_npdg + 1, NULL, " blocks");
1691 } else {
1692 nvme_print_str(4, "Namespace Preferred Deallocate "
1693 "Granularity", -1, "unspecified", 0);
1694 }
1695
1696 if (idns->id_npda != 0) {
1697 nvme_print_uint64(4, "Namespace Preferred Deallocate "
1698 "Alignment", idns->id_npda + 1, NULL, " blocks");
1699 } else {
1700 nvme_print_str(4, "Namespace Preferred Deallocate "
1701 "Alignment", -1, "unspecified", 0);
1702 }
1703
1704 if (idns->id_nows != 0) {
1705 nvme_print_uint64(4, "Namespace Optimal Write Size",
1706 idns->id_nows + 1, NULL, " blocks");
1707 } else {
1708 nvme_print_str(4, "Namespace Optimal Write Size",
1709 -1, "unspecified", 0);
1710 }
1711
1712 if (idns->id_anagrpid != 0) {
1713 nvme_print_uint64(4, "Namespace ANA Group Identifier",
1714 idns->id_anagrpid, NULL, NULL);
1715 } else {
1716 nvme_print_str(4, "Namespace ANA Group Identifier",
1717 -1, "unsupported", 0);
1718 }
1719 }
1720
1721 nvme_print(4, "Namespace Attributes", -1, NULL);
1722 nvme_print_bit(6, "Write Protected",
1723 nvme_vers_atleast(version, &nvme_vers_1v4),
1724 idns->id_nsattr.nsa_wprot, "yes", "no");
1725
1726 if (verbose) {
1727 if (idns->id_nvmsetid != 0) {
1728 nvme_print_uint64(4, "Namespace Set Identifier",
1729 idns->id_nvmsetid, NULL, NULL);
1730 } else {
1731 nvme_print_str(4, "Namespace Set Identifier",
1732 -1, "unsupported", 0);
1733 }
1734
1735 if (idns->id_endgid != 0) {
1736 nvme_print_uint64(4, "Namespace Endurance Group "
1737 "Identifier", idns->id_endgid, NULL, NULL);
1738 } else {
1739 nvme_print_str(4, "Namespace Endurance Group "
1740 "Identifier", -1, "unsupported", 0);
1741 }
1742 }
1743
1744 if (nvme_vers_atleast(version, &nvme_vers_1v2)) {
1745 uint8_t guid[16] = { 0 };
1746 if (memcmp(guid, idns->id_nguid, sizeof (guid) != 0)) {
1747 nvme_print_guid(4, "Namespace GUID", idns->id_nguid);
1748 } else {
1749 nvme_print_str(4, "Namespace GUID",
1750 -1, "unsupported", 0);
1751 }
1752 } else {
1753 nvme_print_str(4, "Namespace GUID", -1, "unsupported", 0);
1754 }
1755
1756
1757 if (nvme_vers_atleast(version, &nvme_vers_1v1)) {
1758 uint8_t oui[8] = { 0 };
1759 if (memcmp(oui, idns->id_eui64, sizeof (oui)) != 0) {
1760 nvme_print_eui64(4, "IEEE Extended Unique Identifier",
1761 idns->id_eui64);
1762 } else {
1763 nvme_print_str(4, "IEEE Extended Unique Identifier",
1764 -1, "unsupported", 0);
1765 }
1766 } else {
1767 nvme_print_str(4, "IEEE Extended Unique Identifier", -1,
1768 "unsupported", 0);
1769 }
1770
1771 for (i = 0; i <= idns->id_nlbaf; i++) {
1772 if (verbose == 0 && idns->id_lbaf[i].lbaf_ms != 0)
1773 continue;
1774
1775 nvme_print(4, "LBA Format", i, NULL);
1776 nvme_print_uint64(6, "Metadata Size",
1777 idns->id_lbaf[i].lbaf_ms, NULL, " bytes");
1778 nvme_print_uint64(6, "LBA Data Size",
1779 1 << idns->id_lbaf[i].lbaf_lbads, NULL, " bytes");
1780 nvme_print_str(6, "Relative Performance", -1,
1781 lbaf_relative_performance[idns->id_lbaf[i].lbaf_rp], 0);
1782 }
1783 }
1784
1785 /*
1786 * nvme_print_identify_nsid_list
1787 *
1788 * Print a NVMe Namespace List.
1789 */
1790 void
nvme_print_identify_nsid_list(const char * header,const nvme_identify_nsid_list_t * nslist)1791 nvme_print_identify_nsid_list(const char *header,
1792 const nvme_identify_nsid_list_t *nslist)
1793 {
1794 uint32_t i;
1795
1796 nvme_print(0, header, -1, NULL);
1797
1798 /*
1799 * The namespace ID list is ordered, unused entries are 0.
1800 */
1801 for (i = 0;
1802 i < ARRAY_SIZE(nslist->nl_nsid) && nslist->nl_nsid[i] != 0;
1803 i++) {
1804 nvme_print_uint64(2, "Namespace Identifier", nslist->nl_nsid[i],
1805 NULL, NULL);
1806 }
1807 }
1808
1809 /*
1810 * nvme_print_identify_nsid_desc
1811 *
1812 * Print a NVMe Namespace Identifier Descriptor list.
1813 */
1814 void
nvme_print_identify_nsid_desc(void * nsdesc)1815 nvme_print_identify_nsid_desc(void *nsdesc)
1816 {
1817 const nvme_identify_nsid_desc_t *desc = nsdesc;
1818 int i = 0;
1819 uintptr_t ptr, end;
1820
1821 nvme_print(0, "Namespace Identification Descriptors", -1, NULL);
1822
1823 for (ptr = (uintptr_t)desc, end = ptr + NVME_IDENTIFY_BUFSIZE;
1824 desc->nd_nidl != 0 && ptr + desc->nd_nidl + 4 <= end;
1825 desc = (nvme_identify_nsid_desc_t *)(ptr += desc->nd_nidl + 4)) {
1826 const char *nidt;
1827
1828 if (desc->nd_nidt >= ARRAY_SIZE(ns_identifier_type))
1829 nidt = "Reserved";
1830 else
1831 nidt = ns_identifier_type[desc->nd_nidt];
1832
1833 nvme_print(2, "Namespace Identifier Descriptor", i++, NULL);
1834 nvme_print_str(4, "Namespace Identifier Type", -1, nidt, 0);
1835 nvme_print_uint64(4, "Namespace Identifier Length",
1836 desc->nd_nidl, NULL, NULL);
1837
1838 if (desc->nd_nidt == NVME_NSID_DESC_EUI64 &&
1839 desc->nd_nidl == NVME_NSID_DESC_LEN_EUI64) {
1840 nvme_print_eui64(4, "IEEE Extended Unique Identifier",
1841 desc->nd_nid);
1842 } else if (desc->nd_nidt == NVME_NSID_DESC_NGUID &&
1843 desc->nd_nidl == NVME_NSID_DESC_LEN_NGUID) {
1844 nvme_print_guid(4, "Namespace GUID", desc->nd_nid);
1845 } else if (desc->nd_nidt == NVME_NSID_DESC_NUUID &&
1846 desc->nd_nidl == NVME_NSID_DESC_LEN_NUUID) {
1847 nvme_print_uuid(4, "Namespace UUID", desc->nd_nid);
1848 } else if (desc->nd_nidt < NVME_NSID_DESC_MIN ||
1849 desc->nd_nidt > NVME_NSID_DESC_MAX) {
1850 nvme_print_hexbuf(4, "Raw Bytes", desc->nd_nid,
1851 desc->nd_nidl);
1852 } else {
1853 nvme_print_hexbuf(4,
1854 "Raw Bytes (Invalid Descriptor Length)",
1855 desc->nd_nid, desc->nd_nidl);
1856 }
1857 }
1858 }
1859
1860 /*
1861 * nvme_print_identify_ctrl_list
1862 *
1863 * Print a NVMe Controller List.
1864 */
1865 void
nvme_print_identify_ctrl_list(const char * header,const nvme_identify_ctrl_list_t * ctlist)1866 nvme_print_identify_ctrl_list(const char *header,
1867 const nvme_identify_ctrl_list_t *ctlist)
1868 {
1869 int i;
1870
1871 nvme_print(0, header, -1, NULL);
1872 for (i = 0; i != ctlist->cl_nid; i++) {
1873 nvme_print_uint64(2, "Controller Identifier",
1874 ctlist->cl_ctlid[i], NULL, NULL);
1875 }
1876 }
1877
1878 /*
1879 * nvme_print_error_log
1880 *
1881 * This function pretty-prints all non-zero error log entries, or all entries
1882 * if verbose is set.
1883 */
1884 void
nvme_print_error_log(int nlog,const nvme_error_log_entry_t * elog,const nvme_version_t * version)1885 nvme_print_error_log(int nlog, const nvme_error_log_entry_t *elog,
1886 const nvme_version_t *version)
1887 {
1888 int i;
1889
1890 nvme_print(0, "Error Log", -1, NULL);
1891 for (i = 0; i != nlog; i++)
1892 if (elog[i].el_count == 0)
1893 break;
1894 nvme_print_uint64(2, "Number of Error Log Entries", i, NULL, NULL);
1895
1896 for (i = 0; i != nlog; i++) {
1897 int sc = elog[i].el_sf.sf_sc;
1898 const char *sc_str = "Unknown";
1899
1900 if (elog[i].el_count == 0 && verbose == 0)
1901 break;
1902
1903 switch (elog[i].el_sf.sf_sct) {
1904 case 0: /* Generic Command Status */
1905 if (sc < ARRAY_SIZE(generic_status_codes)) {
1906 sc_str = generic_status_codes[sc];
1907 } else if (sc >= 0x80 &&
1908 sc - 0x80 < ARRAY_SIZE(generic_nvm_status_codes)) {
1909 sc_str = generic_nvm_status_codes[sc - 0x80];
1910 }
1911 break;
1912 case 1: /* Specific Command Status */
1913 if (sc < ARRAY_SIZE(specific_status_codes)) {
1914 sc_str = specific_status_codes[sc];
1915 } else if (sc >= 0x80 &&
1916 sc - 0x80 < ARRAY_SIZE(specific_nvm_status_codes)) {
1917 sc_str = specific_nvm_status_codes[sc - 0x80];
1918 }
1919 break;
1920 case 2: /* Media Errors */
1921 if (sc >= 0x80 &&
1922 sc - 0x80 < ARRAY_SIZE(media_nvm_status_codes)) {
1923 sc_str = media_nvm_status_codes[sc - 0x80];
1924 }
1925 break;
1926 case 3: /* Path Related Status */
1927 if (sc < ARRAY_SIZE(path_status_codes)) {
1928 sc_str = path_status_codes[sc];
1929 } else if (sc >= 0x60 &&
1930 sc - 0x60 < ARRAY_SIZE(path_controller_codes)) {
1931 sc_str = path_controller_codes[sc - 0x60];
1932 } else if (sc >= 0x70 &&
1933 sc - 0x70 < ARRAY_SIZE(path_host_codes)) {
1934 sc_str = path_host_codes[sc - 0x70];
1935 }
1936 break;
1937 case 7: /* Vendor Specific */
1938 sc_str = "Unknown Vendor Specific";
1939 break;
1940 default:
1941 sc_str = "Reserved";
1942 break;
1943 }
1944
1945 nvme_print(2, "Entry", i, NULL);
1946 nvme_print_uint64(4, "Error Count",
1947 elog[i].el_count, NULL, NULL);
1948 nvme_print_uint64(4, "Submission Queue ID",
1949 elog[i].el_sqid, NULL, NULL);
1950 nvme_print_uint64(4, "Command ID",
1951 elog[i].el_cid, NULL, NULL);
1952 nvme_print(4, "Status Field", -1, NULL);
1953 nvme_print_uint64(6, "Phase Tag",
1954 elog[i].el_sf.sf_p, NULL, NULL);
1955 nvme_print(6, "Status Code", -1, "0x%0.2x (%s)",
1956 sc, sc_str);
1957 nvme_print(6, "Status Code Type", -1, "0x%x (%s)",
1958 elog[i].el_sf.sf_sct,
1959 status_code_types[elog[i].el_sf.sf_sct]);
1960 nvme_print_bit(6, "More",
1961 nvme_vers_atleast(version, &nvme_vers_1v0),
1962 elog[i].el_sf.sf_m, "yes", "no");
1963 nvme_print_bit(6, "Do Not Retry",
1964 nvme_vers_atleast(version, &nvme_vers_1v0),
1965 elog[i].el_sf.sf_m, "yes", "no");
1966 nvme_print_uint64(4, "Parameter Error Location byte",
1967 elog[i].el_byte, "0x%0.2"PRIx64, NULL);
1968 nvme_print_uint64(4, "Parameter Error Location bit",
1969 elog[i].el_bit, NULL, NULL);
1970 nvme_print_uint64(4, "Logical Block Address",
1971 elog[i].el_lba, NULL, NULL);
1972 nvme_print(4, "Namespace ID", -1, "%d",
1973 elog[i].el_nsid == 0xffffffff ?
1974 0 : elog[i].el_nsid);
1975 nvme_print_uint64(4,
1976 "Vendor Specific Information Available",
1977 elog[i].el_vendor, NULL, NULL);
1978 }
1979 }
1980
1981 /*
1982 * nvme_print_health_log
1983 *
1984 * This function pretty-prints a summary of the SMART/Health log, or all
1985 * of the log if verbose is set.
1986 */
1987 void
nvme_print_health_log(const nvme_health_log_t * hlog,const nvme_identify_ctrl_t * idctl,const nvme_version_t * version)1988 nvme_print_health_log(const nvme_health_log_t *hlog,
1989 const nvme_identify_ctrl_t *idctl, const nvme_version_t *version)
1990 {
1991 nvme_print(0, "SMART/Health Information", -1, NULL);
1992 nvme_print(2, "Critical Warnings", -1, NULL);
1993 nvme_print_bit(4, "Available Space",
1994 nvme_vers_atleast(version, &nvme_vers_1v0),
1995 hlog->hl_crit_warn.cw_avail, "low", "OK");
1996 nvme_print_bit(4, "Temperature",
1997 nvme_vers_atleast(version, &nvme_vers_1v0),
1998 hlog->hl_crit_warn.cw_temp, "too high", "OK");
1999 nvme_print_bit(4, "Device Reliability",
2000 nvme_vers_atleast(version, &nvme_vers_1v0),
2001 hlog->hl_crit_warn.cw_reliab, "degraded", "OK");
2002 nvme_print_bit(4, "Media",
2003 nvme_vers_atleast(version, &nvme_vers_1v0),
2004 hlog->hl_crit_warn.cw_readonly, "read-only", "OK");
2005 if (idctl->id_vwc.vwc_present != 0)
2006 nvme_print_bit(4, "Volatile Memory Backup",
2007 nvme_vers_atleast(version, &nvme_vers_1v0),
2008 hlog->hl_crit_warn.cw_volatile, "failed", "OK");
2009
2010 nvme_print_temp(2, "Temperature", hlog->hl_temp);
2011 nvme_print_uint64(2, "Available Spare Capacity",
2012 hlog->hl_avail_spare, NULL, "%");
2013
2014 if (verbose != 0)
2015 nvme_print_uint64(2, "Available Spare Threshold",
2016 hlog->hl_avail_spare_thr, NULL, "%");
2017
2018 nvme_print_uint64(2, "Device Life Used",
2019 hlog->hl_used, NULL, "%");
2020
2021 if (verbose == 0)
2022 return;
2023
2024 /*
2025 * The following two fields are in 1000 512 byte units. Convert that to
2026 * GB by doing binary shifts (9 left and 30 right) and multiply by 10^3.
2027 */
2028 nvme_print_uint128(2, "Data Read",
2029 hlog->hl_data_read, "GB", 30 - 9, 3);
2030 nvme_print_uint128(2, "Data Written",
2031 hlog->hl_data_write, "GB", 30 - 9, 3);
2032
2033 nvme_print_uint128(2, "Read Commands",
2034 hlog->hl_host_read, NULL, 0, 0);
2035 nvme_print_uint128(2, "Write Commands",
2036 hlog->hl_host_write, NULL, 0, 0);
2037 nvme_print_uint128(2, "Controller Busy",
2038 hlog->hl_ctrl_busy, "min", 0, 0);
2039 nvme_print_uint128(2, "Power Cycles",
2040 hlog->hl_power_cycles, NULL, 0, 0);
2041 nvme_print_uint128(2, "Power On",
2042 hlog->hl_power_on_hours, "h", 0, 0);
2043 nvme_print_uint128(2, "Unsafe Shutdowns",
2044 hlog->hl_unsafe_shutdn, NULL, 0, 0);
2045 nvme_print_uint128(2, "Uncorrectable Media Errors",
2046 hlog->hl_media_errors, NULL, 0, 0);
2047 nvme_print_uint128(2, "Errors Logged",
2048 hlog->hl_errors_logged, NULL, 0, 0);
2049
2050 if (!nvme_vers_atleast(version, &nvme_vers_1v2)) {
2051 return;
2052 }
2053
2054 if (idctl->ap_wctemp != 0) {
2055 nvme_print_uint64(2, "Warning Composite Temperature Time",
2056 hlog->hl_warn_temp_time, NULL, "min");
2057 }
2058
2059 if (idctl->ap_cctemp != 0) {
2060 nvme_print_uint64(2, "Critical Composite Temperature Time",
2061 hlog->hl_crit_temp_time, NULL, "min");
2062 }
2063
2064 if (hlog->hl_temp_sensor_1 != 0) {
2065 nvme_print_temp(2, "Temperature Sensor 1",
2066 hlog->hl_temp_sensor_1);
2067 }
2068
2069 if (hlog->hl_temp_sensor_2 != 0) {
2070 nvme_print_temp(2, "Temperature Sensor 2",
2071 hlog->hl_temp_sensor_2);
2072 }
2073
2074 if (hlog->hl_temp_sensor_3 != 0) {
2075 nvme_print_temp(2, "Temperature Sensor 3",
2076 hlog->hl_temp_sensor_3);
2077 }
2078
2079 if (hlog->hl_temp_sensor_4 != 0) {
2080 nvme_print_temp(2, "Temperature Sensor 4",
2081 hlog->hl_temp_sensor_4);
2082 }
2083
2084 if (hlog->hl_temp_sensor_5 != 0) {
2085 nvme_print_temp(2, "Temperature Sensor 5",
2086 hlog->hl_temp_sensor_5);
2087 }
2088
2089 if (hlog->hl_temp_sensor_6 != 0) {
2090 nvme_print_temp(2, "Temperature Sensor 6",
2091 hlog->hl_temp_sensor_6);
2092 }
2093
2094 if (hlog->hl_temp_sensor_7 != 0) {
2095 nvme_print_temp(2, "Temperature Sensor 7",
2096 hlog->hl_temp_sensor_7);
2097 }
2098
2099 if (hlog->hl_temp_sensor_8 != 0) {
2100 nvme_print_temp(2, "Temperature Sensor 8",
2101 hlog->hl_temp_sensor_8);
2102 }
2103
2104 if (!nvme_vers_atleast(version, &nvme_vers_1v3)) {
2105 return;
2106 }
2107
2108 nvme_print_uint64(2, "Thermal Management Temp 1 Transition Count",
2109 hlog->hl_tmtemp_1_tc, NULL, NULL);
2110
2111 nvme_print_uint64(2, "Thermal Management Temp 2 Transition Count",
2112 hlog->hl_tmtemp_2_tc, NULL, NULL);
2113
2114 nvme_print_uint64(2, "Time for Thermal Management Temp 1",
2115 hlog->hl_tmtemp_1_time, NULL, "sec");
2116
2117 nvme_print_uint64(2, "Time for Thermal Management Temp 2",
2118 hlog->hl_tmtemp_2_time, NULL, "sec");
2119 }
2120
2121 /*
2122 * nvme_print_fwslot_log
2123 *
2124 * This function pretty-prints the firmware slot information.
2125 */
2126 void
nvme_print_fwslot_log(const nvme_fwslot_log_t * fwlog,const nvme_identify_ctrl_t * idctl)2127 nvme_print_fwslot_log(const nvme_fwslot_log_t *fwlog,
2128 const nvme_identify_ctrl_t *idctl)
2129 {
2130 int i;
2131
2132 char str[NVME_FWVER_SZ + sizeof (" (read-only)")];
2133
2134 nvme_print(0, "Firmware Slot Information", -1, NULL);
2135 nvme_print_uint64(2, "Active Firmware Slot", fwlog->fw_afi, NULL, NULL);
2136 if (fwlog->fw_next != 0)
2137 nvme_print_uint64(2, "Next Firmware Slot", fwlog->fw_next,
2138 NULL, NULL);
2139
2140
2141 (void) snprintf(str, sizeof (str), "%.*s%s",
2142 nvme_strlen(fwlog->fw_frs[0], sizeof (fwlog->fw_frs[0])),
2143 fwlog->fw_frs[0], idctl->id_frmw.fw_readonly ? " (read-only)" : "");
2144 nvme_print_str(2, "Firmware Revision for Slot", 1, str, sizeof (str));
2145
2146 for (i = 1; i < idctl->id_frmw.fw_nslot; i++) {
2147 nvme_print_str(2, "Firmware Revision for Slot", i + 1,
2148 fwlog->fw_frs[i][0] == '\0' ? "<Unused>" :
2149 fwlog->fw_frs[i], sizeof (fwlog->fw_frs[i]));
2150 }
2151 }
2152
2153 /*
2154 * nvme_print_feat_*
2155 *
2156 * These functions pretty-print the data structures returned by GET FEATURES.
2157 */
2158 void
nvme_print_feat_unknown(nvme_feat_output_t output,uint32_t cdw0,void * b,size_t s)2159 nvme_print_feat_unknown(nvme_feat_output_t output, uint32_t cdw0, void *b,
2160 size_t s)
2161 {
2162 if ((output & NVME_FEAT_OUTPUT_CDW0) != 0) {
2163 nvme_print_uint64(4, "cdw0", cdw0, "0x%"PRIx64, NULL);
2164 }
2165
2166 if ((output & NVME_FEAT_OUTPUT_DATA) != 0) {
2167 nvme_print_hexbuf(4, "data", b, s);
2168 }
2169 }
2170
2171 void
nvme_print_feat_arbitration(uint32_t cdw0,void * b,size_t s,const nvme_identify_ctrl_t * id,const nvme_version_t * version)2172 nvme_print_feat_arbitration(uint32_t cdw0, void *b, size_t s,
2173 const nvme_identify_ctrl_t *id, const nvme_version_t *version)
2174 {
2175 _NOTE(ARGUNUSED(b));
2176 _NOTE(ARGUNUSED(s));
2177 _NOTE(ARGUNUSED(id));
2178 nvme_arbitration_t arb;
2179
2180 arb.r = cdw0;
2181 if (arb.b.arb_ab != 7)
2182 nvme_print_uint64(4, "Arbitration Burst",
2183 1 << arb.b.arb_ab, NULL, NULL);
2184 else
2185 nvme_print_str(4, "Arbitration Burst", 0,
2186 "no limit", 0);
2187 nvme_print_uint64(4, "Low Priority Weight",
2188 (uint16_t)arb.b.arb_lpw + 1, NULL, NULL);
2189 nvme_print_uint64(4, "Medium Priority Weight",
2190 (uint16_t)arb.b.arb_mpw + 1, NULL, NULL);
2191 nvme_print_uint64(4, "High Priority Weight",
2192 (uint16_t)arb.b.arb_hpw + 1, NULL, NULL);
2193 }
2194
2195 void
nvme_print_feat_power_mgmt(uint32_t cdw0,void * b,size_t s,const nvme_identify_ctrl_t * id,const nvme_version_t * version)2196 nvme_print_feat_power_mgmt(uint32_t cdw0, void *b, size_t s,
2197 const nvme_identify_ctrl_t *id, const nvme_version_t *version)
2198 {
2199 _NOTE(ARGUNUSED(b));
2200 _NOTE(ARGUNUSED(s));
2201 _NOTE(ARGUNUSED(id));
2202 nvme_power_mgmt_t pm;
2203
2204 pm.r = cdw0;
2205 nvme_print_uint64(4, "Power State", (uint8_t)pm.b.pm_ps,
2206 NULL, NULL);
2207 }
2208
2209 void
nvme_print_feat_lba_range(uint32_t cdw0,void * buf,size_t bufsize,const nvme_identify_ctrl_t * id,const nvme_version_t * version)2210 nvme_print_feat_lba_range(uint32_t cdw0, void *buf, size_t bufsize,
2211 const nvme_identify_ctrl_t *id, const nvme_version_t *version)
2212 {
2213 _NOTE(ARGUNUSED(id));
2214
2215 nvme_lba_range_type_t lrt;
2216 nvme_lba_range_t *lr;
2217 size_t n_lr;
2218 int i;
2219
2220 if (buf == NULL)
2221 return;
2222
2223 lrt.r = cdw0;
2224 lr = buf;
2225
2226 n_lr = bufsize / sizeof (nvme_lba_range_t);
2227 if (n_lr > lrt.b.lr_num + 1)
2228 n_lr = lrt.b.lr_num + 1;
2229
2230 nvme_print_uint64(4, "Number of LBA Ranges",
2231 (uint8_t)lrt.b.lr_num + 1, NULL, NULL);
2232
2233 for (i = 0; i != n_lr; i++) {
2234 if (verbose == 0 && lr[i].lr_nlb == 0)
2235 continue;
2236
2237 nvme_print(4, "LBA Range", i, NULL);
2238 if (lr[i].lr_type < ARRAY_SIZE(lba_range_types))
2239 nvme_print_str(6, "Type", -1,
2240 lba_range_types[lr[i].lr_type], 0);
2241 else
2242 nvme_print_uint64(6, "Type",
2243 lr[i].lr_type, NULL, NULL);
2244 nvme_print(6, "Attributes", -1, NULL);
2245 nvme_print_bit(8, "Writable",
2246 nvme_vers_atleast(version, &nvme_vers_1v0),
2247 lr[i].lr_attr.lr_write, "yes", "no");
2248 nvme_print_bit(8, "Hidden",
2249 nvme_vers_atleast(version, &nvme_vers_1v0),
2250 lr[i].lr_attr.lr_hidden, "yes", "no");
2251 nvme_print_uint64(6, "Starting LBA",
2252 lr[i].lr_slba, NULL, NULL);
2253 nvme_print_uint64(6, "Number of Logical Blocks",
2254 lr[i].lr_nlb, NULL, NULL);
2255 nvme_print(6, "Unique Identifier", -1,
2256 "%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x"
2257 "%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
2258 lr[i].lr_guid[0], lr[i].lr_guid[1],
2259 lr[i].lr_guid[2], lr[i].lr_guid[3],
2260 lr[i].lr_guid[4], lr[i].lr_guid[5],
2261 lr[i].lr_guid[6], lr[i].lr_guid[7],
2262 lr[i].lr_guid[8], lr[i].lr_guid[9],
2263 lr[i].lr_guid[10], lr[i].lr_guid[11],
2264 lr[i].lr_guid[12], lr[i].lr_guid[13],
2265 lr[i].lr_guid[14], lr[i].lr_guid[15]);
2266 }
2267 }
2268
2269 void
nvme_print_feat_temperature(uint32_t cdw0,void * b,size_t s,const nvme_identify_ctrl_t * id,const nvme_version_t * version)2270 nvme_print_feat_temperature(uint32_t cdw0, void *b, size_t s,
2271 const nvme_identify_ctrl_t *id, const nvme_version_t *version)
2272 {
2273 _NOTE(ARGUNUSED(s));
2274 _NOTE(ARGUNUSED(id));
2275 nvme_temp_threshold_t tt;
2276 char *label = b;
2277
2278 tt.r = cdw0;
2279 nvme_print_temp(4, label, tt.b.tt_tmpth);
2280 }
2281
2282 void
nvme_print_feat_error(uint32_t cdw0,void * b,size_t s,const nvme_identify_ctrl_t * id,const nvme_version_t * version)2283 nvme_print_feat_error(uint32_t cdw0, void *b, size_t s,
2284 const nvme_identify_ctrl_t *id, const nvme_version_t *version)
2285 {
2286 _NOTE(ARGUNUSED(b));
2287 _NOTE(ARGUNUSED(s));
2288 _NOTE(ARGUNUSED(id));
2289 nvme_error_recovery_t er;
2290
2291 er.r = cdw0;
2292 if (er.b.er_tler > 0)
2293 nvme_print_uint64(4, "Time Limited Error Recovery",
2294 (uint32_t)er.b.er_tler * 100, NULL, "ms");
2295 else
2296 nvme_print_str(4, "Time Limited Error Recovery", -1,
2297 "no time limit", 0);
2298 }
2299
2300 void
nvme_print_feat_write_cache(uint32_t cdw0,void * b,size_t s,const nvme_identify_ctrl_t * id,const nvme_version_t * version)2301 nvme_print_feat_write_cache(uint32_t cdw0, void *b, size_t s,
2302 const nvme_identify_ctrl_t *id, const nvme_version_t *version)
2303 {
2304 _NOTE(ARGUNUSED(b));
2305 _NOTE(ARGUNUSED(s));
2306 _NOTE(ARGUNUSED(id));
2307 nvme_write_cache_t wc;
2308
2309 wc.r = cdw0;
2310 nvme_print_bit(4, "Volatile Write Cache",
2311 nvme_vers_atleast(version, &nvme_vers_1v0),
2312 wc.b.wc_wce, "enabled", "disabled");
2313 }
2314
2315 void
nvme_print_feat_nqueues(uint32_t cdw0,void * b,size_t s,const nvme_identify_ctrl_t * id,const nvme_version_t * version)2316 nvme_print_feat_nqueues(uint32_t cdw0, void *b, size_t s,
2317 const nvme_identify_ctrl_t *id, const nvme_version_t *version)
2318 {
2319 _NOTE(ARGUNUSED(b));
2320 _NOTE(ARGUNUSED(s));
2321 _NOTE(ARGUNUSED(id));
2322 nvme_nqueues_t nq;
2323
2324 nq.r = cdw0;
2325 nvme_print_uint64(4, "Number of Submission Queues",
2326 nq.b.nq_nsq + 1, NULL, NULL);
2327 nvme_print_uint64(4, "Number of Completion Queues",
2328 nq.b.nq_ncq + 1, NULL, NULL);
2329 }
2330
2331 void
nvme_print_feat_intr_coal(uint32_t cdw0,void * b,size_t s,const nvme_identify_ctrl_t * id,const nvme_version_t * version)2332 nvme_print_feat_intr_coal(uint32_t cdw0, void *b, size_t s,
2333 const nvme_identify_ctrl_t *id, const nvme_version_t *version)
2334 {
2335 _NOTE(ARGUNUSED(b));
2336 _NOTE(ARGUNUSED(s));
2337 _NOTE(ARGUNUSED(id));
2338 nvme_intr_coal_t ic;
2339
2340 ic.r = cdw0;
2341 nvme_print_uint64(4, "Aggregation Threshold",
2342 ic.b.ic_thr + 1, NULL, NULL);
2343 nvme_print_uint64(4, "Aggregation Time",
2344 (uint16_t)ic.b.ic_time * 100, NULL, "us");
2345 }
2346 void
nvme_print_feat_intr_vect(uint32_t cdw0,void * b,size_t s,const nvme_identify_ctrl_t * id,const nvme_version_t * version)2347 nvme_print_feat_intr_vect(uint32_t cdw0, void *b, size_t s,
2348 const nvme_identify_ctrl_t *id, const nvme_version_t *version)
2349 {
2350 _NOTE(ARGUNUSED(b));
2351 _NOTE(ARGUNUSED(s));
2352 _NOTE(ARGUNUSED(id));
2353 nvme_intr_vect_t iv;
2354 char *tmp;
2355
2356 iv.r = cdw0;
2357 if (asprintf(&tmp, "Vector %d Coalescing Disable", iv.b.iv_iv) < 0)
2358 err(-1, "nvme_print_feat_common()");
2359
2360 nvme_print_bit(4, tmp, iv.b.iv_cd,
2361 nvme_vers_atleast(version, &nvme_vers_1v0),
2362 "yes", "no");
2363 }
2364
2365 void
nvme_print_feat_write_atom(uint32_t cdw0,void * b,size_t s,const nvme_identify_ctrl_t * id,const nvme_version_t * version)2366 nvme_print_feat_write_atom(uint32_t cdw0, void *b, size_t s,
2367 const nvme_identify_ctrl_t *id, const nvme_version_t *version)
2368 {
2369 _NOTE(ARGUNUSED(b));
2370 _NOTE(ARGUNUSED(s));
2371 _NOTE(ARGUNUSED(id));
2372 nvme_write_atomicity_t wa;
2373
2374 wa.r = cdw0;
2375 nvme_print_bit(4, "Disable Normal", wa.b.wa_dn,
2376 nvme_vers_atleast(version, &nvme_vers_1v0),
2377 "yes", "no");
2378 }
2379
2380 void
nvme_print_feat_async_event(uint32_t cdw0,void * b,size_t s,const nvme_identify_ctrl_t * idctl,const nvme_version_t * version)2381 nvme_print_feat_async_event(uint32_t cdw0, void *b, size_t s,
2382 const nvme_identify_ctrl_t *idctl, const nvme_version_t *version)
2383 {
2384 _NOTE(ARGUNUSED(b));
2385 _NOTE(ARGUNUSED(s));
2386 nvme_async_event_conf_t aec;
2387
2388 aec.r = cdw0;
2389 nvme_print_bit(4, "Available Space below threshold",
2390 nvme_vers_atleast(version, &nvme_vers_1v0),
2391 aec.b.aec_avail, "enabled", "disabled");
2392 nvme_print_bit(4, "Temperature above threshold",
2393 nvme_vers_atleast(version, &nvme_vers_1v0),
2394 aec.b.aec_temp, "enabled", "disabled");
2395 nvme_print_bit(4, "Device Reliability compromised",
2396 nvme_vers_atleast(version, &nvme_vers_1v0),
2397 aec.b.aec_reliab, "enabled", "disabled");
2398 nvme_print_bit(4, "Media read-only",
2399 nvme_vers_atleast(version, &nvme_vers_1v0),
2400 aec.b.aec_readonly, "enabled", "disabled");
2401 if (idctl->id_vwc.vwc_present != 0) {
2402 nvme_print_bit(4, "Volatile Memory Backup failed",
2403 nvme_vers_atleast(version, &nvme_vers_1v0),
2404 aec.b.aec_volatile, "enabled", "disabled");
2405 }
2406
2407 /* NVMe 1.2 */
2408 nvme_print_bit(4, "Namespace attribute notices",
2409 nvme_vers_atleast(version, &nvme_vers_1v2),
2410 aec.b.aec_nsan, "enabled", "disabled");
2411 nvme_print_bit(4, "Firmware activation notices",
2412 nvme_vers_atleast(version, &nvme_vers_1v2),
2413 aec.b.aec_fwact, "enabled", "disabled");
2414
2415 /* NVMe 1.3 */
2416 nvme_print_bit(4, "Telemetry log notices",
2417 nvme_vers_atleast(version, &nvme_vers_1v3),
2418 aec.b.aec_telln, "enabled", "disabled");
2419
2420 /* NVMe 1.4 */
2421 nvme_print_bit(4, "ANA change notices",
2422 nvme_vers_atleast(version, &nvme_vers_1v4),
2423 aec.b.aec_ansacn, "enabled", "disabled");
2424 nvme_print_bit(4,
2425 "Predictable latency event aggr. LCNs",
2426 nvme_vers_atleast(version, &nvme_vers_1v4),
2427 aec.b.aec_plat, "enabled", "disabled");
2428 nvme_print_bit(4, "LBA status information notices",
2429 nvme_vers_atleast(version, &nvme_vers_1v4),
2430 aec.b.aec_lbasi, "enabled", "disabled");
2431 nvme_print_bit(4, "Endurance group event aggregate LCNs",
2432 nvme_vers_atleast(version, &nvme_vers_1v4),
2433 aec.b.aec_egeal, "enabled", "disabled");
2434 }
2435
2436 void
nvme_print_feat_auto_pst(uint32_t cdw0,void * buf,size_t bufsize,const nvme_identify_ctrl_t * id,const nvme_version_t * version)2437 nvme_print_feat_auto_pst(uint32_t cdw0, void *buf, size_t bufsize,
2438 const nvme_identify_ctrl_t *id, const nvme_version_t *version)
2439 {
2440 _NOTE(ARGUNUSED(id));
2441
2442 nvme_auto_power_state_trans_t apst;
2443 nvme_auto_power_state_t *aps;
2444 int i;
2445 int cnt = bufsize / sizeof (nvme_auto_power_state_t);
2446
2447 if (buf == NULL)
2448 return;
2449
2450 apst.r = cdw0;
2451 aps = buf;
2452
2453 nvme_print_bit(4, "Autonomous Power State Transition",
2454 nvme_vers_atleast(version, &nvme_vers_1v0),
2455 apst.b.apst_apste, "enabled", "disabled");
2456 for (i = 0; i != cnt; i++) {
2457 if (aps[i].apst_itps == 0 && aps[i].apst_itpt == 0)
2458 break;
2459
2460 nvme_print(4, "Power State", i, NULL);
2461 nvme_print_uint64(6, "Idle Transition Power State",
2462 (uint16_t)aps[i].apst_itps, NULL, NULL);
2463 nvme_print_uint64(6, "Idle Time Prior to Transition",
2464 aps[i].apst_itpt, NULL, "ms");
2465 }
2466 }
2467
2468 void
nvme_print_feat_progress(uint32_t cdw0,void * b,size_t s,const nvme_identify_ctrl_t * id,const nvme_version_t * version)2469 nvme_print_feat_progress(uint32_t cdw0, void *b, size_t s,
2470 const nvme_identify_ctrl_t *id, const nvme_version_t *version)
2471 {
2472 _NOTE(ARGUNUSED(b));
2473 _NOTE(ARGUNUSED(s));
2474 _NOTE(ARGUNUSED(id));
2475 nvme_software_progress_marker_t spm;
2476
2477 spm.r = cdw0;
2478 nvme_print_uint64(4, "Pre-Boot Software Load Count",
2479 spm.b.spm_pbslc, NULL, NULL);
2480 }
2481
2482 /*
2483 * This is designed to print out a large buffer as decipherable hexadecimal.
2484 * This is intended for log pages or command output where there is unknown
2485 * printing. For an inline hex buffer, see nvme_print_hexbuf(). Our expectation
2486 * here is that we have approximately 6 digits worth of address on the left then
2487 * we'll spell out each byte, followed by the translated form on the right. Each
2488 * of these groups is separated by pipes.
2489 */
2490 void
nvmeadm_dump_hex(const uint8_t * buf,size_t len)2491 nvmeadm_dump_hex(const uint8_t *buf, size_t len)
2492 {
2493 size_t off = 0;
2494
2495 if (len == 0) {
2496 return;
2497 }
2498
2499 /*
2500 * First we print the header.
2501 */
2502 (void) printf(" ");
2503 (void) printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f");
2504 (void) printf(" 0123456789abcdef\n");
2505
2506 while (len > 0) {
2507 size_t nents = MIN(len, 16);
2508 len -= nents;
2509
2510 (void) printf("0x%06x |", off);
2511 for (size_t i = 0; i < nents; i++) {
2512 (void) printf(" %02x", buf[i]);
2513 }
2514
2515 for (size_t i = nents; i < 16; i++) {
2516 (void) printf(" ");
2517 }
2518
2519 (void) printf(" | ");
2520
2521 for (size_t i = 0; i < nents; i++) {
2522 if (isprint(buf[i])) {
2523 (void) printf("%c", buf[i]);
2524 } else {
2525 (void) putc('.', stdout);
2526 }
2527 }
2528
2529 (void) putc('\n', stdout);
2530 buf += nents;
2531 off += nents;
2532 }
2533 }
2534