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