Bug Summary

File:.build-ci/../nvme-print-stdout.c
Warning:line 1190, column 27
Although the value stored to 'ana_state' is used in the enclosing expression, the value is never actually read from 'ana_state'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name nvme-print-stdout.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/__w/nvme-cli/nvme-cli/.build-ci -fcoverage-compilation-dir=/__w/nvme-cli/nvme-cli/.build-ci -resource-dir /usr/lib/llvm-19/lib/clang/19 -include /__w/nvme-cli/nvme-cli/.build-ci/nvme-config.h -I nvme.p -I . -I .. -I ccan -I ../ccan -I libnvme/src -I ../libnvme/src -I /usr/include/json-c -D _FILE_OFFSET_BITS=64 -D _GNU_SOURCE -U NDEBUG -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -std=gnu99 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-opt-analyze-headers -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /__w/nvme-cli/nvme-cli/.build-ci/scan-results/2026-06-24-175442-590-1 -x c ../nvme-print-stdout.c
1// SPDX-License-Identifier: GPL-2.0-or-later
2#include <assert.h>
3#include <errno(*__errno_location ()).h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <time.h>
8#include <sys/stat.h>
9#include <sys/types.h>
10
11#ifdef CONFIG_FABRICS
12#include <sys/socket.h>
13#include <arpa/inet.h>
14#endif
15
16#include <ccan/strset/strset.h>
17#include <ccan/htable/htable_type.h>
18#include <ccan/htable/htable.h>
19#include <ccan/hash/hash.h>
20
21#include <libnvme.h>
22
23#include "nvme.h"
24#include "nvme-print.h"
25#include "nvme-models.h"
26#include "util/suffix.h"
27#include "util/types.h"
28#include "util/table.h"
29#include "logging.h"
30#include "common.h"
31
32enum simple_list_col {
33 SIMPLE_LIST_COL_NODE,
34 SIMPLE_LIST_COL_GENERIC,
35 SIMPLE_LIST_COL_SN,
36 SIMPLE_LIST_COL_MODEL,
37 SIMPLE_LIST_COL_NS,
38 SIMPLE_LIST_COL_USAGE,
39 SIMPLE_LIST_COL_FORMAT,
40 SIMPLE_LIST_COL_FW_REV,
41};
42
43static const uint8_t zero_uuid[16] = { 0 };
44static const uint8_t invalid_uuid[16] = {[0 ... 15] = 0xff };
45static const char dash[100] = {[0 ... 99] = '-'};
46
47static struct print_ops stdout_print_ops;
48
49static const char *subsys_key(const struct libnvme_subsystem *s)
50{
51 return libnvme_subsystem_get_name((libnvme_subsystem_t)s);
52}
53
54static const char *ctrl_key(const struct libnvme_ctrl *c)
55{
56 return libnvme_ctrl_get_name((libnvme_ctrl_t)c);
57}
58
59static const char *ns_key(const struct libnvme_ns *n)
60{
61 return libnvme_ns_get_name((libnvme_ns_t)n);
62}
63
64static bool_Bool subsys_cmp(const struct libnvme_subsystem *s, const char *name)
65{
66 return !strcmp(libnvme_subsystem_get_name((libnvme_subsystem_t)s), name);
67}
68
69static bool_Bool ctrl_cmp(const struct libnvme_ctrl *c, const char *name)
70{
71 return !strcmp(libnvme_ctrl_get_name((libnvme_ctrl_t)c), name);
72}
73
74static bool_Bool ns_cmp(const struct libnvme_ns *n, const char *name)
75{
76 return !strcmp(libnvme_ns_get_name((libnvme_ns_t)n), name);
77}
78
79HTABLE_DEFINE_TYPE(struct libnvme_subsystem, subsys_key, hash_string,struct htable_subsys { struct htable raw; }; struct htable_subsys_iter
{ struct htable_iter i; }; static inline size_t htable_subsys_hash
(const void *elem, void *priv) { (void)priv; return hash_string
(subsys_key((const struct libnvme_subsystem *)elem)); } static
inline void htable_subsys_init(struct htable_subsys *ht) { htable_init
(&ht->raw, htable_subsys_hash, ((void*)0)); } static inline
_Bool htable_subsys_init_sized(struct htable_subsys *ht, size_t
s) { return htable_init_sized(&ht->raw, htable_subsys_hash
, ((void*)0), s); } static inline size_t htable_subsys_count(
const struct htable_subsys *ht) { return htable_count(&ht
->raw); } static inline void htable_subsys_clear(struct htable_subsys
*ht) { htable_clear(&ht->raw); } static inline _Bool htable_subsys_copy
(struct htable_subsys *dst, const struct htable_subsys *src) {
return htable_copy_(&dst->raw, ((void)"../nvme-print-stdout.c"
":" "80", &src->raw)); } static inline _Bool htable_subsys_add
(struct htable_subsys *ht, const struct libnvme_subsystem *elem
) { return htable_add_(((void)"../nvme-print-stdout.c" ":" "80"
, &ht->raw), hash_string(subsys_key(elem)), elem); } static
inline _Bool htable_subsys_del(struct htable_subsys *ht, const
struct libnvme_subsystem *elem) { return htable_del_(((void)
"../nvme-print-stdout.c" ":" "80", &ht->raw), hash_string
(subsys_key(elem)), elem); } static inline struct libnvme_subsystem
*htable_subsys_get(const struct htable_subsys *ht, const typeof
(subsys_key((const struct libnvme_subsystem *)((void*)0))) k)
{ struct htable_iter i; size_t h = hash_string(k); void *c; for
(c = htable_firstval_(((void)"../nvme-print-stdout.c" ":" "80"
, &ht->raw), &i, h); c; c = htable_nextval_(((void
)"../nvme-print-stdout.c" ":" "80", &ht->raw), &i,
h)) { if (subsys_cmp(c, k)) return c; } return ((void*)0); }
static inline struct libnvme_subsystem *htable_subsys_getmatch_
(const struct htable_subsys *ht, const typeof(subsys_key((const
struct libnvme_subsystem *)((void*)0))) k, size_t h, struct libnvme_subsystem
*v, struct htable_subsys_iter *iter) { while (v) { if (subsys_cmp
(v, k)) break; v = htable_nextval_(((void)"../nvme-print-stdout.c"
":" "80", &ht->raw), &iter->i, h); } return v;
} static inline struct libnvme_subsystem *htable_subsys_getfirst
(const struct htable_subsys *ht, const typeof(subsys_key((const
struct libnvme_subsystem *)((void*)0))) k, struct htable_subsys_iter
*iter) { size_t h = hash_string(k); struct libnvme_subsystem
*v = htable_firstval_(((void)"../nvme-print-stdout.c" ":" "80"
, &ht->raw), &iter->i, h); return htable_subsys_getmatch_
(ht, k, h, v, iter); } static inline struct libnvme_subsystem
*htable_subsys_getnext(const struct htable_subsys *ht, const
typeof(subsys_key((const struct libnvme_subsystem *)((void*)
0))) k, struct htable_subsys_iter *iter) { size_t h = hash_string
(k); struct libnvme_subsystem *v = htable_nextval_(((void)"../nvme-print-stdout.c"
":" "80", &ht->raw), &iter->i, h); return htable_subsys_getmatch_
(ht, k, h, v, iter); } static inline _Bool htable_subsys_delkey
(struct htable_subsys *ht, const typeof(subsys_key((const struct
libnvme_subsystem *)((void*)0))) k) { struct libnvme_subsystem
*elem = htable_subsys_get(ht, k); if (elem) return htable_subsys_del
(ht, elem); return 0; } static inline void htable_subsys_delval
(struct htable_subsys *ht, struct htable_subsys_iter *iter) {
htable_delval_(((void)"../nvme-print-stdout.c" ":" "80", &
ht->raw), &iter->i); } static inline struct libnvme_subsystem
*htable_subsys_pick(const struct htable_subsys *ht, size_t seed
, struct htable_subsys_iter *iter) { return htable_pick_(((void
)"../nvme-print-stdout.c" ":" "80", &ht->raw), seed, iter
? &iter->i : ((void*)0)); } static inline struct libnvme_subsystem
*htable_subsys_first(const struct htable_subsys *ht, struct htable_subsys_iter
*iter) { return htable_first_(((void)"../nvme-print-stdout.c"
":" "80", &ht->raw), &iter->i); } static inline
struct libnvme_subsystem *htable_subsys_next(const struct htable_subsys
*ht, struct htable_subsys_iter *iter) { return htable_next_(
((void)"../nvme-print-stdout.c" ":" "80", &ht->raw), &
iter->i); } static inline struct libnvme_subsystem *htable_subsys_prev
(const struct htable_subsys *ht, struct htable_subsys_iter *iter
) { return htable_prev_(((void)"../nvme-print-stdout.c" ":" "80"
, &ht->raw), &iter->i); }
80 subsys_cmp, htable_subsys)struct htable_subsys { struct htable raw; }; struct htable_subsys_iter
{ struct htable_iter i; }; static inline size_t htable_subsys_hash
(const void *elem, void *priv) { (void)priv; return hash_string
(subsys_key((const struct libnvme_subsystem *)elem)); } static
inline void htable_subsys_init(struct htable_subsys *ht) { htable_init
(&ht->raw, htable_subsys_hash, ((void*)0)); } static inline
_Bool htable_subsys_init_sized(struct htable_subsys *ht, size_t
s) { return htable_init_sized(&ht->raw, htable_subsys_hash
, ((void*)0), s); } static inline size_t htable_subsys_count(
const struct htable_subsys *ht) { return htable_count(&ht
->raw); } static inline void htable_subsys_clear(struct htable_subsys
*ht) { htable_clear(&ht->raw); } static inline _Bool htable_subsys_copy
(struct htable_subsys *dst, const struct htable_subsys *src) {
return htable_copy_(&dst->raw, ((void)"../nvme-print-stdout.c"
":" "80", &src->raw)); } static inline _Bool htable_subsys_add
(struct htable_subsys *ht, const struct libnvme_subsystem *elem
) { return htable_add_(((void)"../nvme-print-stdout.c" ":" "80"
, &ht->raw), hash_string(subsys_key(elem)), elem); } static
inline _Bool htable_subsys_del(struct htable_subsys *ht, const
struct libnvme_subsystem *elem) { return htable_del_(((void)
"../nvme-print-stdout.c" ":" "80", &ht->raw), hash_string
(subsys_key(elem)), elem); } static inline struct libnvme_subsystem
*htable_subsys_get(const struct htable_subsys *ht, const typeof
(subsys_key((const struct libnvme_subsystem *)((void*)0))) k)
{ struct htable_iter i; size_t h = hash_string(k); void *c; for
(c = htable_firstval_(((void)"../nvme-print-stdout.c" ":" "80"
, &ht->raw), &i, h); c; c = htable_nextval_(((void
)"../nvme-print-stdout.c" ":" "80", &ht->raw), &i,
h)) { if (subsys_cmp(c, k)) return c; } return ((void*)0); }
static inline struct libnvme_subsystem *htable_subsys_getmatch_
(const struct htable_subsys *ht, const typeof(subsys_key((const
struct libnvme_subsystem *)((void*)0))) k, size_t h, struct libnvme_subsystem
*v, struct htable_subsys_iter *iter) { while (v) { if (subsys_cmp
(v, k)) break; v = htable_nextval_(((void)"../nvme-print-stdout.c"
":" "80", &ht->raw), &iter->i, h); } return v;
} static inline struct libnvme_subsystem *htable_subsys_getfirst
(const struct htable_subsys *ht, const typeof(subsys_key((const
struct libnvme_subsystem *)((void*)0))) k, struct htable_subsys_iter
*iter) { size_t h = hash_string(k); struct libnvme_subsystem
*v = htable_firstval_(((void)"../nvme-print-stdout.c" ":" "80"
, &ht->raw), &iter->i, h); return htable_subsys_getmatch_
(ht, k, h, v, iter); } static inline struct libnvme_subsystem
*htable_subsys_getnext(const struct htable_subsys *ht, const
typeof(subsys_key((const struct libnvme_subsystem *)((void*)
0))) k, struct htable_subsys_iter *iter) { size_t h = hash_string
(k); struct libnvme_subsystem *v = htable_nextval_(((void)"../nvme-print-stdout.c"
":" "80", &ht->raw), &iter->i, h); return htable_subsys_getmatch_
(ht, k, h, v, iter); } static inline _Bool htable_subsys_delkey
(struct htable_subsys *ht, const typeof(subsys_key((const struct
libnvme_subsystem *)((void*)0))) k) { struct libnvme_subsystem
*elem = htable_subsys_get(ht, k); if (elem) return htable_subsys_del
(ht, elem); return 0; } static inline void htable_subsys_delval
(struct htable_subsys *ht, struct htable_subsys_iter *iter) {
htable_delval_(((void)"../nvme-print-stdout.c" ":" "80", &
ht->raw), &iter->i); } static inline struct libnvme_subsystem
*htable_subsys_pick(const struct htable_subsys *ht, size_t seed
, struct htable_subsys_iter *iter) { return htable_pick_(((void
)"../nvme-print-stdout.c" ":" "80", &ht->raw), seed, iter
? &iter->i : ((void*)0)); } static inline struct libnvme_subsystem
*htable_subsys_first(const struct htable_subsys *ht, struct htable_subsys_iter
*iter) { return htable_first_(((void)"../nvme-print-stdout.c"
":" "80", &ht->raw), &iter->i); } static inline
struct libnvme_subsystem *htable_subsys_next(const struct htable_subsys
*ht, struct htable_subsys_iter *iter) { return htable_next_(
((void)"../nvme-print-stdout.c" ":" "80", &ht->raw), &
iter->i); } static inline struct libnvme_subsystem *htable_subsys_prev
(const struct htable_subsys *ht, struct htable_subsys_iter *iter
) { return htable_prev_(((void)"../nvme-print-stdout.c" ":" "80"
, &ht->raw), &iter->i); }
;
81HTABLE_DEFINE_TYPE(struct libnvme_ctrl, ctrl_key, hash_string,struct htable_ctrl { struct htable raw; }; struct htable_ctrl_iter
{ struct htable_iter i; }; static inline size_t htable_ctrl_hash
(const void *elem, void *priv) { (void)priv; return hash_string
(ctrl_key((const struct libnvme_ctrl *)elem)); } static inline
void htable_ctrl_init(struct htable_ctrl *ht) { htable_init(
&ht->raw, htable_ctrl_hash, ((void*)0)); } static inline
_Bool htable_ctrl_init_sized(struct htable_ctrl *ht, size_t s
) { return htable_init_sized(&ht->raw, htable_ctrl_hash
, ((void*)0), s); } static inline size_t htable_ctrl_count(const
struct htable_ctrl *ht) { return htable_count(&ht->raw
); } static inline void htable_ctrl_clear(struct htable_ctrl *
ht) { htable_clear(&ht->raw); } static inline _Bool htable_ctrl_copy
(struct htable_ctrl *dst, const struct htable_ctrl *src) { return
htable_copy_(&dst->raw, ((void)"../nvme-print-stdout.c"
":" "82", &src->raw)); } static inline _Bool htable_ctrl_add
(struct htable_ctrl *ht, const struct libnvme_ctrl *elem) { return
htable_add_(((void)"../nvme-print-stdout.c" ":" "82", &ht
->raw), hash_string(ctrl_key(elem)), elem); } static inline
_Bool htable_ctrl_del(struct htable_ctrl *ht, const struct libnvme_ctrl
*elem) { return htable_del_(((void)"../nvme-print-stdout.c" ":"
"82", &ht->raw), hash_string(ctrl_key(elem)), elem); }
static inline struct libnvme_ctrl *htable_ctrl_get(const struct
htable_ctrl *ht, const typeof(ctrl_key((const struct libnvme_ctrl
*)((void*)0))) k) { struct htable_iter i; size_t h = hash_string
(k); void *c; for (c = htable_firstval_(((void)"../nvme-print-stdout.c"
":" "82", &ht->raw), &i, h); c; c = htable_nextval_
(((void)"../nvme-print-stdout.c" ":" "82", &ht->raw), &
i, h)) { if (ctrl_cmp(c, k)) return c; } return ((void*)0); }
static inline struct libnvme_ctrl *htable_ctrl_getmatch_(const
struct htable_ctrl *ht, const typeof(ctrl_key((const struct libnvme_ctrl
*)((void*)0))) k, size_t h, struct libnvme_ctrl *v, struct htable_ctrl_iter
*iter) { while (v) { if (ctrl_cmp(v, k)) break; v = htable_nextval_
(((void)"../nvme-print-stdout.c" ":" "82", &ht->raw), &
iter->i, h); } return v; } static inline struct libnvme_ctrl
*htable_ctrl_getfirst(const struct htable_ctrl *ht, const typeof
(ctrl_key((const struct libnvme_ctrl *)((void*)0))) k, struct
htable_ctrl_iter *iter) { size_t h = hash_string(k); struct libnvme_ctrl
*v = htable_firstval_(((void)"../nvme-print-stdout.c" ":" "82"
, &ht->raw), &iter->i, h); return htable_ctrl_getmatch_
(ht, k, h, v, iter); } static inline struct libnvme_ctrl *htable_ctrl_getnext
(const struct htable_ctrl *ht, const typeof(ctrl_key((const struct
libnvme_ctrl *)((void*)0))) k, struct htable_ctrl_iter *iter
) { size_t h = hash_string(k); struct libnvme_ctrl *v = htable_nextval_
(((void)"../nvme-print-stdout.c" ":" "82", &ht->raw), &
iter->i, h); return htable_ctrl_getmatch_(ht, k, h, v, iter
); } static inline _Bool htable_ctrl_delkey(struct htable_ctrl
*ht, const typeof(ctrl_key((const struct libnvme_ctrl *)((void
*)0))) k) { struct libnvme_ctrl *elem = htable_ctrl_get(ht, k
); if (elem) return htable_ctrl_del(ht, elem); return 0; } static
inline void htable_ctrl_delval(struct htable_ctrl *ht, struct
htable_ctrl_iter *iter) { htable_delval_(((void)"../nvme-print-stdout.c"
":" "82", &ht->raw), &iter->i); } static inline
struct libnvme_ctrl *htable_ctrl_pick(const struct htable_ctrl
*ht, size_t seed, struct htable_ctrl_iter *iter) { return htable_pick_
(((void)"../nvme-print-stdout.c" ":" "82", &ht->raw), seed
, iter ? &iter->i : ((void*)0)); } static inline struct
libnvme_ctrl *htable_ctrl_first(const struct htable_ctrl *ht
, struct htable_ctrl_iter *iter) { return htable_first_(((void
)"../nvme-print-stdout.c" ":" "82", &ht->raw), &iter
->i); } static inline struct libnvme_ctrl *htable_ctrl_next
(const struct htable_ctrl *ht, struct htable_ctrl_iter *iter)
{ return htable_next_(((void)"../nvme-print-stdout.c" ":" "82"
, &ht->raw), &iter->i); } static inline struct libnvme_ctrl
*htable_ctrl_prev(const struct htable_ctrl *ht, struct htable_ctrl_iter
*iter) { return htable_prev_(((void)"../nvme-print-stdout.c"
":" "82", &ht->raw), &iter->i); }
82 ctrl_cmp, htable_ctrl)struct htable_ctrl { struct htable raw; }; struct htable_ctrl_iter
{ struct htable_iter i; }; static inline size_t htable_ctrl_hash
(const void *elem, void *priv) { (void)priv; return hash_string
(ctrl_key((const struct libnvme_ctrl *)elem)); } static inline
void htable_ctrl_init(struct htable_ctrl *ht) { htable_init(
&ht->raw, htable_ctrl_hash, ((void*)0)); } static inline
_Bool htable_ctrl_init_sized(struct htable_ctrl *ht, size_t s
) { return htable_init_sized(&ht->raw, htable_ctrl_hash
, ((void*)0), s); } static inline size_t htable_ctrl_count(const
struct htable_ctrl *ht) { return htable_count(&ht->raw
); } static inline void htable_ctrl_clear(struct htable_ctrl *
ht) { htable_clear(&ht->raw); } static inline _Bool htable_ctrl_copy
(struct htable_ctrl *dst, const struct htable_ctrl *src) { return
htable_copy_(&dst->raw, ((void)"../nvme-print-stdout.c"
":" "82", &src->raw)); } static inline _Bool htable_ctrl_add
(struct htable_ctrl *ht, const struct libnvme_ctrl *elem) { return
htable_add_(((void)"../nvme-print-stdout.c" ":" "82", &ht
->raw), hash_string(ctrl_key(elem)), elem); } static inline
_Bool htable_ctrl_del(struct htable_ctrl *ht, const struct libnvme_ctrl
*elem) { return htable_del_(((void)"../nvme-print-stdout.c" ":"
"82", &ht->raw), hash_string(ctrl_key(elem)), elem); }
static inline struct libnvme_ctrl *htable_ctrl_get(const struct
htable_ctrl *ht, const typeof(ctrl_key((const struct libnvme_ctrl
*)((void*)0))) k) { struct htable_iter i; size_t h = hash_string
(k); void *c; for (c = htable_firstval_(((void)"../nvme-print-stdout.c"
":" "82", &ht->raw), &i, h); c; c = htable_nextval_
(((void)"../nvme-print-stdout.c" ":" "82", &ht->raw), &
i, h)) { if (ctrl_cmp(c, k)) return c; } return ((void*)0); }
static inline struct libnvme_ctrl *htable_ctrl_getmatch_(const
struct htable_ctrl *ht, const typeof(ctrl_key((const struct libnvme_ctrl
*)((void*)0))) k, size_t h, struct libnvme_ctrl *v, struct htable_ctrl_iter
*iter) { while (v) { if (ctrl_cmp(v, k)) break; v = htable_nextval_
(((void)"../nvme-print-stdout.c" ":" "82", &ht->raw), &
iter->i, h); } return v; } static inline struct libnvme_ctrl
*htable_ctrl_getfirst(const struct htable_ctrl *ht, const typeof
(ctrl_key((const struct libnvme_ctrl *)((void*)0))) k, struct
htable_ctrl_iter *iter) { size_t h = hash_string(k); struct libnvme_ctrl
*v = htable_firstval_(((void)"../nvme-print-stdout.c" ":" "82"
, &ht->raw), &iter->i, h); return htable_ctrl_getmatch_
(ht, k, h, v, iter); } static inline struct libnvme_ctrl *htable_ctrl_getnext
(const struct htable_ctrl *ht, const typeof(ctrl_key((const struct
libnvme_ctrl *)((void*)0))) k, struct htable_ctrl_iter *iter
) { size_t h = hash_string(k); struct libnvme_ctrl *v = htable_nextval_
(((void)"../nvme-print-stdout.c" ":" "82", &ht->raw), &
iter->i, h); return htable_ctrl_getmatch_(ht, k, h, v, iter
); } static inline _Bool htable_ctrl_delkey(struct htable_ctrl
*ht, const typeof(ctrl_key((const struct libnvme_ctrl *)((void
*)0))) k) { struct libnvme_ctrl *elem = htable_ctrl_get(ht, k
); if (elem) return htable_ctrl_del(ht, elem); return 0; } static
inline void htable_ctrl_delval(struct htable_ctrl *ht, struct
htable_ctrl_iter *iter) { htable_delval_(((void)"../nvme-print-stdout.c"
":" "82", &ht->raw), &iter->i); } static inline
struct libnvme_ctrl *htable_ctrl_pick(const struct htable_ctrl
*ht, size_t seed, struct htable_ctrl_iter *iter) { return htable_pick_
(((void)"../nvme-print-stdout.c" ":" "82", &ht->raw), seed
, iter ? &iter->i : ((void*)0)); } static inline struct
libnvme_ctrl *htable_ctrl_first(const struct htable_ctrl *ht
, struct htable_ctrl_iter *iter) { return htable_first_(((void
)"../nvme-print-stdout.c" ":" "82", &ht->raw), &iter
->i); } static inline struct libnvme_ctrl *htable_ctrl_next
(const struct htable_ctrl *ht, struct htable_ctrl_iter *iter)
{ return htable_next_(((void)"../nvme-print-stdout.c" ":" "82"
, &ht->raw), &iter->i); } static inline struct libnvme_ctrl
*htable_ctrl_prev(const struct htable_ctrl *ht, struct htable_ctrl_iter
*iter) { return htable_prev_(((void)"../nvme-print-stdout.c"
":" "82", &ht->raw), &iter->i); }
;
83HTABLE_DEFINE_TYPE(struct libnvme_ns, ns_key, hash_string,struct htable_ns { struct htable raw; }; struct htable_ns_iter
{ struct htable_iter i; }; static inline size_t htable_ns_hash
(const void *elem, void *priv) { (void)priv; return hash_string
(ns_key((const struct libnvme_ns *)elem)); } static inline void
htable_ns_init(struct htable_ns *ht) { htable_init(&ht->
raw, htable_ns_hash, ((void*)0)); } static inline _Bool htable_ns_init_sized
(struct htable_ns *ht, size_t s) { return htable_init_sized(&
ht->raw, htable_ns_hash, ((void*)0), s); } static inline size_t
htable_ns_count(const struct htable_ns *ht) { return htable_count
(&ht->raw); } static inline void htable_ns_clear(struct
htable_ns *ht) { htable_clear(&ht->raw); } static inline
_Bool htable_ns_copy(struct htable_ns *dst, const struct htable_ns
*src) { return htable_copy_(&dst->raw, ((void)"../nvme-print-stdout.c"
":" "84", &src->raw)); } static inline _Bool htable_ns_add
(struct htable_ns *ht, const struct libnvme_ns *elem) { return
htable_add_(((void)"../nvme-print-stdout.c" ":" "84", &ht
->raw), hash_string(ns_key(elem)), elem); } static inline _Bool
htable_ns_del(struct htable_ns *ht, const struct libnvme_ns *
elem) { return htable_del_(((void)"../nvme-print-stdout.c" ":"
"84", &ht->raw), hash_string(ns_key(elem)), elem); } static
inline struct libnvme_ns *htable_ns_get(const struct htable_ns
*ht, const typeof(ns_key((const struct libnvme_ns *)((void*)
0))) k) { struct htable_iter i; size_t h = hash_string(k); void
*c; for (c = htable_firstval_(((void)"../nvme-print-stdout.c"
":" "84", &ht->raw), &i, h); c; c = htable_nextval_
(((void)"../nvme-print-stdout.c" ":" "84", &ht->raw), &
i, h)) { if (ns_cmp(c, k)) return c; } return ((void*)0); } static
inline struct libnvme_ns *htable_ns_getmatch_(const struct htable_ns
*ht, const typeof(ns_key((const struct libnvme_ns *)((void*)
0))) k, size_t h, struct libnvme_ns *v, struct htable_ns_iter
*iter) { while (v) { if (ns_cmp(v, k)) break; v = htable_nextval_
(((void)"../nvme-print-stdout.c" ":" "84", &ht->raw), &
iter->i, h); } return v; } static inline struct libnvme_ns
*htable_ns_getfirst(const struct htable_ns *ht, const typeof
(ns_key((const struct libnvme_ns *)((void*)0))) k, struct htable_ns_iter
*iter) { size_t h = hash_string(k); struct libnvme_ns *v = htable_firstval_
(((void)"../nvme-print-stdout.c" ":" "84", &ht->raw), &
iter->i, h); return htable_ns_getmatch_(ht, k, h, v, iter)
; } static inline struct libnvme_ns *htable_ns_getnext(const struct
htable_ns *ht, const typeof(ns_key((const struct libnvme_ns *
)((void*)0))) k, struct htable_ns_iter *iter) { size_t h = hash_string
(k); struct libnvme_ns *v = htable_nextval_(((void)"../nvme-print-stdout.c"
":" "84", &ht->raw), &iter->i, h); return htable_ns_getmatch_
(ht, k, h, v, iter); } static inline _Bool htable_ns_delkey(struct
htable_ns *ht, const typeof(ns_key((const struct libnvme_ns *
)((void*)0))) k) { struct libnvme_ns *elem = htable_ns_get(ht
, k); if (elem) return htable_ns_del(ht, elem); return 0; } static
inline void htable_ns_delval(struct htable_ns *ht, struct htable_ns_iter
*iter) { htable_delval_(((void)"../nvme-print-stdout.c" ":" "84"
, &ht->raw), &iter->i); } static inline struct libnvme_ns
*htable_ns_pick(const struct htable_ns *ht, size_t seed, struct
htable_ns_iter *iter) { return htable_pick_(((void)"../nvme-print-stdout.c"
":" "84", &ht->raw), seed, iter ? &iter->i : (
(void*)0)); } static inline struct libnvme_ns *htable_ns_first
(const struct htable_ns *ht, struct htable_ns_iter *iter) { return
htable_first_(((void)"../nvme-print-stdout.c" ":" "84", &
ht->raw), &iter->i); } static inline struct libnvme_ns
*htable_ns_next(const struct htable_ns *ht, struct htable_ns_iter
*iter) { return htable_next_(((void)"../nvme-print-stdout.c"
":" "84", &ht->raw), &iter->i); } static inline
struct libnvme_ns *htable_ns_prev(const struct htable_ns *ht
, struct htable_ns_iter *iter) { return htable_prev_(((void)"../nvme-print-stdout.c"
":" "84", &ht->raw), &iter->i); }
84 ns_cmp, htable_ns)struct htable_ns { struct htable raw; }; struct htable_ns_iter
{ struct htable_iter i; }; static inline size_t htable_ns_hash
(const void *elem, void *priv) { (void)priv; return hash_string
(ns_key((const struct libnvme_ns *)elem)); } static inline void
htable_ns_init(struct htable_ns *ht) { htable_init(&ht->
raw, htable_ns_hash, ((void*)0)); } static inline _Bool htable_ns_init_sized
(struct htable_ns *ht, size_t s) { return htable_init_sized(&
ht->raw, htable_ns_hash, ((void*)0), s); } static inline size_t
htable_ns_count(const struct htable_ns *ht) { return htable_count
(&ht->raw); } static inline void htable_ns_clear(struct
htable_ns *ht) { htable_clear(&ht->raw); } static inline
_Bool htable_ns_copy(struct htable_ns *dst, const struct htable_ns
*src) { return htable_copy_(&dst->raw, ((void)"../nvme-print-stdout.c"
":" "84", &src->raw)); } static inline _Bool htable_ns_add
(struct htable_ns *ht, const struct libnvme_ns *elem) { return
htable_add_(((void)"../nvme-print-stdout.c" ":" "84", &ht
->raw), hash_string(ns_key(elem)), elem); } static inline _Bool
htable_ns_del(struct htable_ns *ht, const struct libnvme_ns *
elem) { return htable_del_(((void)"../nvme-print-stdout.c" ":"
"84", &ht->raw), hash_string(ns_key(elem)), elem); } static
inline struct libnvme_ns *htable_ns_get(const struct htable_ns
*ht, const typeof(ns_key((const struct libnvme_ns *)((void*)
0))) k) { struct htable_iter i; size_t h = hash_string(k); void
*c; for (c = htable_firstval_(((void)"../nvme-print-stdout.c"
":" "84", &ht->raw), &i, h); c; c = htable_nextval_
(((void)"../nvme-print-stdout.c" ":" "84", &ht->raw), &
i, h)) { if (ns_cmp(c, k)) return c; } return ((void*)0); } static
inline struct libnvme_ns *htable_ns_getmatch_(const struct htable_ns
*ht, const typeof(ns_key((const struct libnvme_ns *)((void*)
0))) k, size_t h, struct libnvme_ns *v, struct htable_ns_iter
*iter) { while (v) { if (ns_cmp(v, k)) break; v = htable_nextval_
(((void)"../nvme-print-stdout.c" ":" "84", &ht->raw), &
iter->i, h); } return v; } static inline struct libnvme_ns
*htable_ns_getfirst(const struct htable_ns *ht, const typeof
(ns_key((const struct libnvme_ns *)((void*)0))) k, struct htable_ns_iter
*iter) { size_t h = hash_string(k); struct libnvme_ns *v = htable_firstval_
(((void)"../nvme-print-stdout.c" ":" "84", &ht->raw), &
iter->i, h); return htable_ns_getmatch_(ht, k, h, v, iter)
; } static inline struct libnvme_ns *htable_ns_getnext(const struct
htable_ns *ht, const typeof(ns_key((const struct libnvme_ns *
)((void*)0))) k, struct htable_ns_iter *iter) { size_t h = hash_string
(k); struct libnvme_ns *v = htable_nextval_(((void)"../nvme-print-stdout.c"
":" "84", &ht->raw), &iter->i, h); return htable_ns_getmatch_
(ht, k, h, v, iter); } static inline _Bool htable_ns_delkey(struct
htable_ns *ht, const typeof(ns_key((const struct libnvme_ns *
)((void*)0))) k) { struct libnvme_ns *elem = htable_ns_get(ht
, k); if (elem) return htable_ns_del(ht, elem); return 0; } static
inline void htable_ns_delval(struct htable_ns *ht, struct htable_ns_iter
*iter) { htable_delval_(((void)"../nvme-print-stdout.c" ":" "84"
, &ht->raw), &iter->i); } static inline struct libnvme_ns
*htable_ns_pick(const struct htable_ns *ht, size_t seed, struct
htable_ns_iter *iter) { return htable_pick_(((void)"../nvme-print-stdout.c"
":" "84", &ht->raw), seed, iter ? &iter->i : (
(void*)0)); } static inline struct libnvme_ns *htable_ns_first
(const struct htable_ns *ht, struct htable_ns_iter *iter) { return
htable_first_(((void)"../nvme-print-stdout.c" ":" "84", &
ht->raw), &iter->i); } static inline struct libnvme_ns
*htable_ns_next(const struct htable_ns *ht, struct htable_ns_iter
*iter) { return htable_next_(((void)"../nvme-print-stdout.c"
":" "84", &ht->raw), &iter->i); } static inline
struct libnvme_ns *htable_ns_prev(const struct htable_ns *ht
, struct htable_ns_iter *iter) { return htable_prev_(((void)"../nvme-print-stdout.c"
":" "84", &ht->raw), &iter->i); }
;
85
86static void htable_ctrl_add_unique(struct htable_ctrl *ht, libnvme_ctrl_t c)
87{
88 if (htable_ctrl_get(ht, libnvme_ctrl_get_name(c)))
89 return;
90
91 htable_ctrl_add(ht, c);
92}
93
94static void htable_ns_add_unique(struct htable_ns *ht, libnvme_ns_t n)
95{
96 struct htable_ns_iter it;
97 libnvme_ns_t _n;
98
99 /*
100 * Test if namespace pointer is already in the hash, and thus avoid
101 * inserting severaltimes the same pointer.
102 */
103 for (_n = htable_ns_getfirst(ht, libnvme_ns_get_name(n), &it);
104 _n;
105 _n = htable_ns_getnext(ht, libnvme_ns_get_name(n), &it)) {
106 if (_n == n)
107 return;
108 }
109 htable_ns_add(ht, n);
110}
111
112struct nvme_resources {
113 struct libnvme_global_ctx *ctx;
114
115 struct htable_subsys ht_s;
116 struct htable_ctrl ht_c;
117 struct htable_ns ht_n;
118 struct strset subsystems;
119 struct strset ctrls;
120 struct strset namespaces;
121};
122
123struct nvme_resources_table {
124 struct nvme_resources *res;
125 struct table *t;
126};
127
128static int nvme_resources_init(struct libnvme_global_ctx *ctx, struct nvme_resources *res)
129{
130 libnvme_host_t h;
131 libnvme_subsystem_t s;
132 libnvme_ctrl_t c;
133 libnvme_ns_t n;
134 libnvme_path_t p;
135
136 res->ctx = ctx;
137 htable_subsys_init(&res->ht_s);
138 htable_ctrl_init(&res->ht_c);
139 htable_ns_init(&res->ht_n);
140 strset_init(&res->subsystems);
141 strset_init(&res->ctrls);
142 strset_init(&res->namespaces);
143
144 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
{
145 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
{
146 htable_subsys_add(&res->ht_s, s);
147 strset_add(&res->subsystems, libnvme_subsystem_get_name(s));
148
149 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
150 htable_ctrl_add_unique(&res->ht_c, c);
151 strset_add(&res->ctrls, libnvme_ctrl_get_name(c));
152
153 libnvme_ctrl_for_each_ns(c, n)for (n = libnvme_ctrl_first_ns(c); n != ((void*)0); n = libnvme_ctrl_next_ns
(c, n))
{
154 htable_ns_add_unique(&res->ht_n, n);
155 strset_add(&res->namespaces, libnvme_ns_get_name(n));
156 }
157
158 libnvme_ctrl_for_each_path(c, p)for (p = libnvme_ctrl_first_path(c); p != ((void*)0); p = libnvme_ctrl_next_path
(c, p))
{
159 n = libnvme_path_get_ns(p);
160 if (n) {
161 htable_ns_add_unique(&res->ht_n, n);
162 strset_add(&res->namespaces, libnvme_ns_get_name(n));
163 }
164 }
165 }
166
167 libnvme_subsystem_for_each_ns(s, n)for (n = libnvme_subsystem_first_ns(s); n != ((void*)0); n = libnvme_subsystem_next_ns
(s, n))
{
168 htable_ns_add_unique(&res->ht_n, n);
169 strset_add(&res->namespaces, libnvme_ns_get_name(n));
170 }
171 }
172 }
173
174 return 0;
175}
176
177static void nvme_resources_free(struct nvme_resources *res)
178{
179 strset_clear(&res->namespaces);
180 strset_clear(&res->ctrls);
181 strset_clear(&res->subsystems);
182 htable_ns_clear(&res->ht_n);
183 htable_ctrl_clear(&res->ht_c);
184 htable_subsys_clear(&res->ht_s);
185}
186
187static void stdout_feature_show_fields(enum nvme_features_id fid,
188 unsigned int result,
189 unsigned char *buf);
190static void stdout_smart_log(struct nvme_smart_log *smart, unsigned int nsid, const char *devname);
191
192static void stdout_predictable_latency_per_nvmset(
193 struct nvme_nvmset_predictable_lat_log *plpns_log,
194 __u16 nvmset_id, const char *devname)
195{
196 printf("Predictable Latency Per NVM Set Log for device: %s\n",
197 devname);
198 printf("Predictable Latency Per NVM Set Log for NVM Set ID: %u\n",
199 le16_to_cpu(nvmset_id));
200 printf("Status: %u\n", plpns_log->status);
201 printf("Event Type: %u\n",
202 le16_to_cpu(plpns_log->event_type));
203 printf("DTWIN Reads Typical: %"PRIu64"l" "u""\n",
204 le64_to_cpu(plpns_log->dtwin_rt));
205 printf("DTWIN Writes Typical: %"PRIu64"l" "u""\n",
206 le64_to_cpu(plpns_log->dtwin_wt));
207 printf("DTWIN Time Maximum: %"PRIu64"l" "u""\n",
208 le64_to_cpu(plpns_log->dtwin_tmax));
209 printf("NDWIN Time Minimum High: %"PRIu64"l" "u""\n",
210 le64_to_cpu(plpns_log->ndwin_tmin_hi));
211 printf("NDWIN Time Minimum Low: %"PRIu64"l" "u""\n",
212 le64_to_cpu(plpns_log->ndwin_tmin_lo));
213 printf("DTWIN Reads Estimate: %"PRIu64"l" "u""\n",
214 le64_to_cpu(plpns_log->dtwin_re));
215 printf("DTWIN Writes Estimate: %"PRIu64"l" "u""\n",
216 le64_to_cpu(plpns_log->dtwin_we));
217 printf("DTWIN Time Estimate: %"PRIu64"l" "u""\n\n\n",
218 le64_to_cpu(plpns_log->dtwin_te));
219}
220
221static void stdout_predictable_latency_event_agg_log(
222 struct nvme_aggregate_predictable_lat_event *pea_log,
223 __u64 log_entries, __u32 size, const char *devname)
224{
225 __u64 num_iter;
226 __u64 num_entries;
227
228 num_entries = le64_to_cpu(pea_log->num_entries);
229 printf("Predictable Latency Event Aggregate Log for device: %s\n", devname);
230
231 printf("Number of Entries Available: %"PRIu64"l" "u""\n", (uint64_t)num_entries);
232
233 num_iter = min(num_entries, log_entries)((num_entries) > (log_entries) ? (log_entries) : (num_entries
))
;
234 for (int i = 0; i < num_iter; i++)
235 printf("Entry[%d]: %u\n", i + 1, le16_to_cpu(pea_log->entries[i]));
236}
237
238static void stdout_persistent_event_log_rci(__le32 pel_header_rci)
239{
240 __u32 rci = le32_to_cpu(pel_header_rci);
241 __u32 rsvd19 = NVME_PEL_RCI_RSVD(rci)(((rci) >> NVME_PEL_RCI_RSVD_SHIFT) & NVME_PEL_RCI_RSVD_MASK
)
;
242 __u8 rce = NVME_PEL_RCI_RCE(rci)(((rci) >> NVME_PEL_RCI_RCE_SHIFT) & NVME_PEL_RCI_RCE_MASK
)
;
243 __u8 rcpit = NVME_PEL_RCI_RCPIT(rci)(((rci) >> NVME_PEL_RCI_RCPIT_SHIFT) & NVME_PEL_RCI_RCPIT_MASK
)
;
244 __u16 rcpid = NVME_PEL_RCI_RCPID(rci)(((rci) >> NVME_PEL_RCI_RCPID_SHIFT) & NVME_PEL_RCI_RCPID_MASK
)
;
245
246 if (rsvd19)
247 printf(" [31:19] : %#x\tReserved\n", rsvd19);
248 printf("\tReporting Context Exists (RCE): %s(%u)\n", rce ? "true" : "false", rce);
249 printf("\tReporting Context Port Identifier Type (RCPIT): %u(%s)\n", rcpit,
250 nvme_pel_rci_rcpit_to_string(rcpit));
251 printf("\tReporting Context Port Identifier (RCPID): %#x\n\n", rcpid);
252}
253
254static void stdout_persistent_event_entry_ehai(__u8 ehai)
255{
256 __u8 rsvd1 = NVME_PEL_EHAI_RSVD(ehai)(((ehai) >> NVME_PEL_EHAI_RSVD_SHIFT) & NVME_PEL_EHAI_RSVD_MASK
)
;
257 __u8 pit = NVME_PEL_EHAI_PIT(ehai)(((ehai) >> NVME_PEL_EHAI_PIT_SHIFT) & NVME_PEL_EHAI_PIT_MASK
)
;
258
259 printf(" [7:2] : %#x\tReserved\n", rsvd1);
260 printf("\tPort Identifier Type (PIT): %u(%s)\n", pit, nvme_pel_ehai_pit_to_string(pit));
261}
262
263static void stdout_add_bitmap(int i, __u8 seb)
264{
265 for (int bit = 0; bit < CHAR_BIT8; bit++) {
266 if (nvme_pel_event_to_string(bit + i * CHAR_BIT8)) {
267 if ((seb >> bit) & 0x1)
268 printf(" Support %s\n",
269 nvme_pel_event_to_string(bit + i * CHAR_BIT8));
270 }
271 }
272}
273
274static void stdout_persistent_event_log_fdp_events(unsigned int cdw11, unsigned int cdw12,
275 unsigned char *buf)
276{
277 unsigned int num = NVME_GET(cdw11, FEAT_FDPE_NOET)(((cdw11) >> NVME_FEAT_FDPE_NOET_SHIFT) & NVME_FEAT_FDPE_NOET_MASK
)
;
278
279 for (unsigned int i = 0; i < num; i++) {
280 printf("\t%-53s: %sEnabled\n", nvme_fdp_event_to_string(buf[i]),
281 NVME_GET(cdw12, FDP_SUPP_EVENT_ENABLED)(((cdw12) >> NVME_FDP_SUPP_EVENT_ENABLED_SHIFT) & NVME_FDP_SUPP_EVENT_ENABLED_MASK
)
? "" : "Not ");
282 }
283}
284
285void nvme_show_pel_header(struct nvme_persistent_event_log *pevent_log_head, int human)
286{
287 printf("Log Identifier: %u\n", pevent_log_head->lid);
288 printf("Total Number of Events: %u\n", le32_to_cpu(pevent_log_head->tnev));
289 printf("Total Log Length : %"PRIu64"l" "u""\n", le64_to_cpu(pevent_log_head->tll));
290 printf("Log Revision: %u\n", pevent_log_head->rv);
291 printf("Log Header Length: %u\n", pevent_log_head->lhl);
292 printf("Timestamp: %"PRIu64"l" "u""\n", le64_to_cpu(pevent_log_head->ts));
293 printf("Power On Hours (POH): %s",
294 uint128_t_to_l10n_string(le128_to_cpu(pevent_log_head->poh)));
295 printf("Power Cycle Count: %"PRIu64"l" "u""\n", le64_to_cpu(pevent_log_head->pcc));
296 printf("PCI Vendor ID (VID): %u\n", le16_to_cpu(pevent_log_head->vid));
297 printf("PCI Subsystem Vendor ID (SSVID): %u\n", le16_to_cpu(pevent_log_head->ssvid));
298 printf("Serial Number (SN): %-.*s\n", (int)sizeof(pevent_log_head->sn),
299 pevent_log_head->sn);
300 printf("Model Number (MN): %-.*s\n", (int)sizeof(pevent_log_head->mn), pevent_log_head->mn);
301 printf("NVM Subsystem NVMe Qualified Name (SUBNQN): %-.*s\n",
302 (int)sizeof(pevent_log_head->subnqn), pevent_log_head->subnqn);
303 printf("Generation Number: %u\n", le16_to_cpu(pevent_log_head->gen_number));
304 printf("Reporting Context Information (RCI): %u\n", le32_to_cpu(pevent_log_head->rci));
305
306 if (human)
307 stdout_persistent_event_log_rci(pevent_log_head->rci);
308
309 printf("Supported Events Bitmap:\n");
310 for (int i = 0; i < 32; i++) {
311 if (!pevent_log_head->seb[i])
312 continue;
313 stdout_add_bitmap(i, pevent_log_head->seb[i]);
314 }
315}
316
317void nvme_show_pel_event_header(int i, struct nvme_persistent_event_entry *pevent_entry_head,
318 int human)
319{
320 __u16 vsil = le16_to_cpu(pevent_entry_head->vsil);
321
322 printf("Event Number: %u\n", i);
323 printf("Event Type: %s\n", nvme_pel_event_to_string(pevent_entry_head->etype));
324 printf("Event Type Revision: %u\n", pevent_entry_head->etype_rev);
325 printf("Event Header Length: %u\n", pevent_entry_head->ehl);
326 printf("Event Header Additional Info: %u\n", pevent_entry_head->ehai);
327
328 if (human)
329 stdout_persistent_event_entry_ehai(pevent_entry_head->ehai);
330
331 printf("Controller Identifier: %u\n", le16_to_cpu(pevent_entry_head->cntlid));
332 printf("Event Timestamp: %"PRIu64"l" "u""\n", le64_to_cpu(pevent_entry_head->ets));
333 printf("Port Identifier: %u\n", le16_to_cpu(pevent_entry_head->pelpid));
334 printf("Vendor Specific Information Length: %u\n", vsil);
335 printf("Event Length: %u\n", le16_to_cpu(pevent_entry_head->el));
336
337 if (vsil) {
338 printf("Vendor Specific Information:\n");
339 d((void *)pevent_entry_head + 1, vsil, 16, 1);
340 }
341}
342
343void nvme_show_pel_smart_health_event(void *pevent_log_info, __u32 offset,
344 const char *devname)
345{
346 struct nvme_smart_log *smart_event = pevent_log_info + offset;
347
348 printf("Smart Health Event Entry:\n");
349 stdout_smart_log(smart_event, NVME_NSID_ALL, devname);
350}
351
352void nvme_show_pel_fw_commit_event(void *pevent_log_info, __u32 offset)
353{
354 struct nvme_fw_commit_event *fw_commit_event = pevent_log_info + offset;
355
356 printf("FW Commit Event Entry:\n");
357 printf("Old Firmware Revision: %"PRIu64"l" "u"" (%s)\n", le64_to_cpu(fw_commit_event->old_fw_rev),
358 util_fw_to_string((char *)&fw_commit_event->old_fw_rev));
359 printf("New Firmware Revision: %"PRIu64"l" "u"" (%s)\n", le64_to_cpu(fw_commit_event->new_fw_rev),
360 util_fw_to_string((char *)&fw_commit_event->new_fw_rev));
361 printf("FW Commit Action: %u\n", fw_commit_event->fw_commit_action);
362 printf("FW Slot: %u\n", fw_commit_event->fw_slot);
363 printf("Status Code Type for Firmware Commit Command: %u\n", fw_commit_event->sct_fw);
364 printf("Status Returned for Firmware Commit Command: %u\n", fw_commit_event->sc_fw);
365 printf("Vendor Assigned Firmware Commit Result Code: %u\n",
366 le16_to_cpu(fw_commit_event->vndr_assign_fw_commit_rc));
367}
368
369void nvme_show_pel_timestamp_event(void *pevent_log_info, __u32 offset)
370{
371 struct nvme_time_stamp_change_event *ts_change_event = pevent_log_info + offset;
372
373 printf("Time Stamp Change Event Entry:\n");
374 printf("Previous Timestamp: %"PRIu64"l" "u""\n", le64_to_cpu(ts_change_event->previous_timestamp));
375 printf("Milliseconds Since Reset: %"PRIu64"l" "u""\n",
376 le64_to_cpu(ts_change_event->ml_secs_since_reset));
377}
378
379void nvme_show_pel_power_on_reset_event(void *pevent_log_info, __u32 offset,
380 struct nvme_persistent_event_entry *pevent_entry_head)
381{
382 __u64 *fw_rev;
383 __u32 por_info_len = le16_to_cpu(pevent_entry_head->el) -
384 le16_to_cpu(pevent_entry_head->vsil) - sizeof(*fw_rev);
385 struct nvme_power_on_reset_info_list *por_event;
386 __u32 por_info_list = por_info_len / sizeof(*por_event);
387
388 printf("Power On Reset Event Entry:\n");
389 fw_rev = pevent_log_info + offset;
390 printf("Firmware Revision: %"PRIu64"l" "u"" (%s)\n", le64_to_cpu(*fw_rev),
391 util_fw_to_string((char *)fw_rev));
392 printf("Reset Information List:\n");
393
394 for (int i = 0; i < por_info_list; i++) {
395 por_event = pevent_log_info + offset + sizeof(*fw_rev) + i * sizeof(*por_event);
396 printf("Controller ID: %u\n", le16_to_cpu(por_event->cid));
397 printf("Firmware Activation: %u\n", por_event->fw_act);
398 printf("Operation in Progress: %u\n", por_event->op_in_prog);
399 printf("Controller Power Cycle: %u\n", le32_to_cpu(por_event->ctrl_power_cycle));
400 printf("Power on milliseconds: %"PRIu64"l" "u""\n",
401 le64_to_cpu(por_event->power_on_ml_seconds));
402 printf("Controller Timestamp: %"PRIu64"l" "u""\n",
403 le64_to_cpu(por_event->ctrl_time_stamp));
404 }
405}
406
407void nvme_show_pel_nss_hw_error_event(void *pevent_log_info, __u32 offset)
408{
409 struct nvme_nss_hw_err_event *nss_hw_err_event = pevent_log_info + offset;
410
411 printf("NVM Subsystem Hardware Error Event Code Entry: %u, %s\n",
412 le16_to_cpu(nss_hw_err_event->nss_hw_err_event_code),
413 nvme_nss_hw_error_to_string(nss_hw_err_event->nss_hw_err_event_code));
414}
415
416void nvme_show_pel_change_ns_event(void *pevent_log_info, __u32 offset)
417{
418 struct nvme_change_ns_event *ns_event = pevent_log_info + offset;
419
420 printf("Change Namespace Event Entry:\n");
421 printf("Namespace Management CDW10: %u\n", le32_to_cpu(ns_event->nsmgt_cdw10));
422 printf("Namespace Size: %"PRIu64"l" "u""\n", le64_to_cpu(ns_event->nsze));
423 printf("Namespace Capacity: %"PRIu64"l" "u""\n", le64_to_cpu(ns_event->nscap));
424 printf("Formatted LBA Size: %u\n", ns_event->flbas);
425 printf("End-to-end Data Protection Type Settings: %u\n", ns_event->dps);
426 printf("Namespace Multi-path I/O and Namespace Sharing Capabilities: %u\n", ns_event->nmic);
427 printf("ANA Group Identifier: %u\n", le32_to_cpu(ns_event->ana_grp_id));
428 printf("NVM Set Identifier: %u\n", le16_to_cpu(ns_event->nvmset_id));
429 printf("Namespace ID: %u\n", le32_to_cpu(ns_event->nsid));
430}
431
432void nvme_show_pel_format_start_event(void *pevent_log_info, __u32 offset)
433{
434 struct nvme_format_nvm_start_event *format_start_event = pevent_log_info + offset;
435
436 printf("Format NVM Start Event Entry:\n");
437 printf("Namespace Identifier: %u\n", le32_to_cpu(format_start_event->nsid));
438 printf("Format NVM Attributes: %u\n", format_start_event->fna);
439 printf("Format NVM CDW10: %u\n", le32_to_cpu(format_start_event->format_nvm_cdw10));
440}
441
442void nvme_show_pel_format_completion_event(void *pevent_log_info, __u32 offset)
443{
444 struct nvme_format_nvm_compln_event *format_cmpln_event = pevent_log_info + offset;
445
446 printf("Format NVM Completion Event Entry:\n");
447 printf("Namespace Identifier: %u\n", le32_to_cpu(format_cmpln_event->nsid));
448 printf("Smallest Format Progress Indicator: %u\n", format_cmpln_event->smallest_fpi);
449 printf("Format NVM Status: %u\n", format_cmpln_event->format_nvm_status);
450 printf("Completion Information: %u\n", le16_to_cpu(format_cmpln_event->compln_info));
451 printf("Status Field: %u\n", le32_to_cpu(format_cmpln_event->status_field));
452}
453
454void nvme_show_pel_sanitize_start_event(void *pevent_log_info, __u32 offset)
455{
456 struct nvme_sanitize_start_event *sanitize_start_event = pevent_log_info + offset;
457
458 printf("Sanitize Start Event Entry:\n");
459 printf("SANICAP: %u\n", sanitize_start_event->sani_cap);
460 printf("Sanitize CDW10: %u\n", le32_to_cpu(sanitize_start_event->sani_cdw10));
461 printf("Sanitize CDW11: %u\n", le32_to_cpu(sanitize_start_event->sani_cdw11));
462}
463
464void nvme_show_pel_sanitize_completion_event(void *pevent_log_info, __u32 offset)
465{
466 struct nvme_sanitize_compln_event *sanitize_cmpln_event = pevent_log_info + offset;
467
468 printf("Sanitize Completion Event Entry:\n");
469 printf("Sanitize Progress: %u\n", le16_to_cpu(sanitize_cmpln_event->sani_prog));
470 printf("Sanitize Status: %u\n", le16_to_cpu(sanitize_cmpln_event->sani_status));
471 printf("Completion Information: %u\n", le16_to_cpu(sanitize_cmpln_event->cmpln_info));
472}
473
474void nvme_show_pel_set_feature_event(void *pevent_log_info, __u32 offset)
475{
476 int fid, cdw11, cdw12, dword_cnt;
477 unsigned char *mem_buf;
478 struct nvme_set_feature_event *set_feat_event = pevent_log_info + offset;
479
480 printf("Set Feature Event Entry:\n");
481 dword_cnt = NVME_SET_FEAT_EVENT_DW_COUNT(set_feat_event->layout)(((set_feat_event->layout) >> NVME_SET_FEAT_EVENT_DW_COUNT_SHIFT
) & NVME_SET_FEAT_EVENT_DW_COUNT_MASK)
;
482 fid = NVME_GET(le32_to_cpu(set_feat_event->cdw_mem[0]), SET_FEATURES_CDW10_FID)(((le32_to_cpu(set_feat_event->cdw_mem[0])) >> NVME_SET_FEATURES_CDW10_FID_SHIFT
) & NVME_SET_FEATURES_CDW10_FID_MASK)
;
483 cdw11 = le32_to_cpu(set_feat_event->cdw_mem[1]);
484
485 printf("Set Feature ID: 0x%02x (%s), value: 0x%08x\n", fid, nvme_feature_to_string(fid),
486 cdw11);
487
488 if (!NVME_SET_FEAT_EVENT_MB_COUNT(set_feat_event->layout)(((set_feat_event->layout) >> NVME_SET_FEAT_EVENT_MB_COUNT_SHIFT
) & NVME_SET_FEAT_EVENT_MB_COUNT_MASK)
)
489 return;
490
491 mem_buf = (unsigned char *)set_feat_event + 4 + dword_cnt * 4;
492 if (fid == NVME_FEAT_FID_FDP_EVENTS) {
493 cdw12 = le32_to_cpu(set_feat_event->cdw_mem[2]);
494 stdout_persistent_event_log_fdp_events(cdw11, cdw12, mem_buf);
495 } else {
496 stdout_feature_show_fields(fid, cdw11, mem_buf);
497 }
498}
499
500void nvme_show_pel_thermal_excursion_event(void *pevent_log_info, __u32 offset)
501{
502 struct nvme_thermal_exc_event *thermal_exc_event = pevent_log_info + offset;
503
504 printf("Thermal Excursion Event Entry:\n");
505 printf("Over Temperature: %u\n", thermal_exc_event->over_temp);
506 printf("Threshold: %u\n", thermal_exc_event->threshold);
507}
508
509static void pel_vs_event_data(void *vsed, __u8 vsedt, __u16 vsedl)
510{
511 printf("Vendor Specific Event Data:\n");
512 switch (vsedt) {
513 case NVME_PEL_VSEDT_EVENT_NAME:
514 printf("Event Name for Vendor Specific Event Code:\n");
515 printf("%.*s\n", vsedl, (char *)vsed);
516 break;
517 case NVME_PEL_VSEDT_ASCII_STRING:
518 printf("ASCII String Data:\n");
519 printf("%.*s\n", vsedl, (char *)vsed);
520 break;
521 case NVME_PEL_VSEDT_BINARY:
522 printf("Binary Data:\n");
523 d(vsed, vsedl, 16, 1);
524 break;
525 case NVME_PEL_VSEDT_SIGNED_INT:
526 printf("Signed Integer Data: %" PRId64"l" "d" "\n", (int64_t)vsedt);
527 break;
528 default:
529 printf("Reserved data type. As Binary:\n");
530 d(vsed, vsedl, 16, 1);
531 }
532}
533
534void nvme_show_pel_vendor_specific_event(void *pevent_log_info, __u32 offset,
535 __u32 event_data_len)
536{
537 __u32 progress = 0;
538 __u16 vsedl;
539 int i;
540 struct nvme_vs_event_desc *vs_desc;
541
542 printf("Vendor Specific Event Entry:\n");
543 for (i = 0; progress < event_data_len; i++) {
544 vs_desc = pevent_log_info + offset + progress;
545 vsedl = le16_to_cpu(vs_desc->vsedl);
546
547 printf("Vendor Specific Event Descriptor %u:\n", i);
548 printf("Vendor Specific Event Code: %u\n", le16_to_cpu(vs_desc->vsec));
549 printf("Vendor Specific Event Data Type: %u\n", vs_desc->vsedt);
550 printf("Vendor Specific Event UIndex: %u\n", vs_desc->uidx);
551 printf("Vendor Specific Event Data Length: %u\n", vsedl);
552 if (vsedl)
553 pel_vs_event_data(vs_desc + 1, vs_desc->vsedt,
554 vsedl);
555 progress += sizeof(*vs_desc) + vsedl;
556 }
557}
558
559static void stdout_persistent_event_log(void *pevent_log_info, __u8 action, __u32 size,
560 const char *devname)
561{
562 struct nvme_persistent_event_log *pevent_log_head;
563 __u32 offset = sizeof(*pevent_log_head);
564 __u16 vsil, el;
565 struct nvme_persistent_event_entry *pevent_entry_head;
566 int human = stdout_print_ops.flags & VERBOSE;
567
568 printf("Persistent Event Log for device: %s\n", devname);
569 printf("Action for Persistent Event Log: %u\n", action);
570
571 if (size < offset) {
572 printf("No log data can be shown with this log len at least " \
573 "512 bytes is required or can be 0 to read the complete " \
574 "log page after context established\n");
575 return;
576 }
577
578 pevent_log_head = pevent_log_info;
579
580 nvme_show_pel_header(pevent_log_head, human);
581
582 printf("\n");
583 printf("\nPersistent Event Entries:\n");
584 for (int i = 0; i < le32_to_cpu(pevent_log_head->tnev); i++) {
585 if (offset + sizeof(*pevent_entry_head) >= size)
586 break;
587
588 pevent_entry_head = pevent_log_info + offset;
589 vsil = le16_to_cpu(pevent_entry_head->vsil);
590 el = le16_to_cpu(pevent_entry_head->el);
591
592 if ((offset + pevent_entry_head->ehl + 3 + el) >= size)
593 break;
594
595 nvme_show_pel_event_header(i, pevent_entry_head, human);
596
597 offset += pevent_entry_head->ehl + vsil + 3;
598
599 switch (pevent_entry_head->etype) {
600 case NVME_PEL_SMART_HEALTH_EVENT:
601 nvme_show_pel_smart_health_event(pevent_log_info,
602 offset, devname);
603 break;
604 case NVME_PEL_FW_COMMIT_EVENT:
605 nvme_show_pel_fw_commit_event(pevent_log_info, offset);
606 break;
607 case NVME_PEL_TIMESTAMP_EVENT:
608 nvme_show_pel_timestamp_event(pevent_log_info, offset);
609 break;
610 case NVME_PEL_POWER_ON_RESET_EVENT:
611 nvme_show_pel_power_on_reset_event(pevent_log_info,
612 offset,
613 pevent_entry_head);
614 break;
615 case NVME_PEL_NSS_HW_ERROR_EVENT:
616 nvme_show_pel_nss_hw_error_event(pevent_log_info,
617 offset);
618 break;
619 case NVME_PEL_CHANGE_NS_EVENT:
620 nvme_show_pel_change_ns_event(pevent_log_info, offset);
621 break;
622 case NVME_PEL_FORMAT_START_EVENT:
623 nvme_show_pel_format_start_event(pevent_log_info,
624 offset);
625 break;
626 case NVME_PEL_FORMAT_COMPLETION_EVENT:
627 nvme_show_pel_format_completion_event(pevent_log_info,
628 offset);
629 break;
630 case NVME_PEL_SANITIZE_START_EVENT:
631 nvme_show_pel_sanitize_start_event(pevent_log_info,
632 offset);
633 break;
634 case NVME_PEL_SANITIZE_COMPLETION_EVENT:
635 nvme_show_pel_sanitize_completion_event(pevent_log_info,
636 offset);
637 break;
638 case NVME_PEL_SET_FEATURE_EVENT:
639 nvme_show_pel_set_feature_event(pevent_log_info,
640 offset);
641 break;
642 case NVME_PEL_TELEMETRY_CRT:
643 d(pevent_log_info + offset, 512, 16, 1);
644 break;
645 case NVME_PEL_THERMAL_EXCURSION_EVENT:
646 nvme_show_pel_thermal_excursion_event(pevent_log_info,
647 offset);
648 break;
649 case NVME_PEL_SANITIZE_MEDIA_VERIF_EVENT:
650 printf("Sanitize Media Verification Event\n");
651 break;
652 case NVME_PEL_VENDOR_SPECIFIC_EVENT:
653 nvme_show_pel_vendor_specific_event(pevent_log_info,
654 offset, el - vsil);
655 break;
656 default:
657 printf("Reserved Event\n\n");
658 break;
659 }
660 offset += el;
661 printf("\n");
662 }
663}
664
665static void stdout_endurance_group_event_agg_log(
666 struct nvme_aggregate_endurance_group_event *endurance_log,
667 __u64 log_entries, __u32 size, const char *devname)
668{
669 printf("Endurance Group Event Aggregate Log for device: %s\n", devname);
670
671 printf("Number of Entries Available: %"PRIu64"l" "u""\n",
672 le64_to_cpu(endurance_log->num_entries));
673
674 for (int i = 0; i < log_entries; i++) {
675 printf("Entry[%d]: %u\n", i + 1,
676 le16_to_cpu(endurance_log->entries[i]));
677 }
678}
679
680static void stdout_lba_status_log(void *lba_status, __u32 size,
681 const char *devname)
682{
683 struct nvme_lba_status_log *hdr;
684 struct nvme_lbas_ns_element *ns_element;
685 struct nvme_lba_rd *range_desc;
686 int offset = sizeof(*hdr);
687 __u32 num_lba_desc, num_elements;
688
689 hdr = lba_status;
690 printf("LBA Status Log for device: %s\n", devname);
691 printf("LBA Status Log Page Length: %"PRIu32"u""\n",
692 le32_to_cpu(hdr->lslplen));
693 num_elements = le32_to_cpu(hdr->nlslne);
694 printf("Number of LBA Status Log Namespace Elements: %"PRIu32"u""\n",
695 num_elements);
696 printf("Estimate of Unrecoverable Logical Blocks: %"PRIu32"u""\n",
697 le32_to_cpu(hdr->estulb));
698 printf("LBA Status Generation Counter: %"PRIu16"u""\n", le16_to_cpu(hdr->lsgc));
699 for (int ele = 0; ele < num_elements; ele++) {
700 ns_element = lba_status + offset;
701 printf("Namespace Element Identifier: %"PRIu32"u""\n",
702 le32_to_cpu(ns_element->neid));
703 num_lba_desc = le32_to_cpu(ns_element->nlrd);
704 printf("Number of LBA Range Descriptors: %"PRIu32"u""\n", num_lba_desc);
705 printf("Recommended Action Type: %u\n", ns_element->ratype);
706
707 offset += sizeof(*ns_element);
708 if (num_lba_desc != 0xffffffff) {
709 for (int i = 0; i < num_lba_desc; i++) {
710 range_desc = lba_status + offset;
711 printf("RSLBA[%d]: %"PRIu64"l" "u""\n", i,
712 le64_to_cpu(range_desc->rslba));
713 printf("RNLB[%d]: %"PRIu32"u""\n", i,
714 le32_to_cpu(range_desc->rnlb));
715 offset += sizeof(*range_desc);
716 }
717 } else {
718 printf("Number of LBA Range Descriptors (NLRD) set to %#x for "\
719 "NS element %d\n", num_lba_desc, ele);
720 }
721 }
722}
723
724static void stdout_resv_notif_log(struct nvme_resv_notification_log *resv,
725 const char *devname)
726{
727 printf("Reservation Notif Log for device: %s\n", devname);
728 printf("Log Page Count : %"PRIx64"l" "x""\n",
729 le64_to_cpu(resv->lpc));
730 printf("Resv Notif Log Page Type : %u (%s)\n",
731 resv->rnlpt,
732 nvme_resv_notif_to_string(resv->rnlpt));
733 printf("Num of Available Log Pages : %u\n", resv->nalp);
734 printf("Namespace ID: : %"PRIx32"x""\n",
735 le32_to_cpu(resv->nsid));
736}
737
738static void stdout_fid_support_effects_log_human(__u32 fid_support)
739{
740 const char *set = "+";
741 const char *clr = "-";
742 __u16 fsp;
743
744 printf(" FSUPP+");
745 printf(" UDCC%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_UDCC) ? set : clr);
746 printf(" NCC%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_NCC) ? set : clr);
747 printf(" NIC%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_NIC) ? set : clr);
748 printf(" CCC%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_CCC) ? set : clr);
749 printf(" USS%s", (fid_support & NVME_FID_SUPPORTED_EFFECTS_UUID_SEL) ? set : clr);
750
751 fsp = NVME_GET(fid_support, FID_SUPPORTED_EFFECTS_SCOPE)(((fid_support) >> NVME_FID_SUPPORTED_EFFECTS_SCOPE_SHIFT
) & NVME_FID_SUPPORTED_EFFECTS_SCOPE_MASK)
;
752
753 printf(" NAMESPACE SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_NS) ? set : clr);
754 printf(" CONTROLLER SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_CTRL) ? set : clr);
755 printf(" NVM SET SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_NVM_SET) ? set : clr);
756 printf(" ENDURANCE GROUP SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_ENDGRP) ? set : clr);
757 printf(" DOMAIN SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_DOMAIN) ? set : clr);
758 printf(" NVM Subsystem SCOPE%s", (fsp & NVME_FID_SUPPORTED_EFFECTS_SCOPE_NSS) ? set : clr);
759}
760
761static void stdout_fid_support_effects_log(struct nvme_fid_supported_effects_log *fid_log,
762 const char *devname)
763{
764 __u32 fid_effect;
765 int i, human = stdout_print_ops.flags & VERBOSE;
766
767 printf("FID Supports Effects Log for device: %s\n", devname);
768 printf("Admin Command Set\n");
769 for (i = 0; i < 256; i++) {
770 fid_effect = le32_to_cpu(fid_log->fid_support[i]);
771 if (fid_effect & NVME_FID_SUPPORTED_EFFECTS_FSUPP) {
772 printf("FID %02x -> Support Effects Log: %08x", i,
773 fid_effect);
774 if (human)
775 stdout_fid_support_effects_log_human(fid_effect);
776 printf("\n");
777 }
778 }
779}
780
781static void stdout_mi_cmd_support_effects_log_human(__u32 mi_cmd_support)
782{
783 const char *set = "+";
784 const char *clr = "-";
785 __u16 csp;
786
787 printf(" CSUPP+");
788 printf(" UDCC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_UDCC) ? set : clr);
789 printf(" NCC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_NCC) ? set : clr);
790 printf(" NIC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_NIC) ? set : clr);
791 printf(" CCC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_CCC) ? set : clr);
792
793 csp = NVME_GET(mi_cmd_support, MI_CMD_SUPPORTED_EFFECTS_SCOPE)(((mi_cmd_support) >> NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_SHIFT
) & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_MASK)
;
794
795 printf(" NAMESPACE SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NS) ? set : clr);
796 printf(" CONTROLLER SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_CTRL) ? set : clr);
797 printf(" NVM SET SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NVM_SET) ? set : clr);
798 printf(" ENDURANCE GROUP SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_ENDGRP) ? set : clr);
799 printf(" DOMAIN SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_DOMAIN) ? set : clr);
800 printf(" NVM Subsystem SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NSS) ? set : clr);
801}
802
803static void stdout_mi_cmd_support_effects_log(struct nvme_mi_cmd_supported_effects_log *mi_cmd_log,
804 const char *devname)
805{
806 __u32 mi_cmd_effect;
807 int i, human = stdout_print_ops.flags & VERBOSE;
808
809 printf("MI Commands Support Effects Log for device: %s\n", devname);
810 printf("Admin Command Set\n");
811 for (i = 0; i < NVME_LOG_MI_CMD_SUPPORTED_EFFECTS_MAX; i++) {
812 mi_cmd_effect = le32_to_cpu(mi_cmd_log->mi_cmd_support[i]);
813 if (mi_cmd_effect & NVME_MI_CMD_SUPPORTED_EFFECTS_CSUPP) {
814 printf("MI CMD %02x -> Support Effects Log: %08x", i,
815 mi_cmd_effect);
816 if (human)
817 stdout_mi_cmd_support_effects_log_human(mi_cmd_effect);
818 printf("\n");
819 }
820 }
821}
822
823static void stdout_boot_part_log(void *bp_log, const char *devname,
824 __u32 size)
825{
826 struct nvme_boot_partition *hdr = bp_log;
827
828 printf("Boot Partition Log for device: %s\n", devname);
829 printf("Log ID: %u\n", hdr->lid);
830 printf("Boot Partition Size: %u KiB\n",
831 NVME_BOOT_PARTITION_INFO_BPSZ(le32_to_cpu(hdr->bpinfo))(((le32_to_cpu(hdr->bpinfo)) >> NVME_BOOT_PARTITION_INFO_BPSZ_SHIFT
) & NVME_BOOT_PARTITION_INFO_BPSZ_MASK)
);
832 printf("Active BPID: %u\n", NVME_BOOT_PARTITION_INFO_ABPID(le32_to_cpu(hdr->bpinfo))(((le32_to_cpu(hdr->bpinfo)) >> NVME_BOOT_PARTITION_INFO_ABPID_SHIFT
) & NVME_BOOT_PARTITION_INFO_ABPID_MASK)
);
833}
834
835static const char *eomip_to_string(__u8 eomip)
836{
837 const char *string;
838
839 switch (eomip) {
840 case NVME_PHY_RX_EOM_NOT_STARTED:
841 string = "Not Started";
842 break;
843 case NVME_PHY_RX_EOM_IN_PROGRESS:
844 string = "In Progress";
845 break;
846 case NVME_PHY_RX_EOM_COMPLETED:
847 string = "Completed";
848 break;
849 default:
850 string = "Unknown";
851 break;
852 }
853 return string;
854}
855
856static void stdout_phy_rx_eom_odp(uint8_t odp)
857{
858 __u8 rsvd = NVME_EOM_ODP_RSVD(odp)(((odp) >> NVME_EOM_ODP_RSVD_SHIFT) & NVME_EOM_ODP_RSVD_MASK
)
;
859 __u8 edfp = NVME_EOM_ODP_EDFP(odp)(((odp) >> NVME_EOM_ODP_EDFP_SHIFT) & NVME_EOM_ODP_EDFP_MASK
)
;
860 __u8 pefp = NVME_EOM_ODP_PEFP(odp)(((odp) >> NVME_EOM_ODP_PEFP_SHIFT) & NVME_EOM_ODP_PEFP_MASK
)
;
861
862 if (rsvd)
863 printf(" [7:2] : %#x\tReserved\n", rsvd);
864 printf(" [1:1] : %#x\tEye Data Field %sPresent\n",
865 edfp, edfp ? "" : "Not ");
866 printf(" [0:0] : %#x\tPrintable Eye Field %sPresent\n",
867 pefp, pefp ? "" : "Not ");
868}
869
870static void stdout_eom_printable_eye(struct nvme_eom_lane_desc *lane)
871{
872 char *eye = (char *)lane->eye_desc;
873 int i, j;
874
875 printf("Printable Eye:\n");
876 for (i = 0; i < le16_to_cpu(lane->nrows); i++) {
877 for (j = 0; j < le16_to_cpu(lane->ncols); j++)
878 printf("%c", eye[i * le16_to_cpu(lane->ncols) + j]);
879 printf("\n");
880 }
881}
882
883static void stdout_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log)
884{
885 void *p = log->descs;
886 int i;
887
888 for (i = 0; i < log->nd; i++) {
889 struct nvme_eom_lane_desc *desc = p;
890 unsigned char *vsdata = NULL((void*)0);
891 unsigned int vsdataoffset = 0;
892 uint16_t nrows, ncols, edlen;
893
894 nrows = le16_to_cpu(desc->nrows);
895 ncols = le16_to_cpu(desc->ncols);
896 edlen = le16_to_cpu(desc->edlen);
897
898 printf("Measurement Status: %s\n",
899 desc->mstatus ? "Successful" : "Not Successful");
900 printf("Lane: %u\n", desc->lane);
901 printf("Eye: %u\n", desc->eye);
902 printf("Top: %u\n", le16_to_cpu(desc->top));
903 printf("Bottom: %u\n", le16_to_cpu(desc->bottom));
904 printf("Left: %u\n", le16_to_cpu(desc->left));
905 printf("Right: %u\n", le16_to_cpu(desc->right));
906 printf("Number of Rows: %u\n", nrows);
907 printf("Number of Columns: %u\n", ncols);
908 printf("Eye Data Length: %u\n", desc->edlen);
909
910 if (NVME_EOM_ODP_PEFP(log->odp)(((log->odp) >> NVME_EOM_ODP_PEFP_SHIFT) & NVME_EOM_ODP_PEFP_MASK
)
)
911 stdout_eom_printable_eye(desc);
912
913 /* Eye Data field is vendor specific */
914 if (edlen == 0)
915 continue;
916
917 vsdataoffset = (nrows * ncols) + sizeof(struct nvme_eom_lane_desc);
918 vsdata = (unsigned char *)((unsigned char *)desc + vsdataoffset);
919 printf("Eye Data:\n");
920 d(vsdata, edlen, 16, 1);
921 printf("\n");
922
923 p += log->dsize;
924 }
925}
926
927static void stdout_phy_rx_eom_log(struct nvme_phy_rx_eom_log *log, __u16 controller)
928{
929 int human = stdout_print_ops.flags & VERBOSE;
930
931 printf("Physical Interface Receiver Eye Opening Measurement Log for controller ID: %u\n", controller);
932 printf("Log ID: %u\n", log->lid);
933 printf("EOM In Progress: %s\n", eomip_to_string(log->eomip));
934 printf("Header Size: %u\n", le16_to_cpu(log->hsize));
935 printf("Result Size: %u\n", le32_to_cpu(log->rsize));
936 printf("EOM Data Generation Number: %u\n", log->eomdgn);
937 printf("Log Revision: %u\n", log->lr);
938 printf("Optional Data Present: %u\n", log->odp);
939 if (human)
940 stdout_phy_rx_eom_odp(log->odp);
941 printf("Lanes: %u\n", log->lanes);
942 printf("Eyes Per Lane: %u\n", log->epl);
943 printf("Log Specific Parameter Field Copy: %u\n", log->lspfc);
944 printf("Link Information: %u\n", log->li);
945 printf("Log Specific Identifier Copy: %u\n", le16_to_cpu(log->lsic));
946 printf("Descriptor Size: %u\n", le32_to_cpu(log->dsize));
947 printf("Number of Descriptors: %u\n", le16_to_cpu(log->nd));
948 printf("Maximum Top Bottom: %u\n", le16_to_cpu(log->maxtb));
949 printf("Maximum Left Right: %u\n", le16_to_cpu(log->maxlr));
950 printf("Estimated Time for Good Quality: %u\n", le16_to_cpu(log->etgood));
951 printf("Estimated Time for Better Quality: %u\n", le16_to_cpu(log->etbetter));
952 printf("Estimated Time for Best Quality: %u\n", le16_to_cpu(log->etbest));
953
954 if (log->eomip == NVME_PHY_RX_EOM_COMPLETED)
955 stdout_phy_rx_eom_descs(log);
956}
957
958static void stdout_media_unit_stat_log(struct nvme_media_unit_stat_log *mus_log)
959{
960 int i;
961 int nmu = le16_to_cpu(mus_log->nmu);
962
963 printf("Number of Media Unit Status Descriptors: %u\n", nmu);
964 printf("Number of Channels: %u\n", le16_to_cpu(mus_log->cchans));
965 printf("Selected Configuration: %u\n", le16_to_cpu(mus_log->sel_config));
966 for (i = 0; i < nmu; i++) {
967 printf("Media Unit Status Descriptor: %u\n", i);
968 printf("Media Unit Identifier: %u\n",
969 le16_to_cpu(mus_log->mus_desc[i].muid));
970 printf("Domain Identifier: %u\n",
971 le16_to_cpu(mus_log->mus_desc[i].domainid));
972 printf("Endurance Group Identifier: %u\n",
973 le16_to_cpu(mus_log->mus_desc[i].endgid));
974 printf("NVM Set Identifier: %u\n",
975 le16_to_cpu(mus_log->mus_desc[i].nvmsetid));
976 printf("Capacity Adjustment Factor: %u\n",
977 le16_to_cpu(mus_log->mus_desc[i].cap_adj_fctr));
978 printf("Available Spare: %u\n", mus_log->mus_desc[i].avl_spare);
979 printf("Percentage Used: %u\n", mus_log->mus_desc[i].percent_used);
980 printf("Number of Channels: %u\n", mus_log->mus_desc[i].mucs);
981 printf("Channel Identifiers Offset: %u\n", mus_log->mus_desc[i].cio);
982 }
983}
984
985static void stdout_fdp_config_fdpa(uint8_t fdpa)
986{
987 __u8 valid = NVME_GET(fdpa, FDP_CONFIG_FDPA_VALID)(((fdpa) >> NVME_FDP_CONFIG_FDPA_VALID_SHIFT) & NVME_FDP_CONFIG_FDPA_VALID_MASK
)
;
988 __u8 rsvd = (fdpa >> 5) & 0x3;
989 __u8 fdpvwc = NVME_GET(fdpa, FDP_CONFIG_FDPA_FDPVWC)(((fdpa) >> NVME_FDP_CONFIG_FDPA_FDPVWC_SHIFT) & NVME_FDP_CONFIG_FDPA_FDPVWC_MASK
)
;
990 __u8 rgif = NVME_GET(fdpa, FDP_CONFIG_FDPA_RGIF)(((fdpa) >> NVME_FDP_CONFIG_FDPA_RGIF_SHIFT) & NVME_FDP_CONFIG_FDPA_RGIF_MASK
)
;
991
992 printf(" [7:7] : %#x\tFDP Configuration %sValid\n",
993 valid, valid ? "" : "Not ");
994 if (rsvd)
995 printf(" [6:5] : %#x\tReserved\n", rsvd);
996 printf(" [4:4] : %#x\tFDP Volatile Write Cache %sPresent\n",
997 fdpvwc, fdpvwc ? "" : "Not ");
998 printf(" [3:0] : %#x\tReclaim Group Identifier Format\n", rgif);
999}
1000
1001static void stdout_fdp_configs(struct nvme_fdp_config_log *log, size_t len)
1002{
1003 void *p = log->configs;
1004 int human = stdout_print_ops.flags & VERBOSE;
1005 uint16_t n;
1006
1007 n = le16_to_cpu(log->n) + 1;
1008
1009 for (int i = 0; i < n; i++) {
1010 struct nvme_fdp_config_desc *config = p;
1011
1012 printf("FDP Attributes: %#x\n", config->fdpa);
1013 if (human)
1014 stdout_fdp_config_fdpa(config->fdpa);
1015
1016 printf("Vendor Specific Size: %u\n", config->vss);
1017 printf("Number of Reclaim Groups: %"PRIu32"u""\n", le32_to_cpu(config->nrg));
1018 printf("Number of Reclaim Unit Handles: %"PRIu16"u""\n", le16_to_cpu(config->nruh));
1019 printf("Number of Namespaces Supported: %"PRIu32"u""\n", le32_to_cpu(config->nnss));
1020 printf("Reclaim Unit Nominal Size: %"PRIu64"l" "u""\n", le64_to_cpu(config->runs));
1021 printf("Estimated Reclaim Unit Time Limit: %"PRIu32"u""\n", le32_to_cpu(config->erutl));
1022
1023 printf("Reclaim Unit Handle List:\n");
1024 for (int j = 0; j < le16_to_cpu(config->nruh); j++) {
1025 struct nvme_fdp_ruh_desc *ruh = &config->ruhs[j];
1026
1027 printf(" [%d]: %s\n", j, ruh->ruht == NVME_FDP_RUHT_INITIALLY_ISOLATED ? "Initially Isolated" : "Persistently Isolated");
1028 }
1029
1030 p += config->size;
1031 }
1032}
1033
1034static void stdout_fdp_usage(struct nvme_fdp_ruhu_log *log, size_t len)
1035{
1036 uint16_t nruh = le16_to_cpu(log->nruh);
1037
1038 for (int i = 0; i < nruh; i++) {
1039 struct nvme_fdp_ruhu_desc *ruhu = &log->ruhus[i];
1040
1041 printf("Reclaim Unit Handle %d Attributes: %#"PRIx8"x"" (%s)\n", i, ruhu->ruha,
1042 ruhu->ruha == 0x0 ? "Unused" : (
1043 ruhu->ruha == 0x1 ? "Host Specified" : (
1044 ruhu->ruha == 0x2 ? "Controller Specified" : "Unknown")));
1045 }
1046}
1047
1048static void stdout_fdp_stats(struct nvme_fdp_stats_log *log)
1049{
1050 printf("Host Bytes with Metadata Written (HBMW): %s\n",
1051 uint128_t_to_l10n_string(le128_to_cpu(log->hbmw)));
1052 printf("Media Bytes with Metadata Written (MBMW): %s\n",
1053 uint128_t_to_l10n_string(le128_to_cpu(log->mbmw)));
1054 printf("Media Bytes Erased (MBE): %s\n",
1055 uint128_t_to_l10n_string(le128_to_cpu(log->mbe)));
1056}
1057
1058static void stdout_fdp_events(struct nvme_fdp_events_log *log)
1059{
1060 struct tm *tm;
1061 char buffer[320];
1062 time_t ts;
1063 uint32_t n = le32_to_cpu(log->n);
1064
1065 for (unsigned int i = 0; i < n; i++) {
1066 struct nvme_fdp_event *event = &log->events[i];
1067
1068 ts = int48_to_long(event->ts.timestamp) / 1000;
1069 tm = localtime(&ts);
1070
1071 printf("Event[%u]\n", i);
1072 printf(" Event Type: %#"PRIx8"x"" (%s)\n", event->type,
1073 nvme_fdp_event_to_string(event->type));
1074 printf(" Event Timestamp: %"PRIu64"l" "u"" (%s)\n", int48_to_long(event->ts.timestamp),
1075 strftime(buffer, sizeof(buffer), "%c %Z", tm) ? buffer : "-");
1076
1077 if (event->flags & NVME_FDP_EVENT_F_PIV)
1078 printf(" Placement Identifier (PID): %#"PRIx16"x""\n",
1079 le16_to_cpu(event->pid));
1080
1081 if (event->flags & NVME_FDP_EVENT_F_NSIDV)
1082 printf(" Namespace Identifier (NSID): %"PRIu32"u""\n", le32_to_cpu(event->nsid));
1083
1084 if (event->type == NVME_FDP_EVENT_REALLOC) {
1085 struct nvme_fdp_event_realloc *mr;
1086
1087 mr = (struct nvme_fdp_event_realloc *)&event->type_specific;
1088
1089 printf(" Number of LBAs Moved (NLBAM): %"PRIu16"u""\n", le16_to_cpu(mr->nlbam));
1090
1091 if (mr->flags & NVME_FDP_EVENT_REALLOC_F_LBAV)
1092 printf(" Logical Block Address (LBA): %#"PRIx64"l" "x""\n",
1093 le64_to_cpu(mr->lba));
1094 }
1095
1096 if (event->flags & NVME_FDP_EVENT_F_LV) {
1097 printf(" Reclaim Group Identifier: %"PRIu16"u""\n", le16_to_cpu(event->rgid));
1098 printf(" Reclaim Unit Handle Identifier %"PRIu8"u""\n", event->ruhid);
1099 }
1100
1101 printf("\n");
1102 }
1103}
1104
1105static void stdout_fdp_ruh_status(struct nvme_fdp_ruh_status *status, size_t len)
1106{
1107 uint16_t nruhsd = le16_to_cpu(status->nruhsd);
1108
1109 for (unsigned int i = 0; i < nruhsd; i++) {
1110 struct nvme_fdp_ruh_status_desc *ruhs = &status->ruhss[i];
1111
1112 printf("Placement Identifier %"PRIu16"u""; Reclaim Unit Handle Identifier %"PRIu16"u""\n",
1113 le16_to_cpu(ruhs->pid), le16_to_cpu(ruhs->ruhid));
1114 printf(" Estimated Active Reclaim Unit Time Remaining (EARUTR): %"PRIu32"u""\n",
1115 le32_to_cpu(ruhs->earutr));
1116 printf(" Reclaim Unit Available Media Writes (RUAMW): %"PRIu64"l" "u""\n",
1117 le64_to_cpu(ruhs->ruamw));
1118
1119 printf("\n");
1120 }
1121}
1122
1123static void stdout_supported_cap_config_log(struct nvme_supported_cap_config_list_log *cap)
1124{
1125 struct nvme_end_grp_chan_desc *chan_desc;
1126 int i, j, k, l, m, sccn, egcn, egsets, egchans, chmus;
1127
1128 sccn = cap->sccn;
1129 printf("Number of Supported Capacity Configurations: %u\n", sccn);
1130 for (i = 0; i < sccn; i++) {
1131 printf("Capacity Configuration Descriptor: %u\n", i);
1132 printf("Capacity Configuration Identifier: %u\n",
1133 le16_to_cpu(cap->cap_config_desc[i].cap_config_id));
1134 printf("Domain Identifier: %u\n",
1135 le16_to_cpu(cap->cap_config_desc[i].domainid));
1136 egcn = le16_to_cpu(cap->cap_config_desc[i].egcn);
1137 printf("Number of Endurance Group Configuration Descriptors: %u\n", egcn);
1138 for (j = 0; j < egcn; j++) {
1139 printf("Endurance Group Identifier: %u\n",
1140 le16_to_cpu(cap->cap_config_desc[i].egcd[j].endgid));
1141 printf("Capacity Adjustment Factor: %u\n",
1142 le16_to_cpu(cap->cap_config_desc[i].egcd[j].cap_adj_factor));
1143 printf("Total Endurance Group Capacity: %s\n",
1144 uint128_t_to_l10n_string(le128_to_cpu(
1145 cap->cap_config_desc[i].egcd[j].tegcap)));
1146 printf("Spare Endurance Group Capacity: %s\n",
1147 uint128_t_to_l10n_string(le128_to_cpu(
1148 cap->cap_config_desc[i].egcd[j].segcap)));
1149 printf("Endurance Estimate: %s\n",
1150 uint128_t_to_l10n_string(le128_to_cpu(
1151 cap->cap_config_desc[i].egcd[j].end_est)));
1152 egsets = le16_to_cpu(cap->cap_config_desc[i].egcd[j].egsets);
1153 printf("Number of NVM Sets: %u\n", egsets);
1154 for (k = 0; k < egsets; k++)
1155 printf("NVM Set %d Identifier: %u\n", i,
1156 le16_to_cpu(cap->cap_config_desc[i].egcd[j].nvmsetid[k]));
1157
1158 chan_desc = (struct nvme_end_grp_chan_desc *)
1159 &cap->cap_config_desc[i].egcd[j].nvmsetid[egsets];
1160 egchans = le16_to_cpu(chan_desc->egchans);
1161 printf("Number of Channels: %u\n", egchans);
1162 for (l = 0; l < egchans; l++) {
1163 printf("Channel Identifier: %u\n",
1164 le16_to_cpu(chan_desc->chan_config_desc[l].chanid));
1165 chmus = le16_to_cpu(chan_desc->chan_config_desc[l].chmus);
1166 printf("Number of Channel Media Units: %u\n", chmus);
1167 for (m = 0; m < chmus; m++) {
1168 printf("Media Unit Identifier: %u\n",
1169 le16_to_cpu(chan_desc->chan_config_desc[l].mu_config_desc[m].muid));
1170 printf("Media Unit Descriptor Length: %u\n",
1171 le16_to_cpu(chan_desc->chan_config_desc[l].mu_config_desc[m].mudl));
1172 }
1173 }
1174 }
1175 }
1176}
1177
1178static unsigned int stdout_subsystem_multipath(libnvme_subsystem_t s)
1179{
1180 libnvme_ns_t n;
1181 libnvme_path_t p;
1182 unsigned int i = 0;
1183
1184 n = libnvme_subsystem_first_ns(s);
1185 if (!n)
1186 return 0;
1187
1188 libnvme_namespace_for_each_path(n, p)for (p = libnvme_namespace_first_path(n); p != ((void*)0); p =
libnvme_namespace_next_path(n, p))
{
1189 libnvme_ctrl_t c = libnvme_path_get_ctrl(p);
1190 const char *ana_state = ana_state = libnvme_path_get_ana_state(p);
Although the value stored to 'ana_state' is used in the enclosing expression, the value is never actually read from 'ana_state'
1191
1192 printf(" +- %s %s %s %s %s\n",
1193 libnvme_ctrl_get_name(c),
1194 libnvme_ctrl_get_transport(c),
1195 libnvme_ctrl_get_traddr(c),
1196 libnvme_ctrl_get_state(c),
1197 ana_state);
1198 i++;
1199 }
1200
1201 return i;
1202}
1203
1204static void stdout_subsystem_ctrls(libnvme_subsystem_t s)
1205{
1206 libnvme_ctrl_t c;
1207
1208 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
1209 printf(" +- %s %s %s %s\n",
1210 libnvme_ctrl_get_name(c),
1211 libnvme_ctrl_get_transport(c),
1212 libnvme_ctrl_get_traddr(c),
1213 libnvme_ctrl_get_state(c));
1214 }
1215}
1216
1217static void stdout_subsys_config(libnvme_subsystem_t s, bool_Bool show_iopolicy)
1218{
1219 int len = strlen(libnvme_subsystem_get_name(s));
1220
1221 printf("%s - NQN=%s\n", libnvme_subsystem_get_name(s),
1222 libnvme_subsystem_get_subsysnqn(s));
1223 printf("%*s hostnqn=%s\n", len, " ",
1224 libnvme_host_get_hostnqn(libnvme_subsystem_get_host(s)));
1225 if (show_iopolicy)
1226 printf("%*s iopolicy=%s\n", len, " ",
1227 libnvme_subsystem_get_iopolicy(s));
1228
1229 if (stdout_print_ops.flags & VERBOSE) {
1230 printf("%*s model=%s\n", len, " ",
1231 libnvme_subsystem_get_model(s));
1232 printf("%*s serial=%s\n", len, " ",
1233 libnvme_subsystem_get_serial(s));
1234 printf("%*s firmware=%s\n", len, " ",
1235 libnvme_subsystem_get_firmware(s));
1236 printf("%*s type=%s\n", len, " ",
1237 libnvme_subsystem_get_subsystype(s));
1238 }
1239}
1240
1241static void stdout_subsystem(struct libnvme_global_ctx *ctx, bool_Bool show_ana)
1242{
1243 libnvme_host_t h;
1244 bool_Bool first = true1;
1245
1246 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
{
1247 libnvme_subsystem_t s;
1248
1249 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
{
1250 bool_Bool no_ctrl = true1;
1251 libnvme_ctrl_t c;
1252
1253 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
1254 no_ctrl = false0;
1255 if (no_ctrl)
1256 continue;
1257
1258 if (!first)
1259 printf("\n");
1260 first = false0;
1261
1262 stdout_subsys_config(s,
1263 stdout_print_ops.flags & VERBOSE);
1264 printf("\\\n");
1265
1266 if (!show_ana || !stdout_subsystem_multipath(s))
1267 stdout_subsystem_ctrls(s);
1268 }
1269 }
1270}
1271
1272static void stdout_subsystem_list(struct libnvme_global_ctx *ctx, bool_Bool show_ana)
1273{
1274 stdout_subsystem(ctx, show_ana);
1275}
1276
1277static void stdout_registers_cap(struct nvme_bar_cap *cap)
1278{
1279 printf("\tNVM Subsystem Shutdown Enhancements Supported (NSSES) : %s\n",
1280 cap->nsses ? "Supported" : "Not Supported");
1281 printf("\tController Ready With Media Support (CRWMS) : %s\n",
1282 cap->crwms ? "Supported" : "Not Supported");
1283 printf("\tController Ready Independent of Media Support (CRIMS) : %s\n",
1284 cap->crims ? "Supported" : "Not Supported");
1285 printf("\tNVM Subsystem Shutdown Supported (NSSS) : %s\n", cap->nsss ? "Supported" : "Not Supported");
1286 printf("\tController Memory Buffer Supported (CMBS) : The Controller Memory Buffer is %s\n",
1287 cap->cmbs ? "Supported" : "Not Supported");
1288 printf("\tPersistent Memory Region Supported (PMRS) : The Persistent Memory Region is %s\n",
1289 cap->pmrs ? "Supported" : "Not Supported");
1290 printf("\tMemory Page Size Maximum (MPSMAX) : %u bytes\n", 1 << (12 + cap->mpsmax));
1291 printf("\tMemory Page Size Minimum (MPSMIN) : %u bytes\n", 1 << (12 + cap->mpsmin));
1292 printf("\tController Power Scope (CPS) : %s\n",
1293 !cap->cps ? "Not Reported" : cap->cps == 1 ? "Controller scope" :
1294 cap->cps == 2 ? "Domain scope" : "NVM subsystem scope");
1295 printf("\tBoot Partition Support (BPS) : %s\n", cap->bps ? "Yes" : "No");
1296 printf("\tCommand Sets Supported (CSS) : NVM command set is %s\n",
1297 cap->css & 0x01 ? "Supported" : "Not Supported");
1298 printf("\t One or more I/O Command Sets are %s\n",
1299 cap->css & 0x40 ? "Supported" : "Not Supported");
1300 printf("\t %s\n",
1301 cap->css & 0x80 ? "Only Admin Command Set Supported" : "I/O Command Set is Supported");
1302 printf("\tNVM Subsystem Reset Supported (NSSRS) : %s\n", cap->nssrs ? "Yes" : "No");
1303 printf("\tDoorbell Stride (DSTRD) : %u bytes\n", 1 << (2 + cap->dstrd));
1304 printf("\tTimeout (TO) : %u ms\n", cap->to * 500);
1305 printf("\tArbitration Mechanism Supported (AMS) : Weighted Round Robin with Urgent Priority Class is %s\n",
1306 cap->ams & 0x01 ? "Supported" : "Not supported");
1307 printf("\tContiguous Queues Required (CQR) : %s\n", cap->cqr ? "Yes" : "No");
1308 printf("\tMaximum Queue Entries Supported (MQES) : %u\n\n", cap->mqes + 1);
1309}
1310
1311static void stdout_registers_version(__u32 vs)
1312{
1313 printf("\tNVMe specification %d.%d.%d\n\n", NVME_MAJOR(vs)(((vs) >> NVME_VS_MJR_SHIFT) & NVME_VS_MJR_MASK), NVME_MINOR(vs)(((vs) >> NVME_VS_MNR_SHIFT) & NVME_VS_MNR_MASK),
1314 NVME_TERTIARY(vs)(((vs) >> NVME_VS_TER_SHIFT) & NVME_VS_TER_MASK));
1315}
1316
1317static void stdout_registers_cc_ams(__u8 ams)
1318{
1319 printf("\tArbitration Mechanism Selected (AMS) : ");
1320 switch (ams) {
1321 case NVME_CC_AMS_RR:
1322 printf("Round Robin\n");
1323 break;
1324 case NVME_CC_AMS_WRRU:
1325 printf("Weighted Round Robin with Urgent Priority Class\n");
1326 break;
1327 case NVME_CC_AMS_VS:
1328 printf("Vendor Specific\n");
1329 break;
1330 default:
1331 printf("Reserved\n");
1332 break;
1333 }
1334}
1335
1336static void stdout_registers_cc_shn(__u8 shn)
1337{
1338 printf("\tShutdown Notification (SHN) : ");
1339 switch (shn) {
1340 case NVME_CC_SHN_NONE:
1341 printf("No notification; no effect\n");
1342 break;
1343 case NVME_CC_SHN_NORMAL:
1344 printf("Normal shutdown notification\n");
1345 break;
1346 case NVME_CC_SHN_ABRUPT:
1347 printf("Abrupt shutdown notification\n");
1348 break;
1349 default:
1350 printf("Reserved\n");
1351 break;
1352 }
1353}
1354
1355static void stdout_registers_cc(__u32 cc)
1356{
1357 printf("\tController Ready Independent of Media Enable (CRIME) : %s\n",
1358 NVME_CC_CRIME(cc)(((cc) >> NVME_CC_CRIME_SHIFT) & NVME_CC_CRIME_MASK
)
? "Enabled" : "Disabled");
1359
1360 printf("\tI/O Completion Queue Entry Size (IOCQES) : %u bytes\n",
1361 POWER_OF_TWO(NVME_CC_IOCQES(cc))(1 << ((((cc) >> NVME_CC_IOCQES_SHIFT) & NVME_CC_IOCQES_MASK
)))
);
1362 printf("\tI/O Submission Queue Entry Size (IOSQES) : %u bytes\n",
1363 POWER_OF_TWO(NVME_CC_IOSQES(cc))(1 << ((((cc) >> NVME_CC_IOSQES_SHIFT) & NVME_CC_IOSQES_MASK
)))
);
1364 stdout_registers_cc_shn(NVME_CC_SHN(cc)(((cc) >> NVME_CC_SHN_SHIFT) & NVME_CC_SHN_MASK));
1365 stdout_registers_cc_ams(NVME_CC_AMS(cc)(((cc) >> NVME_CC_AMS_SHIFT) & NVME_CC_AMS_MASK));
1366 printf("\tMemory Page Size (MPS) : %u bytes\n",
1367 POWER_OF_TWO(12 + NVME_CC_MPS(cc))(1 << (12 + (((cc) >> NVME_CC_MPS_SHIFT) & NVME_CC_MPS_MASK
)))
);
1368 printf("\tI/O Command Set Selected (CSS) : %s\n",
1369 NVME_CC_CSS(cc)(((cc) >> NVME_CC_CSS_SHIFT) & NVME_CC_CSS_MASK) == NVME_CC_CSS_NVM ? "NVM Command Set" :
1370 NVME_CC_CSS(cc)(((cc) >> NVME_CC_CSS_SHIFT) & NVME_CC_CSS_MASK) == NVME_CC_CSS_CSI ? "All supported I/O Command Sets" :
1371 NVME_CC_CSS(cc)(((cc) >> NVME_CC_CSS_SHIFT) & NVME_CC_CSS_MASK) == NVME_CC_CSS_ADMIN ? "Admin Command Set only" : "Reserved");
1372 printf("\tEnable (EN) : %s\n\n", NVME_CC_EN(cc)(((cc) >> NVME_CC_EN_SHIFT) & NVME_CC_EN_MASK) ? "Yes" : "No");
1373}
1374
1375static void stdout_registers_csts_shst(__u8 shst)
1376{
1377 printf("\tShutdown Status (SHST): ");
1378 switch (shst) {
1379 case NVME_CSTS_SHST_NORMAL:
1380 printf("Normal operation (no shutdown has been requested)\n");
1381 break;
1382 case NVME_CSTS_SHST_OCCUR:
1383 printf("Shutdown processing occurring\n");
1384 break;
1385 case NVME_CSTS_SHST_CMPLT:
1386 printf("Shutdown processing complete\n");
1387 break;
1388 default:
1389 printf("Reserved\n");
1390 break;
1391 }
1392}
1393
1394static void stdout_registers_csts(__u32 csts)
1395{
1396 printf("\tShutdown Type (ST): %s\n",
1397 NVME_CSTS_ST(csts)(((csts) >> NVME_CSTS_ST_SHIFT) & NVME_CSTS_ST_MASK
)
? "Subsystem" : "Controller");
1398 printf("\tProcessing Paused (PP): %s\n", NVME_CSTS_PP(csts)(((csts) >> NVME_CSTS_PP_SHIFT) & NVME_CSTS_PP_MASK
)
? "Yes" : "No");
1399 printf("\tNVM Subsystem Reset Occurred (NSSRO): %s\n",
1400 NVME_CSTS_NSSRO(csts)(((csts) >> NVME_CSTS_NSSRO_SHIFT) & NVME_CSTS_NSSRO_MASK
)
? "Yes" : "No");
1401 stdout_registers_csts_shst(NVME_CSTS_SHST(csts)(((csts) >> NVME_CSTS_SHST_SHIFT) & NVME_CSTS_SHST_MASK
)
);
1402 printf("\tController Fatal Status (CFS): %s\n",
1403 NVME_CSTS_CFS(csts)(((csts) >> NVME_CSTS_CFS_SHIFT) & NVME_CSTS_CFS_MASK
)
? "True" : "False");
1404 printf("\tReady (RDY): %s\n\n",
1405 NVME_CSTS_RDY(csts)(((csts) >> NVME_CSTS_RDY_SHIFT) & NVME_CSTS_RDY_MASK
)
? "Yes" : "No");
1406}
1407
1408static void stdout_registers_nssd(__u32 nssd)
1409{
1410 printf("\tNVM Subsystem Shutdown Control (NSSC): %#x\n\n", nssd);
1411}
1412
1413static void stdout_registers_crto(__u32 crto)
1414{
1415 printf("\tCRIMT : %d secs\n", NVME_CRTO_CRIMT(crto)(((crto) >> NVME_CRTO_CRIMT_SHIFT) & NVME_CRTO_CRIMT_MASK
)
/ 2);
1416 printf("\tCRWMT : %d secs\n", NVME_CRTO_CRWMT(crto)(((crto) >> NVME_CRTO_CRWMT_SHIFT) & NVME_CRTO_CRWMT_MASK
)
/ 2);
1417}
1418
1419static void stdout_registers_aqa(__u32 aqa)
1420{
1421 printf("\tAdmin Completion Queue Size (ACQS): %u\n", NVME_AQA_ACQS(aqa)(((aqa) >> NVME_AQA_ACQS_SHIFT) & NVME_AQA_ACQS_MASK
)
+ 1);
1422 printf("\tAdmin Submission Queue Size (ASQS): %u\n\n", NVME_AQA_ASQS(aqa)(((aqa) >> NVME_AQA_ASQS_SHIFT) & NVME_AQA_ASQS_MASK
)
+ 1);
1423}
1424
1425static void stdout_registers_asq(uint64_t asq)
1426{
1427 printf("\tAdmin Submission Queue Base (ASQB): %"PRIx64"l" "x""\n", (uint64_t)NVME_ASQ_ASQB(asq)(((asq) >> NVME_ASQ_ASQB_SHIFT) & NVME_ASQ_ASQB_MASK
)
);
1428}
1429
1430static void stdout_registers_acq(uint64_t acq)
1431{
1432 printf("\tAdmin Completion Queue Base (ACQB): %"PRIx64"l" "x""\n", (uint64_t)NVME_ACQ_ACQB(acq)(((acq) >> NVME_ACQ_ACQB_SHIFT) & NVME_ACQ_ACQB_MASK
)
);
1433}
1434
1435static void stdout_registers_cmbloc(__u32 cmbloc, bool_Bool support)
1436{
1437 static const char * const enforced[] = { "Enforced", "Not Enforced" };
1438
1439 if (!support) {
1440 printf("\tController Memory Buffer feature is not supported\n\n");
1441 return;
1442 }
1443
1444 printf("\tOffset (OFST): ");
1445 printf("%#x (See cmbsz.szu for granularity)\n", NVME_CMBLOC_OFST(cmbloc)(((cmbloc) >> NVME_CMBLOC_OFST_SHIFT) & NVME_CMBLOC_OFST_MASK
)
);
1446
1447 printf("\tCMB Queue Dword Alignment (CQDA): %d\n",
1448 NVME_CMBLOC_CQDA(cmbloc)(((cmbloc) >> NVME_CMBLOC_CQDA_SHIFT) & NVME_CMBLOC_CQDA_MASK
)
);
1449
1450 printf("\tCMB Data Metadata Mixed Memory Support (CDMMMS): %s\n",
1451 enforced[NVME_CMBLOC_CDMMMS(cmbloc)(((cmbloc) >> NVME_CMBLOC_CDMMMS_SHIFT) & NVME_CMBLOC_CDMMMS_MASK
)
]);
1452
1453 printf("\tCMB Data Pointer and Command Independent Locations Support (CDPCILS): %s\n",
1454 enforced[NVME_CMBLOC_CDPCILS(cmbloc)(((cmbloc) >> NVME_CMBLOC_CDPCILS_SHIFT) & NVME_CMBLOC_CDPCILS_MASK
)
]);
1455
1456 printf("\tCMB Data Pointer Mixed Locations Support (CDPMLS): %s\n",
1457 enforced[NVME_CMBLOC_CDPLMS(cmbloc)(((cmbloc) >> NVME_CMBLOC_CDPLMS_SHIFT) & NVME_CMBLOC_CDPLMS_MASK
)
]);
1458
1459 printf("\tCMB Queue Physically Discontiguous Support (CQPDS): %s\n",
1460 enforced[NVME_CMBLOC_CQPDS(cmbloc)(((cmbloc) >> NVME_CMBLOC_CQPDS_SHIFT) & NVME_CMBLOC_CQPDS_MASK
)
]);
1461
1462 printf("\tCMB Queue Mixed Memory Support (CQMMS): %s\n",
1463 enforced[NVME_CMBLOC_CQMMS(cmbloc)(((cmbloc) >> NVME_CMBLOC_CQMMS_SHIFT) & NVME_CMBLOC_CQMMS_MASK
)
]);
1464
1465 printf("\tBase Indicator Register (BIR): %#x\n\n",
1466 NVME_CMBLOC_BIR(cmbloc)(((cmbloc) >> NVME_CMBLOC_BIR_SHIFT) & NVME_CMBLOC_BIR_MASK
)
);
1467}
1468
1469static void stdout_registers_cmbsz(__u32 cmbsz)
1470{
1471 if (!cmbsz) {
1472 printf("\tController Memory Buffer feature is not supported\n\n");
1473 return;
1474 }
1475
1476 printf("\tSize (SZ): %u\n", NVME_CMBSZ_SZ(cmbsz)(((cmbsz) >> NVME_CMBSZ_SZ_SHIFT) & NVME_CMBSZ_SZ_MASK
)
);
1477 printf("\tSize Units (SZU): %s\n",
1478 nvme_register_szu_to_string(NVME_CMBSZ_SZU(cmbsz)(((cmbsz) >> NVME_CMBSZ_SZU_SHIFT) & NVME_CMBSZ_SZU_MASK
)
));
1479 printf("\tWrite Data Support (WDS): Write Data and metadata transfer in Controller Memory Buffer is %s\n",
1480 NVME_CMBSZ_WDS(cmbsz)(((cmbsz) >> NVME_CMBSZ_WDS_SHIFT) & NVME_CMBSZ_WDS_MASK
)
? "Supported" : "Not supported");
1481 printf("\tRead Data Support (RDS): Read Data and metadata transfer in Controller Memory Buffer is %s\n",
1482 NVME_CMBSZ_RDS(cmbsz)(((cmbsz) >> NVME_CMBSZ_RDS_SHIFT) & NVME_CMBSZ_RDS_MASK
)
? "Supported" : "Not supported");
1483 printf("\tPRP SGL List Support (LISTS): PRP/SG Lists in Controller Memory Buffer is %s\n",
1484 NVME_CMBSZ_LISTS(cmbsz)(((cmbsz) >> NVME_CMBSZ_LISTS_SHIFT) & NVME_CMBSZ_LISTS_MASK
)
? "Supported" : "Not supported");
1485 printf("\tCompletion Queue Support (CQS): Admin and I/O Completion Queues in Controller Memory Buffer is %s\n",
1486 NVME_CMBSZ_CQS(cmbsz)(((cmbsz) >> NVME_CMBSZ_CQS_SHIFT) & NVME_CMBSZ_CQS_MASK
)
? "Supported" : "Not supported");
1487 printf("\tSubmission Queue Support (SQS): Admin and I/O Submission Queues in Controller Memory Buffer is %s\n\n",
1488 NVME_CMBSZ_SQS(cmbsz)(((cmbsz) >> NVME_CMBSZ_SQS_SHIFT) & NVME_CMBSZ_SQS_MASK
)
? "Supported" : "Not supported");
1489}
1490
1491static void stdout_registers_bpinfo_brs(__u8 brs)
1492{
1493 printf("\tBoot Read Status (BRS): ");
1494 switch (brs) {
1495 case 0:
1496 printf("No Boot Partition read operation requested\n");
1497 break;
1498 case 1:
1499 printf("Boot Partition read in progress\n");
1500 break;
1501 case 2:
1502 printf("Boot Partition read completed successfully\n");
1503 break;
1504 case 3:
1505 printf("Error completing Boot Partition read\n");
1506 break;
1507 default:
1508 printf("Invalid\n");
1509 break;
1510 }
1511}
1512
1513static void stdout_registers_bpinfo(__u32 bpinfo)
1514{
1515 printf("\tActive Boot Partition ID (ABPID): %u\n", NVME_BPINFO_ABPID(bpinfo)(((bpinfo) >> NVME_BPINFO_ABPID_SHIFT) & NVME_BPINFO_ABPID_MASK
)
);
1516 stdout_registers_bpinfo_brs(NVME_BPINFO_BRS(bpinfo)(((bpinfo) >> NVME_BPINFO_BRS_SHIFT) & NVME_BPINFO_BRS_MASK
)
);
1517 printf("\tBoot Partition Size (BPSZ): %u\n", NVME_BPINFO_BPSZ(bpinfo)(((bpinfo) >> NVME_BPINFO_BPSZ_SHIFT) & NVME_BPINFO_BPSZ_MASK
)
);
1518}
1519
1520static void stdout_registers_bprsel(__u32 bprsel)
1521{
1522 printf("\tBoot Partition Identifier (BPID): %u\n", NVME_BPRSEL_BPID(bprsel)(((bprsel) >> NVME_BPRSEL_BPID_SHIFT) & NVME_BPRSEL_BPID_MASK
)
);
1523 printf("\tBoot Partition Read Offset (BPROF): %x\n", NVME_BPRSEL_BPROF(bprsel)(((bprsel) >> NVME_BPRSEL_BPROF_SHIFT) & NVME_BPRSEL_BPROF_MASK
)
);
1524 printf("\tBoot Partition Read Size (BPRSZ): %x\n", NVME_BPRSEL_BPRSZ(bprsel)(((bprsel) >> NVME_BPRSEL_BPRSZ_SHIFT) & NVME_BPRSEL_BPRSZ_MASK
)
);
1525}
1526
1527static void stdout_registers_bpmbl(uint64_t bpmbl)
1528{
1529 printf("\tBoot Partition Memory Buffer Base Address (BMBBA): %"PRIx64"l" "x""\n",
1530 (uint64_t)NVME_BPMBL_BMBBA(bpmbl)(((bpmbl) >> NVME_BPMBL_BMBBA_SHIFT) & NVME_BPMBL_BMBBA_MASK
)
);
1531}
1532
1533static void stdout_registers_cmbmsc(uint64_t cmbmsc)
1534{
1535 printf("\tController Base Address (CBA): %" PRIx64"l" "x" "\n",
1536 (uint64_t)NVME_CMBMSC_CBA(cmbmsc)(((cmbmsc) >> NVME_CMBMSC_CBA_SHIFT) & NVME_CMBMSC_CBA_MASK
)
);
1537 printf("\tController Memory Space Enable (CMSE): %" PRIx64"l" "x" "\n", NVME_CMBMSC_CMSE(cmbmsc)(((cmbmsc) >> NVME_CMBMSC_CMSE_SHIFT) & NVME_CMBMSC_CMSE_MASK
)
);
1538 printf("\tCapabilities Registers Enabled (CRE): ");
1539 printf("CMBLOC and CMBSZ registers are %senabled\n\n",
1540 NVME_CMBMSC_CRE(cmbmsc)(((cmbmsc) >> NVME_CMBMSC_CRE_SHIFT) & NVME_CMBMSC_CRE_MASK
)
? "" : "NOT ");
1541}
1542
1543static void stdout_registers_cmbsts(__u32 cmbsts)
1544{
1545 printf("\tController Base Address Invalid (CBAI): %x\n\n", NVME_CMBSTS_CBAI(cmbsts)(((cmbsts) >> NVME_CMBSTS_CBAI_SHIFT) & NVME_CMBSTS_CBAI_MASK
)
);
1546}
1547
1548static void stdout_registers_cmbebs(__u32 cmbebs)
1549{
1550 printf("\tCMB Elasticity Buffer Size Base (CMBWBZ): %#x\n", NVME_CMBEBS_CMBWBZ(cmbebs)(((cmbebs) >> NVME_CMBEBS_CMBWBZ_SHIFT) & NVME_CMBEBS_CMBWBZ_MASK
)
);
1551 printf("\tRead Bypass Behavior : ");
1552 printf("memory reads not conflicting with memory writes in the CMB Elasticity Buffer ");
1553 printf("%s bypass those memory writes\n", NVME_CMBEBS_RBB(cmbebs)(((cmbebs) >> NVME_CMBEBS_RBB_SHIFT) & NVME_CMBEBS_RBB_MASK
)
? "SHALL" : "MAY");
1554 printf("\tCMB Elasticity Buffer Size Units (CMBSZU): %s\n\n",
1555 nvme_register_unit_to_string(NVME_CMBEBS_CMBSZU(cmbebs)(((cmbebs) >> NVME_CMBEBS_CMBSZU_SHIFT) & NVME_CMBEBS_CMBSZU_MASK
)
));
1556}
1557
1558static void stdout_registers_cmbswtp(__u32 cmbswtp)
1559{
1560 printf("\tCMB Sustained Write Throughput (CMBSWTV): %#x\n",
1561 NVME_CMBSWTP_CMBSWTV(cmbswtp)(((cmbswtp) >> NVME_CMBSWTP_CMBSWTV_SHIFT) & NVME_CMBSWTP_CMBSWTV_MASK
)
);
1562 printf("\tCMB Sustained Write Throughput Units (CMBSWTU): %s/second\n\n",
1563 nvme_register_unit_to_string(NVME_CMBSWTP_CMBSWTU(cmbswtp)(((cmbswtp) >> NVME_CMBSWTP_CMBSWTU_SHIFT) & NVME_CMBSWTP_CMBSWTU_MASK
)
));
1564}
1565
1566static void stdout_registers_pmrcap(__u32 pmrcap)
1567{
1568 printf("\tController Memory Space Supported (CMSS): ");
1569 printf("Referencing PMR with host supplied addresses is %sSupported\n",
1570 NVME_PMRCAP_CMSS(pmrcap)(((pmrcap) >> NVME_PMRCAP_CMSS_SHIFT) & NVME_PMRCAP_CMSS_MASK
)
? "" : "Not ");
1571 printf("\tPersistent Memory Region Timeout (PMRTO): %x\n",
1572 NVME_PMRCAP_PMRTO(pmrcap)(((pmrcap) >> NVME_PMRCAP_PMRTO_SHIFT) & NVME_PMRCAP_PMRTO_MASK
)
);
1573 printf("\tPersistent Memory Region Write Barrier Mechanisms (PMRWBM): %x\n",
1574 NVME_PMRCAP_PMRWBM(pmrcap)(((pmrcap) >> NVME_PMRCAP_PMRWBM_SHIFT) & NVME_PMRCAP_PMRWBM_MASK
)
);
1575 printf("\tPersistent Memory Region Time Units (PMRTU): ");
1576 printf("PMR time unit is %s\n", NVME_PMRCAP_PMRTU(pmrcap)(((pmrcap) >> NVME_PMRCAP_PMRTU_SHIFT) & NVME_PMRCAP_PMRTU_MASK
)
? "minutes" : "500 milliseconds");
1577 printf("\tBase Indicator Register (BIR): %x\n",
1578 NVME_PMRCAP_BIR(pmrcap)(((pmrcap) >> NVME_PMRCAP_BIR_SHIFT) & NVME_PMRCAP_BIR_MASK
)
);
1579 printf("\tWrite Data Support (WDS): ");
1580 printf("Write data to the PMR is %ssupported\n", NVME_PMRCAP_WDS(pmrcap)(((pmrcap) >> NVME_PMRCAP_WDS_SHIFT) & NVME_PMRCAP_WDS_MASK
)
? "" : "not ");
1581 printf("\tRead Data Support (RDS): ");
1582 printf("Read data from the PMR is %ssupported\n", NVME_PMRCAP_RDS(pmrcap)(((pmrcap) >> NVME_PMRCAP_RDS_SHIFT) & NVME_PMRCAP_RDS_MASK
)
? "" : "not ");
1583}
1584
1585static void stdout_registers_pmrctl(__u32 pmrctl)
1586{
1587 printf("\tEnable (EN): PMR is %s\n", NVME_PMRCTL_EN(pmrctl)(((pmrctl) >> NVME_PMRCTL_EN_SHIFT) & NVME_PMRCTL_EN_MASK
)
? "READY" : "Disabled");
1588}
1589
1590static void stdout_registers_pmrsts(__u32 pmrsts, bool_Bool ready)
1591{
1592 printf("\tController Base Address Invalid (CBAI): %x\n", NVME_PMRSTS_CBAI(pmrsts)(((pmrsts) >> NVME_PMRSTS_CBAI_SHIFT) & NVME_PMRSTS_CBAI_MASK
)
);
1593 printf("\tHealth Status (HSTS): %s\n",
1594 nvme_register_pmr_hsts_to_string(NVME_PMRSTS_HSTS(pmrsts)(((pmrsts) >> NVME_PMRSTS_HSTS_SHIFT) & NVME_PMRSTS_HSTS_MASK
)
));
1595 printf("\tNot Ready (NRDY): ");
1596 printf("The Persistent Memory Region is %s to process ",
1597 !NVME_PMRSTS_NRDY(pmrsts)(((pmrsts) >> NVME_PMRSTS_NRDY_SHIFT) & NVME_PMRSTS_NRDY_MASK
)
&& ready ? "READY" : "Not Ready");
1598 printf("PCI Express memory read and write requests\n");
1599 printf("\tError (ERR): %x\n", NVME_PMRSTS_ERR(pmrsts)(((pmrsts) >> NVME_PMRSTS_ERR_SHIFT) & NVME_PMRSTS_ERR_MASK
)
);
1600}
1601
1602static void stdout_registers_pmrebs(__u32 pmrebs)
1603{
1604 printf("\tPMR Elasticity Buffer Size Base (PMRWBZ): %x\n", NVME_PMREBS_PMRWBZ(pmrebs)(((pmrebs) >> NVME_PMREBS_PMRWBZ_SHIFT) & NVME_PMREBS_PMRWBZ_MASK
)
);
1605 printf("\tRead Bypass Behavior : ");
1606 printf("memory reads not conflicting with memory writes ");
1607 printf("in the PMR Elasticity Buffer %s bypass those memory writes\n",
1608 NVME_PMREBS_RBB(pmrebs)(((pmrebs) >> NVME_PMREBS_RBB_SHIFT) & NVME_PMREBS_RBB_MASK
)
? "SHALL" : "MAY");
1609 printf("\tPMR Elasticity Buffer Size Units (PMRSZU): %s\n",
1610 nvme_register_unit_to_string(NVME_PMREBS_PMRSZU(pmrebs)(((pmrebs) >> NVME_PMREBS_PMRSZU_SHIFT) & NVME_PMREBS_PMRSZU_MASK
)
));
1611}
1612
1613static void stdout_registers_pmrswtp(__u32 pmrswtp)
1614{
1615 printf("\tPMR Sustained Write Throughput (PMRSWTV): %x\n",
1616 NVME_PMRSWTP_PMRSWTV(pmrswtp)(((pmrswtp) >> NVME_PMRSWTP_PMRSWTU_SHIFT) & NVME_PMRSWTP_PMRSWTU_MASK
)
);
1617 printf("\tPMR Sustained Write Throughput Units (PMRSWTU): %s/second\n",
1618 nvme_register_unit_to_string(NVME_PMRSWTP_PMRSWTU(pmrswtp)(((pmrswtp) >> NVME_PMRSWTP_PMRSWTU_SHIFT) & NVME_PMRSWTP_PMRSWTU_MASK
)
));
1619}
1620
1621static void stdout_registers_pmrmscl(uint32_t pmrmscl)
1622{
1623 printf("\tController Base Address (CBA): %#x\n",
1624 (uint32_t)NVME_PMRMSC_CBA(pmrmscl)(((pmrmscl) >> NVME_PMRMSC_CBA_SHIFT) & NVME_PMRMSC_CBA_MASK
)
);
1625 printf("\tController Memory Space Enable (CMSE): %#x\n\n", NVME_PMRMSC_CMSE(pmrmscl)(((pmrmscl) >> NVME_PMRMSC_CMSE_SHIFT) & NVME_PMRMSC_CMSE_MASK
)
);
1626}
1627
1628static void stdout_registers_pmrmscu(uint32_t pmrmscu)
1629{
1630 printf("\tController Base Address (CBA): %#x\n",
1631 pmrmscu);
1632}
1633
1634static void stdout_ctrl_register_human(int offset, uint64_t value, bool_Bool support)
1635{
1636 switch (offset) {
1637 case NVME_REG_CAP:
1638 stdout_registers_cap((struct nvme_bar_cap *)&value);
1639 break;
1640 case NVME_REG_VS:
1641 stdout_registers_version(value);
1642 break;
1643 case NVME_REG_INTMS:
1644 printf("\tInterrupt Vector Mask Set (IVMS): %#"PRIx64"l" "x""\n\n", value);
1645 break;
1646 case NVME_REG_INTMC:
1647 printf("\tInterrupt Vector Mask Clear (IVMC): %#"PRIx64"l" "x""\n\n", value);
1648 break;
1649 case NVME_REG_CC:
1650 stdout_registers_cc(value);
1651 break;
1652 case NVME_REG_CSTS:
1653 stdout_registers_csts(value);
1654 break;
1655 case NVME_REG_NSSR:
1656 printf("\tNVM Subsystem Reset Control (NSSRC): %"PRIu64"l" "u""\n\n", value);
1657 break;
1658 case NVME_REG_AQA:
1659 stdout_registers_aqa(value);
1660 break;
1661 case NVME_REG_ASQ:
1662 stdout_registers_asq(value);
1663 break;
1664 case NVME_REG_ACQ:
1665 stdout_registers_acq(value);
1666 break;
1667 case NVME_REG_CMBLOC:
1668 stdout_registers_cmbloc(value, support);
1669 break;
1670 case NVME_REG_CMBSZ:
1671 stdout_registers_cmbsz(value);
1672 break;
1673 case NVME_REG_BPINFO:
1674 stdout_registers_bpinfo(value);
1675 break;
1676 case NVME_REG_BPRSEL:
1677 stdout_registers_bprsel(value);
1678 break;
1679 case NVME_REG_BPMBL:
1680 stdout_registers_bpmbl(value);
1681 break;
1682 case NVME_REG_CMBMSC:
1683 stdout_registers_cmbmsc(value);
1684 break;
1685 case NVME_REG_CMBSTS:
1686 stdout_registers_cmbsts(value);
1687 break;
1688 case NVME_REG_CMBEBS:
1689 stdout_registers_cmbebs(value);
1690 break;
1691 case NVME_REG_CMBSWTP:
1692 stdout_registers_cmbswtp(value);
1693 break;
1694 case NVME_REG_NSSD:
1695 stdout_registers_nssd(value);
1696 break;
1697 case NVME_REG_CRTO:
1698 stdout_registers_crto(value);
1699 break;
1700 case NVME_REG_PMRCAP:
1701 stdout_registers_pmrcap(value);
1702 break;
1703 case NVME_REG_PMRCTL:
1704 stdout_registers_pmrctl(value);
1705 break;
1706 case NVME_REG_PMRSTS:
1707 stdout_registers_pmrsts(value, support);
1708 break;
1709 case NVME_REG_PMREBS:
1710 stdout_registers_pmrebs(value);
1711 break;
1712 case NVME_REG_PMRSWTP:
1713 stdout_registers_pmrswtp(value);
1714 break;
1715 case NVME_REG_PMRMSCL:
1716 stdout_registers_pmrmscl(value);
1717 break;
1718 case NVME_REG_PMRMSCU:
1719 stdout_registers_pmrmscu(value);
1720 break;
1721 default:
1722 printf("unknown register: %#04x (%s), value: %#"PRIx64"l" "x""\n",
1723 offset, nvme_register_to_string(offset), value);
1724 break;
1725 }
1726}
1727
1728static void stdout_ctrl_register_common(int offset, uint64_t value, bool_Bool fabrics)
1729{
1730 bool_Bool human = !!(stdout_print_ops.flags & VERBOSE);
1731 const char *name = nvme_register_to_string(offset);
1732 const char *type = fabrics ? "property" : "register";
1733
1734 if (human) {
1735 printf("%s: %#"PRIx64"l" "x""\n", name, value);
1736 stdout_ctrl_register_human(offset, value, true1);
1737 return;
1738 }
1739
1740 printf("%s: %#04x (%s), value: %#"PRIx64"l" "x""\n", type, offset,
1741 name, value);
1742}
1743
1744static void stdout_ctrl_register(int offset, uint64_t value)
1745{
1746 stdout_ctrl_register_common(offset, value, false0);
1747}
1748
1749static void stdout_ctrl_register_support(void *bar, bool_Bool fabrics, int offset, bool_Bool human,
1750 bool_Bool support)
1751{
1752 uint64_t value = nvme_is_64bit_reg(offset) ? mmio_read64(bar + offset) :
1753 mmio_read32(bar + offset);
1754
1755 if (fabrics && value == -1)
1756 return;
1757
1758 printf("%-8s: ", nvme_register_symbol_to_string(offset));
1759
1760 printf("%#"PRIx64"l" "x""\n", value);
1761
1762 if (human)
1763 stdout_ctrl_register_human(offset, value, support);
1764}
1765
1766void stdout_ctrl_registers(void *bar, bool_Bool fabrics)
1767{
1768 uint32_t value;
1769 bool_Bool human = !!(stdout_print_ops.flags & VERBOSE);
1770 int offset;
1771 bool_Bool support;
1772
1773 for (offset = NVME_REG_CAP; offset <= NVME_REG_PMRMSCU; offset += get_reg_size(offset)) {
1774 if (!nvme_is_ctrl_reg(offset) || (fabrics && !nvme_is_fabrics_reg(offset)))
1775 continue;
1776 switch (offset) {
1777 case NVME_REG_CMBLOC:
1778 value = mmio_read32(bar + NVME_REG_CMBSZ);
1779 support = nvme_registers_cmbloc_support(value);
1780 break;
1781 case NVME_REG_PMRSTS:
1782 value = mmio_read32(bar + NVME_REG_PMRCTL);
1783 support = nvme_registers_pmrctl_ready(value);
1784 break;
1785 default:
1786 support = true1;
1787 break;
1788 }
1789 stdout_ctrl_register_support(bar, fabrics, offset, human, support);
1790 }
1791}
1792
1793static void stdout_single_property(int offset, uint64_t value)
1794{
1795 stdout_ctrl_register_common(offset, value, true1);
1796}
1797
1798static void stdout_status(int status)
1799{
1800 int val;
1801 int type;
1802
1803 /*
1804 * Callers should be checking for negative values first, but provide a
1805 * sensible fallback anyway
1806 */
1807 if (status < 0) {
1808 fprintf(stderrstderr, "Error: %s\n", libnvme_strerror(errno(*__errno_location ())));
1809 return;
1810 }
1811
1812 val = nvme_status_get_value(status);
1813 type = nvme_status_get_type(status);
1814
1815 switch (type) {
1816 case NVME_STATUS_TYPE_NVME:
1817 fprintf(stderrstderr, "NVMe status: %s(%#x)\n",
1818 libnvme_status_to_string(val, false0), val);
1819 break;
1820#ifdef CONFIG_MI
1821 case NVME_STATUS_TYPE_MI:
1822 fprintf(stderrstderr, "NVMe-MI status: %s(%#x)\n",
1823 libnvme_mi_status_to_string(val), val);
1824 break;
1825#endif
1826 default:
1827 fprintf(stderrstderr, "Unknown status type %d, value %#x\n", type,
1828 val);
1829 break;
1830 }
1831}
1832
1833static void stdout_opcode_status(int status, bool_Bool admin, __u8 opcode)
1834{
1835 int val = nvme_status_get_value(status);
1836 int type = nvme_status_get_type(status);
1837
1838 if (status >= 0 && type == NVME_STATUS_TYPE_NVME) {
1839 fprintf(stderrstderr, "NVMe status: %s(0x%x)\n",
1840 libnvme_opcode_status_to_string(val, admin, opcode), val);
1841 return;
1842 }
1843
1844 stdout_status(status);
1845}
1846
1847static void stdout_error_status(int status, const char *msg, va_list ap)
1848{
1849 vfprintf(stderrstderr, msg, ap);
1850 fprintf(stderrstderr, ": ");
1851 stdout_status(status);
1852}
1853
1854static void stdout_id_ctrl_cmic(__u8 cmic)
1855{
1856 __u8 rsvd = NVME_CMIC_MULTI_RSVD(cmic)(((cmic) >> NVME_CMIC_MULTI_RSVD_SHIFT) & NVME_CMIC_MULTI_RSVD_MASK
)
;
1857 __u8 ana = NVME_CMIC_MULTI_ANA(cmic)(((cmic) >> NVME_CMIC_MULTI_ANA_SHIFT) & NVME_CMIC_MULTI_ANA_MASK
)
;
1858 __u8 sriov = NVME_CMIC_MULTI_SRIOV(cmic)(((cmic) >> NVME_CMIC_MULTI_SRIOV_SHIFT) & NVME_CMIC_MULTI_SRIOV_MASK
)
;
1859 __u8 mctl = NVME_CMIC_MULTI_CTRL(cmic)(((cmic) >> NVME_CMIC_MULTI_CTRL_SHIFT) & NVME_CMIC_MULTI_CTRL_MASK
)
;
1860 __u8 mp = NVME_CMIC_MULTI_PORT(cmic)(((cmic) >> NVME_CMIC_MULTI_PORT_SHIFT) & NVME_CMIC_MULTI_PORT_MASK
)
;
1861
1862 if (rsvd)
1863 printf(" [7:4] : %#x\tReserved\n", rsvd);
1864 printf(" [3:3] : %#x\tANA %ssupported\n", ana, ana ? "" : "not ");
1865 printf(" [2:2] : %#x\t%s\n", sriov, sriov ? "SR-IOV" : "PCI");
1866 printf(" [1:1] : %#x\t%s Controller\n", mctl, mctl ? "Multi" : "Single");
1867 printf(" [0:0] : %#x\t%s Port\n", mp, mp ? "Multi" : "Single");
1868 printf("\n");
1869}
1870
1871static void stdout_id_ctrl_oaes(__le32 ctrl_oaes)
1872{
1873 __u32 oaes = le32_to_cpu(ctrl_oaes);
1874 __u32 dlpcn = (oaes & NVME_CTRL_OAES_DL) >> 31;
1875 __u32 rsvd28 = (oaes & 0x70000000) >> 28;
1876 __u32 zdcn = (oaes & NVME_CTRL_OAES_ZD) >> 27;
1877 __u32 rsvd20 = (oaes & 0x7fe0000) >> 20;
1878 __u32 ansan = (oaes & NVME_CTRL_OAES_ANSAN) >> 19;
1879 __u32 rsvd18 = (oaes >> 18) & 0x1;
1880 __u32 rgcns = (oaes & NVME_CTRL_OAES_RGCNS) >> 17;
1881 __u32 tthr = (oaes & NVME_CTRL_OAES_TTH) >> 16;
1882 __u32 normal_shn = (oaes & NVME_CTRL_OAES_NS) >> 15;
1883 __u32 egealpcn = (oaes & NVME_CTRL_OAES_EGE) >> 14;
1884 __u32 lbasin = (oaes & NVME_CTRL_OAES_LBAS) >> 13;
1885 __u32 plealcn = (oaes & NVME_CTRL_OAES_PLEA) >> 12;
1886 __u32 anacn = (oaes & NVME_CTRL_OAES_ANA) >> 11;
1887 __u32 rsvd10 = (oaes >> 10) & 0x1;
1888 __u32 fan = (oaes & NVME_CTRL_OAES_FA) >> 9;
1889 __u32 nace = (oaes & NVME_CTRL_OAES_NA) >> 8;
1890 __u32 rsvd0 = oaes & 0xFF;
1891
1892 printf(" [31:31] : %#x\tDiscovery Log Change Notice %sSupported\n",
1893 dlpcn, dlpcn ? "" : "Not ");
1894 if (rsvd28)
1895 printf(" [30:28] : %#x\tReserved\n", rsvd28);
1896 printf(" [27:27] : %#x\tZone Descriptor Changed Notices %sSupported\n",
1897 zdcn, zdcn ? "" : "Not ");
1898 if (rsvd20)
1899 printf(" [26:20] : %#x\tReserved\n", rsvd20);
1900 printf(" [19:19] : %#x\tAllocated Namespace Attribute Notices %sSupported\n",
1901 ansan, ansan ? "" : "Not ");
1902 if (rsvd18)
1903 printf(" [18:18] : %#x\tReserved\n", rsvd18);
1904 printf(" [17:17] : %#x\tReachability Groups Change Notices %sSupported\n",
1905 rgcns, rgcns ? "" : "Not ");
1906 printf(" [16:16] : %#x\tTemperature Threshold Hysteresis Recovery %sSupported\n",
1907 tthr, tthr ? "" : "Not ");
1908 printf(" [15:15] : %#x\tNormal NSS Shutdown Event %sSupported\n",
1909 normal_shn, normal_shn ? "" : "Not ");
1910 printf(" [14:14] : %#x\tEndurance Group Event Aggregate Log Page"\
1911 " Change Notice %sSupported\n",
1912 egealpcn, egealpcn ? "" : "Not ");
1913 printf(" [13:13] : %#x\tLBA Status Information Notices %sSupported\n",
1914 lbasin, lbasin ? "" : "Not ");
1915 printf(" [12:12] : %#x\tPredictable Latency Event Aggregate Log Change"\
1916 " Notices %sSupported\n",
1917 plealcn, plealcn ? "" : "Not ");
1918 printf(" [11:11] : %#x\tAsymmetric Namespace Access Change Notices"\
1919 " %sSupported\n", anacn, anacn ? "" : "Not ");
1920 if (rsvd10)
1921 printf(" [10:10] : %#x\tReserved\n", rsvd10);
1922 printf(" [9:9] : %#x\tFirmware Activation Notices %sSupported\n",
1923 fan, fan ? "" : "Not ");
1924 printf(" [8:8] : %#x\tNamespace Attribute Changed Event %sSupported\n",
1925 nace, nace ? "" : "Not ");
1926 if (rsvd0)
1927 printf(" [7:0] : %#x\tReserved\n", rsvd0);
1928 printf("\n");
1929}
1930
1931static void stdout_id_ctrl_ctratt(__le32 ctrl_ctratt)
1932{
1933 __u32 ctratt = le32_to_cpu(ctrl_ctratt);
1934 __u32 rsvd22 = (ctratt >> 22);
1935 __u32 pms = (ctratt & NVME_CTRL_CTRATT_PMS) >> 21;
1936 __u32 pls = (ctratt & NVME_CTRL_CTRATT_PLS) >> 20;
1937 __u32 fdps = (ctratt & NVME_CTRL_CTRATT_FDPS) >> 19;
1938 __u32 rhii = (ctratt & NVME_CTRL_CTRATT_RHII) >> 18;
1939 __u32 hmbr = (ctratt & NVME_CTRL_CTRATT_HMBR) >> 17;
1940 __u32 mem = (ctratt & NVME_CTRL_CTRATT_MEM) >> 16;
1941 __u32 elbas = (ctratt & NVME_CTRL_CTRATT_ELBAS) >> 15;
1942 __u32 dnvms = (ctratt & NVME_CTRL_CTRATT_DEL_NVM_SETS) >> 14;
1943 __u32 deg = (ctratt & NVME_CTRL_CTRATT_DEL_ENDURANCE_GROUPS) >> 13;
1944 __u32 vcm = (ctratt & NVME_CTRL_CTRATT_VARIABLE_CAP) >> 12;
1945 __u32 fcm = (ctratt & NVME_CTRL_CTRATT_FIXED_CAP) >> 11;
1946 __u32 mds = (ctratt & NVME_CTRL_CTRATT_MDS) >> 10;
1947 __u32 ulist = (ctratt & NVME_CTRL_CTRATT_UUID_LIST) >> 9;
1948 __u32 sqa = (ctratt & NVME_CTRL_CTRATT_SQ_ASSOCIATIONS) >> 8;
1949 __u32 ng = (ctratt & NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY) >> 7;
1950 __u32 tbkas = (ctratt & NVME_CTRL_CTRATT_TBKAS) >> 6;
1951 __u32 plm = (ctratt & NVME_CTRL_CTRATT_PREDICTABLE_LAT) >> 5;
1952 __u32 egs = (ctratt & NVME_CTRL_CTRATT_ENDURANCE_GROUPS) >> 4;
1953 __u32 rrlvls = (ctratt & NVME_CTRL_CTRATT_READ_RECV_LVLS) >> 3;
1954 __u32 nsets = (ctratt & NVME_CTRL_CTRATT_NVM_SETS) >> 2;
1955 __u32 nopspm = (ctratt & NVME_CTRL_CTRATT_NON_OP_PSP) >> 1;
1956 __u32 hids = (ctratt & NVME_CTRL_CTRATT_128_ID) >> 0;
1957
1958 if (rsvd22)
1959 printf(" [31:22] : %#x\tReserved\n", rsvd22);
1960 printf(" [21:21] : %#x\tPower Measurement %sSupported\n",
1961 pms, pms ? "" : "Not ");
1962 printf(" [20:20] : %#x\tPower Limit %sSupported\n",
1963 pls, pls ? "" : "Not ");
1964 printf(" [19:19] : %#x\tFlexible Data Placement %sSupported\n",
1965 fdps, fdps ? "" : "Not ");
1966 printf(" [18:18] : %#x\tReservations and Host Identifier Interaction %sSupported\n",
1967 rhii, rhii ? "" : "Not ");
1968 printf(" [17:17] : %#x\tHMB Restrict Non-Operational Power State Access %sSupported\n",
1969 hmbr, hmbr ? "" : "Not ");
1970 printf(" [16:16] : %#x\tMDTS and Size Limits Exclude Metadata %sSupported\n",
1971 mem, mem ? "" : "Not ");
1972 printf(" [15:15] : %#x\tExtended LBA Formats %sSupported\n",
1973 elbas, elbas ? "" : "Not ");
1974 printf(" [14:14] : %#x\tDelete NVM Set %sSupported\n",
1975 dnvms, dnvms ? "" : "Not ");
1976 printf(" [13:13] : %#x\tDelete Endurance Group %sSupported\n",
1977 deg, deg ? "" : "Not ");
1978 printf(" [12:12] : %#x\tVariable Capacity Management %sSupported\n",
1979 vcm, vcm ? "" : "Not ");
1980 printf(" [11:11] : %#x\tFixed Capacity Management %sSupported\n",
1981 fcm, fcm ? "" : "Not ");
1982 printf(" [10:10] : %#x\tMulti Domain Subsystem %sSupported\n",
1983 mds, mds ? "" : "Not ");
1984 printf(" [9:9] : %#x\tUUID List %sSupported\n",
1985 ulist, ulist ? "" : "Not ");
1986 printf(" [8:8] : %#x\tSQ Associations %sSupported\n",
1987 sqa, sqa ? "" : "Not ");
1988 printf(" [7:7] : %#x\tNamespace Granularity %sSupported\n",
1989 ng, ng ? "" : "Not ");
1990 printf(" [6:6] : %#x\tTraffic Based Keep Alive %sSupported\n",
1991 tbkas, tbkas ? "" : "Not ");
1992 printf(" [5:5] : %#x\tPredictable Latency Mode %sSupported\n",
1993 plm, plm ? "" : "Not ");
1994 printf(" [4:4] : %#x\tEndurance Groups %sSupported\n",
1995 egs, egs ? "" : "Not ");
1996 printf(" [3:3] : %#x\tRead Recovery Levels %sSupported\n",
1997 rrlvls, rrlvls ? "" : "Not ");
1998 printf(" [2:2] : %#x\tNVM Sets %sSupported\n",
1999 nsets, nsets ? "" : "Not ");
2000 printf(" [1:1] : %#x\tNon-Operational Power State Permissive %sSupported\n",
2001 nopspm, nopspm ? "" : "Not ");
2002 printf(" [0:0] : %#x\t128-bit Host Identifier %sSupported\n",
2003 hids, hids ? "" : "Not ");
2004 printf("\n");
2005}
2006
2007static void stdout_id_ctrl_bpcap(__u8 ctrl_bpcap)
2008{
2009 __u8 rsvd3 = (ctrl_bpcap >> 3);
2010 __u8 sfbpwps = NVME_GET(ctrl_bpcap, CTRL_BACAP_SFBPWPS)(((ctrl_bpcap) >> NVME_CTRL_BACAP_SFBPWPS_SHIFT) & NVME_CTRL_BACAP_SFBPWPS_MASK
)
;
2011 __u8 rpmbbpwps = NVME_GET(ctrl_bpcap, CTRL_BACAP_RPMBBPWPS)(((ctrl_bpcap) >> NVME_CTRL_BACAP_RPMBBPWPS_SHIFT) &
NVME_CTRL_BACAP_RPMBBPWPS_MASK)
;
2012 static const char * const rpmbbpwps_def[] = {
2013 "Support Not Specified",
2014 "Not Supported",
2015 "Supported"
2016 };
2017
2018 if (rsvd3)
2019 printf(" [7:3] : %#x\tReserved\n", rsvd3);
2020
2021 printf(" [2:2] : %#x\tSet Features Boot Partition Write Protection %sSupported\n",
2022 sfbpwps, sfbpwps ? "" : "Not ");
2023 printf(" [1:0] : %#x\tRPMB Boot Partition Write Protection %s\n",
2024 rpmbbpwps, rpmbbpwps_def[rpmbbpwps]);
2025 printf("\n");
2026}
2027
2028static void stdout_id_ctrl_plsi(__u8 ctrl_plsi)
2029{
2030 __u8 rsvd2 = (ctrl_plsi >> 2);
2031 __u8 plsfq = NVME_GET(ctrl_plsi, CTRL_PLSI_PLSFQ)(((ctrl_plsi) >> NVME_CTRL_PLSI_PLSFQ_SHIFT) & NVME_CTRL_PLSI_PLSFQ_MASK
)
;
2032 __u8 plsepf = NVME_GET(ctrl_plsi, CTRL_PLSI_PLSEPF)(((ctrl_plsi) >> NVME_CTRL_PLSI_PLSEPF_SHIFT) & NVME_CTRL_PLSI_PLSEPF_MASK
)
;
2033
2034 if (rsvd2)
2035 printf(" [7:2] : %#x\tReserved\n", rsvd2);
2036
2037 printf(" [1:1] : %#x\tPower Loss Signaling with Forced Quiescence %sSupported\n",
2038 plsfq, plsfq ? "" : "Not ");
2039 printf(" [0:0] : %#x\tPower Loss Signaling with Emergency Power Fail %sSupported\n",
2040 plsepf, plsepf ? "" : "Not ");
2041 printf("\n");
2042}
2043
2044static void stdout_id_ctrl_crcap(__u8 ctrl_crcap)
2045{
2046 __u8 rsvd2 = (ctrl_crcap >> 2);
2047 __u8 rgidc = NVME_GET(ctrl_crcap, CTRL_CRCAP_RGIDC)(((ctrl_crcap) >> NVME_CTRL_CRCAP_RGIDC_SHIFT) & NVME_CTRL_CRCAP_RGIDC_MASK
)
;
2048 __u8 rrsup = NVME_GET(ctrl_crcap, CTRL_CRCAP_RRSUP)(((ctrl_crcap) >> NVME_CTRL_CRCAP_RRSUP_SHIFT) & NVME_CTRL_CRCAP_RRSUP_MASK
)
;
2049
2050 if (rsvd2)
2051 printf(" [7:2] : %#x\tReserved\n", rsvd2);
2052
2053 printf(" [1:1] : %#x\tRGRPID %s while the namespace is attached to any controller.\n",
2054 rgidc, rgidc ? "does not change" : "may change");
2055 printf(" [0:0] : %#x\tReachability Reporting %sSupported\n",
2056 rrsup, rrsup ? "" : "Not ");
2057 printf("\n");
2058}
2059
2060static void stdout_id_ctrl_cntrltype(__u8 cntrltype)
2061{
2062 __u8 rsvd = (cntrltype & 0xFC) >> 2;
2063 __u8 cntrl = cntrltype & 0x3;
2064
2065 static const char * const type[] = {
2066 "Controller type not reported",
2067 "I/O Controller",
2068 "Discovery Controller",
2069 "Administrative Controller"
2070 };
2071
2072 printf(" [7:2] : %#x\tReserved\n", rsvd);
2073 printf(" [1:0] : %#x\t%s\n", cntrltype, type[cntrl]);
2074}
2075
2076static void stdout_id_ctrl_nvmsr(__u8 nvmsr)
2077{
2078 __u8 rsvd = (nvmsr >> 2) & 0xfc;
2079 __u8 nvmee = (nvmsr >> 1) & 0x1;
2080 __u8 nvmesd = nvmsr & 0x1;
2081
2082 if (rsvd)
2083 printf(" [7:2] : %#x\tReserved\n", rsvd);
2084 printf(" [1:1] : %#x\tNVM subsystem %spart of an Enclosure\n",
2085 nvmee, nvmee ? "" : "Not ");
2086 printf(" [0:0] : %#x\tNVM subsystem %spart of a Storage Device\n",
2087 nvmesd, nvmesd ? "" : "Not ");
2088 printf("\n");
2089}
2090
2091static void stdout_id_ctrl_vwci(__u8 vwci)
2092{
2093 __u8 vwcrv = (vwci >> 7) & 0x1;
2094 __u8 vwcr = vwci & 0xfe;
2095
2096 printf(" [7:7] : %#x\tVPD Write Cycles Remaining field is %svalid.\n",
2097 vwcrv, vwcrv ? "" : "Not ");
2098 printf(" [6:0] : %#x\tVPD Write Cycles Remaining\n", vwcr);
2099 printf("\n");
2100
2101}
2102
2103static void stdout_id_ctrl_mec(__u8 mec)
2104{
2105 __u8 rsvd = (mec >> 2) & 0xfc;
2106 __u8 pcieme = (mec >> 1) & 0x1;
2107 __u8 smbusme = mec & 0x1;
2108
2109 if (rsvd)
2110 printf(" [7:2] : %#x\tReserved\n", rsvd);
2111 printf(" [1:1] : %#x\tNVM subsystem %scontains a Management Endpoint"\
2112 " on a PCIe port\n", pcieme, pcieme ? "" : "Not ");
2113 printf(" [0:0] : %#x\tNVM subsystem %scontains a Management Endpoint"\
2114 " on an SMBus/I2C port\n", smbusme, smbusme ? "" : "Not ");
2115 printf("\n");
2116
2117}
2118
2119static void stdout_id_ctrl_oacs(__le16 ctrl_oacs)
2120{
2121 __u16 oacs = le16_to_cpu(ctrl_oacs);
2122 __u16 rsvd = (oacs & 0xF000) >> 12;
2123 __u16 hmlms = (oacs & 0x800) >> 11;
2124 __u16 lock = (oacs & NVME_CTRL_OACS_CMD_FEAT_LD) >> 10;
2125 __u16 glbas = (oacs & NVME_CTRL_OACS_LBA_STATUS) >> 9;
2126 __u16 dbc = (oacs & NVME_CTRL_OACS_DBBUF_CFG) >> 8;
2127 __u16 vir = (oacs & NVME_CTRL_OACS_VIRT_MGMT) >> 7;
2128 __u16 nmi = (oacs & NVME_CTRL_OACS_NVME_MI) >> 6;
2129 __u16 dir = (oacs & NVME_CTRL_OACS_DIRECTIVES) >> 5;
2130 __u16 sft = (oacs & NVME_CTRL_OACS_SELF_TEST) >> 4;
2131 __u16 nsm = (oacs & NVME_CTRL_OACS_NS_MGMT) >> 3;
2132 __u16 fwc = (oacs & NVME_CTRL_OACS_FW) >> 2;
2133 __u16 fmt = (oacs & NVME_CTRL_OACS_FORMAT) >> 1;
2134 __u16 sec = oacs & NVME_CTRL_OACS_SECURITY;
2135
2136 if (rsvd)
2137 printf(" [15:12] : %#x\tReserved\n", rsvd);
2138 printf(" [11:11] : %#x\tHost Managed Live Migration %sSupported\n",
2139 hmlms, hmlms ? "" : "Not ");
2140 printf(" [10:10] : %#x\tLockdown Command and Feature %sSupported\n",
2141 lock, lock ? "" : "Not ");
2142 printf(" [9:9] : %#x\tGet LBA Status Capability %sSupported\n",
2143 glbas, glbas ? "" : "Not ");
2144 printf(" [8:8] : %#x\tDoorbell Buffer Config %sSupported\n",
2145 dbc, dbc ? "" : "Not ");
2146 printf(" [7:7] : %#x\tVirtualization Management %sSupported\n",
2147 vir, vir ? "" : "Not ");
2148 printf(" [6:6] : %#x\tNVMe-MI Send and Receive %sSupported\n",
2149 nmi, nmi ? "" : "Not ");
2150 printf(" [5:5] : %#x\tDirectives %sSupported\n",
2151 dir, dir ? "" : "Not ");
2152 printf(" [4:4] : %#x\tDevice Self-test %sSupported\n",
2153 sft, sft ? "" : "Not ");
2154 printf(" [3:3] : %#x\tNS Management and Attachment %sSupported\n",
2155 nsm, nsm ? "" : "Not ");
2156 printf(" [2:2] : %#x\tFW Commit and Download %sSupported\n",
2157 fwc, fwc ? "" : "Not ");
2158 printf(" [1:1] : %#x\tFormat NVM %sSupported\n",
2159 fmt, fmt ? "" : "Not ");
2160 printf(" [0:0] : %#x\tSecurity Send and Receive %sSupported\n",
2161 sec, sec ? "" : "Not ");
2162 printf("\n");
2163}
2164
2165static void stdout_id_ctrl_frmw(__u8 frmw)
2166{
2167 __u8 rsvd = (frmw & 0xC0) >> 6;
2168 __u8 smud = (frmw >> 5) & 0x1;
2169 __u8 fawr = (frmw & 0x10) >> 4;
2170 __u8 nfws = (frmw & 0xE) >> 1;
2171 __u8 s1ro = frmw & 0x1;
2172
2173 if (rsvd)
2174 printf(" [7:6] : %#x\tReserved\n", rsvd);
2175 printf(" [5:5] : %#x\tMultiple FW or Boot Update Detection %sSupported\n",
2176 smud, smud ? "" : "Not ");
2177 printf(" [4:4] : %#x\tFirmware Activate Without Reset %sSupported\n",
2178 fawr, fawr ? "" : "Not ");
2179 printf(" [3:1] : %#x\tNumber of Firmware Slots\n", nfws);
2180 printf(" [0:0] : %#x\tFirmware Slot 1 Read%s\n",
2181 s1ro, s1ro ? "-Only" : "/Write");
2182 printf("\n");
2183}
2184
2185static void stdout_id_ctrl_lpa(__u8 lpa)
2186{
2187 __u8 rsvd = (lpa & 0x80) >> 7;
2188 __u8 tel = (lpa >> 6) & 0x1;
2189 __u8 lid_sup = (lpa >> 5) & 0x1;
2190 __u8 persevnt = (lpa & 0x10) >> 4;
2191 __u8 telem = (lpa & 0x8) >> 3;
2192 __u8 ed = (lpa & 0x4) >> 2;
2193 __u8 celp = (lpa & 0x2) >> 1;
2194 __u8 smlp = lpa & 0x1;
2195
2196 if (rsvd)
2197 printf(" [7:7] : %#x\tReserved\n", rsvd);
2198 printf(" [6:6] : %#x\tTelemetry Log Data Area 4 %sSupported\n",
2199 tel, tel ? "" : "Not ");
2200 printf(" [5:5] : %#x\tLID 0x0, Scope of each command in LID 0x5, "\
2201 "0x12, 0x13 %sSupported\n", lid_sup, lid_sup ? "" : "Not ");
2202 printf(" [4:4] : %#x\tPersistent Event log %sSupported\n",
2203 persevnt, persevnt ? "" : "Not ");
2204 printf(" [3:3] : %#x\tTelemetry host/controller initiated log page %sSupported\n",
2205 telem, telem ? "" : "Not ");
2206 printf(" [2:2] : %#x\tExtended data for Get Log Page %sSupported\n",
2207 ed, ed ? "" : "Not ");
2208 printf(" [1:1] : %#x\tCommand Effects Log Page %sSupported\n",
2209 celp, celp ? "" : "Not ");
2210 printf(" [0:0] : %#x\tSMART/Health Log Page per NS %sSupported\n",
2211 smlp, smlp ? "" : "Not ");
2212 printf("\n");
2213}
2214
2215static void stdout_id_ctrl_elpe(__u8 elpe)
2216{
2217 printf(" [7:0] : %d (0's based)\tError Log Page Entries (ELPE)\n",
2218 elpe);
2219 printf("\n");
2220}
2221
2222static void stdout_id_ctrl_npss(__u8 npss)
2223{
2224 printf(" [7:0] : %d (0's based)\tNumber of Power States Support (NPSS)\n",
2225 npss);
2226 printf("\n");
2227}
2228
2229static void stdout_id_ctrl_avscc(__u8 avscc)
2230{
2231 __u8 rsvd = (avscc & 0xFE) >> 1;
2232 __u8 fmt = avscc & 0x1;
2233
2234 if (rsvd)
2235 printf(" [7:1] : %#x\tReserved\n", rsvd);
2236 printf(" [0:0] : %#x\tAdmin Vendor Specific Commands uses %s Format\n",
2237 fmt, fmt ? "NVMe" : "Vendor Specific");
2238 printf("\n");
2239}
2240
2241static void stdout_id_ctrl_apsta(__u8 apsta)
2242{
2243 __u8 rsvd = (apsta & 0xFE) >> 1;
2244 __u8 apst = apsta & 0x1;
2245
2246 if (rsvd)
2247 printf(" [7:1] : %#x\tReserved\n", rsvd);
2248 printf(" [0:0] : %#x\tAutonomous Power State Transitions %sSupported\n",
2249 apst, apst ? "" : "Not ");
2250 printf("\n");
2251}
2252
2253static void stdout_id_ctrl_wctemp(__le16 wctemp)
2254{
2255 printf(" [15:0] : %s (%u K, %s)\tWarning Composite Temperature Threshold (WCTEMP)\n",
2256 nvme_degrees_string(le16_to_cpu(wctemp)), le16_to_cpu(wctemp),
2257 nvme_degrees_fahrenheit_string(le16_to_cpu(wctemp)));
2258 printf("\n");
2259}
2260
2261static void stdout_id_ctrl_cctemp(__le16 cctemp)
2262{
2263 printf(" [15:0] : %s (%u K, %s)\tCritical Composite Temperature Threshold (CCTEMP)\n",
2264 nvme_degrees_string(le16_to_cpu(cctemp)), le16_to_cpu(cctemp),
2265 nvme_degrees_fahrenheit_string(le16_to_cpu(cctemp)));
2266 printf("\n");
2267}
2268
2269static void stdout_id_ctrl_tnvmcap(__u8 *tnvmcap)
2270{
2271 printf("[127:0] : %s\n", uint128_t_to_l10n_string(le128_to_cpu(tnvmcap)));
2272 printf("\tTotal NVM Capacity (TNVMCAP)\n\n");
2273}
2274
2275static void stdout_id_ctrl_unvmcap(__u8 *unvmcap)
2276{
2277 printf("[127:0] : %s\n", uint128_t_to_l10n_string(le128_to_cpu(unvmcap)));
2278 printf("\tUnallocated NVM Capacity (UNVMCAP)\n\n");
2279}
2280
2281void stdout_id_ctrl_rpmbs(__le32 ctrl_rpmbs)
2282{
2283 __u32 rpmbs = le32_to_cpu(ctrl_rpmbs);
2284 __u32 asz = (rpmbs & 0xFF000000) >> 24;
2285 __u32 tsz = (rpmbs & 0xFF0000) >> 16;
2286 __u32 rsvd = (rpmbs & 0xFFC0) >> 6;
2287 __u32 auth = (rpmbs & 0x38) >> 3;
2288 __u32 rpmb = rpmbs & 0x7;
2289
2290 printf(" [31:24]: %#x\tAccess Size\n", asz);
2291 printf(" [23:16]: %#x\tTotal Size\n", tsz);
2292 if (rsvd)
2293 printf(" [15:6] : %#x\tReserved\n", rsvd);
2294 printf(" [5:3] : %#x\tAuthentication Method\n", auth);
2295 printf(" [2:0] : %#x\tNumber of RPMB Units\n", rpmb);
2296 printf("\n");
2297}
2298
2299static void stdout_id_ctrl_dsto(__u8 dsto)
2300{
2301 __u8 rsvd2 = (dsto & 0xfc) >> 2;
2302 __u8 hirs = (dsto & 0x2) >> 1;
2303 __u8 sdso = dsto & 0x1;
2304
2305 if (rsvd2)
2306 printf(" [7:2] : %#x\tReserved\n", rsvd2);
2307 printf(" [1:1] : %#x\tHost-Initiated Refresh capability %sSupported\n",
2308 hirs, hirs ? "" : "Not ");
2309 printf(" [0:0] : %#x\tNVM subsystem supports %s at a time\n", sdso,
2310 sdso ? "only one device self-test operation in progress" :
2311 "one device self-test operation per controller");
2312 printf("\n");
2313}
2314
2315static void stdout_id_ctrl_hctma(__le16 ctrl_hctma)
2316{
2317 __u16 hctma = le16_to_cpu(ctrl_hctma);
2318 __u16 rsvd = (hctma & 0xFFFE) >> 1;
2319 __u16 hctm = hctma & 0x1;
2320
2321 if (rsvd)
2322 printf(" [15:1] : %#x\tReserved\n", rsvd);
2323 printf(" [0:0] : %#x\tHost Controlled Thermal Management %sSupported\n",
2324 hctm, hctm ? "" : "Not ");
2325 printf("\n");
2326}
2327
2328static void stdout_id_ctrl_mntmt(__le16 mntmt)
2329{
2330 printf(" [15:0] : %s (%u K, %s)\tMinimum Thermal Management Temperature (MNTMT)\n",
2331 nvme_degrees_string(le16_to_cpu(mntmt)), le16_to_cpu(mntmt),
2332 nvme_degrees_fahrenheit_string(le16_to_cpu(mntmt)));
2333 printf("\n");
2334}
2335
2336static void stdout_id_ctrl_mxtmt(__le16 mxtmt)
2337{
2338 printf(" [15:0] : %s (%u K, %s)\tMaximum Thermal Management Temperature (MXTMT)\n",
2339 nvme_degrees_string(le16_to_cpu(mxtmt)), le16_to_cpu(mxtmt),
2340 nvme_degrees_fahrenheit_string(le16_to_cpu(mxtmt)));
2341 printf("\n");
2342}
2343
2344static void stdout_id_ctrl_sanicap(__le32 ctrl_sanicap)
2345{
2346 __u32 sanicap = le32_to_cpu(ctrl_sanicap);
2347 __u32 rsvd4 = (sanicap & 0x1FFFFFF0) >> 4;
2348 __u32 vers = (sanicap & 0x8) >> 3;
2349 __u32 ows = (sanicap & 0x4) >> 2;
2350 __u32 bes = (sanicap & 0x2) >> 1;
2351 __u32 ces = sanicap & 0x1;
2352 __u32 ndi = (sanicap & 0x20000000) >> 29;
2353 __u32 nodmmas = (sanicap & 0xC0000000) >> 30;
2354
2355 static const char * const modifies_media[] = {
2356 "Additional media modification after sanitize operation completes successfully is not defined",
2357 "Media is not additionally modified after sanitize operation completes successfully",
2358 "Media is additionally modified after sanitize operation completes successfully",
2359 "Reserved"
2360 };
2361
2362 printf(" [31:30] : %#x\t%s\n", nodmmas, modifies_media[nodmmas]);
2363 printf(" [29:29] : %#x\tNo-Deallocate After Sanitize bit in Sanitize command %sSupported\n",
2364 ndi, ndi ? "Not " : "");
2365 if (rsvd4)
2366 printf(" [28:4] : %#x\tReserved\n", rsvd4);
2367 printf(" [3:3] : %#x\tMedia Verification and Post-Verification Deallocation state %sSupported\n",
2368 vers, vers ? "" : "Not ");
2369 printf(" [2:2] : %#x\tOverwrite Sanitize Operation %sSupported\n",
2370 ows, ows ? "" : "Not ");
2371 printf(" [1:1] : %#x\tBlock Erase Sanitize Operation %sSupported\n",
2372 bes, bes ? "" : "Not ");
2373 printf(" [0:0] : %#x\tCrypto Erase Sanitize Operation %sSupported\n",
2374 ces, ces ? "" : "Not ");
2375 printf("\n");
2376}
2377
2378static void stdout_id_ctrl_anacap(__u8 anacap)
2379{
2380 __u8 nz = (anacap & 0x80) >> 7;
2381 __u8 grpid_static = (anacap & 0x40) >> 6;
2382 __u8 rsvd = (anacap & 0x20) >> 5;
2383 __u8 ana_change = (anacap & 0x10) >> 4;
2384 __u8 ana_persist_loss = (anacap & 0x08) >> 3;
2385 __u8 ana_inaccessible = (anacap & 0x04) >> 2;
2386 __u8 ana_nonopt = (anacap & 0x02) >> 1;
2387 __u8 ana_opt = (anacap & 0x01);
2388
2389 printf(" [7:7] : %#x\tNon-zero group ID %sSupported\n",
2390 nz, nz ? "" : "Not ");
2391 printf(" [6:6] : %#x\tGroup ID does %schange\n",
2392 grpid_static, grpid_static ? "not " : "");
2393 if (rsvd)
2394 printf(" [5:5] : %#x\tReserved\n", rsvd);
2395 printf(" [4:4] : %#x\tANA Change state %sSupported\n",
2396 ana_change, ana_change ? "" : "Not ");
2397 printf(" [3:3] : %#x\tANA Persistent Loss state %sSupported\n",
2398 ana_persist_loss, ana_persist_loss ? "" : "Not ");
2399 printf(" [2:2] : %#x\tANA Inaccessible state %sSupported\n",
2400 ana_inaccessible, ana_inaccessible ? "" : "Not ");
2401 printf(" [1:1] : %#x\tANA Non-optimized state %sSupported\n",
2402 ana_nonopt, ana_nonopt ? "" : "Not ");
2403 printf(" [0:0] : %#x\tANA Optimized state %sSupported\n",
2404 ana_opt, ana_opt ? "" : "Not ");
2405 printf("\n");
2406}
2407
2408static void stdout_id_ctrl_kpioc(__u8 ctrl_kpioc)
2409{
2410 __u8 rsvd2 = (ctrl_kpioc >> 2);
2411 __u8 kpiosc = NVME_GET(ctrl_kpioc, CTRL_KPIOC_KPIOSC)(((ctrl_kpioc) >> NVME_CTRL_KPIOC_KPIOSC_SHIFT) & NVME_CTRL_KPIOC_KPIOSC_MASK
)
;
2412 __u8 kpios = NVME_GET(ctrl_kpioc, CTRL_KPIOC_KPIOS)(((ctrl_kpioc) >> NVME_CTRL_KPIOC_KPIOS_SHIFT) & NVME_CTRL_KPIOC_KPIOS_MASK
)
;
2413
2414 if (rsvd2)
2415 printf(" [7:2] : %#x\tReserved\n", rsvd2);
2416
2417 printf(" [1:1] : %#x\tKey Per I/O capability %s to all namespaces\n",
2418 kpiosc, kpiosc ? "applies" : "Not apply");
2419 printf(" [0:0] : %#x\tKey Per I/O capability %sSupported\n",
2420 kpios, kpios ? "" : "Not ");
2421 printf("\n");
2422}
2423
2424static void stdout_id_ctrl_tmpthha(__u8 tmpthha)
2425{
2426 __u8 rsvd3 = (tmpthha & 0xf8) >> 3;
2427 __u8 tmpthmh = tmpthha & 0x7;
2428
2429 if (rsvd3)
2430 printf(" [7:3] : %#x\tReserved\n", rsvd3);
2431 printf(" [2:0] : %#x\tTemperature Threshold Maximum Hysteresis\n",
2432 tmpthmh);
2433 printf("\n");
2434}
2435
2436static void stdout_id_ctrl_cdpa(__le16 ctrl_cdpa)
2437{
2438 __u16 cdpa = le16_to_cpu(ctrl_cdpa);
2439 __u16 rsvd1 = (cdpa >> 1);
2440 bool_Bool hmac_sha_384 = !!(cdpa & NVME_CTRL_CDPA_HMAC_SHA_384);
2441
2442 if (rsvd1)
2443 printf(" [15:1] : %#x\tReserved\n", rsvd1);
2444 printf(" [0:0] : %#x\tHMAC-SHA-384 %sSupported\n",
2445 hmac_sha_384, hmac_sha_384 ? "" : "Not ");
2446
2447 printf("\n");
2448}
2449
2450static void stdout_id_ctrl_ipmsr(__le16 ctrl_ipmsr)
2451{
2452 __u16 ipmsr = le16_to_cpu(ctrl_ipmsr);
2453 __u16 srs = NVME_GET(ipmsr, CTRL_IPMSR_SRS)(((ipmsr) >> NVME_CTRL_IPMSR_SRS_SHIFT) & NVME_CTRL_IPMSR_SRS_MASK
)
;
2454 __u16 srv = NVME_GET(ipmsr, CTRL_IPMSR_SRV)(((ipmsr) >> NVME_CTRL_IPMSR_SRV_SHIFT) & NVME_CTRL_IPMSR_SRV_MASK
)
;
2455
2456 printf(" [15:8] : %#x\tSample Rate Scale (%s)\n", srs,
2457 nvme_ipmsr_srs_to_string(srs));
2458 printf(" [7:0] : %#x\tSample Rate Value\n", srv);
2459
2460 printf("\n");
2461}
2462
2463static void stdout_id_ctrl_sqes(__u8 sqes)
2464{
2465 __u8 msqes = (sqes & 0xF0) >> 4;
2466 __u8 rsqes = sqes & 0xF;
2467
2468 printf(" [7:4] : %#x\tMax SQ Entry Size (%d)\n", msqes, 1 << msqes);
2469 printf(" [3:0] : %#x\tMin SQ Entry Size (%d)\n", rsqes, 1 << rsqes);
2470 printf("\n");
2471}
2472
2473static void stdout_id_ctrl_cqes(__u8 cqes)
2474{
2475 __u8 mcqes = (cqes & 0xF0) >> 4;
2476 __u8 rcqes = cqes & 0xF;
2477
2478 printf(" [7:4] : %#x\tMax CQ Entry Size (%d)\n", mcqes, 1 << mcqes);
2479 printf(" [3:0] : %#x\tMin CQ Entry Size (%d)\n", rcqes, 1 << rcqes);
2480 printf("\n");
2481}
2482
2483static void stdout_id_ctrl_oncs(__le16 ctrl_oncs)
2484{
2485 __u16 oncs = le16_to_cpu(ctrl_oncs);
2486 __u16 rsvd13 = oncs >> 13;
2487 bool_Bool nszs = !!(oncs & NVME_CTRL_ONCS_NAMESPACE_ZEROES);
2488 bool_Bool maxwzd = !!(oncs & NVME_CTRL_ONCS_WRITE_ZEROES_DEALLOCATE);
2489 bool_Bool nvmafc = !!(oncs & NVME_CTRL_ONCS_ALL_FAST_COPY);
2490 bool_Bool nvmcsa = !!(oncs & NVME_CTRL_ONCS_COPY_SINGLE_ATOMICITY);
2491 bool_Bool nvmcpys = !!(oncs & NVME_CTRL_ONCS_COPY);
2492 bool_Bool nvmvfys = !!(oncs & NVME_CTRL_ONCS_VERIFY);
2493 bool_Bool tss = !!(oncs & NVME_CTRL_ONCS_TIMESTAMP);
2494 bool_Bool reservs = !!(oncs & NVME_CTRL_ONCS_RESERVATIONS);
2495 bool_Bool ssfs = !!(oncs & NVME_CTRL_ONCS_SAVE_FEATURES);
2496 bool_Bool nvmwzsv = !!(oncs & NVME_CTRL_ONCS_WRITE_ZEROES);
2497 bool_Bool nvmdsmsv = !!(oncs & NVME_CTRL_ONCS_DSM);
2498 bool_Bool nvmwusv = !!(oncs & NVME_CTRL_ONCS_WRITE_UNCORRECTABLE);
2499 bool_Bool nvmcmps = !!(oncs & NVME_CTRL_ONCS_COMPARE);
2500
2501 if (rsvd13)
2502 printf(" [15:13] : %#x\tReserved\n", rsvd13);
2503 printf(" [12:12] : %#x\tNamespace Zeroes %sSupported\n",
2504 nszs, nszs ? "" : "Not ");
2505 printf(" [11:11] : %#x\tMaximum Write Zeroes with Deallocate %sSupported\n",
2506 maxwzd, maxwzd ? "" : "Not ");
2507 printf(" [10:10] : %#x\tAll Fast Copy %sSupported\n",
2508 nvmafc, nvmafc ? "" : "Not ");
2509 printf(" [9:9] : %#x\tCopy Single Atomicity %sSupported\n",
2510 nvmcsa, nvmcsa ? "" : "Not ");
2511 printf(" [8:8] : %#x\tCopy %sSupported\n",
2512 nvmcpys, nvmcpys ? "" : "Not ");
2513 printf(" [7:7] : %#x\tVerify %sSupported\n",
2514 nvmvfys, nvmvfys ? "" : "Not ");
2515 printf(" [6:6] : %#x\tTimestamp %sSupported\n",
2516 tss, tss ? "" : "Not ");
2517 printf(" [5:5] : %#x\tReservations %sSupported\n",
2518 reservs, reservs ? "" : "Not ");
2519 printf(" [4:4] : %#x\tSave and Select %sSupported\n",
2520 ssfs, ssfs ? "" : "Not ");
2521 printf(" [3:3] : %#x\tWrite Zeroes Support Variants\n",
2522 nvmwzsv);
2523 printf(" [2:2] : %#x\tDataset Management Support Variants\n",
2524 nvmdsmsv);
2525 printf(" [1:1] : %#x\tWrite Uncorrectable Support Variants\n",
2526 nvmwusv);
2527 printf(" [0:0] : %#x\tCompare Command %sSupported\n",
2528 nvmcmps, nvmcmps ? "" : "Not ");
2529 printf("\n");
2530}
2531
2532static void stdout_id_ctrl_fuses(__le16 ctrl_fuses)
2533{
2534 __u16 fuses = le16_to_cpu(ctrl_fuses);
2535 __u16 rsvd = (fuses & 0xFE) >> 1;
2536 __u16 cmpw = fuses & 0x1;
2537
2538 if (rsvd)
2539 printf(" [15:1] : %#x\tReserved\n", rsvd);
2540 printf(" [0:0] : %#x\tFused Compare and Write %sSupported\n",
2541 cmpw, cmpw ? "" : "Not ");
2542 printf("\n");
2543}
2544
2545static void stdout_id_ctrl_fna(__u8 fna)
2546{
2547 __u8 rsvd = (fna & 0xF0) >> 4;
2548 __u8 bcnsid = (fna & NVME_CTRL_FNA_NSID_FFFFFFFF) >> 3;
2549 __u8 cese = (fna & NVME_CTRL_FNA_CRYPTO_ERASE) >> 2;
2550 __u8 cens = (fna & NVME_CTRL_FNA_SEC_ALL_NAMESPACES) >> 1;
2551 __u8 fmns = fna & NVME_CTRL_FNA_FMT_ALL_NAMESPACES;
2552
2553 if (rsvd)
2554 printf(" [7:4] : %#x\tReserved\n", rsvd);
2555 printf(" [3:3] : %#x\tFormat NVM Broadcast NSID (FFFFFFFFh) %sSupported\n",
2556 bcnsid, bcnsid ? "Not " : "");
2557 printf(" [2:2] : %#x\tCrypto Erase %sSupported as part of Secure Erase\n",
2558 cese, cese ? "" : "Not ");
2559 printf(" [1:1] : %#x\tCrypto Erase Applies to %s Namespace(s)\n",
2560 cens, cens ? "All" : "Single");
2561 printf(" [0:0] : %#x\tFormat Applies to %s Namespace(s)\n",
2562 fmns, fmns ? "All" : "Single");
2563 printf("\n");
2564}
2565
2566static void stdout_id_ctrl_vwc(__u8 vwc)
2567{
2568 __u8 rsvd = (vwc & 0xF8) >> 3;
2569 __u8 flush = (vwc & 0x6) >> 1;
2570 __u8 vwcp = vwc & 0x1;
2571
2572 static const char * const flush_behavior[] = {
2573 "Support for the NSID field set to FFFFFFFFh is not indicated",
2574 "Reserved",
2575 "The Flush command does not support NSID set to FFFFFFFFh",
2576 "The Flush command supports NSID set to FFFFFFFFh"
2577 };
2578
2579 if (rsvd)
2580 printf(" [7:3] : %#x\tReserved\n", rsvd);
2581 printf(" [2:1] : %#x\t%s\n", flush, flush_behavior[flush]);
2582 printf(" [0:0] : %#x\tVolatile Write Cache %sPresent\n", vwcp, vwcp ? "" : "Not ");
2583 printf("\n");
2584}
2585
2586static void stdout_id_ctrl_icsvscc(__u8 icsvscc)
2587{
2588 __u8 rsvd = (icsvscc & 0xFE) >> 1;
2589 __u8 fmt = icsvscc & 0x1;
2590
2591 if (rsvd)
2592 printf(" [7:1] : %#x\tReserved\n", rsvd);
2593 printf(" [0:0] : %#x\tNVM Vendor Specific Commands uses %s Format\n",
2594 fmt, fmt ? "NVMe" : "Vendor Specific");
2595 printf("\n");
2596}
2597
2598static void stdout_id_ctrl_nwpc(__u8 nwpc)
2599{
2600 __u8 no_wp_wp = (nwpc & 0x01);
2601 __u8 wp_power_cycle = (nwpc & 0x02) >> 1;
2602 __u8 wp_permanent = (nwpc & 0x04) >> 2;
2603 __u8 rsvd = (nwpc & 0xF8) >> 3;
2604
2605 if (rsvd)
2606 printf(" [7:3] : %#x\tReserved\n", rsvd);
2607
2608 printf(" [2:2] : %#x\tPermanent Write Protect %sSupported\n",
2609 wp_permanent, wp_permanent ? "" : "Not ");
2610 printf(" [1:1] : %#x\tWrite Protect Until Power Supply %sSupported\n",
2611 wp_power_cycle, wp_power_cycle ? "" : "Not ");
2612 printf(" [0:0] : %#x\tNo Write Protect and Write Protect Namespace %sSupported\n",
2613 no_wp_wp, no_wp_wp ? "" : "Not ");
2614 printf("\n");
2615}
2616
2617static void stdout_id_ctrl_ocfs(__le16 ctrl_ocfs)
2618{
2619 __u16 ocfs = le16_to_cpu(ctrl_ocfs);
2620 __u16 rsvd = ocfs >> 4;
2621 __u8 copy_fmt_supported;
2622 int copy_fmt;
2623
2624 if (rsvd)
2625 printf(" [15:4] : %#x\tReserved\n", rsvd);
2626 for (copy_fmt = 3; copy_fmt >= 0; copy_fmt--) {
2627 copy_fmt_supported = ocfs >> copy_fmt & 1;
2628 printf(" [%d:%d] : %#x\tController Copy Format %xh %sSupported\n", copy_fmt,
2629 copy_fmt, copy_fmt_supported, copy_fmt, copy_fmt_supported ? "" : "Not ");
2630 }
2631 printf("\n");
2632}
2633
2634static void stdout_id_ctrl_sgls(__le32 ctrl_sgls)
2635{
2636 __u32 sgls = le32_to_cpu(ctrl_sgls);
2637 __u32 rsvd0 = (sgls & 0xFFC00000) >> 22;
2638 __u32 trsdbd = (sgls & 0x200000) >> 21;
2639 __u32 aofdsl = (sgls & 0x100000) >> 20;
2640 __u32 mpcsd = (sgls & 0x80000) >> 19;
2641 __u32 sglltb = (sgls & 0x40000) >> 18;
2642 __u32 bacmdb = (sgls & 0x20000) >> 17;
2643 __u32 bbs = (sgls & 0x10000) >> 16;
2644 __u32 sdt = (sgls >> 8) & 0xff;
2645 __u32 rsvd1 = (sgls & 0xF8) >> 3;
2646 __u32 key = (sgls & 0x4) >> 2;
2647 __u32 sglsp = sgls & 0x3;
2648
2649 if (rsvd0)
2650 printf(" [31:22]: %#x\tReserved\n", rsvd0);
2651 if (sglsp || (!sglsp && trsdbd))
2652 printf(" [21:21]: %#x\tTransport SGL Data Block Descriptor %sSupported\n",
2653 trsdbd, trsdbd ? "" : "Not ");
2654 if (sglsp || (!sglsp && aofdsl))
2655 printf(" [20:20]: %#x\tAddress Offsets %sSupported\n",
2656 aofdsl, aofdsl ? "" : "Not ");
2657 if (sglsp || (!sglsp && mpcsd))
2658 printf(" [19:19]: %#x\tMetadata Pointer Containing "
2659 "SGL Descriptor is %sSupported\n",
2660 mpcsd, mpcsd ? "" : "Not ");
2661 if (sglsp || (!sglsp && sglltb))
2662 printf(" [18:18]: %#x\tSGL Length Larger than Buffer %sSupported\n",
2663 sglltb, sglltb ? "" : "Not ");
2664 if (sglsp || (!sglsp && bacmdb))
2665 printf(" [17:17]: %#x\tByte-Aligned Contig. MD Buffer %sSupported\n",
2666 bacmdb, bacmdb ? "" : "Not ");
2667 if (sglsp || (!sglsp && bbs))
2668 printf(" [16:16]: %#x\tSGL Bit-Bucket %sSupported\n",
2669 bbs, bbs ? "" : "Not ");
2670 printf(" [15:8] : %#x\tSGL Descriptor Threshold\n", sdt);
2671 if (rsvd1)
2672 printf(" [7:3] : %#x\tReserved\n", rsvd1);
2673 if (sglsp || (!sglsp && key))
2674 printf(" [2:2] : %#x\tKeyed SGL Data Block descriptor %sSupported\n",
2675 key, key ? "" : "Not ");
2676 if (sglsp == 0x3)
2677 printf(" [1:0] : %#x\tReserved\n", sglsp);
2678 else if (sglsp == 0x2)
2679 printf(" [1:0] : %#x\tScatter-Gather Lists Supported."
2680 " Dword alignment required.\n", sglsp);
2681 else if (sglsp == 0x1)
2682 printf(" [1:0] : %#x\tScatter-Gather Lists Supported."
2683 " No Dword alignment required.\n", sglsp);
2684 else
2685 printf(" [1:0] : %#x\tScatter-Gather Lists Not Supported\n", sglsp);
2686 printf("\n");
2687}
2688
2689static void stdout_id_ctrl_trattr(__u8 ctrl_trattr)
2690{
2691 __u8 rsvd3 = (ctrl_trattr >> 3);
2692 __u8 mrtll = NVME_GET(ctrl_trattr, CTRL_TRATTR_MRTLL)(((ctrl_trattr) >> NVME_CTRL_TRATTR_MRTLL_SHIFT) & NVME_CTRL_TRATTR_MRTLL_MASK
)
;
2693 __u8 tudcs = NVME_GET(ctrl_trattr, CTRL_TRATTR_TUDCS)(((ctrl_trattr) >> NVME_CTRL_TRATTR_TUDCS_SHIFT) & NVME_CTRL_TRATTR_TUDCS_MASK
)
;
2694 __u8 thmcs = NVME_GET(ctrl_trattr, CTRL_TRATTR_THMCS)(((ctrl_trattr) >> NVME_CTRL_TRATTR_THMCS_SHIFT) & NVME_CTRL_TRATTR_THMCS_MASK
)
;
2695
2696 if (rsvd3)
2697 printf(" [7:3] : %#x\tReserved\n", rsvd3);
2698
2699 printf(" [2:2] : %#x\tMemory Range Tracking Length Limit\n", mrtll);
2700 printf(" [1:1] : %#x\tTracking User Data Changes %sSupported\n",
2701 tudcs, tudcs ? "" : "Not ");
2702 printf(" [0:0] : %#x\tTrack Host Memory Changes %sSupported\n",
2703 thmcs, thmcs ? "" : "Not ");
2704 printf("\n");
2705}
2706
2707static void stdout_id_ctrl_fcatt(__u8 fcatt)
2708{
2709 __u8 rsvd = (fcatt & 0xFE) >> 1;
2710 __u8 scm = fcatt & 0x1;
2711
2712 if (rsvd)
2713 printf(" [7:1] : %#x\tReserved\n", rsvd);
2714 printf(" [0:0] : %#x\t%s Controller Model\n",
2715 scm, scm ? "Static" : "Dynamic");
2716 printf("\n");
2717}
2718
2719static void stdout_id_ctrl_ofcs(__le16 ofcs)
2720{
2721 __u16 rsvd = (ofcs & 0xfffe) >> 1;
2722 __u8 disconn = ofcs & 0x1;
2723
2724 if (rsvd)
2725 printf(" [15:1] : %#x\tReserved\n", rsvd);
2726 printf(" [0:0] : %#x\tDisconnect command %s Supported\n",
2727 disconn, disconn ? "" : "Not");
2728 printf("\n");
2729
2730}
2731
2732static void stdout_id_ctrl_dctype(__u8 dctype)
2733{
2734 __u8 rsvd = (dctype & 0xFC) >> 2;
2735 __u8 dctype_val = dctype & 0x3;
2736 char *dctype_str;
2737
2738 if (rsvd)
2739 printf(" [7:3] : %#x\tReserved\n", rsvd);
2740 if (dctype_val == NVME_CTRL_DCTYPE_CDC)
2741 dctype_str = "CDC";
2742 else if (dctype_val == NVME_CTRL_DCTYPE_DDC)
2743 dctype_str = "DDC";
2744 else
2745 dctype_str = "not reported";
2746
2747 printf(" [0:2] : %#x\tDiscovery Controller Type: %s\n",
2748 dctype_val, dctype_str);
2749 printf("\n");
2750}
2751
2752static void stdout_id_ns_size(uint64_t nsze, uint64_t ncap, uint64_t nuse)
2753{
2754 printf("nsze : %#"PRIx64"l" "x""\tTotal size in logical blocks\n",
2755 le64_to_cpu(nsze));
2756 printf("ncap : %#"PRIx64"l" "x""\tMaximum size in logical blocks\n",
2757 le64_to_cpu(ncap));
2758 printf("nuse : %#"PRIx64"l" "x""\tCurrent size in logical blocks\n",
2759 le64_to_cpu(nuse));
2760}
2761
2762static void stdout_id_ns_nsfeat(__u8 nsfeat)
2763{
2764 __u8 optrperf = (nsfeat & 0x80) >> 7;
2765 __u8 mam = (nsfeat & 0x40) >> 6;
2766 __u8 optperf = (nsfeat & 0x30) >> 4;
2767 __u8 uidreuse = (nsfeat & 0x8) >> 3;
2768 __u8 dulbe = (nsfeat & 0x4) >> 2;
2769 __u8 na = (nsfeat & 0x2) >> 1;
2770 __u8 thin = nsfeat & 0x1;
2771
2772 printf(" [7:7] : %#x\tNPRG, NPRA and NORS are %sSupported\n",
2773 optrperf, optrperf ? "" : "Not ");
2774 printf(" [6:6] : %#x\t%s Atomicity Mode applies to write operations\n",
2775 mam, mam ? "Multiple" : "Single");
2776 printf(" [5:4] : %#x\tNPWG, NPWA, %s%sNPDA, and NOWS are %sSupported\n",
2777 optperf, ((optperf & 0x1) || (!optperf)) ? "NPDG, " : "",
2778 ((optperf & 0x2) || (!optperf)) ? "NPDGL, " : "", optperf ? "" : "Not ");
2779 printf(" [3:3] : %#x\tNGUID and EUI64 fields if non-zero, %sReused\n",
2780 uidreuse, uidreuse ? "Never " : "");
2781 printf(" [2:2] : %#x\tDeallocated or Unwritten Logical Block error %sSupported\n",
2782 dulbe, dulbe ? "" : "Not ");
2783 printf(" [1:1] : %#x\tNamespace uses %s\n",
2784 na, na ? "NAWUN, NAWUPF, and NACWU" : "AWUN, AWUPF, and ACWU");
2785 printf(" [0:0] : %#x\tThin Provisioning %sSupported\n",
2786 thin, thin ? "" : "Not ");
2787 printf("\n");
2788}
2789
2790static void stdout_id_ns_flbas(__u8 flbas)
2791{
2792 __u8 rsvd = (flbas & 0x80) >> 7;
2793 __u8 msb2_lbaf = NVME_FLBAS_HIGHER(flbas)(((flbas) >> NVME_FLBAS_HIGHER_SHIFT) & NVME_FLBAS_HIGHER_MASK
)
;
2794 __u8 mdedata = NVME_FLBAS_META_EXT(flbas)(((flbas) >> NVME_FLBAS_META_EXT_SHIFT) & NVME_FLBAS_META_EXT_MASK
)
;
2795 __u8 lsb4_lbaf = NVME_FLBAS_LOWER(flbas)(((flbas) >> NVME_FLBAS_LOWER_SHIFT) & NVME_FLBAS_LOWER_MASK
)
;
2796
2797 if (rsvd)
2798 printf(" [7:7] : %#x\tReserved\n", rsvd);
2799 printf(" [6:5] : %#x\tMost significant 2 bits of Current LBA Format Selected\n",
2800 msb2_lbaf);
2801 printf(" [4:4] : %#x\tMetadata Transferred %s\n",
2802 mdedata, mdedata ? "at End of Data LBA" : "in Separate Contiguous Buffer");
2803 printf(" [3:0] : %#x\tLeast significant 4 bits of Current LBA Format Selected\n",
2804 lsb4_lbaf);
2805 printf("\n");
2806}
2807
2808static void stdout_id_ns_mc(__u8 mc)
2809{
2810 __u8 rsvd = (mc & 0xFC) >> 2;
2811 __u8 mdp = (mc & 0x2) >> 1;
2812 __u8 extdlba = mc & 0x1;
2813
2814 if (rsvd)
2815 printf(" [7:2] : %#x\tReserved\n", rsvd);
2816 printf(" [1:1] : %#x\tMetadata Pointer %sSupported\n",
2817 mdp, mdp ? "" : "Not ");
2818 printf(" [0:0] : %#x\tMetadata as Part of Extended Data LBA %sSupported\n",
2819 extdlba, extdlba ? "" : "Not ");
2820 printf("\n");
2821}
2822
2823static void stdout_id_ns_dpc(__u8 dpc)
2824{
2825 __u8 rsvd = (dpc & 0xE0) >> 5;
2826 __u8 pil8 = (dpc & 0x10) >> 4;
2827 __u8 pif8 = (dpc & 0x8) >> 3;
2828 __u8 pit3 = (dpc & 0x4) >> 2;
2829 __u8 pit2 = (dpc & 0x2) >> 1;
2830 __u8 pit1 = dpc & 0x1;
2831
2832 if (rsvd)
2833 printf(" [7:5] : %#x\tReserved\n", rsvd);
2834 printf(" [4:4] : %#x\tProtection Information Transferred as Last Bytes of Metadata %sSupported\n",
2835 pil8, pil8 ? "" : "Not ");
2836 printf(" [3:3] : %#x\tProtection Information Transferred as First Bytes of Metadata %sSupported\n",
2837 pif8, pif8 ? "" : "Not ");
2838 printf(" [2:2] : %#x\tProtection Information Type 3 %sSupported\n",
2839 pit3, pit3 ? "" : "Not ");
2840 printf(" [1:1] : %#x\tProtection Information Type 2 %sSupported\n",
2841 pit2, pit2 ? "" : "Not ");
2842 printf(" [0:0] : %#x\tProtection Information Type 1 %sSupported\n",
2843 pit1, pit1 ? "" : "Not ");
2844 printf("\n");
2845}
2846
2847static void stdout_id_ns_dps(__u8 dps)
2848{
2849 __u8 rsvd = (dps & 0xF0) >> 4;
2850 __u8 pif8 = (dps & 0x8) >> 3;
2851 __u8 pit = dps & 0x7;
2852
2853 if (rsvd)
2854 printf(" [7:4] : %#x\tReserved\n", rsvd);
2855 printf(" [3:3] : %#x\tProtection Information is Transferred as %s Bytes of Metadata\n",
2856 pif8, pif8 ? "First" : "Last");
2857 printf(" [2:0] : %#x\tProtection Information %s\n", pit,
2858 pit == 3 ? "Type 3 Enabled" :
2859 pit == 2 ? "Type 2 Enabled" :
2860 pit == 1 ? "Type 1 Enabled" :
2861 pit == 0 ? "Disabled" : "Reserved Enabled");
2862 printf("\n");
2863}
2864
2865static void stdout_id_ns_nmic(__u8 nmic)
2866{
2867 __u8 rsvd = (nmic & 0xfc) >> 2;
2868 __u8 disns = (nmic & 0x2) >> 1;
2869 __u8 shrns = nmic & 0x1;
2870
2871 if (rsvd)
2872 printf(" [7:2] : %#x\tReserved\n", rsvd);
2873 printf(" [1:1] : %#x\tNamespace is %sa Dispersed Namespace\n",
2874 disns, disns ? "" : "Not ");
2875 printf(" [0:0] : %#x\tNamespace Multipath %sCapable\n",
2876 shrns, shrns ? "" : "Not ");
2877 printf("\n");
2878}
2879
2880static void stdout_id_ns_rescap(__u8 rescap)
2881{
2882 __u8 iekr = (rescap & 0x80) >> 7;
2883 __u8 eaar = (rescap & 0x40) >> 6;
2884 __u8 wear = (rescap & 0x20) >> 5;
2885 __u8 earo = (rescap & 0x10) >> 4;
2886 __u8 wero = (rescap & 0x8) >> 3;
2887 __u8 ea = (rescap & 0x4) >> 2;
2888 __u8 we = (rescap & 0x2) >> 1;
2889 __u8 ptpl = rescap & 0x1;
2890
2891 printf(" [7:7] : %#x\tIgnore Existing Key - Used as defined in revision %s\n",
2892 iekr, iekr ? "1.3 or later" : "1.2.1 or earlier");
2893 printf(" [6:6] : %#x\tExclusive Access - All Registrants %sSupported\n",
2894 eaar, eaar ? "" : "Not ");
2895 printf(" [5:5] : %#x\tWrite Exclusive - All Registrants %sSupported\n",
2896 wear, wear ? "" : "Not ");
2897 printf(" [4:4] : %#x\tExclusive Access - Registrants Only %sSupported\n",
2898 earo, earo ? "" : "Not ");
2899 printf(" [3:3] : %#x\tWrite Exclusive - Registrants Only %sSupported\n",
2900 wero, wero ? "" : "Not ");
2901 printf(" [2:2] : %#x\tExclusive Access %sSupported\n",
2902 ea, ea ? "" : "Not ");
2903 printf(" [1:1] : %#x\tWrite Exclusive %sSupported\n",
2904 we, we ? "" : "Not ");
2905 printf(" [0:0] : %#x\tPersist Through Power Loss %sSupported\n",
2906 ptpl, ptpl ? "" : "Not ");
2907 printf("\n");
2908}
2909
2910static void stdout_id_ns_fpi(__u8 fpi)
2911{
2912 __u8 fpis = (fpi & 0x80) >> 7;
2913 __u8 fpii = fpi & 0x7F;
2914
2915 printf(" [7:7] : %#x\tFormat Progress Indicator %sSupported\n",
2916 fpis, fpis ? "" : "Not ");
2917 if (fpis || (!fpis && fpii))
2918 printf(" [6:0] : %#x\tFormat Progress Indicator (Remaining %d%%)\n",
2919 fpii, fpii);
2920 printf("\n");
2921}
2922
2923static void stdout_id_ns_nsattr(__u8 nsattr)
2924{
2925 __u8 rsvd = (nsattr & 0xFE) >> 1;
2926 __u8 write_protected = nsattr & 0x1;
2927
2928 if (rsvd)
2929 printf(" [7:1] : %#x\tReserved\n", rsvd);
2930 printf(" [0:0] : %#x\tNamespace %sWrite Protected\n",
2931 write_protected, write_protected ? "" : "Not ");
2932 printf("\n");
2933}
2934
2935static void stdout_id_ns_dlfeat(__u8 dlfeat)
2936{
2937 __u8 rsvd = (dlfeat & 0xE0) >> 5;
2938 __u8 guard = (dlfeat & 0x10) >> 4;
2939 __u8 dwz = (dlfeat & 0x8) >> 3;
2940 __u8 val = dlfeat & 0x7;
2941
2942 if (rsvd)
2943 printf(" [7:5] : %#x\tReserved\n", rsvd);
2944 printf(" [4:4] : %#x\tGuard Field of Deallocated Logical Blocks is set to %s\n",
2945 guard, guard ? "CRC of The Value Read" : "0xFFFF");
2946 printf(" [3:3] : %#x\tDeallocate Bit in the Write Zeroes Command is %sSupported\n",
2947 dwz, dwz ? "" : "Not ");
2948 printf(" [2:0] : %#x\tBytes Read From a Deallocated Logical Block and its Metadata are %s\n",
2949 val, val == 2 ? "0xFF" :
2950 val == 1 ? "0x00" :
2951 val == 0 ? "Not Reported" : "Reserved Value");
2952 printf("\n");
2953}
2954
2955static void stdout_id_ns_kpios(__u8 kpios)
2956{
2957 __u8 rsvd = (kpios & 0xfc) >> 2;
2958 __u8 kpiosns = (kpios & 0x2) >> 1;
2959 __u8 kpioens = kpios & 0x1;
2960
2961 if (rsvd)
2962 printf(" [7:2] : %#x\tReserved\n", rsvd);
2963 printf(" [1:1] : %#x\tKey Per I/O Capability %sSupported\n",
2964 kpiosns, kpiosns ? "" : "Not ");
2965 printf(" [0:0] : %#x\tKey Per I/O Capability %s\n", kpioens,
2966 kpioens ? "Enabled" : "Disabled");
2967 printf("\n");
2968}
2969
2970static void stdout_id_ns(struct nvme_id_ns *ns, unsigned int nsid,
2971 unsigned int lba_index, bool_Bool cap_only)
2972{
2973 bool_Bool human = stdout_print_ops.flags & VERBOSE;
2974 int vs = stdout_print_ops.flags & VS;
2975 int i;
2976 __u8 flbas;
2977 char *in_use = "(in use)";
2978
2979 if (!cap_only) {
2980 printf("NVME Identify Namespace %d:\n", nsid);
2981
2982 if (human)
2983 stdout_id_ns_size(ns->nsze, ns->ncap, ns->nuse);
2984 else {
2985 printf("nsze : %#"PRIx64"l" "x""\n", le64_to_cpu(ns->nsze));
2986 printf("ncap : %#"PRIx64"l" "x""\n", le64_to_cpu(ns->ncap));
2987 printf("nuse : %#"PRIx64"l" "x""\n", le64_to_cpu(ns->nuse));
2988 }
2989
2990 printf("nsfeat : %#x\n", ns->nsfeat);
2991 if (human)
2992 stdout_id_ns_nsfeat(ns->nsfeat);
2993 } else
2994 printf("NVMe Identify Namespace for LBA format[%d]:\n", lba_index);
2995
2996 printf("nlbaf : %d\n", ns->nlbaf);
2997 if (!cap_only) {
2998 printf("flbas : %#x\n", ns->flbas);
2999 if (human)
3000 stdout_id_ns_flbas(ns->flbas);
3001 } else
3002 in_use = "";
3003
3004 printf("mc : %#x\n", ns->mc);
3005 if (human)
3006 stdout_id_ns_mc(ns->mc);
3007 printf("dpc : %#x\n", ns->dpc);
3008 if (human)
3009 stdout_id_ns_dpc(ns->dpc);
3010 if (!cap_only) {
3011 printf("dps : %#x\n", ns->dps);
3012 if (human)
3013 stdout_id_ns_dps(ns->dps);
3014 printf("nmic : %#x\n", ns->nmic);
3015 if (human)
3016 stdout_id_ns_nmic(ns->nmic);
3017 printf("rescap : %#x\n", ns->rescap);
3018 if (human)
3019 stdout_id_ns_rescap(ns->rescap);
3020 printf("fpi : %#x\n", ns->fpi);
3021 if (human)
3022 stdout_id_ns_fpi(ns->fpi);
3023 printf("dlfeat : %d\n", ns->dlfeat);
3024 if (human)
3025 stdout_id_ns_dlfeat(ns->dlfeat);
3026 printf("nawun : %d\n", le16_to_cpu(ns->nawun));
3027 printf("nawupf : %d\n", le16_to_cpu(ns->nawupf));
3028 printf("nacwu : %d\n", le16_to_cpu(ns->nacwu));
3029 printf("nabsn : %d\n", le16_to_cpu(ns->nabsn));
3030 printf("nabo : %d\n", le16_to_cpu(ns->nabo));
3031 printf("nabspf : %d\n", le16_to_cpu(ns->nabspf));
3032 printf("noiob : %d\n", le16_to_cpu(ns->noiob));
3033 printf("nvmcap : %s\n",
3034 uint128_t_to_l10n_string(le128_to_cpu(ns->nvmcap)));
3035 if (ns->nsfeat & 0x30) {
3036 printf("npwg : %u\n", le16_to_cpu(ns->npwg));
3037 printf("npwa : %u\n", le16_to_cpu(ns->npwa));
3038 if (ns->nsfeat & 0x10)
3039 printf("npdg : %u\n", le16_to_cpu(ns->npdg));
3040 printf("npda : %u\n", le16_to_cpu(ns->npda));
3041 printf("nows : %u\n", le16_to_cpu(ns->nows));
3042 }
3043 printf("mssrl : %u\n", le16_to_cpu(ns->mssrl));
3044 printf("mcl : %u\n", le32_to_cpu(ns->mcl));
3045 printf("msrc : %u\n", ns->msrc);
3046 printf("kpios : %u\n", ns->kpios);
3047 if (human)
3048 stdout_id_ns_kpios(ns->kpios);
3049 }
3050 printf("nulbaf : %u\n", ns->nulbaf);
3051 if (!cap_only) {
3052 printf("kpiodaag: %u\n", le32_to_cpu(ns->kpiodaag));
3053 printf("anagrpid: %u\n", le32_to_cpu(ns->anagrpid));
3054 printf("nsattr : %u\n", ns->nsattr);
3055 if (human)
3056 stdout_id_ns_nsattr(ns->nsattr);
3057 printf("nvmsetid: %d\n", le16_to_cpu(ns->nvmsetid));
3058 printf("endgid : %d\n", le16_to_cpu(ns->endgid));
3059
3060 printf("nguid : ");
3061 for (i = 0; i < 16; i++)
3062 printf("%02x", ns->nguid[i]);
3063 printf("\n");
3064
3065 printf("eui64 : ");
3066 for (i = 0; i < 8; i++)
3067 printf("%02x", ns->eui64[i]);
3068 printf("\n");
3069 }
3070
3071 nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &flbas);
3072 for (i = 0; i <= ns->nlbaf + ns->nulbaf; i++) {
3073 if (human)
3074 printf("LBA Format %2d : Metadata Size: %-3d bytes - "
3075 "Data Size: %-2d bytes - Relative Performance: %#x %s %s\n",
3076 i, le16_to_cpu(ns->lbaf[i].ms),
3077 1 << ns->lbaf[i].ds, ns->lbaf[i].rp,
3078 ns->lbaf[i].rp == 3 ? "Degraded" :
3079 ns->lbaf[i].rp == 2 ? "Good" :
3080 ns->lbaf[i].rp == 1 ? "Better" : "Best",
3081 i == flbas ? in_use : "");
3082 else
3083 printf("lbaf %2d : ms:%-3d lbads:%-2d rp:%#x %s\n", i,
3084 le16_to_cpu(ns->lbaf[i].ms), ns->lbaf[i].ds,
3085 ns->lbaf[i].rp, i == flbas ? in_use : "");
3086 }
3087
3088 if (vs && !cap_only) {
3089 printf("vs[]:\n");
3090 d(ns->vs, sizeof(ns->vs), 16, 1);
3091 }
3092}
3093
3094static void stdout_cmd_set_independent_id_ns_nsfeat(__u8 nsfeat)
3095{
3096 __u8 rsvd6 = (nsfeat & 0xE0) >> 6;
3097 __u8 vwcnp = (nsfeat & 0x20) >> 5;
3098 __u8 rmedia = (nsfeat & 0x10) >> 4;
3099 __u8 uidreuse = (nsfeat & 0x8) >> 3;
3100 __u8 rsvd0 = (nsfeat & 0x7);
3101
3102 if (rsvd6)
3103 printf(" [7:6] : %#x\tReserved\n", rsvd6);
3104 printf(" [5:5] : %#x\tVolatile Write Cache is %sPresent\n",
3105 vwcnp, vwcnp ? "" : "Not ");
3106 printf(" [4:4] : %#x\tNamespace %sstore data on rotational media\n",
3107 rmedia, rmedia ? "" : "does not ");
3108 printf(" [3:3] : %#x\tNGUID and EUI64 fields if non-zero, %sReused\n",
3109 uidreuse, uidreuse ? "Never " : "");
3110 if (rsvd0)
3111 printf(" [2:0] : %#x\tReserved\n", rsvd0);
3112 printf("\n");
3113}
3114
3115static void stdout_cmd_set_independent_id_ns_nstat(__u8 nstat)
3116{
3117 __u8 rsvd3 = (nstat & 0xf8) >> 3;
3118 __u8 ioi = (nstat & 0x6) >> 1;
3119 __u8 nrdy = nstat & 0x1;
3120
3121 static const char * const ioi_string[] = {
3122 "I/O performance degradation is not reported",
3123 "Reserved",
3124 "I/O performance is not currently degraded",
3125 "I/O performance is currently degraded"
3126 };
3127
3128 if (rsvd3)
3129 printf(" [7:3] : %#x\tReserved\n", rsvd3);
3130 printf(" [2:1] : %#x\t%s\n", ioi, ioi_string[ioi]);
3131 printf(" [0:0] : %#x\tName space is %sready\n",
3132 nrdy, nrdy ? "" : "not ");
3133 printf("\n");
3134}
3135
3136static void stdout_cmd_set_independent_id_ns(struct nvme_id_independent_id_ns *ns,
3137 unsigned int nsid)
3138{
3139 int human = stdout_print_ops.flags & VERBOSE;
3140
3141 printf("NVME Identify Command Set Independent Namespace %d:\n", nsid);
3142 printf("nsfeat : %#x\n", ns->nsfeat);
3143 if (human)
3144 stdout_cmd_set_independent_id_ns_nsfeat(ns->nsfeat);
3145 printf("nmic : %#x\n", ns->nmic);
3146 if (human)
3147 stdout_id_ns_nmic(ns->nmic);
3148 printf("rescap : %#x\n", ns->rescap);
3149 if (human)
3150 stdout_id_ns_rescap(ns->rescap);
3151 printf("fpi : %#x\n", ns->fpi);
3152 if (human)
3153 stdout_id_ns_fpi(ns->fpi);
3154 printf("anagrpid: %u\n", le32_to_cpu(ns->anagrpid));
3155 printf("nsattr : %u\n", ns->nsattr);
3156 if (human)
3157 stdout_id_ns_nsattr(ns->nsattr);
3158 printf("nvmsetid: %d\n", le16_to_cpu(ns->nvmsetid));
3159 printf("endgid : %d\n", le16_to_cpu(ns->endgid));
3160
3161 printf("nstat : %#x\n", ns->nstat);
3162 if (human)
3163 stdout_cmd_set_independent_id_ns_nstat(ns->nstat);
3164 printf("kpios : %#x\n", ns->kpios);
3165 if (human)
3166 stdout_id_ns_kpios(ns->kpios);
3167 printf("maxkt : %#x\n", le16_to_cpu(ns->maxkt));
3168 printf("rgrpid : %#x\n", le32_to_cpu(ns->rgrpid));
3169}
3170
3171static void stdout_id_ns_descs(void *data, unsigned int nsid)
3172{
3173 int pos, len = 0;
3174 int i, verbose = stdout_print_ops.flags & VERBOSE;
3175 __u8 uuid[NVME_UUID_LEN16];
3176 char uuid_str[NVME_UUID_LEN_STRING37];
3177 __u8 eui64[8];
3178 __u8 nguid[16];
3179 __u8 csi;
3180
3181 printf("NVME Namespace Identification Descriptors NS %d:\n", nsid);
3182 for (pos = 0; pos < NVME_IDENTIFY_DATA_SIZE; pos += len) {
3183 struct nvme_ns_id_desc *cur = data + pos;
3184
3185 if (cur->nidl == 0)
3186 break;
3187
3188 if (verbose) {
3189 printf("loc : %d\n", pos);
3190 printf("nidt : %d\n", (int)cur->nidt);
3191 printf("nidl : %d\n", (int)cur->nidl);
3192 }
3193
3194 switch (cur->nidt) {
3195 case NVME_NIDT_EUI64:
3196 memcpy(eui64, data + pos + sizeof(*cur), sizeof(eui64));
3197 if (verbose)
3198 printf("type : eui64\n");
3199 printf("eui64 : ");
3200 for (i = 0; i < 8; i++)
3201 printf("%02x", eui64[i]);
3202 printf("\n");
3203 len = sizeof(eui64);
3204 break;
3205 case NVME_NIDT_NGUID:
3206 memcpy(nguid, data + pos + sizeof(*cur), sizeof(nguid));
3207 if (verbose)
3208 printf("type : nguid\n");
3209 printf("nguid : ");
3210 for (i = 0; i < 16; i++)
3211 printf("%02x", nguid[i]);
3212 printf("\n");
3213 len = sizeof(nguid);
3214 break;
3215 case NVME_NIDT_UUID:
3216 memcpy(uuid, data + pos + sizeof(*cur), 16);
3217 libnvme_uuid_to_string(uuid, uuid_str);
3218 if (verbose)
3219 printf("type : uuid\n");
3220 printf("uuid : %s\n", uuid_str);
3221 len = sizeof(uuid);
3222 break;
3223 case NVME_NIDT_CSI:
3224 memcpy(&csi, data + pos + sizeof(*cur), 1);
3225 if (verbose)
3226 printf("type : csi\n");
3227 printf("csi : %#x\n", csi);
3228 len += sizeof(csi);
3229 break;
3230 default:
3231 /* Skip unknown types */
3232 len = cur->nidl;
3233 break;
3234 }
3235
3236 len += sizeof(*cur);
3237 }
3238}
3239
3240static void print_psd_workload(__u8 apw)
3241{
3242 switch (apw & 0x7) {
3243 case NVME_PSD_WORKLOAD_NP:
3244 /* Unknown or not provided */
3245 printf("-");
3246 break;
3247 case 1:
3248 /* Extended idle period with burst of random write */
3249 printf("1MiB 32 RW, 30s idle");
3250 break;
3251 case 2:
3252 /* Heavy sequential writes */
3253 printf("80K 128KiB SW");
3254 break;
3255 default:
3256 printf("reserved");
3257 break;
3258 }
3259}
3260
3261static void print_power_and_scale(__u16 power, __u8 scale)
3262{
3263 switch (scale & 0x3) {
3264 case NVME_PSD_PS_NOT_REPORTED:
3265 /* Not reported for this power state */
3266 printf("-");
3267 break;
3268 case NVME_PSD_PS_100_MICRO_WATT:
3269 /* Units of 0.0001W */
3270 printf("%01u.%04uW", power / 10000, power % 10000);
3271 break;
3272 case NVME_PSD_PS_10_MILLI_WATT:
3273 /* Units of 0.01W */
3274 printf("%01u.%02uW", power / 100, power % 100);
3275 break;
3276 default:
3277 printf("reserved");
3278 break;
3279 }
3280}
3281
3282static void print_ps_power_and_scale(__le16 ctr_power, __u8 scale)
3283{
3284 print_power_and_scale(le16_to_cpu(ctr_power), scale);
3285}
3286
3287static void print_power_field(__u32 pwr)
3288{
3289 print_power_and_scale(pwr & 0xffff, (pwr >> 16) & 0x3);
3290}
3291
3292static void print_psd_time(const char *desc, __u8 time, __u8 ts)
3293{
3294 int width = 12 + strlen(desc);
3295 char value[STR_LEN100] = { 0 };
3296
3297 switch (time) {
3298 case 0:
3299 snprintf(value, sizeof(value), "-");
3300 break;
3301 case 1 ... 99:
3302 snprintf(value, sizeof(value), "%d (unit: %s)", time,
3303 nvme_time_scale_to_string(ts));
3304 break;
3305 default:
3306 snprintf(value, sizeof(value), "reserved");
3307 break;
3308 }
3309
3310 printf("%*s: %s\n", width, desc, value);
3311}
3312
3313static void stdout_id_ctrl_power(struct nvme_id_ctrl *ctrl)
3314{
3315 int i;
3316
3317 for (i = 0; i <= ctrl->npss; i++) {
3318 __u16 max_power = le16_to_cpu(ctrl->psd[i].mp);
3319
3320 printf("ps %4d : mp:", i);
3321
3322 if (ctrl->psd[i].flags & NVME_PSD_FLAGS_MXPS)
3323 printf("%01u.%04uW ", max_power / 10000, max_power % 10000);
3324 else
3325 printf("%01u.%02uW ", max_power / 100, max_power % 100);
3326
3327 if (ctrl->psd[i].flags & NVME_PSD_FLAGS_NOPS)
3328 printf("non-");
3329
3330 printf("operational enlat:%d exlat:%d rrt:%d rrl:%d\n"
3331 " rwt:%d rwl:%d idle_power:",
3332 le32_to_cpu(ctrl->psd[i].enlat),
3333 le32_to_cpu(ctrl->psd[i].exlat),
3334 ctrl->psd[i].rrt, ctrl->psd[i].rrl,
3335 ctrl->psd[i].rwt, ctrl->psd[i].rwl);
3336 print_ps_power_and_scale(ctrl->psd[i].idlp,
3337 nvme_psd_power_scale(ctrl->psd[i].ips));
3338 printf(" active_power:");
3339 print_ps_power_and_scale(ctrl->psd[i].actp,
3340 nvme_psd_power_scale(ctrl->psd[i].apws));
3341 printf("\n active_power_workload:");
3342 print_psd_workload(ctrl->psd[i].apws);
3343 printf("\n");
3344 print_psd_time("emergency power fail recovery time", ctrl->psd[i].epfrt,
3345 ctrl->psd[i].epfr_fqv_ts & 0xf);
3346 print_psd_time("forced quiescence vault time", ctrl->psd[i].fqvt,
3347 ctrl->psd[i].epfr_fqv_ts >> 4);
3348 print_psd_time("emergency power fail vault time", ctrl->psd[i].epfvt,
3349 ctrl->psd[i].epfvts & 0xf);
3350 }
3351}
3352
3353static void stdout_id_ctrl(struct nvme_id_ctrl *ctrl, const char *product_name,
3354 void (*vendor_show)(__u8 *vs, struct json_object *root))
3355{
3356 bool_Bool human = stdout_print_ops.flags & VERBOSE, vs = stdout_print_ops.flags & VS;
3357
3358 if (human && product_name)
3359 printf("%s\n\n", product_name);
3360
3361 printf("NVME Identify Controller:\n");
3362 printf("vid : %#x\n", le16_to_cpu(ctrl->vid));
3363 printf("ssvid : %#x\n", le16_to_cpu(ctrl->ssvid));
3364 printf("sn : %-.*s\n", (int)sizeof(ctrl->sn), ctrl->sn);
3365 printf("mn : %-.*s\n", (int)sizeof(ctrl->mn), ctrl->mn);
3366 printf("fr : %-.*s\n", (int)sizeof(ctrl->fr), ctrl->fr);
3367 printf("rab : %d\n", ctrl->rab);
3368 printf("ieee : %02x%02x%02x\n",
3369 ctrl->ieee[2], ctrl->ieee[1], ctrl->ieee[0]);
3370 printf("cmic : %#x\n", ctrl->cmic);
3371 if (human)
3372 stdout_id_ctrl_cmic(ctrl->cmic);
3373 printf("mdts : %d\n", ctrl->mdts);
3374 printf("cntlid : %#x\n", le16_to_cpu(ctrl->cntlid));
3375 printf("ver : %#x\n", le32_to_cpu(ctrl->ver));
3376 printf("rtd3r : %#x\n", le32_to_cpu(ctrl->rtd3r));
3377 printf("rtd3e : %#x\n", le32_to_cpu(ctrl->rtd3e));
3378 printf("oaes : %#x\n", le32_to_cpu(ctrl->oaes));
3379 if (human)
3380 stdout_id_ctrl_oaes(ctrl->oaes);
3381 printf("ctratt : %#x\n", le32_to_cpu(ctrl->ctratt));
3382 if (human)
3383 stdout_id_ctrl_ctratt(ctrl->ctratt);
3384 printf("rrls : %#x\n", le16_to_cpu(ctrl->rrls));
3385 printf("bpcap : %#x\n", le16_to_cpu(ctrl->bpcap));
3386 if (human)
3387 stdout_id_ctrl_bpcap(ctrl->bpcap);
3388 printf("nssl : %#x\n", le32_to_cpu(ctrl->nssl));
3389 printf("plsi : %u\n", ctrl->plsi);
3390 if (human)
3391 stdout_id_ctrl_plsi(ctrl->plsi);
3392 printf("cntrltype : %d\n", ctrl->cntrltype);
3393 if (human)
3394 stdout_id_ctrl_cntrltype(ctrl->cntrltype);
3395 printf("fguid : %s\n", util_uuid_to_string(ctrl->fguid));
3396 printf("crdt1 : %u\n", le16_to_cpu(ctrl->crdt1));
3397 printf("crdt2 : %u\n", le16_to_cpu(ctrl->crdt2));
3398 printf("crdt3 : %u\n", le16_to_cpu(ctrl->crdt3));
3399 printf("crcap : %u\n", ctrl->crcap);
3400 if (human)
3401 stdout_id_ctrl_crcap(ctrl->crcap);
3402 printf("nvmsr : %u\n", ctrl->nvmsr);
3403 if (human)
3404 stdout_id_ctrl_nvmsr(ctrl->nvmsr);
3405 printf("vwci : %u\n", ctrl->vwci);
3406 if (human)
3407 stdout_id_ctrl_vwci(ctrl->vwci);
3408 printf("mec : %u\n", ctrl->mec);
3409 if (human)
3410 stdout_id_ctrl_mec(ctrl->mec);
3411
3412 printf("oacs : %#x\n", le16_to_cpu(ctrl->oacs));
3413 if (human)
3414 stdout_id_ctrl_oacs(ctrl->oacs);
3415 printf("acl : %d\n", ctrl->acl);
3416 printf("aerl : %d\n", ctrl->aerl);
3417 printf("frmw : %#x\n", ctrl->frmw);
3418 if (human)
3419 stdout_id_ctrl_frmw(ctrl->frmw);
3420 printf("lpa : %#x\n", ctrl->lpa);
3421 if (human)
3422 stdout_id_ctrl_lpa(ctrl->lpa);
3423 printf("elpe : %d\n", ctrl->elpe);
3424 if (human)
3425 stdout_id_ctrl_elpe(ctrl->elpe);
3426 printf("npss : %d\n", ctrl->npss);
3427 if (human)
3428 stdout_id_ctrl_npss(ctrl->npss);
3429 printf("avscc : %#x\n", ctrl->avscc);
3430 if (human)
3431 stdout_id_ctrl_avscc(ctrl->avscc);
3432 printf("apsta : %#x\n", ctrl->apsta);
3433 if (human)
3434 stdout_id_ctrl_apsta(ctrl->apsta);
3435 printf("wctemp : %d\n", le16_to_cpu(ctrl->wctemp));
3436 if (human)
3437 stdout_id_ctrl_wctemp(ctrl->wctemp);
3438 printf("cctemp : %d\n", le16_to_cpu(ctrl->cctemp));
3439 if (human)
3440 stdout_id_ctrl_cctemp(ctrl->cctemp);
3441 printf("mtfa : %d\n", le16_to_cpu(ctrl->mtfa));
3442 printf("hmpre : %u\n", le32_to_cpu(ctrl->hmpre));
3443 printf("hmmin : %u\n", le32_to_cpu(ctrl->hmmin));
3444 printf("tnvmcap : %s\n",
3445 uint128_t_to_l10n_string(le128_to_cpu(ctrl->tnvmcap)));
3446 if (human)
3447 stdout_id_ctrl_tnvmcap(ctrl->tnvmcap);
3448 printf("unvmcap : %s\n",
3449 uint128_t_to_l10n_string(le128_to_cpu(ctrl->unvmcap)));
3450 if (human)
3451 stdout_id_ctrl_unvmcap(ctrl->unvmcap);
3452 printf("rpmbs : %#x\n", le32_to_cpu(ctrl->rpmbs));
3453 if (human)
3454 stdout_id_ctrl_rpmbs(ctrl->rpmbs);
3455 printf("edstt : %d\n", le16_to_cpu(ctrl->edstt));
3456 printf("dsto : %d\n", ctrl->dsto);
3457 if (human)
3458 stdout_id_ctrl_dsto(ctrl->dsto);
3459 printf("fwug : %d\n", ctrl->fwug);
3460 printf("kas : %d\n", le16_to_cpu(ctrl->kas));
3461 printf("hctma : %#x\n", le16_to_cpu(ctrl->hctma));
3462 if (human)
3463 stdout_id_ctrl_hctma(ctrl->hctma);
3464 printf("mntmt : %d\n", le16_to_cpu(ctrl->mntmt));
3465 if (human)
3466 stdout_id_ctrl_mntmt(ctrl->mntmt);
3467 printf("mxtmt : %d\n", le16_to_cpu(ctrl->mxtmt));
3468 if (human)
3469 stdout_id_ctrl_mxtmt(ctrl->mxtmt);
3470 printf("sanicap : %#x\n", le32_to_cpu(ctrl->sanicap));
3471 if (human)
3472 stdout_id_ctrl_sanicap(ctrl->sanicap);
3473 printf("hmminds : %u\n", le32_to_cpu(ctrl->hmminds));
3474 printf("hmmaxd : %d\n", le16_to_cpu(ctrl->hmmaxd));
3475 printf("nsetidmax : %d\n", le16_to_cpu(ctrl->nsetidmax));
3476 printf("endgidmax : %d\n", le16_to_cpu(ctrl->endgidmax));
3477 printf("anatt : %d\n", ctrl->anatt);
3478 printf("anacap : %d\n", ctrl->anacap);
3479 if (human)
3480 stdout_id_ctrl_anacap(ctrl->anacap);
3481 printf("anagrpmax : %u\n", ctrl->anagrpmax);
3482 printf("nanagrpid : %u\n", le32_to_cpu(ctrl->nanagrpid));
3483 printf("pels : %u\n", le32_to_cpu(ctrl->pels));
3484 printf("domainid : %d\n", le16_to_cpu(ctrl->domainid));
3485 printf("kpioc : %u\n", ctrl->kpioc);
3486 if (human)
3487 stdout_id_ctrl_kpioc(ctrl->kpioc);
3488 printf("mptfawr : %d\n", le16_to_cpu(ctrl->mptfawr));
3489 printf("megcap : %s\n",
3490 uint128_t_to_l10n_string(le128_to_cpu(ctrl->megcap)));
3491 printf("tmpthha : %#x\n", ctrl->tmpthha);
3492 if (human)
3493 stdout_id_ctrl_tmpthha(ctrl->tmpthha);
3494 printf("cqt : %d\n", le16_to_cpu(ctrl->cqt));
3495 printf("cdpa : %d\n", le16_to_cpu(ctrl->cdpa));
3496 if (human)
3497 stdout_id_ctrl_cdpa(ctrl->cdpa);
3498 printf("mup : %d\n", le16_to_cpu(ctrl->mup));
3499 printf("ipmsr : %#x\n", le16_to_cpu(ctrl->ipmsr));
3500 if (human)
3501 stdout_id_ctrl_ipmsr(ctrl->ipmsr);
3502 printf("msmt : %#x\n", le16_to_cpu(ctrl->msmt));
3503 printf("sqes : %#x\n", ctrl->sqes);
3504 if (human)
3505 stdout_id_ctrl_sqes(ctrl->sqes);
3506 printf("cqes : %#x\n", ctrl->cqes);
3507 if (human)
3508 stdout_id_ctrl_cqes(ctrl->cqes);
3509 printf("maxcmd : %d\n", le16_to_cpu(ctrl->maxcmd));
3510 printf("nn : %u\n", le32_to_cpu(ctrl->nn));
3511 printf("oncs : %#x\n", le16_to_cpu(ctrl->oncs));
3512 if (human)
3513 stdout_id_ctrl_oncs(ctrl->oncs);
3514 printf("fuses : %#x\n", le16_to_cpu(ctrl->fuses));
3515 if (human)
3516 stdout_id_ctrl_fuses(ctrl->fuses);
3517 printf("fna : %#x\n", ctrl->fna);
3518 if (human)
3519 stdout_id_ctrl_fna(ctrl->fna);
3520 printf("vwc : %#x\n", ctrl->vwc);
3521 if (human)
3522 stdout_id_ctrl_vwc(ctrl->vwc);
3523 printf("awun : %d\n", le16_to_cpu(ctrl->awun));
3524 printf("awupf : %d\n", le16_to_cpu(ctrl->awupf));
3525 printf("icsvscc : %d\n", ctrl->icsvscc);
3526 if (human)
3527 stdout_id_ctrl_icsvscc(ctrl->icsvscc);
3528 printf("nwpc : %d\n", ctrl->nwpc);
3529 if (human)
3530 stdout_id_ctrl_nwpc(ctrl->nwpc);
3531 printf("acwu : %d\n", le16_to_cpu(ctrl->acwu));
3532 printf("ocfs : %#x\n", le16_to_cpu(ctrl->ocfs));
3533 if (human)
3534 stdout_id_ctrl_ocfs(ctrl->ocfs);
3535 printf("sgls : %#x\n", le32_to_cpu(ctrl->sgls));
3536 if (human)
3537 stdout_id_ctrl_sgls(ctrl->sgls);
3538 printf("mnan : %u\n", le32_to_cpu(ctrl->mnan));
3539 printf("maxdna : %s\n",
3540 uint128_t_to_l10n_string(le128_to_cpu(ctrl->maxdna)));
3541 printf("maxcna : %u\n", le32_to_cpu(ctrl->maxcna));
3542 printf("oaqd : %u\n", le32_to_cpu(ctrl->oaqd));
3543 printf("rhiri : %d\n", ctrl->rhiri);
3544 printf("hirt : %d\n", ctrl->hirt);
3545 printf("cmmrtd : %d\n", le16_to_cpu(ctrl->cmmrtd));
3546 printf("nmmrtd : %d\n", le16_to_cpu(ctrl->nmmrtd));
3547 printf("minmrtg : %d\n", ctrl->minmrtg);
3548 printf("maxmrtg : %d\n", ctrl->maxmrtg);
3549 printf("trattr : %d\n", ctrl->trattr);
3550 if (human)
3551 stdout_id_ctrl_trattr(ctrl->trattr);
3552 printf("mcudmq : %d\n", le16_to_cpu(ctrl->mcudmq));
3553 printf("mnsudmq : %d\n", le16_to_cpu(ctrl->mnsudmq));
3554 printf("mcmr : %d\n", le16_to_cpu(ctrl->mcmr));
3555 printf("nmcmr : %d\n", le16_to_cpu(ctrl->nmcmr));
3556 printf("mcdqpc : %d\n", le16_to_cpu(ctrl->mcdqpc));
3557 printf("subnqn : %-.*s\n", (int)sizeof(ctrl->subnqn), ctrl->subnqn);
3558 printf("ioccsz : %u\n", le32_to_cpu(ctrl->ioccsz));
3559 printf("iorcsz : %u\n", le32_to_cpu(ctrl->iorcsz));
3560 printf("icdoff : %d\n", le16_to_cpu(ctrl->icdoff));
3561 printf("fcatt : %#x\n", ctrl->fcatt);
3562 if (human)
3563 stdout_id_ctrl_fcatt(ctrl->fcatt);
3564 printf("msdbd : %d\n", ctrl->msdbd);
3565 printf("ofcs : %d\n", le16_to_cpu(ctrl->ofcs));
3566 if (human)
3567 stdout_id_ctrl_ofcs(ctrl->ofcs);
3568 printf("dctype : %d\n", ctrl->dctype);
3569 if (human)
3570 stdout_id_ctrl_dctype(ctrl->dctype);
3571 printf("ccrl : %d\n", ctrl->ccrl);
3572
3573 stdout_id_ctrl_power(ctrl);
3574 if (vendor_show)
3575 vendor_show(ctrl->vs, NULL((void*)0));
3576 else if (vs) {
3577 printf("vs[]:\n");
3578 d(ctrl->vs, sizeof(ctrl->vs), 16, 1);
3579 }
3580}
3581
3582static void stdout_id_ctrl_nvm_kpiocap(__u8 kpiocap)
3583{
3584 __u8 rsvd2 = (kpiocap & 0xfc) >> 2;
3585 __u8 kpiosc = (kpiocap & 0x2) >> 1;
3586 __u8 kpios = kpiocap & 0x1;
3587
3588 if (rsvd2)
3589 printf(" [7:2] : %#x\tReserved\n", rsvd2);
3590 printf(" [1:1] : %#x\tKey Per I/O capability enabled and disabled %s in the"
3591 "NVM subsystem\n", kpiosc, kpiosc ? "all namespaces" : "each namespace");
3592 printf(" [0:0] : %#x\tKey Per I/O capability %sSupported\n", kpios,
3593 kpios ? "" : "Not ");
3594}
3595
3596static void stdout_id_ctrl_nvm_aocs(__u16 aocs)
3597{
3598 __u16 rsvd = (aocs & 0xfffe) >> 1;
3599 __u8 ralbas = aocs & 0x1;
3600
3601 if (rsvd)
3602 printf(" [15:1] : %#x\tReserved\n", rsvd);
3603 printf(" [0:0] : %#x\tReporting Allocated LBA %sSupported\n", ralbas,
3604 ralbas ? "" : "Not ");
3605 printf("\n");
3606}
3607
3608static void stdout_id_ctrl_nvm_ver(__u32 ver)
3609{
3610 printf(" NVM command set specification: %d.%d.%d\n\n", NVME_MAJOR(ver)(((ver) >> NVME_VS_MJR_SHIFT) & NVME_VS_MJR_MASK), NVME_MINOR(ver)(((ver) >> NVME_VS_MNR_SHIFT) & NVME_VS_MNR_MASK),
3611 NVME_TERTIARY(ver)(((ver) >> NVME_VS_TER_SHIFT) & NVME_VS_TER_MASK));
3612}
3613
3614static void stdout_id_ctrl_nvm_lbamqf(__u8 lbamqf)
3615{
3616 printf(" 0x%x: ", lbamqf);
3617
3618 switch (lbamqf) {
3619 case NVME_ID_CTRL_NVM_LBAMQF_TYPE_0:
3620 printf("LBA Migration Queue Entry Type 0\n\n");
3621 break;
3622 case NVME_ID_CTRL_NVM_LBAMQF_VENDOR_MIN ... NVME_ID_CTRL_NVM_LBAMQF_VENDOR_MAX:
3623 printf("Vendor Specific\n\n");
3624 break;
3625 default:
3626 printf("Reserved\n\n");
3627 break;
3628 }
3629}
3630
3631static void stdout_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm)
3632{
3633 int verbose = stdout_print_ops.flags & VERBOSE;
3634
3635 printf("NVMe Identify Controller NVM:\n");
3636 printf("vsl : %u\n", ctrl_nvm->vsl);
3637 printf("wzsl : %u\n", ctrl_nvm->wzsl);
3638 printf("wusl : %u\n", ctrl_nvm->wusl);
3639 printf("dmrl : %u\n", ctrl_nvm->dmrl);
3640 printf("dmrsl : %u\n", le32_to_cpu(ctrl_nvm->dmrsl));
3641 printf("dmsl : %"PRIu64"l" "u""\n", le64_to_cpu(ctrl_nvm->dmsl));
3642 printf("kpiocap: %u\n", ctrl_nvm->kpiocap);
3643 if (verbose)
3644 stdout_id_ctrl_nvm_kpiocap(ctrl_nvm->kpiocap);
3645 printf("wzdsl : %u\n", ctrl_nvm->wzdsl);
3646 printf("aocs : %u\n", le16_to_cpu(ctrl_nvm->aocs));
3647 if (verbose)
3648 stdout_id_ctrl_nvm_aocs(le16_to_cpu(ctrl_nvm->aocs));
3649 printf("ver : 0x%x\n", le32_to_cpu(ctrl_nvm->ver));
3650 if (verbose)
3651 stdout_id_ctrl_nvm_ver(le32_to_cpu(ctrl_nvm->ver));
3652 printf("lbamqf : %u\n", ctrl_nvm->lbamqf);
3653 if (verbose)
3654 stdout_id_ctrl_nvm_lbamqf(ctrl_nvm->lbamqf);
3655}
3656
3657static void stdout_nvm_id_ns_pic(__u8 pic)
3658{
3659 __u8 rsvd = (pic & 0xF0) >> 4;
3660 __u8 qpifs = (pic & 0x8) >> 3;
3661 __u8 stcrs = (pic & 0x4) >> 2;
3662 __u8 pic_16bpistm = (pic & 0x2) >> 1;
3663 __u8 pic_16bpists = pic & 0x1;
3664
3665 if (rsvd)
3666 printf(" [7:4] : %#x\tReserved\n", rsvd);
3667 printf(" [3:3] : %#x\tQualified Protection Information Format %sSupported\n",
3668 qpifs, qpifs ? "" : "Not ");
3669 printf(" [2:2] : %#x\tStorage Tag Check Read %sSupported\n",
3670 stcrs, stcrs ? "" : "Not ");
3671 printf(" [1:1] : %#x\t16b Guard Protection Information Storage Tag Mask\n",
3672 pic_16bpistm);
3673 printf(" [0:0] : %#x\t16b Guard Protection Information Storage Tag %sSupported\n",
3674 pic_16bpists, pic_16bpists ? "" : "Not ");
3675 printf("\n");
3676}
3677
3678static void stdout_nvm_id_ns_pifa(__u8 pifa)
3679{
3680 __u8 rsvd = (pifa & 0xF8) >> 3;
3681 __u8 stmla = pifa & 0x7;
3682
3683 if (rsvd)
3684 printf(" [7:3] : %#x\tReserved\n", rsvd);
3685 printf(" [2:0] : %#x\tStorage Tag Masking Level Attribute : %s\n", stmla,
3686 stmla == 0 ? "Bit Granularity Masking" :
3687 stmla == 1 ? "Byte Granularity Masking" :
3688 stmla == 2 ? "Masking Not Supported" : "Reserved");
3689 printf("\n");
3690}
3691
3692static char *pif_to_string(__u8 pif, bool_Bool qpifs, bool_Bool pif_field)
3693{
3694 switch (pif) {
3695 case NVME_NVM_PIF_16B_GUARD:
3696 return "16b Guard";
3697 case NVME_NVM_PIF_32B_GUARD:
3698 return "32b Guard";
3699 case NVME_NVM_PIF_64B_GUARD:
3700 return "64b Guard";
3701 case NVME_NVM_PIF_QTYPE:
3702 if (pif_field && qpifs)
3703 return "Qualified Type";
3704 default:
3705 return "Reserved";
3706 }
3707}
3708
3709static void stdout_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns, unsigned int nsid,
3710 struct nvme_id_ns *ns, unsigned int lba_index,
3711 bool_Bool cap_only)
3712{
3713 int i, verbose = stdout_print_ops.flags & VERBOSE;
3714 bool_Bool qpifs = (nvm_ns->pic & 0x8) >> 3;
3715 __u32 elbaf;
3716 __u8 lbaf;
3717 int pif, sts, qpif;
3718 char *in_use = "(in use)";
3719
3720 nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &lbaf);
3721
3722 if (!cap_only) {
3723 printf("NVMe NVM Identify Namespace %d:\n", nsid);
3724 printf("lbstm : %#"PRIx64"l" "x""\n", le64_to_cpu(nvm_ns->lbstm));
3725 } else {
3726 printf("NVMe NVM Identify Namespace for LBA format[%d]:\n", lba_index);
3727 in_use = "";
3728 }
3729 printf("pic : %#x\n", nvm_ns->pic);
3730 if (verbose)
3731 stdout_nvm_id_ns_pic(nvm_ns->pic);
3732 printf("pifa : %#x\n", nvm_ns->pifa);
3733 if (verbose)
3734 stdout_nvm_id_ns_pifa(nvm_ns->pifa);
3735
3736 for (i = 0; i <= ns->nlbaf + ns->nulbaf; i++) {
3737 elbaf = le32_to_cpu(nvm_ns->elbaf[i]);
3738 qpif = (elbaf >> 9) & 0xF;
3739 pif = (elbaf >> 7) & 0x3;
3740 sts = elbaf & 0x7f;
3741 if (verbose)
3742 printf("Extended LBA Format %2d : Qualified Protection Information Format: "
3743 "%s(%d) - Protection Information Format: %s(%d) - Storage Tag Size "
3744 "(MSB): %-2d %s\n", i, pif_to_string(qpif, qpifs, false0), qpif,
3745 pif_to_string(pif, qpifs, true1), pif, sts, i == lbaf ? in_use : "");
3746 else
3747 printf("elbaf %2d : qpif:%d pif:%d sts:%-2d %s\n", i,
3748 qpif, pif, sts, i == lbaf ? in_use : "");
3749 }
3750 if (ns->nsfeat & 0x20)
3751 printf("npdgl : %#x\n", le32_to_cpu(nvm_ns->npdgl));
3752
3753 printf("nprg : %#x\n", le32_to_cpu(nvm_ns->nprg));
3754 printf("npra : %#x\n", le32_to_cpu(nvm_ns->npra));
3755 printf("nors : %#x\n", le32_to_cpu(nvm_ns->nors));
3756 printf("npdal : %#x\n", le32_to_cpu(nvm_ns->npdal));
3757 printf("lbapss: %#x\n", le32_to_cpu(nvm_ns->lbapss));
3758 printf("tlbaag: %#x\n", le32_to_cpu(nvm_ns->tlbaag));
3759}
3760
3761static void stdout_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl)
3762{
3763 printf("NVMe ZNS Identify Controller:\n");
3764 printf("zasl : %u\n", ctrl->zasl);
3765}
3766
3767static void show_nvme_id_ns_zoned_zoc(__le16 ns_zoc)
3768{
3769 __u16 zoc = le16_to_cpu(ns_zoc);
3770 __u8 rsvd = (zoc & 0xfffc) >> 2;
3771 __u8 ze = (zoc & 0x2) >> 1;
3772 __u8 vzc = zoc & 0x1;
3773
3774 if (rsvd)
3775 printf(" [15:2] : %#x\tReserved\n", rsvd);
3776 printf(" [1:1] : %#x\t Zone Active Excursions: %s\n",
3777 ze, ze ? "Yes (Host support required)" : "No");
3778 printf(" [0:0] : %#x\t Variable Zone Capacity: %s\n",
3779 vzc, vzc ? "Yes (Host support required)" : "No");
3780 printf("\n");
3781}
3782
3783static void show_nvme_id_ns_zoned_ozcs(__le16 ns_ozcs)
3784{
3785 __u16 ozcs = le16_to_cpu(ns_ozcs);
3786 __u8 rsvd = (ozcs & 0xfffc) >> 2;
3787 __u8 razb = ozcs & 0x1;
3788 __u8 zrwasup = (ozcs & 0x2) >> 1;
3789
3790 if (rsvd)
3791 printf(" [15:1] : %#x\tReserved\n", rsvd);
3792 printf(" [0:0] : %#x\t Read Across Zone Boundaries: %s\n",
3793 razb, razb ? "Yes" : "No");
3794 printf(" [1:1] : %#x\t Zone Random Write Area: %s\n", zrwasup,
3795 zrwasup ? "Yes" : "No");
3796}
3797
3798static void stdout_zns_id_ns_recommended_limit(__le32 ns_rl, int human,
3799 const char *target_limit)
3800{
3801 unsigned int recommended_limit = le32_to_cpu(ns_rl);
3802
3803 if (!recommended_limit && human)
3804 printf("%s : Not Reported\n", target_limit);
3805 else
3806 printf("%s : %u\n", target_limit, recommended_limit);
3807}
3808
3809static void stdout_zns_id_ns_zrwacap(__u8 zrwacap)
3810{
3811 __u8 rsvd = (zrwacap & 0xfe) >> 1;
3812 __u8 expflushsup = zrwacap & 0x1;
3813
3814 if (rsvd)
3815 printf(" [7:1] : %#x\tReserved\n", rsvd);
3816 printf(" [0:0] : %#x\t Explicit ZRWA Flush Operations: %s\n",
3817 expflushsup, expflushsup ? "Yes" : "No");
3818}
3819
3820static void stdout_zns_id_ns(struct nvme_zns_id_ns *ns,
3821 struct nvme_id_ns *id_ns)
3822{
3823 int human = stdout_print_ops.flags & VERBOSE, vs = stdout_print_ops.flags & VS;
3824 uint8_t lbaf;
3825 int i;
3826
3827 nvme_id_ns_flbas_to_lbaf_inuse(id_ns->flbas, &lbaf);
3828
3829 printf("ZNS Command Set Identify Namespace:\n");
3830
3831 if (human) {
3832 printf("zoc : %u\tZone Operation Characteristics\n", le16_to_cpu(ns->zoc));
3833 show_nvme_id_ns_zoned_zoc(ns->zoc);
3834 } else {
3835 printf("zoc : %u\n", le16_to_cpu(ns->zoc));
3836 }
3837
3838 if (human) {
3839 printf("ozcs : %u\tOptional Zoned Command Support\n", le16_to_cpu(ns->ozcs));
3840 show_nvme_id_ns_zoned_ozcs(ns->ozcs);
3841 } else {
3842 printf("ozcs : %u\n", le16_to_cpu(ns->ozcs));
3843 }
3844
3845 if (human) {
3846 if (ns->mar == 0xffffffff)
3847 printf("mar : No Active Resource Limit\n");
3848 else
3849 printf("mar : %u\tActive Resources\n", le32_to_cpu(ns->mar) + 1);
3850 } else {
3851 printf("mar : %#x\n", le32_to_cpu(ns->mar));
3852 }
3853
3854 if (human) {
3855 if (ns->mor == 0xffffffff)
3856 printf("mor : No Open Resource Limit\n");
3857 else
3858 printf("mor : %u\tOpen Resources\n", le32_to_cpu(ns->mor) + 1);
3859 } else {
3860 printf("mor : %#x\n", le32_to_cpu(ns->mor));
3861 }
3862
3863 stdout_zns_id_ns_recommended_limit(ns->rrl, human, "rrl ");
3864 stdout_zns_id_ns_recommended_limit(ns->frl, human, "frl ");
3865 stdout_zns_id_ns_recommended_limit(ns->rrl1, human, "rrl1");
3866 stdout_zns_id_ns_recommended_limit(ns->rrl2, human, "rrl2");
3867 stdout_zns_id_ns_recommended_limit(ns->rrl3, human, "rrl3");
3868 stdout_zns_id_ns_recommended_limit(ns->frl1, human, "frl1");
3869 stdout_zns_id_ns_recommended_limit(ns->frl2, human, "frl2");
3870 stdout_zns_id_ns_recommended_limit(ns->frl3, human, "frl3");
3871
3872 printf("numzrwa : %#x\n", le32_to_cpu(ns->numzrwa));
3873 printf("zrwafg : %u\n", le16_to_cpu(ns->zrwafg));
3874 printf("zrwasz : %u\n", le16_to_cpu(ns->zrwasz));
3875 if (human) {
3876 printf("zrwacap : %u\tZone Random Write Area Capability\n", ns->zrwacap);
3877 stdout_zns_id_ns_zrwacap(ns->zrwacap);
3878 } else {
3879 printf("zrwacap : %u\n", ns->zrwacap);
3880 }
3881
3882 for (i = 0; i <= id_ns->nlbaf; i++) {
3883 if (human)
3884 printf("LBA Format Extension %2d : Zone Size: %#"PRIx64"l" "x"" LBAs - "
3885 "Zone Descriptor Extension Size: %-1d bytes%s\n",
3886 i, le64_to_cpu(ns->lbafe[i].zsze), ns->lbafe[i].zdes << 6,
3887 i == lbaf ? " (in use)" : "");
3888 else
3889 printf("lbafe %2d: zsze:%#"PRIx64"l" "x"" zdes:%u%s\n", i,
3890 (uint64_t)le64_to_cpu(ns->lbafe[i].zsze),
3891 ns->lbafe[i].zdes, i == lbaf ? " (in use)" : "");
3892 }
3893
3894 if (vs) {
3895 printf("vs[] :\n");
3896 d(ns->vs, sizeof(ns->vs), 16, 1);
3897 }
3898}
3899
3900static void stdout_list_ns(struct nvme_ns_list *ns_list)
3901{
3902 int i, verbose = stdout_print_ops.flags & VERBOSE;
3903
3904 printf("NVME Namespace List:\n");
3905 for (i = 0; i < 1024; i++) {
3906 if (ns_list->ns[i]) {
3907 if (verbose)
3908 printf("Identifier %4u: NSID %#x\n",
3909 i, le32_to_cpu(ns_list->ns[i]));
3910 else
3911 printf("[%4u]:%#x\n",
3912 i, le32_to_cpu(ns_list->ns[i]));
3913 }
3914 }
3915}
3916
3917static void stdout_zns_start_zone_list(__u64 nr_zones, struct json_object **zone_list)
3918{
3919 printf("nr_zones: %"PRIu64"l" "u""\n", (uint64_t)le64_to_cpu(nr_zones));
3920}
3921
3922static void stdout_zns_changed(struct nvme_zns_changed_zone_log *log)
3923{
3924 uint16_t nrzid;
3925 int i;
3926
3927 nrzid = le16_to_cpu(log->nrzid);
3928 printf("NVMe Changed Zone List:\n");
3929
3930 if (nrzid == 0xFFFF) {
3931 printf("Too many zones have changed to fit into the log. Use report zones for changes.\n");
3932 return;
3933 }
3934
3935 printf("nrzid: %u\n", nrzid);
3936 for (i = 0; i < nrzid; i++)
3937 printf("zid %03d: %"PRIu64"l" "u""\n", i, (uint64_t)le64_to_cpu(log->zid[i]));
3938}
3939
3940static void stdout_zns_report_zone_attributes(__u8 za, __u8 zai)
3941{
3942 const char * const recommended_limit[4] = {"", "1", "2", "3"};
3943
3944 printf("Attrs: Zone Descriptor Extension is %sVaild\n",
3945 za & NVME_ZNS_ZA_ZDEV ? "" : "Not ");
3946
3947 if (za & NVME_ZNS_ZA_RZR)
3948 printf(" Reset Zone Recommended with Reset Recommended Limit%s\n",
3949 recommended_limit[(zai&0xd)>>2]);
3950
3951 if (za & NVME_ZNS_ZA_FZR)
3952 printf(" Finish Zone Recommended with Finish Recommended Limit%s\n",
3953 recommended_limit[zai&0x3]);
3954
3955 if (za & NVME_ZNS_ZA_ZFC)
3956 printf(" Zone Finished by Controller\n");
3957}
3958
3959static void stdout_zns_report_zones(void *report, __u32 descs,
3960 __u8 ext_size, __u32 report_size,
3961 struct json_object *zone_list)
3962{
3963 struct nvme_zone_report *r = report;
3964 struct nvme_zns_desc *desc;
3965 int i, verbose = stdout_print_ops.flags & VERBOSE;
3966 __u64 nr_zones = le64_to_cpu(r->nr_zones);
3967
3968 if (nr_zones < descs)
3969 descs = nr_zones;
3970
3971 for (i = 0; i < descs; i++) {
3972 desc = (struct nvme_zns_desc *)
3973 (report + sizeof(*r) + i * (sizeof(*desc) + ext_size));
3974 if (verbose) {
3975 printf("SLBA: %#-10"PRIx64"l" "x"" WP: %#-10"PRIx64"l" "x"" Cap: %#-10"PRIx64"l" "x"" State: %-12s Type: %-14s\n",
3976 (uint64_t)le64_to_cpu(desc->zslba), (uint64_t)le64_to_cpu(desc->wp),
3977 (uint64_t)le64_to_cpu(desc->zcap), nvme_zone_state_to_string(desc->zs >> 4),
3978 nvme_zone_type_to_string(desc->zt));
3979 stdout_zns_report_zone_attributes(desc->za, desc->zai);
3980 } else {
3981 printf("SLBA: %#-10"PRIx64"l" "x"" WP: %#-10"PRIx64"l" "x"" Cap: %#-10"PRIx64"l" "x"" State: %#-4x Type: %#-4x Attrs: %#-4x AttrsInfo: %#-4x\n",
3982 (uint64_t)le64_to_cpu(desc->zslba), (uint64_t)le64_to_cpu(desc->wp),
3983 (uint64_t)le64_to_cpu(desc->zcap), desc->zs, desc->zt,
3984 desc->za, desc->zai);
3985 }
3986
3987 if (ext_size && (desc->za & NVME_ZNS_ZA_ZDEV)) {
3988 printf("Extension Data: ");
3989 d((unsigned char *)desc + sizeof(*desc), ext_size, 16, 1);
3990 printf("..\n");
3991 }
3992 }
3993}
3994
3995static void stdout_list_ctrl(struct nvme_ctrl_list *ctrl_list)
3996{
3997 __u16 num = le16_to_cpu(ctrl_list->num);
3998 int i;
3999
4000 printf("num of ctrls present: %u\n", num);
4001 for (i = 0; i < min(num, 2047)((num) > (2047) ? (2047) : (num)); i++)
4002 printf("[%4u]:%#x\n", i, le16_to_cpu(ctrl_list->identifier[i]));
4003}
4004
4005static void stdout_id_nvmset(struct nvme_id_nvmset_list *nvmset,
4006 unsigned int nvmset_id)
4007{
4008 int i;
4009
4010 printf("NVME Identify NVM Set List %d:\n", nvmset_id);
4011 printf("nid : %d\n", nvmset->nid);
4012 printf(".................\n");
4013 for (i = 0; i < nvmset->nid; i++) {
4014 printf(" NVM Set Attribute Entry[%2d]\n", i);
4015 printf(".................\n");
4016 printf("nvmset_id : %d\n",
4017 le16_to_cpu(nvmset->ent[i].endgid));
4018 printf("endurance_group_id : %d\n",
4019 le16_to_cpu(nvmset->ent[i].endgid));
4020 printf("random_4k_read_typical : %u\n",
4021 le32_to_cpu(nvmset->ent[i].rr4kt));
4022 printf("optimal_write_size : %u\n",
4023 le32_to_cpu(nvmset->ent[i].ows));
4024 printf("total_nvmset_cap : %s\n",
4025 uint128_t_to_l10n_string(
4026 le128_to_cpu(nvmset->ent[i].tnvmsetcap)));
4027 printf("unalloc_nvmset_cap : %s\n",
4028 uint128_t_to_l10n_string(
4029 le128_to_cpu(nvmset->ent[i].unvmsetcap)));
4030 printf(".................\n");
4031 }
4032}
4033
4034static void stdout_primary_ctrl_caps_crt(__u8 crt)
4035{
4036 __u8 rsvd = (crt & 0xFC) >> 2;
4037 __u8 vi = (crt & 0x2) >> 1;
4038 __u8 vq = crt & 0x1;
4039
4040 if (rsvd)
4041 printf(" [7:2] : %#x\tReserved\n", rsvd);
4042 printf(" [1:1] %#x\tVI Resources are %ssupported\n", vi, vi ? "" : "not ");
4043 printf(" [0:0] %#x\tVQ Resources are %ssupported\n", vq, vq ? "" : "not ");
4044}
4045
4046static void stdout_primary_ctrl_cap(const struct nvme_primary_ctrl_cap *caps)
4047{
4048 int human = stdout_print_ops.flags & VERBOSE;
4049
4050 printf("NVME Identify Primary Controller Capabilities:\n");
4051 printf("cntlid : %#x\n", le16_to_cpu(caps->cntlid));
4052 printf("portid : %#x\n", le16_to_cpu(caps->portid));
4053 printf("crt : %#x\n", caps->crt);
4054 if (human)
4055 stdout_primary_ctrl_caps_crt(caps->crt);
4056 printf("vqfrt : %u\n", le32_to_cpu(caps->vqfrt));
4057 printf("vqrfa : %u\n", le32_to_cpu(caps->vqrfa));
4058 printf("vqrfap : %d\n", le16_to_cpu(caps->vqrfap));
4059 printf("vqprt : %d\n", le16_to_cpu(caps->vqprt));
4060 printf("vqfrsm : %d\n", le16_to_cpu(caps->vqfrsm));
4061 printf("vqgran : %d\n", le16_to_cpu(caps->vqgran));
4062 printf("vifrt : %u\n", le32_to_cpu(caps->vifrt));
4063 printf("virfa : %u\n", le32_to_cpu(caps->virfa));
4064 printf("virfap : %d\n", le16_to_cpu(caps->virfap));
4065 printf("viprt : %d\n", le16_to_cpu(caps->viprt));
4066 printf("vifrsm : %d\n", le16_to_cpu(caps->vifrsm));
4067 printf("vigran : %d\n", le16_to_cpu(caps->vigran));
4068}
4069
4070static void stdout_list_secondary_ctrl(const struct nvme_secondary_ctrl_list *sc_list,
4071 __u32 count)
4072{
4073 const struct nvme_secondary_ctrl *sc_entry =
4074 &sc_list->sc_entry[0];
4075 static const char * const state_desc[] = { "Offline", "Online" };
4076
4077 __u16 num = sc_list->num;
4078 __u32 entries = min(num, count)((num) > (count) ? (count) : (num));
4079 int i;
4080
4081 printf("Identify Secondary Controller List:\n");
4082 printf(" NUMID : Number of Identifiers : %d\n", num);
4083
4084 for (i = 0; i < entries; i++) {
4085 printf(" SCEntry[%-3d]:\n", i);
4086 printf("................\n");
4087 printf(" SCID : Secondary Controller Identifier : %#.04x\n",
4088 le16_to_cpu(sc_entry[i].scid));
4089 printf(" PCID : Primary Controller Identifier : %#.04x\n",
4090 le16_to_cpu(sc_entry[i].pcid));
4091 printf(" SCS : Secondary Controller State : %#.04x (%s)\n",
4092 sc_entry[i].scs,
4093 state_desc[sc_entry[i].scs & 0x1]);
4094 printf(" VFN : Virtual Function Number : %#.04x\n",
4095 le16_to_cpu(sc_entry[i].vfn));
4096 printf(" NVQ : Num VQ Flex Resources Assigned : %#.04x\n",
4097 le16_to_cpu(sc_entry[i].nvq));
4098 printf(" NVI : Num VI Flex Resources Assigned : %#.04x\n",
4099 le16_to_cpu(sc_entry[i].nvi));
4100 }
4101}
4102
4103static void stdout_id_ns_granularity_list(const struct nvme_id_ns_granularity_list *glist)
4104{
4105 int i;
4106
4107 printf("Identify Namespace Granularity List:\n");
4108 printf(" ATTR : Namespace Granularity Attributes: %#x\n",
4109 glist->attributes);
4110 printf(" NUMD : Number of Descriptors : %d\n",
4111 glist->num_descriptors);
4112
4113 /* Number of Descriptors is a 0's based value */
4114 for (i = 0; i <= glist->num_descriptors; i++) {
4115 printf("\n Entry[%2d] :\n", i);
4116 printf("................\n");
4117 printf(" NSG : Namespace Size Granularity : %#"PRIx64"l" "x""\n",
4118 le64_to_cpu(glist->entry[i].nszegran));
4119 printf(" NCG : Namespace Capacity Granularity : %#"PRIx64"l" "x""\n",
4120 le64_to_cpu(glist->entry[i].ncapgran));
4121 }
4122}
4123
4124static void stdout_id_uuid_list(const struct nvme_id_uuid_list *uuid_list)
4125{
4126 int i, human = stdout_print_ops.flags & VERBOSE;
4127
4128 printf("NVME Identify UUID:\n");
4129
4130 for (i = 0; i < NVME_ID_UUID_LIST_MAX; i++) {
4131 __u8 uuid[NVME_UUID_LEN16];
4132 char *association = "";
4133 uint8_t identifier_association = uuid_list->entry[i].header & 0x3;
4134 /* The list is terminated by a zero UUID value */
4135 if (memcmp(uuid_list->entry[i].uuid, zero_uuid, NVME_UUID_LEN16) == 0)
4136 break;
4137 memcpy(&uuid, uuid_list->entry[i].uuid, NVME_UUID_LEN16);
4138 if (human) {
4139 switch (identifier_association) {
4140 case 0x0:
4141 association = "No association reported";
4142 break;
4143 case 0x1:
4144 association = "associated with PCI Vendor ID";
4145 break;
4146 case 0x2:
4147 association = "associated with PCI Subsystem Vendor ID";
4148 break;
4149 default:
4150 association = "Reserved";
4151 break;
4152 }
4153 }
4154 printf(" Entry[%3d]\n", i+1);
4155 printf(".................\n");
4156 printf("association : %#x %s\n", identifier_association, association);
4157 printf("UUID : %s", util_uuid_to_string(uuid));
4158 if (memcmp(uuid_list->entry[i].uuid, invalid_uuid,
4159 sizeof(zero_uuid)) == 0)
4160 printf(" (Invalid UUID)");
4161 printf("\n.................\n");
4162 }
4163}
4164
4165static void stdout_id_domain_list(struct nvme_id_domain_list *id_dom)
4166{
4167 int i;
4168
4169 printf("Number of Domain Entries: %u\n", id_dom->num);
4170 for (i = 0; i < id_dom->num; i++) {
4171 printf("Domain Id for Attr Entry[%u]: %u\n", i,
4172 le16_to_cpu(id_dom->domain_attr[i].dom_id));
4173 printf("Domain Capacity for Attr Entry[%u]: %s\n", i,
4174 uint128_t_to_l10n_string(
4175 le128_to_cpu(id_dom->domain_attr[i].dom_cap)));
4176 printf("Unallocated Domain Capacity for Attr Entry[%u]: %s\n", i,
4177 uint128_t_to_l10n_string(
4178 le128_to_cpu(id_dom->domain_attr[i].unalloc_dom_cap)));
4179 printf("Max Endurance Group Domain Capacity for Attr Entry[%u]: %s\n", i,
4180 uint128_t_to_l10n_string(
4181 le128_to_cpu(id_dom->domain_attr[i].max_egrp_dom_cap)));
4182 }
4183}
4184
4185static void stdout_endurance_group_list(struct nvme_id_endurance_group_list *endgrp_list)
4186{
4187 int i;
4188 __u16 num = le16_to_cpu(endgrp_list->num);
4189
4190 printf("num of endurance group ids: %u\n", num);
4191 for (i = 0; i < min(num, 2047)((num) > (2047) ? (2047) : (num)); i++)
4192 printf("[%4u]:%#x\n", i, le16_to_cpu(endgrp_list->identifier[i]));
4193}
4194
4195static void stdout_id_iocs_iocsc(__u64 iocsc)
4196{
4197 __u8 cpncs = NVME_GET(iocsc, IOCS_IOCSC_CPNCS)(((iocsc) >> NVME_IOCS_IOCSC_CPNCS_SHIFT) & NVME_IOCS_IOCSC_CPNCS_MASK
)
;
4198 __u8 slmcs = NVME_GET(iocsc, IOCS_IOCSC_SLMCS)(((iocsc) >> NVME_IOCS_IOCSC_SLMCS_SHIFT) & NVME_IOCS_IOCSC_SLMCS_MASK
)
;
4199 __u8 znscs = NVME_GET(iocsc, IOCS_IOCSC_ZNSCS)(((iocsc) >> NVME_IOCS_IOCSC_ZNSCS_SHIFT) & NVME_IOCS_IOCSC_ZNSCS_MASK
)
;
4200 __u8 kvcs = NVME_GET(iocsc, IOCS_IOCSC_KVCS)(((iocsc) >> NVME_IOCS_IOCSC_KVCS_SHIFT) & NVME_IOCS_IOCSC_KVCS_MASK
)
;
4201 __u8 nvmcs = NVME_GET(iocsc, IOCS_IOCSC_NVMCS)(((iocsc) >> NVME_IOCS_IOCSC_NVMCS_SHIFT) & NVME_IOCS_IOCSC_NVMCS_MASK
)
;
4202
4203 printf(" [4:4] : %#x\tComputational Programs Namespace Command Set %sSelected\n",
4204 cpncs, cpncs ? "" : "Not ");
4205 printf(" [3:3] : %#x\tSubsystem Local Memory Command Set %sSelected\n", slmcs,
4206 slmcs ? "" : "Not ");
4207 printf(" [2:2] : %#x\tZoned Namespace Command Set %sSelected\n", znscs,
4208 znscs ? "" : "Not ");
4209 printf(" [1:1] : %#x\tKey Value Command Set %sSelected\n", kvcs, kvcs ? "" : "Not ");
4210 printf(" [0:0] : %#x\tNVM Command Set %sSelected\n", nvmcs, nvmcs ? "" : "Not ");
4211 printf("\n");
4212}
4213
4214static void stdout_id_iocs(struct nvme_id_iocs *iocs)
4215{
4216 bool_Bool human = stdout_print_ops.flags & VERBOSE;
4217 __u16 i;
4218
4219 for (i = 0; i < ARRAY_SIZE(iocs->iocsc)(sizeof(iocs->iocsc) / sizeof((iocs->iocsc)[0])); i++) {
4220 if (iocs->iocsc[i]) {
4221 printf("I/O Command Set Combination[%u]:%"PRIx64"l" "x""\n", i,
4222 (uint64_t)le64_to_cpu(iocs->iocsc[i]));
4223 if (human)
4224 stdout_id_iocs_iocsc(le64_to_cpu(iocs->iocsc[i]));
4225 }
4226 }
4227}
4228
4229static void stdout_error_log(struct nvme_error_log_page *err_log, int entries,
4230 const char *devname,
4231 struct nvme_error_log_filter *flt)
4232{
4233 int filtered = 0;
4234 int i;
4235 __u16 status;
4236 __u16 sts;
4237
4238 printf("Error Log Entries for device:%s entries:%d\n", devname,
4239 entries);
4240 printf(".................\n");
4241 for (i = 0; i < entries; i++) {
4242 if (nvme_is_error_log_filter(&err_log[i], flt)) {
4243 filtered++;
4244 continue;
4245 }
4246
4247 sts = le16_to_cpu(err_log[i].status_field);
4248 status = NVME_ERR_SF_STATUS_FIELD(sts)(((sts) >> NVME_ERR_SF_STATUS_FIELD_SHIFT) & NVME_ERR_SF_STATUS_FIELD_MASK
)
;
4249
4250 printf(" Entry[%2d]\n", i);
4251 printf(".................\n");
4252 printf("error_count : %"PRIu64"l" "u""\n",
4253 le64_to_cpu(err_log[i].error_count));
4254 printf("sqid : %d\n", le16_to_cpu(err_log[i].sqid));
4255 printf("cmdid : %#x\n",
4256 le16_to_cpu(err_log[i].cmdid));
4257 printf("status_field : %#x (%s)\n", status,
4258 libnvme_status_to_string(status, false0));
4259 printf("phase_tag : %#x\n", NVME_ERR_SF_PHASE_TAG(sts)(((sts) >> NVME_ERR_SF_PHASE_TAG_SHIFT) & NVME_ERR_SF_PHASE_TAG_MASK
)
);
4260 printf("parm_err_loc : %#x\n",
4261 le16_to_cpu(err_log[i].parm_error_location));
4262 printf("lba : %#"PRIx64"l" "x""\n",
4263 le64_to_cpu(err_log[i].lba));
4264 printf("nsid : %#x\n", le32_to_cpu(err_log[i].nsid));
4265 printf("vs : %d\n", err_log[i].vs);
4266 printf("trtype : %#x (%s)\n", err_log[i].trtype,
4267 nvme_trtype_to_string(err_log[i].trtype));
4268 printf("csi : %d\n", err_log[i].csi);
4269 printf("opcode : %#x\n", err_log[i].opcode);
4270 printf("cs : %#"PRIx64"l" "x""\n",
4271 le64_to_cpu(err_log[i].cs));
4272 printf("trtype_spec_info: %#x\n",
4273 le16_to_cpu(err_log[i].trtype_spec_info));
4274 printf("log_page_version: %d\n", err_log[i].log_page_version);
4275 printf(".................\n");
4276 }
4277
4278 if (entries == filtered)
4279 printf("all entries filtered\n");
4280}
4281
4282static void stdout_resv_report(struct nvme_resv_status *status, int bytes,
4283 bool_Bool eds)
4284{
4285 int i, j, regctl, entries;
4286
4287 regctl = status->regctl[0] | (status->regctl[1] << 8);
4288
4289 printf("\nNVME Reservation status:\n\n");
4290 printf("gen : %u\n", le32_to_cpu(status->gen));
4291 printf("rtype : %d\n", status->rtype);
4292 printf("regctl : %d\n", regctl);
4293 printf("ptpls : %d\n", status->ptpls);
4294
4295 /* check Extended Data Structure bit */
4296 if (!eds) {
4297 /*
4298 * if status buffer was too small, don't loop past the end of
4299 * the buffer
4300 */
4301 entries = (bytes - 24) / 24;
4302 if (entries < regctl)
4303 regctl = entries;
4304
4305 for (i = 0; i < regctl; i++) {
4306 printf("regctl[%d] :\n", i);
4307 printf(" cntlid : %x\n",
4308 le16_to_cpu(status->regctl_ds[i].cntlid));
4309 printf(" rcsts : %x\n",
4310 status->regctl_ds[i].rcsts);
4311 printf(" hostid : %"PRIx64"l" "x""\n",
4312 le64_to_cpu(status->regctl_ds[i].hostid));
4313 printf(" rkey : %"PRIx64"l" "x""\n",
4314 le64_to_cpu(status->regctl_ds[i].rkey));
4315 }
4316 } else {
4317 /* if status buffer was too small, don't loop past the end of the buffer */
4318 entries = (bytes - 64) / 64;
4319 if (entries < regctl)
4320 regctl = entries;
4321
4322 for (i = 0; i < regctl; i++) {
4323 printf("regctlext[%d] :\n", i);
4324 printf(" cntlid : %x\n",
4325 le16_to_cpu(status->regctl_eds[i].cntlid));
4326 printf(" rcsts : %x\n",
4327 status->regctl_eds[i].rcsts);
4328 printf(" rkey : %"PRIx64"l" "x""\n",
4329 le64_to_cpu(status->regctl_eds[i].rkey));
4330 printf(" hostid : ");
4331 for (j = 0; j < 16; j++)
4332 printf("%02x",
4333 status->regctl_eds[i].hostid[j]);
4334 printf("\n");
4335 }
4336 }
4337 printf("\n");
4338}
4339
4340static void stdout_fw_log(struct nvme_firmware_slot *fw_log,
4341 const char *devname)
4342{
4343 int i;
4344 __le64 *frs;
4345
4346 printf("Firmware Log for device:%s\n", devname);
4347 printf("afi : %#x\n", fw_log->afi);
4348 for (i = 0; i < 7; i++) {
4349 if (fw_log->frs[i][0]) {
4350 frs = (__le64 *)&fw_log->frs[i];
4351 printf("frs%d : %#016"PRIx64"l" "x"" (%s)\n", i + 1,
4352 le64_to_cpu(*frs),
4353 util_fw_to_string(fw_log->frs[i]));
4354 }
4355 }
4356}
4357
4358static void stdout_changed_ns_list_log(struct nvme_ns_list *log, const char *devname, bool_Bool alloc)
4359{
4360 __u32 nsid;
4361 int i;
4362
4363 if (log->ns[0] != cpu_to_le32(NVME_NSID_ALL)) {
4364 for (i = 0; i < NVME_ID_NS_LIST_MAX; i++) {
4365 nsid = le32_to_cpu(log->ns[i]);
4366 if (nsid == 0) {
4367 printf("no ns changed\n");
4368 break;
4369 }
4370
4371 printf("[%4u]:%#x\n", i, nsid);
4372 }
4373 } else
4374 printf("more than %d ns changed\n",
4375 NVME_ID_NS_LIST_MAX);
4376}
4377
4378static void stdout_effects_log_human(__u32 effect)
4379{
4380 const char *set = "+";
4381 const char *clr = "-";
4382
4383 printf(" CSUPP+");
4384 printf(" LBCC%s", (effect & NVME_CMD_EFFECTS_LBCC) ? set : clr);
4385 printf(" NCC%s", (effect & NVME_CMD_EFFECTS_NCC) ? set : clr);
4386 printf(" NIC%s", (effect & NVME_CMD_EFFECTS_NIC) ? set : clr);
4387 printf(" CCC%s", (effect & NVME_CMD_EFFECTS_CCC) ? set : clr);
4388 printf(" USS%s", (effect & NVME_CMD_EFFECTS_UUID_SEL) ? set : clr);
4389
4390 switch (NVME_CMD_EFFECTS_CSER(effect)(((effect) >> NVME_CMD_EFFECTS_CSER_SHIFT) & NVME_CMD_EFFECTS_CSER_MASK
)
) {
4391 case 0:
4392 printf(" No CSER defined\n");
4393 break;
4394 case 1:
4395 printf(" No admin command for any namespace\n");
4396 break;
4397 default:
4398 printf(" Reserved CSER\n");
4399 }
4400
4401 switch (NVME_CMD_EFFECTS_CSE(effect)(((effect) >> NVME_CMD_EFFECTS_CSE_SHIFT) & NVME_CMD_EFFECTS_CSE_MASK
)
) {
4402 case 0:
4403 printf(" No command restriction\n");
4404 break;
4405 case 1:
4406 printf(" No other command for same namespace\n");
4407 break;
4408 case 2:
4409 printf(" No other command for any namespace\n");
4410 break;
4411 default:
4412 printf(" Reserved CSE\n");
4413 }
4414}
4415
4416static void stdout_effects_entry(int admin, int index,
4417 __le32 entry, unsigned int human)
4418{
4419 __u32 effect;
4420 char *format_string;
4421
4422 format_string = admin ? "ACS%-6d[%-32s] %08x" : "IOCS%-5d[%-32s] %08x";
4423
4424 effect = le32_to_cpu(entry);
4425 if (effect & NVME_CMD_EFFECTS_CSUPP) {
4426 printf(format_string, index, nvme_cmd_to_string(admin, index),
4427 effect);
4428 if (human)
4429 stdout_effects_log_human(effect);
4430 else
4431 printf("\n");
4432 }
4433}
4434
4435static void stdout_effects_log_segment(int admin, int a, int b,
4436 struct nvme_cmd_effects_log *effects,
4437 char *header, int human)
4438{
4439 bool_Bool printed_header = false0;
4440
4441 for (int i = a; i < b; i++) {
4442 __le32 entry;
4443 __u32 effect;
4444
4445 entry = admin ? effects->acs[i] : effects->iocs[i];
4446 effect = le32_to_cpu(entry);
4447
4448 if (!(effect & NVME_CMD_EFFECTS_CSUPP))
4449 continue;
4450
4451 if (!printed_header && header) {
4452 printf("%s\n", header);
4453 printed_header = true1;
4454 }
4455
4456 stdout_effects_entry(admin, i, entry, human);
4457 }
4458
4459 if (printed_header)
4460 printf("\n");
4461}
4462
4463static void stdout_effects_log_page(enum nvme_csi csi,
4464 struct nvme_cmd_effects_log *effects)
4465{
4466 int human = stdout_print_ops.flags & VERBOSE;
4467
4468 switch (csi) {
4469 case NVME_CSI_NVM:
4470 printf("NVM Command Set Log Page\n");
4471 printf("%-.80s\n", dash);
4472 break;
4473 case NVME_CSI_KV:
4474 printf("KV Command Set Log Page\n");
4475 printf("%-.80s\n", dash);
4476 break;
4477 case NVME_CSI_ZNS:
4478 printf("ZNS Command Set Log Page\n");
4479 printf("%-.80s\n", dash);
4480 break;
4481 default:
4482 printf("Unknown Command Set Log Page\n");
4483 printf("%-.80s\n", dash);
4484 break;
4485 }
4486
4487 stdout_effects_log_segment(1, 0, 0xbf, effects, "Admin Commands", human);
4488 stdout_effects_log_segment(1, 0xc0, 0xff, effects, "Vendor Specific Admin Commands", human);
4489 stdout_effects_log_segment(0, 0, 0x80, effects, "I/O Commands", human);
4490 stdout_effects_log_segment(0, 0x80, 0x100, effects, "Vendor Specific I/O Commands", human);
4491}
4492
4493static void stdout_effects_log_pages(struct list_head *list)
4494{
4495 nvme_effects_log_node_t *node = NULL((void*)0);
4496
4497 list_for_each(list, node, node)for ((node) = list_node_to_off_(((void)"../nvme-print-stdout.c"
":" "4497", (list))->n.next, (((__builtin_offsetof(typeof
(*node), node) + ((typeof(node->node) *)0 != (struct list_node
*)0))))); list_node_from_off_((void *)(node), (((__builtin_offsetof
(typeof(*node), node) + ((typeof(node->node) *)0 != (struct
list_node *)0))))) != &((list))->n; (node) = list_node_to_off_
(list_node_from_off_((void *)(node), (((__builtin_offsetof(typeof
(*node), node) + ((typeof(node->node) *)0 != (struct list_node
*)0)))))->next, (((__builtin_offsetof(typeof(*node), node
) + ((typeof(node->node) *)0 != (struct list_node *)0)))))
)
{
4498 stdout_effects_log_page(node->csi, &node->effects);
4499 }
4500}
4501
4502static void stdout_support_log_human(__u32 support, __u8 lid)
4503{
4504 const char *set = "supported";
4505 const char *clr = "not supported";
4506 __u16 lidsp = support >> 16;
4507
4508 printf(" LSUPP is %s\n", (support & 0x1) ? set : clr);
4509 printf(" IOS is %s\n", ((support >> 0x1) & 0x1) ? set : clr);
4510
4511 switch (lid) {
4512 case NVME_LOG_LID_TELEMETRY_HOST:
4513 printf(" Maximum Created Data Area is %s\n",
4514 (lidsp & 0x1) ? set : clr);
4515 break;
4516 case NVME_LOG_LID_PERSISTENT_EVENT:
4517 printf(" Establish Context and Read 512 Bytes of Header is %s\n",
4518 (lidsp & 0x1) ? set : clr);
4519 break;
4520 case NVME_LOG_LID_DISCOVERY:
4521 printf(" Extended Discovery Log Page Entry is %s\n",
4522 (lidsp & 0x1) ? set : clr);
4523 printf(" Port Local Entries Only is %s\n",
4524 (lidsp & 0x2) ? set : clr);
4525 printf(" All NVM Subsystem Entries is %s\n",
4526 (lidsp & 0x4) ? set : clr);
4527 break;
4528 case NVME_LOG_LID_HOST_DISCOVERY:
4529 printf(" All Host Entries is %s\n",
4530 (lidsp & 0x1) ? set : clr);
4531 break;
4532 default:
4533 break;
4534 }
4535}
4536
4537static void stdout_supported_log(struct nvme_supported_log_pages *support_log,
4538 const char *devname)
4539{
4540 int lid, human = stdout_print_ops.flags & VERBOSE;
4541 __u32 support = 0;
4542
4543 printf("Support Log Pages Details for %s:\n", devname);
4544 for (lid = 0; lid < 256; lid++) {
4545 support = le32_to_cpu(support_log->lid_support[lid]);
4546 if (support & 0x1) {
4547 printf("LID %#x - %s\n", lid, nvme_log_to_string(lid));
4548 if (human)
4549 stdout_support_log_human(support, lid);
4550 }
4551 }
4552}
4553
4554static void stdout_endurance_log(struct nvme_endurance_group_log *endurance_log, __u16 group_id,
4555 const char *devname)
4556{
4557 printf("Endurance Group Log for NVME device:%s Group ID:%x\n", devname, group_id);
4558 printf("critical_warning : %u\n", endurance_log->critical_warning);
4559 printf("endurance_group_features: %u\n", endurance_log->endurance_group_features);
4560 printf("avl_spare : %u\n", endurance_log->avl_spare);
4561 printf("avl_spare_threshold : %u\n", endurance_log->avl_spare_threshold);
4562 printf("percent_used : %u%%\n", endurance_log->percent_used);
4563 printf("domain_identifier : %u\n", endurance_log->domain_identifier);
4564 printf("endurance_estimate : %s\n",
4565 uint128_t_to_l10n_string(le128_to_cpu(endurance_log->endurance_estimate)));
4566 printf("data_units_read : %s\n",
4567 uint128_t_to_l10n_string(le128_to_cpu(endurance_log->data_units_read)));
4568 printf("data_units_written : %s\n",
4569 uint128_t_to_l10n_string(le128_to_cpu(endurance_log->data_units_written)));
4570 printf("media_units_written : %s\n",
4571 uint128_t_to_l10n_string(le128_to_cpu(endurance_log->media_units_written)));
4572 printf("host_read_cmds : %s\n",
4573 uint128_t_to_l10n_string(le128_to_cpu(endurance_log->host_read_cmds)));
4574 printf("host_write_cmds : %s\n",
4575 uint128_t_to_l10n_string(le128_to_cpu(endurance_log->host_write_cmds)));
4576 printf("media_data_integrity_err: %s\n",
4577 uint128_t_to_l10n_string(le128_to_cpu(endurance_log->media_data_integrity_err)));
4578 printf("num_err_info_log_entries: %s\n",
4579 uint128_t_to_l10n_string(le128_to_cpu(endurance_log->num_err_info_log_entries)));
4580 printf("total_end_grp_cap : %s\n",
4581 uint128_t_to_l10n_string(le128_to_cpu(endurance_log->total_end_grp_cap)));
4582 printf("unalloc_end_grp_cap : %s\n",
4583 uint128_t_to_l10n_string(le128_to_cpu(endurance_log->unalloc_end_grp_cap)));
4584}
4585
4586static void stdout_smart_log(struct nvme_smart_log *smart, unsigned int nsid, const char *devname)
4587{
4588 __u16 temperature = smart->temperature[1] << 8 | smart->temperature[0];
4589 __u32 ipm = le32_to_cpu(smart->interval_power_measurement);
4590 int i;
4591 bool_Bool human = stdout_print_ops.flags & VERBOSE;
4592
4593 printf("Smart Log for NVME device:%s namespace-id:%x\n", devname, nsid);
4594 printf("critical_warning : %#x\n", smart->critical_warning);
4595
4596 if (human) {
4597 printf(" Available Spare[0] : %d\n",
4598 smart->critical_warning & 0x01);
4599 printf(" Temp. Threshold[1] : %d\n",
4600 (smart->critical_warning & 0x02) >> 1);
4601 printf(" NVM subsystem Reliability[2] : %d\n",
4602 (smart->critical_warning & 0x04) >> 2);
4603 printf(" Read-only[3] : %d\n",
4604 (smart->critical_warning & 0x08) >> 3);
4605 printf(" Volatile mem. backup failed[4] : %d\n",
4606 (smart->critical_warning & 0x10) >> 4);
4607 printf(" Persistent Mem. RO[5] : %d\n",
4608 (smart->critical_warning & 0x20) >> 5);
4609 }
4610
4611 printf("temperature : %s (%u K, %s)\n",
4612 nvme_degrees_string(temperature), temperature,
4613 nvme_degrees_fahrenheit_string(temperature));
4614 printf("available_spare : %u%%\n", smart->avail_spare);
4615 printf("available_spare_threshold : %u%%\n", smart->spare_thresh);
4616 printf("percentage_used : %u%%\n", smart->percent_used);
4617 printf("endurance group critical warning summary: %#x\n", smart->endu_grp_crit_warn_sumry);
4618 printf("Data Units Read : %s (%s)\n",
4619 uint128_t_to_l10n_string(le128_to_cpu(smart->data_units_read)),
4620 uint128_t_to_si_string(le128_to_cpu(smart->data_units_read), 1000 * 512));
4621 printf("Data Units Written : %s (%s)\n",
4622 uint128_t_to_l10n_string(le128_to_cpu(smart->data_units_written)),
4623 uint128_t_to_si_string(le128_to_cpu(smart->data_units_written), 1000 * 512));
4624 printf("host_read_commands : %s\n",
4625 uint128_t_to_l10n_string(le128_to_cpu(smart->host_reads)));
4626 printf("host_write_commands : %s\n",
4627 uint128_t_to_l10n_string(le128_to_cpu(smart->host_writes)));
4628 printf("controller_busy_time : %s\n",
4629 uint128_t_to_l10n_string(le128_to_cpu(smart->ctrl_busy_time)));
4630 printf("power_cycles : %s\n",
4631 uint128_t_to_l10n_string(le128_to_cpu(smart->power_cycles)));
4632 printf("power_on_hours : %s\n",
4633 uint128_t_to_l10n_string(le128_to_cpu(smart->power_on_hours)));
4634 printf("unsafe_shutdowns : %s\n",
4635 uint128_t_to_l10n_string(le128_to_cpu(smart->unsafe_shutdowns)));
4636 printf("media_errors : %s\n",
4637 uint128_t_to_l10n_string(le128_to_cpu(smart->media_errors)));
4638 printf("num_err_log_entries : %s\n",
4639 uint128_t_to_l10n_string(le128_to_cpu(smart->num_err_log_entries)));
4640 printf("Warning Temperature Time : %u\n",
4641 le32_to_cpu(smart->warning_temp_time));
4642 printf("Critical Composite Temperature Time : %u\n",
4643 le32_to_cpu(smart->critical_comp_time));
4644
4645 for (i = 0; i < ARRAY_SIZE(smart->temp_sensor)(sizeof(smart->temp_sensor) / sizeof((smart->temp_sensor
)[0]))
; i++) {
4646 temperature = le16_to_cpu(smart->temp_sensor[i]);
4647 if (!temperature)
4648 continue;
4649 printf("Temperature Sensor %d : %s (%u K, %s)\n", i + 1,
4650 nvme_degrees_string(temperature), temperature,
4651 nvme_degrees_fahrenheit_string(temperature));
4652 }
4653
4654 printf("Thermal Management T1 Trans Count : %u\n",
4655 le32_to_cpu(smart->thm_temp1_trans_count));
4656 printf("Thermal Management T2 Trans Count : %u\n",
4657 le32_to_cpu(smart->thm_temp2_trans_count));
4658 printf("Thermal Management T1 Total Time : %u\n",
4659 le32_to_cpu(smart->thm_temp1_total_time));
4660 printf("Thermal Management T2 Total Time : %u\n",
4661 le32_to_cpu(smart->thm_temp2_total_time));
4662 printf("Operational Lifetime Energy Consumed : %"PRIu64"l" "u""\n",
4663 le64_to_cpu(smart->op_lifetime_energy_consumed));
4664 printf("Interval Power Measurement Type : %s\n",
4665 nvme_power_measurement_type_to_string((ipm >> 20) & 0x3f));
4666 printf("Interval Power Measurement : ");
4667 print_power_field(ipm);
4668 printf("\n");
4669}
4670
4671static void stdout_ana_log(struct nvme_ana_log *ana_log, const char *devname,
4672 size_t len)
4673{
4674 int offset = sizeof(struct nvme_ana_log);
4675 struct nvme_ana_log *hdr = ana_log;
4676 struct nvme_ana_group_desc *desc;
4677 size_t nsid_buf_size;
4678 void *base = ana_log;
4679 __u32 nr_nsids;
4680 int i, j;
4681
4682 printf("Asymmetric Namespace Access Log for NVMe device: %s\n",
4683 devname);
4684 printf("ANA LOG HEADER :-\n");
4685 printf("chgcnt : %"PRIu64"l" "u""\n",
4686 le64_to_cpu(hdr->chgcnt));
4687 printf("ngrps : %u\n", le16_to_cpu(hdr->ngrps));
4688 printf("ANA Log Desc :-\n");
4689
4690 for (i = 0; i < le16_to_cpu(ana_log->ngrps); i++) {
4691 desc = base + offset;
4692 nr_nsids = le32_to_cpu(desc->nnsids);
4693 nsid_buf_size = nr_nsids * sizeof(__le32);
4694
4695 offset += sizeof(*desc);
4696 printf("grpid : %u\n", le32_to_cpu(desc->grpid));
4697 printf("nnsids : %u\n", le32_to_cpu(desc->nnsids));
4698 printf("chgcnt : %"PRIu64"l" "u""\n",
4699 le64_to_cpu(desc->chgcnt));
4700 printf("state : %s\n",
4701 nvme_ana_state_to_string(desc->state));
4702 for (j = 0; j < le32_to_cpu(desc->nnsids); j++)
4703 printf(" nsid : %u\n",
4704 le32_to_cpu(desc->nsids[j]));
4705 printf("\n");
4706 offset += nsid_buf_size;
4707 }
4708}
4709
4710static void stdout_self_test_result(struct nvme_st_result *res)
4711{
4712 static const char * const test_res[] = {
4713 "Operation completed without error",
4714 "Operation was aborted by a Device Self-test command",
4715 "Operation was aborted by a Controller Level Reset",
4716 "Operation was aborted due to a removal of a namespace from the namespace inventory",
4717 "Operation was aborted due to the processing of a Format NVM command",
4718 "A fatal error or unknown test error occurred while the controller was executing the"\
4719 " device self-test operation and the operation did not complete",
4720 "Operation completed with a segment that failed and the segment that failed is not known",
4721 "Operation completed with one or more failed segments and the first segment that failed "\
4722 "is indicated in the SegmentNumber field",
4723 "Operation was aborted for unknown reason",
4724 "Operation was aborted due to a sanitize operation",
4725 "Reserved",
4726 [NVME_ST_RESULT_NOT_USED] = "Entry not used (does not contain a result)",
4727 };
4728 __u8 op, code;
4729
4730 op = res->dsts & NVME_ST_RESULT_MASK;
4731 printf(" Operation Result : %#x", op);
4732 if (stdout_print_ops.flags & VERBOSE)
4733 printf(" %s", (op < ARRAY_SIZE(test_res)(sizeof(test_res) / sizeof((test_res)[0])) && test_res[op]) ?
4734 test_res[op] : test_res[ARRAY_SIZE(test_res)(sizeof(test_res) / sizeof((test_res)[0])) - 1]);
4735 printf("\n");
4736 if (op == NVME_ST_RESULT_NOT_USED)
4737 return;
4738
4739 code = res->dsts >> NVME_ST_CODE_SHIFT;
4740 printf(" Self Test Code : %x", code);
4741
4742 if (stdout_print_ops.flags & VERBOSE) {
4743 switch (code) {
4744 case NVME_ST_CODE_SHORT:
4745 printf(" Short device self-test operation");
4746 break;
4747 case NVME_ST_CODE_EXTENDED:
4748 printf(" Extended device self-test operation");
4749 break;
4750 case NVME_ST_CODE_HOST_INIT:
4751 printf(" Host-Initiated Refresh operation");
4752 break;
4753 case NVME_ST_CODE_VS:
4754 printf(" Vendor specific");
4755 break;
4756 default:
4757 printf(" Reserved");
4758 break;
4759 }
4760 }
4761 printf("\n");
4762
4763 if (op == NVME_ST_RESULT_KNOWN_SEG_FAIL)
4764 printf(" Segment Number : %#x\n", res->seg);
4765
4766 printf(" Valid Diagnostic Information : %#x\n", res->vdi);
4767 printf(" Power on hours (POH) : %#"PRIx64"l" "x""\n",
4768 (uint64_t)le64_to_cpu(res->poh));
4769
4770 if (res->vdi & NVME_ST_VALID_DIAG_INFO_NSID)
4771 printf(" Namespace Identifier : %#x\n",
4772 le32_to_cpu(res->nsid));
4773 if (res->vdi & NVME_ST_VALID_DIAG_INFO_FLBA)
4774 printf(" Failing LBA : %#"PRIx64"l" "x""\n",
4775 (uint64_t)le64_to_cpu(res->flba));
4776 if (res->vdi & NVME_ST_VALID_DIAG_INFO_SCT)
4777 printf(" Status Code Type : %#x\n", res->sct);
4778 if (res->vdi & NVME_ST_VALID_DIAG_INFO_SC) {
4779 printf(" Status Code : %#x", res->sc);
4780 if (stdout_print_ops.flags & VERBOSE)
4781 printf(" %s", libnvme_status_to_string(
4782 (res->sct & 7) << 8 | res->sc, false0));
4783 printf("\n");
4784 }
4785 printf(" Vendor Specific : %#x %#x\n",
4786 res->vs[0], res->vs[1]);
4787}
4788
4789static void stdout_self_test_log(struct nvme_self_test_log *self_test,
4790 __u8 dst_entries, __u32 size,
4791 const char *devname)
4792{
4793 int i;
4794 __u8 num_entries;
4795
4796 printf("Device Self Test Log for NVME device:%s\n", devname);
4797 printf("Current operation : %#x\n", self_test->current_operation);
4798 printf("Current Completion : %u%%\n", self_test->completion);
4799 num_entries = min(dst_entries, NVME_LOG_ST_MAX_RESULTS)((dst_entries) > (NVME_LOG_ST_MAX_RESULTS) ? (NVME_LOG_ST_MAX_RESULTS
) : (dst_entries))
;
4800 for (i = 0; i < num_entries; i++) {
4801 printf("Self Test Result[%d]:\n", i);
4802 stdout_self_test_result(&self_test->result[i]);
4803 }
4804}
4805
4806static void stdout_sanitize_log_sprog(__u32 sprog)
4807{
4808 double percent;
4809
4810 percent = (((double)sprog * 100) / 0x10000);
4811 printf("\t(%f%%)\n", percent);
4812}
4813
4814static void stdout_sanitize_log_sstat(__u16 status)
4815{
4816 const char *str = nvme_sstat_status_to_string(status);
4817 __u16 gde, mvcncld;
4818
4819 printf(" [2:0] : Sanitize Operation Status : %#x\t%s\n",
4820 NVME_GET(status, SANITIZE_SSTAT_STATUS)(((status) >> NVME_SANITIZE_SSTAT_STATUS_SHIFT) & NVME_SANITIZE_SSTAT_STATUS_MASK
)
, str);
4821 printf(" [7:3] : Overwrite Passes Completed : %u\n",
4822 NVME_GET(status, SANITIZE_SSTAT_COMPLETED_PASSES)(((status) >> NVME_SANITIZE_SSTAT_COMPLETED_PASSES_SHIFT
) & NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK)
);
4823
4824 gde = NVME_GET(status, SANITIZE_SSTAT_GLOBAL_DATA_ERASED)(((status) >> NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_SHIFT
) & NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_MASK)
;
4825 if (gde)
4826 str = "No user data has been written in the NVM subsystem and"\
4827 " no PMR has been enabled in the NVM subsystem";
4828 else
4829 str = "User data has been written in the NVM subsystem or"\
4830 " PMR has been enabled in the NVM subsystem";
4831 printf(" [8:8] : Global Data Erased : %#x\t%s\n", gde, str);
4832
4833 mvcncld = NVME_GET(status, SANITIZE_SSTAT_MVCNCLD)(((status) >> NVME_SANITIZE_SSTAT_MVCNCLD_SHIFT) & NVME_SANITIZE_SSTAT_MVCNCLD_MASK
)
;
4834 printf(" [9:9] : Media Verification Canceled: %#x\t%scanceled\n",
4835 mvcncld, mvcncld ? "" : "Not ");
4836 printf("\n");
4837}
4838
4839static void stdout_estimate_sanitize_time(const char *text, uint32_t value)
4840{
4841 printf("%s: %u%s\n", text, value,
4842 value == 0xffffffff ? " (No time period reported)" : "");
4843}
4844
4845static void stdout_sanitize_log_ssi(__u8 ssi, __u16 status)
4846{
4847 __u8 sans, fails;
4848 const char *str;
4849
4850 sans = NVME_GET(ssi, SANITIZE_SSI_SANS)(((ssi) >> NVME_SANITIZE_SSI_SANS_SHIFT) & NVME_SANITIZE_SSI_SANS_MASK
)
;
4851 str = nvme_ssi_state_to_string(sans);
4852 printf(" [3:0] : Sanitize State : %#x\t%s\n", sans, str);
4853
4854 if (status == NVME_SANITIZE_SSTAT_STATUS_COMPLETED_FAILED) {
4855 fails = NVME_GET(ssi, SANITIZE_SSI_FAILS)(((ssi) >> NVME_SANITIZE_SSI_FAILS_SHIFT) & NVME_SANITIZE_SSI_FAILS_MASK
)
;
4856 str = nvme_ssi_state_to_string(fails);
4857 printf(" [7:4] : Failure State : %#x\t%s\n", fails, str);
4858 }
4859 printf("\n");
4860}
4861
4862static void stdout_sanitize_log(struct nvme_sanitize_log_page *sanitize,
4863 const char *devname)
4864{
4865 int human = stdout_print_ops.flags & VERBOSE;
4866 __u16 status = le16_to_cpu(sanitize->sstat) & NVME_SANITIZE_SSTAT_STATUS_MASK;
4867
4868 printf("Sanitize Progress (SPROG) : %u",
4869 le16_to_cpu(sanitize->sprog));
4870
4871 if (human && status == NVME_SANITIZE_SSTAT_STATUS_IN_PROGRESS)
4872 stdout_sanitize_log_sprog(le16_to_cpu(sanitize->sprog));
4873 else
4874 printf("\n");
4875
4876 printf("Sanitize Status (SSTAT) : %#x\n",
4877 le16_to_cpu(sanitize->sstat));
4878 if (human)
4879 stdout_sanitize_log_sstat(le16_to_cpu(sanitize->sstat));
4880
4881 printf("Sanitize Command Dword 10 Information (SCDW10) : %#x\n",
4882 le32_to_cpu(sanitize->scdw10));
4883 stdout_estimate_sanitize_time("Estimated Time For Overwrite ",
4884 le32_to_cpu(sanitize->eto));
4885 stdout_estimate_sanitize_time("Estimated Time For Block Erase ",
4886 le32_to_cpu(sanitize->etbe));
4887 stdout_estimate_sanitize_time("Estimated Time For Crypto Erase ",
4888 le32_to_cpu(sanitize->etce));
4889 stdout_estimate_sanitize_time("Estimated Time For Overwrite (No-Deallocate) ",
4890 le32_to_cpu(sanitize->etond));
4891 stdout_estimate_sanitize_time("Estimated Time For Block Erase (No-Deallocate) ",
4892 le32_to_cpu(sanitize->etbend));
4893 stdout_estimate_sanitize_time("Estimated Time For Crypto Erase (No-Deallocate)",
4894 le32_to_cpu(sanitize->etcend));
4895 stdout_estimate_sanitize_time("Estimated Time For Post-Verification Deallocation",
4896 le32_to_cpu(sanitize->etpvds));
4897
4898 printf("Sanitize State Information (SSI) : %#x\n", sanitize->ssi);
4899 if (human)
4900 stdout_sanitize_log_ssi(sanitize->ssi, status);
4901}
4902
4903static void stdout_select_result(enum nvme_features_id fid, __u64 result)
4904{
4905 if (result & 0x1)
4906 printf(" Feature is saveable\n");
4907 if (result & 0x2)
4908 printf(" Feature is per-namespace\n");
4909 if (result & 0x4)
4910 printf(" Feature is changeable\n");
4911}
4912
4913static void stdout_lba_range(struct nvme_lba_range_type *lbrt, int nr_ranges)
4914{
4915 int i, j;
4916
4917 for (i = 0; i <= nr_ranges; i++) {
4918 printf("\ttype : %#x - %s\n", lbrt->entry[i].type,
4919 nvme_feature_lba_type_to_string(lbrt->entry[i].type));
4920 printf("\tattributes : %#x - %s, %s\n", lbrt->entry[i].attributes,
4921 (lbrt->entry[i].attributes & 0x0001) ?
4922 "LBA range may be overwritten" :
4923 "LBA range should not be overwritten",
4924 ((lbrt->entry[i].attributes & 0x0002) >> 1) ?
4925 "LBA range should be hidden from the OS/EFI/BIOS" :
4926 "LBA range should be visible from the OS/EFI/BIOS");
4927 printf("\tslba : %#"PRIx64"l" "x""\n", le64_to_cpu(lbrt->entry[i].slba));
4928 printf("\tnlb : %#"PRIx64"l" "x""\n", le64_to_cpu(lbrt->entry[i].nlb));
4929 printf("\tguid : ");
4930 for (j = 0; j < ARRAY_SIZE(lbrt->entry[i].guid)(sizeof(lbrt->entry[i].guid) / sizeof((lbrt->entry[i].guid
)[0]))
; j++)
4931 printf("%02x", lbrt->entry[i].guid[j]);
4932 printf("\n");
4933 }
4934}
4935
4936static void stdout_auto_pst(struct nvme_feat_auto_pst *apst)
4937{
4938 int i;
4939 __u64 value;
4940
4941 printf("\tAuto PST Entries");
4942 printf("\t.................\n");
4943 for (i = 0; i < ARRAY_SIZE(apst->apst_entry)(sizeof(apst->apst_entry) / sizeof((apst->apst_entry)[0
]))
; i++) {
4944 value = le64_to_cpu(apst->apst_entry[i]);
4945
4946 printf("\tEntry[%2d]\n", i);
4947 printf("\t.................\n");
4948 printf("\tIdle Time Prior to Transition (ITPT): %u ms\n",
4949 (__u32)NVME_GET(value, APST_ENTRY_ITPT)(((value) >> NVME_APST_ENTRY_ITPT_SHIFT) & NVME_APST_ENTRY_ITPT_MASK
)
);
4950 printf("\tIdle Transition Power State (ITPS): %u\n",
4951 (__u32)NVME_GET(value, APST_ENTRY_ITPS)(((value) >> NVME_APST_ENTRY_ITPS_SHIFT) & NVME_APST_ENTRY_ITPS_MASK
)
);
4952 printf("\t.................\n");
4953 }
4954}
4955
4956static const char *stdout_format_timestamp(__u8 *timestamp_bytes)
4957{
4958 static char buf[STR_LEN100];
4959 uint64_t ts_ms = int48_to_long(timestamp_bytes);
4960
4961 snprintf(buf, sizeof(buf), "%"PRIu64"l" "u"" (%s)", ts_ms,
4962 nvme_format_timestamp(timestamp_bytes));
4963
4964 return buf;
4965}
4966
4967static void stdout_timestamp(struct nvme_timestamp *ts)
4968{
4969 printf("\tThe timestamp is : %s\n", stdout_format_timestamp(ts->timestamp));
4970 printf("\t%s\n", nvme_format_timestamp_origin(ts->attr));
4971 printf("\t%s\n", nvme_format_timestamp_sync(ts->attr));
4972}
4973
4974static void stdout_host_mem_buffer(struct nvme_host_mem_buf_attrs *hmb)
4975{
4976 printf("\tHost Memory Descriptor List Entry Count (HMDLEC): %u\n",
4977 le32_to_cpu(hmb->hmdlec));
4978 printf("\tHost Memory Descriptor List Address (HMDLAU): %#x\n",
4979 le32_to_cpu(hmb->hmdlau));
4980 printf("\tHost Memory Descriptor List Address (HMDLAL): %#x\n",
4981 le32_to_cpu(hmb->hmdlal));
4982 printf("\tHost Memory Buffer Size (HSIZE): %u\n",
4983 le32_to_cpu(hmb->hsize));
4984}
4985
4986static void stdout_directive_show_fields(__u8 dtype, __u8 doper,
4987 unsigned int result, unsigned char *buf)
4988{
4989 __u8 *field = buf;
4990 int count, i;
4991
4992 switch (dtype) {
4993 case NVME_DIRECTIVE_DTYPE_IDENTIFY:
4994 switch (doper) {
4995 case NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM:
4996 printf("\tDirective support\n");
4997 printf("\t\tIdentify Directive : %s\n",
4998 (*field & 0x1) ? "supported" : "not supported");
4999 printf("\t\tStream Directive : %s\n",
5000 (*field & 0x2) ? "supported" : "not supported");
5001 printf("\t\tData Placement Directive : %s\n",
5002 (*field & 0x4) ? "supported" : "not supported");
5003 printf("\tDirective enabled\n");
5004 printf("\t\tIdentify Directive : %s\n",
5005 (*(field + 32) & 0x1) ? "enabled" : "disabled");
5006 printf("\t\tStream Directive : %s\n",
5007 (*(field + 32) & 0x2) ? "enabled" : "disabled");
5008 printf("\t\tData Placement Directive : %s\n",
5009 (*(field + 32) & 0x4) ? "enabled" : "disabled");
5010 printf("\tDirective Persistent Across Controller Level Resets\n");
5011 printf("\t\tIdentify Directive : %s\n",
5012 (*(field + 64) & 0x1) ? "enabled" : "disabled");
5013 printf("\t\tStream Directive : %s\n",
5014 (*(field + 64) & 0x2) ? "enabled" : "disabled");
5015 printf("\t\tData Placement Directive : %s\n",
5016 (*(field + 64) & 0x4) ? "enabled" : "disabled");
5017 break;
5018 default:
5019 fprintf(stderrstderr,
5020 "invalid directive operations for Identify Directives\n");
5021 break;
5022 }
5023 break;
5024 case NVME_DIRECTIVE_DTYPE_STREAMS:
5025 switch (doper) {
5026 case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM:
5027 printf("\tMax Streams Limit (MSL): %u\n",
5028 *(__u16 *)field);
5029 printf("\tNVM Subsystem Streams Available (NSSA): %u\n",
5030 *(__u16 *)(field + 2));
5031 printf("\tNVM Subsystem Streams Open (NSSO): %u\n",
5032 *(__u16 *)(field + 4));
5033 printf("\tNVM Subsystem Stream Capability (NSSC): %u\n",
5034 *(__u16 *)(field + 6));
5035 printf("\tStream Write Size (in unit of LB size) (SWS): %u\n",
5036 *(__u32 *)(field + 16));
5037 printf("\tStream Granularity Size (in unit of SWS) (SGS): %u\n",
5038 *(__u16 *)(field + 20));
5039 printf("\tNamespace Streams Allocated (NSA): %u\n",
5040 *(__u16 *)(field + 22));
5041 printf("\tNamespace Streams Open (NSO): %u\n",
5042 *(__u16 *)(field + 24));
5043 break;
5044 case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS:
5045 count = *(__u16 *)field;
5046 printf("\tOpen Stream Count : %u\n", *(__u16 *)field);
5047 for (i = 0; i < count; i++)
5048 printf("\tStream Identifier %.6u : %u\n", i + 1,
5049 *(__u16 *)(field + ((i + 1) * 2)));
5050 break;
5051 case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE:
5052 printf("\tNamespace Streams Allocated (NSA): %u\n",
5053 result & 0xffff);
5054 break;
5055 default:
5056 fprintf(stderrstderr,
5057 "invalid directive operations for Streams Directives\n");
5058 break;
5059 }
5060 break;
5061 default:
5062 fprintf(stderrstderr, "invalid directive type\n");
5063 break;
5064 }
5065}
5066
5067static void stdout_directive_show(__u8 type, __u8 oper, __u16 spec, __u32 nsid, __u64 result,
5068 void *buf, __u32 len)
5069{
5070 printf("dir-receive: type:%#x operation:%#x spec:%#x nsid:%#x result:%#"PRIx64"l" "x""\n",
5071 type, oper, spec, nsid, (uint64_t)result);
5072 if (stdout_print_ops.flags & VERBOSE)
5073 stdout_directive_show_fields(type, oper, result, buf);
5074 else if (buf)
5075 d(buf, len, 16, 1);
5076}
5077
5078static void stdout_lba_status_info(__u64 result)
5079{
5080 printf("\tLBA Status Information Poll Interval (LSIPI) : %u\n",
5081 (__u32)NVME_FEAT_LBAS_LSIPI(result)(((result) >> NVME_FEAT_LBAS_LSIPI_SHIFT) & NVME_FEAT_LBAS_LSIPI_MASK
)
);
5082 printf("\tLBA Status Information Report Interval (LSIRI): %u\n",
5083 (__u32)NVME_FEAT_LBAS_LSIRI(result)(((result) >> NVME_FEAT_LBAS_LSIRI_SHIFT) & NVME_FEAT_LBAS_LSIRI_MASK
)
);
5084}
5085
5086static bool_Bool line_equal(unsigned char *buf, int len, int width, int offset)
5087{
5088 if (!offset || len < offset + width ||
5089 log_level >= LIBNVME_LOG_DEBUG_VERBOSE)
5090 return false0;
5091
5092 return !memcmp(buf + offset - width, buf + offset, width);
5093}
5094
5095void stdout_d(unsigned char *buf, int len, int width, int group)
5096{
5097 int i, offset = 0;
5098 char ascii[32 + 1] = { 0 };
5099 bool_Bool omitting = false0;
5100
5101 assert(width < sizeof(ascii))((void) sizeof ((width < sizeof(ascii)) ? 1 : 0), __extension__
({ if (width < sizeof(ascii)) ; else __assert_fail ("width < sizeof(ascii)"
, "../nvme-print-stdout.c", 5101, __extension__ __PRETTY_FUNCTION__
); }))
;
5102
5103 printf(" ");
5104
5105 for (i = 0; i <= 15; i++)
5106 printf("%3x", i);
5107
5108 for (i = 0; i < len; i++) {
5109 if (!(i % width)) {
5110 if (line_equal(buf, len, width, offset)) {
5111 if (!omitting) {
5112 omitting = true1;
5113 printf("\n*");
5114 }
5115 offset += width;
5116 continue;
5117 } else if (omitting) {
5118 omitting = false0;
5119 }
5120 printf("\n%04x:", offset);
5121 }
5122 if (omitting)
5123 continue;
5124 if (i % group)
5125 printf("%02x", buf[i]);
5126 else
5127 printf(" %02x", buf[i]);
5128 ascii[i % width] = (buf[i] >= '!' && buf[i] <= '~') ? buf[i] : '.';
5129 if (!((i + 1) % width)) {
5130 printf(" \"%.*s\"", width, ascii);
5131 offset += width;
5132 memset(ascii, 0, sizeof(ascii));
5133 }
5134 }
5135 if (omitting)
5136 printf("\n%04x:\n", offset);
5137
5138 if (strlen(ascii)) {
5139 unsigned int b = width - (i % width);
5140
5141 printf(" %*s \"%.*s\"", 2 * b + b / group + (b % group ? 1 : 0), "", width, ascii);
5142 }
5143
5144 printf("\n");
5145}
5146
5147static void stdout_plm_config(struct nvme_plm_config *plmcfg)
5148{
5149 printf("\tEnable Event :%04x\n", le16_to_cpu(plmcfg->ee));
5150 printf("\tDTWIN Reads Threshold :%"PRIu64"l" "u""\n", le64_to_cpu(plmcfg->dtwinrt));
5151 printf("\tDTWIN Writes Threshold:%"PRIu64"l" "u""\n", le64_to_cpu(plmcfg->dtwinwt));
5152 printf("\tDTWIN Time Threshold :%"PRIu64"l" "u""\n", le64_to_cpu(plmcfg->dtwintt));
5153}
5154
5155static void stdout_feat_perfc_std(struct nvme_std_perf_attr *data)
5156{
5157 printf("random 4 kib average read latency (R4KARL): %s (0x%02x)\n",
5158 nvme_feature_perfc_r4karl_to_string(data->r4karl), data->r4karl);
5159}
5160
5161static void stdout_feat_perfc_id_list(struct nvme_perf_attr_id_list *data)
5162{
5163 int i;
5164 int attri_vs;
5165
5166 printf("attribute type (ATTRTYP): %s (0x%02x)\n",
5167 nvme_feature_perfc_attrtyp_to_string(data->attrtyp), data->attrtyp);
5168 printf("maximum saveable vendor specific performance attributes (MSVSPA): %d\n",
5169 data->msvspa);
5170 printf("unused saveable vendor specific performance attributes (USVSPA): %d\n",
5171 data->usvspa);
5172
5173 printf("performance attribute identifier list\n");
5174 for (i = 0; i < ARRAY_SIZE(data->id_list)(sizeof(data->id_list) / sizeof((data->id_list)[0])); i++) {
5175 attri_vs = i + NVME_FEAT_PERFC_ATTRI_VS_MIN;
5176 printf("performance attribute %02xh identifier (PA%02XHI): %s\n", attri_vs,
5177 attri_vs, util_uuid_to_string(data->id_list[i].id));
5178 }
5179}
5180
5181static void stdout_feat_perfc_vs(struct nvme_vs_perf_attr *data)
5182{
5183 printf("performance attribute identifier (PAID): %s\n", util_uuid_to_string(data->paid));
5184 printf("attribute length (ATTRL): %u\n", data->attrl);
5185 printf("vendor specific (VS):\n");
5186 d((unsigned char *)data->vs, data->attrl, 16, 1);
5187}
5188
5189static void stdout_feat_perfc(unsigned int result,
5190 struct nvme_perf_characteristics *data)
5191{
5192 __u8 attri;
5193 bool_Bool rvspa;
5194
5195 nvme_feature_decode_perf_characteristics(result, &attri, &rvspa);
5196
5197 printf("attribute index (ATTRI): %s (0x%02x)\n", nvme_feature_perfc_attri_to_string(attri),
5198 attri);
5199
5200 switch (attri) {
5201 case NVME_FEAT_PERFC_ATTRI_STD:
5202 stdout_feat_perfc_std(data->std_perf);
5203 break;
5204 case NVME_FEAT_PERFC_ATTRI_ID_LIST:
5205 stdout_feat_perfc_id_list(data->id_list);
5206 break;
5207 case NVME_FEAT_PERFC_ATTRI_VS_MIN ... NVME_FEAT_PERFC_ATTRI_VS_MAX:
5208 stdout_feat_perfc_vs(data->vs_perf);
5209 break;
5210 default:
5211 break;
5212 }
5213}
5214
5215static void stdout_host_metadata(enum nvme_features_id fid,
5216 struct nvme_host_metadata *data)
5217{
5218 struct nvme_metadata_element_desc *desc = &data->descs[0];
5219 int i;
5220 char val[4096];
5221 __u16 len;
5222
5223 printf("\tNum Metadata Element Descriptors: %d\n", data->ndesc);
5224 for (i = 0; i < data->ndesc; i++) {
5225 len = le16_to_cpu(desc->len);
5226 strncpy(val, (char *)desc->val, min(sizeof(val) - 1, len)((sizeof(val) - 1) > (len) ? (len) : (sizeof(val) - 1)));
5227
5228 printf("\tElement[%-3d]:\n", i);
5229 printf("\t\tType : %#02x (%s)\n", desc->type,
5230 nvme_host_metadata_type_to_string(fid, desc->type));
5231 printf("\t\tRevision : %d\n", desc->rev);
5232 printf("\t\tLength : %d\n", len);
5233 printf("\t\tValue : %s\n", val);
5234
5235 desc = (struct nvme_metadata_element_desc *)&desc->val[desc->len];
5236 }
5237}
5238
5239static void stdout_feat_host_id(unsigned int result, unsigned char *hostid)
5240{
5241 bool_Bool exhid;
5242
5243 if (!hostid)
5244 return;
5245
5246 nvme_feature_decode_host_id(result, &exhid);
5247
5248 if (exhid)
5249 printf("\tHost Identifier (HOSTID): %s\n",
5250 uint128_t_to_l10n_string(le128_to_cpu(hostid)));
5251 else
5252 printf("\tHost Identifier (HOSTID): %" PRIu64"l" "u" "\n",
5253 le64_to_cpu(*(__le64 *)hostid));
5254}
5255
5256static void stdout_feature_show(enum nvme_features_id fid, int sel,
5257 unsigned int result, void *buf, __u32 data_len)
5258{
5259 printf("get-feature:%#0*x (%s), %s value:%#0*x\n", fid ? 4 : 2, fid,
5260 nvme_feature_to_string(fid), nvme_select_to_string(sel), result ? 10 : 8, result);
5261
5262 if (NVME_CHECK(sel, GET_FEATURES_SEL, SUPPORTED)((sel) == NVME_GET_FEATURES_SEL_SUPPORTED))
5263 stdout_select_result(fid, result);
5264 else if (stdout_print_ops.flags & VERBOSE)
5265 stdout_feature_show_fields(fid, result, buf);
5266 else if (buf)
5267 d(buf, data_len, 16, 1);
5268}
5269
5270static void stdout_feature_show_fields(enum nvme_features_id fid,
5271 unsigned int result,
5272 unsigned char *buf)
5273{
5274 const char *async = "Send async event";
5275 const char *no_async = "Do not send async event";
5276 __u8 field;
5277
5278 switch (fid) {
5279 case NVME_FEAT_FID_ARBITRATION:
5280 printf("\tHigh Priority Weight (HPW): %u\n", NVME_FEAT_ARB_HPW(result)(((result) >> NVME_FEAT_ARBITRATION_HPW_SHIFT) & NVME_FEAT_ARBITRATION_HPW_MASK
)
+ 1);
5281 printf("\tMedium Priority Weight (MPW): %u\n", NVME_FEAT_ARB_MPW(result)(((result) >> NVME_FEAT_ARBITRATION_MPW_SHIFT) & NVME_FEAT_ARBITRATION_MPW_MASK
)
+ 1);
5282 printf("\tLow Priority Weight (LPW): %u\n", NVME_FEAT_ARB_LPW(result)(((result) >> NVME_FEAT_ARBITRATION_LPW_SHIFT) & NVME_FEAT_ARBITRATION_LPW_MASK
)
+ 1);
5283 printf("\tArbitration Burst (AB): ");
5284 if (NVME_FEAT_ARB_BURST(result)(((result) >> NVME_FEAT_ARBITRATION_BURST_SHIFT) & NVME_FEAT_ARBITRATION_BURST_MASK
)
== NVME_FEAT_ARBITRATION_BURST_MASK)
5285 printf("No limit\n");
5286 else
5287 printf("%u\n", 1 << NVME_FEAT_ARB_BURST(result)(((result) >> NVME_FEAT_ARBITRATION_BURST_SHIFT) & NVME_FEAT_ARBITRATION_BURST_MASK
)
);
5288 break;
5289 case NVME_FEAT_FID_POWER_MGMT:
5290 field = NVME_FEAT_PM_WH(result)(((result) >> NVME_FEAT_PWRMGMT_WH_SHIFT) & NVME_FEAT_PWRMGMT_WH_MASK
)
;
5291 printf("\tWorkload Hint (WH): %u - %s\n", field,
5292 nvme_feature_wl_hints_to_string(field));
5293 printf("\tPower State (PS): %u\n", NVME_FEAT_PM_PS(result)(((result) >> NVME_FEAT_PWRMGMT_PS_SHIFT) & NVME_FEAT_PWRMGMT_PS_MASK
)
);
5294 break;
5295 case NVME_FEAT_FID_LBA_RANGE:
5296 field = NVME_FEAT_LBAR_NR(result)(((result) >> NVME_FEAT_LBAR_NR_SHIFT) & NVME_FEAT_LBAR_NR_MASK
)
;
5297 printf("\tNumber of LBA Ranges (NUM): %u\n", field + 1);
5298 if (buf)
5299 stdout_lba_range((struct nvme_lba_range_type *)buf, field);
5300 break;
5301 case NVME_FEAT_FID_TEMP_THRESH:
5302 field = (result & 0x1c00000) >> 22;
5303 printf("\tTemperature Threshold Hysteresis(TMPTHH): %s (%u K, %s)\n",
5304 nvme_degrees_string(field), field, nvme_degrees_fahrenheit_string(field));
5305 field = NVME_FEAT_TT_THSEL(result)(((result) >> NVME_FEAT_TT_THSEL_SHIFT) & NVME_FEAT_TT_THSEL_MASK
)
;
5306 printf("\tThreshold Type Select (THSEL): %u - %s\n", field,
5307 nvme_feature_temp_type_to_string(field));
5308 field = NVME_FEAT_TT_TMPSEL(result)(((result) >> NVME_FEAT_TT_TMPSEL_SHIFT) & NVME_FEAT_TT_TMPSEL_MASK
)
;
5309 printf("\tThreshold Temperature Select (TMPSEL): %u - %s\n",
5310 field, nvme_feature_temp_sel_to_string(field));
5311 printf("\tTemperature Threshold (TMPTH): %s (%u K, %s)\n",
5312 nvme_degrees_string(NVME_FEAT_TT_TMPTH(result)(((result) >> NVME_FEAT_TT_TMPTH_SHIFT) & NVME_FEAT_TT_TMPTH_MASK
)
), NVME_FEAT_TT_TMPTH(result)(((result) >> NVME_FEAT_TT_TMPTH_SHIFT) & NVME_FEAT_TT_TMPTH_MASK
)
,
5313 nvme_degrees_fahrenheit_string(NVME_FEAT_TT_TMPTH(result)(((result) >> NVME_FEAT_TT_TMPTH_SHIFT) & NVME_FEAT_TT_TMPTH_MASK
)
));
5314 break;
5315 case NVME_FEAT_FID_ERR_RECOVERY:
5316 printf("\tDeallocated or Unwritten Logical Block Error Enable (DULBE): %s\n",
5317 NVME_FEAT_ER_DULBE(result)(((result) >> NVME_FEAT_ERROR_RECOVERY_DULBE_SHIFT) &
NVME_FEAT_ERROR_RECOVERY_DULBE_MASK)
? "Enabled" : "Disabled");
5318 printf("\tTime Limited Error Recovery (TLER): %u ms\n",
5319 NVME_FEAT_ER_TLER(result)(((result) >> NVME_FEAT_ERROR_RECOVERY_TLER_SHIFT) &
NVME_FEAT_ERROR_RECOVERY_TLER_MASK)
* 100);
5320 break;
5321 case NVME_FEAT_FID_VOLATILE_WC:
5322 printf("\tVolatile Write Cache Enable (WCE): %s\n",
5323 NVME_FEAT_VWC_WCE(result)(((result) >> NVME_FEAT_VWC_WCE_SHIFT) & NVME_FEAT_VWC_WCE_MASK
)
? "Enabled" : "Disabled");
5324 break;
5325 case NVME_FEAT_FID_NUM_QUEUES:
5326 printf("\tNumber of IO Completion Queues Allocated (NCQA): %u\n",
5327 NVME_FEAT_NRQS_NCQR(result)(((result) >> NVME_FEAT_NRQS_NCQR_SHIFT) & NVME_FEAT_NRQS_NCQR_MASK
)
+ 1);
5328 printf("\tNumber of IO Submission Queues Allocated (NSQA): %u\n",
5329 NVME_FEAT_NRQS_NSQR(result)(((result) >> NVME_FEAT_NRQS_NSQR_SHIFT) & NVME_FEAT_NRQS_NSQR_MASK
)
+ 1);
5330 break;
5331 case NVME_FEAT_FID_IRQ_COALESCE:
5332 printf("\tAggregation Time (TIME): %u usec\n",
5333 NVME_FEAT_IRQC_TIME(result)(((result) >> NVME_FEAT_IRQC_TIME_SHIFT) & NVME_FEAT_IRQC_TIME_MASK
)
* 100);
5334 printf("\tAggregation Threshold (THR): %u\n", NVME_FEAT_IRQC_THR(result)(((result) >> NVME_FEAT_IRQC_THR_SHIFT) & NVME_FEAT_IRQC_THR_MASK
)
+ 1);
5335 break;
5336 case NVME_FEAT_FID_IRQ_CONFIG:
5337 printf("\tCoalescing Disable (CD): %s\n",
5338 NVME_FEAT_ICFG_CD(result)(((result) >> NVME_FEAT_ICFG_CD_SHIFT) & NVME_FEAT_ICFG_CD_MASK
)
? "True" : "False");
5339 printf("\tInterrupt Vector (IV): %u\n", NVME_FEAT_ICFG_IV(result)(((result) >> NVME_FEAT_ICFG_IV_SHIFT) & NVME_FEAT_ICFG_IV_MASK
)
);
5340 break;
5341 case NVME_FEAT_FID_WRITE_ATOMIC:
5342 printf("\tDisable Normal (DN): %s\n", NVME_FEAT_WA_DN(result)(((result) >> NVME_FEAT_WA_DN_SHIFT) & NVME_FEAT_WA_DN_MASK
)
? "True" : "False");
5343 break;
5344 case NVME_FEAT_FID_ASYNC_EVENT:
5345 printf("\tDiscovery Log Page Change Notices : %s\n",
5346 NVME_FEAT_AE_DLPCN(result)(((result) >> NVME_FEAT_AE_DLPCN_SHIFT) & NVME_FEAT_AE_DLPCN_MASK
)
? async : no_async);
5347 printf("\tHost Discovery Log Page Change Notification : %s\n",
5348 NVME_FEAT_AE_HDLPCN(result)(((result) >> NVME_FEAT_AE_HDLPCN_SHIFT) & NVME_FEAT_AE_HDLPCN_MASK
)
? async : no_async);
5349 printf("\tAVE Discovery Log Page Change Notification : %s\n",
5350 NVME_FEAT_AE_ADLPCN(result)(((result) >> NVME_FEAT_AE_ADLPCN_SHIFT) & NVME_FEAT_AE_ADLPCN_MASK
)
? async : no_async);
5351 printf("\tPull Model DDC Request Log Page Change Notification : %s\n",
5352 NVME_FEAT_AE_PMDRLPCN(result)(((result) >> NVME_FEAT_AE_PMDRLPCN_SHIFT) & NVME_FEAT_AE_PMDRLPCN_MASK
)
? async : no_async);
5353 printf("\tZone Descriptor Changed Notices : %s\n",
5354 NVME_FEAT_AE_ZDCN(result)(((result) >> NVME_FEAT_AE_ZDCN_SHIFT) & NVME_FEAT_AE_ZDCN_MASK
)
? async : no_async);
5355 printf("\tAllocated Namespace Attribute Notices : %s\n",
5356 NVME_FEAT_AE_ANSAN(result)(((result) >> NVME_FEAT_AE_ANSAN_SHIFT) & NVME_FEAT_AE_ANSAN_MASK
)
? async : no_async);
5357 printf("\tReachability Group : %s\n",
5358 NVME_FEAT_AE_RGRP0(result)(((result) >> NVME_FEAT_AE_RGRP0_SHIFT) & NVME_FEAT_AE_RGRP0_MASK
)
? async : no_async);
5359 printf("\tReachability Association : %s\n",
5360 NVME_FEAT_AE_RASSN(result)(((result) >> NVME_FEAT_AE_RASSN_SHIFT) & NVME_FEAT_AE_RASSN_MASK
)
? async : no_async);
5361 printf("\tTemperature Threshold Hysteresis Recovery : %s\n",
5362 NVME_FEAT_AE_TTHRY(result)(((result) >> NVME_FEAT_AE_TTHRY_SHIFT) & NVME_FEAT_AE_TTHRY_MASK
)
? async : no_async);
5363 printf("\tNormal NVM Subsystem Shutdown : %s\n",
5364 NVME_FEAT_AE_NNSSHDN(result)(((result) >> NVME_FEAT_AE_NNSSHDN_SHIFT) & NVME_FEAT_AE_NNSSHDN_MASK
)
? async : no_async);
5365 printf("\tEndurance Group Event Aggregate Log Change Notices : %s\n",
5366 NVME_FEAT_AE_EGA(result)(((result) >> NVME_FEAT_AE_EGA_SHIFT) & NVME_FEAT_AE_EGA_MASK
)
? async : no_async);
5367 printf("\tLBA Status Information Notices : %s\n",
5368 NVME_FEAT_AE_LBAS(result)(((result) >> NVME_FEAT_AE_LBAS_SHIFT) & NVME_FEAT_AE_LBAS_MASK
)
? async : no_async);
5369 printf("\tPredictable Latency Event Aggregate Log Change Notices : %s\n",
5370 NVME_FEAT_AE_PLA(result)(((result) >> NVME_FEAT_AE_PLA_SHIFT) & NVME_FEAT_AE_PLA_MASK
)
? async : no_async);
5371 printf("\tAsymmetric Namespace Access Change Notices : %s\n",
5372 NVME_FEAT_AE_ANA(result)(((result) >> NVME_FEAT_AE_ANA_SHIFT) & NVME_FEAT_AE_ANA_MASK
)
? async : no_async);
5373 printf("\tTelemetry Log Notices : %s\n",
5374 NVME_FEAT_AE_TELEM(result)(((result) >> NVME_FEAT_AE_TELEM_SHIFT) & NVME_FEAT_AE_TELEM_MASK
)
? async : no_async);
5375 printf("\tFirmware Activation Notices : %s\n",
5376 NVME_FEAT_AE_FW(result)(((result) >> NVME_FEAT_AE_FW_SHIFT) & NVME_FEAT_AE_FW_MASK
)
? async : no_async);
5377 printf("\tNamespace Attribute Notices : %s\n",
5378 NVME_FEAT_AE_NAN(result)(((result) >> NVME_FEAT_AE_NAN_SHIFT) & NVME_FEAT_AE_NAN_MASK
)
? async : no_async);
5379 printf("\tSMART / Health Critical Warnings : %s\n",
5380 NVME_FEAT_AE_SMART(result)(((result) >> NVME_FEAT_AE_SMART_SHIFT) & NVME_FEAT_AE_SMART_MASK
)
? async : no_async);
5381 break;
5382 case NVME_FEAT_FID_AUTO_PST:
5383 printf("\tAutonomous Power State Transition Enable (APSTE): %s\n",
5384 NVME_FEAT_APST_APSTE(result)(((result) >> NVME_FEAT_APST_APSTE_SHIFT) & NVME_FEAT_APST_APSTE_MASK
)
? "Enabled" : "Disabled");
5385 if (buf)
5386 stdout_auto_pst((struct nvme_feat_auto_pst *)buf);
5387 break;
5388 case NVME_FEAT_FID_HOST_MEM_BUF:
5389 printf("\tEnable Host Memory (EHM): %s\n",
5390 NVME_FEAT_HMEM_EHM(result)(((result) >> NVME_FEAT_HMEM_EHM_SHIFT) & NVME_FEAT_HMEM_EHM_MASK
)
? "Enabled" : "Disabled");
5391 printf("\tHost Memory Non-operational Access Restriction Enable (HMNARE): %s\n",
5392 (result & 0x00000004) ? "True" : "False");
5393 printf("\tHost Memory Non-operational Access Restricted (HMNAR): %s\n",
5394 (result & 0x00000008) ? "True" : "False");
5395 if (buf)
5396 stdout_host_mem_buffer((struct nvme_host_mem_buf_attrs *)buf);
5397 break;
5398 case NVME_FEAT_FID_TIMESTAMP:
5399 if (buf)
5400 stdout_timestamp((struct nvme_timestamp *)buf);
5401 break;
5402 case NVME_FEAT_FID_KATO:
5403 printf("\tKeep Alive Timeout (KATO) in milliseconds: %u\n", result);
5404 break;
5405 case NVME_FEAT_FID_HCTM:
5406 printf("\tThermal Management Temperature 1 (TMT1) : %u K (%s, %s)\n",
5407 NVME_FEAT_HCTM_TMT1(result)(((result) >> NVME_FEAT_HCTM_TMT1_SHIFT) & NVME_FEAT_HCTM_TMT1_MASK
)
,
5408 nvme_degrees_string(NVME_FEAT_HCTM_TMT1(result)(((result) >> NVME_FEAT_HCTM_TMT1_SHIFT) & NVME_FEAT_HCTM_TMT1_MASK
)
),
5409 nvme_degrees_fahrenheit_string(NVME_FEAT_HCTM_TMT1(result)(((result) >> NVME_FEAT_HCTM_TMT1_SHIFT) & NVME_FEAT_HCTM_TMT1_MASK
)
));
5410 printf("\tThermal Management Temperature 2 (TMT2) : %u K (%s, %s)\n",
5411 NVME_FEAT_HCTM_TMT2(result)(((result) >> NVME_FEAT_HCTM_TMT2_SHIFT) & NVME_FEAT_HCTM_TMT2_MASK
)
,
5412 nvme_degrees_string(NVME_FEAT_HCTM_TMT2(result)(((result) >> NVME_FEAT_HCTM_TMT2_SHIFT) & NVME_FEAT_HCTM_TMT2_MASK
)
),
5413 nvme_degrees_fahrenheit_string(NVME_FEAT_HCTM_TMT2(result)(((result) >> NVME_FEAT_HCTM_TMT2_SHIFT) & NVME_FEAT_HCTM_TMT2_MASK
)
));
5414 break;
5415 case NVME_FEAT_FID_NOPSC:
5416 printf("\tNon-Operational Power State Permissive Mode Enable (NOPPME): %s\n",
5417 NVME_FEAT_NOPS_NOPPME(result)(((result) >> NVME_FEAT_NOPS_NOPPME_SHIFT) & NVME_FEAT_NOPS_NOPPME_MASK
)
? "True" : "False");
5418 break;
5419 case NVME_FEAT_FID_RRL:
5420 printf("\tRead Recovery Level (RRL): %u\n", NVME_FEAT_RRL_RRL(result)(((result) >> NVME_FEAT_RRL_RRL_SHIFT) & NVME_FEAT_RRL_RRL_MASK
)
);
5421 break;
5422 case NVME_FEAT_FID_PLM_CONFIG:
5423 printf("\tPredictable Latency Window Enabled: %s\n",
5424 NVME_FEAT_PLM_LPE(result)(((result) >> NVME_FEAT_PLM_LPE_SHIFT) & NVME_FEAT_PLM_LPE_MASK
)
? "True" : "False");
5425 if (buf)
5426 stdout_plm_config((struct nvme_plm_config *)buf);
5427 break;
5428 case NVME_FEAT_FID_PLM_WINDOW:
5429 printf("\tWindow Select: %s", nvme_plm_window_to_string(result));
5430 break;
5431 case NVME_FEAT_FID_LBA_STS_INTERVAL:
5432 stdout_lba_status_info(result);
5433 break;
5434 case NVME_FEAT_FID_HOST_BEHAVIOR:
5435 if (buf) {
5436 struct nvme_feat_host_behavior *host_behavior =
5437 (struct nvme_feat_host_behavior *)buf;
5438 printf("\tAdvanced Command Retry Enable (ACRE) : %s\n",
5439 host_behavior->acre ? "True" : "False");
5440 printf("\tExtended Telemetry Data Area 4 Supported (ETDAS) : %s\n",
5441 host_behavior->etdas ? "True" : "False");
5442 printf("\tLBA Format Extension Enable (LBAFEE) : %s\n",
5443 host_behavior->lbafee ? "True" : "False");
5444 printf("\tHost Dispersed Namespace Support (HDISNS) : %s\n",
5445 host_behavior->hdisns ? "Enabled" : "Disabled");
5446 printf("\tCopy Descriptor Format 2h Enabled (CDF2E) : %s\n",
5447 host_behavior->cdfe & (1 << 2) ? "True" : "False");
5448 printf("\tCopy Descriptor Format 3h Enabled (CDF3E) : %s\n",
5449 host_behavior->cdfe & (1 << 3) ? "True" : "False");
5450 printf("\tCopy Descriptor Format 4h Enabled (CDF4E) : %s\n",
5451 host_behavior->cdfe & (1 << 4) ? "True" : "False");
5452 }
5453 break;
5454 case NVME_FEAT_FID_SANITIZE:
5455 printf("\tNo-Deallocate Response Mode (NODRM) : %u\n", NVME_FEAT_SC_NODRM(result)(((result) >> NVME_FEAT_SC_NODRM_SHIFT) & NVME_FEAT_SC_NODRM_MASK
)
);
5456 break;
5457 case NVME_FEAT_FID_ENDURANCE_EVT_CFG:
5458 printf("\tEndurance Group Identifier (ENDGID): %u\n", NVME_FEAT_EG_ENDGID(result)(((result) >> NVME_FEAT_EG_ENDGID_SHIFT) & NVME_FEAT_EG_ENDGID_MASK
)
);
5459 printf("\tEndurance Group Critical Warnings : %u\n", NVME_FEAT_EG_EGCW(result)(((result) >> NVME_FEAT_EG_EGCW_SHIFT) & NVME_FEAT_EG_EGCW_MASK
)
);
5460 break;
5461 case NVME_FEAT_FID_IOCS_PROFILE:
5462 printf("\tI/O Command Set Profile: %s\n", result & 0x1 ? "True" : "False");
5463 break;
5464 case NVME_FEAT_FID_SPINUP_CONTROL:
5465 printf("\tSpinup control feature Enabled: %s\n", (result & 1) ? "True" : "False");
5466 break;
5467 case NVME_FEAT_FID_POWER_LOSS_SIGNAL:
5468 printf("\tPower Loss Signaling Mode (PLSM): %s\n",
5469 nvme_pls_mode_to_string(NVME_GET(result, FEAT_PLS_MODE)(((result) >> NVME_FEAT_PLS_MODE_SHIFT) & NVME_FEAT_PLS_MODE_MASK
)
));
5470 break;
5471 case NVME_FEAT_FID_PERF_CHARACTERISTICS:
5472 stdout_feat_perfc(result,
5473 (struct nvme_perf_characteristics *)buf);
5474 break;
5475 case NVME_FEAT_FID_ENH_CTRL_METADATA:
5476 case NVME_FEAT_FID_CTRL_METADATA:
5477 case NVME_FEAT_FID_NS_METADATA:
5478 if (buf)
5479 stdout_host_metadata(fid, (struct nvme_host_metadata *)buf);
5480 break;
5481 case NVME_FEAT_FID_SW_PROGRESS:
5482 printf("\tPre-boot Software Load Count (PBSLC): %u\n", NVME_FEAT_SPM_PBSLC(result)(((result) >> NVME_FEAT_SPM_PBSLC_SHIFT) & NVME_FEAT_SPM_PBSLC_MASK
)
);
5483 break;
5484 case NVME_FEAT_FID_HOST_ID:
5485 stdout_feat_host_id(result, buf);
5486 break;
5487 case NVME_FEAT_FID_RESV_NF_MASK:
5488 printf("\tMask Reservation Preempted Notification (RESPRE): %s\n",
5489 NVME_FEAT_RM_RESPRE(result)(((result) >> NVME_FEAT_RM_RESPRE_SHIFT) & NVME_FEAT_RM_RESPRE_MASK
)
? "True" : "False");
5490 printf("\tMask Reservation Released Notification (RESREL): %s\n",
5491 NVME_FEAT_RM_RESREL(result)(((result) >> NVME_FEAT_RM_RESREL_SHIFT) & NVME_FEAT_RM_RESREL_MASK
)
? "True" : "False");
5492 printf("\tMask Registration Preempted Notification (REGPRE): %s\n",
5493 NVME_FEAT_RM_REGPRE(result)(((result) >> NVME_FEAT_RM_REGPRE_SHIFT) & NVME_FEAT_RM_REGPRE_MASK
)
? "True" : "False");
5494 break;
5495 case NVME_FEAT_FID_RESV_PERSIST:
5496 printf("\tPersist Through Power Loss (PTPL): %s\n",
5497 NVME_FEAT_RP_PTPL(result)(((result) >> NVME_FEAT_RP_PTPL_SHIFT) & NVME_FEAT_RP_PTPL_MASK
)
? "True" : "False");
5498 break;
5499 case NVME_FEAT_FID_WRITE_PROTECT:
5500 printf("\tNamespace Write Protect: %s\n", nvme_ns_wp_cfg_to_string(result));
5501 break;
5502 case NVME_FEAT_FID_FDP:
5503 printf("\tFlexible Direct Placement Enable (FDPE) : %s\n",
5504 (result & 0x1) ? "Yes" : "No");
5505 printf("\tFlexible Direct Placement Configuration Index : %u\n",
5506 (result >> 8) & 0xf);
5507 break;
5508 case NVME_FEAT_FID_FDP_EVENTS:
5509 for (unsigned int i = 0; i < result; i++) {
5510 struct nvme_fdp_supported_event_desc *d;
5511
5512 d = &((struct nvme_fdp_supported_event_desc *)buf)[i];
5513
5514 printf("\t%-53s: %sEnabled\n", nvme_fdp_event_to_string(d->evt),
5515 d->evta & 0x1 ? "" : "Not ");
5516 }
5517 break;
5518 case NVME_FEAT_FID_BP_WRITE_PROTECT:
5519 field = NVME_FEAT_BPWPC_BP1WPS(result)(((result) >> NVME_FEAT_BPWPC_BP1WPS_SHIFT) & NVME_FEAT_BPWPC_BP1WPS_MASK
)
;
5520 printf("\tBoot Partition 1 Write Protection State (BP1WPS): %s\n",
5521 nvme_bpwps_to_string(field));
5522 field = NVME_FEAT_BPWPC_BP0WPS(result)(((result) >> NVME_FEAT_BPWPC_BP0WPS_SHIFT) & NVME_FEAT_BPWPC_BP0WPS_MASK
)
;
5523 printf("\tBoot Partition 0 Write Protection State (BP0WPS): %s\n",
5524 nvme_bpwps_to_string(field));
5525 break;
5526 case NVME_FEAT_FID_POWER_LIMIT:
5527 field = NVME_FEAT_POWER_LIMIT_PLS(result)(((result) >> NVME_FEAT_POWER_LIMIT_PLS_SHIFT) & NVME_FEAT_POWER_LIMIT_PLS_MASK
)
;
5528 printf("\tPower Limit Scale (PLS): %u - %s\n", field,
5529 nvme_feature_power_limit_scale_to_string(field));
5530 printf("\tPower Limit Value (PLV): %u\n",
5531 NVME_FEAT_POWER_LIMIT_PLV(result)(((result) >> NVME_FEAT_POWER_LIMIT_PLV_SHIFT) & NVME_FEAT_POWER_LIMIT_PLV_MASK
)
);
5532 printf("\tPower Limit: ");
5533 print_power_and_scale(NVME_FEAT_POWER_LIMIT_PLV(result)(((result) >> NVME_FEAT_POWER_LIMIT_PLV_SHIFT) & NVME_FEAT_POWER_LIMIT_PLV_MASK
)
, field);
5534 printf("\n");
5535 break;
5536 case NVME_FEAT_FID_POWER_THRESH:
5537 field = NVME_FEAT_POWER_THRESH_EPT(result)(((result) >> NVME_FEAT_POWER_THRESH_EPT_SHIFT) & NVME_FEAT_POWER_THRESH_EPT_MASK
)
;
5538 printf("\tEnable Power Threshold (EPT): %u - %s\n",
5539 field, field ? "Enabled" : "Disabled");
5540 field = NVME_FEAT_POWER_THRESH_PMTS(result)(((result) >> NVME_FEAT_POWER_THRESH_PMTS_SHIFT) & NVME_FEAT_POWER_THRESH_PMTS_MASK
)
;
5541 printf("\tPower Measurement Type Select (PMTS): %u - %s\n",
5542 field, nvme_power_measurement_type_to_string(field));
5543 field = NVME_FEAT_POWER_THRESH_PTS(result)(((result) >> NVME_FEAT_POWER_THRESH_PTS_SHIFT) & NVME_FEAT_POWER_THRESH_PTS_MASK
)
;
5544 printf("\tPower Threshold Scale (PTS): %u - %s\n", field,
5545 nvme_feature_power_limit_scale_to_string(field));
5546 printf("\tPower Threshold Value (PTV): %u\n",
5547 NVME_FEAT_POWER_THRESH_PTV(result)(((result) >> NVME_FEAT_POWER_THRESH_PTV_SHIFT) & NVME_FEAT_POWER_THRESH_PTV_MASK
)
);
5548 printf("\tPower Threshold: ");
5549 print_power_and_scale(NVME_FEAT_POWER_THRESH_PTV(result)(((result) >> NVME_FEAT_POWER_THRESH_PTV_SHIFT) & NVME_FEAT_POWER_THRESH_PTV_MASK
)
,
5550 field);
5551 printf("\n");
5552 break;
5553 case NVME_FEAT_FID_POWER_MEASUREMENT:
5554 field = NVME_FEAT_POWER_MEAS_ACT(result)(((result) >> NVME_FEAT_POWER_MEAS_ACT_SHIFT) & NVME_FEAT_POWER_MEAS_ACT_MASK
)
;
5555 printf("\tAction (ACT): %u - %s\n", field,
5556 nvme_power_measurement_action_to_string(field));
5557 field = NVME_FEAT_POWER_MEAS_PMTS(result)(((result) >> NVME_FEAT_POWER_MEAS_PMTS_SHIFT) & NVME_FEAT_POWER_MEAS_PMTS_MASK
)
;
5558 printf("\tPower Measurement Type Select (PMTS): %u - %s\n",
5559 field, nvme_power_measurement_type_to_string(field));
5560 printf("\tStop Measurement Time (SMT): %u\n",
5561 NVME_FEAT_POWER_MEAS_SMT(result)(((result) >> NVME_FEAT_POWER_MEAS_SMT_SHIFT) & NVME_FEAT_POWER_MEAS_SMT_MASK
)
);
5562 break;
5563 default:
5564 break;
5565 }
5566}
5567
5568static void stdout_lba_status(struct nvme_lba_status *list,
5569 unsigned long len)
5570{
5571 int idx;
5572
5573 printf("Number of LBA Status Descriptors(NLSD): %" PRIu32"u" "\n",
5574 le32_to_cpu(list->nlsd));
5575 printf("Completion Condition(CMPC): %u\n", list->cmpc);
5576
5577 switch (list->cmpc) {
5578 case NVME_LBA_STATUS_CMPC_NO_CMPC:
5579 printf("\tNo indication of the completion condition\n");
5580 break;
5581 case NVME_LBA_STATUS_CMPC_INCOMPLETE:
5582 printf("\tCompleted transferring the amount of data specified in the\n"\
5583 "\tMNDW field. But, additional LBA Status Descriptor Entries are\n"\
5584 "\tavailable to transfer or scan did not complete (if ATYPE = 10h)\n");
5585 break;
5586 case NVME_LBA_STATUS_CMPC_COMPLETE:
5587 printf("\tCompleted the specified action over the number of LBAs specified\n"\
5588 "\tin the Range Length field and transferred all available LBA Status\n"\
5589 "\tDescriptor Entries\n");
5590 break;
5591 default:
5592 break;
5593 }
5594
5595 for (idx = 0; idx < list->nlsd; idx++) {
5596 struct nvme_lba_status_desc *e = &list->descs[idx];
5597
5598 printf("{ DSLBA: %#016"PRIx64"l" "x"", NLB: %#08x, Status: %#02x }\n",
5599 le64_to_cpu(e->dslba), le32_to_cpu(e->nlb),
5600 e->status);
5601 }
5602}
5603
5604static void stdout_dev_full_path(libnvme_ns_t n, char *path, size_t len)
5605{
5606 struct stat st;
5607
5608 snprintf(path, len, "%s", libnvme_ns_get_name(n));
5609 if (strncmp(path, "/dev/spdk/", 10) == 0 && stat(path, &st) == 0)
5610 return;
5611
5612 snprintf(path, len, "/dev/%s", libnvme_ns_get_name(n));
5613 if (stat(path, &st) == 0)
5614 return;
5615
5616 /*
5617 * We could start trying to search for it but let's make
5618 * it simple and just don't show the path at all.
5619 */
5620 snprintf(path, len, "%s", libnvme_ns_get_name(n));
5621}
5622
5623static void stdout_generic_full_path(libnvme_ns_t n, char *path, size_t len)
5624{
5625 int head_instance;
5626 int instance;
5627 struct stat st;
5628
5629 /*
5630 * There is no block devices for SPDK, point generic path to existing
5631 * chardevice.
5632 */
5633 snprintf(path, len, "%s", libnvme_ns_get_name(n));
5634 if (strncmp(path, "/dev/spdk/", 10) == 0 && stat(path, &st) == 0)
5635 return;
5636
5637 if (sscanf(libnvme_ns_get_name(n), "nvme%dn%d", &instance, &head_instance) != 2)
5638 return;
5639
5640 snprintf(path, len, "/dev/ng%dn%d", instance, head_instance);
5641
5642 if (stat(path, &st) == 0)
5643 return;
5644
5645 /*
5646 * We could start trying to search for it but let's make
5647 * it simple and just don't show the path at all.
5648 */
5649 snprintf(path, len, "ng%dn%d", instance, head_instance);
5650}
5651
5652static void list_item(libnvme_ns_t n, struct table *t)
5653{
5654 char usage[128] = { 0 }, format[128] = { 0 };
5655 char devname[128] = { 0 }; char genname[128] = { 0 };
5656
5657 long long lba = libnvme_ns_get_lba_size(n);
5658 double nsze = libnvme_ns_get_lba_count(n) * lba;
5659 double nuse = libnvme_ns_get_lba_util(n) * lba;
5660
5661 const char *s_suffix = suffix_si_get(&nsze);
5662 const char *u_suffix = suffix_si_get(&nuse);
5663 const char *l_suffix = suffix_binary_get(&lba);
5664 char ns[STR_LEN100];
5665 int row;
5666
5667 snprintf(usage, sizeof(usage), "%6.2f %2sB / %6.2f %2sB", nuse,
5668 u_suffix, nsze, s_suffix);
5669 snprintf(format, sizeof(format), "%3.0f %2sB + %2d B", (double)lba,
5670 l_suffix, libnvme_ns_get_meta_size(n));
5671
5672 stdout_dev_full_path(n, devname, sizeof(devname));
5673 stdout_generic_full_path(n, genname, sizeof(genname));
5674
5675 row = table_get_row_id(t);
5676 if (row < 0) {
5677 printf("Failed to add row\n");
5678 return;
5679 }
5680 if (table_set_value_str(t, SIMPLE_LIST_COL_NODE, row, devname, LEFT)) {
5681 printf("Failed to set node value\n");
5682 return;
5683 }
5684 if (table_set_value_str(t, SIMPLE_LIST_COL_GENERIC, row, genname, LEFT)) {
5685 printf("Failed to set generic value\n");
5686 return;
5687 }
5688 if (table_set_value_str(t, SIMPLE_LIST_COL_SN, row, libnvme_ns_get_serial(n), LEFT)) {
5689 printf("Failed to set sn value\n");
5690 return;
5691 }
5692 if (table_set_value_str(t, SIMPLE_LIST_COL_MODEL, row, libnvme_ns_get_model(n), LEFT)) {
5693 printf("Failed to set model value\n");
5694 return;
5695 }
5696 if (!sprintf(ns, "0x%x", libnvme_ns_get_nsid(n))) {
5697 printf("Failed to output ns string\n");
5698 return;
5699 }
5700 if (table_set_value_str(t, SIMPLE_LIST_COL_NS, row, ns, LEFT)) {
5701 printf("Failed to set ns value\n");
5702 return;
5703 }
5704 if (table_set_value_str(t, SIMPLE_LIST_COL_USAGE, row, usage, LEFT)) {
5705 printf("Failed to set usage value\n");
5706 return;
5707 }
5708 if (table_set_value_str(t, SIMPLE_LIST_COL_FORMAT, row, format, LEFT)) {
5709 printf("Failed to set format value\n");
5710 return;
5711 }
5712 if (table_set_value_str(t, SIMPLE_LIST_COL_FW_REV, row, libnvme_ns_get_firmware(n), LEFT)) {
5713 printf("Failed to set fw rev value\n");
5714 return;
5715 }
5716 table_add_row(t, row);
5717}
5718
5719static void stdout_list_item(libnvme_ns_t n, struct table *t)
5720{
5721 list_item(n, t);
5722}
5723
5724static void stdout_list_item_table(libnvme_ns_t n, struct table *t)
5725{
5726 list_item(n, t);
5727}
5728
5729static bool_Bool stdout_simple_ns(const char *name, void *arg)
5730{
5731 struct nvme_resources_table *rst_t = arg;
5732 struct nvme_resources *res = rst_t->res;
5733 libnvme_ns_t n;
5734
5735 n = htable_ns_get(&res->ht_n, name);
5736 stdout_list_item_table(n, rst_t->t);
5737
5738 return true1;
5739}
5740
5741static void stdout_simple_list(struct libnvme_global_ctx *ctx)
5742{
5743 struct nvme_resources res;
5744 struct table_column columns[] = {
5745 { "Node", LEFT, 21 },
5746 { "Generic", LEFT, 21 },
5747 { "SN", LEFT, 20 },
5748 { "Model", LEFT, 40 },
5749 { "Namespace", LEFT, 10 },
5750 { "Usage", LEFT, 26 },
5751 { "Format", LEFT, 16 },
5752 { "FW Rev", LEFT, 8 },
5753 };
5754 struct table *t = table_init_with_columns(columns, ARRAY_SIZE(columns)(sizeof(columns) / sizeof((columns)[0])));
5755 struct nvme_resources_table res_t = { &res, t };
5756
5757 if (!t) {
5758 printf("Failed to init table\n");
5759 return;
5760 }
5761
5762 nvme_resources_init(ctx, &res);
5763
5764 strset_iterate(&res.namespaces, stdout_simple_ns, &res_t)strset_iterate_((&res.namespaces), ((_Bool (*)(const char
*, void *))(((stdout_simple_ns)))), (&res_t))
;
5765
5766 table_print(t);
5767
5768 nvme_resources_free(&res);
5769 table_free(t);
5770}
5771
5772static void stdout_ns_details(libnvme_ns_t n)
5773{
5774 char usage[128] = { 0 }, format[128] = { 0 }, usage_binary[128] = { 0 };
5775 char devname[128] = { 0 }, genname[128] = { 0 };
5776
5777 long long lba = libnvme_ns_get_lba_size(n);
5778 double nsze = libnvme_ns_get_lba_count(n) * lba;
5779 double nuse = libnvme_ns_get_lba_util(n) * lba;
5780 double nsze_binary = nsze, nuse_binary = nuse;
5781
5782 const char *s_suffix = suffix_si_get(&nsze);
5783 const char *u_suffix = suffix_si_get(&nuse);
5784 const char *l_suffix = suffix_binary_get(&lba);
5785
5786 const char *s_suffix_binary, *u_suffix_binary;
5787
5788 sprintf(usage, "%6.2f %1sB / %6.2f %1sB", nuse, u_suffix, nsze, s_suffix);
5789 sprintf(format, "%3.0f %2sB + %2d B", (double)lba, l_suffix,
5790 libnvme_ns_get_meta_size(n));
5791
5792 s_suffix_binary = suffix_dbinary_get(&nsze_binary);
5793 u_suffix_binary = suffix_dbinary_get(&nuse_binary);
5794 sprintf(usage_binary, "(%7.2f %2sB / %7.2f %2sB)", nuse_binary, u_suffix_binary,
5795 nsze_binary, s_suffix_binary);
5796
5797 nvme_dev_full_path(n, devname, sizeof(devname));
5798 nvme_generic_full_path(n, genname, sizeof(genname));
5799
5800 printf("%-17s %-17s %#-10x %-21s %-25s %-16s ", devname,
5801 genname, libnvme_ns_get_nsid(n), usage, usage_binary, format);
5802}
5803
5804static bool_Bool stdout_detailed_name(const char *name, void *arg)
5805{
5806 bool_Bool *first = arg;
5807
5808 printf("%s%s", *first ? "" : ", ", name);
5809 *first = false0;
5810
5811 return true1;
5812}
5813
5814static bool_Bool stdout_detailed_subsys(const char *name, void *arg)
5815{
5816 struct nvme_resources *res = arg;
5817 struct htable_subsys_iter it;
5818 struct strset ctrls;
5819 libnvme_subsystem_t s;
5820 libnvme_ctrl_t c;
5821 bool_Bool first;
5822
5823 strset_init(&ctrls);
5824 first = true1;
5825 for (s = htable_subsys_getfirst(&res->ht_s, name, &it);
5826 s;
5827 s = htable_subsys_getnext(&res->ht_s, name, &it)) {
5828 if (first) {
5829 printf("%-16s %-96s ", name,
5830 libnvme_subsystem_get_subsysnqn(s));
5831 first = false0;
5832 }
5833
5834 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
5835 strset_add(&ctrls, libnvme_ctrl_get_name(c));
5836 }
5837
5838 first = true1;
5839 strset_iterate(&ctrls, stdout_detailed_name, &first)strset_iterate_((&ctrls), ((_Bool (*)(const char *, void *
))(((stdout_detailed_name)))), (&first))
;
5840 strset_clear(&ctrls);
5841 printf("\n");
5842
5843 return true1;
5844}
5845
5846static bool_Bool stdout_detailed_ctrl(const char *name, void *arg)
5847{
5848 struct nvme_resources *res = arg;
5849 struct strset namespaces;
5850 libnvme_ctrl_t c;
5851 libnvme_path_t p;
5852 libnvme_ns_t n;
5853 bool_Bool first;
5854
5855 c = htable_ctrl_get(&res->ht_c, name);
5856 assert(c)((void) sizeof ((c) ? 1 : 0), __extension__ ({ if (c) ; else __assert_fail
("c", "../nvme-print-stdout.c", 5856, __extension__ __PRETTY_FUNCTION__
); }))
;
5857
5858 {
5859 const char *tr = libnvme_ctrl_get_transport(c);
5860 __cleanup_free__attribute__((cleanup(freep))) char *reg_owner = libnvme_ctrl_owner(c);
5861 const char *owner_str;
5862
5863 if (!libnvme_ctrl_is_transport_fabric(c))
5864 owner_str = "kernel";
5865 else
5866 owner_str = reg_owner ? reg_owner : "-";
5867 printf("%-16s %-12s %-6s %-20s %-40s %-8s %-6s %-14s %-6s %-12s ",
5868 libnvme_ctrl_get_name(c),
5869 owner_str,
5870 libnvme_ctrl_get_cntlid(c),
5871 libnvme_ctrl_get_serial(c),
5872 libnvme_ctrl_get_model(c),
5873 libnvme_ctrl_get_firmware(c),
5874 tr,
5875 libnvme_ctrl_get_traddr(c),
5876 libnvme_ctrl_get_phy_slot(c),
5877 libnvme_subsystem_get_name(libnvme_ctrl_get_subsystem(c)));
5878 }
5879
5880 strset_init(&namespaces);
5881
5882 libnvme_ctrl_for_each_ns(c, n)for (n = libnvme_ctrl_first_ns(c); n != ((void*)0); n = libnvme_ctrl_next_ns
(c, n))
5883 strset_add(&namespaces, libnvme_ns_get_name(n));
5884 libnvme_ctrl_for_each_path(c, p)for (p = libnvme_ctrl_first_path(c); p != ((void*)0); p = libnvme_ctrl_next_path
(c, p))
{
5885 n = libnvme_path_get_ns(p);
5886 if (!n)
5887 continue;
5888 strset_add(&namespaces, libnvme_ns_get_name(n));
5889 }
5890
5891 first = true1;
5892 strset_iterate(&namespaces, stdout_detailed_name, &first)strset_iterate_((&namespaces), ((_Bool (*)(const char *, void
*))(((stdout_detailed_name)))), (&first))
;
5893 strset_clear(&namespaces);
5894
5895 printf("\n");
5896
5897 return true1;
5898}
5899
5900static bool_Bool stdout_detailed_ns(const char *name, void *arg)
5901{
5902 struct nvme_resources *res = arg;
5903 struct htable_ns_iter it;
5904 struct strset ctrls;
5905 libnvme_ctrl_t c;
5906 libnvme_path_t p;
5907 libnvme_ns_t n;
5908 bool_Bool first;
5909
5910 strset_init(&ctrls);
5911 first = true1;
5912 for (n = htable_ns_getfirst(&res->ht_n, name, &it);
5913 n;
5914 n = htable_ns_getnext(&res->ht_n, name, &it)) {
5915 if (first) {
5916 stdout_ns_details(n);
5917 first = false0;
5918 }
5919
5920 if (libnvme_ns_get_ctrl(n)) {
5921 printf("%s\n", libnvme_ctrl_get_name(libnvme_ns_get_ctrl(n)));
5922 return true1;
5923 }
5924
5925 libnvme_namespace_for_each_path(n, p)for (p = libnvme_namespace_first_path(n); p != ((void*)0); p =
libnvme_namespace_next_path(n, p))
{
5926 c = libnvme_path_get_ctrl(p);
5927 strset_add(&ctrls, libnvme_ctrl_get_name(c));
5928 }
5929 }
5930
5931 first = true1;
5932 strset_iterate(&ctrls, stdout_detailed_name, &first)strset_iterate_((&ctrls), ((_Bool (*)(const char *, void *
))(((stdout_detailed_name)))), (&first))
;
5933 strset_clear(&ctrls);
5934
5935 printf("\n");
5936 return true1;
5937}
5938
5939static void stdout_detailed_list(struct libnvme_global_ctx *ctx)
5940{
5941 struct nvme_resources res;
5942
5943 nvme_resources_init(ctx, &res);
5944
5945 printf("%-16s %-96s %-.16s\n", "Subsystem", "Subsystem-NQN", "Controllers");
5946 printf("%-.16s %-.96s %-.16s\n", dash, dash, dash);
5947 strset_iterate(&res.subsystems, stdout_detailed_subsys, &res)strset_iterate_((&res.subsystems), ((_Bool (*)(const char
*, void *))(((stdout_detailed_subsys)))), (&res))
;
5948 printf("\n");
5949
5950 printf("%-16s %-12s %-6s %-20s %-40s %-8s %-6s %-14s %-6s %-12s %-16s\n",
5951 "Device", "Orchestrator", "Cntlid", "SN", "MN", "FR", "TxPort",
5952 "Address", "Slot", "Subsystem", "Namespaces");
5953 printf("%-.16s %-.12s %-.6s %-.20s %-.40s %-.8s %-.6s %-.14s %-.6s %-.12s %-.16s\n",
5954 dash, dash, dash, dash, dash, dash, dash, dash, dash, dash, dash);
5955 strset_iterate(&res.ctrls, stdout_detailed_ctrl, &res)strset_iterate_((&res.ctrls), ((_Bool (*)(const char *, void
*))(((stdout_detailed_ctrl)))), (&res))
;
5956 printf("\n");
5957
5958 printf("%-17s %-17s %-10s %-49s %-16s %-16s\n", "Device", "Generic",
5959 "NSID", "Usage", "Format", "Controllers");
5960 printf("%-.17s %-.17s %-.10s %-.49s %-.16s %-.16s\n", dash, dash, dash,
5961 dash, dash, dash);
5962 strset_iterate(&res.namespaces, stdout_detailed_ns, &res)strset_iterate_((&res.namespaces), ((_Bool (*)(const char
*, void *))(((stdout_detailed_ns)))), (&res))
;
5963
5964 nvme_resources_free(&res);
5965}
5966
5967static void stdout_list_items(struct libnvme_global_ctx *ctx)
5968{
5969 if (stdout_print_ops.flags & VERBOSE)
5970 stdout_detailed_list(ctx);
5971 else
5972 stdout_simple_list(ctx);
5973}
5974
5975static int subsystem_topology_multipath_add_row(struct table *t,
5976 const char *iopolicy, const char *nshead,
5977 const char *nsid, const char *nspath,
5978 const char *anastate, const char *iopolicy_info,
5979 const char *ctrl, const char *trtype,
5980 const char *address, const char *state)
5981{
5982 int row;
5983 int col = -1;
5984
5985 row = table_get_row_id(t);
5986 if (row < 0) {
5987 nvme_show_error("Failed to add subsys topology multipath row")nvme_show_message(1, "Failed to add subsys topology multipath row"
)
;
5988 return row;
5989 }
5990
5991 table_set_value_str(t, ++col, row, nshead, CENTERED);
5992 table_set_value_str(t, ++col, row, nsid, CENTERED);
5993 table_set_value_str(t, ++col, row, nspath, CENTERED);
5994 table_set_value_str(t, ++col, row, anastate, CENTERED);
5995 if (!strcmp(iopolicy, "numa") || !strcmp(iopolicy, "queue-depth"))
5996 table_set_value_str(t, ++col, row, iopolicy_info, CENTERED);
5997 table_set_value_str(t, ++col, row, ctrl, CENTERED);
5998 table_set_value_str(t, ++col, row, trtype, CENTERED);
5999 table_set_value_str(t, ++col, row, address, CENTERED);
6000 table_set_value_str(t, ++col, row, state, CENTERED);
6001
6002 table_add_row(t, row);
6003
6004 return 0;
6005}
6006
6007static void stdout_tabular_subsystem_topology_multipath(libnvme_subsystem_t s)
6008{
6009 libnvme_ns_t n;
6010 libnvme_path_t p;
6011 libnvme_ctrl_t c;
6012 bool_Bool first;
6013 char nshead[32], nsid[32];
6014 char iopolicy_info[256];
6015 int ret, num_path;
6016 struct table *t;
6017 const char *iopolicy = libnvme_subsystem_get_iopolicy(s);
6018 struct table_column columns[] = {
6019 {"NSHead", LEFT, AUTO_WIDTH2147483647},
6020 {"NSID", LEFT, AUTO_WIDTH2147483647},
6021 {"NSPath", LEFT, AUTO_WIDTH2147483647},
6022 {"ANAState", LEFT, AUTO_WIDTH2147483647},
6023 {"Nodes", LEFT, AUTO_WIDTH2147483647},
6024 {"Qdepth", LEFT, AUTO_WIDTH2147483647},
6025 {"Controller", LEFT, AUTO_WIDTH2147483647},
6026 {"TrType", LEFT, AUTO_WIDTH2147483647},
6027 {"Address", LEFT, AUTO_WIDTH2147483647},
6028 {"State", LEFT, AUTO_WIDTH2147483647},
6029 };
6030
6031 t = table_create();
6032 if (!t) {
6033 nvme_show_error("Failed to init subsys topology multipath table")nvme_show_message(1, "Failed to init subsys topology multipath table"
)
;
6034 return;
6035 }
6036
6037 if (table_add_columns_filter(t, columns, ARRAY_SIZE(columns)(sizeof(columns) / sizeof((columns)[0])),
6038 subsystem_iopolicy_filter, (void *)s) < 0) {
6039 nvme_show_error("Failed to add subsys topology multipath columns")nvme_show_message(1, "Failed to add subsys topology multipath columns"
)
;
6040 goto free_tbl;
6041 }
6042
6043 libnvme_subsystem_for_each_ns(s, n)for (n = libnvme_subsystem_first_ns(s); n != ((void*)0); n = libnvme_subsystem_next_ns
(s, n))
{
6044 first = true1;
6045 libnvme_namespace_for_each_path(n, p)for (p = libnvme_namespace_first_path(n); p != ((void*)0); p =
libnvme_namespace_next_path(n, p))
{
6046 c = libnvme_path_get_ctrl(p);
6047
6048 /*
6049 * For the first row we print actual NSHead name,
6050 * however, for the subsequent rows we print "arrow"
6051 * ("-->") symbol for NSHead. This "arrow" style makes
6052 * it visually obvious that susequenet entries (if
6053 * present) are a path under the first NSHead.
6054 */
6055 if (first) {
6056 snprintf(nshead, sizeof(nshead), "%s",
6057 libnvme_ns_get_name(n));
6058 first = false0;
6059 } else
6060 snprintf(nshead, sizeof(nshead), "%s", "-->");
6061
6062 snprintf(nsid, sizeof(nsid), "%u", libnvme_ns_get_nsid(n));
6063
6064 if (!strcmp(iopolicy, "numa"))
6065 snprintf(iopolicy_info, sizeof(iopolicy_info),
6066 "%s", libnvme_path_get_numa_nodes(p));
6067 else if (!strcmp(iopolicy, "queue-depth"))
6068 snprintf(iopolicy_info, sizeof(iopolicy_info),
6069 "%d", libnvme_path_get_queue_depth(p));
6070
6071 ret = subsystem_topology_multipath_add_row(t,
6072 iopolicy,
6073 nshead,
6074 nsid,
6075 libnvme_path_get_name(p),
6076 libnvme_path_get_ana_state(p),
6077 iopolicy_info,
6078 libnvme_ctrl_get_name(c),
6079 libnvme_ctrl_get_transport(c),
6080 libnvme_ctrl_get_traddr(c),
6081 libnvme_ctrl_get_state(c));
6082 if (ret < 0)
6083 goto free_tbl;
6084 }
6085 }
6086
6087 /*
6088 * Next we print controller in the subsystem which may not have any
6089 * nvme path associated to it.
6090 */
6091 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
6092 num_path = 0;
6093 libnvme_ctrl_for_each_path(c, p)for (p = libnvme_ctrl_first_path(c); p != ((void*)0); p = libnvme_ctrl_next_path
(c, p))
6094 num_path++;
6095
6096 if (!num_path) {
6097 ret = subsystem_topology_multipath_add_row(t,
6098 iopolicy,
6099 "--", /* NSHead */
6100 "--", /* NSID */
6101 "--", /* NSPath */
6102 "--", /* ANAState */
6103 "--", /* Nodes/Qdepth */
6104 libnvme_ctrl_get_name(c),
6105 libnvme_ctrl_get_transport(c),
6106 libnvme_ctrl_get_traddr(c),
6107 libnvme_ctrl_get_state(c));
6108 if (ret < 0)
6109 goto free_tbl;
6110 }
6111 }
6112
6113 table_print(t);
6114free_tbl:
6115 table_free(t);
6116}
6117
6118static void stdout_subsystem_topology_multipath(libnvme_subsystem_t s,
6119 enum nvme_cli_topo_ranking ranking)
6120{
6121 libnvme_ns_t n;
6122 libnvme_path_t p;
6123 libnvme_ctrl_t c;
6124 const char *iopolicy = libnvme_subsystem_get_iopolicy(s);
6125
6126 if (ranking == NVME_CLI_TOPO_NAMESPACE) {
6127 libnvme_subsystem_for_each_ns(s, n)for (n = libnvme_subsystem_first_ns(s); n != ((void*)0); n = libnvme_subsystem_next_ns
(s, n))
{
6128 if (!libnvme_namespace_first_path(n))
6129 continue;
6130
6131 printf(" +- ns %d\n", libnvme_ns_get_nsid(n));
6132 printf(" \\\n");
6133
6134 libnvme_namespace_for_each_path(n, p)for (p = libnvme_namespace_first_path(n); p != ((void*)0); p =
libnvme_namespace_next_path(n, p))
{
6135 c = libnvme_path_get_ctrl(p);
6136
6137 printf(" +- %s %s %s %s %s\n",
6138 libnvme_ctrl_get_name(c),
6139 libnvme_ctrl_get_transport(c),
6140 libnvme_ctrl_get_traddr(c),
6141 libnvme_ctrl_get_state(c),
6142 libnvme_path_get_ana_state(p));
6143 }
6144 }
6145 } else if (ranking == NVME_CLI_TOPO_CTRL) {
6146 /* NVME_CLI_TOPO_CTRL */
6147 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
6148 printf(" +- %s %s %s\n",
6149 libnvme_ctrl_get_name(c),
6150 libnvme_ctrl_get_transport(c),
6151 libnvme_ctrl_get_traddr(c));
6152 printf(" \\\n");
6153
6154 libnvme_subsystem_for_each_ns(s, n)for (n = libnvme_subsystem_first_ns(s); n != ((void*)0); n = libnvme_subsystem_next_ns
(s, n))
{
6155 libnvme_namespace_for_each_path(n, p)for (p = libnvme_namespace_first_path(n); p != ((void*)0); p =
libnvme_namespace_next_path(n, p))
{
6156 if (libnvme_path_get_ctrl(p) != c)
6157 continue;
6158
6159 printf(" +- ns %d %s %s\n",
6160 libnvme_ns_get_nsid(n),
6161 libnvme_ctrl_get_state(c),
6162 libnvme_path_get_ana_state(p));
6163 }
6164 }
6165 }
6166 } else {
6167 /* NVME_CLI_TOPO_MULTIPATH */
6168 libnvme_subsystem_for_each_ns(s, n)for (n = libnvme_subsystem_first_ns(s); n != ((void*)0); n = libnvme_subsystem_next_ns
(s, n))
{
6169 printf(" +- %s (ns %d)\n",
6170 libnvme_ns_get_name(n),
6171 libnvme_ns_get_nsid(n));
6172 printf(" \\\n");
6173 libnvme_namespace_for_each_path(n, p)for (p = libnvme_namespace_first_path(n); p != ((void*)0); p =
libnvme_namespace_next_path(n, p))
{
6174 c = libnvme_path_get_ctrl(p);
6175
6176 if (!strcmp(iopolicy, "numa")) {
6177 /*
6178 * For iopolicy numa, exclude printing
6179 * qdepth.
6180 */
6181 printf(" +- %s %s %s %s %s %s %s\n",
6182 libnvme_path_get_name(p),
6183 libnvme_path_get_ana_state(p),
6184 libnvme_path_get_numa_nodes(p),
6185 libnvme_ctrl_get_name(c),
6186 libnvme_ctrl_get_transport(c),
6187 libnvme_ctrl_get_traddr(c),
6188 libnvme_ctrl_get_state(c));
6189
6190 } else if (!strcmp(iopolicy, "queue-depth")) {
6191 /*
6192 * For iopolicy queue-depth, exclude
6193 * printing numa nodes.
6194 */
6195 printf(" +- %s %s %d %s %s %s %s\n",
6196 libnvme_path_get_name(p),
6197 libnvme_path_get_ana_state(p),
6198 libnvme_path_get_queue_depth(p),
6199 libnvme_ctrl_get_name(c),
6200 libnvme_ctrl_get_transport(c),
6201 libnvme_ctrl_get_traddr(c),
6202 libnvme_ctrl_get_state(c));
6203
6204 } else { /* round-robin */
6205 /*
6206 * For iopolicy round-robin, exclude
6207 * printing numa nodes and qdepth.
6208 */
6209 printf(" +- %s %s %s %s %s %s\n",
6210 libnvme_path_get_name(p),
6211 libnvme_path_get_ana_state(p),
6212 libnvme_ctrl_get_name(c),
6213 libnvme_ctrl_get_transport(c),
6214 libnvme_ctrl_get_traddr(c),
6215 libnvme_ctrl_get_state(c));
6216 }
6217 }
6218 }
6219 }
6220}
6221
6222static int subsystem_topology_add_row(struct table *t,
6223 const char *ns, const char *nsid, const char *ctrl,
6224 const char *trtype, const char *address, const char *state)
6225{
6226 int row = table_get_row_id(t);
6227 if (row < 0) {
6228 nvme_show_error("Failed to add subsys topology row")nvme_show_message(1, "Failed to add subsys topology row");
6229 return row;
6230 }
6231
6232 table_set_value_str(t, 0, row, ns, CENTERED);
6233 table_set_value_str(t, 1, row, nsid, CENTERED);
6234 table_set_value_str(t, 2, row, ctrl, CENTERED);
6235 table_set_value_str(t, 3, row, trtype, CENTERED);
6236 table_set_value_str(t, 4, row, address, CENTERED);
6237 table_set_value_str(t, 5, row, state, CENTERED);
6238
6239 table_add_row(t, row);
6240
6241 return 0;
6242}
6243
6244static void stdout_tabular_subsystem_topology(libnvme_subsystem_t s)
6245{
6246 libnvme_ctrl_t c;
6247 libnvme_ns_t n;
6248 int ret, num_ns;
6249 struct table *t;
6250 struct table_column columns[] = {
6251 {"Namespace", LEFT, AUTO_WIDTH2147483647},
6252 {"NSID", LEFT, AUTO_WIDTH2147483647},
6253 {"Controller", LEFT, AUTO_WIDTH2147483647},
6254 {"Trtype", LEFT, AUTO_WIDTH2147483647},
6255 {"Address", LEFT, AUTO_WIDTH2147483647},
6256 {"State", LEFT, AUTO_WIDTH2147483647},
6257 };
6258
6259 t = table_create();
6260 if (!t) {
6261 nvme_show_error("Failed to init subsys topology table")nvme_show_message(1, "Failed to init subsys topology table");
6262 return;
6263 }
6264
6265 if (table_add_columns(t, columns, ARRAY_SIZE(columns)(sizeof(columns) / sizeof((columns)[0]))) < 0) {
6266 nvme_show_error("Failed to add subsys topology columns")nvme_show_message(1, "Failed to add subsys topology columns");
6267 goto free_tbl;
6268 }
6269
6270 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
6271 num_ns = 0;
6272
6273 libnvme_ctrl_for_each_ns(c, n)for (n = libnvme_ctrl_first_ns(c); n != ((void*)0); n = libnvme_ctrl_next_ns
(c, n))
6274 num_ns++;
6275
6276 if (!num_ns) {
6277 ret = subsystem_topology_add_row(t,
6278 "--", /* Namespace */
6279 "--", /* NSID */
6280 libnvme_ctrl_get_name(c),
6281 libnvme_ctrl_get_transport(c),
6282 libnvme_ctrl_get_traddr(c),
6283 libnvme_ctrl_get_state(c));
6284 if (ret < 0)
6285 goto free_tbl;
6286 } else {
6287 libnvme_ctrl_for_each_ns(c, n)for (n = libnvme_ctrl_first_ns(c); n != ((void*)0); n = libnvme_ctrl_next_ns
(c, n))
{
6288 char nsid[32];
6289
6290 snprintf(nsid, sizeof(nsid), "%u",
6291 libnvme_ns_get_nsid(n));
6292
6293 ret = subsystem_topology_add_row(t,
6294 libnvme_ns_get_name(n),
6295 (const char *)nsid,
6296 libnvme_ctrl_get_name(c),
6297 libnvme_ctrl_get_transport(c),
6298 libnvme_ctrl_get_traddr(c),
6299 libnvme_ctrl_get_state(c));
6300 if (ret < 0)
6301 goto free_tbl;
6302 }
6303 }
6304 }
6305 table_print(t);
6306free_tbl:
6307 table_free(t);
6308}
6309
6310static void stdout_subsystem_topology(libnvme_subsystem_t s,
6311 enum nvme_cli_topo_ranking ranking)
6312{
6313 libnvme_ctrl_t c;
6314 libnvme_ns_t n;
6315
6316 if (ranking == NVME_CLI_TOPO_NAMESPACE) {
6317 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
6318 libnvme_ctrl_for_each_ns(c, n)for (n = libnvme_ctrl_first_ns(c); n != ((void*)0); n = libnvme_ctrl_next_ns
(c, n))
{
6319 printf(" +- ns %d\n", libnvme_ns_get_nsid(n));
6320 printf(" \\\n");
6321 printf(" +- %s %s %s %s\n",
6322 libnvme_ctrl_get_name(c),
6323 libnvme_ctrl_get_transport(c),
6324 libnvme_ctrl_get_traddr(c),
6325 libnvme_ctrl_get_state(c));
6326 }
6327 }
6328 } else if (ranking == NVME_CLI_TOPO_CTRL) {
6329 /* NVME_CLI_TOPO_CTRL */
6330 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
6331 printf(" +- %s %s %s\n",
6332 libnvme_ctrl_get_name(c),
6333 libnvme_ctrl_get_transport(c),
6334 libnvme_ctrl_get_traddr(c));
6335 printf(" \\\n");
6336 libnvme_ctrl_for_each_ns(c, n)for (n = libnvme_ctrl_first_ns(c); n != ((void*)0); n = libnvme_ctrl_next_ns
(c, n))
{
6337 printf(" +- ns %d %s\n",
6338 libnvme_ns_get_nsid(n),
6339 libnvme_ctrl_get_state(c));
6340 }
6341 }
6342 } else {
6343 /* NVME_CLI_TOPO_MULTIPATH */
6344 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
6345 libnvme_ctrl_for_each_ns(c, n)for (n = libnvme_ctrl_first_ns(c); n != ((void*)0); n = libnvme_ctrl_next_ns
(c, n))
{
6346 c = libnvme_ns_get_ctrl(n);
6347
6348 printf(" +- %s (ns %d)\n",
6349 libnvme_ns_get_name(n),
6350 libnvme_ns_get_nsid(n));
6351 printf(" \\\n");
6352 printf(" +- %s %s %s %s\n",
6353 libnvme_ctrl_get_name(c),
6354 libnvme_ctrl_get_transport(c),
6355 libnvme_ctrl_get_traddr(c),
6356 libnvme_ctrl_get_state(c));
6357 }
6358 }
6359 }
6360}
6361
6362static void stdout_topology_tabular(struct libnvme_global_ctx *ctx)
6363{
6364 libnvme_host_t h;
6365 libnvme_subsystem_t s;
6366 bool_Bool first = true1;
6367
6368 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
{
6369 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
{
6370 bool_Bool no_ctrl = true1;
6371 libnvme_ctrl_t c;
6372
6373 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
6374 no_ctrl = false0;
6375
6376 if (no_ctrl)
6377 continue;
6378
6379 if (!first)
6380 printf("\n");
6381 first = false0;
6382
6383 stdout_subsys_config(s, true1);
6384 printf("\n");
6385
6386 if (nvme_is_multipath(s))
6387 stdout_tabular_subsystem_topology_multipath(s);
6388 else
6389 stdout_tabular_subsystem_topology(s);
6390 }
6391 }
6392}
6393
6394static void stdout_simple_topology(struct libnvme_global_ctx *ctx,
6395 enum nvme_cli_topo_ranking ranking)
6396{
6397 libnvme_host_t h;
6398 libnvme_subsystem_t s;
6399 bool_Bool first = true1;
6400
6401 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
{
6402 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
{
6403 bool_Bool no_ctrl = true1;
6404 libnvme_ctrl_t c;
6405
6406 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
6407 no_ctrl = false0;
6408
6409 if (no_ctrl)
6410 continue;
6411
6412 if (!first)
6413 printf("\n");
6414 first = false0;
6415
6416 stdout_subsys_config(s, true1);
6417 printf("\\\n");
6418
6419 if (nvme_is_multipath(s))
6420 stdout_subsystem_topology_multipath(s, ranking);
6421 else
6422 stdout_subsystem_topology(s, ranking);
6423 }
6424 }
6425}
6426
6427static void stdout_topology_namespace(struct libnvme_global_ctx *ctx)
6428{
6429 stdout_simple_topology(ctx, NVME_CLI_TOPO_NAMESPACE);
6430}
6431
6432static void stdout_topology_ctrl(struct libnvme_global_ctx *ctx)
6433{
6434 stdout_simple_topology(ctx, NVME_CLI_TOPO_CTRL);
6435}
6436
6437static void stdout_topology_multipath(struct libnvme_global_ctx *ctx)
6438{
6439 stdout_simple_topology(ctx, NVME_CLI_TOPO_MULTIPATH);
6440}
6441
6442static void stdout_message(bool_Bool error, const char *msg, va_list ap)
6443{
6444 vfprintf(error ? stderrstderr : stdoutstdout, msg, ap);
6445
6446 fprintf(error ? stderrstderr : stdoutstdout, "\n");
6447}
6448
6449static void stdout_perror(const char *msg, va_list ap)
6450{
6451 __cleanup_free__attribute__((cleanup(freep))) char *error = NULL((void*)0);
6452
6453 if (vasprintf(&error, msg, ap) < 0)
6454 error = NULL((void*)0);
6455
6456 perror(error ? error : alloc_error);
6457}
6458
6459static void stdout_key_value(const char *key, const char *val, va_list ap)
6460{
6461 __cleanup_free__attribute__((cleanup(freep))) char *value = NULL((void*)0);
6462
6463 if (vasprintf(&value, val, ap) < 0)
6464 value = NULL((void*)0);
6465
6466 printf("%s: %s\n", key, value ? value : alloc_error);
6467}
6468
6469#ifdef CONFIG_FABRICS
6470static void stdout_discovery_log(struct nvmf_discovery_log *log, int numrec)
6471{
6472 int i;
6473
6474 printf("\nDiscovery Log Number of Records %d, Generation counter %"PRIu64"l" "u""\n",
6475 numrec, le64_to_cpu(log->genctr));
6476
6477 for (i = 0; i < numrec; i++) {
6478 struct nvmf_disc_log_entry *e = &log->entries[i];
6479
6480 printf("=====Discovery Log Entry %d======\n", i);
6481 printf("trtype: %s\n", libnvmf_trtype_str(e->trtype));
6482 printf("adrfam: %s\n",
6483 strlen(e->traddr) ?
6484 libnvmf_adrfam_str(e->adrfam) : "");
6485 printf("subtype: %s\n", libnvmf_subtype_str(e->subtype));
6486 printf("treq: %s\n", libnvmf_treq_str(e->treq));
6487 printf("portid: %d\n", le16_to_cpu(e->portid));
6488 printf("trsvcid: %s\n", e->trsvcid);
6489 printf("subnqn: %s\n", e->subnqn);
6490 printf("traddr: %s\n", e->traddr);
6491 printf("eflags: %s\n",
6492 libnvmf_eflags_str(le16_to_cpu(e->eflags)));
6493
6494 switch (e->trtype) {
6495 case NVMF_TRTYPE_RDMA:
6496 printf("rdma_prtype: %s\n",
6497 libnvmf_prtype_str(e->tsas.rdma.prtype));
6498 printf("rdma_qptype: %s\n",
6499 libnvmf_qptype_str(e->tsas.rdma.qptype));
6500 printf("rdma_cms: %s\n",
6501 libnvmf_cms_str(e->tsas.rdma.cms));
6502 printf("rdma_pkey: %#04x\n",
6503 le16_to_cpu(e->tsas.rdma.pkey));
6504 break;
6505 case NVMF_TRTYPE_TCP:
6506 printf("sectype: %s\n",
6507 libnvmf_sectype_str(e->tsas.tcp.sectype));
6508 break;
6509 }
6510 }
6511}
6512#else
6513static void stdout_discovery_log(struct nvmf_discovery_log *log, int numrec) {}
6514#endif
6515
6516static void stdout_connect_msg(libnvme_ctrl_t c)
6517{
6518 printf("connecting to device: %s\n", libnvme_ctrl_get_name(c));
6519}
6520
6521static void stdout_mgmt_addr_list_log(struct nvme_mgmt_addr_list_log *ma_list)
6522{
6523 int i;
6524 bool_Bool reserved = true1;
6525
6526 printf("Management Address List:\n");
6527 for (i = 0; i < ARRAY_SIZE(ma_list->mad)(sizeof(ma_list->mad) / sizeof((ma_list->mad)[0])); i++) {
6528 switch (ma_list->mad[i].mat) {
6529 case 1:
6530 case 2:
6531 printf("Descriptor: %d, Type: %d (%s), Address: %s\n", i,
6532 ma_list->mad[i].mat,
6533 ma_list->mad[i].mat == 1 ? "NVM subsystem management agent" :
6534 "fabric interface manager", ma_list->mad[i].madrs);
6535 reserved = false0;
6536 break;
6537 case 0xff:
6538 goto out;
6539 default:
6540 break;
6541 }
6542 }
6543out:
6544 if (reserved)
6545 printf("All management address descriptors reserved\n");
6546}
6547
6548static void stdout_rotational_media_info_log(struct nvme_rotational_media_info_log *info)
6549{
6550 printf("endgid: %u\n", le16_to_cpu(info->endgid));
6551 printf("numa: %u\n", le16_to_cpu(info->numa));
6552 printf("nrs: %u\n", le16_to_cpu(info->nrs));
6553 printf("spinc: %u\n", le32_to_cpu(info->spinc));
6554 printf("fspinc: %u\n", le32_to_cpu(info->fspinc));
6555 printf("ldc: %u\n", le32_to_cpu(info->ldc));
6556 printf("fldc: %u\n", le32_to_cpu(info->fldc));
6557}
6558
6559static void stdout_dispersed_ns_psub_log(struct nvme_dispersed_ns_participating_nss_log *log)
6560{
6561 __u64 numpsub = le64_to_cpu(log->numpsub);
6562 __u64 i;
6563
6564 printf("genctr: %"PRIu64"l" "u""\n", le64_to_cpu(log->genctr));
6565 printf("numpsub: %"PRIu64"l" "u""\n", (uint64_t)numpsub);
6566 for (i = 0; i < numpsub; i++)
6567 printf("participating_nss %"PRIu64"l" "u"": %-.*s\n", (uint64_t)i, NVME_NQN_LENGTH,
6568 &log->participating_nss[i * NVME_NQN_LENGTH]);
6569}
6570
6571static void stdout_reachability_groups_log(struct nvme_reachability_groups_log *log, __u64 len)
6572{
6573 __u16 i;
6574 __u32 j;
6575
6576 print_debug("len: %"PRIu64"\n", (uint64_t)len)do { if (is_printable_at_level(LIBNVME_LOG_DEBUG)) printf("len: %"
"l" "u""\n", (uint64_t)len); } while (0)
;
6577 printf("chngc: %"PRIu64"l" "u""\n", le64_to_cpu(log->chngc));
6578 printf("nrgd: %u\n", le16_to_cpu(log->nrgd));
6579
6580 for (i = 0; i < le16_to_cpu(log->nrgd); i++) {
6581 printf("rgid: %u\n", le32_to_cpu(log->rgd[i].rgid));
6582 printf("nnid: %u\n", le32_to_cpu(log->rgd[i].nnid));
6583 printf("chngc: %"PRIu64"l" "u""\n", le64_to_cpu(log->rgd[i].chngc));
6584 for (j = 0; j < le32_to_cpu(log->rgd[i].nnid); j++)
6585 printf("nsid%u: %u\n", j, le32_to_cpu(log->rgd[i].nsid[j]));
6586 }
6587}
6588
6589static void stdout_reachability_associations_log(struct nvme_reachability_associations_log *log,
6590 __u64 len)
6591{
6592 __u16 i;
6593 __u32 j;
6594
6595 print_debug("len: %"PRIu64"\n", (uint64_t)len)do { if (is_printable_at_level(LIBNVME_LOG_DEBUG)) printf("len: %"
"l" "u""\n", (uint64_t)len); } while (0)
;
6596 printf("chngc: %"PRIu64"l" "u""\n", le64_to_cpu(log->chngc));
6597 printf("nrad: %u\n", le16_to_cpu(log->nrad));
6598
6599 for (i = 0; i < le16_to_cpu(log->nrad); i++) {
6600 printf("rasid: %u\n", le32_to_cpu(log->rad[i].rasid));
6601 printf("nrid: %u\n", le32_to_cpu(log->rad[i].nrid));
6602 printf("chngc: %"PRIu64"l" "u""\n", le64_to_cpu(log->rad[i].chngc));
6603 printf("rac: %u\n", log->rad[i].rac);
6604 for (j = 0; j < le32_to_cpu(log->rad[i].nrid); j++)
6605 printf("rgid%u: %u\n", j, le32_to_cpu(log->rad[i].rgid[j]));
6606 }
6607}
6608
6609#ifdef CONFIG_FABRICS
6610static void stdout_host_discovery_log(struct nvme_host_discover_log *log)
6611{
6612 __u32 i;
6613 __u16 j;
6614 struct nvme_host_ext_discover_log *hedlpe;
6615 struct nvmf_ext_attr *exat;
6616 __u32 thdlpl = le32_to_cpu(log->thdlpl);
6617 __u32 tel;
6618 __u16 numexat;
6619 int n = 0;
6620
6621 printf("genctr: %"PRIu64"l" "u""\n", le64_to_cpu(log->genctr));
6622 printf("numrec: %"PRIu64"l" "u""\n", le64_to_cpu(log->numrec));
6623 printf("recfmt: %u\n", le16_to_cpu(log->recfmt));
6624 printf("hdlpf: %02x\n", log->hdlpf);
6625 printf("thdlpl: %u\n", thdlpl);
6626
6627 for (i = sizeof(*log); i < le32_to_cpu(log->thdlpl); i += tel) {
6628 printf("hedlpe: %d\n", n++);
6629 hedlpe = (void *)log + i;
6630 tel = le32_to_cpu(hedlpe->tel);
6631 numexat = le16_to_cpu(hedlpe->numexat);
6632 printf("trtype: %s\n", libnvmf_trtype_str(hedlpe->trtype));
6633 printf("adrfam: %s\n",
6634 strlen(hedlpe->traddr) ? libnvmf_adrfam_str(hedlpe->adrfam) : "");
6635 printf("eflags: %s\n", libnvmf_eflags_str(le16_to_cpu(hedlpe->eflags)));
6636 printf("hostnqn: %s\n", hedlpe->hostnqn);
6637 printf("traddr: %s\n", hedlpe->traddr);
6638 printf("tsas: ");
6639 switch (hedlpe->trtype) {
6640 case NVMF_TRTYPE_RDMA:
6641 printf("prtype: %s, qptype: %s, cms: %s, pkey: 0x%04x\n",
6642 libnvmf_prtype_str(hedlpe->tsas.rdma.prtype),
6643 libnvmf_qptype_str(hedlpe->tsas.rdma.qptype),
6644 libnvmf_cms_str(hedlpe->tsas.rdma.cms),
6645 le16_to_cpu(hedlpe->tsas.rdma.pkey));
6646 break;
6647 case NVMF_TRTYPE_TCP:
6648 printf("sectype: %s\n", libnvmf_sectype_str(hedlpe->tsas.tcp.sectype));
6649 break;
6650 default:
6651 printf("common:\n");
6652 d((unsigned char *)hedlpe->tsas.common, sizeof(hedlpe->tsas.common), 16, 1);
6653 break;
6654 }
6655 printf("tel: %u\n", tel);
6656 printf("numexat: %u\n", numexat);
6657
6658 exat = hedlpe->exat;
6659 for (j = 0; j < numexat; j++) {
6660 printf("exat: %d\n", j);
6661 printf("exattype: %u\n", le16_to_cpu(exat->exattype));
6662 printf("exatlen: %u\n", le16_to_cpu(exat->exatlen));
6663 printf("exatval:\n");
6664 d((unsigned char *)exat->exatval, le16_to_cpu(exat->exatlen), 16, 1);
6665 exat = libnvmf_exat_ptr_next(exat);
6666 }
6667 }
6668}
6669
6670static void print_traddr(char *field, __u8 adrfam, __u8 *traddr)
6671{
6672 char dst[INET6_ADDRSTRLEN46];
6673 socklen_t size;
6674 int af;
6675
6676 if (adrfam == NVMF_ADDR_FAMILY_IP4) {
6677 af = AF_INET2;
6678 size = INET_ADDRSTRLEN16;
6679 } else if (adrfam == NVMF_ADDR_FAMILY_IP6) {
6680 af = AF_INET610;
6681 size = INET6_ADDRSTRLEN46;
6682 } else {
6683 printf("%s: <invalid>\n", field);
6684 return;
6685 }
6686
6687 if (inet_ntop(af, traddr, dst, size))
6688 printf("%s: %s\n", field, dst);
6689}
6690
6691static void stdout_ave_discovery_log(struct nvme_ave_discover_log *log)
6692{
6693 __u32 i;
6694 __u8 j;
6695 struct nvme_ave_discover_log_entry *adlpe;
6696 struct nvme_ave_tr_record *atr;
6697 __u32 tadlpl = le32_to_cpu(log->tadlpl);
6698 __u32 tel;
6699 __u8 numatr;
6700 int n = 0;
6701
6702 printf("genctr: %"PRIu64"l" "u""\n", le64_to_cpu(log->genctr));
6703 printf("numrec: %"PRIu64"l" "u""\n", le64_to_cpu(log->numrec));
6704 printf("recfmt: %u\n", le16_to_cpu(log->recfmt));
6705 printf("tadlpl: %u\n", tadlpl);
6706
6707 for (i = sizeof(*log); i < le32_to_cpu(log->tadlpl); i += tel) {
6708 printf("adlpe: %d\n", n++);
6709 adlpe = (void *)log + i;
6710 tel = le32_to_cpu(adlpe->tel);
6711 numatr = adlpe->numatr;
6712 printf("tel: %u\n", tel);
6713 printf("avenqn: %s\n", adlpe->avenqn);
6714 printf("numatr: %u\n", numatr);
6715
6716 atr = adlpe->atr;
6717 for (j = 0; j < numatr; j++) {
6718 printf("atr: %d\n", j);
6719 printf("aveadrfam: %s\n", libnvmf_adrfam_str(atr->aveadrfam));
6720 printf("avetrsvcid: %u\n", le16_to_cpu(atr->avetrsvcid));
6721 print_traddr("avetraddr", atr->aveadrfam, atr->avetraddr);
6722 atr++;
6723 }
6724 }
6725}
6726#else
6727static void stdout_host_discovery_log(struct nvme_host_discover_log *log) {}
6728static void stdout_ave_discovery_log(struct nvme_ave_discover_log *log) {}
6729#endif
6730
6731static void stdout_pull_model_ddc_req_log(struct nvme_pull_model_ddc_req_log *log)
6732{
6733 __u32 tpdrpl = le32_to_cpu(log->tpdrpl);
6734 __u32 osp_len = tpdrpl - offsetof(struct nvme_pull_model_ddc_req_log, osp)__builtin_offsetof(struct nvme_pull_model_ddc_req_log, osp);
6735
6736 printf("ori: %u\n", log->ori);
6737 printf("tpdrpl: %u\n", tpdrpl);
6738 printf("osp:\n");
6739 d((unsigned char *)log->osp, osp_len, 16, 1);
6740}
6741
6742static void stdout_power_meas_log(struct nvme_power_meas_log *log, __u32 size)
6743{
6744 __u16 nphd = le16_to_cpu(log->nphd);
6745 __u16 pma = le16_to_cpu(log->pma);
6746 __u8 pmt = NVME_GET(pma, PMA_PMT)(((pma) >> NVME_PMA_PMT_SHIFT) & NVME_PMA_PMT_MASK);
6747 __u32 aipwr = le32_to_cpu(log->aipwr);
6748 __u32 mipwr = le32_to_cpu(log->mipwr);
6749 __u16 i;
6750 bool_Bool verbose = stdout_print_ops.flags & VERBOSE;
6751
6752 printf("Power Measurement Log\n");
6753 printf("%-47s : %u\n", "Version", log->ver);
6754 printf("%-47s : %u\n", "Power Measurement Generation Number", log->pmgn);
6755 printf("%-47s : %#06x\n", "Power Measurement Attributes", pma);
6756
6757 if (verbose) {
6758 printf(" %-43s : %u\n", "Power Measurement Enable", NVME_GET(pma, PMA_PME)(((pma) >> NVME_PMA_PME_SHIFT) & NVME_PMA_PME_MASK));
6759 printf(" %-43s : %u\n", "Non-Contiguous Power Data Flag", NVME_GET(pma, PMA_NCPDF)(((pma) >> NVME_PMA_NCPDF_SHIFT) & NVME_PMA_NCPDF_MASK
)
);
6760 printf(" %-43s : %u\n", "Estimated Power Flag", NVME_GET(pma, PMA_EPF)(((pma) >> NVME_PMA_EPF_SHIFT) & NVME_PMA_EPF_MASK));
6761 printf(" %-43s : %u\n", "Maximum Interval Power Timestamp Support", NVME_GET(pma, PMA_MIPWRTS)(((pma) >> NVME_PMA_MIPWRTS_SHIFT) & NVME_PMA_MIPWRTS_MASK
)
);
6762 printf(" %-43s : %u\n", "Power Histogram Descriptor Overflow", NVME_GET(pma, PMA_PHDO)(((pma) >> NVME_PMA_PHDO_SHIFT) & NVME_PMA_PHDO_MASK
)
);
6763 printf(" %-43s : %u (%s)\n", "Power Measurement Type", pmt,
6764 nvme_power_measurement_type_to_string(pmt));
6765 }
6766
6767 printf("%-47s : %u\n", "Size (bytes)", le32_to_cpu(log->sze));
6768 printf("%-47s : %u\n", "Power Measurement Count", le32_to_cpu(log->pmc));
6769 printf("%-47s : %u\n", "Number of Power Histogram Descriptors", nphd);
6770 printf("%-47s : %u\n", "Stop Measurement Time Remaining (minutes)", le16_to_cpu(log->smtr));
6771 printf("%-47s : %s\n", "Stop Measurement Timestamp", stdout_format_timestamp(log->smts.timestamp));
6772
6773 if (verbose) {
6774 printf(" %-43s : %u (%s)\n", "Timestamp Origin",
6775 NVME_TIMESTAMP_ATTR_TO(log->smts.attr)(((log->smts.attr) >> NVME_TIMESTAMP_ATTR_TO_SHIFT) &
NVME_TIMESTAMP_ATTR_TO_MASK)
,
6776 nvme_format_timestamp_origin(log->smts.attr));
6777 printf(" %-43s : %u (%s)\n", "Sync",
6778 NVME_TIMESTAMP_ATTR_SYNC(log->smts.attr)(((log->smts.attr) >> NVME_TIMESTAMP_ATTR_SYNC_SHIFT
) & NVME_TIMESTAMP_ATTR_SYNC_MASK)
,
6779 nvme_format_timestamp_sync(log->smts.attr));
6780 }
6781
6782 printf("%-47s : %u\n", "Power Histogram Descriptor Size (bytes)", le16_to_cpu(log->phds));
6783 printf("%-47s : %u\n", "Power Histogram Bin Size (mW)", le16_to_cpu(log->phbs));
6784 printf("%-47s : %u\n", "Number of Power Histogram Descriptors Supported", le16_to_cpu(log->nphds));
6785 printf("%-47s : %u\n", "Vendor Specific Size (bytes)", le16_to_cpu(log->vss));
6786 printf("%-47s : %u\n", "Power Histogram Descriptor Overflow Count", le32_to_cpu(log->phdoc));
6787 printf("%-47s : ", "Average Interval Power");
6788 print_power_field(aipwr);
6789 printf("\n");
6790 printf("%-47s : ", "Maximum Interval Power");
6791 print_power_field(mipwr);
6792 printf("\n");
6793 printf("%-47s : %s\n", "Maximum Interval Power Timestamp", stdout_format_timestamp(log->mipwrt.timestamp));
6794
6795 if (verbose) {
6796 printf(" %-43s : %u (%s)\n", "Timestamp Origin",
6797 NVME_TIMESTAMP_ATTR_TO(log->mipwrt.attr)(((log->mipwrt.attr) >> NVME_TIMESTAMP_ATTR_TO_SHIFT
) & NVME_TIMESTAMP_ATTR_TO_MASK)
,
6798 nvme_format_timestamp_origin(log->mipwrt.attr));
6799 printf(" %-43s : %u (%s)\n", "Sync",
6800 NVME_TIMESTAMP_ATTR_SYNC(log->mipwrt.attr)(((log->mipwrt.attr) >> NVME_TIMESTAMP_ATTR_SYNC_SHIFT
) & NVME_TIMESTAMP_ATTR_SYNC_MASK)
,
6801 nvme_format_timestamp_sync(log->mipwrt.attr));
6802 }
6803
6804 printf("%-47s : %u\n", "Interval Power Percent Error", log->ipwrpe);
6805
6806 if (verbose) {
6807 for (i = 0; i < nphd; i++) {
6808 __u32 phblt = le32_to_cpu(log->descs[i].phblt);
6809
6810 printf("Power Histogram Descriptor [%u]:\n", i);
6811 printf(" %-43s : %u\n", "Power Histogram Bin Count", le32_to_cpu(log->descs[i].phbc));
6812 printf(" %-43s : ", "Power Histogram Bin Lower Threshold");
6813 print_power_field(phblt);
6814 printf("\n");
6815 }
6816 }
6817}
6818
6819static void stdout_relatives(struct libnvme_global_ctx *ctx, const char *name)
6820{
6821 struct nvme_resources res;
6822 struct htable_ns_iter it;
6823 bool_Bool block = true1;
6824 bool_Bool first = true1;
6825 libnvme_ctrl_t c;
6826 libnvme_path_t p;
6827 libnvme_ns_t n;
6828 int nsid;
6829 int ret;
6830 int id;
6831
6832 ret = sscanf(name, "nvme%dn%d", &id, &nsid);
6833
6834 switch (ret) {
6835 case 1:
6836 block = false0;
6837 break;
6838 case 2:
6839 break;
6840 default:
6841 return;
6842 }
6843
6844 nvme_resources_init(ctx, &res);
6845
6846 if (block) {
6847 fprintf(stderrstderr, "Namespace %s has parent controller(s):", name);
6848 for (n = htable_ns_getfirst(&res.ht_n, name, &it); n;
6849 n = htable_ns_getnext(&res.ht_n, name, &it)) {
6850 if (libnvme_ns_get_ctrl(n)) {
6851 fprintf(stderrstderr, "%s", libnvme_ctrl_get_name(libnvme_ns_get_ctrl(n)));
6852 break;
6853 }
6854 libnvme_namespace_for_each_path(n, p)for (p = libnvme_namespace_first_path(n); p != ((void*)0); p =
libnvme_namespace_next_path(n, p))
{
6855 c = libnvme_path_get_ctrl(p);
6856 fprintf(stderrstderr, "%s%s", first ? "" : ", ", libnvme_ctrl_get_name(c));
6857 if (first)
6858 first = false0;
6859 }
6860 }
6861 fprintf(stderrstderr, "\n\n");
6862 } else {
6863 c = htable_ctrl_get(&res.ht_c, name);
6864 if (c) {
6865 fprintf(stderrstderr, "Controller %s has child namespace(s):", name);
6866 libnvme_ctrl_for_each_ns(c, n)for (n = libnvme_ctrl_first_ns(c); n != ((void*)0); n = libnvme_ctrl_next_ns
(c, n))
{
6867 fprintf(stderrstderr, "%s%s", first ? "" : ", ", libnvme_ns_get_name(n));
6868 if (first)
6869 first = false0;
6870 }
6871 fprintf(stderrstderr, "\n\n");
6872 }
6873 }
6874
6875 nvme_resources_free(&res);
6876}
6877
6878static void stdout_log(const char *devname, struct nvme_get_log_args *args)
6879{
6880 struct nvme_aggregate_endurance_group_event *end = args->log;
6881 struct nvme_supported_cap_config_list_log *cap = args->log;
6882 struct nvme_fid_supported_effects_log *fid_log = args->log;
6883 struct nvme_mi_cmd_supported_effects_log *mi_cmd_log = args->log;
6884 struct nvme_rotational_media_info_log *info = args->log;
6885 struct nvme_dispersed_ns_participating_nss_log *log = args->log;
6886 struct nvme_mgmt_addr_list_log *ma_list = args->log;
6887 struct nvme_reachability_groups_log *reachability_groups_log = args->log;
6888 struct nvme_reachability_associations_log *reachability_associations_log = args->log;
6889 struct nvmf_discovery_log *discovery_log = args->log;
6890
6891 switch (args->lid) {
6892 case NVME_LOG_LID_SUPPORTED_LOG_PAGES:
6893 break;
6894 case NVME_LOG_LID_ERROR:
6895 stdout_error_log((struct nvme_error_log_page *)args->log,
6896 args->len / sizeof(struct nvme_error_log_page),
6897 devname, NULL((void*)0));
6898 break;
6899 case NVME_LOG_LID_SMART:
6900 stdout_smart_log((struct nvme_smart_log *)args->log, args->nsid, devname);
6901 break;
6902 case NVME_LOG_LID_FW_SLOT:
6903 stdout_fw_log((struct nvme_firmware_slot *)args->log, devname);
6904 break;
6905 case NVME_LOG_LID_CHANGED_NS:
6906 stdout_changed_ns_list_log((struct nvme_ns_list *)args->log, devname, false0);
6907 break;
6908 case NVME_LOG_LID_CMD_EFFECTS:
6909 break;
6910 case NVME_LOG_LID_DEVICE_SELF_TEST:
6911 stdout_self_test_log((struct nvme_self_test_log *)args->log,
6912 args->len / sizeof(struct nvme_self_test_log), 0, devname);
6913 break;
6914 case NVME_LOG_LID_TELEMETRY_HOST:
6915 break;
6916 case NVME_LOG_LID_TELEMETRY_CTRL:
6917 break;
6918 case NVME_LOG_LID_ENDURANCE_GROUP:
6919 stdout_endurance_log((struct nvme_endurance_group_log *)args->log, args->lsi,
6920 devname);
6921 break;
6922 case NVME_LOG_LID_PREDICTABLE_LAT_NVMSET:
6923 stdout_predictable_latency_per_nvmset(
6924 (struct nvme_nvmset_predictable_lat_log *)args->log, args->lsi, devname);
6925 break;
6926 case NVME_LOG_LID_PREDICTABLE_LAT_AGG:
6927 stdout_predictable_latency_event_agg_log(
6928 (struct nvme_aggregate_predictable_lat_event *)args->log,
6929 args->len > sizeof(__u64) ? (args->len - sizeof(__u64)) / sizeof(__le16) : 0,
6930 args->len, devname);
6931 break;
6932 case NVME_LOG_LID_ANA:
6933 stdout_ana_log((struct nvme_ana_log *)args->log, devname, args->len);
6934 break;
6935 case NVME_LOG_LID_PERSISTENT_EVENT:
6936 stdout_persistent_event_log((void *)args->log, args->lsp, args->len, devname);
6937 break;
6938 case NVME_LOG_LID_LBA_STATUS:
6939 stdout_lba_status_log((void *)args->log, args->len, devname);
6940 break;
6941 case NVME_LOG_LID_ENDURANCE_GRP_EVT:
6942 stdout_endurance_group_event_agg_log(end, end->num_entries, args->len, devname);
6943 break;
6944 case NVME_LOG_LID_MEDIA_UNIT_STATUS:
6945 stdout_media_unit_stat_log((struct nvme_media_unit_stat_log *)args->log);
6946 break;
6947 case NVME_LOG_LID_SUPPORTED_CAP_CONFIG_LIST:
6948 stdout_supported_cap_config_log(cap);
6949 break;
6950 case NVME_LOG_LID_FID_SUPPORTED_EFFECTS:
6951 stdout_fid_support_effects_log(fid_log, devname);
6952 break;
6953 case NVME_LOG_LID_MI_CMD_SUPPORTED_EFFECTS:
6954 stdout_mi_cmd_support_effects_log(mi_cmd_log, devname);
6955 break;
6956 case NVME_LOG_LID_CMD_AND_FEAT_LOCKDOWN:
6957 break;
6958 case NVME_LOG_LID_BOOT_PARTITION:
6959 stdout_boot_part_log(args->log, devname, args->len);
6960 break;
6961 case NVME_LOG_LID_ROTATIONAL_MEDIA_INFO:
6962 stdout_rotational_media_info_log(info);
6963 break;
6964 case NVME_LOG_LID_DISPERSED_NS_PARTICIPATING_NSS:
6965 stdout_dispersed_ns_psub_log(log);
6966 break;
6967 case NVME_LOG_LID_MGMT_ADDR_LIST:
6968 stdout_mgmt_addr_list_log(ma_list);
6969 break;
6970 case NVME_LOG_LID_PHY_RX_EOM:
6971 stdout_phy_rx_eom_log((struct nvme_phy_rx_eom_log *)args->log, args->lsi);
6972 break;
6973 case NVME_LOG_LID_REACHABILITY_GROUPS:
6974 stdout_reachability_groups_log(reachability_groups_log, args->len);
6975 break;
6976 case NVME_LOG_LID_REACHABILITY_ASSOCIATIONS:
6977 stdout_reachability_associations_log(reachability_associations_log, args->len);
6978 break;
6979 case NVME_LOG_LID_CHANGED_ALLOC_NS:
6980 stdout_changed_ns_list_log((struct nvme_ns_list *)args->log, devname, true1);
6981 break;
6982 case NVME_LOG_LID_FDP_CONFIGS:
6983 stdout_fdp_configs((struct nvme_fdp_config_log *)args->log, args->len);
6984 break;
6985 case NVME_LOG_LID_FDP_RUH_USAGE:
6986 stdout_fdp_usage((struct nvme_fdp_ruhu_log *)args->log, args->len);
6987 break;
6988 case NVME_LOG_LID_FDP_STATS:
6989 stdout_fdp_stats((struct nvme_fdp_stats_log *)args->log);
6990 break;
6991 case NVME_LOG_LID_FDP_EVENTS:
6992 stdout_fdp_events((struct nvme_fdp_events_log *)args->log);
6993 break;
6994 case NVME_LOG_LID_DISCOVERY:
6995 stdout_discovery_log(discovery_log, le64_to_cpu(discovery_log->numrec));
6996 break;
6997 case NVME_LOG_LID_HOST_DISCOVERY:
6998 stdout_host_discovery_log((struct nvme_host_discover_log *)args->log);
6999 break;
7000 case NVME_LOG_LID_AVE_DISCOVERY:
7001 stdout_ave_discovery_log((struct nvme_ave_discover_log *)args->log);
7002 break;
7003 case NVME_LOG_LID_PULL_MODEL_DDC_REQ:
7004 stdout_pull_model_ddc_req_log((struct nvme_pull_model_ddc_req_log *)args->log);
7005 break;
7006 case NVME_LOG_LID_POWER_MEASUREMENT:
7007 stdout_power_meas_log((struct nvme_power_meas_log *)args->log, args->len);
7008 break;
7009 case NVME_LOG_LID_RESERVATION:
7010 stdout_resv_notif_log((struct nvme_resv_notification_log *)args->log, devname);
7011 break;
7012 case NVME_LOG_LID_SANITIZE:
7013 stdout_sanitize_log((struct nvme_sanitize_log_page *)args->log, devname);
7014 break;
7015 case NVME_LOG_LID_ZNS_CHANGED_ZONES:
7016 stdout_zns_changed((struct nvme_zns_changed_zone_log *)args->log);
7017 break;
7018 default:
7019 break;
7020 }
7021}
7022
7023static struct print_ops stdout_print_ops = {
7024 /* libnvme types.h print functions */
7025 .ana_log = stdout_ana_log,
7026 .boot_part_log = stdout_boot_part_log,
7027 .phy_rx_eom_log = stdout_phy_rx_eom_log,
7028 .ctrl_list = stdout_list_ctrl,
7029 .ctrl_registers = stdout_ctrl_registers,
7030 .ctrl_register = stdout_ctrl_register,
7031 .directive = stdout_directive_show,
7032 .discovery_log = stdout_discovery_log,
7033 .effects_log_list = stdout_effects_log_pages,
7034 .endurance_group_event_agg_log = stdout_endurance_group_event_agg_log,
7035 .endurance_group_list = stdout_endurance_group_list,
7036 .endurance_log = stdout_endurance_log,
7037 .error_log = stdout_error_log,
7038 .fdp_config_log = stdout_fdp_configs,
7039 .fdp_event_log = stdout_fdp_events,
7040 .fdp_ruh_status = stdout_fdp_ruh_status,
7041 .fdp_stats_log = stdout_fdp_stats,
7042 .fdp_usage_log = stdout_fdp_usage,
7043 .fid_supported_effects_log = stdout_fid_support_effects_log,
7044 .fw_log = stdout_fw_log,
7045 .id_ctrl = stdout_id_ctrl,
7046 .id_ctrl_nvm = stdout_id_ctrl_nvm,
7047 .id_domain_list = stdout_id_domain_list,
7048 .id_independent_id_ns = stdout_cmd_set_independent_id_ns,
7049 .id_iocs = stdout_id_iocs,
7050 .id_ns = stdout_id_ns,
7051 .id_ns_descs = stdout_id_ns_descs,
7052 .id_ns_granularity_list = stdout_id_ns_granularity_list,
7053 .id_nvmset_list = stdout_id_nvmset,
7054 .id_uuid_list = stdout_id_uuid_list,
7055 .lba_status = stdout_lba_status,
7056 .lba_status_log = stdout_lba_status_log,
7057 .media_unit_stat_log = stdout_media_unit_stat_log,
7058 .mi_cmd_support_effects_log = stdout_mi_cmd_support_effects_log,
7059 .ns_list = stdout_list_ns,
7060 .ns_list_log = stdout_changed_ns_list_log,
7061 .nvm_id_ns = stdout_nvm_id_ns,
7062 .persistent_event_log = stdout_persistent_event_log,
7063 .predictable_latency_event_agg_log = stdout_predictable_latency_event_agg_log,
7064 .predictable_latency_per_nvmset = stdout_predictable_latency_per_nvmset,
7065 .primary_ctrl_cap = stdout_primary_ctrl_cap,
7066 .relatives = stdout_relatives,
7067 .resv_notification_log = stdout_resv_notif_log,
7068 .resv_report = stdout_resv_report,
7069 .sanitize_log_page = stdout_sanitize_log,
7070 .secondary_ctrl_list = stdout_list_secondary_ctrl,
7071 .select_result = stdout_select_result,
7072 .self_test_log = stdout_self_test_log,
7073 .single_property = stdout_single_property,
7074 .smart_log = stdout_smart_log,
7075 .supported_cap_config_list_log = stdout_supported_cap_config_log,
7076 .supported_log_pages = stdout_supported_log,
7077 .zns_start_zone_list = stdout_zns_start_zone_list,
7078 .zns_changed_zone_log = stdout_zns_changed,
7079 .zns_finish_zone_list = NULL((void*)0),
7080 .zns_id_ctrl = stdout_zns_id_ctrl,
7081 .zns_id_ns = stdout_zns_id_ns,
7082 .zns_report_zones = stdout_zns_report_zones,
7083 .show_feature = stdout_feature_show,
7084 .show_feature_fields = stdout_feature_show_fields,
7085 .id_ctrl_rpmbs = stdout_id_ctrl_rpmbs,
7086 .lba_range = stdout_lba_range,
7087 .lba_status_info = stdout_lba_status_info,
7088 .d = stdout_d,
7089 .show_init = NULL((void*)0),
7090 .show_finish = NULL((void*)0),
7091 .mgmt_addr_list_log = stdout_mgmt_addr_list_log,
7092 .rotational_media_info_log = stdout_rotational_media_info_log,
7093 .dispersed_ns_psub_log = stdout_dispersed_ns_psub_log,
7094 .reachability_groups_log = stdout_reachability_groups_log,
7095 .reachability_associations_log = stdout_reachability_associations_log,
7096 .host_discovery_log = stdout_host_discovery_log,
7097 .ave_discovery_log = stdout_ave_discovery_log,
7098 .pull_model_ddc_req_log = stdout_pull_model_ddc_req_log,
7099 .power_meas_log = stdout_power_meas_log,
7100 .log = stdout_log,
7101
7102 /* libnvme tree print functions */
7103 .list_item = stdout_list_item,
7104 .list_items = stdout_list_items,
7105 .print_nvme_subsystem_list = stdout_subsystem_list,
7106 .topology_ctrl = stdout_topology_ctrl,
7107 .topology_namespace = stdout_topology_namespace,
7108 .topology_multipath = stdout_topology_multipath,
7109 .topology_tabular = stdout_topology_tabular,
7110
7111 /* nvme top */
7112#ifdef CONFIG_TOP
7113 .top = stdout_top,
7114#else
7115 .top = NULL((void*)0),
7116#endif
7117
7118 /* status and error messages */
7119 .connect_msg = stdout_connect_msg,
7120 .show_message = stdout_message,
7121 .show_perror = stdout_perror,
7122 .show_status = stdout_status,
7123 .show_opcode_status = stdout_opcode_status,
7124 .show_error_status = stdout_error_status,
7125 .show_key_value = stdout_key_value,
7126};
7127
7128struct print_ops *nvme_get_stdout_print_ops(nvme_print_flags_t flags)
7129{
7130 stdout_print_ops.flags = flags;
7131 return &stdout_print_ops;
7132}
7133
7134void print_array(char *name, __u8 *data, int size)
7135{
7136 int i;
7137
7138 if (!name || !data || !size)
7139 return;
7140
7141 printf("%s: 0x", name);
7142 for (i = 0; i < size; i++)
7143 printf("%02X", data[size - i - 1]);
7144 printf("\n");
7145}