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