Bug Summary

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