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