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