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