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