Bug Summary

File:.build-ci/../src/nvme-print-json.c
Warning:line 5369, column 12
Potential leak of memory pointed to by 'key'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -O3 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name nvme-print-json.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 static -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/bin/../lib/clang/22 -include /__w/nvme-cli/nvme-cli/.build-ci/nvme-config.h -I nvme.p -I . -I .. -I src -I ../src -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/bin/../lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=gnu11 -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 -fdwarf2-cfi-asm -o /__w/nvme-cli/nvme-cli/.build-ci/scan-results/2026-11-02-081605-642-1 -x c ../src/nvme-print-json.c
1// SPDX-License-Identifier: GPL-2.0-or-later
2
3#include <assert.h>
4#include <errno(*__errno_location ()).h>
5#include <sys/types.h>
6#include <time.h>
7#include <unistd.h>
8
9#ifdef CONFIG_FABRICS
10#include <arpa/inet.h>
11#include <sys/socket.h>
12#endif
13
14#include <libnvme-mi.h>
15#include <libnvme.h>
16
17#include <ccan/array_size/array_size.h>
18#include <ccan/compiler/compiler.h>
19#include <ccan/endian/endian.h>
20#include <ccan/minmax/minmax.h>
21#include <shared/compiler-attributes-util.h>
22#include <shared/mmio-util.h>
23#include <shared/string-util.h>
24#include <shared/unaligned-util.h>
25
26#include "cleanup.h"
27#include "global-ctx.h"
28#include "nvme-iostat.h"
29#include "nvme-json.h"
30#include "nvme-print.h"
31
32#define ERROR_MSG_LEN100 100
33#define NAME_LEN128 128
34#define BUF_LEN320 320
35#define VAL_LEN4096 4096
36
37#define array_add_objjson_array_add_value_object json_array_add_value_object
38#define array_add_strjson_array_add_value_string json_array_add_value_string
39
40#define obj_add_arrayjson_object_add_value_array json_object_add_value_array
41#define obj_add_booljson_object_add_value_bool json_object_add_value_bool
42#define obj_add_intjson_object_add_value_int json_object_add_value_int
43#define obj_add_objjson_object_add_value_object json_object_add_value_object
44#define obj_add_uintjson_object_add_value_uint json_object_add_value_uint
45#define obj_add_uint128json_object_add_value_uint128 json_object_add_value_uint128
46#define obj_add_uint64json_object_add_value_uint64 json_object_add_value_uint64
47#define obj_add_uint_02xjson_object_add_uint_02x json_object_add_uint_02x
48#define obj_add_uint_0xjson_object_add_uint_0x json_object_add_uint_0x
49#define obj_add_byte_arrayjson_object_add_byte_array json_object_add_byte_array
50#define obj_add_nprix64json_object_add_nprix64 json_object_add_nprix64
51#define obj_add_uint_0nxjson_object_add_uint_0nx json_object_add_uint_0nx
52#define obj_add_0nprix64json_object_add_0nprix64 json_object_add_0nprix64
53#define obj_add_strjson_object_add_value_string json_object_add_value_string
54
55static const uint8_t zero_uuid[16] = { 0 };
56static struct print_ops json_print_ops;
57static struct json_object *json_r;
58static bool_Bool json_init;
59
60static void json_feature_show_fields(enum nvme_features_id fid, unsigned int result,
61 unsigned char *buf);
62
63static void d_json(unsigned char *buf, int len, int width, int group, struct json_object *array)
64{
65 int i;
66 char ascii[32 + 1] = { 0 };
67
68 assert(width < sizeof(ascii))((void) sizeof (__assert_single_arg (width < sizeof(ascii)
)), __extension__ ({ if (width < sizeof(ascii)) ; else __assert_fail
("width < sizeof(ascii)", "../src/nvme-print-json.c", 68,
__extension__ __PRETTY_FUNCTION__); }))
;
69
70 for (i = 0; i < len; i++) {
71 ascii[i % width] = (buf[i] >= '!' && buf[i] <= '~') ? buf[i] : '.';
72 if (!((i + 1) % width)) {
73 array_add_strjson_array_add_value_string(array, ascii);
74 memset(ascii, 0, sizeof(ascii));
75 }
76 }
77
78 if (strlen(ascii)) {
79 ascii[i % width + 1] = '\0';
80 array_add_strjson_array_add_value_string(array, ascii);
81 }
82}
83
84static void obj_d(struct json_object *o, const char *k, unsigned char *buf, int len, int width,
85 int group)
86{
87 struct json_object *data = json_create_array()json_object_new_array();
88
89 d_json(buf, len, width, group, data);
90 obj_add_array(o, k, data)json_object_object_add(o, k, data);
91}
92
93
94static void obj_add_uint_nx(struct json_object *o, const char *k, __u32 v)
95{
96 char str[STR_LEN100];
97
98 sprintf(str, "%#x", v);
99 obj_add_strjson_object_add_value_string(o, k, str);
100}
101
102
103static void obj_add_ctrl_address(struct json_object *o, struct libnvme_ctrl *c)
104{
105 const char *address = libnvme_ctrl_get_address(c);
106
107 /* controllers without an address, e.g. loop, don't report one */
108 obj_add_strjson_object_add_value_string(o, "Address", address ? address : "");
109}
110
111static void obj_add_ctrl_address_details(struct json_object *o, const char *k,
112 struct libnvme_ctrl *c)
113{
114 struct json_object *address_details = json_create_object()json_object_new_object();
115 const char *value;
116 bool_Bool has_value = false0;
117
118 value = libnvme_ctrl_get_traddr(c);
119 if (value) {
120 obj_add_strjson_object_add_value_string(address_details, "traddr", value);
121 has_value = true1;
122 }
123
124 value = libnvme_ctrl_get_host_traddr(c);
125 if (value) {
126 obj_add_strjson_object_add_value_string(address_details, "host_traddr", value);
127 has_value = true1;
128 }
129
130 value = libnvme_ctrl_get_host_iface(c);
131 if (value) {
132 obj_add_strjson_object_add_value_string(address_details, "host_iface", value);
133 has_value = true1;
134 }
135
136 value = libnvme_ctrl_get_trsvcid(c);
137 if (value) {
138 obj_add_strjson_object_add_value_string(address_details, "trsvcid", value);
139 has_value = true1;
140 }
141
142 if (!has_value) {
143 json_free_object(address_details)json_object_put(address_details);
144 return;
145 }
146
147 obj_add_obj(o, k, address_details)json_object_object_add(o, k, address_details);
148}
149
150
151static void obj_add_result(struct json_object *o, const char *v, ...)
152{
153 va_list ap;
154
155 __cleanup_free__attribute__((cleanup(shr_freep))) char *value = NULL((void*)0);
156
157 va_start(ap, v)__builtin_va_start(ap, v);
158
159 if (vasprintf(&value, v, ap) < 0)
160 value = NULL((void*)0);
161
162 obj_add_strjson_object_add_value_string(o, "Result", value ? value : alloc_error);
163
164 va_end(ap)__builtin_va_end(ap);
165}
166
167static void obj_add_key(struct json_object *o, const char *k, const char *v, ...)
168{
169 va_list ap;
170
171 __cleanup_free__attribute__((cleanup(shr_freep))) char *value = NULL((void*)0);
172
173 va_start(ap, v)__builtin_va_start(ap, v);
174
175 if (vasprintf(&value, v, ap) < 0)
176 value = NULL((void*)0);
177
178 obj_add_strjson_object_add_value_string(o, k, value ? value : alloc_error);
179
180 va_end(ap)__builtin_va_end(ap);
181}
182
183struct json_object *obj_create_array_obj(struct json_object *o, const char *k)
184{
185 struct json_object *array = json_create_array()json_object_new_array();
186 struct json_object *obj = json_create_object()json_object_new_object();
187
188 obj_add_array(o, k, array)json_object_object_add(o, k, array);
189 array_add_obj(array, obj)json_object_array_add(array, obj);
190
191 return obj;
192}
193
194static struct json_object *obj_create(const char *k)
195{
196 struct json_object *array;
197 struct json_object *obj = json_create_object()json_object_new_object();
198
199 if (json_r) {
200 array = json_create_array()json_object_new_array();
201 obj_add_array(json_r, k, array)json_object_object_add(json_r, k, array);
202 array_add_obj(array, obj)json_object_array_add(array, obj);
203 }
204
205 return obj;
206}
207
208void json_print(struct json_object *r)
209{
210 json_print_object(r, NULL)printf("%s", json_object_to_json_string_ext(r, (1 << 1)
| (1 << 4)))
;
211 printf("\n");
212 json_free_object(r)json_object_put(r);
213}
214
215static void obj_print(struct json_object *o)
216{
217 if (!json_r)
218 json_print(o);
219}
220
221static void json_id_iocs_iocsc(struct json_object *obj_iocsc, __u64 iocsc)
222{
223 __u8 cpncs = NVME_GET(iocsc, IOCS_IOCSC_CPNCS)(((iocsc) >> NVME_IOCS_IOCSC_CPNCS_SHIFT) & NVME_IOCS_IOCSC_CPNCS_MASK
)
;
224 __u8 slmcs = NVME_GET(iocsc, IOCS_IOCSC_SLMCS)(((iocsc) >> NVME_IOCS_IOCSC_SLMCS_SHIFT) & NVME_IOCS_IOCSC_SLMCS_MASK
)
;
225 __u8 znscs = NVME_GET(iocsc, IOCS_IOCSC_ZNSCS)(((iocsc) >> NVME_IOCS_IOCSC_ZNSCS_SHIFT) & NVME_IOCS_IOCSC_ZNSCS_MASK
)
;
226 __u8 kvcs = NVME_GET(iocsc, IOCS_IOCSC_KVCS)(((iocsc) >> NVME_IOCS_IOCSC_KVCS_SHIFT) & NVME_IOCS_IOCSC_KVCS_MASK
)
;
227 __u8 nvmcs = NVME_GET(iocsc, IOCS_IOCSC_NVMCS)(((iocsc) >> NVME_IOCS_IOCSC_NVMCS_SHIFT) & NVME_IOCS_IOCSC_NVMCS_MASK
)
;
228
229 obj_add_strjson_object_add_value_string(obj_iocsc, "Computational Programs Namespace Command Set", cpncs ?
230 "Selected" : "Not selected");
231 obj_add_strjson_object_add_value_string(obj_iocsc, "Subsystem Local Memory Command Set", slmcs ?
232 "Selected" : "Not selected");
233 obj_add_strjson_object_add_value_string(obj_iocsc, "Zoned Namespace Command Set", znscs ? "Selected" : "Not selected");
234 obj_add_strjson_object_add_value_string(obj_iocsc, "Key Value Command Set", kvcs ? "Selected" : "Not selected");
235 obj_add_strjson_object_add_value_string(obj_iocsc, "NVM Command Set", nvmcs ? "Selected" : "Not selected");
236}
237
238static bool_Bool verbose_mode(void)
239{
240 return json_print_ops.flags & VERBOSE;
241}
242
243static void json_id_iocs(struct nvme_id_iocs *iocs)
244{
245 struct json_object *r = json_r;
246 struct json_object *obj_iocsc;
247 char json_str[STR_LEN100];
248 __u16 i;
249
250 for (i = 0; i < ARRAY_SIZE(iocs->iocsc)(sizeof(iocs->iocsc) / sizeof((iocs->iocsc)[0]) + 0); i++) {
251 if (iocs->iocsc[i]) {
252 sprintf(json_str, "I/O Command Set Combination[%u]", i);
253 obj_add_uint64(r, json_str, le64_to_cpu(iocs->iocsc[i]))json_object_object_add(r, json_str, json_object_new_uint64(le64_to_cpu
(iocs->iocsc[i])))
;
254
255 obj_iocsc = json_create_object()json_object_new_object();
256 sprintf(json_str, "IOCSC%u", i);
257 json_id_iocs_iocsc(obj_iocsc, le64_to_cpu(iocs->iocsc[i]));
258 obj_add_obj(r, json_str, obj_iocsc)json_object_object_add(r, json_str, obj_iocsc);
259 }
260 }
261}
262
263static void json_nvme_id_ns_lbaf(struct nvme_id_ns *ns, int i, struct json_object *lbafs)
264{
265 struct json_object *lbaf = json_create_object()json_object_new_object();
266 __u8 flbas;
267
268 nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &flbas);
269
270 if (verbose_mode()) {
271 obj_add_int(lbaf, "LBA Format", i)json_object_object_add(lbaf, "LBA Format", json_object_new_int
(i))
;
272 json_object_add_string(lbaf, "Metadata Size", "%d bytes",
273 le16_to_cpu(ns->lbaf[i].ms));
274 json_object_add_string(lbaf, "Data Size", "%u bytes",
275 nvme_lbaf_data_size(ns->lbaf[i].ds));
276 json_object_add_string(lbaf, "Relative Performance", "0x%x %s",
277 ns->lbaf[i].rp,
278 ns->lbaf[i].rp == 3 ? "Degraded" :
279 ns->lbaf[i].rp == 2 ? "Good" :
280 ns->lbaf[i].rp == 1 ? "Better" : "Best");
281 obj_add_strjson_object_add_value_string(lbaf, "in use", i == flbas ? "yes" : "no");
282 } else {
283 obj_add_int(lbaf, "lbaf", i)json_object_object_add(lbaf, "lbaf", json_object_new_int(i));
284 obj_add_int(lbaf, "ms", le16_to_cpu(ns->lbaf[i].ms))json_object_object_add(lbaf, "ms", json_object_new_int(le16_to_cpu
(ns->lbaf[i].ms)))
;
285 obj_add_int(lbaf, "ds", ns->lbaf[i].ds)json_object_object_add(lbaf, "ds", json_object_new_int(ns->
lbaf[i].ds))
;
286 obj_add_int(lbaf, "rp", ns->lbaf[i].rp)json_object_object_add(lbaf, "rp", json_object_new_int(ns->
lbaf[i].rp))
;
287 obj_add_int(lbaf, "in_use", i == flbas)json_object_object_add(lbaf, "in_use", json_object_new_int(i ==
flbas))
;
288 }
289
290 array_add_obj(lbafs, lbaf)json_object_array_add(lbafs, lbaf);
291}
292
293static void json_nvme_id_ns(struct nvme_id_ns *ns, unsigned int nsid,
294 unsigned int lba_index, bool_Bool cap_only)
295{
296 char nguid_buf[2 * sizeof(ns->nguid) + 1],
297 eui64_buf[2 * sizeof(ns->eui64) + 1];
298 char *nguid = nguid_buf, *eui64 = eui64_buf;
299 struct json_object *r = json_r;
300 struct json_object *lbafs = json_create_array()json_object_new_array();
301 struct json_object *vs = json_create_array()json_object_new_array();
302 int i;
303 shr_uint128_t nvmcap = le128_to_cpu(ns->nvmcap);
304
305 if (!cap_only) {
306 obj_add_uint64(r, "nsze", le64_to_cpu(ns->nsze))json_object_object_add(r, "nsze", json_object_new_uint64(le64_to_cpu
(ns->nsze)))
;
307 obj_add_uint64(r, "ncap", le64_to_cpu(ns->ncap))json_object_object_add(r, "ncap", json_object_new_uint64(le64_to_cpu
(ns->ncap)))
;
308 obj_add_uint64(r, "nuse", le64_to_cpu(ns->nuse))json_object_object_add(r, "nuse", json_object_new_uint64(le64_to_cpu
(ns->nuse)))
;
309 obj_add_int(r, "nsfeat", ns->nsfeat)json_object_object_add(r, "nsfeat", json_object_new_int(ns->
nsfeat))
;
310 }
311
312 obj_add_int(r, "nlbaf", ns->nlbaf)json_object_object_add(r, "nlbaf", json_object_new_int(ns->
nlbaf))
;
313
314 if (!cap_only)
315 obj_add_int(r, "flbas", ns->flbas)json_object_object_add(r, "flbas", json_object_new_int(ns->
flbas))
;
316
317 obj_add_int(r, "mc", ns->mc)json_object_object_add(r, "mc", json_object_new_int(ns->mc
))
;
318 obj_add_int(r, "dpc", ns->dpc)json_object_object_add(r, "dpc", json_object_new_int(ns->dpc
))
;
319
320 if (!cap_only) {
321 obj_add_int(r, "dps", ns->dps)json_object_object_add(r, "dps", json_object_new_int(ns->dps
))
;
322 obj_add_int(r, "nmic", ns->nmic)json_object_object_add(r, "nmic", json_object_new_int(ns->
nmic))
;
323 obj_add_int(r, "rescap", ns->rescap)json_object_object_add(r, "rescap", json_object_new_int(ns->
rescap))
;
324 obj_add_int(r, "fpi", ns->fpi)json_object_object_add(r, "fpi", json_object_new_int(ns->fpi
))
;
325 obj_add_int(r, "dlfeat", ns->dlfeat)json_object_object_add(r, "dlfeat", json_object_new_int(ns->
dlfeat))
;
326 obj_add_int(r, "nawun", le16_to_cpu(ns->nawun))json_object_object_add(r, "nawun", json_object_new_int(le16_to_cpu
(ns->nawun)))
;
327 obj_add_int(r, "nawupf", le16_to_cpu(ns->nawupf))json_object_object_add(r, "nawupf", json_object_new_int(le16_to_cpu
(ns->nawupf)))
;
328 obj_add_int(r, "nacwu", le16_to_cpu(ns->nacwu))json_object_object_add(r, "nacwu", json_object_new_int(le16_to_cpu
(ns->nacwu)))
;
329 obj_add_int(r, "nabsn", le16_to_cpu(ns->nabsn))json_object_object_add(r, "nabsn", json_object_new_int(le16_to_cpu
(ns->nabsn)))
;
330 obj_add_int(r, "nabo", le16_to_cpu(ns->nabo))json_object_object_add(r, "nabo", json_object_new_int(le16_to_cpu
(ns->nabo)))
;
331 obj_add_int(r, "nabspf", le16_to_cpu(ns->nabspf))json_object_object_add(r, "nabspf", json_object_new_int(le16_to_cpu
(ns->nabspf)))
;
332 obj_add_int(r, "noiob", le16_to_cpu(ns->noiob))json_object_object_add(r, "noiob", json_object_new_int(le16_to_cpu
(ns->noiob)))
;
333 obj_add_uint128(r, "nvmcap", nvmcap)json_object_object_add(r, "nvmcap", util_json_object_new_uint128
(nvmcap))
;
334
335 if (ns->nsfeat & 0x30) {
336 obj_add_int(r, "npwg", le16_to_cpu(ns->npwg))json_object_object_add(r, "npwg", json_object_new_int(le16_to_cpu
(ns->npwg)))
;
337 obj_add_int(r, "npwa", le16_to_cpu(ns->npwa))json_object_object_add(r, "npwa", json_object_new_int(le16_to_cpu
(ns->npwa)))
;
338 if (ns->nsfeat & 0x10)
339 obj_add_int(r, "npdg", le16_to_cpu(ns->npdg))json_object_object_add(r, "npdg", json_object_new_int(le16_to_cpu
(ns->npdg)))
;
340 obj_add_int(r, "npda", le16_to_cpu(ns->npda))json_object_object_add(r, "npda", json_object_new_int(le16_to_cpu
(ns->npda)))
;
341 obj_add_int(r, "nows", le16_to_cpu(ns->nows))json_object_object_add(r, "nows", json_object_new_int(le16_to_cpu
(ns->nows)))
;
342 }
343
344 obj_add_int(r, "mssrl", le16_to_cpu(ns->mssrl))json_object_object_add(r, "mssrl", json_object_new_int(le16_to_cpu
(ns->mssrl)))
;
345 obj_add_uint(r, "mcl", le32_to_cpu(ns->mcl))json_object_object_add(r, "mcl", json_object_new_uint64(le32_to_cpu
(ns->mcl)))
;
346 obj_add_int(r, "msrc", ns->msrc)json_object_object_add(r, "msrc", json_object_new_int(ns->
msrc))
;
347 obj_add_uint(r, "kpios", ns->kpios)json_object_object_add(r, "kpios", json_object_new_uint64(ns->
kpios))
;
348 }
349
350 obj_add_int(r, "nulbaf", ns->nulbaf)json_object_object_add(r, "nulbaf", json_object_new_int(ns->
nulbaf))
;
351
352 if (!cap_only) {
353 obj_add_uint(r, "kpiodaag", le32_to_cpu(ns->kpiodaag))json_object_object_add(r, "kpiodaag", json_object_new_uint64(
le32_to_cpu(ns->kpiodaag)))
;
354 obj_add_uint(r, "anagrpid", le32_to_cpu(ns->anagrpid))json_object_object_add(r, "anagrpid", json_object_new_uint64(
le32_to_cpu(ns->anagrpid)))
;
355 obj_add_int(r, "nsattr", ns->nsattr)json_object_object_add(r, "nsattr", json_object_new_int(ns->
nsattr))
;
356 obj_add_int(r, "nvmsetid", le16_to_cpu(ns->nvmsetid))json_object_object_add(r, "nvmsetid", json_object_new_int(le16_to_cpu
(ns->nvmsetid)))
;
357 obj_add_int(r, "endgid", le16_to_cpu(ns->endgid))json_object_object_add(r, "endgid", json_object_new_int(le16_to_cpu
(ns->endgid)))
;
358
359 memset(eui64, 0, sizeof(eui64_buf));
360
361 for (i = 0; i < sizeof(ns->eui64); i++)
362 eui64 += sprintf(eui64, "%02x", ns->eui64[i]);
363
364 memset(nguid, 0, sizeof(nguid_buf));
365
366 for (i = 0; i < sizeof(ns->nguid); i++)
367 nguid += sprintf(nguid, "%02x", ns->nguid[i]);
368
369 obj_add_strjson_object_add_value_string(r, "nguid", nguid_buf);
370 obj_add_strjson_object_add_value_string(r, "eui64", eui64_buf);
371 }
372
373 obj_add_array(r, "lbafs", lbafs)json_object_object_add(r, "lbafs", lbafs);
374
375 for (i = 0; i < nvme_id_ns_nr_lbaf(ns); i++)
376 json_nvme_id_ns_lbaf(ns, i, lbafs);
377
378 d_json(ns->vs, strnlen((const char *)ns->vs, sizeof(ns->vs)), 16, 1, vs);
379 obj_add_array(r, "vs", vs)json_object_object_add(r, "vs", vs);
380}
381
382void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, const char *product_name,
383 void (*vs)(__u8 *vs, struct json_object *r))
384{
385 struct json_object *r = json_r;
386 struct json_object *psds = json_create_array()json_object_new_array();
387 shr_uint128_t tnvmcap = le128_to_cpu(ctrl->tnvmcap);
388 shr_uint128_t unvmcap = le128_to_cpu(ctrl->unvmcap);
389 shr_uint128_t megcap = le128_to_cpu(ctrl->megcap);
390 shr_uint128_t maxdna = le128_to_cpu(ctrl->maxdna);
391 char sn[sizeof(ctrl->sn) + 1], mn[sizeof(ctrl->mn) + 1],
392 fr[sizeof(ctrl->fr) + 1], subnqn[sizeof(ctrl->subnqn) + 1];
393 __u32 ieee = ctrl->ieee[2] << 16 | ctrl->ieee[1] << 8 | ctrl->ieee[0];
394 int i;
395
396 snprintf(sn, sizeof(sn), "%-.*s", (int)sizeof(ctrl->sn), ctrl->sn);
397 snprintf(mn, sizeof(mn), "%-.*s", (int)sizeof(ctrl->mn), ctrl->mn);
398 snprintf(fr, sizeof(fr), "%-.*s", (int)sizeof(ctrl->fr), ctrl->fr);
399 snprintf(subnqn, sizeof(subnqn), "%-.*s", (int)sizeof(ctrl->subnqn), ctrl->subnqn);
400
401 if (product_name)
402 obj_add_strjson_object_add_value_string(r, "product_name", product_name);
403
404 obj_add_int(r, "vid", le16_to_cpu(ctrl->vid))json_object_object_add(r, "vid", json_object_new_int(le16_to_cpu
(ctrl->vid)))
;
405 obj_add_int(r, "ssvid", le16_to_cpu(ctrl->ssvid))json_object_object_add(r, "ssvid", json_object_new_int(le16_to_cpu
(ctrl->ssvid)))
;
406 obj_add_strjson_object_add_value_string(r, "sn", shr_rtrim(sn));
407 obj_add_strjson_object_add_value_string(r, "mn", shr_rtrim(mn));
408 obj_add_strjson_object_add_value_string(r, "fr", shr_rtrim(fr));
409 obj_add_int(r, "rab", ctrl->rab)json_object_object_add(r, "rab", json_object_new_int(ctrl->
rab))
;
410 obj_add_int(r, "ieee", ieee)json_object_object_add(r, "ieee", json_object_new_int(ieee));
411 obj_add_int(r, "cmic", ctrl->cmic)json_object_object_add(r, "cmic", json_object_new_int(ctrl->
cmic))
;
412 obj_add_int(r, "mdts", ctrl->mdts)json_object_object_add(r, "mdts", json_object_new_int(ctrl->
mdts))
;
413 obj_add_int(r, "cntlid", le16_to_cpu(ctrl->cntlid))json_object_object_add(r, "cntlid", json_object_new_int(le16_to_cpu
(ctrl->cntlid)))
;
414 obj_add_uint(r, "ver", le32_to_cpu(ctrl->ver))json_object_object_add(r, "ver", json_object_new_uint64(le32_to_cpu
(ctrl->ver)))
;
415 obj_add_uint(r, "rtd3r", le32_to_cpu(ctrl->rtd3r))json_object_object_add(r, "rtd3r", json_object_new_uint64(le32_to_cpu
(ctrl->rtd3r)))
;
416 obj_add_uint(r, "rtd3e", le32_to_cpu(ctrl->rtd3e))json_object_object_add(r, "rtd3e", json_object_new_uint64(le32_to_cpu
(ctrl->rtd3e)))
;
417 obj_add_uint(r, "oaes", le32_to_cpu(ctrl->oaes))json_object_object_add(r, "oaes", json_object_new_uint64(le32_to_cpu
(ctrl->oaes)))
;
418 obj_add_uint(r, "ctratt", le32_to_cpu(ctrl->ctratt))json_object_object_add(r, "ctratt", json_object_new_uint64(le32_to_cpu
(ctrl->ctratt)))
;
419 obj_add_int(r, "rrls", le16_to_cpu(ctrl->rrls))json_object_object_add(r, "rrls", json_object_new_int(le16_to_cpu
(ctrl->rrls)))
;
420 obj_add_int(r, "bpcap", ctrl->bpcap)json_object_object_add(r, "bpcap", json_object_new_int(ctrl->
bpcap))
;
421 obj_add_uint(r, "nssl", le32_to_cpu(ctrl->nssl))json_object_object_add(r, "nssl", json_object_new_uint64(le32_to_cpu
(ctrl->nssl)))
;
422 obj_add_int(r, "plsi", ctrl->plsi)json_object_object_add(r, "plsi", json_object_new_int(ctrl->
plsi))
;
423 obj_add_int(r, "cntrltype", ctrl->cntrltype)json_object_object_add(r, "cntrltype", json_object_new_int(ctrl
->cntrltype))
;
424 obj_add_strjson_object_add_value_string(r, "fguid", shr_uuid_to_string(ctrl->fguid));
425 obj_add_int(r, "crdt1", le16_to_cpu(ctrl->crdt1))json_object_object_add(r, "crdt1", json_object_new_int(le16_to_cpu
(ctrl->crdt1)))
;
426 obj_add_int(r, "crdt2", le16_to_cpu(ctrl->crdt2))json_object_object_add(r, "crdt2", json_object_new_int(le16_to_cpu
(ctrl->crdt2)))
;
427 obj_add_int(r, "crdt3", le16_to_cpu(ctrl->crdt3))json_object_object_add(r, "crdt3", json_object_new_int(le16_to_cpu
(ctrl->crdt3)))
;
428 obj_add_int(r, "crcap", ctrl->crcap)json_object_object_add(r, "crcap", json_object_new_int(ctrl->
crcap))
;
429 obj_add_int(r, "ciu", ctrl->ciu)json_object_object_add(r, "ciu", json_object_new_int(ctrl->
ciu))
;
430 obj_add_uint64(r, "cirn", le64_to_cpu(*(__le64 *)ctrl->cirn))json_object_object_add(r, "cirn", json_object_new_uint64(le64_to_cpu
(*(__le64 *)ctrl->cirn)))
;
431 obj_add_int(r, "nvmsr", ctrl->nvmsr)json_object_object_add(r, "nvmsr", json_object_new_int(ctrl->
nvmsr))
;
432 obj_add_int(r, "vwci", ctrl->vwci)json_object_object_add(r, "vwci", json_object_new_int(ctrl->
vwci))
;
433 obj_add_int(r, "mec", ctrl->mec)json_object_object_add(r, "mec", json_object_new_int(ctrl->
mec))
;
434 obj_add_int(r, "oacs", le16_to_cpu(ctrl->oacs))json_object_object_add(r, "oacs", json_object_new_int(le16_to_cpu
(ctrl->oacs)))
;
435 obj_add_int(r, "acl", ctrl->acl)json_object_object_add(r, "acl", json_object_new_int(ctrl->
acl))
;
436 obj_add_int(r, "aerl", ctrl->aerl)json_object_object_add(r, "aerl", json_object_new_int(ctrl->
aerl))
;
437 obj_add_int(r, "frmw", ctrl->frmw)json_object_object_add(r, "frmw", json_object_new_int(ctrl->
frmw))
;
438 obj_add_int(r, "lpa", ctrl->lpa)json_object_object_add(r, "lpa", json_object_new_int(ctrl->
lpa))
;
439 obj_add_int(r, "elpe", ctrl->elpe)json_object_object_add(r, "elpe", json_object_new_int(ctrl->
elpe))
;
440 obj_add_int(r, "npss", ctrl->npss)json_object_object_add(r, "npss", json_object_new_int(ctrl->
npss))
;
441 obj_add_int(r, "avscc", ctrl->avscc)json_object_object_add(r, "avscc", json_object_new_int(ctrl->
avscc))
;
442 obj_add_int(r, "apsta", ctrl->apsta)json_object_object_add(r, "apsta", json_object_new_int(ctrl->
apsta))
;
443 obj_add_int(r, "wctemp", le16_to_cpu(ctrl->wctemp))json_object_object_add(r, "wctemp", json_object_new_int(le16_to_cpu
(ctrl->wctemp)))
;
444 obj_add_int(r, "cctemp", le16_to_cpu(ctrl->cctemp))json_object_object_add(r, "cctemp", json_object_new_int(le16_to_cpu
(ctrl->cctemp)))
;
445 obj_add_int(r, "mtfa", le16_to_cpu(ctrl->mtfa))json_object_object_add(r, "mtfa", json_object_new_int(le16_to_cpu
(ctrl->mtfa)))
;
446 obj_add_uint(r, "hmpre", le32_to_cpu(ctrl->hmpre))json_object_object_add(r, "hmpre", json_object_new_uint64(le32_to_cpu
(ctrl->hmpre)))
;
447 obj_add_uint(r, "hmmin", le32_to_cpu(ctrl->hmmin))json_object_object_add(r, "hmmin", json_object_new_uint64(le32_to_cpu
(ctrl->hmmin)))
;
448 obj_add_uint128(r, "tnvmcap", tnvmcap)json_object_object_add(r, "tnvmcap", util_json_object_new_uint128
(tnvmcap))
;
449 obj_add_uint128(r, "unvmcap", unvmcap)json_object_object_add(r, "unvmcap", util_json_object_new_uint128
(unvmcap))
;
450 obj_add_uint(r, "rpmbs", le32_to_cpu(ctrl->rpmbs))json_object_object_add(r, "rpmbs", json_object_new_uint64(le32_to_cpu
(ctrl->rpmbs)))
;
451 obj_add_int(r, "edstt", le16_to_cpu(ctrl->edstt))json_object_object_add(r, "edstt", json_object_new_int(le16_to_cpu
(ctrl->edstt)))
;
452 obj_add_int(r, "dsto", ctrl->dsto)json_object_object_add(r, "dsto", json_object_new_int(ctrl->
dsto))
;
453 obj_add_int(r, "fwug", ctrl->fwug)json_object_object_add(r, "fwug", json_object_new_int(ctrl->
fwug))
;
454 obj_add_int(r, "kas", le16_to_cpu(ctrl->kas))json_object_object_add(r, "kas", json_object_new_int(le16_to_cpu
(ctrl->kas)))
;
455 obj_add_int(r, "hctma", le16_to_cpu(ctrl->hctma))json_object_object_add(r, "hctma", json_object_new_int(le16_to_cpu
(ctrl->hctma)))
;
456 obj_add_int(r, "mntmt", le16_to_cpu(ctrl->mntmt))json_object_object_add(r, "mntmt", json_object_new_int(le16_to_cpu
(ctrl->mntmt)))
;
457 obj_add_int(r, "mxtmt", le16_to_cpu(ctrl->mxtmt))json_object_object_add(r, "mxtmt", json_object_new_int(le16_to_cpu
(ctrl->mxtmt)))
;
458 obj_add_uint(r, "sanicap", le32_to_cpu(ctrl->sanicap))json_object_object_add(r, "sanicap", json_object_new_uint64(le32_to_cpu
(ctrl->sanicap)))
;
459 obj_add_uint(r, "hmminds", le32_to_cpu(ctrl->hmminds))json_object_object_add(r, "hmminds", json_object_new_uint64(le32_to_cpu
(ctrl->hmminds)))
;
460 obj_add_int(r, "hmmaxd", le16_to_cpu(ctrl->hmmaxd))json_object_object_add(r, "hmmaxd", json_object_new_int(le16_to_cpu
(ctrl->hmmaxd)))
;
461 obj_add_int(r, "nsetidmax", le16_to_cpu(ctrl->nsetidmax))json_object_object_add(r, "nsetidmax", json_object_new_int(le16_to_cpu
(ctrl->nsetidmax)))
;
462 obj_add_int(r, "endgidmax", le16_to_cpu(ctrl->endgidmax))json_object_object_add(r, "endgidmax", json_object_new_int(le16_to_cpu
(ctrl->endgidmax)))
;
463 obj_add_int(r, "anatt", ctrl->anatt)json_object_object_add(r, "anatt", json_object_new_int(ctrl->
anatt))
;
464 obj_add_int(r, "anacap", ctrl->anacap)json_object_object_add(r, "anacap", json_object_new_int(ctrl->
anacap))
;
465 obj_add_uint(r, "anagrpmax", le32_to_cpu(ctrl->anagrpmax))json_object_object_add(r, "anagrpmax", json_object_new_uint64
(le32_to_cpu(ctrl->anagrpmax)))
;
466 obj_add_uint(r, "nanagrpid", le32_to_cpu(ctrl->nanagrpid))json_object_object_add(r, "nanagrpid", json_object_new_uint64
(le32_to_cpu(ctrl->nanagrpid)))
;
467 obj_add_uint(r, "pels", le32_to_cpu(ctrl->pels))json_object_object_add(r, "pels", json_object_new_uint64(le32_to_cpu
(ctrl->pels)))
;
468 obj_add_int(r, "domainid", le16_to_cpu(ctrl->domainid))json_object_object_add(r, "domainid", json_object_new_int(le16_to_cpu
(ctrl->domainid)))
;
469 obj_add_int(r, "kpioc", ctrl->kpioc)json_object_object_add(r, "kpioc", json_object_new_int(ctrl->
kpioc))
;
470 obj_add_int(r, "mptfawr", le16_to_cpu(ctrl->mptfawr))json_object_object_add(r, "mptfawr", json_object_new_int(le16_to_cpu
(ctrl->mptfawr)))
;
471 obj_add_uint128(r, "megcap", megcap)json_object_object_add(r, "megcap", util_json_object_new_uint128
(megcap))
;
472 obj_add_int(r, "tmpthha", ctrl->tmpthha)json_object_object_add(r, "tmpthha", json_object_new_int(ctrl
->tmpthha))
;
473 obj_add_int(r, "mupa", ctrl->mupa)json_object_object_add(r, "mupa", json_object_new_int(ctrl->
mupa))
;
474 obj_add_int(r, "cqt", le16_to_cpu(ctrl->cqt))json_object_object_add(r, "cqt", json_object_new_int(le16_to_cpu
(ctrl->cqt)))
;
475 obj_add_int(r, "cdpa", le16_to_cpu(ctrl->cdpa))json_object_object_add(r, "cdpa", json_object_new_int(le16_to_cpu
(ctrl->cdpa)))
;
476 obj_add_int(r, "mup", le16_to_cpu(ctrl->mup))json_object_object_add(r, "mup", json_object_new_int(le16_to_cpu
(ctrl->mup)))
;
477 obj_add_int(r, "ipmsr", le16_to_cpu(ctrl->ipmsr))json_object_object_add(r, "ipmsr", json_object_new_int(le16_to_cpu
(ctrl->ipmsr)))
;
478 obj_add_int(r, "msmt", le16_to_cpu(ctrl->msmt))json_object_object_add(r, "msmt", json_object_new_int(le16_to_cpu
(ctrl->msmt)))
;
479 obj_add_int(r, "mnens", le16_to_cpu(ctrl->mnens))json_object_object_add(r, "mnens", json_object_new_int(le16_to_cpu
(ctrl->mnens)))
;
480 obj_add_int(r, "mnecpens", le16_to_cpu(ctrl->mnecpens))json_object_object_add(r, "mnecpens", json_object_new_int(le16_to_cpu
(ctrl->mnecpens)))
;
481 obj_add_uint(r, "mensnn", le32_to_cpu(ctrl->mensnn))json_object_object_add(r, "mensnn", json_object_new_uint64(le32_to_cpu
(ctrl->mensnn)))
;
482 obj_add_int(r, "ensa", le16_to_cpu(ctrl->ensa))json_object_object_add(r, "ensa", json_object_new_int(le16_to_cpu
(ctrl->ensa)))
;
483 obj_add_int(r, "endsfs", le16_to_cpu(ctrl->endsfs))json_object_object_add(r, "endsfs", json_object_new_int(le16_to_cpu
(ctrl->endsfs)))
;
484 obj_add_uint(r, "vsen1", le32_to_cpu(ctrl->vsen1))json_object_object_add(r, "vsen1", json_object_new_uint64(le32_to_cpu
(ctrl->vsen1)))
;
485 obj_add_uint(r, "vsen2", le32_to_cpu(ctrl->vsen2))json_object_object_add(r, "vsen2", json_object_new_uint64(le32_to_cpu
(ctrl->vsen2)))
;
486 obj_add_uint(r, "vsen3", le32_to_cpu(ctrl->vsen3))json_object_object_add(r, "vsen3", json_object_new_uint64(le32_to_cpu
(ctrl->vsen3)))
;
487 obj_add_uint(r, "vsen4", le32_to_cpu(ctrl->vsen4))json_object_object_add(r, "vsen4", json_object_new_uint64(le32_to_cpu
(ctrl->vsen4)))
;
488 obj_add_int(r, "msvmt", le16_to_cpu(ctrl->msvmt))json_object_object_add(r, "msvmt", json_object_new_int(le16_to_cpu
(ctrl->msvmt)))
;
489 obj_add_int(r, "sqes", ctrl->sqes)json_object_object_add(r, "sqes", json_object_new_int(ctrl->
sqes))
;
490 obj_add_int(r, "cqes", ctrl->cqes)json_object_object_add(r, "cqes", json_object_new_int(ctrl->
cqes))
;
491 obj_add_int(r, "maxcmd", le16_to_cpu(ctrl->maxcmd))json_object_object_add(r, "maxcmd", json_object_new_int(le16_to_cpu
(ctrl->maxcmd)))
;
492 obj_add_uint(r, "nn", le32_to_cpu(ctrl->nn))json_object_object_add(r, "nn", json_object_new_uint64(le32_to_cpu
(ctrl->nn)))
;
493 obj_add_int(r, "oncs", le16_to_cpu(ctrl->oncs))json_object_object_add(r, "oncs", json_object_new_int(le16_to_cpu
(ctrl->oncs)))
;
494 obj_add_int(r, "fuses", le16_to_cpu(ctrl->fuses))json_object_object_add(r, "fuses", json_object_new_int(le16_to_cpu
(ctrl->fuses)))
;
495 obj_add_int(r, "fna", ctrl->fna)json_object_object_add(r, "fna", json_object_new_int(ctrl->
fna))
;
496 obj_add_int(r, "vwc", ctrl->vwc)json_object_object_add(r, "vwc", json_object_new_int(ctrl->
vwc))
;
497 obj_add_int(r, "awun", le16_to_cpu(ctrl->awun))json_object_object_add(r, "awun", json_object_new_int(le16_to_cpu
(ctrl->awun)))
;
498 obj_add_int(r, "awupf", le16_to_cpu(ctrl->awupf))json_object_object_add(r, "awupf", json_object_new_int(le16_to_cpu
(ctrl->awupf)))
;
499 obj_add_int(r, "icsvscc", ctrl->icsvscc)json_object_object_add(r, "icsvscc", json_object_new_int(ctrl
->icsvscc))
;
500 obj_add_int(r, "nwpc", ctrl->nwpc)json_object_object_add(r, "nwpc", json_object_new_int(ctrl->
nwpc))
;
501 obj_add_int(r, "acwu", le16_to_cpu(ctrl->acwu))json_object_object_add(r, "acwu", json_object_new_int(le16_to_cpu
(ctrl->acwu)))
;
502 obj_add_int(r, "ocfs", le16_to_cpu(ctrl->ocfs))json_object_object_add(r, "ocfs", json_object_new_int(le16_to_cpu
(ctrl->ocfs)))
;
503 obj_add_uint(r, "sgls", le32_to_cpu(ctrl->sgls))json_object_object_add(r, "sgls", json_object_new_uint64(le32_to_cpu
(ctrl->sgls)))
;
504 obj_add_uint(r, "mnan", le32_to_cpu(ctrl->mnan))json_object_object_add(r, "mnan", json_object_new_uint64(le32_to_cpu
(ctrl->mnan)))
;
505 obj_add_uint128(r, "maxdna", maxdna)json_object_object_add(r, "maxdna", util_json_object_new_uint128
(maxdna))
;
506 obj_add_uint(r, "maxcna", le32_to_cpu(ctrl->maxcna))json_object_object_add(r, "maxcna", json_object_new_uint64(le32_to_cpu
(ctrl->maxcna)))
;
507 obj_add_uint(r, "oaqd", le32_to_cpu(ctrl->oaqd))json_object_object_add(r, "oaqd", json_object_new_uint64(le32_to_cpu
(ctrl->oaqd)))
;
508 obj_add_int(r, "rhiri", ctrl->rhiri)json_object_object_add(r, "rhiri", json_object_new_int(ctrl->
rhiri))
;
509 obj_add_int(r, "hirt", ctrl->hirt)json_object_object_add(r, "hirt", json_object_new_int(ctrl->
hirt))
;
510 obj_add_int(r, "cmmrtd", le16_to_cpu(ctrl->cmmrtd))json_object_object_add(r, "cmmrtd", json_object_new_int(le16_to_cpu
(ctrl->cmmrtd)))
;
511 obj_add_int(r, "nmmrtd", le16_to_cpu(ctrl->nmmrtd))json_object_object_add(r, "nmmrtd", json_object_new_int(le16_to_cpu
(ctrl->nmmrtd)))
;
512 obj_add_int(r, "minmrtg", ctrl->minmrtg)json_object_object_add(r, "minmrtg", json_object_new_int(ctrl
->minmrtg))
;
513 obj_add_int(r, "maxmrtg", ctrl->maxmrtg)json_object_object_add(r, "maxmrtg", json_object_new_int(ctrl
->maxmrtg))
;
514 obj_add_int(r, "trattr", ctrl->trattr)json_object_object_add(r, "trattr", json_object_new_int(ctrl->
trattr))
;
515 obj_add_int(r, "mcudmq", le16_to_cpu(ctrl->mcudmq))json_object_object_add(r, "mcudmq", json_object_new_int(le16_to_cpu
(ctrl->mcudmq)))
;
516 obj_add_int(r, "mnsudmq", le16_to_cpu(ctrl->mnsudmq))json_object_object_add(r, "mnsudmq", json_object_new_int(le16_to_cpu
(ctrl->mnsudmq)))
;
517 obj_add_int(r, "mcmr", le16_to_cpu(ctrl->mcmr))json_object_object_add(r, "mcmr", json_object_new_int(le16_to_cpu
(ctrl->mcmr)))
;
518 obj_add_int(r, "nmcmr", le16_to_cpu(ctrl->nmcmr))json_object_object_add(r, "nmcmr", json_object_new_int(le16_to_cpu
(ctrl->nmcmr)))
;
519 obj_add_int(r, "mcdqpc", le16_to_cpu(ctrl->mcdqpc))json_object_object_add(r, "mcdqpc", json_object_new_int(le16_to_cpu
(ctrl->mcdqpc)))
;
520
521 if (strlen(subnqn))
522 obj_add_strjson_object_add_value_string(r, "subnqn", subnqn);
523
524 obj_add_uint(r, "ioccsz", le32_to_cpu(ctrl->ioccsz))json_object_object_add(r, "ioccsz", json_object_new_uint64(le32_to_cpu
(ctrl->ioccsz)))
;
525 obj_add_uint(r, "iorcsz", le32_to_cpu(ctrl->iorcsz))json_object_object_add(r, "iorcsz", json_object_new_uint64(le32_to_cpu
(ctrl->iorcsz)))
;
526 obj_add_int(r, "icdoff", le16_to_cpu(ctrl->icdoff))json_object_object_add(r, "icdoff", json_object_new_int(le16_to_cpu
(ctrl->icdoff)))
;
527 obj_add_int(r, "fcatt", ctrl->fcatt)json_object_object_add(r, "fcatt", json_object_new_int(ctrl->
fcatt))
;
528 obj_add_int(r, "msdbd", ctrl->msdbd)json_object_object_add(r, "msdbd", json_object_new_int(ctrl->
msdbd))
;
529 obj_add_int(r, "ofcs", le16_to_cpu(ctrl->ofcs))json_object_object_add(r, "ofcs", json_object_new_int(le16_to_cpu
(ctrl->ofcs)))
;
530 obj_add_int(r, "dctype", ctrl->dctype)json_object_object_add(r, "dctype", json_object_new_int(ctrl->
dctype))
;
531 obj_add_int(r, "ccrl", ctrl->ccrl)json_object_object_add(r, "ccrl", json_object_new_int(ctrl->
ccrl))
;
532
533 obj_add_array(r, "psds", psds)json_object_object_add(r, "psds", psds);
534
535 for (i = 0; i < nvme_id_ctrl_nr_psd(ctrl); i++) {
536 struct json_object *psd = json_create_object()json_object_new_object();
537
538 obj_add_int(psd, "max_power", le16_to_cpu(ctrl->psd[i].mp))json_object_object_add(psd, "max_power", json_object_new_int(
le16_to_cpu(ctrl->psd[i].mp)))
;
539 obj_add_int(psd, "max_power_scale", ctrl->psd[i].flags & NVME_PSD_FLAGS_MXPS)json_object_object_add(psd, "max_power_scale", json_object_new_int
(ctrl->psd[i].flags & NVME_PSD_FLAGS_MXPS))
;
540 obj_add_int(psd, "non-operational_state",json_object_object_add(psd, "non-operational_state", json_object_new_int
(!!(ctrl->psd[i].flags & NVME_PSD_FLAGS_NOPS)))
541 !!(ctrl->psd[i].flags & NVME_PSD_FLAGS_NOPS))json_object_object_add(psd, "non-operational_state", json_object_new_int
(!!(ctrl->psd[i].flags & NVME_PSD_FLAGS_NOPS)))
;
542 obj_add_uint(psd, "entry_lat", le32_to_cpu(ctrl->psd[i].enlat))json_object_object_add(psd, "entry_lat", json_object_new_uint64
(le32_to_cpu(ctrl->psd[i].enlat)))
;
543 obj_add_uint(psd, "exit_lat", le32_to_cpu(ctrl->psd[i].exlat))json_object_object_add(psd, "exit_lat", json_object_new_uint64
(le32_to_cpu(ctrl->psd[i].exlat)))
;
544 obj_add_int(psd, "read_tput", ctrl->psd[i].rrt)json_object_object_add(psd, "read_tput", json_object_new_int(
ctrl->psd[i].rrt))
;
545 obj_add_int(psd, "read_lat", ctrl->psd[i].rrl)json_object_object_add(psd, "read_lat", json_object_new_int(ctrl
->psd[i].rrl))
;
546 obj_add_int(psd, "write_tput", ctrl->psd[i].rwt)json_object_object_add(psd, "write_tput", json_object_new_int
(ctrl->psd[i].rwt))
;
547 obj_add_int(psd, "write_lat", ctrl->psd[i].rwl)json_object_object_add(psd, "write_lat", json_object_new_int(
ctrl->psd[i].rwl))
;
548 obj_add_int(psd, "idle_power", le16_to_cpu(ctrl->psd[i].idlp))json_object_object_add(psd, "idle_power", json_object_new_int
(le16_to_cpu(ctrl->psd[i].idlp)))
;
549 obj_add_int(psd, "idle_scale", nvme_psd_power_scale(ctrl->psd[i].ips))json_object_object_add(psd, "idle_scale", json_object_new_int
(nvme_psd_power_scale(ctrl->psd[i].ips)))
;
550 obj_add_int(psd, "active_power", le16_to_cpu(ctrl->psd[i].actp))json_object_object_add(psd, "active_power", json_object_new_int
(le16_to_cpu(ctrl->psd[i].actp)))
;
551 obj_add_int(psd, "active_power_work", ctrl->psd[i].apws & 7)json_object_object_add(psd, "active_power_work", json_object_new_int
(ctrl->psd[i].apws & 7))
;
552 obj_add_int(psd, "active_scale", nvme_psd_power_scale(ctrl->psd[i].apws))json_object_object_add(psd, "active_scale", json_object_new_int
(nvme_psd_power_scale(ctrl->psd[i].apws)))
;
553 obj_add_int(psd, "emerg_power_fail_recover_time", ctrl->psd[i].epfrt)json_object_object_add(psd, "emerg_power_fail_recover_time", json_object_new_int
(ctrl->psd[i].epfrt))
;
554 obj_add_int(psd, "emerg_power_fail_recover_scale", ctrl->psd[i].epfr_fqv_ts & 0xf)json_object_object_add(psd, "emerg_power_fail_recover_scale",
json_object_new_int(ctrl->psd[i].epfr_fqv_ts & 0xf))
;
555 obj_add_int(psd, "force_quiesce_vault_time", ctrl->psd[i].fqvt)json_object_object_add(psd, "force_quiesce_vault_time", json_object_new_int
(ctrl->psd[i].fqvt))
;
556 obj_add_int(psd, "force_quiesce_vault_scale", ctrl->psd[i].epfr_fqv_ts >> 4)json_object_object_add(psd, "force_quiesce_vault_scale", json_object_new_int
(ctrl->psd[i].epfr_fqv_ts >> 4))
;
557 obj_add_int(psd, "emerg_power_fail_vault_time", ctrl->psd[i].epfvt)json_object_object_add(psd, "emerg_power_fail_vault_time", json_object_new_int
(ctrl->psd[i].epfvt))
;
558 obj_add_int(psd, "emerg_power_fail_vault_scale", ctrl->psd[i].epfvts & 0xf)json_object_object_add(psd, "emerg_power_fail_vault_scale", json_object_new_int
(ctrl->psd[i].epfvts & 0xf))
;
559 obj_add_int(psd, "max_bandwidth", ctrl->psd[i].mbw)json_object_object_add(psd, "max_bandwidth", json_object_new_int
(ctrl->psd[i].mbw))
;
560 obj_add_int(psd, "max_bandwidth_scale",json_object_object_add(psd, "max_bandwidth_scale", json_object_new_int
(ctrl->psd[i].mbws & 0x7))
561 ctrl->psd[i].mbws & 0x7)json_object_object_add(psd, "max_bandwidth_scale", json_object_new_int
(ctrl->psd[i].mbws & 0x7))
;
562 obj_add_int(psd, "min_idle_io_exit_lat_limit",json_object_object_add(psd, "min_idle_io_exit_lat_limit", json_object_new_int
(le16_to_cpu(ctrl->psd[i].miiell)))
563 le16_to_cpu(ctrl->psd[i].miiell))json_object_object_add(psd, "min_idle_io_exit_lat_limit", json_object_new_int
(le16_to_cpu(ctrl->psd[i].miiell)))
;
564
565 array_add_obj(psds, psd)json_object_array_add(psds, psd);
566 }
567
568 if (vs)
569 vs(ctrl->vs, r);
570}
571
572static void json_error_log(struct nvme_error_log_page *err_log, int entries,
573 const char *devname,
574 struct nvme_error_log_filter *flt)
575{
576 struct json_object *r = json_r;
577 struct json_object *errors = json_create_array()json_object_new_array();
578 struct json_object *error;
579 __u16 sts;
580 int i;
581
582 obj_add_array(r, "errors", errors)json_object_object_add(r, "errors", errors);
583
584 for (i = 0; i < entries; i++) {
585 if (nvme_is_error_log_filter(&err_log[i], flt))
586 continue;
587
588 error = json_create_object()json_object_new_object();
589 sts = le16_to_cpu(err_log[i].status_field);
590
591 obj_add_uint64(error, "error_count",json_object_object_add(error, "error_count", json_object_new_uint64
(le64_to_cpu(err_log[i].error_count)))
592 le64_to_cpu(err_log[i].error_count))json_object_object_add(error, "error_count", json_object_new_uint64
(le64_to_cpu(err_log[i].error_count)))
;
593 obj_add_int(error, "sqid", le16_to_cpu(err_log[i].sqid))json_object_object_add(error, "sqid", json_object_new_int(le16_to_cpu
(err_log[i].sqid)))
;
594 obj_add_int(error, "cmdid", le16_to_cpu(err_log[i].cmdid))json_object_object_add(error, "cmdid", json_object_new_int(le16_to_cpu
(err_log[i].cmdid)))
;
595 obj_add_int(error, "status_field",json_object_object_add(error, "status_field", json_object_new_int
((((sts) >> NVME_ERR_SF_STATUS_FIELD_SHIFT) & NVME_ERR_SF_STATUS_FIELD_MASK
)))
596 NVME_ERR_SF_STATUS_FIELD(sts))json_object_object_add(error, "status_field", json_object_new_int
((((sts) >> NVME_ERR_SF_STATUS_FIELD_SHIFT) & NVME_ERR_SF_STATUS_FIELD_MASK
)))
;
597 obj_add_int(error, "phase_tag", NVME_ERR_SF_PHASE_TAG(sts))json_object_object_add(error, "phase_tag", json_object_new_int
((((sts) >> NVME_ERR_SF_PHASE_TAG_SHIFT) & NVME_ERR_SF_PHASE_TAG_MASK
)))
;
598 obj_add_int(error, "parm_error_location",json_object_object_add(error, "parm_error_location", json_object_new_int
(le16_to_cpu(err_log[i].parm_error_location)))
599 le16_to_cpu(err_log[i].parm_error_location))json_object_object_add(error, "parm_error_location", json_object_new_int
(le16_to_cpu(err_log[i].parm_error_location)))
;
600 obj_add_uint64(error, "lba", le64_to_cpu(err_log[i].lba))json_object_object_add(error, "lba", json_object_new_uint64(le64_to_cpu
(err_log[i].lba)))
;
601 obj_add_uint(error, "nsid", le32_to_cpu(err_log[i].nsid))json_object_object_add(error, "nsid", json_object_new_uint64(
le32_to_cpu(err_log[i].nsid)))
;
602 obj_add_int(error, "vs", err_log[i].vs)json_object_object_add(error, "vs", json_object_new_int(err_log
[i].vs))
;
603 obj_add_int(error, "trtype", err_log[i].trtype)json_object_object_add(error, "trtype", json_object_new_int(err_log
[i].trtype))
;
604 obj_add_int(error, "csi", err_log[i].csi)json_object_object_add(error, "csi", json_object_new_int(err_log
[i].csi))
;
605 obj_add_int(error, "opcode", err_log[i].opcode)json_object_object_add(error, "opcode", json_object_new_int(err_log
[i].opcode))
;
606 obj_add_uint64(error, "cs", le64_to_cpu(err_log[i].cs))json_object_object_add(error, "cs", json_object_new_uint64(le64_to_cpu
(err_log[i].cs)))
;
607 obj_add_int(error, "trtype_spec_info",json_object_object_add(error, "trtype_spec_info", json_object_new_int
(le16_to_cpu(err_log[i].trtype_spec_info)))
608 le16_to_cpu(err_log[i].trtype_spec_info))json_object_object_add(error, "trtype_spec_info", json_object_new_int
(le16_to_cpu(err_log[i].trtype_spec_info)))
;
609 obj_add_int(error, "log_page_version",json_object_object_add(error, "log_page_version", json_object_new_int
(err_log[i].log_page_version))
610 err_log[i].log_page_version)json_object_object_add(error, "log_page_version", json_object_new_int
(err_log[i].log_page_version))
;
611
612 array_add_obj(errors, error)json_object_array_add(errors, error);
613 }
614}
615
616void json_nvme_resv_report(struct nvme_resv_status *status,
617 int bytes, bool_Bool eds)
618{
619 struct json_object *r = json_r;
620 struct json_object *rcs = json_create_array()json_object_new_array();
621 int i, j, entries;
622 int regstrnt = status->regstrnt[0] | (status->regstrnt[1] << 8);
623
624 obj_add_uint(r, "gen", le32_to_cpu(status->gen))json_object_object_add(r, "gen", json_object_new_uint64(le32_to_cpu
(status->gen)))
;
625 obj_add_int(r, "rtype", status->rtype)json_object_object_add(r, "rtype", json_object_new_int(status
->rtype))
;
626 obj_add_int(r, "regstrnt", regstrnt)json_object_object_add(r, "regstrnt", json_object_new_int(regstrnt
))
;
627 obj_add_int(r, "ptpls", status->ptpls)json_object_object_add(r, "ptpls", json_object_new_int(status
->ptpls))
;
628
629 /* check Extended Data Structure bit */
630 if (!eds) {
631 /*
632 * if status buffer was too small, don't loop past the end of
633 * the buffer
634 */
635 entries = (bytes - 24) / 24;
636 if (entries < regstrnt)
637 regstrnt = entries;
638
639 obj_add_array(r, "registrants", rcs)json_object_object_add(r, "registrants", rcs);
640 for (i = 0; i < regstrnt; i++) {
641 struct json_object *rc = json_create_object()json_object_new_object();
642
643 obj_add_int(rc, "cntlid", le16_to_cpu(status->registrant_ds[i].cntlid))json_object_object_add(rc, "cntlid", json_object_new_int(le16_to_cpu
(status->registrant_ds[i].cntlid)))
;
644 obj_add_int(rc, "rcsts", status->registrant_ds[i].rcsts)json_object_object_add(rc, "rcsts", json_object_new_int(status
->registrant_ds[i].rcsts))
;
645 obj_add_uint64(rc, "hostid", le64_to_cpu(status->registrant_ds[i].hostid))json_object_object_add(rc, "hostid", json_object_new_uint64(le64_to_cpu
(status->registrant_ds[i].hostid)))
;
646 obj_add_uint64(rc, "rkey", le64_to_cpu(status->registrant_ds[i].rkey))json_object_object_add(rc, "rkey", json_object_new_uint64(le64_to_cpu
(status->registrant_ds[i].rkey)))
;
647
648 array_add_obj(rcs, rc)json_object_array_add(rcs, rc);
649 }
650 } else {
651 char hostid[33];
652
653 /* if status buffer was too small, don't loop past the end of the buffer */
654 entries = (bytes - 64) / 64;
655
656 if (entries < regstrnt)
657 regstrnt = entries;
658
659 obj_add_array(r, "registrantext", rcs)json_object_object_add(r, "registrantext", rcs);
660
661 for (i = 0; i < regstrnt; i++) {
662 struct json_object *rc = json_create_object()json_object_new_object();
663
664 obj_add_int(rc, "cntlid", le16_to_cpu(status->registrant_eds[i].cntlid))json_object_object_add(rc, "cntlid", json_object_new_int(le16_to_cpu
(status->registrant_eds[i].cntlid)))
;
665 obj_add_int(rc, "rcsts", status->registrant_eds[i].rcsts)json_object_object_add(rc, "rcsts", json_object_new_int(status
->registrant_eds[i].rcsts))
;
666 obj_add_uint64(rc, "rkey", le64_to_cpu(status->registrant_eds[i].rkey))json_object_object_add(rc, "rkey", json_object_new_uint64(le64_to_cpu
(status->registrant_eds[i].rkey)))
;
667
668 for (j = 0; j < 16; j++)
669 sprintf(hostid + j * 2, "%02x", status->registrant_eds[i].hostid[j]);
670
671 obj_add_strjson_object_add_value_string(rc, "hostid", hostid);
672 array_add_obj(rcs, rc)json_object_array_add(rcs, rc);
673 }
674 }
675}
676
677void json_fw_log(struct nvme_firmware_slot *fw_log, const char *devname)
678{
679 struct json_object *r = json_r;
680 struct json_object *fwsi = json_create_object()json_object_new_object();
681 char fmt[21];
682 char str[32];
683 int i;
684 __le64 *frs;
685
686 obj_add_int(fwsi, "Active Firmware Slot (afi)", fw_log->afi)json_object_object_add(fwsi, "Active Firmware Slot (afi)", json_object_new_int
(fw_log->afi))
;
687
688 for (i = 0; i < 7; i++) {
689 if (fw_log->frs[i][0]) {
690 snprintf(fmt, sizeof(fmt), "Firmware Rev Slot %d",
691 i + 1);
692 frs = (__le64 *)&fw_log->frs[i];
693 snprintf(str, sizeof(str), "%"PRIu64"l" "u"" (%s)",
694 le64_to_cpu(*frs),
695 shr_fw_to_string(fw_log->frs[i]));
696 obj_add_strjson_object_add_value_string(fwsi, fmt, str);
697 }
698 }
699
700 obj_add_obj(r, devname, fwsi)json_object_object_add(r, devname, fwsi);
701}
702
703void json_changed_ns_list_log(struct nvme_ns_list *log, const char *devname, bool_Bool alloc)
704{
705 struct json_object *r = json_r;
706 struct json_object *nsi;
707 char fmt[32];
708 char str[32];
709 __u32 nsid;
710 int i;
711
712 __cleanup_free__attribute__((cleanup(shr_freep))) char *k = NULL((void*)0);
713
714 if (log->ns[0] == cpu_to_le32(0xffffffff))
715 return;
716
717 nsi = json_create_object()json_object_new_object();
718
719 if (asprintf(&k, "Changed %s Namespace List Log", alloc ? "Allocated" : "Attached") > 0)
720 obj_add_strjson_object_add_value_string(r, k, devname);
721
722 for (i = 0; i < NVME_ID_NS_LIST_MAX; i++) {
723 nsid = le32_to_cpu(log->ns[i]);
724
725 if (nsid == 0)
726 break;
727
728 snprintf(fmt, sizeof(fmt), "[%4u]", i + 1);
729 snprintf(str, sizeof(str), "%#x", nsid);
730 obj_add_strjson_object_add_value_string(nsi, fmt, str);
731 }
732
733 obj_add_obj(r, devname, nsi)json_object_object_add(r, devname, nsi);
734}
735
736static void json_endurance_log(struct nvme_endurance_group_log *endurance_group, __u16 group_id,
737 const char *devname)
738{
739 struct json_object *r = json_r;
740 shr_uint128_t endurance_estimate = le128_to_cpu(endurance_group->endurance_estimate);
741 shr_uint128_t data_units_read = le128_to_cpu(endurance_group->data_units_read);
742 shr_uint128_t data_units_written = le128_to_cpu(endurance_group->data_units_written);
743 shr_uint128_t media_units_written = le128_to_cpu(endurance_group->media_units_written);
744 shr_uint128_t host_read_cmds = le128_to_cpu(endurance_group->host_read_cmds);
745 shr_uint128_t host_write_cmds = le128_to_cpu(endurance_group->host_write_cmds);
746 shr_uint128_t media_data_integrity_err =
747 le128_to_cpu(endurance_group->media_data_integrity_err);
748 shr_uint128_t num_err_info_log_entries =
749 le128_to_cpu(endurance_group->num_err_info_log_entries);
750 shr_uint128_t total_end_grp_cap = le128_to_cpu(endurance_group->total_end_grp_cap);
751 shr_uint128_t unalloc_end_grp_cap = le128_to_cpu(endurance_group->unalloc_end_grp_cap);
752
753 obj_add_int(r, "critical_warning", endurance_group->critical_warning)json_object_object_add(r, "critical_warning", json_object_new_int
(endurance_group->critical_warning))
;
754 obj_add_int(r, "endurance_group_features", endurance_group->endurance_group_features)json_object_object_add(r, "endurance_group_features", json_object_new_int
(endurance_group->endurance_group_features))
;
755 obj_add_int(r, "avl_spare", endurance_group->avl_spare)json_object_object_add(r, "avl_spare", json_object_new_int(endurance_group
->avl_spare))
;
756 obj_add_int(r, "avl_spare_threshold", endurance_group->avl_spare_threshold)json_object_object_add(r, "avl_spare_threshold", json_object_new_int
(endurance_group->avl_spare_threshold))
;
757 obj_add_int(r, "percent_used", endurance_group->percent_used)json_object_object_add(r, "percent_used", json_object_new_int
(endurance_group->percent_used))
;
758 obj_add_int(r, "domain_identifier", endurance_group->domain_identifier)json_object_object_add(r, "domain_identifier", json_object_new_int
(endurance_group->domain_identifier))
;
759 obj_add_uint128(r, "endurance_estimate", endurance_estimate)json_object_object_add(r, "endurance_estimate", util_json_object_new_uint128
(endurance_estimate))
;
760 obj_add_uint128(r, "data_units_read", data_units_read)json_object_object_add(r, "data_units_read", util_json_object_new_uint128
(data_units_read))
;
761 obj_add_uint128(r, "data_units_written", data_units_written)json_object_object_add(r, "data_units_written", util_json_object_new_uint128
(data_units_written))
;
762 obj_add_uint128(r, "media_units_written", media_units_written)json_object_object_add(r, "media_units_written", util_json_object_new_uint128
(media_units_written))
;
763 obj_add_uint128(r, "host_read_cmds", host_read_cmds)json_object_object_add(r, "host_read_cmds", util_json_object_new_uint128
(host_read_cmds))
;
764 obj_add_uint128(r, "host_write_cmds", host_write_cmds)json_object_object_add(r, "host_write_cmds", util_json_object_new_uint128
(host_write_cmds))
;
765 obj_add_uint128(r, "media_data_integrity_err", media_data_integrity_err)json_object_object_add(r, "media_data_integrity_err", util_json_object_new_uint128
(media_data_integrity_err))
;
766 obj_add_uint128(r, "num_err_info_log_entries", num_err_info_log_entries)json_object_object_add(r, "num_err_info_log_entries", util_json_object_new_uint128
(num_err_info_log_entries))
;
767 obj_add_uint128(r, "total_end_grp_cap", total_end_grp_cap)json_object_object_add(r, "total_end_grp_cap", util_json_object_new_uint128
(total_end_grp_cap))
;
768 obj_add_uint128(r, "unalloc_end_grp_cap", unalloc_end_grp_cap)json_object_object_add(r, "unalloc_end_grp_cap", util_json_object_new_uint128
(unalloc_end_grp_cap))
;
769}
770
771static void json_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
772 const char *devname)
773{
774 struct json_object *r = json_r;
775 int c;
776 char key[21];
777 unsigned int temperature = ((smart->temperature[1] << 8) |
778 smart->temperature[0]);
779 shr_uint128_t data_units_read = le128_to_cpu(smart->data_units_read);
780 shr_uint128_t data_units_written = le128_to_cpu(smart->data_units_written);
781 shr_uint128_t host_read_commands = le128_to_cpu(smart->host_reads);
782 shr_uint128_t host_write_commands = le128_to_cpu(smart->host_writes);
783 shr_uint128_t controller_busy_time = le128_to_cpu(smart->ctrl_busy_time);
784 shr_uint128_t power_cycles = le128_to_cpu(smart->power_cycles);
785 shr_uint128_t power_on_hours = le128_to_cpu(smart->power_on_hours);
786 shr_uint128_t unsafe_shutdowns = le128_to_cpu(smart->unsafe_shutdowns);
787 shr_uint128_t media_errors = le128_to_cpu(smart->media_errors);
788 shr_uint128_t num_err_log_entries = le128_to_cpu(smart->num_err_log_entries);
789
790 if (verbose_mode()) {
791 struct json_object *crt = json_create_object()json_object_new_object();
792
793 obj_add_int(crt, "value", smart->critical_warning)json_object_object_add(crt, "value", json_object_new_int(smart
->critical_warning))
;
794 obj_add_int(crt, "available_spare", smart->critical_warning & 1)json_object_object_add(crt, "available_spare", json_object_new_int
(smart->critical_warning & 1))
;
795 obj_add_int(crt, "temp_threshold", (smart->critical_warning & 2) >> 1)json_object_object_add(crt, "temp_threshold", json_object_new_int
((smart->critical_warning & 2) >> 1))
;
796 obj_add_int(crt, "reliability_degraded", (smart->critical_warning & 4) >> 2)json_object_object_add(crt, "reliability_degraded", json_object_new_int
((smart->critical_warning & 4) >> 2))
;
797 obj_add_int(crt, "ro", (smart->critical_warning & 8) >> 3)json_object_object_add(crt, "ro", json_object_new_int((smart->
critical_warning & 8) >> 3))
;
798 obj_add_int(crt, "vmbu_failed", (smart->critical_warning & 0x10) >> 4)json_object_object_add(crt, "vmbu_failed", json_object_new_int
((smart->critical_warning & 0x10) >> 4))
;
799 obj_add_int(crt, "pmr_ro", (smart->critical_warning & 0x20) >> 5)json_object_object_add(crt, "pmr_ro", json_object_new_int((smart
->critical_warning & 0x20) >> 5))
;
800 obj_add_int(crt, "indeterminate_personality",json_object_object_add(crt, "indeterminate_personality", json_object_new_int
((smart->critical_warning & 0x40) >> 6))
801 (smart->critical_warning & 0x40) >> 6)json_object_object_add(crt, "indeterminate_personality", json_object_new_int
((smart->critical_warning & 0x40) >> 6))
;
802
803 obj_add_obj(r, "critical_warning", crt)json_object_object_add(r, "critical_warning", crt);
804 } else {
805 obj_add_int(r, "critical_warning", smart->critical_warning)json_object_object_add(r, "critical_warning", json_object_new_int
(smart->critical_warning))
;
806 }
807
808 obj_add_int(r, "temperature", temperature)json_object_object_add(r, "temperature", json_object_new_int(
temperature))
;
809 obj_add_int(r, "avail_spare", smart->avail_spare)json_object_object_add(r, "avail_spare", json_object_new_int(
smart->avail_spare))
;
810 obj_add_int(r, "spare_thresh", smart->spare_thresh)json_object_object_add(r, "spare_thresh", json_object_new_int
(smart->spare_thresh))
;
811 obj_add_int(r, "percent_used", smart->percent_used)json_object_object_add(r, "percent_used", json_object_new_int
(smart->percent_used))
;
812 obj_add_int(r, "endurance_grp_critical_warning_summary", smart->endu_grp_crit_warn_sumry)json_object_object_add(r, "endurance_grp_critical_warning_summary"
, json_object_new_int(smart->endu_grp_crit_warn_sumry))
;
813 obj_add_int(r, "informative_warning", smart->informative_warning)json_object_object_add(r, "informative_warning", json_object_new_int
(smart->informative_warning))
;
814 obj_add_int(r, "voltage_log_threshold_warning",json_object_object_add(r, "voltage_log_threshold_warning", json_object_new_int
(smart->informative_warning & 0x1))
815 smart->informative_warning & 0x1)json_object_object_add(r, "voltage_log_threshold_warning", json_object_new_int
(smart->informative_warning & 0x1))
;
816 obj_add_uint128(r, "data_units_read", data_units_read)json_object_object_add(r, "data_units_read", util_json_object_new_uint128
(data_units_read))
;
817 obj_add_uint128(r, "data_units_written", data_units_written)json_object_object_add(r, "data_units_written", util_json_object_new_uint128
(data_units_written))
;
818 obj_add_uint128(r, "host_read_commands", host_read_commands)json_object_object_add(r, "host_read_commands", util_json_object_new_uint128
(host_read_commands))
;
819 obj_add_uint128(r, "host_write_commands", host_write_commands)json_object_object_add(r, "host_write_commands", util_json_object_new_uint128
(host_write_commands))
;
820 obj_add_uint128(r, "controller_busy_time", controller_busy_time)json_object_object_add(r, "controller_busy_time", util_json_object_new_uint128
(controller_busy_time))
;
821 obj_add_uint128(r, "power_cycles", power_cycles)json_object_object_add(r, "power_cycles", util_json_object_new_uint128
(power_cycles))
;
822 obj_add_uint128(r, "power_on_hours", power_on_hours)json_object_object_add(r, "power_on_hours", util_json_object_new_uint128
(power_on_hours))
;
823 obj_add_uint128(r, "unsafe_shutdowns", unsafe_shutdowns)json_object_object_add(r, "unsafe_shutdowns", util_json_object_new_uint128
(unsafe_shutdowns))
;
824 obj_add_uint128(r, "media_errors", media_errors)json_object_object_add(r, "media_errors", util_json_object_new_uint128
(media_errors))
;
825 obj_add_uint128(r, "num_err_log_entries", num_err_log_entries)json_object_object_add(r, "num_err_log_entries", util_json_object_new_uint128
(num_err_log_entries))
;
826 obj_add_uint(r, "warning_temp_time", le32_to_cpu(smart->warning_temp_time))json_object_object_add(r, "warning_temp_time", json_object_new_uint64
(le32_to_cpu(smart->warning_temp_time)))
;
827 obj_add_uint(r, "critical_comp_time", le32_to_cpu(smart->critical_comp_time))json_object_object_add(r, "critical_comp_time", json_object_new_uint64
(le32_to_cpu(smart->critical_comp_time)))
;
828
829 for (c = 0; c < 8; c++) {
830 __s32 temp = le16_to_cpu(smart->temp_sensor[c]);
831
832 if (temp == 0)
833 continue;
834
835 sprintf(key, "temperature_sensor_%d", c + 1);
836 obj_add_int(r, key, temp)json_object_object_add(r, key, json_object_new_int(temp));
837 }
838
839 obj_add_uint(r, "thm_temp1_trans_count", le32_to_cpu(smart->thm_temp1_trans_count))json_object_object_add(r, "thm_temp1_trans_count", json_object_new_uint64
(le32_to_cpu(smart->thm_temp1_trans_count)))
;
840 obj_add_uint(r, "thm_temp2_trans_count", le32_to_cpu(smart->thm_temp2_trans_count))json_object_object_add(r, "thm_temp2_trans_count", json_object_new_uint64
(le32_to_cpu(smart->thm_temp2_trans_count)))
;
841 obj_add_uint(r, "thm_temp1_total_time", le32_to_cpu(smart->thm_temp1_total_time))json_object_object_add(r, "thm_temp1_total_time", json_object_new_uint64
(le32_to_cpu(smart->thm_temp1_total_time)))
;
842 obj_add_uint(r, "thm_temp2_total_time", le32_to_cpu(smart->thm_temp2_total_time))json_object_object_add(r, "thm_temp2_total_time", json_object_new_uint64
(le32_to_cpu(smart->thm_temp2_total_time)))
;
843 obj_add_uint64(r, "op_lifetime_energy_consumed", le64_to_cpu(smart->op_lifetime_energy_consumed))json_object_object_add(r, "op_lifetime_energy_consumed", json_object_new_uint64
(le64_to_cpu(smart->op_lifetime_energy_consumed)))
;
844 obj_add_uint(r, "interval_power_measurement", le32_to_cpu(smart->interval_power_measurement))json_object_object_add(r, "interval_power_measurement", json_object_new_uint64
(le32_to_cpu(smart->interval_power_measurement)))
;
845}
846
847static void json_ana_log(struct nvme_ana_log *ana_log, const char *devname,
848 size_t len)
849{
850 size_t offset = sizeof(struct nvme_ana_log);
851 struct nvme_ana_log *hdr = ana_log;
852 struct nvme_ana_group_desc ana_desc;
853 struct json_object *desc_list = json_create_array()json_object_new_array();
854 struct json_object *ns_list;
855 struct json_object *desc;
856 struct json_object *nsid;
857 struct json_object *r = json_r;
858 size_t nsid_buf_size;
859 void *base = ana_log;
860 __le32 *nsids;
861 __u32 nr_nsids;
862 int i, j;
863
864 obj_add_strjson_object_add_value_string(r, "Asymmetric Namespace Access Log for NVMe device", devname);
865 obj_add_uint64(r, "chgcnt", le64_to_cpu(hdr->chgcnt))json_object_object_add(r, "chgcnt", json_object_new_uint64(le64_to_cpu
(hdr->chgcnt)))
;
866 obj_add_uint(r, "ngrps", le16_to_cpu(hdr->ngrps))json_object_object_add(r, "ngrps", json_object_new_uint64(le16_to_cpu
(hdr->ngrps)))
;
867
868 for (i = 0; i < le16_to_cpu(ana_log->ngrps); i++) {
869 if (offset > len || len - offset < sizeof(ana_desc))
870 break;
871 /* descriptors are only 4 byte aligned */
872 memcpy(&ana_desc, base + offset, sizeof(ana_desc));
873 nr_nsids = le32_to_cpu(ana_desc.nnsids);
874 nsid_buf_size = (size_t)nr_nsids * sizeof(__le32);
875 if (len - offset - sizeof(ana_desc) < nsid_buf_size)
876 break;
877
878 desc = json_create_object()json_object_new_object();
879 offset += sizeof(ana_desc);
880 nsids = base + offset;
881 obj_add_uint(desc, "grpid", le32_to_cpu(ana_desc.grpid))json_object_object_add(desc, "grpid", json_object_new_uint64(
le32_to_cpu(ana_desc.grpid)))
;
882 obj_add_uint(desc, "nnsids", le32_to_cpu(ana_desc.nnsids))json_object_object_add(desc, "nnsids", json_object_new_uint64
(le32_to_cpu(ana_desc.nnsids)))
;
883 obj_add_uint64(desc, "chgcnt", le64_to_cpu(ana_desc.chgcnt))json_object_object_add(desc, "chgcnt", json_object_new_uint64
(le64_to_cpu(ana_desc.chgcnt)))
;
884 obj_add_strjson_object_add_value_string(desc, "state",
885 nvme_ana_state_to_string(ana_desc.state));
886
887 ns_list = json_create_array()json_object_new_array();
888 for (j = 0; j < nr_nsids; j++) {
889 nsid = json_create_object()json_object_new_object();
890 obj_add_uint(nsid, "nsid", le32_to_cpu(nsids[j]))json_object_object_add(nsid, "nsid", json_object_new_uint64(le32_to_cpu
(nsids[j])))
;
891 array_add_obj(ns_list, nsid)json_object_array_add(ns_list, nsid);
892 }
893 obj_add_array(desc, "NSIDS", ns_list)json_object_object_add(desc, "NSIDS", ns_list);
894 offset += nsid_buf_size;
895 array_add_obj(desc_list, desc)json_object_array_add(desc_list, desc);
896 }
897
898 obj_add_array(r, "ANA DESC LIST ", desc_list)json_object_object_add(r, "ANA DESC LIST ", desc_list);
899}
900
901static void json_select_result(enum nvme_features_id fid, __u64 result)
902{
903 struct json_object *r = json_r;
904 char json_str[STR_LEN100];
905 struct json_object *feature = json_create_array()json_object_new_array();
906
907 if (result & 0x1)
908 array_add_strjson_array_add_value_string(feature, "saveable");
909 if (result & 0x2)
910 array_add_strjson_array_add_value_string(feature, "per-namespace");
911 if (result & 0x4)
912 array_add_strjson_array_add_value_string(feature, "changeable");
913
914 sprintf(json_str, "Feature: %#0*x: select", fid ? 4 : 2, fid);
915 obj_add_array(r, json_str, feature)json_object_object_add(r, json_str, feature);
916}
917
918static void json_self_test_log(struct nvme_self_test_log *self_test, __u8 dst_entries,
919 __u32 size, const char *devname)
920{
921 struct json_object *valid_attrs;
922 struct json_object *r = json_r;
923 struct json_object *valid = json_create_array()json_object_new_array();
924 int i;
925 __u32 num_entries = min(dst_entries, NVME_LOG_ST_MAX_RESULTS)({ typeof(dst_entries) _a = (dst_entries); typeof(NVME_LOG_ST_MAX_RESULTS
) _b = (NVME_LOG_ST_MAX_RESULTS); do { } while (0); _a < _b
? _a : _b; })
;
926
927 obj_add_int(r, "Current Device Self-Test Operation", self_test->current_operation)json_object_object_add(r, "Current Device Self-Test Operation"
, json_object_new_int(self_test->current_operation))
;
928 obj_add_int(r, "Current Device Self-Test Completion", self_test->completion)json_object_object_add(r, "Current Device Self-Test Completion"
, json_object_new_int(self_test->completion))
;
929
930 for (i = 0; i < num_entries; i++) {
931 valid_attrs = json_create_object()json_object_new_object();
932 obj_add_int(valid_attrs, "Self test result", self_test->result[i].dsts & 0xf)json_object_object_add(valid_attrs, "Self test result", json_object_new_int
(self_test->result[i].dsts & 0xf))
;
933
934 if ((self_test->result[i].dsts & 0xf) == 0xf)
935 goto add;
936
937 obj_add_int(valid_attrs, "Self test code",json_object_object_add(valid_attrs, "Self test code", json_object_new_int
(self_test->result[i].dsts >> 4))
938 self_test->result[i].dsts >> 4)json_object_object_add(valid_attrs, "Self test code", json_object_new_int
(self_test->result[i].dsts >> 4))
;
939 obj_add_int(valid_attrs, "Segment number",json_object_object_add(valid_attrs, "Segment number", json_object_new_int
(self_test->result[i].seg))
940 self_test->result[i].seg)json_object_object_add(valid_attrs, "Segment number", json_object_new_int
(self_test->result[i].seg))
;
941 obj_add_int(valid_attrs, "Valid Diagnostic Information",json_object_object_add(valid_attrs, "Valid Diagnostic Information"
, json_object_new_int(self_test->result[i].vdi))
942 self_test->result[i].vdi)json_object_object_add(valid_attrs, "Valid Diagnostic Information"
, json_object_new_int(self_test->result[i].vdi))
;
943 obj_add_uint64(valid_attrs, "Power on hours",json_object_object_add(valid_attrs, "Power on hours", json_object_new_uint64
(le64_to_cpu(self_test->result[i].poh)))
944 le64_to_cpu(self_test->result[i].poh))json_object_object_add(valid_attrs, "Power on hours", json_object_new_uint64
(le64_to_cpu(self_test->result[i].poh)))
;
945
946 if (self_test->result[i].vdi & NVME_ST_VALID_DIAG_INFO_NSID)
947 obj_add_uint(valid_attrs, "Namespace Identifier",json_object_object_add(valid_attrs, "Namespace Identifier", json_object_new_uint64
(le32_to_cpu(self_test->result[i].nsid)))
948 le32_to_cpu(self_test->result[i].nsid))json_object_object_add(valid_attrs, "Namespace Identifier", json_object_new_uint64
(le32_to_cpu(self_test->result[i].nsid)))
;
949
950 if (self_test->result[i].vdi & NVME_ST_VALID_DIAG_INFO_FLBA)
951 obj_add_uint64(valid_attrs, "Failing LBA",json_object_object_add(valid_attrs, "Failing LBA", json_object_new_uint64
(le64_to_cpu(self_test->result[i].flba)))
952 le64_to_cpu(self_test->result[i].flba))json_object_object_add(valid_attrs, "Failing LBA", json_object_new_uint64
(le64_to_cpu(self_test->result[i].flba)))
;
953
954 if (self_test->result[i].vdi & NVME_ST_VALID_DIAG_INFO_SCT)
955 obj_add_int(valid_attrs, "Status Code Type", self_test->result[i].sct)json_object_object_add(valid_attrs, "Status Code Type", json_object_new_int
(self_test->result[i].sct))
;
956
957 if (self_test->result[i].vdi & NVME_ST_VALID_DIAG_INFO_SC)
958 obj_add_int(valid_attrs, "Status Code", self_test->result[i].sc)json_object_object_add(valid_attrs, "Status Code", json_object_new_int
(self_test->result[i].sc))
;
959
960 obj_add_int(valid_attrs, "Vendor Specific",json_object_object_add(valid_attrs, "Vendor Specific", json_object_new_int
(self_test->result[i].vs[1] << 8 | self_test->result
[i].vs[0]))
961 self_test->result[i].vs[1] << 8 | self_test->result[i].vs[0])json_object_object_add(valid_attrs, "Vendor Specific", json_object_new_int
(self_test->result[i].vs[1] << 8 | self_test->result
[i].vs[0]))
;
962
963add:
964 array_add_obj(valid, valid_attrs)json_object_array_add(valid, valid_attrs);
965 }
966
967 obj_add_array(r, "List of Valid Reports", valid)json_object_object_add(r, "List of Valid Reports", valid);
968}
969
970struct json_object *json_effects_log(enum nvme_csi csi,
971 struct nvme_cmd_effects_log *effects_log)
972{
973 struct json_object *r = json_create_object()json_object_new_object();
974 struct json_object *acs = json_create_object()json_object_new_object();
975 struct json_object *iocs = json_create_object()json_object_new_object();
976 unsigned int opcode;
977 char key[128];
978 __u32 effect;
979
980 obj_add_uint(r, "command_set_identifier", csi)json_object_object_add(r, "command_set_identifier", json_object_new_uint64
(csi))
;
981
982 for (opcode = 0; opcode < 256; opcode++) {
983 effect = le32_to_cpu(effects_log->acs[opcode]);
984 if (effect & NVME_CMD_EFFECTS_CSUPP) {
985 sprintf(key, "ACS_%u (%s)", opcode,
986 nvme_cmd_to_string(1, opcode));
987 obj_add_uint(acs, key, effect)json_object_object_add(acs, key, json_object_new_uint64(effect
))
;
988 }
989 }
990
991 obj_add_obj(r, "admin_cmd_set", acs)json_object_object_add(r, "admin_cmd_set", acs);
992
993 for (opcode = 0; opcode < 256; opcode++) {
994 effect = le32_to_cpu(effects_log->iocs[opcode]);
995 if (effect & NVME_CMD_EFFECTS_CSUPP) {
996 sprintf(key, "IOCS_%u (%s)", opcode,
997 nvme_cmd_to_string(0, opcode));
998 obj_add_uint(iocs, key, effect)json_object_object_add(iocs, key, json_object_new_uint64(effect
))
;
999 }
1000 }
1001
1002 obj_add_obj(r, "io_cmd_set", iocs)json_object_object_add(r, "io_cmd_set", iocs);
1003 return r;
1004}
1005
1006static void json_effects_log_list(struct list_head *list)
1007{
1008 struct json_object *r = json_create_array()json_object_new_array();
1009 nvme_effects_log_node_t *node = NULL((void*)0);
1010
1011 list_for_each(list, node, node)for ((node) = list_node_to_off_(((void)"../src/nvme-print-json.c"
":" "1011", (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)))))
)
{
1012 struct json_object *json_page =
1013 json_effects_log(node->csi, &node->effects);
1014 array_add_obj(r, json_page)json_object_array_add(r, json_page);
1015 }
1016
1017 json_print(r);
1018}
1019
1020static void json_sanitize_log(struct nvme_sanitize_log_page *sanitize_log,
1021 const char *devname)
1022{
1023 struct json_object *r = json_r;
1024 struct json_object *dev = json_create_object()json_object_new_object();
1025 struct json_object *sstat = json_create_object()json_object_new_object();
1026 struct json_object *ssi = json_create_object()json_object_new_object();
1027 const char *status_str;
1028 __u16 status, sos;
1029 __u8 fails, sans;
1030 char str[128];
1031
1032 status = le16_to_cpu(sanitize_log->sstat);
1033
1034 obj_add_int(dev, "sprog", le16_to_cpu(sanitize_log->sprog))json_object_object_add(dev, "sprog", json_object_new_int(le16_to_cpu
(sanitize_log->sprog)))
;
1035 obj_add_int(sstat, "media_verification_canceled", NVME_GET(status, SANITIZE_SSTAT_MVCNCLD))json_object_object_add(sstat, "media_verification_canceled", json_object_new_int
((((status) >> NVME_SANITIZE_SSTAT_MVCNCLD_SHIFT) &
NVME_SANITIZE_SSTAT_MVCNCLD_MASK)))
;
1036 obj_add_int(sstat, "global_erased", NVME_GET(status, SANITIZE_SSTAT_GLOBAL_DATA_ERASED))json_object_object_add(sstat, "global_erased", json_object_new_int
((((status) >> NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_SHIFT
) & NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_MASK)))
;
1037 obj_add_int(sstat, "no_cmplted_passes", NVME_GET(status, SANITIZE_SSTAT_COMPLETED_PASSES))json_object_object_add(sstat, "no_cmplted_passes", json_object_new_int
((((status) >> NVME_SANITIZE_SSTAT_COMPLETED_PASSES_SHIFT
) & NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK)))
;
1038 obj_add_int(sstat, "purged", NVME_GET(status, SANITIZE_SSTAT_PRGD))json_object_object_add(sstat, "purged", json_object_new_int((
((status) >> NVME_SANITIZE_SSTAT_PRGD_SHIFT) & NVME_SANITIZE_SSTAT_PRGD_MASK
)))
;
1039
1040 sos = NVME_GET(status, SANITIZE_SSTAT_STATUS)(((status) >> NVME_SANITIZE_SSTAT_STATUS_SHIFT) & NVME_SANITIZE_SSTAT_STATUS_MASK
)
;
1041 status_str = nvme_sstat_status_to_string(status);
1042 sprintf(str, "(%d) %s", sos, status_str);
1043 obj_add_strjson_object_add_value_string(sstat, "status", str);
1044
1045 obj_add_obj(dev, "sstat", sstat)json_object_object_add(dev, "sstat", sstat);
1046 obj_add_uint(dev, "cdw10_info", le32_to_cpu(sanitize_log->scdw10))json_object_object_add(dev, "cdw10_info", json_object_new_uint64
(le32_to_cpu(sanitize_log->scdw10)))
;
1047 obj_add_uint(dev, "time_over_write", le32_to_cpu(sanitize_log->eto))json_object_object_add(dev, "time_over_write", json_object_new_uint64
(le32_to_cpu(sanitize_log->eto)))
;
1048 obj_add_uint(dev, "time_block_erase", le32_to_cpu(sanitize_log->etbe))json_object_object_add(dev, "time_block_erase", json_object_new_uint64
(le32_to_cpu(sanitize_log->etbe)))
;
1049 obj_add_uint(dev, "time_crypto_erase", le32_to_cpu(sanitize_log->etce))json_object_object_add(dev, "time_crypto_erase", json_object_new_uint64
(le32_to_cpu(sanitize_log->etce)))
;
1050 obj_add_uint(dev, "time_over_write_no_dealloc", le32_to_cpu(sanitize_log->etond))json_object_object_add(dev, "time_over_write_no_dealloc", json_object_new_uint64
(le32_to_cpu(sanitize_log->etond)))
;
1051 obj_add_uint(dev, "time_block_erase_no_dealloc", le32_to_cpu(sanitize_log->etbend))json_object_object_add(dev, "time_block_erase_no_dealloc", json_object_new_uint64
(le32_to_cpu(sanitize_log->etbend)))
;
1052 obj_add_uint(dev, "time_crypto_erase_no_dealloc", le32_to_cpu(sanitize_log->etcend))json_object_object_add(dev, "time_crypto_erase_no_dealloc", json_object_new_uint64
(le32_to_cpu(sanitize_log->etcend)))
;
1053 obj_add_uint(dev, "time_post_verification_dealloc", le32_to_cpu(sanitize_log->etpvds))json_object_object_add(dev, "time_post_verification_dealloc",
json_object_new_uint64(le32_to_cpu(sanitize_log->etpvds))
)
;
1054
1055 sans = NVME_GET(sanitize_log->ssi, SANITIZE_SSI_SANS)(((sanitize_log->ssi) >> NVME_SANITIZE_SSI_SANS_SHIFT
) & NVME_SANITIZE_SSI_SANS_MASK)
;
1056 status_str = nvme_ssi_state_to_string(sans);
1057 sprintf(str, "(%d) %s", sans, status_str);
1058 obj_add_strjson_object_add_value_string(ssi, "sanitize_state", str);
1059
1060 if (sos == NVME_SANITIZE_SSTAT_STATUS_COMPLETED_FAILED) {
1061 fails = NVME_GET(sanitize_log->ssi, SANITIZE_SSI_FAILS)(((sanitize_log->ssi) >> NVME_SANITIZE_SSI_FAILS_SHIFT
) & NVME_SANITIZE_SSI_FAILS_MASK)
;
1062 status_str = nvme_ssi_state_to_string(fails);
1063 sprintf(str, "(%d) %s", fails, status_str);
1064 obj_add_strjson_object_add_value_string(ssi, "failure_state", str);
1065 }
1066
1067 obj_add_obj(dev, "sanitize_state_information", ssi)json_object_object_add(dev, "sanitize_state_information", ssi
)
;
1068 obj_add_obj(r, devname, dev)json_object_object_add(r, devname, dev);
1069}
1070
1071static void json_predictable_latency_per_nvmset(
1072 struct nvme_nvmset_predictable_lat_log *plpns_log,
1073 __u16 nvmset_id, const char *devname)
1074{
1075 struct json_object *r = json_r;
1076
1077 obj_add_uint(r, "nvmset_id", le16_to_cpu(nvmset_id))json_object_object_add(r, "nvmset_id", json_object_new_uint64
(le16_to_cpu(nvmset_id)))
;
1078 obj_add_uint(r, "status", plpns_log->status)json_object_object_add(r, "status", json_object_new_uint64(plpns_log
->status))
;
1079 obj_add_uint(r, "event_type", le16_to_cpu(plpns_log->event_type))json_object_object_add(r, "event_type", json_object_new_uint64
(le16_to_cpu(plpns_log->event_type)))
;
1080 obj_add_uint64(r, "dtwin_reads_typical", le64_to_cpu(plpns_log->dtwin_rt))json_object_object_add(r, "dtwin_reads_typical", json_object_new_uint64
(le64_to_cpu(plpns_log->dtwin_rt)))
;
1081 obj_add_uint64(r, "dtwin_writes_typical", le64_to_cpu(plpns_log->dtwin_wt))json_object_object_add(r, "dtwin_writes_typical", json_object_new_uint64
(le64_to_cpu(plpns_log->dtwin_wt)))
;
1082 obj_add_uint64(r, "dtwin_time_maximum", le64_to_cpu(plpns_log->dtwin_tmax))json_object_object_add(r, "dtwin_time_maximum", json_object_new_uint64
(le64_to_cpu(plpns_log->dtwin_tmax)))
;
1083 obj_add_uint64(r, "ndwin_time_minimum_high", le64_to_cpu(plpns_log->ndwin_tmin_hi))json_object_object_add(r, "ndwin_time_minimum_high", json_object_new_uint64
(le64_to_cpu(plpns_log->ndwin_tmin_hi)))
;
1084 obj_add_uint64(r, "ndwin_time_minimum_low", le64_to_cpu(plpns_log->ndwin_tmin_lo))json_object_object_add(r, "ndwin_time_minimum_low", json_object_new_uint64
(le64_to_cpu(plpns_log->ndwin_tmin_lo)))
;
1085 obj_add_uint64(r, "dtwin_reads_estimate", le64_to_cpu(plpns_log->dtwin_re))json_object_object_add(r, "dtwin_reads_estimate", json_object_new_uint64
(le64_to_cpu(plpns_log->dtwin_re)))
;
1086 obj_add_uint64(r, "dtwin_writes_estimate", le64_to_cpu(plpns_log->dtwin_we))json_object_object_add(r, "dtwin_writes_estimate", json_object_new_uint64
(le64_to_cpu(plpns_log->dtwin_we)))
;
1087 obj_add_uint64(r, "dtwin_time_estimate", le64_to_cpu(plpns_log->dtwin_te))json_object_object_add(r, "dtwin_time_estimate", json_object_new_uint64
(le64_to_cpu(plpns_log->dtwin_te)))
;
1088}
1089
1090static void json_predictable_latency_event_agg_log(
1091 struct nvme_aggregate_predictable_lat_event *pea_log,
1092 __u64 log_entries, __u32 size, const char *devname)
1093{
1094 struct json_object *r = json_r;
1095 struct json_object *valid_attrs;
1096 struct json_object *valid = json_create_array()json_object_new_array();
1097 __u64 num_entries = le64_to_cpu(pea_log->num_entries);
1098 __u64 num_iter = min(num_entries, log_entries)({ typeof(num_entries) _a = (num_entries); typeof(log_entries
) _b = (log_entries); do { } while (0); _a < _b ? _a : _b;
})
;
1099
1100 obj_add_uint64(r, "num_entries_avail", num_entries)json_object_object_add(r, "num_entries_avail", json_object_new_uint64
(num_entries))
;
1101
1102 for (int i = 0; i < num_iter; i++) {
1103 valid_attrs = json_create_object()json_object_new_object();
1104 obj_add_uint(valid_attrs, "entry", le16_to_cpu(pea_log->entries[i]))json_object_object_add(valid_attrs, "entry", json_object_new_uint64
(le16_to_cpu(pea_log->entries[i])))
;
1105 array_add_obj(valid, valid_attrs)json_object_array_add(valid, valid_attrs);
1106 }
1107
1108 obj_add_array(r, "list_of_entries", valid)json_object_object_add(r, "list_of_entries", valid);
1109}
1110
1111static void json_add_bitmap(int i, __u8 seb, struct json_object *r)
1112{
1113 char evt_str[50];
1114 char key[128];
1115
1116 for (int bit = 0; bit < CHAR_BIT8; bit++) {
1117 if (!((seb >> bit) & 0x1))
1118 continue;
1119 sprintf(key, "bitmap_%x", (bit + i * CHAR_BIT8));
1120 snprintf(evt_str, sizeof(evt_str), "Support %s",
1121 nvme_pel_event_to_string(bit + i * CHAR_BIT8));
1122 obj_add_strjson_object_add_value_string(r, key, evt_str);
1123 }
1124}
1125
1126void nvme_json_pevent_log_head(struct nvme_persistent_event_log *pevent_log_head,
1127 struct json_object *r)
1128{
1129 int i;
1130 char sn[sizeof(pevent_log_head->sn) + 1];
1131 char mn[sizeof(pevent_log_head->mn) + 1];
1132 char subnqn[sizeof(pevent_log_head->subnqn) + 1];
1133
1134 snprintf(sn, sizeof(sn), "%-.*s", (int)sizeof(pevent_log_head->sn), pevent_log_head->sn);
1135 snprintf(mn, sizeof(mn), "%-.*s", (int)sizeof(pevent_log_head->mn), pevent_log_head->mn);
1136 snprintf(subnqn, sizeof(subnqn), "%-.*s", (int)sizeof(pevent_log_head->subnqn),
1137 pevent_log_head->subnqn);
1138
1139 obj_add_uint(r, "log_id", pevent_log_head->lid)json_object_object_add(r, "log_id", json_object_new_uint64(pevent_log_head
->lid))
;
1140 obj_add_uint(r, "total_num_of_events", le32_to_cpu(pevent_log_head->tnev))json_object_object_add(r, "total_num_of_events", json_object_new_uint64
(le32_to_cpu(pevent_log_head->tnev)))
;
1141 obj_add_uint64(r, "total_log_len", le64_to_cpu(pevent_log_head->tll))json_object_object_add(r, "total_log_len", json_object_new_uint64
(le64_to_cpu(pevent_log_head->tll)))
;
1142 obj_add_uint(r, "log_revision", pevent_log_head->rv)json_object_object_add(r, "log_revision", json_object_new_uint64
(pevent_log_head->rv))
;
1143 obj_add_uint(r, "log_header_len", le16_to_cpu(pevent_log_head->lhl))json_object_object_add(r, "log_header_len", json_object_new_uint64
(le16_to_cpu(pevent_log_head->lhl)))
;
1144 obj_add_uint64(r, "timestamp", le64_to_cpu(pevent_log_head->ts))json_object_object_add(r, "timestamp", json_object_new_uint64
(le64_to_cpu(pevent_log_head->ts)))
;
1145 obj_add_uint128(r, "power_on_hours", le128_to_cpu(pevent_log_head->poh))json_object_object_add(r, "power_on_hours", util_json_object_new_uint128
(le128_to_cpu(pevent_log_head->poh)))
;
1146 obj_add_uint64(r, "power_cycle_count", le64_to_cpu(pevent_log_head->pcc))json_object_object_add(r, "power_cycle_count", json_object_new_uint64
(le64_to_cpu(pevent_log_head->pcc)))
;
1147 obj_add_uint(r, "pci_vid", le16_to_cpu(pevent_log_head->vid))json_object_object_add(r, "pci_vid", json_object_new_uint64(le16_to_cpu
(pevent_log_head->vid)))
;
1148 obj_add_uint(r, "pci_ssvid", le16_to_cpu(pevent_log_head->ssvid))json_object_object_add(r, "pci_ssvid", json_object_new_uint64
(le16_to_cpu(pevent_log_head->ssvid)))
;
1149 obj_add_strjson_object_add_value_string(r, "sn", sn);
1150 obj_add_strjson_object_add_value_string(r, "mn", mn);
1151 obj_add_strjson_object_add_value_string(r, "subnqn", subnqn);
1152 obj_add_uint(r, "gen_number", le16_to_cpu(pevent_log_head->gen_number))json_object_object_add(r, "gen_number", json_object_new_uint64
(le16_to_cpu(pevent_log_head->gen_number)))
;
1153 obj_add_uint(r, "rci", le32_to_cpu(pevent_log_head->rci))json_object_object_add(r, "rci", json_object_new_uint64(le32_to_cpu
(pevent_log_head->rci)))
;
1154
1155 for (i = 0; i < ARRAY_SIZE(pevent_log_head->seb)(sizeof(pevent_log_head->seb) / sizeof((pevent_log_head->
seb)[0]) + 0)
; i++) {
1156 if (!pevent_log_head->seb[i])
1157 continue;
1158 json_add_bitmap(i, pevent_log_head->seb[i], r);
1159 }
1160}
1161
1162void nvme_json_pel_smart_health(void *pevent_log_info, __u32 offset,
1163 struct json_object *valid_attrs)
1164{
1165 char key[128];
1166 struct nvme_smart_log *smart_event = pevent_log_info + offset;
1167 unsigned int temperature = (smart_event->temperature[1] << 8) | smart_event->temperature[0];
1168 shr_uint128_t data_units_read = le128_to_cpu(smart_event->data_units_read);
1169 shr_uint128_t data_units_written = le128_to_cpu(smart_event->data_units_written);
1170 shr_uint128_t host_read_commands = le128_to_cpu(smart_event->host_reads);
1171 shr_uint128_t host_write_commands = le128_to_cpu(smart_event->host_writes);
1172 shr_uint128_t controller_busy_time = le128_to_cpu(smart_event->ctrl_busy_time);
1173 shr_uint128_t power_cycles = le128_to_cpu(smart_event->power_cycles);
1174 shr_uint128_t power_on_hours = le128_to_cpu(smart_event->power_on_hours);
1175 shr_uint128_t unsafe_shutdowns = le128_to_cpu(smart_event->unsafe_shutdowns);
1176 shr_uint128_t media_errors = le128_to_cpu(smart_event->media_errors);
1177 shr_uint128_t num_err_log_entries = le128_to_cpu(smart_event->num_err_log_entries);
1178 int c;
1179 __s32 temp;
1180
1181 obj_add_int(valid_attrs, "critical_warning", smart_event->critical_warning)json_object_object_add(valid_attrs, "critical_warning", json_object_new_int
(smart_event->critical_warning))
;
1182 obj_add_int(valid_attrs, "temperature", temperature)json_object_object_add(valid_attrs, "temperature", json_object_new_int
(temperature))
;
1183 obj_add_int(valid_attrs, "avail_spare", smart_event->avail_spare)json_object_object_add(valid_attrs, "avail_spare", json_object_new_int
(smart_event->avail_spare))
;
1184 obj_add_int(valid_attrs, "spare_thresh", smart_event->spare_thresh)json_object_object_add(valid_attrs, "spare_thresh", json_object_new_int
(smart_event->spare_thresh))
;
1185 obj_add_int(valid_attrs, "percent_used", smart_event->percent_used)json_object_object_add(valid_attrs, "percent_used", json_object_new_int
(smart_event->percent_used))
;
1186 obj_add_int(valid_attrs, "endurance_grp_critical_warning_summary",json_object_object_add(valid_attrs, "endurance_grp_critical_warning_summary"
, json_object_new_int(smart_event->endu_grp_crit_warn_sumry
))
1187 smart_event->endu_grp_crit_warn_sumry)json_object_object_add(valid_attrs, "endurance_grp_critical_warning_summary"
, json_object_new_int(smart_event->endu_grp_crit_warn_sumry
))
;
1188 obj_add_uint128(valid_attrs, "data_units_read", data_units_read)json_object_object_add(valid_attrs, "data_units_read", util_json_object_new_uint128
(data_units_read))
;
1189 obj_add_uint128(valid_attrs, "data_units_written", data_units_written)json_object_object_add(valid_attrs, "data_units_written", util_json_object_new_uint128
(data_units_written))
;
1190 obj_add_uint128(valid_attrs, "host_read_commands", host_read_commands)json_object_object_add(valid_attrs, "host_read_commands", util_json_object_new_uint128
(host_read_commands))
;
1191 obj_add_uint128(valid_attrs, "host_write_commands", host_write_commands)json_object_object_add(valid_attrs, "host_write_commands", util_json_object_new_uint128
(host_write_commands))
;
1192 obj_add_uint128(valid_attrs, "controller_busy_time", controller_busy_time)json_object_object_add(valid_attrs, "controller_busy_time", util_json_object_new_uint128
(controller_busy_time))
;
1193 obj_add_uint128(valid_attrs, "power_cycles", power_cycles)json_object_object_add(valid_attrs, "power_cycles", util_json_object_new_uint128
(power_cycles))
;
1194 obj_add_uint128(valid_attrs, "power_on_hours", power_on_hours)json_object_object_add(valid_attrs, "power_on_hours", util_json_object_new_uint128
(power_on_hours))
;
1195 obj_add_uint128(valid_attrs, "unsafe_shutdowns", unsafe_shutdowns)json_object_object_add(valid_attrs, "unsafe_shutdowns", util_json_object_new_uint128
(unsafe_shutdowns))
;
1196 obj_add_uint128(valid_attrs, "media_errors", media_errors)json_object_object_add(valid_attrs, "media_errors", util_json_object_new_uint128
(media_errors))
;
1197 obj_add_uint128(valid_attrs, "num_err_log_entries", num_err_log_entries)json_object_object_add(valid_attrs, "num_err_log_entries", util_json_object_new_uint128
(num_err_log_entries))
;
1198 obj_add_uint(valid_attrs, "warning_temp_time", le32_to_cpu(smart_event->warning_temp_time))json_object_object_add(valid_attrs, "warning_temp_time", json_object_new_uint64
(le32_to_cpu(smart_event->warning_temp_time)))
;
1199 obj_add_uint(valid_attrs, "critical_comp_time",json_object_object_add(valid_attrs, "critical_comp_time", json_object_new_uint64
(le32_to_cpu(smart_event->critical_comp_time)))
1200 le32_to_cpu(smart_event->critical_comp_time))json_object_object_add(valid_attrs, "critical_comp_time", json_object_new_uint64
(le32_to_cpu(smart_event->critical_comp_time)))
;
1201
1202 for (c = 0; c < 8; c++) {
1203 temp = le16_to_cpu(smart_event->temp_sensor[c]);
1204 if (!temp)
1205 continue;
1206 sprintf(key, "temperature_sensor_%d", c + 1);
1207 obj_add_int(valid_attrs, key, temp)json_object_object_add(valid_attrs, key, json_object_new_int(
temp))
;
1208 }
1209
1210 obj_add_uint(valid_attrs, "thm_temp1_trans_count",json_object_object_add(valid_attrs, "thm_temp1_trans_count", json_object_new_uint64
(le32_to_cpu(smart_event->thm_temp1_trans_count)))
1211 le32_to_cpu(smart_event->thm_temp1_trans_count))json_object_object_add(valid_attrs, "thm_temp1_trans_count", json_object_new_uint64
(le32_to_cpu(smart_event->thm_temp1_trans_count)))
;
1212 obj_add_uint(valid_attrs, "thm_temp2_trans_count",json_object_object_add(valid_attrs, "thm_temp2_trans_count", json_object_new_uint64
(le32_to_cpu(smart_event->thm_temp2_trans_count)))
1213 le32_to_cpu(smart_event->thm_temp2_trans_count))json_object_object_add(valid_attrs, "thm_temp2_trans_count", json_object_new_uint64
(le32_to_cpu(smart_event->thm_temp2_trans_count)))
;
1214 obj_add_uint(valid_attrs, "thm_temp1_total_time",json_object_object_add(valid_attrs, "thm_temp1_total_time", json_object_new_uint64
(le32_to_cpu(smart_event->thm_temp1_total_time)))
1215 le32_to_cpu(smart_event->thm_temp1_total_time))json_object_object_add(valid_attrs, "thm_temp1_total_time", json_object_new_uint64
(le32_to_cpu(smart_event->thm_temp1_total_time)))
;
1216 obj_add_uint(valid_attrs, "thm_temp2_total_time",json_object_object_add(valid_attrs, "thm_temp2_total_time", json_object_new_uint64
(le32_to_cpu(smart_event->thm_temp2_total_time)))
1217 le32_to_cpu(smart_event->thm_temp2_total_time))json_object_object_add(valid_attrs, "thm_temp2_total_time", json_object_new_uint64
(le32_to_cpu(smart_event->thm_temp2_total_time)))
;
1218}
1219
1220void nvme_json_pel_fw_commit(void *pevent_log_info, __u32 offset,
1221 struct json_object *valid_attrs)
1222{
1223 char fw_str[50];
1224 struct nvme_fw_commit_event *fw_commit_event = pevent_log_info + offset;
1225
1226 snprintf(fw_str, sizeof(fw_str), "%"PRIu64"l" "u"" (%s)", le64_to_cpu(fw_commit_event->old_fw_rev),
1227 shr_fw_to_string((char *)&fw_commit_event->old_fw_rev));
1228 obj_add_strjson_object_add_value_string(valid_attrs, "old_fw_rev", fw_str);
1229 snprintf(fw_str, sizeof(fw_str), "%"PRIu64"l" "u"" (%s)", le64_to_cpu(fw_commit_event->new_fw_rev),
1230 shr_fw_to_string((char *)&fw_commit_event->new_fw_rev));
1231 obj_add_strjson_object_add_value_string(valid_attrs, "new_fw_rev", fw_str);
1232 obj_add_uint(valid_attrs, "fw_commit_action", fw_commit_event->fw_commit_action)json_object_object_add(valid_attrs, "fw_commit_action", json_object_new_uint64
(fw_commit_event->fw_commit_action))
;
1233 obj_add_uint(valid_attrs, "fw_slot", fw_commit_event->fw_slot)json_object_object_add(valid_attrs, "fw_slot", json_object_new_uint64
(fw_commit_event->fw_slot))
;
1234 obj_add_uint(valid_attrs, "sct_fw", fw_commit_event->sct_fw)json_object_object_add(valid_attrs, "sct_fw", json_object_new_uint64
(fw_commit_event->sct_fw))
;
1235 obj_add_uint(valid_attrs, "sc_fw", fw_commit_event->sc_fw)json_object_object_add(valid_attrs, "sc_fw", json_object_new_uint64
(fw_commit_event->sc_fw))
;
1236 obj_add_uint(valid_attrs, "vu_assign_fw_commit_rc",json_object_object_add(valid_attrs, "vu_assign_fw_commit_rc",
json_object_new_uint64(le16_to_cpu(fw_commit_event->vndr_assign_fw_commit_rc
)))
1237 le16_to_cpu(fw_commit_event->vndr_assign_fw_commit_rc))json_object_object_add(valid_attrs, "vu_assign_fw_commit_rc",
json_object_new_uint64(le16_to_cpu(fw_commit_event->vndr_assign_fw_commit_rc
)))
;
1238}
1239
1240void nvme_json_pel_timestamp(void *pevent_log_info, __u32 offset,
1241 struct json_object *valid_attrs)
1242{
1243 struct nvme_time_stamp_change_event *ts_change_event = pevent_log_info + offset;
1244
1245 obj_add_uint64(valid_attrs, "prev_ts", le64_to_cpu(ts_change_event->previous_timestamp))json_object_object_add(valid_attrs, "prev_ts", json_object_new_uint64
(le64_to_cpu(ts_change_event->previous_timestamp)))
;
1246 obj_add_uint64(valid_attrs, "ml_secs_since_reset",json_object_object_add(valid_attrs, "ml_secs_since_reset", json_object_new_uint64
(le64_to_cpu(ts_change_event->ml_secs_since_reset)))
1247 le64_to_cpu(ts_change_event->ml_secs_since_reset))json_object_object_add(valid_attrs, "ml_secs_since_reset", json_object_new_uint64
(le64_to_cpu(ts_change_event->ml_secs_since_reset)))
;
1248}
1249
1250void nvme_json_pel_power_on_reset(void *pevent_log_info, __u32 offset,
1251 struct json_object *valid_attrs,
1252 __le16 vsil, __le16 el,
1253 __u32 size)
1254{
1255 __u64 *fw_rev;
1256 char fw_str[50];
1257 struct nvme_power_on_reset_info_list *por_event;
1258 __u32 ev_len = le16_to_cpu(el);
1259 __u32 vlen = le16_to_cpu(vsil);
1260 __u32 por_info_len, por_info_list;
1261 int i;
1262
1263 if (ev_len < vlen + sizeof(*fw_rev) ||
1264 offset > size - sizeof(*fw_rev))
1265 return;
1266
1267 por_info_len = ev_len - vlen - sizeof(*fw_rev);
1268 por_info_list = por_info_len / sizeof(*por_event);
1269
1270 fw_rev = pevent_log_info + offset;
1271 snprintf(fw_str, sizeof(fw_str), "%"PRIu64"l" "u"" (%s)", le64_to_cpu(*fw_rev),
1272 shr_fw_to_string((char *)fw_rev));
1273 obj_add_strjson_object_add_value_string(valid_attrs, "fw_rev", fw_str);
1274
1275 for (i = 0; i < por_info_list; i++) {
1276 __u32 poff = offset + sizeof(*fw_rev) +
1277 i * sizeof(*por_event);
1278
1279 if (poff > size - sizeof(*por_event))
1280 break;
1281 por_event = pevent_log_info + poff;
1282 obj_add_uint(valid_attrs, "ctrl_id", le16_to_cpu(por_event->cid))json_object_object_add(valid_attrs, "ctrl_id", json_object_new_uint64
(le16_to_cpu(por_event->cid)))
;
1283 obj_add_uint(valid_attrs, "fw_act", por_event->fw_act)json_object_object_add(valid_attrs, "fw_act", json_object_new_uint64
(por_event->fw_act))
;
1284 obj_add_uint(valid_attrs, "op_in_prog", por_event->op_in_prog)json_object_object_add(valid_attrs, "op_in_prog", json_object_new_uint64
(por_event->op_in_prog))
;
1285 obj_add_uint(valid_attrs, "ctrl_power_cycle",json_object_object_add(valid_attrs, "ctrl_power_cycle", json_object_new_uint64
(le32_to_cpu(por_event->ctrl_power_cycle)))
1286 le32_to_cpu(por_event->ctrl_power_cycle))json_object_object_add(valid_attrs, "ctrl_power_cycle", json_object_new_uint64
(le32_to_cpu(por_event->ctrl_power_cycle)))
;
1287 obj_add_uint64(valid_attrs, "power_on_ml_secs",json_object_object_add(valid_attrs, "power_on_ml_secs", json_object_new_uint64
(le64_to_cpu(por_event->power_on_ml_seconds)))
1288 le64_to_cpu(por_event->power_on_ml_seconds))json_object_object_add(valid_attrs, "power_on_ml_secs", json_object_new_uint64
(le64_to_cpu(por_event->power_on_ml_seconds)))
;
1289 obj_add_uint64(valid_attrs, "ctrl_time_stamp",json_object_object_add(valid_attrs, "ctrl_time_stamp", json_object_new_uint64
(le64_to_cpu(por_event->ctrl_time_stamp)))
1290 le64_to_cpu(por_event->ctrl_time_stamp))json_object_object_add(valid_attrs, "ctrl_time_stamp", json_object_new_uint64
(le64_to_cpu(por_event->ctrl_time_stamp)))
;
1291 }
1292}
1293
1294void nvme_json_pel_nss_hw_error(void *pevent_log_info, __u32 offset,
1295 struct json_object *valid_attrs)
1296{
1297 struct nvme_nss_hw_err_event *nss_hw_err_event = pevent_log_info + offset;
1298
1299 obj_add_uint(valid_attrs, "nss_hw_err_code",json_object_object_add(valid_attrs, "nss_hw_err_code", json_object_new_uint64
(le16_to_cpu(nss_hw_err_event->nss_hw_err_event_code)))
1300 le16_to_cpu(nss_hw_err_event->nss_hw_err_event_code))json_object_object_add(valid_attrs, "nss_hw_err_code", json_object_new_uint64
(le16_to_cpu(nss_hw_err_event->nss_hw_err_event_code)))
;
1301}
1302
1303void nvme_json_pel_change_ns(void *pevent_log_info, __u32 offset,
1304 struct json_object *valid_attrs)
1305{
1306 struct nvme_change_ns_event *ns_event = pevent_log_info + offset;
1307
1308 obj_add_uint(valid_attrs, "nsmgt_cdw10", le32_to_cpu(ns_event->nsmgt_cdw10))json_object_object_add(valid_attrs, "nsmgt_cdw10", json_object_new_uint64
(le32_to_cpu(ns_event->nsmgt_cdw10)))
;
1309 obj_add_uint64(valid_attrs, "nsze", le64_to_cpu(ns_event->nsze))json_object_object_add(valid_attrs, "nsze", json_object_new_uint64
(le64_to_cpu(ns_event->nsze)))
;
1310 obj_add_uint64(valid_attrs, "nscap", le64_to_cpu(ns_event->nscap))json_object_object_add(valid_attrs, "nscap", json_object_new_uint64
(le64_to_cpu(ns_event->nscap)))
;
1311 obj_add_uint(valid_attrs, "flbas", ns_event->flbas)json_object_object_add(valid_attrs, "flbas", json_object_new_uint64
(ns_event->flbas))
;
1312 obj_add_uint(valid_attrs, "dps", ns_event->dps)json_object_object_add(valid_attrs, "dps", json_object_new_uint64
(ns_event->dps))
;
1313 obj_add_uint(valid_attrs, "nmic", ns_event->nmic)json_object_object_add(valid_attrs, "nmic", json_object_new_uint64
(ns_event->nmic))
;
1314 obj_add_uint(valid_attrs, "ana_grp_id", le32_to_cpu(ns_event->ana_grp_id))json_object_object_add(valid_attrs, "ana_grp_id", json_object_new_uint64
(le32_to_cpu(ns_event->ana_grp_id)))
;
1315 obj_add_uint(valid_attrs, "nvmset_id", le16_to_cpu(ns_event->nvmset_id))json_object_object_add(valid_attrs, "nvmset_id", json_object_new_uint64
(le16_to_cpu(ns_event->nvmset_id)))
;
1316 obj_add_uint(valid_attrs, "nsid", le32_to_cpu(ns_event->nsid))json_object_object_add(valid_attrs, "nsid", json_object_new_uint64
(le32_to_cpu(ns_event->nsid)))
;
1317}
1318
1319void nvme_json_pel_format_start(void *pevent_log_info, __u32 offset,
1320 struct json_object *valid_attrs)
1321{
1322 struct nvme_format_nvm_start_event *format_start_event = pevent_log_info + offset;
1323
1324 obj_add_uint(valid_attrs, "nsid", le32_to_cpu(format_start_event->nsid))json_object_object_add(valid_attrs, "nsid", json_object_new_uint64
(le32_to_cpu(format_start_event->nsid)))
;
1325 obj_add_uint(valid_attrs, "fna", format_start_event->fna)json_object_object_add(valid_attrs, "fna", json_object_new_uint64
(format_start_event->fna))
;
1326 obj_add_uint(valid_attrs, "format_nvm_cdw10",json_object_object_add(valid_attrs, "format_nvm_cdw10", json_object_new_uint64
(le32_to_cpu(format_start_event->format_nvm_cdw10)))
1327 le32_to_cpu(format_start_event->format_nvm_cdw10))json_object_object_add(valid_attrs, "format_nvm_cdw10", json_object_new_uint64
(le32_to_cpu(format_start_event->format_nvm_cdw10)))
;
1328}
1329
1330void nvme_json_pel_format_completion(void *pevent_log_info, __u32 offset,
1331 struct json_object *valid_attrs)
1332{
1333 struct nvme_format_nvm_compln_event *format_cmpln_event = pevent_log_info + offset;
1334
1335 obj_add_uint(valid_attrs, "nsid", le32_to_cpu(format_cmpln_event->nsid))json_object_object_add(valid_attrs, "nsid", json_object_new_uint64
(le32_to_cpu(format_cmpln_event->nsid)))
;
1336 obj_add_uint(valid_attrs, "smallest_fpi", format_cmpln_event->smallest_fpi)json_object_object_add(valid_attrs, "smallest_fpi", json_object_new_uint64
(format_cmpln_event->smallest_fpi))
;
1337 obj_add_uint(valid_attrs, "format_nvm_status", format_cmpln_event->format_nvm_status)json_object_object_add(valid_attrs, "format_nvm_status", json_object_new_uint64
(format_cmpln_event->format_nvm_status))
;
1338 obj_add_uint(valid_attrs, "compln_info", le16_to_cpu(format_cmpln_event->compln_info))json_object_object_add(valid_attrs, "compln_info", json_object_new_uint64
(le16_to_cpu(format_cmpln_event->compln_info)))
;
1339 obj_add_uint(valid_attrs, "status_field", le32_to_cpu(format_cmpln_event->status_field))json_object_object_add(valid_attrs, "status_field", json_object_new_uint64
(le32_to_cpu(format_cmpln_event->status_field)))
;
1340}
1341void nvme_json_pel_sanitize_start(void *pevent_log_info, __u32 offset,
1342 struct json_object *valid_attrs)
1343{
1344 struct nvme_sanitize_start_event *sanitize_start_event = pevent_log_info + offset;
1345
1346 obj_add_uint(valid_attrs, "SANICAP", le32_to_cpu(sanitize_start_event->sani_cap))json_object_object_add(valid_attrs, "SANICAP", json_object_new_uint64
(le32_to_cpu(sanitize_start_event->sani_cap)))
;
1347 obj_add_uint(valid_attrs, "sani_cdw10", le32_to_cpu(sanitize_start_event->sani_cdw10))json_object_object_add(valid_attrs, "sani_cdw10", json_object_new_uint64
(le32_to_cpu(sanitize_start_event->sani_cdw10)))
;
1348 obj_add_uint(valid_attrs, "sani_cdw11", le32_to_cpu(sanitize_start_event->sani_cdw11))json_object_object_add(valid_attrs, "sani_cdw11", json_object_new_uint64
(le32_to_cpu(sanitize_start_event->sani_cdw11)))
;
1349}
1350
1351void nvme_json_pel_sanitize_completion(void *pevent_log_info, __u32 offset,
1352 struct json_object *valid_attrs)
1353{
1354 struct nvme_sanitize_compln_event *sanitize_cmpln_event = pevent_log_info + offset;
1355
1356 obj_add_uint(valid_attrs, "sani_prog", le16_to_cpu(sanitize_cmpln_event->sani_prog))json_object_object_add(valid_attrs, "sani_prog", json_object_new_uint64
(le16_to_cpu(sanitize_cmpln_event->sani_prog)))
;
1357 obj_add_uint(valid_attrs, "sani_status", le16_to_cpu(sanitize_cmpln_event->sani_status))json_object_object_add(valid_attrs, "sani_status", json_object_new_uint64
(le16_to_cpu(sanitize_cmpln_event->sani_status)))
;
1358 obj_add_uint(valid_attrs, "cmpln_info", le16_to_cpu(sanitize_cmpln_event->cmpln_info))json_object_object_add(valid_attrs, "cmpln_info", json_object_new_uint64
(le16_to_cpu(sanitize_cmpln_event->cmpln_info)))
;
1359}
1360
1361void nvme_json_pel_set_feature(void *data, __u32 len,
1362 struct json_object *valid_attrs)
1363{
1364 struct nvme_set_feature_event *set_feat_event = data;
1365 int 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)
;
1366 int cdw11 = le32_to_cpu(set_feat_event->cdw_mem[1]);
1367 __cleanup_free__attribute__((cleanup(shr_freep))) unsigned char *mem_buf = NULL((void*)0);
1368
1369 obj_add_uint_02xjson_object_add_uint_02x(valid_attrs, "feature", fid);
1370 obj_add_strjson_object_add_value_string(valid_attrs, "name", nvme_feature_to_string(fid));
1371 obj_add_uint_0nxjson_object_add_uint_0nx(valid_attrs, "value", cdw11, 8);
1372
1373 mem_buf = nvme_pel_set_feature_data(data, len);
1374 if (mem_buf)
1375 json_feature_show_fields(fid, cdw11, mem_buf);
1376}
1377
1378void nvme_json_pel_telemetry_crt(void *pevent_log_info, __u32 offset,
1379 struct json_object *valid_attrs,
1380 __le16 el, __u32 size)
1381{
1382 if (le16_to_cpu(el) < 512 || offset > size - 512)
1383 return;
1384 obj_d(valid_attrs, "create", pevent_log_info + offset, 512, 16, 1);
1385}
1386
1387void nvme_json_pel_thermal_excursion(void *pevent_log_info, __u32 offset,
1388 struct json_object *valid_attrs)
1389{
1390 struct nvme_thermal_exc_event *thermal_exc_event = pevent_log_info + offset;
1391
1392 obj_add_uint(valid_attrs, "over_temp", thermal_exc_event->over_temp)json_object_object_add(valid_attrs, "over_temp", json_object_new_uint64
(thermal_exc_event->over_temp))
;
1393 obj_add_uint(valid_attrs, "threshold", thermal_exc_event->threshold)json_object_object_add(valid_attrs, "threshold", json_object_new_uint64
(thermal_exc_event->threshold))
;
1394}
1395
1396static void json_pel_vs_event_data(struct json_object *valid_attrs, void *vsed,
1397 __u8 vsedt, __u16 vsedl)
1398{
1399 struct json_object *vs_data = json_create_object()json_object_new_object();
1400 char *str;
1401
1402 switch (vsedt) {
1403 case NVME_PEL_VSEDT_EVENT_NAME:
1404 str = malloc(vsedl + 1);
1405 if (str) {
1406 memcpy(str, vsed, vsedl);
1407 str[vsedl] = '\0';
1408 obj_add_strjson_object_add_value_string(vs_data, "event_name", str);
1409 free(str);
1410 }
1411 break;
1412 case NVME_PEL_VSEDT_ASCII_STRING:
1413 str = malloc(vsedl + 1);
1414 if (str) {
1415 memcpy(str, vsed, vsedl);
1416 str[vsedl] = '\0';
1417 obj_add_strjson_object_add_value_string(vs_data, "ascii_string_data", str);
1418 free(str);
1419 }
1420 break;
1421 case NVME_PEL_VSEDT_BINARY:
1422 obj_d(vs_data, "binary_data", (unsigned char *)vsed, vsedl, 16, 1);
1423 break;
1424 case NVME_PEL_VSEDT_SIGNED_INT:
1425 if (vsedl < sizeof(__le64)) {
1426 obj_d(vs_data, "binary_data", (unsigned char *)vsed,
1427 vsedl, 16, 1);
1428 break;
1429 }
1430 obj_add_int(vs_data, "signed_integer_data",json_object_object_add(vs_data, "signed_integer_data", json_object_new_int
((int64_t)shr_get_unaligned_le64(vsed)))
1431 (int64_t)shr_get_unaligned_le64(vsed))json_object_object_add(vs_data, "signed_integer_data", json_object_new_int
((int64_t)shr_get_unaligned_le64(vsed)))
;
1432 break;
1433 default:
1434 obj_d(vs_data, "reserved_data_type_bin", (unsigned char *)vsed, vsedl, 16, 1);
1435 break;
1436 }
1437
1438 obj_add_obj(valid_attrs, "vs_event_data", vs_data)json_object_object_add(valid_attrs, "vs_event_data", vs_data);
1439}
1440
1441void nvme_json_pel_vendor_specific_event(void *pevent_log_info, __u32 offset,
1442 __u32 event_data_len,
1443 struct json_object *valid_attrs)
1444{
1445 __u32 progress = 0;
1446 __u16 vsedl;
1447 __u32 i;
1448 struct nvme_vs_event_desc vs_desc;
1449 struct json_object *vs_events = json_create_array()json_object_new_array();
1450
1451 for (i = 0; progress + sizeof(vs_desc) <= event_data_len; i++) {
1452 void *p = pevent_log_info + offset + progress;
1453 struct json_object *vs_event;
1454
1455 /* The descriptors are not aligned. */
1456 memcpy(&vs_desc, p, sizeof(vs_desc));
1457 vsedl = le16_to_cpu(vs_desc.vsedl);
1458 if (vsedl > event_data_len - progress - sizeof(vs_desc))
1459 break;
1460
1461 vs_event = json_create_object()json_object_new_object();
1462
1463 obj_add_uint(vs_event, "vs_event_descriptor_number", i)json_object_object_add(vs_event, "vs_event_descriptor_number"
, json_object_new_uint64(i))
;
1464 obj_add_uint(vs_event, "vs_event_code",json_object_object_add(vs_event, "vs_event_code", json_object_new_uint64
(le16_to_cpu(vs_desc.vsec)))
1465 le16_to_cpu(vs_desc.vsec))json_object_object_add(vs_event, "vs_event_code", json_object_new_uint64
(le16_to_cpu(vs_desc.vsec)))
;
1466 obj_add_uint(vs_event, "vs_event_data_type", vs_desc.vsedt)json_object_object_add(vs_event, "vs_event_data_type", json_object_new_uint64
(vs_desc.vsedt))
;
1467 obj_add_uint(vs_event, "vs_event_uuid_index", vs_desc.uidx)json_object_object_add(vs_event, "vs_event_uuid_index", json_object_new_uint64
(vs_desc.uidx))
;
1468 obj_add_uint(vs_event, "vs_event_data_len", vsedl)json_object_object_add(vs_event, "vs_event_data_len", json_object_new_uint64
(vsedl))
;
1469
1470 if (vsedl)
1471 json_pel_vs_event_data(vs_event, p + sizeof(vs_desc),
1472 vs_desc.vsedt, vsedl);
1473
1474 array_add_obj(vs_events, vs_event)json_object_array_add(vs_events, vs_event);
1475 progress += sizeof(vs_desc) + vsedl;
1476 }
1477
1478 obj_add_array(valid_attrs, "vs_event_entry", vs_events)json_object_object_add(valid_attrs, "vs_event_entry", vs_events
)
;
1479}
1480
1481static void json_pevent_entry(void *pevent_log_info, __u8 action, __u32 size, const char *devname,
1482 __u32 offset, struct json_object *valid)
1483{
1484 int i;
1485 __u16 vsil, el;
1486 __u32 data_len;
1487 struct nvme_persistent_event_log *pevent_log_head = pevent_log_info;
1488 struct nvme_persistent_event_entry *pevent_entry_head;
1489 struct json_object *valid_attrs;
1490
1491 for (i = 0; i < le32_to_cpu(pevent_log_head->tnev); i++) {
1492 pevent_entry_head = nvme_pel_event(pevent_log_info, size,
1493 offset);
1494 if (!pevent_entry_head)
1495 break;
1496
1497 vsil = le16_to_cpu(pevent_entry_head->vsil);
1498 el = le16_to_cpu(pevent_entry_head->el);
1499
1500 valid_attrs = json_create_object()json_object_new_object();
1501
1502 obj_add_uint(valid_attrs, "event_number", i)json_object_object_add(valid_attrs, "event_number", json_object_new_uint64
(i))
;
1503 obj_add_strjson_object_add_value_string(valid_attrs, "event_type",
1504 nvme_pel_event_to_string(pevent_entry_head->etype));
1505 obj_add_uint(valid_attrs, "event_type_rev", pevent_entry_head->etype_rev)json_object_object_add(valid_attrs, "event_type_rev", json_object_new_uint64
(pevent_entry_head->etype_rev))
;
1506 obj_add_uint(valid_attrs, "event_header_len", pevent_entry_head->ehl)json_object_object_add(valid_attrs, "event_header_len", json_object_new_uint64
(pevent_entry_head->ehl))
;
1507 obj_add_uint(valid_attrs, "event_header_additional_info", pevent_entry_head->ehai)json_object_object_add(valid_attrs, "event_header_additional_info"
, json_object_new_uint64(pevent_entry_head->ehai))
;
1508 obj_add_uint(valid_attrs, "ctrl_id", le16_to_cpu(pevent_entry_head->cntlid))json_object_object_add(valid_attrs, "ctrl_id", json_object_new_uint64
(le16_to_cpu(pevent_entry_head->cntlid)))
;
1509 obj_add_uint64(valid_attrs, "event_time_stamp",json_object_object_add(valid_attrs, "event_time_stamp", json_object_new_uint64
(le64_to_cpu(pevent_entry_head->ets)))
1510 le64_to_cpu(pevent_entry_head->ets))json_object_object_add(valid_attrs, "event_time_stamp", json_object_new_uint64
(le64_to_cpu(pevent_entry_head->ets)))
;
1511 obj_add_uint(valid_attrs, "port_id", le16_to_cpu(pevent_entry_head->pelpid))json_object_object_add(valid_attrs, "port_id", json_object_new_uint64
(le16_to_cpu(pevent_entry_head->pelpid)))
;
1512 obj_add_uint(valid_attrs, "vu_info_len", vsil)json_object_object_add(valid_attrs, "vu_info_len", json_object_new_uint64
(vsil))
;
1513 obj_add_uint(valid_attrs, "event_len", el)json_object_object_add(valid_attrs, "event_len", json_object_new_uint64
(el))
;
1514
1515 if (vsil)
1516 obj_d(valid_attrs, "vs_info_bin",
1517 (void *)pevent_entry_head + 1, vsil, 16, 1);
1518
1519 offset += pevent_entry_head->ehl + vsil + 3;
1520
1521 __cleanup_free__attribute__((cleanup(shr_freep))) void *data =
1522 nvme_pel_event_data(pevent_log_info, offset,
1523 el - vsil, &data_len);
1524
1525 if (!data) {
1526 array_add_obj(valid, valid_attrs)json_object_array_add(valid, valid_attrs);
1527 break;
1528 }
1529
1530 switch (pevent_entry_head->etype) {
1531 case NVME_PEL_SMART_HEALTH_EVENT:
1532 nvme_json_pel_smart_health(data, 0, valid_attrs);
1533 break;
1534 case NVME_PEL_FW_COMMIT_EVENT:
1535 nvme_json_pel_fw_commit(data, 0, valid_attrs);
1536 break;
1537 case NVME_PEL_TIMESTAMP_EVENT:
1538 nvme_json_pel_timestamp(data, 0, valid_attrs);
1539 break;
1540 case NVME_PEL_POWER_ON_RESET_EVENT:
1541 nvme_json_pel_power_on_reset(data, 0, valid_attrs,
1542 pevent_entry_head->vsil,
1543 pevent_entry_head->el,
1544 data_len);
1545 break;
1546 case NVME_PEL_NSS_HW_ERROR_EVENT:
1547 nvme_json_pel_nss_hw_error(data, 0, valid_attrs);
1548 break;
1549 case NVME_PEL_CHANGE_NS_EVENT:
1550 nvme_json_pel_change_ns(data, 0, valid_attrs);
1551 break;
1552 case NVME_PEL_FORMAT_START_EVENT:
1553 nvme_json_pel_format_start(data, 0, valid_attrs);
1554 break;
1555 case NVME_PEL_FORMAT_COMPLETION_EVENT:
1556 nvme_json_pel_format_completion(data, 0, valid_attrs);
1557 break;
1558 case NVME_PEL_SANITIZE_START_EVENT:
1559 nvme_json_pel_sanitize_start(data, 0, valid_attrs);
1560 break;
1561 case NVME_PEL_SANITIZE_COMPLETION_EVENT:
1562 nvme_json_pel_sanitize_completion(data, 0, valid_attrs);
1563 break;
1564 case NVME_PEL_SET_FEATURE_EVENT:
1565 nvme_json_pel_set_feature(data, el - vsil,
1566 valid_attrs);
1567 break;
1568 case NVME_PEL_TELEMETRY_CRT:
1569 nvme_json_pel_telemetry_crt(data, 0, valid_attrs,
1570 pevent_entry_head->el,
1571 data_len);
1572 break;
1573 case NVME_PEL_THERMAL_EXCURSION_EVENT:
1574 nvme_json_pel_thermal_excursion(data, 0, valid_attrs);
1575 break;
1576 case NVME_PEL_VENDOR_SPECIFIC_EVENT:
1577 nvme_json_pel_vendor_specific_event(data, 0, el - vsil,
1578 valid_attrs);
1579 break;
1580 default:
1581 break;
1582 }
1583
1584 array_add_obj(valid, valid_attrs)json_object_array_add(valid, valid_attrs);
1585 offset += el - vsil;
1586 }
1587}
1588
1589static void json_persistent_event_log(void *pevent_log_info, __u8 action,
1590 __u32 size, const char *devname)
1591{
1592 struct json_object *r = json_r;
1593 struct json_object *valid;
1594 __u32 offset = sizeof(struct nvme_persistent_event_log);
1595
1596 if (size >= offset) {
1597 valid = json_create_array()json_object_new_array();
1598 nvme_json_pevent_log_head(pevent_log_info, r);
1599 json_pevent_entry(pevent_log_info, action, size, devname, offset, valid);
1600 obj_add_array(r, "list_of_event_entries", valid)json_object_object_add(r, "list_of_event_entries", valid);
1601 } else {
1602 obj_add_result(r, "No log data can be shown with this log len at least " \
1603 "512 bytes is required or can be 0 to read the complete "\
1604 "log page after context established");
1605 }
1606}
1607
1608static void json_endurance_group_event_agg_log(
1609 struct nvme_aggregate_endurance_group_event *endurance_log,
1610 __u64 log_entries, __u32 size, const char *devname)
1611{
1612 struct json_object *r = json_r;
1613 struct json_object *valid_attrs;
1614 struct json_object *valid = json_create_array()json_object_new_array();
1615
1616 obj_add_uint64(r, "num_entries_avail", le64_to_cpu(endurance_log->num_entries))json_object_object_add(r, "num_entries_avail", json_object_new_uint64
(le64_to_cpu(endurance_log->num_entries)))
;
1617
1618 for (int i = 0; i < log_entries; i++) {
1619 valid_attrs = json_create_object()json_object_new_object();
1620 obj_add_uint(valid_attrs, "entry", le16_to_cpu(endurance_log->entries[i]))json_object_object_add(valid_attrs, "entry", json_object_new_uint64
(le16_to_cpu(endurance_log->entries[i])))
;
1621 array_add_obj(valid, valid_attrs)json_object_array_add(valid, valid_attrs);
1622 }
1623
1624 obj_add_array(r, "list_of_entries", valid)json_object_object_add(r, "list_of_entries", valid);
1625}
1626
1627static void json_lba_status(struct nvme_lba_status *list,
1628 unsigned long len)
1629{
1630 struct json_object *r = json_r;
1631 __u32 nlsd = le32_to_cpu(list->nlsd);
1632 size_t nr = nvme_log_nr_entries(nlsd, len, sizeof(*list),
1633 sizeof(list->descs[0]));
1634 size_t idx;
1635 struct nvme_lba_status_desc *e;
1636 struct json_object *lsde;
1637 char json_str[STR_LEN100];
1638
1639 obj_add_uint(r, "Number of LBA Status Descriptors (NLSD)", nlsd)json_object_object_add(r, "Number of LBA Status Descriptors (NLSD)"
, json_object_new_uint64(nlsd))
;
1640 obj_add_uint(r, "Completion Condition (CMPC)", list->cmpc)json_object_object_add(r, "Completion Condition (CMPC)", json_object_new_uint64
(list->cmpc))
;
1641
1642 switch (list->cmpc) {
1643 case NVME_LBA_STATUS_CMPC_NO_CMPC:
1644 obj_add_strjson_object_add_value_string(r, "cmpc-definition", "No indication of the completion condition");
1645 break;
1646 case NVME_LBA_STATUS_CMPC_INCOMPLETE:
1647 obj_add_strjson_object_add_value_string(r, "cmpc-definition",
1648 "Completed transferring the amount of data specified in the"\
1649 "MNDW field. But, additional LBA Status Descriptor Entries are"\
1650 "available to transfer or scan did not complete (if ATYPE = 10h)");
1651 break;
1652 case NVME_LBA_STATUS_CMPC_COMPLETE:
1653 obj_add_strjson_object_add_value_string(r, "cmpc-definition",
1654 "Completed the specified action over the number of LBAs specified"\
1655 "in the Range Length field and transferred all available LBA Status"\
1656 "Descriptor Entries");
1657 break;
1658 default:
1659 break;
1660 }
1661
1662 for (idx = 0; idx < nr; idx++) {
1663 lsde = json_create_object()json_object_new_object();
1664 sprintf(json_str, "LSD entry %zu", idx);
1665 obj_add_obj(r, json_str, lsde)json_object_object_add(r, json_str, lsde);
1666 e = &list->descs[idx];
1667 sprintf(json_str, "0x%016"PRIx64"l" "x""", le64_to_cpu(e->dslba));
1668 obj_add_strjson_object_add_value_string(lsde, "DSLBA", json_str);
1669 sprintf(json_str, "0x%08x", le32_to_cpu(e->nlb));
1670 obj_add_strjson_object_add_value_string(lsde, "NLB", json_str);
1671 sprintf(json_str, "0x%02x", e->status);
1672 obj_add_strjson_object_add_value_string(lsde, "status", json_str);
1673 }
1674}
1675
1676static void json_lba_status_log(void *lba_status, __u32 size, const char *devname)
1677{
1678 struct json_object *r = json_r;
1679 struct json_object *desc;
1680 struct json_object *element;
1681 struct json_object *desc_list;
1682 struct json_object *elements_list;
1683 struct nvme_lba_status_log *hdr = lba_status;
1684 struct nvme_lbas_ns_element *ns_element;
1685 struct nvme_lba_rd *range_desc;
1686 size_t offset = sizeof(*hdr);
1687 __u32 num_lba_desc;
1688 __u32 num_elements;
1689 int ele;
1690 int i;
1691
1692 if (size < sizeof(*hdr))
1693 return;
1694
1695 elements_list = json_create_array()json_object_new_array();
1696 num_elements = le32_to_cpu(hdr->nlslne);
1697
1698 obj_add_uint(r, "lslplen", le32_to_cpu(hdr->lslplen))json_object_object_add(r, "lslplen", json_object_new_uint64(le32_to_cpu
(hdr->lslplen)))
;
1699 obj_add_uint(r, "nlslne", num_elements)json_object_object_add(r, "nlslne", json_object_new_uint64(num_elements
))
;
1700 obj_add_uint(r, "estulb", le32_to_cpu(hdr->estulb))json_object_object_add(r, "estulb", json_object_new_uint64(le32_to_cpu
(hdr->estulb)))
;
1701 obj_add_uint(r, "lsgc", le16_to_cpu(hdr->lsgc))json_object_object_add(r, "lsgc", json_object_new_uint64(le16_to_cpu
(hdr->lsgc)))
;
1702
1703 for (ele = 0; ele < num_elements; ele++) {
1704 if (offset + sizeof(*ns_element) > size)
1705 break;
1706 ns_element = lba_status + offset;
1707 element = json_create_object()json_object_new_object();
1708 obj_add_uint(element, "neid", le32_to_cpu(ns_element->neid))json_object_object_add(element, "neid", json_object_new_uint64
(le32_to_cpu(ns_element->neid)))
;
1709 num_lba_desc = le32_to_cpu(ns_element->nlrd);
1710 obj_add_uint(element, "nlrd", num_lba_desc)json_object_object_add(element, "nlrd", json_object_new_uint64
(num_lba_desc))
;
1711 obj_add_uint(element, "ratype", ns_element->ratype)json_object_object_add(element, "ratype", json_object_new_uint64
(ns_element->ratype))
;
1712
1713 offset += sizeof(*ns_element);
1714 desc_list = json_create_array()json_object_new_array();
1715
1716 if (num_lba_desc != 0xffffffff) {
1717 if (num_lba_desc >
1718 (size - offset) / sizeof(*range_desc)) {
1719 json_free_object(desc_list)json_object_put(desc_list);
1720 json_free_object(element)json_object_put(element);
1721 break;
1722 }
1723 for (i = 0; i < num_lba_desc; i++) {
1724 range_desc = lba_status + offset;
1725 desc = json_create_object()json_object_new_object();
1726 obj_add_uint64(desc, "rslba", le64_to_cpu(range_desc->rslba))json_object_object_add(desc, "rslba", json_object_new_uint64(
le64_to_cpu(range_desc->rslba)))
;
1727 obj_add_uint(desc, "rnlb", le32_to_cpu(range_desc->rnlb))json_object_object_add(desc, "rnlb", json_object_new_uint64(le32_to_cpu
(range_desc->rnlb)))
;
1728
1729 offset += sizeof(*range_desc);
1730 array_add_obj(desc_list, desc)json_object_array_add(desc_list, desc);
1731 }
1732 } else {
1733 obj_add_result(r, "Number of LBA Range Descriptors (NLRD) set to %#x for NS element %d",
1734 num_lba_desc, ele);
1735 }
1736
1737 obj_add_array(element, "descs", desc_list)json_object_object_add(element, "descs", desc_list);
1738 array_add_obj(elements_list, element)json_object_array_add(elements_list, element);
1739 }
1740
1741 obj_add_array(r, "ns_elements", elements_list)json_object_object_add(r, "ns_elements", elements_list);
1742}
1743
1744static void json_resv_notif_log(struct nvme_resv_notification_log *resv,
1745 const char *devname)
1746{
1747 struct json_object *r = json_r;
1748
1749 obj_add_uint64(r, "count", le64_to_cpu(resv->lpc))json_object_object_add(r, "count", json_object_new_uint64(le64_to_cpu
(resv->lpc)))
;
1750 obj_add_uint(r, "rn_log_type", resv->rnlpt)json_object_object_add(r, "rn_log_type", json_object_new_uint64
(resv->rnlpt))
;
1751 obj_add_uint(r, "num_logs", resv->nalp)json_object_object_add(r, "num_logs", json_object_new_uint64(
resv->nalp))
;
1752 obj_add_uint(r, "NSID", le32_to_cpu(resv->nsid))json_object_object_add(r, "NSID", json_object_new_uint64(le32_to_cpu
(resv->nsid)))
;
1753}
1754
1755static void json_fid_support_effects_log(
1756 struct nvme_fid_supported_effects_log *fid_log,
1757 const char *devname)
1758{
1759 struct json_object *r = json_r;
1760 struct json_object *fids;
1761 struct json_object *fids_list = json_create_array()json_object_new_array();
1762 unsigned int fid;
1763 char key[128];
1764 __u32 fid_support;
1765
1766 for (fid = 0; fid < NVME_LOG_FID_SUPPORTED_EFFECTS_MAX; fid++) {
1767 fid_support = le32_to_cpu(fid_log->fid_support[fid]);
1768 if (fid_support & NVME_FID_SUPPORTED_EFFECTS_FSUPP) {
1769 fids = json_create_object()json_object_new_object();
1770 sprintf(key, "fid_%u", fid);
1771 obj_add_uint(fids, key, fid_support)json_object_object_add(fids, key, json_object_new_uint64(fid_support
))
;
1772 array_add_obj(fids_list, fids)json_object_array_add(fids_list, fids);
1773 }
1774 }
1775
1776 obj_add_obj(r, "fid_support", fids_list)json_object_object_add(r, "fid_support", fids_list);
1777}
1778
1779static void json_mi_cmd_support_effects_log(
1780 struct nvme_mi_cmd_supported_effects_log *mi_cmd_log,
1781 const char *devname)
1782{
1783 struct json_object *r = json_r;
1784 struct json_object *mi_cmds;
1785 struct json_object *mi_cmds_list = json_create_array()json_object_new_array();
1786 unsigned int mi_cmd;
1787 char key[128];
1788 __u32 mi_cmd_support;
1789
1790 for (mi_cmd = 0; mi_cmd < NVME_LOG_MI_CMD_SUPPORTED_EFFECTS_MAX; mi_cmd++) {
1791 mi_cmd_support = le32_to_cpu(mi_cmd_log->mi_cmd_support[mi_cmd]);
1792 if (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_CSUPP) {
1793 mi_cmds = json_create_object()json_object_new_object();
1794 sprintf(key, "mi_cmd_%u", mi_cmd);
1795 obj_add_uint(mi_cmds, key, mi_cmd_support)json_object_object_add(mi_cmds, key, json_object_new_uint64(mi_cmd_support
))
;
1796 array_add_obj(mi_cmds_list, mi_cmds)json_object_array_add(mi_cmds_list, mi_cmds);
1797 }
1798 }
1799
1800 obj_add_obj(r, "mi_command_support", mi_cmds_list)json_object_object_add(r, "mi_command_support", mi_cmds_list);
1801}
1802
1803static void json_boot_part_log(void *bp_log, const char *devname,
1804 __u32 size)
1805{
1806 struct nvme_boot_partition *hdr = bp_log;
1807 struct json_object *r = json_r;
1808
1809 obj_add_uint(r, "count", hdr->lid)json_object_object_add(r, "count", json_object_new_uint64(hdr
->lid))
;
1810 obj_add_uint(r, "abpid", NVME_BOOT_PARTITION_INFO_ABPID(le32_to_cpu(hdr->bpinfo)))json_object_object_add(r, "abpid", json_object_new_uint64((((
le32_to_cpu(hdr->bpinfo)) >> NVME_BOOT_PARTITION_INFO_ABPID_SHIFT
) & NVME_BOOT_PARTITION_INFO_ABPID_MASK)))
;
1811 obj_add_uint(r, "bpsz", NVME_BOOT_PARTITION_INFO_BPSZ(le32_to_cpu(hdr->bpinfo)))json_object_object_add(r, "bpsz", json_object_new_uint64((((le32_to_cpu
(hdr->bpinfo)) >> NVME_BOOT_PARTITION_INFO_BPSZ_SHIFT
) & NVME_BOOT_PARTITION_INFO_BPSZ_MASK)))
;
1812}
1813
1814/* Printable Eye string is allocated and returned, caller must free */
1815static char *json_eom_printable_eye(const struct nvme_eom_lane_desc *lane,
1816 const unsigned char *eye,
1817 struct json_object *r)
1818{
1819 size_t nrows = le16_to_cpu(lane->nrows);
1820 size_t ncols = le16_to_cpu(lane->ncols);
1821 struct json_object *eye_array = NULL((void*)0);
1822 char *printable_start = NULL((void*)0);
1823 char *printable = NULL((void*)0);
1824
1825 if (nrows == 0 || ncols == 0)
1826 return NULL((void*)0);
1827
1828 eye_array = json_create_array()json_object_new_array();
1829 if (!eye_array)
1830 return NULL((void*)0);
1831
1832 /*
1833 * Allocate buffer for full printable string (with newlines)
1834 * +1 for null terminator
1835 */
1836 printable = malloc((size_t)nrows * ncols + nrows + 1);
1837 printable_start = printable;
1838
1839 if (!printable)
1840 goto fail_free_eye_array;
1841
1842 for (size_t i = 0; i < nrows; i++) {
1843 char *row = malloc(ncols + 1);
1844
1845 if (!row)
1846 goto fail_free_eye_printable;
1847
1848 for (size_t j = 0; j < ncols; j++) {
1849 char ch = eye[i * ncols + j];
1850 *printable++ = ch;
1851 row[j] = ch;
1852 }
1853
1854 *printable++ = '\n';
1855 row[ncols] = '\0';
1856
1857 array_add_strjson_array_add_value_string(eye_array, row);
1858 free(row);
1859 }
1860
1861 *printable = '\0';
1862
1863 obj_add_array(r, "printable_eye", eye_array)json_object_object_add(r, "printable_eye", eye_array);
1864
1865 return printable_start;
1866
1867fail_free_eye_printable:
1868 free(printable_start);
1869fail_free_eye_array:
1870 json_free_object(eye_array)json_object_put(eye_array);
1871
1872 return NULL((void*)0);
1873}
1874
1875static void json_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log,
1876 struct json_object *r, char **allocated_eyes, size_t len)
1877{
1878 struct eom_desc_iter it;
1879 struct nvme_eom_lane_desc desc;
1880 struct json_object *descs = json_create_array()json_object_new_array();
1881 int i = 0;
1882
1883 obj_add_array(r, "descs", descs)json_object_object_add(r, "descs", descs);
1884
1885 eom_desc_iter_init(&it, log, len);
1886
1887 while (eom_desc_iter_next(&it, &desc)) {
1888 int idx = i++;
1889 __cleanup_free__attribute__((cleanup(shr_freep))) char *hexstr = NULL((void*)0);
1890 unsigned char *vsdata;
1891 uint16_t vsdatalen;
1892 struct json_object *jdesc;
1893 char *hexdata;
1894
1895 jdesc = json_create_object()json_object_new_object();
1896 if (!jdesc)
1897 return;
1898
1899 obj_add_uint(jdesc, "lid", desc.mstatus)json_object_object_add(jdesc, "lid", json_object_new_uint64(desc
.mstatus))
;
1900 obj_add_uint(jdesc, "lane", desc.lane)json_object_object_add(jdesc, "lane", json_object_new_uint64(
desc.lane))
;
1901 obj_add_uint(jdesc, "eye", desc.eye)json_object_object_add(jdesc, "eye", json_object_new_uint64(desc
.eye))
;
1902 obj_add_uint(jdesc, "top", le16_to_cpu(desc.top))json_object_object_add(jdesc, "top", json_object_new_uint64(le16_to_cpu
(desc.top)))
;
1903 obj_add_uint(jdesc, "bottom", le16_to_cpu(desc.bottom))json_object_object_add(jdesc, "bottom", json_object_new_uint64
(le16_to_cpu(desc.bottom)))
;
1904 obj_add_uint(jdesc, "left", le16_to_cpu(desc.left))json_object_object_add(jdesc, "left", json_object_new_uint64(
le16_to_cpu(desc.left)))
;
1905 obj_add_uint(jdesc, "right", le16_to_cpu(desc.right))json_object_object_add(jdesc, "right", json_object_new_uint64
(le16_to_cpu(desc.right)))
;
1906 obj_add_uint(jdesc, "nrows", le16_to_cpu(desc.nrows))json_object_object_add(jdesc, "nrows", json_object_new_uint64
(le16_to_cpu(desc.nrows)))
;
1907 obj_add_uint(jdesc, "ncols", le16_to_cpu(desc.ncols))json_object_object_add(jdesc, "ncols", json_object_new_uint64
(le16_to_cpu(desc.ncols)))
;
1908 obj_add_uint(jdesc, "edlen", le16_to_cpu(desc.edlen))json_object_object_add(jdesc, "edlen", json_object_new_uint64
(le16_to_cpu(desc.edlen)))
;
1909
1910 vsdata = eom_desc_iter_vsdata(&it, &desc, &vsdatalen);
1911 if (!vsdata) {
1912 json_free_object(jdesc)json_object_put(jdesc);
1913 continue;
1914 }
1915
1916 if (NVME_EOM_ODP_PEFP(log->odp)(((log->odp) >> NVME_EOM_ODP_PEFP_SHIFT) & NVME_EOM_ODP_PEFP_MASK
)
)
1917 allocated_eyes[idx] = json_eom_printable_eye(&desc,
1918 eom_desc_iter_eye(&it), jdesc);
1919
1920 if (vsdatalen == 0) {
1921 json_free_object(jdesc)json_object_put(jdesc);
1922 continue;
1923 }
1924
1925 /* 2 hex chars + space per byte */
1926 hexstr = malloc(vsdatalen * 3 + 1);
1927
1928 if (!hexstr) {
1929 json_free_object(jdesc)json_object_put(jdesc);
1930 return;
1931 }
1932
1933 /* Hex dump Vendor Specific Eye Data */
1934 hexdata = hexstr;
1935
1936 for (int offset = 0; offset < vsdatalen; offset++)
1937 hexdata += sprintf(hexdata, "%02X ", vsdata[offset]);
1938 /* remove trailing space */
1939 *(hexdata - 1) = '\0';
1940
1941 obj_add_strjson_object_add_value_string(jdesc, "vsdata_hex", hexstr);
1942
1943 array_add_obj(descs, jdesc)json_object_array_add(descs, jdesc);
1944 }
1945}
1946
1947static void json_phy_rx_eom_log(struct nvme_phy_rx_eom_log *log, __u16 controller, size_t len)
1948{
1949 int i;
1950 uint16_t num_descs;
1951 struct json_object *r = json_r;
1952
1953 __cleanup_free__attribute__((cleanup(shr_freep))) char **allocated_eyes = NULL((void*)0);
1954
1955 if (len < sizeof(*log))
1956 return;
1957
1958 num_descs = le16_to_cpu(log->nd);
1959 if (num_descs > (len - sizeof(*log)) / sizeof(struct nvme_eom_lane_desc))
1960 num_descs = (len - sizeof(*log)) / sizeof(struct nvme_eom_lane_desc);
1961
1962 obj_add_uint(r, "lid", log->lid)json_object_object_add(r, "lid", json_object_new_uint64(log->
lid))
;
1963 obj_add_uint(r, "eomip", log->eomip)json_object_object_add(r, "eomip", json_object_new_uint64(log
->eomip))
;
1964 obj_add_uint(r, "hsize", le16_to_cpu(log->hsize))json_object_object_add(r, "hsize", json_object_new_uint64(le16_to_cpu
(log->hsize)))
;
1965 obj_add_uint(r, "rsize", le32_to_cpu(log->rsize))json_object_object_add(r, "rsize", json_object_new_uint64(le32_to_cpu
(log->rsize)))
;
1966 obj_add_uint(r, "eomdgn", log->eomdgn)json_object_object_add(r, "eomdgn", json_object_new_uint64(log
->eomdgn))
;
1967 obj_add_uint(r, "lr", log->lr)json_object_object_add(r, "lr", json_object_new_uint64(log->
lr))
;
1968 obj_add_uint(r, "lanes", log->lanes)json_object_object_add(r, "lanes", json_object_new_uint64(log
->lanes))
;
1969 obj_add_uint(r, "epl", log->epl)json_object_object_add(r, "epl", json_object_new_uint64(log->
epl))
;
1970 obj_add_uint(r, "lspfc", log->lspfc)json_object_object_add(r, "lspfc", json_object_new_uint64(log
->lspfc))
;
1971 obj_add_uint(r, "li", log->li)json_object_object_add(r, "li", json_object_new_uint64(log->
li))
;
1972 obj_add_uint(r, "lsic", le16_to_cpu(log->lsic))json_object_object_add(r, "lsic", json_object_new_uint64(le16_to_cpu
(log->lsic)))
;
1973 obj_add_uint(r, "dsize", le32_to_cpu(log->dsize))json_object_object_add(r, "dsize", json_object_new_uint64(le32_to_cpu
(log->dsize)))
;
1974 obj_add_uint(r, "nd", le16_to_cpu(log->nd))json_object_object_add(r, "nd", json_object_new_uint64(le16_to_cpu
(log->nd)))
;
1975 obj_add_uint(r, "maxtb", le16_to_cpu(log->maxtb))json_object_object_add(r, "maxtb", json_object_new_uint64(le16_to_cpu
(log->maxtb)))
;
1976 obj_add_uint(r, "maxlr", le16_to_cpu(log->maxlr))json_object_object_add(r, "maxlr", json_object_new_uint64(le16_to_cpu
(log->maxlr)))
;
1977 obj_add_uint(r, "etgood", le16_to_cpu(log->etgood))json_object_object_add(r, "etgood", json_object_new_uint64(le16_to_cpu
(log->etgood)))
;
1978 obj_add_uint(r, "etbetter", le16_to_cpu(log->etbetter))json_object_object_add(r, "etbetter", json_object_new_uint64(
le16_to_cpu(log->etbetter)))
;
1979 obj_add_uint(r, "etbest", le16_to_cpu(log->etbest))json_object_object_add(r, "etbest", json_object_new_uint64(le16_to_cpu
(log->etbest)))
;
1980
1981 if (log->eomip == NVME_PHY_RX_EOM_COMPLETED) {
1982 /* Save Printable Eye strings allocated to free later */
1983 allocated_eyes = calloc(num_descs, sizeof(char *));
1984 if (allocated_eyes)
1985 json_phy_rx_eom_descs(log, r, allocated_eyes, len);
1986 }
1987
1988 if (allocated_eyes) {
1989 for (i = 0; i < num_descs; i++) {
1990 /* Free any Printable Eye strings allocated */
1991 free(allocated_eyes[i]);
1992 }
1993 }
1994}
1995
1996static void json_media_unit_stat_log(struct nvme_media_unit_stat_log *mus,
1997 size_t len)
1998{
1999 struct json_object *r = json_r;
2000 struct json_object *entries = json_create_array()json_object_new_array();
2001 struct nvme_media_unit_stat_desc desc;
2002 struct mus_desc_iter it;
2003
2004 if (len < sizeof(*mus)) {
2005 obj_add_array(r, "mus_list", entries)json_object_object_add(r, "mus_list", entries);
2006 return;
2007 }
2008
2009 obj_add_uint(r, "nmu", le16_to_cpu(mus->nmu))json_object_object_add(r, "nmu", json_object_new_uint64(le16_to_cpu
(mus->nmu)))
;
2010 obj_add_uint(r, "cchans", le16_to_cpu(mus->cchans))json_object_object_add(r, "cchans", json_object_new_uint64(le16_to_cpu
(mus->cchans)))
;
2011 obj_add_uint(r, "sel_config", le16_to_cpu(mus->sel_config))json_object_object_add(r, "sel_config", json_object_new_uint64
(le16_to_cpu(mus->sel_config)))
;
2012
2013 mus_desc_iter_init(&it, mus, len);
2014 while (mus_desc_iter_next(&it, &desc)) {
2015 struct json_object *entry = json_create_object()json_object_new_object();
2016 struct json_object *chans = json_create_array()json_object_new_array();
2017
2018 obj_add_uint(entry, "muid", le16_to_cpu(desc.muid))json_object_object_add(entry, "muid", json_object_new_uint64(
le16_to_cpu(desc.muid)))
;
2019 obj_add_uint(entry, "domainid", le16_to_cpu(desc.domainid))json_object_object_add(entry, "domainid", json_object_new_uint64
(le16_to_cpu(desc.domainid)))
;
2020 obj_add_uint(entry, "endgid", le16_to_cpu(desc.endgid))json_object_object_add(entry, "endgid", json_object_new_uint64
(le16_to_cpu(desc.endgid)))
;
2021 obj_add_uint(entry, "nvmsetid", le16_to_cpu(desc.nvmsetid))json_object_object_add(entry, "nvmsetid", json_object_new_uint64
(le16_to_cpu(desc.nvmsetid)))
;
2022 obj_add_uint(entry, "cap_adj_fctr",json_object_object_add(entry, "cap_adj_fctr", json_object_new_uint64
(le16_to_cpu(desc.cap_adj_fctr)))
2023 le16_to_cpu(desc.cap_adj_fctr))json_object_object_add(entry, "cap_adj_fctr", json_object_new_uint64
(le16_to_cpu(desc.cap_adj_fctr)))
;
2024 obj_add_uint(entry, "avl_spare", desc.avl_spare)json_object_object_add(entry, "avl_spare", json_object_new_uint64
(desc.avl_spare))
;
2025 obj_add_uint(entry, "percent_used", desc.percent_used)json_object_object_add(entry, "percent_used", json_object_new_uint64
(desc.percent_used))
;
2026 obj_add_uint(entry, "mucs", desc.mucs)json_object_object_add(entry, "mucs", json_object_new_uint64(
desc.mucs))
;
2027 obj_add_uint(entry, "cio", desc.cio)json_object_object_add(entry, "cio", json_object_new_uint64(desc
.cio))
;
2028
2029 for (int k = 0; k < desc.mucs; k++) {
2030 struct json_object *chan = json_create_object()json_object_new_object();
2031
2032 obj_add_uint(chan, "chanid",json_object_object_add(chan, "chanid", json_object_new_uint64
(mus_desc_iter_chan(&it, k)))
2033 mus_desc_iter_chan(&it, k))json_object_object_add(chan, "chanid", json_object_new_uint64
(mus_desc_iter_chan(&it, k)))
;
2034 array_add_obj(chans, chan)json_object_array_add(chans, chan);
2035 }
2036 obj_add_array(entry, "chanids", chans)json_object_object_add(entry, "chanids", chans);
2037 array_add_obj(entries, entry)json_object_array_add(entries, entry);
2038 }
2039
2040 obj_add_array(r, "mus_list", entries)json_object_object_add(r, "mus_list", entries);
2041}
2042
2043/*
2044 * An odd Media Unit Descriptor Length leaves the next descriptors
2045 * unaligned, so they are copied before they are read.
2046 */
2047static bool_Bool json_cap_config_chan(struct json_object *chan_list,
2048 unsigned char **p, unsigned char *end)
2049{
2050 struct nvme_channel_config_desc chd;
2051 struct json_object *channel, *media_list;
2052 int chmus;
2053
2054 if (!shr_buf_has_room(*p, end, sizeof(chd)))
2055 return false0;
2056
2057 memcpy(&chd, *p, sizeof(chd));
2058 chmus = le16_to_cpu(chd.chmus);
2059 *p += sizeof(chd);
2060
2061 channel = json_create_object()json_object_new_object();
2062 obj_add_uint(channel, "chanid", le16_to_cpu(chd.chanid))json_object_object_add(channel, "chanid", json_object_new_uint64
(le16_to_cpu(chd.chanid)))
;
2063 obj_add_uint(channel, "chmus", chmus)json_object_object_add(channel, "chmus", json_object_new_uint64
(chmus))
;
2064 media_list = json_create_array()json_object_new_array();
2065 obj_add_array(channel, "Media Descriptor", media_list)json_object_object_add(channel, "Media Descriptor", media_list
)
;
2066 array_add_obj(chan_list, channel)json_object_array_add(chan_list, channel);
2067
2068 for (int m = 0; m < chmus; m++) {
2069 struct nvme_media_unit_config_desc mu;
2070 struct json_object *media;
2071 size_t size;
2072
2073 if (!shr_buf_has_room(*p, end, sizeof(mu)))
2074 return false0;
2075
2076 memcpy(&mu, *p, sizeof(mu));
2077 size = sizeof(mu) + le16_to_cpu(mu.mudl);
2078 if (!shr_buf_has_room(*p, end, size))
2079 return false0;
2080
2081 media = json_create_object()json_object_new_object();
2082 obj_add_uint(media, "muid", le16_to_cpu(mu.muid))json_object_object_add(media, "muid", json_object_new_uint64(
le16_to_cpu(mu.muid)))
;
2083 obj_add_uint(media, "mudl", le16_to_cpu(mu.mudl))json_object_object_add(media, "mudl", json_object_new_uint64(
le16_to_cpu(mu.mudl)))
;
2084 array_add_obj(media_list, media)json_object_array_add(media_list, media);
2085 *p += size;
2086 }
2087
2088 return true1;
2089}
2090
2091static bool_Bool json_cap_config_egcd(struct json_object *end_list,
2092 unsigned char **p, unsigned char *end)
2093{
2094 struct nvme_end_grp_config_desc egcd;
2095 struct nvme_end_grp_chan_desc chan_desc;
2096 struct json_object *endurance, *set_list, *chan_list;
2097 unsigned char *sets;
2098 int egsets, egchans;
2099
2100 if (!shr_buf_has_room(*p, end, sizeof(egcd)))
2101 return false0;
2102
2103 memcpy(&egcd, *p, sizeof(egcd));
2104 egsets = le16_to_cpu(egcd.egsets);
2105 sets = *p + sizeof(egcd);
2106 *p = sets + egsets * sizeof(__le16);
2107 if (!shr_buf_has_room(sets, end, egsets * sizeof(__le16) +
2108 sizeof(chan_desc)))
2109 return false0;
2110
2111 memcpy(&chan_desc, *p, sizeof(chan_desc));
2112 egchans = le16_to_cpu(chan_desc.egchans);
2113 *p += sizeof(chan_desc);
2114
2115 endurance = json_create_object()json_object_new_object();
2116 obj_add_uint(endurance, "endgid", le16_to_cpu(egcd.endgid))json_object_object_add(endurance, "endgid", json_object_new_uint64
(le16_to_cpu(egcd.endgid)))
;
2117 obj_add_uint(endurance, "cap_adj_factor",json_object_object_add(endurance, "cap_adj_factor", json_object_new_uint64
(le16_to_cpu(egcd.cap_adj_factor)))
2118 le16_to_cpu(egcd.cap_adj_factor))json_object_object_add(endurance, "cap_adj_factor", json_object_new_uint64
(le16_to_cpu(egcd.cap_adj_factor)))
;
2119 obj_add_uint128(endurance, "tegcap", le128_to_cpu(egcd.tegcap))json_object_object_add(endurance, "tegcap", util_json_object_new_uint128
(le128_to_cpu(egcd.tegcap)))
;
2120 obj_add_uint128(endurance, "segcap", le128_to_cpu(egcd.segcap))json_object_object_add(endurance, "segcap", util_json_object_new_uint128
(le128_to_cpu(egcd.segcap)))
;
2121 obj_add_uint(endurance, "egsets", egsets)json_object_object_add(endurance, "egsets", json_object_new_uint64
(egsets))
;
2122 obj_add_uint(endurance, "egchans", egchans)json_object_object_add(endurance, "egchans", json_object_new_uint64
(egchans))
;
2123
2124 set_list = json_create_array()json_object_new_array();
2125 for (int k = 0; k < egsets; k++) {
2126 struct json_object *set = json_create_object()json_object_new_object();
2127 __le16 id;
2128
2129 memcpy(&id, sets + k * sizeof(id), sizeof(id));
2130 obj_add_uint(set, "nvmsetid", le16_to_cpu(id))json_object_object_add(set, "nvmsetid", json_object_new_uint64
(le16_to_cpu(id)))
;
2131 array_add_obj(set_list, set)json_object_array_add(set_list, set);
2132 }
2133
2134 chan_list = json_create_array()json_object_new_array();
2135 obj_add_array(endurance, "Channel Descriptor", chan_list)json_object_object_add(endurance, "Channel Descriptor", chan_list
)
;
2136 obj_add_array(endurance, "NVM Set IDs", set_list)json_object_object_add(endurance, "NVM Set IDs", set_list);
2137 array_add_obj(end_list, endurance)json_object_array_add(end_list, endurance);
2138
2139 for (int l = 0; l < egchans; l++) {
2140 if (!json_cap_config_chan(chan_list, p, end))
2141 return false0;
2142 }
2143
2144 return true1;
2145}
2146
2147static void json_supported_cap_config_log(
2148 struct nvme_supported_cap_config_list_log *cap_log, size_t len)
2149{
2150 struct json_object *r = json_r;
2151 struct json_object *cap_list = json_create_array()json_object_new_array();
2152 unsigned char *p = (unsigned char *)cap_log->cap_config_desc;
2153 unsigned char *end = (unsigned char *)cap_log + len;
2154 bool_Bool more = true1;
2155
2156 obj_add_array(r, "Capacity Descriptor", cap_list)json_object_object_add(r, "Capacity Descriptor", cap_list);
2157 if (len < sizeof(*cap_log))
2158 return;
2159
2160 obj_add_uint(r, "sccn", cap_log->sccn)json_object_object_add(r, "sccn", json_object_new_uint64(cap_log
->sccn))
;
2161 for (int i = 0; more && i < cap_log->sccn; i++) {
2162 struct nvme_capacity_config_desc desc;
2163 struct json_object *capacity, *end_list;
2164 int egcn;
2165
2166 if (!shr_buf_has_room(p, end, sizeof(desc)))
2167 break;
2168
2169 memcpy(&desc, p, sizeof(desc));
2170 egcn = le16_to_cpu(desc.egcn);
2171 p += sizeof(desc);
2172
2173 capacity = json_create_object()json_object_new_object();
2174 obj_add_uint(capacity, "cap_config_id",json_object_object_add(capacity, "cap_config_id", json_object_new_uint64
(le16_to_cpu(desc.cap_config_id)))
2175 le16_to_cpu(desc.cap_config_id))json_object_object_add(capacity, "cap_config_id", json_object_new_uint64
(le16_to_cpu(desc.cap_config_id)))
;
2176 obj_add_uint(capacity, "domainid", le16_to_cpu(desc.domainid))json_object_object_add(capacity, "domainid", json_object_new_uint64
(le16_to_cpu(desc.domainid)))
;
2177 obj_add_uint(capacity, "egcn", egcn)json_object_object_add(capacity, "egcn", json_object_new_uint64
(egcn))
;
2178 end_list = json_create_array()json_object_new_array();
2179 obj_add_array(capacity, "Endurance Descriptor", end_list)json_object_object_add(capacity, "Endurance Descriptor", end_list
)
;
2180 array_add_obj(cap_list, capacity)json_object_array_add(cap_list, capacity);
2181
2182 for (int j = 0; more && j < egcn; j++)
2183 more = json_cap_config_egcd(end_list, &p, end);
2184 }
2185}
2186
2187static void json_nvme_fdp_configs(struct nvme_fdp_config_log *log, size_t len)
2188{
2189 struct json_object *r, *obj_configs;
2190 unsigned char *p, *end;
2191 uint16_t n;
2192
2193 r = json_r;
2194 obj_configs = json_create_array()json_object_new_array();
2195
2196 if (len < sizeof(*log)) {
2197 obj_add_array(r, "configs", obj_configs)json_object_object_add(r, "configs", obj_configs);
2198 return;
2199 }
2200
2201 p = (unsigned char *)log->configs;
2202 end = (unsigned char *)log + len;
2203 n = le16_to_cpu(log->n);
2204
2205 obj_add_uint(r, "n", n)json_object_object_add(r, "n", json_object_new_uint64(n));
2206
2207 for (int i = 0; i < n + 1; i++) {
2208 struct nvme_fdp_config_desc config;
2209 struct nvme_fdp_ruh_desc *ruhs;
2210 uint16_t nruh, size, max_nruh;
2211 struct json_object *obj_config, *obj_ruhs;
2212
2213 if (!shr_buf_has_room(p, end, sizeof(config)))
2214 break;
2215
2216 /* descriptors are only 4 byte aligned */
2217 memcpy(&config, p, sizeof(config));
2218 ruhs = (struct nvme_fdp_ruh_desc *)(p + sizeof(config));
2219
2220 size = le16_to_cpu(config.size);
2221 if (size < sizeof(config) || !shr_buf_has_room(p, end, size))
2222 break;
2223
2224 nruh = le16_to_cpu(config.nruh);
2225 max_nruh = (size - sizeof(config)) / sizeof(*ruhs);
2226 if (nruh > max_nruh)
2227 nruh = max_nruh;
2228
2229 obj_config = json_create_object()json_object_new_object();
2230 obj_ruhs = json_create_array()json_object_new_array();
2231
2232 obj_add_uint(obj_config, "fdpa", config.fdpa)json_object_object_add(obj_config, "fdpa", json_object_new_uint64
(config.fdpa))
;
2233 obj_add_uint(obj_config, "vss", config.vss)json_object_object_add(obj_config, "vss", json_object_new_uint64
(config.vss))
;
2234 obj_add_uint(obj_config, "nrg", le32_to_cpu(config.nrg))json_object_object_add(obj_config, "nrg", json_object_new_uint64
(le32_to_cpu(config.nrg)))
;
2235 obj_add_uint(obj_config, "nruh", nruh)json_object_object_add(obj_config, "nruh", json_object_new_uint64
(nruh))
;
2236 obj_add_uint(obj_config, "nnss", le32_to_cpu(config.nnss))json_object_object_add(obj_config, "nnss", json_object_new_uint64
(le32_to_cpu(config.nnss)))
;
2237 obj_add_uint64(obj_config, "runs", le64_to_cpu(config.runs))json_object_object_add(obj_config, "runs", json_object_new_uint64
(le64_to_cpu(config.runs)))
;
2238 obj_add_uint(obj_config, "erutl", le32_to_cpu(config.erutl))json_object_object_add(obj_config, "erutl", json_object_new_uint64
(le32_to_cpu(config.erutl)))
;
2239
2240 for (int j = 0; j < nruh; j++) {
2241 struct nvme_fdp_ruh_desc *ruh = &ruhs[j];
2242
2243 struct json_object *obj_ruh = json_create_object()json_object_new_object();
2244
2245 obj_add_uint(obj_ruh, "ruht", ruh->ruht)json_object_object_add(obj_ruh, "ruht", json_object_new_uint64
(ruh->ruht))
;
2246
2247 array_add_obj(obj_ruhs, obj_ruh)json_object_array_add(obj_ruhs, obj_ruh);
2248 }
2249
2250 obj_add_array(obj_config, "ruhs", obj_ruhs)json_object_object_add(obj_config, "ruhs", obj_ruhs);
2251 array_add_obj(obj_configs, obj_config)json_object_array_add(obj_configs, obj_config);
2252
2253 p += size;
2254 }
2255
2256 obj_add_array(r, "configs", obj_configs)json_object_object_add(r, "configs", obj_configs);
2257}
2258
2259static void json_nvme_fdp_usage(struct nvme_fdp_ruhu_log *log, size_t len)
2260{
2261 struct json_object *r, *obj_ruhus;
2262 uint16_t nruh;
2263
2264 r = json_r;
2265 obj_ruhus = json_create_array()json_object_new_array();
2266
2267 nruh = le16_to_cpu(log->nruh);
2268
2269 obj_add_uint(r, "nruh", nruh)json_object_object_add(r, "nruh", json_object_new_uint64(nruh
))
;
2270
2271 nruh = nvme_log_nr_entries(nruh, len, sizeof(*log),
2272 sizeof(log->ruhus[0]));
2273 for (int i = 0; i < nruh; i++) {
2274 struct nvme_fdp_ruhu_desc *ruhu = &log->ruhus[i];
2275
2276 struct json_object *obj_ruhu = json_create_object()json_object_new_object();
2277
2278 obj_add_uint(obj_ruhu, "ruha", ruhu->ruha)json_object_object_add(obj_ruhu, "ruha", json_object_new_uint64
(ruhu->ruha))
;
2279
2280 array_add_obj(obj_ruhus, obj_ruhu)json_object_array_add(obj_ruhus, obj_ruhu);
2281 }
2282
2283 obj_add_array(r, "ruhus", obj_ruhus)json_object_object_add(r, "ruhus", obj_ruhus);
2284}
2285
2286static void json_nvme_fdp_stats(struct nvme_fdp_stats_log *log)
2287{
2288 struct json_object *r = json_r;
2289
2290 obj_add_uint128(r, "hbmw", le128_to_cpu(log->hbmw))json_object_object_add(r, "hbmw", util_json_object_new_uint128
(le128_to_cpu(log->hbmw)))
;
2291 obj_add_uint128(r, "mbmw", le128_to_cpu(log->mbmw))json_object_object_add(r, "mbmw", util_json_object_new_uint128
(le128_to_cpu(log->mbmw)))
;
2292 obj_add_uint128(r, "mbe", le128_to_cpu(log->mbe))json_object_object_add(r, "mbe", util_json_object_new_uint128
(le128_to_cpu(log->mbe)))
;
2293}
2294
2295static void json_nvme_fdp_events(struct nvme_fdp_events_log *log)
2296{
2297 struct json_object *r, *obj_events;
2298 uint32_t n;
2299
2300 r = json_r;
2301 obj_events = json_create_array()json_object_new_array();
2302
2303 n = le32_to_cpu(log->n);
2304
2305 obj_add_uint(r, "n", n)json_object_object_add(r, "n", json_object_new_uint64(n));
2306
2307 for (unsigned int i = 0; i < n && i < ARRAY_SIZE(log->events)(sizeof(log->events) / sizeof((log->events)[0]) + 0); i++) {
2308 struct nvme_fdp_event *event = &log->events[i];
2309
2310 struct json_object *obj_event = json_create_object()json_object_new_object();
2311
2312 obj_add_uint(obj_event, "type", event->type)json_object_object_add(obj_event, "type", json_object_new_uint64
(event->type))
;
2313 obj_add_uint(obj_event, "fdpef", event->flags)json_object_object_add(obj_event, "fdpef", json_object_new_uint64
(event->flags))
;
2314 obj_add_uint(obj_event, "pid", le16_to_cpu(event->pid))json_object_object_add(obj_event, "pid", json_object_new_uint64
(le16_to_cpu(event->pid)))
;
2315 obj_add_uint64(obj_event, "timestamp",json_object_object_add(obj_event, "timestamp", json_object_new_uint64
(int48_to_long(event->ts.timestamp)))
2316 int48_to_long(event->ts.timestamp))json_object_object_add(obj_event, "timestamp", json_object_new_uint64
(int48_to_long(event->ts.timestamp)))
;
2317 obj_add_uint(obj_event, "nsid", le32_to_cpu(event->nsid))json_object_object_add(obj_event, "nsid", json_object_new_uint64
(le32_to_cpu(event->nsid)))
;
2318
2319 if (event->type == NVME_FDP_EVENT_REALLOC) {
2320 struct nvme_fdp_event_realloc *mr;
2321
2322 mr = (struct nvme_fdp_event_realloc *)&event->type_specific;
2323
2324 obj_add_uint(obj_event, "nlbam", le16_to_cpu(mr->nlbam))json_object_object_add(obj_event, "nlbam", json_object_new_uint64
(le16_to_cpu(mr->nlbam)))
;
2325
2326 if (mr->flags & NVME_FDP_EVENT_REALLOC_F_LBAV)
2327 obj_add_uint64(obj_event, "lba", le64_to_cpu(mr->lba))json_object_object_add(obj_event, "lba", json_object_new_uint64
(le64_to_cpu(mr->lba)))
;
2328 }
2329
2330 array_add_obj(obj_events, obj_event)json_object_array_add(obj_events, obj_event);
2331 }
2332
2333 obj_add_array(r, "events", obj_events)json_object_object_add(r, "events", obj_events);
2334}
2335
2336static void json_nvme_fdp_ruh_status(struct nvme_fdp_ruh_status *status, size_t len)
2337{
2338 struct json_object *r, *obj_ruhss;
2339 uint16_t nruhsd;
2340
2341 r = json_r;
2342 obj_ruhss = json_create_array()json_object_new_array();
2343
2344 nruhsd = le16_to_cpu(status->nruhsd);
2345
2346 obj_add_uint(r, "nruhsd", nruhsd)json_object_object_add(r, "nruhsd", json_object_new_uint64(nruhsd
))
;
2347
2348 nruhsd = nvme_log_nr_entries(nruhsd, len, sizeof(*status),
2349 sizeof(status->ruhss[0]));
2350 for (unsigned int i = 0; i < nruhsd; i++) {
2351 struct nvme_fdp_ruh_status_desc *ruhs = &status->ruhss[i];
2352
2353 struct json_object *obj_ruhs = json_create_object()json_object_new_object();
2354
2355 obj_add_uint(obj_ruhs, "pid", le16_to_cpu(ruhs->pid))json_object_object_add(obj_ruhs, "pid", json_object_new_uint64
(le16_to_cpu(ruhs->pid)))
;
2356 obj_add_uint(obj_ruhs, "ruhid", le16_to_cpu(ruhs->ruhid))json_object_object_add(obj_ruhs, "ruhid", json_object_new_uint64
(le16_to_cpu(ruhs->ruhid)))
;
2357 obj_add_uint(obj_ruhs, "earutr", le32_to_cpu(ruhs->earutr))json_object_object_add(obj_ruhs, "earutr", json_object_new_uint64
(le32_to_cpu(ruhs->earutr)))
;
2358 obj_add_uint64(obj_ruhs, "ruamw", le64_to_cpu(ruhs->ruamw))json_object_object_add(obj_ruhs, "ruamw", json_object_new_uint64
(le64_to_cpu(ruhs->ruamw)))
;
2359
2360 array_add_obj(obj_ruhss, obj_ruhs)json_object_array_add(obj_ruhss, obj_ruhs);
2361 }
2362
2363 obj_add_array(r, "ruhss", obj_ruhss)json_object_object_add(r, "ruhss", obj_ruhss);
2364}
2365
2366static unsigned int json_print_nvme_subsystem_multipath(struct libnvme_subsystem *s, json_object *paths)
2367{
2368 struct libnvme_ns *n;
2369 struct libnvme_path *p;
2370 unsigned int i = 0;
2371
2372 n = libnvme_subsystem_first_ns(s);
2373 if (!n)
2374 return 0;
2375
2376 libnvme_namespace_for_each_path(n, p)for (p = libnvme_namespace_first_path(n); p != ((void*)0); p =
libnvme_namespace_next_path(n, p))
{
2377 struct json_object *path_attrs;
2378 struct libnvme_ctrl *c = libnvme_path_get_ctrl(p);
2379 const char *ana_state;
2380
2381 libnvme_path_get_ana_state(p, &ana_state, "");
2382 path_attrs = json_create_object()json_object_new_object();
2383 obj_add_strjson_object_add_value_string(path_attrs, "Name", libnvme_ctrl_get_name(c));
2384 obj_add_strjson_object_add_value_string(path_attrs, "Transport", libnvme_ctrl_get_transport(c));
2385 obj_add_ctrl_address(path_attrs, c);
2386 obj_add_ctrl_address_details(path_attrs, "AddressDetails", c);
2387 obj_add_strjson_object_add_value_string(path_attrs, "State", libnvme_ctrl_get_state(c));
2388 obj_add_strjson_object_add_value_string(path_attrs, "ANAState", ana_state);
2389 array_add_obj(paths, path_attrs)json_object_array_add(paths, path_attrs);
2390 i++;
2391 }
2392
2393 return i;
2394}
2395
2396static void json_print_nvme_subsystem_ctrls(struct libnvme_subsystem *s,
2397 json_object *paths)
2398{
2399 struct libnvme_ctrl *c;
2400
2401 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
2402 struct json_object *path_attrs;
2403
2404 path_attrs = json_create_object()json_object_new_object();
2405 obj_add_strjson_object_add_value_string(path_attrs, "Name", libnvme_ctrl_get_name(c));
2406 obj_add_strjson_object_add_value_string(path_attrs, "Transport", libnvme_ctrl_get_transport(c));
2407 obj_add_ctrl_address(path_attrs, c);
2408 obj_add_ctrl_address_details(path_attrs, "AddressDetails", c);
2409 obj_add_strjson_object_add_value_string(path_attrs, "State", libnvme_ctrl_get_state(c));
2410 array_add_obj(paths, path_attrs)json_object_array_add(paths, path_attrs);
2411 }
2412}
2413
2414static void json_print_nvme_subsystem_list(struct libnvme_global_ctx *ctx,
2415 bool_Bool show_ana)
2416{
2417 struct json_object *host_attrs, *subsystem_attrs;
2418 struct json_object *subsystems, *paths;
2419 struct json_object *a = json_create_array()json_object_new_array();
2420 struct libnvme_host *h;
2421
2422 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
{
2423 struct libnvme_subsystem *s;
2424 const char *hostid;
2425
2426 host_attrs = json_create_object()json_object_new_object();
2427 obj_add_strjson_object_add_value_string(host_attrs, "HostNQN", libnvme_host_get_hostnqn(h));
2428 hostid = libnvme_host_get_hostid(h);
2429 if (hostid)
2430 obj_add_strjson_object_add_value_string(host_attrs, "HostID", hostid);
2431 subsystems = json_create_array()json_object_new_array();
2432 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
{
2433 struct libnvme_ctrl *c;
2434 bool_Bool no_ctrl = true1;
2435
2436 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
2437 no_ctrl = false0;
2438 if (no_ctrl)
2439 continue;
2440
2441 subsystem_attrs = json_create_object()json_object_new_object();
2442 obj_add_strjson_object_add_value_string(subsystem_attrs, "Name", libnvme_subsystem_get_name(s));
2443 obj_add_strjson_object_add_value_string(subsystem_attrs, "NQN", libnvme_subsystem_get_subsysnqn(s));
2444
2445 if (verbose_mode()) {
2446 const char *model;
2447 const char *serial;
2448 const char *firmware;
2449 const char *iopolicy;
2450
2451 libnvme_subsystem_get_model(s, &model, "");
2452 libnvme_subsystem_get_serial(s, &serial, "");
2453 libnvme_subsystem_get_firmware(s, &firmware,
2454 "");
2455 libnvme_subsystem_get_iopolicy(s, &iopolicy,
2456 "");
2457
2458 obj_add_strjson_object_add_value_string(subsystem_attrs, "Model", model);
2459 obj_add_strjson_object_add_value_string(subsystem_attrs, "Serial", serial);
2460 obj_add_strjson_object_add_value_string(subsystem_attrs, "Firmware",
2461 firmware);
2462 obj_add_strjson_object_add_value_string(subsystem_attrs, "IOPolicy",
2463 iopolicy);
2464 obj_add_strjson_object_add_value_string(subsystem_attrs, "Type",
2465 libnvme_subsystem_get_subsystype(s));
2466 }
2467
2468 array_add_obj(subsystems, subsystem_attrs)json_object_array_add(subsystems, subsystem_attrs);
2469 paths = json_create_array()json_object_new_array();
2470
2471 if (!show_ana || !json_print_nvme_subsystem_multipath(s, paths))
2472 json_print_nvme_subsystem_ctrls(s, paths);
2473
2474 obj_add_array(subsystem_attrs, "Paths", paths)json_object_object_add(subsystem_attrs, "Paths", paths);
2475 }
2476 obj_add_array(host_attrs, "Subsystems", subsystems)json_object_object_add(host_attrs, "Subsystems", subsystems);
2477 array_add_obj(a, host_attrs)json_object_array_add(a, host_attrs);
2478 }
2479
2480 json_print(a);
2481}
2482
2483/* Adds the fields @fields of @value to @o, decoded, under their names */
2484void json_bitfields(struct json_object *o, const struct bitfield *fields,
2485 unsigned int nr, uint64_t value)
2486{
2487 char buf[128];
2488 unsigned int i;
2489
2490 for (i = 0; i < nr; i++) {
2491 bitfield_str(&fields[i], value, buf, sizeof(buf));
2492 obj_add_strjson_object_add_value_string(o, fields[i].name, buf);
2493 }
2494}
2495
2496/*
2497 * The same for each style: the value of each register under its symbol,
2498 * with -v an object of the value and its fields.
2499 */
2500static void json_ctrl_registers(const struct nvme_reg_val *vals,
2501 unsigned int nr,
2502 enum nvme_regs_style style __shr_unused__attribute__((__unused__)))
2503{
2504 struct json_object *r = json_r;
2505 struct json_object *o;
2506 unsigned int i;
2507
2508 for (i = 0; i < nr; i++) {
2509 const struct nvme_reg *reg = vals[i].reg;
2510
2511 if (!verbose_mode()) {
2512 obj_add_uint64(r, reg->sym, vals[i].value)json_object_object_add(r, reg->sym, json_object_new_uint64
(vals[i].value))
;
2513 continue;
2514 }
2515
2516 o = json_create_object()json_object_new_object();
2517 obj_add_uint64(o, "value", vals[i].value)json_object_object_add(o, "value", json_object_new_uint64(vals
[i].value))
;
2518 json_bitfields(o, reg->fields, reg->nr_fields, vals[i].value);
2519 obj_add_obj(r, reg->sym, o)json_object_object_add(r, reg->sym, o);
2520 }
2521}
2522
2523static void json_nvme_cmd_set_independent_id_ns(struct nvme_id_independent_id_ns *ns,
2524 unsigned int nsid)
2525{
2526 struct json_object *r = json_r;
2527
2528 obj_add_int(r, "nsfeat", ns->nsfeat)json_object_object_add(r, "nsfeat", json_object_new_int(ns->
nsfeat))
;
2529 obj_add_int(r, "nmic", ns->nmic)json_object_object_add(r, "nmic", json_object_new_int(ns->
nmic))
;
2530 obj_add_int(r, "rescap", ns->rescap)json_object_object_add(r, "rescap", json_object_new_int(ns->
rescap))
;
2531 obj_add_int(r, "fpi", ns->fpi)json_object_object_add(r, "fpi", json_object_new_int(ns->fpi
))
;
2532 obj_add_uint(r, "anagrpid", le32_to_cpu(ns->anagrpid))json_object_object_add(r, "anagrpid", json_object_new_uint64(
le32_to_cpu(ns->anagrpid)))
;
2533 obj_add_int(r, "nsattr", ns->nsattr)json_object_object_add(r, "nsattr", json_object_new_int(ns->
nsattr))
;
2534 obj_add_int(r, "nvmsetid", le16_to_cpu(ns->nvmsetid))json_object_object_add(r, "nvmsetid", json_object_new_int(le16_to_cpu
(ns->nvmsetid)))
;
2535 obj_add_int(r, "endgid", le16_to_cpu(ns->endgid))json_object_object_add(r, "endgid", json_object_new_int(le16_to_cpu
(ns->endgid)))
;
2536 obj_add_int(r, "nstat", ns->nstat)json_object_object_add(r, "nstat", json_object_new_int(ns->
nstat))
;
2537 obj_add_int(r, "kpios", ns->kpios)json_object_object_add(r, "kpios", json_object_new_int(ns->
kpios))
;
2538 obj_add_int(r, "maxkt", le16_to_cpu(ns->maxkt))json_object_object_add(r, "maxkt", json_object_new_int(le16_to_cpu
(ns->maxkt)))
;
2539 obj_add_int(r, "rgrpid", le32_to_cpu(ns->rgrpid))json_object_object_add(r, "rgrpid", json_object_new_int(le32_to_cpu
(ns->rgrpid)))
;
2540}
2541
2542static void json_nvme_id_ns_descs(void *data, unsigned int nsid)
2543{
2544 /* large enough to hold uuid str (37) or nguid str (32) + zero byte */
2545 char json_str[STR_LEN100];
2546 char *json_str_p;
2547 union {
2548 __u8 eui64[NVME_NIDT_EUI64_LEN];
2549 __u8 nguid[NVME_NIDT_NGUID_LEN];
2550 __u8 uuid[NVME_UUID_LEN16];
2551 __u8 csi;
2552 } desc;
2553 struct json_object *r = json_r;
2554 struct json_object *json_array = NULL((void*)0);
2555 struct nvme_ns_id_desc *cur;
2556 size_t pos, off;
2557 int i;
2558
2559 for (pos = 0; (cur = nvme_ns_id_desc(data, pos));
2560 pos += sizeof(*cur) + cur->nidl) {
2561 const char *nidt_name = NULL((void*)0);
2562
2563 memset(json_str, 0, sizeof(json_str));
2564 json_str_p = json_str;
2565 off = pos + sizeof(*cur);
2566
2567 switch (nvme_ns_id_desc_type(cur)) {
2568 case NVME_NIDT_EUI64:
2569 memcpy(desc.eui64, data + off, sizeof(desc.eui64));
2570 for (i = 0; i < sizeof(desc.eui64); i++)
2571 json_str_p += sprintf(json_str_p, "%02x", desc.eui64[i]);
2572 nidt_name = "eui64";
2573 break;
2574 case NVME_NIDT_NGUID:
2575 memcpy(desc.nguid, data + off, sizeof(desc.nguid));
2576 for (i = 0; i < sizeof(desc.nguid); i++)
2577 json_str_p += sprintf(json_str_p, "%02x", desc.nguid[i]);
2578 nidt_name = "nguid";
2579 break;
2580 case NVME_NIDT_UUID:
2581 memcpy(desc.uuid, data + off, sizeof(desc.uuid));
2582 libnvme_uuid_to_string(desc.uuid, json_str);
2583 nidt_name = "uuid";
2584 break;
2585 case NVME_NIDT_CSI:
2586 memcpy(&desc.csi, data + off, sizeof(desc.csi));
2587 sprintf(json_str_p, "%#x", desc.csi);
2588 nidt_name = "csi";
2589 break;
2590 default:
2591 /* Skip unknown types */
2592 break;
2593 }
2594
2595 if (nidt_name) {
2596 struct json_object *elem = json_create_object()json_object_new_object();
2597
2598 obj_add_int(elem, "loc", pos)json_object_object_add(elem, "loc", json_object_new_int(pos));
2599 obj_add_int(elem, "nidt", (int)cur->nidt)json_object_object_add(elem, "nidt", json_object_new_int((int
)cur->nidt))
;
2600 obj_add_int(elem, "nidl", (int)cur->nidl)json_object_object_add(elem, "nidl", json_object_new_int((int
)cur->nidl))
;
2601 obj_add_strjson_object_add_value_string(elem, "Type", nidt_name);
2602 obj_add_strjson_object_add_value_string(elem, nidt_name, json_str);
2603
2604 if (!json_array)
2605 json_array = json_create_array()json_object_new_array();
2606 array_add_obj(json_array, elem)json_object_array_add(json_array, elem);
2607 }
2608 }
2609
2610 if (json_array)
2611 obj_add_array(r, "ns-descs", json_array)json_object_object_add(r, "ns-descs", json_array);
2612}
2613
2614static void json_nvme_id_ctrl_nvm(struct nvme_id_ctrl_nvm *ctrl_nvm)
2615{
2616 struct json_object *r = json_r;
2617
2618 obj_add_uint(r, "vsl", ctrl_nvm->vsl)json_object_object_add(r, "vsl", json_object_new_uint64(ctrl_nvm
->vsl))
;
2619 obj_add_uint(r, "wzsl", ctrl_nvm->wzsl)json_object_object_add(r, "wzsl", json_object_new_uint64(ctrl_nvm
->wzsl))
;
2620 obj_add_uint(r, "wusl", ctrl_nvm->wusl)json_object_object_add(r, "wusl", json_object_new_uint64(ctrl_nvm
->wusl))
;
2621 obj_add_uint(r, "dmrl", ctrl_nvm->dmrl)json_object_object_add(r, "dmrl", json_object_new_uint64(ctrl_nvm
->dmrl))
;
2622 obj_add_uint(r, "dmrsl", le32_to_cpu(ctrl_nvm->dmrsl))json_object_object_add(r, "dmrsl", json_object_new_uint64(le32_to_cpu
(ctrl_nvm->dmrsl)))
;
2623 obj_add_uint64(r, "dmsl", le64_to_cpu(ctrl_nvm->dmsl))json_object_object_add(r, "dmsl", json_object_new_uint64(le64_to_cpu
(ctrl_nvm->dmsl)))
;
2624 obj_add_uint(r, "kpiocap", ctrl_nvm->kpiocap)json_object_object_add(r, "kpiocap", json_object_new_uint64(ctrl_nvm
->kpiocap))
;
2625 obj_add_uint(r, "wzdsl", ctrl_nvm->wzdsl)json_object_object_add(r, "wzdsl", json_object_new_uint64(ctrl_nvm
->wzdsl))
;
2626 obj_add_uint(r, "aocs", le16_to_cpu(ctrl_nvm->aocs))json_object_object_add(r, "aocs", json_object_new_uint64(le16_to_cpu
(ctrl_nvm->aocs)))
;
2627
2628 if (verbose_mode()) {
2629 __u16 rsvd = (ctrl_nvm->aocs & 0xfffe) >> 1;
2630 __u8 ralbas = ctrl_nvm->aocs & 0x1;
2631
2632 if (rsvd)
2633 obj_add_uint(r, "[15:1]: Reserved", rsvd)json_object_object_add(r, "[15:1]: Reserved", json_object_new_uint64
(rsvd))
;
2634 obj_add_uint(r, "[0:0]: Reporting Allocated LBA Supported", ralbas)json_object_object_add(r, "[0:0]: Reporting Allocated LBA Supported"
, json_object_new_uint64(ralbas))
;
2635 }
2636
2637 obj_add_uint(r, "ver", le32_to_cpu(ctrl_nvm->ver))json_object_object_add(r, "ver", json_object_new_uint64(le32_to_cpu
(ctrl_nvm->ver)))
;
2638 obj_add_uint(r, "lbamqf", ctrl_nvm->lbamqf)json_object_object_add(r, "lbamqf", json_object_new_uint64(ctrl_nvm
->lbamqf))
;
2639}
2640
2641static void json_nvme_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns,
2642 unsigned int nsid, struct nvme_id_ns *ns,
2643 unsigned int lba_index, bool_Bool cap_only)
2644
2645{
2646 struct json_object *r = json_r;
2647 struct json_object *elbafs = json_create_array()json_object_new_array();
2648 int i;
2649
2650 if (!cap_only)
2651 obj_add_uint64(r, "lbstm", le64_to_cpu(nvm_ns->lbstm))json_object_object_add(r, "lbstm", json_object_new_uint64(le64_to_cpu
(nvm_ns->lbstm)))
;
2652
2653 obj_add_int(r, "pic", nvm_ns->pic)json_object_object_add(r, "pic", json_object_new_int(nvm_ns->
pic))
;
2654 obj_add_int(r, "pifa", nvm_ns->pifa)json_object_object_add(r, "pifa", json_object_new_int(nvm_ns->
pifa))
;
2655
2656 obj_add_array(r, "elbafs", elbafs)json_object_object_add(r, "elbafs", elbafs);
2657
2658 for (i = 0; i < nvme_id_ns_nr_lbaf(ns); i++) {
2659 struct json_object *elbaf = json_create_object()json_object_new_object();
2660 unsigned int elbaf_val = le32_to_cpu(nvm_ns->elbaf[i]);
2661
2662 obj_add_uint(elbaf, "sts", elbaf_val & 0x7F)json_object_object_add(elbaf, "sts", json_object_new_uint64(elbaf_val
& 0x7F))
;
2663 obj_add_uint(elbaf, "pif", (elbaf_val >> 7) & 0x3)json_object_object_add(elbaf, "pif", json_object_new_uint64((
elbaf_val >> 7) & 0x3))
;
2664 obj_add_uint(elbaf, "qpif", (elbaf_val >> 9) & 0xF)json_object_object_add(elbaf, "qpif", json_object_new_uint64(
(elbaf_val >> 9) & 0xF))
;
2665
2666 array_add_obj(elbafs, elbaf)json_object_array_add(elbafs, elbaf);
2667 }
2668 if (ns->nsfeat & 0x20)
2669 obj_add_int(r, "npdgl", le32_to_cpu(nvm_ns->npdgl))json_object_object_add(r, "npdgl", json_object_new_int(le32_to_cpu
(nvm_ns->npdgl)))
;
2670
2671 obj_add_uint(r, "nprg", le32_to_cpu(nvm_ns->nprg))json_object_object_add(r, "nprg", json_object_new_uint64(le32_to_cpu
(nvm_ns->nprg)))
;
2672 obj_add_uint(r, "npra", le32_to_cpu(nvm_ns->npra))json_object_object_add(r, "npra", json_object_new_uint64(le32_to_cpu
(nvm_ns->npra)))
;
2673 obj_add_uint(r, "nors", le32_to_cpu(nvm_ns->nors))json_object_object_add(r, "nors", json_object_new_uint64(le32_to_cpu
(nvm_ns->nors)))
;
2674 obj_add_uint(r, "npdal", le32_to_cpu(nvm_ns->npdal))json_object_object_add(r, "npdal", json_object_new_uint64(le32_to_cpu
(nvm_ns->npdal)))
;
2675 obj_add_uint(r, "lbapss", le32_to_cpu(nvm_ns->lbapss))json_object_object_add(r, "lbapss", json_object_new_uint64(le32_to_cpu
(nvm_ns->lbapss)))
;
2676 obj_add_uint(r, "tlbaag", le32_to_cpu(nvm_ns->tlbaag))json_object_object_add(r, "tlbaag", json_object_new_uint64(le32_to_cpu
(nvm_ns->tlbaag)))
;
2677}
2678
2679static void json_nvme_zns_id_ctrl(struct nvme_zns_id_ctrl *ctrl)
2680{
2681 struct json_object *r = json_r;
2682
2683 obj_add_int(r, "zasl", ctrl->zasl)json_object_object_add(r, "zasl", json_object_new_int(ctrl->
zasl))
;
2684}
2685
2686static void json_nvme_zns_id_ns(struct nvme_zns_id_ns *ns,
2687 struct nvme_id_ns *id_ns)
2688{
2689 struct json_object *r = json_r;
2690 struct json_object *lbafs = json_create_array()json_object_new_array();
2691 int i;
2692
2693 obj_add_int(r, "zoc", le16_to_cpu(ns->zoc))json_object_object_add(r, "zoc", json_object_new_int(le16_to_cpu
(ns->zoc)))
;
2694 obj_add_int(r, "ozcs", le16_to_cpu(ns->ozcs))json_object_object_add(r, "ozcs", json_object_new_int(le16_to_cpu
(ns->ozcs)))
;
2695 obj_add_uint(r, "mar", le32_to_cpu(ns->mar))json_object_object_add(r, "mar", json_object_new_uint64(le32_to_cpu
(ns->mar)))
;
2696 obj_add_uint(r, "mor", le32_to_cpu(ns->mor))json_object_object_add(r, "mor", json_object_new_uint64(le32_to_cpu
(ns->mor)))
;
2697 obj_add_uint(r, "rrl", le32_to_cpu(ns->rrl))json_object_object_add(r, "rrl", json_object_new_uint64(le32_to_cpu
(ns->rrl)))
;
2698 obj_add_uint(r, "frl", le32_to_cpu(ns->frl))json_object_object_add(r, "frl", json_object_new_uint64(le32_to_cpu
(ns->frl)))
;
2699 obj_add_uint(r, "rrl1", le32_to_cpu(ns->rrl1))json_object_object_add(r, "rrl1", json_object_new_uint64(le32_to_cpu
(ns->rrl1)))
;
2700 obj_add_uint(r, "rrl2", le32_to_cpu(ns->rrl2))json_object_object_add(r, "rrl2", json_object_new_uint64(le32_to_cpu
(ns->rrl2)))
;
2701 obj_add_uint(r, "rrl3", le32_to_cpu(ns->rrl3))json_object_object_add(r, "rrl3", json_object_new_uint64(le32_to_cpu
(ns->rrl3)))
;
2702 obj_add_uint(r, "frl1", le32_to_cpu(ns->frl1))json_object_object_add(r, "frl1", json_object_new_uint64(le32_to_cpu
(ns->frl1)))
;
2703 obj_add_uint(r, "frl2", le32_to_cpu(ns->frl2))json_object_object_add(r, "frl2", json_object_new_uint64(le32_to_cpu
(ns->frl2)))
;
2704 obj_add_uint(r, "frl3", le32_to_cpu(ns->frl3))json_object_object_add(r, "frl3", json_object_new_uint64(le32_to_cpu
(ns->frl3)))
;
2705 obj_add_uint(r, "numzrwa", le32_to_cpu(ns->numzrwa))json_object_object_add(r, "numzrwa", json_object_new_uint64(le32_to_cpu
(ns->numzrwa)))
;
2706 obj_add_int(r, "zrwafg", le16_to_cpu(ns->zrwafg))json_object_object_add(r, "zrwafg", json_object_new_int(le16_to_cpu
(ns->zrwafg)))
;
2707 obj_add_int(r, "zrwasz", le16_to_cpu(ns->zrwasz))json_object_object_add(r, "zrwasz", json_object_new_int(le16_to_cpu
(ns->zrwasz)))
;
2708 obj_add_int(r, "zrwacap", ns->zrwacap)json_object_object_add(r, "zrwacap", json_object_new_int(ns->
zrwacap))
;
2709
2710 obj_add_array(r, "lbafe", lbafs)json_object_object_add(r, "lbafe", lbafs);
2711
2712 for (i = 0; i <= id_ns->nlbaf && i < ARRAY_SIZE(ns->lbafe)(sizeof(ns->lbafe) / sizeof((ns->lbafe)[0]) + 0); i++) {
2713 struct json_object *lbaf = json_create_object()json_object_new_object();
2714
2715 obj_add_uint64(lbaf, "zsze", le64_to_cpu(ns->lbafe[i].zsze))json_object_object_add(lbaf, "zsze", json_object_new_uint64(le64_to_cpu
(ns->lbafe[i].zsze)))
;
2716 obj_add_int(lbaf, "zdes", ns->lbafe[i].zdes)json_object_object_add(lbaf, "zdes", json_object_new_int(ns->
lbafe[i].zdes))
;
2717
2718 array_add_obj(lbafs, lbaf)json_object_array_add(lbafs, lbaf);
2719 }
2720}
2721
2722static void json_nvme_list_ns(struct nvme_ns_list *ns_list)
2723{
2724 struct json_object *r = json_r;
2725 struct json_object *valid_attrs;
2726 struct json_object *valid = json_create_array()json_object_new_array();
2727 int i;
2728
2729 for (i = 0; i < 1024; i++) {
2730 if (ns_list->ns[i]) {
2731 valid_attrs = json_create_object()json_object_new_object();
2732 obj_add_uint(valid_attrs, "nsid", le32_to_cpu(ns_list->ns[i]))json_object_object_add(valid_attrs, "nsid", json_object_new_uint64
(le32_to_cpu(ns_list->ns[i])))
;
2733 array_add_obj(valid, valid_attrs)json_object_array_add(valid, valid_attrs);
2734 }
2735 }
2736
2737 obj_add_array(r, "nsid_list", valid)json_object_object_add(r, "nsid_list", valid);
2738}
2739
2740static void json_zns_start_zone_list(__u64 nr_zones, struct json_object **zone_list)
2741{
2742 *zone_list = json_create_array()json_object_new_array();
2743}
2744
2745static void json_zns_changed(struct nvme_zns_changed_zone_log *log)
2746{
2747 struct json_object *r = json_r;
2748 char json_str[STR_LEN100];
2749 uint16_t nrzid = le16_to_cpu(log->nrzid);
2750 int i;
2751
2752 if (nrzid == 0xFFFF) {
2753 obj_add_result(r, "Too many zones have changed to fit into the log. Use report zones for changes.");
2754 } else {
2755 obj_add_uint(r, "nrzid", nrzid)json_object_object_add(r, "nrzid", json_object_new_uint64(nrzid
))
;
2756 for (i = 0; i < nrzid && i < ARRAY_SIZE(log->zid)(sizeof(log->zid) / sizeof((log->zid)[0]) + 0); i++) {
2757 sprintf(json_str, "zid %03d", i);
2758 obj_add_uint64(r, json_str, (uint64_t)le64_to_cpu(log->zid[i]))json_object_object_add(r, json_str, json_object_new_uint64((uint64_t
)le64_to_cpu(log->zid[i])))
;
2759 }
2760 }
2761}
2762
2763static void json_zns_finish_zone_list(__u64 nr_zones,
2764 struct json_object *zone_list)
2765{
2766 struct json_object *r = json_r;
2767
2768 obj_add_uint(r, "nr_zones", nr_zones)json_object_object_add(r, "nr_zones", json_object_new_uint64(
nr_zones))
;
2769 obj_add_array(r, "zone_list", zone_list)json_object_object_add(r, "zone_list", zone_list);
2770}
2771
2772static void json_nvme_zns_report_zones(void *report, __u32 descs,
2773 __u8 ext_size, __u32 report_size,
2774 struct json_object *zone_list)
2775{
2776 struct json_object *zone;
2777 struct json_object *ext_data;
2778 struct nvme_zone_report *r = report;
2779 struct nvme_zns_desc *desc;
2780 int i;
2781
2782 for (i = 0; i < descs; i++) {
2783 desc = (struct nvme_zns_desc *)
2784 (report + sizeof(*r) + i * (sizeof(*desc) + ext_size));
2785 zone = json_create_object()json_object_new_object();
2786
2787 obj_add_uint64(zone, "slba", le64_to_cpu(desc->zslba))json_object_object_add(zone, "slba", json_object_new_uint64(le64_to_cpu
(desc->zslba)))
;
2788 obj_add_uint64(zone, "wp", le64_to_cpu(desc->wp))json_object_object_add(zone, "wp", json_object_new_uint64(le64_to_cpu
(desc->wp)))
;
2789 obj_add_uint64(zone, "cap", le64_to_cpu(desc->zcap))json_object_object_add(zone, "cap", json_object_new_uint64(le64_to_cpu
(desc->zcap)))
;
2790 obj_add_strjson_object_add_value_string(zone, "state", nvme_zone_state_to_string(desc->zs >> 4));
2791 obj_add_strjson_object_add_value_string(zone, "type", nvme_zone_type_to_string(desc->zt));
2792 obj_add_uint(zone, "attrs", desc->za)json_object_object_add(zone, "attrs", json_object_new_uint64(
desc->za))
;
2793 obj_add_uint(zone, "attrs_info", desc->zai)json_object_object_add(zone, "attrs_info", json_object_new_uint64
(desc->zai))
;
2794
2795 if (ext_size) {
2796 if (desc->za & NVME_ZNS_ZA_ZDEV) {
2797 ext_data = json_create_array()json_object_new_array();
2798 d_json((unsigned char *)desc + sizeof(*desc),
2799 ext_size, 16, 1, ext_data);
2800 obj_add_array(zone, "ext_data", ext_data)json_object_object_add(zone, "ext_data", ext_data);
2801 } else {
2802 obj_add_strjson_object_add_value_string(zone, "ext_data", "Not valid");
2803 }
2804 }
2805
2806 array_add_obj(zone_list, zone)json_object_array_add(zone_list, zone);
2807 }
2808}
2809
2810static void json_feature_show_fields_arbitration(struct json_object *r, unsigned int result)
2811{
2812 char json_str[STR_LEN100];
2813
2814 obj_add_uint(r, "High Priority Weight (HPW)", ((result & 0xff000000) >> 24) + 1)json_object_object_add(r, "High Priority Weight (HPW)", json_object_new_uint64
(((result & 0xff000000) >> 24) + 1))
;
2815 obj_add_uint(r, "Medium Priority Weight (MPW)", ((result & 0xff0000) >> 16) + 1)json_object_object_add(r, "Medium Priority Weight (MPW)", json_object_new_uint64
(((result & 0xff0000) >> 16) + 1))
;
2816 obj_add_uint(r, "Low Priority Weight (LPW)", ((result & 0xff00) >> 8) + 1)json_object_object_add(r, "Low Priority Weight (LPW)", json_object_new_uint64
(((result & 0xff00) >> 8) + 1))
;
2817
2818 if ((result & 7) == 7)
2819 sprintf(json_str, "No limit");
2820 else
2821 sprintf(json_str, "%u", 1 << (result & 7));
2822
2823 obj_add_strjson_object_add_value_string(r, "Arbitration Burst (AB)", json_str);
2824}
2825
2826static void json_feature_show_fields_power_mgmt(struct json_object *r, unsigned int result)
2827{
2828 __u8 field = (result & 0xe0) >> 5;
2829
2830 obj_add_uint(r, "Workload Hint (WH)", field)json_object_object_add(r, "Workload Hint (WH)", json_object_new_uint64
(field))
;
2831 obj_add_strjson_object_add_value_string(r, "WH description", nvme_feature_wl_hints_to_string(field));
2832 obj_add_uint(r, "Power State (PS)", result & 0x1f)json_object_object_add(r, "Power State (PS)", json_object_new_uint64
(result & 0x1f))
;
2833 obj_add_uint(r, "Idle I/O Exit Latency Limit (IIELL)",json_object_object_add(r, "Idle I/O Exit Latency Limit (IIELL)"
, json_object_new_uint64((((result) >> NVME_FEAT_PWRMGMT_IIELL_SHIFT
) & NVME_FEAT_PWRMGMT_IIELL_MASK)))
2834 NVME_FEAT_PM_IIELL(result))json_object_object_add(r, "Idle I/O Exit Latency Limit (IIELL)"
, json_object_new_uint64((((result) >> NVME_FEAT_PWRMGMT_IIELL_SHIFT
) & NVME_FEAT_PWRMGMT_IIELL_MASK)))
;
2835}
2836
2837static void json_lba_range_entry(struct nvme_lba_range_type *lbrt, int nr_ranges,
2838 struct json_object *r)
2839{
2840 char json_str[STR_LEN100];
2841 struct json_object *lbare;
2842 int i;
2843 int j;
2844 struct json_object *lbara = json_create_array()json_object_new_array();
2845
2846 obj_add_array(r, "LBA Ranges", lbara)json_object_object_add(r, "LBA Ranges", lbara);
2847
2848 for (i = 0; i <= nr_ranges; i++) {
2849 lbare = json_create_object()json_object_new_object();
2850 array_add_obj(lbara, lbare)json_object_array_add(lbara, lbare);
2851
2852 obj_add_int(lbare, "LBA range", i)json_object_object_add(lbare, "LBA range", json_object_new_int
(i))
;
2853
2854 obj_add_uint_nx(lbare, "type", lbrt->entry[i].type);
2855
2856 obj_add_strjson_object_add_value_string(lbare, "type description",
2857 nvme_feature_lba_type_to_string(lbrt->entry[i].type));
2858
2859 obj_add_uint_nx(lbare, "attributes", lbrt->entry[i].attributes);
2860
2861 obj_add_strjson_object_add_value_string(lbare, "attribute[0]", lbrt->entry[i].attributes & 1 ?
2862 "LBA range may be overwritten" : "LBA range should not be overwritten");
2863
2864 obj_add_strjson_object_add_value_string(lbare, "attribute[1]", lbrt->entry[i].attributes & 2 ?
2865 "LBA range should be hidden from the OS/EFI/BIOS" :
2866 "LBA range should be visible from the OS/EFI/BIOS");
2867
2868 obj_add_nprix64json_object_add_nprix64(lbare, "slba", le64_to_cpu(lbrt->entry[i].slba));
2869
2870 obj_add_nprix64json_object_add_nprix64(lbare, "nlb", le64_to_cpu(lbrt->entry[i].nlb));
2871
2872 for (j = 0; j < ARRAY_SIZE(lbrt->entry[i].guid)(sizeof(lbrt->entry[i].guid) / sizeof((lbrt->entry[i].guid
)[0]) + 0)
; j++)
2873 sprintf(&json_str[j * 2], "%02x", lbrt->entry[i].guid[j]);
2874
2875 obj_add_strjson_object_add_value_string(lbare, "guid", json_str);
2876 }
2877}
2878
2879static void json_feature_show_fields_lba_range(struct json_object *r, __u8 field,
2880 unsigned char *buf)
2881{
2882 obj_add_uint(r, "Number of LBA Ranges (NUM)", field + 1)json_object_object_add(r, "Number of LBA Ranges (NUM)", json_object_new_uint64
(field + 1))
;
2883
2884 if (buf)
2885 json_lba_range_entry((struct nvme_lba_range_type *)buf, field, r);
2886}
2887
2888static void json_feature_show_fields_temp_thresh(struct json_object *r, unsigned int result)
2889{
2890 char json_str[STR_LEN100];
2891 __u8 field;
2892
2893 field = (result & 0x1c00000) >> 22;
2894 sprintf(json_str, "%s", nvme_degrees_string(field));
2895 obj_add_strjson_object_add_value_string(r, "Temperature Threshold Hysteresis (TMPTHH)", json_str);
2896
2897 sprintf(json_str, "%u K", field);
2898 obj_add_strjson_object_add_value_string(r, "TMPTHH kelvin", json_str);
2899
2900 field = (result & 0x300000) >> 20;
2901 obj_add_uint(r, "Threshold Type Select (THSEL)", field)json_object_object_add(r, "Threshold Type Select (THSEL)", json_object_new_uint64
(field))
;
2902 obj_add_strjson_object_add_value_string(r, "THSEL description", nvme_feature_temp_type_to_string(field));
2903
2904 field = (result & 0xf0000) >> 16;
2905
2906 obj_add_uint(r, "Threshold Temperature Select (TMPSEL)", field)json_object_object_add(r, "Threshold Temperature Select (TMPSEL)"
, json_object_new_uint64(field))
;
2907 obj_add_strjson_object_add_value_string(r, "TMPSEL description", nvme_feature_temp_sel_to_string(field));
2908
2909 sprintf(json_str, "%s", nvme_degrees_string(result & 0xffff));
2910 obj_add_strjson_object_add_value_string(r, "Temperature Threshold (TMPTH)", json_str);
2911
2912 sprintf(json_str, "%u K", result & 0xffff);
2913 obj_add_strjson_object_add_value_string(r, "TMPTH kelvin", json_str);
2914}
2915
2916static void json_feature_show_fields_err_recovery(struct json_object *r, unsigned int result)
2917{
2918 char json_str[STR_LEN100];
2919
2920 obj_add_strjson_object_add_value_string(r, "Deallocated or Unwritten Logical Block Error Enable (DULBE)",
2921 (result & 0x10000) >> 16 ? "Enabled" : "Disabled");
2922
2923 sprintf(json_str, "%u ms", (result & 0xffff) * 100);
2924 obj_add_strjson_object_add_value_string(r, "Time Limited Error Recovery (TLER)", json_str);
2925}
2926
2927static void json_feature_show_fields_volatile_wc(struct json_object *r, unsigned int result)
2928{
2929 obj_add_strjson_object_add_value_string(r, "Volatile Write Cache Enable (WCE)", result & 1 ? "Enabled" : "Disabled");
2930}
2931
2932static void json_feature_show_fields_num_queues(struct json_object *r, unsigned int result)
2933{
2934 obj_add_uint(r, "Number of IO Completion Queues Allocated (NCQA)",json_object_object_add(r, "Number of IO Completion Queues Allocated (NCQA)"
, json_object_new_uint64(((result & 0xffff0000) >> 16
) + 1))
2935 ((result & 0xffff0000) >> 16) + 1)json_object_object_add(r, "Number of IO Completion Queues Allocated (NCQA)"
, json_object_new_uint64(((result & 0xffff0000) >> 16
) + 1))
;
2936 obj_add_uint(r, "Number of IO Submission Queues Allocated (NSQA)", (result & 0xffff) + 1)json_object_object_add(r, "Number of IO Submission Queues Allocated (NSQA)"
, json_object_new_uint64((result & 0xffff) + 1))
;
2937}
2938
2939static void json_feature_show_fields_irq_coalesce(struct json_object *r, unsigned int result)
2940{
2941 char json_str[STR_LEN100];
2942
2943 sprintf(json_str, "%u usec", ((result & 0xff00) >> 8) * 100);
2944 obj_add_strjson_object_add_value_string(r, "Aggregation Time (TIME)", json_str);
2945
2946 obj_add_uint(r, "Aggregation Threshold (THR)", (result & 0xff) + 1)json_object_object_add(r, "Aggregation Threshold (THR)", json_object_new_uint64
((result & 0xff) + 1))
;
2947}
2948
2949static void json_feature_show_fields_irq_config(struct json_object *r, unsigned int result)
2950{
2951 obj_add_strjson_object_add_value_string(r, "Coalescing Disable (CD)", (result & 0x10000) >> 16 ? "True" : "False");
2952 obj_add_uint(r, "Interrupt Vector (IV)", result & 0xffff)json_object_object_add(r, "Interrupt Vector (IV)", json_object_new_uint64
(result & 0xffff))
;
2953}
2954
2955static void json_feature_show_fields_write_atomic(struct json_object *r, unsigned int result)
2956{
2957 obj_add_strjson_object_add_value_string(r, "Disable Normal (DN)", result & 1 ? "True" : "False");
2958}
2959
2960static void json_feature_show_fields_async_event(struct json_object *r, unsigned int result)
2961{
2962 const char *async = "Send async event";
2963 const char *no_async = "Do not send async event";
2964
2965 obj_add_strjson_object_add_value_string(r, feat_ae_dlpcn,
2966 NVME_FEAT_AE_DLPCN(result)(((result) >> NVME_FEAT_AE_DLPCN_SHIFT) & NVME_FEAT_AE_DLPCN_MASK
)
? async : no_async);
2967 obj_add_strjson_object_add_value_string(r, feat_ae_hdlpcn,
2968 NVME_FEAT_AE_HDLPCN(result)(((result) >> NVME_FEAT_AE_HDLPCN_SHIFT) & NVME_FEAT_AE_HDLPCN_MASK
)
? async : no_async);
2969 obj_add_strjson_object_add_value_string(r, feat_ae_adlpcn,
2970 NVME_FEAT_AE_ADLPCN(result)(((result) >> NVME_FEAT_AE_ADLPCN_SHIFT) & NVME_FEAT_AE_ADLPCN_MASK
)
? async : no_async);
2971 obj_add_strjson_object_add_value_string(r, feat_ae_pmdrlpcn,
2972 NVME_FEAT_AE_PMDRLPCN(result)(((result) >> NVME_FEAT_AE_PMDRLPCN_SHIFT) & NVME_FEAT_AE_PMDRLPCN_MASK
)
? async : no_async);
2973 obj_add_strjson_object_add_value_string(r, feat_ae_zdcn,
2974 NVME_FEAT_AE_ZDCN(result)(((result) >> NVME_FEAT_AE_ZDCN_SHIFT) & NVME_FEAT_AE_ZDCN_MASK
)
? async : no_async);
2975 obj_add_strjson_object_add_value_string(r, feat_ae_tthry,
2976 NVME_FEAT_AE_TTHRY(result)(((result) >> NVME_FEAT_AE_TTHRY_SHIFT) & NVME_FEAT_AE_TTHRY_MASK
)
? async : no_async);
2977 obj_add_strjson_object_add_value_string(r, feat_ae_rlccn,
2978 NVME_FEAT_AE_RLCCN(result)(((result) >> NVME_FEAT_AE_RLCCN_SHIFT) & NVME_FEAT_AE_RLCCN_MASK
)
? async : no_async);
2979 obj_add_strjson_object_add_value_string(r, feat_ae_lhcn,
2980 NVME_FEAT_AE_LHCN(result)(((result) >> NVME_FEAT_AE_LHCN_SHIFT) & NVME_FEAT_AE_LHCN_MASK
)
? async : no_async);
2981 obj_add_strjson_object_add_value_string(r, feat_ae_ccrcn,
2982 NVME_FEAT_AE_CCRCN(result)(((result) >> NVME_FEAT_AE_CCRCN_SHIFT) & NVME_FEAT_AE_CCRCN_MASK
)
? async : no_async);
2983 obj_add_strjson_object_add_value_string(r, feat_ae_ansan,
2984 NVME_FEAT_AE_ANSAN(result)(((result) >> NVME_FEAT_AE_ANSAN_SHIFT) & NVME_FEAT_AE_ANSAN_MASK
)
? async : no_async);
2985 obj_add_strjson_object_add_value_string(r, feat_ae_rgrp0,
2986 NVME_FEAT_AE_RGRP0(result)(((result) >> NVME_FEAT_AE_RGRP0_SHIFT) & NVME_FEAT_AE_RGRP0_MASK
)
? async : no_async);
2987 obj_add_strjson_object_add_value_string(r, feat_ae_rassn,
2988 NVME_FEAT_AE_RASSN(result)(((result) >> NVME_FEAT_AE_RASSN_SHIFT) & NVME_FEAT_AE_RASSN_MASK
)
? async : no_async);
2989 obj_add_strjson_object_add_value_string(r, feat_ae_nnsshdn,
2990 NVME_FEAT_AE_NNSSHDN(result)(((result) >> NVME_FEAT_AE_NNSSHDN_SHIFT) & NVME_FEAT_AE_NNSSHDN_MASK
)
? async : no_async);
2991 obj_add_strjson_object_add_value_string(r, feat_ae_ega,
2992 NVME_FEAT_AE_EGA(result)(((result) >> NVME_FEAT_AE_EGA_SHIFT) & NVME_FEAT_AE_EGA_MASK
)
? async : no_async);
2993 obj_add_strjson_object_add_value_string(r, feat_ae_lbas,
2994 NVME_FEAT_AE_LBAS(result)(((result) >> NVME_FEAT_AE_LBAS_SHIFT) & NVME_FEAT_AE_LBAS_MASK
)
? async : no_async);
2995 obj_add_strjson_object_add_value_string(r, feat_ae_pla,
2996 NVME_FEAT_AE_PLA(result)(((result) >> NVME_FEAT_AE_PLA_SHIFT) & NVME_FEAT_AE_PLA_MASK
)
? async : no_async);
2997 obj_add_strjson_object_add_value_string(r, feat_ae_ana,
2998 NVME_FEAT_AE_ANA(result)(((result) >> NVME_FEAT_AE_ANA_SHIFT) & NVME_FEAT_AE_ANA_MASK
)
? async : no_async);
2999 obj_add_strjson_object_add_value_string(r, feat_ae_telem,
3000 NVME_FEAT_AE_TELEM(result)(((result) >> NVME_FEAT_AE_TELEM_SHIFT) & NVME_FEAT_AE_TELEM_MASK
)
? async : no_async);
3001 obj_add_strjson_object_add_value_string(r, feat_ae_fw, NVME_FEAT_AE_FW(result)(((result) >> NVME_FEAT_AE_FW_SHIFT) & NVME_FEAT_AE_FW_MASK
)
? async : no_async);
3002 obj_add_strjson_object_add_value_string(r, feat_ae_nan,
3003 NVME_FEAT_AE_NAN(result)(((result) >> NVME_FEAT_AE_NAN_SHIFT) & NVME_FEAT_AE_NAN_MASK
)
? async : no_async);
3004 obj_add_strjson_object_add_value_string(r, feat_ae_smart,
3005 NVME_FEAT_AE_SMART(result)(((result) >> NVME_FEAT_AE_SMART_SHIFT) & NVME_FEAT_AE_SMART_MASK
)
? async : no_async);
3006}
3007
3008static void json_auto_pst(struct nvme_feat_auto_pst *apst, struct json_object *r)
3009{
3010 int i;
3011 __u64 value;
3012 char json_str[STR_LEN100];
3013 struct json_object *apsta = json_create_array()json_object_new_array();
3014 struct json_object *apste;
3015
3016 obj_add_array(r, "Auto PST Entries", apsta)json_object_object_add(r, "Auto PST Entries", apsta);
3017
3018 for (i = 0; i < ARRAY_SIZE(apst->apst_entry)(sizeof(apst->apst_entry) / sizeof((apst->apst_entry)[0
]) + 0)
; i++) {
3019 apste = json_create_object()json_object_new_object();
3020 array_add_obj(apsta, apste)json_object_array_add(apsta, apste);
3021 sprintf(json_str, "%2d", i);
3022 obj_add_strjson_object_add_value_string(apste, "entry", json_str);
3023 value = le64_to_cpu(apst->apst_entry[i]);
3024 sprintf(json_str, "%u ms", (__u32)NVME_GET(value, APST_ENTRY_ITPT)(((value) >> NVME_APST_ENTRY_ITPT_SHIFT) & NVME_APST_ENTRY_ITPT_MASK
)
);
3025 obj_add_strjson_object_add_value_string(apste, "Idle Time Prior to Transition (ITPT)", json_str);
3026 obj_add_uint(apste, "Idle Transition Power State (ITPS)",json_object_object_add(apste, "Idle Transition Power State (ITPS)"
, json_object_new_uint64((__u32)(((value) >> NVME_APST_ENTRY_ITPS_SHIFT
) & NVME_APST_ENTRY_ITPS_MASK)))
3027 (__u32)NVME_GET(value, APST_ENTRY_ITPS))json_object_object_add(apste, "Idle Transition Power State (ITPS)"
, json_object_new_uint64((__u32)(((value) >> NVME_APST_ENTRY_ITPS_SHIFT
) & NVME_APST_ENTRY_ITPS_MASK)))
;
3028 }
3029}
3030
3031static void json_feature_show_fields_auto_pst(struct json_object *r, unsigned int result,
3032 unsigned char *buf)
3033{
3034 obj_add_strjson_object_add_value_string(r, "Autonomous Power State Transition Enable (APSTE)", result & 1 ? "Enabled" :
3035 "Disabled");
3036
3037 if (buf)
3038 json_auto_pst((struct nvme_feat_auto_pst *)buf, r);
3039}
3040
3041static void json_host_mem_buffer(struct nvme_host_mem_buf_attrs *hmb, struct json_object *r)
3042{
3043 char json_str[STR_LEN100];
3044
3045 obj_add_uint(r, "Host Memory Descriptor List Entry Count (HMDLEC)", le32_to_cpu(hmb->hmdlec))json_object_object_add(r, "Host Memory Descriptor List Entry Count (HMDLEC)"
, json_object_new_uint64(le32_to_cpu(hmb->hmdlec)))
;
3046
3047 sprintf(json_str, "0x%x", le32_to_cpu(hmb->hmdlau));
3048 obj_add_strjson_object_add_value_string(r, "Host Memory Descriptor List Address (HMDLAU)", json_str);
3049
3050 sprintf(json_str, "0x%x", le32_to_cpu(hmb->hmdlal));
3051 obj_add_strjson_object_add_value_string(r, "Host Memory Descriptor List Address (HMDLAL)", json_str);
3052
3053 obj_add_uint(r, "Host Memory Buffer Size (HSIZE)", le32_to_cpu(hmb->hsize))json_object_object_add(r, "Host Memory Buffer Size (HSIZE)", json_object_new_uint64
(le32_to_cpu(hmb->hsize)))
;
3054}
3055
3056static void json_feature_show_fields_host_mem_buf(struct json_object *r, unsigned int result,
3057 unsigned char *buf)
3058{
3059 obj_add_strjson_object_add_value_string(r, "Enable Host Memory (EHM)", result & 1 ? "Enabled" : "Disabled");
3060 obj_add_strjson_object_add_value_string(r, "Host Memory Non-operational Access Restriction Enable (HMNARE)",
3061 (result & 0x00000004) ? "True" : "False");
3062 obj_add_strjson_object_add_value_string(r, "Host Memory Non-operational Access Restricted (HMNAR)",
3063 (result & 0x00000008) ? "True" : "False");
3064
3065 if (buf)
3066 json_host_mem_buffer((struct nvme_host_mem_buf_attrs *)buf, r);
3067}
3068
3069static void json_timestamp(struct json_object *r, struct nvme_timestamp *ts)
3070{
3071 obj_add_uint64(r, "timestamp", int48_to_long(ts->timestamp))json_object_object_add(r, "timestamp", json_object_new_uint64
(int48_to_long(ts->timestamp)))
;
3072 obj_add_strjson_object_add_value_string(r, "timestamp string", nvme_format_timestamp(ts->timestamp));
3073 obj_add_strjson_object_add_value_string(r, "timestamp origin", nvme_format_timestamp_origin(ts->attr));
3074 obj_add_strjson_object_add_value_string(r, "synch", nvme_format_timestamp_sync(ts->attr));
3075}
3076
3077static void json_feature_show_fields_timestamp(struct json_object *r, unsigned char *buf)
3078{
3079 if (buf)
3080 json_timestamp(r, (struct nvme_timestamp *)buf);
3081}
3082
3083static void json_feature_show_fields_kato(struct json_object *r, unsigned int result)
3084{
3085 obj_add_uint(r, "Keep Alive Timeout (KATO) in milliseconds", result)json_object_object_add(r, "Keep Alive Timeout (KATO) in milliseconds"
, json_object_new_uint64(result))
;
3086}
3087
3088static void json_feature_show_fields_hctm(struct json_object *r, unsigned int result)
3089{
3090 char json_str[STR_LEN100];
3091
3092 sprintf(json_str, "%u K", result >> 16);
3093 obj_add_strjson_object_add_value_string(r, "Thermal Management Temperature 1 (TMT1)", json_str);
3094
3095 sprintf(json_str, "%s", nvme_degrees_string(result >> 16));
3096 obj_add_strjson_object_add_value_string(r, "TMT1 celsius", json_str);
3097
3098 sprintf(json_str, "%u K", result & 0xffff);
3099 obj_add_strjson_object_add_value_string(r, "Thermal Management Temperature 2", json_str);
3100
3101 sprintf(json_str, "%s", nvme_degrees_string(result & 0xffff));
3102 obj_add_strjson_object_add_value_string(r, "TMT2 celsius", json_str);
3103}
3104
3105static void json_feature_show_fields_nopsc(struct json_object *r, unsigned int result)
3106{
3107 obj_add_strjson_object_add_value_string(r, "Non-Operational Power State Permissive Mode Enable (NOPPME)", result & 1 ?
3108 "True" : "False");
3109}
3110
3111static void json_feature_show_fields_rrl(struct json_object *r, unsigned int result)
3112{
3113 obj_add_uint(r, "Read Recovery Level (RRL)", result & 0xf)json_object_object_add(r, "Read Recovery Level (RRL)", json_object_new_uint64
(result & 0xf))
;
3114}
3115
3116static void json_plm_config(struct nvme_plm_config *plmcfg, struct json_object *r)
3117{
3118 char json_str[STR_LEN100];
3119
3120 sprintf(json_str, "%04x", le16_to_cpu(plmcfg->ee));
3121 obj_add_strjson_object_add_value_string(r, "Enable Event", json_str);
3122
3123 obj_add_uint64(r, "DTWIN Reads Threshold", le64_to_cpu(plmcfg->dtwinrt))json_object_object_add(r, "DTWIN Reads Threshold", json_object_new_uint64
(le64_to_cpu(plmcfg->dtwinrt)))
;
3124 obj_add_uint64(r, "DTWIN Writes Threshold", le64_to_cpu(plmcfg->dtwinwt))json_object_object_add(r, "DTWIN Writes Threshold", json_object_new_uint64
(le64_to_cpu(plmcfg->dtwinwt)))
;
3125 obj_add_uint64(r, "DTWIN Time Threshold", le64_to_cpu(plmcfg->dtwintt))json_object_object_add(r, "DTWIN Time Threshold", json_object_new_uint64
(le64_to_cpu(plmcfg->dtwintt)))
;
3126}
3127
3128static void json_feature_show_fields_plm_config(struct json_object *r, unsigned int result,
3129 unsigned char *buf)
3130{
3131 obj_add_strjson_object_add_value_string(r, "Predictable Latency Window Enabled", result & 1 ? "True" : "False");
3132
3133 if (buf)
3134 json_plm_config((struct nvme_plm_config *)buf, r);
3135}
3136
3137static void json_feature_show_fields_plm_window(struct json_object *r, unsigned int result)
3138{
3139 obj_add_strjson_object_add_value_string(r, "Window Select", nvme_plm_window_to_string(result));
3140}
3141
3142static void json_feature_show_fields_lba_sts_interval(struct json_object *r, unsigned int result)
3143{
3144 obj_add_uint(r, "LBA Status Information Poll Interval (LSIPI)", result >> 16)json_object_object_add(r, "LBA Status Information Poll Interval (LSIPI)"
, json_object_new_uint64(result >> 16))
;
3145 obj_add_uint(r, "LBA Status Information Report Interval (LSIRI)", result & 0xffff)json_object_object_add(r, "LBA Status Information Report Interval (LSIRI)"
, json_object_new_uint64(result & 0xffff))
;
3146}
3147
3148static void json_feature_show_fields_host_behavior(struct json_object *r, unsigned char *buf)
3149{
3150 if (buf) {
3151 struct nvme_feat_host_behavior *host = (struct nvme_feat_host_behavior *)buf;
3152
3153 obj_add_strjson_object_add_value_string(r, "Host Behavior Support", buf[0] & 0x1 ? "True" : "False");
3154 obj_add_strjson_object_add_value_string(r, "Advanced Command Retry Enable (ACRE)", host->acre ?
3155 "True" : "False");
3156 obj_add_strjson_object_add_value_string(r, "Extended Telemetry Data Area 4 Supported (ETDAS)", host->etdas ?
3157 "True" : "False");
3158 obj_add_strjson_object_add_value_string(r, "LBA Format Extension Enable (LBAFEE)", host->lbafee ?
3159 "True" : "False");
3160 obj_add_strjson_object_add_value_string(r, "Host Dispersed Namespace Support (HDISNS)", host->hdisns ?
3161 "Enabled" : "Disabled");
3162 obj_add_strjson_object_add_value_string(r, "Copy Descriptor Format 2h Enable (CDF2E)", host->cdfe & (1 << 2) ?
3163 "True" : "False");
3164 obj_add_strjson_object_add_value_string(r, "Copy Descriptor Format 3h Enable (CDF3E)", host->cdfe & (1 << 3) ?
3165 "True" : "False");
3166 obj_add_strjson_object_add_value_string(r, "Copy Descriptor Format 4h Enable (CDF4E)", host->cdfe & (1 << 4) ?
3167 "True" : "False");
3168 }
3169}
3170
3171static void json_feature_show_fields_sanitize(struct json_object *r, unsigned int result)
3172{
3173 obj_add_uint(r, "No-Deallocate Response Mode (NODRM)", result & 1)json_object_object_add(r, "No-Deallocate Response Mode (NODRM)"
, json_object_new_uint64(result & 1))
;
3174}
3175
3176static void json_feature_show_fields_endurance_evt_cfg(struct json_object *r, unsigned int result)
3177{
3178 obj_add_uint(r, "Endurance Group Identifier (ENDGID)", result & 0xffff)json_object_object_add(r, "Endurance Group Identifier (ENDGID)"
, json_object_new_uint64(result & 0xffff))
;
3179 obj_add_uint(r, "Endurance Group Critical Warnings", result >> 16 & 0xff)json_object_object_add(r, "Endurance Group Critical Warnings"
, json_object_new_uint64(result >> 16 & 0xff))
;
3180}
3181
3182static void json_feature_show_fields_iocs_profile(struct json_object *r, unsigned int result)
3183{
3184 obj_add_strjson_object_add_value_string(r, "I/O Command Set Profile", result & 0x1 ? "True" : "False");
3185}
3186
3187static void json_feature_show_fields_spinup_control(struct json_object *r, unsigned int result)
3188{
3189 obj_add_strjson_object_add_value_string(r, "Spinup control feature Enabled", result & 1 ? "True" : "False");
3190}
3191
3192static void json_feature_show_fields_power_loss_signal(struct json_object *r, unsigned int result)
3193{
3194 obj_add_strjson_object_add_value_string(r, "Power Loss Signaling Mode (PLSM)",
3195 nvme_pls_mode_to_string(NVME_GET(result, FEAT_PLS_MODE)(((result) >> NVME_FEAT_PLS_MODE_SHIFT) & NVME_FEAT_PLS_MODE_MASK
)
));
3196}
3197
3198static void json_feat_perfc_std(struct json_object *r, struct nvme_std_perf_attr *data)
3199{
3200 obj_add_strjson_object_add_value_string(r, "random 4 kib average read latency",
3201 nvme_feature_perfc_r4karl_to_string(data->r4karl));
3202 obj_add_uint_02xjson_object_add_uint_02x(r, "R4KARL", data->r4karl);
3203}
3204
3205static void json_feat_perfc_id_list(struct json_object *r, struct nvme_perf_attr_id_list *data)
3206{
3207 int i;
3208 int attri_vs;
3209 char json_str[STR_LEN100];
3210 struct json_object *paida = json_create_array()json_object_new_array();
3211 struct json_object *paide;
3212
3213 obj_add_strjson_object_add_value_string(r, "attribute type", nvme_feature_perfc_attrtyp_to_string(data->attrtyp));
3214 obj_add_uint_02xjson_object_add_uint_02x(r, "ATTRTYP", data->attrtyp);
3215 obj_add_int(r, "maximum saveable vendor specific performance attributes (MSVSPA)",json_object_object_add(r, "maximum saveable vendor specific performance attributes (MSVSPA)"
, json_object_new_int(data->msvspa))
3216 data->msvspa)json_object_object_add(r, "maximum saveable vendor specific performance attributes (MSVSPA)"
, json_object_new_int(data->msvspa))
;
3217 obj_add_int(r, "unused saveable vendor specific performance attributes (USVSPA)",json_object_object_add(r, "unused saveable vendor specific performance attributes (USVSPA)"
, json_object_new_int(data->usvspa))
3218 data->usvspa)json_object_object_add(r, "unused saveable vendor specific performance attributes (USVSPA)"
, json_object_new_int(data->usvspa))
;
3219
3220 obj_add_array(r, "performance attribute identifier list", paida)json_object_object_add(r, "performance attribute identifier list"
, paida)
;
3221 for (i = 0; i < ARRAY_SIZE(data->id_list)(sizeof(data->id_list) / sizeof((data->id_list)[0]) + 0
)
; i++) {
3222 paide = json_create_object()json_object_new_object();
3223 array_add_obj(paida, paide)json_object_array_add(paida, paide);
3224 attri_vs = i + NVME_FEAT_PERFC_ATTRI_VS_MIN;
3225 sprintf(json_str, "performance attribute %02xh identifier (PA%02XHI)", attri_vs,
3226 attri_vs);
3227 obj_add_strjson_object_add_value_string(paide, json_str, shr_uuid_to_string(data->id_list[i].id));
3228 }
3229}
3230
3231static void json_feat_perfc_vs(struct json_object *r, struct nvme_vs_perf_attr *data)
3232{
3233 __u16 attrl = le16_to_cpu(data->attrl);
3234
3235 obj_add_strjson_object_add_value_string(r, "performance attribute identifier (PAID)", shr_uuid_to_string(data->paid));
3236 obj_add_uint(r, "attribute length (ATTRL)", attrl)json_object_object_add(r, "attribute length (ATTRL)", json_object_new_uint64
(attrl))
;
3237 obj_d(r, "vendor specific (VS)", (unsigned char *)data->vs,
3238 min_t(size_t, attrl, sizeof(data->vs))({ size_t _ta = (attrl); size_t _tb = (sizeof(data->vs)); (
{ typeof(_ta) _a = (_ta); typeof(_tb) _b = (_tb); do { } while
(0); _a < _b ? _a : _b; }); })
, 16, 1);
3239}
3240
3241static void json_feat_perfc(struct json_object *r, enum nvme_features_id fid, unsigned int result,
3242 struct nvme_perf_characteristics *data)
3243{
3244 __u8 attri;
3245 bool_Bool rvspa;
3246
3247 nvme_feature_decode_perf_characteristics(result, &attri, &rvspa);
3248
3249 obj_add_strjson_object_add_value_string(r, "attribute index", nvme_feature_perfc_attri_to_string(attri));
3250 obj_add_uint_02xjson_object_add_uint_02x(r, "ATTRI", attri);
3251
3252 switch (attri) {
3253 case NVME_FEAT_PERFC_ATTRI_STD:
3254 json_feat_perfc_std(r, data->std_perf);
3255 break;
3256 case NVME_FEAT_PERFC_ATTRI_ID_LIST:
3257 json_feat_perfc_id_list(r, data->id_list);
3258 break;
3259 case NVME_FEAT_PERFC_ATTRI_VS_MIN ... NVME_FEAT_PERFC_ATTRI_VS_MAX:
3260 json_feat_perfc_vs(r, data->vs_perf);
3261 break;
3262 default:
3263 break;
3264 }
3265}
3266
3267static void json_host_metadata(struct json_object *r, enum nvme_features_id fid,
3268 struct nvme_host_metadata *data)
3269{
3270 struct nvme_metadata_element_desc desc;
3271 const __u8 *v;
3272 size_t off = 0;
3273 int i;
3274 char val[VAL_LEN4096];
3275 __u16 len;
3276 char json_str[STR_LEN100];
3277 struct json_object *desca = json_create_array()json_object_new_array();
3278 struct json_object *desce;
3279
3280 obj_add_int(r, "Num Metadata Element Descriptors", data->ndesc)json_object_object_add(r, "Num Metadata Element Descriptors",
json_object_new_int(data->ndesc))
;
3281
3282 obj_add_array(r, "Metadata Element Descriptors", desca)json_object_object_add(r, "Metadata Element Descriptors", desca
)
;
3283
3284 for (i = 0; i < data->ndesc; i++) {
3285 v = nvme_host_metadata_element(data, &off, &desc, &len);
3286 if (!v)
3287 break;
3288
3289 desce = json_create_object()json_object_new_object();
3290 array_add_obj(desca, desce)json_object_array_add(desca, desce);
3291
3292 obj_add_int(desce, "Element", i)json_object_object_add(desce, "Element", json_object_new_int(
i))
;
3293
3294 snprintf(json_str, sizeof(json_str), "0x%02x", desc.type);
3295 obj_add_strjson_object_add_value_string(desce, "Type", json_str);
3296
3297 obj_add_strjson_object_add_value_string(desce, "Type definition",
3298 nvme_host_metadata_type_to_string(fid, desc.type));
3299
3300 obj_add_int(desce, "Revision", desc.rev)json_object_object_add(desce, "Revision", json_object_new_int
(desc.rev))
;
3301
3302 obj_add_int(desce, "Length", le16_to_cpu(desc.len))json_object_object_add(desce, "Length", json_object_new_int(le16_to_cpu
(desc.len)))
;
3303
3304 snprintf(val, sizeof(val), "%.*s", len, (const char *)v);
3305 obj_add_strjson_object_add_value_string(desce, "Value", val);
3306 }
3307}
3308
3309static void json_feature_show_fields_ns_metadata(struct json_object *r, enum nvme_features_id fid,
3310 unsigned char *buf)
3311{
3312 if (buf)
3313 json_host_metadata(r, fid, (struct nvme_host_metadata *)buf);
3314}
3315
3316static void json_feature_show_fields_sw_progress(struct json_object *r, unsigned int result)
3317{
3318 obj_add_uint(r, "Pre-boot Software Load Count (PBSLC)", result & 0xff)json_object_object_add(r, "Pre-boot Software Load Count (PBSLC)"
, json_object_new_uint64(result & 0xff))
;
3319}
3320
3321static void json_feature_show_fields_host_id(struct json_object *r,
3322 unsigned int result, unsigned char *hostid)
3323{
3324 bool_Bool exhid;
3325
3326 if (!hostid)
3327 return;
3328
3329 nvme_feature_decode_host_id(result, &exhid);
3330
3331 if (exhid)
3332 obj_add_strjson_object_add_value_string(r, "Host Identifier (HOSTID)",
3333 uint128_t_to_l10n_string(le128_to_cpu(hostid)));
3334 else
3335 obj_add_uint64(r, "Host Identifier (HOSTID)",json_object_object_add(r, "Host Identifier (HOSTID)", json_object_new_uint64
(le64_to_cpu(*(__le64 *)hostid)))
3336 le64_to_cpu(*(__le64 *)hostid))json_object_object_add(r, "Host Identifier (HOSTID)", json_object_new_uint64
(le64_to_cpu(*(__le64 *)hostid)))
;
3337}
3338
3339static void json_feature_show_fields_resv_nf_mask(struct json_object *r, unsigned int result)
3340{
3341 obj_add_strjson_object_add_value_string(r, "Mask Reservation Preempted Notification (RESPRE)", (result & 8) >> 3 ?
3342 "True" : "False");
3343 obj_add_strjson_object_add_value_string(r, "Mask Reservation Released Notification (RESREL)", (result & 4) >> 2 ?
3344 "True" : "False");
3345 obj_add_strjson_object_add_value_string(r, "Mask Registration Preempted Notification (REGPRE)", (result & 2) >> 1 ?
3346 "True" : "False");
3347}
3348
3349static void json_feature_show_fields_resv_persist(struct json_object *r, unsigned int result)
3350{
3351 obj_add_strjson_object_add_value_string(r, "Persist Through Power Loss (PTPL)", result & 1 ? "True" : "False");
3352}
3353
3354static void json_feature_show_fields_write_protect(struct json_object *r, unsigned int result)
3355{
3356 obj_add_strjson_object_add_value_string(r, "Namespace Write Protect", nvme_ns_wp_cfg_to_string(result));
3357}
3358
3359static void json_feature_show_fields_fdp(struct json_object *r, unsigned int result)
3360{
3361 obj_add_strjson_object_add_value_string(r, "Flexible Direct Placement Enable (FDPE)", result & 1 ? "Yes" : "No");
3362 obj_add_uint(r, "Flexible Direct Placement Configuration Index", result >> 8 & 0xf)json_object_object_add(r, "Flexible Direct Placement Configuration Index"
, json_object_new_uint64(result >> 8 & 0xf))
;
3363}
3364
3365static void json_feature_show_fields_fdp_events(struct json_object *r, unsigned int result,
3366 unsigned char *buf)
3367{
3368 unsigned int i;
3369 struct nvme_fdp_supported_event_desc *d;
3370 char json_str[STR_LEN100];
3371
3372 // NOET is in bits 7:0; bits 31:8 are reserved.
3373 for (i = 0; i < (result & 0xff); i++) {
3374 d = &((struct nvme_fdp_supported_event_desc *)buf)[i];
3375 sprintf(json_str, "%s", d->evta & 0x1 ? "Enabled" : "Not enabled");
3376 obj_add_strjson_object_add_value_string(r, nvme_fdp_event_to_string(d->evt), json_str);
3377 }
3378}
3379
3380static void json_feature_show_fields_bpwp(struct json_object *r, unsigned int result)
3381{
3382 __u8 field;
3383
3384 field = NVME_FEAT_BPWPC_BP0WPS(result)(((result) >> NVME_FEAT_BPWPC_BP0WPS_SHIFT) & NVME_FEAT_BPWPC_BP0WPS_MASK
)
;
3385 obj_add_strjson_object_add_value_string(r, "Boot Partition 0 Write Protection State", nvme_bpwps_to_string(field));
3386 field = NVME_FEAT_BPWPC_BP1WPS(result)(((result) >> NVME_FEAT_BPWPC_BP1WPS_SHIFT) & NVME_FEAT_BPWPC_BP1WPS_MASK
)
;
3387 obj_add_strjson_object_add_value_string(r, "Boot Partition 1 Write Protection State", nvme_bpwps_to_string(field));
3388}
3389
3390static char *get_power_and_scale(__u16 power, __u8 scale)
3391{
3392 char *str;
3393 int ret;
3394
3395 switch (scale) {
3396 case NVME_PSD_PS_NOT_REPORTED:
3397 /* Not reported for this power state */
3398 ret = asprintf(&str, "-");
3399 break;
3400 case NVME_PSD_PS_100_MICRO_WATT:
3401 /* Units of 0.0001W */
3402 ret = asprintf(&str, "%01u.%04uW", power / 10000,
3403 power % 10000);
3404 break;
3405 case NVME_PSD_PS_10_MILLI_WATT:
3406 /* Units of 0.01W */
3407 ret = asprintf(&str, "%01u.%02uW", power / 100, power % 100);
3408 break;
3409 default:
3410 ret = asprintf(&str, "reserved");
3411 break;
3412 }
3413
3414 if (ret > 0)
3415 return str;
3416
3417 return NULL((void*)0);
3418}
3419
3420static void json_feature_show_fields_power_limit(struct json_object *r,
3421 unsigned int result)
3422{
3423 __u8 field = NVME_FEAT_POWER_LIMIT_PLS(result)(((result) >> NVME_FEAT_POWER_LIMIT_PLS_SHIFT) & NVME_FEAT_POWER_LIMIT_PLS_MASK
)
;
3424
3425 __cleanup_free__attribute__((cleanup(shr_freep))) char *k =
3426 get_power_and_scale(NVME_FEAT_POWER_LIMIT_PLV(result)(((result) >> NVME_FEAT_POWER_LIMIT_PLV_SHIFT) & NVME_FEAT_POWER_LIMIT_PLV_MASK
)
, field);
3427
3428 obj_add_strjson_object_add_value_string(r, "Power Limit Scale (PLS)",
3429 nvme_feature_power_limit_scale_to_string(field));
3430 obj_add_uint(r, "Power Limit Value (PLV)",json_object_object_add(r, "Power Limit Value (PLV)", json_object_new_uint64
((((result) >> NVME_FEAT_POWER_LIMIT_PLV_SHIFT) & NVME_FEAT_POWER_LIMIT_PLV_MASK
)))
3431 NVME_FEAT_POWER_LIMIT_PLV(result))json_object_object_add(r, "Power Limit Value (PLV)", json_object_new_uint64
((((result) >> NVME_FEAT_POWER_LIMIT_PLV_SHIFT) & NVME_FEAT_POWER_LIMIT_PLV_MASK
)))
;
3432 obj_add_strjson_object_add_value_string(r, "Power Limit", k);
3433}
3434
3435static void json_feature_show_fields_power_thresh(struct json_object *r,
3436 unsigned int result)
3437{
3438 __u8 field;
3439 __u16 ptv;
3440 __cleanup_free__attribute__((cleanup(shr_freep))) char *k = NULL((void*)0);
3441
3442 field = NVME_FEAT_POWER_THRESH_EPT(result)(((result) >> NVME_FEAT_POWER_THRESH_EPT_SHIFT) & NVME_FEAT_POWER_THRESH_EPT_MASK
)
;
3443
3444 obj_add_strjson_object_add_value_string(r, "Enable Power Threshold (EPT)",
3445 field ? "Enabled" : "Disabled");
3446
3447 field = NVME_FEAT_POWER_THRESH_PMTS(result)(((result) >> NVME_FEAT_POWER_THRESH_PMTS_SHIFT) & NVME_FEAT_POWER_THRESH_PMTS_MASK
)
;
3448 obj_add_strjson_object_add_value_string(r, "Power Measurement Type Select (PMTS)",
3449 nvme_power_measurement_type_to_string(field));
3450
3451 field = NVME_FEAT_POWER_THRESH_PTS(result)(((result) >> NVME_FEAT_POWER_THRESH_PTS_SHIFT) & NVME_FEAT_POWER_THRESH_PTS_MASK
)
;
3452 obj_add_strjson_object_add_value_string(r, "Power Threshold Scale (PTS)",
3453 nvme_feature_power_limit_scale_to_string(field));
3454
3455 ptv = NVME_FEAT_POWER_THRESH_PTV(result)(((result) >> NVME_FEAT_POWER_THRESH_PTV_SHIFT) & NVME_FEAT_POWER_THRESH_PTV_MASK
)
;
3456
3457 obj_add_uint(r, "Power Threshold Value (PTV)", ptv)json_object_object_add(r, "Power Threshold Value (PTV)", json_object_new_uint64
(ptv))
;
3458
3459 k = get_power_and_scale(ptv, NVME_FEAT_POWER_THRESH_PTS(result)(((result) >> NVME_FEAT_POWER_THRESH_PTS_SHIFT) & NVME_FEAT_POWER_THRESH_PTS_MASK
)
);
3460 obj_add_strjson_object_add_value_string(r, "Power Threshold", k);
3461}
3462
3463static void json_feature_show_fields_power_meas(struct json_object *r,
3464 unsigned int result)
3465{
3466 __u8 field;
3467 __u16 smt;
3468
3469 field = NVME_FEAT_POWER_MEAS_ACT(result)(((result) >> NVME_FEAT_POWER_MEAS_ACT_SHIFT) & NVME_FEAT_POWER_MEAS_ACT_MASK
)
;
3470 obj_add_strjson_object_add_value_string(r, "Action (ACT)",
3471 nvme_power_measurement_action_to_string(field));
3472
3473 field = NVME_FEAT_POWER_MEAS_PMTS(result)(((result) >> NVME_FEAT_POWER_MEAS_PMTS_SHIFT) & NVME_FEAT_POWER_MEAS_PMTS_MASK
)
;
3474 obj_add_strjson_object_add_value_string(r, "Power Measurement Type Select (PMTS)",
3475 nvme_power_measurement_type_to_string(field));
3476
3477 smt = NVME_FEAT_POWER_MEAS_SMT(result)(((result) >> NVME_FEAT_POWER_MEAS_SMT_SHIFT) & NVME_FEAT_POWER_MEAS_SMT_MASK
)
;
3478
3479 obj_add_uint(r, "Stop Measurement Time (SMT)", smt)json_object_object_add(r, "Stop Measurement Time (SMT)", json_object_new_uint64
(smt))
;
3480}
3481
3482static void json_feature_show_fields_voltage_threshold(struct json_object *r,
3483 unsigned int result)
3484{
3485 obj_add_uint(r, "Voltage Sensor Select (VSENS)",json_object_object_add(r, "Voltage Sensor Select (VSENS)", json_object_new_uint64
((((result) >> NVME_FEAT_VOLTAGE_THRESHOLD_VSENS_SHIFT)
& NVME_FEAT_VOLTAGE_THRESHOLD_VSENS_MASK)))
3486 NVME_FEAT_VOLTAGE_THRESHOLD_VSENS(result))json_object_object_add(r, "Voltage Sensor Select (VSENS)", json_object_new_uint64
((((result) >> NVME_FEAT_VOLTAGE_THRESHOLD_VSENS_SHIFT)
& NVME_FEAT_VOLTAGE_THRESHOLD_VSENS_MASK)))
;
3487 obj_add_strjson_object_add_value_string(r, "Enable Voltage Threshold (EVT)",
3488 result & NVME_FEAT_VOLTAGE_THRESHOLD_EVT ? "Enabled" : "Disabled");
3489 obj_add_uint(r, "Overvoltage Threshold (OVT)",json_object_object_add(r, "Overvoltage Threshold (OVT)", json_object_new_uint64
((((result) >> NVME_FEAT_VOLTAGE_THRESHOLD_OVT_SHIFT) &
NVME_FEAT_VOLTAGE_THRESHOLD_OVT_MASK)))
3490 NVME_FEAT_VOLTAGE_THRESHOLD_OVT(result))json_object_object_add(r, "Overvoltage Threshold (OVT)", json_object_new_uint64
((((result) >> NVME_FEAT_VOLTAGE_THRESHOLD_OVT_SHIFT) &
NVME_FEAT_VOLTAGE_THRESHOLD_OVT_MASK)))
;
3491 obj_add_uint(r, "Undervoltage Threshold (UVT)",json_object_object_add(r, "Undervoltage Threshold (UVT)", json_object_new_uint64
((((result) >> NVME_FEAT_VOLTAGE_THRESHOLD_UVT_SHIFT) &
NVME_FEAT_VOLTAGE_THRESHOLD_UVT_MASK)))
3492 NVME_FEAT_VOLTAGE_THRESHOLD_UVT(result))json_object_object_add(r, "Undervoltage Threshold (UVT)", json_object_new_uint64
((((result) >> NVME_FEAT_VOLTAGE_THRESHOLD_UVT_SHIFT) &
NVME_FEAT_VOLTAGE_THRESHOLD_UVT_MASK)))
;
3493}
3494
3495static void json_feature_show_fields_voltage_measurement(struct json_object *r,
3496 unsigned int result)
3497{
3498 obj_add_uint(r, "Action (ACT)", NVME_FEAT_VOLTAGE_MEASUREMENT_ACT(result))json_object_object_add(r, "Action (ACT)", json_object_new_uint64
((((result) >> NVME_FEAT_VOLTAGE_MEASUREMENT_ACT_SHIFT)
& NVME_FEAT_VOLTAGE_MEASUREMENT_ACT_MASK)))
;
3499}
3500
3501static void json_rate_limiting_data(struct json_object *r, struct nvme_rate_limiting_data *rld)
3502{
3503 __u16 rlc = le16_to_cpu(rld->rlc);
3504 __u16 rlm = NVME_RATE_LIMITING_RLC_RLM(rlc)(((rlc) >> NVME_RATE_LIMITING_RLC_RLM_SHIFT) & NVME_RATE_LIMITING_RLC_RLM_MASK
)
;
3505
3506 obj_add_strjson_object_add_value_string(r, "Rate Limiting Enable (RLE)",
3507 NVME_RATE_LIMITING_RLC_RLE(rlc)(((rlc) >> NVME_RATE_LIMITING_RLC_RLE_SHIFT) & NVME_RATE_LIMITING_RLC_RLE_MASK
)
? "Enabled" : "Disabled");
3508 obj_add_uint(r, "Rate Limiting Mode (RLM)", rlm)json_object_object_add(r, "Rate Limiting Mode (RLM)", json_object_new_uint64
(rlm))
;
3509 obj_add_strjson_object_add_value_string(r, "RLM description",
3510 rlm == NVME_RATE_LIMITING_MODE_SOFT_LIMIT ? "Soft Limit" :
3511 rlm == NVME_RATE_LIMITING_MODE_HARD_LIMIT ? "Hard Limit" : "Reserved");
3512 obj_add_uint(r, "Bandwidth Scale Factor (BWSF)", rld->bwsf)json_object_object_add(r, "Bandwidth Scale Factor (BWSF)", json_object_new_uint64
(rld->bwsf))
;
3513 obj_add_uint64(r, "Total Bandwidth Value (TBWV)", le64_to_cpu(rld->tbwv))json_object_object_add(r, "Total Bandwidth Value (TBWV)", json_object_new_uint64
(le64_to_cpu(rld->tbwv)))
;
3514 obj_add_uint64(r, "Write Bandwidth Value (WBWV)", le64_to_cpu(rld->wbwv))json_object_object_add(r, "Write Bandwidth Value (WBWV)", json_object_new_uint64
(le64_to_cpu(rld->wbwv)))
;
3515 obj_add_uint(r, "Total IOPS (TIOPS)", le32_to_cpu(rld->tiops))json_object_object_add(r, "Total IOPS (TIOPS)", json_object_new_uint64
(le32_to_cpu(rld->tiops)))
;
3516 obj_add_uint(r, "Write IOPS (WIOPS)", le32_to_cpu(rld->wiops))json_object_object_add(r, "Write IOPS (WIOPS)", json_object_new_uint64
(le32_to_cpu(rld->wiops)))
;
3517 obj_add_uint(r, "Read IOPS Ratio (RIOPSR)", rld->riopsr)json_object_object_add(r, "Read IOPS Ratio (RIOPSR)", json_object_new_uint64
(rld->riopsr))
;
3518 obj_add_uint(r, "Write IOPS Ratio (WIOPSR)", rld->wiopsr)json_object_object_add(r, "Write IOPS Ratio (WIOPSR)", json_object_new_uint64
(rld->wiopsr))
;
3519 obj_add_uint(r, "Read Bandwidth Ratio (RBWR)", rld->rbwr)json_object_object_add(r, "Read Bandwidth Ratio (RBWR)", json_object_new_uint64
(rld->rbwr))
;
3520 obj_add_uint(r, "Write Bandwidth Ratio (WBWR)", rld->wbwr)json_object_object_add(r, "Write Bandwidth Ratio (WBWR)", json_object_new_uint64
(rld->wbwr))
;
3521}
3522
3523static void json_feature_show_fields_rate_limiting(struct json_object *r, unsigned char *buf)
3524{
3525 if (buf)
3526 json_rate_limiting_data(r, (struct nvme_rate_limiting_data *)buf);
3527}
3528
3529static void json_feature_show(enum nvme_features_id fid, int sel,
3530 unsigned int result, void *buf, __u32 data_len)
3531{
3532 struct json_object *r;
3533 char json_str[STR_LEN100];
3534
3535 sprintf(json_str, "feature: %#0*x", fid ? 4 : 2, fid);
3536 r = obj_create(json_str);
3537
3538 obj_add_strjson_object_add_value_string(r, "name", nvme_feature_to_string(fid));
3539
3540 sprintf(json_str, "%#0*x", result ? 10 : 8, result);
3541 obj_add_strjson_object_add_value_string(r, nvme_select_to_string(sel), json_str);
3542
3543 obj_print(r);
3544
3545 if (NVME_CHECK(sel, GET_FEATURES_SEL, SUPPORTED)((sel) == NVME_GET_FEATURES_SEL_SUPPORTED))
3546 json_select_result(fid, result);
3547 else
3548 json_feature_show_fields(fid, result, buf);
3549}
3550
3551static void json_feature_show_fields(enum nvme_features_id fid, unsigned int result,
3552 unsigned char *buf)
3553{
3554 struct json_object *r;
3555 char json_str[STR_LEN100];
3556
3557 sprintf(json_str, "Feature: %#0*x", fid ? 4 : 2, fid);
3558 r = obj_create(json_str);
3559
3560 switch (fid) {
3561 case NVME_FEAT_FID_ARBITRATION:
3562 json_feature_show_fields_arbitration(r, result);
3563 break;
3564 case NVME_FEAT_FID_POWER_MGMT:
3565 json_feature_show_fields_power_mgmt(r, result);
3566 break;
3567 case NVME_FEAT_FID_LBA_RANGE:
3568 json_feature_show_fields_lba_range(r, result & 0x3f, buf);
3569 break;
3570 case NVME_FEAT_FID_TEMP_THRESH:
3571 json_feature_show_fields_temp_thresh(r, result);
3572 break;
3573 case NVME_FEAT_FID_ERR_RECOVERY:
3574 json_feature_show_fields_err_recovery(r, result);
3575 break;
3576 case NVME_FEAT_FID_VOLATILE_WC:
3577 json_feature_show_fields_volatile_wc(r, result);
3578 break;
3579 case NVME_FEAT_FID_NUM_QUEUES:
3580 json_feature_show_fields_num_queues(r, result);
3581 break;
3582 case NVME_FEAT_FID_IRQ_COALESCE:
3583 json_feature_show_fields_irq_coalesce(r, result);
3584 break;
3585 case NVME_FEAT_FID_IRQ_CONFIG:
3586 json_feature_show_fields_irq_config(r, result);
3587 break;
3588 case NVME_FEAT_FID_WRITE_ATOMIC:
3589 json_feature_show_fields_write_atomic(r, result);
3590 break;
3591 case NVME_FEAT_FID_ASYNC_EVENT:
3592 json_feature_show_fields_async_event(r, result);
3593 break;
3594 case NVME_FEAT_FID_AUTO_PST:
3595 json_feature_show_fields_auto_pst(r, result, buf);
3596 break;
3597 case NVME_FEAT_FID_HOST_MEM_BUF:
3598 json_feature_show_fields_host_mem_buf(r, result, buf);
3599 break;
3600 case NVME_FEAT_FID_TIMESTAMP:
3601 json_feature_show_fields_timestamp(r, buf);
3602 break;
3603 case NVME_FEAT_FID_KATO:
3604 json_feature_show_fields_kato(r, result);
3605 break;
3606 case NVME_FEAT_FID_HCTM:
3607 json_feature_show_fields_hctm(r, result);
3608 break;
3609 case NVME_FEAT_FID_NOPSC:
3610 json_feature_show_fields_nopsc(r, result);
3611 break;
3612 case NVME_FEAT_FID_RRL:
3613 json_feature_show_fields_rrl(r, result);
3614 break;
3615 case NVME_FEAT_FID_PLM_CONFIG:
3616 json_feature_show_fields_plm_config(r, result, buf);
3617 break;
3618 case NVME_FEAT_FID_PLM_WINDOW:
3619 json_feature_show_fields_plm_window(r, result);
3620 break;
3621 case NVME_FEAT_FID_LBA_STS_INTERVAL:
3622 json_feature_show_fields_lba_sts_interval(r, result);
3623 break;
3624 case NVME_FEAT_FID_HOST_BEHAVIOR:
3625 json_feature_show_fields_host_behavior(r, buf);
3626 break;
3627 case NVME_FEAT_FID_SANITIZE:
3628 json_feature_show_fields_sanitize(r, result);
3629 break;
3630 case NVME_FEAT_FID_ENDURANCE_EVT_CFG:
3631 json_feature_show_fields_endurance_evt_cfg(r, result);
3632 break;
3633 case NVME_FEAT_FID_IOCS_PROFILE:
3634 json_feature_show_fields_iocs_profile(r, result);
3635 break;
3636 case NVME_FEAT_FID_SPINUP_CONTROL:
3637 json_feature_show_fields_spinup_control(r, result);
3638 break;
3639 case NVME_FEAT_FID_POWER_LOSS_SIGNAL:
3640 json_feature_show_fields_power_loss_signal(r, result);
3641 break;
3642 case NVME_FEAT_FID_PERF_CHARACTERISTICS:
3643 json_feat_perfc(r, fid, result, (struct nvme_perf_characteristics *)buf);
3644 break;
3645 case NVME_FEAT_FID_ENH_CTRL_METADATA:
3646 case NVME_FEAT_FID_CTRL_METADATA:
3647 case NVME_FEAT_FID_NS_METADATA:
3648 json_feature_show_fields_ns_metadata(r, fid, buf);
3649 break;
3650 case NVME_FEAT_FID_SW_PROGRESS:
3651 json_feature_show_fields_sw_progress(r, result);
3652 break;
3653 case NVME_FEAT_FID_HOST_ID:
3654 json_feature_show_fields_host_id(r, result, buf);
3655 break;
3656 case NVME_FEAT_FID_RESV_NF_MASK:
3657 json_feature_show_fields_resv_nf_mask(r, result);
3658 break;
3659 case NVME_FEAT_FID_RESV_PERSIST:
3660 json_feature_show_fields_resv_persist(r, result);
3661 break;
3662 case NVME_FEAT_FID_WRITE_PROTECT:
3663 json_feature_show_fields_write_protect(r, result);
3664 break;
3665 case NVME_FEAT_FID_FDP:
3666 json_feature_show_fields_fdp(r, result);
3667 break;
3668 case NVME_FEAT_FID_FDP_EVENTS:
3669 json_feature_show_fields_fdp_events(r, result, buf);
3670 break;
3671 case NVME_FEAT_FID_BP_WRITE_PROTECT:
3672 json_feature_show_fields_bpwp(r, result);
3673 break;
3674 case NVME_FEAT_FID_POWER_LIMIT:
3675 json_feature_show_fields_power_limit(r, result);
3676 break;
3677 case NVME_FEAT_FID_POWER_THRESH:
3678 json_feature_show_fields_power_thresh(r, result);
3679 break;
3680 case NVME_FEAT_FID_POWER_MEASUREMENT:
3681 json_feature_show_fields_power_meas(r, result);
3682 break;
3683 case NVME_FEAT_FID_VOLTAGE_THRESHOLD:
3684 json_feature_show_fields_voltage_threshold(r, result);
3685 break;
3686 case NVME_FEAT_FID_VOLTAGE_MEASUREMENT:
3687 json_feature_show_fields_voltage_measurement(r, result);
3688 break;
3689 case NVME_FEAT_FID_RATE_LIMITING:
3690 json_feature_show_fields_rate_limiting(r, buf);
3691 break;
3692 default:
3693 break;
3694 }
3695
3696 obj_print(r);
3697}
3698
3699void json_id_ctrl_rpmbs(__le32 ctrl_rpmbs)
3700{
3701 struct json_object *r = json_r;
3702 __u32 rpmbs = le32_to_cpu(ctrl_rpmbs);
3703 __u32 asz = (rpmbs & 0xFF000000) >> 24;
3704 __u32 tsz = (rpmbs & 0xFF0000) >> 16;
3705 __u32 rsvd = (rpmbs & 0xFFC0) >> 6;
3706 __u32 auth = (rpmbs & 0x38) >> 3;
3707 __u32 rpmb = rpmbs & 7;
3708
3709 obj_add_uint_nx(r, "[31:24]: Access Size", asz);
3710 obj_add_uint_nx(r, "[23:16]: Total Size", tsz);
3711
3712 if (rsvd)
3713 obj_add_uint_nx(r, "[15:6]: Reserved", rsvd);
3714
3715 obj_add_uint_nx(r, "[5:3]: Authentication Method", auth);
3716 obj_add_uint_nx(r, "[2:0]: Number of RPMB Units", rpmb);
3717}
3718
3719static void json_lba_range(struct nvme_lba_range_type *lbrt, int nr_ranges)
3720{
3721 struct json_object *r = json_r;
3722
3723 json_lba_range_entry(lbrt, nr_ranges, r);
3724}
3725
3726static void json_lba_status_info(__u64 result)
3727{
3728 struct json_object *r = json_r;
3729
3730 obj_add_uint(r, "LBA Status Information Poll Interval (LSIPI)", (result >> 16) & 0xffff)json_object_object_add(r, "LBA Status Information Poll Interval (LSIPI)"
, json_object_new_uint64((result >> 16) & 0xffff))
;
3731 obj_add_uint(r, "LBA Status Information Report Interval (LSIRI)", result & 0xffff)json_object_object_add(r, "LBA Status Information Report Interval (LSIRI)"
, json_object_new_uint64(result & 0xffff))
;
3732}
3733
3734void json_d(unsigned char *buf, int len, int width, int group)
3735{
3736 struct json_object *r = json_r;
3737 char json_str[STR_LEN100];
3738
3739 sprintf(json_str, "data: buf=%p len=%d width=%d group=%d", buf, len, width, group);
3740 obj_d(r, json_str, buf, len, width, group);
3741}
3742
3743static void json_nvme_list_ctrl(struct nvme_ctrl_list *ctrl_list)
3744{
3745 __u16 num = le16_to_cpu(ctrl_list->num);
3746 struct json_object *r = json_r;
3747 struct json_object *valid_attrs;
3748 struct json_object *valid = json_create_array()json_object_new_array();
3749 int i;
3750
3751 obj_add_uint(r, "num_ctrl", le16_to_cpu(ctrl_list->num))json_object_object_add(r, "num_ctrl", json_object_new_uint64(
le16_to_cpu(ctrl_list->num)))
;
3752
3753 for (i = 0; i < min(num, 2047)({ typeof(num) _a = (num); typeof(2047) _b = (2047); do { } while
(0); _a < _b ? _a : _b; })
; i++) {
3754 valid_attrs = json_create_object()json_object_new_object();
3755 obj_add_uint(valid_attrs, "ctrl_id", le16_to_cpu(ctrl_list->identifier[i]))json_object_object_add(valid_attrs, "ctrl_id", json_object_new_uint64
(le16_to_cpu(ctrl_list->identifier[i])))
;
3756 array_add_obj(valid, valid_attrs)json_object_array_add(valid, valid_attrs);
3757 }
3758
3759 obj_add_array(r, "ctrl_list", valid)json_object_object_add(r, "ctrl_list", valid);
3760}
3761
3762static void json_nvme_id_nvmset(struct nvme_id_nvmset_list *nvmset,
3763 unsigned int nvmeset_id)
3764{
3765 __u32 nent = nvmset->nid;
3766 struct json_object *entries = json_create_array()json_object_new_array();
3767 struct json_object *r = json_r;
3768 int i;
3769
3770 obj_add_int(r, "nid", nent)json_object_object_add(r, "nid", json_object_new_int(nent));
3771
3772 for (i = 0; i < nent && i < ARRAY_SIZE(nvmset->ent)(sizeof(nvmset->ent) / sizeof((nvmset->ent)[0]) + 0); i++) {
3773 struct json_object *entry = json_create_object()json_object_new_object();
3774
3775 obj_add_int(entry, "nvmset_id", le16_to_cpu(nvmset->ent[i].nvmsetid))json_object_object_add(entry, "nvmset_id", json_object_new_int
(le16_to_cpu(nvmset->ent[i].nvmsetid)))
;
3776 obj_add_int(entry, "endurance_group_id", le16_to_cpu(nvmset->ent[i].endgid))json_object_object_add(entry, "endurance_group_id", json_object_new_int
(le16_to_cpu(nvmset->ent[i].endgid)))
;
3777 obj_add_uint(entry, "random_4k_read_typical", le32_to_cpu(nvmset->ent[i].rr4kt))json_object_object_add(entry, "random_4k_read_typical", json_object_new_uint64
(le32_to_cpu(nvmset->ent[i].rr4kt)))
;
3778 obj_add_uint(entry, "optimal_write_size", le32_to_cpu(nvmset->ent[i].ows))json_object_object_add(entry, "optimal_write_size", json_object_new_uint64
(le32_to_cpu(nvmset->ent[i].ows)))
;
3779 obj_add_uint128(entry, "total_nvmset_cap", le128_to_cpu(nvmset->ent[i].tnvmsetcap))json_object_object_add(entry, "total_nvmset_cap", util_json_object_new_uint128
(le128_to_cpu(nvmset->ent[i].tnvmsetcap)))
;
3780 obj_add_uint128(entry, "unalloc_nvmset_cap",json_object_object_add(entry, "unalloc_nvmset_cap", util_json_object_new_uint128
(le128_to_cpu(nvmset->ent[i].unvmsetcap)))
3781 le128_to_cpu(nvmset->ent[i].unvmsetcap))json_object_object_add(entry, "unalloc_nvmset_cap", util_json_object_new_uint128
(le128_to_cpu(nvmset->ent[i].unvmsetcap)))
;
3782 array_add_obj(entries, entry)json_object_array_add(entries, entry);
3783 }
3784
3785 obj_add_array(r, "NVMSet", entries)json_object_object_add(r, "NVMSet", entries);
3786}
3787
3788static void json_nvme_primary_ctrl_cap(const struct nvme_primary_ctrl_cap *caps)
3789{
3790 struct json_object *r = json_r;
3791
3792 obj_add_uint(r, "cntlid", le16_to_cpu(caps->cntlid))json_object_object_add(r, "cntlid", json_object_new_uint64(le16_to_cpu
(caps->cntlid)))
;
3793 obj_add_uint(r, "portid", le16_to_cpu(caps->portid))json_object_object_add(r, "portid", json_object_new_uint64(le16_to_cpu
(caps->portid)))
;
3794 obj_add_uint(r, "crt", caps->crt)json_object_object_add(r, "crt", json_object_new_uint64(caps->
crt))
;
3795
3796 obj_add_uint(r, "vqfrt", le32_to_cpu(caps->vqfrt))json_object_object_add(r, "vqfrt", json_object_new_uint64(le32_to_cpu
(caps->vqfrt)))
;
3797 obj_add_uint(r, "vqrfa", le32_to_cpu(caps->vqrfa))json_object_object_add(r, "vqrfa", json_object_new_uint64(le32_to_cpu
(caps->vqrfa)))
;
3798 obj_add_int(r, "vqrfap", le16_to_cpu(caps->vqrfap))json_object_object_add(r, "vqrfap", json_object_new_int(le16_to_cpu
(caps->vqrfap)))
;
3799 obj_add_int(r, "vqprt", le16_to_cpu(caps->vqprt))json_object_object_add(r, "vqprt", json_object_new_int(le16_to_cpu
(caps->vqprt)))
;
3800 obj_add_int(r, "vqfrsm", le16_to_cpu(caps->vqfrsm))json_object_object_add(r, "vqfrsm", json_object_new_int(le16_to_cpu
(caps->vqfrsm)))
;
3801 obj_add_int(r, "vqgran", le16_to_cpu(caps->vqgran))json_object_object_add(r, "vqgran", json_object_new_int(le16_to_cpu
(caps->vqgran)))
;
3802
3803 obj_add_uint(r, "vifrt", le32_to_cpu(caps->vifrt))json_object_object_add(r, "vifrt", json_object_new_uint64(le32_to_cpu
(caps->vifrt)))
;
3804 obj_add_uint(r, "virfa", le32_to_cpu(caps->virfa))json_object_object_add(r, "virfa", json_object_new_uint64(le32_to_cpu
(caps->virfa)))
;
3805 obj_add_int(r, "virfap", le16_to_cpu(caps->virfap))json_object_object_add(r, "virfap", json_object_new_int(le16_to_cpu
(caps->virfap)))
;
3806 obj_add_int(r, "viprt", le16_to_cpu(caps->viprt))json_object_object_add(r, "viprt", json_object_new_int(le16_to_cpu
(caps->viprt)))
;
3807 obj_add_int(r, "vifrsm", le16_to_cpu(caps->vifrsm))json_object_object_add(r, "vifrsm", json_object_new_int(le16_to_cpu
(caps->vifrsm)))
;
3808 obj_add_int(r, "vigran", le16_to_cpu(caps->vigran))json_object_object_add(r, "vigran", json_object_new_int(le16_to_cpu
(caps->vigran)))
;
3809}
3810
3811static void json_nvme_list_secondary_ctrl(const struct nvme_secondary_ctrl_list *sc_list,
3812 __u32 count)
3813{
3814 const struct nvme_secondary_ctrl *sc_entry = &sc_list->sc_entry[0];
3815 __u32 nent = min(sc_list->num, count)({ typeof(sc_list->num) _a = (sc_list->num); typeof(count
) _b = (count); do { } while (0); _a < _b ? _a : _b; })
;
3816 struct json_object *entries = json_create_array()json_object_new_array();
3817 struct json_object *r = json_r;
3818 int i;
3819
3820 obj_add_int(r, "num", nent)json_object_object_add(r, "num", json_object_new_int(nent));
3821
3822 for (i = 0; i < nent; i++) {
3823 struct json_object *entry = json_create_object()json_object_new_object();
3824
3825 obj_add_int(entry, "secondary-controller-identifier",json_object_object_add(entry, "secondary-controller-identifier"
, json_object_new_int(le16_to_cpu(sc_entry[i].scid)))
3826 le16_to_cpu(sc_entry[i].scid))json_object_object_add(entry, "secondary-controller-identifier"
, json_object_new_int(le16_to_cpu(sc_entry[i].scid)))
;
3827 obj_add_int(entry, "primary-controller-identifier", le16_to_cpu(sc_entry[i].pcid))json_object_object_add(entry, "primary-controller-identifier"
, json_object_new_int(le16_to_cpu(sc_entry[i].pcid)))
;
3828 obj_add_int(entry, "secondary-controller-state", sc_entry[i].scs)json_object_object_add(entry, "secondary-controller-state", json_object_new_int
(sc_entry[i].scs))
;
3829 obj_add_int(entry, "virtual-function-number", le16_to_cpu(sc_entry[i].vfn))json_object_object_add(entry, "virtual-function-number", json_object_new_int
(le16_to_cpu(sc_entry[i].vfn)))
;
3830 obj_add_int(entry, "num-virtual-queues", le16_to_cpu(sc_entry[i].nvq))json_object_object_add(entry, "num-virtual-queues", json_object_new_int
(le16_to_cpu(sc_entry[i].nvq)))
;
3831 obj_add_int(entry, "num-virtual-interrupts", le16_to_cpu(sc_entry[i].nvi))json_object_object_add(entry, "num-virtual-interrupts", json_object_new_int
(le16_to_cpu(sc_entry[i].nvi)))
;
3832 array_add_obj(entries, entry)json_object_array_add(entries, entry);
3833 }
3834
3835 obj_add_array(r, "secondary-controllers", entries)json_object_object_add(r, "secondary-controllers", entries);
3836}
3837
3838static void json_nvme_id_ns_granularity_list(
3839 const struct nvme_id_ns_granularity_list *glist)
3840{
3841 int i;
3842 struct json_object *r = json_r;
3843 struct json_object *entries = json_create_array()json_object_new_array();
3844
3845 obj_add_int(r, "attributes", glist->attributes)json_object_object_add(r, "attributes", json_object_new_int(glist
->attributes))
;
3846 obj_add_int(r, "num-descriptors", glist->num_descriptors)json_object_object_add(r, "num-descriptors", json_object_new_int
(glist->num_descriptors))
;
3847
3848 for (i = 0; i <= glist->num_descriptors && i < ARRAY_SIZE(glist->entry)(sizeof(glist->entry) / sizeof((glist->entry)[0]) + 0);
3849 i++) {
3850 struct json_object *entry = json_create_object()json_object_new_object();
3851
3852 obj_add_uint64(entry, "namespace-size-granularity",json_object_object_add(entry, "namespace-size-granularity", json_object_new_uint64
(le64_to_cpu(glist->entry[i].nszegran)))
3853 le64_to_cpu(glist->entry[i].nszegran))json_object_object_add(entry, "namespace-size-granularity", json_object_new_uint64
(le64_to_cpu(glist->entry[i].nszegran)))
;
3854 obj_add_uint64(entry, "namespace-capacity-granularity",json_object_object_add(entry, "namespace-capacity-granularity"
, json_object_new_uint64(le64_to_cpu(glist->entry[i].ncapgran
)))
3855 le64_to_cpu(glist->entry[i].ncapgran))json_object_object_add(entry, "namespace-capacity-granularity"
, json_object_new_uint64(le64_to_cpu(glist->entry[i].ncapgran
)))
;
3856 array_add_obj(entries, entry)json_object_array_add(entries, entry);
3857 }
3858
3859 obj_add_array(r, "namespace-granularity-list", entries)json_object_object_add(r, "namespace-granularity-list", entries
)
;
3860}
3861
3862static void json_nvme_id_uuid_list(const struct nvme_id_uuid_list *uuid_list)
3863{
3864 struct json_object *r = json_r;
3865 struct json_object *entries = json_create_array()json_object_new_array();
3866 int i;
3867
3868 for (i = 0; i < NVME_ID_UUID_LIST_MAX; i++) {
3869 __u8 uuid[NVME_UUID_LEN16];
3870 struct json_object *entry;
3871
3872 /* The list is terminated by a zero UUID value */
3873 if (memcmp(uuid_list->entry[i].uuid, zero_uuid, sizeof(zero_uuid)) == 0)
3874 break;
3875 entry = json_create_object()json_object_new_object();
3876 memcpy(&uuid, uuid_list->entry[i].uuid, sizeof(uuid));
3877 obj_add_int(entry, "association",json_object_object_add(entry, "association", json_object_new_int
(uuid_list->entry[i].header & 0x3))
3878 uuid_list->entry[i].header & 0x3)json_object_object_add(entry, "association", json_object_new_int
(uuid_list->entry[i].header & 0x3))
;
3879 obj_add_strjson_object_add_value_string(entry, "uuid",
3880 shr_uuid_to_string(uuid));
3881 array_add_obj(entries, entry)json_object_array_add(entries, entry);
3882 }
3883
3884 obj_add_array(r, "UUID-list", entries)json_object_object_add(r, "UUID-list", entries);
3885}
3886
3887static void json_id_domain_list(struct nvme_id_domain_list *id_dom)
3888{
3889 struct json_object *r = json_r;
3890 struct json_object *entries = json_create_array()json_object_new_array();
3891 struct json_object *entry;
3892 int i;
3893 shr_uint128_t dom_cap, unalloc_dom_cap, max_egrp_dom_cap;
3894
3895 obj_add_uint(r, "num_dom_entries", id_dom->num)json_object_object_add(r, "num_dom_entries", json_object_new_uint64
(id_dom->num))
;
3896
3897 for (i = 0; i < id_dom->num && i < ARRAY_SIZE(id_dom->domain_attr)(sizeof(id_dom->domain_attr) / sizeof((id_dom->domain_attr
)[0]) + 0)
;
3898 i++) {
3899 entry = json_create_object()json_object_new_object();
3900 dom_cap = le128_to_cpu(id_dom->domain_attr[i].dom_cap);
3901 unalloc_dom_cap = le128_to_cpu(id_dom->domain_attr[i].unalloc_dom_cap);
3902 max_egrp_dom_cap = le128_to_cpu(id_dom->domain_attr[i].max_egrp_dom_cap);
3903
3904 obj_add_uint(entry, "dom_id", le16_to_cpu(id_dom->domain_attr[i].dom_id))json_object_object_add(entry, "dom_id", json_object_new_uint64
(le16_to_cpu(id_dom->domain_attr[i].dom_id)))
;
3905 obj_add_uint128(entry, "dom_cap", dom_cap)json_object_object_add(entry, "dom_cap", util_json_object_new_uint128
(dom_cap))
;
3906 obj_add_uint128(entry, "unalloc_dom_cap", unalloc_dom_cap)json_object_object_add(entry, "unalloc_dom_cap", util_json_object_new_uint128
(unalloc_dom_cap))
;
3907 obj_add_uint128(entry, "max_egrp_dom_cap", max_egrp_dom_cap)json_object_object_add(entry, "max_egrp_dom_cap", util_json_object_new_uint128
(max_egrp_dom_cap))
;
3908
3909 array_add_obj(entries, entry)json_object_array_add(entries, entry);
3910 }
3911
3912 obj_add_array(r, "domain_list", entries)json_object_object_add(r, "domain_list", entries);
3913}
3914
3915static void json_nvme_endurance_group_list(struct nvme_id_endurance_group_list *endgrp_list)
3916{
3917 struct json_object *r = json_r;
3918 struct json_object *valid_attrs;
3919 struct json_object *valid = json_create_array()json_object_new_array();
3920 int i;
3921
3922 obj_add_uint(r, "num_endgrp_id", le16_to_cpu(endgrp_list->num))json_object_object_add(r, "num_endgrp_id", json_object_new_uint64
(le16_to_cpu(endgrp_list->num)))
;
3923
3924 for (i = 0; i < min(le16_to_cpu(endgrp_list->num), 2047)({ typeof(le16_to_cpu(endgrp_list->num)) _a = (le16_to_cpu
(endgrp_list->num)); typeof(2047) _b = (2047); do { } while
(0); _a < _b ? _a : _b; })
; i++) {
3925 valid_attrs = json_create_object()json_object_new_object();
3926 obj_add_uint(valid_attrs, "endgrp_id", le16_to_cpu(endgrp_list->identifier[i]))json_object_object_add(valid_attrs, "endgrp_id", json_object_new_uint64
(le16_to_cpu(endgrp_list->identifier[i])))
;
3927 array_add_obj(valid, valid_attrs)json_object_array_add(valid, valid_attrs);
3928 }
3929
3930 obj_add_array(r, "endgrp_list", valid)json_object_object_add(r, "endgrp_list", valid);
3931}
3932
3933static void json_support_log(struct nvme_supported_log_pages *support_log,
3934 const char *devname)
3935{
3936 struct json_object *r = json_r;
3937 struct json_object *valid = json_create_array()json_object_new_array();
3938 struct json_object *valid_attrs;
3939 unsigned int lid;
3940 char key[128];
3941 __u32 support;
3942
3943 for (lid = 0; lid < 256; lid++) {
3944 support = le32_to_cpu(support_log->lid_support[lid]);
3945 if (support & 0x1) {
3946 valid_attrs = json_create_object()json_object_new_object();
3947 sprintf(key, "lid_0x%x ", lid);
3948 obj_add_uint(valid_attrs, key, support)json_object_object_add(valid_attrs, key, json_object_new_uint64
(support))
;
3949 array_add_obj(valid, valid_attrs)json_object_array_add(valid, valid_attrs);
3950 }
3951 }
3952
3953 obj_add_array(r, "supported_logs", valid)json_object_object_add(r, "supported_logs", valid);
3954}
3955
3956static void json_print_detail_list_multipath(struct libnvme_subsystem *s,
3957 struct json_object *jss)
3958{
3959 struct libnvme_ns *n;
3960 struct libnvme_path *p;
3961 struct json_object *jnss = json_create_array()json_object_new_array();
3962
3963 libnvme_subsystem_for_each_ns(s, n)for (n = libnvme_subsystem_first_ns(s); n != ((void*)0); n = libnvme_subsystem_next_ns
(s, n))
{
3964 struct json_object *jns = json_create_object()json_object_new_object();
3965 struct json_object *jpaths = json_create_array()json_object_new_array();
3966 int lba;
3967 uint64_t lba_count, nsze, nuse;
3968
3969 libnvme_ns_get_lba_size(n, &lba, 0);
3970 libnvme_ns_get_lba_count(n, &lba_count, 0);
3971 nsze = lba_count * lba;
3972 libnvme_ns_get_lba_util(n, &nuse, 0);
3973 nuse *= lba;
3974
3975 obj_add_strjson_object_add_value_string(jns, "NameSpace", libnvme_ns_get_name(n));
3976 obj_add_strjson_object_add_value_string(jns, "Generic", libnvme_ns_get_generic_name(n));
3977 obj_add_int(jns, "NSID", libnvme_ns_get_nsid(n))json_object_object_add(jns, "NSID", json_object_new_int(libnvme_ns_get_nsid
(n)))
;
3978 obj_add_uint64(jns, "UsedBytes", nuse)json_object_object_add(jns, "UsedBytes", json_object_new_uint64
(nuse))
;
3979 obj_add_uint64(jns, "MaximumLBA", lba_count)json_object_object_add(jns, "MaximumLBA", json_object_new_uint64
(lba_count))
;
3980 obj_add_uint64(jns, "PhysicalSize", nsze)json_object_object_add(jns, "PhysicalSize", json_object_new_uint64
(nsze))
;
3981 obj_add_int(jns, "SectorSize", lba)json_object_object_add(jns, "SectorSize", json_object_new_int
(lba))
;
3982
3983 libnvme_namespace_for_each_path(n, p)for (p = libnvme_namespace_first_path(n); p != ((void*)0); p =
libnvme_namespace_next_path(n, p))
{
3984 struct libnvme_ctrl *c;
3985 struct json_object *jpath = json_create_object()json_object_new_object();
3986 const char *slot;
3987 const char *cntlid;
3988 const char *serial;
3989 const char *model;
3990 const char *firmware;
3991 const char *ana_state;
3992
3993 libnvme_path_get_ana_state(p, &ana_state, "");
3994 obj_add_strjson_object_add_value_string(jpath, "Path", libnvme_path_get_name(p));
3995 obj_add_strjson_object_add_value_string(jpath, "ANAState", ana_state);
3996
3997 /*
3998 * For multipath, each path maps to one controller.
3999 * So get the controller from the path and then add
4000 * controller attributes.
4001 */
4002 c = libnvme_path_get_ctrl(p);
4003 libnvme_ctrl_get_phy_slot(c, &slot, "");
4004 libnvme_ctrl_get_cntlid(c, &cntlid, "");
4005 libnvme_ctrl_get_serial(c, &serial, "");
4006 libnvme_ctrl_get_model(c, &model, "");
4007 libnvme_ctrl_get_firmware(c, &firmware, "");
4008 obj_add_strjson_object_add_value_string(jpath, "Controller", libnvme_ctrl_get_name(c));
4009 obj_add_strjson_object_add_value_string(jpath, "Cntlid", cntlid);
4010 obj_add_strjson_object_add_value_string(jpath, "SerialNumber", serial);
4011 obj_add_strjson_object_add_value_string(jpath, "ModelNumber", model);
4012 obj_add_strjson_object_add_value_string(jpath, "Firmware", firmware);
4013 obj_add_strjson_object_add_value_string(jpath, "Transport", libnvme_ctrl_get_transport(c));
4014 obj_add_ctrl_address(jpath, c);
4015 obj_add_ctrl_address_details(jpath, "AddressDetails", c);
4016 obj_add_strjson_object_add_value_string(jpath, "Slot", slot ? slot : "");
4017
4018 array_add_obj(jpaths, jpath)json_object_array_add(jpaths, jpath);
4019 }
4020
4021 obj_add_obj(jns, "Paths", jpaths)json_object_object_add(jns, "Paths", jpaths);
4022 array_add_obj(jnss, jns)json_object_array_add(jnss, jns);
4023 }
4024 obj_add_obj(jss, "Namespaces", jnss)json_object_object_add(jss, "Namespaces", jnss);
4025}
4026
4027static void json_print_detail_list(struct libnvme_subsystem *s, struct json_object *jss)
4028{
4029 struct libnvme_ctrl *c;
4030 struct libnvme_ns *n;
4031 struct json_object *jctrls = json_create_array()json_object_new_array();
4032
4033 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
4034 struct json_object *jctrl = json_create_object()json_object_new_object();
4035 struct json_object *jnss = json_create_array()json_object_new_array();
4036 const char *slot;
4037 const char *cntlid;
4038 const char *serial;
4039 const char *model;
4040 const char *firmware;
4041
4042 libnvme_ctrl_get_phy_slot(c, &slot, "");
4043 libnvme_ctrl_get_cntlid(c, &cntlid, "");
4044 libnvme_ctrl_get_serial(c, &serial, "");
4045 libnvme_ctrl_get_model(c, &model, "");
4046 libnvme_ctrl_get_firmware(c, &firmware, "");
4047
4048 obj_add_strjson_object_add_value_string(jctrl, "Controller", libnvme_ctrl_get_name(c));
4049 obj_add_strjson_object_add_value_string(jctrl, "Cntlid", cntlid);
4050 obj_add_strjson_object_add_value_string(jctrl, "SerialNumber", serial);
4051 obj_add_strjson_object_add_value_string(jctrl, "ModelNumber", model);
4052 obj_add_strjson_object_add_value_string(jctrl, "Firmware", firmware);
4053 obj_add_strjson_object_add_value_string(jctrl, "Transport", libnvme_ctrl_get_transport(c));
4054 obj_add_ctrl_address(jctrl, c);
4055 obj_add_ctrl_address_details(jctrl, "AddressDetails", c);
4056 obj_add_strjson_object_add_value_string(jctrl, "Slot", slot ? slot : "");
4057
4058 libnvme_ctrl_for_each_ns(c, n)for (n = libnvme_ctrl_first_ns(c); n != ((void*)0); n = libnvme_ctrl_next_ns
(c, n))
{
4059 struct json_object *jns = json_create_object()json_object_new_object();
4060 int lba;
4061 uint64_t lba_count, nsze, nuse;
4062
4063 libnvme_ns_get_lba_size(n, &lba, 0);
4064 libnvme_ns_get_lba_count(n, &lba_count, 0);
4065 nsze = lba_count * lba;
4066 libnvme_ns_get_lba_util(n, &nuse, 0);
4067 nuse *= lba;
4068
4069 obj_add_strjson_object_add_value_string(jns, "NameSpace", libnvme_ns_get_name(n));
4070 obj_add_strjson_object_add_value_string(jns, "Generic", libnvme_ns_get_generic_name(n));
4071 obj_add_int(jns, "NSID", libnvme_ns_get_nsid(n))json_object_object_add(jns, "NSID", json_object_new_int(libnvme_ns_get_nsid
(n)))
;
4072 obj_add_uint64(jns, "UsedBytes", nuse)json_object_object_add(jns, "UsedBytes", json_object_new_uint64
(nuse))
;
4073 obj_add_uint64(jns, "MaximumLBA", lba_count)json_object_object_add(jns, "MaximumLBA", json_object_new_uint64
(lba_count))
;
4074 obj_add_uint64(jns, "PhysicalSize", nsze)json_object_object_add(jns, "PhysicalSize", json_object_new_uint64
(nsze))
;
4075 obj_add_int(jns, "SectorSize", lba)json_object_object_add(jns, "SectorSize", json_object_new_int
(lba))
;
4076
4077 array_add_obj(jnss, jns)json_object_array_add(jnss, jns);
4078 }
4079
4080 obj_add_obj(jctrl, "Namespaces", jnss)json_object_object_add(jctrl, "Namespaces", jnss);
4081 array_add_obj(jctrls, jctrl)json_object_array_add(jctrls, jctrl);
4082 }
4083
4084 obj_add_obj(jss, "Controllers", jctrls)json_object_object_add(jss, "Controllers", jctrls);
4085}
4086
4087static void json_detail_list_v2(struct libnvme_global_ctx *ctx)
4088{
4089 struct json_object *r = json_r;
4090 struct json_object *jdev = json_create_array()json_object_new_array();
4091
4092 struct libnvme_host *h;
4093 struct libnvme_subsystem *s;
4094
4095 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
{
4096 struct json_object *hss = json_create_object()json_object_new_object();
4097 struct json_object *jsslist = json_create_array()json_object_new_array();
4098 const char *hostid;
4099
4100 obj_add_strjson_object_add_value_string(hss, "HostNQN", libnvme_host_get_hostnqn(h));
4101 hostid = libnvme_host_get_hostid(h);
4102 if (hostid)
4103 obj_add_strjson_object_add_value_string(hss, "HostID", hostid);
4104
4105 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
{
4106 struct json_object *jss = json_create_object()json_object_new_object();
4107
4108 obj_add_strjson_object_add_value_string(jss, "Subsystem", libnvme_subsystem_get_name(s));
4109 obj_add_strjson_object_add_value_string(jss, "SubsystemNQN", libnvme_subsystem_get_subsysnqn(s));
4110
4111 if (nvme_is_multipath(s))
4112 json_print_detail_list_multipath(s, jss);
4113 else
4114 json_print_detail_list(s, jss);
4115
4116 array_add_obj(jsslist, jss)json_object_array_add(jsslist, jss);
4117 }
4118
4119 obj_add_obj(hss, "Subsystems", jsslist)json_object_object_add(hss, "Subsystems", jsslist);
4120 array_add_obj(jdev, hss)json_object_array_add(jdev, hss);
4121 }
4122
4123 obj_add_array(r, "Devices", jdev)json_object_object_add(r, "Devices", jdev);
4124}
4125
4126static void json_detail_list(struct libnvme_global_ctx *ctx)
4127{
4128 struct json_object *r = json_r;
4129 struct json_object *jdev = json_create_array()json_object_new_array();
4130
4131 struct libnvme_host *h;
4132 struct libnvme_subsystem *s;
4133 struct libnvme_ctrl *c;
4134 struct libnvme_path *p;
4135 struct libnvme_ns *n;
4136
4137 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
{
4138 struct json_object *hss = json_create_object()json_object_new_object();
4139 struct json_object *jsslist = json_create_array()json_object_new_array();
4140 const char *hostid;
4141
4142 obj_add_strjson_object_add_value_string(hss, "HostNQN", libnvme_host_get_hostnqn(h));
4143 hostid = libnvme_host_get_hostid(h);
4144 if (hostid)
4145 obj_add_strjson_object_add_value_string(hss, "HostID", hostid);
4146
4147 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
{
4148 struct json_object *jss = json_create_object()json_object_new_object();
4149 struct json_object *jctrls = json_create_array()json_object_new_array();
4150 struct json_object *jnss = json_create_array()json_object_new_array();
4151
4152 obj_add_strjson_object_add_value_string(jss, "Subsystem", libnvme_subsystem_get_name(s));
4153 obj_add_strjson_object_add_value_string(jss, "SubsystemNQN", libnvme_subsystem_get_subsysnqn(s));
4154
4155 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
4156 struct json_object *jctrl = json_create_object()json_object_new_object();
4157 struct json_object *jnss = json_create_array()json_object_new_array();
4158 struct json_object *jpaths = json_create_array()json_object_new_array();
4159 const char *cntlid;
4160 const char *serial;
4161 const char *model;
4162 const char *firmware;
4163 const char *slot;
4164
4165 libnvme_ctrl_get_cntlid(c, &cntlid, "");
4166 libnvme_ctrl_get_serial(c, &serial, "");
4167 libnvme_ctrl_get_model(c, &model, "");
4168 libnvme_ctrl_get_firmware(c, &firmware, "");
4169 libnvme_ctrl_get_phy_slot(c, &slot, "");
4170
4171 obj_add_strjson_object_add_value_string(jctrl, "Controller", libnvme_ctrl_get_name(c));
4172 obj_add_strjson_object_add_value_string(jctrl, "Cntlid", cntlid);
4173 obj_add_strjson_object_add_value_string(jctrl, "SerialNumber", serial);
4174 obj_add_strjson_object_add_value_string(jctrl, "ModelNumber", model);
4175 obj_add_strjson_object_add_value_string(jctrl, "Firmware", firmware);
4176 obj_add_strjson_object_add_value_string(jctrl, "Transport", libnvme_ctrl_get_transport(c));
4177 obj_add_ctrl_address(jctrl, c);
4178 obj_add_ctrl_address_details(jctrl, "AddressDetails", c);
4179 obj_add_strjson_object_add_value_string(jctrl, "Slot", slot);
4180
4181 libnvme_ctrl_for_each_ns(c, n)for (n = libnvme_ctrl_first_ns(c); n != ((void*)0); n = libnvme_ctrl_next_ns
(c, n))
{
4182 struct json_object *jns = json_create_object()json_object_new_object();
4183 int lba;
4184 uint64_t lba_count, nsze, nuse;
4185
4186 libnvme_ns_get_lba_size(n, &lba, 0);
4187 libnvme_ns_get_lba_count(n,
4188 &lba_count, 0);
4189 nsze = lba_count * lba;
4190 libnvme_ns_get_lba_util(n, &nuse, 0);
4191 nuse *= lba;
4192
4193 obj_add_strjson_object_add_value_string(jns, "NameSpace", libnvme_ns_get_name(n));
4194 obj_add_strjson_object_add_value_string(jns, "Generic", libnvme_ns_get_generic_name(n));
4195 obj_add_int(jns, "NSID", libnvme_ns_get_nsid(n))json_object_object_add(jns, "NSID", json_object_new_int(libnvme_ns_get_nsid
(n)))
;
4196 obj_add_uint64(jns, "UsedBytes", nuse)json_object_object_add(jns, "UsedBytes", json_object_new_uint64
(nuse))
;
4197 obj_add_uint64(jns, "MaximumLBA",json_object_object_add(jns, "MaximumLBA", json_object_new_uint64
(lba_count))
4198 lba_count)json_object_object_add(jns, "MaximumLBA", json_object_new_uint64
(lba_count))
;
4199 obj_add_uint64(jns, "PhysicalSize", nsze)json_object_object_add(jns, "PhysicalSize", json_object_new_uint64
(nsze))
;
4200 obj_add_int(jns, "SectorSize", lba)json_object_object_add(jns, "SectorSize", json_object_new_int
(lba))
;
4201
4202 array_add_obj(jnss, jns)json_object_array_add(jnss, jns);
4203 }
4204 obj_add_obj(jctrl, "Namespaces", jnss)json_object_object_add(jctrl, "Namespaces", jnss);
4205
4206 libnvme_ctrl_for_each_path(c, p)for (p = libnvme_ctrl_first_path(c); p != ((void*)0); p = libnvme_ctrl_next_path
(c, p))
{
4207 struct json_object *jpath = json_create_object()json_object_new_object();
4208 const char *ana_state;
4209
4210 libnvme_path_get_ana_state(p,
4211 &ana_state, "");
4212 obj_add_strjson_object_add_value_string(jpath, "Path", libnvme_path_get_name(p));
4213 obj_add_strjson_object_add_value_string(jpath, "ANAState",
4214 ana_state);
4215
4216 array_add_obj(jpaths, jpath)json_object_array_add(jpaths, jpath);
4217 }
4218 obj_add_obj(jctrl, "Paths", jpaths)json_object_object_add(jctrl, "Paths", jpaths);
4219
4220 array_add_obj(jctrls, jctrl)json_object_array_add(jctrls, jctrl);
4221 }
4222 obj_add_obj(jss, "Controllers", jctrls)json_object_object_add(jss, "Controllers", jctrls);
4223
4224 libnvme_subsystem_for_each_ns(s, n)for (n = libnvme_subsystem_first_ns(s); n != ((void*)0); n = libnvme_subsystem_next_ns
(s, n))
{
4225 struct json_object *jns = json_create_object()json_object_new_object();
4226 int lba;
4227 uint64_t lba_count, nsze, nuse;
4228
4229 libnvme_ns_get_lba_size(n, &lba, 0);
4230 libnvme_ns_get_lba_count(n, &lba_count, 0);
4231 nsze = lba_count * lba;
4232 libnvme_ns_get_lba_util(n, &nuse, 0);
4233 nuse *= lba;
4234
4235 obj_add_strjson_object_add_value_string(jns, "NameSpace", libnvme_ns_get_name(n));
4236 obj_add_strjson_object_add_value_string(jns, "Generic", libnvme_ns_get_generic_name(n));
4237 obj_add_int(jns, "NSID", libnvme_ns_get_nsid(n))json_object_object_add(jns, "NSID", json_object_new_int(libnvme_ns_get_nsid
(n)))
;
4238 obj_add_uint64(jns, "UsedBytes", nuse)json_object_object_add(jns, "UsedBytes", json_object_new_uint64
(nuse))
;
4239 obj_add_uint64(jns, "MaximumLBA", lba_count)json_object_object_add(jns, "MaximumLBA", json_object_new_uint64
(lba_count))
;
4240 obj_add_uint64(jns, "PhysicalSize", nsze)json_object_object_add(jns, "PhysicalSize", json_object_new_uint64
(nsze))
;
4241 obj_add_int(jns, "SectorSize", lba)json_object_object_add(jns, "SectorSize", json_object_new_int
(lba))
;
4242
4243 array_add_obj(jnss, jns)json_object_array_add(jnss, jns);
4244 }
4245 obj_add_obj(jss, "Namespaces", jnss)json_object_object_add(jss, "Namespaces", jnss);
4246
4247 array_add_obj(jsslist, jss)json_object_array_add(jsslist, jss);
4248 }
4249
4250 obj_add_obj(hss, "Subsystems", jsslist)json_object_object_add(hss, "Subsystems", jsslist);
4251 array_add_obj(jdev, hss)json_object_array_add(jdev, hss);
4252 }
4253
4254 obj_add_array(r, "Devices", jdev)json_object_object_add(r, "Devices", jdev);
4255}
4256
4257static struct json_object *json_list_item_obj(struct libnvme_ns *n)
4258{
4259 struct json_object *r = json_create_object()json_object_new_object();
4260 char devname[NAME_LEN128] = { 0 };
4261 char genname[NAME_LEN128] = { 0 };
4262 int lba;
4263 uint64_t lba_count, nsze, nuse;
4264
4265 libnvme_ns_get_lba_size(n, &lba, 0);
4266 libnvme_ns_get_lba_count(n, &lba_count, 0);
4267 nsze = lba_count * lba;
4268 libnvme_ns_get_lba_util(n, &nuse, 0);
4269 nuse *= lba;
4270
4271 nvme_dev_full_path(n, devname, sizeof(devname));
4272 nvme_generic_full_path(n, genname, sizeof(genname));
4273
4274 obj_add_int(r, "NameSpace", libnvme_ns_get_nsid(n))json_object_object_add(r, "NameSpace", json_object_new_int(libnvme_ns_get_nsid
(n)))
;
4275 obj_add_strjson_object_add_value_string(r, "DevicePath", devname);
4276 obj_add_strjson_object_add_value_string(r, "GenericPath", genname);
4277 obj_add_strjson_object_add_value_string(r, "Firmware", libnvme_ns_get_firmware(n));
4278 obj_add_strjson_object_add_value_string(r, "ModelNumber", libnvme_ns_get_model(n));
4279 obj_add_strjson_object_add_value_string(r, "SerialNumber", libnvme_ns_get_serial(n));
4280 obj_add_uint64(r, "UsedBytes", nuse)json_object_object_add(r, "UsedBytes", json_object_new_uint64
(nuse))
;
4281 obj_add_uint64(r, "MaximumLBA", lba_count)json_object_object_add(r, "MaximumLBA", json_object_new_uint64
(lba_count))
;
4282 obj_add_uint64(r, "PhysicalSize", nsze)json_object_object_add(r, "PhysicalSize", json_object_new_uint64
(nsze))
;
4283 obj_add_int(r, "SectorSize", lba)json_object_object_add(r, "SectorSize", json_object_new_int(lba
))
;
4284
4285 return r;
4286}
4287
4288static void json_simple_list(struct libnvme_global_ctx *ctx)
4289{
4290 struct json_object *r = json_r;
4291 struct json_object *jdevices = json_create_array()json_object_new_array();
4292
4293 struct libnvme_host *h;
4294 struct libnvme_subsystem *s;
4295 struct libnvme_ctrl *c;
4296 struct libnvme_ns *n;
4297
4298 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
{
4299 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
{
4300 libnvme_subsystem_for_each_ns(s, n)for (n = libnvme_subsystem_first_ns(s); n != ((void*)0); n = libnvme_subsystem_next_ns
(s, n))
4301 array_add_obj(jdevices, json_list_item_obj(n))json_object_array_add(jdevices, json_list_item_obj(n));
4302
4303 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
4304 libnvme_ctrl_for_each_ns(c, n)for (n = libnvme_ctrl_first_ns(c); n != ((void*)0); n = libnvme_ctrl_next_ns
(c, n))
4305 array_add_obj(jdevices, json_list_item_obj(n))json_object_array_add(jdevices, json_list_item_obj(n));
4306 }
4307 }
4308 }
4309
4310 obj_add_array(r, "Devices", jdevices)json_object_object_add(r, "Devices", jdevices);
4311}
4312
4313static void json_list_item(struct libnvme_ns *n, struct shr_table *t)
4314{
4315 struct json_object *r = json_list_item_obj(n);
4316
4317 json_print(r);
4318}
4319
4320static void json_print_list_items(struct libnvme_global_ctx *ctx)
4321{
4322 if (json_print_ops.flags & VERBOSE) {
4323 if (nvme_args.output_format_ver == 2)
4324 json_detail_list_v2(ctx);
4325 else
4326 json_detail_list(ctx);
4327 } else
4328 json_simple_list(ctx);
4329}
4330
4331static unsigned int json_subsystem_topology_multipath(struct libnvme_subsystem *s,
4332 json_object *namespaces)
4333{
4334 struct libnvme_ns *n;
4335 struct libnvme_path *p;
4336 unsigned int i = 0;
4337 const char *iopolicy;
4338
4339 libnvme_subsystem_get_iopolicy(s, &iopolicy, "");
4340
4341 libnvme_subsystem_for_each_ns(s, n)for (n = libnvme_subsystem_first_ns(s); n != ((void*)0); n = libnvme_subsystem_next_ns
(s, n))
{
4342 struct json_object *ns_attrs;
4343 struct json_object *paths;
4344
4345 ns_attrs = json_create_object()json_object_new_object();
4346 obj_add_int(ns_attrs, "NSID", libnvme_ns_get_nsid(n))json_object_object_add(ns_attrs, "NSID", json_object_new_int(
libnvme_ns_get_nsid(n)))
;
4347 obj_add_strjson_object_add_value_string(ns_attrs, "Name", libnvme_ns_get_name(n));
4348
4349 paths = json_create_array()json_object_new_array();
4350 libnvme_namespace_for_each_path(n, p)for (p = libnvme_namespace_first_path(n); p != ((void*)0); p =
libnvme_namespace_next_path(n, p))
{
4351 struct json_object *path_attrs;
4352 struct json_object *ctrls, *ctrl_attrs;
4353 struct libnvme_ctrl *c;
4354 const char *ana_state;
4355
4356 libnvme_path_get_ana_state(p, &ana_state, "");
4357 path_attrs = json_create_object()json_object_new_object();
4358 obj_add_strjson_object_add_value_string(path_attrs, "Path", libnvme_path_get_name(p));
4359 obj_add_strjson_object_add_value_string(path_attrs, "ANAState", ana_state);
4360
4361 /*
4362 * For iopolicy numa exclude "Qdepth", for iopolicy
4363 * queue-depth exclude "NUMANodes" and for iopolicy
4364 * round-robin exclude both "Qdepth" and "NUMANodes".
4365 */
4366 if (!strcmp(iopolicy, "numa")) {
4367 const char *numa_nodes;
4368
4369 libnvme_path_get_numa_nodes(p, &numa_nodes,
4370 "");
4371 obj_add_strjson_object_add_value_string(path_attrs, "NUMANodes",
4372 numa_nodes);
4373 } else if (!strcmp(iopolicy, "queue-depth")) {
4374 int queue_depth;
4375
4376 libnvme_path_get_queue_depth(p, &queue_depth,
4377 0);
4378 obj_add_int(path_attrs, "Qdepth", queue_depth)json_object_object_add(path_attrs, "Qdepth", json_object_new_int
(queue_depth))
;
4379 }
4380
4381 c = libnvme_path_get_ctrl(p);
4382 ctrls = json_create_array()json_object_new_array();
4383 ctrl_attrs = json_create_object()json_object_new_object();
4384 obj_add_strjson_object_add_value_string(ctrl_attrs, "Name", libnvme_ctrl_get_name(c));
4385 obj_add_strjson_object_add_value_string(ctrl_attrs, "Transport", libnvme_ctrl_get_transport(c));
4386 obj_add_ctrl_address(ctrl_attrs, c);
4387 obj_add_ctrl_address_details(ctrl_attrs, "AddressDetails", c);
4388 obj_add_strjson_object_add_value_string(ctrl_attrs, "State", libnvme_ctrl_get_state(c));
4389 array_add_obj(ctrls, ctrl_attrs)json_object_array_add(ctrls, ctrl_attrs);
4390 obj_add_array(path_attrs, "Controller", ctrls)json_object_object_add(path_attrs, "Controller", ctrls);
4391
4392 array_add_obj(paths, path_attrs)json_object_array_add(paths, path_attrs);
4393 }
4394 obj_add_array(ns_attrs, "Paths", paths)json_object_object_add(ns_attrs, "Paths", paths);
4395 array_add_obj(namespaces, ns_attrs)json_object_array_add(namespaces, ns_attrs);
4396 i++;
4397 }
4398
4399 return i;
4400}
4401
4402static void json_print_nvme_subsystem_topology(struct libnvme_subsystem *s,
4403 json_object *namespaces)
4404{
4405 struct libnvme_ctrl *c;
4406 struct libnvme_ns *n;
4407
4408 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
4409 libnvme_ctrl_for_each_ns(c, n)for (n = libnvme_ctrl_first_ns(c); n != ((void*)0); n = libnvme_ctrl_next_ns
(c, n))
{
4410 struct json_object *ctrl_attrs;
4411 struct json_object *ns_attrs;
4412 struct json_object *ctrl;
4413
4414 ns_attrs = json_create_object()json_object_new_object();
4415 obj_add_int(ns_attrs, "NSID", libnvme_ns_get_nsid(n))json_object_object_add(ns_attrs, "NSID", json_object_new_int(
libnvme_ns_get_nsid(n)))
;
4416 obj_add_strjson_object_add_value_string(ns_attrs, "Name", libnvme_ns_get_name(n));
4417
4418 ctrl = json_create_array()json_object_new_array();
4419 ctrl_attrs = json_create_object()json_object_new_object();
4420 obj_add_strjson_object_add_value_string(ctrl_attrs, "Name",
4421 libnvme_ctrl_get_name(c));
4422 obj_add_strjson_object_add_value_string(ctrl_attrs, "Transport",
4423 libnvme_ctrl_get_transport(c));
4424 obj_add_ctrl_address(ctrl_attrs, c);
4425 obj_add_ctrl_address_details(ctrl_attrs, "AddressDetails", c);
4426 obj_add_strjson_object_add_value_string(ctrl_attrs, "State",
4427 libnvme_ctrl_get_state(c));
4428
4429 array_add_obj(ctrl, ctrl_attrs)json_object_array_add(ctrl, ctrl_attrs);
4430 obj_add_array(ns_attrs, "Controller", ctrl)json_object_object_add(ns_attrs, "Controller", ctrl);
4431 array_add_obj(namespaces, ns_attrs)json_object_array_add(namespaces, ns_attrs);
4432 }
4433 }
4434}
4435
4436static void json_simple_topology(struct libnvme_global_ctx *ctx)
4437{
4438 struct json_object *host_attrs, *subsystem_attrs;
4439 struct json_object *subsystems, *namespaces;
4440 struct json_object *a = json_create_array()json_object_new_array();
4441 struct libnvme_host *h;
4442
4443 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
{
4444 struct libnvme_subsystem *s;
4445 const char *hostid;
4446
4447 host_attrs = json_create_object()json_object_new_object();
4448 obj_add_strjson_object_add_value_string(host_attrs, "HostNQN", libnvme_host_get_hostnqn(h));
4449 hostid = libnvme_host_get_hostid(h);
4450 if (hostid)
4451 obj_add_strjson_object_add_value_string(host_attrs, "HostID", hostid);
4452 subsystems = json_create_array()json_object_new_array();
4453 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
{
4454 const char *iopolicy;
4455
4456 subsystem_attrs = json_create_object()json_object_new_object();
4457 obj_add_strjson_object_add_value_string(subsystem_attrs, "Name", libnvme_subsystem_get_name(s));
4458 obj_add_strjson_object_add_value_string(subsystem_attrs, "NQN", libnvme_subsystem_get_subsysnqn(s));
4459 libnvme_subsystem_get_iopolicy(s, &iopolicy, "");
4460 obj_add_strjson_object_add_value_string(subsystem_attrs, "IOPolicy", iopolicy);
4461
4462 if (verbose_mode()) {
4463 const char *model;
4464 const char *serial;
4465 const char *firmware;
4466
4467 libnvme_subsystem_get_model(s, &model, "");
4468 libnvme_subsystem_get_serial(s, &serial, "");
4469 libnvme_subsystem_get_firmware(s, &firmware,
4470 "");
4471
4472 obj_add_strjson_object_add_value_string(subsystem_attrs, "Model", model);
4473 obj_add_strjson_object_add_value_string(subsystem_attrs, "Serial", serial);
4474 obj_add_strjson_object_add_value_string(subsystem_attrs, "Firmware",
4475 firmware);
4476 obj_add_strjson_object_add_value_string(subsystem_attrs, "Type",
4477 libnvme_subsystem_get_subsystype(s));
4478 }
4479
4480 array_add_obj(subsystems, subsystem_attrs)json_object_array_add(subsystems, subsystem_attrs);
4481 namespaces = json_create_array()json_object_new_array();
4482
4483 if (!json_subsystem_topology_multipath(s, namespaces))
4484 json_print_nvme_subsystem_topology(s, namespaces);
4485
4486 obj_add_array(subsystem_attrs, "Namespaces", namespaces)json_object_object_add(subsystem_attrs, "Namespaces", namespaces
)
;
4487 }
4488 obj_add_array(host_attrs, "Subsystems", subsystems)json_object_object_add(host_attrs, "Subsystems", subsystems);
4489 array_add_obj(a, host_attrs)json_object_array_add(a, host_attrs);
4490 }
4491
4492 json_print(a);
4493}
4494
4495#ifdef CONFIG_TOP
4496/* A rate with two decimals, as nvme top shows it */
4497static void obj_add_rate(struct json_object *o, const char *k, double v)
4498{
4499 char buf[64];
4500
4501 snprintf(buf, sizeof(buf), "%.2f", v);
4502 json_object_object_add(o, k, json_object_new_double_s(v, buf));
4503}
4504
4505/* An attribute of a kernel which may not have it is left out */
4506static void obj_add_count(struct json_object *o, const char *k, int ret,
4507 long v)
4508{
4509 if (!ret)
4510 json_object_object_add(o, k, json_object_new_int64(v));
4511}
4512
4513static void obj_add_iostat(struct json_object *o, const struct nvme_iostat *st)
4514{
4515 struct json_object *r = json_create_object()json_object_new_object();
4516
4517 obj_add_rate(r, "ReadIOPS", st->r_iops);
4518 obj_add_rate(r, "WriteIOPS", st->w_iops);
4519 obj_add_rate(r, "ReadLatencyMs", st->r_lat);
4520 obj_add_rate(r, "WriteLatencyMs", st->w_lat);
4521 obj_add_rate(r, "ReadBytesPerSec", st->r_bw);
4522 obj_add_rate(r, "WriteBytesPerSec", st->w_bw);
4523 obj_add_uint(r, "Inflights", st->inflights)json_object_object_add(r, "Inflights", json_object_new_uint64
(st->inflights))
;
4524 obj_add_rate(r, "UtilPercent", st->util);
4525
4526 obj_add_obj(o, "Stats", r)json_object_object_add(o, "Stats", r);
4527}
4528
4529/* The sum of the rates, and the highest latencies and utilization */
4530static void obj_add_iostat_aggr(struct json_object *o,
4531 const struct nvme_iostat *st)
4532{
4533 struct json_object *r = json_create_object()json_object_new_object();
4534
4535 obj_add_rate(r, "ReadIOPS", st->r_iops);
4536 obj_add_rate(r, "WriteIOPS", st->w_iops);
4537 obj_add_rate(r, "MaxReadLatencyMs", st->r_lat);
4538 obj_add_rate(r, "MaxWriteLatencyMs", st->w_lat);
4539 obj_add_rate(r, "ReadBytesPerSec", st->r_bw);
4540 obj_add_rate(r, "WriteBytesPerSec", st->w_bw);
4541 obj_add_rate(r, "MaxUtilPercent", st->util);
4542
4543 obj_add_obj(o, "Stats", r)json_object_object_add(o, "Stats", r);
4544}
4545
4546static struct json_object *json_top_path(struct libnvme_path *p)
4547{
4548 struct json_object *r = json_create_object()json_object_new_object();
4549 struct nvme_iostat st;
4550 const char *str;
4551 int qdepth, ret;
4552 long v;
4553
4554 obj_add_strjson_object_add_value_string(r, "Name", libnvme_path_get_name(p));
4555 obj_add_strjson_object_add_value_string(r, "Controller",
4556 libnvme_ctrl_get_name(libnvme_path_get_ctrl(p)));
4557 if (!libnvme_path_get_ana_state(p, &str, NULL((void*)0)))
4558 obj_add_strjson_object_add_value_string(r, "ANAState", str);
4559 if (!libnvme_path_get_numa_nodes(p, &str, NULL((void*)0)))
4560 obj_add_strjson_object_add_value_string(r, "NUMANodes", str);
4561 if (!libnvme_path_get_queue_depth(p, &qdepth, 0))
4562 obj_add_int(r, "Qdepth", qdepth)json_object_object_add(r, "Qdepth", json_object_new_int(qdepth
))
;
4563 ret = libnvme_path_get_command_retry_count(p, &v, 0);
4564 obj_add_count(r, "Retries", ret, v);
4565 ret = libnvme_path_get_multipath_failover_count(p, &v, 0);
4566 obj_add_count(r, "Failovers", ret, v);
4567 ret = libnvme_path_get_command_error_count(p, &v, 0);
4568 obj_add_count(r, "Errors", ret, v);
4569
4570 nvme_iostat_path(p, &st);
4571 obj_add_iostat(r, &st);
4572
4573 return r;
4574}
4575
4576static struct json_object *json_top_nshead(struct libnvme_ns *n,
4577 struct nvme_iostat *aggr)
4578{
4579 struct json_object *r = json_create_object()json_object_new_object();
4580 struct json_object *paths = json_create_array()json_object_new_array();
4581 struct libnvme_path *p;
4582 struct nvme_iostat st;
4583 int ret;
4584 long v;
4585
4586 obj_add_strjson_object_add_value_string(r, "Name", libnvme_ns_get_name(n));
4587 obj_add_uint(r, "NSID", libnvme_ns_get_nsid(n))json_object_object_add(r, "NSID", json_object_new_uint64(libnvme_ns_get_nsid
(n)))
;
4588 ret = libnvme_ns_get_io_requeue_no_usable_path_count(n, &v, 0);
4589 obj_add_count(r, "RequeueIO", ret, v);
4590 ret = libnvme_ns_get_io_fail_no_available_path_count(n, &v, 0);
4591 obj_add_count(r, "FailIO", ret, v);
4592
4593 nvme_iostat_ns(n, &st);
4594 nvme_iostat_aggr(aggr, &st);
4595 obj_add_iostat(r, &st);
4596
4597 libnvme_namespace_for_each_path(n, p)for (p = libnvme_namespace_first_path(n); p != ((void*)0); p =
libnvme_namespace_next_path(n, p))
4598 array_add_obj(paths, json_top_path(p))json_object_array_add(paths, json_top_path(p));
4599 obj_add_array(r, "Paths", paths)json_object_object_add(r, "Paths", paths);
4600
4601 return r;
4602}
4603
4604static struct json_object *json_top_ns(struct libnvme_ns *n,
4605 struct libnvme_ctrl *c,
4606 struct nvme_iostat *aggr)
4607{
4608 struct json_object *r = json_create_object()json_object_new_object();
4609 struct nvme_iostat st;
4610 int ret;
4611 long v;
4612
4613 obj_add_strjson_object_add_value_string(r, "Name", libnvme_ns_get_name(n));
4614 obj_add_uint(r, "NSID", libnvme_ns_get_nsid(n))json_object_object_add(r, "NSID", json_object_new_uint64(libnvme_ns_get_nsid
(n)))
;
4615 obj_add_strjson_object_add_value_string(r, "Controller", libnvme_ctrl_get_name(c));
4616 ret = libnvme_ns_get_command_retry_count(n, &v, 0);
4617 obj_add_count(r, "Retries", ret, v);
4618 ret = libnvme_ns_get_command_error_count(n, &v, 0);
4619 obj_add_count(r, "Errors", ret, v);
4620
4621 nvme_iostat_ns(n, &st);
4622 nvme_iostat_aggr(aggr, &st);
4623 obj_add_iostat(r, &st);
4624
4625 return r;
4626}
4627
4628static struct json_object *json_top_ctrl(struct libnvme_ctrl *c,
4629 bool_Bool multipath)
4630{
4631 struct json_object *r = json_create_object()json_object_new_object();
4632 struct nvme_iostat aggr = { 0 }, st;
4633 struct libnvme_path *p;
4634 struct libnvme_ns *n;
4635 const char *node;
4636 int npaths = 0, ret;
4637 long v;
4638
4639 obj_add_strjson_object_add_value_string(r, "Name", libnvme_ctrl_get_name(c));
4640 obj_add_strjson_object_add_value_string(r, "Transport", libnvme_ctrl_get_transport(c));
4641 obj_add_ctrl_address(r, c);
4642 obj_add_strjson_object_add_value_string(r, "State", libnvme_ctrl_get_state(c));
4643 if (!libnvme_ctrl_get_numa_node(c, &node, NULL((void*)0)))
4644 obj_add_int(r, "NUMANode", atoi(node))json_object_object_add(r, "NUMANode", json_object_new_int(atoi
(node)))
;
4645 ret = libnvme_ctrl_get_reset_count(c, &v, 0);
4646 obj_add_count(r, "Resets", ret, v);
4647 ret = libnvme_ctrl_get_reconnect_count(c, &v, 0);
4648 obj_add_count(r, "Reconnects", ret, v);
4649 ret = libnvme_ctrl_get_command_error_count(c, &v, 0);
4650 obj_add_count(r, "Errors", ret, v);
4651
4652 if (multipath) {
4653 libnvme_ctrl_for_each_path(c, p)for (p = libnvme_ctrl_first_path(c); p != ((void*)0); p = libnvme_ctrl_next_path
(c, p))
{
4654 npaths++;
4655 nvme_iostat_path(p, &st);
4656 nvme_iostat_aggr(&aggr, &st);
4657 }
4658 obj_add_int(r, "Paths", npaths)json_object_object_add(r, "Paths", json_object_new_int(npaths
))
;
4659 } else {
4660 libnvme_ctrl_for_each_ns(c, n)for (n = libnvme_ctrl_first_ns(c); n != ((void*)0); n = libnvme_ctrl_next_ns
(c, n))
{
4661 nvme_iostat_ns(n, &st);
4662 nvme_iostat_aggr(&aggr, &st);
4663 }
4664 }
4665 obj_add_iostat_aggr(r, &aggr);
4666
4667 return r;
4668}
4669
4670static struct json_object *json_top_subsys(struct libnvme_subsystem *s)
4671{
4672 struct json_object *r = json_create_object()json_object_new_object();
4673 struct json_object *namespaces = json_create_array()json_object_new_array();
4674 struct json_object *ctrls = json_create_array()json_object_new_array();
4675 bool_Bool multipath = nvme_is_multipath(s);
4676 struct nvme_iostat aggr = { 0 };
4677 struct libnvme_ctrl *c;
4678 struct libnvme_ns *n;
4679 const char *str;
4680
4681 obj_add_strjson_object_add_value_string(r, "Name", libnvme_subsystem_get_name(s));
4682 obj_add_strjson_object_add_value_string(r, "NQN", libnvme_subsystem_get_subsysnqn(s));
4683 obj_add_strjson_object_add_value_string(r, "HostNQN",
4684 libnvme_host_get_hostnqn(libnvme_subsystem_get_host(s)));
4685 if (!libnvme_subsystem_get_iopolicy(s, &str, NULL((void*)0)))
4686 obj_add_strjson_object_add_value_string(r, "IOPolicy", str);
4687 if (!libnvme_subsystem_get_model(s, &str, NULL((void*)0)))
4688 obj_add_strjson_object_add_value_string(r, "Model", str);
4689 if (!libnvme_subsystem_get_serial(s, &str, NULL((void*)0)))
4690 obj_add_strjson_object_add_value_string(r, "Serial", str);
4691 if (!libnvme_subsystem_get_firmware(s, &str, NULL((void*)0)))
4692 obj_add_strjson_object_add_value_string(r, "Firmware", str);
4693 obj_add_strjson_object_add_value_string(r, "Type", libnvme_subsystem_get_subsystype(s));
4694
4695 if (multipath) {
4696 libnvme_subsystem_for_each_ns(s, n)for (n = libnvme_subsystem_first_ns(s); n != ((void*)0); n = libnvme_subsystem_next_ns
(s, n))
4697 array_add_obj(namespaces, json_top_nshead(n, &aggr))json_object_array_add(namespaces, json_top_nshead(n, &aggr
))
;
4698 } else {
4699 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
4700 libnvme_ctrl_for_each_ns(c, n)for (n = libnvme_ctrl_first_ns(c); n != ((void*)0); n = libnvme_ctrl_next_ns
(c, n))
4701 array_add_obj(namespaces,json_object_array_add(namespaces, json_top_ns(n, c, &aggr
))
4702 json_top_ns(n, c, &aggr))json_object_array_add(namespaces, json_top_ns(n, c, &aggr
))
;
4703 }
4704 obj_add_iostat_aggr(r, &aggr);
4705 obj_add_array(r, "Namespaces", namespaces)json_object_object_add(r, "Namespaces", namespaces);
4706
4707 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
4708 array_add_obj(ctrls, json_top_ctrl(c, multipath))json_object_array_add(ctrls, json_top_ctrl(c, multipath));
4709 obj_add_array(r, "Controllers", ctrls)json_object_object_add(r, "Controllers", ctrls);
4710
4711 return r;
4712}
4713
4714static void json_top_update(struct libnvme_global_ctx *ctx)
4715{
4716 struct libnvme_subsystem *s;
4717 struct libnvme_host *h;
4718
4719 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
4720 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
4721 nvme_iostat_update_subsys(s, nvme_is_multipath(s));
4722}
4723
4724/* Takes two samples @interval seconds apart and prints the rates */
4725static void json_top(int interval)
4726{
4727 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
4728 struct json_object *r, *subsystems;
4729 struct libnvme_subsystem *s;
4730 struct libnvme_host *h;
4731 int err;
4732
4733 err = nvme_create_global_ctx(&ctx);
4734 if (err)
4735 return;
4736
4737 if (libnvme_scan_topology(ctx, NULL((void*)0), NULL((void*)0))) {
4738 nvme_show_error("Failed to scan topology")nvme_show_message(1, "Failed to scan topology");
4739 return;
4740 }
4741
4742 json_top_update(ctx);
4743 sleep(interval);
4744 json_top_update(ctx);
4745
4746 r = json_create_object()json_object_new_object();
4747 obj_add_int(r, "Interval", interval)json_object_object_add(r, "Interval", json_object_new_int(interval
))
;
4748 subsystems = json_create_array()json_object_new_array();
4749 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
4750 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
4751 array_add_obj(subsystems, json_top_subsys(s))json_object_array_add(subsystems, json_top_subsys(s));
4752 obj_add_array(r, "Subsystems", subsystems)json_object_object_add(r, "Subsystems", subsystems);
4753
4754 json_print(r);
4755}
4756#endif /* CONFIG_TOP */
4757
4758static void json_directive_show_fields_identify(__u8 doper, __u8 *field,
4759 __u32 len,
4760 struct json_object *r)
4761{
4762 struct json_object *support;
4763 struct json_object *enabled;
4764 struct json_object *persistent;
4765
4766 switch (doper) {
4767 case NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM:
4768 if (len < NVME_DIRECTIVE_IDENTIFY_PARAM_LEN96) {
4769 obj_add_strjson_object_add_value_string(r, "Error", "directive data too short");
4770 break;
4771 }
4772 support = json_create_object()json_object_new_object();
4773 obj_add_obj(r, "Directive support", support)json_object_object_add(r, "Directive support", support);
4774 obj_add_strjson_object_add_value_string(support, "Identify Directive",
4775 *field & 0x1 ? "Supported" : "Not supported");
4776 obj_add_strjson_object_add_value_string(support, "Stream Directive",
4777 *field & 0x2 ? "Supported" : "Not supported");
4778 obj_add_strjson_object_add_value_string(support, "Data Placement Directive",
4779 *field & 0x4 ? "Supported" : "Not supported");
4780 enabled = json_create_object()json_object_new_object();
4781 obj_add_obj(r, "Directive enabled", enabled)json_object_object_add(r, "Directive enabled", enabled);
4782 obj_add_strjson_object_add_value_string(enabled, "Identify Directive",
4783 *(field + 32) & 0x1 ? "Enabled" : "Disabled");
4784 obj_add_strjson_object_add_value_string(enabled, "Stream Directive",
4785 *(field + 32) & 0x2 ? "Enabled" : "Disabled");
4786 obj_add_strjson_object_add_value_string(enabled, "Data Placement Directive",
4787 *(field + 32) & 0x4 ? "Enabled" : "Disabled");
4788 persistent = json_create_object()json_object_new_object();
4789 obj_add_obj(r,json_object_object_add(r, "Directive Persistent Across Controller Level Resets"
, persistent)
4790 "Directive Persistent Across Controller Level Resets",json_object_object_add(r, "Directive Persistent Across Controller Level Resets"
, persistent)
4791 persistent)json_object_object_add(r, "Directive Persistent Across Controller Level Resets"
, persistent)
;
4792 obj_add_strjson_object_add_value_string(persistent, "Identify Directive",
4793 *(field + 64) & 0x1 ? "Enabled" : "Disabled");
4794 obj_add_strjson_object_add_value_string(persistent, "Stream Directive",
4795 *(field + 64) & 0x2 ? "Enabled" : "Disabled");
4796 obj_add_strjson_object_add_value_string(persistent, "Data Placement Directive",
4797 *(field + 64) & 0x4 ? "Enabled" : "Disabled");
4798 break;
4799 default:
4800 obj_add_strjson_object_add_value_string(r, "Error", "invalid directive operations for Identify Directives");
4801 break;
4802 }
4803}
4804
4805static void json_directive_show_fields_streams(__u8 doper,
4806 unsigned int result, __u8 *field,
4807 __u32 len, struct json_object *r)
4808{
4809 struct nvme_streams_directive_params *params = (void *)field;
4810 struct nvme_streams_directive_status *status = (void *)field;
4811 int count;
4812 int i;
4813 char json_str[STR_LEN100];
4814
4815 switch (doper) {
4816 case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM:
4817 if (len < sizeof(*params)) {
4818 obj_add_strjson_object_add_value_string(r, "Error", "directive data too short");
4819 break;
4820 }
4821 obj_add_uint(r, "Max Streams Limit (MSL)",json_object_object_add(r, "Max Streams Limit (MSL)", json_object_new_uint64
(le16_to_cpu(params->msl)))
4822 le16_to_cpu(params->msl))json_object_object_add(r, "Max Streams Limit (MSL)", json_object_new_uint64
(le16_to_cpu(params->msl)))
;
4823 obj_add_uint(r, "NVM Subsystem Streams Available (NSSA)",json_object_object_add(r, "NVM Subsystem Streams Available (NSSA)"
, json_object_new_uint64(le16_to_cpu(params->nssa)))
4824 le16_to_cpu(params->nssa))json_object_object_add(r, "NVM Subsystem Streams Available (NSSA)"
, json_object_new_uint64(le16_to_cpu(params->nssa)))
;
4825 obj_add_uint(r, "NVM Subsystem Streams Open (NSSO)",json_object_object_add(r, "NVM Subsystem Streams Open (NSSO)"
, json_object_new_uint64(le16_to_cpu(params->nsso)))
4826 le16_to_cpu(params->nsso))json_object_object_add(r, "NVM Subsystem Streams Open (NSSO)"
, json_object_new_uint64(le16_to_cpu(params->nsso)))
;
4827 obj_add_uint(r, "NVM Subsystem Stream Capability (NSSC)",json_object_object_add(r, "NVM Subsystem Stream Capability (NSSC)"
, json_object_new_uint64(params->nssc))
4828 params->nssc)json_object_object_add(r, "NVM Subsystem Stream Capability (NSSC)"
, json_object_new_uint64(params->nssc))
;
4829 obj_add_uint(r, "Stream Write Size (in unit of LB size) (SWS)",json_object_object_add(r, "Stream Write Size (in unit of LB size) (SWS)"
, json_object_new_uint64(le32_to_cpu(params->sws)))
4830 le32_to_cpu(params->sws))json_object_object_add(r, "Stream Write Size (in unit of LB size) (SWS)"
, json_object_new_uint64(le32_to_cpu(params->sws)))
;
4831 obj_add_uint(r, "Stream Granularity Size (in unit of SWS) (SGS)",json_object_object_add(r, "Stream Granularity Size (in unit of SWS) (SGS)"
, json_object_new_uint64(le16_to_cpu(params->sgs)))
4832 le16_to_cpu(params->sgs))json_object_object_add(r, "Stream Granularity Size (in unit of SWS) (SGS)"
, json_object_new_uint64(le16_to_cpu(params->sgs)))
;
4833 obj_add_uint(r, "Namespace Streams Allocated (NSA)",json_object_object_add(r, "Namespace Streams Allocated (NSA)"
, json_object_new_uint64(le16_to_cpu(params->nsa)))
4834 le16_to_cpu(params->nsa))json_object_object_add(r, "Namespace Streams Allocated (NSA)"
, json_object_new_uint64(le16_to_cpu(params->nsa)))
;
4835 obj_add_uint(r, "Namespace Streams Open (NSO)",json_object_object_add(r, "Namespace Streams Open (NSO)", json_object_new_uint64
(le16_to_cpu(params->nso)))
4836 le16_to_cpu(params->nso))json_object_object_add(r, "Namespace Streams Open (NSO)", json_object_new_uint64
(le16_to_cpu(params->nso)))
;
4837 break;
4838 case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS:
4839 if (len < sizeof(*status)) {
4840 obj_add_strjson_object_add_value_string(r, "Error", "directive data too short");
4841 break;
4842 }
4843 count = nvme_streams_status_nr_sid(status, len);
4844 obj_add_uint(r, "Open Stream Count", le16_to_cpu(status->osc))json_object_object_add(r, "Open Stream Count", json_object_new_uint64
(le16_to_cpu(status->osc)))
;
4845 for (i = 0; i < count; i++) {
4846 sprintf(json_str, "Stream Identifier %.6u", i + 1);
4847 obj_add_uint(r, json_str, le16_to_cpu(status->sid[i]))json_object_object_add(r, json_str, json_object_new_uint64(le16_to_cpu
(status->sid[i])))
;
4848 }
4849 break;
4850 case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE:
4851 obj_add_uint(r, "Namespace Streams Allocated (NSA)", result & 0xffff)json_object_object_add(r, "Namespace Streams Allocated (NSA)"
, json_object_new_uint64(result & 0xffff))
;
4852 break;
4853 default:
4854 obj_add_strjson_object_add_value_string(r, "Error",
4855 "invalid directive operations for Streams Directives");
4856 break;
4857 }
4858}
4859
4860static void json_directive_show_fields(__u8 dtype, __u8 doper, unsigned int result,
4861 __u8 *field, __u32 len,
4862 struct json_object *r)
4863{
4864 switch (dtype) {
4865 case NVME_DIRECTIVE_DTYPE_IDENTIFY:
4866 json_directive_show_fields_identify(doper, field, len, r);
4867 break;
4868 case NVME_DIRECTIVE_DTYPE_STREAMS:
4869 json_directive_show_fields_streams(doper, result, field, len,
4870 r);
4871 break;
4872 default:
4873 obj_add_strjson_object_add_value_string(r, "Error", "invalid directive type");
4874 break;
4875 }
4876}
4877
4878static void json_directive_show(__u8 type, __u8 oper, __u16 spec, __u32 nsid, __u64 result,
4879 void *buf, __u32 len)
4880{
4881 struct json_object *r = json_r;
4882 struct json_object *data;
4883 char json_str[STR_LEN100];
4884
4885 sprintf(json_str, "%#x", type);
4886 obj_add_strjson_object_add_value_string(r, "Type", json_str);
4887 sprintf(json_str, "%#x", oper);
4888 obj_add_strjson_object_add_value_string(r, "Operation", json_str);
4889 sprintf(json_str, "%#x", spec);
4890 obj_add_strjson_object_add_value_string(r, "spec", json_str);
4891 sprintf(json_str, "%#x", nsid);
4892 obj_add_strjson_object_add_value_string(r, "NSID", json_str);
4893 sprintf(json_str, "%#"PRIx64"l" "x", (uint64_t)result);
4894 obj_add_result(r, json_str);
4895
4896 if (verbose_mode()) {
4897 json_directive_show_fields(type, oper, result, buf, len, r);
4898 } else if (buf) {
4899 data = json_create_array()json_object_new_array();
4900 d_json((unsigned char *)buf, len, 16, 1, data);
4901 obj_add_array(r, "data", data)json_object_object_add(r, "data", data);
4902 }
4903}
4904
4905#ifdef CONFIG_FABRICS
4906static void json_discovery_log(const struct nvmf_discovery_log *log, int numrec)
4907{
4908 struct json_object *r = json_r;
4909 struct json_object *entries = json_create_array()json_object_new_array();
4910 int i;
4911
4912 obj_add_uint64(r, "genctr", le64_to_cpu(log->genctr))json_object_object_add(r, "genctr", json_object_new_uint64(le64_to_cpu
(log->genctr)))
;
4913 obj_add_array(r, "records", entries)json_object_object_add(r, "records", entries);
4914
4915 for (i = 0; i < numrec; i++) {
4916 const struct nvmf_disc_log_entry *e = &log->entries[i];
4917 struct json_object *entry = json_create_object()json_object_new_object();
4918 /*
4919 * e->trsvcid/subnqn/traddr are fixed-width fields off the wire,
4920 * not guaranteed NUL-terminated. json_object_new_string()
4921 * needs a NUL-terminated C string, so make NUL-terminated
4922 * copies and trim trailing spaces (if any). Members of e
4923 * cannot be modified directly (we do not own that data).
4924 */
4925 __cleanup_free__attribute__((cleanup(shr_freep))) char *trsvcid = NULL((void*)0);
4926 __cleanup_free__attribute__((cleanup(shr_freep))) char *traddr = NULL((void*)0);
4927 __cleanup_free__attribute__((cleanup(shr_freep))) char *subnqn = NULL((void*)0);
4928
4929 trsvcid = shr_buf2str(e->trsvcid, sizeof(e->trsvcid));
4930 traddr = shr_buf2str(e->traddr, sizeof(e->traddr));
4931 subnqn = shr_buf2str(e->subnqn, sizeof(e->subnqn));
4932
4933 obj_add_strjson_object_add_value_string(entry, "trtype", libnvmf_trtype_str(e->trtype));
4934 obj_add_strjson_object_add_value_string(entry, "adrfam", libnvmf_adrfam_str(e->adrfam));
4935 obj_add_strjson_object_add_value_string(entry, "subtype", libnvmf_subtype_str(e->subtype));
4936 obj_add_strjson_object_add_value_string(entry, "treq", libnvmf_treq_str(e->treq));
4937 obj_add_uint(entry, "portid", le16_to_cpu(e->portid))json_object_object_add(entry, "portid", json_object_new_uint64
(le16_to_cpu(e->portid)))
;
4938 obj_add_strjson_object_add_value_string(entry, "trsvcid", trsvcid);
4939 obj_add_strjson_object_add_value_string(entry, "subnqn", subnqn);
4940 obj_add_strjson_object_add_value_string(entry, "traddr", traddr);
4941 obj_add_strjson_object_add_value_string(entry, "eflags", libnvmf_eflags_str(le16_to_cpu(e->eflags)));
4942
4943 switch (e->trtype) {
4944 case NVMF_TRTYPE_RDMA:
4945 obj_add_strjson_object_add_value_string(entry, "rdma_prtype", libnvmf_prtype_str(e->tsas.rdma.prtype));
4946 obj_add_strjson_object_add_value_string(entry, "rdma_qptype", libnvmf_qptype_str(e->tsas.rdma.qptype));
4947 obj_add_strjson_object_add_value_string(entry, "rdma_cms", libnvmf_cms_str(e->tsas.rdma.cms));
4948 obj_add_uint(entry, "rdma_pkey", le16_to_cpu(e->tsas.rdma.pkey))json_object_object_add(entry, "rdma_pkey", json_object_new_uint64
(le16_to_cpu(e->tsas.rdma.pkey)))
;
4949 break;
4950 case NVMF_TRTYPE_TCP:
4951 obj_add_strjson_object_add_value_string(entry, "sectype", libnvmf_sectype_str(e->tsas.tcp.sectype));
4952 break;
4953 default:
4954 break;
4955 }
4956 array_add_obj(entries, entry)json_object_array_add(entries, entry);
4957 }
4958}
4959#else
4960static void json_discovery_log(const struct nvmf_discovery_log *log,
4961 int numrec)
4962{
4963}
4964#endif
4965
4966#ifdef CONFIG_FABRICS
4967static void json_add_param(const char *key, const char *value, void *user_data)
4968{
4969 obj_add_strjson_object_add_value_string(user_data, key, value);
4970}
4971
4972/*
4973 * libnvmf_config_conn_for_each() callback for "nvme config show -o json".
4974 * Reports fields as configured, not canonicalized through a TID (which has
4975 * no per-field accessors). hostnqn/hostid are null when a persona falls
4976 * back to the system default, not the value it would resolve to.
4977 */
4978static void json_add_conn(const struct libnvmf_config_conn *c, void *user_data)
4979{
4980 struct json_object *entries = user_data;
4981 struct json_object *entry = json_create_object()json_object_new_object();
4982 struct json_object *params_obj = json_create_object()json_object_new_object();
4983 const struct libnvmf_params *params = libnvmf_config_conn_get_params(c);
4984
4985 obj_add_strjson_object_add_value_string(entry, "source", libnvmf_config_conn_get_source(c));
4986 obj_add_bool(entry, "is_dc", libnvmf_config_conn_is_dc(c))json_object_object_add(entry, "is_dc", json_object_new_boolean
(libnvmf_config_conn_is_dc(c)))
;
4987 obj_add_strjson_object_add_value_string(entry, "transport", libnvmf_config_conn_get_transport(c));
4988 obj_add_strjson_object_add_value_string(entry, "traddr", libnvmf_config_conn_get_traddr(c));
4989 obj_add_strjson_object_add_value_string(entry, "trsvcid", libnvmf_config_conn_get_trsvcid(c));
4990 obj_add_strjson_object_add_value_string(entry, "nqn", libnvmf_config_conn_get_subsysnqn(c));
4991 obj_add_strjson_object_add_value_string(entry, "host-traddr",
4992 libnvmf_config_conn_get_host_traddr(c));
4993 obj_add_strjson_object_add_value_string(entry, "host-iface", libnvmf_config_conn_get_host_iface(c));
4994 obj_add_strjson_object_add_value_string(entry, "hostnqn", libnvmf_config_conn_get_hostnqn(c));
4995 obj_add_strjson_object_add_value_string(entry, "hostid", libnvmf_config_conn_get_hostid(c));
4996
4997 libnvmf_params_for_each(params, json_add_param, params_obj);
4998 obj_add_obj(entry, "params", params_obj)json_object_object_add(entry, "params", params_obj);
4999
5000 array_add_obj(entries, entry)json_object_array_add(entries, entry);
5001}
5002
5003static void json_config_conn_list(struct libnvmf_config *config)
5004{
5005 struct json_object *r = json_r;
5006 struct json_object *entries = json_create_array()json_object_new_array();
5007
5008 obj_add_array(r, "connections", entries)json_object_object_add(r, "connections", entries);
5009 libnvmf_config_conn_for_each(config, json_add_conn, entries);
5010}
5011#else
5012static void json_config_conn_list(struct libnvmf_config *config) {}
5013#endif
5014
5015static void json_connect_msg(struct libnvme_ctrl *c)
5016{
5017 struct json_object *r = json_r;
5018
5019 obj_add_strjson_object_add_value_string(r, "device", libnvme_ctrl_get_name(c));
5020}
5021
5022static void json_output_object(struct json_object *r)
5023{
5024 json_print(r);
5025}
5026
5027static void json_output_status(int status)
5028{
5029 struct json_object *r;
5030 char json_str[STR_LEN100];
5031 int val;
5032 int type;
5033
5034 sprintf(json_str, "status: %d", status);
5035 r = obj_create(json_str);
5036
5037 if (status < 0) {
5038 obj_add_strjson_object_add_value_string(r, "error", libnvme_strerror(-status));
5039 obj_print(r);
5040 return;
5041 }
5042
5043 val = nvme_status_get_value(status);
5044 type = nvme_status_get_type(status);
5045
5046 switch (type) {
5047 case NVME_STATUS_TYPE_NVME:
5048 obj_add_strjson_object_add_value_string(r, "error", libnvme_status_to_string(val, false0));
5049 obj_add_strjson_object_add_value_string(r, "type", "nvme");
5050 break;
5051#ifdef CONFIG_MI
5052 case NVME_STATUS_TYPE_MI:
5053 obj_add_strjson_object_add_value_string(r, "error", libnvme_mi_status_to_string(val));
5054 obj_add_strjson_object_add_value_string(r, "type", "nvme-mi");
5055 break;
5056#endif
5057 default:
5058 obj_add_strjson_object_add_value_string(r, "type", "Unknown");
5059 break;
5060 }
5061
5062 obj_print(r);
5063}
5064
5065static void json_output_opcode_status(int status, bool_Bool admin, __u8 opcode)
5066{
5067 struct json_object *r;
5068 char json_str[STR_LEN100];
5069 int val = nvme_status_get_value(status);
5070 int type = nvme_status_get_type(status);
5071
5072 if (status >= 0 && type == NVME_STATUS_TYPE_NVME) {
5073 sprintf(json_str, "status: %d", status);
5074 r = obj_create(json_str);
5075 obj_add_strjson_object_add_value_string(r, "error",
5076 libnvme_opcode_status_to_string(val, admin, opcode));
5077 obj_add_strjson_object_add_value_string(r, "type", "nvme");
5078 obj_print(r);
5079 return;
5080 }
5081
5082 json_output_status(status);
5083}
5084
5085static void json_output_error_status(int status, const char *msg, va_list ap)
5086{
5087 struct json_object *r;
5088 char json_str[STR_LEN100];
5089 int val;
5090 int type;
5091
5092 __cleanup_free__attribute__((cleanup(shr_freep))) char *value = NULL((void*)0);
5093
5094 if (vasprintf(&value, msg, ap) < 0)
5095 value = NULL((void*)0);
5096
5097 sprintf(json_str, "Error: %s", value ? value : alloc_error);
5098 r = obj_create(json_str);
5099
5100 if (status < 0) {
5101 obj_add_strjson_object_add_value_string(r, "error", libnvme_strerror(-status));
5102 obj_print(r);
5103 return;
5104 }
5105
5106 val = nvme_status_get_value(status);
5107 type = nvme_status_get_type(status);
5108
5109 switch (type) {
5110 case NVME_STATUS_TYPE_NVME:
5111 obj_add_strjson_object_add_value_string(r, "status", libnvme_status_to_string(val, false0));
5112 obj_add_strjson_object_add_value_string(r, "type", "nvme");
5113 break;
5114#ifdef CONFIG_MI
5115 case NVME_STATUS_TYPE_MI:
5116 obj_add_strjson_object_add_value_string(r, "status", libnvme_mi_status_to_string(val));
5117 obj_add_strjson_object_add_value_string(r, "type", "nvme-mi");
5118 break;
5119#endif
5120 default:
5121 obj_add_strjson_object_add_value_string(r, "type", "Unknown");
5122 break;
5123 }
5124
5125 obj_add_int(r, "value", val)json_object_object_add(r, "value", json_object_new_int(val));
5126
5127 obj_print(r);
5128}
5129
5130static void json_output_message(bool_Bool error, const char *msg, va_list ap)
5131{
5132 struct json_object *r = json_r;
5133
5134 __cleanup_free__attribute__((cleanup(shr_freep))) char *value = NULL((void*)0);
5135
5136 if (vasprintf(&value, msg, ap) < 0)
5137 value = NULL((void*)0);
5138
5139 obj_add_strjson_object_add_value_string(r, error ? "error" : "result", value ? value : alloc_error);
5140}
5141
5142static void json_output_perror(const char *msg, va_list ap)
5143{
5144 struct json_object *r = json_r;
5145 int err = errno(*__errno_location ());
5146
5147 __cleanup_free__attribute__((cleanup(shr_freep))) char *error = NULL((void*)0);
5148
5149 if (vasprintf(&error, msg, ap) < 0)
5150 error = NULL((void*)0);
5151
5152 obj_add_key(r, "error", "%s: %s", error ? error : alloc_error,
5153 libnvme_strerror(err));
5154}
5155
5156static char *trim_white_space(char *str)
5157{
5158 char *end;
5159
5160 if (!str)
5161 return NULL((void*)0);
5162
5163 /* Trim leading space */
5164 while (isspace((unsigned char)*str)((*__ctype_b_loc ())[(int) (((unsigned char)*str))] & (unsigned
short int) _ISspace)
)
5165 str++;
5166
5167 /* All spaces */
5168 if (!*str)
5169 return str;
5170
5171 /* Trim trailing space */
5172 end = str + strlen(str) - 1;
5173 while (end > str && isspace((unsigned char)*end)((*__ctype_b_loc ())[(int) (((unsigned char)*end))] & (unsigned
short int) _ISspace)
)
5174 end--;
5175
5176 /* Write new null terminator character */
5177 end[1] = '\0';
5178
5179 return str;
5180}
5181
5182static void json_output_key_value(const char *key, const char *val, va_list ap)
5183{
5184 struct json_object *r = json_r;
5185
5186 __cleanup_free__attribute__((cleanup(shr_freep))) char *value = NULL((void*)0);
5187 __cleanup_free__attribute__((cleanup(shr_freep))) char *key_dup = strdup(key);
5188 char *key_trim = trim_white_space(key_dup);
5189
5190 if (vasprintf(&value, val, ap) < 0)
5191 value = NULL((void*)0);
5192
5193 obj_add_strjson_object_add_value_string(r, key_trim ? key_trim : key, value ? value : "Could not allocate string");
5194}
5195
5196void json_show_init(void)
5197{
5198 json_init = true1;
5199
5200 if (!json_r)
5201 json_r = json_create_object()json_object_new_object();
5202}
5203
5204bool_Bool json_empty(struct json_object *obj)
5205{
5206 if (!obj)
5207 return true1;
5208
5209 switch (json_object_get_type(obj)) {
5210 case json_type_object:
5211 return json_object_object_length(obj) == 0;
5212 case json_type_array:
5213 return json_object_array_length(obj) == 0;
5214 default:
5215 return false0; /* scalars always have something to print */
5216 }
5217}
5218
5219void json_show_finish(void)
5220{
5221 /* nvme_main() finishes even if no command started a document */
5222 if (!json_init)
5223 return;
5224 json_init = false0;
5225
5226 if (!json_empty(json_r))
5227 json_output_object(json_r);
5228 else
5229 json_free_object(json_r)json_object_put(json_r);
5230
5231 json_r = NULL((void*)0);
5232}
5233
5234/*
5235 * A sandboxed printer: the child inherits the document as it was at the
5236 * fork. Let the printer write to an object of its own instead, whose
5237 * members the caller adds to its document.
5238 */
5239static int json_capture_begin(void)
5240{
5241 if (!json_init)
5242 return 0;
5243
5244 json_r = json_create_object()json_object_new_object();
5245 return json_r ? 0 : -ENOMEM12;
5246}
5247
5248static int json_member_put(struct printbuf *pb, const char *s, size_t len)
5249{
5250 uint32_t n = len;
5251
5252 if (len > UINT32_MAX(4294967295U))
5253 return -EOVERFLOW75;
5254 printbuf_memappend(pb, (const char *)&n, sizeof(n));
5255 printbuf_memappend(pb, s, len);
5256
5257 return 0;
5258}
5259
5260/*
5261 * The members the printer added, serialized as pairs of a length and the
5262 * key, a length and the value. @buf is to free().
5263 */
5264static int json_capture_end(void **buf, size_t *len)
5265{
5266 struct printbuf *pb;
5267 const char *v;
5268 int err = 0;
5269
5270 *buf = NULL((void*)0);
5271 *len = 0;
5272 if (!json_init)
5273 return 0;
5274
5275 pb = printbuf_new();
5276 if (!pb)
5277 return -ENOMEM12;
5278 json_object_object_foreach(json_r, key, val)char *key = ((void*)0); struct json_object *val __attribute__
((__unused__)) = ((void*)0); for (struct lh_entry *entrykey =
lh_table_head(json_object_get_object(json_r)), *entry_nextkey
= ((void*)0); ({ if (entrykey) { key = (char *)lh_entry_k(entrykey
); val = (struct json_object *)lh_entry_v(entrykey); entry_nextkey
= lh_entry_next(entrykey); }; entrykey; }); entrykey = entry_nextkey
)
{
5279 v = json_object_to_json_string_ext(val,
5280 JSON_C_TO_STRING_PRETTY(1 << 1) |
5281 JSON_C_TO_STRING_NOSLASHESCAPE(1 << 4));
5282 if (!v || json_member_put(pb, key, strlen(key)) ||
5283 json_member_put(pb, v, strlen(v))) {
5284 err = -ENOMEM12;
5285 break;
5286 }
5287 }
5288 if (!err && printbuf_length(pb)((pb)->bpos)) {
5289 *buf = malloc(printbuf_length(pb)((pb)->bpos));
5290 if (*buf) {
5291 memcpy(*buf, pb->buf, printbuf_length(pb)((pb)->bpos));
5292 *len = printbuf_length(pb)((pb)->bpos);
5293 } else {
5294 err = -ENOMEM12;
5295 }
5296 }
5297 printbuf_free(pb);
5298
5299 return err;
5300}
5301
5302/* Writes a serialized value as it is, indented to @level */
5303static int json_member_serialize(struct json_object *jso,
5304 struct printbuf *pb, int level, int flags)
5305{
5306 const char *s = json_object_get_string(jso);
5307 size_t len = json_object_get_string_len(jso), i, start = 0;
5308 int j;
5309
5310 for (i = 0; i < len; i++) {
5311 if (s[i] != '\n')
5312 continue;
5313 printbuf_memappend(pb, s + start, i - start + 1);
5314 start = i + 1;
5315 if (flags & JSON_C_TO_STRING_PRETTY(1 << 1))
5316 for (j = 0; j < level; j++)
5317 printbuf_strappend(pb, " ")printbuf_memappend((pb), ("" " "), sizeof(" ") - 1);
5318 }
5319 printbuf_memappend(pb, s + start, len - start);
5320
5321 return 0;
5322}
5323
5324static bool_Bool json_member_get(const char **p, const char *end,
5325 const char **s, uint32_t *n)
5326{
5327 if ((size_t)(end - *p) < sizeof(*n))
5328 return false0;
5329 memcpy(n, *p, sizeof(*n));
5330 *p += sizeof(*n);
5331 if ((size_t)(end - *p) < *n)
5332 return false0;
5333 *s = *p;
5334 *p += *n;
5335
5336 return true1;
5337}
5338
5339/*
5340 * Adds the members of a sandboxed printer to the document. They are added
5341 * as the child serialized them, not parsed again: a parse would turn 128
5342 * bit numbers into doubles. A member replaces one of the same key, as when
5343 * the printer runs in process. The child may have been taken over: check
5344 * the framing, the values are only copied to the output.
5345 */
5346static int json_capture_add(const void *buf, size_t len)
5347{
5348 const char *p = buf, *end = p + len, *k, *v;
5349 struct json_object *val;
5350 __cleanup_free__attribute__((cleanup(shr_freep))) char *key = NULL((void*)0);
5351 uint32_t klen, vlen;
5352
5353 if (!len)
1
Assuming 'len' is not equal to 0
5354 return 0;
5355 if (!json_init || !json_r)
2
Assuming 'json_init' is true
3
Assuming 'json_r' is non-null
4
Taking false branch
5356 return -EPROTO71;
5357
5358 while (p
4.1
'p' is < 'end'
< end) {
5359 if (!json_member_get(&p, end, &k, &klen) ||
6
Taking false branch
5360 !json_member_get(&p, end, &v, &vlen) ||
5361 memchr(k, '\0', klen)_Generic (0 ? (k) : (void *) 1, const void *: (const void *) (
memchr (k, '\0', klen)), default: memchr (k, '\0', klen))
)
5
Assuming the condition is false
5362 return -EPROTO71;
5363 free(key);
5364 key = strndup(k, klen);
7
Memory is allocated
5365 if (!key)
8
Assuming 'key' is non-null
9
Taking false branch
5366 return -ENOMEM12;
5367 val = json_object_new_string_len(v, vlen);
5368 if (!val)
10
Assuming 'val' is null
11
Taking true branch
5369 return -ENOMEM12;
12
Potential leak of memory pointed to by 'key'
5370 json_object_set_serializer(val, json_member_serialize,
5371 NULL((void*)0), NULL((void*)0));
5372 json_object_object_add(json_r, key, val);
5373 }
5374
5375 return 0;
5376}
5377
5378static void json_mgmt_addr_list_log(struct nvme_mgmt_addr_list_log *ma_list)
5379{
5380 int i;
5381 bool_Bool reserved = true1;
5382 struct json_object *r = json_r;
5383 struct json_object *mad;
5384 struct json_object *mat;
5385 char json_str[STR_LEN100];
5386 char madrs[sizeof(ma_list->mad[0].madrs) + 1];
5387
5388 for (i = 0; i < ARRAY_SIZE(ma_list->mad)(sizeof(ma_list->mad) / sizeof((ma_list->mad)[0]) + 0); i++) {
5389 switch (ma_list->mad[i].mat) {
5390 case 1:
5391 case 2:
5392 mad = json_create_object()json_object_new_object();
5393 mat = json_create_object()json_object_new_object();
5394 obj_add_strjson_object_add_value_string(mat, "definition", ma_list->mad[i].mat == 1 ?
5395 "NVM subsystem management agent" : "fabric interface manager");
5396 snprintf(json_str, sizeof(json_str), "type: %d", ma_list->mad[i].mat);
5397 obj_add_obj(mad, json_str, mat)json_object_object_add(mad, json_str, mat);
5398 snprintf(madrs, sizeof(madrs), "%-.*s",
5399 (int)sizeof(ma_list->mad[i].madrs),
5400 ma_list->mad[i].madrs);
5401 obj_add_strjson_object_add_value_string(mad, "address", madrs);
5402 snprintf(json_str, sizeof(json_str), "descriptor: %d", i);
5403 obj_add_obj(r, json_str, mad)json_object_object_add(r, json_str, mad);
5404 reserved = false0;
5405 break;
5406 case 0xff:
5407 goto out;
5408 default:
5409 break;
5410 }
5411 }
5412
5413out:
5414 if (reserved)
5415 obj_add_strjson_object_add_value_string(r, "list", "All management address descriptors reserved");
5416}
5417
5418static void json_rotational_media_info_log(struct nvme_rotational_media_info_log *info)
5419{
5420 struct json_object *r = json_r;
5421
5422 obj_add_uint(r, "endgid", le16_to_cpu(info->endgid))json_object_object_add(r, "endgid", json_object_new_uint64(le16_to_cpu
(info->endgid)))
;
5423 obj_add_uint(r, "numa", le16_to_cpu(info->numa))json_object_object_add(r, "numa", json_object_new_uint64(le16_to_cpu
(info->numa)))
;
5424 obj_add_uint(r, "nrs", le16_to_cpu(info->nrs))json_object_object_add(r, "nrs", json_object_new_uint64(le16_to_cpu
(info->nrs)))
;
5425 obj_add_uint(r, "spinc", le32_to_cpu(info->spinc))json_object_object_add(r, "spinc", json_object_new_uint64(le32_to_cpu
(info->spinc)))
;
5426 obj_add_uint(r, "fspinc", le32_to_cpu(info->fspinc))json_object_object_add(r, "fspinc", json_object_new_uint64(le32_to_cpu
(info->fspinc)))
;
5427 obj_add_uint(r, "ldc", le32_to_cpu(info->ldc))json_object_object_add(r, "ldc", json_object_new_uint64(le32_to_cpu
(info->ldc)))
;
5428 obj_add_uint(r, "fldc", le32_to_cpu(info->fldc))json_object_object_add(r, "fldc", json_object_new_uint64(le32_to_cpu
(info->fldc)))
;
5429}
5430
5431static void json_dispersed_ns_psub_log(
5432 struct nvme_dispersed_ns_participating_nss_log *log, __u64 len)
5433{
5434 struct json_object *r = json_r;
5435 __u64 numpsub = le64_to_cpu(log->numpsub);
5436 __u64 i, n;
5437 char json_str[STR_LEN100];
5438 char psub[NVME_NQN_LENGTH + 1];
5439
5440 obj_add_uint64(r, "genctr", le64_to_cpu(log->genctr))json_object_object_add(r, "genctr", json_object_new_uint64(le64_to_cpu
(log->genctr)))
;
5441 obj_add_uint64(r, "numpsub", numpsub)json_object_object_add(r, "numpsub", json_object_new_uint64(numpsub
))
;
5442 n = nvme_log_nr_entries(numpsub, len, sizeof(*log), NVME_NQN_LENGTH);
5443 for (i = 0; i < n; i++) {
5444 snprintf(json_str, sizeof(json_str), "participating_nss %"PRIu64"l" "u""", (uint64_t)i);
5445 snprintf(psub, sizeof(psub), "%-.*s", NVME_NQN_LENGTH,
5446 &log->participating_nss[i * NVME_NQN_LENGTH]);
5447 obj_add_strjson_object_add_value_string(r, json_str, psub);
5448 }
5449}
5450
5451static void json_reachability_groups_log(
5452 struct nvme_reachability_groups_log *log, __u64 len)
5453{
5454 struct json_object *r = json_r;
5455 struct nvme_reachability_group_desc desc;
5456 __u64 off = sizeof(*log);
5457 __le32 *nsid;
5458 __u16 i;
5459 __u32 j;
5460 char json_str[STR_LEN100];
5461 struct json_object *rgd, *nsids;
5462
5463 obj_add_uint64(r, "chngc", le64_to_cpu(log->chngc))json_object_object_add(r, "chngc", json_object_new_uint64(le64_to_cpu
(log->chngc)))
;
5464 obj_add_uint(r, "nrgd", le16_to_cpu(log->nrgd))json_object_object_add(r, "nrgd", json_object_new_uint64(le16_to_cpu
(log->nrgd)))
;
5465
5466 for (i = 0; i < le16_to_cpu(log->nrgd) &&
5467 nvme_reachability_group(log, len, off, &desc); i++) {
5468 snprintf(json_str, sizeof(json_str), "rgid: %u",
5469 le32_to_cpu(desc.rgid));
5470 rgd = json_create_object()json_object_new_object();
5471 obj_add_uint(rgd, "nnid", le32_to_cpu(desc.nnid))json_object_object_add(rgd, "nnid", json_object_new_uint64(le32_to_cpu
(desc.nnid)))
;
5472 obj_add_uint64(rgd, "chngc", le64_to_cpu(desc.chngc))json_object_object_add(rgd, "chngc", json_object_new_uint64(le64_to_cpu
(desc.chngc)))
;
5473 nsids = json_create_array()json_object_new_array();
5474 nsid = nvme_reachability_ids(log, off, sizeof(desc));
5475 for (j = 0; j < le32_to_cpu(desc.nnid); j++)
5476 json_object_array_add(nsids,
5477 json_object_new_uint64(le32_to_cpu(nsid[j])));
5478 obj_add_array(rgd, "nsid", nsids)json_object_object_add(rgd, "nsid", nsids);
5479 obj_add_obj(r, json_str, rgd)json_object_object_add(r, json_str, rgd);
5480 off = nvme_reachability_group_next(&desc, off);
5481 }
5482}
5483
5484static void json_reachability_associations_log(struct nvme_reachability_associations_log *log,
5485 __u64 len)
5486{
5487 struct json_object *r = json_r;
5488 struct nvme_reachability_association_desc desc;
5489 __u64 off = sizeof(*log);
5490 __le32 *rgid;
5491 __u16 i;
5492 __u32 j;
5493 char json_str[STR_LEN100];
5494 struct json_object *rad, *rgids;
5495
5496 obj_add_uint64(r, "chngc", le64_to_cpu(log->chngc))json_object_object_add(r, "chngc", json_object_new_uint64(le64_to_cpu
(log->chngc)))
;
5497 obj_add_uint(r, "nrad", le16_to_cpu(log->nrad))json_object_object_add(r, "nrad", json_object_new_uint64(le16_to_cpu
(log->nrad)))
;
5498
5499 for (i = 0; i < le16_to_cpu(log->nrad) &&
5500 nvme_reachability_association(log, len, off, &desc); i++) {
5501 snprintf(json_str, sizeof(json_str), "rasid: %u",
5502 le32_to_cpu(desc.rasid));
5503 rad = json_create_object()json_object_new_object();
5504 obj_add_uint(rad, "nrid", le32_to_cpu(desc.nrid))json_object_object_add(rad, "nrid", json_object_new_uint64(le32_to_cpu
(desc.nrid)))
;
5505 obj_add_uint64(rad, "chngc", le64_to_cpu(desc.chngc))json_object_object_add(rad, "chngc", json_object_new_uint64(le64_to_cpu
(desc.chngc)))
;
5506 obj_add_uint(rad, "rac", desc.rac)json_object_object_add(rad, "rac", json_object_new_uint64(desc
.rac))
;
5507 rgids = json_create_array()json_object_new_array();
5508 rgid = nvme_reachability_ids(log, off, sizeof(desc));
5509 for (j = 0; j < le32_to_cpu(desc.nrid); j++)
5510 json_object_array_add(rgids,
5511 json_object_new_uint64(le32_to_cpu(rgid[j])));
5512 obj_add_array(rad, "rgid", rgids)json_object_object_add(rad, "rgid", rgids);
5513 obj_add_obj(r, json_str, rad)json_object_object_add(r, json_str, rad);
5514 off = nvme_reachability_association_next(&desc, off);
5515 }
5516}
5517
5518#ifdef CONFIG_FABRICS
5519static void json_host_discovery_log(struct nvme_host_discovery_log *log,
5520 __u64 len)
5521{
5522 struct json_object *r = json_r;
5523 __u64 i;
5524 __u16 j;
5525 struct nvme_host_ext_discovery_log hedlpe;
5526 struct nvmf_ext_attr exat;
5527 void *rec, *p;
5528 char hostnqn[sizeof(hedlpe.hostnqn) + 1];
5529 char traddr[sizeof(hedlpe.traddr) + 1];
5530 __u32 thdlpl = le32_to_cpu(log->thdlpl);
5531 __u32 tel;
5532 __u16 numexat;
5533 char json_str[STR_LEN100];
5534 struct json_object *hedlpe_o;
5535 struct json_object *tsas_o;
5536 struct json_object *exat_o;
5537 int n = 0;
5538
5539 obj_add_uint64(r, "genctr", le64_to_cpu(log->genctr))json_object_object_add(r, "genctr", json_object_new_uint64(le64_to_cpu
(log->genctr)))
;
5540 obj_add_uint64(r, "numrec", le64_to_cpu(log->numrec))json_object_object_add(r, "numrec", json_object_new_uint64(le64_to_cpu
(log->numrec)))
;
5541 obj_add_uint(r, "recfmt", le16_to_cpu(log->recfmt))json_object_object_add(r, "recfmt", json_object_new_uint64(le16_to_cpu
(log->recfmt)))
;
5542 obj_add_uint_02xjson_object_add_uint_02x(r, "hdlpf", log->hdlpf);
5543 obj_add_uint(r, "thdlpl", thdlpl)json_object_object_add(r, "thdlpl", json_object_new_uint64(thdlpl
))
;
5544
5545 for (i = sizeof(*log);
5546 (rec = nvme_host_discovery_record(log, len, i)); i += tel) {
5547 memcpy(&hedlpe, rec, sizeof(hedlpe));
5548 hedlpe_o = json_create_object()json_object_new_object();
5549 tel = le32_to_cpu(hedlpe.tel);
5550 numexat = le16_to_cpu(hedlpe.numexat);
5551 snprintf(hostnqn, sizeof(hostnqn), "%-.*s",
5552 (int)sizeof(hedlpe.hostnqn), hedlpe.hostnqn);
5553 snprintf(traddr, sizeof(traddr), "%-.*s",
5554 (int)sizeof(hedlpe.traddr), hedlpe.traddr);
5555 obj_add_strjson_object_add_value_string(hedlpe_o, "trtype",
5556 libnvmf_trtype_str(hedlpe.trtype));
5557 obj_add_strjson_object_add_value_string(hedlpe_o, "adrfam", traddr[0] ?
5558 libnvmf_adrfam_str(hedlpe.adrfam) : "");
5559 obj_add_strjson_object_add_value_string(hedlpe_o, "eflags",
5560 libnvmf_eflags_str(le16_to_cpu(hedlpe.eflags)));
5561 obj_add_strjson_object_add_value_string(hedlpe_o, "hostnqn", hostnqn);
5562 obj_add_strjson_object_add_value_string(hedlpe_o, "traddr", traddr);
5563 tsas_o = json_create_object()json_object_new_object();
5564 switch (hedlpe.trtype) {
5565 case NVMF_TRTYPE_RDMA:
5566 obj_add_strjson_object_add_value_string(tsas_o, "prtype",
5567 libnvmf_prtype_str(hedlpe.tsas.rdma.prtype));
5568 obj_add_strjson_object_add_value_string(tsas_o, "qptype",
5569 libnvmf_qptype_str(hedlpe.tsas.rdma.qptype));
5570 obj_add_strjson_object_add_value_string(tsas_o, "cms",
5571 libnvmf_cms_str(hedlpe.tsas.rdma.cms));
5572 obj_add_uint_0nxjson_object_add_uint_0nx(tsas_o, "pkey",
5573 le16_to_cpu(hedlpe.tsas.rdma.pkey), 4);
5574 break;
5575 case NVMF_TRTYPE_TCP:
5576 obj_add_strjson_object_add_value_string(tsas_o, "sectype",
5577 libnvmf_sectype_str(hedlpe.tsas.tcp.sectype));
5578 break;
5579 default:
5580 obj_d(tsas_o, "common",
5581 (unsigned char *)hedlpe.tsas.common,
5582 sizeof(hedlpe.tsas.common), 16, 1);
5583 break;
5584 }
5585 obj_add_obj(hedlpe_o, "tsas", tsas_o)json_object_object_add(hedlpe_o, "tsas", tsas_o);
5586 obj_add_uint(hedlpe_o, "tel", tel)json_object_object_add(hedlpe_o, "tel", json_object_new_uint64
(tel))
;
5587 obj_add_uint(hedlpe_o, "numexat", numexat)json_object_object_add(hedlpe_o, "numexat", json_object_new_uint64
(numexat))
;
5588
5589 p = rec + sizeof(hedlpe);
5590 for (j = 0; j < numexat &&
5591 (p = nvme_host_discovery_exat(rec, tel, p, &exat)); j++) {
5592 exat_o = json_create_object()json_object_new_object();
5593 snprintf(json_str, sizeof(json_str), "exat: %d", j);
5594 obj_add_uint(exat_o, "exattype",json_object_object_add(exat_o, "exattype", json_object_new_uint64
(le16_to_cpu(exat.exattype)))
5595 le16_to_cpu(exat.exattype))json_object_object_add(exat_o, "exattype", json_object_new_uint64
(le16_to_cpu(exat.exattype)))
;
5596 obj_add_uint(exat_o, "exatlen",json_object_object_add(exat_o, "exatlen", json_object_new_uint64
(le16_to_cpu(exat.exatlen)))
5597 le16_to_cpu(exat.exatlen))json_object_object_add(exat_o, "exatlen", json_object_new_uint64
(le16_to_cpu(exat.exatlen)))
;
5598 obj_d(exat_o, "exatval",
5599 (unsigned char *)p + sizeof(exat),
5600 le16_to_cpu(exat.exatlen), 16, 1);
5601 obj_add_obj(hedlpe_o, json_str, exat_o)json_object_object_add(hedlpe_o, json_str, exat_o);
5602 p = nvme_host_discovery_exat_next(p, &exat);
5603 }
5604 snprintf(json_str, sizeof(json_str), "hedlpe: %d", n++);
5605 obj_add_obj(r, json_str, hedlpe_o)json_object_object_add(r, json_str, hedlpe_o);
5606 }
5607}
5608
5609static void obj_add_traddr(struct json_object *o, const char *k, __u8 adrfam, __u8 *traddr)
5610{
5611 char dst[INET6_ADDRSTRLEN46];
5612 socklen_t size;
5613 int af;
5614
5615 if (adrfam == NVMF_ADDR_FAMILY_IP4) {
5616 af = AF_INET2;
5617 size = INET_ADDRSTRLEN16;
5618 } else if (adrfam == NVMF_ADDR_FAMILY_IP6) {
5619 af = AF_INET610;
5620 size = INET6_ADDRSTRLEN46;
5621 } else {
5622 obj_add_strjson_object_add_value_string(o, k, "<invalid>");
5623 return;
5624 }
5625
5626 if (inet_ntop(af, traddr, dst, size))
5627 obj_add_strjson_object_add_value_string(o, k, dst);
5628}
5629
5630static void json_ave_discovery_log(struct nvme_ave_discovery_log *log,
5631 __u64 len)
5632{
5633 struct json_object *r = json_r;
5634 __u64 i;
5635 __u8 j;
5636 struct nvme_ave_discovery_log_entry adlpe;
5637 char avenqn[sizeof(adlpe.avenqn) + 1];
5638 struct nvme_ave_tr_record atr;
5639 void *rec;
5640 __u32 tadlpl = le32_to_cpu(log->tadlpl);
5641 __u32 tel;
5642 __u8 numatr;
5643 int n = 0;
5644 char json_str[STR_LEN100];
5645 struct json_object *adlpe_o;
5646 struct json_object *atr_o;
5647
5648 obj_add_uint64(r, "genctr", le64_to_cpu(log->genctr))json_object_object_add(r, "genctr", json_object_new_uint64(le64_to_cpu
(log->genctr)))
;
5649 obj_add_uint64(r, "numrec", le64_to_cpu(log->numrec))json_object_object_add(r, "numrec", json_object_new_uint64(le64_to_cpu
(log->numrec)))
;
5650 obj_add_uint(r, "recfmt", le16_to_cpu(log->recfmt))json_object_object_add(r, "recfmt", json_object_new_uint64(le16_to_cpu
(log->recfmt)))
;
5651 obj_add_uint(r, "thdlpl", tadlpl)json_object_object_add(r, "thdlpl", json_object_new_uint64(tadlpl
))
;
5652
5653 for (i = sizeof(*log);
5654 (rec = nvme_ave_discovery_record(log, len, i)); i += tel) {
5655 memcpy(&adlpe, rec, sizeof(adlpe));
5656 adlpe_o = json_create_object()json_object_new_object();
5657 tel = le32_to_cpu(adlpe.tel);
5658 numatr = adlpe.numatr;
5659 snprintf(avenqn, sizeof(avenqn), "%-.*s",
5660 (int)sizeof(adlpe.avenqn), adlpe.avenqn);
5661 obj_add_uint(adlpe_o, "tel", tel)json_object_object_add(adlpe_o, "tel", json_object_new_uint64
(tel))
;
5662 obj_add_strjson_object_add_value_string(adlpe_o, "avenqn", avenqn);
5663 obj_add_uint(adlpe_o, "numatr", numatr)json_object_object_add(adlpe_o, "numatr", json_object_new_uint64
(numatr))
;
5664
5665 /* the transport records must fit the record */
5666 numatr = nvme_log_nr_entries(numatr, tel, sizeof(adlpe),
5667 sizeof(atr));
5668 for (j = 0; j < numatr; j++) {
5669 memcpy(&atr, rec + sizeof(adlpe) + j * sizeof(atr),
5670 sizeof(atr));
5671 atr_o = json_create_object()json_object_new_object();
5672 snprintf(json_str, sizeof(json_str), "atr: %d", j);
5673 obj_add_strjson_object_add_value_string(atr_o, "aveadrfam",
5674 libnvmf_adrfam_str(atr.aveadrfam));
5675 obj_add_uint(atr_o, "avetrsvcid",json_object_object_add(atr_o, "avetrsvcid", json_object_new_uint64
(le16_to_cpu(atr.avetrsvcid)))
5676 le16_to_cpu(atr.avetrsvcid))json_object_object_add(atr_o, "avetrsvcid", json_object_new_uint64
(le16_to_cpu(atr.avetrsvcid)))
;
5677 obj_add_traddr(atr_o, "avetraddr", atr.aveadrfam,
5678 atr.avetraddr);
5679 obj_add_obj(adlpe_o, json_str, atr_o)json_object_object_add(adlpe_o, json_str, atr_o);
5680 }
5681 snprintf(json_str, sizeof(json_str), "adlpe: %d", n++);
5682 obj_add_obj(r, json_str, adlpe_o)json_object_object_add(r, json_str, adlpe_o);
5683 }
5684}
5685#else
5686static void json_host_discovery_log(struct nvme_host_discovery_log *log,
5687 __u64 len)
5688{
5689}
5690
5691static void json_ave_discovery_log(struct nvme_ave_discovery_log *log,
5692 __u64 len)
5693{
5694}
5695#endif
5696
5697static void json_pull_model_ddc_req_log(struct nvme_pull_model_ddc_req_log *log,
5698 __u64 len)
5699{
5700 struct json_object *r = json_r;
5701 __u32 tpdrpl = le32_to_cpu(log->tpdrpl);
5702 __u32 osp_len = nvme_pull_model_ddc_req_osp_len(log, len);
5703
5704 obj_add_uint(r, "ori", log->ori)json_object_object_add(r, "ori", json_object_new_uint64(log->
ori))
;
5705 obj_add_uint(r, "tpdrpl", tpdrpl)json_object_object_add(r, "tpdrpl", json_object_new_uint64(tpdrpl
))
;
5706 obj_d(r, "osp", (unsigned char *)log->osp, osp_len, 16, 1);
5707}
5708
5709static void json_power_meas_log(struct nvme_power_meas_log *log, __u32 size)
5710{
5711 struct json_object *r = json_r;
5712 struct json_object *descs;
5713 struct json_object *smts_obj;
5714 struct json_object *mipwrt_obj;
5715 __u16 nphd = le16_to_cpu(log->nphd);
5716 __u16 pma = le16_to_cpu(log->pma);
5717 __u8 pmt = NVME_GET(pma, PMA_PMT)(((pma) >> NVME_PMA_PMT_SHIFT) & NVME_PMA_PMT_MASK);
5718 __u16 i;
5719
5720 obj_add_uint(r, "ver", log->ver)json_object_object_add(r, "ver", json_object_new_uint64(log->
ver))
;
5721 obj_add_uint(r, "pmgn", log->pmgn)json_object_object_add(r, "pmgn", json_object_new_uint64(log->
pmgn))
;
5722 obj_add_uint(r, "pma", pma)json_object_object_add(r, "pma", json_object_new_uint64(pma));
5723 obj_add_uint(r, "pme", NVME_GET(pma, PMA_PME))json_object_object_add(r, "pme", json_object_new_uint64((((pma
) >> NVME_PMA_PME_SHIFT) & NVME_PMA_PME_MASK)))
;
5724 obj_add_uint(r, "ncpdf", NVME_GET(pma, PMA_NCPDF))json_object_object_add(r, "ncpdf", json_object_new_uint64((((
pma) >> NVME_PMA_NCPDF_SHIFT) & NVME_PMA_NCPDF_MASK
)))
;
5725 obj_add_uint(r, "epf", NVME_GET(pma, PMA_EPF))json_object_object_add(r, "epf", json_object_new_uint64((((pma
) >> NVME_PMA_EPF_SHIFT) & NVME_PMA_EPF_MASK)))
;
5726 obj_add_uint(r, "mipwrts", NVME_GET(pma, PMA_MIPWRTS))json_object_object_add(r, "mipwrts", json_object_new_uint64((
((pma) >> NVME_PMA_MIPWRTS_SHIFT) & NVME_PMA_MIPWRTS_MASK
)))
;
5727 obj_add_uint(r, "phdo", NVME_GET(pma, PMA_PHDO))json_object_object_add(r, "phdo", json_object_new_uint64((((pma
) >> NVME_PMA_PHDO_SHIFT) & NVME_PMA_PHDO_MASK)))
;
5728 obj_add_uint(r, "pmt", pmt)json_object_object_add(r, "pmt", json_object_new_uint64(pmt));
5729 obj_add_strjson_object_add_value_string(r, "pmt_str", nvme_power_measurement_type_to_string(pmt));
5730 obj_add_uint(r, "sze", le32_to_cpu(log->sze))json_object_object_add(r, "sze", json_object_new_uint64(le32_to_cpu
(log->sze)))
;
5731 obj_add_uint(r, "pmc", le32_to_cpu(log->pmc))json_object_object_add(r, "pmc", json_object_new_uint64(le32_to_cpu
(log->pmc)))
;
5732 obj_add_uint(r, "nphd", nphd)json_object_object_add(r, "nphd", json_object_new_uint64(nphd
))
;
5733 obj_add_uint(r, "smtr", le16_to_cpu(log->smtr))json_object_object_add(r, "smtr", json_object_new_uint64(le16_to_cpu
(log->smtr)))
;
5734
5735 smts_obj = json_create_object()json_object_new_object();
5736 json_timestamp(smts_obj, &log->smts);
5737 obj_add_obj(r, "smts", smts_obj)json_object_object_add(r, "smts", smts_obj);
5738
5739 obj_add_uint(r, "phds", le16_to_cpu(log->phds))json_object_object_add(r, "phds", json_object_new_uint64(le16_to_cpu
(log->phds)))
;
5740 obj_add_uint(r, "phbs", le16_to_cpu(log->phbs))json_object_object_add(r, "phbs", json_object_new_uint64(le16_to_cpu
(log->phbs)))
;
5741 obj_add_uint(r, "nphds", le16_to_cpu(log->nphds))json_object_object_add(r, "nphds", json_object_new_uint64(le16_to_cpu
(log->nphds)))
;
5742 obj_add_uint(r, "vss", le16_to_cpu(log->vss))json_object_object_add(r, "vss", json_object_new_uint64(le16_to_cpu
(log->vss)))
;
5743 obj_add_uint(r, "phdoc", le32_to_cpu(log->phdoc))json_object_object_add(r, "phdoc", json_object_new_uint64(le32_to_cpu
(log->phdoc)))
;
5744 obj_add_uint(r, "aipwr", le32_to_cpu(log->aipwr))json_object_object_add(r, "aipwr", json_object_new_uint64(le32_to_cpu
(log->aipwr)))
;
5745 obj_add_uint(r, "mipwr", le32_to_cpu(log->mipwr))json_object_object_add(r, "mipwr", json_object_new_uint64(le32_to_cpu
(log->mipwr)))
;
5746
5747 mipwrt_obj = json_create_object()json_object_new_object();
5748 json_timestamp(mipwrt_obj, &log->mipwrt);
5749 obj_add_obj(r, "mipwrt", mipwrt_obj)json_object_object_add(r, "mipwrt", mipwrt_obj);
5750
5751 obj_add_uint(r, "ipwrpe", log->ipwrpe)json_object_object_add(r, "ipwrpe", json_object_new_uint64(log
->ipwrpe))
;
5752
5753 /* the descriptors the buffer holds */
5754 nphd = nvme_log_nr_entries(nphd, size, sizeof(*log),
5755 sizeof(log->descs[0]));
5756 descs = json_create_array()json_object_new_array();
5757 for (i = 0; i < nphd; i++) {
5758 struct json_object *desc = json_create_object()json_object_new_object();
5759
5760 obj_add_uint(desc, "phbc", le32_to_cpu(log->descs[i].phbc))json_object_object_add(desc, "phbc", json_object_new_uint64(le32_to_cpu
(log->descs[i].phbc)))
;
5761 obj_add_uint(desc, "phblt", le32_to_cpu(log->descs[i].phblt))json_object_object_add(desc, "phblt", json_object_new_uint64(
le32_to_cpu(log->descs[i].phblt)))
;
5762 json_object_array_add(descs, desc);
5763 }
5764 obj_add_obj(r, "descs", descs)json_object_object_add(r, "descs", descs);
5765}
5766
5767static struct print_ops json_print_ops = {
5768 /* libnvme types.h print functions */
5769 .ana_log = json_ana_log,
5770 .boot_part_log = json_boot_part_log,
5771 .phy_rx_eom_log = json_phy_rx_eom_log,
5772 .ctrl_list = json_nvme_list_ctrl,
5773 .ctrl_registers = json_ctrl_registers,
5774 .directive = json_directive_show,
5775 .discovery_log = json_discovery_log,
5776 .effects_log_list = json_effects_log_list,
5777 .endurance_group_event_agg_log = json_endurance_group_event_agg_log,
5778 .endurance_group_list = json_nvme_endurance_group_list,
5779 .endurance_log = json_endurance_log,
5780 .error_log = json_error_log,
5781 .fdp_config_log = json_nvme_fdp_configs,
5782 .fdp_event_log = json_nvme_fdp_events,
5783 .fdp_ruh_status = json_nvme_fdp_ruh_status,
5784 .fdp_stats_log = json_nvme_fdp_stats,
5785 .fdp_usage_log = json_nvme_fdp_usage,
5786 .fid_supported_effects_log = json_fid_support_effects_log,
5787 .fw_log = json_fw_log,
5788 .id_ctrl = json_nvme_id_ctrl,
5789 .id_ctrl_nvm = json_nvme_id_ctrl_nvm,
5790 .id_domain_list = json_id_domain_list,
5791 .id_independent_id_ns = json_nvme_cmd_set_independent_id_ns,
5792 .id_iocs = json_id_iocs,
5793 .id_ns = json_nvme_id_ns,
5794 .id_ns_descs = json_nvme_id_ns_descs,
5795 .id_ns_granularity_list = json_nvme_id_ns_granularity_list,
5796 .id_nvmset_list = json_nvme_id_nvmset,
5797 .id_uuid_list = json_nvme_id_uuid_list,
5798 .lba_status = json_lba_status,
5799 .lba_status_log = json_lba_status_log,
5800 .media_unit_stat_log = json_media_unit_stat_log,
5801 .mi_cmd_support_effects_log = json_mi_cmd_support_effects_log,
5802 .ns_list = json_nvme_list_ns,
5803 .ns_list_log = json_changed_ns_list_log,
5804 .nvm_id_ns = json_nvme_nvm_id_ns,
5805 .persistent_event_log = json_persistent_event_log,
5806 .predictable_latency_event_agg_log = json_predictable_latency_event_agg_log,
5807 .predictable_latency_per_nvmset = json_predictable_latency_per_nvmset,
5808 .primary_ctrl_cap = json_nvme_primary_ctrl_cap,
5809 .resv_notification_log = json_resv_notif_log,
5810 .resv_report = json_nvme_resv_report,
5811 .sanitize_log_page = json_sanitize_log,
5812 .secondary_ctrl_list = json_nvme_list_secondary_ctrl,
5813 .select_result = json_select_result,
5814 .self_test_log = json_self_test_log,
5815 .smart_log = json_smart_log,
5816 .supported_cap_config_list_log = json_supported_cap_config_log,
5817 .supported_log_pages = json_support_log,
5818 .zns_start_zone_list = json_zns_start_zone_list,
5819 .zns_changed_zone_log = json_zns_changed,
5820 .zns_finish_zone_list = json_zns_finish_zone_list,
5821 .zns_id_ctrl = json_nvme_zns_id_ctrl,
5822 .zns_id_ns = json_nvme_zns_id_ns,
5823 .zns_report_zones = json_nvme_zns_report_zones,
5824 .show_feature = json_feature_show,
5825 .show_feature_fields = json_feature_show_fields,
5826 .id_ctrl_rpmbs = json_id_ctrl_rpmbs,
5827 .lba_range = json_lba_range,
5828 .lba_status_info = json_lba_status_info,
5829 .d = json_d,
5830 .show_init = json_show_init,
5831 .show_finish = json_show_finish,
5832 .mgmt_addr_list_log = json_mgmt_addr_list_log,
5833 .rotational_media_info_log = json_rotational_media_info_log,
5834 .dispersed_ns_psub_log = json_dispersed_ns_psub_log,
5835 .reachability_groups_log = json_reachability_groups_log,
5836 .reachability_associations_log = json_reachability_associations_log,
5837 .host_discovery_log = json_host_discovery_log,
5838 .ave_discovery_log = json_ave_discovery_log,
5839 .pull_model_ddc_req_log = json_pull_model_ddc_req_log,
5840 .power_meas_log = json_power_meas_log,
5841
5842 /* libnvme tree print functions */
5843 .list_item = json_list_item,
5844 .list_items = json_print_list_items,
5845 .print_nvme_subsystem_list = json_print_nvme_subsystem_list,
5846 .topology_ctrl = json_simple_topology,
5847 .topology_namespace = json_simple_topology,
5848 .topology_multipath = json_simple_topology,
5849
5850 /* nvme top */
5851#ifdef CONFIG_TOP
5852 .top = json_top,
5853#endif
5854
5855 /* config show */
5856 .config_conn_list = json_config_conn_list,
5857
5858 /* status and error messages */
5859 .connect_msg = json_connect_msg,
5860 .show_message = json_output_message,
5861 .show_perror = json_output_perror,
5862 .show_status = json_output_status,
5863 .show_opcode_status = json_output_opcode_status,
5864 .show_error_status = json_output_error_status,
5865 .show_key_value = json_output_key_value,
5866 .capture_begin = json_capture_begin,
5867 .capture_end = json_capture_end,
5868 .capture_add = json_capture_add,
5869};
5870
5871/*
5872 * json-c seeds its string hash on the first lookup. Built without
5873 * getrandom(), as the meson subproject is, it reads /dev/urandom then,
5874 * which a printer in the sandbox cannot open.
5875 */
5876static void json_seed_hash(void)
5877{
5878 struct json_object *o = json_create_object()json_object_new_object();
5879
5880 json_object_object_get_ex(o, "", NULL((void*)0));
5881 json_free_object(o)json_object_put(o);
5882}
5883
5884struct print_ops *nvme_get_json_print_ops(nvme_print_flags_t flags)
5885{
5886 json_seed_hash();
5887 json_print_ops.flags = flags;
5888 return &json_print_ops;
5889}