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