diff --git a/.github/cross/ubuntu-cross-armhf.txt b/.github/cross/ubuntu-cross-armhf.txt index 41c8328906..ac5dd62209 100644 --- a/.github/cross/ubuntu-cross-armhf.txt +++ b/.github/cross/ubuntu-cross-armhf.txt @@ -6,6 +6,9 @@ pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config' ld = '/usr/bin/arm-linux/gnueabihf-ld' exe_wrapper = '/usr/bin/qemu-arm-static' +c_native = 'gcc' +cpp_native = 'g++' + [properties] root = '/usr/arm-linux-gnueabihf' has_function_printf = true diff --git a/.github/cross/ubuntu-cross-ppc64le.txt b/.github/cross/ubuntu-cross-ppc64le.txt index 6baaefbc26..76b00e4c3f 100644 --- a/.github/cross/ubuntu-cross-ppc64le.txt +++ b/.github/cross/ubuntu-cross-ppc64le.txt @@ -6,6 +6,9 @@ pkgconfig = '/usr/bin/powerpc64le-linux-gnu-pkg-config' ld = '/usr/bin/powerpc64le-linux-gnu-ld' exe_wrapper = '/usr/bin/qemu-ppc64le-static' +c_native = 'gcc' +cpp_native = 'g++' + [properties] root = '/usr/powerpc64le-linux-gnu' has_function_printf = true diff --git a/.github/cross/ubuntu-cross-s390x.txt b/.github/cross/ubuntu-cross-s390x.txt index 51a3511fbe..dae5b76d51 100644 --- a/.github/cross/ubuntu-cross-s390x.txt +++ b/.github/cross/ubuntu-cross-s390x.txt @@ -6,6 +6,9 @@ pkgconfig = '/usr/bin/s390x-linux-gnu-pkg-config' ld = '/usr/bin/s390x-linux-gnu-ld' exe_wrapper = '/usr/bin/qemu-s390x-static' +c_native = 'gcc' +cpp_native = 'g++' + [properties] root = '/usr/s390x-linux-gnu' has_function_printf = true diff --git a/README.md b/README.md index 1113b1e400..4080e0b6aa 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ callback, and the plug-in structure that contains that command. The prototype looks like this: ```c - int f(int argc, char **argv, struct command *cmd, struct plugin *plugin); + int f(int argc, char **argv, struct command *command, struct plugin *plugin); ``` The argc and argv are adjusted from the command line arguments to start diff --git a/cmd_handler.h b/cmd_handler.h index c4b26f4d5c..e886a15270 100644 --- a/cmd_handler.h +++ b/cmd_handler.h @@ -10,7 +10,7 @@ #undef ENTRY #define ENTRY(n, h, f, ...) \ -static int f(int argc, char **argv, struct command *command, struct plugin *plugin); +static int f(int argc, char **argv, struct command *acmd, struct plugin *plugin); #undef COMMAND_LIST #define COMMAND_LIST(args...) args diff --git a/fabrics.c b/fabrics.c index 9eb6a09e96..4e2c9958ef 100644 --- a/fabrics.c +++ b/fabrics.c @@ -171,7 +171,6 @@ static int set_discovery_kato(struct nvme_fabrics_config *cfg) return tmo; } - static int nvme_add_ctrl(nvme_host_t h, nvme_ctrl_t c, struct nvme_fabrics_config *cfg) { @@ -182,31 +181,31 @@ static int nvme_add_ctrl(nvme_host_t h, nvme_ctrl_t c, * __create_discover_ctrl and callers depend on errno being set * in the error case. */ - errno = 0; ret = nvmf_add_ctrl(h, c, cfg); if (!ret) return 0; - if (errno == EAGAIN || (errno == EINTR && !nvme_sigint_received)) { - print_debug("nvmf_add_ctrl returned '%s'\n", strerror(errno)); + if (ret == -EAGAIN || (ret == -EINTR && !nvme_sigint_received)) { + print_debug("nvmf_add_ctrl returned '%s'\n", strerror(-ret)); goto retry; } - return -errno; + return ret; } -static nvme_ctrl_t __create_discover_ctrl(nvme_root_t r, nvme_host_t h, - struct nvme_fabrics_config *cfg, - struct tr_config *trcfg) +static int __create_discover_ctrl(struct nvme_global_ctx *ctx, nvme_host_t h, + struct nvme_fabrics_config *cfg, + struct tr_config *trcfg, + nvme_ctrl_t *ctrl) { nvme_ctrl_t c; int tmo, ret; - c = nvme_create_ctrl(r, trcfg->subsysnqn, trcfg->transport, + ret = nvme_create_ctrl(ctx, trcfg->subsysnqn, trcfg->transport, trcfg->traddr, trcfg->host_traddr, - trcfg->host_iface, trcfg->trsvcid); - if (!c) - return NULL; + trcfg->host_iface, trcfg->trsvcid, &c); + if (ret) + return ret; nvme_ctrl_set_discovery_ctrl(c, true); nvme_ctrl_set_unique_discovery_ctrl(c, @@ -217,41 +216,51 @@ static nvme_ctrl_t __create_discover_ctrl(nvme_root_t r, nvme_host_t h, cfg->keep_alive_tmo = tmo; if (ret) { nvme_free_ctrl(c); - return NULL; + return ret; } - return c; + *ctrl = c; + return 0; } -nvme_ctrl_t nvmf_create_discover_ctrl(nvme_root_t r, nvme_host_t h, - struct nvme_fabrics_config *cfg, - struct tr_config *trcfg) +int nvmf_create_discover_ctrl(struct nvme_global_ctx *ctx, nvme_host_t h, + struct nvme_fabrics_config *cfg, + struct tr_config *trcfg, + nvme_ctrl_t *ctrl) { _cleanup_free_ struct nvme_id_ctrl *id = NULL; nvme_ctrl_t c; + int ret; - c = __create_discover_ctrl(r, h, cfg, trcfg); - if (!c) - return NULL; + ret = __create_discover_ctrl(ctx, h, cfg, trcfg, &c); + if (ret) + return ret; - if (nvme_ctrl_is_unique_discovery_ctrl(c)) - return c; + if (nvme_ctrl_is_unique_discovery_ctrl(c)) { + *ctrl = c; + return 0; + } id = nvme_alloc(sizeof(*id)); - if (!id) - return NULL; + if (!id) { + nvme_free_ctrl(c); + return -ENOMEM; + } /* Find out the name of discovery controller */ - if (nvme_ctrl_identify(c, id)) { + ret = nvme_ctrl_identify(c, id); + if (ret) { fprintf(stderr, "failed to identify controller, error %s\n", - nvme_strerror(errno)); + nvme_strerror(-ret)); nvme_disconnect_ctrl(c); nvme_free_ctrl(c); - return NULL; + return ret; } - if (!strcmp(id->subnqn, NVME_DISC_SUBSYS_NAME)) - return c; + if (!strcmp(id->subnqn, NVME_DISC_SUBSYS_NAME)) { + *ctrl = c; + return 0; + } /* * The subsysnqn is not the well-known name. Prefer the unique @@ -261,7 +270,12 @@ nvme_ctrl_t nvmf_create_discover_ctrl(nvme_root_t r, nvme_host_t h, nvme_free_ctrl(c); trcfg->subsysnqn = id->subnqn; - return __create_discover_ctrl(r, h, cfg, trcfg); + ret = __create_discover_ctrl(ctx, h, cfg, trcfg, &c); + if (ret) + return ret; + + *ctrl = c; + return 0; } static void save_discovery_log(char *raw, struct nvmf_discovery_log *log) @@ -295,6 +309,7 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg, nvme_subsystem_t s = nvme_ctrl_get_subsystem(c); nvme_host_t h = nvme_subsystem_get_host(s); uint64_t numrec; + int ret; struct nvme_get_discovery_args args = { .c = c, @@ -305,11 +320,11 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg, .lsp = 0, }; - log = nvmf_get_discovery_wargs(&args); - if (!log) { + ret = nvmf_get_discovery_wargs(&args, &log); + if (ret) { fprintf(stderr, "failed to get discovery log: %s\n", - nvme_strerror(errno)); - return -errno; + nvme_strerror(-ret)); + return ret; } numrec = le64_to_cpu(log->numrec); @@ -377,13 +392,12 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg, disconnect = false; } - errno = 0; - child = nvmf_connect_disc_entry(h, e, defcfg, - &discover); + ret = nvmf_connect_disc_entry(h, e, defcfg, + &discover, &child); defcfg->keep_alive_tmo = tmo; - if (child) { + if (!ret) { if (discover) __discover(child, defcfg, raw, true, persistent, flags); @@ -392,7 +406,7 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg, nvme_disconnect_ctrl(child); nvme_free_ctrl(child); } - } else if (errno == ENVME_CONNECT_ALREADY && !quiet) { + } else if (ret == -ENVME_CONNECT_ALREADY && !quiet) { const char *subnqn = log->entries[i].subnqn; const char *trtype = nvmf_trtype_str(log->entries[i].trtype); const char *traddr = log->entries[i].traddr; @@ -410,7 +424,7 @@ static int __discover(nvme_ctrl_t c, struct nvme_fabrics_config *defcfg, return 0; } -char *nvmf_get_default_trsvcid(const char *transport, bool discovery_ctrl) +char * nvmf_get_default_trsvcid(const char *transport, bool discovery_ctrl) { if (!transport) return NULL; @@ -428,7 +442,7 @@ char *nvmf_get_default_trsvcid(const char *transport, bool discovery_ctrl) return NULL; } -static int discover_from_conf_file(nvme_root_t r, nvme_host_t h, +static int discover_from_conf_file(struct nvme_global_ctx *ctx, nvme_host_t h, const char *desc, bool connect, const struct nvme_fabrics_config *defcfg) { @@ -514,8 +528,8 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h, } } - c = nvmf_create_discover_ctrl(r, h, &cfg, &trcfg); - if (!c) + ret = nvmf_create_discover_ctrl(ctx, h, &cfg, &trcfg, &c); + if (ret) goto next; __discover(c, &cfg, raw, connect, persistent, flags); @@ -531,11 +545,11 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h, return ret; } -static int _discover_from_json_config_file(nvme_root_t r, nvme_host_t h, - nvme_ctrl_t c, const char *desc, bool connect, - const struct nvme_fabrics_config *defcfg, - nvme_print_flags_t flags, - bool force) +static int _discover_from_json_config_file(struct nvme_global_ctx *ctx, + nvme_host_t h, nvme_ctrl_t c, + const char *desc, bool connect, + const struct nvme_fabrics_config *defcfg, + nvme_print_flags_t flags, bool force) { const char *transport, *traddr, *host_traddr; const char *host_iface, *trsvcid, *subsysnqn; @@ -605,8 +619,8 @@ static int _discover_from_json_config_file(nvme_root_t r, nvme_host_t h, } } - cn = nvmf_create_discover_ctrl(r, h, &cfg, &trcfg); - if (!cn) + ret = nvmf_create_discover_ctrl(ctx, h, &cfg, &trcfg, &cn); + if (ret) return 0; __discover(cn, &cfg, raw, connect, persistent, flags); @@ -617,12 +631,12 @@ static int _discover_from_json_config_file(nvme_root_t r, nvme_host_t h, return ret; } -static int discover_from_json_config_file(nvme_root_t r, const char *hostnqn, +static int discover_from_json_config_file(struct nvme_global_ctx *ctx, + const char *hostnqn, const char *hostid, const char *desc, bool connect, const struct nvme_fabrics_config *defcfg, - nvme_print_flags_t flags, - bool force) + nvme_print_flags_t flags, bool force) { const char *hnqn, *hid; nvme_host_t h; @@ -630,7 +644,7 @@ static int discover_from_json_config_file(nvme_root_t r, const char *hostnqn, nvme_ctrl_t c; int ret = 0, err; - nvme_for_each_host(r, h) { + nvme_for_each_host(ctx, h) { nvme_for_each_subsystem(h, s) { hnqn = nvme_host_get_hostnqn(h); if (hostnqn && hnqn && strcmp(hostnqn, hnqn)) @@ -641,7 +655,7 @@ static int discover_from_json_config_file(nvme_root_t r, const char *hostnqn, nvme_subsystem_for_each_ctrl(s, c) { err = _discover_from_json_config_file( - r, h, c, desc, connect, defcfg, + ctx, h, c, desc, connect, defcfg, flags, force); if (err) { @@ -661,7 +675,7 @@ static int discover_from_json_config_file(nvme_root_t r, const char *hostnqn, return ret; } -static int nvme_read_volatile_config(nvme_root_t r) +static int nvme_read_volatile_config(struct nvme_global_ctx *ctx) { char *filename, *ext; struct dirent *dir; @@ -685,7 +699,7 @@ static int nvme_read_volatile_config(nvme_root_t r) break; } - if (nvme_read_config(r, filename)) + if (nvme_read_config(ctx, filename)) ret = 0; free(filename); @@ -695,13 +709,13 @@ static int nvme_read_volatile_config(nvme_root_t r) return ret; } -static int nvme_read_config_checked(nvme_root_t r, const char *filename) +static int nvme_read_config_checked(struct nvme_global_ctx *ctx, + const char *filename) { if (access(filename, F_OK)) return -errno; - if (nvme_read_config(r, filename)) - return -errno; - return 0; + + return nvme_read_config(ctx, filename); } /* returns negative errno values */ @@ -717,7 +731,7 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect) _cleanup_free_ char *hid = NULL; char *context = NULL; nvme_print_flags_t flags; - _cleanup_nvme_root_ nvme_root_t r = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; nvme_host_t h; nvme_ctrl_t c = NULL; unsigned int verbose = 0; @@ -762,33 +776,33 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect) log_level = map_log_level(verbose, quiet); - r = nvme_create_root(stderr, log_level); - if (!r) { + ctx = nvme_create_global_ctx(stderr, log_level); + if (!ctx) { fprintf(stderr, "Failed to create topology root: %s\n", nvme_strerror(errno)); - return -errno; + return -ENOMEM; } if (context) - nvme_root_set_application(r, context); + nvme_set_application(ctx, context); - if (!nvme_read_config_checked(r, config_file)) + if (!nvme_read_config_checked(ctx, config_file)) json_config = true; - if (!nvme_read_volatile_config(r)) + if (!nvme_read_volatile_config(ctx)) json_config = true; - nvme_root_skip_namespaces(r); - ret = nvme_scan_topology(r, NULL, NULL); + nvme_skip_namespaces(ctx); + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret < 0) { fprintf(stderr, "Failed to scan topology: %s\n", - nvme_strerror(errno)); - return -errno; + nvme_strerror(-ret)); + return ret; } - ret = nvme_host_get_ids(r, hostnqn, hostid, &hnqn, &hid); + ret = nvme_host_get_ids(ctx, hostnqn, hostid, &hnqn, &hid); if (ret < 0) - return -errno; + return ret; - h = nvme_lookup_host(r, hnqn, hid); + h = nvme_lookup_host(ctx, hnqn, hid); if (!h) { ret = -ENOMEM; goto out_free; @@ -805,20 +819,20 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect) if (!device && !transport && !traddr) { if (!nonbft) - ret = discover_from_nbft(r, hostnqn, hostid, + ret = discover_from_nbft(ctx, hostnqn, hostid, hnqn, hid, desc, connect, &cfg, nbft_path, flags, verbose); if (nbft) goto out_free; if (json_config) - ret = discover_from_json_config_file(r, hostnqn, hostid, + ret = discover_from_json_config_file(ctx, hostnqn, hostid, desc, connect, &cfg, flags, force); if (ret || access(PATH_NVMF_DISC, F_OK)) goto out_free; - ret = discover_from_conf_file(r, h, desc, connect, &cfg); + ret = discover_from_conf_file(ctx, h, desc, connect, &cfg); goto out_free; } @@ -835,8 +849,8 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect) }; if (device && !force) { - c = nvme_scan_ctrl(r, device); - if (c) { + ret = nvme_scan_ctrl(ctx, device, &c); + if (!ret) { /* Check if device matches command-line options */ if (!nvme_ctrl_config_match(c, transport, traddr, trsvcid, subsysnqn, cfg.host_traddr, cfg.host_iface)) { @@ -893,13 +907,12 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect) } if (!c) { /* No device or non-matching device, create a new controller */ - c = nvmf_create_discover_ctrl(r, h, &cfg, &trcfg); - if (!c) { - if (errno != ENVME_CONNECT_IGNORED) + ret = nvmf_create_discover_ctrl(ctx, h, &cfg, &trcfg, &c); + if (ret) { + if (ret != -ENVME_CONNECT_IGNORED) fprintf(stderr, "failed to add controller, error %s\n", - nvme_strerror(errno)); - ret = -errno; + nvme_strerror(-ret)); goto out_free; } } @@ -911,12 +924,13 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect) out_free: if (dump_config) - nvme_dump_config(r); + nvme_dump_config(ctx); return ret; } -static int nvme_connect_config(nvme_root_t r, const char *hostnqn, const char *hostid, +static int nvme_connect_config(struct nvme_global_ctx *ctx, const char *hostnqn, + const char *hostid, const struct nvme_fabrics_config *cfg) { const char *hnqn, *hid; @@ -926,7 +940,7 @@ static int nvme_connect_config(nvme_root_t r, const char *hostnqn, const char *h nvme_ctrl_t c, _c; int ret = 0, err; - nvme_for_each_host(r, h) { + nvme_for_each_host(ctx, h) { nvme_for_each_subsystem(h, s) { hnqn = nvme_host_get_hostnqn(h); if (hostnqn && hnqn && strcmp(hostnqn, hnqn)) @@ -946,7 +960,7 @@ static int nvme_connect_config(nvme_root_t r, const char *hostnqn, const char *h err = nvmf_connect_ctrl(c); if (err) { - if (errno == ENVME_CONNECT_ALREADY) + if (err == -ENVME_CONNECT_ALREADY) continue; fprintf(stderr, @@ -1005,7 +1019,7 @@ int nvmf_connect(const char *desc, int argc, char **argv) char *config_file = NULL; char *context = NULL; unsigned int verbose = 0; - _cleanup_nvme_root_ nvme_root_t r = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; nvme_host_t h; _cleanup_nvme_ctrl_ nvme_ctrl_t c = NULL; int ret; @@ -1060,31 +1074,31 @@ int nvmf_connect(const char *desc, int argc, char **argv) do_connect: log_level = map_log_level(verbose, quiet); - r = nvme_create_root(stderr, log_level); - if (!r) { + ctx = nvme_create_global_ctx(stderr, log_level); + if (!ctx) { fprintf(stderr, "Failed to create topology root: %s\n", nvme_strerror(errno)); - return -errno; + return -ENOMEM; } if (context) - nvme_root_set_application(r, context); + nvme_set_application(ctx, context); - nvme_read_config(r, config_file); - nvme_read_volatile_config(r); + nvme_read_config(ctx, config_file); + nvme_read_volatile_config(ctx); - nvme_root_skip_namespaces(r); - ret = nvme_scan_topology(r, NULL, NULL); + nvme_skip_namespaces(ctx); + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret < 0) { fprintf(stderr, "Failed to scan topology: %s\n", - nvme_strerror(errno)); + nvme_strerror(-ret)); return ret; } - ret = nvme_host_get_ids(r, hostnqn, hostid, &hnqn, &hid); + ret = nvme_host_get_ids(ctx, hostnqn, hostid, &hnqn, &hid); if (ret < 0) - return -errno; + return ret; - h = nvme_lookup_host(r, hnqn, hid); + h = nvme_lookup_host(ctx, hnqn, hid); if (!h) return -ENOMEM; if (hostkey) @@ -1093,7 +1107,7 @@ int nvmf_connect(const char *desc, int argc, char **argv) trsvcid = nvmf_get_default_trsvcid(transport, false); if (config_file) - return nvme_connect_config(r, hostnqn, hostid, &cfg); + return nvme_connect_config(ctx, hostnqn, hostid, &cfg); struct tr_config trcfg = { .subsysnqn = subsysnqn, @@ -1110,10 +1124,10 @@ int nvmf_connect(const char *desc, int argc, char **argv) return -EALREADY; } - c = nvme_create_ctrl(r, subsysnqn, transport, traddr, - cfg.host_traddr, cfg.host_iface, trsvcid); - if (!c) - return -ENOMEM; + ret = nvme_create_ctrl(ctx, subsysnqn, transport, traddr, + cfg.host_traddr, cfg.host_iface, trsvcid, &c); + if (ret) + return ret; if (ctrlkey) nvme_ctrl_set_dhchap_key(c, ctrlkey); @@ -1131,18 +1145,19 @@ int nvmf_connect(const char *desc, int argc, char **argv) nvme_show_connect_msg(c, flags); if (dump_config) - nvme_dump_config(r); + nvme_dump_config(ctx); return 0; } -static nvme_ctrl_t lookup_nvme_ctrl(nvme_root_t r, const char *name) +static nvme_ctrl_t lookup_nvme_ctrl(struct nvme_global_ctx *ctx, + const char *name) { nvme_host_t h; nvme_subsystem_t s; nvme_ctrl_t c; - nvme_for_each_host(r, h) { + nvme_for_each_host(ctx, h) { nvme_for_each_subsystem(h, s) { nvme_subsystem_for_each_ctrl(s, c) { if (!strcmp(nvme_ctrl_get_name(c), name)) @@ -1153,7 +1168,7 @@ static nvme_ctrl_t lookup_nvme_ctrl(nvme_root_t r, const char *name) return NULL; } -static void nvmf_disconnect_nqn(nvme_root_t r, char *nqn) +static void nvmf_disconnect_nqn(struct nvme_global_ctx *ctx, char *nqn) { int i = 0; char *n = nqn; @@ -1165,7 +1180,7 @@ static void nvmf_disconnect_nqn(nvme_root_t r, char *nqn) while ((p = strsep(&n, ",")) != NULL) { if (!strlen(p)) continue; - nvme_for_each_host(r, h) { + nvme_for_each_host(ctx, h) { nvme_for_each_subsystem(h, s) { if (strcmp(nvme_subsystem_get_nqn(s), p)) continue; @@ -1182,7 +1197,7 @@ static void nvmf_disconnect_nqn(nvme_root_t r, char *nqn) int nvmf_disconnect(const char *desc, int argc, char **argv) { const char *device = "nvme device handle"; - _cleanup_nvme_root_ nvme_root_t r = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; nvme_ctrl_t c; char *p; int ret; @@ -1219,30 +1234,30 @@ int nvmf_disconnect(const char *desc, int argc, char **argv) log_level = map_log_level(cfg.verbose, false); - r = nvme_create_root(stderr, log_level); - if (!r) { + ctx = nvme_create_global_ctx(stderr, log_level); + if (!ctx) { fprintf(stderr, "Failed to create topology root: %s\n", nvme_strerror(errno)); - return -errno; + return -ENOMEM; } - nvme_root_skip_namespaces(r); - ret = nvme_scan_topology(r, NULL, NULL); + nvme_skip_namespaces(ctx); + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret < 0) { /* * Do not report an error when the modules are not * loaded, this allows the user to unconditionally call * disconnect. */ - if (errno == ENOENT) + if (ret == -ENOENT) return 0; fprintf(stderr, "Failed to scan topology: %s\n", - nvme_strerror(errno)); - return -errno; + nvme_strerror(-ret)); + return ret; } if (cfg.nqn) - nvmf_disconnect_nqn(r, cfg.nqn); + nvmf_disconnect_nqn(ctx, cfg.nqn); if (cfg.device) { char *d; @@ -1251,17 +1266,17 @@ int nvmf_disconnect(const char *desc, int argc, char **argv) while ((p = strsep(&d, ",")) != NULL) { if (!strncmp(p, "/dev/", 5)) p += 5; - c = lookup_nvme_ctrl(r, p); + c = lookup_nvme_ctrl(ctx, p); if (!c) { fprintf(stderr, "Did not find device %s\n", p); - return -errno; + return -ENODEV; } ret = nvme_disconnect_ctrl(c); if (ret) fprintf(stderr, "Failed to disconnect %s: %s\n", - p, nvme_strerror(errno)); + p, nvme_strerror(-ret)); } } @@ -1270,7 +1285,7 @@ int nvmf_disconnect(const char *desc, int argc, char **argv) int nvmf_disconnect_all(const char *desc, int argc, char **argv) { - _cleanup_nvme_root_ nvme_root_t r = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; nvme_host_t h; nvme_subsystem_t s; nvme_ctrl_t c; @@ -1295,29 +1310,29 @@ int nvmf_disconnect_all(const char *desc, int argc, char **argv) log_level = map_log_level(cfg.verbose, false); - r = nvme_create_root(stderr, log_level); - if (!r) { + ctx = nvme_create_global_ctx(stderr, log_level); + if (!ctx) { fprintf(stderr, "Failed to create topology root: %s\n", nvme_strerror(errno)); - return -errno; + return -ENOMEM; } - nvme_root_skip_namespaces(r); - ret = nvme_scan_topology(r, NULL, NULL); + nvme_skip_namespaces(ctx); + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret < 0) { /* * Do not report an error when the modules are not * loaded, this allows the user to unconditionally call * disconnect. */ - if (errno == ENOENT) + if (ret == -ENOENT) return 0; fprintf(stderr, "Failed to scan topology: %s\n", - nvme_strerror(errno)); - return -errno; + nvme_strerror(-ret)); + return ret; } - nvme_for_each_host(r, h) { + nvme_for_each_host(ctx, h) { nvme_for_each_subsystem(h, s) { nvme_subsystem_for_each_ctrl(s, c) { if (cfg.transport && @@ -1349,7 +1364,7 @@ int nvmf_config(const char *desc, int argc, char **argv) char *keyring = NULL, *tls_key = NULL, *tls_key_identity = NULL; char *config_file = PATH_NVMF_CONFIG; unsigned int verbose = 0; - _cleanup_nvme_root_ nvme_root_t r = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; int ret; struct nvme_fabrics_config cfg; bool scan_tree = false, modify_config = false, update_config = false; @@ -1374,22 +1389,22 @@ int nvmf_config(const char *desc, int argc, char **argv) log_level = map_log_level(verbose, quiet); - r = nvme_create_root(stderr, log_level); - if (!r) { + ctx = nvme_create_global_ctx(stderr, log_level); + if (!ctx) { fprintf(stderr, "Failed to create topology root: %s\n", nvme_strerror(errno)); - return -errno; + return -ENOMEM; } - nvme_read_config(r, config_file); + nvme_read_config(ctx, config_file); if (scan_tree) { - nvme_root_skip_namespaces(r); - ret = nvme_scan_topology(r, NULL, NULL); + nvme_skip_namespaces(ctx); + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret < 0) { fprintf(stderr, "Failed to scan topology: %s\n", - nvme_strerror(errno)); - return -errno; + nvme_strerror(-ret)); + return -ret; } } @@ -1414,27 +1429,26 @@ int nvmf_config(const char *desc, int argc, char **argv) hostnqn = hnqn = nvmf_hostnqn_from_file(); if (!hostid && hnqn) hostid = hid = nvmf_hostid_from_file(); - h = nvme_lookup_host(r, hostnqn, hostid); + h = nvme_lookup_host(ctx, hostnqn, hostid); if (!h) { - fprintf(stderr, "Failed to lookup host '%s': %s\n", - hostnqn, nvme_strerror(errno)); - return -errno; + fprintf(stderr, "Failed to lookup host '%s'\n", + hostnqn); + return -ENODEV; } if (hostkey) nvme_host_set_dhchap_key(h, hostkey); s = nvme_lookup_subsystem(h, NULL, subsysnqn); if (!s) { - fprintf(stderr, "Failed to lookup subsystem '%s': %s\n", - subsysnqn, nvme_strerror(errno)); - return -errno; + fprintf(stderr, "Failed to lookup subsystem '%s'\n", + subsysnqn); + return -ENODEV; } c = nvme_lookup_ctrl(s, transport, traddr, cfg.host_traddr, cfg.host_iface, trsvcid, NULL); if (!c) { - fprintf(stderr, "Failed to lookup controller: %s\n", - nvme_strerror(errno)); - return -errno; + fprintf(stderr, "Failed to lookup controller\n"); + return -ENODEV; } if (ctrlkey) nvme_ctrl_set_dhchap_key(c, ctrlkey); @@ -1444,10 +1458,10 @@ int nvmf_config(const char *desc, int argc, char **argv) } if (update_config) - nvme_update_config(r); + nvme_update_config(ctx); if (dump_config) - nvme_dump_config(r); + nvme_dump_config(ctx); return 0; } @@ -1479,7 +1493,7 @@ static int dim_operation(nvme_ctrl_t c, enum nvmf_dim_tas tas, const char *name) int nvmf_dim(const char *desc, int argc, char **argv) { - _cleanup_nvme_root_ nvme_root_t r = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; enum nvmf_dim_tas tas; nvme_ctrl_t c; char *p; @@ -1528,18 +1542,18 @@ int nvmf_dim(const char *desc, int argc, char **argv) log_level = map_log_level(cfg.verbose, false); - r = nvme_create_root(stderr, log_level); - if (!r) { + ctx = nvme_create_global_ctx(stderr, log_level); + if (!ctx) { fprintf(stderr, "Failed to create topology root: %s\n", nvme_strerror(errno)); - return -errno; + return -ENODEV; } - nvme_root_skip_namespaces(r); - ret = nvme_scan_topology(r, NULL, NULL); + nvme_skip_namespaces(ctx); + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret < 0) { fprintf(stderr, "Failed to scan topology: %s\n", - nvme_strerror(errno)); - return -errno; + nvme_strerror(-ret)); + return ret; } if (cfg.nqn) { @@ -1550,7 +1564,7 @@ int nvmf_dim(const char *desc, int argc, char **argv) while ((p = strsep(&n, ",")) != NULL) { if (!strlen(p)) continue; - nvme_for_each_host(r, h) { + nvme_for_each_host(ctx, h) { nvme_for_each_subsystem(h, s) { if (strcmp(nvme_subsystem_get_nqn(s), p)) continue; @@ -1567,12 +1581,12 @@ int nvmf_dim(const char *desc, int argc, char **argv) while ((p = strsep(&d, ",")) != NULL) { if (!strncmp(p, "/dev/", 5)) p += 5; - c = nvme_scan_ctrl(r, p); - if (!c) { + ret = nvme_scan_ctrl(ctx, p, &c); + if (ret) { fprintf(stderr, "Did not find device %s: %s\n", p, nvme_strerror(errno)); - return -errno; + return ret; } ret = dim_operation(c, tas, p); } diff --git a/fabrics.h b/fabrics.h index aec305dc31..50ff00dee4 100644 --- a/fabrics.h +++ b/fabrics.h @@ -18,9 +18,10 @@ extern int nvmf_disconnect(const char *desc, int argc, char **argv); extern int nvmf_disconnect_all(const char *desc, int argc, char **argv); extern int nvmf_config(const char *desc, int argc, char **argv); extern int nvmf_dim(const char *desc, int argc, char **argv); -extern nvme_ctrl_t nvmf_create_discover_ctrl(nvme_root_t r, nvme_host_t h, - struct nvme_fabrics_config *cfg, - struct tr_config *trcfg); +extern int nvmf_create_discover_ctrl(struct nvme_global_ctx *ctx, nvme_host_t h, + struct nvme_fabrics_config *cfg, + struct tr_config *trcfg, + nvme_ctrl_t *ctrl); extern char *nvmf_get_default_trsvcid(const char *transport, bool discovery_ctrl); diff --git a/libnvme-wrap.c b/libnvme-wrap.c index b5b48383b6..70ce5cb443 100644 --- a/libnvme-wrap.c +++ b/libnvme-wrap.c @@ -36,38 +36,3 @@ rtype __attribute__((weak)) name(proto) \ return fn(args); \ return defret; \ } - -FN(nvme_get_version, - const char *, PROTO(enum nvme_version type), - ARGS(type), "n/a") - -VOID_FN(nvme_init_copy_range_f1, - PROTO(struct nvme_copy_range_f1 *copy, __u16 *nlbs, - __u64 *slbas, __u64 *eilbrts, __u32 *elbatms, - __u32 *elbats, __u16 nr), - ARGS(copy, nlbs, slbas, eilbrts, elbatms, elbats, nr)) - -VOID_FN(nvme_init_copy_range_f2, - PROTO(struct nvme_copy_range_f2 *copy, __u32 *snsids, - __u16 *nlbs, __u64 *slbas, __u16 *sopts, __u32 *eilbrts, - __u32 *elbatms, __u32 *elbats, __u16 nr), - ARGS(copy, snsids, nlbs, slbas, sopts, eilbrts, elbatms, elbats, nr)) - -VOID_FN(nvme_init_copy_range_f3, - PROTO(struct nvme_copy_range_f3 *copy, __u32 *snsids, - __u16 *nlbs, __u64 *slbas, __u16 *sopts, __u64 *eilbrts, - __u32 *elbatms, __u32 *elbats, __u16 nr), - ARGS(copy, snsids, nlbs, slbas, sopts, eilbrts, elbatms, elbats, nr)) - -FN(nvme_get_feature_length2, - int, - PROTO(int fid, __u32 cdw11, enum nvme_data_tfr dir, - __u32 *len), - ARGS(fid, cdw11, dir, len), - -EEXIST) - -FN(nvme_ctrl_is_persistent, - bool, - PROTO(nvme_ctrl_t c), - ARGS(c), - false) diff --git a/logging.c b/logging.c index e037a851aa..a8b1bd16cd 100644 --- a/logging.c +++ b/logging.c @@ -107,7 +107,7 @@ static void nvme_log_retry(int errnum) printf("passthru command returned '%s'\n", strerror(errnum)); } -int nvme_submit_passthru(int fd, unsigned long ioctl_cmd, +int nvme_submit_passthru(struct nvme_transport_handle *hdl, unsigned long ioctl_cmd, struct nvme_passthru_cmd *cmd, __u32 *result) { struct timeval start; @@ -119,7 +119,7 @@ int nvme_submit_passthru(int fd, unsigned long ioctl_cmd, if (!nvme_cfg.dry_run) { retry: - err = ioctl(fd, ioctl_cmd, cmd); + err = ioctl(nvme_transport_handle_get_fd(hdl), ioctl_cmd, cmd); if ((err && (errno == EAGAIN || (errno == EINTR && !nvme_sigint_received))) && !nvme_cfg.no_retries) { @@ -140,7 +140,7 @@ int nvme_submit_passthru(int fd, unsigned long ioctl_cmd, return err; } -int nvme_submit_passthru64(int fd, unsigned long ioctl_cmd, +int nvme_submit_passthru64(struct nvme_transport_handle *hdl, unsigned long ioctl_cmd, struct nvme_passthru_cmd64 *cmd, __u64 *result) { @@ -153,7 +153,7 @@ int nvme_submit_passthru64(int fd, unsigned long ioctl_cmd, if (!nvme_cfg.dry_run) { retry: - err = ioctl(fd, ioctl_cmd, cmd); + err = ioctl(nvme_transport_handle_get_fd(hdl), ioctl_cmd, cmd); if ((err && (errno == EAGAIN || (errno == EINTR && !nvme_sigint_received))) && !nvme_cfg.no_retries) { diff --git a/meson.build b/meson.build index 3afd8ba3b1..91859b9c66 100644 --- a/meson.build +++ b/meson.build @@ -50,8 +50,6 @@ conf.set('RUNDIR', '"@0@"'.format(rundir)) # Check for libnvme availability libnvme_dep = dependency('libnvme', version: '>=1.15', required: true, fallback : ['libnvme', 'libnvme_dep']) -libnvme_mi_dep = dependency('libnvme-mi', required: true, - fallback : ['libnvme', 'libnvme_mi_dep']) # Check for libjson-c availability if get_option('json-c').disabled() @@ -295,7 +293,6 @@ sources = [ 'nvme-print-stdout.c', 'nvme-print-binary.c', 'nvme-rpmb.c', - 'nvme-wrap.c', 'plugin.c', 'libnvme-wrap.c', 'logging.c', @@ -318,7 +315,7 @@ subdir('Documentation') executable( 'nvme', sources, - dependencies: [ libnvme_dep, libnvme_mi_dep, json_c_dep ], + dependencies: [ libnvme_dep, json_c_dep ], link_args: '-ldl', include_directories: incdir, install: true, diff --git a/nbft.c b/nbft.c index b5c82b07ca..1c39c0d774 100644 --- a/nbft.c +++ b/nbft.c @@ -103,8 +103,7 @@ static bool validate_uri(struct nbft_info_discovery *dd, return true; } -/* returns 0 for success or negative errno otherwise */ -static int do_connect(nvme_root_t r, +static int do_connect(struct nvme_global_ctx *ctx, nvme_host_t h, struct nvmf_disc_log_entry *e, struct nbft_info_subsystem_ns *ss, @@ -124,18 +123,18 @@ static int do_connect(nvme_root_t r, if (c && nvme_ctrl_get_name(c)) return 0; - c = nvme_create_ctrl(r, trcfg->subsysnqn, trcfg->transport, + ret = nvme_create_ctrl(ctx, trcfg->subsysnqn, trcfg->transport, trcfg->traddr, trcfg->host_traddr, - trcfg->host_iface, trcfg->trsvcid); - if (!c) - return -ENOMEM; + trcfg->host_iface, trcfg->trsvcid, &c); + if (ret) + return ret; /* Pause logging for unavailable SSNSs */ if (ss && ss->unavailable && verbose < 1) { - saved_log_level = nvme_get_logging_level(r, + saved_log_level = nvme_get_logging_level(ctx, &saved_log_pid, &saved_log_tstamp); - nvme_init_logging(r, -1, false, false); + nvme_init_logging(ctx, -1, false, false); } if (e) { @@ -144,17 +143,16 @@ static int do_connect(nvme_root_t r, cfg->tls = true; } - errno = 0; ret = nvmf_add_ctrl(h, c, cfg); /* Resume logging */ if (ss && ss->unavailable && verbose < 1) - nvme_init_logging(r, + nvme_init_logging(ctx, saved_log_level, saved_log_pid, saved_log_tstamp); - if (ret == -1) { + if (ret) { nvme_free_ctrl(c); /* * In case this SSNS was marked as 'unavailable' and @@ -167,7 +165,7 @@ static int do_connect(nvme_root_t r, ss->index); return 0; } - return -errno; + return ret; } if (flags == NORMAL) @@ -179,7 +177,7 @@ static int do_connect(nvme_root_t r, } static int do_discover(struct nbft_info_discovery *dd, - nvme_root_t r, + struct nvme_global_ctx *ctx, nvme_host_t h, nvme_ctrl_t c, struct nvme_fabrics_config *defcfg, @@ -188,8 +186,8 @@ static int do_discover(struct nbft_info_discovery *dd, unsigned int verbose) { struct nvmf_discovery_log *log = NULL; - int i; int ret; + int i; struct nvme_get_discovery_args args = { .c = c, @@ -200,12 +198,12 @@ static int do_discover(struct nbft_info_discovery *dd, .lsp = 0, }; - log = nvmf_get_discovery_wargs(&args); - if (!log) { + ret = nvmf_get_discovery_wargs(&args, &log); + if (ret) { fprintf(stderr, "Discovery Descriptor %d: failed to get discovery log: %s\n", - dd->index, nvme_strerror(errno)); - return -errno; + dd->index, nvme_strerror(-ret)); + return ret; } for (i = 0; i < le64_to_cpu(log->numrec); i++) { @@ -238,13 +236,15 @@ static int do_discover(struct nbft_info_discovery *dd, if (e->subtype == NVME_NQN_DISC) { nvme_ctrl_t child; - child = nvmf_connect_disc_entry(h, e, defcfg, NULL); - do_discover(dd, r, h, child, defcfg, &trcfg, + ret = nvmf_connect_disc_entry(h, e, defcfg, NULL, &child); + if (ret) + return ret; + do_discover(dd, ctx, h, child, defcfg, &trcfg, flags, verbose); nvme_disconnect_ctrl(child); nvme_free_ctrl(child); } else { - ret = do_connect(r, h, e, NULL, &trcfg, + ret = do_connect(ctx, h, e, NULL, &trcfg, defcfg, flags, verbose); /* @@ -258,7 +258,7 @@ static int do_discover(struct nbft_info_discovery *dd, const char *htradr = trcfg.host_traddr; trcfg.host_traddr = NULL; - ret = do_connect(r, h, e, NULL, &trcfg, + ret = do_connect(ctx, h, e, NULL, &trcfg, defcfg, flags, verbose); if (ret == 0 && verbose >= 1) @@ -282,9 +282,8 @@ static int do_discover(struct nbft_info_discovery *dd, return 0; } -/* returns negative errno values */ -int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg, - char *hostnqn_sys, char *hostid_sys, +int discover_from_nbft(struct nvme_global_ctx *ctx, char *hostnqn_arg, + char *hostid_arg, char *hostnqn_sys, char *hostid_sys, const char *desc, bool connect, struct nvme_fabrics_config *cfg, char *nbft_path, nvme_print_flags_t flags, unsigned int verbose) @@ -329,7 +328,7 @@ int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg, hostid = hostid_sys; } - h = nvme_lookup_host(r, hostnqn, hostid); + h = nvme_lookup_host(ctx, hostnqn, hostid); if (!h) { ret = -ENOENT; goto out_free; @@ -363,7 +362,7 @@ int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg, .trsvcid = (*ss)->trsvcid, }; - rr = do_connect(r, h, NULL, *ss, &trcfg, + rr = do_connect(ctx, h, NULL, *ss, &trcfg, cfg, flags, verbose); /* @@ -376,7 +375,7 @@ int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg, strlen(hfi->tcp_info.dhcp_server_ipaddr) > 0) { trcfg.host_traddr = NULL; - rr = do_connect(r, h, NULL, *ss, &trcfg, + rr = do_connect(ctx, h, NULL, *ss, &trcfg, cfg, flags, verbose); if (rr == 0 && verbose >= 1) @@ -421,7 +420,9 @@ int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg, continue; hfi = (*dd)->hfi; - uri = nvme_parse_uri((*dd)->uri); + ret = nvme_parse_uri((*dd)->uri, &uri); + if (ret) + continue; if (!validate_uri(*dd, uri)) continue; @@ -452,28 +453,24 @@ int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg, persistent = true; if (!c) { - c = nvmf_create_discover_ctrl(r, h, cfg, &trcfg); - if (!c && errno == ENVME_CONNECT_ADDRNOTAVAIL && + ret = nvmf_create_discover_ctrl(ctx, h, cfg, &trcfg, &c); + if (ret == -ENVME_CONNECT_ADDRNOTAVAIL && !strcmp(trcfg.transport, "tcp") && strlen(hfi->tcp_info.dhcp_server_ipaddr) > 0) { trcfg.host_traddr = NULL; - c = nvmf_create_discover_ctrl(r, h, cfg, &trcfg); + ret = nvmf_create_discover_ctrl(ctx, h, cfg, &trcfg, &c); } - } + } else + ret = 0; - if (!c) { + if (ret) { fprintf(stderr, "Discovery Descriptor %d: failed to add discovery controller: %s\n", - (*dd)->index, - nvme_strerror(errno)); - if (errno == ENOMEM) { - ret = -ENOMEM; - goto out_free; - } - continue; + (*dd)->index, nvme_strerror(-ret)); + goto out_free; } - rr = do_discover(*dd, r, h, c, cfg, &trcfg, + rr = do_discover(*dd, ctx, h, c, cfg, &trcfg, flags, verbose); if (!persistent) nvme_disconnect_ctrl(c); diff --git a/nbft.h b/nbft.h index 88e0f357ae..412ce67f6e 100644 --- a/nbft.h +++ b/nbft.h @@ -12,8 +12,8 @@ struct nbft_file_entry { int read_nbft_files(struct list_head *nbft_list, char *path); void free_nbfts(struct list_head *nbft_list); -extern int discover_from_nbft(nvme_root_t r, char *hostnqn_arg, char *hostid_arg, - char *hostnqn_sys, char *hostid_sys, - const char *desc, bool connect, +extern int discover_from_nbft(struct nvme_global_ctx *ctx, char *hostnqn_arg, + char *hostid_arg, char *hostnqn_sys, + char *hostid_sys, const char *desc, bool connect, struct nvme_fabrics_config *cfg, char *nbft_path, nvme_print_flags_t flags, unsigned int verbose); diff --git a/nvme-print-json.c b/nvme-print-json.c index 11b6661624..8e6eeaa82b 100644 --- a/nvme-print-json.c +++ b/nvme-print-json.c @@ -1781,7 +1781,7 @@ static void json_pel_set_feature(void *pevent_log_info, __u32 offset, struct json_object *valid_attrs) { struct nvme_set_feature_event *set_feat_event = pevent_log_info + offset; - int fid = NVME_GET(le32_to_cpu(set_feat_event->cdw_mem[0]), FEATURES_CDW10_FID); + int fid = NVME_GET(le32_to_cpu(set_feat_event->cdw_mem[0]), SET_FEATURES_CDW10_FID); int cdw11 = le32_to_cpu(set_feat_event->cdw_mem[1]); int dword_cnt = NVME_SET_FEAT_EVENT_DW_COUNT(set_feat_event->layout); unsigned char *mem_buf; @@ -2611,14 +2611,15 @@ static void json_print_nvme_subsystem_ctrls(nvme_subsystem_t s, } } -static void json_print_nvme_subsystem_list(nvme_root_t r, bool show_ana) +static void json_print_nvme_subsystem_list(struct nvme_global_ctx *ctx, + bool show_ana) { struct json_object *host_attrs, *subsystem_attrs; struct json_object *subsystems, *paths; struct json_object *a = json_create_array(); nvme_host_t h; - nvme_for_each_host(r, h) { + nvme_for_each_host(ctx, h) { nvme_subsystem_t s; const char *hostid; @@ -4519,7 +4520,7 @@ static void json_print_detail_list(nvme_subsystem_t s, struct json_object *jss) obj_add_obj(jss, "Controllers", jctrls); } -static void json_detail_list(nvme_root_t t) +static void json_detail_list(struct nvme_global_ctx *ctx) { struct json_object *r = json_create_object(); struct json_object *jdev = json_create_array(); @@ -4527,7 +4528,7 @@ static void json_detail_list(nvme_root_t t) nvme_host_t h; nvme_subsystem_t s; - nvme_for_each_host(t, h) { + nvme_for_each_host(ctx, h) { struct json_object *hss = json_create_object(); struct json_object *jsslist = json_create_array(); const char *hostid; @@ -4586,7 +4587,7 @@ static struct json_object *json_list_item_obj(nvme_ns_t n) return r; } -static void json_simple_list(nvme_root_t t) +static void json_simple_list(struct nvme_global_ctx *ctx) { struct json_object *r = json_create_object(); struct json_object *jdevices = json_create_array(); @@ -4596,7 +4597,7 @@ static void json_simple_list(nvme_root_t t) nvme_ctrl_t c; nvme_ns_t n; - nvme_for_each_host(t, h) { + nvme_for_each_host(ctx, h) { nvme_for_each_subsystem(h, s) { nvme_subsystem_for_each_ns(s, n) array_add_obj(jdevices, json_list_item_obj(n)); @@ -4620,12 +4621,12 @@ static void json_list_item(nvme_ns_t n) json_print(r); } -static void json_print_list_items(nvme_root_t t) +static void json_print_list_items(struct nvme_global_ctx *ctx) { if (verbose_mode()) - json_detail_list(t); + json_detail_list(ctx); else - json_simple_list(t); + json_simple_list(ctx); } static unsigned int json_subsystem_topology_multipath(nvme_subsystem_t s, @@ -4697,14 +4698,14 @@ static void json_print_nvme_subsystem_topology(nvme_subsystem_t s, } } -static void json_simple_topology(nvme_root_t r) +static void json_simple_topology(struct nvme_global_ctx *ctx) { struct json_object *host_attrs, *subsystem_attrs; struct json_object *subsystems, *namespaces; struct json_object *a = json_create_array(); nvme_host_t h; - nvme_for_each_host(r, h) { + nvme_for_each_host(ctx, h) { nvme_subsystem_t s; const char *hostid; @@ -4787,7 +4788,7 @@ static void json_directive_show_fields_identify(__u8 doper, __u8 *field, struct } } -static void json_directive_show_fields_streams(__u8 doper, unsigned int result, __u16 *field, +static void json_directive_show_fields_streams(__u8 doper, unsigned int result, __u16 *field, struct json_object *r) { int count; diff --git a/nvme-print-stdout.c b/nvme-print-stdout.c index c597b60872..87d1eb31ef 100644 --- a/nvme-print-stdout.c +++ b/nvme-print-stdout.c @@ -93,7 +93,7 @@ static void htable_ns_add_unique(struct htable_ns *ht, nvme_ns_t n) } struct nvme_resources { - nvme_root_t r; + struct nvme_global_ctx *ctx; struct htable_subsys ht_s; struct htable_ctrl ht_c; @@ -103,7 +103,7 @@ struct nvme_resources { struct strset namespaces; }; -static int nvme_resources_init(nvme_root_t r, struct nvme_resources *res) +static int nvme_resources_init(struct nvme_global_ctx *ctx, struct nvme_resources *res) { nvme_host_t h; nvme_subsystem_t s; @@ -111,7 +111,7 @@ static int nvme_resources_init(nvme_root_t r, struct nvme_resources *res) nvme_ns_t n; nvme_path_t p; - res->r = r; + res->ctx = ctx; htable_subsys_init(&res->ht_s); htable_ctrl_init(&res->ht_c); htable_ns_init(&res->ht_n); @@ -119,7 +119,7 @@ static int nvme_resources_init(nvme_root_t r, struct nvme_resources *res) strset_init(&res->ctrls); strset_init(&res->namespaces); - nvme_for_each_host(r, h) { + nvme_for_each_host(ctx, h) { nvme_for_each_subsystem(h, s) { htable_subsys_add(&res->ht_s, s); strset_add(&res->subsystems, nvme_subsystem_get_name(s)); @@ -449,7 +449,7 @@ static void pel_set_feature_event(void *pevent_log_info, __u32 offset) printf("Set Feature Event Entry:\n"); dword_cnt = NVME_SET_FEAT_EVENT_DW_COUNT(set_feat_event->layout); - fid = NVME_GET(le32_to_cpu(set_feat_event->cdw_mem[0]), FEATURES_CDW10_FID); + fid = NVME_GET(le32_to_cpu(set_feat_event->cdw_mem[0]), SET_FEATURES_CDW10_FID); cdw11 = le32_to_cpu(set_feat_event->cdw_mem[1]); printf("Set Feature ID: 0x%02x (%s), value: 0x%08x\n", fid, nvme_feature_to_string(fid), @@ -1141,12 +1141,12 @@ static void stdout_subsys_config(nvme_subsystem_t s) } } -static void stdout_subsystem(nvme_root_t r, bool show_ana) +static void stdout_subsystem(struct nvme_global_ctx *ctx, bool show_ana) { nvme_host_t h; bool first = true; - nvme_for_each_host(r, h) { + nvme_for_each_host(ctx, h) { nvme_subsystem_t s; nvme_for_each_subsystem(h, s) { @@ -1171,9 +1171,9 @@ static void stdout_subsystem(nvme_root_t r, bool show_ana) } } -static void stdout_subsystem_list(nvme_root_t r, bool show_ana) +static void stdout_subsystem_list(struct nvme_global_ctx *ctx, bool show_ana) { - stdout_subsystem(r, show_ana); + stdout_subsystem(ctx, show_ana); } static void stdout_registers_cap(struct nvme_bar_cap *cap) @@ -4303,7 +4303,7 @@ static void stdout_support_log_human(__u32 support, __u8 lid) printf(" Establish Context and Read 512 Bytes of Header is %s\n", (lidsp & 0x1) ? set : clr); break; - case NVME_LOG_LID_DISCOVER: + case NVME_LOG_LID_DISCOVERY: printf(" Extended Discovery Log Page Entry is %s\n", (lidsp & 0x1) ? set : clr); printf(" Port Local Entries Only is %s\n", @@ -4311,7 +4311,7 @@ static void stdout_support_log_human(__u32 support, __u8 lid) printf(" All NVM Subsystem Entries is %s\n", (lidsp & 0x4) ? set : clr); break; - case NVME_LOG_LID_HOST_DISCOVER: + case NVME_LOG_LID_HOST_DISCOVERY: printf(" All Host Entries is %s\n", (lidsp & 0x1) ? set : clr); break; @@ -5150,7 +5150,7 @@ static void stdout_feature_show_fields(enum nvme_features_id fid, break; case NVME_FEAT_FID_PLM_CONFIG: printf("\tPredictable Latency Window Enabled: %s\n", - NVME_FEAT_PLM_PLME(result) ? "True" : "False"); + NVME_FEAT_PLM_LPE(result) ? "True" : "False"); if (buf) stdout_plm_config((struct nvme_plm_config *)buf); break; @@ -5383,11 +5383,11 @@ static bool stdout_simple_ns(const char *name, void *arg) return true; } -static void stdout_simple_list(nvme_root_t r) +static void stdout_simple_list(struct nvme_global_ctx *ctx) { struct nvme_resources res; - nvme_resources_init(r, &res); + nvme_resources_init(ctx, &res); printf("%-21s %-21s %-20s %-40s %-10s %-26s %-16s %-8s\n", "Node", "Generic", "SN", "Model", "Namespace", "Usage", "Format", "FW Rev"); @@ -5553,11 +5553,11 @@ static bool stdout_detailed_ns(const char *name, void *arg) return true; } -static void stdout_detailed_list(nvme_root_t r) +static void stdout_detailed_list(struct nvme_global_ctx *ctx) { struct nvme_resources res; - nvme_resources_init(r, &res); + nvme_resources_init(ctx, &res); printf("%-16s %-96s %-.16s\n", "Subsystem", "Subsystem-NQN", "Controllers"); printf("%-.16s %-.96s %-.16s\n", dash, dash, dash); @@ -5581,12 +5581,12 @@ static void stdout_detailed_list(nvme_root_t r) nvme_resources_free(&res); } -static void stdout_list_items(nvme_root_t r) +static void stdout_list_items(struct nvme_global_ctx *ctx) { if (stdout_print_ops.flags & VERBOSE) - stdout_detailed_list(r); + stdout_detailed_list(ctx); else - stdout_simple_list(r); + stdout_simple_list(ctx); } static void stdout_subsystem_topology_multipath(nvme_subsystem_t s, @@ -5674,14 +5674,14 @@ static void stdout_subsystem_topology(nvme_subsystem_t s, } } -static void stdout_simple_topology(nvme_root_t r, +static void stdout_simple_topology(struct nvme_global_ctx *ctx, enum nvme_cli_topo_ranking ranking) { nvme_host_t h; nvme_subsystem_t s; bool first = true; - nvme_for_each_host(r, h) { + nvme_for_each_host(ctx, h) { nvme_for_each_subsystem(h, s) { if (!first) printf("\n"); @@ -5698,14 +5698,14 @@ static void stdout_simple_topology(nvme_root_t r, } } -static void stdout_topology_namespace(nvme_root_t r) +static void stdout_topology_namespace(struct nvme_global_ctx *ctx) { - stdout_simple_topology(r, NVME_CLI_TOPO_NAMESPACE); + stdout_simple_topology(ctx, NVME_CLI_TOPO_NAMESPACE); } -static void stdout_topology_ctrl(nvme_root_t r) +static void stdout_topology_ctrl(struct nvme_global_ctx *ctx) { - stdout_simple_topology(r, NVME_CLI_TOPO_CTRL); + stdout_simple_topology(ctx, NVME_CLI_TOPO_CTRL); } static void stdout_message(bool error, const char *msg, va_list ap) @@ -5993,7 +5993,7 @@ static void stdout_pull_model_ddc_req_log(struct nvme_pull_model_ddc_req_log *lo d((unsigned char *)log->osp, osp_len, 16, 1); } -static void stdout_relatives(nvme_root_t r, const char *name) +static void stdout_relatives(struct nvme_global_ctx *ctx, const char *name) { struct nvme_resources res; struct htable_ns_iter it; @@ -6018,7 +6018,7 @@ static void stdout_relatives(nvme_root_t r, const char *name) return; } - nvme_resources_init(r, &res); + nvme_resources_init(ctx, &res); if (block) { fprintf(stderr, "Namespace %s has parent controller(s):", name); @@ -6152,7 +6152,7 @@ static void stdout_log(const char *devname, struct nvme_get_log_args *args) case NVME_LOG_LID_REACHABILITY_ASSOCIATIONS: stdout_reachability_associations_log(reachability_associations_log, args->len); break; - case NVME_LOG_LID_CHANGED_ALLOC_NS_LIST: + case NVME_LOG_LID_CHANGED_ALLOC_NS: stdout_changed_ns_list_log((struct nvme_ns_list *)args->log, devname, true); break; case NVME_LOG_LID_FDP_CONFIGS: @@ -6167,13 +6167,13 @@ static void stdout_log(const char *devname, struct nvme_get_log_args *args) case NVME_LOG_LID_FDP_EVENTS: stdout_fdp_events((struct nvme_fdp_events_log *)args->log); break; - case NVME_LOG_LID_DISCOVER: + case NVME_LOG_LID_DISCOVERY: stdout_discovery_log(discovery_log, le64_to_cpu(discovery_log->numrec)); break; - case NVME_LOG_LID_HOST_DISCOVER: + case NVME_LOG_LID_HOST_DISCOVERY: stdout_host_discovery_log((struct nvme_host_discover_log *)args->log); break; - case NVME_LOG_LID_AVE_DISCOVER: + case NVME_LOG_LID_AVE_DISCOVERY: stdout_ave_discovery_log((struct nvme_ave_discover_log *)args->log); break; case NVME_LOG_LID_PULL_MODEL_DDC_REQ: diff --git a/nvme-print.c b/nvme-print.c index 3a71dffcbe..695feb52ab 100644 --- a/nvme-print.c +++ b/nvme-print.c @@ -376,10 +376,10 @@ void nvme_show_supported_cap_config_log( nvme_print(supported_cap_config_list_log, flags, cap); } -void nvme_show_subsystem_list(nvme_root_t r, bool show_ana, +void nvme_show_subsystem_list(struct nvme_global_ctx *ctx, bool show_ana, nvme_print_flags_t flags) { - nvme_print(print_nvme_subsystem_list, flags, r, show_ana); + nvme_print(print_nvme_subsystem_list, flags, ctx, show_ana); } const char *nvme_register_szu_to_string(__u8 szu) @@ -491,9 +491,10 @@ void nvme_show_single_property(int offset, uint64_t value64, nvme_print_flags_t nvme_print(single_property, flags, offset, value64); } -void nvme_show_relatives(nvme_root_t r, const char *name, nvme_print_flags_t flags) +void nvme_show_relatives(struct nvme_global_ctx *ctx, const char *name, + nvme_print_flags_t flags) { - nvme_print(relatives, flags, r, name); + nvme_print(relatives, flags, ctx, name); } void d(unsigned char *buf, int len, int width, int group) @@ -786,14 +787,14 @@ const char *nvme_log_to_string(__u8 lid) case NVME_LOG_LID_PHY_RX_EOM: return "Physical Interface Receiver Eye Opening Measurement"; case NVME_LOG_LID_REACHABILITY_GROUPS: return "Reachability Groups"; case NVME_LOG_LID_REACHABILITY_ASSOCIATIONS: return "Reachability Associations"; - case NVME_LOG_LID_CHANGED_ALLOC_NS_LIST: return "Changed Allocated Namespace List"; + case NVME_LOG_LID_CHANGED_ALLOC_NS: return "Changed Allocated Namespace List"; case NVME_LOG_LID_FDP_CONFIGS: return "FDP Configurations"; case NVME_LOG_LID_FDP_RUH_USAGE: return "Reclaim Unit Handle Usage"; case NVME_LOG_LID_FDP_STATS: return "FDP Statistics"; case NVME_LOG_LID_FDP_EVENTS: return "FDP Events"; - case NVME_LOG_LID_DISCOVER: return "Discovery"; - case NVME_LOG_LID_HOST_DISCOVER: return "Host Discovery"; - case NVME_LOG_LID_AVE_DISCOVER: return "AVE Discovery"; + case NVME_LOG_LID_DISCOVERY: return "Discovery"; + case NVME_LOG_LID_HOST_DISCOVERY: return "Host Discovery"; + case NVME_LOG_LID_AVE_DISCOVERY: return "AVE Discovery"; case NVME_LOG_LID_PULL_MODEL_DDC_REQ: return "Pull Model DDC Request"; case NVME_LOG_LID_RESERVATION: return "Reservation Notification"; case NVME_LOG_LID_SANITIZE: return "Sanitize Status"; @@ -1540,19 +1541,19 @@ void nvme_show_list_item(nvme_ns_t n) nvme_print(list_item, NORMAL, n); } -void nvme_show_list_items(nvme_root_t r, nvme_print_flags_t flags) +void nvme_show_list_items(struct nvme_global_ctx *ctx, nvme_print_flags_t flags) { - nvme_print(list_items, flags, r); + nvme_print(list_items, flags, ctx); } -void nvme_show_topology(nvme_root_t r, +void nvme_show_topology(struct nvme_global_ctx *ctx, enum nvme_cli_topo_ranking ranking, nvme_print_flags_t flags) { if (ranking == NVME_CLI_TOPO_NAMESPACE) - nvme_print(topology_namespace, flags, r); + nvme_print(topology_namespace, flags, ctx); else - nvme_print(topology_ctrl, flags, r); + nvme_print(topology_ctrl, flags, ctx); } void nvme_show_message(bool error, const char *msg, ...) diff --git a/nvme-print.h b/nvme-print.h index 4ccf5e6351..f175cc8fc5 100644 --- a/nvme-print.h +++ b/nvme-print.h @@ -3,6 +3,7 @@ #define NVME_PRINT_H #include "nvme.h" +#include "types.h" #include #include @@ -64,7 +65,7 @@ struct print_ops { void (*predictable_latency_event_agg_log)(struct nvme_aggregate_predictable_lat_event *pea_log, __u64 log_entries, __u32 size, const char *devname); void (*predictable_latency_per_nvmset)(struct nvme_nvmset_predictable_lat_log *plpns_log, __u16 nvmset_id, const char *devname); void (*primary_ctrl_cap)(const struct nvme_primary_ctrl_cap *caps); - void (*relatives)(nvme_root_t r, const char *name); + void (*relatives)(struct nvme_global_ctx *ctx, const char *name); void (*resv_notification_log)(struct nvme_resv_notification_log *resv, const char *devname); void (*resv_report)(struct nvme_resv_status *status, int bytes, bool eds); void (*sanitize_log_page)(struct nvme_sanitize_log_page *sanitize_log, const char *devname); @@ -102,10 +103,10 @@ struct print_ops { /* libnvme tree print functions */ void (*list_item)(nvme_ns_t n); - void (*list_items)(nvme_root_t t); - void (*print_nvme_subsystem_list)(nvme_root_t r, bool show_ana); - void (*topology_ctrl)(nvme_root_t r); - void (*topology_namespace)(nvme_root_t r); + void (*list_items)(struct nvme_global_ctx *ctx); + void (*print_nvme_subsystem_list)(struct nvme_global_ctx *ctx, bool show_ana); + void (*topology_ctrl)(struct nvme_global_ctx *ctx); + void (*topology_namespace)(struct nvme_global_ctx *ctx); /* status and error messages */ void (*connect_msg)(nvme_ctrl_t c); @@ -155,7 +156,7 @@ struct print_ops *nvme_get_binary_print_ops(nvme_print_flags_t flags); void nvme_show_status(int status); void nvme_show_lba_status_info(__u32 result); -void nvme_show_relatives(nvme_root_t r, const char *name, nvme_print_flags_t flags); +void nvme_show_relatives(struct nvme_global_ctx *ctx, const char *name, nvme_print_flags_t flags); void nvme_show_id_iocs(struct nvme_id_iocs *iocs, nvme_print_flags_t flags); void nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, nvme_print_flags_t flags, @@ -226,8 +227,8 @@ void nvme_show_single_property(int offset, uint64_t prop, nvme_print_flags_t fla void nvme_show_id_ns_descs(void *data, unsigned int nsid, nvme_print_flags_t flags); void nvme_show_lba_status(struct nvme_lba_status *list, unsigned long len, nvme_print_flags_t flags); -void nvme_show_list_items(nvme_root_t t, nvme_print_flags_t flags); -void nvme_show_subsystem_list(nvme_root_t t, bool show_ana, +void nvme_show_list_items(struct nvme_global_ctx *ctx, nvme_print_flags_t flags); +void nvme_show_subsystem_list(struct nvme_global_ctx *ctx, bool show_ana, nvme_print_flags_t flags); void nvme_show_id_nvmset(struct nvme_id_nvmset_list *nvmset, unsigned nvmset_id, nvme_print_flags_t flags); @@ -247,7 +248,7 @@ void nvme_show_endurance_group_list(struct nvme_id_endurance_group_list *endgrp_ nvme_print_flags_t flags); void nvme_show_list_ns(struct nvme_ns_list *ns_list, nvme_print_flags_t flags); -void nvme_show_topology(nvme_root_t t, +void nvme_show_topology(struct nvme_global_ctx *ctx, enum nvme_cli_topo_ranking ranking, nvme_print_flags_t flags); diff --git a/nvme-rpmb.c b/nvme-rpmb.c index ece313c29a..040781725c 100644 --- a/nvme-rpmb.c +++ b/nvme-rpmb.c @@ -132,8 +132,8 @@ unsigned char *create_hash(const char *algo, /* Function that computes hmac-sha256 hash of given data and key pair. Returns * byte stream (non-null terminated) upon success, NULL otherwise. */ -unsigned char * -hmac_sha256(unsigned char *data, int datalen, unsigned char *key, int keylen) +unsigned char *hmac_sha256(unsigned char *data, int datalen, unsigned char *key, + int keylen) { return create_hash(HMAC_SHA256_ALGO_NAME, HMAC_SHA256_HASH_SIZE, @@ -146,8 +146,7 @@ hmac_sha256(unsigned char *data, int datalen, unsigned char *key, int keylen) /* Function that computes md5 of given buffer - md5 hash is used as nonce * Returns byte stream (non-null terminated) upon success, NULL otherwise. */ -unsigned char * -rpmb_md5(unsigned char *data, int datalen) +unsigned char *rpmb_md5(unsigned char *data, int datalen) { return create_hash(MD5_HASH_ALGO_NAME, MD5_HASH_HASH_SIZE, @@ -204,7 +203,7 @@ static int read_file(const char *file, unsigned char **data, unsigned int *len) /* Write given buffer data to specified file */ static void write_file(unsigned char *data, size_t len, const char *dir, - const char *file, const char *msg) + const char *file, const char *msg) { char temp_folder[PATH_MAX] = { 0 }; _cleanup_file_ FILE *fp = NULL; @@ -272,47 +271,24 @@ struct rpmb_config_block_t { #define RPMB_NVME_SECP 0xEA #define RPMB_NVME_SPSP 0x0001 -static int send_rpmb_req(int fd, unsigned char tgt, int size, - struct rpmb_data_frame_t *req) +static int send_rpmb_req(struct nvme_transport_handle *hdl, unsigned char tgt, + int size, struct rpmb_data_frame_t *req) { - struct nvme_security_send_args args = { - .args_size = sizeof(args), - .fd = fd, - .nsid = 0, - .nssf = tgt, - .spsp0 = RPMB_NVME_SPSP, - .spsp1 = 0, - .secp = RPMB_NVME_SECP, - .tl = 0, - .data_len = size, - .data = (void *)req, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; + struct nvme_passthru_cmd cmd; - return nvme_security_send(&args); + nvme_init_security_send(&cmd, NVME_NSID_NONE, tgt, RPMB_NVME_SPSP, + RPMB_NVME_SECP, 0, req, size); + return nvme_submit_admin_passthru(hdl, &cmd, NULL); } -static int recv_rpmb_rsp(int fd, int tgt, int size, +static int recv_rpmb_rsp(struct nvme_transport_handle *hdl, int tgt, int size, struct rpmb_data_frame_t *rsp) { + struct nvme_passthru_cmd cmd; - struct nvme_security_receive_args args = { - .args_size = sizeof(args), - .fd = fd, - .nsid = 0, - .nssf = tgt, - .spsp0 = RPMB_NVME_SPSP, - .spsp1 = 0, - .secp = RPMB_NVME_SECP, - .al = 0, - .data_len = size, - .data = (void *)rsp, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - return nvme_security_receive(&args); + nvme_init_security_receive(&cmd, 0, tgt, RPMB_NVME_SPSP, + RPMB_NVME_SECP, 0, rsp, size); + return nvme_submit_admin_passthru(hdl, &cmd, NULL); } /* Initialize nonce value in rpmb request frame */ @@ -375,9 +351,8 @@ rpmb_request_init(unsigned int req_size, } /* Process rpmb response and print appropriate error message */ -static int check_rpmb_response( struct rpmb_data_frame_t *req, - struct rpmb_data_frame_t *rsp, - char *msg) +static int check_rpmb_response(struct rpmb_data_frame_t *req, + struct rpmb_data_frame_t *rsp, char *msg) { const char *rpmb_result_string [] = { "Operation successful", @@ -419,10 +394,10 @@ static int check_rpmb_response( struct rpmb_data_frame_t *req, * successful completion (caller must free), NULL otherwise */ static struct rpmb_data_frame_t * -rpmb_read_request(int fd, +rpmb_read_request(struct nvme_transport_handle *hdl, struct rpmb_data_frame_t *req, - int req_size, - int rsp_size) + int req_size, + int rsp_size) { struct rpmb_data_frame_t *rsp = NULL; unsigned char msg[1024] = { 0 }; @@ -431,7 +406,7 @@ rpmb_read_request(int fd, sprintf((char *)msg, "RPMB request 0x%04x to target 0x%x", req->type, req->target); - error = send_rpmb_req(fd, req->target, req_size, req); + error = send_rpmb_req(hdl, req->target, req_size, req); if (error != 0) { fprintf(stderr, "%s failed with error = 0x%x\n", msg, error); @@ -446,7 +421,7 @@ rpmb_read_request(int fd, } /* Read result of previous request */ - error = recv_rpmb_rsp(fd, req->target, rsp_size, rsp); + error = recv_rpmb_rsp(hdl, req->target, rsp_size, rsp); if (error) { fprintf(stderr, "error 0x%x receiving response for %s\n", error, msg); @@ -463,7 +438,7 @@ rpmb_read_request(int fd, } /* read current write counter value from controller */ -static int rpmb_read_write_counter(int fd, +static int rpmb_read_write_counter(struct nvme_transport_handle *hdl, unsigned char target, unsigned int *counter) { @@ -475,7 +450,7 @@ static int rpmb_read_write_counter(int fd, req = rpmb_request_init(req_size, RPMB_REQ_READ_WRITE_CNTR, target, 1, 0, 0, NULL, 0, 0); if (req == NULL) goto out; - if ((rsp = rpmb_read_request(fd, req, req_size, req_size)) == NULL) { + if ((rsp = rpmb_read_request(hdl, req, req_size, req_size)) == NULL) { goto out; } *counter = rsp->write_counter; @@ -491,7 +466,8 @@ static int rpmb_read_write_counter(int fd, * current write counter value returned as part of response, in case of error it * returns 0 */ -static unsigned int rpmb_read_config_block(int fd, unsigned char **config_buf) +static unsigned int rpmb_read_config_block(struct nvme_transport_handle *hdl, + unsigned char **config_buf) { int req_size = sizeof(struct rpmb_data_frame_t); int cfg_size = sizeof(struct rpmb_config_block_t); @@ -507,7 +483,7 @@ static unsigned int rpmb_read_config_block(int fd, unsigned char **config_buf) 0, 0, 0); if (!req) return 0; - if ((rsp = rpmb_read_request(fd, req, req_size, rsp_size)) == NULL) + if ((rsp = rpmb_read_request(hdl, req, req_size, rsp_size)) == NULL) { free(req); return 0; @@ -531,7 +507,8 @@ static unsigned int rpmb_read_config_block(int fd, unsigned char **config_buf) } -static int rpmb_auth_data_read(int fd, unsigned char target, +static int rpmb_auth_data_read(struct nvme_transport_handle *hdl, + unsigned char target, unsigned int offset, unsigned char **msg_buf, int msg_size, int acc_size) @@ -557,7 +534,7 @@ static int rpmb_auth_data_read(int fd, unsigned char target, target, 1, offset, xfer, 0, 0, 0); if (req == NULL) break; - if ((rsp = rpmb_read_request(fd, req, req_size, rsp_size)) == NULL) + if ((rsp = rpmb_read_request(hdl, req, req_size, rsp_size)) == NULL) { fprintf(stderr, "read_request failed\n"); free(req); @@ -583,8 +560,9 @@ static int rpmb_auth_data_read(int fd, unsigned char target, } /* Implementation of programming authentication key to given RPMB target */ -static int rpmb_program_auth_key(int fd, unsigned char target, - unsigned char *key_buf, int key_size) +static int rpmb_program_auth_key(struct nvme_transport_handle *hdl, + unsigned char target, unsigned char *key_buf, + int key_size) { int req_size = sizeof(struct rpmb_data_frame_t); int rsp_size = sizeof(struct rpmb_data_frame_t); @@ -602,7 +580,7 @@ static int rpmb_program_auth_key(int fd, unsigned char target, } /* send the request and get response */ - err = send_rpmb_req(fd, req->target, req_size, req); + err = send_rpmb_req(hdl, req->target, req_size, req); if (err) { fprintf(stderr, "RPMB request 0x%04x for 0x%x, err: %d\n", req->type, req->target, err); @@ -619,7 +597,7 @@ static int rpmb_program_auth_key(int fd, unsigned char target, rsp->target = req->target; rsp->type = RPMB_REQ_READ_RESULT; - err = send_rpmb_req(fd, req->target, rsp_size, rsp); + err = send_rpmb_req(hdl, req->target, rsp_size, rsp); if (err || rsp->result) { fprintf(stderr, "Program auth key read result 0x%x, error = 0x%x\n", rsp->result, err); @@ -628,7 +606,7 @@ static int rpmb_program_auth_key(int fd, unsigned char target, /* reuse response buffer */ memset(rsp, 0, rsp_size); - err = recv_rpmb_rsp(fd, req->target, rsp_size, rsp); + err = recv_rpmb_rsp(hdl, req->target, rsp_size, rsp); if (err != 0) fprintf(stderr, "Program Key recv error = 0x%x\n", err); else @@ -646,7 +624,8 @@ static int rpmb_program_auth_key(int fd, unsigned char target, * number of bytes actually written to, otherwise negetive error code * on failures. */ -static int auth_data_write_chunk(int fd, unsigned char tgt, unsigned int addr, +static int auth_data_write_chunk(struct nvme_transport_handle *hdl, + unsigned char tgt, unsigned int addr, unsigned char *msg_buf, int msg_size, unsigned char *keybuf, int keysize) { @@ -661,7 +640,7 @@ static int auth_data_write_chunk(int fd, unsigned char tgt, unsigned int addr, int error = -ENOMEM; /* get current write counter and copy to the request */ - error = rpmb_read_write_counter(fd, tgt, &write_cntr); + error = rpmb_read_write_counter(hdl, tgt, &write_cntr); if (error != 0) { fprintf(stderr, "Failed to read write counter for write-data\n"); goto out; @@ -689,7 +668,7 @@ static int auth_data_write_chunk(int fd, unsigned char tgt, unsigned int addr, memcpy(req->mac, mac, 32); /* send the request and get response */ - error = send_rpmb_req(fd, tgt, req_size, req); + error = send_rpmb_req(hdl, tgt, req_size, req); if (error != 0) { fprintf(stderr, "RPMB request 0x%04x for 0x%x, error: %d\n", req->type, tgt, error); @@ -700,7 +679,7 @@ static int auth_data_write_chunk(int fd, unsigned char tgt, unsigned int addr, rsp = (struct rpmb_data_frame_t *)calloc(rsp_size, 1); rsp->target = req->target; rsp->type = RPMB_REQ_READ_RESULT; - error = send_rpmb_req(fd, tgt, rsp_size, rsp); + error = send_rpmb_req(hdl, tgt, rsp_size, rsp); if (error != 0 || rsp->result != 0) { fprintf(stderr, "Write-data read result 0x%x, error = 0x%x\n", rsp->result, error); @@ -709,7 +688,7 @@ static int auth_data_write_chunk(int fd, unsigned char tgt, unsigned int addr, /* Read final response */ memset(rsp, 0, rsp_size); - error = recv_rpmb_rsp(fd, tgt, rsp_size, rsp); + error = recv_rpmb_rsp(hdl, tgt, rsp_size, rsp); if (error != 0) fprintf(stderr, "Auth data write recv error = 0x%x\n", error); else @@ -723,17 +702,18 @@ static int auth_data_write_chunk(int fd, unsigned char tgt, unsigned int addr, } /* send the request and get response */ -static int rpmb_auth_data_write(int fd, unsigned char target, - unsigned int addr, int acc_size, - unsigned char *msg_buf, int msg_size, - unsigned char *keybuf, int keysize) +static int rpmb_auth_data_write(struct nvme_transport_handle *hdl, + unsigned char target, unsigned int addr, + int acc_size, unsigned char *msg_buf, + int msg_size, unsigned char *keybuf, + int keysize) { int chunk_size = acc_size < msg_size ? acc_size : msg_size; int xfer = chunk_size; int offset = 0; while (xfer > 0 ) { - if (auth_data_write_chunk(fd, target, (addr + offset / 512), + if (auth_data_write_chunk(hdl, target, (addr + offset / 512), msg_buf + offset, xfer, keybuf, keysize) != 0) { @@ -752,7 +732,8 @@ static int rpmb_auth_data_write(int fd, unsigned char target, } /* writes given config_block buffer to the drive target 0 */ -static int rpmb_write_config_block(int fd, unsigned char *cfg_buf, +static int rpmb_write_config_block(struct nvme_transport_handle *hdl, + unsigned char *cfg_buf, unsigned char *keybuf, int keysize) { int cfg_size = sizeof(struct rpmb_config_block_t); @@ -775,7 +756,7 @@ static int rpmb_write_config_block(int fd, unsigned char *cfg_buf, } /* read config block write_counter from controller */ - write_cntr = rpmb_read_config_block(fd, &cfg_buf_read); + write_cntr = rpmb_read_config_block(hdl, &cfg_buf_read); if (cfg_buf_read == NULL) { fprintf(stderr, "failed to read config block write counter\n"); error = -EIO; @@ -794,7 +775,7 @@ static int rpmb_write_config_block(int fd, unsigned char *cfg_buf, memcpy(req->mac, mac, sizeof(req->mac)); - error = send_rpmb_req(fd, 0, req_size, req); + error = send_rpmb_req(hdl, 0, req_size, req); if (error != 0) { fprintf(stderr, "Write-config RPMB request, error = 0x%x\n", error); @@ -814,7 +795,7 @@ static int rpmb_write_config_block(int fd, unsigned char *cfg_buf, rsp->target = req->target; rsp->type = RPMB_REQ_READ_RESULT; /* get the response and validate */ - error = recv_rpmb_rsp(fd, req->target, rsp_size, rsp); + error = recv_rpmb_rsp(hdl, req->target, rsp_size, rsp); if (error != 0) { fprintf(stderr,"Failed getting write-config response\ error = 0x%x\n", error); @@ -837,7 +818,7 @@ static bool invalid_xfer_size(int blocks, unsigned int bpsz) } /* Handling rpmb sub-command */ -int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *plugin) +int rpmb_cmd_option(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Run RPMB command on the supporting controller"; const char *msg = "data to be written on write-data or write-config commands"; @@ -886,13 +867,14 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p OPT_END() }; + _cleanup_free_ unsigned char *key_buf = NULL; + _cleanup_free_ unsigned char *msg_buf = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; unsigned int write_cntr = 0; - unsigned char *key_buf = NULL; - unsigned char *msg_buf = NULL; unsigned int msg_size = 0; unsigned int key_size = 0; struct nvme_id_ctrl ctrl; - struct nvme_dev *dev; int err = -1; union ctrl_rpmbs_reg { @@ -905,25 +887,25 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p }; unsigned int rpmbs; } regs; - - if ((err = parse_and_open(&dev, argc, argv, desc, opts))) + + if ((err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts))) return err; /* before parsing commands, check if controller supports any RPMB targets */ - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) - goto out; + return err; regs.rpmbs = le32_to_cpu(ctrl.rpmbs); if (regs.num_targets == 0) { fprintf(stderr, "No RPMB targets are supported by the drive\n"); - goto out; + return -1; } /* parse and validate options; default print rpmb support info */ if (cfg.cmd == 0 || strcmp(cfg.cmd, "info") == 0) { nvme_show_id_ctrl_rpmbs(regs.rpmbs, 0); - goto out; + return -1; } if (strcmp(cfg.cmd, "program-key") == 0) @@ -940,7 +922,7 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p cfg.opt = RPMB_REQ_AUTH_DCB_READ; else { fprintf(stderr, "Invalid option %s for rpmb command\n", cfg.cmd); - goto out; + return -1; } /* input file/data processing */ @@ -951,13 +933,13 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p key_buf = read_rpmb_key(cfg.key, cfg.keyfile, &key_size); if (key_buf == NULL) { fprintf(stderr, "Failed to read key\n"); - goto out; + return -1; } if (key_size > 223 || key_size <= 0) { fprintf(stderr, "Invalid key size %d, valid input 1 to 223\n", key_size); - goto out; + return -1; } if (cfg.opt == RPMB_REQ_AUTH_DCB_WRITE || @@ -971,7 +953,7 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p if (err || msg_size <= 0) { fprintf(stderr, "Failed to read file %s\n", cfg.msgfile); - goto out; + return -1; } } } @@ -979,18 +961,16 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p switch (cfg.opt) { case RPMB_REQ_READ_WRITE_CNTR: - err = rpmb_read_write_counter(dev_fd(dev), cfg.target, - &write_cntr); + err = rpmb_read_write_counter(hdl, cfg.target, &write_cntr); if (err == 0) printf("Write Counter is: %u\n", write_cntr); break; case RPMB_REQ_AUTH_DCB_READ: - write_cntr = rpmb_read_config_block(dev_fd(dev), - &msg_buf); + write_cntr = rpmb_read_config_block(hdl, &msg_buf); if (msg_buf == NULL) { fprintf(stderr, "failed read config blk\n"); - goto out; + return -1; } /* no output file is given, print the data on stdout */ @@ -1019,7 +999,7 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p msg_size); break; } - err = rpmb_auth_data_read(dev_fd(dev), cfg.target, + err = rpmb_auth_data_read(hdl, cfg.target, cfg.address, &msg_buf, cfg.blocks, (regs.access_size + 1)); @@ -1040,7 +1020,7 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p } else if ((cfg.blocks * 512) < msg_size) { msg_size = cfg.blocks * 512; } - err = rpmb_auth_data_write(dev_fd(dev), cfg.target, + err = rpmb_auth_data_write(hdl, cfg.target, cfg.address, ((regs.access_size + 1) * 512), msg_buf, msg_size, @@ -1052,25 +1032,17 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p break; case RPMB_REQ_AUTH_DCB_WRITE: - err = rpmb_write_config_block(dev_fd(dev), msg_buf, + err = rpmb_write_config_block(hdl, msg_buf, key_buf, key_size); break; case RPMB_REQ_AUTH_KEY_PROGRAM: - err = rpmb_program_auth_key(dev_fd(dev), cfg.target, + err = rpmb_program_auth_key(hdl, cfg.target, key_buf, key_size); break; default: break; } - -out: - /* release memory */ - free(key_buf); - free(msg_buf); - - /* close device */ - dev_close(dev); - + return err; } diff --git a/nvme-wrap.c b/nvme-wrap.c deleted file mode 100644 index 99467a1607..0000000000 --- a/nvme-wrap.c +++ /dev/null @@ -1,515 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Definitions for the NVM Express interface: libnvme/libnvme-mi device - * wrappers. - */ - -#include - -#include -#include - -#include "nvme.h" -#include "nvme-wrap.h" - -/* - * Helper for libnvme functions that pass the fd/ep separately. These just - * pass the correct handle to the direct/MI function. - * @op: the name of the libnvme function, without the nvme_/nvme_mi prefix - * @d: device handle: struct nvme_dev - */ -#define do_admin_op(op, d, ...) ({ \ - int __rc; \ - if (d->type == NVME_DEV_DIRECT) \ - __rc = nvme_ ## op(d->direct.fd, __VA_ARGS__); \ - else if (d->type == NVME_DEV_MI) \ - __rc = nvme_mi_admin_ ## op (d->mi.ctrl, __VA_ARGS__); \ - else \ - __rc = -ENODEV; \ - __rc; }) - -/* - * Helper for libnvme functions use the 'struct _args' pattern. These need - * the fd and timeout set for the direct interface, and pass the ep as - * an argument for the MI interface - * @op: the name of the libnvme function, without the nvme_/nvme_mi prefix - * @d: device handle: struct nvme_dev - * @args: op-specific args struct - */ -#define do_admin_args_op(op, d, args) ({ \ - int __rc; \ - if (d->type == NVME_DEV_DIRECT) { \ - args->fd = d->direct.fd; \ - __rc = nvme_ ## op(args); \ - } else if (d->type == NVME_DEV_MI) \ - __rc = nvme_mi_admin_ ## op (d->mi.ctrl, args); \ - else \ - __rc = -ENODEV; \ - __rc; }) - -int nvme_cli_identify(struct nvme_dev *dev, struct nvme_identify_args *args) -{ - return do_admin_args_op(identify, dev, args); -} - -int nvme_cli_identify_ctrl(struct nvme_dev *dev, struct nvme_id_ctrl *ctrl) -{ - return do_admin_op(identify_ctrl, dev, ctrl); -} - -int nvme_cli_identify_ctrl_list(struct nvme_dev *dev, __u16 ctrl_id, - struct nvme_ctrl_list *list) -{ - return do_admin_op(identify_ctrl_list, dev, ctrl_id, list); -} - -int nvme_cli_identify_nsid_ctrl_list(struct nvme_dev *dev, __u32 nsid, - __u16 ctrl_id, - struct nvme_ctrl_list *list) -{ - return do_admin_op(identify_nsid_ctrl_list, dev, nsid, ctrl_id, list); -} - -int nvme_cli_identify_ns(struct nvme_dev *dev, __u32 nsid, - struct nvme_id_ns *ns) -{ - return do_admin_op(identify_ns, dev, nsid, ns); -} - -int nvme_cli_identify_ns_descs(struct nvme_dev *dev, __u32 nsid, - struct nvme_ns_id_desc *descs) -{ - return do_admin_op(identify_ns_descs, dev, nsid, descs); -} - -int nvme_cli_identify_allocated_ns(struct nvme_dev *dev, __u32 nsid, - struct nvme_id_ns *ns) -{ - return do_admin_op(identify_allocated_ns, dev, nsid, ns); -} - -int nvme_cli_identify_active_ns_list(struct nvme_dev *dev, __u32 nsid, - struct nvme_ns_list *list) -{ - return do_admin_op(identify_active_ns_list, dev, nsid, list); -} - -int nvme_cli_identify_allocated_ns_list(struct nvme_dev *dev, __u32 nsid, - struct nvme_ns_list *list) -{ - return do_admin_op(identify_allocated_ns_list, dev, nsid, list); -} - -int nvme_cli_identify_primary_ctrl(struct nvme_dev *dev, __u16 cntid, - struct nvme_primary_ctrl_cap *cap) -{ - return do_admin_op(identify_primary_ctrl, dev, cntid, cap); -} - -int nvme_cli_identify_secondary_ctrl_list(struct nvme_dev *dev, __u16 cntid, - struct nvme_secondary_ctrl_list *sc_list) -{ - return do_admin_op(identify_secondary_ctrl_list, dev, cntid, - sc_list); -} - -int nvme_cli_get_features(struct nvme_dev *dev, - struct nvme_get_features_args *args) -{ - return do_admin_args_op(get_features, dev, args); -} - -int nvme_cli_get_features_arbitration(struct nvme_dev *dev, enum nvme_get_features_sel sel, - __u32 *result) -{ - return do_admin_op(get_features_arbitration, dev, sel, result); -} - -int nvme_cli_get_features_power_mgmt(struct nvme_dev *dev, enum nvme_get_features_sel sel, - __u32 *result) -{ - return do_admin_op(get_features_power_mgmt, dev, sel, result); -} - -int nvme_cli_set_features(struct nvme_dev *dev, struct nvme_set_features_args *args) -{ - return do_admin_args_op(set_features, dev, args); -} - -int nvme_cli_set_features_arbitration(struct nvme_dev *dev, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, - bool save, __u32 *result) -{ - if (dev->type == NVME_DEV_DIRECT) - return nvme_set_features_arbitration(dev_fd(dev), ab, lpw, mpw, hpw, save, result); - - return -ENODEV; -} - -int nvme_cli_features_power_mgmt(struct nvme_dev *dev, __u8 ps, __u8 wh, bool save, __u32 *result) -{ - return do_admin_op(set_features_power_mgmt, dev, ps, wh, save, result); -} - -int nvme_cli_ns_mgmt_delete(struct nvme_dev *dev, __u32 nsid, __u32 timeout) -{ - if (dev->type == NVME_DEV_DIRECT) - return nvme_ns_mgmt_delete_timeout(dev_fd(dev), nsid, timeout); - - return do_admin_op(ns_mgmt_delete, dev, nsid); -} - -int nvme_cli_ns_attach(struct nvme_dev *dev, struct nvme_ns_attach_args *args) -{ - return do_admin_args_op(ns_attach, dev, args); -} - -int nvme_cli_ns_attach_ctrls(struct nvme_dev *dev, __u32 nsid, - struct nvme_ctrl_list *ctrlist) -{ - return do_admin_op(ns_attach_ctrls, dev, nsid, ctrlist); -} - -int nvme_cli_ns_detach_ctrls(struct nvme_dev *dev, __u32 nsid, - struct nvme_ctrl_list *ctrlist) -{ - return do_admin_op(ns_detach_ctrls, dev, nsid, ctrlist); -} - -int nvme_cli_format_nvm(struct nvme_dev *dev, struct nvme_format_nvm_args *args) -{ - return do_admin_args_op(format_nvm, dev, args); -} - -int nvme_cli_sanitize_nvm(struct nvme_dev *dev, struct nvme_sanitize_nvm_args *args) -{ - return do_admin_args_op(sanitize_nvm, dev, args); -} - -int nvme_cli_get_log(struct nvme_dev *dev, struct nvme_get_log_args *args) -{ - return do_admin_args_op(get_log, dev, args); -} - -int nvme_cli_get_log_page(struct nvme_dev *dev, __u32 xfer_len, - struct nvme_get_log_args *args) -{ - return do_admin_op(get_log_page, dev, xfer_len, args); -} - -int nvme_cli_get_nsid_log(struct nvme_dev *dev, bool rae, - enum nvme_cmd_get_log_lid lid, - __u32 nsid, __u32 len, void *log) -{ - return do_admin_op(get_nsid_log, dev, rae, lid, nsid, len, log); -} - -int nvme_cli_get_log_simple(struct nvme_dev *dev, - enum nvme_cmd_get_log_lid lid, - __u32 len, void *log) -{ - return do_admin_op(get_log_simple, dev, lid, len, log); -} - -int nvme_cli_get_log_supported_log_pages(struct nvme_dev *dev, bool rae, - struct nvme_supported_log_pages *log) -{ - return do_admin_op(get_log_supported_log_pages, dev, rae, log); -} - -int nvme_cli_get_log_error(struct nvme_dev *dev, unsigned int nr_entries, - bool rae, struct nvme_error_log_page *err_log) -{ - return do_admin_op(get_log_error, dev, nr_entries, rae, err_log); -} - -int nvme_cli_get_log_smart(struct nvme_dev *dev, __u32 nsid, bool rae, - struct nvme_smart_log *smart_log) -{ - return do_admin_op(get_log_smart, dev, nsid, rae, smart_log); -} - -int nvme_cli_get_log_fw_slot(struct nvme_dev *dev, bool rae, - struct nvme_firmware_slot *fw_log) -{ - return do_admin_op(get_log_fw_slot, dev, rae, fw_log); -} - -int nvme_cli_get_log_changed_ns_list(struct nvme_dev *dev, bool rae, - struct nvme_ns_list *ns_log) -{ - return do_admin_op(get_log_changed_ns_list, dev, rae, ns_log); -} - -int nvme_cli_get_log_changed_alloc_ns_list(struct nvme_dev *dev, bool rae, __u32 len, - struct nvme_ns_list *ns_log) -{ - return do_admin_op(get_log_changed_alloc_ns_list, dev, rae, len, ns_log); -} - -int nvme_cli_get_log_cmd_effects(struct nvme_dev *dev, enum nvme_csi csi, - struct nvme_cmd_effects_log *effects_log) -{ - return do_admin_op(get_log_cmd_effects, dev, csi, effects_log); -} - -int nvme_cli_get_log_device_self_test(struct nvme_dev *dev, - struct nvme_self_test_log *log) -{ - return do_admin_op(get_log_device_self_test, dev, log); -} - -int nvme_cli_get_log_create_telemetry_host_mcda(struct nvme_dev *dev, - enum nvme_telemetry_da mcda, - struct nvme_telemetry_log *log) -{ - return do_admin_op(get_log_create_telemetry_host_mcda, dev, mcda, log); -} - -int nvme_cli_get_log_telemetry_host(struct nvme_dev *dev, __u64 offset, - __u32 len, void *log) -{ - return do_admin_op(get_log_telemetry_host, dev, offset, len, log); -} - -int nvme_cli_get_log_telemetry_ctrl(struct nvme_dev *dev, bool rae, - __u64 offset, __u32 len, void *log) -{ - return do_admin_op(get_log_telemetry_ctrl, dev, rae, offset, len, log); -} - -int nvme_cli_get_log_endurance_group(struct nvme_dev *dev, __u16 endgid, - struct nvme_endurance_group_log *log) -{ - return do_admin_op(get_log_endurance_group, dev, endgid, log); -} - -int nvme_cli_get_log_predictable_lat_nvmset(struct nvme_dev *dev, - __u16 nvmsetid, - struct nvme_nvmset_predictable_lat_log *log) -{ - return do_admin_op(get_log_predictable_lat_nvmset, dev, nvmsetid, log); -} - -int nvme_cli_get_log_predictable_lat_event(struct nvme_dev *dev, bool rae, - __u32 offset, __u32 len, void *log) -{ - return do_admin_op(get_log_predictable_lat_event, dev, rae, offset, - len, log); -} - -int nvme_cli_get_ana_log_atomic(struct nvme_dev *dev, bool rgo, bool rae, - unsigned int retries, - struct nvme_ana_log *log, __u32 *len) -{ - return do_admin_op(get_ana_log_atomic, dev, rgo, rae, retries, log, len); -} - -int nvme_cli_get_log_lba_status(struct nvme_dev *dev, bool rae, - __u64 offset, __u32 len, void *log) -{ - return do_admin_op(get_log_lba_status, dev, rae, offset, len, log); -} - -int nvme_cli_get_log_endurance_grp_evt(struct nvme_dev *dev, bool rae, - __u32 offset, __u32 len, void *log) -{ - return do_admin_op(get_log_endurance_grp_evt, dev, rae, offset, len, - log); -} - -int nvme_cli_get_log_fid_supported_effects(struct nvme_dev *dev, bool rae, - struct nvme_fid_supported_effects_log *log) -{ - return do_admin_op(get_log_fid_supported_effects, dev, rae, log); -} - -int nvme_cli_get_log_mi_cmd_supported_effects(struct nvme_dev *dev, bool rae, - struct nvme_mi_cmd_supported_effects_log *log) -{ - return do_admin_op(get_log_mi_cmd_supported_effects, dev, rae, log); -} - -int nvme_cli_get_log_boot_partition(struct nvme_dev *dev, bool rae, __u8 lsp, - __u32 len, - struct nvme_boot_partition *part) -{ - return do_admin_op(get_log_boot_partition, dev, rae, lsp, len, part); -} - -int nvme_cli_get_log_phy_rx_eom(struct nvme_dev *dev, __u8 lsp, __u16 controller, - __u32 len, struct nvme_phy_rx_eom_log *part) -{ - return do_admin_op(get_log_phy_rx_eom, dev, lsp, controller, len, part); -} - -int nvme_cli_get_log_discovery(struct nvme_dev *dev, bool rae, - __u32 offset, __u32 len, void *log) -{ - return do_admin_op(get_log_discovery, dev, rae, offset, len, log); -} - -int nvme_cli_get_log_media_unit_stat(struct nvme_dev *dev, __u16 domid, - struct nvme_media_unit_stat_log *mus) -{ - return do_admin_op(get_log_media_unit_stat, dev, domid, mus); -} - -int nvme_cli_get_log_support_cap_config_list(struct nvme_dev *dev, - __u16 domid, - struct nvme_supported_cap_config_list_log *cap) -{ - return do_admin_op(get_log_support_cap_config_list, dev, domid, cap); -} - -int nvme_cli_get_log_reservation(struct nvme_dev *dev, bool rae, - struct nvme_resv_notification_log *log) -{ - return do_admin_op(get_log_reservation, dev, rae, log); -} - -int nvme_cli_get_log_sanitize(struct nvme_dev *dev, bool rae, - struct nvme_sanitize_log_page *log) -{ - return do_admin_op(get_log_sanitize, dev, rae, log); -} - -int nvme_cli_get_log_zns_changed_zones(struct nvme_dev *dev, __u32 nsid, - bool rae, - struct nvme_zns_changed_zone_log *log) -{ - return do_admin_op(get_log_zns_changed_zones, dev, nsid, rae, log); -} - -int nvme_cli_get_log_persistent_event(struct nvme_dev *dev, - enum nvme_pevent_log_action action, - __u32 size, void *pevent_log) -{ - return do_admin_op(get_log_persistent_event, dev, action, size, - pevent_log); -} - -int nvme_cli_fw_download(struct nvme_dev *dev, - struct nvme_fw_download_args *args) -{ - return do_admin_args_op(fw_download, dev, args); -} - -int nvme_cli_fw_commit(struct nvme_dev *dev, - struct nvme_fw_commit_args *args) -{ - return do_admin_args_op(fw_commit, dev, args); -} - -int nvme_cli_admin_passthru(struct nvme_dev *dev, __u8 opcode, __u8 flags, - __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, - __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, - __u32 cdw14, __u32 cdw15, __u32 data_len, - void *data, __u32 metadata_len, void *metadata, - __u32 timeout_ms, __u32 *result) -{ - return do_admin_op(admin_passthru, dev, opcode, flags, rsvd, nsid, - cdw2, cdw3, cdw10, cdw11, cdw12, cdw13, cdw14, cdw15, - data_len, data, metadata_len, metadata, timeout_ms, - result); -} - -/* The MI & direct interfaces don't have an exactly-matching API for - * ns_mgmt_create, as we don't support a timeout for MI. - */ -int nvme_cli_ns_mgmt_create(struct nvme_dev *dev, - struct nvme_ns_mgmt_host_sw_specified *data, - __u32 *nsid, __u32 timeout, __u8 csi) -{ - if (dev->type == NVME_DEV_DIRECT) - return nvme_ns_mgmt_create(dev_fd(dev), NULL, nsid, timeout, - csi, data); - if (dev->type == NVME_DEV_MI) - return nvme_mi_admin_ns_mgmt_create(dev->mi.ctrl, NULL, - csi, nsid, data); - - return -ENODEV; -} - -int nvme_cli_get_feature_length2(int fid, __u32 cdw11, enum nvme_data_tfr dir, - __u32 *len) -{ - int err; - - err = nvme_get_feature_length2(fid, cdw11, dir, len); - if (err != -EEXIST) - return err; - return nvme_get_feature_length(fid, cdw11, len); -} - -int nvme_cli_security_send(struct nvme_dev *dev, - struct nvme_security_send_args* args) -{ - return do_admin_args_op(security_send, dev, args); -} - -int nvme_cli_security_receive(struct nvme_dev *dev, - struct nvme_security_receive_args* args) -{ - /* Cannot use do_admin_args_op here because the API have different suffix*/ - if (dev->type == NVME_DEV_DIRECT) { - args->fd = dev->direct.fd; - args->timeout = NVME_DEFAULT_IOCTL_TIMEOUT; - return nvme_security_receive(args); - } - - if (dev->type == NVME_DEV_MI) - return nvme_mi_admin_security_recv(dev->mi.ctrl, args); - - return -ENODEV; -} - -int nvme_cli_get_log_mgmt_addr_list(struct nvme_dev *dev, __u32 len, - struct nvme_mgmt_addr_list_log *ma_list) -{ - return do_admin_op(get_log_mgmt_addr_list, dev, len, ma_list); -} - -int nvme_cli_get_log_rotational_media_info(struct nvme_dev *dev, __u16 endgid, __u32 len, - struct nvme_rotational_media_info_log *info) -{ - if (dev->type == NVME_DEV_DIRECT) - return nvme_get_log_rotational_media_info(dev->direct.fd, endgid, len, info); - - return -ENODEV; -} - -int nvme_cli_get_log_dispersed_ns_participating_nss(struct nvme_dev *dev, __u32 nsid, __u32 len, - struct nvme_dispersed_ns_participating_nss_log *log) -{ - return do_admin_op(get_log_dispersed_ns_participating_nss, dev, nsid, len, log); -} - -int nvme_cli_get_log_reachability_groups(struct nvme_dev *dev, bool rgo, bool rae, __u32 len, - struct nvme_reachability_groups_log *log) -{ - return do_admin_op(get_log_reachability_groups, dev, rgo, rae, len, log); -} - -int nvme_cli_get_log_reachability_associations(struct nvme_dev *dev, bool rao, bool rae, __u32 len, - struct nvme_reachability_associations_log *log) -{ - return do_admin_op(get_log_reachability_associations, dev, rao, rae, len, log); -} - -int nvme_cli_get_log_host_discovery(struct nvme_dev *dev, bool allhoste, bool rae, __u32 len, - struct nvme_host_discover_log *log) -{ - return do_admin_op(get_log_host_discover, dev, allhoste, rae, len, log); -} - -int nvme_cli_get_log_ave_discovery(struct nvme_dev *dev, bool rae, __u32 len, - struct nvme_ave_discover_log *log) -{ - return do_admin_op(get_log_ave_discover, dev, rae, len, log); -} - -int nvme_cli_get_log_pull_model_ddc_req(struct nvme_dev *dev, bool rae, __u32 len, - struct nvme_pull_model_ddc_req_log *log) -{ - return do_admin_op(get_log_pull_model_ddc_req, dev, rae, len, log); -} diff --git a/nvme-wrap.h b/nvme-wrap.h deleted file mode 100644 index 4f46c0afc7..0000000000 --- a/nvme-wrap.h +++ /dev/null @@ -1,180 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Definitions for the NVM Express interface: libnvme/libnvme-mi device - * wrappers. - */ - -#ifndef _NVME_WRAP_H -#define _NVME_WRAP_H - -#include "nvme.h" - -int nvme_cli_identify(struct nvme_dev *dev, struct nvme_identify_args *args); -int nvme_cli_identify_ctrl(struct nvme_dev *dev, struct nvme_id_ctrl *ctrl); -int nvme_cli_identify_ctrl_list(struct nvme_dev *dev, __u16 ctrl_id, - struct nvme_ctrl_list *list); -int nvme_cli_identify_nsid_ctrl_list(struct nvme_dev *dev, __u32 nsid, - __u16 ctrl_id, - struct nvme_ctrl_list *list); -int nvme_cli_identify_ns(struct nvme_dev *dev, __u32 nsid, - struct nvme_id_ns *ns); -int nvme_cli_identify_ns_descs(struct nvme_dev *dev, __u32 nsid, - struct nvme_ns_id_desc *descs); -int nvme_cli_identify_allocated_ns(struct nvme_dev *dev, __u32 nsid, - struct nvme_id_ns *ns); -int nvme_cli_identify_active_ns_list(struct nvme_dev *dev, __u32 nsid, - struct nvme_ns_list *list); -int nvme_cli_identify_allocated_ns_list(struct nvme_dev *dev, __u32 nsid, - struct nvme_ns_list *list); -int nvme_cli_identify_primary_ctrl(struct nvme_dev *dev, __u16 cntid, - struct nvme_primary_ctrl_cap *cap); -int nvme_cli_identify_secondary_ctrl_list(struct nvme_dev *dev, __u16 cntid, - struct nvme_secondary_ctrl_list *sc_list); -int nvme_cli_ns_mgmt_delete(struct nvme_dev *dev, __u32 nsid, __u32 timeout); -int nvme_cli_ns_mgmt_create(struct nvme_dev *dev, - struct nvme_ns_mgmt_host_sw_specified *data, - __u32 *nsid, __u32 timeout, __u8 csi); - -int nvme_cli_ns_attach(struct nvme_dev *dev, struct nvme_ns_attach_args *args); - -int nvme_cli_ns_attach_ctrls(struct nvme_dev *dev, __u32 nsid, - struct nvme_ctrl_list *ctrlist); -int nvme_cli_ns_detach_ctrls(struct nvme_dev *dev, __u32 nsid, - struct nvme_ctrl_list *ctrlist); - -int nvme_cli_format_nvm(struct nvme_dev *dev, struct nvme_format_nvm_args *args); -int nvme_cli_sanitize_nvm(struct nvme_dev *dev, - struct nvme_sanitize_nvm_args *args); - -int nvme_cli_get_features(struct nvme_dev *dev, - struct nvme_get_features_args *args); -int nvme_cli_get_features_arbitration(struct nvme_dev *dev, enum nvme_get_features_sel sel, - __u32 *result); -int nvme_cli_get_features_power_mgmt(struct nvme_dev *dev, enum nvme_get_features_sel sel, - __u32 *result); -int nvme_cli_set_features(struct nvme_dev *dev, struct nvme_set_features_args *args); -int nvme_cli_set_features_arbitration(struct nvme_dev *dev, __u8 ab, __u8 lpw, __u8 mpw, __u8 hpw, - bool save, __u32 *result); -int nvme_set_features_power_mgmt(int fd, __u8 ps, __u8 wh, bool save, __u32 *result); - -int nvme_cli_get_log(struct nvme_dev *dev, struct nvme_get_log_args *args); -int nvme_cli_get_log_page(struct nvme_dev *dev, - __u32 xfer_len, - struct nvme_get_log_args *args); - -int nvme_cli_get_nsid_log(struct nvme_dev *dev, bool rae, - enum nvme_cmd_get_log_lid lid, - __u32 nsid, __u32 len, void *log); -int nvme_cli_get_log_simple(struct nvme_dev *dev, - enum nvme_cmd_get_log_lid lid, - __u32 len, void *log); -int nvme_cli_get_log_supported_log_pages(struct nvme_dev *dev, bool rae, - struct nvme_supported_log_pages *log); -int nvme_cli_get_log_error(struct nvme_dev *dev, unsigned int nr_entries, - bool rae, struct nvme_error_log_page *err_log); -int nvme_cli_get_log_smart(struct nvme_dev *dev, __u32 nsid, bool rae, - struct nvme_smart_log *smart_log); -int nvme_cli_get_log_fw_slot(struct nvme_dev *dev, bool rae, - struct nvme_firmware_slot *fw_log); -int nvme_cli_get_log_changed_ns_list(struct nvme_dev *dev, bool rae, - struct nvme_ns_list *ns_log); -int nvme_cli_get_log_changed_alloc_ns_list(struct nvme_dev *dev, bool rae, __u32 len, - struct nvme_ns_list *ns_log); -int nvme_cli_get_log_cmd_effects(struct nvme_dev *dev, enum nvme_csi csi, - struct nvme_cmd_effects_log *effects_log); -int nvme_cli_get_log_device_self_test(struct nvme_dev *dev, - struct nvme_self_test_log *log); -int nvme_cli_get_log_create_telemetry_host_mcda(struct nvme_dev *dev, - enum nvme_telemetry_da mcda, - struct nvme_telemetry_log *log); -int nvme_cli_get_log_telemetry_host(struct nvme_dev *dev, __u64 offset, - __u32 len, void *log); -int nvme_cli_get_log_telemetry_ctrl(struct nvme_dev *dev, bool rae, - __u64 offset, __u32 len, void *log); -int nvme_cli_get_log_endurance_group(struct nvme_dev *dev, __u16 endgid, - struct nvme_endurance_group_log *log); -int nvme_cli_get_log_predictable_lat_nvmset(struct nvme_dev *dev, - __u16 nvmsetid, - struct nvme_nvmset_predictable_lat_log *log); -int nvme_cli_get_log_predictable_lat_event(struct nvme_dev *dev, bool rae, - __u32 offset, __u32 len, void *log); -int nvme_cli_get_ana_log_atomic(struct nvme_dev *dev, bool rgo, bool rae, - unsigned int retries, - struct nvme_ana_log *log, __u32 *len); -int nvme_cli_get_log_lba_status(struct nvme_dev *dev, bool rae, - __u64 offset, __u32 len, void *log); -int nvme_cli_get_log_endurance_grp_evt(struct nvme_dev *dev, bool rae, - __u32 offset, __u32 len, void *log); -int nvme_cli_get_log_fid_supported_effects(struct nvme_dev *dev, bool rae, - struct nvme_fid_supported_effects_log *log); -int nvme_cli_get_log_mi_cmd_supported_effects(struct nvme_dev *dev, bool rae, - struct nvme_mi_cmd_supported_effects_log *log); -int nvme_cli_get_log_boot_partition(struct nvme_dev *dev, bool rae, __u8 lsp, - __u32 len, - struct nvme_boot_partition *part); -int nvme_cli_get_log_phy_rx_eom(struct nvme_dev *dev, __u8 lsp, __u16 controller, - __u32 len, struct nvme_phy_rx_eom_log *part); -int nvme_cli_get_log_discovery(struct nvme_dev *dev, bool rae, - __u32 offset, __u32 len, void *log); -int nvme_cli_get_log_media_unit_stat(struct nvme_dev *dev, __u16 domid, - struct nvme_media_unit_stat_log *mus); -int nvme_cli_get_log_support_cap_config_list(struct nvme_dev *dev, - __u16 domid, - struct nvme_supported_cap_config_list_log *cap); -int nvme_cli_get_log_reservation(struct nvme_dev *dev, bool rae, - struct nvme_resv_notification_log *log); -int nvme_cli_get_log_sanitize(struct nvme_dev *dev, bool rae, - struct nvme_sanitize_log_page *log); -int nvme_cli_get_log_zns_changed_zones(struct nvme_dev *dev, __u32 nsid, - bool rae, - struct nvme_zns_changed_zone_log *log); -int nvme_cli_get_log_persistent_event(struct nvme_dev *dev, - enum nvme_pevent_log_action action, - __u32 size, void *pevent_log); - -int nvme_cli_fw_download(struct nvme_dev *dev, - struct nvme_fw_download_args *args); - -int nvme_cli_fw_commit(struct nvme_dev *dev, - struct nvme_fw_commit_args *args); - -int nvme_cli_admin_passthru(struct nvme_dev *dev, __u8 opcode, __u8 flags, - __u16 rsvd, __u32 nsid, __u32 cdw2, __u32 cdw3, - __u32 cdw10, __u32 cdw11, __u32 cdw12, __u32 cdw13, - __u32 cdw14, __u32 cdw15, __u32 data_len, - void *data, __u32 metadata_len, void *metadata, - __u32 timeout_ms, __u32 *result); - -int nvme_cli_get_feature_length2(int fid, __u32 cdw11, enum nvme_data_tfr dir, - __u32 *len); - -int nvme_cli_security_send(struct nvme_dev *dev, - struct nvme_security_send_args* args); - -int nvme_cli_security_receive(struct nvme_dev *dev, - struct nvme_security_receive_args* args); - -int nvme_cli_get_log_mgmt_addr_list(struct nvme_dev *dev, __u32 len, - struct nvme_mgmt_addr_list_log *ma_list); - -int nvme_cli_get_log_rotational_media_info(struct nvme_dev *dev, __u16 endgid, __u32 len, - struct nvme_rotational_media_info_log *info); - -int nvme_cli_get_log_dispersed_ns_participating_nss(struct nvme_dev *dev, __u32 nsid, __u32 len, - struct nvme_dispersed_ns_participating_nss_log *log); - -int nvme_cli_get_log_reachability_groups(struct nvme_dev *dev, bool rgo, bool rae, __u32 len, - struct nvme_reachability_groups_log *log); - -int nvme_cli_get_log_reachability_associations(struct nvme_dev *dev, bool rgo, bool rae, __u32 len, - struct nvme_reachability_associations_log *log); - -int nvme_cli_get_log_host_discovery(struct nvme_dev *dev, bool allhoste, bool rae, __u32 len, - struct nvme_host_discover_log *log); - -int nvme_cli_get_log_ave_discovery(struct nvme_dev *dev, bool rae, __u32 len, - struct nvme_ave_discover_log *log); - -int nvme_cli_get_log_pull_model_ddc_req(struct nvme_dev *dev, bool rae, __u32 len, - struct nvme_pull_model_ddc_req_log *log); -#endif /* _NVME_WRAP_H */ diff --git a/nvme.c b/nvme.c index 307036ba08..f5ad02df05 100644 --- a/nvme.c +++ b/nvme.c @@ -61,7 +61,6 @@ #include "plugin.h" #include "util/base64.h" #include "util/crc32.h" -#include "nvme-wrap.h" #include "util/argconfig.h" #include "util/suffix.h" #include "logging.h" @@ -263,7 +262,7 @@ struct nvme_config nvme_cfg = { .output_format_ver = 1, }; -static void *mmap_registers(struct nvme_dev *dev, bool writable); +static void *mmap_registers(struct nvme_transport_handle *hdl, bool writable); static OPT_VALS(feature_name) = { VAL_BYTE("arbitration", NVME_FEAT_FID_ARBITRATION), @@ -340,119 +339,6 @@ static ssize_t getrandom_bytes(void *buf, size_t buflen) #endif } -static bool is_chardev(struct nvme_dev *dev) -{ - return S_ISCHR(dev->direct.stat.st_mode); -} - -static bool is_blkdev(struct nvme_dev *dev) -{ - return S_ISBLK(dev->direct.stat.st_mode); -} - -static int open_dev_direct(struct nvme_dev **devp, char *devstr, int flags) -{ - struct nvme_dev *dev; - int err; - - dev = calloc(1, sizeof(*dev)); - if (!dev) - return -1; - - dev->type = NVME_DEV_DIRECT; - dev->name = basename(devstr); - err = open(devstr, flags); - if (err < 0) { - nvme_show_perror(devstr); - goto err_free; - } - dev->direct.fd = err; - - err = fstat(dev_fd(dev), &dev->direct.stat); - if (err < 0) { - nvme_show_perror(devstr); - goto err_close; - } - if (!is_chardev(dev) && !is_blkdev(dev)) { - nvme_show_error("%s is not a block or character device", devstr); - errno = ENODEV; - err = -1; - goto err_close; - } - *devp = dev; - return 0; - -err_close: - close(dev_fd(dev)); -err_free: - free(dev); - return err; -} - -static int parse_mi_dev(char *dev, unsigned int *net, uint8_t *eid, - unsigned int *ctrl) -{ - int rc; - - /* ,: form */ - rc = sscanf(dev, "mctp:%u,%hhu:%u", net, eid, ctrl); - if (rc == 3) - return 0; - - /* , form, implicit ctrl-id = 0 */ - *ctrl = 0; - rc = sscanf(dev, "mctp:%u,%hhu", net, eid); - if (rc == 2) - return 0; - - return -1; -} - -static int open_dev_mi_mctp(struct nvme_dev **devp, char *devstr) -{ - unsigned int net, ctrl_id; - struct nvme_dev *dev; - unsigned char eid; - int rc; - - rc = parse_mi_dev(devstr, &net, &eid, &ctrl_id); - if (rc) { - nvme_show_error("invalid device specifier '%s'", devstr); - return rc; - } - - dev = calloc(1, sizeof(*dev)); - if (!dev) - return -1; - - dev->type = NVME_DEV_MI; - dev->name = devstr; - - /* todo: verbose argument */ - dev->mi.root = nvme_mi_create_root(stderr, LOG_WARNING); - if (!dev->mi.root) - goto err_free; - - dev->mi.ep = nvme_mi_open_mctp(dev->mi.root, net, eid); - if (!dev->mi.ep) - goto err_free_root; - - dev->mi.ctrl = nvme_mi_init_ctrl(dev->mi.ep, ctrl_id); - if (!dev->mi.ctrl) - goto err_close_ep; - - *devp = dev; - return 0; - -err_close_ep: - nvme_mi_close(dev->mi.ep); -err_free_root: - nvme_mi_free_root(dev->mi.root); -err_free: - free(dev); - return -1; -} - static int check_arg_dev(int argc, char **argv) { if (optind >= argc) { @@ -463,7 +349,9 @@ static int check_arg_dev(int argc, char **argv) return 0; } -static int get_dev(struct nvme_dev **dev, int argc, char **argv, int flags) +static int get_transport_handle(struct nvme_global_ctx *ctx, int argc, + char **argv, int flags, + struct nvme_transport_handle **hdl) { char *devname; int ret; @@ -473,17 +361,12 @@ static int get_dev(struct nvme_dev **dev, int argc, char **argv, int flags) return ret; devname = argv[optind]; - errno = ENXIO; - - if (!strncmp(devname, "mctp:", strlen("mctp:"))) - ret = open_dev_mi_mctp(dev, devname); - else - ret = open_dev_direct(dev, devname, flags); + ret = nvme_open(ctx, devname, hdl); if (!ret && log_level >= LOG_DEBUG) nvme_show_init(); - return ret ? -errno : 0; + return ret; } static int parse_args(int argc, char *argv[], const char *desc, @@ -501,32 +384,59 @@ static int parse_args(int argc, char *argv[], const char *desc, return 0; } -int parse_and_open(struct nvme_dev **dev, int argc, char **argv, - const char *desc, - struct argconfig_commandline_options *opts) +int parse_and_open(struct nvme_global_ctx **ctx, + struct nvme_transport_handle **hdl, int argc, char **argv, + const char *desc, struct argconfig_commandline_options *opts) { + struct nvme_transport_handle *hdl_new; + struct nvme_global_ctx *ctx_new; int ret; ret = parse_args(argc, argv, desc, opts); if (ret) return ret; - ret = get_dev(dev, argc, argv, O_RDONLY); - if (ret < 0) + ctx_new = nvme_create_global_ctx(stdout, log_level); + if (!ctx_new) + return ret; + + ret = get_transport_handle(ctx_new, argc, argv, O_RDONLY, &hdl_new); + if (ret) { + nvme_free_global_ctx(ctx_new); argconfig_print_help(desc, opts); + return -ENXIO; + } - return ret; + *ctx = ctx_new; + *hdl = hdl_new; + return 0; } -int open_exclusive(struct nvme_dev **dev, int argc, char **argv, +int open_exclusive(struct nvme_global_ctx **ctx, + struct nvme_transport_handle **hdl, int argc, char **argv, int ignore_exclusive) { + struct nvme_transport_handle *hdl_new; + struct nvme_global_ctx *ctx_new; int flags = O_RDONLY; + int ret; if (!ignore_exclusive) flags |= O_EXCL; - return get_dev(dev, argc, argv, flags); + ctx_new = nvme_create_global_ctx(stdout, log_level); + if (!ctx_new) + return -ENOMEM; + + ret = get_transport_handle(ctx_new, argc, argv, flags, &hdl_new); + if (ret) { + nvme_free_global_ctx(ctx_new); + return -ENXIO; + } + + *ctx = ctx_new; + *hdl = hdl_new; + return 0; } int validate_output_format(const char *format, nvme_print_flags_t *flags) @@ -562,31 +472,15 @@ bool nvme_is_output_format_json(void) return flags == JSON; } -void dev_close(struct nvme_dev *dev) -{ - if (log_level >= LOG_DEBUG) - nvme_show_finish(); - - switch (dev->type) { - case NVME_DEV_DIRECT: - close(dev_fd(dev)); - break; - case NVME_DEV_MI: - nvme_mi_close(dev->mi.ep); - nvme_mi_free_root(dev->mi.root); - break; - } - free(dev); -} - -static int get_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_smart_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve SMART log for the given device " "(or optionally a namespace) in either decoded format " "(default) or binary."; _cleanup_free_ struct nvme_smart_log *smart_log = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; const char *namespace = "(optional) desired namespace"; nvme_print_flags_t flags; int err = -1; @@ -608,7 +502,7 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_output), OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_info)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -628,27 +522,27 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug if (!smart_log) return -ENOMEM; - err = nvme_cli_get_log_smart(dev, cfg.namespace_id, false, - smart_log); + err = nvme_get_log_smart(hdl, cfg.namespace_id, smart_log); if (!err) nvme_show_smart_log(smart_log, cfg.namespace_id, - dev->name, flags); + nvme_transport_handle_get_name(hdl), flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("smart log: %s", nvme_strerror(errno)); + nvme_show_error("smart log: %s", nvme_strerror(-err)); return err; } -static int get_ana_log(int argc, char **argv, struct command *cmd, +static int get_ana_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve ANA log for the given device in " "decoded format (default), json or binary."; const char *groups = "Return ANA groups only."; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL; _cleanup_free_ struct nvme_ana_log *ana_log = NULL; size_t max_ana_log_len; @@ -667,7 +561,8 @@ static int get_ana_log(int argc, char **argv, struct command *cmd, NVME_ARGS(opts, OPT_FLAG("groups", 'g', &cfg.groups, groups)); - err = parse_and_open(&dev, argc, argv, desc, opts); + + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -681,10 +576,10 @@ static int get_ana_log(int argc, char **argv, struct command *cmd, if (!ctrl) return -ENOMEM; - err = nvme_cli_identify_ctrl(dev, ctrl); + err = nvme_identify_ctrl(hdl, ctrl); if (err) { nvme_show_error("ERROR : nvme_identify_ctrl() failed: %s", - nvme_strerror(errno)); + nvme_strerror(-err)); return err; } @@ -699,19 +594,18 @@ static int get_ana_log(int argc, char **argv, struct command *cmd, if (!ana_log) return -ENOMEM; - err = nvme_cli_get_ana_log_atomic(dev, cfg.groups, true, 10, - ana_log, &ana_log_len); + err = nvme_get_ana_log_atomic(hdl, true, cfg.groups, ana_log, &ana_log_len, 10); if (!err) - nvme_show_ana_log(ana_log, dev->name, ana_log_len, flags); + nvme_show_ana_log(ana_log, nvme_transport_handle_get_name(hdl), ana_log_len, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("ana-log: %s", nvme_strerror(errno)); + nvme_show_error("ana-log: %s", nvme_strerror(-err)); return err; } -static int parse_telemetry_da(struct nvme_dev *dev, +static int parse_telemetry_da(struct nvme_transport_handle *hdl, enum nvme_telemetry_da da, struct nvme_telemetry_log *telem, size_t *size) @@ -721,14 +615,16 @@ static int parse_telemetry_da(struct nvme_dev *dev, size_t dalb, da1lb = le16_to_cpu(telem->dalb1), da2lb = le16_to_cpu(telem->dalb2), da3lb = le16_to_cpu(telem->dalb3), da4lb = le32_to_cpu(telem->dalb4); bool data_area_4_support; + int err; id_ctrl = nvme_alloc(sizeof(*id_ctrl)); if (!id_ctrl) return -ENOMEM; - if (nvme_cli_identify_ctrl(dev, id_ctrl)) { - perror("identify-ctrl"); - return -errno; + err = nvme_identify_ctrl(hdl, id_ctrl); + if (err) { + fprintf(stderr, "identify-ctrl: %s", nvme_strerror(-err)); + return err; } data_area_4_support = id_ctrl->lpa & 0x40; @@ -772,7 +668,7 @@ static int parse_telemetry_da(struct nvme_dev *dev, return 0; } -static int get_log_telemetry_ctrl(struct nvme_dev *dev, bool rae, size_t size, +static int get_log_telemetry_ctrl(struct nvme_transport_handle *hdl, bool rae, size_t size, struct nvme_telemetry_log **buf) { struct nvme_telemetry_log *log; @@ -780,22 +676,19 @@ static int get_log_telemetry_ctrl(struct nvme_dev *dev, bool rae, size_t size, log = nvme_alloc(size); if (!log) - return -errno; + return -ENOMEM; - err = nvme_cli_get_log_telemetry_ctrl(dev, rae, 0, size, log); + err = nvme_get_log_telemetry_ctrl(hdl, rae, 0, log, size); if (err) { free(log); - if (errno) - return -errno; - else - return err; + return err; } *buf = log; return 0; } -static int get_log_telemetry_host(struct nvme_dev *dev, size_t size, +static int get_log_telemetry_host(struct nvme_transport_handle *hdl, size_t size, struct nvme_telemetry_log **buf) { struct nvme_telemetry_log *log; @@ -803,22 +696,19 @@ static int get_log_telemetry_host(struct nvme_dev *dev, size_t size, log = nvme_alloc(size); if (!log) - return -errno; + return -ENOMEM; - err = nvme_cli_get_log_telemetry_host(dev, 0, size, log); + err = nvme_get_log_telemetry_host(hdl, 0, log, size); if (err) { free(log); - if (errno) - return -errno; - else - return err; + return err; } *buf = log; return 0; } -static int __create_telemetry_log_host(struct nvme_dev *dev, +static int __create_telemetry_log_host(struct nvme_transport_handle *hdl, enum nvme_telemetry_da da, size_t *size, struct nvme_telemetry_log **buf) @@ -830,22 +720,18 @@ static int __create_telemetry_log_host(struct nvme_dev *dev, if (!log) return -ENOMEM; - err = nvme_cli_get_log_create_telemetry_host_mcda(dev, da, log); - if (err) { - if (errno) - return -errno; - else - return err; - } + err = nvme_get_log_create_telemetry_host_mcda(hdl, da, log); + if (err) + return err; - err = parse_telemetry_da(dev, da, log, size); + err = parse_telemetry_da(hdl, da, log, size); if (err) return err; - return get_log_telemetry_host(dev, *size, buf); + return get_log_telemetry_host(hdl, *size, buf); } -static int __get_telemetry_log_ctrl(struct nvme_dev *dev, +static int __get_telemetry_log_ctrl(struct nvme_transport_handle *hdl, bool rae, enum nvme_telemetry_da da, size_t *size, @@ -856,23 +742,21 @@ static int __get_telemetry_log_ctrl(struct nvme_dev *dev, log = nvme_alloc(NVME_LOG_TELEM_BLOCK_SIZE); if (!log) - return -errno; + return -ENOMEM; /* * set rae = true so it won't clear the current telemetry log in * controller */ - err = nvme_cli_get_log_telemetry_ctrl(dev, true, 0, - NVME_LOG_TELEM_BLOCK_SIZE, - log); + err = nvme_get_log_telemetry_ctrl(hdl, true, 0, log, + NVME_LOG_TELEM_BLOCK_SIZE); if (err) goto free; if (!log->ctrlavail) { if (!rae) { - err = nvme_cli_get_log_telemetry_ctrl(dev, rae, 0, - NVME_LOG_TELEM_BLOCK_SIZE, - log); + err = nvme_get_log_telemetry_ctrl(hdl, rae, 0, log, + NVME_LOG_TELEM_BLOCK_SIZE); goto free; } @@ -883,18 +767,18 @@ static int __get_telemetry_log_ctrl(struct nvme_dev *dev, return 0; } - err = parse_telemetry_da(dev, da, log, size); + err = parse_telemetry_da(hdl, da, log, size); if (err) goto free; - return get_log_telemetry_ctrl(dev, rae, *size, buf); + return get_log_telemetry_ctrl(hdl, rae, *size, buf); free: free(log); return err; } -static int __get_telemetry_log_host(struct nvme_dev *dev, +static int __get_telemetry_log_host(struct nvme_transport_handle *hdl, enum nvme_telemetry_da da, size_t *size, struct nvme_telemetry_log **buf) @@ -904,22 +788,21 @@ static int __get_telemetry_log_host(struct nvme_dev *dev, log = nvme_alloc(sizeof(*log)); if (!log) - return -errno; + return -ENOMEM; - err = nvme_cli_get_log_telemetry_host(dev, 0, - NVME_LOG_TELEM_BLOCK_SIZE, - log); + err = nvme_get_log_telemetry_host(hdl, 0, log, + NVME_LOG_TELEM_BLOCK_SIZE); if (err) return err; - err = parse_telemetry_da(dev, da, log, size); + err = parse_telemetry_da(hdl, da, log, size); if (err) return err; - return get_log_telemetry_host(dev, *size, buf); + return get_log_telemetry_host(hdl, *size, buf); } -static int get_telemetry_log(int argc, char **argv, struct command *cmd, +static int get_telemetry_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve telemetry log and write to binary file"; @@ -931,10 +814,11 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, "If given, This option will override dgen. 0 : controller determines data area"; _cleanup_free_ struct nvme_telemetry_log *log = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_fd_ int output = -1; int err = 0; - size_t total_size; + size_t total_size = 0; __u8 *data_ptr = NULL; int data_written = 0, data_remaining = 0; nvme_print_flags_t flags; @@ -964,7 +848,8 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, OPT_FLAG("rae", 'r', &cfg.rae, rae), OPT_BYTE("mcda", 'm', &cfg.mcda, mcda)); - err = parse_and_open(&dev, argc, argv, desc, opts); + + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1001,17 +886,17 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, return -ENOMEM; if (cfg.ctrl_init) - err = __get_telemetry_log_ctrl(dev, cfg.rae, cfg.data_area, + err = __get_telemetry_log_ctrl(hdl, cfg.rae, cfg.data_area, &total_size, &log); else if (cfg.host_gen) - err = __create_telemetry_log_host(dev, cfg.data_area, + err = __create_telemetry_log_host(hdl, cfg.data_area, &total_size, &log); else - err = __get_telemetry_log_host(dev, cfg.data_area, + err = __get_telemetry_log_host(hdl, cfg.data_area, &total_size, &log); if (err < 0) { - nvme_show_error("get-telemetry-log: %s", nvme_strerror(errno)); + nvme_show_error("get-telemetry-log: %s", nvme_strerror(-err)); return err; } else if (err > 0) { nvme_show_status(err); @@ -1050,13 +935,14 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd, return err; } -static int get_endurance_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_endurance_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieves endurance groups log page and prints the log."; const char *group_id = "The endurance group identifier"; _cleanup_free_ struct nvme_endurance_group_log *endurance_log = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err; @@ -1071,7 +957,8 @@ static int get_endurance_log(int argc, char **argv, struct command *cmd, struct NVME_ARGS(opts, OPT_SHRT("group-id", 'g', &cfg.group_id, group_id)); - err = parse_and_open(&dev, argc, argv, desc, opts); + + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1085,20 +972,20 @@ static int get_endurance_log(int argc, char **argv, struct command *cmd, struct if (!endurance_log) return -ENOMEM; - err = nvme_cli_get_log_endurance_group(dev, cfg.group_id, - endurance_log); + err = nvme_get_log_endurance_group(hdl, cfg.group_id, + endurance_log); if (!err) nvme_show_endurance_log(endurance_log, cfg.group_id, - dev->name, flags); + nvme_transport_handle_get_name(hdl), flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("endurance log: %s", nvme_strerror(errno)); + nvme_show_error("endurance log: %s", nvme_strerror(-err)); return err; } -static int collect_effects_log(struct nvme_dev *dev, enum nvme_csi csi, +static int collect_effects_log(struct nvme_transport_handle *hdl, enum nvme_csi csi, struct list_head *list, int flags) { nvme_effects_log_node_t *node; @@ -1110,7 +997,7 @@ static int collect_effects_log(struct nvme_dev *dev, enum nvme_csi csi, node->csi = csi; - err = nvme_cli_get_log_cmd_effects(dev, csi, &node->effects); + err = nvme_get_log_cmd_effects(hdl, csi, &node->effects); if (err) { free(node); return err; @@ -1119,11 +1006,13 @@ static int collect_effects_log(struct nvme_dev *dev, enum nvme_csi csi, return 0; } -static int get_effects_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_effects_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve command effects log page and print the table."; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd64 cmd; struct list_head log_pages; nvme_effects_log_node_t *node; @@ -1149,7 +1038,8 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_log), OPT_INT("csi", 'c', &cfg.csi, csi)); - err = parse_and_open(&dev, argc, argv, desc, opts); + + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1169,37 +1059,31 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl if (cfg.csi < 0) { __u64 cap; - if (is_blkdev(dev)) { + if (nvme_transport_handle_is_blkdev(hdl)) { nvme_show_error("Block device isn't allowed without csi"); return -EINVAL; } - bar = mmap_registers(dev, false); + bar = mmap_registers(hdl, false); if (bar) { cap = mmio_read64(bar + NVME_REG_CAP); munmap(bar, getpagesize()); } else { - struct nvme_get_property_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .offset = NVME_REG_CAP, - .value = &cap, - .timeout = nvme_cfg.timeout, - }; - err = nvme_get_property(&args); + nvme_init_get_property(&cmd, NVME_REG_CAP); + err = nvme_submit_admin_passthru64(hdl, &cmd, &cap); if (err) goto cleanup_list; } if (NVME_CAP_CSS(cap) & NVME_CAP_CSS_NVM) - err = collect_effects_log(dev, NVME_CSI_NVM, + err = collect_effects_log(hdl, NVME_CSI_NVM, &log_pages, flags); if (!err && (NVME_CAP_CSS(cap) & NVME_CAP_CSS_CSI)) - err = collect_effects_log(dev, NVME_CSI_ZNS, + err = collect_effects_log(hdl, NVME_CSI_ZNS, &log_pages, flags); } else { - err = collect_effects_log(dev, cfg.csi, &log_pages, flags); + err = collect_effects_log(hdl, cfg.csi, &log_pages, flags); } if (!err) @@ -1216,19 +1100,20 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl return err; } -static int get_supported_log_pages(int argc, char **argv, struct command *cmd, +static int get_supported_log_pages(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve supported logs and print the table."; _cleanup_free_ struct nvme_supported_log_pages *supports = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err = -1; NVME_ARGS(opts); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1245,18 +1130,18 @@ static int get_supported_log_pages(int argc, char **argv, struct command *cmd, if (!supports) return -ENOMEM; - err = nvme_cli_get_log_supported_log_pages(dev, false, supports); + err = nvme_get_log_supported_log_pages(hdl, supports); if (!err) - nvme_show_supported_log(supports, dev->name, flags); + nvme_show_supported_log(supports, nvme_transport_handle_get_name(hdl), flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("supported log pages: %s", nvme_strerror(errno)); + nvme_show_error("supported log pages: %s", nvme_strerror(-err)); return err; } -static int get_error_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_error_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve specified number of " "error log entries from a given device " @@ -1265,7 +1150,8 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug const char *raw = "dump in binary format"; _cleanup_free_ struct nvme_error_log_page *err_log = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct nvme_id_ctrl ctrl = { 0 }; nvme_print_flags_t flags; int err = -1; @@ -1284,7 +1170,7 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug OPT_UINT("log-entries", 'e', &cfg.log_entries, log_entries), OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1302,7 +1188,7 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug return -1; } - err = nvme_cli_identify_ctrl(dev, &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err < 0) { nvme_show_perror("identify controller"); return err; @@ -1316,10 +1202,10 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug if (!err_log) return -ENOMEM; - err = nvme_cli_get_log_error(dev, cfg.log_entries, false, err_log); + err = nvme_get_log_error(hdl, NVME_NSID_ALL, cfg.log_entries, err_log); if (!err) nvme_show_error_log(err_log, cfg.log_entries, - dev->name, flags); + nvme_transport_handle_get_name(hdl), flags); else if (err > 0) nvme_show_status(err); else @@ -1328,13 +1214,14 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug return err; } -static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_fw_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve the firmware log for the " "specified device in either decoded format (default) or binary."; _cleanup_free_ struct nvme_firmware_slot *fw_log = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err; @@ -1349,7 +1236,7 @@ static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin NVME_ARGS(opts, OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1366,13 +1253,13 @@ static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin if (!fw_log) return -ENOMEM; - err = nvme_cli_get_log_fw_slot(dev, false, fw_log); + err = nvme_get_log_fw_slot(hdl, false, fw_log); if (!err) - nvme_show_fw_log(fw_log, dev->name, flags); + nvme_show_fw_log(fw_log, nvme_transport_handle_get_name(hdl), flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("fw log: %s", nvme_strerror(errno)); + nvme_show_error("fw log: %s", nvme_strerror(-err)); return err; } @@ -1380,9 +1267,9 @@ static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin static int get_changed_ns_list_log(int argc, char **argv, bool alloc) { _cleanup_free_ char *desc = NULL; - _cleanup_free_ struct nvme_ns_list *changed_ns_list_log = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err; @@ -1402,7 +1289,7 @@ static int get_changed_ns_list_log(int argc, char **argv, bool alloc) "in either decoded format (default) or binary.") < 0) desc = NULL; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1420,37 +1307,37 @@ static int get_changed_ns_list_log(int argc, char **argv, bool alloc) return -ENOMEM; if (alloc) - err = nvme_cli_get_log_changed_alloc_ns_list(dev, true, - sizeof(*changed_ns_list_log), - changed_ns_list_log); + err = nvme_get_log_changed_alloc_ns_list(hdl, + changed_ns_list_log, sizeof(*changed_ns_list_log)); else - err = nvme_cli_get_log_changed_ns_list(dev, true, - changed_ns_list_log); + err = nvme_get_log_changed_ns_list(hdl, NVME_NSID_NONE, + changed_ns_list_log); if (!err) - nvme_show_changed_ns_list_log(changed_ns_list_log, dev->name, flags, alloc); + nvme_show_changed_ns_list_log(changed_ns_list_log, nvme_transport_handle_get_name(hdl), + flags, alloc); else if (err > 0) nvme_show_status(err); else nvme_show_error("changed %s ns list log: %s", alloc ? "allocated" : "attached", - nvme_strerror(errno)); + nvme_strerror(-err)); return err; } -static int get_changed_attach_ns_list_log(int argc, char **argv, struct command *cmd, +static int get_changed_attach_ns_list_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { return get_changed_ns_list_log(argc, argv, false); } -static int get_changed_alloc_ns_list_log(int argc, char **argv, struct command *cmd, +static int get_changed_alloc_ns_list_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { return get_changed_ns_list_log(argc, argv, true); } static int get_pred_lat_per_nvmset_log(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { const char *desc = "Retrieve Predictable latency per nvm set log " "page and prints it for the given device in either decoded " @@ -1458,7 +1345,8 @@ static int get_pred_lat_per_nvmset_log(int argc, char **argv, const char *nvmset_id = "NVM Set Identifier"; _cleanup_free_ struct nvme_nvmset_predictable_lat_log *plpns_log = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err; @@ -1476,7 +1364,7 @@ static int get_pred_lat_per_nvmset_log(int argc, char **argv, OPT_SHRT("nvmset-id", 'i', &cfg.nvmset_id, nvmset_id), OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1493,28 +1381,30 @@ static int get_pred_lat_per_nvmset_log(int argc, char **argv, if (!plpns_log) return -ENOMEM; - err = nvme_cli_get_log_predictable_lat_nvmset(dev, cfg.nvmset_id, - plpns_log); + err = nvme_get_log_predictable_lat_nvmset(hdl, cfg.nvmset_id, + plpns_log); if (!err) - nvme_show_predictable_latency_per_nvmset(plpns_log, cfg.nvmset_id, dev->name, + nvme_show_predictable_latency_per_nvmset(plpns_log, cfg.nvmset_id, + nvme_transport_handle_get_name(hdl), flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("predictable latency per nvm set: %s", nvme_strerror(errno)); + nvme_show_error("predictable latency per nvm set: %s", nvme_strerror(-err)); return err; } static int get_pred_lat_event_agg_log(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { const char *desc = "Retrieve Predictable Latency Event " "Aggregate Log page and prints it, for the given " "device in either decoded format(default), json or binary."; const char *log_entries = "Number of pending NVM Set log Entries list"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL; _cleanup_free_ void *pea_log = NULL; nvme_print_flags_t flags; @@ -1538,7 +1428,7 @@ static int get_pred_lat_event_agg_log(int argc, char **argv, OPT_FLAG("rae", 'r', &cfg.rae, rae), OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1560,9 +1450,9 @@ static int get_pred_lat_event_agg_log(int argc, char **argv, if (!ctrl) return -ENOMEM; - err = nvme_cli_identify_ctrl(dev, ctrl); + err = nvme_identify_ctrl(hdl, ctrl); if (err < 0) { - nvme_show_error("identify controller: %s", nvme_strerror(errno)); + nvme_show_error("identify controller: %s", nvme_strerror(-err)); return err; } else if (err) { nvme_show_status(err); @@ -1576,22 +1466,22 @@ static int get_pred_lat_event_agg_log(int argc, char **argv, if (!pea_log) return -ENOMEM; - err = nvme_cli_get_log_predictable_lat_event(dev, cfg.rae, 0, - log_size, pea_log); + err = nvme_get_log_predictable_lat_event(hdl, cfg.rae, 0, + pea_log, log_size); if (!err) nvme_show_predictable_latency_event_agg_log(pea_log, cfg.log_entries, log_size, - dev->name, flags); + nvme_transport_handle_get_name(hdl), flags); else if (err > 0) nvme_show_status(err); else nvme_show_error("predictable latency event aggregate log page: %s", - nvme_strerror(errno)); + nvme_strerror(-err)); return err; } static int get_persistent_event_log(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { const char *desc = "Retrieve Persistent Event log info for " "the given device in either decoded format(default), json or binary."; @@ -1602,7 +1492,8 @@ static int get_persistent_event_log(int argc, char **argv, _cleanup_free_ struct nvme_persistent_event_log *pevent = NULL; struct nvme_persistent_event_log *pevent_collected = NULL; _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; void *pevent_log_info; int err; @@ -1624,7 +1515,7 @@ static int get_persistent_event_log(int argc, char **argv, OPT_UINT("log_len", 'l', &cfg.log_len, log_len), OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1641,10 +1532,10 @@ static int get_persistent_event_log(int argc, char **argv, if (!pevent) return -ENOMEM; - err = nvme_cli_get_log_persistent_event(dev, cfg.action, - sizeof(*pevent), pevent); + err = nvme_get_log_persistent_event(hdl, cfg.action, + pevent, sizeof(*pevent)); if (err < 0) { - nvme_show_error("persistent event log: %s", nvme_strerror(errno)); + nvme_show_error("persistent event log: %s", nvme_strerror(-err)); return err; } else if (err) { nvme_show_status(err); @@ -1679,14 +1570,14 @@ static int get_persistent_event_log(int argc, char **argv, return -ENOMEM; } - err = nvme_cli_get_log_persistent_event(dev, cfg.action, - cfg.log_len, pevent_log_info); + err = nvme_get_log_persistent_event(hdl, cfg.action, + pevent_log_info, cfg.log_len); if (!err) { - err = nvme_cli_get_log_persistent_event(dev, cfg.action, - sizeof(*pevent), - pevent); + err = nvme_get_log_persistent_event(hdl, cfg.action, + pevent, + sizeof(*pevent)); if (err < 0) { - nvme_show_error("persistent event log: %s", nvme_strerror(errno)); + nvme_show_error("persistent event log: %s", nvme_strerror(-err)); return err; } else if (err) { nvme_show_status(err); @@ -1700,25 +1591,26 @@ static int get_persistent_event_log(int argc, char **argv, } nvme_show_persistent_event_log(pevent_log_info, cfg.action, - cfg.log_len, dev->name, flags); + cfg.log_len, nvme_transport_handle_get_name(hdl), flags); } else if (err > 0) { nvme_show_status(err); } else { - nvme_show_error("persistent event log: %s", nvme_strerror(errno)); + nvme_show_error("persistent event log: %s", nvme_strerror(-err)); } return err; } static int get_endurance_event_agg_log(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { const char *desc = "Retrieve Retrieve Predictable Latency " "Event Aggregate page and prints it, for the given " "device in either decoded format(default), json or binary."; const char *log_entries = "Number of pending Endurance Group Event log Entries list"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL; _cleanup_free_ void *endurance_log = NULL; nvme_print_flags_t flags; @@ -1742,7 +1634,7 @@ static int get_endurance_event_agg_log(int argc, char **argv, OPT_FLAG("rae", 'r', &cfg.rae, rae), OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1764,9 +1656,9 @@ static int get_endurance_event_agg_log(int argc, char **argv, if (!ctrl) return -ENOMEM; - err = nvme_cli_identify_ctrl(dev, ctrl); + err = nvme_identify_ctrl(hdl, ctrl); if (err < 0) { - nvme_show_error("identify controller: %s", nvme_strerror(errno)); + nvme_show_error("identify controller: %s", nvme_strerror(-err)); return err; } else if (err) { nvme_show_error("could not identify controller"); @@ -1780,27 +1672,28 @@ static int get_endurance_event_agg_log(int argc, char **argv, if (!endurance_log) return -ENOMEM; - err = nvme_cli_get_log_endurance_grp_evt(dev, cfg.rae, 0, log_size, - endurance_log); + err = nvme_get_log_endurance_grp_evt(hdl, cfg.rae, 0, + endurance_log, log_size); if (!err) nvme_show_endurance_group_event_agg_log(endurance_log, cfg.log_entries, log_size, - dev->name, flags); + nvme_transport_handle_get_name(hdl), flags); else if (err > 0) nvme_show_status(err); else nvme_show_error("endurance group event aggregate log page: %s", - nvme_strerror(errno)); + nvme_strerror(-err)); return err; } static int get_lba_status_log(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { const char *desc = "Retrieve Get LBA Status Info Log and prints it, " "for the given device in either decoded format(default),json or binary."; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ void *lba_status = NULL; nvme_print_flags_t flags; __u32 lslplen; @@ -1817,7 +1710,7 @@ static int get_lba_status_log(int argc, char **argv, NVME_ARGS(opts, OPT_FLAG("rae", 'r', &cfg.rae, rae)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1827,10 +1720,9 @@ static int get_lba_status_log(int argc, char **argv, return err; } - err = nvme_cli_get_log_lba_status(dev, true, 0, sizeof(__u32), - &lslplen); + err = nvme_get_log_lba_status(hdl, false, 0, &lslplen, sizeof(__u32)); if (err < 0) { - nvme_show_error("lba status log page: %s", nvme_strerror(errno)); + nvme_show_error("lba status log page: %s", nvme_strerror(-err)); return err; } else if (err) { nvme_show_status(err); @@ -1841,19 +1733,19 @@ static int get_lba_status_log(int argc, char **argv, if (!lba_status) return -ENOMEM; - err = nvme_cli_get_log_lba_status(dev, cfg.rae, 0, lslplen, lba_status); + err = nvme_get_log_lba_status(hdl, cfg.rae, 0, lba_status, lslplen); if (!err) - nvme_show_lba_status_log(lba_status, lslplen, dev->name, flags); + nvme_show_lba_status_log(lba_status, lslplen, nvme_transport_handle_get_name(hdl), flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("lba status log page: %s", nvme_strerror(errno)); + nvme_show_error("lba status log page: %s", nvme_strerror(-err)); return err; } static int get_resv_notif_log(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { const char *desc = "Retrieve Reservation Notification " @@ -1861,13 +1753,14 @@ static int get_resv_notif_log(int argc, char **argv, "device in either decoded format(default), json or binary."; _cleanup_free_ struct nvme_resv_notification_log *resv = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err; NVME_ARGS(opts); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1881,26 +1774,27 @@ static int get_resv_notif_log(int argc, char **argv, if (!resv) return -ENOMEM; - err = nvme_cli_get_log_reservation(dev, false, resv); + err = nvme_get_log_reservation(hdl, resv); if (!err) - nvme_show_resv_notif_log(resv, dev->name, flags); + nvme_show_resv_notif_log(resv, nvme_transport_handle_get_name(hdl), flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("resv notifi log: %s", nvme_strerror(errno)); + nvme_show_error("resv notifi log: %s", nvme_strerror(-err)); return err; } -static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_boot_part_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Boot Partition " "log page and prints it, for the given " "device in either decoded format(default), json or binary."; const char *fname = "boot partition data output file name"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ struct nvme_boot_partition *boot = NULL; _cleanup_free_ __u8 *bp_log = NULL; nvme_print_flags_t flags; @@ -1922,7 +1816,7 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct OPT_BYTE("lsp", 's', &cfg.lsp, lsp), OPT_FILE("output-file", 'f', &cfg.file_name, fname)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1953,10 +1847,9 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct if (!boot) return -ENOMEM; - err = nvme_cli_get_log_boot_partition(dev, false, cfg.lsp, - sizeof(*boot), boot); + err = nvme_get_log_boot_partition(hdl, cfg.lsp, boot, sizeof(*boot)); if (err < 0) { - nvme_show_error("boot partition log: %s", nvme_strerror(errno)); + nvme_show_error("boot partition log: %s", nvme_strerror(-err)); return err; } else if (err) { nvme_show_status(err); @@ -1968,15 +1861,16 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct if (!bp_log) return -ENOMEM; - err = nvme_cli_get_log_boot_partition(dev, false, cfg.lsp, - sizeof(*boot) + bpsz, - (struct nvme_boot_partition *)bp_log); + err = nvme_get_log_boot_partition(hdl, cfg.lsp, + (struct nvme_boot_partition *)bp_log, + sizeof(*boot) + bpsz); if (!err) - nvme_show_boot_part_log(&bp_log, dev->name, sizeof(*boot) + bpsz, flags); + nvme_show_boot_part_log(&bp_log, nvme_transport_handle_get_name(hdl), + sizeof(*boot) + bpsz, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("boot partition log: %s", nvme_strerror(errno)); + nvme_show_error("boot partition log: %s", nvme_strerror(-err)); err = write(output, (void *) bp_log + sizeof(*boot), bpsz); if (err != bpsz) @@ -1988,7 +1882,7 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct return err; } -static int get_phy_rx_eom_log(int argc, char **argv, struct command *cmd, +static int get_phy_rx_eom_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Physical Interface Receiver Eye Opening " @@ -1998,7 +1892,8 @@ static int get_phy_rx_eom_log(int argc, char **argv, struct command *cmd, _cleanup_free_ struct nvme_phy_rx_eom_log *phy_rx_eom_log = NULL; size_t phy_rx_eom_log_len; nvme_print_flags_t flags; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err = -1; __u8 lsp_tmp; @@ -2016,7 +1911,7 @@ static int get_phy_rx_eom_log(int argc, char **argv, struct command *cmd, OPT_BYTE("lsp", 's', &cfg.lsp, lsp), OPT_SHRT("controller", 'c', &cfg.controller, controller)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -2046,13 +1941,13 @@ static int get_phy_rx_eom_log(int argc, char **argv, struct command *cmd, /* Just read measurement, take given action when fetching full log */ lsp_tmp = cfg.lsp & 0xf3; - err = nvme_cli_get_log_phy_rx_eom(dev, lsp_tmp, cfg.controller, phy_rx_eom_log_len, - phy_rx_eom_log); + err = nvme_get_log_phy_rx_eom(hdl, lsp_tmp, cfg.controller, phy_rx_eom_log, + phy_rx_eom_log_len); if (err) { if (err > 0) nvme_show_status(err); else - nvme_show_error("phy-rx-eom-log: %s", nvme_strerror(errno)); + nvme_show_error("phy-rx-eom-log: %s", nvme_strerror(-err)); return err; } @@ -2068,25 +1963,26 @@ static int get_phy_rx_eom_log(int argc, char **argv, struct command *cmd, if (!phy_rx_eom_log) return -ENOMEM; - err = nvme_cli_get_log_phy_rx_eom(dev, cfg.lsp, cfg.controller, phy_rx_eom_log_len, - phy_rx_eom_log); + err = nvme_get_log_phy_rx_eom(hdl, cfg.lsp, cfg.controller, phy_rx_eom_log, + phy_rx_eom_log_len); if (!err) nvme_show_phy_rx_eom_log(phy_rx_eom_log, cfg.controller, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("phy-rx-eom-log: %s", nvme_strerror(errno)); + nvme_show_error("phy-rx-eom-log: %s", nvme_strerror(-err)); return err; } -static int get_media_unit_stat_log(int argc, char **argv, struct command *cmd, +static int get_media_unit_stat_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve the configuration and wear of media units and print it"; _cleanup_free_ struct nvme_media_unit_stat_log *mus = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err = -1; @@ -2104,7 +2000,7 @@ static int get_media_unit_stat_log(int argc, char **argv, struct command *cmd, OPT_UINT("domain-id", 'd', &cfg.domainid, domainid), OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -2121,24 +2017,25 @@ static int get_media_unit_stat_log(int argc, char **argv, struct command *cmd, if (!mus) return -ENOMEM; - err = nvme_cli_get_log_media_unit_stat(dev, cfg.domainid, mus); + err = nvme_get_log_media_unit_stat(hdl, cfg.domainid, mus); if (!err) nvme_show_media_unit_stat_log(mus, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("media unit status log: %s", nvme_strerror(errno)); + nvme_show_error("media unit status log: %s", nvme_strerror(-err)); return err; } -static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd, +static int get_supp_cap_config_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve the list of Supported Capacity Configuration Descriptors"; _cleanup_free_ struct nvme_supported_cap_config_list_log *cap_log = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err = -1; @@ -2156,7 +2053,7 @@ static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd, OPT_UINT("domain-id", 'd', &cfg.domainid, domainid), OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -2173,8 +2070,8 @@ static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd, if (!cap_log) return -ENOMEM; - err = nvme_cli_get_log_support_cap_config_list(dev, cfg.domainid, - cap_log); + err = nvme_get_log_support_cap_config_list(hdl, cfg.domainid, + cap_log); if (!err) nvme_show_supported_cap_config_log(cap_log, flags); else if (err > 0) @@ -2185,20 +2082,22 @@ static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd, return err; } -static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int io_mgmt_send(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "I/O Management Send"; const char *data = "optional file for data (default stdin)"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_fd_ int dfd = STDIN_FILENO; _cleanup_free_ void *buf = NULL; + struct nvme_passthru_cmd cmd; int err = -1; - _cleanup_fd_ int dfd = STDIN_FILENO; struct config { + __u32 nsid; __u16 mos; __u8 mo; - __u32 namespace_id; char *file; __u32 data_len; }; @@ -2208,18 +2107,18 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi }; NVME_ARGS(opts, - OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired), - OPT_SHRT("mos", 's', &cfg.mos, mos), - OPT_BYTE("mo", 'm', &cfg.mo, mo), - OPT_FILE("data", 'd', &cfg.file, data), - OPT_UINT("data-len", 'l', &cfg.data_len, buf_len)); + OPT_UINT("namespace-id", 'n', &cfg.nsid, namespace_id_desired), + OPT_SHRT("mos", 's', &cfg.mos, mos), + OPT_BYTE("mo", 'm', &cfg.mo, mo), + OPT_FILE("data", 'd', &cfg.file, data), + OPT_UINT("data-len", 'l', &cfg.data_len, buf_len)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + if (!cfg.nsid) { + err = nvme_get_nsid(hdl, &cfg.nsid); if (err < 0) { nvme_show_perror("get-namespace-id"); return err; @@ -2246,21 +2145,11 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi return err; } - struct nvme_io_mgmt_send_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .mos = cfg.mos, - .mo = cfg.mo, - .data_len = cfg.data_len, - .data = buf, - .timeout = nvme_cfg.timeout, - }; - - err = nvme_io_mgmt_send(&args); + nvme_init_io_mgmt_send(&cmd, cfg.nsid, cfg.mo, cfg.mos, buf, cfg.data_len); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); if (!err) printf("io-mgmt-send: Success, mos:%u mo:%u nsid:%d\n", - cfg.mos, cfg.mo, cfg.namespace_id); + cfg.mos, cfg.mo, cfg.nsid); else if (err > 0) nvme_show_status(err); else @@ -2269,20 +2158,22 @@ static int io_mgmt_send(int argc, char **argv, struct command *cmd, struct plugi return err; } -static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int io_mgmt_recv(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "I/O Management Receive"; const char *data = "optional file for data (default stdout)"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; _cleanup_free_ void *buf = NULL; - int err = -1; + struct nvme_passthru_cmd cmd; _cleanup_fd_ int dfd = -1; + int err = -1; struct config { __u16 mos; __u8 mo; - __u32 namespace_id; + __u32 nsid; char *file; __u32 data_len; }; @@ -2292,18 +2183,18 @@ static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugi }; NVME_ARGS(opts, - OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired), - OPT_SHRT("mos", 's', &cfg.mos, mos), - OPT_BYTE("mo", 'm', &cfg.mo, mo), - OPT_FILE("data", 'd', &cfg.file, data), - OPT_UINT("data-len", 'l', &cfg.data_len, buf_len)); + OPT_UINT("namespace-id", 'n', &cfg.nsid, namespace_id_desired), + OPT_SHRT("mos", 's', &cfg.mos, mos), + OPT_BYTE("mo", 'm', &cfg.mo, mo), + OPT_FILE("data", 'd', &cfg.file, data), + OPT_UINT("data-len", 'l', &cfg.data_len, buf_len)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + if (!cfg.nsid) { + err = nvme_get_nsid(hdl, &cfg.nsid); if (err < 0) { nvme_show_perror("get-namespace-id"); return err; @@ -2316,21 +2207,12 @@ static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugi return -ENOMEM; } - struct nvme_io_mgmt_recv_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .mos = cfg.mos, - .mo = cfg.mo, - .data_len = cfg.data_len, - .data = buf, - .timeout = nvme_cfg.timeout, - }; - - err = nvme_io_mgmt_recv(&args); + nvme_init_io_mgmt_recv(&cmd, cfg.nsid, cfg.mo, cfg.mos, buf, + cfg.data_len); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); if (!err) { printf("io-mgmt-recv: Success, mos:%u mo:%u nsid:%d\n", - cfg.mos, cfg.mo, cfg.namespace_id); + cfg.mos, cfg.mo, cfg.nsid); if (cfg.file) { dfd = open(cfg.file, O_WRONLY | O_CREAT, 0644); @@ -2356,7 +2238,7 @@ static int io_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugi return err; } -static int get_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve desired number of bytes " "from a given log on a specified device in either " @@ -2370,8 +2252,10 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl const char *offset_type = "offset type"; const char *xfer_len = "read chunk size (default 4k)"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ unsigned char *log = NULL; + struct nvme_passthru_cmd cmd; int err; nvme_print_flags_t flags; @@ -2438,14 +2322,14 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl VAL_BYTE("phy-rx-eom", NVME_LOG_LID_PHY_RX_EOM), VAL_BYTE("reachability-groups", NVME_LOG_LID_REACHABILITY_GROUPS), VAL_BYTE("reachability-associations", NVME_LOG_LID_REACHABILITY_ASSOCIATIONS), - VAL_BYTE("changed-alloc-ns-list", NVME_LOG_LID_CHANGED_ALLOC_NS_LIST), + VAL_BYTE("changed-alloc-ns-list", NVME_LOG_LID_CHANGED_ALLOC_NS), VAL_BYTE("fdp-configs", NVME_LOG_LID_FDP_CONFIGS), VAL_BYTE("fdp-ruh-usage", NVME_LOG_LID_FDP_RUH_USAGE), VAL_BYTE("fdp-stats", NVME_LOG_LID_FDP_STATS), VAL_BYTE("fdp-events", NVME_LOG_LID_FDP_EVENTS), - VAL_BYTE("discover", NVME_LOG_LID_DISCOVER), - VAL_BYTE("host-discover", NVME_LOG_LID_HOST_DISCOVER), - VAL_BYTE("ave-discover", NVME_LOG_LID_AVE_DISCOVER), + VAL_BYTE("discover", NVME_LOG_LID_DISCOVERY), + VAL_BYTE("host-discover", NVME_LOG_LID_HOST_DISCOVERY), + VAL_BYTE("ave-discover", NVME_LOG_LID_AVE_DISCOVERY), VAL_BYTE("pull-model-ddc-req", NVME_LOG_LID_PULL_MODEL_DDC_REQ), VAL_BYTE("reservation", NVME_LOG_LID_RESERVATION), VAL_BYTE("sanitize", NVME_LOG_LID_SANITIZE), @@ -2468,7 +2352,7 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl OPT_FLAG("ot", 'O', &cfg.ot, offset_type), OPT_UINT("xfer-len", 'x', &cfg.xfer_len, xfer_len)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -2508,46 +2392,63 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl return -ENOMEM; struct nvme_get_log_args args = { - .args_size = sizeof(args), - .lid = cfg.log_id, .nsid = cfg.namespace_id, - .lpo = cfg.lpo, + .rae = cfg.rae, .lsp = cfg.lsp, + .lid = cfg.log_id, .lsi = cfg.lsi, - .rae = cfg.rae, - .uuidx = cfg.uuid_index, .csi = cfg.csi, .ot = cfg.ot, - .len = cfg.log_len, + .uidx = cfg.uuid_index, + .lpo = cfg.lpo, .log = log, + .len = cfg.log_len, .result = NULL, }; - err = nvme_cli_get_log_page(dev, cfg.xfer_len, &args); + nvme_init_get_log(&cmd, cfg.namespace_id, cfg.log_id, + cfg.csi, log, cfg.log_len); + cmd.cdw10 |= NVME_FIELD_ENCODE(cfg.lsp, + NVME_LOG_CDW10_LSP_SHIFT, + NVME_LOG_CDW10_LSP_MASK); + cmd.cdw11 |= NVME_FIELD_ENCODE(cfg.lsi, + NVME_LOG_CDW11_LSI_SHIFT, + NVME_LOG_CDW11_LSI_MASK); + cmd.cdw12 = cfg.lpo & 0xffffffff; + cmd.cdw13 = cfg.lpo >> 32; + cmd.cdw14 |= NVME_FIELD_ENCODE(cfg.uuid_index, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK) | + NVME_FIELD_ENCODE(cfg.ot, + NVME_LOG_CDW14_OT_SHIFT, + NVME_LOG_CDW14_OT_MASK); + + err = nvme_get_log(hdl, &cmd, cfg.rae, NVME_LOG_PAGE_PDU_SIZE, NULL); if (!err) { if (!cfg.raw_binary) { - printf("Device:%s log-id:%d namespace-id:%#x\n", dev->name, cfg.log_id, - cfg.namespace_id); + printf("Device:%s log-id:%d namespace-id:%#x\n", nvme_transport_handle_get_name(hdl), + cfg.log_id, cfg.namespace_id); d(log, cfg.log_len, 16, 1); if (argconfig_parse_seen(opts, "verbose")) - nvme_show_log(dev->name, &args, VERBOSE); + nvme_show_log(nvme_transport_handle_get_name(hdl), &args, VERBOSE); } else { d_raw((unsigned char *)log, cfg.log_len); } } else if (err > 0) { nvme_show_status(err); } else { - nvme_show_error("log page: %s", nvme_strerror(errno)); + nvme_show_error("log page: %s", nvme_strerror(-err)); } return err; } -static int sanitize_log(int argc, char **argv, struct command *command, struct plugin *plugin) +static int sanitize_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve sanitize log and show it."; _cleanup_free_ struct nvme_sanitize_log_page *sanitize_log = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err; @@ -2568,7 +2469,7 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log), OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_log)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -2588,24 +2489,25 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p if (!sanitize_log) return -ENOMEM; - err = nvme_cli_get_log_sanitize(dev, cfg.rae, sanitize_log); + err = nvme_get_log_sanitize(hdl, cfg.rae, sanitize_log); if (!err) - nvme_show_sanitize_log(sanitize_log, dev->name, flags); + nvme_show_sanitize_log(sanitize_log, nvme_transport_handle_get_name(hdl), flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("sanitize status log: %s", nvme_strerror(errno)); + nvme_show_error("sanitize status log: %s", nvme_strerror(-err)); return err; } -static int get_fid_support_effects_log(int argc, char **argv, struct command *cmd, +static int get_fid_support_effects_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve FID Support and Effects log and show it."; _cleanup_free_ struct nvme_fid_supported_effects_log *fid_support_log = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err = -1; @@ -2620,7 +2522,7 @@ static int get_fid_support_effects_log(int argc, char **argv, struct command *cm NVME_ARGS(opts, OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -2637,24 +2539,25 @@ static int get_fid_support_effects_log(int argc, char **argv, struct command *cm if (!fid_support_log) return -ENOMEM; - err = nvme_cli_get_log_fid_supported_effects(dev, false, fid_support_log); + err = nvme_get_log_fid_supported_effects(hdl, false, fid_support_log); if (!err) - nvme_show_fid_support_effects_log(fid_support_log, dev->name, flags); + nvme_show_fid_support_effects_log(fid_support_log, nvme_transport_handle_get_name(hdl), flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("fid support effects log: %s", nvme_strerror(errno)); + nvme_show_error("fid support effects log: %s", nvme_strerror(-err)); return err; } -static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command *cmd, +static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve NVMe-MI Command Support and Effects log and show it."; _cleanup_free_ struct nvme_mi_cmd_supported_effects_log *mi_cmd_support_log = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err = -1; @@ -2669,7 +2572,7 @@ static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command NVME_ARGS(opts, OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_log)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -2686,25 +2589,27 @@ static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command if (!mi_cmd_support_log) return -ENOMEM; - err = nvme_cli_get_log_mi_cmd_supported_effects(dev, false, mi_cmd_support_log); + err = nvme_get_log_mi_cmd_supported_effects(hdl, mi_cmd_support_log); if (!err) - nvme_show_mi_cmd_support_effects_log(mi_cmd_support_log, dev->name, flags); + nvme_show_mi_cmd_support_effects_log(mi_cmd_support_log, nvme_transport_handle_get_name(hdl), flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("mi command support effects log: %s", nvme_strerror(errno)); + nvme_show_error("mi command support effects log: %s", nvme_strerror(-err)); return err; } -static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int list_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Show controller list information for the subsystem the " "given device is part of, or optionally controllers attached to a specific namespace."; const char *controller = "controller to display"; _cleanup_free_ struct nvme_ctrl_list *cntlist = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; int err; @@ -2722,7 +2627,7 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin * OPT_SHRT("cntid", 'c', &cfg.cntid, controller), OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_optional)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -2737,21 +2642,23 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin * return -ENOMEM; if (cfg.namespace_id == NVME_NSID_NONE) - err = nvme_cli_identify_ctrl_list(dev, cfg.cntid, cntlist); + nvme_init_identify_ctrl_list(&cmd, cfg.cntid, cntlist); else - err = nvme_cli_identify_nsid_ctrl_list(dev, cfg.namespace_id, - cfg.cntid, cntlist); + nvme_init_identify_ns_ctrl_list(&cmd, cfg.namespace_id, + cfg.cntid, cntlist); + + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) nvme_show_list_ctrl(cntlist, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("id controller list: %s", nvme_strerror(errno)); + nvme_show_error("id controller list: %s", nvme_strerror(-err)); return err; } -static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int list_ns(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "For the specified controller handle, show the " "namespace list in the associated NVMe subsystem, optionally starting with a given nsid."; @@ -2760,7 +2667,9 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl const char *all = "show all namespaces in the subsystem, whether attached or inactive"; _cleanup_free_ struct nvme_ns_list *ns_list = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + enum nvme_identify_cns cns; nvme_print_flags_t flags; int err; @@ -2781,7 +2690,7 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl OPT_INT("csi", 'y', &cfg.csi, csi), OPT_FLAG("all", 'a', &cfg.all, all)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -2803,39 +2712,35 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl if (!ns_list) return -ENOMEM; - struct nvme_identify_args args = { - .args_size = sizeof(args), - .timeout = nvme_cfg.timeout, - .data = ns_list, - .nsid = cfg.namespace_id - 1. - }; if (cfg.csi < 0) { - args.cns = cfg.all ? NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST : + cns = cfg.all ? NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST : NVME_IDENTIFY_CNS_NS_ACTIVE_LIST; - } else { - args.cns = cfg.all ? NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS_LIST : + cfg.csi = 0; + } else { + cns = cfg.all ? NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS_LIST : NVME_IDENTIFY_CNS_CSI_NS_ACTIVE_LIST; - args.csi = cfg.csi; } - err = nvme_cli_identify(dev, &args); + err = nvme_identify(hdl, cfg.namespace_id - 1, cfg.csi, cns, ns_list, + sizeof(*ns_list)); if (!err) nvme_show_list_ns(ns_list, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("id namespace list: %s", nvme_strerror(errno)); + nvme_show_error("id namespace list: %s", nvme_strerror(-err)); return err; } -static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int id_ns_lba_format(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send an Identify Namespace command to the given " "device, returns capability field properties of the specified " "LBA Format index in various formats."; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ struct nvme_id_ns *ns = NULL; nvme_print_flags_t flags; int err = -1; @@ -2854,7 +2759,7 @@ static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct p OPT_UINT("lba-format-index", 'i', &cfg.lba_format_index, lba_format_index), OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -2871,9 +2776,9 @@ static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct p if (!ns) return -ENOMEM; - err = nvme_identify_ns_csi_user_data_format(dev_fd(dev), + err = nvme_identify_csi_ns_user_data_format(hdl, NVME_CSI_NVM, cfg.lba_format_index, - cfg.uuid_index, NVME_CSI_NVM, ns); + cfg.uuid_index, ns); if (!err) nvme_show_id_ns(ns, 0, cfg.lba_format_index, true, flags); else if (err > 0) @@ -2884,14 +2789,16 @@ static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct p return err; } -static int id_endurance_grp_list(int argc, char **argv, struct command *cmd, +static int id_endurance_grp_list(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Show endurance group list information for the given endurance group id"; const char *endurance_grp_id = "Endurance Group ID"; _cleanup_free_ struct nvme_id_endurance_group_list *endgrp_list = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; int err = -1; @@ -2906,7 +2813,7 @@ static int id_endurance_grp_list(int argc, char **argv, struct command *cmd, NVME_ARGS(opts, OPT_SHRT("endgrp-id", 'i', &cfg.endgrp_id, endurance_grp_id)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -2920,18 +2827,20 @@ static int id_endurance_grp_list(int argc, char **argv, struct command *cmd, if (!endgrp_list) return -ENOMEM; - err = nvme_identify_endurance_group_list(dev_fd(dev), cfg.endgrp_id, endgrp_list); + nvme_init_identify_endurance_group_id(&cmd, cfg.endgrp_id, + endgrp_list); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) nvme_show_endurance_group_list(endgrp_list, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("Id endurance group list: %s", nvme_strerror(errno)); + nvme_show_error("Id endurance group list: %s", nvme_strerror(-err)); return err; } -static bool is_ns_mgmt_support(struct nvme_dev *dev) +static bool is_ns_mgmt_support(struct nvme_transport_handle *hdl) { int err; @@ -2940,17 +2849,17 @@ static bool is_ns_mgmt_support(struct nvme_dev *dev) if (ctrl) return false; - err = nvme_cli_identify_ctrl(dev, ctrl); + err = nvme_identify_ctrl(hdl, ctrl); if (err) return false; return le16_to_cpu(ctrl->oacs) & NVME_CTRL_OACS_NS_MGMT; } -static void ns_mgmt_show_status(struct nvme_dev *dev, int err, char *cmd, __u32 nsid) +static void ns_mgmt_show_status(struct nvme_transport_handle *hdl, int err, char *cmd, __u32 nsid) { if (err < 0) { - nvme_show_error("%s: %s", cmd, nvme_strerror(errno)); + nvme_show_error("%s: %s", cmd, nvme_strerror(-err)); return; } @@ -2961,14 +2870,14 @@ static void ns_mgmt_show_status(struct nvme_dev *dev, int err, char *cmd, __u32 nvme_show_key_value("nsid", "%d", nsid); } else { nvme_show_status(err); - if (!is_ns_mgmt_support(dev)) + if (!is_ns_mgmt_support(hdl)) nvme_show_error("NS management and attachment not supported"); } nvme_show_finish(); } -static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int delete_ns(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Delete the given namespace by " "sending a namespace management command to " @@ -2978,9 +2887,11 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin * "the namespace is not already inactive, once deleted."; const char *namespace_id = "namespace to delete"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - int err; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; + int err; struct config { __u32 namespace_id; @@ -2995,7 +2906,7 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin * NVME_ARGS(opts, OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -3006,45 +2917,49 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin * } if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); return err; } } - err = nvme_cli_ns_mgmt_delete(dev, cfg.namespace_id, nvme_cfg.timeout); - ns_mgmt_show_status(dev, err, cmd->name, cfg.namespace_id); + nvme_init_ns_mgmt_delete(&cmd, cfg.namespace_id); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); + ns_mgmt_show_status(hdl, err, acmd->name, cfg.namespace_id); return err; } -static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, struct command *cmd) +static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, struct command *acmd) { + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_free_ struct nvme_ctrl_list *cntlist = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - int err, num; __u16 list[NVME_ID_CTRL_LIST_MAX]; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; + int err, num; const char *namespace_id = "namespace to attach"; const char *cont = "optional comma-sep controller id list"; struct config { - __u32 namespace_id; + __u32 nsid; char *cntlist; }; struct config cfg = { - .namespace_id = 0, + .nsid = 0, .cntlist = "", }; NVME_ARGS(opts, - OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id), - OPT_LIST("controllers", 'c', &cfg.cntlist, cont)); + OPT_UINT("namespace-id", 'n', &cfg.nsid, namespace_id), + OPT_LIST("controllers", 'c', &cfg.cntlist, cont)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -3054,21 +2969,21 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s return err; } - if (is_blkdev(dev)) { - nvme_show_error("%s: a block device opened (dev: %s, nsid: %d)", cmd->name, - dev->name, cfg.namespace_id); + if (nvme_transport_handle_is_blkdev(hdl)) { + nvme_show_error("%s: a block device opened (dev: %s, nsid: %d)", acmd->name, + nvme_transport_handle_get_name(hdl), cfg.nsid); return -EINVAL; } - if (!cfg.namespace_id) { - nvme_show_error("%s: namespace-id parameter required", cmd->name); + if (!cfg.nsid) { + nvme_show_error("%s: namespace-id parameter required", acmd->name); return -EINVAL; } num = argconfig_parse_comma_sep_array_u16(cfg.cntlist, list, ARRAY_SIZE(list)); if (num == -1) { - nvme_show_error("%s: controller id list is malformed", cmd->name); + nvme_show_error("%s: controller id list is malformed", acmd->name); return -EINVAL; } @@ -3081,27 +2996,27 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s } else { struct nvme_id_ctrl ctrl = { 0 }; - if (nvme_cli_identify_ctrl(dev, &ctrl)) { - perror("identify-ctrl"); - return -errno; + err = nvme_identify_ctrl(hdl, &ctrl); + if (err) { + fprintf(stderr, "identify-ctrl %s\n", nvme_strerror(-err)); + return err; } cntlist->num = cpu_to_le16(1); cntlist->identifier[0] = ctrl.cntlid; } if (attach) - err = nvme_cli_ns_attach_ctrls(dev, cfg.namespace_id, - cntlist); + nvme_init_ns_attach_ctrls(&cmd, cfg.nsid, cntlist); else - err = nvme_cli_ns_detach_ctrls(dev, cfg.namespace_id, - cntlist); + nvme_init_ns_detach_ctrls(&cmd, cfg.nsid, cntlist); - ns_mgmt_show_status(dev, err, cmd->name, cfg.namespace_id); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); + ns_mgmt_show_status(hdl, err, acmd->name, cfg.nsid); return err; } -static int attach_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int attach_ns(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Attach the given namespace to the " "given controller or comma-sep list of controllers. ID of the " @@ -3109,20 +3024,20 @@ static int attach_ns(int argc, char **argv, struct command *cmd, struct plugin * "controller. A namespace must be attached to a controller " "before IO commands may be directed to that namespace."; - return nvme_attach_ns(argc, argv, 1, desc, cmd); + return nvme_attach_ns(argc, argv, 1, desc, acmd); } -static int detach_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int detach_ns(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Detach the given namespace from the " "given controller; de-activates the given namespace's ID. A " "namespace must be attached to a controller before IO " "commands may be directed to that namespace."; - return nvme_attach_ns(argc, argv, 0, desc, cmd); + return nvme_attach_ns(argc, argv, 0, desc, acmd); } -static int parse_lba_num_si(struct nvme_dev *dev, const char *opt, +static int parse_lba_num_si(struct nvme_transport_handle *hdl, const char *opt, const char *val, __u8 flbas, __u64 *num, __u64 align) { _cleanup_free_ struct nvme_ns_list *ns_list = NULL; @@ -3135,13 +3050,6 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt, int err = -EINVAL; int lbas; - struct nvme_identify_args args = { - .args_size = sizeof(args), - .timeout = nvme_cfg.timeout, - .cns = NVME_IDENTIFY_CNS_NS_ACTIVE_LIST, - .nsid = nsid - 1. - }; - if (!val) return 0; @@ -3156,10 +3064,10 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt, if (!ctrl) return -ENOMEM; - err = nvme_cli_identify_ctrl(dev, ctrl); + err = nvme_identify_ctrl(hdl, ctrl); if (err) { if (err < 0) - nvme_show_error("identify controller: %s", nvme_strerror(errno)); + nvme_show_error("identify controller: %s", nvme_strerror(-err)); else nvme_show_status(err); return err; @@ -3168,16 +3076,15 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt, ns_list = nvme_alloc(sizeof(*ns_list)); if (!ns_list) return -ENOMEM; - args.data = ns_list; - if ((ctrl->oacs & 0x8) >> 3) + if ((ctrl->oacs & 0x8) >> 3) { nsid = NVME_NSID_ALL; - else { - err = nvme_cli_identify(dev, &args); + } else { + err = nvme_identify_active_ns_list(hdl, nsid - 1, ns_list); if (err) { if (err < 0) nvme_show_error("identify namespace list: %s", - nvme_strerror(errno)); + nvme_strerror(-err)); else nvme_show_status(err); return err; @@ -3189,10 +3096,10 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt, if (!ns) return -ENOMEM; - err = nvme_cli_identify_ns(dev, nsid, ns); + err = nvme_identify_ns(hdl, nsid, ns); if (err) { if (err < 0) - nvme_show_error("identify namespace: %s", nvme_strerror(errno)); + nvme_show_error("identify namespace: %s", nvme_strerror(-err)); else nvme_show_status(err); return err; @@ -3201,10 +3108,11 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt, nvme_id_ns_flbas_to_lbaf_inuse(flbas, &lbaf); lbas = (1 << ns->lbaf[lbaf].ds) + le16_to_cpu(ns->lbaf[lbaf].ms); - if (suffix_si_parse(val, &endptr, (uint64_t *)num)) { + err = suffix_si_parse(val, &endptr, (uint64_t *)num); + if (err) { nvme_show_error("Expected long suffixed integer argument for '%s-si' but got '%s'!", opt, val); - return -errno; + return -err; } if (endptr[0]) { @@ -3219,7 +3127,7 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt, return 0; } -static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int create_ns(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send a namespace management command " "to the specified device to create a namespace with the given " @@ -3247,18 +3155,20 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin * "Requested Number of ZRWA Resources (RNUMZRWA) for Zoned Namespace Command Set"; const char *phndls = "Comma separated list of Placement Handle Associated RUH"; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ struct nvme_ns_mgmt_host_sw_specified *data = NULL; - _cleanup_free_ struct nvme_id_ns *ns = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - int err = 0, i; - __u32 nsid; - uint16_t num_phandle; - uint16_t phndl[128] = { 0, }; - _cleanup_free_ struct nvme_id_ctrl *id = NULL; _cleanup_free_ struct nvme_id_ns_granularity_list *gr_list = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_free_ struct nvme_id_ctrl *id = NULL; + _cleanup_free_ struct nvme_id_ns *ns = NULL; __u64 align_nsze = 1 << 20; /* Default 1 MiB */ __u64 align_ncap = align_nsze; + struct nvme_passthru_cmd cmd; + uint16_t phndl[128] = { 0, }; nvme_print_flags_t flags; + uint16_t num_phandle; + int err = 0, i; + __u32 nsid; struct config { __u64 nsze; @@ -3327,7 +3237,7 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin * OPT_UINT("rnumzrwa", 'u', &cfg.rnumzrwa, rnumzrwa), OPT_LIST("phndls", 'p', &cfg.phndls, phndls)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -3355,10 +3265,10 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin * if (!ns) return -ENOMEM; - err = nvme_cli_identify_ns(dev, NVME_NSID_ALL, ns); + err = nvme_identify_ns(hdl, NVME_NSID_ALL, ns); if (err) { if (err < 0) { - nvme_show_error("identify-namespace: %s", nvme_strerror(errno)); + nvme_show_error("identify-namespace: %s", nvme_strerror(-err)); } else { fprintf(stderr, "identify failed\n"); nvme_show_status(err); @@ -3385,10 +3295,10 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin * if (!id) return -ENOMEM; - err = nvme_identify_ctrl(dev_fd(dev), id); + err = nvme_identify_ctrl(hdl, id); if (err) { if (err < 0) { - nvme_show_error("identify-controller: %s", nvme_strerror(errno)); + nvme_show_error("identify-controller: %s", nvme_strerror(-err)); } else { fprintf(stderr, "identify controller failed\n"); nvme_show_status(err); @@ -3401,7 +3311,7 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin * if (!gr_list) return -ENOMEM; - if (!nvme_identify_ns_granularity(dev_fd(dev), gr_list)) { + if (!nvme_identify_ns_granularity(hdl, gr_list)) { struct nvme_id_ns_granularity_desc *desc; int index = cfg.flbas; @@ -3434,11 +3344,11 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin * } parse_lba: - err = parse_lba_num_si(dev, "nsze", cfg.nsze_si, cfg.flbas, &cfg.nsze, align_nsze); + err = parse_lba_num_si(hdl, "nsze", cfg.nsze_si, cfg.flbas, &cfg.nsze, align_nsze); if (err) return err; - err = parse_lba_num_si(dev, "ncap", cfg.ncap_si, cfg.flbas, &cfg.ncap, align_ncap); + err = parse_lba_num_si(hdl, "ncap", cfg.ncap_si, cfg.flbas, &cfg.ncap, align_ncap); if (err) return err; @@ -3475,8 +3385,9 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin * for (i = 0; i < num_phandle; i++) data->phndl[i] = cpu_to_le16(phndl[i]); - err = nvme_cli_ns_mgmt_create(dev, data, &nsid, nvme_cfg.timeout, cfg.csi); - ns_mgmt_show_status(dev, err, cmd->name, nsid); + nvme_init_ns_mgmt_create(&cmd, cfg.csi, data); + err = nvme_submit_admin_passthru(hdl, &cmd, &nsid); + ns_mgmt_show_status(hdl, err, acmd->name, nsid); return err; } @@ -3507,10 +3418,10 @@ static bool nvme_match_device_filter(nvme_subsystem_t s, return false; } -static int list_subsys(int argc, char **argv, struct command *cmd, +static int list_subsys(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - _cleanup_nvme_root_ nvme_root_t r = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; nvme_print_flags_t flags; const char *desc = "Retrieve information for subsystems"; nvme_scan_filter_t filter = NULL; @@ -3537,14 +3448,13 @@ static int list_subsys(int argc, char **argv, struct command *cmd, if (argconfig_parse_seen(opts, "verbose")) flags |= VERBOSE; - - r = nvme_create_root(stderr, log_level); - if (!r) { + ctx = nvme_create_global_ctx(stdout, log_level); + if (!ctx) { if (devname) nvme_show_error("Failed to scan nvme subsystem for %s", devname); else nvme_show_error("Failed to scan nvme subsystem"); - return -errno; + return -ENOMEM; } if (devname) { @@ -3557,22 +3467,22 @@ static int list_subsys(int argc, char **argv, struct command *cmd, filter = nvme_match_device_filter; } - err = nvme_scan_topology(r, filter, (void *)devname); + err = nvme_scan_topology(ctx, filter, (void *)devname); if (err) { - nvme_show_error("Failed to scan topology: %s", nvme_strerror(errno)); - return -errno; + nvme_show_error("Failed to scan topology: %s", nvme_strerror(-err)); + return err; } - nvme_show_subsystem_list(r, nsid != NVME_NSID_ALL, flags); + nvme_show_subsystem_list(ctx, nsid != NVME_NSID_ALL, flags); return 0; } -static int list(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int list(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve basic information for all NVMe namespaces"; nvme_print_flags_t flags; - _cleanup_nvme_root_ nvme_root_t r = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; int err = 0; NVME_ARGS(opts); @@ -3590,23 +3500,23 @@ static int list(int argc, char **argv, struct command *cmd, struct plugin *plugi if (argconfig_parse_seen(opts, "verbose")) flags |= VERBOSE; - r = nvme_create_root(stderr, log_level); - if (!r) { + ctx = nvme_create_global_ctx(stdout, log_level); + if (!ctx) { nvme_show_error("Failed to create topology root: %s", nvme_strerror(errno)); - return -errno; + return -ENOMEM; } - err = nvme_scan_topology(r, NULL, NULL); + err = nvme_scan_topology(ctx, NULL, NULL); if (err < 0) { - nvme_show_error("Failed to scan topology: %s", nvme_strerror(errno)); + nvme_show_error("Failed to scan topology: %d", nvme_strerror(-err)); return err; } - nvme_show_list_items(r, flags); + nvme_show_list_items(ctx, flags); return err; } -int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin, +int __id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin, void (*vs)(__u8 *vs, struct json_object *root)) { const char *desc = "Send an Identify Controller command to " @@ -3617,7 +3527,8 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin, const char *vendor_specific = "dump binary vendor field"; _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err; @@ -3638,7 +3549,7 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin, OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_identify), OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_identify)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -3661,23 +3572,23 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin, if (!ctrl) return -ENOMEM; - err = nvme_cli_identify_ctrl(dev, ctrl); + err = nvme_identify_ctrl(hdl, ctrl); if (!err) nvme_show_id_ctrl(ctrl, flags, vs); else if (err > 0) nvme_show_status(err); else - nvme_show_error("identify controller: %s", nvme_strerror(errno)); + nvme_show_error("identify controller: %s", nvme_strerror(-err)); return err; } -static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return __id_ctrl(argc, argv, cmd, plugin, NULL); + return __id_ctrl(argc, argv, acmd, plugin, NULL); } -static int nvm_id_ctrl(int argc, char **argv, struct command *cmd, +static int nvm_id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send an Identify Controller NVM Command Set " @@ -3685,13 +3596,15 @@ static int nvm_id_ctrl(int argc, char **argv, struct command *cmd, "the specified controller in various formats."; _cleanup_free_ struct nvme_id_ctrl_nvm *ctrl_nvm = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; int err = -1; NVME_ARGS(opts); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -3708,18 +3621,19 @@ static int nvm_id_ctrl(int argc, char **argv, struct command *cmd, if (!ctrl_nvm) return -ENOMEM; - err = nvme_nvm_identify_ctrl(dev_fd(dev), ctrl_nvm); + nvme_init_identify_csi_ctrl(&cmd, NVME_CSI_NVM, ctrl_nvm); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) nvme_show_id_ctrl_nvm(ctrl_nvm, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("nvm identify controller: %s", nvme_strerror(errno)); + nvme_show_error("nvm identify controller: %s", nvme_strerror(-err)); return err; } -static int nvm_id_ns(int argc, char **argv, struct command *cmd, +static int nvm_id_ns(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send an Identify Namespace NVM Command Set " @@ -3728,7 +3642,8 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd, _cleanup_free_ struct nvme_nvm_id_ns *id_ns = NULL; _cleanup_free_ struct nvme_id_ns *ns = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err = -1; @@ -3746,7 +3661,7 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd, OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired), OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -3760,7 +3675,7 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd, flags |= VERBOSE; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { nvme_show_perror("get-namespace-id"); return err; @@ -3771,7 +3686,7 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd, if (!ns) return -ENOMEM; - err = nvme_cli_identify_ns(dev, cfg.namespace_id, ns); + err = nvme_identify_ns(hdl, cfg.namespace_id, ns); if (err) { nvme_show_status(err); return err; @@ -3781,9 +3696,8 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd, if (!id_ns) return -ENOMEM; - err = nvme_identify_ns_csi(dev_fd(dev), cfg.namespace_id, - cfg.uuid_index, - NVME_CSI_NVM, id_ns); + err = nvme_identify_csi_ns(hdl, cfg.namespace_id, NVME_CSI_NVM, + cfg.uuid_index, id_ns); if (!err) nvme_show_nvm_id_ns(id_ns, cfg.namespace_id, ns, 0, false, flags); else if (err > 0) @@ -3794,7 +3708,7 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd, return err; } -static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int nvm_id_ns_lba_format(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send an NVM Command Set specific Identify Namespace " "command to the given device, returns capability field properties of " @@ -3802,7 +3716,8 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru _cleanup_free_ struct nvme_nvm_id_ns *nvm_ns = NULL; _cleanup_free_ struct nvme_id_ns *ns = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err = -1; @@ -3820,7 +3735,7 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru OPT_UINT("lba-format-index", 'i', &cfg.lba_format_index, lba_format_index), OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -3837,7 +3752,7 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru if (!ns) return -ENOMEM; - err = nvme_cli_identify_ns(dev, NVME_NSID_ALL, ns); + err = nvme_identify_ns(hdl, NVME_NSID_ALL, ns); if (err) { ns->nlbaf = NVME_FEAT_LBA_RANGE_MAX - 1; ns->nulbaf = 0; @@ -3847,8 +3762,9 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru if (!nvm_ns) return -ENOMEM; - err = nvme_identify_iocs_ns_csi_user_data_format(dev_fd(dev), cfg.lba_format_index, - cfg.uuid_index, NVME_CSI_NVM, nvm_ns); + err = nvme_identify_csi_ns_user_data_format(hdl, NVME_CSI_NVM, + cfg.lba_format_index, + cfg.uuid_index, nvm_ns); if (!err) nvme_show_nvm_id_ns(nvm_ns, 0, ns, cfg.lba_format_index, true, flags); else if (err > 0) @@ -3859,14 +3775,15 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru return err; } -static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int ns_descs(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send Namespace Identification Descriptors command to the " "given device, returns the namespace identification descriptors " "of the specific namespace in either human-readable or binary format."; const char *raw = "show descriptors in binary format"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ void *nsdescs = NULL; nvme_print_flags_t flags; int err; @@ -3885,7 +3802,7 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired), OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -3902,9 +3819,9 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p flags |= VERBOSE; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); return err; } } @@ -3913,18 +3830,18 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p if (!nsdescs) return -ENOMEM; - err = nvme_cli_identify_ns_descs(dev, cfg.namespace_id, nsdescs); + err = nvme_identify_ns_descs_list(hdl, cfg.namespace_id, nsdescs); if (!err) nvme_show_id_ns_descs(nsdescs, cfg.namespace_id, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("identify namespace: %s", nvme_strerror(errno)); + nvme_show_error("identify namespace: %s", nvme_strerror(-err)); return err; } -static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int id_ns(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send an Identify Namespace command to the " "given device, returns properties of the specified namespace " @@ -3933,8 +3850,10 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug const char *force = "Return this namespace, even if not attached (1.2 devices only)"; const char *vendor_specific = "dump binary vendor fields"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ struct nvme_id_ns *ns = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; int err; @@ -3961,7 +3880,7 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_identify), OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_identify)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -3981,9 +3900,9 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug flags |= VERBOSE; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); return err; } } @@ -3992,22 +3911,24 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug if (!ns) return -ENOMEM; - if (cfg.force) - err = nvme_cli_identify_allocated_ns(dev, cfg.namespace_id, ns); - else - err = nvme_cli_identify_ns(dev, cfg.namespace_id, ns); + if (cfg.force) { + nvme_init_identify_allocated_ns(&cmd, cfg.namespace_id, ns); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); + } else { + err = nvme_identify_ns(hdl, cfg.namespace_id, ns); + } if (!err) nvme_show_id_ns(ns, cfg.namespace_id, 0, false, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("identify namespace: %s", nvme_strerror(errno)); + nvme_show_error("identify namespace: %s", nvme_strerror(-err)); return err; } -static int cmd_set_independent_id_ns(int argc, char **argv, struct command *cmd, +static int cmd_set_independent_id_ns(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send an I/O Command Set Independent Identify " @@ -4015,7 +3936,9 @@ static int cmd_set_independent_id_ns(int argc, char **argv, struct command *cmd, "specified namespace in human-readable or binary or json format."; _cleanup_free_ struct nvme_id_independent_id_ns *ns = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; int err = -1; @@ -4036,7 +3959,7 @@ static int cmd_set_independent_id_ns(int argc, char **argv, struct command *cmd, OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_identify), OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_identify)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -4053,7 +3976,7 @@ static int cmd_set_independent_id_ns(int argc, char **argv, struct command *cmd, flags |= VERBOSE; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { nvme_show_perror("get-namespace-id"); return err; @@ -4064,32 +3987,35 @@ static int cmd_set_independent_id_ns(int argc, char **argv, struct command *cmd, if (!ns) return -ENOMEM; - err = nvme_identify_independent_identify_ns(dev_fd(dev), cfg.namespace_id, ns); + nvme_init_identify_csi_independent_identify_id_ns(&cmd, + cfg.namespace_id, ns); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) nvme_show_cmd_set_independent_id_ns(ns, cfg.namespace_id, flags); else if (err > 0) nvme_show_status(err); else nvme_show_error("I/O command set independent identify namespace: %s", - nvme_strerror(errno)); + nvme_strerror(-err)); return err; } -static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int id_ns_granularity(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send an Identify Namespace Granularity List command to the " "given device, returns namespace granularity list " "in either human-readable or binary format."; _cleanup_free_ struct nvme_id_ns_granularity_list *granularity_list = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err; NVME_ARGS(opts); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -4103,18 +4029,18 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct if (!granularity_list) return -ENOMEM; - err = nvme_identify_ns_granularity(dev_fd(dev), granularity_list); + err = nvme_identify_ns_granularity(hdl, granularity_list); if (!err) nvme_show_id_ns_granularity_list(granularity_list, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("identify namespace granularity: %s", nvme_strerror(errno)); + nvme_show_error("identify namespace granularity: %s", nvme_strerror(-err)); return err; } -static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int id_nvmset(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send an Identify NVM Set List command to the " "given device, returns entries for NVM Set identifiers greater " @@ -4123,7 +4049,9 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin * const char *nvmset_id = "NVM Set Identify value"; _cleanup_free_ struct nvme_id_nvmset_list *nvmset = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; int err; @@ -4138,7 +4066,7 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin * NVME_ARGS(opts, OPT_SHRT("nvmset_id", 'i', &cfg.nvmset_id, nvmset_id)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -4152,18 +4080,20 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin * if (!nvmset) return -ENOMEM; - err = nvme_identify_nvmset_list(dev_fd(dev), cfg.nvmset_id, nvmset); + nvme_init_identify_nvmset_list(&cmd, NVME_NSID_NONE, + cfg.nvmset_id, nvmset); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) nvme_show_id_nvmset(nvmset, cfg.nvmset_id, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("identify nvm set list: %s", nvme_strerror(errno)); + nvme_show_error("identify nvm set list: %s", nvme_strerror(-err)); return err; } -static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int id_uuid(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send an Identify UUID List command to the " "given device, returns list of supported Vendor Specific UUIDs " @@ -4172,7 +4102,8 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl const char *human_readable = "show uuid in readable format"; _cleanup_free_ struct nvme_id_uuid_list *uuid_list = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err; @@ -4190,7 +4121,7 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw), OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -4210,18 +4141,18 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl if (!uuid_list) return -ENOMEM; - err = nvme_identify_uuid(dev_fd(dev), uuid_list); + err = nvme_identify_uuid_list(hdl, uuid_list); if (!err) nvme_show_id_uuid_list(uuid_list, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("identify UUID list: %s", nvme_strerror(errno)); + nvme_show_error("identify UUID list: %s", nvme_strerror(-err)); return err; } -static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int id_iocs(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send an Identify Command Set Data command to " "the given device, returns properties of the specified controller " @@ -4229,7 +4160,9 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl const char *controller_id = "identifier of desired controller"; _cleanup_free_ struct nvme_id_iocs *iocs = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; int err; @@ -4244,7 +4177,7 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl NVME_ARGS(opts, OPT_SHRT("controller-id", 'c', &cfg.cntid, controller_id)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -4261,20 +4194,21 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl if (!iocs) return -ENOMEM; - err = nvme_identify_iocs(dev_fd(dev), cfg.cntid, iocs); + nvme_init_identify_command_set_structure(&cmd, cfg.cntid, iocs); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) { printf("NVMe Identify I/O Command Set:\n"); nvme_show_id_iocs(iocs, flags); } else if (err > 0) { nvme_show_status(err); } else { - nvme_show_error("NVMe Identify I/O Command Set: %s", nvme_strerror(errno)); + nvme_show_error("NVMe Identify I/O Command Set: %s", nvme_strerror(-err)); } return err; } -static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int id_domain(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send an Identify Domain List command to the " "given device, returns properties of the specified domain " @@ -4282,7 +4216,9 @@ static int id_domain(int argc, char **argv, struct command *cmd, struct plugin * const char *domain_id = "identifier of desired domain"; _cleanup_free_ struct nvme_id_domain_list *id_domain = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; int err; @@ -4297,7 +4233,7 @@ static int id_domain(int argc, char **argv, struct command *cmd, struct plugin * NVME_ARGS(opts, OPT_SHRT("dom-id", 'd', &cfg.dom_id, domain_id)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -4311,7 +4247,8 @@ static int id_domain(int argc, char **argv, struct command *cmd, struct plugin * if (!id_domain) return -ENOMEM; - err = nvme_identify_domain_list(dev_fd(dev), cfg.dom_id, id_domain); + nvme_init_identify_domain_list(&cmd, cfg.dom_id, id_domain); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) { printf("NVMe Identify command for Domain List is successful:\n"); printf("NVMe Identify Domain List:\n"); @@ -4319,24 +4256,25 @@ static int id_domain(int argc, char **argv, struct command *cmd, struct plugin * } else if (err > 0) { nvme_show_status(err); } else { - nvme_show_error("NVMe Identify Domain List: %s", nvme_strerror(errno)); + nvme_show_error("NVMe Identify Domain List: %s", nvme_strerror(-err)); } return err; } -static int get_ns_id(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_ns_id(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get namespace ID of a the block device."; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; unsigned int nsid; int err; nvme_print_flags_t flags; NVME_ARGS(opts); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -4346,18 +4284,18 @@ static int get_ns_id(int argc, char **argv, struct command *cmd, struct plugin * return err; } - err = nvme_get_nsid(dev_fd(dev), &nsid); + err = nvme_get_nsid(hdl, &nsid); if (err < 0) { - nvme_show_error("get namespace ID: %s", nvme_strerror(errno)); - return -errno; + nvme_show_error("get namespace ID: %s", nvme_strerror(-err)); + return err; } - printf("%s: namespace-id:%d\n", dev->name, nsid); + printf("%s: namespace-id:%d\n", nvme_transport_handle_get_name(hdl), nsid); return 0; } -static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int virtual_mgmt(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "The Virtualization Management command is supported by primary controllers " "that support the Virtualization Enhancements capability. This command is used for:\n" @@ -4375,7 +4313,9 @@ static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugi "9h: Secondary Online"; const char *nr = "Number of Controller Resources(NR)"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; __u32 result; int err; @@ -4399,32 +4339,23 @@ static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugi OPT_BYTE("act", 'a', &cfg.act, act), OPT_SHRT("nr", 'n', &cfg.nr, nr)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - struct nvme_virtual_mgmt_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .act = cfg.act, - .rt = cfg.rt, - .cntlid = cfg.cntlid, - .nr = cfg.nr, - .timeout = nvme_cfg.timeout, - .result = &result, - }; - err = nvme_virtual_mgmt(&args); + nvme_init_virtual_mgmt(&cmd, cfg.act, cfg.rt, cfg.cntlid, cfg.nr); + err = nvme_submit_admin_passthru(hdl, &cmd, &result); if (!err) printf("success, Number of Controller Resources Modified (NRM):%#x\n", result); else if (err > 0) nvme_show_status(err); else - nvme_show_error("virt-mgmt: %s", nvme_strerror(errno)); + nvme_show_error("virt-mgmt: %s", nvme_strerror(-err)); return err; } -static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int primary_ctrl_caps(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *cntlid = "Controller ID"; const char *desc = "Send an Identify Primary Controller Capabilities " @@ -4432,7 +4363,9 @@ static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct "decoded format (default), json or binary."; _cleanup_free_ struct nvme_primary_ctrl_cap *caps = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; int err; @@ -4450,7 +4383,7 @@ static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct OPT_UINT("cntlid", 'c', &cfg.cntlid, cntlid), OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_info)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -4467,19 +4400,20 @@ static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct if (!caps) return -ENOMEM; - err = nvme_cli_identify_primary_ctrl(dev, cfg.cntlid, caps); + nvme_init_identify_primary_ctrl_cap(&cmd, cfg.cntlid, caps); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) nvme_show_primary_ctrl_cap(caps, flags); else if (err > 0) nvme_show_status(err); else nvme_show_error("identify primary controller capabilities: %s", - nvme_strerror(errno)); + nvme_strerror(-err)); return err; } -static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int list_secondary_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Show secondary controller list associated with the primary controller of the given device."; @@ -4487,7 +4421,9 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc const char *num_entries = "number of entries to retrieve"; _cleanup_free_ struct nvme_secondary_ctrl_list *sc_list = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; int err; @@ -4505,7 +4441,7 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc OPT_SHRT("cntid", 'c', &cfg.cntid, controller), OPT_UINT("num-entries", 'e', &cfg.num_entries, num_entries)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -4524,13 +4460,14 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc if (!sc_list) return -ENOMEM; - err = nvme_cli_identify_secondary_ctrl_list(dev, cfg.cntid, sc_list); + nvme_init_identify_secondary_ctrl_list(&cmd, cfg.cntid, sc_list); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) nvme_show_list_secondary_ctrl(sc_list, cfg.num_entries, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("id secondary controller list: %s", nvme_strerror(errno)); + nvme_show_error("id secondary controller list: %s", nvme_strerror(-err)); return err; } @@ -4549,7 +4486,7 @@ static int sleep_self_test(unsigned int seconds) return 0; } -static int wait_self_test(struct nvme_dev *dev) +static int wait_self_test(struct nvme_transport_handle *hdl) { static const char spin[] = {'-', '\\', '|', '/' }; _cleanup_free_ struct nvme_self_test_log *log = NULL; @@ -4565,9 +4502,9 @@ static int wait_self_test(struct nvme_dev *dev) if (!log) return -ENOMEM; - err = nvme_cli_identify_ctrl(dev, ctrl); + err = nvme_identify_ctrl(hdl, ctrl); if (err) { - nvme_show_error("identify-ctrl: %s", nvme_strerror(errno)); + nvme_show_error("identify-ctrl: %s", nvme_strerror(-err)); return err; } @@ -4581,7 +4518,7 @@ static int wait_self_test(struct nvme_dev *dev) if (err) return err; - err = nvme_cli_get_log_device_self_test(dev, log); + err = nvme_get_log_device_self_test(hdl, log); if (err) { printf("\n"); if (err < 0) @@ -4616,22 +4553,22 @@ static int wait_self_test(struct nvme_dev *dev) return 0; } -static void abort_self_test(struct nvme_dev_self_test_args *args) +static void abort_self_test(struct nvme_transport_handle *hdl, __u32 nsid) { + struct nvme_passthru_cmd cmd; int err; - args->stc = NVME_DST_STC_ABORT; - - err = nvme_dev_self_test(args); + nvme_init_dev_self_test(&cmd, nsid, NVME_DST_STC_ABORT); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) printf("Aborting device self-test operation\n"); else if (err > 0) nvme_show_status(err); else - nvme_show_error("Device self-test: %s", nvme_strerror(errno)); + nvme_show_error("Device self-test: %s", nvme_strerror(-err)); } -static int device_self_test(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int device_self_test(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Implementing the device self-test feature " "which provides the necessary log to determine the state of the device"; @@ -4647,9 +4584,11 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p "fh Abort the device self-test operation"; const char *wait = "Wait for the test to finish"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - int err; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; + int err; struct config { __u32 namespace_id; @@ -4668,7 +4607,7 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p OPT_BYTE("self-test-code", 's', &cfg.stc, self_test_code), OPT_FLAG("wait", 'w', &cfg.wait, wait)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -4685,7 +4624,7 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p if (!log) return -ENOMEM; - err = nvme_cli_get_log_device_self_test(dev, log); + err = nvme_get_log_device_self_test(hdl, log); if (err) { printf("\n"); if (err < 0) @@ -4698,7 +4637,7 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p printf("no self test running\n"); } else { if (cfg.wait) - err = wait_self_test(dev); + err = wait_self_test(hdl); else printf("progress %d%%\n", log->completion); } @@ -4706,15 +4645,8 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p goto check_abort; } - struct nvme_dev_self_test_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .stc = cfg.stc, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - err = nvme_dev_self_test(&args); + nvme_init_dev_self_test(&cmd, cfg.namespace_id, cfg.stc); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) { if (cfg.stc == NVME_ST_CODE_ABORT) printf("Aborting device self-test operation\n"); @@ -4726,21 +4658,21 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p printf("Host-Initiated Refresh started\n"); if (cfg.wait && cfg.stc != NVME_ST_CODE_ABORT) - err = wait_self_test(dev); + err = wait_self_test(hdl); } else if (err > 0) { nvme_show_status(err); } else { - nvme_show_error("Device self-test: %s", nvme_strerror(errno)); + nvme_show_error("Device self-test: %s", nvme_strerror(-err)); } check_abort: if (err == -EINTR) - abort_self_test(&args); + abort_self_test(hdl, cfg.namespace_id); return err; } -static int self_test_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int self_test_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve the self-test log for the given device and given test " "(or optionally a namespace) in either decoded format (default) or binary."; @@ -4748,7 +4680,8 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug "by default all the 20 entries will be retrieved"; _cleanup_free_ struct nvme_self_test_log *log = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err; @@ -4763,7 +4696,7 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug NVME_ARGS(opts, OPT_BYTE("dst-entries", 'e', &cfg.dst_entries, dst_entries)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -4780,22 +4713,23 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug if (!log) return -ENOMEM; - err = nvme_cli_get_log_device_self_test(dev, log); + err = nvme_get_log_device_self_test(hdl, log); if (!err) - nvme_show_self_test_log(log, cfg.dst_entries, 0, dev->name, flags); + nvme_show_self_test_log(log, cfg.dst_entries, 0, nvme_transport_handle_get_name(hdl), flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("self test log: %s", nvme_strerror(errno)); + nvme_show_error("self test log: %s", nvme_strerror(-err)); return err; } -static int get_feature_id(struct nvme_dev *dev, struct feat_cfg *cfg, +static int get_feature_id(struct nvme_transport_handle *hdl, struct feat_cfg *cfg, void **buf, __u32 *result) { if (!cfg->data_len) nvme_get_feature_length(cfg->feature_id, cfg->cdw11, + NVME_DATA_TFR_CTRL_TO_HOST, &cfg->data_len); if (cfg->feature_id == NVME_FEAT_FID_FDP_EVENTS) { @@ -4812,19 +4746,8 @@ static int get_feature_id(struct nvme_dev *dev, struct feat_cfg *cfg, return -1; } - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fid = cfg->feature_id, - .nsid = cfg->namespace_id, - .sel = cfg->sel, - .cdw11 = cfg->cdw11, - .uuidx = cfg->uuid_index, - .data_len = cfg->data_len, - .data = *buf, - .timeout = nvme_cfg.timeout, - .result = result, - }; - return nvme_cli_get_features(dev, &args); + return nvme_get_features(hdl, cfg->namespace_id, cfg->feature_id, cfg->sel, + cfg->cdw11, cfg->uuid_index, *buf, cfg->data_len, result); } static int filter_out_flags(int status) @@ -4856,7 +4779,7 @@ static void get_feature_id_print(struct feat_cfg cfg, int err, __u32 result, !nvme_status_equals(status, type, NVME_SC_INVALID_NS)) nvme_show_status(err); } else { - nvme_show_error("get-feature: %s", nvme_strerror(errno)); + nvme_show_error("get-feature: %s", nvme_strerror(-err)); } } @@ -4872,7 +4795,7 @@ static bool is_get_feature_result_set(enum nvme_features_id feature_id) return true; } -static int get_feature_id_changed(struct nvme_dev *dev, struct feat_cfg cfg, +static int get_feature_id_changed(struct nvme_transport_handle *hdl, struct feat_cfg cfg, nvme_print_flags_t flags) { int err; @@ -4885,11 +4808,11 @@ static int get_feature_id_changed(struct nvme_dev *dev, struct feat_cfg cfg, if (cfg.changed) cfg.sel = NVME_GET_FEATURES_SEL_CURRENT; - err = get_feature_id(dev, &cfg, &buf, &result); + err = get_feature_id(hdl, &cfg, &buf, &result); if (!err && cfg.changed) { cfg.sel = NVME_GET_FEATURES_SEL_DEFAULT; - err_def = get_feature_id(dev, &cfg, &buf_def, &result_def); + err_def = get_feature_id(hdl, &cfg, &buf_def, &result_def); } if (!err && !is_get_feature_result_set(cfg.feature_id)) @@ -4902,7 +4825,7 @@ static int get_feature_id_changed(struct nvme_dev *dev, struct feat_cfg cfg, return err; } -static int get_feature_ids(struct nvme_dev *dev, struct feat_cfg cfg, +static int get_feature_ids(struct nvme_transport_handle *hdl, struct feat_cfg cfg, nvme_print_flags_t flags) { int err = 0; @@ -4917,7 +4840,7 @@ static int get_feature_ids(struct nvme_dev *dev, struct feat_cfg cfg, for (i = cfg.feature_id; i < feat_max; i++, feat_num++) { cfg.feature_id = i; - err = get_feature_id_changed(dev, cfg, flags); + err = get_feature_id_changed(hdl, cfg, flags); if (!err) continue; status = filter_out_flags(err); @@ -4935,7 +4858,7 @@ static int get_feature_ids(struct nvme_dev *dev, struct feat_cfg cfg, return err; } -static int get_feature(int argc, char **argv, struct command *cmd, +static int get_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Read operating parameters of the " @@ -4955,7 +4878,8 @@ static int get_feature(int argc, char **argv, struct command *cmd, const char *changed = "show feature changed"; nvme_print_flags_t flags = NORMAL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; struct feat_cfg cfg = { @@ -4980,7 +4904,7 @@ static int get_feature(int argc, char **argv, struct command *cmd, OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable), OPT_FLAG("changed", 'C', &cfg.changed, changed)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -4991,10 +4915,10 @@ static int get_feature(int argc, char **argv, struct command *cmd, } if (!argconfig_parse_seen(opts, "namespace-id")) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { - if (errno != ENOTTY) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + if (err != -ENOTTY) { + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); return err; } cfg.namespace_id = NVME_NSID_ALL; @@ -5016,7 +4940,7 @@ static int get_feature(int argc, char **argv, struct command *cmd, nvme_show_init(); - err = get_feature_ids(dev, cfg, flags); + err = get_feature_ids(hdl, cfg, flags); nvme_show_finish(); @@ -5028,11 +4952,12 @@ static int get_feature(int argc, char **argv, struct command *cmd, * errors. Returns -1 on (fatal) error; signifying that the transfer should * be aborted. */ -static int fw_download_single(struct nvme_dev *dev, void *fw_buf, +static int fw_download_single(struct nvme_transport_handle *hdl, void *fw_buf, unsigned int fw_len, uint32_t offset, uint32_t len, bool progress, bool ignore_ovr) { const unsigned int max_retries = 3; + struct nvme_passthru_cmd cmd; bool retryable, ovr; int err, try; @@ -5041,22 +4966,17 @@ static int fw_download_single(struct nvme_dev *dev, void *fw_buf, offset, fw_len, (int)(100 * offset / fw_len)); } - struct nvme_fw_download_args args = { - .args_size = sizeof(args), - .offset = offset, - .data_len = len, - .data = fw_buf, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - for (try = 0; try < max_retries; try++) { if (try > 0) { fprintf(stderr, "retrying offset %x (%u/%u)\n", offset, try, max_retries); } - err = nvme_cli_fw_download(dev, &args); + err = nvme_init_fw_download(&cmd, fw_buf, len, offset); + if (err) + return err; + + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) return 0; @@ -5093,7 +5013,7 @@ static int fw_download_single(struct nvme_dev *dev, void *fw_buf, offset, fw_len); if (err < 0) { - fprintf(stderr, "fw-download: %s\n", nvme_strerror(errno)); + fprintf(stderr, "fw-download: %s\n", nvme_strerror(-err)); } else { nvme_show_status(err); if (ovr) { @@ -5120,7 +5040,7 @@ static int fw_download_single(struct nvme_dev *dev, void *fw_buf, return -1; } -static int fw_download(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int fw_download(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Copy all or part of a firmware image to " "a controller for future update. Optionally, specify how " @@ -5136,7 +5056,8 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin const char *progress = "display firmware transfer progress"; const char *ignore_ovr = "ignore overwrite errors"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; _cleanup_fd_ int fw_fd = -1; unsigned int fw_size, pos; @@ -5169,7 +5090,7 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin OPT_FLAG("progress", 'p', &cfg.progress, progress), OPT_FLAG("ignore-ovr", 'i', &cfg.ignore_ovr, ignore_ovr)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -5199,9 +5120,9 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin } if (cfg.xfer == 0) { - err = nvme_cli_identify_ctrl(dev, &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) { - nvme_show_error("identify-ctrl: %s", nvme_strerror(errno)); + nvme_show_error("identify-ctrl: %s", nvme_strerror(-err)); return err; } if (ctrl.fwug == 0 || ctrl.fwug == 0xff) @@ -5230,7 +5151,7 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin for (pos = 0; pos < fw_size; pos += cfg.xfer) { cfg.xfer = min(cfg.xfer, fw_size - pos); - err = fw_download_single(dev, fw_buf + pos, fw_size, + err = fw_download_single(hdl, fw_buf + pos, fw_size, cfg.offset + pos, cfg.xfer, cfg.progress, cfg.ignore_ovr); if (err) @@ -5261,7 +5182,7 @@ static char *nvme_fw_status_reset_type(__u16 status) } } -static bool fw_commit_support_mud(struct nvme_dev *dev) +static bool fw_commit_support_mud(struct nvme_transport_handle *hdl) { _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL; int err; @@ -5270,19 +5191,18 @@ static bool fw_commit_support_mud(struct nvme_dev *dev) if (!ctrl) return false; - err = nvme_cli_identify_ctrl(dev, ctrl); - + err = nvme_identify_ctrl(hdl, ctrl); if (err) - nvme_show_error("identify-ctrl: %s", nvme_strerror(errno)); + nvme_show_error("identify-ctrl: %s", nvme_strerror(-err)); else if (ctrl->frmw >> 5 & 0x1) return true; return false; } -static void fw_commit_print_mud(struct nvme_dev *dev, __u32 result) +static void fw_commit_print_mud(struct nvme_transport_handle *hdl, __u32 result) { - if (!fw_commit_support_mud(dev)) + if (!fw_commit_support_mud(hdl)) return; printf("Multiple Update Detected (MUD) Value: %u\n", result); @@ -5296,7 +5216,7 @@ static void fw_commit_print_mud(struct nvme_dev *dev, __u32 result) "sequence due to processing a command from a Management Endpoint\n"); } -static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int fw_commit(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Verify downloaded firmware image and " "commit to specific firmware slot. Device is not automatically " @@ -5307,7 +5227,9 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin * const char *action = "[0-7]: commit action"; const char *bpid = "[0,1]: boot partition identifier, if applicable (default: 0)"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; __u32 result; int err; nvme_print_flags_t flags; @@ -5329,7 +5251,7 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin * OPT_BYTE("action", 'a', &cfg.action, action), OPT_BYTE("bpid", 'b', &cfg.bpid, bpid)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -5352,19 +5274,11 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin * return -EINVAL; } - struct nvme_fw_commit_args args = { - .args_size = sizeof(args), - .slot = cfg.slot, - .action = cfg.action, - .bpid = cfg.bpid, - .timeout = nvme_cfg.timeout, - .result = &result, - }; - err = nvme_cli_fw_commit(dev, &args); - + nvme_init_fw_commit(&cmd, cfg.slot, cfg.action, cfg.bpid); + err = nvme_submit_admin_passthru(hdl, &cmd, &result); if (err < 0) { - nvme_show_error("fw-commit: %s", nvme_strerror(errno)); - } else if (err != 0) { + nvme_show_error("fw-commit: %s", nvme_strerror(-err)); + } else if (err > 0) { __u32 val = nvme_status_get_value(err); int type = nvme_status_get_type(err); @@ -5393,70 +5307,73 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin * if (cfg.action == 6 || cfg.action == 7) printf(" bpid:%d", cfg.bpid); printf("\n"); - fw_commit_print_mud(dev, result); + fw_commit_print_mud(hdl, result); } return err; } -static int subsystem_reset(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int subsystem_reset(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Resets the NVMe subsystem"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; NVME_ARGS(opts); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = nvme_subsystem_reset(dev_fd(dev)); + err = nvme_subsystem_reset(hdl); if (err < 0) { - if (errno == ENOTTY) + if (err == -ENOTTY) nvme_show_error("Subsystem-reset: NVM Subsystem Reset not supported."); else - nvme_show_error("Subsystem-reset: %s", nvme_strerror(errno)); + nvme_show_error("Subsystem-reset: %s", nvme_strerror(-err)); } else if (argconfig_parse_seen(opts, "verbose")) - printf("resetting subsystem through %s\n", dev->name); + printf("resetting subsystem through %s\n", nvme_transport_handle_get_name(hdl)); return err; } -static int reset(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int reset(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Resets the NVMe controller\n"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; NVME_ARGS(opts); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = nvme_ctrl_reset(dev_fd(dev)); + err = nvme_ctrl_reset(hdl); if (err < 0) - nvme_show_error("Reset: %s", nvme_strerror(errno)); + nvme_show_error("Reset: %s", nvme_strerror(-err)); else if (argconfig_parse_seen(opts, "verbose")) - printf("resetting controller %s\n", dev->name); + printf("resetting controller %s\n", nvme_transport_handle_get_name(hdl)); return err; } -static int ns_rescan(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int ns_rescan(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Rescans the NVMe namespaces\n"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; nvme_print_flags_t flags; NVME_ARGS(opts); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -5466,16 +5383,16 @@ static int ns_rescan(int argc, char **argv, struct command *cmd, struct plugin * return err; } - err = nvme_ns_rescan(dev_fd(dev)); + err = nvme_ns_rescan(hdl); if (err < 0) - nvme_show_error("Namespace Rescan: %s\n", nvme_strerror(errno)); + nvme_show_error("Namespace Rescan: %s\n", nvme_strerror(-err)); else if (argconfig_parse_seen(opts, "verbose")) - printf("rescanning namespaces through %s\n", dev->name); + printf("rescanning namespaces through %s\n", nvme_transport_handle_get_name(hdl)); return err; } -static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int sanitize_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send a sanitize command."; const char *emvs_desc = "Enter media verification state."; @@ -5487,9 +5404,11 @@ static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugi "3 = Start overwrite, 4 = Start crypto erase, 5 = Exit media verification"; const char *ovrpat_desc = "Overwrite pattern."; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - int err; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; + int err; struct config { bool no_dealloc; @@ -5529,7 +5448,7 @@ static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugi OPT_UINT("ovrpat", 'p', &cfg.ovrpat, ovrpat_desc), OPT_FLAG("emvs", 'e', &cfg.emvs, emvs_desc)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -5573,39 +5492,24 @@ static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugi } } - struct nvme_sanitize_nvm_args args = { - .args_size = sizeof(args), - .sanact = cfg.sanact, - .ause = cfg.ause, - .owpass = cfg.owpass, - .oipbp = cfg.oipbp, - .nodas = cfg.no_dealloc, - .ovrpat = cfg.ovrpat, - .result = NULL, - .emvs = cfg.emvs, - }; - - err = nvme_cli_sanitize_nvm(dev, &args); + nvme_init_sanitize_nvm(&cmd, cfg.sanact, cfg.ause, cfg.owpass, + cfg.oipbp, cfg.no_dealloc, cfg.emvs, cfg.ovrpat); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (err < 0) - nvme_show_error("sanitize: %s", nvme_strerror(errno)); + nvme_show_error("sanitize: %s", nvme_strerror(-err)); else if (err > 0) nvme_show_status(err); return err; } -static int nvme_get_single_property(int fd, struct get_reg_config *cfg, __u64 *value) +static int nvme_get_single_property(struct nvme_transport_handle *hdl, struct get_reg_config *cfg, __u64 *value) { + struct nvme_passthru_cmd64 cmd; int err; - struct nvme_get_property_args args = { - .args_size = sizeof(args), - .fd = fd, - .offset = cfg->offset, - .value = value, - .timeout = nvme_cfg.timeout, - }; - err = nvme_get_property(&args); + nvme_init_get_property(&cmd, cfg->offset); + err = nvme_submit_admin_passthru64(hdl, &cmd, value); if (!err) return 0; @@ -5623,12 +5527,12 @@ static int nvme_get_single_property(int fd, struct get_reg_config *cfg, __u64 *v if (cfg->fabrics && err > 0) nvme_show_status(err); else - nvme_show_error("get-property: %s", nvme_strerror(errno)); + nvme_show_error("get-property: %s", nvme_strerror(-err)); return err; } -static int nvme_get_properties(int fd, void **pbar, struct get_reg_config *cfg) +static int nvme_get_properties(struct nvme_transport_handle *hdl, void **pbar, struct get_reg_config *cfg) { int err, size = getpagesize(); bool is_64bit = false; @@ -5637,10 +5541,8 @@ static int nvme_get_properties(int fd, void **pbar, struct get_reg_config *cfg) int offset; bar = malloc(size); - if (!bar) { - nvme_show_error("malloc: %s", strerror(errno)); - return -errno; - } + if (!bar) + return -ENOMEM; memset(bar, 0xff, size); for (offset = NVME_REG_CAP; offset <= NVME_REG_CMBSZ; @@ -5649,7 +5551,7 @@ static int nvme_get_properties(int fd, void **pbar, struct get_reg_config *cfg) continue; cfg->offset = offset; - err = nvme_get_single_property(fd, cfg, &value); + err = nvme_get_single_property(hdl, cfg, &value); if (err) break; @@ -5668,7 +5570,7 @@ static int nvme_get_properties(int fd, void **pbar, struct get_reg_config *cfg) return err; } -static void *mmap_registers(struct nvme_dev *dev, bool writable) +static void *mmap_registers(struct nvme_transport_handle *hdl, bool writable) { char path[512]; void *membase; @@ -5678,12 +5580,12 @@ static void *mmap_registers(struct nvme_dev *dev, bool writable) if (writable) prot |= PROT_WRITE; - sprintf(path, "/sys/class/nvme/%s/device/resource0", dev->name); + sprintf(path, "/sys/class/nvme/%s/device/resource0", nvme_transport_handle_get_name(hdl)); fd = open(path, writable ? O_RDWR : O_RDONLY); if (fd < 0) { if (log_level >= LOG_INFO) nvme_show_error("%s did not find a pci resource, open failed %s", - dev->name, strerror(errno)); + nvme_transport_handle_get_name(hdl), strerror(errno)); return NULL; } @@ -5703,14 +5605,15 @@ static void *mmap_registers(struct nvme_dev *dev, bool writable) return membase; } -static int show_registers(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int show_registers(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Reads and shows the defined NVMe controller registers\n" "in binary or human-readable format"; const char *human_readable = "show info in readable format in case of output_format == normal"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; void *bar; int err; @@ -5723,11 +5626,11 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu NVME_ARGS(opts, OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - if (is_blkdev(dev)) { + if (nvme_transport_handle_is_blkdev(hdl)) { nvme_show_error("Only character device is allowed"); return -EINVAL; } @@ -5741,10 +5644,10 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu if (cfg.human_readable || argconfig_parse_seen(opts, "verbose")) flags |= VERBOSE; - bar = mmap_registers(dev, false); + bar = mmap_registers(hdl, false); if (!bar) { cfg.fabrics = true; - err = nvme_get_properties(dev_fd(dev), &bar, &cfg); + err = nvme_get_properties(hdl, &bar, &cfg); if (err) return err; } @@ -5829,38 +5732,31 @@ static bool is_reg_selected(struct get_reg_config *cfg, int offset) return false; } -static int get_register_properties(int fd, void **pbar, struct get_reg_config *cfg) +static int get_register_properties(struct nvme_transport_handle *hdl, void **pbar, struct get_reg_config *cfg) { + struct nvme_passthru_cmd64 cmd; int offset = NVME_REG_CRTO; __u64 value; int size; int err; void *bar; - struct nvme_get_property_args args = { - .args_size = sizeof(args), - .fd = fd, - .value = &value, - .timeout = nvme_cfg.timeout, - }; size = offset + get_reg_size(offset); bar = malloc(size); - if (!bar) { - nvme_show_error("malloc: %s", strerror(errno)); - return -1; - } + if (!bar) + return -ENOMEM; for (offset = NVME_REG_CAP; offset <= NVME_REG_CRTO; offset += get_reg_size(offset)) { if ((cfg->offset != offset && !is_reg_selected(cfg, offset)) || !nvme_is_fabrics_reg(offset)) continue; - args.offset = offset; - err = nvme_get_property(&args); + nvme_init_get_property(&cmd, offset); + err = nvme_submit_admin_passthru64(hdl, &cmd, &value); if (nvme_status_equals(err, NVME_STATUS_TYPE_NVME, NVME_SC_INVALID_FIELD)) { value = -1; } else if (err) { - nvme_show_error("get-property: %s", nvme_strerror(errno)); + nvme_show_error("get-property: %s", nvme_strerror(-err)); free(bar); return err; } @@ -5935,7 +5831,7 @@ static bool get_register_offset(void *bar, bool fabrics, struct get_reg_config * return offset_matched; } -static int get_register(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_register(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Reads and shows the defined NVMe controller register.\n" "Register offset must be one of:\n" @@ -5961,7 +5857,8 @@ static int get_register(int argc, char **argv, struct command *cmd, struct plugi const char *pmrmscl = "PMRMSCL=0xe14 register offset"; const char *pmrmscu = "PMRMSCU=0xe18 register offset"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; nvme_print_flags_t flags; bool fabrics = false; @@ -6004,11 +5901,11 @@ static int get_register(int argc, char **argv, struct command *cmd, struct plugi OPT_FLAG("pmrmscl", 0, &cfg.pmrmscl, pmrmscl), OPT_FLAG("pmrmscu", 0, &cfg.pmrmscu, pmrmscu)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - if (is_blkdev(dev)) { + if (nvme_transport_handle_is_blkdev(hdl)) { nvme_show_error("Only character device is allowed"); return -EINVAL; } @@ -6022,9 +5919,9 @@ static int get_register(int argc, char **argv, struct command *cmd, struct plugi if (cfg.human_readable || argconfig_parse_seen(opts, "verbose")) flags |= VERBOSE; - bar = mmap_registers(dev, false); + bar = mmap_registers(hdl, false); if (!bar) { - err = get_register_properties(dev_fd(dev), &bar, &cfg); + err = get_register_properties(hdl, &bar, &cfg); if (err) return err; fabrics = true; @@ -6047,20 +5944,15 @@ static int get_register(int argc, char **argv, struct command *cmd, struct plugi return err; } -static int nvme_set_single_property(int fd, int offset, uint64_t value) +static int nvme_set_single_property(struct nvme_transport_handle *hdl, int offset, uint64_t value) { - struct nvme_set_property_args args = { - .args_size = sizeof(args), - .fd = fd, - .offset = offset, - .value = value, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - int err = nvme_set_property(&args); + struct nvme_passthru_cmd cmd; + int err; + nvme_init_set_property(&cmd, offset, value); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (err < 0) - nvme_show_error("set-property: %s", nvme_strerror(errno)); + nvme_show_error("set-property: %s", nvme_strerror(-err)); else if (!err) printf("set-property: %#02x (%s), value: %#"PRIx64"\n", offset, nvme_register_to_string(offset), value); @@ -6070,7 +5962,7 @@ static int nvme_set_single_property(int fd, int offset, uint64_t value) return err; } -static int set_register_property(int fd, int offset, uint64_t value) +static int set_register_property(struct nvme_transport_handle *hdl, int offset, uint64_t value) { if (!nvme_is_fabrics_reg(offset)) { printf("register: %#04x (%s) not fabrics\n", offset, @@ -6078,13 +5970,13 @@ static int set_register_property(int fd, int offset, uint64_t value) return -EINVAL; } - return nvme_set_single_property(fd, offset, value); + return nvme_set_single_property(hdl, offset, value); } -static int nvme_set_register(int fd, void *bar, int offset, uint64_t value, bool mmio32) +static int nvme_set_register(struct nvme_transport_handle *hdl, void *bar, int offset, uint64_t value, bool mmio32) { if (!bar) - return set_register_property(fd, offset, value); + return set_register_property(hdl, offset, value); if (nvme_is_64bit_reg(offset)) mmio_write64(bar + offset, value, mmio32); @@ -6163,7 +6055,7 @@ static inline int set_register_names_check(struct argconfig_commandline_options return 0; } -static int set_register_offset(int fd, void *bar, struct argconfig_commandline_options *opts, +static int set_register_offset(struct nvme_transport_handle *hdl, void *bar, struct argconfig_commandline_options *opts, struct set_reg_config *cfg) { int err; @@ -6179,98 +6071,98 @@ static int set_register_offset(int fd, void *bar, struct argconfig_commandline_o return err; } - err = nvme_set_register(fd, bar, cfg->offset, cfg->value, cfg->mmio32); + err = nvme_set_register(hdl, bar, cfg->offset, cfg->value, cfg->mmio32); if (err) return err; return 0; } -static int set_register_names(int fd, void *bar, struct argconfig_commandline_options *opts, +static int set_register_names(struct nvme_transport_handle *hdl, void *bar, struct argconfig_commandline_options *opts, struct set_reg_config *cfg) { int err; if (argconfig_parse_seen(opts, "intms")) { - err = nvme_set_register(fd, bar, NVME_REG_INTMS, cfg->intms, cfg->mmio32); + err = nvme_set_register(hdl, bar, NVME_REG_INTMS, cfg->intms, cfg->mmio32); if (err) return err; } if (argconfig_parse_seen(opts, "intmc")) { - err = nvme_set_register(fd, bar, NVME_REG_INTMC, cfg->intmc, cfg->mmio32); + err = nvme_set_register(hdl, bar, NVME_REG_INTMC, cfg->intmc, cfg->mmio32); if (err) return err; } if (argconfig_parse_seen(opts, "cc")) { - err = nvme_set_register(fd, bar, NVME_REG_CC, cfg->cc, cfg->mmio32); + err = nvme_set_register(hdl, bar, NVME_REG_CC, cfg->cc, cfg->mmio32); if (err) return err; } if (argconfig_parse_seen(opts, "csts")) { - err = nvme_set_register(fd, bar, NVME_REG_CSTS, cfg->csts, cfg->mmio32); + err = nvme_set_register(hdl, bar, NVME_REG_CSTS, cfg->csts, cfg->mmio32); if (err) return err; } if (argconfig_parse_seen(opts, "nssr")) { - err = nvme_set_register(fd, bar, NVME_REG_NSSR, cfg->nssr, cfg->mmio32); + err = nvme_set_register(hdl, bar, NVME_REG_NSSR, cfg->nssr, cfg->mmio32); if (err) return err; } if (argconfig_parse_seen(opts, "aqa")) { - err = nvme_set_register(fd, bar, NVME_REG_AQA, cfg->aqa, cfg->mmio32); + err = nvme_set_register(hdl, bar, NVME_REG_AQA, cfg->aqa, cfg->mmio32); if (err) return err; } if (argconfig_parse_seen(opts, "asq")) { - err = nvme_set_register(fd, bar, NVME_REG_ASQ, cfg->asq, cfg->mmio32); + err = nvme_set_register(hdl, bar, NVME_REG_ASQ, cfg->asq, cfg->mmio32); if (err) return err; } if (argconfig_parse_seen(opts, "acq")) { - err = nvme_set_register(fd, bar, NVME_REG_ACQ, cfg->acq, cfg->mmio32); + err = nvme_set_register(hdl, bar, NVME_REG_ACQ, cfg->acq, cfg->mmio32); if (err) return err; } if (argconfig_parse_seen(opts, "bprsel")) { - err = nvme_set_register(fd, bar, NVME_REG_BPRSEL, cfg->bprsel, cfg->mmio32); + err = nvme_set_register(hdl, bar, NVME_REG_BPRSEL, cfg->bprsel, cfg->mmio32); if (err) return err; } if (argconfig_parse_seen(opts, "cmbmsc")) { - err = nvme_set_register(fd, bar, NVME_REG_CMBMSC, cfg->cmbmsc, cfg->mmio32); + err = nvme_set_register(hdl, bar, NVME_REG_CMBMSC, cfg->cmbmsc, cfg->mmio32); if (err) return err; } if (argconfig_parse_seen(opts, "nssd")) { - err = nvme_set_register(fd, bar, NVME_REG_NSSD, cfg->nssd, cfg->mmio32); + err = nvme_set_register(hdl, bar, NVME_REG_NSSD, cfg->nssd, cfg->mmio32); if (err) return err; } if (argconfig_parse_seen(opts, "pmrctl")) { - err = nvme_set_register(fd, bar, NVME_REG_PMRCTL, cfg->pmrctl, cfg->mmio32); + err = nvme_set_register(hdl, bar, NVME_REG_PMRCTL, cfg->pmrctl, cfg->mmio32); if (err) return err; } if (argconfig_parse_seen(opts, "pmrmscl")) { - err = nvme_set_register(fd, bar, NVME_REG_PMRMSCL, cfg->pmrmscl, cfg->mmio32); + err = nvme_set_register(hdl, bar, NVME_REG_PMRMSCL, cfg->pmrmscl, cfg->mmio32); if (err) return err; } if (argconfig_parse_seen(opts, "pmrmscu")) { - err = nvme_set_register(fd, bar, NVME_REG_PMRMSCU, cfg->pmrmscu, cfg->mmio32); + err = nvme_set_register(hdl, bar, NVME_REG_PMRMSCU, cfg->pmrmscu, cfg->mmio32); if (err) return err; } @@ -6278,15 +6170,15 @@ static int set_register_names(int fd, void *bar, struct argconfig_commandline_op return 0; } -static int set_register(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int set_register(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Writes and shows the defined NVMe controller register"; const char *value = "the value of the register to be set"; const char *mmio32 = "Access 64-bit registers as 2 32-bit"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; - void *bar; struct set_reg_config cfg = { @@ -6313,22 +6205,22 @@ static int set_register(int argc, char **argv, struct command *cmd, struct plugi OPT_UINT("pmrmscl", 0, &cfg.pmrmscl, pmrmscl), OPT_UINT("pmrmscu", 0, &cfg.pmrmscu, pmrmscu)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - if (is_blkdev(dev)) { + if (nvme_transport_handle_is_blkdev(hdl)) { nvme_show_error("Only character device is allowed"); return -EINVAL; } - bar = mmap_registers(dev, true); + bar = mmap_registers(hdl, true); if (argconfig_parse_seen(opts, "offset")) - err = set_register_offset(dev_fd(dev), bar, opts, &cfg); + err = set_register_offset(hdl, bar, opts, &cfg); if (!err) - err = set_register_names(dev_fd(dev), bar, opts, &cfg); + err = set_register_names(hdl, bar, opts, &cfg); if (bar) munmap(bar, getpagesize()); @@ -6336,7 +6228,7 @@ static int set_register(int argc, char **argv, struct command *cmd, struct plugi return err; } -static int get_property(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_property(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Reads and shows the defined NVMe controller property\n" "for NVMe over Fabric. Property offset must be one of:\n" @@ -6344,7 +6236,8 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi const char *offset = "offset of the requested property"; const char *human_readable = "show property in readable format"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u64 value; int err; nvme_print_flags_t flags = NORMAL; @@ -6359,7 +6252,7 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi OPT_UINT("offset", 'O', &cfg.offset, offset), OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -6377,21 +6270,22 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi if (cfg.human_readable || argconfig_parse_seen(opts, "verbose")) flags |= VERBOSE; - err = nvme_get_single_property(dev_fd(dev), &cfg, &value); + err = nvme_get_single_property(hdl, &cfg, &value); if (!err) nvme_show_single_property(cfg.offset, value, flags); return err; } -static int set_property(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int set_property(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Writes and shows the defined NVMe controller property for NVMe over Fabric"; const char *offset = "the offset of the property"; const char *value = "the value of the property to be set"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; nvme_print_flags_t flags; @@ -6404,7 +6298,7 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi OPT_UINT("offset", 'O', &cfg.offset, offset), OPT_UINT("value", 'V', &cfg.value, value)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -6423,30 +6317,30 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi return -EINVAL; } - return nvme_set_single_property(dev_fd(dev), cfg.offset, cfg.value); + return nvme_set_single_property(hdl, cfg.offset, cfg.value); } static void show_relatives(const char *name, nvme_print_flags_t flags) { int err = 0; - _cleanup_nvme_root_ nvme_root_t r = nvme_create_root(stderr, log_level); + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = nvme_create_global_ctx(stderr, log_level); - if (!r) { + if (!ctx) { nvme_show_error("Failed to create topology root: %s", nvme_strerror(errno)); return; } - err = nvme_scan_topology(r, NULL, NULL); + err = nvme_scan_topology(ctx, NULL, NULL); if (err < 0) { nvme_show_error("Failed to scan topology: %s", nvme_strerror(errno)); return; } - nvme_show_relatives(r, name, flags); + nvme_show_relatives(ctx, name, flags); } -static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int format_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Re-format a specified namespace on the\n" "given device. Can erase all data in namespace (user\n" @@ -6456,18 +6350,21 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin const char *ses = "[0-2]: secure erase"; const char *pil = "[0-1]: protection info location last/first bytes of metadata"; const char *pi = "[0-3]: protection info off/Type 1/Type 2/Type 3"; - const char *ms = "[0-1]: extended format off/on"; + const char *mset = "[0-1]: extended format off/on"; const char *reset = "Automatically reset the controller after successful format"; const char *bs = "target block size"; const char *force = "The \"I know what I'm doing\" flag, skip confirmation before sending command"; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL; _cleanup_free_ struct nvme_id_ns *ns = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + nvme_print_flags_t flags = NORMAL; + struct nvme_passthru_cmd cmd; __u8 prev_lbaf = 0; int block_size; int err, i; - nvme_print_flags_t flags = NORMAL; struct config { __u32 namespace_id; @@ -6475,7 +6372,7 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin __u8 ses; __u8 pi; __u8 pil; - __u8 ms; + __u8 mset; bool reset; bool force; __u64 bs; @@ -6487,7 +6384,7 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin .ses = 0, .pi = 0, .pil = 0, - .ms = 0, + .mset = 0, .reset = false, .force = false, .bs = 0, @@ -6501,7 +6398,7 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin OPT_BYTE("ses", 's', &cfg.ses, ses), OPT_BYTE("pi", 'i', &cfg.pi, pi), OPT_BYTE("pil", 'p', &cfg.pil, pil), - OPT_BYTE("ms", 'm', &cfg.ms, ms), + OPT_BYTE("ms", 'm', &cfg.mset, mset), OPT_FLAG("reset", 'r', &cfg.reset, reset), OPT_FLAG("force", 0, &cfg.force, force), OPT_SUFFIX("block-size", 'b', &cfg.bs, bs)); @@ -6510,9 +6407,9 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin if (err) return err; - err = open_exclusive(&dev, argc, argv, cfg.force); + err = open_exclusive(&ctx, &hdl, argc, argv, cfg.force); if (err) { - if (errno == EBUSY) { + if (-err == EBUSY) { fprintf(stderr, "Failed to open %s.\n", basename(argv[optind])); fprintf(stderr, "Namespace is currently busy.\n"); if (!cfg.force) @@ -6547,10 +6444,10 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin if (!ctrl) return -ENOMEM; - err = nvme_cli_identify_ctrl(dev, ctrl); + err = nvme_identify_ctrl(hdl, ctrl); if (err) { - nvme_show_error("identify-ctrl: %s", nvme_strerror(errno)); - return -errno; + nvme_show_error("identify-ctrl: %s", nvme_strerror(-err)); + return err; } if (ctrl->fna & NVME_CTRL_FNA_FMT_ALL_NAMESPACES) { @@ -6561,10 +6458,10 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin */ cfg.namespace_id = NVME_NSID_ALL; } else if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); - return -errno; + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); + return err; } } @@ -6580,10 +6477,10 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin if (!ns) return -ENOMEM; - err = nvme_cli_identify_ns(dev, cfg.namespace_id, ns); + err = nvme_identify_ns(hdl, cfg.namespace_id, ns); if (err) { if (err < 0) { - nvme_show_error("identify-namespace: %s", nvme_strerror(errno)); + nvme_show_error("identify-namespace: %s", nvme_strerror(-err)); } else { fprintf(stderr, "identify failed\n"); nvme_show_status(err); @@ -6632,16 +6529,16 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin nvme_show_error("invalid pil:%d", cfg.pil); return -EINVAL; } - if (cfg.ms > 1) { - nvme_show_error("invalid ms:%d", cfg.ms); + if (cfg.mset > 1) { + nvme_show_error("invalid mset:%d", cfg.mset); return -EINVAL; } if (!cfg.force) { fprintf(stderr, "You are about to format %s, namespace %#x%s.\n", - dev->name, cfg.namespace_id, + nvme_transport_handle_get_name(hdl), cfg.namespace_id, cfg.namespace_id == NVME_NSID_ALL ? "(ALL namespaces)" : ""); - show_relatives(dev->name, flags); + show_relatives(nvme_transport_handle_get_name(hdl), flags); fprintf(stderr, "WARNING: Format may irrevocably delete this device's data.\n" "You have 10 seconds to press Ctrl-C to cancel this operation.\n\n" @@ -6650,28 +6547,18 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin fprintf(stderr, "Sending format operation ...\n"); } - struct nvme_format_nvm_args args = { - .args_size = sizeof(args), - .nsid = cfg.namespace_id, - .lbafu = (cfg.lbaf >> 4) & 0x3, - .lbaf = cfg.lbaf & 0xf, - .mset = cfg.ms, - .pi = cfg.pi, - .pil = cfg.pil, - .ses = cfg.ses, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - err = nvme_cli_format_nvm(dev, &args); + nvme_init_format_nvm(&cmd, cfg.namespace_id, cfg.lbaf, cfg.mset, + cfg.pi, cfg.pil, cfg.ses); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (err < 0) { - nvme_show_error("format: %s", nvme_strerror(errno)); + nvme_show_error("format: %s", nvme_strerror(-err)); } else if (err != 0) { nvme_show_status(err); } else { printf("Success formatting namespace:%x\n", cfg.namespace_id); - if (dev->type == NVME_DEV_DIRECT && cfg.lbaf != prev_lbaf) { - if (is_chardev(dev)) { - if (ioctl(dev_fd(dev), NVME_IOCTL_RESCAN) < 0) { + if (nvme_transport_handle_is_direct(hdl) && cfg.lbaf != prev_lbaf) { + if (nvme_transport_handle_is_chardev(hdl)) { + if (ioctl(nvme_transport_handle_get_fd(hdl), NVME_IOCTL_RESCAN) < 0) { nvme_show_error("failed to rescan namespaces"); return -errno; } @@ -6685,20 +6572,21 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin * to the given one because blkdev will not * update by itself without re-opening fd. */ - if (ioctl(dev_fd(dev), BLKBSZSET, &block_size) < 0) { + if (ioctl(nvme_transport_handle_get_fd(hdl), BLKBSZSET, &block_size) < 0) { nvme_show_error("failed to set block size to %d", block_size); return -errno; } - if (ioctl(dev_fd(dev), BLKRRPART) < 0) { + if (ioctl(nvme_transport_handle_get_fd(hdl), BLKRRPART) < 0) { nvme_show_error("failed to re-read partition table"); return -errno; } } } - if (dev->type == NVME_DEV_DIRECT && cfg.reset && is_chardev(dev)) - nvme_ctrl_reset(dev_fd(dev)); + if (nvme_transport_handle_is_direct(hdl) && cfg.reset && + nvme_transport_handle_is_chardev(hdl)) + nvme_ctrl_reset(hdl); } return err; @@ -6707,7 +6595,7 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin #define STRTOUL_AUTO_BASE (0) #define NVME_FEAT_TIMESTAMP_DATA_SIZE (6) -static int set_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int set_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Modify the saveable or changeable " "current operating parameters of the controller. " @@ -6718,13 +6606,14 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin "for each Feature are vendor-specific and may not be modified." "Use get-feature to determine which Features are supported by" "the controller and are saveable/changeable."; - const char *feature_id = "feature identifier (required)"; + const char *fid = "feature identifier (required)"; const char *data = "optional file for feature data (default stdin)"; const char *value = "new value of feature (required)"; const char *cdw12 = "feature cdw12, if used"; - const char *save = "specifies that the controller shall save the attribute"; + const char *sv = "specifies that the controller shall save the attribute"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ void *buf = NULL; _cleanup_fd_ int ffd = STDIN_FILENO; int err; @@ -6732,37 +6621,37 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin nvme_print_flags_t flags; struct config { - __u32 namespace_id; - __u8 feature_id; + __u32 nsid; + __u8 fid; __u64 value; __u32 cdw12; - __u8 uuid_index; + __u8 uidx; __u32 data_len; char *file; - bool save; + bool sv; }; struct config cfg = { - .namespace_id = 0, - .feature_id = 0, + .nsid = 0, + .fid = 0, .value = 0, - .uuid_index = 0, + .uidx = 0, .data_len = 0, .file = "", - .save = false, + .sv = false, }; NVME_ARGS(opts, - OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired), - OPT_BYTE("feature-id", 'f', &cfg.feature_id, feature_id, feature_name), - OPT_SUFFIX("value", 'V', &cfg.value, value), - OPT_UINT("cdw12", 'c', &cfg.cdw12, cdw12), - OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index_specify), - OPT_UINT("data-len", 'l', &cfg.data_len, buf_len), - OPT_FILE("data", 'd', &cfg.file, data), - OPT_FLAG("save", 's', &cfg.save, save)); - - err = parse_and_open(&dev, argc, argv, desc, opts); + OPT_UINT("namespace-id", 'n', &cfg.nsid, namespace_desired), + OPT_BYTE("feature-id", 'f', &cfg.fid, fid, feature_name), + OPT_SUFFIX("value", 'V', &cfg.value, value), + OPT_UINT("cdw12", 'c', &cfg.cdw12, cdw12), + OPT_BYTE("uuid-index", 'U', &cfg.uidx, uuid_index_specify), + OPT_UINT("data-len", 'l', &cfg.data_len, buf_len), + OPT_FILE("data", 'd', &cfg.file, data), + OPT_FLAG("save", 's', &cfg.sv, sv)); + + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -6773,30 +6662,30 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin } if (!argconfig_parse_seen(opts, "namespace-id")) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.nsid); if (err < 0) { - if (errno != ENOTTY) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); - return -errno; + if (err != -ENOTTY) { + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); + return err; } - cfg.namespace_id = NVME_NSID_ALL; + cfg.nsid = NVME_NSID_ALL; } } - if (!cfg.feature_id) { + if (!cfg.fid) { nvme_show_error("feature-id required param"); return -EINVAL; } - if (cfg.uuid_index > 127) { - nvme_show_error("invalid uuid index param: %u", cfg.uuid_index); + if (cfg.uidx > 127) { + nvme_show_error("invalid uuid index param: %u", cfg.uidx); return -1; } if (!cfg.data_len) - nvme_cli_get_feature_length2(cfg.feature_id, cfg.value, - NVME_DATA_TFR_HOST_TO_CTRL, - &cfg.data_len); + nvme_get_feature_length(cfg.fid, cfg.value, + NVME_DATA_TFR_HOST_TO_CTRL, + &cfg.data_len); if (cfg.data_len) { buf = nvme_alloc(cfg.data_len); @@ -6811,7 +6700,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin * should use the buffer method if the value exceeds this * length. */ - if (cfg.feature_id == NVME_FEAT_FID_TIMESTAMP && + if (cfg.fid == NVME_FEAT_FID_TIMESTAMP && argconfig_parse_seen(opts, "value")) { memcpy(buf, &cfg.value, NVME_FEAT_TIMESTAMP_DATA_SIZE); } else { @@ -6833,34 +6722,20 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin } } - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = cfg.feature_id, - .nsid = cfg.namespace_id, - .cdw11 = cfg.value, - .cdw12 = cfg.cdw12, - .save = cfg.save, - .uuidx = cfg.uuid_index, - .cdw15 = 0, - .data_len = cfg.data_len, - .data = buf, - .timeout = nvme_cfg.timeout, - .result = &result, - }; - err = nvme_set_features(&args); + err = nvme_set_features(hdl, cfg.nsid, cfg.fid, cfg.sv, cfg.value, cfg.cdw12, + 0, cfg.uidx, 0, buf, cfg.data_len, &result); if (err < 0) { - nvme_show_error("set-feature: %s", nvme_strerror(errno)); + nvme_show_error("set-feature: %s", nvme_strerror(-err)); } else if (!err) { printf("set-feature:%#0*x (%s), value:%#0*"PRIx64", cdw12:%#0*x, save:%#x\n", - cfg.feature_id ? 4 : 2, cfg.feature_id, - nvme_feature_to_string(cfg.feature_id), + cfg.fid ? 4 : 2, cfg.fid, + nvme_feature_to_string(cfg.fid), cfg.value ? 10 : 8, (uint64_t)cfg.value, - cfg.cdw12 ? 10 : 8, cfg.cdw12, cfg.save); - if (cfg.feature_id == NVME_FEAT_FID_LBA_STS_INTERVAL) + cfg.cdw12 ? 10 : 8, cfg.cdw12, cfg.sv); + if (cfg.fid == NVME_FEAT_FID_LBA_STS_INTERVAL) nvme_show_lba_status_info(result); if (buf) { - if (cfg.feature_id == NVME_FEAT_FID_LBA_RANGE) + if (cfg.fid == NVME_FEAT_FID_LBA_RANGE) nvme_show_lba_range((struct nvme_lba_range_type *)buf, result, 0); else d(buf, cfg.data_len, 16, 1); @@ -6872,7 +6747,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin return err; } -static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int sec_send(int argc, char **argv, struct command *acmd, struct plugin *plugin) { struct stat sb; const char *desc = "Transfer security protocol data to\n" @@ -6882,7 +6757,9 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p const char *file = "transfer payload"; const char *tl = "transfer length (cf. SPC-4)"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; _cleanup_free_ void *sec_buf = NULL; _cleanup_fd_ int sec_fd = -1; unsigned int sec_size; @@ -6915,7 +6792,7 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p OPT_SHRT("spsp", 's', &cfg.spsp, spsp), OPT_UINT("tl", 't', &cfg.tl, tl)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -6963,25 +6840,13 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p return -errno; } - struct nvme_security_send_args args = { - .args_size = sizeof(args), - .nsid = cfg.namespace_id, - .nssf = cfg.nssf, - .spsp0 = cfg.spsp & 0xff, - .spsp1 = cfg.spsp >> 8, - .secp = cfg.secp, - .tl = cfg.tl, - .data_len = cfg.tl, - .data = sec_buf, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - - err = nvme_cli_security_send(dev, &args); + nvme_init_security_send(&cmd, cfg.namespace_id, cfg.nssf, cfg.spsp, + cfg.secp, cfg.tl, sec_buf, cfg.tl); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (err < 0) - nvme_show_error("security-send: %s", nvme_strerror(errno)); - else if (err != 0) + nvme_show_error("security-send: %s", nvme_strerror(-err)); + else if (err > 0) nvme_show_status(err); else printf("NVME Security Send Command Success\n"); @@ -6989,15 +6854,17 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p return err; } -static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int dir_send(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Set directive parameters of the specified directive type."; const char *endir = "directive enable"; const char *ttype = "target directive type to be enabled/disabled"; const char *input = "write/send file (default stdin)"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ void *buf = NULL; + struct nvme_passthru_cmd cmd; __u32 result; __u32 dw12 = 0; _cleanup_fd_ int ffd = STDIN_FILENO; @@ -7041,7 +6908,7 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_directive), OPT_FILE("input-file", 'i', &cfg.file, input)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -7098,22 +6965,12 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p } } - struct nvme_directive_send_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .dspec = cfg.dspec, - .doper = cfg.doper, - .dtype = cfg.dtype, - .cdw12 = dw12, - .data_len = cfg.data_len, - .data = buf, - .timeout = nvme_cfg.timeout, - .result = &result, - }; - err = nvme_directive_send(&args); + nvme_init_directive_send(&cmd, cfg.namespace_id, cfg.doper, cfg.dtype, + cfg.dspec, buf, cfg.data_len); + cmd.cdw12 = dw12; + err = nvme_submit_admin_passthru(hdl, &cmd, &result); if (err < 0) { - nvme_show_error("dir-send: %s", nvme_strerror(errno)); + nvme_show_error("dir-send: %s", nvme_strerror(-err)); return err; } if (!err) { @@ -7132,12 +6989,14 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p return err; } -static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int write_uncor(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "The Write Uncorrectable command is used to set a range of logical blocks to invalid."; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; int err; struct config { @@ -7163,14 +7022,14 @@ static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin OPT_BYTE("dir-type", 'T', &cfg.dtype, dtype), OPT_SHRT("dir-spec", 'S', &cfg.dspec, dspec_w_dtype)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); return err; } } @@ -7180,20 +7039,11 @@ static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin return -EINVAL; } - struct nvme_io_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .slba = cfg.start_block, - .nlb = cfg.block_count, - .control = cfg.dtype << 4, - .dspec = cfg.dspec, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - err = nvme_write_uncorrectable(&args); + nvme_init_write_uncorrectable(&cmd, cfg.namespace_id, cfg.start_block, + cfg.block_count, cfg.dtype << 4, cfg.dspec); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (err < 0) - nvme_show_error("write uncorrectable: %s", nvme_strerror(errno)); + nvme_show_error("write uncorrectable: %s", nvme_strerror(-err)); else if (err != 0) nvme_show_status(err); else @@ -7249,11 +7099,13 @@ static void get_pif_sts(struct nvme_id_ns *ns, struct nvme_nvm_id_ns *nvm_ns, __ *pif = (elbaf & NVME_NVM_ELBAF_QPIF_MASK) >> 9; } -static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int write_zeroes(int argc, char **argv, struct command *acmd, struct plugin *plugin) { _cleanup_free_ struct nvme_nvm_id_ns *nvm_ns = NULL; _cleanup_free_ struct nvme_id_ns *ns = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; __u8 sts = 0, pif = 0; __u16 control = 0; __u32 result = 0; @@ -7321,7 +7173,7 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi OPT_SHRT("dir-spec", 'D', &cfg.dspec, dspec_w_dtype), OPT_FLAG("namespace-zeroes", 'Z', &cfg.nsz, nsz)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -7346,9 +7198,9 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi control |= NVME_IO_NSZ; control |= (cfg.dtype << 4); if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); return err; } } @@ -7357,9 +7209,9 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi if (!ns) return -ENOMEM; - err = nvme_cli_identify_ns(dev, cfg.namespace_id, ns); + err = nvme_identify_ns(hdl, cfg.namespace_id, ns); if (err < 0) { - nvme_show_error("identify namespace: %s", nvme_strerror(errno)); + nvme_show_error("identify namespace: %s", nvme_strerror(-err)); return err; } else if (err) { nvme_show_status(err); @@ -7370,7 +7222,8 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi if (!nvm_ns) return -ENOMEM; - err = nvme_identify_ns_csi(dev_fd(dev), cfg.namespace_id, 0, NVME_CSI_NVM, nvm_ns); + err = nvme_identify_csi_ns(hdl, cfg.namespace_id, NVME_CSI_NVM, 0, + nvm_ns); if (!err) { get_pif_sts(ns, nvm_ns, &pif, &sts); } @@ -7378,27 +7231,15 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif)) return -EINVAL; - struct nvme_io_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .slba = cfg.start_block, - .nlb = cfg.block_count, - .control = control, - .reftag = (__u32)cfg.ref_tag, - .reftag_u64 = cfg.ref_tag, - .apptag = cfg.app_tag, - .appmask = cfg.app_tag_mask, - .sts = sts, - .pif = pif, - .storage_tag = cfg.storage_tag, - .dspec = cfg.dspec, - .timeout = nvme_cfg.timeout, - .result = &result, - }; - err = nvme_write_zeros(&args); + nvme_init_write_zeros(&cmd, cfg.namespace_id, cfg.start_block, + cfg.block_count, control, cfg.dspec, 0, 0); + nvme_init_var_size_tags((struct nvme_passthru_cmd64 *)&cmd, pif, sts, + cfg.ref_tag, cfg.storage_tag); + nvme_init_app_tag((struct nvme_passthru_cmd64 *)&cmd, cfg.app_tag, + cfg.app_tag_mask); + err = nvme_submit_io_passthru(hdl, &cmd, &result); if (err < 0) - nvme_show_error("write-zeroes: %s", nvme_strerror(errno)); + nvme_show_error("write-zeroes: %s", nvme_strerror(-err)); else if (err != 0) nvme_show_status(err); else { @@ -7414,7 +7255,7 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi return err; } -static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int dsm(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "The Dataset Management command is used by the host to\n" "indicate attributes for ranges of logical blocks. This includes attributes\n" @@ -7428,8 +7269,10 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin const char *idr = "Attribute Integral Dataset for Read"; const char *cdw11 = "All the command DWORD 11 attributes. Use instead of specifying individual attributes"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ struct nvme_dsm_range *dsm = NULL; + struct nvme_passthru_cmd cmd; uint16_t nr, nc, nb, ns; __u32 ctx_attrs[256] = {0,}; __u32 nlbs[256] = {0,}; @@ -7469,7 +7312,7 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin OPT_FLAG("idr", 'r', &cfg.idr, idr), OPT_UINT("cdw11", 'c', &cfg.cdw11, cdw11)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -7489,9 +7332,9 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin } if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); return err; } } @@ -7503,20 +7346,12 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin return -ENOMEM; nvme_init_dsm_range(dsm, ctx_attrs, nlbs, slbas, nr); - struct nvme_dsm_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .attrs = cfg.cdw11, - .nr_ranges = nr, - .dsm = dsm, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - err = nvme_dsm(&args); + nvme_init_dsm(&cmd, cfg.namespace_id, nr, cfg.idr, cfg.idw, cfg.ad, dsm, + sizeof(*dsm) * 256); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); if (err < 0) - nvme_show_error("data-set management: %s", nvme_strerror(errno)); - else if (err != 0) + nvme_show_error("data-set management: %s", nvme_strerror(-err)); + else if (err > 0) nvme_show_status(err); else printf("NVMe DSM: success\n"); @@ -7524,7 +7359,41 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin return err; } -static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int +identify_pif_sts(struct nvme_transport_handle *hdl, + __u32 nsid, __u8 *pif, __u8 *sts) +{ + _cleanup_free_ struct nvme_nvm_id_ns *nvm_ns = NULL; + + _cleanup_free_ struct nvme_id_ns *ns = NULL; + + int err; + + ns = nvme_alloc(sizeof(*ns)); + if (!ns) + return -ENOMEM; + + err = nvme_identify_ns(hdl, nsid, ns); + if (err > 0) { + nvme_show_status(err); + return err; + } else if (err < 0) { + nvme_show_error("identify namespace: %s", nvme_strerror(-err)); + return err; + } + + nvm_ns = nvme_alloc(sizeof(*nvm_ns)); + if (!nvm_ns) + return -ENOMEM; + + err = nvme_identify_csi_ns(hdl, nsid, NVME_CSI_NVM, 0, nvm_ns); + if (!err) + get_pif_sts(ns, nvm_ns, pif, sts); + + return 0; +} + +static int copy_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "The Copy command is used by the host to copy data\n" "from one or more source logical block ranges to a\n" @@ -7548,12 +7417,16 @@ static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *p const char *d_dspec = "directive specific (write part)"; const char *d_format = "source range entry format"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u16 nr, nb, ns, nrts, natms, nats, nids; + struct nvme_passthru_cmd cmd; __u16 nlbs[256] = { 0 }; __u64 slbas[256] = { 0 }; __u32 snsids[256] = { 0 }; __u16 sopts[256] = { 0 }; + __u8 pif = 0; + __u8 sts = 0; int err; union { @@ -7636,28 +7509,39 @@ static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *p OPT_SHRT("dir-spec", 'S', &cfg.dspec, d_dspec), OPT_BYTE("format", 'F', &cfg.format, d_format)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - nb = argconfig_parse_comma_sep_array_u16(cfg.nlbs, nlbs, ARRAY_SIZE(nlbs)); - ns = argconfig_parse_comma_sep_array_u64(cfg.slbas, slbas, ARRAY_SIZE(slbas)); - nids = argconfig_parse_comma_sep_array_u32(cfg.snsids, snsids, ARRAY_SIZE(snsids)); - argconfig_parse_comma_sep_array_u16(cfg.sopts, sopts, ARRAY_SIZE(sopts)); - - if (cfg.format == 0 || cfg.format == 2) { - nrts = argconfig_parse_comma_sep_array_u32(cfg.eilbrts, eilbrts.short_pi, - ARRAY_SIZE(eilbrts.short_pi)); - } else if (cfg.format == 1 || cfg.format == 3) { - nrts = argconfig_parse_comma_sep_array_u64(cfg.eilbrts, eilbrts.long_pi, - ARRAY_SIZE(eilbrts.long_pi)); - } else { + nb = argconfig_parse_comma_sep_array_u16(cfg.nlbs, nlbs, + ARRAY_SIZE(nlbs)); + ns = argconfig_parse_comma_sep_array_u64(cfg.slbas, slbas, + ARRAY_SIZE(slbas)); + nids = argconfig_parse_comma_sep_array_u32(cfg.snsids, snsids, + ARRAY_SIZE(snsids)); + argconfig_parse_comma_sep_array_u16(cfg.sopts, sopts, + ARRAY_SIZE(sopts)); + + switch (cfg.format) { + case 0: + case 2: + nrts = argconfig_parse_comma_sep_array_u32(cfg.eilbrts, + eilbrts.short_pi, ARRAY_SIZE(eilbrts.short_pi)); + break; + case 1: + case 3: + nrts = argconfig_parse_comma_sep_array_u64(cfg.eilbrts, + eilbrts.long_pi, ARRAY_SIZE(eilbrts.long_pi)); + break; + default: nvme_show_error("invalid format"); return -EINVAL; } - natms = argconfig_parse_comma_sep_array_u32(cfg.elbatms, elbatms, ARRAY_SIZE(elbatms)); - nats = argconfig_parse_comma_sep_array_u32(cfg.elbats, elbats, ARRAY_SIZE(elbats)); + natms = argconfig_parse_comma_sep_array_u32(cfg.elbatms, elbatms, + ARRAY_SIZE(elbatms)); + nats = argconfig_parse_comma_sep_array_u32(cfg.elbats, elbats, + ARRAY_SIZE(elbats)); nr = max(nb, max(ns, max(nrts, max(natms, nats)))); if (cfg.format == 2 || cfg.format == 3) { @@ -7675,9 +7559,10 @@ static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *p } if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + nvme_show_error("get-namespace-id: %s", + nvme_strerror(-err)); return err; } } @@ -7686,40 +7571,42 @@ static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *p if (!copy) return -ENOMEM; - if (cfg.format == 0) - nvme_init_copy_range(copy->f0, nlbs, slbas, eilbrts.short_pi, elbatms, elbats, nr); - else if (cfg.format == 1) - nvme_init_copy_range_f1(copy->f1, nlbs, slbas, eilbrts.long_pi, elbatms, elbats, nr); - else if (cfg.format == 2) - nvme_init_copy_range_f2(copy->f2, snsids, nlbs, slbas, sopts, eilbrts.short_pi, elbatms, - elbats, nr); - else if (cfg.format == 3) - nvme_init_copy_range_f3(copy->f3, snsids, nlbs, slbas, sopts, eilbrts.long_pi, elbatms, - elbats, nr); - - struct nvme_copy_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .copy = copy->f0, - .sdlba = cfg.sdlba, - .nr = nr, - .prinfor = cfg.prinfor, - .prinfow = cfg.prinfow, - .dtype = cfg.dtype, - .dspec = cfg.dspec, - .format = cfg.format, - .lr = cfg.lr, - .fua = cfg.fua, - .ilbrt_u64 = cfg.ilbrt, - .lbatm = cfg.lbatm, - .lbat = cfg.lbat, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - err = nvme_copy(&args); + switch (cfg.format) { + case 1: + nvme_init_copy_range_f1(copy->f1, nlbs, slbas, eilbrts.long_pi, + elbatms, elbats, nr); + break; + case 2: + nvme_init_copy_range_f2(copy->f2, snsids, nlbs, slbas, sopts, + eilbrts.short_pi, elbatms, elbats, nr); + break; + case 3: + nvme_init_copy_range_f3(copy->f3, snsids, nlbs, slbas, sopts, + eilbrts.long_pi, elbatms, elbats, nr); + break; + default: + nvme_init_copy_range(copy->f0, nlbs, slbas, eilbrts.short_pi, + elbatms, elbats, nr); + break; + } + + err = identify_pif_sts(hdl, cfg.namespace_id, &pif, &sts); + if (err) + return err; + + if (invalid_tags(0, cfg.ilbrt, sts, pif)) + return -EINVAL; + + nvme_init_copy(&cmd, cfg.namespace_id, cfg.sdlba, nr, cfg.format, + cfg.prinfor, cfg.prinfow, 0, cfg.dtype, false, false, + cfg.fua, cfg.lr, 0, cfg.dspec, copy->f0); + nvme_init_var_size_tags((struct nvme_passthru_cmd64 *)&cmd, pif, sts, + cfg.ilbrt, 0); + nvme_init_app_tag((struct nvme_passthru_cmd64 *)&cmd, cfg.lbat, + cfg.lbatm); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); if (err < 0) - nvme_show_error("NVMe Copy: %s", nvme_strerror(errno)); + nvme_show_error("NVMe Copy: %s", nvme_strerror(-err)); else if (err != 0) nvme_show_status(err); else @@ -7728,7 +7615,7 @@ static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *p return err; } -static int flush_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int flush_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Commit data and metadata associated with\n" "given namespaces to nonvolatile media. Applies to all commands\n" @@ -7736,7 +7623,8 @@ static int flush_cmd(int argc, char **argv, struct command *cmd, struct plugin * "flushed by the controller, from any namespace, depending on controller and\n" "associated namespace status."; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; struct config { @@ -7750,21 +7638,21 @@ static int flush_cmd(int argc, char **argv, struct command *cmd, struct plugin * NVME_ARGS(opts, OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); return err; } } - err = nvme_flush(dev_fd(dev), cfg.namespace_id); + err = nvme_flush(hdl, cfg.namespace_id); if (err < 0) - nvme_show_error("flush: %s", nvme_strerror(errno)); + nvme_show_error("flush: %s", nvme_strerror(-err)); else if (err != 0) nvme_show_status(err); else @@ -7773,7 +7661,7 @@ static int flush_cmd(int argc, char **argv, struct command *cmd, struct plugin * return err; } -static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int resv_acquire(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Obtain a reservation on a given\n" "namespace. Only one reservation is allowed at a time on a\n" @@ -7783,9 +7671,12 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi const char *prkey = "pre-empt reservation key"; const char *racqa = "reservation acquire action"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - int err; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; + __le64 payload[2]; + int err; struct config { __u32 namespace_id; @@ -7813,7 +7704,7 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi OPT_BYTE("racqa", 'a', &cfg.racqa, racqa), OPT_FLAG("iekey", 'i', &cfg.iekey, iekey)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -7824,9 +7715,9 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi } if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); return err; } } @@ -7835,22 +7726,12 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi return -EINVAL; } - struct nvme_resv_acquire_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .rtype = cfg.rtype, - .racqa = cfg.racqa, - .iekey = !!cfg.iekey, - .crkey = cfg.crkey, - .nrkey = cfg.prkey, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - err = nvme_resv_acquire(&args); + nvme_init_resv_acquire(&cmd, cfg.namespace_id, cfg.racqa, cfg.iekey, + false, cfg.rtype, cfg.crkey, cfg.prkey, payload); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); if (err < 0) - nvme_show_error("reservation acquire: %s", nvme_strerror(errno)); - else if (err != 0) + nvme_show_error("reservation acquire: %s", nvme_strerror(-err)); + else if (err > 0) nvme_show_status(err); else printf("NVME Reservation Acquire success\n"); @@ -7858,7 +7739,7 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi return err; } -static int resv_register(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int resv_register(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Register, de-register, or\n" "replace a controller's reservation on a given namespace.\n" @@ -7867,9 +7748,12 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug const char *rrega = "reservation registration action"; const char *cptpl = "change persistence through power loss setting"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - int err; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; + __le64 payload[2]; + int err; struct config { __u32 namespace_id; @@ -7896,7 +7780,7 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug OPT_BYTE("cptpl", 'p', &cfg.cptpl, cptpl), OPT_FLAG("iekey", 'i', &cfg.iekey, iekey)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -7907,9 +7791,9 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug } if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); return err; } } @@ -7923,22 +7807,13 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug return -EINVAL; } - struct nvme_resv_register_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .rrega = cfg.rrega, - .cptpl = cfg.cptpl, - .iekey = !!cfg.iekey, - .crkey = cfg.crkey, - .nrkey = cfg.nrkey, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - err = nvme_resv_register(&args); + nvme_init_resv_register(&cmd, cfg.namespace_id, cfg.rrega, cfg.iekey, + false, cfg.cptpl, cfg.crkey, cfg.nrkey, + payload); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); if (err < 0) - nvme_show_error("reservation register: %s", nvme_strerror(errno)); - else if (err != 0) + nvme_show_error("reservation register: %s", nvme_strerror(-err)); + else if (err > 0) nvme_show_status(err); else printf("NVME Reservation success\n"); @@ -7946,7 +7821,7 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug return err; } -static int resv_release(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int resv_release(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Releases reservation held on a\n" "namespace by the given controller. If rtype != current reservation\n" @@ -7958,12 +7833,15 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi "the issuing controller are notified."; const char *rrela = "reservation release action"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - int err; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; + __le64 payload[1]; + int err; struct config { - __u32 namespace_id; + __u32 nsid; __u64 crkey; __u8 rtype; __u8 rrela; @@ -7971,7 +7849,7 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi }; struct config cfg = { - .namespace_id = 0, + .nsid = 0, .crkey = 0, .rtype = 0, .rrela = 0, @@ -7979,13 +7857,13 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi }; NVME_ARGS(opts, - OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired), - OPT_SUFFIX("crkey", 'c', &cfg.crkey, crkey), - OPT_BYTE("rtype", 't', &cfg.rtype, rtype), - OPT_BYTE("rrela", 'a', &cfg.rrela, rrela), - OPT_FLAG("iekey", 'i', &cfg.iekey, iekey)); + OPT_UINT("namespace-id", 'n', &cfg.nsid, namespace_desired), + OPT_SUFFIX("crkey", 'c', &cfg.crkey, crkey), + OPT_BYTE("rtype", 't', &cfg.rtype, rtype), + OPT_BYTE("rrela", 'a', &cfg.rrela, rrela), + OPT_FLAG("iekey", 'i', &cfg.iekey, iekey)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -7995,10 +7873,10 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi return err; } - if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + if (!cfg.nsid) { + err = nvme_get_nsid(hdl, &cfg.nsid); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); return err; } } @@ -8007,20 +7885,11 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi return -EINVAL; } - struct nvme_resv_release_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .rtype = cfg.rtype, - .rrela = cfg.rrela, - .iekey = !!cfg.iekey, - .crkey = cfg.crkey, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - err = nvme_resv_release(&args); + nvme_init_resv_release(&cmd, cfg.nsid, cfg.rrela, cfg.iekey, false, + cfg.rtype, cfg.crkey, payload); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); if (err < 0) - nvme_show_error("reservation release: %s", nvme_strerror(errno)); + nvme_show_error("reservation release: %s", nvme_strerror(-err)); else if (err != 0) nvme_show_status(err); else @@ -8029,7 +7898,7 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi return err; } -static int resv_report(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int resv_report(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Returns Reservation Status data\n" "structure describing any existing reservations on and the\n" @@ -8038,33 +7907,35 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin const char *numd = "number of dwords to transfer"; const char *eds = "request extended data structure"; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; _cleanup_free_ struct nvme_resv_status *status = NULL; _cleanup_free_ struct nvme_id_ctrl *ctrl = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; int err, size; struct config { - __u32 namespace_id; + __u32 nsid; __u32 numd; __u8 eds; bool raw_binary; }; struct config cfg = { - .namespace_id = 0, + .nsid = 0, .numd = 0, .eds = false, .raw_binary = false, }; NVME_ARGS(opts, - OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired), - OPT_UINT("numd", 'd', &cfg.numd, numd), - OPT_FLAG("eds", 'e', &cfg.eds, eds), - OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_dump)); + OPT_UINT("namespace-id", 'n', &cfg.nsid, namespace_id_desired), + OPT_UINT("numd", 'd', &cfg.numd, numd), + OPT_FLAG("eds", 'e', &cfg.eds, eds), + OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_dump)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -8077,10 +7948,10 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin if (cfg.raw_binary) flags = BINARY; - if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + if (!cfg.nsid) { + err = nvme_get_nsid(hdl, &cfg.nsid); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); return err; } } @@ -8096,10 +7967,10 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin if (!ctrl) return -ENOMEM; - err = nvme_cli_identify_ctrl(dev, ctrl); + err = nvme_identify_ctrl(hdl, ctrl); if (err) { - nvme_show_error("identify-ctrl: %s", nvme_strerror(errno)); - return -errno; + nvme_show_error("identify-ctrl: %s", nvme_strerror(-err)); + return err; } if (ctrl->ctratt & NVME_CTRL_CTRATT_128_ID) @@ -8109,23 +7980,14 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin if (!status) return -ENOMEM; - struct nvme_resv_report_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .eds = cfg.eds, - .len = size, - .report = status, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - err = nvme_resv_report(&args); + nvme_init_resv_report(&cmd, cfg.nsid, cfg.eds, false, status, size); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); if (!err) nvme_show_resv_report(status, size, cfg.eds, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("reservation report: %s", nvme_strerror(errno)); + nvme_show_error("reservation report: %s", nvme_strerror(-err)); return err; } @@ -8140,22 +8002,24 @@ unsigned long long elapsed_utime(struct timeval start_time, static int submit_io(int opcode, char *command, const char *desc, int argc, char **argv) { + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + unsigned long long buffer_size = 0, mbuffer_size = 0; + _cleanup_free_ struct nvme_nvm_id_ns *nvm_ns = NULL; + _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; + _cleanup_free_ struct nvme_id_ns *ns = NULL; + unsigned int logical_block_size = 0; struct timeval start_time, end_time; - void *buffer; _cleanup_free_ void *mbuffer = NULL; - int err = 0; _cleanup_fd_ int dfd = -1, mfd = -1; - int flags, pi_size; - int mode = 0644; + __u8 lba_index, sts = 0, pif = 0; __u16 control = 0, nblocks = 0; + struct nvme_passthru_cmd cmd; + int flags, pi_size; __u32 dsmgmt = 0; - unsigned int logical_block_size = 0; - unsigned long long buffer_size = 0, mbuffer_size = 0; - _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - _cleanup_free_ struct nvme_nvm_id_ns *nvm_ns = NULL; - _cleanup_free_ struct nvme_id_ns *ns = NULL; - __u8 lba_index, sts = 0, pif = 0; + int mode = 0644; + void *buffer; + int err = 0; __u16 ms; const char *start_block_addr = "64-bit addr of first block to access"; @@ -8245,18 +8109,20 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char OPT_FLAG("force", 0, &cfg.force, force)); if (opcode != nvme_cmd_write) { - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; } else { err = parse_args(argc, argv, desc, opts); if (err) return err; - err = open_exclusive(&dev, argc, argv, cfg.force); + err = open_exclusive(&ctx, &hdl, argc, argv, cfg.force); if (err) { - if (errno == EBUSY) { - fprintf(stderr, "Failed to open %s.\n", basename(argv[optind])); - fprintf(stderr, "Namespace is currently busy.\n"); + if (err == -EBUSY) { + fprintf(stderr, "Failed to open %s.\n", + basename(argv[optind])); + fprintf(stderr, + "Namespace is currently busy.\n"); if (!cfg.force) fprintf(stderr, "Use the force [--force] option to ignore that.\n"); @@ -8268,9 +8134,10 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char } if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + nvme_show_error("get-namespace-id: %s", + nvme_strerror(-err)); return err; } } @@ -8288,7 +8155,8 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char control |= NVME_IO_STC; if (cfg.dtype) { if (cfg.dtype > 0xf) { - nvme_show_error("Invalid directive type, %x", cfg.dtype); + nvme_show_error("Invalid directive type, %x", + cfg.dtype); return -EINVAL; } control |= cfg.dtype << 4; @@ -8328,12 +8196,12 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char if (!ns) return -ENOMEM; - err = nvme_cli_identify_ns(dev, cfg.namespace_id, ns); + err = nvme_identify_ns(hdl, cfg.namespace_id, ns); if (err > 0) { nvme_show_status(err); return err; } else if (err < 0) { - nvme_show_error("identify namespace: %s", nvme_strerror(errno)); + nvme_show_error("identify namespace: %s", nvme_strerror(-err)); return err; } @@ -8345,7 +8213,8 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char if (!nvm_ns) return -ENOMEM; - err = nvme_identify_ns_csi(dev_fd(dev), cfg.namespace_id, 0, NVME_CSI_NVM, nvm_ns); + err = nvme_identify_csi_ns(hdl, cfg.namespace_id, NVME_CSI_NVM, 0, + nvm_ns); if (!err) get_pif_sts(ns, nvm_ns, &pif, &sts); @@ -8362,7 +8231,9 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char buffer_size = ((long long)cfg.block_count + 1) * logical_block_size; if (cfg.data_size < buffer_size) - nvme_show_error("Rounding data size to fit block count (%lld bytes)", buffer_size); + nvme_show_error( + "Rounding data size to fit block count (%lld bytes)", + buffer_size); else buffer_size = cfg.data_size; @@ -8370,11 +8241,16 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char /* Use the value provided */ nblocks = cfg.block_count; } else { - /* Get the required block count. Note this is a zeroes based value. */ - nblocks = ((buffer_size + (logical_block_size - 1)) / logical_block_size) - 1; + /* + * Get the required block count. Note this is a zeroes based + * value. + */ + nblocks = ((buffer_size + (logical_block_size - 1)) / + logical_block_size) - 1; /* Update the data size based on the required block count */ - buffer_size = ((unsigned long long)nblocks + 1) * logical_block_size; + buffer_size = ((unsigned long long)nblocks + 1) * + logical_block_size; } buffer = nvme_alloc_huge(buffer_size, &mh); @@ -8386,8 +8262,9 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char if (cfg.metadata_size) { mbuffer_size = ((unsigned long long)cfg.block_count + 1) * ms; if (ms && cfg.metadata_size < mbuffer_size) - nvme_show_error("Rounding metadata size to fit block count (%lld bytes)", - mbuffer_size); + nvme_show_error( + "Rounding metadata size to fit block count (%lld bytes)", + mbuffer_size); else mbuffer_size = cfg.metadata_size; @@ -8404,7 +8281,9 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char err = read(dfd, (void *)buffer, cfg.data_size); if (err < 0) { err = -errno; - nvme_show_error("failed to read data buffer from input file %s", strerror(errno)); + nvme_show_error( + "failed to read data buffer from input file %s", + strerror(errno)); return err; } } @@ -8413,7 +8292,9 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char err = read(mfd, (void *)mbuffer, mbuffer_size); if (err < 0) { err = -errno; - nvme_show_error("failed to read meta-data buffer from input file %s", strerror(errno)); + nvme_show_error( + "failed to read meta-data buffer from input file %s", + strerror(errno)); return err; } } @@ -8424,56 +8305,59 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char printf("flags : %02x\n", 0); printf("control : %04x\n", control); printf("nblocks : %04x\n", nblocks); - printf("metadata : %"PRIx64"\n", (uint64_t)(uintptr_t)mbuffer); - printf("addr : %"PRIx64"\n", (uint64_t)(uintptr_t)buffer); - printf("slba : %"PRIx64"\n", (uint64_t)cfg.start_block); + printf("metadata : %"PRIx64"\n", + (uint64_t)(uintptr_t)mbuffer); + printf("addr : %"PRIx64"\n", + (uint64_t)(uintptr_t)buffer); + printf("slba : %"PRIx64"\n", + (uint64_t)cfg.start_block); printf("dsmgmt : %08x\n", dsmgmt); - printf("reftag : %"PRIx64"\n", (uint64_t)cfg.ref_tag); + printf("reftag : %"PRIx64"\n", + (uint64_t)cfg.ref_tag); printf("apptag : %04x\n", cfg.app_tag); printf("appmask : %04x\n", cfg.app_tag_mask); printf("storagetagcheck : %04x\n", cfg.storage_tag_check); - printf("storagetag : %"PRIx64"\n", (uint64_t)cfg.storage_tag); + printf("storagetag : %"PRIx64"\n", + (uint64_t)cfg.storage_tag); printf("pif : %02x\n", pif); printf("sts : %02x\n", sts); } if (nvme_cfg.dry_run) return 0; - struct nvme_io_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .slba = cfg.start_block, - .nlb = nblocks, - .control = control, - .dsm = cfg.dsmgmt, - .sts = sts, - .pif = pif, - .dspec = cfg.dspec, - .reftag = (__u32)cfg.ref_tag, - .reftag_u64 = cfg.ref_tag, - .apptag = cfg.app_tag, - .appmask = cfg.app_tag_mask, - .storage_tag = cfg.storage_tag, - .data_len = buffer_size, - .data = buffer, - .metadata_len = mbuffer_size, - .metadata = mbuffer, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; gettimeofday(&start_time, NULL); - err = nvme_io(&args, opcode); + nvme_init_io(&cmd, opcode, cfg.namespace_id, cfg.start_block, buffer, + buffer_size, mbuffer, mbuffer_size); + cmd.cdw12 = NVME_FIELD_ENCODE(nblocks, + NVME_IOCS_COMMON_CDW12_NLB_SHIFT, + NVME_IOCS_COMMON_CDW12_NLB_MASK) | + NVME_FIELD_ENCODE(control, + NVME_IOCS_COMMON_CDW12_CONTROL_SHIFT, + NVME_IOCS_COMMON_CDW12_CONTROL_MASK); + cmd.cdw13 = NVME_FIELD_ENCODE(cfg.dspec, + NVME_IOCS_COMMON_CDW13_DSPEC_SHIFT, + NVME_IOCS_COMMON_CDW13_DSPEC_MASK) | + NVME_FIELD_ENCODE(cfg.dsmgmt, + NVME_IOCS_COMMON_CDW13_DSM_SHIFT, + NVME_IOCS_COMMON_CDW13_DSM_MASK); + nvme_init_var_size_tags((struct nvme_passthru_cmd64 *)&cmd, pif, sts, + cfg.ref_tag, cfg.storage_tag); + nvme_init_app_tag((struct nvme_passthru_cmd64 *)&cmd, cfg.app_tag, + cfg.app_tag_mask); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); gettimeofday(&end_time, NULL); if (cfg.latency) - printf(" latency: %s: %llu us\n", command, elapsed_utime(start_time, end_time)); + printf(" latency: %s: %llu us\n", + command, elapsed_utime(start_time, end_time)); if (err < 0) { - nvme_show_error("submit-io: %s", nvme_strerror(errno)); + nvme_show_error("submit-io: %s", nvme_strerror(-err)); } else if (err) { nvme_show_status(err); } else { - if (!(opcode & 1) && write(dfd, (void *)buffer, buffer_size) < 0) { - nvme_show_error("write: %s: failed to write buffer to output file", + if (!(opcode & 1) && + write(dfd, (void *)buffer, buffer_size) < 0) { + nvme_show_error( + "write: %s: failed to write buffer to output file", strerror(errno)); err = -EINVAL; } else if (!(opcode & 1) && cfg.metadata_size && @@ -8490,7 +8374,7 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char return err; } -static int compare(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int compare(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Compare specified logical blocks on\n" "device with specified data buffer; return failure if buffer\n" @@ -8499,7 +8383,7 @@ static int compare(int argc, char **argv, struct command *cmd, struct plugin *pl return submit_io(nvme_cmd_compare, "compare", desc, argc, argv); } -static int read_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int read_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Copy specified logical blocks on the given\n" "device to specified data buffer (default buffer is stdout)."; @@ -8507,7 +8391,7 @@ static int read_cmd(int argc, char **argv, struct command *cmd, struct plugin *p return submit_io(nvme_cmd_read, "read", desc, argc, argv); } -static int write_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int write_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Copy from provided data buffer (default\n" "buffer is stdin) to specified logical blocks on the given device."; @@ -8515,11 +8399,13 @@ static int write_cmd(int argc, char **argv, struct command *cmd, struct plugin * return submit_io(nvme_cmd_write, "write", desc, argc, argv); } -static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int verify_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { _cleanup_free_ struct nvme_nvm_id_ns *nvm_ns = NULL; _cleanup_free_ struct nvme_id_ns *ns = NULL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; __u8 sts = 0, pif = 0; __u16 control = 0; int err; @@ -8571,7 +8457,8 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin OPT_SUFFIX("storage-tag", 'S', &cfg.storage_tag, storage_tag), OPT_FLAG("storage-tag-check", 'C', &cfg.storage_tag_check, storage_tag_check)); - err = parse_and_open(&dev, argc, argv, desc, opts); + + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -8587,9 +8474,9 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin control |= NVME_IO_STC; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { - nvme_show_error("get-namespace-id: %s", nvme_strerror(errno)); + nvme_show_error("get-namespace-id: %s", nvme_strerror(-err)); return err; } } @@ -8598,9 +8485,9 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin if (!ns) return -ENOMEM; - err = nvme_cli_identify_ns(dev, cfg.namespace_id, ns); + err = nvme_identify_ns(hdl, cfg.namespace_id, ns); if (err < 0) { - nvme_show_error("identify namespace: %s", nvme_strerror(errno)); + nvme_show_error("identify namespace: %s", nvme_strerror(-err)); return err; } else if (err) { nvme_show_status(err); @@ -8611,8 +8498,8 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin if (!nvm_ns) return -ENOMEM; - err = nvme_identify_ns_csi(dev_fd(dev), cfg.namespace_id, 0, - NVME_CSI_NVM, nvm_ns); + err = nvme_identify_csi_ns(hdl, cfg.namespace_id, NVME_CSI_NVM, 0, + nvm_ns); if (!err) { get_pif_sts(ns, nvm_ns, &pif, &sts); } @@ -8620,26 +8507,15 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif)) return -EINVAL; - struct nvme_io_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .slba = cfg.start_block, - .nlb = cfg.block_count, - .control = control, - .reftag = cfg.ref_tag, - .reftag_u64 = cfg.ref_tag, - .apptag = cfg.app_tag, - .appmask = cfg.app_tag_mask, - .sts = sts, - .pif = pif, - .storage_tag = cfg.storage_tag, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - err = nvme_verify(&args); + nvme_init_verify(&cmd, cfg.namespace_id, cfg.start_block, + cfg.block_count, control, 0, NULL, 0, NULL, 0); + nvme_init_var_size_tags((struct nvme_passthru_cmd64 *)&cmd, pif, sts, + cfg.ref_tag, cfg.storage_tag); + nvme_init_app_tag((struct nvme_passthru_cmd64 *)&cmd, cfg.app_tag, + cfg.app_tag_mask); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); if (err < 0) - nvme_show_error("verify: %s", nvme_strerror(errno)); + nvme_show_error("verify: %s", nvme_strerror(-err)); else if (err != 0) nvme_show_status(err); else @@ -8648,7 +8524,7 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin return err; } -static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int sec_recv(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Obtain results of one or more\n" "previously submitted security-sends. Results, and association\n" @@ -8659,10 +8535,12 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p const char *size = "size of buffer (prints to stdout on success)"; const char *al = "allocation length (cf. SPC-4)"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; _cleanup_free_ void *sec_buf = NULL; - int err; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; + int err; struct config { __u32 namespace_id; @@ -8693,7 +8571,7 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p OPT_UINT("al", 't', &cfg.al, al), OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_dump)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -8709,24 +8587,12 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p return -ENOMEM; } - struct nvme_security_receive_args args = { - .args_size = sizeof(args), - .nsid = cfg.namespace_id, - .nssf = cfg.nssf, - .spsp0 = cfg.spsp & 0xff, - .spsp1 = cfg.spsp >> 8, - .secp = cfg.secp, - .al = cfg.al, - .data_len = cfg.size, - .data = sec_buf, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - - err = nvme_cli_security_receive(dev, &args); + nvme_init_security_receive(&cmd, cfg.namespace_id, cfg.nssf, cfg.spsp, + cfg.secp, cfg.al, sec_buf, cfg.size); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (err < 0) { - nvme_show_error("security receive: %s", nvme_strerror(errno)); - } else if (err != 0) { + nvme_show_error("security receive: %s", nvme_strerror(-err)); + } else if (err > 0) { nvme_show_status(err); } else { printf("NVME Security Receive Command Success\n"); @@ -8739,7 +8605,7 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p return err; } -static int get_lba_status(int argc, char **argv, struct command *cmd, +static int get_lba_status(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Information about potentially unrecoverable LBAs."; @@ -8752,7 +8618,9 @@ static int get_lba_status(int argc, char **argv, struct command *cmd, const char *rl = "Range Length(RL) specifies the length of the range of contiguous LBAs beginning at SLBA"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; _cleanup_free_ void *buf = NULL; nvme_print_flags_t flags; unsigned long buf_len; @@ -8781,7 +8649,7 @@ static int get_lba_status(int argc, char **argv, struct command *cmd, OPT_BYTE("action", 'a', &cfg.atype, atype), OPT_SHRT("range-len", 'l', &cfg.rl, rl)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -8801,30 +8669,20 @@ static int get_lba_status(int argc, char **argv, struct command *cmd, if (!buf) return -ENOMEM; - struct nvme_get_lba_status_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .slba = cfg.slba, - .mndw = cfg.mndw, - .rl = cfg.rl, - .atype = cfg.atype, - .lbas = buf, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - err = nvme_get_lba_status(&args); + nvme_init_get_lba_status(&cmd, cfg.namespace_id, cfg.slba, cfg.mndw, + cfg.atype, cfg.rl, buf); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) nvme_show_lba_status(buf, buf_len, flags); else if (err > 0) nvme_show_status(err); else - nvme_show_error("get lba status: %s", nvme_strerror(errno)); + nvme_show_error("get lba status: %s", nvme_strerror(-err)); return err; } -static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int capacity_mgmt(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Host software uses the Capacity Management command to\n" "configure Endurance Groups and NVM Sets in an NVM subsystem by either\n" @@ -8837,7 +8695,9 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug const char *cap_upper = "Most significant 32 bits of the capacity in bytes of the Endurance Group or NVM Set to be created"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; int err = -1; __u32 result; nvme_print_flags_t flags; @@ -8862,7 +8722,8 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug OPT_UINT("cap-lower", 'l', &cfg.dw11, cap_lower), OPT_UINT("cap-upper", 'u', &cfg.dw12, cap_upper)); - err = parse_and_open(&dev, argc, argv, desc, opts); + + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -8877,17 +8738,9 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug return -1; } - struct nvme_capacity_mgmt_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .op = cfg.operation, - .element_id = cfg.element_id, - .cdw11 = cfg.dw11, - .cdw12 = cfg.dw12, - .timeout = nvme_cfg.timeout, - .result = &result, - }; - err = nvme_capacity_mgmt(&args); + nvme_init_capacity_mgmt(&cmd, cfg.operation, cfg.element_id, + (__u64)cfg.dw12 << 32 | cfg.dw11); + err = nvme_submit_admin_passthru(hdl, &cmd, &result); if (!err) { printf("Capacity Management Command is Success\n"); if (cfg.operation == 1) @@ -8897,20 +8750,22 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug } else if (err > 0) { nvme_show_status(err); } else if (err < 0) { - nvme_show_error("capacity management: %s", nvme_strerror(errno)); + nvme_show_error("capacity management: %s", nvme_strerror(-err)); } return err; } -static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int dir_receive(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Read directive parameters of the specified directive type."; const char *nsr = "namespace stream requested"; nvme_print_flags_t flags = NORMAL; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ void *buf = NULL; + struct nvme_passthru_cmd cmd; __u32 result; __u32 dw12 = 0; int err; @@ -8947,7 +8802,7 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin OPT_SHRT("req-resource", 'r', &cfg.nsr, nsr), OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable_directive)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -8997,39 +8852,29 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin return -ENOMEM; } - struct nvme_directive_recv_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .dspec = cfg.dspec, - .doper = cfg.doper, - .dtype = cfg.dtype, - .cdw12 = dw12, - .data_len = cfg.data_len, - .data = buf, - .timeout = nvme_cfg.timeout, - .result = &result, - }; - err = nvme_directive_recv(&args); + nvme_init_directive_recv(&cmd, cfg.namespace_id, cfg.doper, cfg.dtype, + cfg.dspec, buf, cfg.data_len); + cmd.cdw12 = dw12; + err = nvme_submit_admin_passthru(hdl, &cmd, &result); if (!err) nvme_directive_show(cfg.dtype, cfg.doper, cfg.dspec, cfg.namespace_id, result, buf, cfg.data_len, flags); else if (err > 0) nvme_show_status(err); else if (err < 0) - nvme_show_error("dir-receive: %s", nvme_strerror(errno)); + nvme_show_error("dir-receive: %s", nvme_strerror(-err)); return err; } /* rpmb_cmd_option is defined in nvme-rpmb.c */ extern int rpmb_cmd_option(int, char **, struct command *, struct plugin *); -static int rpmb_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int rpmb_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return rpmb_cmd_option(argc, argv, cmd, plugin); + return rpmb_cmd_option(argc, argv, acmd, plugin); } -static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int lockdown_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "The Lockdown command is used to control the\n" "Command and Feature Lockdown capability which configures the\n" @@ -9050,7 +8895,9 @@ static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugi "List that is used by the command.If this field is cleared to 0h,\n" "then no UUID index is specified"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; int err = -1; struct config { @@ -9076,7 +8923,7 @@ static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugi OPT_BYTE("scp", 's', &cfg.scp, scp_desc), OPT_BYTE("uuid", 'U', &cfg.uuid, uuid_desc)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -9098,20 +8945,11 @@ static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugi return -1; } - struct nvme_lockdown_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .scp = cfg.scp, - .prhbt = cfg.prhbt, - .ifc = cfg.ifc, - .ofi = cfg.ofi, - .uuidx = cfg.uuid, - .timeout = nvme_cfg.timeout, - .result = NULL, - }; - err = nvme_lockdown(&args); + nvme_init_lockdown(&cmd, cfg.scp, cfg.prhbt, cfg.ifc, cfg.ofi, + cfg.uuid); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (err < 0) - nvme_show_error("lockdown: %s", nvme_strerror(errno)); + nvme_show_error("lockdown: %s", nvme_strerror(-err)); else if (err > 0) nvme_show_status(err); else @@ -9146,7 +8984,7 @@ static void passthru_print_read_output(struct passthru_config cfg, void *data, i } static int passthru(int argc, char **argv, bool admin, - const char *desc, struct command *cmd) + const char *desc, struct command *acmd) { const char *opcode = "opcode (required)"; const char *cflags = "command flags"; @@ -9169,7 +9007,8 @@ static int passthru(int argc, char **argv, bool admin, const char *prefill = "prefill buffers with known byte-value, default 0"; _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_fd_ int dfd = -1, mfd = -1; int flags; int mode = 0644; @@ -9231,7 +9070,7 @@ static int passthru(int argc, char **argv, bool admin, OPT_FLAG("write", 'w', &cfg.write, wr), OPT_FLAG("latency", 'T', &cfg.latency, latency)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -9242,7 +9081,7 @@ static int passthru(int argc, char **argv, bool admin, } if (!argconfig_parse_seen(opts, "opcode")) { - nvme_show_error("%s: opcode parameter required", cmd->name); + nvme_show_error("%s: opcode parameter required", acmd->name); return -EINVAL; } @@ -9335,17 +9174,17 @@ static int passthru(int argc, char **argv, bool admin, gettimeofday(&start_time, NULL); if (admin) - err = nvme_cli_admin_passthru(dev, cfg.opcode, cfg.flags, - cfg.rsvd, - cfg.namespace_id, cfg.cdw2, - cfg.cdw3, cfg.cdw10, - cfg.cdw11, cfg.cdw12, cfg.cdw13, - cfg.cdw14, - cfg.cdw15, cfg.data_len, data, - cfg.metadata_len, - mdata, nvme_cfg.timeout, &result); + err = nvme_admin_passthru(hdl, cfg.opcode, cfg.flags, + cfg.rsvd, + cfg.namespace_id, cfg.cdw2, + cfg.cdw3, cfg.cdw10, + cfg.cdw11, cfg.cdw12, cfg.cdw13, + cfg.cdw14, + cfg.cdw15, cfg.data_len, data, + cfg.metadata_len, + mdata, nvme_cfg.timeout, &result); else - err = nvme_io_passthru(dev_fd(dev), cfg.opcode, cfg.flags, + err = nvme_io_passthru(hdl, cfg.opcode, cfg.flags, cfg.rsvd, cfg.namespace_id, cfg.cdw2, cfg.cdw3, cfg.cdw10, @@ -9363,7 +9202,7 @@ static int passthru(int argc, char **argv, bool admin, elapsed_utime(start_time, end_time)); if (err < 0) { - nvme_show_error("%s: %s", __func__, nvme_strerror(errno)); + nvme_show_error("%s: %s", __func__, nvme_strerror(-err)); } else if (err) { nvme_show_status(err); } else { @@ -9376,30 +9215,30 @@ static int passthru(int argc, char **argv, bool admin, return err; } -static int io_passthru(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int io_passthru(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send a user-defined IO command to the specified device via IOCTL passthrough, return results."; - return passthru(argc, argv, false, desc, cmd); + return passthru(argc, argv, false, desc, acmd); } -static int admin_passthru(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int admin_passthru(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send a user-defined Admin command to the specified device via IOCTL passthrough, return results."; - return passthru(argc, argv, true, desc, cmd); + return passthru(argc, argv, true, desc, acmd); } -static int gen_hostnqn_cmd(int argc, char **argv, struct command *command, struct plugin *plugin) +static int gen_hostnqn_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { char *hostnqn; hostnqn = nvmf_hostnqn_generate(); if (!hostnqn) { nvme_show_error("\"%s\" not supported. Install lib uuid and rebuild.", - command->name); + acmd->name); return -ENOTSUP; } printf("%s\n", hostnqn); @@ -9407,7 +9246,7 @@ static int gen_hostnqn_cmd(int argc, char **argv, struct command *command, struc return 0; } -static int show_hostnqn_cmd(int argc, char **argv, struct command *command, struct plugin *plugin) +static int show_hostnqn_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { char *hostnqn; @@ -9427,7 +9266,7 @@ static int show_hostnqn_cmd(int argc, char **argv, struct command *command, stru } -static int gen_dhchap_key(int argc, char **argv, struct command *command, struct plugin *plugin) +static int gen_dhchap_key(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Generate a DH-HMAC-CHAP host key usable for NVMe In-Band Authentication."; @@ -9541,8 +9380,9 @@ static int gen_dhchap_key(int argc, char **argv, struct command *command, struct } } - if (nvme_gen_dhchap_key(cfg.nqn, cfg.hmac, cfg.key_len, raw_secret, key) < 0) - return -errno; + err = nvme_gen_dhchap_key(cfg.nqn, cfg.hmac, cfg.key_len, raw_secret, key); + if (err) + return err; crc = crc32(crc, key, cfg.key_len); key[cfg.key_len++] = crc & 0xff; @@ -9557,7 +9397,7 @@ static int gen_dhchap_key(int argc, char **argv, struct command *command, struct return 0; } -static int check_dhchap_key(int argc, char **argv, struct command *command, struct plugin *plugin) +static int check_dhchap_key(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Check a DH-HMAC-CHAP host key for usability for NVMe In-Band Authentication."; @@ -9657,18 +9497,17 @@ static int append_keyfile(const char *keyring, long id, const char *keyfile) long kr_id; char type; - kr_id = nvme_lookup_keyring(keyring); - if (kr_id <= 0) { + err = nvme_lookup_keyring(keyring, &kr_id); + if (err) { nvme_show_error("Failed to lookup keyring '%s', %s", - keyring, strerror(errno)); - return -errno; + keyring, strerror(-err)); + return err; } identity = nvme_describe_key_serial(id); if (!identity) { - nvme_show_error("Failed to get identity info, %s", - strerror(errno)); - return -errno; + nvme_show_error("Failed to get identity info"); + return -EINVAL; } if (sscanf(identity, "NVMe%01d%c%02d %*s", &ver, &type, &hmac) != 3) { @@ -9676,19 +9515,20 @@ static int append_keyfile(const char *keyring, long id, const char *keyfile) return -EINVAL; } - key_data = nvme_read_key(kr_id, id, &key_len); - if (!key_data) { + err = nvme_read_key(kr_id, id, &key_len, &key_data); + if (err) { nvme_show_error("Failed to read back derive TLS PSK, %s", - strerror(errno)); - return -errno; + strerror(-err)); + return err; } - exported_key = nvme_export_tls_key_versioned(ver, hmac, - key_data, key_len); - if (!exported_key) { + err = nvme_export_tls_key_versioned(ver, hmac, + key_data, key_len, + &exported_key); + if (err) { nvme_show_error("Failed to export key, %s", - strerror(errno)); - return -errno; + strerror(-err)); + return err; } old_umask = umask(0); @@ -9717,7 +9557,7 @@ static int append_keyfile(const char *keyring, long id, const char *keyfile) return err; } -static int gen_tls_key(int argc, char **argv, struct command *command, struct plugin *plugin) +static int gen_tls_key(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Generate a TLS key in NVMe PSK Interchange format."; const char *secret = @@ -9828,17 +9668,21 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl } } - encoded_key = nvme_export_tls_key(raw_secret, key_len); + err = nvme_export_tls_key(raw_secret, key_len, &encoded_key); + if (err) { + nvme_show_error("Failed to export key, %s", strerror(errno)); + return err; + } printf("%s\n", encoded_key); if (cfg.insert) { - tls_key = nvme_insert_tls_key_versioned(cfg.keyring, - cfg.keytype, cfg.hostnqn, - cfg.subsysnqn, cfg.version, - cfg.hmac, raw_secret, key_len); - if (tls_key <= 0) { - nvme_show_error("Failed to insert key, error %d", errno); - return -errno; + err = nvme_insert_tls_key_versioned(cfg.keyring, + cfg.keytype, cfg.hostnqn, + cfg.subsysnqn, cfg.version, + cfg.hmac, raw_secret, key_len, &tls_key); + if (err) { + nvme_show_error("Failed to insert key, error %d", err); + return err; } printf("Inserted TLS key %08x\n", (unsigned int)tls_key); @@ -9853,7 +9697,7 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl return 0; } -static int check_tls_key(int argc, char **argv, struct command *command, struct plugin *plugin) +static int check_tls_key(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Check a TLS key for NVMe PSK Interchange format.\n"; const char *keydata = "TLS key (in PSK Interchange format) to be validated."; @@ -9916,10 +9760,10 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct return -EINVAL; } - decoded_key = nvme_import_tls_key(cfg.keydata, &decoded_len, &hmac); - if (!decoded_key) { - nvme_show_error("Key decoding failed, error %d\n", errno); - return -errno; + err = nvme_import_tls_key(cfg.keydata, &decoded_len, &hmac, &decoded_key); + if (err) { + nvme_show_error("Key decoding failed, error %d\n", err); + return err; } if (cfg.subsysnqn) { @@ -9936,13 +9780,14 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct } if (cfg.insert) { - tls_key = nvme_insert_tls_key_versioned(cfg.keyring, - cfg.keytype, cfg.hostnqn, - cfg.subsysnqn, cfg.identity, - hmac, decoded_key, decoded_len); - if (tls_key <= 0) { - nvme_show_error("Failed to insert key, error %d", errno); - return -errno; + err = nvme_insert_tls_key_versioned(cfg.keyring, + cfg.keytype, cfg.hostnqn, + cfg.subsysnqn, cfg.identity, + hmac, decoded_key, decoded_len, + &tls_key); + if (err) { + nvme_show_error("Failed to insert key, error %d", -err); + return err; } printf("Inserted TLS key %08x\n", (unsigned int)tls_key); @@ -9954,13 +9799,14 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct } else { _cleanup_free_ char *tls_id = NULL; - tls_id = nvme_generate_tls_key_identity(cfg.hostnqn, - cfg.subsysnqn, cfg.identity, - hmac, decoded_key, decoded_len); - if (!tls_id) { + err = nvme_generate_tls_key_identity(cfg.hostnqn, + cfg.subsysnqn, cfg.identity, + hmac, decoded_key, decoded_len, + &tls_id); + if (err) { nvme_show_error("Failed to generate identity, error %d", - errno); - return -errno; + err); + return err; } printf("%s\n", tls_id); } @@ -9971,39 +9817,41 @@ static void __scan_tls_key(long keyring_id, long key_id, char *desc, int desc_len, void *data) { FILE *fd = data; - _cleanup_free_ const unsigned char *key_data = NULL; + _cleanup_free_ unsigned char *key_data = NULL; _cleanup_free_ char *encoded_key = NULL; int key_len; int ver, hmac; char type; + int err; - key_data = nvme_read_key(keyring_id, key_id, &key_len); - if (!key_data) + err = nvme_read_key(keyring_id, key_id, &key_len, &key_data); + if (err) return; if (sscanf(desc, "NVMe%01d%c%02d %*s", &ver, &type, &hmac) != 3) return; - encoded_key = nvme_export_tls_key_versioned(ver, hmac, - key_data, key_len); - if (!encoded_key) + err = nvme_export_tls_key_versioned(ver, hmac, key_data, key_len, + &encoded_key); + if (err) return; fprintf(fd, "%s %s\n", desc, encoded_key); } static int import_key(const char *keyring, FILE *fd) { - long keyring_id; + long keyring_id, key; char tls_str[512]; char *tls_key; unsigned char *psk; unsigned int hmac; int linenum = -1, key_len; + int err; - keyring_id = nvme_lookup_keyring(keyring); - if (!keyring_id) { + err = nvme_lookup_keyring(keyring, &keyring_id); + if (err) { nvme_show_error("Invalid keyring '%s'", keyring); - return -ENOKEY; + return err; } while (fgets(tls_str, 512, fd)) { @@ -10017,14 +9865,17 @@ static int import_key(const char *keyring, FILE *fd) *tls_key = '\0'; tls_key++; tls_key[strcspn(tls_key, "\n")] = 0; - psk = nvme_import_tls_key(tls_key, &key_len, &hmac); - if (!psk) { + err = nvme_import_tls_key(tls_key, &key_len, &hmac, &psk); + if (err) { nvme_show_error("Failed to import key in line %d", linenum); continue; } - nvme_update_key(keyring_id, "psk", tls_str, - psk, key_len); + err = nvme_update_key(keyring_id, "psk", tls_str, + psk, key_len, &key); + if (err) { + continue; + } free(psk); } @@ -10032,7 +9883,7 @@ static int import_key(const char *keyring, FILE *fd) } -static int tls_key(int argc, char **argv, struct command *command, struct plugin *plugin) +static int tls_key(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Manipulation of TLS keys.\n"; const char *keyring = "Keyring for the retained key."; @@ -10111,7 +9962,7 @@ static int tls_key(int argc, char **argv, struct command *command, struct plugin err = nvme_scan_tls_keys(cfg.keyring, __scan_tls_key, fd); if (err < 0) { nvme_show_error("Export of TLS keys failed with '%s'", - nvme_strerror(errno)); + nvme_strerror(-err)); return err; } @@ -10123,7 +9974,7 @@ static int tls_key(int argc, char **argv, struct command *command, struct plugin err = import_key(cfg.keyring, fd); if (err) { nvme_show_error("Import of TLS keys failed with '%s'", - nvme_strerror(errno)); + nvme_strerror(-err)); return err; } @@ -10133,7 +9984,7 @@ static int tls_key(int argc, char **argv, struct command *command, struct plugin err = nvme_revoke_tls_key(cfg.keyring, cfg.keytype, cfg.revoke); if (err) { nvme_show_error("Failed to revoke key '%s'", - nvme_strerror(errno)); + nvme_strerror(-err)); return err; } @@ -10149,12 +10000,12 @@ static int tls_key(int argc, char **argv, struct command *command, struct plugin return err; } -static int show_topology_cmd(int argc, char **argv, struct command *command, struct plugin *plugin) +static int show_topology_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Show the topology\n"; const char *ranking = "Ranking order: namespace|ctrl"; nvme_print_flags_t flags; - _cleanup_nvme_root_ nvme_root_t r = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; enum nvme_cli_topo_ranking rank; int err; @@ -10191,52 +10042,52 @@ static int show_topology_cmd(int argc, char **argv, struct command *command, str return -EINVAL; } - r = nvme_create_root(stderr, log_level); - if (!r) { + ctx = nvme_create_global_ctx(stderr, log_level); + if (!ctx) { nvme_show_error("Failed to create topology root: %s", nvme_strerror(errno)); - return -errno; + return -ENOMEM; } - err = nvme_scan_topology(r, NULL, NULL); + err = nvme_scan_topology(ctx, NULL, NULL); if (err < 0) { - nvme_show_error("Failed to scan topology: %s", nvme_strerror(errno)); + nvme_show_error("Failed to scan topology: %s", nvme_strerror(-err)); return err; } - nvme_show_topology(r, rank, flags); + nvme_show_topology(ctx, rank, flags); return err; } -static int discover_cmd(int argc, char **argv, struct command *command, struct plugin *plugin) +static int discover_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send Get Log Page request to Discovery Controller."; return nvmf_discover(desc, argc, argv, false); } -static int connect_all_cmd(int argc, char **argv, struct command *command, struct plugin *plugin) +static int connect_all_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Discover NVMeoF subsystems and connect to them"; return nvmf_discover(desc, argc, argv, true); } -static int connect_cmd(int argc, char **argv, struct command *command, struct plugin *plugin) +static int connect_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Connect to NVMeoF subsystem"; return nvmf_connect(desc, argc, argv); } -static int disconnect_cmd(int argc, char **argv, struct command *command, struct plugin *plugin) +static int disconnect_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Disconnect from NVMeoF subsystem"; return nvmf_disconnect(desc, argc, argv); } -int disconnect_all_cmd(int argc, char **argv, struct command *command, +int disconnect_all_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Disconnect from all connected NVMeoF subsystems"; @@ -10244,14 +10095,14 @@ int disconnect_all_cmd(int argc, char **argv, struct command *command, return nvmf_disconnect_all(desc, argc, argv); } -static int config_cmd(int argc, char **argv, struct command *command, struct plugin *plugin) +static int config_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Configuration of NVMeoF subsystems"; return nvmf_config(desc, argc, argv); } -static int dim_cmd(int argc, char **argv, struct command *command, struct plugin *plugin) +static int dim_cmd(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send Discovery Information Management command to a Discovery Controller (DC)"; @@ -10275,7 +10126,8 @@ static int nvme_mi(int argc, char **argv, __u8 admin_opcode, const char *desc) _cleanup_fd_ int fd = -1; int flags; _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 result; struct config { @@ -10307,7 +10159,7 @@ static int nvme_mi(int argc, char **argv, __u8 admin_opcode, const char *desc) OPT_UINT("nmd1", '1', &cfg.nmd1, nmd1), OPT_FILE("input-file", 'i', &cfg.input_file, input)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -10350,11 +10202,11 @@ static int nvme_mi(int argc, char **argv, __u8 admin_opcode, const char *desc) } } - err = nvme_cli_admin_passthru(dev, admin_opcode, 0, 0, cfg.namespace_id, 0, 0, - cfg.nmimt << 11 | 4, cfg.opcode, cfg.nmd0, cfg.nmd1, 0, 0, - cfg.data_len, data, 0, NULL, 0, &result); + err = nvme_admin_passthru(hdl, admin_opcode, 0, 0, cfg.namespace_id, 0, 0, + cfg.nmimt << 11 | 4, cfg.opcode, cfg.nmd0, cfg.nmd1, 0, 0, + cfg.data_len, data, 0, NULL, 0, &result); if (err < 0) { - nvme_show_error("nmi_recv: %s", nvme_strerror(errno)); + nvme_show_error("nmi_recv: %s", nvme_strerror(-err)); } else if (err) { nvme_show_status(err); } else { @@ -10374,7 +10226,7 @@ static int nvme_mi(int argc, char **argv, __u8 admin_opcode, const char *desc) return err; } -static int nmi_recv(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int nmi_recv(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send a NVMe-MI Receive command to the specified device, return results."; @@ -10382,26 +10234,26 @@ static int nmi_recv(int argc, char **argv, struct command *cmd, struct plugin *p return nvme_mi(argc, argv, nvme_admin_nvme_mi_recv, desc); } -static int nmi_send(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int nmi_send(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send a NVMe-MI Send command to the specified device, return results."; return nvme_mi(argc, argv, nvme_admin_nvme_mi_send, desc); } -static int get_mgmt_addr_list_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_mgmt_addr_list_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Management Address List Log, show it"; nvme_print_flags_t flags; int err = -1; _cleanup_free_ struct nvme_mgmt_addr_list_log *ma_log = NULL; - - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; NVME_ARGS(opts); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -10415,7 +10267,7 @@ static int get_mgmt_addr_list_log(int argc, char **argv, struct command *cmd, st if (!ma_log) return -ENOMEM; - err = nvme_cli_get_log_mgmt_addr_list(dev, sizeof(*ma_log), ma_log); + err = nvme_get_log_mgmt_addr_list(hdl, ma_log, sizeof(*ma_log)); if (!err) nvme_show_mgmt_addr_list_log(ma_log, flags); else if (err > 0) @@ -10426,7 +10278,7 @@ static int get_mgmt_addr_list_log(int argc, char **argv, struct command *cmd, st return err; } -static int get_rotational_media_info_log(int argc, char **argv, struct command *cmd, +static int get_rotational_media_info_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Rotational Media Information Log, show it"; @@ -10434,8 +10286,8 @@ static int get_rotational_media_info_log(int argc, char **argv, struct command * int err = -1; _cleanup_free_ struct nvme_rotational_media_info_log *info = NULL; - - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct config { __u16 endgid; @@ -10448,7 +10300,7 @@ static int get_rotational_media_info_log(int argc, char **argv, struct command * NVME_ARGS(opts, OPT_UINT("endg-id", 'e', &cfg.endgid, endgid)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -10462,7 +10314,7 @@ static int get_rotational_media_info_log(int argc, char **argv, struct command * if (!info) return -ENOMEM; - err = nvme_cli_get_log_rotational_media_info(dev, cfg.endgid, sizeof(*info), info); + err = nvme_get_log_rotational_media_info(hdl, cfg.endgid, info, sizeof(*info)); if (!err) nvme_show_rotational_media_info_log(info, flags); else if (err > 0) @@ -10473,26 +10325,20 @@ static int get_rotational_media_info_log(int argc, char **argv, struct command * return err; } -static int get_dispersed_ns_psub(struct nvme_dev *dev, __u32 nsid, +static int get_dispersed_ns_psub(struct nvme_transport_handle *hdl, __u32 nsid, struct nvme_dispersed_ns_participating_nss_log **logp) { - int err; + struct nvme_dispersed_ns_participating_nss_log *log; __u64 header_len = sizeof(**logp); + struct nvme_passthru_cmd cmd; __u64 psub_list_len; - struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = NVME_LOG_LID_DISPERSED_NS_PARTICIPATING_NSS, - .nsid = nsid, - .lpo = header_len, - }; - struct nvme_dispersed_ns_participating_nss_log *log = nvme_alloc(header_len); + int err; + log = nvme_alloc(header_len); if (!log) return -ENOMEM; - err = nvme_cli_get_log_dispersed_ns_participating_nss(dev, nsid, header_len, log); + err = nvme_get_log_dispersed_ns_participating_nss(hdl, nsid, log, header_len); if (err) goto err_free; @@ -10504,10 +10350,11 @@ static int get_dispersed_ns_psub(struct nvme_dev *dev, __u32 nsid, goto err_free; } - args.log = log->participating_nss, - args.len = psub_list_len; - - err = nvme_cli_get_log_page(dev, NVME_LOG_PAGE_PDU_SIZE, &args); + nvme_init_get_log_dispersed_ns_participating_nss(&cmd, nsid, + (void *)log->participating_nss, psub_list_len); + cmd.cdw12 = header_len & 0xffffffff; + cmd.cdw13 = header_len >> 32; + err = nvme_get_log(hdl, &cmd, false, NVME_LOG_PAGE_PDU_SIZE, NULL); if (err) goto err_free; @@ -10519,15 +10366,15 @@ static int get_dispersed_ns_psub(struct nvme_dev *dev, __u32 nsid, return err; } -static int get_dispersed_ns_participating_nss_log(int argc, char **argv, struct command *cmd, +static int get_dispersed_ns_participating_nss_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Dispersed Namespace Participating NVM Subsystems Log, show it"; nvme_print_flags_t flags; int err; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ struct nvme_dispersed_ns_participating_nss_log *log = NULL; struct config { @@ -10540,7 +10387,7 @@ static int get_dispersed_ns_participating_nss_log(int argc, char **argv, struct NVME_ARGS(opts, OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -10550,7 +10397,7 @@ static int get_dispersed_ns_participating_nss_log(int argc, char **argv, struct return err; } - err = get_dispersed_ns_psub(dev, cfg.namespace_id, &log); + err = get_dispersed_ns_psub(hdl, cfg.namespace_id, &log); if (!err) nvme_show_dispersed_ns_psub_log(log, flags); else if (err > 0) @@ -10561,20 +10408,43 @@ static int get_dispersed_ns_participating_nss_log(int argc, char **argv, struct return err; } -static int get_log_offset(struct nvme_dev *dev, struct nvme_get_log_args *args, __u64 *offset, +static int get_log_offset(struct nvme_transport_handle *hdl, + struct nvme_get_log_args *args, __u64 *offset, __u32 len, void **log) { + struct nvme_passthru_cmd cmd; + args->lpo = *offset, args->log = *log + *offset, args->len = len; *offset += args->len; + *log = nvme_realloc(*log, *offset); if (!*log) return -ENOMEM; - return nvme_cli_get_log_page(dev, NVME_LOG_PAGE_PDU_SIZE, args); -} -static int get_reachability_group_desc(struct nvme_dev *dev, struct nvme_get_log_args *args, + nvme_init_get_log(&cmd, args->nsid, args->lid, + args->csi, args->log, args->len); + cmd.cdw10 |= NVME_FIELD_ENCODE(args->lsp, + NVME_LOG_CDW10_LSP_SHIFT, + NVME_LOG_CDW10_LSP_MASK); + cmd.cdw11 |= NVME_FIELD_ENCODE(args->lsi, + NVME_LOG_CDW11_LSI_SHIFT, + NVME_LOG_CDW11_LSI_MASK); + cmd.cdw12 = args->lpo & 0xffffffff; + cmd.cdw13 = args->lpo >> 32; + cmd.cdw14 |= NVME_FIELD_ENCODE(args->uidx, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK) | + NVME_FIELD_ENCODE(args->ot, + NVME_LOG_CDW14_OT_SHIFT, + NVME_LOG_CDW14_OT_MASK); + + return nvme_get_log(hdl, &cmd, args->rae, + NVME_LOG_PAGE_PDU_SIZE, args->result); +} + +static int get_reachability_group_desc(struct nvme_transport_handle *hdl, struct nvme_get_log_args *args, __u64 *offset, struct nvme_reachability_groups_log **logp) { int err; @@ -10584,11 +10454,11 @@ static int get_reachability_group_desc(struct nvme_dev *dev, struct nvme_get_log for (i = 0; i < le16_to_cpu(log->nrgd); i++) { len = sizeof(*log->rgd); - err = get_log_offset(dev, args, offset, len, (void **)&log); + err = get_log_offset(hdl, args, offset, len, (void **)&log); if (err) goto err_free; len = le32_to_cpu(log->rgd[i].nnid) * sizeof(*log->rgd[i].nsid); - err = get_log_offset(dev, args, offset, len, (void **)&log); + err = get_log_offset(hdl, args, offset, len, (void **)&log); if (err) goto err_free; } @@ -10602,7 +10472,7 @@ static int get_reachability_group_desc(struct nvme_dev *dev, struct nvme_get_log return err; } -static int get_reachability_groups(struct nvme_dev *dev, bool rgo, bool rae, +static int get_reachability_groups(struct nvme_transport_handle *hdl, bool rgo, bool rae, struct nvme_reachability_groups_log **logp, __u64 *lenp) { @@ -10610,24 +10480,21 @@ static int get_reachability_groups(struct nvme_dev *dev, bool rgo, bool rae, struct nvme_reachability_groups_log *log; __u64 log_len = sizeof(*log); struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = NVME_LOG_LID_REACHABILITY_GROUPS, .nsid = NVME_NSID_ALL, - .lsp = rgo, .rae = rae, + .lsp = rgo, + .lid = NVME_LOG_LID_REACHABILITY_GROUPS, }; log = nvme_alloc(log_len); if (!log) return -ENOMEM; - err = nvme_cli_get_log_reachability_groups(dev, rgo, rae, log_len, log); + err = nvme_get_log_reachability_groups(hdl, rae, rgo, log, log_len); if (err) goto err_free; - err = get_reachability_group_desc(dev, &args, &log_len, &log); + err = get_reachability_group_desc(hdl, &args, &log_len, &log); if (err) goto err_free; @@ -10640,7 +10507,7 @@ static int get_reachability_groups(struct nvme_dev *dev, bool rgo, bool rae, return err; } -static int get_reachability_groups_log(int argc, char **argv, struct command *cmd, +static int get_reachability_groups_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Reachability Groups Log, show it"; @@ -10648,10 +10515,9 @@ static int get_reachability_groups_log(int argc, char **argv, struct command *cm nvme_print_flags_t flags; int err; __u64 len = 0; - _cleanup_free_ struct nvme_reachability_groups_log *log = NULL; - - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct config { bool rgo; @@ -10667,7 +10533,7 @@ static int get_reachability_groups_log(int argc, char **argv, struct command *cm OPT_FLAG("groups-only", 'g', &cfg.rgo, rgo), OPT_FLAG("rae", 'r', &cfg.rae, rae)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -10677,7 +10543,7 @@ static int get_reachability_groups_log(int argc, char **argv, struct command *cm return err; } - err = get_reachability_groups(dev, cfg.rgo, cfg.rae, &log, &len); + err = get_reachability_groups(hdl, cfg.rgo, cfg.rae, &log, &len); if (!err) nvme_show_reachability_groups_log(log, len, flags); else if (err > 0) @@ -10688,7 +10554,7 @@ static int get_reachability_groups_log(int argc, char **argv, struct command *cm return err; } -static int get_reachability_association_desc(struct nvme_dev *dev, struct nvme_get_log_args *args, +static int get_reachability_association_desc(struct nvme_transport_handle *hdl, struct nvme_get_log_args *args, __u64 *offset, struct nvme_reachability_associations_log **logp) { @@ -10699,11 +10565,11 @@ static int get_reachability_association_desc(struct nvme_dev *dev, struct nvme_g for (i = 0; i < le16_to_cpu(log->nrad); i++) { len = sizeof(*log->rad); - err = get_log_offset(dev, args, offset, len, (void **)&log); + err = get_log_offset(hdl, args, offset, len, (void **)&log); if (err) goto err_free; len = le32_to_cpu(log->rad[i].nrid) * sizeof(*log->rad[i].rgid); - err = get_log_offset(dev, args, offset, len, (void **)&log); + err = get_log_offset(hdl, args, offset, len, (void **)&log); if (err) goto err_free; } @@ -10717,7 +10583,7 @@ static int get_reachability_association_desc(struct nvme_dev *dev, struct nvme_g return err; } -static int get_reachability_associations(struct nvme_dev *dev, bool rao, bool rae, +static int get_reachability_associations(struct nvme_transport_handle *hdl, bool rao, bool rae, struct nvme_reachability_associations_log **logp, __u64 *lenp) { @@ -10725,24 +10591,22 @@ static int get_reachability_associations(struct nvme_dev *dev, bool rao, bool ra struct nvme_reachability_associations_log *log; __u64 log_len = sizeof(*log); struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = NVME_LOG_LID_REACHABILITY_ASSOCIATIONS, .nsid = NVME_NSID_ALL, - .lsp = rao, .rae = rae, + .lsp = rao, + .lid = NVME_LOG_LID_REACHABILITY_ASSOCIATIONS, }; log = nvme_alloc(log_len); if (!log) return -ENOMEM; - err = nvme_cli_get_log_reachability_associations(dev, rao, rae, log_len, log); + err = nvme_get_log_reachability_associations(hdl, rae, rao, + log, log_len); if (err) goto err_free; - err = get_reachability_association_desc(dev, &args, &log_len, &log); + err = get_reachability_association_desc(hdl, &args, &log_len, &log); if (err) goto err_free; @@ -10755,7 +10619,7 @@ static int get_reachability_associations(struct nvme_dev *dev, bool rao, bool ra return err; } -static int get_reachability_associations_log(int argc, char **argv, struct command *cmd, +static int get_reachability_associations_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Reachability Associations Log, show it"; @@ -10763,10 +10627,9 @@ static int get_reachability_associations_log(int argc, char **argv, struct comma nvme_print_flags_t flags; int err; __u64 len = 0; - _cleanup_free_ struct nvme_reachability_associations_log *log = NULL; - - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct config { bool rao; @@ -10782,7 +10645,7 @@ static int get_reachability_associations_log(int argc, char **argv, struct comma OPT_FLAG("associations-only", 'a', &cfg.rao, rao), OPT_FLAG("rae", 'r', &cfg.rae, rae)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -10792,7 +10655,7 @@ static int get_reachability_associations_log(int argc, char **argv, struct comma return err; } - err = get_reachability_associations(dev, cfg.rao, cfg.rae, &log, &len); + err = get_reachability_associations(hdl, cfg.rao, cfg.rae, &log, &len); if (!err) nvme_show_reachability_associations_log(log, len, flags); else if (err > 0) @@ -10803,33 +10666,30 @@ static int get_reachability_associations_log(int argc, char **argv, struct comma return err; } -static int get_host_discovery(struct nvme_dev *dev, bool allhoste, bool rae, +static int get_host_discovery(struct nvme_transport_handle *hdl, bool allhoste, bool rae, struct nvme_host_discover_log **logp) { int err; struct nvme_host_discover_log *log; __u64 log_len = sizeof(*log); struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = NVME_LOG_LID_HOST_DISCOVER, .nsid = NVME_NSID_ALL, - .lsp = allhoste, .rae = rae, + .lsp = allhoste, + .lid = NVME_LOG_LID_HOST_DISCOVERY, }; log = nvme_alloc(log_len); if (!log) return -ENOMEM; - err = nvme_cli_get_log_host_discovery(dev, allhoste, rae, log_len, log); + err = nvme_get_log_host_discovery(hdl, rae, allhoste, log, log_len); if (err) goto err_free; log_len = le32_to_cpu(log->thdlpl); - err = get_log_offset(dev, &args, &log_len, le32_to_cpu(log->thdlpl) - log_len, - (void **)&log); + err = get_log_offset(hdl, &args, &log_len, + le32_to_cpu(log->thdlpl) - log_len, (void **)&log); if (err) goto err_free; @@ -10841,16 +10701,15 @@ static int get_host_discovery(struct nvme_dev *dev, bool allhoste, bool rae, return err; } -static int get_host_discovery_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_host_discovery_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Host Discovery Log, show it"; const char *allhoste = "All Host Entries"; nvme_print_flags_t flags; int err; - _cleanup_free_ struct nvme_host_discover_log *log = NULL; - - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct config { bool allhoste; @@ -10866,7 +10725,8 @@ static int get_host_discovery_log(int argc, char **argv, struct command *cmd, st OPT_FLAG("all-host-entries", 'a', &cfg.allhoste, allhoste), OPT_FLAG("rae", 'r', &cfg.rae, rae)); - err = parse_and_open(&dev, argc, argv, desc, opts); + + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -10876,7 +10736,7 @@ static int get_host_discovery_log(int argc, char **argv, struct command *cmd, st return err; } - err = get_host_discovery(dev, cfg.allhoste, cfg.rae, &log); + err = get_host_discovery(hdl, cfg.allhoste, cfg.rae, &log); if (!err) nvme_show_host_discovery_log(log, flags); else if (err > 0) @@ -10887,31 +10747,28 @@ static int get_host_discovery_log(int argc, char **argv, struct command *cmd, st return err; } -static int get_ave_discovery(struct nvme_dev *dev, bool rae, struct nvme_ave_discover_log **logp) +static int get_ave_discovery(struct nvme_transport_handle *hdl, bool rae, struct nvme_ave_discover_log **logp) { int err; struct nvme_ave_discover_log *log; __u64 log_len = sizeof(*log); struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = NVME_LOG_LID_AVE_DISCOVER, .nsid = NVME_NSID_ALL, .rae = rae, + .lid = NVME_LOG_LID_AVE_DISCOVERY, }; log = nvme_alloc(log_len); if (!log) return -ENOMEM; - err = nvme_cli_get_log_ave_discovery(dev, rae, log_len, log); + err = nvme_get_log_ave_discovery(hdl, rae, log, log_len); if (err) goto err_free; log_len = le32_to_cpu(log->tadlpl); - err = get_log_offset(dev, &args, &log_len, le32_to_cpu(log->tadlpl) - log_len, - (void **)&log); + err = get_log_offset(hdl, &args, &log_len, + le32_to_cpu(log->tadlpl) - log_len, (void **)&log); if (err) goto err_free; @@ -10923,15 +10780,15 @@ static int get_ave_discovery(struct nvme_dev *dev, bool rae, struct nvme_ave_dis return err; } -static int get_ave_discovery_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_ave_discovery_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve AVE Discovery Log, show it"; nvme_print_flags_t flags; int err; _cleanup_free_ struct nvme_ave_discover_log *log = NULL; - - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct config { bool rae; @@ -10943,7 +10800,7 @@ static int get_ave_discovery_log(int argc, char **argv, struct command *cmd, str NVME_ARGS(opts, OPT_FLAG("rae", 'r', &cfg.rae, rae)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -10953,7 +10810,7 @@ static int get_ave_discovery_log(int argc, char **argv, struct command *cmd, str return err; } - err = get_ave_discovery(dev, cfg.rae, &log); + err = get_ave_discovery(hdl, cfg.rae, &log); if (!err) nvme_show_ave_discovery_log(log, flags); else if (err > 0) @@ -10964,31 +10821,28 @@ static int get_ave_discovery_log(int argc, char **argv, struct command *cmd, str return err; } -static int get_pull_model_ddc_req(struct nvme_dev *dev, +static int get_pull_model_ddc_req(struct nvme_transport_handle *hdl, bool rae, struct nvme_pull_model_ddc_req_log **logp) { int err; struct nvme_pull_model_ddc_req_log *log; __u64 log_len = sizeof(*log); struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = NVME_LOG_LID_PULL_MODEL_DDC_REQ, .nsid = NVME_NSID_ALL, .rae = rae, + .lid = NVME_LOG_LID_PULL_MODEL_DDC_REQ, }; log = nvme_alloc(log_len); if (!log) return -ENOMEM; - err = nvme_cli_get_log_pull_model_ddc_req(dev, rae, log_len, log); + err = nvme_get_log_pull_model_ddc_req(hdl, rae, log, log_len); if (err) goto err_free; log_len = le32_to_cpu(log->tpdrpl); - err = get_log_offset(dev, &args, &log_len, le32_to_cpu(log->tpdrpl) - log_len, + err = get_log_offset(hdl, &args, &log_len, le32_to_cpu(log->tpdrpl) - log_len, (void **)&log); if (err) goto err_free; @@ -11001,7 +10855,7 @@ static int get_pull_model_ddc_req(struct nvme_dev *dev, return err; } -static int get_pull_model_ddc_req_log(int argc, char **argv, struct command *cmd, +static int get_pull_model_ddc_req_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Pull Model DDC Request Log, show it"; @@ -11009,8 +10863,8 @@ static int get_pull_model_ddc_req_log(int argc, char **argv, struct command *cmd int err; _cleanup_free_ struct nvme_pull_model_ddc_req_log *log = NULL; - - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct config { bool rae; @@ -11022,7 +10876,7 @@ static int get_pull_model_ddc_req_log(int argc, char **argv, struct command *cmd NVME_ARGS(opts, OPT_FLAG("rae", 'r', &cfg.rae, rae)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -11032,7 +10886,7 @@ static int get_pull_model_ddc_req_log(int argc, char **argv, struct command *cmd return err; } - err = get_pull_model_ddc_req(dev, cfg.rae, &log); + err = get_pull_model_ddc_req(hdl, cfg.rae, &log); if (!err) nvme_show_pull_model_ddc_req_log(log, flags); else if (err > 0) diff --git a/nvme.h b/nvme.h index 248c5c7ca6..4c88afef19 100644 --- a/nvme.h +++ b/nvme.h @@ -50,30 +50,6 @@ enum nvme_cli_topo_ranking { #define SYS_NVME "/sys/class/nvme" -enum nvme_dev_type { - NVME_DEV_DIRECT, - NVME_DEV_MI, -}; - -struct nvme_dev { - enum nvme_dev_type type; - union { - struct { - int fd; - struct stat stat; - } direct; - struct { - nvme_root_t root; - nvme_mi_ep_t ep; - nvme_mi_ctrl_t ctrl; - } mi; - }; - - const char *name; -}; - -#define dev_fd(d) __dev_fd(d, __func__, __LINE__) - struct nvme_config { char *output_format; int verbose; @@ -101,27 +77,6 @@ struct nvme_config { OPT_END() \ } -static inline int __dev_fd(struct nvme_dev *dev, const char *func, int line) -{ - if (dev->type != NVME_DEV_DIRECT) { - fprintf(stderr, - "warning: %s:%d not a direct transport!\n", - func, line); - return -1; - } - return dev->direct.fd; -} - -static inline nvme_mi_ep_t dev_mi_ep(struct nvme_dev *dev) -{ - if (dev->type != NVME_DEV_MI) { - fprintf(stderr, - "warning: not a MI transport!\n"); - return NULL; - } - return dev->mi.ep; -} - static inline bool nvme_is_multipath(nvme_subsystem_t s) { nvme_ns_t n; @@ -137,16 +92,16 @@ static inline bool nvme_is_multipath(nvme_subsystem_t s) void register_extension(struct plugin *plugin); /* - * parse_and_open - parses arguments and opens the NVMe device, populating @dev + * parse_and_open - parses arguments and opens the NVMe device, populating @ctx, @hdl */ -int parse_and_open(struct nvme_dev **dev, int argc, char **argv, const char *desc, - struct argconfig_commandline_options *clo); - -void dev_close(struct nvme_dev *dev); +int parse_and_open(struct nvme_global_ctx **ctx, + struct nvme_transport_handle **hdl, int argc, char **argv, + const char *desc, struct argconfig_commandline_options *clo); +// TODO: unsure if we need a double ptr here static inline DEFINE_CLEANUP_FUNC( - cleanup_nvme_dev, struct nvme_dev *, dev_close) -#define _cleanup_nvme_dev_ __cleanup__(cleanup_nvme_dev) + cleanup_nvme_transport_handle, struct nvme_transport_handle *, nvme_close) +#define _cleanup_nvme_transport_handle_ __cleanup__(cleanup_nvme_transport_handle) extern const char *output_format; extern const char *timeout; @@ -156,7 +111,7 @@ extern struct nvme_config nvme_cfg; int validate_output_format(const char *format, nvme_print_flags_t *flags); bool nvme_is_output_format_json(void); -int __id_ctrl(int argc, char **argv, struct command *cmd, +int __id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin, void (*vs)(uint8_t *vs, struct json_object *root)); const char *nvme_strerror(int errnum); @@ -172,4 +127,16 @@ void d_raw(unsigned char *buf, unsigned len); int get_reg_size(int offset); bool nvme_is_ctrl_reg(int offset); + +static inline int nvme_get_nsid_log(struct nvme_transport_handle *hdl, + __u32 nsid, bool rae, + enum nvme_cmd_get_log_lid lid, + void *log, __u32 len) +{ + struct nvme_passthru_cmd cmd; + + nvme_init_get_log(&cmd, nsid, lid, NVME_CSI_NVM, log, len); + + return nvme_get_log(hdl, &cmd, rae, NVME_LOG_PAGE_PDU_SIZE, NULL); +} #endif /* _NVME_H */ diff --git a/plugin.c b/plugin.c index 678129ecfe..0406bd0246 100644 --- a/plugin.c +++ b/plugin.c @@ -39,16 +39,18 @@ static int help(int argc, char **argv, struct plugin *plugin) } for (i = 0; plugin->commands[i]; i++) { - struct command *cmd = plugin->commands[i]; + struct command *command = plugin->commands[i]; - if (strcmp(str, cmd->name)) - if (!cmd->alias || (cmd->alias && strcmp(str, cmd->alias))) + if (strcmp(str, command->name)) + if (!command->alias || + (command->alias && strcmp(str, command->alias))) continue; if (plugin->name) - sprintf(man, "%s-%s-%s", prog->name, plugin->name, cmd->name); + sprintf(man, "%s-%s-%s", prog->name, + plugin->name, command->name); else - sprintf(man, "%s-%s", prog->name, cmd->name); + sprintf(man, "%s-%s", prog->name, command->name); if (execlp("man", "man", man, (char *)NULL)) perror(argv[1]); } diff --git a/plugin.h b/plugin.h index 0262efe1a8..4d1face5bd 100644 --- a/plugin.h +++ b/plugin.h @@ -27,7 +27,7 @@ struct plugin { struct command { char *name; char *help; - int (*fn)(int argc, char **argv, struct command *command, struct plugin *plugin); + int (*fn)(int argc, char **argv, struct command *acmd, struct plugin *plugin); char *alias; }; diff --git a/plugins/amzn/amzn-nvme.c b/plugins/amzn/amzn-nvme.c index 983c31bcbe..77edd942c5 100644 --- a/plugins/amzn/amzn-nvme.c +++ b/plugins/amzn/amzn-nvme.c @@ -92,9 +92,9 @@ static void amzn_id_ctrl(__u8 *vs, struct json_object *root) printf("bdev : %s\n", bdev); } -static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return __id_ctrl(argc, argv, cmd, plugin, amzn_id_ctrl); + return __id_ctrl(argc, argv, acmd, plugin, amzn_id_ctrl); } static void amzn_print_latency_histogram(struct amzn_latency_histogram *hist) @@ -203,15 +203,16 @@ static void amzn_print_normal_stats(struct amzn_latency_log_page *log) amzn_print_latency_histogram(&log->write_io_latency_histogram); } -static int get_stats(int argc, char **argv, struct command *cmd, +static int get_stats(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "display command latency statistics"; - struct nvme_dev *dev; struct amzn_latency_log_page log = { 0 }; - int rc; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; - int err; + int err, rc; struct config { char *output_format; @@ -226,29 +227,13 @@ static int get_stats(int argc, char **argv, struct command *cmd, "Output Format: normal|json"), OPT_END()}; - rc = parse_and_open(&dev, argc, argv, desc, opts); + rc = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (rc) return rc; - struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .lid = AMZN_NVME_STATS_LOGPAGE_ID, - .nsid = 1, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = 0, - .rae = false, - .uuidx = 0, - .csi = NVME_CSI_NVM, - .ot = false, - .len = sizeof(log), - .log = &log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - rc = nvme_get_log(&args); + nvme_init_get_log(&cmd, 1, AMZN_NVME_STATS_LOGPAGE_ID, NVME_CSI_NVM, + &log, sizeof(log)); + err = nvme_get_log(hdl, &cmd, false, NVME_LOG_PAGE_PDU_SIZE, NULL); if (rc != 0) { fprintf(stderr, "[ERROR] %s: Failed to get log page, rc = %d", __func__, rc); diff --git a/plugins/dapustor/dapustor-nvme.c b/plugins/dapustor/dapustor-nvme.c index b98b1a0458..268f45c101 100644 --- a/plugins/dapustor/dapustor-nvme.c +++ b/plugins/dapustor/dapustor-nvme.c @@ -482,24 +482,24 @@ static void show_dapustor_smart_log(struct nvme_additional_smart_log *smart, } static int dapustor_additional_smart_log_data( - int dev_fd, + struct nvme_transport_handle *hdl, struct nvme_additional_smart_log *smart_log, struct nvme_extended_additional_smart_log *ext_smart_log, bool *has_ext) { int err; - err = nvme_get_log_simple(dev_fd, 0xca, sizeof(*smart_log), smart_log); + err = nvme_get_log_simple(hdl, 0xca, smart_log, sizeof(*smart_log)); if (err) { nvme_show_status(err); return err; } - err = nvme_get_log_simple(dev_fd, 0xcb, sizeof(*ext_smart_log), ext_smart_log); + err = nvme_get_log_simple(hdl, 0xcb, ext_smart_log, sizeof(*ext_smart_log)); *has_ext = !err; return 0; } -static int dapustor_additional_smart_log(int argc, char **argv, struct command *cmd, +static int dapustor_additional_smart_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get DapuStor vendor specific additional smart log, and show it."; @@ -509,11 +509,12 @@ static int dapustor_additional_smart_log(int argc, char **argv, struct command * const char *json = "Dump output in json format"; #endif /* CONFIG_JSONC */ - struct nvme_additional_smart_log smart_log; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct nvme_extended_additional_smart_log ext_smart_log; - struct nvme_dev *dev; - int err; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_additional_smart_log smart_log; bool has_ext = false; + int err; struct config { uint32_t namespace_id; @@ -532,24 +533,28 @@ static int dapustor_additional_smart_log(int argc, char **argv, struct command * OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = dapustor_additional_smart_log_data(dev_fd(dev), &smart_log, &ext_smart_log, &has_ext); + err = dapustor_additional_smart_log_data(hdl, &smart_log, + &ext_smart_log, &has_ext); if (!err) { if (cfg.json) show_dapustor_smart_log_jsn(&smart_log, &ext_smart_log, - cfg.namespace_id, dev->name, has_ext); + cfg.namespace_id, + nvme_transport_handle_get_name(hdl), + has_ext); else if (!cfg.raw_binary) show_dapustor_smart_log(&smart_log, &ext_smart_log, - cfg.namespace_id, dev->name, has_ext); + cfg.namespace_id, + nvme_transport_handle_get_name(hdl), has_ext); else { d_raw((unsigned char *)&smart_log, sizeof(smart_log)); if (has_ext) - d_raw((unsigned char *)&ext_smart_log, sizeof(ext_smart_log)); + d_raw((unsigned char *)&ext_smart_log, + sizeof(ext_smart_log)); } } - dev_close(dev); return err; } diff --git a/plugins/dell/dell-nvme.c b/plugins/dell/dell-nvme.c index 8ed10e7fb5..d77138eb2c 100644 --- a/plugins/dell/dell-nvme.c +++ b/plugins/dell/dell-nvme.c @@ -47,8 +47,8 @@ static void dell_id_ctrl(__u8 *vs, struct json_object *root) printf("array_ver : %s\n", array_ver); } -static int id_ctrl(int argc, char **argv, struct command *cmd, +static int id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return __id_ctrl(argc, argv, cmd, plugin, dell_id_ctrl); + return __id_ctrl(argc, argv, acmd, plugin, dell_id_ctrl); } diff --git a/plugins/dera/dera-nvme.c b/plugins/dera/dera-nvme.c index ca4b53d698..70b957fd40 100644 --- a/plugins/dera/dera-nvme.c +++ b/plugins/dera/dera-nvme.c @@ -95,7 +95,7 @@ enum dera_device_status DEVICE_STAUTS__OVER_TEMPRATURE = 0x09, }; -static int nvme_dera_get_device_status(int fd, enum dera_device_status *result) +static int nvme_dera_get_device_status(struct nvme_transport_handle *hdl, enum dera_device_status *result) { int err = 0; @@ -107,30 +107,31 @@ static int nvme_dera_get_device_status(int fd, enum dera_device_status *result) .cdw12 = 0x104, }; - err = nvme_submit_admin_passthru(fd, &cmd, NULL); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err && result) *result = cmd.result; return err; } -static int get_status(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_status(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - struct nvme_dera_smart_info_log log; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; enum dera_device_status state = DEVICE_STATUS_FATAL_ERROR; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; char *desc = "Get the Dera device status"; - struct nvme_dev *dev; + struct nvme_dera_smart_info_log log; int err; OPT_ARGS(opts) = { OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = nvme_get_log_simple(dev_fd(dev), 0xc0, sizeof(log), &log); + err = nvme_get_log_simple(hdl, 0xc0, &log, sizeof(log)); if (err) goto exit; @@ -152,7 +153,7 @@ static int get_status(int argc, char **argv, struct command *cmd, struct plugin "Runtime Low", }; - err = nvme_dera_get_device_status(dev_fd(dev), &state); + err = nvme_dera_get_device_status(hdl, &state); if (!err) { if (state > 0 && state < 4) printf("device_status : %s %d%% completed\n", dev_status[state], log.rebuild_percent); @@ -199,7 +200,6 @@ static int get_status(int argc, char **argv, struct command *cmd, struct plugin if (err > 0) nvme_show_status(err); - dev_close(dev); return err; } diff --git a/plugins/fdp/fdp.c b/plugins/fdp/fdp.c index 1aec7579d6..00ba0335d6 100644 --- a/plugins/fdp/fdp.c +++ b/plugins/fdp/fdp.c @@ -17,18 +17,19 @@ #define CREATE_CMD #include "fdp.h" -static int fdp_configs(int argc, char **argv, struct command *cmd, - struct plugin *plugin) +static int fdp_configs(int argc, char **argv, struct command *acmd, + struct plugin *plugin) { const char *desc = "Get Flexible Data Placement Configurations"; const char *egid = "Endurance group identifier"; const char *human_readable = "show log in readable format"; const char *raw = "use binary output"; - nvme_print_flags_t flags; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_free_ void *log = NULL; struct nvme_fdp_config_log hdr; - void *log = NULL; + nvme_print_flags_t flags; int err; struct config { @@ -52,13 +53,13 @@ static int fdp_configs(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; err = validate_output_format(cfg.output_format, &flags); if (err < 0) - goto out; + return err; if (cfg.raw_binary) flags = BINARY; @@ -68,50 +69,43 @@ static int fdp_configs(int argc, char **argv, struct command *cmd, if (!cfg.egid) { fprintf(stderr, "endurance group identifier required\n"); - err = -EINVAL; - goto out; + return -EINVAL; } - err = nvme_get_log_fdp_configurations(dev->direct.fd, cfg.egid, 0, - sizeof(hdr), &hdr); + err = nvme_get_log_fdp_configurations(hdl, cfg.egid, 0, + &hdr, sizeof(hdr)); if (err) { nvme_show_status(errno); - goto out; + return err; } log = malloc(hdr.size); - if (!log) { - err = -ENOMEM; - goto out; - } + if (!log) + return -ENOMEM; - err = nvme_get_log_fdp_configurations(dev->direct.fd, cfg.egid, 0, - hdr.size, log); + err = nvme_get_log_fdp_configurations(hdl, cfg.egid, 0, log, hdr.size); if (err) { nvme_show_status(errno); - goto out; + return err; } nvme_show_fdp_configs(log, hdr.size, flags); -out: - dev_close(dev); - free(log); - - return err; + return 0; } -static int fdp_usage(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int fdp_usage(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Flexible Data Placement Reclaim Unit Handle Usage"; const char *egid = "Endurance group identifier"; const char *raw = "use binary output"; - nvme_print_flags_t flags; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_free_ void *log = NULL; struct nvme_fdp_ruhu_log hdr; + nvme_print_flags_t flags; size_t len; - void *log = NULL; int err; struct config { @@ -133,56 +127,51 @@ static int fdp_usage(int argc, char **argv, struct command *cmd, struct plugin * OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; err = validate_output_format(cfg.output_format, &flags); if (err < 0) - goto out; + return err; if (cfg.raw_binary) flags = BINARY; - err = nvme_get_log_reclaim_unit_handle_usage(dev->direct.fd, cfg.egid, - 0, sizeof(hdr), &hdr); + err = nvme_get_log_reclaim_unit_handle_usage(hdl, cfg.egid, + 0, &hdr, sizeof(hdr)); if (err) { nvme_show_status(err); - goto out; + return err; } len = sizeof(hdr) + le16_to_cpu(hdr.nruh) * sizeof(struct nvme_fdp_ruhu_desc); log = malloc(len); - if (!log) { - err = -ENOMEM; - goto out; - } + if (!log) + return -ENOMEM; - err = nvme_get_log_reclaim_unit_handle_usage(dev->direct.fd, cfg.egid, - 0, len, log); + err = nvme_get_log_reclaim_unit_handle_usage(hdl, cfg.egid, + 0, log, len); if (err) { nvme_show_status(err); - goto out; + return err; } nvme_show_fdp_usage(log, len, flags); -out: - dev_close(dev); - free(log); - - return err; + return 0; } -static int fdp_stats(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int fdp_stats(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Flexible Data Placement Statistics"; const char *egid = "Endurance group identifier"; const char *raw = "use binary output"; - nvme_print_flags_t flags; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct nvme_fdp_stats_log stats; + nvme_print_flags_t flags; int err; struct config { @@ -204,49 +193,46 @@ static int fdp_stats(int argc, char **argv, struct command *cmd, struct plugin * OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; err = validate_output_format(cfg.output_format, &flags); if (err < 0) - goto out; + return err; if (cfg.raw_binary) flags = BINARY; if (!cfg.egid) { fprintf(stderr, "endurance group identifier required\n"); - err = -EINVAL; - goto out; + return -EINVAL; } memset(&stats, 0x0, sizeof(stats)); - err = nvme_get_log_fdp_stats(dev->direct.fd, cfg.egid, 0, sizeof(stats), &stats); + err = nvme_get_log_fdp_stats(hdl, cfg.egid, 0, &stats, sizeof(stats)); if (err) { nvme_show_status(err); - goto out; + return err; } nvme_show_fdp_stats(&stats, flags); -out: - dev_close(dev); - - return err; + return 0; } -static int fdp_events(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int fdp_events(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Flexible Data Placement Events"; const char *egid = "Endurance group identifier"; const char *host_events = "Get host events"; const char *raw = "use binary output"; - nvme_print_flags_t flags; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct nvme_fdp_events_log events; + nvme_print_flags_t flags; int err; struct config { @@ -271,55 +257,53 @@ static int fdp_events(int argc, char **argv, struct command *cmd, struct plugin OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; err = validate_output_format(cfg.output_format, &flags); if (err < 0) - goto out; + return err; if (cfg.raw_binary) flags = BINARY; if (!cfg.egid) { fprintf(stderr, "endurance group identifier required\n"); - err = -EINVAL; - goto out; + return -EINVAL; } memset(&events, 0x0, sizeof(events)); - err = nvme_get_log_fdp_events(dev->direct.fd, cfg.egid, - cfg.host_events, 0, sizeof(events), &events); + err = nvme_get_log_fdp_events(hdl, cfg.egid, + cfg.host_events, 0, &events, sizeof(events)); if (err) { nvme_show_status(err); - goto out; + return err; } nvme_show_fdp_events(&events, flags); -out: - dev_close(dev); - - return err; + return 0; } -static int fdp_status(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int fdp_status(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Reclaim Unit Handle Status"; const char *namespace_id = "Namespace identifier"; const char *raw = "use binary output"; - nvme_print_flags_t flags; - struct nvme_dev *dev; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_free_ void *buf = NULL; struct nvme_fdp_ruh_status hdr; - size_t len; - void *buf = NULL; + struct nvme_passthru_cmd cmd; + nvme_print_flags_t flags; int err = -1; + size_t len; struct config { - __u32 namespace_id; + __u32 nsid; char *output_format; bool raw_binary; }; @@ -330,76 +314,73 @@ static int fdp_status(int argc, char **argv, struct command *cmd, struct plugin }; OPT_ARGS(opts) = { - OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id), - OPT_FMT("output-format", 'o', &cfg.output_format, output_format), - OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw), + OPT_UINT("namespace-id", 'n', &cfg.nsid, namespace_id), + OPT_FMT("output-format", 'o', &cfg.output_format, output_format), + OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw), OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; err = validate_output_format(cfg.output_format, &flags); if (err < 0) - goto out; + return err; if (cfg.raw_binary) flags = BINARY; - if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + if (!cfg.nsid) { + err = nvme_get_nsid(hdl, &cfg.nsid); if (err < 0) { perror("get-namespace-id"); - goto out; + return err; } } - err = nvme_fdp_reclaim_unit_handle_status(dev_fd(dev), - cfg.namespace_id, sizeof(hdr), &hdr); + nvme_init_fdp_reclaim_unit_handle_status(&cmd, cfg.nsid, &hdr, + sizeof(hdr)); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); if (err) { nvme_show_status(err); - goto out; + return err; } len = sizeof(struct nvme_fdp_ruh_status) + le16_to_cpu(hdr.nruhsd) * sizeof(struct nvme_fdp_ruh_status_desc); buf = malloc(len); - if (!buf) { - err = -ENOMEM; - goto out; - } + if (!buf) + return -ENOMEM; - err = nvme_fdp_reclaim_unit_handle_status(dev_fd(dev), - cfg.namespace_id, len, buf); + nvme_init_fdp_reclaim_unit_handle_status(&cmd, cfg.nsid, buf, len); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); if (err) { nvme_show_status(err); - goto out; + return err; } nvme_show_fdp_ruh_status(buf, len, flags); -out: - free(buf); - dev_close(dev); - - return err; + return 0; } -static int fdp_update(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int fdp_update(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Reclaim Unit Handle Update"; const char *namespace_id = "Namespace identifier"; const char *_pids = "Comma-separated list of placement identifiers to update"; - struct nvme_dev *dev; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; unsigned short pids[256]; __u16 buf[256]; - int npids; int err = -1; + int npids; struct config { - __u32 namespace_id; + __u32 nsid; char *pids; }; @@ -408,171 +389,141 @@ static int fdp_update(int argc, char **argv, struct command *cmd, struct plugin }; OPT_ARGS(opts) = { - OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id), - OPT_LIST("pids", 'p', &cfg.pids, _pids), + OPT_UINT("namespace-id", 'n', &cfg.nsid, namespace_id), + OPT_LIST("pids", 'p', &cfg.pids, _pids), OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; npids = argconfig_parse_comma_sep_array_short(cfg.pids, pids, ARRAY_SIZE(pids)); if (npids < 0) { perror("could not parse pids"); - err = -EINVAL; - goto out; + return -EINVAL; } else if (npids == 0) { fprintf(stderr, "no placement identifiers set\n"); - err = -EINVAL; - goto out; + return -EINVAL; } - if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + if (!cfg.nsid) { + err = nvme_get_nsid(hdl, &cfg.nsid); if (err < 0) { perror("get-namespace-id"); - goto out; + return err; } } for (unsigned int i = 0; i < npids; i++) buf[i] = cpu_to_le16(pids[i]); - err = nvme_fdp_reclaim_unit_handle_update(dev_fd(dev), cfg.namespace_id, npids, buf); + nvme_init_fdp_reclaim_unit_handle_status(&cmd, cfg.nsid, buf, npids); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); if (err) { nvme_show_status(err); - goto out; + return err; } printf("update: Success\n"); -out: - dev_close(dev); - - return err; + return 0; } -static int fdp_set_events(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int fdp_set_events(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Enable or disable FDP events"; - const char *namespace_id = "Namespace identifier"; + const char *nsid = "Namespace identifier"; const char *enable = "Enable/disable event"; const char *event_types = "Comma-separated list of event types"; const char *ph = "Placement Handle"; - const char *save = "specifies that the controller shall save the attribute"; + const char *sv = "specifies that the controller shall save the attribute"; - struct nvme_dev *dev; - int err = -1; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; unsigned short evts[255]; - int nev; __u8 buf[255]; + int err = -1; + int nev; struct config { - __u32 namespace_id; + __u32 nsid; __u16 ph; char *event_types; bool enable; - bool save; + bool sv; }; struct config cfg = { .enable = false, - .save = false, + .sv = false, }; OPT_ARGS(opts) = { - OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id), + OPT_UINT("namespace-id", 'n', &cfg.nsid, nsid), OPT_SHRT("placement-handle", 'p', &cfg.ph, ph), OPT_FLAG("enable", 'e', &cfg.enable, enable), - OPT_FLAG("save", 's', &cfg.save, save), + OPT_FLAG("save", 's', &cfg.sv, sv), OPT_LIST("event-types", 't', &cfg.event_types, event_types), OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; nev = argconfig_parse_comma_sep_array_short(cfg.event_types, evts, ARRAY_SIZE(evts)); if (nev < 0) { perror("could not parse event types"); - err = -EINVAL; - goto out; + return -EINVAL; } else if (nev == 0) { fprintf(stderr, "no event types set\n"); - err = -EINVAL; - goto out; + return -EINVAL; } else if (nev > 255) { fprintf(stderr, "too many event types (max 255)\n"); - err = -EINVAL; - goto out; + return -EINVAL; } - if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + if (!cfg.nsid) { + err = nvme_get_nsid(hdl, &cfg.nsid); if (err < 0) { if (errno != ENOTTY) { fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno)); - goto out; + return err; } - cfg.namespace_id = NVME_NSID_ALL; + cfg.nsid = NVME_NSID_ALL; } } for (unsigned int i = 0; i < nev; i++) buf[i] = (__u8)evts[i]; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = NVME_FEAT_FID_FDP_EVENTS, - .save = cfg.save, - .nsid = cfg.namespace_id, - .cdw11 = (nev << 16) | cfg.ph, - .cdw12 = cfg.enable ? 0x1 : 0x0, - .data_len = sizeof(buf), - .data = buf, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - err = nvme_set_features(&args); + err = nvme_set_features(hdl, cfg.nsid, NVME_FEAT_FID_FDP_EVENTS, cfg.sv, + (nev << 16) | cfg.ph, cfg.enable ? 0x1 : 0x0, + 0, 0, 0, buf, sizeof(buf), NULL); if (err) { nvme_show_status(err); - goto out; + return err;; } printf("set-events: Success\n"); -out: - dev_close(dev); - - return err; + return 0; } -static int fdp_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int fdp_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Show, enable or disable FDP configuration"; const char *enable_conf_idx = "FDP configuration index to enable"; const char *endurance_group = "Endurance group ID"; const char *disable = "Disable current FDP configuration"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - int err = -1; - __u32 result; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; bool enabling_conf_idx = false; - struct nvme_set_features_args setf_args = { - .args_size = sizeof(setf_args), - .fd = -1, - .fid = NVME_FEAT_FID_FDP, - .save = 1, - .nsid = NVME_NSID_ALL, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - }; + __u32 result; + int err = -1; struct config { bool disable; @@ -594,7 +545,7 @@ static int fdp_feature(int argc, char **argv, struct command *cmd, struct plugin OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -605,23 +556,11 @@ static int fdp_feature(int argc, char **argv, struct command *cmd, struct plugin } if (!enabling_conf_idx && !cfg.disable) { - struct nvme_get_features_args getf_args = { - .args_size = sizeof(getf_args), - .fd = dev_fd(dev), - .fid = NVME_FEAT_FID_FDP, - .nsid = NVME_NSID_ALL, - .sel = NVME_GET_FEATURES_SEL_CURRENT, - .cdw11 = cfg.endgid, - .uuidx = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - nvme_show_result("Endurance Group : %d", cfg.endgid); - err = nvme_get_features(&getf_args); + err = nvme_get_features(hdl, NVME_NSID_ALL, NVME_FEAT_FID_FDP, + NVME_GET_FEATURES_SEL_CURRENT, cfg.endgid, 0, + NULL, 0, &result); if (err) { nvme_show_status(err); return err; @@ -634,11 +573,9 @@ static int fdp_feature(int argc, char **argv, struct command *cmd, struct plugin return err; } - setf_args.fd = dev_fd(dev); - setf_args.cdw11 = cfg.endgid; - setf_args.cdw12 = cfg.fdpcidx << 8 | (!cfg.disable); - - err = nvme_set_features(&setf_args); + err = nvme_set_features(hdl, NVME_NSID_ALL, NVME_FEAT_FID_FDP, 1, cfg.endgid, + cfg.fdpcidx << 8 | (!cfg.disable), + 0, 0, 0, NULL, 0, NULL); if (err) { nvme_show_status(err); return err; diff --git a/plugins/feat/feat-nvme.c b/plugins/feat/feat-nvme.c index b2de2926e2..e7b7607279 100644 --- a/plugins/feat/feat-nvme.c +++ b/plugins/feat/feat-nvme.c @@ -49,7 +49,8 @@ static const char *temp_thresh_feat = "temperature threshold feature"; static const char *arbitration_feat = "arbitration feature"; static const char *volatile_wc_feat = "volatile write cache feature"; -static int feat_get(struct nvme_dev *dev, const __u8 fid, __u32 cdw11, __u8 sel, const char *feat) +static int feat_get(struct nvme_transport_handle *hdl, const __u8 fid, + __u32 cdw11, __u8 sel, const char *feat) { __u32 result; int err; @@ -58,7 +59,7 @@ static int feat_get(struct nvme_dev *dev, const __u8 fid, __u32 cdw11, __u8 sel, _cleanup_free_ void *buf = NULL; if (!NVME_CHECK(sel, GET_FEATURES_SEL, SUPPORTED)) - nvme_get_feature_length(fid, cdw11, &len); + nvme_get_feature_length(fid, cdw11, NVME_DATA_TFR_CTRL_TO_HOST, &len); if (len) { buf = nvme_alloc(len - 1); @@ -66,19 +67,7 @@ static int feat_get(struct nvme_dev *dev, const __u8 fid, __u32 cdw11, __u8 sel, return -ENOMEM; } - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .sel = sel, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - .cdw11 = cdw11, - .data = buf, - .data_len = len, - }; - - err = nvme_get_features(&args); + err = nvme_get_features(hdl, 0, fid, sel, cdw11, 0, buf, len, &result); nvme_show_init(); @@ -99,22 +88,15 @@ static int feat_get(struct nvme_dev *dev, const __u8 fid, __u32 cdw11, __u8 sel, return err; } -static int power_mgmt_set(struct nvme_dev *dev, const __u8 fid, __u8 ps, __u8 wh, bool save) +static int power_mgmt_set(struct nvme_transport_handle *hdl, const __u8 fid, + __u8 ps, __u8 wh, bool sv) { + __u32 cdw11 = NVME_SET(ps, FEAT_PWRMGMT_PS) | NVME_SET(wh, FEAT_PWRMGMT_WH); __u32 result; int err; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .cdw11 = NVME_SET(ps, FEAT_PWRMGMT_PS) | NVME_SET(wh, FEAT_PWRMGMT_WH), - .save = save, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, fid, sv, cdw11, 0, 0, 0, 0, NULL, 0, + &result); nvme_show_init(); @@ -123,9 +105,9 @@ static int power_mgmt_set(struct nvme_dev *dev, const __u8 fid, __u8 ps, __u8 wh } else if (err < 0) { nvme_show_perror("Set %s", power_mgmt_feat); } else { - nvme_show_result("Set %s: 0x%04x (%s)", power_mgmt_feat, args.cdw11, - save ? "Save" : "Not save"); - nvme_feature_show_fields(fid, args.cdw11, NULL); + nvme_show_result("Set %s: 0x%04x (%s)", power_mgmt_feat, cdw11, + sv ? "Save" : "Not save"); + nvme_feature_show_fields(fid, cdw11, NULL); } nvme_show_finish(); @@ -133,13 +115,14 @@ static int power_mgmt_set(struct nvme_dev *dev, const __u8 fid, __u8 ps, __u8 wh return err; } -static int feat_power_mgmt(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int feat_power_mgmt(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *ps = "power state"; const char *wh = "workload hint"; const __u8 fid = NVME_FEAT_FID_POWER_MGMT; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; struct config { @@ -154,20 +137,20 @@ static int feat_power_mgmt(int argc, char **argv, struct command *cmd, struct pl OPT_BYTE("ps", 'p', &cfg.ps, ps), OPT_BYTE("wh", 'w', &cfg.wh, wh)); - err = parse_and_open(&dev, argc, argv, POWER_MGMT_DESC, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, POWER_MGMT_DESC, opts); if (err) return err; if (argconfig_parse_seen(opts, "ps")) - err = power_mgmt_set(dev, fid, cfg.ps, cfg.wh, argconfig_parse_seen(opts, "save")); + err = power_mgmt_set(hdl, fid, cfg.ps, cfg.wh, argconfig_parse_seen(opts, "save")); else - err = feat_get(dev, fid, 0, cfg.sel, power_mgmt_feat); + err = feat_get(hdl, fid, 0, cfg.sel, power_mgmt_feat); return err; } -static int perfc_set(struct nvme_dev *dev, __u8 fid, __u32 cdw11, struct perfc_config *cfg, - bool save) +static int perfc_set(struct nvme_transport_handle *hdl, __u8 fid, __u32 cdw11, + struct perfc_config *cfg, bool sv) { __u32 result; int err; @@ -178,18 +161,6 @@ static int perfc_set(struct nvme_dev *dev, __u8 fid, __u32 cdw11, struct perfc_c .attr_buf = { 0 }, }; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .cdw11 = cdw11, - .save = save, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - .data = &data, - .data_len = sizeof(data), - }; - switch (cfg->attri) { case NVME_FEAT_PERFC_ATTRI_STD: data.std_perf->r4karl = cfg->r4karl; @@ -216,7 +187,8 @@ static int perfc_set(struct nvme_dev *dev, __u8 fid, __u32 cdw11, struct perfc_c break; } - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, fid, sv, cdw11, 0, 0, 0, 0, &data, + sizeof(data), &result); nvme_show_init(); @@ -225,9 +197,9 @@ static int perfc_set(struct nvme_dev *dev, __u8 fid, __u32 cdw11, struct perfc_c } else if (err < 0) { nvme_show_perror("Set %s", perfc_feat); } else { - nvme_show_result("Set %s: 0x%04x (%s)", perfc_feat, args.cdw11, - save ? "Save" : "Not save"); - nvme_feature_show_fields(args.fid, args.cdw11, NULL); + nvme_show_result("Set %s: 0x%04x (%s)", perfc_feat, cdw11, + sv ? "Save" : "Not save"); + nvme_feature_show_fields(fid, cdw11, NULL); } nvme_show_finish(); @@ -235,7 +207,7 @@ static int perfc_set(struct nvme_dev *dev, __u8 fid, __u32 cdw11, struct perfc_c return err; } -static int feat_perfc(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int feat_perfc(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *namespace_id_optional = "optional namespace attached to controller"; const char *attri = "attribute index"; @@ -245,7 +217,8 @@ static int feat_perfc(int argc, char **argv, struct command *cmd, struct plugin const char *attrl = "attribute length"; const char *vs_data = "vendor specific data"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; __u8 fid = NVME_FEAT_FID_PERF_CHARACTERISTICS; __u32 cdw11; @@ -261,7 +234,7 @@ static int feat_perfc(int argc, char **argv, struct command *cmd, struct plugin OPT_SHRT("attrl", 'A', &cfg.attrl, attrl), OPT_FILE("vs-data", 'V', &cfg.vs_data, vs_data)); - err = parse_and_open(&dev, argc, argv, PERFC_DESC, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, PERFC_DESC, opts); if (err) return err; @@ -269,29 +242,23 @@ static int feat_perfc(int argc, char **argv, struct command *cmd, struct plugin if (argconfig_parse_seen(opts, "rvspa") || argconfig_parse_seen(opts, "r4karl") || argconfig_parse_seen(opts, "paid")) - err = perfc_set(dev, fid, cdw11, &cfg, argconfig_parse_seen(opts, "save")); + err = perfc_set(hdl, fid, cdw11, &cfg, argconfig_parse_seen(opts, "save")); else - err = feat_get(dev, fid, cdw11, cfg.sel, perfc_feat); + err = feat_get(hdl, fid, cdw11, cfg.sel, perfc_feat); return err; } -static int hctm_set(struct nvme_dev *dev, const __u8 fid, __u16 tmt1, __u16 tmt2, bool save) +static int hctm_set(struct nvme_transport_handle *hdl, const __u8 fid, + __u16 tmt1, __u16 tmt2, bool sv) { + __u32 cdw11 = NVME_SET(tmt1, FEAT_HCTM_TMT1) + | NVME_SET(tmt2, FEAT_HCTM_TMT2); __u32 result; int err; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .cdw11 = NVME_SET(tmt1, FEAT_HCTM_TMT1) | NVME_SET(tmt2, FEAT_HCTM_TMT2), - .save = save, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, fid, sv, cdw11, 0, 0, 0, 0, NULL, 0, + &result); nvme_show_init(); @@ -300,9 +267,9 @@ static int hctm_set(struct nvme_dev *dev, const __u8 fid, __u16 tmt1, __u16 tmt2 } else if (err < 0) { nvme_show_perror("Set %s", hctm_feat); } else { - nvme_show_result("Set %s: 0x%04x (%s)", hctm_feat, args.cdw11, - save ? "Save" : "Not save"); - nvme_feature_show_fields(fid, args.cdw11, NULL); + nvme_show_result("Set %s: 0x%04x (%s)", hctm_feat, cdw11, + sv ? "Save" : "Not save"); + nvme_feature_show_fields(fid, cdw11, NULL); } nvme_show_finish(); @@ -310,11 +277,12 @@ static int hctm_set(struct nvme_dev *dev, const __u8 fid, __u16 tmt1, __u16 tmt2 return err; } -static int feat_hctm(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int feat_hctm(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const __u8 fid = NVME_FEAT_FID_HCTM; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; struct config { @@ -329,39 +297,30 @@ static int feat_hctm(int argc, char **argv, struct command *cmd, struct plugin * OPT_SHRT("tmt1", 't', &cfg.tmt1, TMT(1)), OPT_SHRT("tmt2", 'T', &cfg.tmt2, TMT(2))); - err = parse_and_open(&dev, argc, argv, HCTM_DESC, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, HCTM_DESC, opts); if (err) return err; if (argconfig_parse_seen(opts, "tmt1") || argconfig_parse_seen(opts, "tmt2")) - err = hctm_set(dev, fid, cfg.tmt1, cfg.tmt2, argconfig_parse_seen(opts, "save")); + err = hctm_set(hdl, fid, cfg.tmt1, cfg.tmt2, argconfig_parse_seen(opts, "save")); else - err = feat_get(dev, fid, 0, cfg.sel, hctm_feat); + err = feat_get(hdl, fid, 0, cfg.sel, hctm_feat); return err; } -static int timestamp_set(struct nvme_dev *dev, const __u8 fid, __u64 tstmp, bool save) +static int timestamp_set(struct nvme_transport_handle *hdl, const __u8 fid, + __u64 tstmp, bool sv) { __u32 result; int err; struct nvme_timestamp ts; __le64 timestamp = cpu_to_le64(tstmp); - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .save = save, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - .data = &ts, - .data_len = sizeof(ts), - }; - memcpy(ts.timestamp, ×tamp, sizeof(ts.timestamp)); - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, fid, sv, 0, 0, 0, 0, 0, &ts, sizeof(ts), + &result); nvme_show_init(); @@ -370,8 +329,8 @@ static int timestamp_set(struct nvme_dev *dev, const __u8 fid, __u64 tstmp, bool } else if (err < 0) { nvme_show_perror("Set %s", timestamp_feat); } else { - nvme_show_result("Set %s: (%s)", timestamp_feat, save ? "Save" : "Not save"); - nvme_feature_show_fields(fid, args.cdw11, args.data); + nvme_show_result("Set %s: (%s)", timestamp_feat, sv ? "Save" : "Not save"); + nvme_feature_show_fields(fid, 0, (unsigned char *)&ts); } nvme_show_finish(); @@ -379,12 +338,13 @@ static int timestamp_set(struct nvme_dev *dev, const __u8 fid, __u64 tstmp, bool return err; } -static int feat_timestamp(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int feat_timestamp(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const __u8 fid = NVME_FEAT_FID_TIMESTAMP; const char *tstmp = "timestamp"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; struct config { @@ -396,34 +356,37 @@ static int feat_timestamp(int argc, char **argv, struct command *cmd, struct plu FEAT_ARGS(opts, OPT_LONG("tstmp", 't', &cfg.tstmp, tstmp)); - err = parse_and_open(&dev, argc, argv, TIMESTAMP_DESC, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, TIMESTAMP_DESC, opts); if (err) return err; if (argconfig_parse_seen(opts, "tstmp")) - err = timestamp_set(dev, fid, cfg.tstmp, argconfig_parse_seen(opts, "save")); + err = timestamp_set(hdl, fid, cfg.tstmp, argconfig_parse_seen(opts, "save")); else - err = feat_get(dev, fid, 0, cfg.sel, timestamp_feat); + err = feat_get(hdl, fid, 0, cfg.sel, timestamp_feat); return err; } -static int temp_thresh_set(int fd, const __u8 fid, struct argconfig_commandline_options *opts, +static int temp_thresh_set(struct nvme_transport_handle *hdl, const __u8 fid, + struct argconfig_commandline_options *opts, struct temp_thresh_config *cfg) { __u32 result; int err; enum nvme_get_features_sel sel = NVME_GET_FEATURES_SEL_CURRENT; + struct nvme_passthru_cmd cmd; __u16 tmpth; __u8 tmpsel; __u8 thsel; __u8 tmpthh; - bool save = argconfig_parse_seen(opts, "save"); + bool sv = argconfig_parse_seen(opts, "save"); - if (save) + if (sv) sel = NVME_GET_FEATURES_SEL_SAVED; - err = nvme_get_features_temp_thresh2(fd, sel, cfg->tmpsel, cfg->thsel, &result); + nvme_init_get_features_temp_thresh(&cmd, sel, cfg->tmpsel, cfg->thsel); + err = nvme_submit_admin_passthru(hdl, &cmd, &result); if (!err) { nvme_feature_decode_temp_threshold(result, &tmpth, &tmpsel, &thsel, &tmpthh); if (!argconfig_parse_seen(opts, "tmpth")) @@ -432,8 +395,9 @@ static int temp_thresh_set(int fd, const __u8 fid, struct argconfig_commandline_ cfg->tmpthh = tmpthh; } - err = nvme_set_features_temp_thresh2(fd, cfg->tmpth, cfg->tmpsel, cfg->thsel, cfg->tmpthh, - save, &result); + nvme_init_set_features_temp_thresh(&cmd, sv, cfg->tmpth, cfg->tmpsel, + cfg->thsel, cfg->tmpthh); + err = nvme_submit_admin_passthru(hdl, &cmd, &result); nvme_show_init(); @@ -442,7 +406,7 @@ static int temp_thresh_set(int fd, const __u8 fid, struct argconfig_commandline_ } else if (err < 0) { nvme_show_perror("Set %s", temp_thresh_feat); } else { - nvme_show_result("Set %s: (%s)", temp_thresh_feat, save ? "Save" : "Not save"); + nvme_show_result("Set %s: (%s)", temp_thresh_feat, sv ? "Save" : "Not save"); nvme_feature_show_fields(fid, NVME_SET(cfg->tmpth, FEAT_TT_TMPTH) | NVME_SET(cfg->tmpsel, FEAT_TT_TMPSEL) | NVME_SET(cfg->thsel, FEAT_TT_THSEL) | @@ -454,7 +418,7 @@ static int temp_thresh_set(int fd, const __u8 fid, struct argconfig_commandline_ return err; } -static int feat_temp_thresh(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int feat_temp_thresh(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const __u8 fid = NVME_FEAT_FID_TEMP_THRESH; const char *tmpth = "temperature threshold"; @@ -462,7 +426,8 @@ static int feat_temp_thresh(int argc, char **argv, struct command *cmd, struct p const char *thsel = "threshold type select"; const char *tmpthh = "temperature threshold hysteresis"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; struct temp_thresh_config cfg = { 0 }; @@ -473,32 +438,35 @@ static int feat_temp_thresh(int argc, char **argv, struct command *cmd, struct p OPT_BYTE("thsel", 'H', &cfg.thsel, thsel), OPT_BYTE("tmpthh", 'M', &cfg.tmpthh, tmpthh)); - err = parse_and_open(&dev, argc, argv, TEMP_THRESH_DESC, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, TEMP_THRESH_DESC, opts); if (err) return err; if (argconfig_parse_seen(opts, "tmpth") || argconfig_parse_seen(opts, "tmpthh")) - err = temp_thresh_set(dev_fd(dev), fid, opts, &cfg); + err = temp_thresh_set(hdl, fid, opts, &cfg); else - err = feat_get(dev, fid, NVME_SET(cfg.tmpsel, FEAT_TT_TMPSEL) | + err = feat_get(hdl, fid, NVME_SET(cfg.tmpsel, FEAT_TT_TMPSEL) | NVME_SET(cfg.thsel, FEAT_TT_THSEL), cfg.sel, temp_thresh_feat); return err; } -static int arbitration_set(int fd, const __u8 fid, struct argconfig_commandline_options *opts, +static int arbitration_set(struct nvme_transport_handle *hdl, const __u8 fid, + struct argconfig_commandline_options *opts, struct arbitration_config *cfg) { enum nvme_get_features_sel sel = NVME_GET_FEATURES_SEL_CURRENT; - bool save = argconfig_parse_seen(opts, "save"); + bool sv = argconfig_parse_seen(opts, "save"); + struct nvme_passthru_cmd cmd; __u8 ab, lpw, mpw, hpw; __u32 result; int err; - if (save) + if (sv) sel = NVME_GET_FEATURES_SEL_SAVED; - err = nvme_get_features_arbitration(fd, sel, &result); + nvme_init_get_features_arbitration(&cmd, sel); + err = nvme_submit_admin_passthru(hdl, &cmd, &result); if (!err) { nvme_feature_decode_arbitration(result, &ab, &lpw, &mpw, &hpw); if (!argconfig_parse_seen(opts, "ab")) @@ -511,8 +479,9 @@ static int arbitration_set(int fd, const __u8 fid, struct argconfig_commandline_ cfg->hpw = hpw; } - err = nvme_set_features_arbitration(fd, cfg->ab, cfg->lpw, cfg->mpw, cfg->hpw, - save, &result); + nvme_init_set_features_arbitration(&cmd, sv, cfg->ab, cfg->lpw, + cfg->mpw, cfg->hpw); + err = nvme_submit_admin_passthru(hdl, &cmd, &result); nvme_show_init(); @@ -521,7 +490,7 @@ static int arbitration_set(int fd, const __u8 fid, struct argconfig_commandline_ } else if (err < 0) { nvme_show_perror("Set %s", temp_thresh_feat); } else { - nvme_show_result("Set %s: (%s)", arbitration_feat, save ? "Save" : "Not save"); + nvme_show_result("Set %s: (%s)", arbitration_feat, sv ? "Save" : "Not save"); nvme_feature_show_fields(fid, NVME_SET(cfg->ab, FEAT_ARBITRATION_BURST) | NVME_SET(cfg->lpw, FEAT_ARBITRATION_LPW) | NVME_SET(cfg->mpw, FEAT_ARBITRATION_MPW) | @@ -533,16 +502,17 @@ static int arbitration_set(int fd, const __u8 fid, struct argconfig_commandline_ return err; } -static int feat_arbitration(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int feat_arbitration(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const __u8 fid = NVME_FEAT_FID_ARBITRATION; const char *ab = "arbitration burst"; const char *lpw = "low priority weight"; const char *mpw = "medium priority weight"; const char *hpw = "high priority weight"; - int err; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + int err; struct arbitration_config cfg = { 0 }; @@ -552,32 +522,25 @@ static int feat_arbitration(int argc, char **argv, struct command *cmd, struct p OPT_BYTE("mpw", 'm', &cfg.mpw, mpw), OPT_BYTE("hpw", 'H', &cfg.hpw, hpw)); - err = parse_and_open(&dev, argc, argv, TEMP_THRESH_DESC, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, TEMP_THRESH_DESC, opts); if (err) return err; if (argc == 2 || argconfig_parse_seen(opts, "sel")) - return feat_get(dev, fid, 0, cfg.sel, "arbitration feature"); + return feat_get(hdl, fid, 0, cfg.sel, "arbitration feature"); - return arbitration_set(dev_fd(dev), fid, opts, &cfg); + return arbitration_set(hdl, fid, opts, &cfg); } -static int volatile_wc_set(struct nvme_dev *dev, const __u8 fid, bool wce, bool save) +static int volatile_wc_set(struct nvme_transport_handle *hdl, const __u8 fid, + bool wce, bool sv) { + __u32 cdw11 = NVME_SET(wce, FEAT_VWC_WCE); __u32 result; int err; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .cdw11 = NVME_SET(wce, FEAT_VWC_WCE), - .save = save, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, fid, sv, cdw11, 0, 0, 0, 0, NULL, 0, + &result); nvme_show_init(); @@ -586,9 +549,9 @@ static int volatile_wc_set(struct nvme_dev *dev, const __u8 fid, bool wce, bool } else if (err < 0) { nvme_show_perror("Set %s", volatile_wc_feat); } else { - nvme_show_result("Set %s: 0x%04x (%s)", volatile_wc_feat, args.cdw11, - save ? "Save" : "Not save"); - nvme_feature_show_fields(fid, args.cdw11, NULL); + nvme_show_result("Set %s: 0x%04x (%s)", volatile_wc_feat, cdw11, + sv ? "Save" : "Not save"); + nvme_feature_show_fields(fid, cdw11, NULL); } nvme_show_finish(); @@ -596,12 +559,13 @@ static int volatile_wc_set(struct nvme_dev *dev, const __u8 fid, bool wce, bool return err; } -static int feat_volatile_wc(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int feat_volatile_wc(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const __u8 fid = NVME_FEAT_FID_VOLATILE_WC; const char *wce = "volatile write cache enable"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; struct config { @@ -613,14 +577,14 @@ static int feat_volatile_wc(int argc, char **argv, struct command *cmd, struct p FEAT_ARGS(opts, OPT_FLAG("wce", 'w', &cfg.wce, wce)); - err = parse_and_open(&dev, argc, argv, VOLATILE_WC_DESC, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, VOLATILE_WC_DESC, opts); if (err) return err; if (argconfig_parse_seen(opts, "wce")) - err = volatile_wc_set(dev, fid, cfg.wce, argconfig_parse_seen(opts, "save")); + err = volatile_wc_set(hdl, fid, cfg.wce, argconfig_parse_seen(opts, "save")); else - err = feat_get(dev, fid, 0, cfg.sel, volatile_wc_feat); + err = feat_get(hdl, fid, 0, cfg.sel, volatile_wc_feat); return err; } diff --git a/plugins/huawei/huawei-nvme.c b/plugins/huawei/huawei-nvme.c index 5de0d3bd9b..8ae01c49c1 100644 --- a/plugins/huawei/huawei-nvme.c +++ b/plugins/huawei/huawei-nvme.c @@ -64,15 +64,16 @@ struct huawei_list_element_len { unsigned int array_name; }; -static int huawei_get_nvme_info(int fd, struct huawei_list_item *item, const char *node) +static int huawei_get_nvme_info(struct nvme_transport_handle *hdl, + struct huawei_list_item *item, const char *node) { + struct stat nvme_stat_info; int err; int len; - struct stat nvme_stat_info; memset(item, 0, sizeof(*item)); - err = nvme_identify_ctrl(fd, &item->ctrl); + err = nvme_identify_ctrl(hdl, &item->ctrl); if (err) return err; @@ -84,12 +85,12 @@ static int huawei_get_nvme_info(int fd, struct huawei_list_item *item, const cha } item->huawei_device = true; - err = nvme_get_nsid(fd, &item->nsid); - err = nvme_identify_ns(fd, item->nsid, &item->ns); + err = nvme_get_nsid(hdl, &item->nsid); + err = nvme_identify_ns(hdl, item->nsid, &item->ns); if (err) return err; - err = fstat(fd, &nvme_stat_info); + err = fstat(nvme_transport_handle_get_fd(hdl), &nvme_stat_info); if (err < 0) return err; @@ -290,9 +291,11 @@ static void huawei_print_list_items(struct huawei_list_item *list_items, unsigne huawei_print_list_item(&list_items[i], element_len); } -static int huawei_list(int argc, char **argv, struct command *command, - struct plugin *plugin) +static int huawei_list(int argc, char **argv, struct command *acmd, + struct plugin *plugin) { + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = + nvme_create_global_ctx(stdout, DEFAULT_LOGLEVEL); char path[264]; struct dirent **devices; struct huawei_list_item *list_items; @@ -313,6 +316,9 @@ static int huawei_list(int argc, char **argv, struct command *command, OPT_END() }; + if (!ctx) + return -ENOMEM; + ret = argconfig_parse(argc, argv, desc, opts); if (ret) return ret; @@ -333,23 +339,21 @@ static int huawei_list(int argc, char **argv, struct command *command, } for (i = 0; i < n; i++) { - int fd; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; snprintf(path, sizeof(path), "/dev/%s", devices[i]->d_name); - fd = open(path, O_RDONLY); - if (fd < 0) { + ret = nvme_open(ctx, path, &hdl); + if (ret) { fprintf(stderr, "Cannot open device %s: %s\n", - path, strerror(errno)); + path, strerror(-ret)); continue; } - ret = huawei_get_nvme_info(fd, &list_items[huawei_num], path); - if (ret) { - close(fd); + ret = huawei_get_nvme_info(hdl, &list_items[huawei_num], path); + if (ret) goto out_free_list_items; - } + if (list_items[huawei_num].huawei_device == true) huawei_num++; - close(fd); } if (huawei_num > 0) { @@ -381,7 +385,7 @@ static void huawei_do_id_ctrl(__u8 *vs, struct json_object *root) printf("array name : %s\n", strlen(array_name) > 1 ? array_name : "NULL"); } -static int huawei_id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int huawei_id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return __id_ctrl(argc, argv, cmd, plugin, huawei_do_id_ctrl); + return __id_ctrl(argc, argv, acmd, plugin, huawei_do_id_ctrl); } diff --git a/plugins/innogrit/innogrit-nvme.c b/plugins/innogrit/innogrit-nvme.c index 9e7be483e2..1182c27987 100644 --- a/plugins/innogrit/innogrit-nvme.c +++ b/plugins/innogrit/innogrit-nvme.c @@ -12,13 +12,15 @@ #include "libnvme.h" #include "nvme-print.h" #include "typedef.h" +#include "util/cleanup.h" #define CREATE_CMD #include "innogrit-nvme.h" -static int nvme_vucmd(int fd, unsigned char opcode, unsigned int cdw12, - unsigned int cdw13, unsigned int cdw14, - unsigned int cdw15, char *data, int data_len) +static int nvme_vucmd(struct nvme_transport_handle *hdl, unsigned char opcode, + unsigned int cdw12, unsigned int cdw13, + unsigned int cdw14, unsigned int cdw15, char *data, + int data_len) { struct nvme_passthru_cmd cmd; @@ -33,33 +35,25 @@ static int nvme_vucmd(int fd, unsigned char opcode, unsigned int cdw12, cmd.nsid = 0xffffffff; cmd.addr = (__u64)(__u64)(uintptr_t)data; cmd.data_len = data_len; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + return nvme_submit_admin_passthru(hdl, &cmd, NULL); } -int getlogpage(struct nvme_dev *dev, unsigned char ilogid, unsigned char ilsp, - char *data, int data_len, unsigned int *result) +static int getlogpage(struct nvme_transport_handle *hdl, unsigned char ilogid, + unsigned char ilsp, char *data, int data_len, + unsigned int *result) { - struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .lid = ilogid, - .nsid = 0xffffffff, - .lpo = 0, - .lsp = ilsp, - .lsi = 0, - .rae = true, - .uuidx = 0, - .csi = NVME_CSI_NVM, - .ot = false, - .len = data_len, - .log = (void *)data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = result, - }; - return nvme_get_log(&args); + struct nvme_passthru_cmd cmd; + + nvme_init_get_log(&cmd, NVME_NSID_ALL, ilogid, NVME_CSI_NVM, + data, data_len); + cmd.cdw10 |= NVME_FIELD_ENCODE(ilsp, + NVME_LOG_CDW10_LSP_SHIFT, + NVME_LOG_CDW10_LSP_MASK); + + return nvme_get_log(hdl, &cmd, true, NVME_LOG_PAGE_PDU_SIZE, result); } -int getvsctype(struct nvme_dev *dev) +static int getvsctype(struct nvme_transport_handle *hdl) { unsigned char ilogid; char data[4096]; @@ -68,28 +62,29 @@ int getvsctype(struct nvme_dev *dev) memset(data, 0, 4096); // pdrvinfo by getlogpage for (ilogid = 0xe1; ilogid < 0xe2; ilogid++) { - getlogpage(dev, ilogid, 0, data, 4096, NULL); + getlogpage(hdl, ilogid, 0, data, 4096, NULL); if (pdrvinfo->signature == 0x5A) return 1; } //pdrvinfo by vucmd - nvme_vucmd(dev_fd(dev), 0xfe, 0x82, 0X03, 0x00, 0, (char *)data, 4096); + nvme_vucmd(hdl, 0xfe, 0x82, 0X03, 0x00, 0, (char *)data, 4096); if (pdrvinfo->signature == 0x5A) return 1; return 0; } -int getvsc_eventlog(struct nvme_dev *dev, FILE *fp) +static int getvsc_eventlog(struct nvme_transport_handle *hdl, FILE *fp) { - char data[4096]; unsigned int errcnt, rxlen, start_flag; + int ivsctype = getvsctype(hdl); + struct evlg_flush_hdr *pevlog; unsigned long long end_flag; - struct evlg_flush_hdr *pevlog = (struct evlg_flush_hdr *)data; + char data[4096]; int ret = -1; - int ivsctype = getvsctype(dev); + pevlog = (struct evlg_flush_hdr *)data; start_flag = 0; rxlen = 0; errcnt = 0; @@ -97,12 +92,12 @@ int getvsc_eventlog(struct nvme_dev *dev, FILE *fp) while (1) { memset(data, 0, 4096); if (ivsctype == 0) { - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET_EVENT_LOG, 0, 0, + ret = nvme_vucmd(hdl, NVME_VSC_GET_EVENT_LOG, 0, 0, (SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF), (char *)data, 4096); } else { - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_TYPE1_GET, 0x60, 0, + ret = nvme_vucmd(hdl, NVME_VSC_TYPE1_GET, 0x60, 0, 0, 0, (char *)data, 4096); } @@ -140,18 +135,18 @@ int getvsc_eventlog(struct nvme_dev *dev, FILE *fp) return IG_SUCCESS; } -int getlogpage_eventlog(struct nvme_dev *dev, FILE *fp) +int getlogpage_eventlog(struct nvme_transport_handle *hdl, FILE *fp) { unsigned int i, result, total_size; char data[4096]; int ret = 0; result = 0; - ret = getlogpage(dev, 0xcb, 0x01, data, 4096, NULL); + ret = getlogpage(hdl, 0xcb, 0x01, data, 4096, NULL); if (ret) return IG_UNSUPPORT; - ret = getlogpage(dev, 0xcb, 0x02, data, 4096, &result); + ret = getlogpage(hdl, 0xcb, 0x02, data, 4096, &result); if ((ret) || (result == 0)) return IG_UNSUPPORT; @@ -159,7 +154,7 @@ int getlogpage_eventlog(struct nvme_dev *dev, FILE *fp) printf("total eventlog : %d.%d MB\n", total_size / SIZE_MB, (total_size % SIZE_MB) * 100 / SIZE_MB); for (i = 0; i <= total_size; i += 4096) { - ret = getlogpage(dev, 0xcb, 0x00, data, 4096, NULL); + ret = getlogpage(hdl, 0xcb, 0x00, data, 4096, NULL); printf("\rget eventlog : %d.%d MB ", i / SIZE_MB, (i % SIZE_MB) * 100 / SIZE_MB); if (ret) { @@ -173,22 +168,23 @@ int getlogpage_eventlog(struct nvme_dev *dev, FILE *fp) } static int innogrit_geteventlog(int argc, char **argv, - struct command *command, - struct plugin *plugin) + struct command *command, + struct plugin *plugin) { - time_t timep; - struct tm *logtime; - char currentdir[128], filename[512]; const char *desc = "Recrieve event log for the given device "; - struct nvme_dev *dev; - FILE *fp = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_file_ FILE *fp = NULL; + char currentdir[128], filename[512]; + struct tm *logtime; + time_t timep; int ret = -1; OPT_ARGS(opts) = { OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; @@ -198,49 +194,48 @@ static int innogrit_geteventlog(int argc, char **argv, time(&timep); logtime = localtime(&timep); sprintf(filename, "%s/eventlog_%02d%02d-%02d%02d%02d.eraw", currentdir, - logtime->tm_mon+1, logtime->tm_mday, logtime->tm_hour, logtime->tm_min, - logtime->tm_sec); + logtime->tm_mon + 1, logtime->tm_mday, logtime->tm_hour, + logtime->tm_min, logtime->tm_sec); printf("output eventlog file : %s\n", filename); fp = fopen(filename, "a+"); - getvsctype(dev); - ret = getlogpage_eventlog(dev, fp); + getvsctype(hdl); + ret = getlogpage_eventlog(hdl, fp); if (ret == IG_UNSUPPORT) - ret = getvsc_eventlog(dev, fp); + ret = getvsc_eventlog(hdl, fp); - fclose(fp); - dev_close(dev); chmod(filename, 0666); return ret; } -static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, - struct plugin *plugin) +static int innogrit_vsc_getcdump(int argc, char **argv, struct command *acmd, + struct plugin *plugin) { - time_t timep; - struct tm *logtime; + const char *desc = "Recrieve cdump data for the given device "; char currentdir[128], filename[512], fname[128]; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; unsigned int itotal, icur, ivsctype; - char data[4096]; - struct cdumpinfo cdumpinfo; - unsigned char busevsc = false; unsigned int ipackcount, ipackindex; - char fwvera[32]; - const char *desc = "Recrieve cdump data for the given device "; - struct nvme_dev *dev; + unsigned char busevsc = false; + struct cdumpinfo cdumpinfo; + struct tm *logtime; FILE *fp = NULL; + char data[4096]; + char fwvera[32]; + time_t timep; int ret = -1; OPT_ARGS(opts) = { OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - ivsctype = getvsctype(dev); + ivsctype = getvsctype(hdl); if (getcwd(currentdir, 128) == NULL) return -1; @@ -252,11 +247,11 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, memset(data, 0, 4096); if (ivsctype == 0) { - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, + ret = nvme_vucmd(hdl, NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, (SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF), (char *)data, 4096); } else { - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_TYPE1_GET, 0x82, 0x00, + ret = nvme_vucmd(hdl, NVME_VSC_TYPE1_GET, 0x82, 0x00, 0, 0, (char *)data, 4096); } @@ -284,9 +279,8 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, if (busevsc == false) { memset(data, 0, 4096); - ret = nvme_get_nsid_log(dev_fd(dev), true, 0x07, - NVME_NSID_ALL, - 4096, data); + ret = nvme_get_nsid_log(hdl, NVME_NSID_ALL,true, 0x07, + data, 4096); if (ret != 0) return ret; @@ -313,25 +307,25 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, memset(data, 0, 4096); if (busevsc) { if (ivsctype == 0) { - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, + ret = nvme_vucmd(hdl, NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, (SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF), (char *)data, 4096); } else { - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_TYPE1_GET, + ret = nvme_vucmd(hdl, NVME_VSC_TYPE1_GET, 0x82, 0x00, 0, 0, (char *)data, 4096); } } else { - ret = nvme_get_nsid_log(dev_fd(dev), true, - 0x07, - NVME_NSID_ALL, 4096, data); + ret = nvme_get_nsid_log(hdl, NVME_NSID_ALL, true, + 0x07, data, 4096); } if (ret != 0) return ret; fwrite(data, 1, 4096, fp); - printf("\rWait for dump data %d%%" XCLEAN_LINE, ((icur+4096) * 100/itotal)); + printf("\rWait for dump data %d%%" XCLEAN_LINE, + ((icur + 4096) * 100 / itotal)); } memset(data, 0, 4096); strcpy((char *)data, "cdumpend"); @@ -342,20 +336,18 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, memset(data, 0, 4096); if (busevsc) { if (ivsctype == 0) { - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, + ret = nvme_vucmd(hdl, NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, (SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF), (char *)data, 4096); } else { - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_TYPE1_GET, + ret = nvme_vucmd(hdl, NVME_VSC_TYPE1_GET, 0x82, 0x00, 0, 0, (char *)data, 4096); } } else { - ret = nvme_get_nsid_log(dev_fd(dev), true, - 0x07, - NVME_NSID_ALL, 4096, - data); + ret = nvme_get_nsid_log(hdl, NVME_NSID_ALL, true, + 0x07, data, 4096); } if (ret != 0) return ret; @@ -374,7 +366,6 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, } printf("\n"); - dev_close(dev); if (fp != NULL) fclose(fp); return ret; diff --git a/plugins/inspur/inspur-nvme.c b/plugins/inspur/inspur-nvme.c index cda3507533..041a0dede8 100644 --- a/plugins/inspur/inspur-nvme.c +++ b/plugins/inspur/inspur-nvme.c @@ -204,23 +204,23 @@ void show_r1_media_err_log(r1_cli_vendor_log_t *vendorlog) } } -static int nvme_get_vendor_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int nvme_get_vendor_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - __u8 local_mem[BYTE_OF_4K]; char *desc = "Get the Inspur vendor log"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + __u8 local_mem[BYTE_OF_4K]; int err; OPT_ARGS(opts) = { OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; memset(local_mem, 0, BYTE_OF_4K); - err = nvme_get_log_simple(dev_fd(dev), - (enum nvme_cmd_get_log_lid)VENDOR_SMART_LOG_PAGE, - sizeof(r1_cli_vendor_log_t), local_mem); + err = nvme_get_log_simple(hdl, (enum nvme_cmd_get_log_lid)VENDOR_SMART_LOG_PAGE, + local_mem, sizeof(r1_cli_vendor_log_t)); if (!err) { show_r1_vendor_log((r1_cli_vendor_log_t *)local_mem); show_r1_media_err_log((r1_cli_vendor_log_t *)local_mem); @@ -228,6 +228,5 @@ static int nvme_get_vendor_log(int argc, char **argv, struct command *cmd, struc nvme_show_status(err); } - dev_close(dev); return err; } diff --git a/plugins/intel/intel-nvme.c b/plugins/intel/intel-nvme.c index faf1a1534c..ef22ef58ea 100644 --- a/plugins/intel/intel-nvme.c +++ b/plugins/intel/intel-nvme.c @@ -129,12 +129,13 @@ static void intel_id_ctrl(__u8 *vs, struct json_object *root) printf("mic_fw : %s\n", mic_fw); } -static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return __id_ctrl(argc, argv, cmd, plugin, intel_id_ctrl); + return __id_ctrl(argc, argv, acmd, plugin, intel_id_ctrl); } -static void show_intel_smart_log_jsn(struct nvme_additional_smart_log *smart, +static void +show_intel_smart_log_jsn(struct nvme_additional_smart_log *smart, unsigned int nsid, const char *devname) { struct json_object *root, *entry_stats, *dev_stats, *multi; @@ -330,7 +331,7 @@ static void show_intel_smart_log(struct nvme_additional_smart_log *smart, print_intel_smart_log_items(iter); } -static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_additional_smart_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Intel vendor specific additional smart log (optionally, for the specified namespace), and show it."; @@ -341,7 +342,8 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd, #endif /* CONFIG_JSONC */ struct nvme_additional_smart_log smart_log; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; struct config { @@ -361,33 +363,32 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = nvme_get_log_simple(dev_fd(dev), 0xca, sizeof(smart_log), - &smart_log); + err = nvme_get_log_simple(hdl, 0xca, &smart_log, sizeof(smart_log)); if (!err) { if (cfg.json) show_intel_smart_log_jsn(&smart_log, cfg.namespace_id, - dev->name); + nvme_transport_handle_get_name(hdl)); else if (!cfg.raw_binary) show_intel_smart_log(&smart_log, cfg.namespace_id, - dev->name); + nvme_transport_handle_get_name(hdl)); else d_raw((unsigned char *)&smart_log, sizeof(smart_log)); } else if (err > 0) { nvme_show_status(err); } - dev_close(dev); return err; } -static int get_market_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_market_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Intel Marketing Name log and show it."; const char *raw = "dump output in binary format"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; char log[512]; int err; @@ -403,11 +404,11 @@ static int get_market_log(int argc, char **argv, struct command *cmd, struct plu OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = nvme_get_log_simple(dev_fd(dev), 0xdd, sizeof(log), log); + err = nvme_get_log_simple(hdl, 0xdd, log, sizeof(log)); if (!err) { if (!cfg.raw_binary) printf("Intel Marketing Name Log:\n%s\n", log); @@ -415,7 +416,6 @@ static int get_market_log(int argc, char **argv, struct command *cmd, struct plu d_raw((unsigned char *)&log, sizeof(log)); } else if (err > 0) nvme_show_status(err); - dev_close(dev); return err; } @@ -445,10 +445,11 @@ static void show_temp_stats(struct intel_temp_stats *stats) printf("Estimated offset : %"PRIu64"\n", le64_to_cpu(stats->est_offset)); } -static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_temp_stats_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { struct intel_temp_stats stats; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; const char *desc = "Get Temperature Statistics log and show it."; @@ -465,11 +466,11 @@ static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = nvme_get_log_simple(dev_fd(dev), 0xc5, sizeof(stats), &stats); + err = nvme_get_log_simple(hdl, 0xc5, &stats, sizeof(stats)); if (!err) { if (!cfg.raw_binary) show_temp_stats(&stats); @@ -477,7 +478,6 @@ static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct d_raw((unsigned char *)&stats, sizeof(stats)); } else if (err > 0) nvme_show_status(err); - dev_close(dev); return err; } @@ -770,8 +770,7 @@ static void json_lat_stats_linear(struct intel_lat_stats *stats, } } -static void json_lat_stats_3_0(struct intel_lat_stats *stats, - int write) +static void json_lat_stats_3_0(struct intel_lat_stats *stats, int write) { struct json_object *root = json_create_object(); struct json_object *bucket_list = json_object_new_array(); @@ -789,8 +788,7 @@ static void json_lat_stats_3_0(struct intel_lat_stats *stats, json_free_object(root); } -static void json_lat_stats_4_0(struct intel_lat_stats *stats, - int write) +static void json_lat_stats_4_0(struct intel_lat_stats *stats, int write) { struct json_object *root = json_create_object(); struct json_object *bucket_list = json_object_new_array(); @@ -968,7 +966,8 @@ static void json_lat_stats(int write) printf("\n"); } -static void print_dash_separator(int count) +static void +print_dash_separator(int count) { for (int i = 0; i < count; i++) putchar('-'); @@ -1026,10 +1025,11 @@ static void show_lat_stats(int write) } } -static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_lat_stats_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { __u8 data[NAND_LAT_STATS_LEN]; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; const char *desc = "Get Intel Latency Statistics log and show it."; @@ -1055,44 +1055,34 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; /* For optate, latency stats are deleted every time their LID is pulled. * Therefore, we query the longest lat_stats log page first. */ - err = nvme_get_log_simple(dev_fd(dev), cfg.write ? 0xc2 : 0xc1, - sizeof(data), &data); + err = nvme_get_log_simple(hdl, cfg.write ? 0xc2 : 0xc1, + &data, sizeof(data)); media_version[0] = (data[1] << 8) | data[0]; media_version[1] = (data[3] << 8) | data[2]; if (err) - goto close_dev; + return err; if (media_version[0] == 1000) { __u32 thresholds[OPTANE_V1000_BUCKET_LEN] = {0}; __u32 result; - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = 0xf7, - .nsid = 0, - .sel = 0, - .cdw11 = cfg.write ? 0x1 : 0x0, - .uuidx = 0, - .data_len = sizeof(thresholds), - .data = thresholds, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_get_features(&args); + err = nvme_get_features(hdl, 0, 0xf7, + 0, cfg.write ? 0x1 : 0x0, + 0, thresholds, sizeof(thresholds), + &result); if (err) { fprintf(stderr, "Querying thresholds failed. "); nvme_show_status(err); - goto close_dev; + return err; } /* Update bucket thresholds to be printed */ @@ -1128,9 +1118,7 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct sizeof(stats)); } -close_dev: - dev_close(dev); - return err; + return 0; } struct intel_assert_dump { @@ -1231,15 +1219,15 @@ static void print_intel_nlog(struct intel_vu_nlog *intel_nlog) } static int read_entire_cmd(struct nvme_passthru_cmd *cmd, int total_size, - const size_t max_tfer, int out_fd, int ioctl_fd, - __u8 *buf) + const size_t max_tfer, int out_fd, + struct nvme_transport_handle *hdl, __u8 *buf) { int err = 0; size_t dword_tfer = 0; dword_tfer = min(max_tfer, total_size); while (total_size > 0) { - err = nvme_submit_admin_passthru(ioctl_fd, cmd, NULL); + err = nvme_submit_admin_passthru(hdl, cmd, NULL); if (err) { fprintf(stderr, "failed on cmd.data_len %u cmd.cdw13 %u cmd.cdw12 %x cmd.cdw10 %u err %x remaining size %d\n", @@ -1273,8 +1261,8 @@ static int write_header(__u8 *buf, int fd, size_t amnt) return 0; } -static int read_header(struct nvme_passthru_cmd *cmd, __u8 *buf, int ioctl_fd, - __u32 dw12, int nsid) +static int read_header(struct nvme_passthru_cmd *cmd, __u8 *buf, + struct nvme_transport_handle *hdl, __u32 dw12, int nsid) { memset(cmd, 0, sizeof(*cmd)); memset(buf, 0, 4096); @@ -1284,15 +1272,15 @@ static int read_header(struct nvme_passthru_cmd *cmd, __u8 *buf, int ioctl_fd, cmd->cdw12 = dw12; cmd->data_len = 0x1000; cmd->addr = (unsigned long)(void *)buf; - return read_entire_cmd(cmd, 0x400, 0x400, -1, ioctl_fd, buf); + return read_entire_cmd(cmd, 0x400, 0x400, -1, hdl, buf); } -static int setup_file(char *f, char *file, int fd, int type) +static int setup_file(char *f, char *file, struct nvme_transport_handle *hdl, int type) { struct nvme_id_ctrl ctrl; int err = 0, i = sizeof(ctrl.sn) - 1; - err = nvme_identify_ctrl(fd, &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) return err; @@ -1308,7 +1296,8 @@ static int setup_file(char *f, char *file, int fd, int type) return err; } -static int get_internal_log_old(__u8 *buf, int output, int fd, +static int get_internal_log_old(__u8 *buf, int output, + struct nvme_transport_handle *hdl, struct nvme_passthru_cmd *cmd) { struct intel_vu_log *intel; @@ -1330,7 +1319,7 @@ static int get_internal_log_old(__u8 *buf, int output, int fd, cmd->opcode = 0xd2; cmd->cdw10 = min(dwmax, intel->size); cmd->data_len = min(dmamax, intel->size); - err = read_entire_cmd(cmd, intel->size, dwmax, output, fd, buf); + err = read_entire_cmd(cmd, intel->size, dwmax, output, hdl, buf); if (err) goto out; @@ -1339,8 +1328,8 @@ static int get_internal_log_old(__u8 *buf, int output, int fd, return err; } -static int get_internal_log(int argc, char **argv, struct command *command, - struct plugin *plugin) +static int get_internal_log(int argc, char **argv, struct command *acmd, + struct plugin *plugin) { __u8 buf[0x2000]; char f[0x100]; @@ -1351,7 +1340,8 @@ static int get_internal_log(int argc, char **argv, struct command *command, struct intel_vu_nlog *intel_nlog = (struct intel_vu_nlog *)buf; struct intel_assert_dump *ad = (struct intel_assert_dump *) intel->reserved; struct intel_event_header *ehdr = (struct intel_event_header *)intel->reserved; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; const char *desc = "Get Intel Firmware Log and save it."; const char *log = "Log type: 0, 1, or 2 for nlog, event log, and assert log, respectively."; @@ -1387,7 +1377,7 @@ static int get_internal_log(int argc, char **argv, struct command *command, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { free(intel); return err; @@ -1399,7 +1389,7 @@ static int get_internal_log(int argc, char **argv, struct command *command, } if (!cfg.file) { - err = setup_file(f, cfg.file, dev_fd(dev), cfg.log); + err = setup_file(f, cfg.file, hdl, cfg.log); if (err) goto out_free; cfg.file = f; @@ -1417,7 +1407,7 @@ static int get_internal_log(int argc, char **argv, struct command *command, goto out_free; } - err = read_header(&cmd, buf, dev_fd(dev), cdlog.u.entireDword, + err = read_header(&cmd, buf, hdl, cdlog.u.entireDword, cfg.namespace_id); if (err) goto out; @@ -1427,7 +1417,7 @@ static int get_internal_log(int argc, char **argv, struct command *command, if ((intel->ver.major < 1 && intel->ver.minor < 1) || (intel->ver.major <= 1 && intel->ver.minor <= 1 && cfg.log == 0)) { cmd.addr = (unsigned long)(void *)buf; - err = get_internal_log_old(buf, output, dev_fd(dev), &cmd); + err = get_internal_log_old(buf, output, hdl, &cmd); goto out; } @@ -1472,7 +1462,7 @@ static int get_internal_log(int argc, char **argv, struct command *command, cmd.data_len = min(0x400, ad[i].assertsize) * 4; err = read_entire_cmd(&cmd, ad[i].assertsize, 0x400, output, - dev_fd(dev), + hdl, buf); if (err) goto out; @@ -1482,7 +1472,7 @@ static int get_internal_log(int argc, char **argv, struct command *command, if (count > 1) cdlog.u.fields.selectNlog = i; - err = read_header(&cmd, buf, dev_fd(dev), + err = read_header(&cmd, buf, hdl, cdlog.u.entireDword, cfg.namespace_id); if (err) @@ -1497,7 +1487,7 @@ static int get_internal_log(int argc, char **argv, struct command *command, cmd.data_len = min(0x1000, intel_nlog->nlogbytesize); err = read_entire_cmd(&cmd, intel_nlog->nlogbytesize / 4, 0x400, output, - dev_fd(dev), + hdl, buf); if (err) goto out; @@ -1507,7 +1497,7 @@ static int get_internal_log(int argc, char **argv, struct command *command, cmd.data_len = 0x400; err = read_entire_cmd(&cmd, ehdr->edumps[j].coresize, 0x400, output, - dev_fd(dev), + hdl, buf); if (err) goto out; @@ -1526,7 +1516,6 @@ static int get_internal_log(int argc, char **argv, struct command *command, close(output); out_free: free(intel); - dev_close(dev); return err; } @@ -1544,8 +1533,9 @@ static int enable_lat_stats_tracking(int argc, char **argv, const __u32 cdw11 = 0x0; const __u32 cdw12 = 0x0; const __u32 data_len = 32; - const __u32 save = 0; - struct nvme_dev *dev; + const __u32 sv = 0; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; void *buf = NULL; __u32 result; int err; @@ -1559,13 +1549,13 @@ static int enable_lat_stats_tracking(int argc, char **argv, .disable = false, }; - struct argconfig_commandline_options command_line_options[] = { + struct argconfig_commandline_options opts[] = { {"enable", 'e', "", CFG_FLAG, &cfg.enable, no_argument, enable_desc}, {"disable", 'd', "", CFG_FLAG, &cfg.disable, no_argument, disable_desc}, {NULL} }; - err = parse_and_open(&dev, argc, argv, desc, command_line_options); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); enum Option { None = -1, @@ -1583,52 +1573,23 @@ static int enable_lat_stats_tracking(int argc, char **argv, if (err) return err; - struct nvme_get_features_args args_get = { - .args_size = sizeof(args_get), - .fd = dev_fd(dev), - .fid = fid, - .nsid = nsid, - .sel = sel, - .cdw11 = cdw11, - .uuidx = 0, - .data_len = data_len, - .data = buf, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - struct nvme_set_features_args args_set = { - .args_size = sizeof(args_set), - .fd = dev_fd(dev), - .fid = fid, - .nsid = nsid, - .cdw11 = option, - .cdw12 = cdw12, - .save = save, - .uuidx = 0, - .cdw15 = 0, - .data_len = data_len, - .data = buf, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - switch (option) { case None: - err = nvme_get_features(&args_get); + err = nvme_get_features(hdl, nsid, fid, sel, cdw11, 0, buf, + data_len, &result); if (!err) { printf( "Latency Statistics Tracking (FID 0x%X) is currently (%i).\n", fid, result); } else { printf("Could not read feature id 0xE2.\n"); - dev_close(dev); return err; } break; case True: case False: - err = nvme_set_features(&args_set); + err = nvme_set_features(hdl, nsid, fid, sv, option, cdw12, 0, 0, 0, buf, + data_len, &result); if (err > 0) { nvme_show_status(err); } else if (err < 0) { @@ -1643,7 +1604,6 @@ static int enable_lat_stats_tracking(int argc, char **argv, printf("%d not supported.\n", option); return -EINVAL; } - dev_close(dev); return err; } @@ -1657,8 +1617,9 @@ static int set_lat_stats_thresholds(int argc, char **argv, const __u32 nsid = 0; const __u8 fid = 0xf7; const __u32 cdw12 = 0x0; - const __u32 save = 0; - struct nvme_dev *dev; + const __u32 sv = 0; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 result; int err, num; @@ -1679,7 +1640,7 @@ static int set_lat_stats_thresholds(int argc, char **argv, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1688,8 +1649,8 @@ static int set_lat_stats_thresholds(int argc, char **argv, * valid buckets a user is allowed to modify. Read or write doesn't * matter */ - err = nvme_get_log_simple(dev_fd(dev), 0xc2, - sizeof(media_version), media_version); + err = nvme_get_log_simple(hdl, 0xc2, + media_version, sizeof(media_version)); if (err) { fprintf(stderr, "Querying media version failed. "); nvme_show_status(err); @@ -1708,22 +1669,8 @@ static int set_lat_stats_thresholds(int argc, char **argv, } - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .nsid = nsid, - .cdw11 = cfg.write ? 0x1 : 0x0, - .cdw12 = cdw12, - .save = save, - .uuidx = 0, - .cdw15 = 0, - .data_len = sizeof(thresholds), - .data = thresholds, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); + err = nvme_set_features(hdl, nsid, fid, sv, cfg.write ? 0x1 : 0x0, cdw12, + 0, 0, 0, thresholds, sizeof(thresholds), &result); if (err > 0) { nvme_show_status(err); @@ -1736,7 +1683,6 @@ static int set_lat_stats_thresholds(int argc, char **argv, } close_dev: - dev_close(dev); return err; } diff --git a/plugins/lm/lm-nvme.c b/plugins/lm/lm-nvme.c index 4f4159fbe9..fdf6f42f82 100644 --- a/plugins/lm/lm-nvme.c +++ b/plugins/lm/lm-nvme.c @@ -29,7 +29,6 @@ #include "libnvme.h" #include "plugin.h" #include "linux/types.h" -#include "nvme-wrap.h" #include "util/cleanup.h" #define CREATE_CMD @@ -37,7 +36,7 @@ #include "lm-print.h" -static inline const char *arg_str(const char * const *strings, size_t array_size, size_t idx) +static inline const char * arg_str(const char * const *strings, size_t array_size, size_t idx) { if (idx < array_size && strings[idx]) return strings[idx]; @@ -47,7 +46,7 @@ static inline const char *arg_str(const char * const *strings, size_t array_size #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #define ARGSTR(s, i) arg_str(s, ARRAY_SIZE(s), i) -static int lm_create_cdq(int argc, char **argv, struct command *command, struct plugin *plugin) +static int lm_create_cdq(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Create Controller Data Queue for controller of specific type and size"; const char *sz = "CDQ Size (in dwords)"; @@ -58,9 +57,12 @@ static int lm_create_cdq(int argc, char **argv, struct command *command, struct "will write to invalid memory, inevitably leading to MMU faults or " "worse."; - _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; struct lba_migration_queue_entry_type_0 *queue = NULL; + _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; + struct nvme_passthru_cmd cmd; + __u32 result; int err = -1; struct config { @@ -87,7 +89,7 @@ static int lm_create_cdq(int argc, char **argv, struct command *command, struct OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -105,33 +107,28 @@ static int lm_create_cdq(int argc, char **argv, struct command *command, struct return -ENOMEM; } - struct nvme_lm_cdq_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .sel = NVME_LM_SEL_CREATE_CDQ, - .mos = NVME_SET(cfg.qt, LM_QT), - .cntlid = cfg.cntlid, - .sz = cfg.sz, - .data = queue - }; - - err = nvme_lm_cdq(&args); + nvme_init_lm_cdq_create(&cmd, NVME_SET(cfg.qt, LM_QT), + cfg.cntlid, cfg.sz, queue); + err = nvme_submit_admin_passthru(hdl, &cmd, &result); if (err < 0) nvme_show_error("ERROR: nvme_lm_cdq() failed: %s", nvme_strerror(errno)); else if (err) nvme_show_status(err); else - printf("Create CDQ Successful: CDQID=0x%04x\n", args.cdqid); + printf("Create CDQ Successful: CDQID=0x%04x\n", + NVME_GET(result, LM_CREATE_CDQ_CDQID)); return err; } -static int lm_delete_cdq(int argc, char **argv, struct command *command, struct plugin *plugin) +static int lm_delete_cdq(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Delete Controller Data Queue"; const char *cdqid = "Controller Data Queue ID"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; int err = -1; struct config { @@ -147,18 +144,12 @@ static int lm_delete_cdq(int argc, char **argv, struct command *command, struct OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - struct nvme_lm_cdq_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .sel = NVME_LM_SEL_DELETE_CDQ, - .cdqid = cfg.cdqid, - }; - - err = nvme_lm_cdq(&args); + nvme_init_lm_cdq_delete(&cmd, 0, cfg.cdqid); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (err < 0) nvme_show_error("ERROR: nvme_lm_cdq() failed: %s", nvme_strerror(errno)); else if (err > 0) @@ -174,7 +165,7 @@ static const char * const lm_track_send_select_argstr[] = { [NVME_LM_SEL_TRACK_MEMORY_CHANGES] = "Track Memory Changes" }; -static int lm_track_send(int argc, char **argv, struct command *command, struct plugin *plugin) +static int lm_track_send(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Track Send command used to manage the tracking of information by a " "controller"; @@ -187,7 +178,9 @@ static int lm_track_send(int argc, char **argv, struct command *command, struct const char *stop = "Equivalent to stop tracking with defaults"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; int err = -1; struct config { @@ -215,7 +208,7 @@ static int lm_track_send(int argc, char **argv, struct command *command, struct OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -240,15 +233,8 @@ static int lm_track_send(int argc, char **argv, struct command *command, struct cfg.mos = NVME_SET(NVME_LM_LACT_STOP_LOGGING, LM_LACT); } - struct nvme_lm_track_send_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .cdqid = cfg.cdqid, - .sel = cfg.sel, - .mos = cfg.mos, - }; - - err = nvme_lm_track_send(&args); + nvme_init_lm_track_send(&cmd, cfg.sel, cfg.mos, cfg.cdqid); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (err < 0) nvme_show_error("ERROR: nvme_lm_track_send() failed %s", strerror(errno)); else if (err) @@ -266,7 +252,7 @@ static const char * const lm_migration_send_select_argstr[] = { [NVME_LM_SEL_SET_CONTROLLER_STATE] = "Set Controller State" }; -static int lm_migration_send(int argc, char **argv, struct command *command, struct plugin *plugin) +static int lm_migration_send(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Migration Send command is used to manage the migration of a controller"; const char *sel = "Select (SEL) the type of management operation to perform " @@ -292,9 +278,11 @@ static int lm_migration_send(int argc, char **argv, struct command *command, str const char *numd = "Number of Dwords (NUMD)"; const char *input = "Controller State Data input file"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - _cleanup_file_ FILE *file = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; + _cleanup_file_ FILE *file = NULL; + struct nvme_passthru_cmd cmd; void *data = NULL; int err = -1; @@ -341,7 +329,7 @@ static int lm_migration_send(int argc, char **argv, struct command *command, str OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -390,22 +378,12 @@ static int lm_migration_send(int argc, char **argv, struct command *command, str } } - struct nvme_lm_migration_send_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .sel = cfg.sel, - .mos = NVME_SET(cfg.seqind, LM_SEQIND), - .cntlid = cfg.cntlid, - .csuuidi = cfg.csuuidi, - .uidx = cfg.uidx, - .stype = cfg.stype, - .offset = cfg.offset, - .dudmq = cfg.dudmq, - .numd = cfg.numd, - .data = data, - }; - - err = nvme_lm_migration_send(&args); + nvme_init_lm_migration_send(&cmd, cfg.sel, + NVME_SET(cfg.seqind, LM_SEQIND), cfg.cntlid, + cfg.stype, cfg.dudmq, cfg.csvi, cfg.csuuidi, + cfg.offset, cfg.uidx, data, + (cfg.numd << 2)); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (err < 0) nvme_show_error("ERROR: nvme_lm_migration_send() failed %s", strerror(errno)); else if (err > 0) @@ -418,7 +396,7 @@ static int lm_migration_send(int argc, char **argv, struct command *command, str return err; } -static int lm_migration_recv(int argc, char **argv, struct command *command, struct plugin *plugin) +static int lm_migration_recv(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Migration Receive command is used to obtain information used to manage " " a migratable controller"; @@ -434,12 +412,16 @@ static int lm_migration_recv(int argc, char **argv, struct command *command, str const char *output = "Controller State Data output file"; const char *human_readable_info = "show info in readable format"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - _cleanup_file_ FILE *fd = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; + _cleanup_file_ FILE *fd = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; void *data = NULL; + __u32 result = 0; int err = -1; + __u16 mos; struct config { __u8 sel; @@ -481,7 +463,7 @@ static int lm_migration_recv(int argc, char **argv, struct command *command, str OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -511,22 +493,11 @@ static int lm_migration_recv(int argc, char **argv, struct command *command, str if (!data) return -ENOMEM; - __u32 result = 0; - struct nvme_lm_migration_recv_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .sel = cfg.sel, - .mos = NVME_SET(cfg.csvi, LM_GET_CONTROLLER_STATE_CSVI), - .uidx = cfg.uidx, - .csuuidi = cfg.csuuidi, - .offset = cfg.offset, - .cntlid = cfg.cntlid, - .numd = cfg.numd, - .data = data, - .result = &result, - }; - - err = nvme_lm_migration_recv(&args); + mos = NVME_SET(cfg.csvi, LM_GET_CONTROLLER_STATE_CSVI); + nvme_init_lm_migration_recv(&cmd, cfg.offset, mos, cfg.cntlid, + cfg.csuuidi, cfg.sel, cfg.uidx, 0, data, + (cfg.numd + 1) << 2); + err = nvme_submit_admin_passthru(hdl, &cmd, &result); if (err < 0) nvme_show_error("ERROR: nvme_lm_migration_recv() failed %s", strerror(errno)); else if (err) @@ -555,7 +526,7 @@ enum lm_controller_data_queue_feature_id { lm_cdq_feature_id = 0x21 }; -static int lm_set_cdq(int argc, char **argv, struct command *command, struct plugin *plugin) +static int lm_set_cdq(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "This Feature allows a host to update the status of the head pointer " "of a CDQ and specify the configuration of a CDQ Tail event."; @@ -564,7 +535,8 @@ static int lm_set_cdq(int argc, char **argv, struct command *command, struct plu const char *tpt = "If specified, the slot that causes the controller " " to issue a CDQ Tail Pointer event"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err = -1; struct config { @@ -586,21 +558,13 @@ static int lm_set_cdq(int argc, char **argv, struct command *command, struct plu OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = lm_cdq_feature_id, - .cdw11 = cfg.cdqid | - ((cfg.tpt >= 0) ? NVME_SET(1, LM_CTRL_DATA_QUEUE_ETPT) : 0), - .cdw12 = cfg.hp, - .cdw13 = cfg.tpt - }; - - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, lm_cdq_feature_id, 0, cfg.cdqid | + ((cfg.tpt >= 0) ? NVME_SET(1, LM_CTRL_DATA_QUEUE_ETPT) : 0), + cfg.hp, cfg.tpt, 0, 0, NULL, 0, NULL); if (err < 0) nvme_show_error("ERROR: nvme_set_features() failed %s", nvme_strerror(errno)); else if (err) @@ -611,13 +575,14 @@ static int lm_set_cdq(int argc, char **argv, struct command *command, struct plu return err; } -static int lm_get_cdq(int argc, char **argv, struct command *command, struct plugin *plugin) +static int lm_get_cdq(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "This Feature allows a host to retrieve the status of the head pointer " "of a CDQ and specify the configuration of a CDQ Tail event."; const char *cdqid = "Controller Data Queue ID"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; int err = -1; @@ -637,7 +602,7 @@ static int lm_get_cdq(int argc, char **argv, struct command *command, struct plu OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -649,16 +614,8 @@ static int lm_get_cdq(int argc, char **argv, struct command *command, struct plu struct nvme_lm_ctrl_data_queue_fid_data data; - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = lm_cdq_feature_id, - .cdw11 = cfg.cdqid, - .data = &data, - .data_len = sizeof(data) - }; - - err = nvme_get_features(&args); + err = nvme_get_features(hdl, 0, lm_cdq_feature_id, 0, cfg.cdqid, 0, + &data, sizeof(data), NULL); if (err < 0) nvme_show_error("ERROR: nvme_get_features() failed %s", nvme_strerror(errno)); else if (err) diff --git a/plugins/mangoboost/mangoboost-nvme.c b/plugins/mangoboost/mangoboost-nvme.c index 2f810c921f..8d64386208 100644 --- a/plugins/mangoboost/mangoboost-nvme.c +++ b/plugins/mangoboost/mangoboost-nvme.c @@ -52,8 +52,8 @@ static void mangoboost_id_ctrl(__u8 *vs, struct json_object *root) printf("json_rpc_2_0_ver : %s\n", json_rpc_2_0_ver); } -static int id_ctrl(int argc, char **argv, struct command *cmd, +static int id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return __id_ctrl(argc, argv, cmd, plugin, mangoboost_id_ctrl); + return __id_ctrl(argc, argv, acmd, plugin, mangoboost_id_ctrl); } diff --git a/plugins/memblaze/memblaze-nvme.c b/plugins/memblaze/memblaze-nvme.c index 6f55601caa..9509797386 100644 --- a/plugins/memblaze/memblaze-nvme.c +++ b/plugins/memblaze/memblaze-nvme.c @@ -107,8 +107,8 @@ static __u64 raw_2_u64(const __u8 *buf, size_t len) return le64_to_cpu(val); } -static void get_memblaze_new_smart_info(struct nvme_p4_smart_log *smart, int index, __u8 *nm_val, - __u8 *raw_val) +static void get_memblaze_new_smart_info(struct nvme_p4_smart_log *smart, + int index, __u8 *nm_val, __u8 *raw_val) { memcpy(nm_val, smart->itemArr[index].nmVal, NM_SIZE); memcpy(raw_val, smart->itemArr[index].rawVal, RAW_SIZE); @@ -352,14 +352,14 @@ static void show_memblaze_smart_log_old(struct nvme_memblaze_smart_log *smart, } } -static int show_memblaze_smart_log(int fd, __u32 nsid, const char *devname, - struct nvme_memblaze_smart_log *smart) +static int show_memblaze_smart_log(struct nvme_transport_handle *hdl, __u32 nsid, + const char *devname, struct nvme_memblaze_smart_log *smart) { struct nvme_id_ctrl ctrl; char fw_ver[10]; int err = 0; - err = nvme_identify_ctrl(fd, &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) return err; @@ -412,7 +412,7 @@ int parse_params(char *str, int number, ...) return 0; } -static int mb_get_additional_smart_log(int argc, char **argv, struct command *cmd, +static int mb_get_additional_smart_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { struct nvme_memblaze_smart_log smart_log; @@ -420,7 +420,8 @@ static int mb_get_additional_smart_log(int argc, char **argv, struct command *cm "Get Memblaze vendor specific additional smart log, and show it."; const char *namespace = "(optional) desired namespace"; const char *raw = "dump output in binary format"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct config { __u32 namespace_id; bool raw_binary; @@ -437,15 +438,16 @@ static int mb_get_additional_smart_log(int argc, char **argv, struct command *cm OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = nvme_get_nsid_log(dev_fd(dev), false, 0xca, cfg.namespace_id, - sizeof(smart_log), &smart_log); + err = nvme_get_nsid_log(hdl, cfg.namespace_id, false, 0xca, + &smart_log, sizeof(smart_log)); if (!err) { if (!cfg.raw_binary) - err = show_memblaze_smart_log(dev_fd(dev), cfg.namespace_id, dev->name, + err = show_memblaze_smart_log(hdl, cfg.namespace_id, + nvme_transport_handle_get_name(hdl), &smart_log); else d_raw((unsigned char *)&smart_log, sizeof(smart_log)); @@ -470,37 +472,25 @@ static char *mb_feature_to_string(int feature) } } -static int mb_get_powermanager_status(int argc, char **argv, struct command *cmd, +static int mb_get_powermanager_status(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Memblaze power management ststus\n (value 0 - 25w, 1 - 20w, 2 - 15w)"; __u32 result; __u32 feature_id = MB_FEAT_POWER_MGMT; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; OPT_ARGS(opts) = { OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = feature_id, - .nsid = 0, - .sel = 0, - .cdw11 = 0, - .uuidx = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_get_features(&args); + err = nvme_get_features(hdl, 0, feature_id, 0, 0, 0, NULL, 0, &result); if (err < 0) perror("get-feature"); if (!err) @@ -511,13 +501,14 @@ static int mb_get_powermanager_status(int argc, char **argv, struct command *cmd return err; } -static int mb_set_powermanager_status(int argc, char **argv, struct command *cmd, +static int mb_set_powermanager_status(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Set Memblaze power management status\n (value 0 - 25w, 1 - 20w, 2 - 15w)"; const char *value = "new value of feature (required)"; const char *save = "specifies that the controller shall save the attribute"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 result; int err; @@ -539,26 +530,12 @@ static int mb_set_powermanager_status(int argc, char **argv, struct command *cmd OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = cfg.feature_id, - .nsid = 0, - .cdw11 = cfg.value, - .cdw12 = 0, - .save = cfg.save, - .uuidx = 0, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, cfg.feature_id, cfg.save, cfg.value, 0, 0, 0, + 0, NULL, 0, &result); if (err < 0) perror("set-feature"); if (!err) @@ -573,7 +550,7 @@ static int mb_set_powermanager_status(int argc, char **argv, struct command *cmd #define P2MIN (1) #define P2MAX (5000) #define MB_FEAT_HIGH_LATENCY_VALUE_SHIFT (15) -static int mb_set_high_latency_log(int argc, char **argv, struct command *cmd, +static int mb_set_high_latency_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Set Memblaze high latency log\n" @@ -582,7 +559,9 @@ static int mb_set_high_latency_log(int argc, char **argv, struct command *cmd, " p2 value: 1 .. 5000 ms"; const char *param = "input parameters"; int param1 = 0, param2 = 0; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + __u32 result; int err; @@ -603,7 +582,7 @@ static int mb_set_high_latency_log(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -617,22 +596,8 @@ static int mb_set_high_latency_log(int argc, char **argv, struct command *cmd, } cfg.value = (param1 << MB_FEAT_HIGH_LATENCY_VALUE_SHIFT) | param2; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = cfg.feature_id, - .nsid = 0, - .cdw11 = cfg.value, - .cdw12 = 0, - .save = false, - .uuidx = 0, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, cfg.feature_id, false, cfg.value, 0, 0, 0, + 0, NULL, 0, &result); if (err < 0) perror("set-feature"); if (!err) @@ -731,12 +696,14 @@ static int glp_high_latency(FILE *fdi, char *buf, int buflen, int print) return 1; } -static int mb_high_latency_log_print(int argc, char **argv, struct command *cmd, +static int mb_high_latency_log_print(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Memblaze high latency log"; char buf[LOG_PAGE_SIZE]; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + FILE *fdi = NULL; int err; @@ -744,20 +711,20 @@ static int mb_high_latency_log_print(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; fdi = fopen(FID_C3_LOG_FILENAME, "w+"); glp_high_latency_show_bar(fdi, DO_PRINT_FLAG); - err = nvme_get_log_simple(dev_fd(dev), GLP_ID_VU_GET_HIGH_LATENCY_LOG, sizeof(buf), &buf); + err = nvme_get_log_simple(hdl, GLP_ID_VU_GET_HIGH_LATENCY_LOG, &buf, sizeof(buf)); while (1) { if (!glp_high_latency(fdi, buf, LOG_PAGE_SIZE, DO_PRINT_FLAG)) break; - err = nvme_get_log_simple(dev_fd(dev), GLP_ID_VU_GET_HIGH_LATENCY_LOG, sizeof(buf), - &buf); + err = nvme_get_log_simple(hdl, GLP_ID_VU_GET_HIGH_LATENCY_LOG, + &buf, sizeof(buf)); if (err) { nvme_show_status(err); break; @@ -769,7 +736,7 @@ static int mb_high_latency_log_print(int argc, char **argv, struct command *cmd, return err; } -static int memblaze_fw_commit(int fd, int select) +static int memblaze_fw_commit(struct nvme_transport_handle *hdl, int select) { struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_fw_commit, @@ -777,10 +744,10 @@ static int memblaze_fw_commit(int fd, int select) .cdw12 = select, }; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + return nvme_submit_admin_passthru(hdl, &cmd, NULL); } -static int mb_selective_download(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int mb_selective_download(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "This performs a selective firmware download, which allows the user to\n" @@ -791,11 +758,15 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str "ALL - This updates the eeprom, OOB, and main firmware"; const char *fw = "firmware file (required)"; const char *select = "FW Select (e.g., --select=OOB, EEP, ALL)"; - int xfer = 4096; - void *fw_buf; + + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + int selectNo, fw_fd, fw_size, err, offset = 0; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + struct nvme_passthru_cmd cmd; + int xfer = 4096; struct stat sb; + void *fw_buf; int i; struct config { @@ -814,7 +785,7 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -874,16 +845,12 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str while (fw_size > 0) { xfer = min(xfer, fw_size); - struct nvme_fw_download_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .offset = offset, - .data_len = xfer, - .data = fw_buf, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - err = nvme_fw_download(&args); + err = nvme_init_fw_download(&cmd, fw_buf, xfer, offset); + if (err) { + perror("fw-download"); + goto out_free; + } + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (err < 0) { perror("fw-download"); goto out_free; @@ -896,7 +863,7 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str offset += xfer; } - err = memblaze_fw_commit(dev_fd(dev), selectNo); + err = memblaze_fw_commit(hdl, selectNo); if (err == 0x10B || err == 0x20B) { err = 0; @@ -996,12 +963,14 @@ int io_latency_histogram(char *file, char *buf, int print, int logid) return 1; } -static int mb_lat_stats_log_print(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int mb_lat_stats_log_print(int argc, char **argv, struct command *acmd, struct plugin *plugin) { char stats[LOG_PAGE_SIZE]; char f1[] = FID_C1_LOG_FILENAME; char f2[] = FID_C2_LOG_FILENAME; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + int err; const char *desc = "Get Latency Statistics log and show it."; @@ -1019,11 +988,11 @@ static int mb_lat_stats_log_print(int argc, char **argv, struct command *cmd, st OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = nvme_get_log_simple(dev_fd(dev), cfg.write ? 0xc2 : 0xc1, sizeof(stats), &stats); + err = nvme_get_log_simple(hdl, cfg.write ? 0xc2 : 0xc1, &stats, sizeof(stats)); if (!err) io_latency_histogram(cfg.write ? f2 : f1, stats, DO_PRINT_FLAG, cfg.write ? GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM : @@ -1034,11 +1003,13 @@ static int mb_lat_stats_log_print(int argc, char **argv, struct command *cmd, st return err; } -static int memblaze_clear_error_log(int argc, char **argv, struct command *cmd, +static int memblaze_clear_error_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { char *desc = "Clear Memblaze devices error log."; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + int err; __u32 result; @@ -1059,26 +1030,12 @@ static int memblaze_clear_error_log(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = cfg.feature_id, - .nsid = 0, - .cdw11 = cfg.value, - .cdw12 = 0, - .save = cfg.save, - .uuidx = 0, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, cfg.feature_id, cfg.save, cfg.value, 0, 0, 0, + 0, NULL, 0, &result); if (err < 0) perror("set-feature"); if (!err) @@ -1090,7 +1047,7 @@ static int memblaze_clear_error_log(int argc, char **argv, struct command *cmd, return err; } -static int mb_set_lat_stats(int argc, char **argv, struct command *command, struct plugin *plugin) +static int mb_set_lat_stats(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = ( "Enable/Disable Latency Statistics Tracking.\n" @@ -1104,7 +1061,9 @@ static int mb_set_lat_stats(int argc, char **argv, struct command *command, stru const __u32 cdw12 = 0x0; const __u32 data_len = 32; const __u32 save = 0; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + void *buf = NULL; __u32 result; int err; @@ -1118,13 +1077,13 @@ static int mb_set_lat_stats(int argc, char **argv, struct command *command, stru .disable = false, }; - struct argconfig_commandline_options command_line_options[] = { + struct argconfig_commandline_options opts[] = { {"enable", 'e', "", CFG_FLAG, &cfg.enable, no_argument, enable_desc}, {"disable", 'd', "", CFG_FLAG, &cfg.disable, no_argument, disable_desc}, {NULL} }; - err = parse_and_open(&dev, argc, argv, desc, command_line_options); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); enum Option { None = -1, @@ -1138,41 +1097,12 @@ static int mb_set_lat_stats(int argc, char **argv, struct command *command, stru else if (cfg.enable || cfg.disable) option = cfg.enable; - struct nvme_get_features_args args_get = { - .args_size = sizeof(args_get), - .fd = dev_fd(dev), - .fid = fid, - .nsid = nsid, - .sel = sel, - .cdw11 = cdw11, - .uuidx = 0, - .data_len = data_len, - .data = buf, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - struct nvme_set_features_args args_set = { - .args_size = sizeof(args_set), - .fd = dev_fd(dev), - .fid = fid, - .nsid = nsid, - .cdw11 = option, - .cdw12 = cdw12, - .save = save, - .uuidx = 0, - .cdw15 = 0, - .data_len = data_len, - .data = buf, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - if (err) return err; switch (option) { case None: - err = nvme_get_features(&args_get); + err = nvme_get_features(hdl, nsid, fid, sel, cdw11, 0, buf, data_len, + &result); if (!err) { printf("Latency Statistics Tracking (FID 0x%X) is currently (%i).\n", fid, result); @@ -1183,7 +1113,8 @@ static int mb_set_lat_stats(int argc, char **argv, struct command *command, stru break; case True: case False: - err = nvme_set_features(&args_set); + err = nvme_set_features(hdl, nsid, fid, save, option, cdw12, 0, 0, + 0, buf, data_len, &result); if (err > 0) { nvme_show_status(err); } else if (err < 0) { @@ -1590,7 +1521,7 @@ static void smart_log_add_print(struct smart_log_add *log, const char *devname) } } -static int mb_get_smart_log_add(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int mb_get_smart_log_add(int argc, char **argv, struct command *acmd, struct plugin *plugin) { int err = 0; @@ -1606,9 +1537,11 @@ static int mb_get_smart_log_add(int argc, char **argv, struct command *cmd, stru OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, "dump the whole log buffer in binary format"), OPT_END()}; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; - err = parse_and_open(&dev, argc, argv, cmd->help, opts); + + err = parse_and_open(&ctx, &hdl, argc, argv, acmd->help, opts); if (err) return err; @@ -1616,17 +1549,16 @@ static int mb_get_smart_log_add(int argc, char **argv, struct command *cmd, stru struct smart_log_add log = {0}; - err = nvme_get_log_simple(dev_fd(dev), LID_SMART_LOG_ADD, sizeof(struct smart_log_add), - &log); + err = nvme_get_log_simple(hdl, LID_SMART_LOG_ADD, &log, sizeof(struct smart_log_add)); if (!err) { if (!cfg.raw_binary) - smart_log_add_print(&log, dev->name); + smart_log_add_print(&log, nvme_transport_handle_get_name(hdl)); else d_raw((unsigned char *)&log, sizeof(struct smart_log_add)); } else if (err > 0) { nvme_show_status(err); } else { - nvme_show_error("%s: %s", cmd->name, nvme_strerror(errno)); + nvme_show_error("%s: %s", acmd->name, nvme_strerror(errno)); } return err; @@ -1732,7 +1664,7 @@ struct __packed performance_stats { }; }; -static int mb_set_latency_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int mb_set_latency_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { int err = 0; @@ -1767,9 +1699,11 @@ static int mb_set_latency_feature(int argc, char **argv, struct command *cmd, st "set trim high latency log threshold, it's a 0-based value and unit is 10ms"), OPT_END()}; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + - err = parse_and_open(&dev, argc, argv, cmd->help, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, acmd->help, opts); if (err) return err; @@ -1778,38 +1712,23 @@ static int mb_set_latency_feature(int argc, char **argv, struct command *cmd, st uint32_t result = 0; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = FID_LATENCY_FEATURE, - .nsid = 0, - .cdw11 = 0 | cfg.perf_monitor, - .cdw12 = 0 | cfg.cmd_mask, - .cdw13 = 0 | - (cfg.read_threshold & 0xff) | - ((cfg.write_threshold & 0xff) << 8) | - ((cfg.de_allocate_trim_threshold & 0xff) << 16), - .cdw15 = 0, - .save = 0, - .uuidx = 0, - .data = NULL, - .data_len = 0, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, FID_LATENCY_FEATURE, 0, 0 | cfg.perf_monitor, + 0 | cfg.cmd_mask, + 0 | (cfg.read_threshold & 0xff) | + ((cfg.write_threshold & 0xff) << 8) | + ((cfg.de_allocate_trim_threshold & 0xff) << 16), + 0, 0, NULL, 0, &result); if (!err) - printf("%s have done successfully. result = %#" PRIx32 ".\n", cmd->name, result); + printf("%s have done successfully. result = %#" PRIx32 ".\n", acmd->name, result); else if (err > 0) nvme_show_status(err); else - nvme_show_error("%s: %s", cmd->name, nvme_strerror(errno)); + nvme_show_error("%s: %s", acmd->name, nvme_strerror(errno)); return err; } -static int mb_get_latency_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int mb_get_latency_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { int err = 0; @@ -1818,9 +1737,10 @@ static int mb_get_latency_feature(int argc, char **argv, struct command *cmd, st OPT_ARGS(opts) = { OPT_END()}; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; - err = parse_and_open(&dev, argc, argv, cmd->help, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, acmd->help, opts); if (err) return err; @@ -1828,9 +1748,10 @@ static int mb_get_latency_feature(int argc, char **argv, struct command *cmd, st uint32_t result = 0; - err = nvme_get_features_simple(dev_fd(dev), FID_LATENCY_FEATURE, 0, &result); + err = nvme_get_features_simple(hdl, FID_LATENCY_FEATURE, + NVME_GET_FEATURES_SEL_CURRENT, &result); if (!err) { - printf("%s have done successfully. result = %#" PRIx32 ".\n", cmd->name, result); + printf("%s have done successfully. result = %#" PRIx32 ".\n", acmd->name, result); printf("latency statistics enable status = %d\n", (result & (0x01 << 0)) >> 0); printf("high latency enable status = %d\n", (result & (0x01 << 1)) >> 1); @@ -1846,7 +1767,7 @@ static int mb_get_latency_feature(int argc, char **argv, struct command *cmd, st } else if (err > 0) { nvme_show_status(err); } else { - nvme_show_error("%s: %s", cmd->name, nvme_strerror(errno)); + nvme_show_error("%s: %s", acmd->name, nvme_strerror(errno)); } return err; @@ -1952,7 +1873,7 @@ static void latency_stats_print(struct latency_stats *log, const char *devname) } } -static int mb_get_latency_stats(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int mb_get_latency_stats(int argc, char **argv, struct command *acmd, struct plugin *plugin) { // Get the configuration @@ -1969,9 +1890,10 @@ static int mb_get_latency_stats(int argc, char **argv, struct command *cmd, stru "dump the whole log buffer in binary format"), OPT_END()}; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; - int err = parse_and_open(&dev, argc, argv, cmd->help, opts); + int err = parse_and_open(&ctx, &hdl, argc, argv, acmd->help, opts); if (err) return err; @@ -1980,17 +1902,16 @@ static int mb_get_latency_stats(int argc, char **argv, struct command *cmd, stru struct latency_stats log = {0}; - err = nvme_get_log_simple(dev_fd(dev), LID_LATENCY_STATISTICS, sizeof(struct latency_stats), - &log); + err = nvme_get_log_simple(hdl, LID_LATENCY_STATISTICS, &log, sizeof(struct latency_stats)); if (!err) { if (!cfg.raw_binary) - latency_stats_print(&log, dev->name); + latency_stats_print(&log, nvme_transport_handle_get_name(hdl)); else d_raw((unsigned char *)&log, sizeof(struct latency_stats)); } else if (err > 0) { nvme_show_status(err); } else { - nvme_show_error("%s: %s", cmd->name, nvme_strerror(errno)); + nvme_show_error("%s: %s", acmd->name, nvme_strerror(errno)); } return err; @@ -2057,7 +1978,7 @@ static void high_latency_log_print(struct high_latency_log *log, const char *dev } } -static int mb_get_high_latency_log(int argc, char **argv, struct command *cmd, +static int mb_get_high_latency_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { // Get the configuration @@ -2075,10 +1996,10 @@ static int mb_get_high_latency_log(int argc, char **argv, struct command *cmd, "dump the whole log buffer in binary format"), OPT_END()}; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - - int err = parse_and_open(&dev, argc, argv, cmd->help, opts); + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + int err = parse_and_open(&ctx, &hdl, argc, argv, acmd->help, opts); if (err) return err; @@ -2086,17 +2007,17 @@ static int mb_get_high_latency_log(int argc, char **argv, struct command *cmd, struct high_latency_log log = {0}; - err = nvme_get_log_simple(dev_fd(dev), LID_HIGH_LATENCY_LOG, - sizeof(struct high_latency_log), &log); + err = nvme_get_log_simple(hdl, LID_HIGH_LATENCY_LOG, + &log, sizeof(struct high_latency_log)); if (!err) { if (!cfg.raw_binary) - high_latency_log_print(&log, dev->name); + high_latency_log_print(&log, nvme_transport_handle_get_name(hdl)); else d_raw((unsigned char *)&log, sizeof(struct high_latency_log)); } else if (err > 0) { nvme_show_status(err); } else { - nvme_show_error("%s: %s", cmd->name, nvme_strerror(errno)); + nvme_show_error("%s: %s", acmd->name, nvme_strerror(errno)); } return err; @@ -2299,7 +2220,7 @@ static void performance_stats_print(struct performance_stats *log, const char *d } } -static int mb_get_performance_stats(int argc, char **argv, struct command *cmd, +static int mb_get_performance_stats(int argc, char **argv, struct command *acmd, struct plugin *plugin) { // Get the configuration @@ -2322,9 +2243,10 @@ static int mb_get_performance_stats(int argc, char **argv, struct command *cmd, "dump the whole log buffer in binary format"), OPT_END()}; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; - int err = parse_and_open(&dev, argc, argv, cmd->help, opts); + int err = parse_and_open(&ctx, &hdl, argc, argv, acmd->help, opts); if (err) return err; @@ -2344,16 +2266,16 @@ static int mb_get_performance_stats(int argc, char **argv, struct command *cmd, int xfer_size = (cfg.duration % 2) > 0 ? (4 + (cfg.duration + 1) * sizeof(struct performance_stats_timestamp)) : log_size; - err = nvme_get_log_simple(dev_fd(dev), LID_PERFORMANCE_STATISTICS, xfer_size, &log); + err = nvme_get_log_simple(hdl, LID_PERFORMANCE_STATISTICS, &log, xfer_size); if (!err) { if (!cfg.raw_binary) - performance_stats_print(&log, dev->name, cfg.duration); + performance_stats_print(&log, nvme_transport_handle_get_name(hdl), cfg.duration); else d_raw((unsigned char *)&log, log_size); } else if (err > 0) { nvme_show_status(err); } else { - nvme_show_error("%s: %s", cmd->name, nvme_strerror(errno)); + nvme_show_error("%s: %s", acmd->name, nvme_strerror(errno)); } return err; diff --git a/plugins/micron/micron-nvme.c b/plugins/micron/micron-nvme.c index 13df5ac93a..1bb100dd7f 100644 --- a/plugins/micron/micron-nvme.c +++ b/plugins/micron/micron-nvme.c @@ -389,14 +389,14 @@ static int SetupDebugDataDirectories(char *strSN, char *strFilePath, return err; } -static int GetLogPageSize(int nFD, unsigned char ucLogID, int *nLogSize) +static int GetLogPageSize(struct nvme_transport_handle *hdl, unsigned char ucLogID, int *nLogSize) { int err = 0; unsigned char pTmpBuf[CommonChunkSize] = { 0 }; struct LogPageHeader_t *pLogHeader = NULL; if (ucLogID == 0xC1 || ucLogID == 0xC2 || ucLogID == 0xC4) { - err = nvme_get_log_simple(nFD, ucLogID, CommonChunkSize, pTmpBuf); + err = nvme_get_log_simple(hdl, ucLogID, pTmpBuf, CommonChunkSize); if (!err) { pLogHeader = (struct LogPageHeader_t *) pTmpBuf; struct LogPageHeader_t *pLogHeader1 = (struct LogPageHeader_t *) pLogHeader; @@ -416,8 +416,8 @@ static int GetLogPageSize(int nFD, unsigned char ucLogID, int *nLogSize) return err; } -static int NVMEGetLogPage(int nFD, unsigned char ucLogID, unsigned char *pBuffer, int nBuffSize, - int offset) +static int NVMEGetLogPage(struct nvme_transport_handle *hdl, unsigned char ucLogID, unsigned char *pBuffer, int nBuffSize, + int offset) { int err = 0; struct nvme_passthru_cmd cmd = { 0 }; @@ -468,7 +468,7 @@ static int NVMEGetLogPage(int nFD, unsigned char ucLogID, unsigned char *pBuffer cmd.addr = (__u64) (uintptr_t) pTempPtr; cmd.nsid = 0xFFFFFFFF; cmd.data_len = uiXferDwords * 4; - err = nvme_submit_admin_passthru(nFD, &cmd, NULL); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); ullBytesRead += uiXferDwords * 4; if (ucLogID == 0x07 || ucLogID == 0x08 || ucLogID == 0xE9) pTempPtr = pBuffer + (ullBytesRead - offset); @@ -479,8 +479,8 @@ static int NVMEGetLogPage(int nFD, unsigned char ucLogID, unsigned char *pBuffer return err; } -static int NVMEResetLog(int nFD, unsigned char ucLogID, int nBufferSize, - long long llMaxSize) +static int NVMEResetLog(struct nvme_transport_handle *hdl, unsigned char ucLogID, int nBufferSize, + long long llMaxSize) { unsigned int *pBuffer = NULL; int err = 0; @@ -490,7 +490,7 @@ static int NVMEResetLog(int nFD, unsigned char ucLogID, int nBufferSize, return err; while (!err && llMaxSize > 0) { - err = NVMEGetLogPage(nFD, ucLogID, (unsigned char *)pBuffer, nBufferSize, 0); + err = NVMEGetLogPage(hdl, ucLogID, (unsigned char *)pBuffer, nBufferSize, 0); if (err) { free(pBuffer); return err; @@ -506,8 +506,8 @@ static int NVMEResetLog(int nFD, unsigned char ucLogID, int nBufferSize, return err; } -static int GetCommonLogPage(int nFD, unsigned char ucLogID, - unsigned char **pBuffer, int nBuffSize) +static int GetCommonLogPage(struct nvme_transport_handle *hdl, unsigned char ucLogID, + unsigned char **pBuffer, int nBuffSize) { unsigned char *pTempPtr = NULL; int err = 0; @@ -516,7 +516,7 @@ static int GetCommonLogPage(int nFD, unsigned char ucLogID, if (!pTempPtr) goto exit_status; memset(pTempPtr, 0, nBuffSize); - err = nvme_get_log_simple(nFD, ucLogID, nBuffSize, pTempPtr); + err = nvme_get_log_simple(hdl, ucLogID, pTempPtr, nBuffSize); *pBuffer = pTempPtr; exit_status: @@ -526,13 +526,14 @@ static int GetCommonLogPage(int nFD, unsigned char ucLogID, /* * Plugin Commands */ -static int micron_parse_options(struct nvme_dev **dev, int argc, char **argv, - const char *desc, +static int micron_parse_options(struct nvme_global_ctx **ctx, + struct nvme_transport_handle **hdl, int argc, + char **argv, const char *desc, struct argconfig_commandline_options *opts, enum eDriveModel *modelp) { int idx; - int err = parse_and_open(dev, argc, argv, desc, opts); + int err = parse_and_open(ctx, hdl, argc, argv, desc, opts); if (err) { perror("open"); @@ -548,18 +549,18 @@ static int micron_parse_options(struct nvme_dev **dev, int argc, char **argv, return 0; } -static int micron_fw_commit(int fd, int select) +static int micron_fw_commit(struct nvme_transport_handle *hdl, int select) { struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_fw_commit, .cdw10 = 8, .cdw12 = select, }; - return ioctl(fd, NVME_IOCTL_ADMIN_CMD, &cmd); + return ioctl(nvme_transport_handle_get_fd(hdl), NVME_IOCTL_ADMIN_CMD, &cmd); } static int micron_selective_download(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { const char *desc = "This performs a selective firmware download, which allows the user to\n" @@ -570,11 +571,15 @@ static int micron_selective_download(int argc, char **argv, "ALL - This updates the eeprom, OOB, and main firmware"; const char *fw = "firmware file (required)"; const char *select = "FW Select (e.g., --select=ALL)"; - int xfer = 4096; - void *fw_buf; + + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + int selectNo, fw_fd, fw_size, err, offset = 0; - struct nvme_dev *dev; + struct nvme_passthru_cmd cmd; + int xfer = 4096; struct stat sb; + void *fw_buf; struct config { char *fw; @@ -592,13 +597,12 @@ static int micron_selective_download(int argc, char **argv, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; if (strlen(cfg.select) != 3) { fprintf(stderr, "Invalid select flag\n"); - dev_close(dev); return -EINVAL; } @@ -613,14 +617,12 @@ static int micron_selective_download(int argc, char **argv, selectNo = 26; } else { fprintf(stderr, "Invalid select flag\n"); - dev_close(dev); return -EINVAL; } fw_fd = open(cfg.fw, O_RDONLY); if (fw_fd < 0) { fprintf(stderr, "no firmware file provided\n"); - dev_close(dev); return -EINVAL; } @@ -652,17 +654,12 @@ static int micron_selective_download(int argc, char **argv, while (fw_size > 0) { xfer = min(xfer, fw_size); - struct nvme_fw_download_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .offset = offset, - .data_len = xfer, - .data = fw_buf, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - - err = nvme_fw_download(&args); + err = nvme_init_fw_download(&cmd, fw_buf, xfer, offset); + if (err) { + perror("fw-download"); + goto out_free; + } + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (err < 0) { perror("fw-download"); goto out_free; @@ -675,7 +672,7 @@ static int micron_selective_download(int argc, char **argv, offset += xfer; } - err = micron_fw_commit(dev_fd(dev), selectNo); + err = micron_fw_commit(hdl, selectNo); if (err == 0x10B || err == 0x20B) { err = 0; @@ -687,25 +684,24 @@ static int micron_selective_download(int argc, char **argv, free(fw_buf); out: close(fw_fd); - dev_close(dev); return err; } static int micron_smbus_option(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { __u32 result = 0; __u32 cdw11 = 0; const char *desc = "Enable/Disable/Get status of SMBUS option on controller"; const char *option = "enable or disable or status"; const char *value = - "1 - hottest component temperature, 0 - composite temperature (default) for enable option, 0 (current), 1 (default), 2 (saved) for status options" - ; + "1 - hottest component temperature, 0 - composite temperature (default) for enable option, 0 (current), 1 (default), 2 (saved) for status options"; const char *save = "1 - persistent, 0 - non-persistent (default)"; int fid = MICRON_FEATURE_SMBUS_OPTION; enum eDriveModel model = UNKNOWN_MODEL; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err = 0; struct { @@ -727,40 +723,25 @@ static int micron_smbus_option(int argc, char **argv, OPT_END() }; - err = micron_parse_options(&dev, argc, argv, desc, opts, &model); + err = micron_parse_options(&ctx, &hdl, argc, argv, desc, opts, &model); if (err < 0) return err; if (model != M5407 && model != M5411 && model != M6003 && model != M6004) { printf("This option is not supported for specified drive\n"); - dev_close(dev); return err; } if (!strcmp(opt.option, "enable")) { cdw11 = opt.value << 1 | 1; - err = nvme_set_features_simple(dev_fd(dev), fid, 1, cdw11, opt.save, - &result); + err = nvme_set_features_simple(hdl, 1, fid, opt.save, cdw11, + &result); if (!err) printf("successfully enabled SMBus on drive\n"); else printf("Failed to enabled SMBus on drive\n"); } else if (!strcmp(opt.option, "status")) { - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .nsid = 1, - .sel = opt.value, - .cdw11 = 0, - .uuidx = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_get_features(&args); + err = nvme_get_features(hdl, 1, fid, opt.value, 0, 0, NULL, 0, &result); if (!err) printf("SMBus status on the drive: %s (returns %s temperature)\n", (result & 1) ? "enabled" : "disabled", @@ -769,8 +750,8 @@ static int micron_smbus_option(int argc, char **argv, printf("Failed to retrieve SMBus status on the drive\n"); } else if (!strcmp(opt.option, "disable")) { cdw11 = opt.value << 1 | 0; - err = nvme_set_features_simple(dev_fd(dev), fid, 1, cdw11, opt.save, - &result); + err = nvme_set_features_simple(hdl, 1, fid, opt.save, cdw11, + &result); if (!err) printf("Successfully disabled SMBus on drive\n"); else @@ -778,15 +759,13 @@ static int micron_smbus_option(int argc, char **argv, } else { printf("Invalid option %s, valid values are enable, disable or status\n", opt.option); - dev_close(dev); return -1; } - close(dev_fd(dev)); return err; } -static int micron_temp_stats(int argc, char **argv, struct command *cmd, +static int micron_temp_stats(int argc, char **argv, struct command *acmd, struct plugin *plugin) { @@ -804,14 +783,14 @@ static int micron_temp_stats(int argc, char **argv, struct command *cmd, bool is_json = false; struct json_object *root; struct json_object *logPages; - struct nvme_dev *dev; - + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; OPT_ARGS(opts) = { OPT_FMT("format", 'f', &cfg.fmt, fmt), OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { printf("\nDevice not found\n"); return -1; @@ -820,7 +799,7 @@ static int micron_temp_stats(int argc, char **argv, struct command *cmd, if (!strcmp(cfg.fmt, "json")) is_json = true; - err = nvme_get_log_smart(dev_fd(dev), 0xffffffff, false, &smart_log); + err = nvme_get_log_smart(hdl, NVME_NSID_ALL, &smart_log); if (!err) { temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]); temperature = temperature ? temperature - 273 : 0; @@ -856,7 +835,6 @@ static int micron_temp_stats(int argc, char **argv, struct command *cmd, printf("%-10s%d : %u C\n", "Temperature Sensor #", i + 1, tempSensors[i]); } } - dev_close(dev); return err; } @@ -922,11 +900,12 @@ struct pcie_error_counters { static int micron_pcie_stats(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { int i, err = 0, bus = 0, domain = 0, device = 0, function = 0, ctrlIdx; - char strTempFile[1024], strTempFile2[1024], command[1024]; - struct nvme_dev *dev; + char strTempFile[1024], strTempFile2[1024], cmdbuf[1024]; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; char *businfo = NULL; char *devicename = NULL; char tdevice[NAME_MAX] = { 0 }; @@ -956,7 +935,7 @@ static int micron_pcie_stats(int argc, char **argv, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { printf("\nDevice not found\n"); return -1; @@ -979,7 +958,7 @@ static int micron_pcie_stats(int argc, char **argv, admin_cmd.addr = (__u64)(uintptr_t)&pcie_error_counters; admin_cmd.data_len = sizeof(pcie_error_counters); admin_cmd.cdw10 = 1; - err = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL); + err = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (!err) { counters = true; correctable_errors = 10; @@ -1019,9 +998,9 @@ static int micron_pcie_stats(int argc, char **argv, businfo = strrchr(strTempFile2, '/'); if (sscanf(businfo, "/%x:%x:%x.%x", &domain, &bus, &device, &function) != 4) domain = bus = device = function = 0; - sprintf(command, "setpci -s %x:%x.%x ECAP_AER+10.L", bus, device, + sprintf(cmdbuf, "setpci -s %x:%x.%x ECAP_AER+10.L", bus, device, function); - fp = popen(command, "r"); + fp = popen(cmdbuf, "r"); if (!fp) { printf("Failed to retrieve error count\n"); goto out; @@ -1034,9 +1013,9 @@ static int micron_pcie_stats(int argc, char **argv, } pclose(fp); - sprintf(command, "setpci -s %x:%x.%x ECAP_AER+0x4.L", bus, device, + sprintf(cmdbuf, "setpci -s %x:%x.%x ECAP_AER+0x4.L", bus, device, function); - fp = popen(command, "r"); + fp = popen(cmdbuf, "r"); if (!fp) { printf("Failed to retrieve error count\n"); goto out; @@ -1100,17 +1079,17 @@ static int micron_pcie_stats(int argc, char **argv, } out: - dev_close(dev); return err; } static int micron_clear_pcie_correctable_errors(int argc, char **argv, - struct command *cmd, + struct command *command, struct plugin *plugin) { int err = -EINVAL, bus, domain, device, function; - char strTempFile[1024], strTempFile2[1024], command[1024]; - struct nvme_dev *dev; + char strTempFile[1024], strTempFile2[1024], cmdbuf[1024]; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; char *businfo = NULL; char *devicename = NULL; char tdevice[PATH_MAX] = { 0 }; @@ -1128,7 +1107,7 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv, OPT_END() }; - err = micron_parse_options(&dev, argc, argv, desc, opts, &model); + err = micron_parse_options(&ctx, &hdl, argc, argv, desc, opts, &model); if (err < 0) return err; @@ -1137,8 +1116,8 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv, * If these fail, proceed with sysfs interface to set/clear bits */ if (model == M51CX || model == M51BY || model == M51CY) { - err = nvme_set_features_simple(dev_fd(dev), fid, 0, (1 << 31), false, - &result); + err = nvme_set_features_simple(hdl, 0, fid, false, (1 << 31), + &result); if (!err) err = (int)result; if (!err) { @@ -1149,7 +1128,7 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv, admin_cmd.opcode = 0xD6; admin_cmd.addr = 0; admin_cmd.cdw10 = 0; - err = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL); + err = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (!err) { printf("Device correctable error counters are cleared!\n"); goto out; @@ -1196,19 +1175,19 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv, businfo = strrchr(strTempFile2, '/'); if (sscanf(businfo, "/%x:%x:%x.%x", &domain, &bus, &device, &function) != 4) domain = bus = device = function = 0; - sprintf(command, "setpci -s %x:%x.%x ECAP_AER+0x10.L=0xffffffff", bus, + sprintf(cmdbuf, "setpci -s %x:%x.%x ECAP_AER+0x10.L=0xffffffff", bus, device, function); err = -1; - fp = popen(command, "r"); + fp = popen(cmdbuf, "r"); if (!fp) { printf("Failed to clear error count\n"); goto out; } pclose(fp); - sprintf(command, "setpci -s %x:%x.%x ECAP_AER+0x10.L", bus, device, + sprintf(cmdbuf, "setpci -s %x:%x.%x ECAP_AER+0x10.L", bus, device, function); - fp = popen(command, "r"); + fp = popen(cmdbuf, "r"); if (!fp) { printf("Failed to retrieve error count\n"); goto out; @@ -1224,7 +1203,6 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv, printf("Device correctable errors detected: %s\n", correctable); err = 0; out: - dev_close(dev); return err; } @@ -1815,7 +1793,7 @@ static void print_hyperscale_nand_stats(__u8 *buf, bool is_json) static bool nsze_from_oacs;/* read nsze for now from idd[4059] */ static int micron_nand_stats(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { const char *desc = "Retrieve Micron NAND stats for the given device "; unsigned int extSmartLog[D0_log_size/sizeof(int)] = { 0 }; @@ -1823,7 +1801,8 @@ static int micron_nand_stats(int argc, char **argv, unsigned char logC0[C0_log_size] = { 0 }; enum eDriveModel eModel = UNKNOWN_MODEL; struct nvme_id_ctrl ctrl; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err, ctrlIdx; __u8 nsze; bool has_d0_log = true; @@ -1843,7 +1822,7 @@ static int micron_nand_stats(int argc, char **argv, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { printf("\nDevice not found\n"); return -1; @@ -1852,7 +1831,7 @@ static int micron_nand_stats(int argc, char **argv, if (!strcmp(cfg.fmt, "normal")) is_json = false; - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) { printf("Error %d retrieving controller identification data\n", err); goto out; @@ -1868,14 +1847,14 @@ static int micron_nand_stats(int argc, char **argv, goto out; } - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) { fprintf(stderr, "ERROR : identify_ctrl() failed with 0x%x\n", err); return -1; } if ((ctrl.vs[536] == MICRON_CUST_ID_GG) && (eModel == M51CX)) { - err = nvme_get_log_simple(dev_fd(dev), 0xC0, C0_log_size, logC0); + err = nvme_get_log_simple(hdl, 0xC0, logC0, C0_log_size); if (err == 0) { print_hyperscale_nand_stats((__u8 *)logC0, is_json); goto out; @@ -1885,12 +1864,12 @@ static int micron_nand_stats(int argc, char **argv, } } - err = nvme_get_log_simple(dev_fd(dev), 0xD0, D0_log_size, extSmartLog); + err = nvme_get_log_simple(hdl, 0xD0, extSmartLog, D0_log_size); has_d0_log = (err == 0); /* should check for firmware version if this log is supported or not */ if (eModel != M5407 && eModel != M5410) { - err = nvme_get_log_simple(dev_fd(dev), 0xFB, FB_log_size, logFB); + err = nvme_get_log_simple(hdl, 0xFB, logFB, FB_log_size); has_fb_log = !err; } @@ -1910,7 +1889,6 @@ static int micron_nand_stats(int argc, char **argv, err = -ENOTTY; } out: - dev_close(dev); if (err > 0) nvme_show_status(err); @@ -1967,14 +1945,15 @@ static void print_log(__u8 *buf, bool is_json, unsigned char ucLogID) } static int micron_smart_ext_log(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { const char *desc = "Retrieve extended SMART logs for the given device "; unsigned int extSmartLog[E1_log_size/sizeof(int)] = { 0 }; enum eDriveModel eModel = UNKNOWN_MODEL; int err = 0, ctrlIdx = 0; __u8 log_id; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; bool is_json = true; struct format { char *fmt; @@ -1988,7 +1967,7 @@ static int micron_smart_ext_log(int argc, char **argv, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { printf("\nDevice not found\n"); return -1; @@ -2009,23 +1988,24 @@ static int micron_smart_ext_log(int argc, char **argv, err = -1; goto out; } - err = nvme_get_log_simple(dev_fd(dev), log_id, E1_log_size, extSmartLog); + err = nvme_get_log_simple(hdl, log_id, extSmartLog, E1_log_size); if (!err) print_log((__u8 *)extSmartLog, is_json, log_id); out: - dev_close(dev); if (err > 0) nvme_show_status(err); return err; } -static int micron_work_load_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int micron_work_load_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Micron Workload logs for the given device "; unsigned int micronWorkLoadLog[C5_MicronWorkLoad_log_size/sizeof(int)] = { 0 }; enum eDriveModel eModel = UNKNOWN_MODEL; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + int err = 0, ctrlIdx = 0; bool is_json = true; struct format { @@ -2040,7 +2020,7 @@ static int micron_work_load_log(int argc, char **argv, struct command *cmd, stru OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { printf("\nDevice not found\n"); return -1; @@ -2053,8 +2033,8 @@ static int micron_work_load_log(int argc, char **argv, struct command *cmd, stru ctrlIdx = 0; eModel = GetDriveModel(ctrlIdx); if (eModel == M6001 || eModel == M6004 || eModel == M6003) { - err = nvme_get_log_simple(dev_fd(dev), 0xC5, - C5_MicronWorkLoad_log_size, micronWorkLoadLog); + err = nvme_get_log_simple(hdl, 0xC5, + micronWorkLoadLog, C5_MicronWorkLoad_log_size); if (!err) print_log((__u8 *)micronWorkLoadLog, is_json, 0xC5); } else { @@ -2064,21 +2044,22 @@ static int micron_work_load_log(int argc, char **argv, struct command *cmd, stru } out: - dev_close(dev); if (err > 0) nvme_show_status(err); return err; } static int micron_vendor_telemetry_log(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { const char *desc = "Retrieve Vendor Telemetry logs for the given device "; unsigned int vendorTelemetryLog[C6_log_size/sizeof(int)] = { 0 }; enum eDriveModel eModel = UNKNOWN_MODEL; int err = 0, ctrlIdx = 0; bool is_json = true; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct format { char *fmt; }; @@ -2091,7 +2072,7 @@ static int micron_vendor_telemetry_log(int argc, char **argv, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { printf("\nDevice not found\n"); return -1; @@ -2105,7 +2086,7 @@ static int micron_vendor_telemetry_log(int argc, char **argv, eModel = GetDriveModel(ctrlIdx); if (eModel == M6001 || eModel == M6004 || eModel == M6003) { - err = nvme_get_log_simple(dev_fd(dev), 0xC6, C6_log_size, vendorTelemetryLog); + err = nvme_get_log_simple(hdl, 0xC6, vendorTelemetryLog, C6_log_size); if (!err) print_log((__u8 *)vendorTelemetryLog, is_json, 0xC6); } else { @@ -2115,7 +2096,6 @@ static int micron_vendor_telemetry_log(int argc, char **argv, } out: - dev_close(dev); if (err > 0) nvme_show_status(err); return err; @@ -2201,16 +2181,16 @@ static void GetCtrlIDDInfo(const char *dir, struct nvme_id_ctrl *ctrlp) "nvme_controller_identify_data.bin", "id-ctrl"); } -static void GetSmartlogData(int fd, const char *dir) +static void GetSmartlogData(struct nvme_transport_handle *hdl, const char *dir) { struct nvme_smart_log smart_log; - if (!nvme_get_log_smart(fd, -1, false, &smart_log)) + if (!nvme_get_log_smart(hdl, NVME_NSID_ALL, &smart_log)) WriteData((__u8 *)&smart_log, sizeof(smart_log), dir, "smart_data.bin", "smart log"); } -static void GetErrorlogData(int fd, int entries, const char *dir) +static void GetErrorlogData(struct nvme_transport_handle *hdl, int entries, const char *dir) { int logSize = entries * sizeof(struct nvme_error_log_page); struct nvme_error_log_page *error_log = @@ -2219,14 +2199,14 @@ static void GetErrorlogData(int fd, int entries, const char *dir) if (!error_log) return; - if (!nvme_get_log_error(fd, entries, false, error_log)) + if (!nvme_get_log_error(hdl, NVME_NSID_ALL, entries, error_log)) WriteData((__u8 *)error_log, logSize, dir, "error_information_log.bin", "error log"); free(error_log); } -static void GetGenericLogs(int fd, const char *dir) +static void GetGenericLogs(struct nvme_transport_handle *hdl, const char *dir) { struct nvme_self_test_log self_test_log; struct nvme_firmware_slot fw_log; @@ -2238,26 +2218,26 @@ static void GetGenericLogs(int fd, const char *dir) int err = 0; /* get self test log */ - if (!nvme_get_log_device_self_test(fd, &self_test_log)) + if (!nvme_get_log_device_self_test(hdl, &self_test_log)) WriteData((__u8 *)&self_test_log, sizeof(self_test_log), dir, "drive_self_test.bin", "self test log"); /* get fw slot info log */ - if (!nvme_get_log_fw_slot(fd, false, &fw_log)) + if (!nvme_get_log_fw_slot(hdl, false, &fw_log)) WriteData((__u8 *)&fw_log, sizeof(fw_log), dir, "firmware_slot_info_log.bin", "firmware log"); /* get effects log */ - if (!nvme_get_log_cmd_effects(fd, NVME_CSI_NVM, &effects)) + if (!nvme_get_log_cmd_effects(hdl, NVME_CSI_NVM, &effects)) WriteData((__u8 *)&effects, sizeof(effects), dir, "command_effects_log.bin", "effects log"); /* get persistent event log */ - (void)nvme_get_log_persistent_event(fd, NVME_PEVENT_LOG_RELEASE_CTX, - sizeof(pevent_log), &pevent_log); + (void)nvme_get_log_persistent_event(hdl, NVME_PEVENT_LOG_RELEASE_CTX, + &pevent_log, sizeof(pevent_log)); memset(&pevent_log, 0, sizeof(pevent_log)); - err = nvme_get_log_persistent_event(fd, NVME_PEVENT_LOG_EST_CTX_AND_READ, - sizeof(pevent_log), &pevent_log); + err = nvme_get_log_persistent_event(hdl, NVME_PEVENT_LOG_EST_CTX_AND_READ, + &pevent_log, sizeof(pevent_log)); if (err) { fprintf(stderr, "Setting persistent event log read ctx failed (ignored)!\n"); return; @@ -2270,19 +2250,19 @@ static void GetGenericLogs(int fd, const char *dir) return; } - err = nvme_get_log_persistent_event(fd, NVME_PEVENT_LOG_READ, - log_len, pevent_log_info); + err = nvme_get_log_persistent_event(hdl, NVME_PEVENT_LOG_READ, + pevent_log_info, log_len); if (!err) WriteData((__u8 *)pevent_log_info, log_len, dir, "persistent_event_log.bin", "persistent event log"); } -static void GetNSIDDInfo(int fd, const char *dir, int nsid) +static void GetNSIDDInfo(struct nvme_transport_handle *hdl, const char *dir, int nsid) { char file[PATH_MAX] = { 0 }; struct nvme_id_ns ns; - if (!nvme_identify_ns(fd, nsid, &ns)) { + if (!nvme_identify_ns(hdl, nsid, &ns)) { sprintf(file, "identify_namespace_%d_data.bin", nsid); WriteData((__u8 *)&ns, sizeof(ns), dir, file, "id-ns"); } @@ -2328,7 +2308,7 @@ static void GetOSConfig(const char *strOSDirName) } } -static int micron_telemetry_log(int fd, __u8 type, __u8 **data, +static int micron_telemetry_log(struct nvme_transport_handle *hdl, __u8 type, __u8 **data, int *logSize, int da) { int err, bs = 512, offset = bs; @@ -2340,9 +2320,9 @@ static int micron_telemetry_log(int fd, __u8 type, __u8 **data, if (!buffer) return -1; if (ctrl_init) - err = nvme_get_log_telemetry_ctrl(fd, true, 0, bs, buffer); + err = nvme_get_log_telemetry_ctrl(hdl, true, 0, buffer, bs); else - err = nvme_get_log_telemetry_host(fd, 0, bs, buffer); + err = nvme_get_log_telemetry_host(hdl, 0, buffer, bs); if (err) { fprintf(stderr, "Failed to get telemetry log header for 0x%X\n", type); free(buffer); @@ -2370,9 +2350,9 @@ static int micron_telemetry_log(int fd, __u8 type, __u8 **data, if (buffer) { while (!err && offset != *logSize) { if (ctrl_init) - err = nvme_get_log_telemetry_ctrl(fd, true, 0, *logSize, buffer + offset); + err = nvme_get_log_telemetry_ctrl(hdl, true, 0, buffer + offset, *logSize); else - err = nvme_get_log_telemetry_host(fd, 0, *logSize, buffer + offset); + err = nvme_get_log_telemetry_host(hdl, 0, buffer + offset, *logSize); offset += bs; } } @@ -2387,7 +2367,7 @@ static int micron_telemetry_log(int fd, __u8 type, __u8 **data, return err; } -static int GetTelemetryData(int fd, const char *dir) +static int GetTelemetryData(struct nvme_transport_handle *hdl, const char *dir) { unsigned char *buffer = NULL; int i, err, logSize = 0; @@ -2401,7 +2381,7 @@ static int GetTelemetryData(int fd, const char *dir) }; for (i = 0; i < (int)(ARRAY_SIZE(tmap)); i++) { - err = micron_telemetry_log(fd, tmap[i].log, &buffer, &logSize, 0); + err = micron_telemetry_log(hdl, tmap[i].log, &buffer, &logSize, 0); if (!err && logSize > 0 && buffer) { sprintf(msg, "telemetry log: 0x%X", tmap[i].log); WriteData(buffer, logSize, dir, tmap[i].file, msg); @@ -2413,7 +2393,7 @@ static int GetTelemetryData(int fd, const char *dir) return err; } -static int GetFeatureSettings(int fd, const char *dir) +static int GetFeatureSettings(struct nvme_transport_handle *hdl, const char *dir) { unsigned char *bufp, buf[4096] = { 0 }; int i, err, len, errcnt = 0; @@ -2446,21 +2426,8 @@ static int GetFeatureSettings(int fd, const char *dir) len = 0; bufp = NULL; } - - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = fd, - .fid = fmap[i].id, - .nsid = 1, - .sel = 0, - .cdw11 = 0x0, - .uuidx = 0, - .data_len = len, - .data = bufp, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &attrVal, - }; - err = nvme_get_features(&args); + err = nvme_get_features(hdl, 1, fmap[i].id, 0, 0x0, 0, bufp, len, + &attrVal); if (!err) { sprintf(msg, "feature: 0x%X", fmap[i].id); WriteData((__u8 *)&attrVal, sizeof(attrVal), dir, fmap[i].file, msg); @@ -2475,7 +2442,7 @@ static int GetFeatureSettings(int fd, const char *dir) return (int)(errcnt == ARRAY_SIZE(fmap)); } -static int micron_drive_info(int argc, char **argv, struct command *cmd, +static int micron_drive_info(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get drive HW information"; @@ -2495,7 +2462,8 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd, bool is_json = false; struct json_object *root; struct json_object *driveInfo; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct format { char *fmt; }; @@ -2511,19 +2479,17 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd, OPT_END() }; - err = micron_parse_options(&dev, argc, argv, desc, opts, &model); + err = micron_parse_options(&ctx, &hdl, argc, argv, desc, opts, &model); if (err < 0) return err; if (model == UNKNOWN_MODEL) { fprintf(stderr, "ERROR : Unsupported drive for vs-drive-info cmd"); - dev_close(dev); return -1; } if (strcmp(cfg.fmt, "normal") || strcmp(cfg.fmt, "json")) { fprintf(stderr, "Invalid output format\n"); - dev_close(dev); return -1; } @@ -2535,17 +2501,15 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd, admin_cmd.addr = (__u64) (uintptr_t) &dinfo; admin_cmd.data_len = (__u32)sizeof(dinfo); admin_cmd.cdw12 = 3; - err = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL); + err = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (err) { fprintf(stderr, "ERROR : drive-info opcode failed with 0x%x\n", err); - dev_close(dev); return -1; } } else { - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) { fprintf(stderr, "ERROR : identify_ctrl() failed with 0x%x\n", err); - dev_close(dev); return -1; } dinfo.hw_ver_major = ctrl.vs[820]; @@ -2555,7 +2519,7 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd, } if ((custId == MICRON_CUST_ID_GG) && (model == M51CX)) { - err = nvme_get_log_simple(dev_fd(dev), 0xC0, C0_log_size, logC0); + err = nvme_get_log_simple(hdl, 0xC0, logC0, C0_log_size); if (err == 0) { dinfo.bs_ver_major = *((__u16 *)(logC0+300)); dinfo.bs_ver_minor = *((__u16 *)(logC0+302)); @@ -2653,19 +2617,18 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd, } - dev_close(dev); return 0; } static int micron_cloud_ssd_plugin_version(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { printf("nvme-cli Micron cloud SSD plugin version: %s.%s\n", __version_major, __version_minor); return 0; } -static int micron_plugin_version(int argc, char **argv, struct command *cmd, +static int micron_plugin_version(int argc, char **argv, struct command *acmd, struct plugin *plugin) { printf("nvme-cli Micron plugin version: %s.%s.%s\n", @@ -2807,7 +2770,7 @@ static void micron_fw_activation_history_header_print(void) printf("__________|___________|_________|__________|___________|________|________|________\n"); } -static int micron_fw_activation_history(int argc, char **argv, struct command *cmd, +static int micron_fw_activation_history(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Firmware Activation history of the given drive"; @@ -2815,7 +2778,8 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c int count = 0; unsigned int logC2[C2_log_size/sizeof(int)] = { 0 }; enum eDriveModel eModel = UNKNOWN_MODEL; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; bool is_json = false; struct json_object *root, *fw_act, *element; @@ -2834,7 +2798,7 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c OPT_END() }; - err = micron_parse_options(&dev, argc, argv, desc, opts, &eModel); + err = micron_parse_options(&ctx, &hdl, argc, argv, desc, opts, &eModel); if (err < 0) return -1; @@ -2850,7 +2814,7 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c goto out; } - err = nvme_get_log_simple(dev_fd(dev), 0xC2, C2_log_size, logC2); + err = nvme_get_log_simple(hdl, 0xC2, logC2, C2_log_size); if (err) { fprintf(stderr, "Failed to retrieve fw activation history log, error: %x\n", err); goto out; @@ -2900,21 +2864,20 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c } } out: - dev_close(dev); return err; } #define MICRON_FID_LATENCY_MONITOR 0xD0 #define MICRON_LOG_LATENCY_MONITOR 0xD1 -static int micron_latency_stats_track(int argc, char **argv, struct command *cmd, +static int micron_latency_stats_track(int argc, char **argv, struct command *acmd, struct plugin *plugin) { int err = 0; __u32 result = 0; const char *desc = "Enable, Disable or Get cmd latency monitoring stats"; const char *option = "enable or disable or status, default is status"; - const char *command = + const char *cmdstr = "commands to monitor for - all|read|write|trim, default is all i.e, enabled for all commands" ; const char *thrtime = @@ -2926,7 +2889,8 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd uint32_t command_mask = 0x7; /* 1:read 2:write 4:trim 7:all */ uint32_t timing_mask = 0x08080800; /* R[31-24]:W[23:16]:T[15:8]:0 */ uint32_t enable = 2; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct { char *option; char *command; @@ -2939,13 +2903,13 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd OPT_ARGS(opts) = { OPT_STRING("option", 'o', "option", &opt.option, option), - OPT_STRING("command", 'c', "command", &opt.command, command), + OPT_STRING("command", 'c', "command", &opt.command, cmdstr), OPT_UINT("threshold", 't', &opt.threshold, thrtime), OPT_END() }; - err = micron_parse_options(&dev, argc, argv, desc, opts, &model); + err = micron_parse_options(&ctx, &hdl, argc, argv, desc, opts, &model); if (err < 0) return -1; @@ -2955,28 +2919,12 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd enable = 0; } else if (strcmp(opt.option, "status")) { printf("Invalid control option %s specified\n", opt.option); - dev_close(dev); return -1; } - struct nvme_get_features_args g_args = { - .args_size = sizeof(g_args), - .fd = dev_fd(dev), - .fid = fid, - .nsid = 0, - .sel = 0, - .cdw11 = 0, - .uuidx = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_get_features(&g_args); + err = nvme_get_features(hdl, 0, fid, 0, 0, 0, NULL, 0, &result); if (err) { printf("Failed to retrieve latency monitoring feature status\n"); - dev_close(dev); return err; } @@ -2998,7 +2946,6 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd } else if (!result) { printf("\n"); } - dev_close(dev); return err; } @@ -3006,12 +2953,10 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd if (enable == 1) { if (opt.threshold > 2550) { printf("The maximum threshold value cannot be more than 2550 ms\n"); - dev_close(dev); return -1; } else if (opt.threshold % 10) { /* timing mask is in terms of 10ms units, so min allowed is 10ms */ printf("The threshold value should be multiple of 10 ms\n"); - dev_close(dev); return -1; } opt.threshold /= 10; @@ -3030,27 +2975,11 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd } else if (strcmp(opt.command, "all")) { printf("Invalid command %s specified for option %s\n", opt.command, opt.option); - dev_close(dev); return -1; } - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = MICRON_FID_LATENCY_MONITOR, - .nsid = 0, - .cdw11 = enable, - .cdw12 = command_mask, - .save = 1, - .uuidx = 0, - .cdw13 = timing_mask, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, MICRON_FID_LATENCY_MONITOR, 1, enable, + command_mask, timing_mask, 0, 0, NULL, 0, &result); if (!err) { printf("Successfully %sd latency monitoring for %s commands with %dms threshold\n", opt.option, opt.command, !opt.threshold ? 800 : opt.threshold * 10); @@ -3059,12 +2988,11 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd opt.option, opt.command, !opt.threshold ? 800 : opt.threshold * 10); } - dev_close(dev); return err; } -static int micron_latency_stats_logs(int argc, char **argv, struct command *cmd, +static int micron_latency_stats_logs(int argc, char **argv, struct command *acmd, struct plugin *plugin) { #define LATENCY_LOG_ENTRIES 16 @@ -3100,7 +3028,8 @@ static int micron_latency_stats_logs(int argc, char **argv, struct command *cmd, uint32_t rfu[6]; } log[LATENCY_LOG_ENTRIES]; enum eDriveModel model = UNKNOWN_MODEL; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err = -1; const char *desc = "Display Latency tracking log information"; @@ -3108,15 +3037,14 @@ static int micron_latency_stats_logs(int argc, char **argv, struct command *cmd, OPT_END() }; - err = micron_parse_options(&dev, argc, argv, desc, opts, &model); + err = micron_parse_options(&ctx, &hdl, argc, argv, desc, opts, &model); if (err) return err; memset(&log, 0, sizeof(log)); - err = nvme_get_log_simple(dev_fd(dev), 0xD1, sizeof(log), &log); + err = nvme_get_log_simple(hdl, 0xD1, &log, sizeof(log)); if (err) { if (err < 0) printf("Unable to retrieve latency stats log the drive\n"); - dev_close(dev); return err; } /* print header and each log entry */ @@ -3129,17 +3057,17 @@ static int micron_latency_stats_logs(int argc, char **argv, struct command *cmd, log[i].slba_low, log[i].slba_high, log[i].nlb, log[i].deac, log[i].prinfo, log[i].fua, log[i].lr); printf("\n"); - dev_close(dev); return err; } -static int micron_latency_stats_info(int argc, char **argv, struct command *cmd, +static int micron_latency_stats_info(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "display command latency statistics"; - const char *command = "command to display stats - all|read|write|trim, default is all"; + const char *cmdstr = "command to display stats - all|read|write|trim, default is all"; int err = 0; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; enum eDriveModel model = UNKNOWN_MODEL; #define LATENCY_BUCKET_COUNT 32 #define LATENCY_BUCKET_RSVD 32 @@ -3178,11 +3106,11 @@ static int micron_latency_stats_info(int argc, char **argv, struct command *cmd, char *cmd_str = "All"; OPT_ARGS(opts) = { - OPT_STRING("command", 'c', "command", &opt.command, command), + OPT_STRING("command", 'c', "command", &opt.command, cmdstr), OPT_END() }; - err = micron_parse_options(&dev, argc, argv, desc, opts, &model); + err = micron_parse_options(&ctx, &hdl, argc, argv, desc, opts, &model); if (err < 0) return err; if (!strcmp(opt.command, "read")) { @@ -3196,16 +3124,14 @@ static int micron_latency_stats_info(int argc, char **argv, struct command *cmd, cmd_str = "Trim"; } else if (strcmp(opt.command, "all")) { printf("Invalid command option %s to display latency stats\n", opt.command); - dev_close(dev); - return -1; + return -1; } memset(&log, 0, sizeof(log)); - err = nvme_get_log_simple(dev_fd(dev), 0xD0, sizeof(log), &log); + err = nvme_get_log_simple(hdl, 0xD0, &log, sizeof(log)); if (err) { if (err < 0) printf("Unable to retrieve latency stats log the drive\n"); - dev_close(dev); return err; } printf("Micron IO %s Command Latency Statistics\n" @@ -3227,11 +3153,10 @@ static int micron_latency_stats_info(int argc, char **argv, struct command *cmd, sprintf(end, "%u%s", thresholds[b].end, thresholds[b].unit); printf("%2d %8s %8s %8"PRIu64"\n", bucket, start, end, cmd_stats[b]); } - dev_close(dev); return err; } -static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *cmd, +static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Smart or Extended Smart Health log for the given device "; @@ -3239,7 +3164,8 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c unsigned int logFB[FB_log_size/sizeof(int)] = { 0 }; struct nvme_id_ctrl ctrl; enum eDriveModel eModel = UNKNOWN_MODEL; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; bool is_json = true; nsze_from_oacs = false; struct format { @@ -3256,7 +3182,7 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c OPT_END() }; - err = micron_parse_options(&dev, argc, argv, desc, opts, &eModel); + err = micron_parse_options(&ctx, &hdl, argc, argv, desc, opts, &eModel); if (err < 0) return -1; @@ -3268,9 +3194,9 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c __u8 spec = (eModel == M5410) ? 0 : 1; __u8 nsze; - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (!err) - err = nvme_get_log_simple(dev_fd(dev), 0xFB, FB_log_size, logFB); + err = nvme_get_log_simple(hdl, 0xFB, logFB, FB_log_size); if (err) { if (err < 0) printf("Unable to retrieve smart log 0xFB for the drive\n"); @@ -3292,55 +3218,53 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c goto out; } - err = nvme_get_log_simple(dev_fd(dev), 0xC0, C0_log_size, logC0); + err = nvme_get_log_simple(hdl, 0xC0, logC0, C0_log_size); if (!err) print_smart_cloud_health_log((__u8 *)logC0, is_json, eModel); else if (err < 0) printf("Unable to retrieve extended smart log 0xC0 for the drive\n"); out: - dev_close(dev); if (err > 0) nvme_show_status(err); return err; } static int micron_clr_fw_activation_history(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { const char *desc = "Clear FW activation history"; __u32 result = 0; __u8 fid = MICRON_FEATURE_CLEAR_FW_ACTIVATION_HISTORY; enum eDriveModel model = UNKNOWN_MODEL; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; OPT_ARGS(opts) = { OPT_END() }; int err = 0; - err = micron_parse_options(&dev, argc, argv, desc, opts, &model); + err = micron_parse_options(&ctx, &hdl, argc, argv, desc, opts, &model); if (err < 0) return err; if ((model != M51CX) && (model != M51BY) && (model != M51CY) && (model != M6003) && (model != M6004)) { printf("This option is not supported for specified drive\n"); - dev_close(dev); return err; } - err = nvme_set_features_simple(dev_fd(dev), fid, 1 << 31, 0, 0, &result); + err = nvme_set_features_simple(hdl, 1 << 31, fid, 0, 0, &result); if (!err) err = (int)result; else printf("Failed to clear fw activation history, error = 0x%x\n", err); - dev_close(dev); return err; } static int micron_telemetry_cntrl_option(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { int err = 0; __u32 result = 0; @@ -3353,7 +3277,8 @@ static int micron_telemetry_cntrl_option(int argc, char **argv, int fid = MICRON_FEATURE_TELEMETRY_CONTROL_OPTION; enum eDriveModel model = UNKNOWN_MODEL; struct nvme_id_ctrl ctrl = { 0 }; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct { char *option; @@ -3369,75 +3294,33 @@ static int micron_telemetry_cntrl_option(int argc, char **argv, OPT_END() }; - err = micron_parse_options(&dev, argc, argv, desc, opts, &model); + err = micron_parse_options(&ctx, &hdl, argc, argv, desc, opts, &model); if (err < 0) return -1; - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if ((ctrl.lpa & 0x8) != 0x8) { printf("drive doesn't support host/controller generated telemetry logs\n"); - dev_close(dev); return err; } if (!strcmp(opt.option, "enable")) { - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .nsid = 1, - .cdw11 = 1, - .cdw12 = 0, - .save = (opt.select & 0x1), - .uuidx = 0, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 1, fid, (opt.select & 0x1), 1, 0, 0, 0, 0, + NULL, 0, &result); if (!err) printf("successfully set controller telemetry option\n"); else printf("Failed to set controller telemetry option\n"); } else if (!strcmp(opt.option, "disable")) { - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .nsid = 1, - .cdw11 = 0, - .cdw12 = 0, - .save = (opt.select & 0x1), - .uuidx = 0, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 1, fid, (opt.select & 0x1), 0, 0, 0, 0, 0, + NULL, 0, &result); if (!err) printf("successfully disabled controller telemetry option\n"); else printf("Failed to disable controller telemetry option\n"); } else if (!strcmp(opt.option, "status")) { - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .nsid = 1, - .sel = opt.select & 0x3, - .cdw11 = 0, - .uuidx = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_get_features(&args); + err = nvme_get_features(hdl, 1, fid, opt.select & 0x3, 0, 0, NULL, 0, + &result); if (!err) printf("Controller telemetry option : %s\n", (result) ? "enabled" : "disabled"); @@ -3446,11 +3329,9 @@ static int micron_telemetry_cntrl_option(int argc, char **argv, } else { printf("invalid option %s, valid values are enable,disable or status\n", opt.option); - dev_close(dev); return -1; } - dev_close(dev); return err; } @@ -3469,28 +3350,12 @@ struct micron_common_log_header { }; /* helper function to retrieve logs with specific offset and max chunk size */ -int nvme_get_log_lpo(int fd, __u8 log_id, __u32 lpo, __u32 chunk, - __u32 data_len, void *data) +int nvme_get_log_lpo(struct nvme_transport_handle *hdl, __u8 log_id, __u32 lpo, __u32 chunk, + __u32 data_len, void *data) { __u32 offset = lpo, xfer_len = data_len; + struct nvme_passthru_cmd cmd; void *ptr = data; - struct nvme_get_log_args args = { - .lpo = offset, - .result = NULL, - .log = ptr, - .args_size = sizeof(args), - .fd = fd, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = log_id, - .len = xfer_len, - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, - .uuidx = NVME_UUID_NONE, - .rae = false, - .ot = false, - }; int ret = 0; /* divide data into multiple chunks */ @@ -3499,10 +3364,10 @@ int nvme_get_log_lpo(int fd, __u8 log_id, __u32 lpo, __u32 chunk, if (xfer_len > chunk) xfer_len = chunk; - args.lpo = offset; - args.log = ptr; - args.len = xfer_len; - ret = nvme_get_log(&args); + nvme_init_get_log(&cmd, NVME_NSID_ALL, log_id, NVME_CSI_NVM, + ptr, xfer_len); + nvme_init_get_log_lpo(&cmd, lpo); + ret = nvme_get_log(hdl, &cmd, false, xfer_len, NULL); if (ret) return ret; offset += xfer_len; @@ -3512,7 +3377,7 @@ int nvme_get_log_lpo(int fd, __u8 log_id, __u32 lpo, __u32 chunk, } /* retrieves logs with common log format */ -static int get_common_log(int fd, uint8_t id, uint8_t **buf, int *size) +static int get_common_log(struct nvme_transport_handle *hdl, uint8_t id, uint8_t **buf, int *size) { struct micron_common_log_header hdr = { 0 }; int log_size = sizeof(hdr), first = 0, second = 0; @@ -3520,7 +3385,7 @@ static int get_common_log(int fd, uint8_t id, uint8_t **buf, int *size) int ret = -1; int chunk = 0x4000; /* max chunk size to be used for these logs */ - ret = nvme_get_log_simple(fd, id, sizeof(hdr), &hdr); + ret = nvme_get_log_simple(hdl, id, &hdr, sizeof(hdr)); if (ret) { fprintf(stderr, "pull hdr failed for %u with error: 0x%x\n", id, ret); return ret; @@ -3555,7 +3420,7 @@ static int get_common_log(int fd, uint8_t id, uint8_t **buf, int *size) return -ENOMEM; } memcpy(buffer, &hdr, sizeof(hdr)); - ret = nvme_get_log_lpo(fd, id, sizeof(hdr), chunk, hdr.log_size, + ret = nvme_get_log_lpo(hdl, id, sizeof(hdr), chunk, hdr.log_size, buffer + sizeof(hdr)); if (!ret) log_size += hdr.log_size; @@ -3578,7 +3443,7 @@ static int get_common_log(int fd, uint8_t id, uint8_t **buf, int *size) second = hdr.write_pointer - sizeof(hdr); if (first) { - ret = nvme_get_log_lpo(fd, id, hdr.write_pointer, chunk, first, + ret = nvme_get_log_lpo(hdl, id, hdr.write_pointer, chunk, first, buffer + sizeof(hdr)); if (ret) { free(buffer); @@ -3588,7 +3453,7 @@ static int get_common_log(int fd, uint8_t id, uint8_t **buf, int *size) log_size += first; } if (second) { - ret = nvme_get_log_lpo(fd, id, sizeof(hdr), chunk, second, + ret = nvme_get_log_lpo(hdl, id, sizeof(hdr), chunk, second, buffer + sizeof(hdr) + first); if (ret) { fprintf(stderr, "failed to get log: 0x%X\n", id); @@ -3603,7 +3468,7 @@ static int get_common_log(int fd, uint8_t id, uint8_t **buf, int *size) return ret; } -static int GetOcpEnhancedTelemetryLog(int fd, const char *dir, int nLogID) +static int GetOcpEnhancedTelemetryLog(struct nvme_transport_handle *hdl, const char *dir, int nLogID) { int err = 0; unsigned char *pTelemetryDataHeader = 0; @@ -3619,22 +3484,9 @@ static int GetOcpEnhancedTelemetryLog(int fd, const char *dir, int nLogID) pBuffer[1] = 1; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = fd, - .fid = MICRON_FEATURE_OCP_ENHANCED_TELEMETRY, - .nsid = NVME_NSID_ALL, - .cdw11 = 0, - .cdw12 = 0, - .save = 1, - .uuidx = 0, - .cdw15 = 0, - .data_len = uiBufferSize, - .data = pBuffer, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); + err = nvme_set_features(hdl, NVME_NSID_ALL, + MICRON_FEATURE_OCP_ENHANCED_TELEMETRY, 1, 0, 0, 0, + 0, 0, pBuffer, uiBufferSize, &result); if (err != 0) printf("Failed to set ETDAS, Data Area 4 won't be avialable >>> "); @@ -3646,7 +3498,7 @@ static int GetOcpEnhancedTelemetryLog(int fd, const char *dir, int nLogID) printf("Unable to allocate buffer of size 0x%X bytes for telemetry header", 512); return -1; } - err = NVMEGetLogPage(fd, nLogID, pTelemetryDataHeader, 512, 0); + err = NVMEGetLogPage(hdl, nLogID, pTelemetryDataHeader, 512, 0); if (err != 0) return err; @@ -3687,7 +3539,7 @@ static int GetOcpEnhancedTelemetryLog(int fd, const char *dir, int nLogID) continue; } /* Fetch the Data */ - err = NVMEGetLogPage(fd, nLogID, pTelemetryBuffer, nallocSize, nOffset); + err = NVMEGetLogPage(hdl, nLogID, pTelemetryBuffer, nallocSize, nOffset); if (err != 0) { printf( @@ -3737,7 +3589,7 @@ static int GetOcpEnhancedTelemetryLog(int fd, const char *dir, int nLogID) } -static int micron_internal_logs(int argc, char **argv, struct command *cmd, +static int micron_internal_logs(int argc, char **argv, struct command *acmd, struct plugin *plugin) { int err = -EINVAL; @@ -3751,7 +3603,8 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd, char sn[20] = { 0 }; char msg[256] = { 0 }; int c_logs_index = 8; /* should be current size of aVendorLogs */ - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct { unsigned char ucLogPage; const char *strFileName; @@ -3836,7 +3689,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -3880,7 +3733,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd, goto out; } - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) goto out; @@ -3892,7 +3745,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd, } int logSize = 0; __u8 *buffer = NULL; const char *dir = "."; - err = micron_telemetry_log(dev_fd(dev), cfg.log, &buffer, &logSize, + err = micron_telemetry_log(hdl, cfg.log, &buffer, &logSize, cfg.data_area); if (!err && logSize > 0 && buffer) { sprintf(msg, "telemetry log: 0x%X", cfg.log); @@ -3924,28 +3777,28 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd, GetDriveInfo(strOSDirName, ctrlIdx, &ctrl); for (int i = 1; i <= ctrl.nn; i++) - GetNSIDDInfo(dev_fd(dev), strCtrlDirName, i); + GetNSIDDInfo(hdl, strCtrlDirName, i); - GetSmartlogData(dev_fd(dev), strCtrlDirName); - GetErrorlogData(dev_fd(dev), ctrl.elpe, strCtrlDirName); - GetGenericLogs(dev_fd(dev), strCtrlDirName); + GetSmartlogData(hdl, strCtrlDirName); + GetErrorlogData(hdl, ctrl.elpe, strCtrlDirName); + GetGenericLogs(hdl, strCtrlDirName); /* pull if telemetry log data is supported */ if ((ctrl.lpa & 0x8) == 0x8) { if (eModel == M51BY) { - err = GetOcpEnhancedTelemetryLog(dev_fd(dev), strCtrlDirName, + err = GetOcpEnhancedTelemetryLog(hdl, strCtrlDirName, NVME_LOG_LID_TELEMETRY_HOST); if (err != 0) printf("Failed to fetch the host telemetry log"); - err = GetOcpEnhancedTelemetryLog(dev_fd(dev), strCtrlDirName, + err = GetOcpEnhancedTelemetryLog(hdl, strCtrlDirName, NVME_LOG_LID_TELEMETRY_CTRL); if (err != 0) printf("Failed to fetch the controller telemetry log"); } else { - GetTelemetryData(dev_fd(dev), strCtrlDirName); + GetTelemetryData(hdl, strCtrlDirName); } } - GetFeatureSettings(dev_fd(dev), strCtrlDirName); + GetFeatureSettings(hdl, strCtrlDirName); if (eModel != M5410 && eModel != M5407) { memcpy(&aVendorLogs[c_logs_index], aM51XXLogs, sizeof(aM51XXLogs)); @@ -3967,7 +3820,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd, break; case 0xE9: if (eModel == M51CX || eModel == M51BY) { - err = NVMEGetLogPage(dev_fd(dev), aVendorLogs[i].ucLogPage, + err = NVMEGetLogPage(hdl, aVendorLogs[i].ucLogPage, (unsigned char *)&stWllHdr, sizeof(struct MICRON_WORKLOAD_LOG_HDR), 0); if (err == 0) { @@ -3983,7 +3836,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd, } memcpy(dataBuffer, &stWllHdr, sizeof(struct MICRON_WORKLOAD_LOG_HDR)); - err = NVMEGetLogPage(dev_fd(dev), + err = NVMEGetLogPage(hdl, aVendorLogs[i].ucLogPage, (dataBuffer + sizeof(struct MICRON_WORKLOAD_LOG_HDR)), @@ -4002,14 +3855,14 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd, if (eModel == M51CX || eModel == M51BY || eModel == M51CY) continue; - err = get_common_log(dev_fd(dev), aVendorLogs[i].ucLogPage, + err = get_common_log(hdl, aVendorLogs[i].ucLogPage, &dataBuffer, &bSize); break; case 0xE3: case 0xE4: case 0xE8: case 0xEA: - err = get_common_log(dev_fd(dev), aVendorLogs[i].ucLogPage, + err = get_common_log(hdl, aVendorLogs[i].ucLogPage, &dataBuffer, &bSize); break; case 0xC1: @@ -4017,9 +3870,9 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd, if (eModel == M51CX || eModel == M51BY || eModel == M51CY) continue; - err = GetLogPageSize(dev_fd(dev), aVendorLogs[i].ucLogPage, &bSize); + err = GetLogPageSize(hdl, aVendorLogs[i].ucLogPage, &bSize); if (err == 0 && bSize > 0) - err = GetCommonLogPage(dev_fd(dev), + err = GetCommonLogPage(hdl, aVendorLogs[i].ucLogPage, &dataBuffer, bSize); break; @@ -4027,10 +3880,10 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd, if (eModel == M51BY || eModel == M51CY) continue; - err = GetLogPageSize(dev_fd(dev), aVendorLogs[i].ucLogPage, + err = GetLogPageSize(hdl, aVendorLogs[i].ucLogPage, &bSize); if (!err && bSize > 0) - err = GetCommonLogPage(dev_fd(dev), aVendorLogs[i].ucLogPage, + err = GetCommonLogPage(hdl, aVendorLogs[i].ucLogPage, &dataBuffer, bSize); break; case 0xE6: @@ -4049,13 +3902,13 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd, if (bSize && dataBuffer) { memset(dataBuffer, 0, bSize); if (eModel == M5410 || eModel == M5407) - err = NVMEGetLogPage(dev_fd(dev), + err = NVMEGetLogPage(hdl, aVendorLogs[i].ucLogPage, dataBuffer, bSize, 0); else - err = nvme_get_log_simple(dev_fd(dev), + err = nvme_get_log_simple(hdl, aVendorLogs[i].ucLogPage, - bSize, dataBuffer); + dataBuffer, bSize); } break; case 0xF7: @@ -4063,7 +3916,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd, case 0xFC: case 0xFD: if (eModel == M51BX) - (void)NVMEResetLog(dev_fd(dev), aVendorLogs[i].ucLogPage, + (void)NVMEResetLog(hdl, aVendorLogs[i].ucLogPage, aVendorLogs[i].nLogSize, aVendorLogs[i].nMaxSize); default: @@ -4072,15 +3925,15 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd, if (!dataBuffer) break; memset(dataBuffer, 0, bSize); - err = nvme_get_log_simple(dev_fd(dev), aVendorLogs[i].ucLogPage, - bSize, dataBuffer); + err = nvme_get_log_simple(hdl, aVendorLogs[i].ucLogPage, + dataBuffer, bSize); maxSize = aVendorLogs[i].nMaxSize - bSize; while (!err && maxSize > 0 && ((unsigned int *)dataBuffer)[0] != 0xdeadbeef) { sprintf(msg, "log 0x%x", aVendorLogs[i].ucLogPage); WriteData(dataBuffer, bSize, strCtrlDirName, aVendorLogs[i].strFileName, msg); - err = nvme_get_log_simple(dev_fd(dev), + err = nvme_get_log_simple(hdl, aVendorLogs[i].ucLogPage, - bSize, dataBuffer); + dataBuffer, bSize); if (err || (((unsigned int *)dataBuffer)[0] == 0xdeadbeef)) break; maxSize -= bSize; @@ -4099,26 +3952,26 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd, err = ZipAndRemoveDir(strMainDirName, cfg.package); out: - dev_close(dev); return err; } #define MIN_LOG_SIZE 512 -static int micron_logpage_dir(int argc, char **argv, struct command *cmd, +static int micron_logpage_dir(int argc, char **argv, struct command *acmd, struct plugin *plugin) { int err = -1; const char *desc = "List the supported log pages"; enum eDriveModel model = UNKNOWN_MODEL; char logbuf[MIN_LOG_SIZE]; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int i; OPT_ARGS(opts) = { OPT_END() }; - err = micron_parse_options(&dev, argc, argv, desc, opts, &model); + err = micron_parse_options(&ctx, &hdl, argc, argv, desc, opts, &model); if (err < 0) return err; @@ -4160,8 +4013,8 @@ static int micron_logpage_dir(int argc, char **argv, struct command *cmd, printf("Supported log page list\nLog ID : Description\n"); for (i = 0; i < ARRAY_SIZE(log_list); i++) { - err = nvme_get_log_simple(dev_fd(dev), log_list[i].log_id, - MIN_LOG_SIZE, &logbuf[0]); + err = nvme_get_log_simple(hdl, log_list[i].log_id, + &logbuf[0], MIN_LOG_SIZE); if (err) continue; printf("%02Xh : %s\n", log_list[i].log_id, log_list[i].desc); @@ -4171,14 +4024,15 @@ static int micron_logpage_dir(int argc, char **argv, struct command *cmd, } static int micron_cloud_boot_SSD_version(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { const char *desc = "Prints HyperScale Boot Version"; unsigned char logC0[C0_log_size] = { 0 }; struct nvme_id_ctrl ctrl; enum eDriveModel eModel = UNKNOWN_MODEL; int err = 0; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct format { char *fmt; }; @@ -4192,11 +4046,11 @@ static int micron_cloud_boot_SSD_version(int argc, char **argv, OPT_END() }; - err = micron_parse_options(&dev, argc, argv, desc, opts, &eModel); + err = micron_parse_options(&ctx, &hdl, argc, argv, desc, opts, &eModel); if (err < 0) return -1; - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err == 0) { if (ctrl.vs[536] != MICRON_CUST_ID_GG) { printf( @@ -4209,7 +4063,7 @@ static int micron_cloud_boot_SSD_version(int argc, char **argv, goto out; } - err = nvme_get_log_simple(dev_fd(dev), 0xC0, C0_log_size, logC0); + err = nvme_get_log_simple(hdl, 0xC0, logC0, C0_log_size); if (err == 0) { __u16 major, minor; @@ -4223,11 +4077,10 @@ static int micron_cloud_boot_SSD_version(int argc, char **argv, goto out; } out: - dev_close(dev); return err; } -static int micron_device_waf(int argc, char **argv, struct command *cmd, +static int micron_device_waf(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Prints device Write Amplification Factor(WAF)"; @@ -4236,7 +4089,8 @@ static int micron_device_waf(int argc, char **argv, struct command *cmd, struct nvme_smart_log smart_log; enum eDriveModel eModel = UNKNOWN_MODEL; int err = 0; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; long double tlc_units_written, slc_units_written; long double data_units_written, write_amplification_factor; @@ -4256,11 +4110,11 @@ static int micron_device_waf(int argc, char **argv, struct command *cmd, OPT_END() }; - err = micron_parse_options(&dev, argc, argv, desc, opts, &eModel); + err = micron_parse_options(&ctx, &hdl, argc, argv, desc, opts, &eModel); if (err < 0) return -1; - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err == 0) { if (ctrl.vs[536] != MICRON_CUST_ID_GG) { printf("vs-device-waf option is not supported for specified drive\n"); @@ -4271,13 +4125,13 @@ static int micron_device_waf(int argc, char **argv, struct command *cmd, goto out; } - err = nvme_get_log_smart(dev_fd(dev), 0xffffffff, false, &smart_log); + err = nvme_get_log_smart(hdl, NVME_NSID_ALL, &smart_log); if (err != 0) { fprintf(stderr, "nvme_smart_log() failed, err = %d\n", err); goto out; } - err = nvme_get_log_simple(dev_fd(dev), 0xC0, C0_log_size, logC0); + err = nvme_get_log_simple(hdl, 0xC0, logC0, C0_log_size); if (err != 0) { fprintf(stderr, "Failed to get extended smart log, err = %d\n", err); goto out; @@ -4290,11 +4144,10 @@ static int micron_device_waf(int argc, char **argv, struct command *cmd, printf("Write Amplification Factor %.0Lf\n", write_amplification_factor); out: - dev_close(dev); return err; } -static int micron_cloud_log(int argc, char **argv, struct command *cmd, +static int micron_cloud_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Smart or Extended Smart Health log for the given device "; @@ -4302,7 +4155,8 @@ static int micron_cloud_log(int argc, char **argv, struct command *cmd, struct nvme_id_ctrl ctrl; enum eDriveModel eModel = UNKNOWN_MODEL; int err = 0; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; bool is_json = true; struct format { char *fmt; @@ -4317,7 +4171,7 @@ static int micron_cloud_log(int argc, char **argv, struct command *cmd, OPT_END() }; - err = micron_parse_options(&dev, argc, argv, desc, opts, &eModel); + err = micron_parse_options(&ctx, &hdl, argc, argv, desc, opts, &eModel); if (err < 0) return -1; @@ -4331,7 +4185,7 @@ static int micron_cloud_log(int argc, char **argv, struct command *cmd, goto out; } - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err == 0) { if (ctrl.vs[536] != MICRON_CUST_ID_GG) { printf("vs-cloud-log option is not supported for specified drive\n"); @@ -4342,14 +4196,13 @@ static int micron_cloud_log(int argc, char **argv, struct command *cmd, goto out; } - err = nvme_get_log_simple(dev_fd(dev), 0xC0, C0_log_size, logC0); + err = nvme_get_log_simple(hdl, 0xC0, logC0, C0_log_size); if (err == 0) print_hyperscale_cloud_health_log((__u8 *)logC0, is_json); else if (err < 0) printf("Unable to retrieve extended smart log 0xC0 for the drive\n"); out: - dev_close(dev); if (err > 0) nvme_show_status(err); return err; diff --git a/plugins/nbft/nbft-plugin.c b/plugins/nbft/nbft-plugin.c index 292b516385..f6952348a5 100644 --- a/plugins/nbft/nbft-plugin.c +++ b/plugins/nbft/nbft-plugin.c @@ -529,7 +529,7 @@ static void normal_show_nbfts(struct list_head *nbft_list, bool show_subsys, } } -int show_nbft(int argc, char **argv, struct command *cmd, struct plugin *plugin) +int show_nbft(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Display contents of the ACPI NBFT files."; struct list_head nbft_list; diff --git a/plugins/netapp/netapp-nvme.c b/plugins/netapp/netapp-nvme.c index b82ef5eb62..8d64c9668c 100644 --- a/plugins/netapp/netapp-nvme.c +++ b/plugins/netapp/netapp-nvme.c @@ -724,7 +724,7 @@ static void netapp_ontapdevices_print_json(struct ontapdevice_info *devices, json_free_object(root); } -static int nvme_get_ontap_c2_log(int fd, __u32 nsid, void *buf, __u32 buflen) +static int nvme_get_ontap_c2_log(struct nvme_transport_handle *hdl, __u32 nsid, void *buf, __u32 buflen) { struct nvme_passthru_cmd get_log; int err; @@ -745,7 +745,7 @@ static int nvme_get_ontap_c2_log(int fd, __u32 nsid, void *buf, __u32 buflen) get_log.cdw10 |= ONTAP_C2_LOG_NSINFO_LSP << 8; get_log.cdw11 = numdu; - err = nvme_submit_admin_passthru(fd, &get_log, NULL); + err = nvme_submit_admin_passthru(hdl, &get_log, NULL); if (err) { fprintf(stderr, "ioctl error %0x\n", err); return 1; @@ -754,12 +754,13 @@ static int nvme_get_ontap_c2_log(int fd, __u32 nsid, void *buf, __u32 buflen) return 0; } -static int netapp_smdevices_get_info(int fd, struct smdevice_info *item, +static int netapp_smdevices_get_info(struct nvme_transport_handle *hdl, + struct smdevice_info *item, const char *dev) { int err; - err = nvme_identify_ctrl(fd, &item->ctrl); + err = nvme_identify_ctrl(hdl, &item->ctrl); if (err) { fprintf(stderr, "Identify Controller failed to %s (%s)\n", dev, @@ -771,8 +772,11 @@ static int netapp_smdevices_get_info(int fd, struct smdevice_info *item, if (strncmp("NetApp E-Series", item->ctrl.mn, 15) != 0) return 0; /* not the right model of controller */ - err = nvme_get_nsid(fd, &item->nsid); - err = nvme_identify_ns(fd, item->nsid, &item->ns); + err = nvme_get_nsid(hdl, &item->nsid); + if (err) + return err; + + err = nvme_identify_ns(hdl, item->nsid, &item->ns); if (err) { fprintf(stderr, "Unable to identify namespace for %s (%s)\n", @@ -785,13 +789,14 @@ static int netapp_smdevices_get_info(int fd, struct smdevice_info *item, return 1; } -static int netapp_ontapdevices_get_info(int fd, struct ontapdevice_info *item, - const char *dev) +static int netapp_ontapdevices_get_info(struct nvme_transport_handle *hdl, + struct ontapdevice_info *item, + const char *dev) { - int err; void *nsdescs; + int err; - err = nvme_identify_ctrl(fd, &item->ctrl); + err = nvme_identify_ctrl(hdl, &item->ctrl); if (err) { fprintf(stderr, "Identify Controller failed to %s (%s)\n", dev, err < 0 ? strerror(-err) : @@ -803,9 +808,9 @@ static int netapp_ontapdevices_get_info(int fd, struct ontapdevice_info *item, /* not the right controller model */ return 0; - err = nvme_get_nsid(fd, &item->nsid); + err = nvme_get_nsid(hdl, &item->nsid); - err = nvme_identify_ns(fd, item->nsid, &item->ns); + err = nvme_identify_ns(hdl, item->nsid, &item->ns); if (err) { fprintf(stderr, "Unable to identify namespace for %s (%s)\n", dev, err < 0 ? strerror(-err) : @@ -820,7 +825,7 @@ static int netapp_ontapdevices_get_info(int fd, struct ontapdevice_info *item, memset(nsdescs, 0, 0x1000); - err = nvme_identify_ns_descs(fd, item->nsid, nsdescs); + err = nvme_identify_ns_descs_list(hdl, item->nsid, nsdescs); if (err) { fprintf(stderr, "Unable to identify namespace descriptor for %s (%s)\n", dev, err < 0 ? strerror(-err) : @@ -832,7 +837,7 @@ static int netapp_ontapdevices_get_info(int fd, struct ontapdevice_info *item, memcpy(item->uuid, nsdescs + sizeof(struct nvme_ns_id_desc), sizeof(item->uuid)); free(nsdescs); - err = nvme_get_ontap_c2_log(fd, item->nsid, item->log_data, ONTAP_C2_LOG_SIZE); + err = nvme_get_ontap_c2_log(hdl, item->nsid, item->log_data, ONTAP_C2_LOG_SIZE); if (err) { fprintf(stderr, "Unable to get log page data for %s (%s)\n", dev, err < 0 ? strerror(-err) : @@ -883,17 +888,18 @@ static int netapp_output_format(char *format) } /* handler for 'nvme netapp smdevices' */ -static int netapp_smdevices(int argc, char **argv, struct command *command, - struct plugin *plugin) +static int netapp_smdevices(int argc, char **argv, struct command *acmd, + struct plugin *plugin) { const char *desc = "Display information about E-Series volumes."; - + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = nvme_create_global_ctx(stdout, DEFAULT_LOGLEVEL); struct dirent **devices; - int num, i, fd, ret, fmt; + int num, i, ret, fmt; struct smdevice_info *smdevices; char path[264]; char *devname = NULL; int num_smdevices = 0; + struct nvme_transport_handle *hdl; struct config { bool verbose; @@ -910,6 +916,9 @@ static int netapp_smdevices(int argc, char **argv, struct command *command, OPT_END() }; + if (!ctx) + return -ENOMEM; + ret = argconfig_parse(argc, argv, desc, opts); if (ret < 0) return ret; @@ -955,16 +964,16 @@ static int netapp_smdevices(int argc, char **argv, struct command *command, for (i = 0; i < num; i++) { snprintf(path, sizeof(path), "%s%s", dev_path, devices[i]->d_name); - fd = open(path, O_RDONLY); - if (fd < 0) { + ret = nvme_open(ctx, path, &hdl); + if (ret) { fprintf(stderr, "Unable to open %s: %s\n", path, - strerror(errno)); + strerror(-ret)); continue; } - num_smdevices += netapp_smdevices_get_info(fd, + num_smdevices += netapp_smdevices_get_info(hdl, &smdevices[num_smdevices], path); - close(fd); + nvme_close(hdl); } if (num_smdevices) { @@ -990,16 +999,18 @@ static int netapp_smdevices(int argc, char **argv, struct command *command, } /* handler for 'nvme netapp ontapdevices' */ -static int netapp_ontapdevices(int argc, char **argv, struct command *command, +static int netapp_ontapdevices(int argc, char **argv, struct command *acmd, struct plugin *plugin) { + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = nvme_create_global_ctx(stdout, DEFAULT_LOGLEVEL); const char *desc = "Display information about ONTAP devices."; struct dirent **devices; - int num, i, fd, ret, fmt; + int num, i, ret, fmt; struct ontapdevice_info *ontapdevices; char path[264]; char *devname = NULL; int num_ontapdevices = 0; + struct nvme_transport_handle *hdl; struct config { bool verbose; @@ -1016,6 +1027,9 @@ static int netapp_ontapdevices(int argc, char **argv, struct command *command, OPT_END() }; + if (!ctx) + return -ENOMEM; + ret = argconfig_parse(argc, argv, desc, opts); if (ret < 0) return ret; @@ -1061,17 +1075,17 @@ static int netapp_ontapdevices(int argc, char **argv, struct command *command, for (i = 0; i < num; i++) { snprintf(path, sizeof(path), "%s%s", dev_path, devices[i]->d_name); - fd = open(path, O_RDONLY); - if (fd < 0) { + ret = nvme_open(ctx, path, &hdl); + if (ret) { fprintf(stderr, "Unable to open %s: %s\n", path, - strerror(errno)); + strerror(-ret)); continue; } - num_ontapdevices += netapp_ontapdevices_get_info(fd, + num_ontapdevices += netapp_ontapdevices_get_info(hdl, &ontapdevices[num_ontapdevices], path); - close(fd); + nvme_close(hdl); } if (num_ontapdevices) { diff --git a/plugins/nvidia/nvidia-nvme.c b/plugins/nvidia/nvidia-nvme.c index 71e0bc3305..e4e3d9b6fb 100644 --- a/plugins/nvidia/nvidia-nvme.c +++ b/plugins/nvidia/nvidia-nvme.c @@ -46,8 +46,8 @@ static void nvidia_id_ctrl(__u8 *vs, struct json_object *root) printf("json_rpc_2_0_ver : %s\n", json_rpc_2_0_ver); } -static int id_ctrl(int argc, char **argv, struct command *cmd, +static int id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return __id_ctrl(argc, argv, cmd, plugin, nvidia_id_ctrl); + return __id_ctrl(argc, argv, acmd, plugin, nvidia_id_ctrl); } diff --git a/plugins/ocp/ocp-clear-features.c b/plugins/ocp/ocp-clear-features.c index ddb95cb7f3..bccbc8809d 100644 --- a/plugins/ocp/ocp-clear-features.c +++ b/plugins/ocp/ocp-clear-features.c @@ -14,9 +14,10 @@ static int ocp_clear_feature(int argc, char **argv, const char *desc, const __u8 fid) { + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 result = 0; __u32 clear = 1 << 31; - struct nvme_dev *dev; __u8 uuid_index = 0; bool uuid = true; int err; @@ -27,7 +28,7 @@ static int ocp_clear_feature(int argc, char **argv, const char *desc, const __u8 OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -36,31 +37,15 @@ static int ocp_clear_feature(int argc, char **argv, const char *desc, const __u8 if (uuid) { /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &uuid_index); + err = ocp_get_uuid_index(hdl, &uuid_index); if (err || !uuid_index) { fprintf(stderr, "ERROR: No OCP UUID index found\n"); - goto close_dev; + return err; } } - struct nvme_set_features_args args = { - .result = &result, - .data = NULL, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .nsid = 0, - .cdw11 = clear, - .cdw12 = 0, - .cdw13 = 0, - .cdw15 = 0, - .data_len = 0, - .save = 0, - .uuidx = uuid_index, - .fid = fid, - }; - - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, fid, 0, clear, 0, 0, uuid_index, 0, NULL, 0, + &result); if (err == 0) printf("Success : %s\n", desc); @@ -68,14 +53,11 @@ static int ocp_clear_feature(int argc, char **argv, const char *desc, const __u8 nvme_show_status(err); else printf("Fail : %s\n", desc); -close_dev: - /* Redundant close() to make static code analysis happy */ - close(dev->direct.fd); - dev_close(dev); + return err; } -int get_ocp_error_counters(int argc, char **argv, struct command *cmd, +int get_ocp_error_counters(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Define Issue Get Feature cmd (FID: 0xC3) Clear PCIe Corr Err Counters"; @@ -83,8 +65,8 @@ int get_ocp_error_counters(int argc, char **argv, struct command *cmd, const char *nsid = "Byte[04-07]: Namespace Identifier Valid/Invalid/Inactive"; const char *no_uuid = "Do not try to automatically detect UUID index"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 result; int err; bool uuid; @@ -107,7 +89,7 @@ int get_ocp_error_counters(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -115,28 +97,15 @@ int get_ocp_error_counters(int argc, char **argv, struct command *cmd, if (uuid) { /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &uuid_index); + err = ocp_get_uuid_index(hdl, &uuid_index); if (err || !uuid_index) { nvme_show_error("ERROR: No OCP UUID index found"); return err; } } - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = OCP_FID_CPCIE, - .nsid = cfg.nsid, - .sel = cfg.sel, - .cdw11 = 0, - .uuidx = uuid_index, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_get_features(&args); + err = nvme_get_features(hdl, cfg.nsid, OCP_FID_CPCIE, cfg.sel, 0, + uuid_index, NULL, 0, &result); if (!err) { printf("get-feature:0xC3 %s value: %#08x\n", nvme_select_to_string(cfg.sel), result); @@ -150,14 +119,16 @@ int get_ocp_error_counters(int argc, char **argv, struct command *cmd, return err; } -int ocp_clear_fw_update_history(int argc, char **argv, struct command *cmd, struct plugin *plugin) +int ocp_clear_fw_update_history(int argc, char **argv, struct command *acmd, + struct plugin *plugin) { const char *desc = "OCP Clear Firmware Update History"; return ocp_clear_feature(argc, argv, desc, OCP_FID_CFUH); } -int ocp_clear_pcie_correctable_errors(int argc, char **argv, struct command *cmd, +int ocp_clear_pcie_correctable_errors(int argc, char **argv, + struct command *command, struct plugin *plugin) { const char *desc = "OCP Clear PCIe Correctable Error Counters"; diff --git a/plugins/ocp/ocp-clear-features.h b/plugins/ocp/ocp-clear-features.h index 9727b88c01..05696e754b 100644 --- a/plugins/ocp/ocp-clear-features.h +++ b/plugins/ocp/ocp-clear-features.h @@ -6,10 +6,10 @@ * leonardo.da.cunha@solidigm.com */ -int ocp_clear_fw_update_history(int argc, char **argv, struct command *cmd, struct plugin *plugin); +int ocp_clear_fw_update_history(int argc, char **argv, struct command *acmd, struct plugin *plugin); -int ocp_clear_pcie_correctable_errors(int argc, char **argv, struct command *cmd, +int ocp_clear_pcie_correctable_errors(int argc, char **argv, struct command *acmd, struct plugin *plugin); -int get_ocp_error_counters(int argc, char **argv, struct command *cmd, +int get_ocp_error_counters(int argc, char **argv, struct command *acmd, struct plugin *plugin); diff --git a/plugins/ocp/ocp-fw-activation-history.c b/plugins/ocp/ocp-fw-activation-history.c index d3eb60c262..02c45bc539 100644 --- a/plugins/ocp/ocp-fw-activation-history.c +++ b/plugins/ocp/ocp-fw-activation-history.c @@ -24,59 +24,45 @@ static const unsigned char ocp_fw_activation_history_guid[GUID_LEN] = { 0xac, 0xf3, 0x1c, 0xd1 }; -int ocp_fw_activation_history_log(int argc, char **argv, struct command *cmd, +int ocp_fw_activation_history_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - const char *description = "Retrieves the OCP firmware activation history log."; + const char *desc = "Retrieves the OCP firmware activation history log."; char *format = "normal"; - OPT_ARGS(options) = { + OPT_ARGS(opts) = { OPT_FMT("output-format", 'o', &format, "output format : normal | json"), OPT_END() }; - struct nvme_dev *dev = NULL; - int err = parse_and_open(&dev, argc, argv, description, options); + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct fw_activation_history fw_history = { 0 }; + struct nvme_passthru_cmd cmd; + __u8 uuid_index = 0; + int err; + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - __u8 uuid_index = 0; - /* * Best effort attempt at uuid. Otherwise, assume no index (i.e. 0) * Log GUID check will ensure correctness of returned data */ - ocp_get_uuid_index(dev, &uuid_index); - - struct fw_activation_history fw_history = { 0 }; - - struct nvme_get_log_args args = { - .lpo = 0, - .result = NULL, - .log = &fw_history, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = (enum nvme_cmd_get_log_lid)OCP_LID_FAHL_OBSOLETE, - .len = sizeof(fw_history), - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = 0, - .uuidx = uuid_index, - .rae = false, - .ot = false, - }; - - err = nvme_get_log(&args); - + ocp_get_uuid_index(hdl, &uuid_index); + nvme_init_get_log(&cmd, NVME_NSID_ALL, + (enum nvme_cmd_get_log_lid)OCP_LID_FAHL_OBSOLETE, + NVME_CSI_NVM, &fw_history, sizeof(fw_history)); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_index, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + err = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (err) nvme_show_status(err); - dev_close(dev); - int guid_cmp_res = memcmp(fw_history.log_page_guid, ocp_fw_activation_history_guid, sizeof(ocp_fw_activation_history_guid)); diff --git a/plugins/ocp/ocp-fw-activation-history.h b/plugins/ocp/ocp-fw-activation-history.h index fa37e4bd60..89a86f65da 100644 --- a/plugins/ocp/ocp-fw-activation-history.h +++ b/plugins/ocp/ocp-fw-activation-history.h @@ -40,7 +40,7 @@ struct __packed fw_activation_history { __le64 log_page_guid[2]; }; -int ocp_fw_activation_history_log(int argc, char **argv, struct command *cmd, +int ocp_fw_activation_history_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); #endif diff --git a/plugins/ocp/ocp-hardware-component-log.c b/plugins/ocp/ocp-hardware-component-log.c index 81473e2140..6a50839b63 100644 --- a/plugins/ocp/ocp-hardware-component-log.c +++ b/plugins/ocp/ocp-hardware-component-log.c @@ -167,29 +167,29 @@ const char *hwcomp_id_to_string(__u32 id) return "Reserved"; } -static int get_hwcomp_log_data(struct nvme_dev *dev, struct hwcomp_log *log) +static int get_hwcomp_log_data(struct nvme_transport_handle *hdl, struct hwcomp_log *log) { - int ret = 0; size_t desc_offset = offsetof(struct hwcomp_log, desc); - long double log_bytes; + struct nvme_passthru_cmd cmd; nvme_uint128_t log_size; + long double log_bytes; + __u32 len; + __u8 uidx; + int ret = 0; - struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = (enum nvme_cmd_get_log_lid)OCP_LID_HWCOMP, - .nsid = NVME_NSID_ALL, - .log = log, - .len = desc_offset, - }; - - ocp_get_uuid_index(dev, &args.uuidx); + ocp_get_uuid_index(hdl, &uidx); #ifdef HWCOMP_DUMMY memcpy(log, hwcomp_dummy, desc_offset); #else /* HWCOMP_DUMMY */ - ret = nvme_get_log_page(dev_fd(dev), NVME_LOG_PAGE_PDU_SIZE, &args); + nvme_init_get_log(&cmd, NVME_NSID_ALL, + (enum nvme_cmd_get_log_lid)OCP_LID_HWCOMP, + NVME_CSI_NVM, log, desc_offset); + cmd.cdw14 |= NVME_FIELD_ENCODE(uidx, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + ret = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (ret) { print_info_error("error: ocp: failed to get hwcomp log size (ret: %d)\n", ret); return ret; @@ -212,23 +212,25 @@ static int get_hwcomp_log_data(struct nvme_dev *dev, struct hwcomp_log *log) return -EINVAL; } - args.len = log_bytes - desc_offset; + len = log_bytes - desc_offset; - print_info("args.len: %u\n", args.len); + print_info("args.len: %u\n", len); - log->desc = calloc(1, args.len); + log->desc = calloc(1, len); if (!log->desc) { fprintf(stderr, "error: ocp: calloc: %s\n", strerror(errno)); return -errno; } - args.log = log->desc, - args.lpo = desc_offset, - #ifdef HWCOMP_DUMMY - memcpy(log->desc, &hwcomp_dummy[desc_offset], args.len); + memcpy(log->desc, &hwcomp_dummy[desc_offset], len); #else /* HWCOMP_DUMMY */ - ret = nvme_get_log_page(dev_fd(dev), NVME_LOG_PAGE_PDU_SIZE, &args); + nvme_init_get_log(&cmd, NVME_NSID_ALL, + (enum nvme_cmd_get_log_lid)OCP_LID_HWCOMP, + NVME_CSI_NVM, log->desc, len); + nvme_init_get_log_lpo(&cmd, desc_offset); + ret = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (ret) { print_info_error("error: ocp: failed to get log page (hwcomp: %02X, ret: %d)\n", OCP_LID_HWCOMP, ret); @@ -240,7 +242,7 @@ static int get_hwcomp_log_data(struct nvme_dev *dev, struct hwcomp_log *log) return ret; } -static int get_hwcomp_log(struct nvme_dev *dev, __u32 id, bool list) +static int get_hwcomp_log(struct nvme_transport_handle *hdl, __u32 id, bool list) { int ret; nvme_print_flags_t fmt; @@ -254,7 +256,7 @@ static int get_hwcomp_log(struct nvme_dev *dev, __u32 id, bool list) return ret; } - ret = get_hwcomp_log_data(dev, &log); + ret = get_hwcomp_log_data(hdl, &log); if (ret) { print_info_error("error: ocp: failed get hwcomp log: %02X data, ret: %d\n", OCP_LID_HWCOMP, ret); @@ -268,9 +270,10 @@ static int get_hwcomp_log(struct nvme_dev *dev, __u32 id, bool list) return 0; } -int ocp_hwcomp_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +int ocp_hwcomp_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = 0; const char *desc = "retrieve hardware component log"; struct config { @@ -300,11 +303,11 @@ int ocp_hwcomp_log(int argc, char **argv, struct command *cmd, struct plugin *pl NVME_ARGS(opts, OPT_LONG("comp-id", 'i', &cfg.id, id_desc, id), OPT_FLAG("list", 'l', &cfg.list, list_desc)); - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - ret = get_hwcomp_log(dev, cfg.id, cfg.list); + ret = get_hwcomp_log(hdl, cfg.id, cfg.list); if (ret) fprintf(stderr, "error: ocp: failed to get hwcomp log: %02X, ret: %d\n", OCP_LID_HWCOMP, ret); diff --git a/plugins/ocp/ocp-hardware-component-log.h b/plugins/ocp/ocp-hardware-component-log.h index 1755388fc6..9137d87df6 100644 --- a/plugins/ocp/ocp-hardware-component-log.h +++ b/plugins/ocp/ocp-hardware-component-log.h @@ -58,7 +58,7 @@ enum hwcomp_id { HWCOMP_ID_MAX = 0xffff, }; -int ocp_hwcomp_log(int argc, char **argv, struct command *cmd, struct plugin *plugin); +int ocp_hwcomp_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); const char *hwcomp_id_to_string(__u32 id); #endif /* OCP_HARDWARE_COMPONENT_LOG_H */ diff --git a/plugins/ocp/ocp-nvme.c b/plugins/ocp/ocp-nvme.c index 5151f9f81f..85a48cfef3 100644 --- a/plugins/ocp/ocp-nvme.c +++ b/plugins/ocp/ocp-nvme.c @@ -24,7 +24,6 @@ #include "util/types.h" #include "logging.h" #include "nvme-print.h" -#include "nvme-wrap.h" #include "ocp-smart-extended-log.h" #include "ocp-clear-features.h" @@ -196,7 +195,7 @@ static const char *nrtdp = "Number of reads to trigger device panic"; static const char *save = "Specifies that the controller shall save the attribute"; static const char *enable_ieee1667_silo = "enable IEEE1667 silo"; -static int get_c3_log_page(struct nvme_dev *dev, char *format) +static int get_c3_log_page(struct nvme_transport_handle *hdl, char *format) { struct ssd_latency_monitor_log *log_data; nvme_print_flags_t fmt; @@ -217,7 +216,7 @@ static int get_c3_log_page(struct nvme_dev *dev, char *format) } memset(data, 0, sizeof(__u8) * C3_LATENCY_MON_LOG_BUF_LEN); - ret = ocp_get_log_simple(dev, OCP_LID_LMLOG, C3_LATENCY_MON_LOG_BUF_LEN, data); + ret = ocp_get_log_simple(hdl, OCP_LID_LMLOG, C3_LATENCY_MON_LOG_BUF_LEN, data); if (strcmp(format, "json")) fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret); @@ -247,7 +246,7 @@ static int get_c3_log_page(struct nvme_dev *dev, char *format) goto out; } } - ocp_c3_log(dev, log_data, fmt); + ocp_c3_log(hdl, log_data, fmt); } else { fprintf(stderr, "ERROR : OCP : Unable to read C3 data from buffer\n"); } @@ -262,7 +261,8 @@ static int ocp_latency_monitor_log(int argc, char **argv, struct plugin *plugin) { const char *desc = "Retrieve latency monitor log data."; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = 0; struct config { @@ -279,24 +279,24 @@ static int ocp_latency_monitor_log(int argc, char **argv, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - ret = get_c3_log_page(dev, cfg.output_format); + ret = get_c3_log_page(hdl, cfg.output_format); if (ret) fprintf(stderr, "ERROR : OCP : Failure reading the C3 Log Page, ret = %d\n", ret); - dev_close(dev); return ret; } -int ocp_set_latency_monitor_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin) +int ocp_set_latency_monitor_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { int err = -1; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 result; struct feature_latency_monitor buf = { 0 }; __u32 nsid = NVME_NSID_ALL; @@ -355,23 +355,23 @@ int ocp_set_latency_monitor_feature(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = fstat(dev_fd(dev), &nvme_stat); + err = fstat(nvme_transport_handle_get_fd(hdl), &nvme_stat); if (err < 0) return err; if (S_ISBLK(nvme_stat.st_mode)) { - err = nvme_get_nsid(dev_fd(dev), &nsid); + err = nvme_get_nsid(hdl, &nsid); if (err < 0) { perror("invalid-namespace-id"); return err; } } - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) return err; @@ -386,20 +386,8 @@ int ocp_set_latency_monitor_feature(int argc, char **argv, struct command *cmd, buf.discard_debug_log = cfg.discard_debug_log; buf.latency_monitor_feature_enable = cfg.latency_monitor_feature_enable; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = OCP_FID_LM, - .nsid = 0, - .cdw12 = 0, - .save = 1, - .data_len = sizeof(struct feature_latency_monitor), - .data = (void *)&buf, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, OCP_FID_LM, 1, 0, 0, 0, 0, 0, (void *)&buf, + sizeof(struct feature_latency_monitor), &result); if (err < 0) { perror("set-feature"); } else if (!err) { @@ -423,14 +411,15 @@ int ocp_set_latency_monitor_feature(int argc, char **argv, struct command *cmd, return err; } -static int ocp_get_latency_monitor_feature(int argc, char **argv, struct command *cmd, +static int ocp_get_latency_monitor_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Define Issue Get Feature command (FID: 0xC5) Latency Monitor"; const char *sel = "[0-3]: current/default/saved/supported/"; const char *nsid = "Byte[04-07]: Namespace Identifier Valid/Invalid/Inactive"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 result; int err; @@ -454,7 +443,7 @@ static int ocp_get_latency_monitor_feature(int argc, char **argv, struct command OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -462,28 +451,15 @@ static int ocp_get_latency_monitor_feature(int argc, char **argv, struct command if (uuid) { /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &uuid_index); + err = ocp_get_uuid_index(hdl, &uuid_index); if (err || !uuid_index) { nvme_show_error("ERROR: No OCP UUID index found"); return err; } } - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = OCP_FID_LM, - .nsid = cfg.nsid, - .sel = cfg.sel, - .cdw11 = 0, - .uuidx = uuid_index, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_get_features(&args); + err = nvme_get_features(hdl, cfg.nsid, OCP_FID_LM, cfg.sel, 0, + uuid_index, NULL, 0, &result); if (!err) { printf("get-feature:0xC5 %s value: %#08x\n", nvme_select_to_string(cfg.sel), result); @@ -519,36 +495,23 @@ static const char *eol_plp_failure_mode_to_string(__u8 mode) return "Reserved"; } -static int eol_plp_failure_mode_get(struct nvme_dev *dev, const __u32 nsid, const __u8 fid, +static int eol_plp_failure_mode_get(struct nvme_transport_handle *hdl, const __u32 nsid, const __u8 fid, __u8 sel, bool uuid) { + __u8 uidx = 0; __u32 result; int err; - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .nsid = nsid, - .sel = sel, - .cdw11 = 0, - .uuidx = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - if (uuid) { /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &args.uuidx); - if (err || !args.uuidx) { + err = ocp_get_uuid_index(hdl, &uidx); + if (err || !uidx) { nvme_show_error("ERROR: No OCP UUID index found"); return err; } } - err = nvme_get_features(&args); + err = nvme_get_features(hdl, nsid, fid, sel, 0, uidx, NULL, 0, &result); if (!err) { nvme_show_result("End of Life Behavior (feature: %#0*x): %#0*x (%s: %s)", fid ? 4 : 2, fid, result ? 10 : 8, result, @@ -563,40 +526,25 @@ static int eol_plp_failure_mode_get(struct nvme_dev *dev, const __u32 nsid, cons return err; } -static int eol_plp_failure_mode_set(struct nvme_dev *dev, const __u32 nsid, - const __u8 fid, __u8 mode, bool save, +static int eol_plp_failure_mode_set(struct nvme_transport_handle *hdl, const __u32 nsid, + const __u8 fid, __u8 mode, bool sv, bool uuid) { __u32 result; int err; - __u8 uuid_index = 0; + __u8 uidx = 0; if (uuid) { /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &uuid_index); - if (err || !uuid_index) { + err = ocp_get_uuid_index(hdl, &uidx); + if (err || !uidx) { nvme_show_error("ERROR: No OCP UUID index found"); return err; } } - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .nsid = nsid, - .cdw11 = mode << 30, - .cdw12 = 0, - .save = save, - .uuidx = uuid_index, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_set_features(&args); + err = nvme_set_features(hdl, nsid, fid, sv, mode << 30, 0, 0, uidx, 0, NULL, + 0, &result); if (err > 0) { nvme_show_status(err); } else if (err < 0) { @@ -605,14 +553,14 @@ static int eol_plp_failure_mode_set(struct nvme_dev *dev, const __u32 nsid, } else { nvme_show_result("Successfully set mode (feature: %#0*x): %#0*x (%s: %s).", fid ? 4 : 2, fid, mode ? 10 : 8, mode, - save ? "Save" : "Not save", + sv ? "Save" : "Not save", eol_plp_failure_mode_to_string(mode)); } return err; } -static int eol_plp_failure_mode(int argc, char **argv, struct command *cmd, +static int eol_plp_failure_mode(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Define EOL or PLP circuitry failure mode.\n" @@ -620,7 +568,8 @@ static int eol_plp_failure_mode(int argc, char **argv, struct command *cmd, const char *mode = "[0-3]: default/rom/wtm/normal"; const __u32 nsid = 0; const __u8 fid = OCP_FID_ROWTM; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; struct config { @@ -641,20 +590,18 @@ static int eol_plp_failure_mode(int argc, char **argv, struct command *cmd, OPT_BYTE("sel", 'S', &cfg.sel, sel), OPT_FLAG("no-uuid", 'n', NULL, no_uuid)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; if (argconfig_parse_seen(opts, "mode")) - err = eol_plp_failure_mode_set(dev, nsid, fid, cfg.mode, + err = eol_plp_failure_mode_set(hdl, nsid, fid, cfg.mode, cfg.save, !argconfig_parse_seen(opts, "no-uuid")); else - err = eol_plp_failure_mode_get(dev, nsid, fid, cfg.sel, + err = eol_plp_failure_mode_get(hdl, nsid, fid, cfg.sel, !argconfig_parse_seen(opts, "no-uuid")); - dev_close(dev); - return err; } @@ -722,7 +669,7 @@ static void print_telemetry_header(struct telemetry_initiated_log *logheader, in } } -static int get_telemetry_data(struct nvme_dev *dev, __u32 ns, __u8 tele_type, +static int get_telemetry_data(struct nvme_transport_handle *hdl, __u32 ns, __u8 tele_type, __u32 data_len, void *data, __u8 nLSP, __u8 nRAE, __u64 offset) { @@ -741,7 +688,7 @@ static int get_telemetry_data(struct nvme_dev *dev, __u32 ns, __u8 tele_type, cmd.cdw12 = (__u32)(0x00000000FFFFFFFF & offset); cmd.cdw13 = (__u32)((0xFFFFFFFF00000000 & offset) >> 8); cmd.cdw14 = 0; - return nvme_submit_admin_passthru(dev_fd(dev), &cmd, NULL); + return nvme_submit_admin_passthru(hdl, &cmd, NULL); } static void print_telemetry_data_area_1(struct telemetry_data_area_1 *da1, @@ -861,7 +808,7 @@ static void print_telemetry_da_fifo(struct telemetry_event_desc *da_fifo, printf("===============================================\n\n"); } } -static int extract_dump_get_log(struct nvme_dev *dev, char *featurename, char *filename, char *sn, +static int extract_dump_get_log(struct nvme_transport_handle *hdl, char *featurename, char *filename, char *sn, int dumpsize, int transfersize, __u32 nsid, __u8 log_id, __u8 lsp, __u64 offset, bool rae) { @@ -872,6 +819,7 @@ static int extract_dump_get_log(struct nvme_dev *dev, char *featurename, char *f int output = 0; int total_loop_cnt = dumpsize / transfersize; int last_xfer_size = dumpsize % transfersize; + struct nvme_passthru_cmd cmd; if (last_xfer_size) total_loop_cnt++; @@ -886,24 +834,10 @@ static int extract_dump_get_log(struct nvme_dev *dev, char *featurename, char *f for (i = 0; i < total_loop_cnt; i++) { memset(data, 0, transfersize); - struct nvme_get_log_args args = { - .lpo = offset, - .result = NULL, - .log = (void *)data, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .lid = log_id, - .len = transfersize, - .nsid = nsid, - .lsp = lsp, - .uuidx = 0, - .rae = rae, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .csi = NVME_CSI_NVM, - .ot = false, - }; - - err = nvme_get_log(&args); + nvme_init_get_log(&cmd, nsid, log_id, NVME_CSI_NVM, + data, transfersize); + nvme_init_get_log_lpo(&cmd, offset); + err = nvme_get_log(hdl, &cmd, rae, NVME_LOG_PAGE_PDU_SIZE, NULL); if (err) { if (i > 0) goto close_output; @@ -942,7 +876,7 @@ static int extract_dump_get_log(struct nvme_dev *dev, char *featurename, char *f return err; } -static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn, +static int get_telemetry_dump(struct nvme_transport_handle *hdl, char *filename, char *sn, enum TELEMETRY_TYPE tele_type, int data_area, bool header_print) { __u32 err = 0, nsid = 0; @@ -975,7 +909,7 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn, } /* Get the telemetry header */ - err = get_telemetry_data(dev, nsid, tele_type, TELEMETRY_HEADER_SIZE, (void *)data, lsp, + err = get_telemetry_data(hdl, nsid, tele_type, TELEMETRY_HEADER_SIZE, (void *)data, lsp, rae, 0); if (err) { printf("get_telemetry_header failed, err: %d.\n", err); @@ -986,7 +920,7 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn, print_telemetry_header(logheader, tele_type); /* Get the telemetry data */ - err = get_telemetry_data(dev, nsid, tele_type, TELEMETRY_DATA_SIZE, (void *)data1, lsp, + err = get_telemetry_data(hdl, nsid, tele_type, TELEMETRY_DATA_SIZE, (void *)data1, lsp, rae, 512); if (err) { printf("get_telemetry_data failed for type: 0x%x, err: %d.\n", tele_type, err); @@ -1032,7 +966,7 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn, char *da1_stat = calloc(da1_sz, sizeof(char)); - err = get_telemetry_data(dev, nsid, tele_type, da1_sz, (void *)da1_stat, lsp, rae, + err = get_telemetry_data(hdl, nsid, tele_type, da1_sz, (void *)da1_stat, lsp, rae, da1_off); if (err) { printf("get_telemetry_data da1 stats failed, err: %d.\n", err); @@ -1083,7 +1017,7 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn, printf("Get DA 1 FIFO addr: %p, offset 0x%"PRIx64"\n", da1_fifo, (uint64_t)da1_off); - err = get_telemetry_data(dev, nsid, tele_type, + err = get_telemetry_data(hdl, nsid, tele_type, le64_to_cpu(da1->event_fifos[i].size) * 4, (void *)da1_fifo, lsp, rae, da1_off); if (err) { @@ -1140,7 +1074,7 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn, char *da2_stat = calloc(da1_sz, sizeof(char)); - err = get_telemetry_data(dev, nsid, tele_type, da1_sz, (void *)da2_stat, lsp, rae, + err = get_telemetry_data(hdl, nsid, tele_type, da1_sz, (void *)da2_stat, lsp, rae, da1_off); if (err) { printf("get_telemetry_data da2 stats failed, err: %d.\n", err); @@ -1189,7 +1123,7 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn, char *da1_fifo = calloc(da1_sz, sizeof(char)); - err = get_telemetry_data(dev, nsid, tele_type, + err = get_telemetry_data(hdl, nsid, tele_type, le64_to_cpu(da1->event_fifos[i].size) * 4, (void *)da1_fifo, lsp, rae, da1_off); if (err) { @@ -1231,18 +1165,19 @@ static int get_telemetry_dump(struct nvme_dev *dev, char *filename, char *sn, } snprintf(dumpname, FILE_NAME_SIZE, "Telemetry_%s_Area_%d", featurename, data_area); - err = extract_dump_get_log(dev, dumpname, filename, sn, size * TELEMETRY_BYTE_PER_BLOCK, + err = extract_dump_get_log(hdl, dumpname, filename, sn, size * TELEMETRY_BYTE_PER_BLOCK, TELEMETRY_TRANSFER_SIZE, nsid, tele_type, 0, offset, rae); return err; } -static int get_telemetry_log_page_data(struct nvme_dev *dev, int tele_type) +static int get_telemetry_log_page_data(struct nvme_transport_handle *hdl, int tele_type) { char file_path[PATH_MAX]; void *telemetry_log; const size_t bs = 512; struct nvme_telemetry_log *hdr; + struct nvme_passthru_cmd cmd; size_t full_size, offset = bs; int err, fd; @@ -1271,25 +1206,11 @@ static int get_telemetry_log_page_data(struct nvme_dev *dev, int tele_type) goto exit_status; } - struct nvme_get_log_args args = { - .lpo = 0, - .result = NULL, - .log = hdr, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = log_id, - .len = bs, - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_TELEM_HOST_LSP_CREATE, - .uuidx = NVME_UUID_NONE, - .rae = true, - .ot = false, - }; - - err = nvme_get_log(&args); + nvme_init_get_log(&cmd, NVME_NSID_ALL, log_id, NVME_CSI_NVM, hdr, bs); + cmd.cdw10 |= NVME_FIELD_ENCODE(NVME_LOG_TELEM_HOST_LSP_CREATE, + NVME_LOG_CDW10_LSP_SHIFT, + NVME_LOG_CDW10_LSP_MASK); + err = nvme_get_log(hdl, &cmd, false, NVME_LOG_PAGE_PDU_SIZE, NULL); if (err < 0) nvme_show_error("Failed to fetch the log from drive.\n"); else if (err > 0) { @@ -1307,10 +1228,10 @@ static int get_telemetry_log_page_data(struct nvme_dev *dev, int tele_type) full_size = (le16_to_cpu(hdr->dalb3) * bs) + offset; while (offset != full_size) { - args.log = telemetry_log; - args.lpo = offset; - args.lsp = NVME_LOG_LSP_NONE; - err = nvme_get_log(&args); + nvme_init_get_log(&cmd, NVME_NSID_ALL, log_id, NVME_CSI_NVM, + telemetry_log, bs); + nvme_init_get_log_lpo(&cmd, offset); + err = nvme_get_log(hdl, &cmd, false, NVME_LOG_PAGE_PDU_SIZE, NULL); if (err < 0) { nvme_show_error("Failed to fetch the log from drive.\n"); break; @@ -1338,7 +1259,7 @@ static int get_telemetry_log_page_data(struct nvme_dev *dev, int tele_type) return err; } -static int get_c9_log_page_data(struct nvme_dev *dev, int print_data, int save_bin) +static int get_c9_log_page_data(struct nvme_transport_handle *hdl, int print_data, int save_bin) { int ret = 0; __le64 stat_id_str_table_ofst = 0; @@ -1356,7 +1277,7 @@ static int get_c9_log_page_data(struct nvme_dev *dev, int print_data, int save_b } memset(header_data, 0, sizeof(__u8) * C9_TELEMETRY_STR_LOG_LEN); - ret = ocp_get_log_simple(dev, OCP_LID_TELSLG, C9_TELEMETRY_STR_LOG_LEN, header_data); + ret = ocp_get_log_simple(hdl, OCP_LID_TELSLG, C9_TELEMETRY_STR_LOG_LEN, header_data); if (!ret) { log_data = (struct telemetry_str_log_format *)header_data; @@ -1398,7 +1319,7 @@ static int get_c9_log_page_data(struct nvme_dev *dev, int print_data, int save_b } memset(pC9_string_buffer, 0, sizeof(__u8) * total_log_page_sz); - ret = ocp_get_log_simple(dev, OCP_LID_TELSLG, total_log_page_sz, pC9_string_buffer); + ret = ocp_get_log_simple(hdl, OCP_LID_TELSLG, total_log_page_sz, pC9_string_buffer); } else { fprintf(stderr, "ERROR : OCP : Unable to read C9 data.\n"); } @@ -1476,7 +1397,7 @@ int parse_ocp_telemetry_log(struct ocp_telemetry_parse_options *options) return 0; } -static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int ocp_telemetry_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve and parse OCP Telemetry log."; const char *telemetry_log = "Telemetry log binary;\n 'host.bin' or 'controller.bin'"; @@ -1489,7 +1410,8 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct "e.g. '-a 1 for Data Area 1.'\n'-a 2 for Data Areas 1 and 2.';\n"; const char *telemetry_type = "Telemetry Type; 'host', 'host0', 'host1' or 'controller'"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err = 0; __u32 nsid = NVME_NSID_ALL; struct stat nvme_stat; @@ -1510,24 +1432,24 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; if (opt.telemetry_type == 0) opt.telemetry_type = "host"; - err = fstat(dev_fd(dev), &nvme_stat); + err = fstat(nvme_transport_handle_get_fd(hdl), &nvme_stat); if (err < 0) return err; if (S_ISBLK(nvme_stat.st_mode)) { - err = nvme_get_nsid(dev_fd(dev), &nsid); + err = nvme_get_nsid(hdl, &nsid); if (err < 0) return err; } - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) return err; @@ -1567,7 +1489,7 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct if (!opt.telemetry_log) { nvme_show_result("\nMissing telemetry-log. Fetching from drive...\n"); - err = get_telemetry_log_page_data(dev, tele_type);//Pull Telemetry log + err = get_telemetry_log_page_data(hdl, tele_type);//Pull Telemetry log if (err) { nvme_show_error("Failed to fetch telemetry-log from the drive.\n"); goto out; @@ -1578,7 +1500,7 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct if (!opt.string_log) { nvme_show_result("Missing string-log. Fetching from drive...\n"); - err = get_c9_log_page_data(dev, 0, 1); //Pull String log + err = get_c9_log_page_data(hdl, 0, 1); //Pull String log if (err) { nvme_show_error("Failed to fetch string-log from the drive.\n"); goto out; @@ -1613,7 +1535,7 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct printf("Extracting Telemetry Host(%d) Dump (Data Area %d)...\n", (tele_type == TELEMETRY_TYPE_HOST_0) ? 0 : 1, tele_area); - err = get_telemetry_dump(dev, opt.output_file, sn, tele_type, tele_area, true); + err = get_telemetry_dump(hdl, opt.output_file, sn, tele_type, tele_area, true); if (err) fprintf(stderr, "NVMe Status: %s(%x)\n", nvme_status_to_string(err, false), err); @@ -1622,7 +1544,6 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd, struct printf("ocp internal-log command completed.\n"); out: - dev_close(dev); return err; } @@ -1643,10 +1564,10 @@ static __u8 unsupported_req_guid[GUID_LEN] = { }; /* Function declaration for unsupported requirement log page (LID:C5h) */ -static int ocp_unsupported_requirements_log(int argc, char **argv, struct command *cmd, +static int ocp_unsupported_requirements_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); -static int get_c5_log_page(struct nvme_dev *dev, char *format) +static int get_c5_log_page(struct nvme_transport_handle *hdl, char *format) { nvme_print_flags_t fmt; int ret; @@ -1668,7 +1589,7 @@ static int get_c5_log_page(struct nvme_dev *dev, char *format) } memset(data, 0, sizeof(__u8) * C5_UNSUPPORTED_REQS_LEN); - ret = ocp_get_log_simple(dev, OCP_LID_URLP, C5_UNSUPPORTED_REQS_LEN, data); + ret = ocp_get_log_simple(hdl, OCP_LID_URLP, C5_UNSUPPORTED_REQS_LEN, data); if (!ret) { log_data = (struct unsupported_requirement_log *)data; @@ -1691,7 +1612,7 @@ static int get_c5_log_page(struct nvme_dev *dev, char *format) goto out; } } - ocp_c5_log(dev, log_data, fmt); + ocp_c5_log(hdl, log_data, fmt); } else { fprintf(stderr, "ERROR : OCP : Unable to read C3 data from buffer\n"); } @@ -1701,11 +1622,12 @@ static int get_c5_log_page(struct nvme_dev *dev, char *format) return ret; } -static int ocp_unsupported_requirements_log(int argc, char **argv, struct command *cmd, +static int ocp_unsupported_requirements_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve unsupported requirements log data."; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = 0; struct config { @@ -1721,15 +1643,14 @@ static int ocp_unsupported_requirements_log(int argc, char **argv, struct comman OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - ret = get_c5_log_page(dev, cfg.output_format); + ret = get_c5_log_page(hdl, cfg.output_format); if (ret) fprintf(stderr, "ERROR : OCP : Failure reading the C5 Log Page, ret = %d\n", ret); - dev_close(dev); return ret; } @@ -1748,10 +1669,10 @@ static __u8 error_recovery_guid[GUID_LEN] = { 0xba, 0x83, 0x19, 0x5a }; -static int get_c1_log_page(struct nvme_dev *dev, char *format); -static int ocp_error_recovery_log(int argc, char **argv, struct command *cmd, struct plugin *plugin); +static int get_c1_log_page(struct nvme_transport_handle *hdl, char *format); +static int ocp_error_recovery_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); -static int get_c1_log_page(struct nvme_dev *dev, char *format) +static int get_c1_log_page(struct nvme_transport_handle *hdl, char *format) { struct ocp_error_recovery_log_page *log_data; nvme_print_flags_t fmt; @@ -1772,7 +1693,7 @@ static int get_c1_log_page(struct nvme_dev *dev, char *format) } memset(data, 0, sizeof(__u8) * C1_ERROR_RECOVERY_LOG_BUF_LEN); - ret = ocp_get_log_simple(dev, OCP_LID_EREC, C1_ERROR_RECOVERY_LOG_BUF_LEN, data); + ret = ocp_get_log_simple(hdl, OCP_LID_EREC, C1_ERROR_RECOVERY_LOG_BUF_LEN, data); if (!ret) { log_data = (struct ocp_error_recovery_log_page *)data; @@ -1806,10 +1727,11 @@ static int get_c1_log_page(struct nvme_dev *dev, char *format) return ret; } -static int ocp_error_recovery_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int ocp_error_recovery_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve C1h Error Recovery Log data."; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = 0; struct config { @@ -1825,14 +1747,14 @@ static int ocp_error_recovery_log(int argc, char **argv, struct command *cmd, st OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - ret = get_c1_log_page(dev, cfg.output_format); + ret = get_c1_log_page(hdl, cfg.output_format); if (ret) fprintf(stderr, "ERROR : OCP : Failure reading the C1h Log Page, ret = %d\n", ret); - dev_close(dev); + return ret; } @@ -1850,10 +1772,10 @@ static __u8 dev_cap_req_guid[GUID_LEN] = { 0x91, 0x3c, 0x05, 0xb7 }; -static int get_c4_log_page(struct nvme_dev *dev, char *format); -static int ocp_device_capabilities_log(int argc, char **argv, struct command *cmd, struct plugin *plugin); +static int get_c4_log_page(struct nvme_transport_handle *hdl, char *format); +static int ocp_device_capabilities_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); -static int get_c4_log_page(struct nvme_dev *dev, char *format) +static int get_c4_log_page(struct nvme_transport_handle *hdl, char *format) { struct ocp_device_capabilities_log_page *log_data; nvme_print_flags_t fmt; @@ -1874,7 +1796,7 @@ static int get_c4_log_page(struct nvme_dev *dev, char *format) } memset(data, 0, sizeof(__u8) * C4_DEV_CAP_REQ_LEN); - ret = ocp_get_log_simple(dev, OCP_LID_DCLP, C4_DEV_CAP_REQ_LEN, data); + ret = ocp_get_log_simple(hdl, OCP_LID_DCLP, C4_DEV_CAP_REQ_LEN, data); if (!ret) { log_data = (struct ocp_device_capabilities_log_page *)data; @@ -1908,10 +1830,11 @@ static int get_c4_log_page(struct nvme_dev *dev, char *format) return ret; } -static int ocp_device_capabilities_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int ocp_device_capabilities_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve C4h Device Capabilities Log data."; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = 0; struct config { @@ -1927,14 +1850,14 @@ static int ocp_device_capabilities_log(int argc, char **argv, struct command *cm OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - ret = get_c4_log_page(dev, cfg.output_format); + ret = get_c4_log_page(hdl, cfg.output_format); if (ret) fprintf(stderr, "ERROR : OCP : Failure reading the C4h Log Page, ret = %d\n", ret); - dev_close(dev); + return ret; } @@ -1944,36 +1867,21 @@ static int ocp_device_capabilities_log(int argc, char **argv, struct command *cm /////////////////////////////////////////////////////////////////////////////// /// Set Telemetry Profile (Feature Identifier C8h) Set Feature -static int ocp_set_telemetry_profile(struct nvme_dev *dev, __u8 tps) +static int ocp_set_telemetry_profile(struct nvme_transport_handle *hdl, __u8 tps) { __u32 result; int err; - __u8 uuid_index = 0; + __u8 uidx = 0; /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &uuid_index); - if (err || !uuid_index) { + err = ocp_get_uuid_index(hdl, &uidx); + if (err || !uidx) { nvme_show_error("ERROR: No OCP UUID index found"); return err; } - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = OCP_FID_TEL_CFG, - .nsid = 0xFFFFFFFF, - .cdw11 = tps, - .cdw12 = 0, - .save = true, - .uuidx = uuid_index, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0xFFFFFFFF, OCP_FID_TEL_CFG, true, tps, 0, 0, + uidx, 0, NULL, 0, &result); if (err > 0) { nvme_show_status(err); } else if (err < 0) { @@ -1987,12 +1895,13 @@ static int ocp_set_telemetry_profile(struct nvme_dev *dev, __u8 tps) return err; } -static int ocp_set_telemetry_profile_feature(int argc, char **argv, struct command *cmd, +static int ocp_set_telemetry_profile_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Set Telemetry Profile (Feature Identifier C8h) Set Feature."; const char *tps = "Telemetry Profile Select for device debug data collection"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; struct config { @@ -2008,17 +1917,15 @@ static int ocp_set_telemetry_profile_feature(int argc, char **argv, struct comma OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; if (argconfig_parse_seen(opts, "telemetry-profile-select")) - err = ocp_set_telemetry_profile(dev, cfg.tps); + err = ocp_set_telemetry_profile(hdl, cfg.tps); else nvme_show_error("Telemetry Profile Select is a required argument"); - dev_close(dev); - return err; } @@ -2027,14 +1934,15 @@ static int ocp_set_telemetry_profile_feature(int argc, char **argv, struct comma /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// /// DSSD Power State (Feature Identifier C8h) Get Feature -static int ocp_get_telemetry_profile_feature(int argc, char **argv, struct command *cmd, +static int ocp_get_telemetry_profile_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Define Issue Get Feature command (FID: 0xC8) Latency Monitor"; const char *sel = "[0-3]: current/default/saved/supported/"; const char *nsid = "Byte[04-07]: Namespace Identifier Valid/Invalid/Inactive"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 result; int err; @@ -2058,7 +1966,7 @@ static int ocp_get_telemetry_profile_feature(int argc, char **argv, struct comma OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -2066,28 +1974,15 @@ static int ocp_get_telemetry_profile_feature(int argc, char **argv, struct comma if (uuid) { /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &uuid_index); + err = ocp_get_uuid_index(hdl, &uuid_index); if (err || !uuid_index) { nvme_show_error("ERROR: No OCP UUID index found"); return err; } } - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = OCP_FID_TEL_CFG, - .nsid = cfg.nsid, - .sel = cfg.sel, - .cdw11 = 0, - .uuidx = uuid_index, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_get_features(&args); + err = nvme_get_features(hdl, cfg.nsid, OCP_FID_TEL_CFG, cfg.sel, 0, + uuid_index, NULL, 0, &result); if (!err) { printf("get-feature:0xC8 %s value: %#08x\n", nvme_select_to_string(cfg.sel), result); @@ -2107,40 +2002,27 @@ static int ocp_get_telemetry_profile_feature(int argc, char **argv, struct comma /////////////////////////////////////////////////////////////////////////////// /// DSSD Power State (Feature Identifier C7h) Set Feature -static int set_dssd_power_state(struct nvme_dev *dev, const __u32 nsid, - const __u8 fid, __u8 power_state, bool save, +static int +set_dssd_power_state(struct nvme_transport_handle *hdl, + const __u32 nsid, + const __u8 fid, __u8 power_state, bool sv, bool uuid) { __u32 result; int err; - __u8 uuid_index = 0; + __u8 uidx = 0; if (uuid) { /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &uuid_index); - if (err || !uuid_index) { + err = ocp_get_uuid_index(hdl, &uidx); + if (err || !uidx) { nvme_show_error("ERROR: No OCP UUID index found"); return err; } } - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .nsid = nsid, - .cdw11 = power_state, - .cdw12 = 0, - .save = save, - .uuidx = uuid_index, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_set_features(&args); + err = nvme_set_features(hdl, nsid, fid, sv, power_state, 0, 0, + uidx, 0, NULL, 0, &result); if (err > 0) { nvme_show_status(err); } else if (err < 0) { @@ -2149,20 +2031,21 @@ static int set_dssd_power_state(struct nvme_dev *dev, const __u32 nsid, } else { printf("Successfully set DSSD Power State (feature: 0xC7) to below values\n"); printf("DSSD Power State: 0x%x\n", power_state); - printf("Save bit Value: 0x%x\n", save); + printf("Save bit Value: 0x%x\n", sv); } return err; } -static int set_dssd_power_state_feature(int argc, char **argv, struct command *cmd, +static int set_dssd_power_state_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Define DSSD Power State (Feature Identifier C7h) Set Feature."; const char *power_state = "DSSD Power State to set in watts"; const char *save = "Specifies that the controller shall save the attribute"; const __u32 nsid = 0; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; struct config { @@ -2182,16 +2065,14 @@ static int set_dssd_power_state_feature(int argc, char **argv, struct command *c OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; if (argconfig_parse_seen(opts, "power-state")) - err = set_dssd_power_state(dev, nsid, OCP_FID_DSSDPS, cfg.power_state, cfg.save, + err = set_dssd_power_state(hdl, nsid, OCP_FID_DSSDPS, cfg.power_state, cfg.save, !argconfig_parse_seen(opts, "no-uuid")); - dev_close(dev); - return err; } @@ -2201,7 +2082,7 @@ static int set_dssd_power_state_feature(int argc, char **argv, struct command *c /////////////////////////////////////////////////////////////////////////////// /// DSSD Power State (Feature Identifier C7h) Get Feature -static int get_dssd_power_state(struct nvme_dev *dev, const __u32 nsid, +static int get_dssd_power_state(struct nvme_transport_handle *hdl, const __u32 nsid, const __u8 fid, __u8 sel, bool uuid) { __u32 result; @@ -2210,28 +2091,14 @@ static int get_dssd_power_state(struct nvme_dev *dev, const __u32 nsid, if (uuid) { /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &uuid_index); + err = ocp_get_uuid_index(hdl, &uuid_index); if (err || !uuid_index) { nvme_show_error("ERROR: No OCP UUID index found"); return err; } } - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .nsid = nsid, - .sel = sel, - .cdw11 = 0, - .uuidx = uuid_index, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_get_features(&args); + err = nvme_get_features(hdl, nsid, fid, sel, 0, uuid_index, NULL, 0, &result); if (!err) { printf("get-feature:0xC7 %s value: %#08x\n", nvme_select_to_string(sel), result); @@ -2244,7 +2111,7 @@ static int get_dssd_power_state(struct nvme_dev *dev, const __u32 nsid, return err; } -static int get_dssd_power_state_feature(int argc, char **argv, struct command *cmd, +static int get_dssd_power_state_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Define DSSD Power State (Feature Identifier C7h) Get Feature."; @@ -2252,7 +2119,8 @@ static int get_dssd_power_state_feature(int argc, char **argv, struct command *c const char *sel = "[0-3]: current/default/saved/supported/"; const __u32 nsid = 0; const __u8 fid = OCP_FID_DSSDPS; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int i, err; struct config { @@ -2272,25 +2140,23 @@ static int get_dssd_power_state_feature(int argc, char **argv, struct command *c OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; if (argconfig_parse_seen(opts, "all")) { for (i = 0; i < 3; i++) { - err = get_dssd_power_state(dev, nsid, fid, i, + err = get_dssd_power_state(hdl, nsid, fid, i, !argconfig_parse_seen(opts, "no-uuid")); if (err) break; } } else if (argconfig_parse_seen(opts, "sel")) - err = get_dssd_power_state(dev, nsid, fid, cfg.sel, + err = get_dssd_power_state(hdl, nsid, fid, cfg.sel, !argconfig_parse_seen(opts, "no-uuid")); else nvme_show_error("Required to have --sel as an argument, or pass the --all flag."); - dev_close(dev); - return err; } @@ -2300,68 +2166,54 @@ static int get_dssd_power_state_feature(int argc, char **argv, struct command *c /////////////////////////////////////////////////////////////////////////////// /// plp_health_check_interval -static int set_plp_health_check_interval(int argc, char **argv, struct command *cmd, +static int set_plp_health_check_interval(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Define Issue Set Feature command (FID : 0xC6) PLP Health Check Interval"; const char *plp_health_interval = "[31:16]:PLP Health Check Interval"; - const char *save = "Specifies that the controller shall save the attribute"; + const char *sv = "Specifies that the controller shall save the attribute"; const __u32 nsid = 0; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; __u32 result; - __u8 uuid_index = 0; + __u8 uidx = 0; struct config { __le16 plp_health_interval; - bool save; + bool sv; }; struct config cfg = { .plp_health_interval = 0, - .save = false, + .sv = false, }; OPT_ARGS(opts) = { OPT_BYTE("plp_health_interval", 'p', &cfg.plp_health_interval, plp_health_interval), - OPT_FLAG("save", 's', &cfg.save, save), + OPT_FLAG("save", 's', &cfg.sv, sv), OPT_FLAG("no-uuid", 'n', NULL, no_uuid), OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; if (!argconfig_parse_seen(opts, "no-uuid")) { /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &uuid_index); - if (err || !uuid_index) { + err = ocp_get_uuid_index(hdl, &uidx); + if (err || !uidx) { printf("ERROR: No OCP UUID index found"); return err; } } - - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = OCP_FID_PLPI, - .nsid = nsid, - .cdw11 = cfg.plp_health_interval << 16, - .cdw12 = 0, - .save = cfg.save, - .uuidx = uuid_index, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_set_features(&args); + err = nvme_set_features(hdl, nsid, OCP_FID_PLPI, cfg.sv, + cfg.plp_health_interval << 16, 0, 0, uidx, 0, NULL, 0, + &result); if (err > 0) { nvme_show_status(err); } else if (err < 0) { @@ -2370,19 +2222,20 @@ static int set_plp_health_check_interval(int argc, char **argv, struct command * } else { printf("Successfully set the PLP Health Check Interval"); printf("PLP Health Check Interval: 0x%x\n", cfg.plp_health_interval); - printf("Save bit Value: 0x%x\n", cfg.save); + printf("Save bit Value: 0x%x\n", cfg.sv); } return err; } -static int get_plp_health_check_interval(int argc, char **argv, struct command *cmd, +static int get_plp_health_check_interval(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Define Issue Get Feature command (FID : 0xC6) PLP Health Check Interval"; const __u32 nsid = 0; const __u8 fid = 0xc6; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 result; int err; @@ -2399,26 +2252,12 @@ static int get_plp_health_check_interval(int argc, char **argv, struct command * OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = OCP_FID_PLPI, - .nsid = nsid, - .sel = cfg.sel, - .cdw11 = 0, - .uuidx = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_get_features(&args); + err = nvme_get_features(hdl, nsid, OCP_FID_PLPI, cfg.sel, 0, 0, + NULL, 0, &result); if (!err) { printf("get-feature:0xC6 %s value: %#08x\n", nvme_select_to_string(cfg.sel), result); @@ -2437,63 +2276,49 @@ static int get_plp_health_check_interval(int argc, char **argv, struct command * /////////////////////////////////////////////////////////////////////////////// /// dssd_async_event_config -static int set_dssd_async_event_config(int argc, char **argv, struct command *cmd, +static int set_dssd_async_event_config(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Issue Set Feature command (FID : 0xC9) DSSD Async Event Config"; const char *epn = "[0]:Enable Panic Notices"; - const char *save = "Specifies that the controller shall save the attribute"; + const char *sv = "Specifies that the controller shall save the attribute"; const __u32 nsid = 0; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; __u32 result; - __u8 uuid_index = 0; + __u8 uidx = 0; struct config { bool epn; - bool save; + bool sv; }; struct config cfg = { .epn = false, - .save = false, + .sv = false, }; OPT_ARGS(opts) = { OPT_FLAG("enable-panic-notices", 'e', &cfg.epn, epn), - OPT_FLAG("save", 's', &cfg.save, save), + OPT_FLAG("save", 's', &cfg.sv, sv), OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &uuid_index); - if (err || !uuid_index) { + err = ocp_get_uuid_index(hdl, &uidx); + if (err || !uidx) { printf("ERROR: No OCP UUID index found\n"); return err; } - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = OCP_FID_DAEC, - .nsid = nsid, - .cdw11 = cfg.epn ? 1 : 0, - .cdw12 = 0, - .save = cfg.save, - .uuidx = uuid_index, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_set_features(&args); + err = nvme_set_features(hdl, nsid, OCP_FID_DAEC, cfg.sv, cfg.epn ? 1 : 0, + 0, 0, uidx, 0, NULL, 0, &result); if (err > 0) { nvme_show_status(err); } else if (err < 0) { @@ -2502,12 +2327,12 @@ static int set_dssd_async_event_config(int argc, char **argv, struct command *cm } else { printf("Successfully set the DSSD Asynchronous Event Configuration\n"); printf("Enable Panic Notices bit Value: 0x%x\n", cfg.epn); - printf("Save bit Value: 0x%x\n", cfg.save); + printf("Save bit Value: 0x%x\n", cfg.sv); } return err; } -static int get_dssd_async_event_config(int argc, char **argv, struct command *cmd, +static int get_dssd_async_event_config(int argc, char **argv, struct command *acmd, struct plugin *plugin) { @@ -2515,7 +2340,8 @@ static int get_dssd_async_event_config(int argc, char **argv, struct command *cm const char *sel = "[0-3]: current/default/saved/supported"; const __u32 nsid = 0; const __u8 fid = OCP_FID_DAEC; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 result; int err; @@ -2532,26 +2358,11 @@ static int get_dssd_async_event_config(int argc, char **argv, struct command *cm OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = fid, - .nsid = nsid, - .sel = cfg.sel, - .cdw11 = 0, - .uuidx = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_get_features(&args); + err = nvme_get_features(hdl, nsid, fid, cfg.sel, 0, 0, NULL, 0, &result); if (!err) { printf("get-feature:0xC9 %s value: %#08x\n", nvme_select_to_string(cfg.sel), result); @@ -2571,10 +2382,10 @@ static int get_dssd_async_event_config(int argc, char **argv, struct command *cm /// Telemetry String Log Format Log Page (LID : C9h) /* Function declaration for Telemetry String Log Format (LID:C9h) */ -static int ocp_telemetry_str_log_format(int argc, char **argv, struct command *cmd, +static int ocp_telemetry_str_log_format(int argc, char **argv, struct command *acmd, struct plugin *plugin); -static int get_c9_log_page(struct nvme_dev *dev, char *format) +static int get_c9_log_page(struct nvme_transport_handle *hdl, char *format) { int ret = 0; nvme_print_flags_t fmt; @@ -2586,9 +2397,9 @@ static int get_c9_log_page(struct nvme_dev *dev, char *format) } if (fmt == BINARY) - ret = get_c9_log_page_data(dev, 0, 1); + ret = get_c9_log_page_data(hdl, 0, 1); else - ret = get_c9_log_page_data(dev, 0, 0); + ret = get_c9_log_page_data(hdl, 0, 0); if (!ret) { ocp_c9_log(log_data, pC9_string_buffer, total_log_page_sz, fmt); @@ -2600,10 +2411,11 @@ static int get_c9_log_page(struct nvme_dev *dev, char *format) return ret; } -static int ocp_telemetry_str_log_format(int argc, char **argv, struct command *cmd, +static int ocp_telemetry_str_log_format(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = 0; const char *desc = "Retrieve telemetry string log format"; @@ -2621,16 +2433,14 @@ static int ocp_telemetry_str_log_format(int argc, char **argv, struct command *c OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - ret = get_c9_log_page(dev, cfg.output_format); + ret = get_c9_log_page(hdl, cfg.output_format); if (ret) fprintf(stderr, "ERROR : OCP : Failure reading the C9 Log Page, ret = %d\n", ret); - dev_close(dev); - return ret; } @@ -2651,10 +2461,10 @@ static __u8 tcg_configuration_guid[GUID_LEN] = { }; /* Function declaration for TCG Configuration log page (LID:C7h) */ -static int ocp_tcg_configuration_log(int argc, char **argv, struct command *cmd, +static int ocp_tcg_configuration_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); -static int get_c7_log_page(struct nvme_dev *dev, char *format) +static int get_c7_log_page(struct nvme_transport_handle *hdl, char *format) { nvme_print_flags_t fmt; int ret; @@ -2676,7 +2486,7 @@ static int get_c7_log_page(struct nvme_dev *dev, char *format) } memset(data, 0, sizeof(__u8) * C7_TCG_CONFIGURATION_LEN); - ret = ocp_get_log_simple(dev, OCP_LID_TCGL, C7_TCG_CONFIGURATION_LEN, data); + ret = ocp_get_log_simple(hdl, OCP_LID_TCGL, C7_TCG_CONFIGURATION_LEN, data); if (!ret) { log_data = (struct tcg_configuration_log *)data; @@ -2699,7 +2509,7 @@ static int get_c7_log_page(struct nvme_dev *dev, char *format) goto out; } } - ocp_c7_log(dev, log_data, fmt); + ocp_c7_log(hdl, log_data, fmt); } else { fprintf(stderr, "ERROR : OCP : Unable to read C7 data from buffer\n"); } @@ -2709,11 +2519,12 @@ static int get_c7_log_page(struct nvme_dev *dev, char *format) return ret; } -static int ocp_tcg_configuration_log(int argc, char **argv, struct command *cmd, +static int ocp_tcg_configuration_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve TCG Configuration Log Page Data"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = 0; struct config { @@ -2729,15 +2540,14 @@ static int ocp_tcg_configuration_log(int argc, char **argv, struct command *cmd, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - ret = get_c7_log_page(dev, cfg.output_format); + ret = get_c7_log_page(hdl, cfg.output_format); if (ret) fprintf(stderr, "ERROR : OCP : Failure reading the C7 Log Page, ret = %d\n", ret); - dev_close(dev); return ret; } @@ -2748,77 +2558,72 @@ static int ocp_tcg_configuration_log(int argc, char **argv, struct command *cmd, /// Misc static int clear_fw_update_history(int argc, char **argv, - struct command *cmd, struct plugin *plugin) + struct command *command, struct plugin *plugin) { - return ocp_clear_fw_update_history(argc, argv, cmd, plugin); + return ocp_clear_fw_update_history(argc, argv, command, plugin); } -static int smart_add_log(int argc, char **argv, struct command *cmd, +static int smart_add_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return ocp_smart_add_log(argc, argv, cmd, plugin); + return ocp_smart_add_log(argc, argv, acmd, plugin); } -static int clear_pcie_correctable_error_counters(int argc, char **argv, struct command *cmd, +static int clear_pcie_correctable_error_counters(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return ocp_clear_pcie_correctable_errors(argc, argv, cmd, plugin); + return ocp_clear_pcie_correctable_errors(argc, argv, acmd, plugin); } -static int get_clear_pcie_correctable_error_counters(int argc, char **argv, struct command *cmd, +static int get_clear_pcie_correctable_error_counters(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return get_ocp_error_counters(argc, argv, cmd, plugin); + return get_ocp_error_counters(argc, argv, acmd, plugin); } -static int fw_activation_history_log(int argc, char **argv, struct command *cmd, +static int fw_activation_history_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return ocp_fw_activation_history_log(argc, argv, cmd, plugin); + return ocp_fw_activation_history_log(argc, argv, acmd, plugin); } -static int error_injection_get(struct nvme_dev *dev, const __u8 sel, bool uuid) +static int error_injection_get(struct nvme_transport_handle *hdl, const __u8 sel, bool uuid) { struct erri_get_cq_entry cq_entry; + __u32 *result = (__u32 *)&cq_entry; + __u32 data_len = 0; + __u8 uidx = 0; int err; int i; const __u8 fid = OCP_FID_ERRI; _cleanup_free_ struct erri_entry *entry = NULL; - struct nvme_get_features_args args = { - .result = (__u32 *)&cq_entry, - .data = entry, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .sel = sel, - .data_len = sizeof(*entry) * ERRI_ENTRIES_MAX, - .fid = fid, - }; + data_len = sizeof(*entry) * ERRI_ENTRIES_MAX; if (uuid) { /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &args.uuidx); - if (err || !args.uuidx) { + err = ocp_get_uuid_index(hdl, &uidx); + if (err || !uidx) { nvme_show_error("ERROR: No OCP UUID index found"); return err; } } - entry = nvme_alloc(args.data_len); + entry = nvme_alloc(data_len); if (!entry) { nvme_show_error("malloc: %s", strerror(errno)); return -errno; } - err = nvme_cli_get_features(dev, &args); + err = nvme_get_features(hdl, 0, fid, sel, 0, uidx, entry, + data_len, result); if (!err) { nvme_show_result("Number of Error Injecttions (feature: %#0*x): %#0*x (%s: %d)", fid ? 4 : 2, fid, cq_entry.nume ? 10 : 8, cq_entry.nume, nvme_select_to_string(sel), cq_entry.nume); if (sel == NVME_GET_FEATURES_SEL_SUPPORTED) - nvme_show_select_result(fid, *args.result); + nvme_show_select_result(fid, *result); for (i = 0; i < cq_entry.nume; i++) { printf("Entry: %d, Flags: %x (%s%s), Type: %x (%s), NRTDP: %d\n", i, entry->flags, entry->enable ? "Enabled" : "Disabled", @@ -2832,7 +2637,7 @@ static int error_injection_get(struct nvme_dev *dev, const __u8 sel, bool uuid) return err; } -static int get_error_injection(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_error_injection(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Return set of error injection"; int err; @@ -2841,7 +2646,8 @@ static int get_error_injection(int argc, char **argv, struct command *cmd, struc }; struct config cfg = { 0 }; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; OPT_ARGS(opts) = { OPT_BYTE("sel", 's', &cfg.sel, sel), @@ -2849,26 +2655,19 @@ static int get_error_injection(int argc, char **argv, struct command *cmd, struc OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - return error_injection_get(dev, cfg.sel, !argconfig_parse_seen(opts, "no-uuid")); + return error_injection_get(hdl, cfg.sel, !argconfig_parse_seen(opts, "no-uuid")); } -static int error_injection_set(struct nvme_dev *dev, struct erri_config *cfg, bool uuid) +static int error_injection_set(struct nvme_transport_handle *hdl, struct erri_config *cfg, bool uuid) { int err; + __u8 uidx; __u32 result; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = OCP_FID_ERRI, - .cdw11 = cfg->number, - .data_len = cfg->number * sizeof(struct erri_entry), - .timeout = nvme_cfg.timeout, - .result = &result, - }; + __u32 data_len = cfg->number * sizeof(struct erri_entry); _cleanup_fd_ int ffd = -1; @@ -2876,14 +2675,14 @@ static int error_injection_set(struct nvme_dev *dev, struct erri_config *cfg, bo if (uuid) { /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &args.uuidx); - if (err || !args.uuidx) { + err = ocp_get_uuid_index(hdl, &uidx); + if (err || !uidx) { nvme_show_error("ERROR: No OCP UUID index found"); return err; } } - entry = nvme_alloc(args.data_len); + entry = nvme_alloc(data_len); if (!entry) { nvme_show_error("malloc: %s", strerror(errno)); return -errno; @@ -2895,7 +2694,7 @@ static int error_injection_set(struct nvme_dev *dev, struct erri_config *cfg, bo nvme_show_error("Failed to open file %s: %s", cfg->file, strerror(errno)); return -EINVAL; } - err = read(ffd, entry, args.data_len); + err = read(ffd, entry, data_len); if (err < 0) { nvme_show_error("failed to read data buffer from input file: %s", strerror(errno)); @@ -2908,9 +2707,8 @@ static int error_injection_set(struct nvme_dev *dev, struct erri_config *cfg, bo entry->nrtdp = cfg->nrtdp; } - args.data = entry; - - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, OCP_FID_ERRI, 0, cfg->number, + 0, 0, uidx, 0, entry, data_len, &result); if (err) { if (err < 0) nvme_show_error("set-error-injection: %s", nvme_strerror(errno)); @@ -2920,14 +2718,14 @@ static int error_injection_set(struct nvme_dev *dev, struct erri_config *cfg, bo } printf("set-error-injection, data: %s, number: %d, uuid: %d, type: %d, nrtdp: %d\n", - cfg->file, cfg->number, args.uuidx, cfg->type, cfg->nrtdp); - if (args.data) - d(args.data, args.data_len, 16, 1); + cfg->file, cfg->number, uidx, cfg->type, cfg->nrtdp); + if (entry) + d((unsigned char *)entry, data_len, 16, 1); return 0; } -static int set_error_injection(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int set_error_injection(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Inject error conditions"; int err; @@ -2935,7 +2733,8 @@ static int set_error_injection(int argc, char **argv, struct command *cmd, struc .number = 1, }; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; NVME_ARGS(opts, OPT_FILE("data", 'd', &cfg.file, data), @@ -2944,41 +2743,35 @@ static int set_error_injection(int argc, char **argv, struct command *cmd, struc OPT_SHRT("type", 't', &cfg.type, type), OPT_SHRT("nrtdp", 'r', &cfg.nrtdp, nrtdp)); - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - return error_injection_set(dev, &cfg, !argconfig_parse_seen(opts, "no-uuid")); + return error_injection_set(hdl, &cfg, !argconfig_parse_seen(opts, "no-uuid")); } -static int enable_ieee1667_silo_get(struct nvme_dev *dev, const __u8 sel, bool uuid) +static int enable_ieee1667_silo_get(struct nvme_transport_handle *hdl, const __u8 sel, bool uuid) { struct ieee1667_get_cq_entry cq_entry; + __u32 *result = (__u32 *)&cq_entry; + __u8 uidx = 0; int err; const __u8 fid = OCP_FID_1667; - struct nvme_get_features_args args = { - .result = (__u32 *)&cq_entry, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .sel = sel, - .fid = fid, - }; - if (uuid) { /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &args.uuidx); - if (err || !args.uuidx) { + err = ocp_get_uuid_index(hdl, &uidx); + if (err || !uidx) { nvme_show_error("ERROR: No OCP UUID index found"); return err; } } - err = nvme_cli_get_features(dev, &args); + err = nvme_get_features(hdl, 0, fid, sel, 0, uidx, NULL, 0, + result); if (!err) { if (sel == NVME_GET_FEATURES_SEL_SUPPORTED) - nvme_show_select_result(fid, *args.result); + nvme_show_select_result(fid, *result); else nvme_show_result("IEEE1667 Sifo Enabled (feature: 0x%02x): 0x%0x (%s: %s)", fid, cq_entry.enabled, nvme_select_to_string(sel), @@ -2990,7 +2783,7 @@ static int enable_ieee1667_silo_get(struct nvme_dev *dev, const __u8 sel, bool u return err; } -static int get_enable_ieee1667_silo(int argc, char **argv, struct command *cmd, +static int get_enable_ieee1667_silo(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "return set of enable IEEE1667 silo"; @@ -3000,7 +2793,8 @@ static int get_enable_ieee1667_silo(int argc, char **argv, struct command *cmd, }; struct config cfg = { 0 }; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; OPT_ARGS(opts) = { OPT_BYTE("sel", 's', &cfg.sel, sel), @@ -3008,62 +2802,57 @@ static int get_enable_ieee1667_silo(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - return enable_ieee1667_silo_get(dev, cfg.sel, !argconfig_parse_seen(opts, "no-uuid")); + return enable_ieee1667_silo_get(hdl, cfg.sel, !argconfig_parse_seen(opts, "no-uuid")); } -static int enable_ieee1667_silo_set(struct nvme_dev *dev, +static int enable_ieee1667_silo_set(struct nvme_transport_handle *hdl, struct argconfig_commandline_options *opts) { struct ieee1667_get_cq_entry cq_entry; int err; + __u8 uidx = 0; const __u8 fid = OCP_FID_1667; bool enable = argconfig_parse_seen(opts, "enable"); - - struct nvme_set_features_args args = { - .result = (__u32 *)&cq_entry, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .cdw11 = OCP_SET(enable, ENABLE_IEEE1667_SILO), - .save = argconfig_parse_seen(opts, "save"), - .fid = fid, - }; + bool sv = argconfig_parse_seen(opts, "save"); + __u32 cdw11 = OCP_SET(enable, ENABLE_IEEE1667_SILO); if (!argconfig_parse_seen(opts, "no-uuid")) { /* OCP 2.0 requires UUID index support */ - err = ocp_get_uuid_index(dev, &args.uuidx); - if (err || !args.uuidx) { + err = ocp_get_uuid_index(hdl, &uidx); + if (err || !uidx) { nvme_show_error("ERROR: No OCP UUID index found"); return err; } } - err = nvme_cli_set_features(dev, &args); + err = nvme_set_features(hdl, 0, fid, sv, cdw11, 0, 0, uidx, 0, NULL, 0, + (__u32 *)&cq_entry); if (err > 0) { nvme_show_status(err); } else if (err < 0) { nvme_show_perror(enable_ieee1667_silo); fprintf(stderr, "Command failed while parsing.\n"); } else { - enable = OCP_GET(args.cdw11, ENABLE_IEEE1667_SILO); + enable = OCP_GET(cdw11, ENABLE_IEEE1667_SILO); nvme_show_result("Successfully set enable (feature: 0x%02x): %d (%s: %s).", fid, - enable, args.save ? "Save" : "Not save", + enable, sv ? "Save" : "Not save", enable ? "Enabled" : "Disabled"); } return err; } -static int set_enable_ieee1667_silo(int argc, char **argv, struct command *cmd, +static int set_enable_ieee1667_silo(int argc, char **argv, struct command *acmd, struct plugin *plugin) { int err; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; OPT_ARGS(opts) = { OPT_FLAG("enable", 'e', NULL, no_uuid), @@ -3072,14 +2861,14 @@ static int set_enable_ieee1667_silo(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, enable_ieee1667_silo, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, enable_ieee1667_silo, opts); if (err) return err; - return enable_ieee1667_silo_set(dev, opts); + return enable_ieee1667_silo_set(hdl, opts); } -static int hwcomp_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int hwcomp_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return ocp_hwcomp_log(argc, argv, cmd, plugin); + return ocp_hwcomp_log(argc, argv, acmd, plugin); } diff --git a/plugins/ocp/ocp-print-binary.c b/plugins/ocp/ocp-print-binary.c index c966b4737f..50604296bc 100644 --- a/plugins/ocp/ocp-print-binary.c +++ b/plugins/ocp/ocp-print-binary.c @@ -15,7 +15,7 @@ static void binary_hwcomp_log(struct hwcomp_log *log, __u32 id, bool list) d_raw((unsigned char *)log, log_bytes); } -static void binary_c5_log(struct nvme_dev *dev, struct unsupported_requirement_log *log_data) +static void binary_c5_log(struct nvme_transport_handle *hdl, struct unsupported_requirement_log *log_data) { d_raw((unsigned char *)log_data, sizeof(*log_data)); } @@ -36,7 +36,7 @@ static void binary_c9_log(struct telemetry_str_log_format *log_data, __u8 *log_d d_raw((unsigned char *)log_data_buf, total_log_page_size); } -static void binary_c7_log(struct nvme_dev *dev, struct tcg_configuration_log *log_data) +static void binary_c7_log(struct nvme_transport_handle *hdl, struct tcg_configuration_log *log_data) { d_raw((unsigned char *)log_data, sizeof(*log_data)); } diff --git a/plugins/ocp/ocp-print-json.c b/plugins/ocp/ocp-print-json.c index e3ce2daf23..ee88f05f83 100644 --- a/plugins/ocp/ocp-print-json.c +++ b/plugins/ocp/ocp-print-json.c @@ -478,7 +478,7 @@ static void json_telemetry_log(struct ocp_telemetry_parse_options *options) print_ocp_telemetry_json(options); } -static void json_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *log_data) +static void json_c3_log(struct nvme_transport_handle *hdl, struct ssd_latency_monitor_log *log_data) { struct json_object *root; char ts_buf[128]; @@ -649,7 +649,7 @@ static void json_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *lo json_free_object(root); } -static void json_c5_log(struct nvme_dev *dev, struct unsupported_requirement_log *log_data) +static void json_c5_log(struct nvme_transport_handle *hdl, struct unsupported_requirement_log *log_data) { int j; struct json_object *root; @@ -1023,7 +1023,7 @@ static void json_c9_log(struct telemetry_str_log_format *log_data, __u8 *log_dat json_free_object(root); } -static void json_c7_log(struct nvme_dev *dev, struct tcg_configuration_log *log_data) +static void json_c7_log(struct nvme_transport_handle *hdl, struct tcg_configuration_log *log_data) { int j; struct json_object *root; diff --git a/plugins/ocp/ocp-print-stdout.c b/plugins/ocp/ocp-print-stdout.c index d63a318715..f99fbda6c3 100644 --- a/plugins/ocp/ocp-print-stdout.c +++ b/plugins/ocp/ocp-print-stdout.c @@ -246,14 +246,15 @@ static void stdout_telemetry_log(struct ocp_telemetry_parse_options *options) #endif /* CONFIG_JSONC */ } -static void stdout_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *log_data) +static void stdout_c3_log(struct nvme_transport_handle *hdl, struct ssd_latency_monitor_log *log_data) { char ts_buf[128]; int i, j; __u16 log_page_version = le16_to_cpu(log_data->log_page_version); printf("-Latency Monitor/C3 Log Page Data-\n"); - printf(" Controller : %s\n", dev->name); + printf(" Controller : %s\n", + nvme_transport_handle_get_name(hdl)); printf(" Feature Status 0x%x\n", log_data->feature_status); printf(" Active Bucket Timer %d min\n", @@ -384,7 +385,7 @@ static void stdout_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log * } } -static void stdout_c5_log(struct nvme_dev *dev, struct unsupported_requirement_log *log_data) +static void stdout_c5_log(struct nvme_transport_handle *hdl, struct unsupported_requirement_log *log_data) { int j; @@ -685,7 +686,7 @@ static void stdout_c9_log(struct telemetry_str_log_format *log_data, __u8 *log_d } } -static void stdout_c7_log(struct nvme_dev *dev, struct tcg_configuration_log *log_data) +static void stdout_c7_log(struct nvme_transport_handle *hdl, struct tcg_configuration_log *log_data) { int j; __u16 log_page_version = le16_to_cpu(log_data->log_page_version); diff --git a/plugins/ocp/ocp-print.c b/plugins/ocp/ocp-print.c index 31037db946..43acf729c2 100644 --- a/plugins/ocp/ocp-print.c +++ b/plugins/ocp/ocp-print.c @@ -47,16 +47,18 @@ void ocp_show_telemetry_log(struct ocp_telemetry_parse_options *options, nvme_pr ocp_print(telemetry_log, flags, options); } -void ocp_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *log_data, +void ocp_c3_log(struct nvme_transport_handle *hdl, + struct ssd_latency_monitor_log *log_data, nvme_print_flags_t flags) { - ocp_print(c3_log, flags, dev, log_data); + ocp_print(c3_log, flags, hdl, log_data); } -void ocp_c5_log(struct nvme_dev *dev, struct unsupported_requirement_log *log_data, +void ocp_c5_log(struct nvme_transport_handle *hdl, + struct unsupported_requirement_log *log_data, nvme_print_flags_t flags) { - ocp_print(c5_log, flags, dev, log_data); + ocp_print(c5_log, flags, hdl, log_data); } void ocp_c1_log(struct ocp_error_recovery_log_page *log_data, nvme_print_flags_t flags) @@ -75,8 +77,9 @@ void ocp_c9_log(struct telemetry_str_log_format *log_data, __u8 *log_data_buf, ocp_print(c9_log, flags, log_data, log_data_buf, total_log_page_size); } -void ocp_c7_log(struct nvme_dev *dev, struct tcg_configuration_log *log_data, +void ocp_c7_log(struct nvme_transport_handle *hdl, + struct tcg_configuration_log *log_data, nvme_print_flags_t flags) { - ocp_print(c7_log, flags, dev, log_data); + ocp_print(c7_log, flags, hdl, log_data); } diff --git a/plugins/ocp/ocp-print.h b/plugins/ocp/ocp-print.h index e9ede1c09e..35b9e10c1a 100644 --- a/plugins/ocp/ocp-print.h +++ b/plugins/ocp/ocp-print.h @@ -13,13 +13,13 @@ struct ocp_print_ops { void (*fw_act_history)(const struct fw_activation_history *fw_history); void (*smart_extended_log)(struct ocp_smart_extended_log *log, unsigned int version); void (*telemetry_log)(struct ocp_telemetry_parse_options *options); - void (*c3_log)(struct nvme_dev *dev, struct ssd_latency_monitor_log *log_data); - void (*c5_log)(struct nvme_dev *dev, struct unsupported_requirement_log *log_data); + void (*c3_log)(struct nvme_transport_handle *hdl, struct ssd_latency_monitor_log *log_data); + void (*c5_log)(struct nvme_transport_handle *hdl, struct unsupported_requirement_log *log_data); void (*c1_log)(struct ocp_error_recovery_log_page *log_data); void (*c4_log)(struct ocp_device_capabilities_log_page *log_data); void (*c9_log)(struct telemetry_str_log_format *log_data, __u8 *log_data_buf, int total_log_page_size); - void (*c7_log)(struct nvme_dev *dev, struct tcg_configuration_log *log_data); + void (*c7_log)(struct nvme_transport_handle *hdl, struct tcg_configuration_log *log_data); nvme_print_flags_t flags; }; @@ -40,14 +40,14 @@ void ocp_fw_act_history(const struct fw_activation_history *fw_history, nvme_pri void ocp_smart_extended_log(struct ocp_smart_extended_log *log, unsigned int version, nvme_print_flags_t flags); void ocp_show_telemetry_log(struct ocp_telemetry_parse_options *options, nvme_print_flags_t flags); -void ocp_c3_log(struct nvme_dev *dev, struct ssd_latency_monitor_log *log_data, +void ocp_c3_log(struct nvme_transport_handle *hdl, struct ssd_latency_monitor_log *log_data, nvme_print_flags_t flags); -void ocp_c5_log(struct nvme_dev *dev, struct unsupported_requirement_log *log_data, +void ocp_c5_log(struct nvme_transport_handle *hdl, struct unsupported_requirement_log *log_data, nvme_print_flags_t flags); void ocp_c1_log(struct ocp_error_recovery_log_page *log_data, nvme_print_flags_t flags); void ocp_c4_log(struct ocp_device_capabilities_log_page *log_data, nvme_print_flags_t flags); void ocp_c9_log(struct telemetry_str_log_format *log_data, __u8 *log_data_buf, int total_log_page_size, nvme_print_flags_t flags); -void ocp_c7_log(struct nvme_dev *dev, struct tcg_configuration_log *log_data, +void ocp_c7_log(struct nvme_transport_handle *hdl, struct tcg_configuration_log *log_data, nvme_print_flags_t flags); #endif /* OCP_PRINT_H */ diff --git a/plugins/ocp/ocp-smart-extended-log.c b/plugins/ocp/ocp-smart-extended-log.c index 5e081c969f..d2341356f4 100644 --- a/plugins/ocp/ocp-smart-extended-log.c +++ b/plugins/ocp/ocp-smart-extended-log.c @@ -26,21 +26,15 @@ static __u8 scao_guid[GUID_LEN] = { 0xC9, 0x14, 0xD5, 0xAF }; -static int get_c0_log_page(struct nvme_dev *dev, char *format, +static int get_c0_log_page(struct nvme_transport_handle *hdl, char *format, unsigned int format_version) { - nvme_print_flags_t fmt; struct ocp_smart_extended_log *data; - int i; + struct nvme_passthru_cmd cmd; + nvme_print_flags_t fmt; + __u8 uidx; int ret; - int fd = dev_fd(dev); - struct nvme_get_log_args args = { - .args_size = sizeof(args), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = (enum nvme_cmd_get_log_lid)OCP_LID_SMART, - .nsid = NVME_NSID_ALL, - .len = C0_SMART_CLOUD_ATTR_LEN, - }; + int i; ret = validate_output_format(format, &fmt); if (ret < 0) { @@ -55,9 +49,15 @@ static int get_c0_log_page(struct nvme_dev *dev, char *format, } memset(data, 0, sizeof(__u8) * C0_SMART_CLOUD_ATTR_LEN); - args.log = data; - ocp_get_uuid_index(dev, &args.uuidx); - ret = nvme_get_log_page(fd, NVME_LOG_PAGE_PDU_SIZE, &args); + ocp_get_uuid_index(hdl, &uidx); + nvme_init_get_log(&cmd, NVME_NSID_ALL, + (enum nvme_cmd_get_log_lid)OCP_LID_SMART, + NVME_CSI_NVM, data, C0_SMART_CLOUD_ATTR_LEN); + cmd.cdw14 |= NVME_FIELD_ENCODE(uidx, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + ret = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (strcmp(format, "json")) fprintf(stderr, "NVMe Status:%s(%x)\n", @@ -96,11 +96,12 @@ static int get_c0_log_page(struct nvme_dev *dev, char *format, return ret; } -int ocp_smart_add_log(int argc, char **argv, struct command *cmd, - struct plugin *plugin) +int ocp_smart_add_log(int argc, char **argv, struct command *acmd, + struct plugin *plugin) { const char *desc = "Retrieve the extended SMART health data."; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = 0; struct config { @@ -119,15 +120,14 @@ int ocp_smart_add_log(int argc, char **argv, struct command *cmd, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - ret = get_c0_log_page(dev, cfg.output_format, + ret = get_c0_log_page(hdl, cfg.output_format, cfg.output_format_version); if (ret) fprintf(stderr, "ERROR : OCP : Failure reading the C0 Log Page, ret = %d\n", ret); - dev_close(dev); return ret; } diff --git a/plugins/ocp/ocp-smart-extended-log.h b/plugins/ocp/ocp-smart-extended-log.h index df338099bf..9ac52e508f 100644 --- a/plugins/ocp/ocp-smart-extended-log.h +++ b/plugins/ocp/ocp-smart-extended-log.h @@ -151,7 +151,7 @@ struct ocp_smart_extended_log { __u8 log_page_guid[16]; /* [511:496] */ }; -int ocp_smart_add_log(int argc, char **argv, struct command *cmd, +int ocp_smart_add_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); #endif diff --git a/plugins/ocp/ocp-utils.c b/plugins/ocp/ocp-utils.c index e3c0747fa9..665c0c2163 100644 --- a/plugins/ocp/ocp-utils.c +++ b/plugins/ocp/ocp-utils.c @@ -10,6 +10,7 @@ #include "util/types.h" #include "ocp-nvme.h" #include "ocp-utils.h" +#include "types.h" const unsigned char ocp_uuid[NVME_UUID_LEN] = { 0xc1, 0x94, 0xd5, 0x5b, 0xe0, 0x94, 0x47, 0x94, 0xa2, 0x1d, @@ -28,34 +29,32 @@ int ocp_find_uuid_index(struct nvme_id_uuid_list *uuid_list, __u8 *index) return 0; } -int ocp_get_uuid_index(struct nvme_dev *dev, __u8 *index) +int ocp_get_uuid_index(struct nvme_transport_handle *hdl, __u8 *index) { struct nvme_id_uuid_list uuid_list; - int err = nvme_identify_uuid(dev_fd(dev), &uuid_list); + int err; *index = 0; + + err = nvme_identify_uuid_list(hdl, &uuid_list); if (err) return err; return ocp_find_uuid_index(&uuid_list, index); } -int ocp_get_log_simple(struct nvme_dev *dev, enum ocp_dssd_log_id lid, __u32 len, void *log) +int ocp_get_log_simple(struct nvme_transport_handle *hdl, + enum ocp_dssd_log_id lid, __u32 len, void *log) { - int fd = dev_fd(dev); - struct nvme_get_log_args args = { - .log = log, - .args_size = sizeof(args), - .fd = fd, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = (enum nvme_cmd_get_log_lid)lid, - .len = len, - .nsid = NVME_NSID_ALL, - .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, - }; - - ocp_get_uuid_index(dev, &args.uuidx); - - return nvme_get_log_page(fd, NVME_LOG_PAGE_PDU_SIZE, &args); + struct nvme_passthru_cmd cmd; + __u8 uidx; + + ocp_get_uuid_index(hdl, &uidx); + nvme_init_get_log(&cmd, NVME_NSID_ALL, (enum nvme_cmd_get_log_lid) lid, + NVME_CSI_NVM, log, len); + cmd.cdw14 |= NVME_FIELD_ENCODE(uidx, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + + return nvme_get_log(hdl, &cmd, false, NVME_LOG_PAGE_PDU_SIZE, NULL); } diff --git a/plugins/ocp/ocp-utils.h b/plugins/ocp/ocp-utils.h index 9832474eac..58eef7b031 100644 --- a/plugins/ocp/ocp-utils.h +++ b/plugins/ocp/ocp-utils.h @@ -19,7 +19,7 @@ extern const unsigned char ocp_uuid[NVME_UUID_LEN]; * Return: Zero if nvme device has UUID list identify page, or positive result of get uuid list * or negative POSIX error code otherwise. */ -int ocp_get_uuid_index(struct nvme_dev *dev, __u8 *index); +int ocp_get_uuid_index(struct nvme_transport_handle *hdl, __u8 *index); /** * ocp_find_uuid_index() - Find OCP UUID index in UUID list @@ -30,4 +30,4 @@ int ocp_get_uuid_index(struct nvme_dev *dev, __u8 *index); */ int ocp_find_uuid_index(struct nvme_id_uuid_list *uuid_list, __u8 *index); -int ocp_get_log_simple(struct nvme_dev *dev, enum ocp_dssd_log_id lid, __u32 len, void *log); +int ocp_get_log_simple(struct nvme_transport_handle *hdl, enum ocp_dssd_log_id lid, __u32 len, void *log); diff --git a/plugins/sandisk/sandisk-nvme.c b/plugins/sandisk/sandisk-nvme.c index d552f8f342..39c8102af5 100644 --- a/plugins/sandisk/sandisk-nvme.c +++ b/plugins/sandisk/sandisk-nvme.c @@ -28,8 +28,10 @@ #include "sandisk-utils.h" #include "plugins/wdc/wdc-nvme-cmds.h" -static int sndk_do_cap_telemetry_log(struct nvme_dev *dev, const char *file, - __u32 bs, int type, int data_area) +static int sndk_do_cap_telemetry_log(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl, + const char *file, __u32 bs, int type, + int data_area) { struct nvme_telemetry_log *log; size_t full_size = 0; @@ -40,15 +42,14 @@ static int sndk_do_cap_telemetry_log(struct nvme_dev *dev, const char *file, int data_written = 0, data_remaining = 0; struct nvme_id_ctrl ctrl; __u64 capabilities = 0; - nvme_root_t r; bool host_behavior_changed = false; struct nvme_feat_host_behavior prev = {0}; + struct nvme_passthru_cmd cmd; __u32 result; - - + int ret; memset(&ctrl, 0, sizeof(struct nvme_id_ctrl)); - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) { fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", err); return err; @@ -59,8 +60,10 @@ static int sndk_do_cap_telemetry_log(struct nvme_dev *dev, const char *file, return -EINVAL; } - r = nvme_scan(NULL); - capabilities = sndk_get_drive_capabilities(r, dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret) + return ret; + capabilities = sndk_get_drive_capabilities(ctx, hdl); if (type == SNDK_TELEMETRY_TYPE_HOST) { host_gen = 1; @@ -72,19 +75,21 @@ static int sndk_do_cap_telemetry_log(struct nvme_dev *dev, const char *file, return -EINVAL; } - int err = nvme_get_features_host_behavior(dev_fd(dev), 0, &prev, &result); + nvme_init_get_features_host_behavior(&cmd, 0, &prev); + int err = nvme_submit_admin_passthru(hdl, &cmd, &result); if (!err && !prev.etdas) { struct nvme_feat_host_behavior da4_enable = prev; da4_enable.etdas = 1; - nvme_set_features_host_behavior(dev_fd(dev), 0, &da4_enable); + nvme_init_set_features_host_behavior(&cmd, 0, &da4_enable); + nvme_submit_admin_passthru(hdl, &cmd, NULL); host_behavior_changed = true; } } } else if (type == SNDK_TELEMETRY_TYPE_CONTROLLER) { if (capabilities & SNDK_DRIVE_CAP_INTERNAL_LOG) { - err = sndk_check_ctrl_telemetry_option_disabled(dev); + err = sndk_check_ctrl_telemetry_option_disabled(hdl); if (err) return err; } @@ -108,13 +113,13 @@ static int sndk_do_cap_telemetry_log(struct nvme_dev *dev, const char *file, } if (ctrl_init) - err = nvme_get_ctrl_telemetry(dev_fd(dev), true, &log, + err = nvme_get_ctrl_telemetry(hdl, true, &log, data_area, &full_size); else if (host_gen) - err = nvme_get_new_host_telemetry(dev_fd(dev), &log, + err = nvme_get_new_host_telemetry(hdl, &log, data_area, &full_size); else - err = nvme_get_host_telemetry(dev_fd(dev), &log, data_area, + err = nvme_get_host_telemetry(hdl, &log, data_area, &full_size); if (err < 0) { @@ -157,8 +162,10 @@ static int sndk_do_cap_telemetry_log(struct nvme_dev *dev, const char *file, err = -1; } - if (host_behavior_changed) - nvme_set_features_host_behavior(dev_fd(dev), 0, &prev); + if (host_behavior_changed) { + nvme_init_set_features_host_behavior(&cmd, 0, &prev); + nvme_submit_admin_passthru(hdl, &cmd, NULL); + } free(log); close_output: @@ -166,8 +173,8 @@ static int sndk_do_cap_telemetry_log(struct nvme_dev *dev, const char *file, return err; } -static __u32 sndk_dump_udui_data(int fd, __u32 dataLen, __u32 offset, - __u8 *dump_data) +static __u32 sndk_dump_udui_data(struct nvme_transport_handle *hdl, + __u32 dataLen, __u32 offset, __u8 *dump_data) { int ret; struct nvme_passthru_cmd admin_cmd; @@ -179,7 +186,7 @@ static __u32 sndk_dump_udui_data(int fd, __u32 dataLen, __u32 offset, admin_cmd.data_len = dataLen; admin_cmd.cdw10 = ((dataLen >> 2) - 1); admin_cmd.cdw12 = offset; - ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (ret) { fprintf(stderr, "ERROR: SNDK: reading DUI data failed\n"); nvme_show_status(ret); @@ -188,8 +195,9 @@ static __u32 sndk_dump_udui_data(int fd, __u32 dataLen, __u32 offset, return ret; } -static int sndk_do_cap_udui(int fd, char *file, __u32 xfer_size, int verbose, - __u64 file_size, __u64 offset) +static int sndk_do_cap_udui(struct nvme_transport_handle *hdl, char *file, + __u32 xfer_size, int verbose, __u64 file_size, + __u64 offset) { int ret = 0; int output; @@ -209,7 +217,7 @@ static int sndk_do_cap_udui(int fd, char *file, __u32 xfer_size, int verbose, memset(log, 0, udui_log_hdr_size); /* get the udui telemetry and log headers */ - ret = sndk_dump_udui_data(fd, udui_log_hdr_size, 0, (__u8 *)log); + ret = sndk_dump_udui_data(hdl, udui_log_hdr_size, 0, (__u8 *)log); if (ret) { fprintf(stderr, "%s: ERROR: SNDK: Get UDUI header failed\n", __func__); nvme_show_status(ret); @@ -238,7 +246,7 @@ static int sndk_do_cap_udui(int fd, char *file, __u32 xfer_size, int verbose, while (offset < total_size) { if (chunk_size > total_size - offset) chunk_size = total_size - offset; - ret = sndk_dump_udui_data(fd, chunk_size, offset, + ret = sndk_dump_udui_data(hdl, chunk_size, offset, ((__u8 *)log)); if (ret) { fprintf(stderr, @@ -290,8 +298,6 @@ static int sndk_vs_internal_fw_log(int argc, char **argv, const char *verbose = "Display more debug messages."; char f[PATH_MAX] = {0}; char fileSuffix[PATH_MAX] = {0}; - struct nvme_dev *dev; - nvme_root_t r; __u32 xfer_size = 0; int telemetry_type = 0, telemetry_data_area = 0; struct SNDK_UtilsTimeInfo timeInfo; @@ -299,6 +305,8 @@ static int sndk_vs_internal_fw_log(int argc, char **argv, __u64 capabilities = 0; __u32 device_id, read_vendor_id; int ret = -1; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct config { char *file; @@ -331,12 +339,12 @@ static int sndk_vs_internal_fw_log(int argc, char **argv, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); - if (!sndk_check_device(r, dev)) + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !sndk_check_device(ctx, hdl)) goto out; if (cfg.xfer_size) { @@ -346,7 +354,7 @@ static int sndk_vs_internal_fw_log(int argc, char **argv, goto out; } - ret = sndk_get_pci_ids(r, dev, &device_id, &read_vendor_id); + ret = sndk_get_pci_ids(ctx, hdl, &device_id, &read_vendor_id); if (cfg.file) { int verify_file; @@ -369,7 +377,7 @@ static int sndk_vs_internal_fw_log(int argc, char **argv, timeInfo.second); snprintf(fileSuffix, PATH_MAX, "_internal_fw_log_%s", (char *)timeStamp); - ret = sndk_get_serial_name(dev, f, PATH_MAX, fileSuffix); + ret = sndk_get_serial_name(hdl, f, PATH_MAX, fileSuffix); if (ret) { fprintf(stderr, "ERROR: SNDK: failed to generate file name\n"); goto out; @@ -410,7 +418,7 @@ static int sndk_vs_internal_fw_log(int argc, char **argv, goto out; } - capabilities = sndk_get_drive_capabilities(r, dev); + capabilities = sndk_get_drive_capabilities(ctx, hdl); /* Supported through WDC plugin for non-telemetry */ if ((capabilities & SNDK_DRIVE_CAP_INTERNAL_LOG) && @@ -419,7 +427,7 @@ static int sndk_vs_internal_fw_log(int argc, char **argv, if (!telemetry_data_area) telemetry_data_area = 3; - ret = sndk_do_cap_telemetry_log(dev, f, xfer_size, + ret = sndk_do_cap_telemetry_log(ctx, hdl, f, xfer_size, telemetry_type, telemetry_data_area); goto out; } @@ -431,11 +439,11 @@ static int sndk_vs_internal_fw_log(int argc, char **argv, if (!telemetry_data_area) telemetry_data_area = 3; - ret = sndk_do_cap_telemetry_log(dev, f, xfer_size, + ret = sndk_do_cap_telemetry_log(ctx, hdl, f, xfer_size, telemetry_type, telemetry_data_area); goto out; } else { - ret = sndk_do_cap_udui(dev_fd(dev), f, xfer_size, + ret = sndk_do_cap_udui(hdl, f, xfer_size, cfg.verbose, cfg.file_size, cfg.offset); goto out; @@ -443,13 +451,9 @@ static int sndk_vs_internal_fw_log(int argc, char **argv, } /* Fallback to WDC plugin if otherwise not supported */ - nvme_free_tree(r); - dev_close(dev); return run_wdc_vs_internal_fw_log(argc, argv, command, plugin); out: - nvme_free_tree(r); - dev_close(dev); return ret; } @@ -549,26 +553,28 @@ static int sndk_capabilities(int argc, char **argv, struct plugin *plugin) { const char *desc = "Send a capabilities command."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; uint64_t capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; int ret; OPT_ARGS(opts) = { OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; /* get capabilities */ - r = nvme_scan(NULL); - sndk_check_device(r, dev); - capabilities = sndk_get_drive_capabilities(r, dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || sndk_check_device(ctx, hdl)) + return -1; + + capabilities = sndk_get_drive_capabilities(ctx, hdl); /* print command and supported status */ - printf("Sandisk Plugin Capabilities for NVME device:%s\n", dev->name); + printf("Sandisk Plugin Capabilities for NVME device:%s\n", nvme_transport_handle_get_name(hdl)); printf("vs-internal-log : %s\n", capabilities & SNDK_DRIVE_CAP_INTERNAL_LOG_MASK ? "Supported" : "Not Supported"); printf("vs-nand-stats : %s\n", @@ -635,8 +641,6 @@ static int sndk_capabilities(int argc, char **argv, printf("set-latency-monitor-feature : %s\n", capabilities & SNDK_DRIVE_CAP_SET_LATENCY_MONITOR ? "Supported" : "Not Supported"); printf("capabilities : Supported\n"); - nvme_free_tree(r); - dev_close(dev); return 0; } diff --git a/plugins/sandisk/sandisk-utils.c b/plugins/sandisk/sandisk-utils.c index 2e96877649..c98d567c45 100644 --- a/plugins/sandisk/sandisk-utils.c +++ b/plugins/sandisk/sandisk-utils.c @@ -17,27 +17,28 @@ #include "sandisk-utils.h" #include "plugins/wdc/wdc-nvme-cmds.h" - -int sndk_get_pci_ids(nvme_root_t r, struct nvme_dev *dev, - uint32_t *device_id, uint32_t *vendor_id) +int sndk_get_pci_ids(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl, uint32_t *device_id, + uint32_t *vendor_id) { char vid[256], did[256], id[32]; nvme_ctrl_t c = NULL; nvme_ns_t n = NULL; int fd, ret; - c = nvme_scan_ctrl(r, dev->name); - if (c) { + ret = nvme_scan_ctrl(ctx, nvme_transport_handle_get_name(hdl), &c); + if (!ret) { snprintf(vid, sizeof(vid), "%s/device/vendor", nvme_ctrl_get_sysfs_dir(c)); snprintf(did, sizeof(did), "%s/device/device", nvme_ctrl_get_sysfs_dir(c)); nvme_free_ctrl(c); } else { - n = nvme_scan_namespace(dev->name); - if (!n) { - fprintf(stderr, "Unable to find %s\n", dev->name); - return -1; + ret = nvme_scan_namespace(nvme_transport_handle_get_name(hdl), &n); + if (ret) { + fprintf(stderr, "Unable to find %s\n", + nvme_transport_handle_get_name(hdl)); + return ret; } snprintf(vid, sizeof(vid), "%s/device/device/vendor", @@ -88,13 +89,13 @@ int sndk_get_pci_ids(nvme_root_t r, struct nvme_dev *dev, return 0; } -int sndk_get_vendor_id(struct nvme_dev *dev, uint32_t *vendor_id) +int sndk_get_vendor_id(struct nvme_transport_handle *hdl, uint32_t *vendor_id) { - int ret; struct nvme_id_ctrl ctrl; + int ret; memset(&ctrl, 0, sizeof(struct nvme_id_ctrl)); - ret = nvme_identify_ctrl(dev_fd(dev), &ctrl); + ret = nvme_identify_ctrl(hdl, &ctrl); if (ret) { fprintf(stderr, "ERROR: SNDK: nvme_identify_ctrl() failed 0x%x\n", ret); return -1; @@ -105,16 +106,17 @@ int sndk_get_vendor_id(struct nvme_dev *dev, uint32_t *vendor_id) return ret; } -bool sndk_check_device(nvme_root_t r, struct nvme_dev *dev) +bool sndk_check_device(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl) { - int ret; - bool supported; uint32_t read_device_id = -1, read_vendor_id = -1; + bool supported; + int ret; - ret = sndk_get_pci_ids(r, dev, &read_device_id, &read_vendor_id); + ret = sndk_get_pci_ids(ctx, hdl, &read_device_id, &read_vendor_id); if (ret < 0) { /* Use the identify nvme command to get vendor id due to NVMeOF device. */ - if (sndk_get_vendor_id(dev, &read_vendor_id) < 0) + if (sndk_get_vendor_id(hdl, &read_vendor_id) < 0) return false; } @@ -131,16 +133,16 @@ bool sndk_check_device(nvme_root_t r, struct nvme_dev *dev) return supported; } -__u64 sndk_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev) +__u64 sndk_get_drive_capabilities(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl) { + uint32_t read_device_id = -1, read_vendor_id = -1; __u64 capabilities = 0; - int ret; - uint32_t read_device_id = -1, read_vendor_id = -1; - ret = sndk_get_pci_ids(r, dev, &read_device_id, &read_vendor_id); + ret = sndk_get_pci_ids(ctx, hdl, &read_device_id, &read_vendor_id); if (ret < 0) { - if (sndk_get_vendor_id(dev, &read_vendor_id) < 0) + if (sndk_get_vendor_id(hdl, &read_vendor_id) < 0) return capabilities; } @@ -150,7 +152,7 @@ __u64 sndk_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev) * so we can only use the vendor_id */ if (read_device_id == -1 && read_vendor_id != -1) { - capabilities = sndk_get_enc_drive_capabilities(r, dev); + capabilities = sndk_get_enc_drive_capabilities(ctx, hdl); return capabilities; } @@ -197,20 +199,20 @@ __u64 sndk_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev) /* Check for fallback WDC plugin support */ if (!capabilities) - capabilities = run_wdc_get_drive_capabilities(r, dev); + capabilities = run_wdc_get_drive_capabilities(ctx, hdl); return capabilities; } -__u64 sndk_get_enc_drive_capabilities(nvme_root_t r, - struct nvme_dev *dev) +__u64 sndk_get_enc_drive_capabilities(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl) { int ret; uint32_t read_vendor_id; __u64 capabilities = 0; __u32 cust_id; - ret = sndk_get_vendor_id(dev, &read_vendor_id); + ret = sndk_get_vendor_id(hdl, &read_vendor_id); if (ret < 0) return capabilities; @@ -222,26 +224,26 @@ __u64 sndk_get_enc_drive_capabilities(nvme_root_t r, SNDK_DRIVE_CAP_RESIZE); /* verify the 0xC3 log page is supported */ - if (run_wdc_nvme_check_supported_log_page(r, dev, + if (run_wdc_nvme_check_supported_log_page(ctx, hdl, SNDK_LATENCY_MON_LOG_ID)) capabilities |= SNDK_DRIVE_CAP_C3_LOG_PAGE; /* verify the 0xCB log page is supported */ - if (run_wdc_nvme_check_supported_log_page(r, dev, + if (run_wdc_nvme_check_supported_log_page(ctx, hdl, SNDK_NVME_GET_FW_ACT_HISTORY_LOG_ID)) capabilities |= SNDK_DRIVE_CAP_FW_ACTIVATE_HISTORY; /* verify the 0xCA log page is supported */ - if (run_wdc_nvme_check_supported_log_page(r, dev, + if (run_wdc_nvme_check_supported_log_page(ctx, hdl, SNDK_NVME_GET_DEVICE_INFO_LOG_ID)) capabilities |= SNDK_DRIVE_CAP_CA_LOG_PAGE; /* verify the 0xD0 log page is supported */ - if (run_wdc_nvme_check_supported_log_page(r, dev, + if (run_wdc_nvme_check_supported_log_page(ctx, hdl, SNDK_NVME_GET_VU_SMART_LOG_ID)) capabilities |= SNDK_DRIVE_CAP_D0_LOG_PAGE; - cust_id = run_wdc_get_fw_cust_id(r, dev); + cust_id = run_wdc_get_fw_cust_id(ctx, hdl); if (cust_id == SNDK_INVALID_CUSTOMER_ID) { fprintf(stderr, "%s: ERROR: SNDK: invalid customer id\n", __func__); return -1; @@ -265,8 +267,8 @@ __u64 sndk_get_enc_drive_capabilities(nvme_root_t r, return capabilities; } -int sndk_get_serial_name(struct nvme_dev *dev, char *file, size_t len, - const char *suffix) +int sndk_get_serial_name(struct nvme_transport_handle *hdl, char *file, + size_t len, const char *suffix) { int i; int ret; @@ -279,7 +281,7 @@ int sndk_get_serial_name(struct nvme_dev *dev, char *file, size_t len, strncpy(orig, file, PATH_MAX - 1); memset(file, 0, len); memset(&ctrl, 0, sizeof(struct nvme_id_ctrl)); - ret = nvme_identify_ctrl(dev_fd(dev), &ctrl); + ret = nvme_identify_ctrl(hdl, &ctrl); if (ret) { fprintf(stderr, "ERROR: SNDK: nvme_identify_ctrl() failed 0x%x\n", ret); return -1; @@ -327,7 +329,8 @@ void sndk_UtilsGetTime(struct SNDK_UtilsTimeInfo *timeInfo) #endif /* HAVE_TM_GMTOFF */ } -int sndk_UtilsSnprintf(char *buffer, unsigned int sizeOfBuffer, const char *format, ...) +int sndk_UtilsSnprintf(char *buffer, unsigned int sizeOfBuffer, + const char *format, ...) { int res = 0; va_list vArgs; @@ -340,14 +343,15 @@ int sndk_UtilsSnprintf(char *buffer, unsigned int sizeOfBuffer, const char *form } /* Verify the Controller Initiated Option is enabled */ -int sndk_check_ctrl_telemetry_option_disabled(struct nvme_dev *dev) +int sndk_check_ctrl_telemetry_option_disabled(struct nvme_transport_handle *hdl) { int err; __u32 result; - err = nvme_get_features_data(dev_fd(dev), - SNDK_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, - 0, 4, NULL, &result); + err = nvme_get_features(hdl, 0, + SNDK_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, + NVME_GET_FEATURES_SEL_CURRENT, 0, 0, + NULL, 4, &result); if (!err) { if (result) { fprintf(stderr, diff --git a/plugins/sandisk/sandisk-utils.h b/plugins/sandisk/sandisk-utils.h index da89a4f8b2..c9cfc74a56 100644 --- a/plugins/sandisk/sandisk-utils.h +++ b/plugins/sandisk/sandisk-utils.h @@ -211,24 +211,24 @@ struct SNDK_UtilsTimeInfo { int zone; /* Zone value like +530 or -300 */ }; -int sndk_get_pci_ids(nvme_root_t r, - struct nvme_dev *dev, +int sndk_get_pci_ids(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl, uint32_t *device_id, uint32_t *vendor_id); -int sndk_get_vendor_id(struct nvme_dev *dev, +int sndk_get_vendor_id(struct nvme_transport_handle *hdl, uint32_t *vendor_id); -bool sndk_check_device(nvme_root_t r, - struct nvme_dev *dev); +bool sndk_check_device(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl); -__u64 sndk_get_drive_capabilities(nvme_root_t r, - struct nvme_dev *dev); +__u64 sndk_get_drive_capabilities(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl); -__u64 sndk_get_enc_drive_capabilities(nvme_root_t r, - struct nvme_dev *dev); +__u64 sndk_get_enc_drive_capabilities(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl); -int sndk_get_serial_name(struct nvme_dev *dev, char *file, size_t len, +int sndk_get_serial_name(struct nvme_transport_handle *hdl, char *file, size_t len, const char *suffix); void sndk_UtilsGetTime(struct SNDK_UtilsTimeInfo *timeInfo); @@ -236,4 +236,4 @@ void sndk_UtilsGetTime(struct SNDK_UtilsTimeInfo *timeInfo); int sndk_UtilsSnprintf(char *buffer, unsigned int sizeOfBuffer, const char *format, ...); -int sndk_check_ctrl_telemetry_option_disabled(struct nvme_dev *dev); +int sndk_check_ctrl_telemetry_option_disabled(struct nvme_transport_handle *hdl); diff --git a/plugins/scaleflux/sfx-nvme.c b/plugins/scaleflux/sfx-nvme.c index 63e0e2e4d8..1d2f768b91 100644 --- a/plugins/scaleflux/sfx-nvme.c +++ b/plugins/scaleflux/sfx-nvme.c @@ -19,7 +19,6 @@ #include "libnvme.h" #include "plugin.h" #include "linux/types.h" -#include "nvme-wrap.h" #include "nvme-print.h" #include "util/cleanup.h" #include "util/types.h" @@ -47,7 +46,7 @@ -int nvme_query_cap(int fd, __u32 nsid, __u32 data_len, void *data) +int nvme_query_cap(struct nvme_transport_handle *hdl, __u32 nsid, __u32 data_len, void *data) { int rc = 0; struct nvme_passthru_cmd cmd = { @@ -57,11 +56,11 @@ int nvme_query_cap(int fd, __u32 nsid, __u32 data_len, void *data) .data_len = data_len, }; - rc = ioctl(fd, SFX_GET_FREESPACE, data); - return rc ? nvme_submit_admin_passthru(fd, &cmd, NULL) : 0; + rc = ioctl(nvme_transport_handle_get_fd(hdl), SFX_GET_FREESPACE, data); + return rc ? nvme_submit_admin_passthru(hdl, &cmd, NULL) : 0; } -int nvme_change_cap(int fd, __u32 nsid, __u64 capacity) +int nvme_change_cap(struct nvme_transport_handle *hdl, __u32 nsid, __u64 capacity) { struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_change_cap, @@ -70,10 +69,10 @@ int nvme_change_cap(int fd, __u32 nsid, __u64 capacity) .cdw11 = (capacity >> 32), }; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + return nvme_submit_admin_passthru(hdl, &cmd, NULL); } -int nvme_sfx_set_features(int fd, __u32 nsid, __u32 fid, __u32 value) +int nvme_sfx_set_features(struct nvme_transport_handle *hdl, __u32 nsid, __u32 fid, __u32 value) { struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_sfx_set_features, @@ -82,10 +81,10 @@ int nvme_sfx_set_features(int fd, __u32 nsid, __u32 fid, __u32 value) .cdw11 = value, }; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + return nvme_submit_admin_passthru(hdl, &cmd, NULL); } -int nvme_sfx_get_features(int fd, __u32 nsid, __u32 fid, __u32 *result) +int nvme_sfx_get_features(struct nvme_transport_handle *hdl, __u32 nsid, __u32 fid, __u32 *result) { int err = 0; struct nvme_passthru_cmd cmd = { @@ -94,7 +93,7 @@ int nvme_sfx_get_features(int fd, __u32 nsid, __u32 fid, __u32 *result) .cdw10 = fid, }; - err = nvme_submit_admin_passthru(fd, &cmd, NULL); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err && result) *result = cmd.result; @@ -325,7 +324,7 @@ static void show_sfx_smart_log(struct nvme_additional_smart_log *smart, } -static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_additional_smart_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { struct nvme_additional_smart_log smart_log; char *desc = @@ -335,7 +334,8 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd, #ifdef CONFIG_JSONC const char *json = "Dump output in json format"; #endif /* CONFIG_JSONC */ - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct config { __u32 namespace_id; bool raw_binary; @@ -354,25 +354,24 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = nvme_get_nsid_log(dev_fd(dev), false, 0xca, cfg.namespace_id, - sizeof(smart_log), (void *)&smart_log); + err = nvme_get_nsid_log(hdl, cfg.namespace_id, false, 0xca, + (void *)&smart_log, sizeof(smart_log)); if (!err) { if (cfg.json) show_sfx_smart_log_jsn(&smart_log, cfg.namespace_id, - dev->name); + nvme_transport_handle_get_name(hdl)); else if (!cfg.raw_binary) show_sfx_smart_log(&smart_log, cfg.namespace_id, - dev->name); + nvme_transport_handle_get_name(hdl)); else d_raw((unsigned char *)&smart_log, sizeof(smart_log)); } else if (err > 0) { nvme_show_status(err); } - dev_close(dev); return err; } @@ -497,13 +496,14 @@ static void show_lat_stats_myrtle(struct sfx_lat_stats_myrtle *stats, int write) } -static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_lat_stats_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { struct sfx_lat_stats stats; char *desc = "Get ScaleFlux Latency Statistics log and show it."; const char *raw = "dump output in binary format"; const char *write = "Get write statistics (read default)"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct config { bool raw_binary; bool write; @@ -519,12 +519,12 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = nvme_get_log_simple(dev_fd(dev), cfg.write ? 0xc3 : 0xc1, - sizeof(stats), (void *)&stats); + err = nvme_get_log_simple(hdl, cfg.write ? 0xc3 : 0xc1, + (void *)&stats, sizeof(stats)); if (!err) { if ((stats.ver.maj == VANDA_MAJOR_IDX) && (stats.ver.min == VANDA_MINOR_IDX)) { if (!cfg.raw_binary) @@ -543,11 +543,10 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct } else if (err > 0) { nvme_show_status(err); } - dev_close(dev); return err; } -int sfx_nvme_get_log(int fd, __u32 nsid, __u8 log_id, __u32 data_len, void *data) +int sfx_nvme_get_log(struct nvme_transport_handle *hdl, __u32 nsid, __u8 log_id, __u32 data_len, void *data) { struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_get_log_page, @@ -561,7 +560,7 @@ int sfx_nvme_get_log(int fd, __u32 nsid, __u8 log_id, __u32 data_len, void *data cmd.cdw10 = log_id | (numdl << 16); cmd.cdw11 = numdu; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + return nvme_submit_admin_passthru(hdl, &cmd, NULL); } /** @@ -573,14 +572,14 @@ int sfx_nvme_get_log(int fd, __u32 nsid, __u8 log_id, __u32 data_len, void *data * * @return -1 fail ; 0 success */ -static int get_bb_table(int fd, __u32 nsid, unsigned char *buf, __u64 size) +static int get_bb_table(struct nvme_transport_handle *hdl, __u32 nsid, unsigned char *buf, __u64 size) { - if (fd < 0 || !buf || size != 256*4096*sizeof(unsigned char)) { + if (nvme_transport_handle_get_fd(hdl) < 0 || !buf || size != 256*4096*sizeof(unsigned char)) { fprintf(stderr, "Invalid Param \r\n"); return -EINVAL; } - return sfx_nvme_get_log(fd, nsid, SFX_LOG_BBT, size, (void *)buf); + return sfx_nvme_get_log(hdl, nsid, SFX_LOG_BBT, size, (void *)buf); } /** @@ -645,11 +644,12 @@ static void bd_table_show(unsigned char *bd_table, __u64 table_size) * * @return */ -static int sfx_get_bad_block(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int sfx_get_bad_block(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const __u64 buf_size = 256*4096*sizeof(unsigned char); unsigned char *data_buf; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err = 0; char *desc = "Get bad block table of sfx block device."; @@ -658,18 +658,17 @@ static int sfx_get_bad_block(int argc, char **argv, struct command *cmd, struct OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; data_buf = malloc(buf_size); if (!data_buf) { fprintf(stderr, "malloc fail, errno %d\r\n", errno); - dev_close(dev); return -1; } - err = get_bb_table(dev_fd(dev), NVME_NSID_ALL, data_buf, buf_size); + err = get_bb_table(hdl, NVME_NSID_ALL, data_buf, buf_size); if (err < 0) { perror("get-bad-block"); } else if (err) { @@ -680,7 +679,6 @@ static int sfx_get_bad_block(int argc, char **argv, struct command *cmd, struct } free(data_buf); - dev_close(dev); return 0; } @@ -699,12 +697,13 @@ static void show_cap_info(struct sfx_freespace_ctx *ctx) printf("map_unit :0x%"PRIx64"K\n", (uint64_t)(ctx->map_unit * 4)); } -static int query_cap_info(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int query_cap_info(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - struct sfx_freespace_ctx ctx = { 0 }; + struct sfx_freespace_ctx sfctx = { 0 }; char *desc = "query current capacity info"; const char *raw = "dump output in binary format"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct config { bool raw_binary; }; @@ -716,26 +715,25 @@ static int query_cap_info(int argc, char **argv, struct command *cmd, struct plu OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - if (nvme_query_cap(dev_fd(dev), NVME_NSID_ALL, sizeof(ctx), &ctx)) { + if (nvme_query_cap(hdl, NVME_NSID_ALL, sizeof(sfctx), &sfctx)) { perror("sfx-query-cap"); err = -1; } if (!err) { if (!cfg.raw_binary) - show_cap_info(&ctx); + show_cap_info(&sfctx); else - d_raw((unsigned char *)&ctx, sizeof(ctx)); + d_raw((unsigned char *)&sfctx, sizeof(sfctx)); } - dev_close(dev); return err; } -static int change_sanity_check(int fd, __u64 trg_in_4k, int *shrink) +static int change_sanity_check(struct nvme_transport_handle *hdl, __u64 trg_in_4k, int *shrink) { struct sfx_freespace_ctx freespace_ctx = { 0 }; struct sysinfo s_info; @@ -744,7 +742,7 @@ static int change_sanity_check(int fd, __u64 trg_in_4k, int *shrink) __u64 provisioned_cap_4k = 0; int extend = 0; - if (nvme_query_cap(fd, NVME_NSID_ALL, sizeof(freespace_ctx), &freespace_ctx)) + if (nvme_query_cap(hdl, NVME_NSID_ALL, sizeof(freespace_ctx), &freespace_ctx)) return -1; /* @@ -817,13 +815,14 @@ static int sfx_confirm_change(const char *str) return 1; } -static int change_cap(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int change_cap(int argc, char **argv, struct command *acmd, struct plugin *plugin) { char *desc = "dynamic change capacity"; const char *cap_gb = "cap size in GB"; const char *cap_byte = "cap size in byte"; const char *force = "The \"I know what I'm doing\" flag, skip confirmation before sending command"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u64 cap_in_4k = 0; __u64 cap_in_sec = 0; int shrink = 0; @@ -848,7 +847,7 @@ static int change_cap(int argc, char **argv, struct command *cmd, struct plugin OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -859,34 +858,31 @@ static int change_cap(int argc, char **argv, struct command *cmd, struct plugin printf("%dG %"PRIu64"B %"PRIu64" 4K\n", cfg.capacity_in_gb, (uint64_t)cfg.cap_in_byte, (uint64_t)cap_in_4k); - if (change_sanity_check(dev_fd(dev), cap_in_4k, &shrink)) { + if (change_sanity_check(hdl, cap_in_4k, &shrink)) { printf("ScaleFlux change-capacity: fail\n"); - dev_close(dev); return err; } if (!cfg.force && shrink && !sfx_confirm_change("Changing Cap may irrevocably delete this device's data")) { - dev_close(dev); return 0; } - err = nvme_change_cap(dev_fd(dev), NVME_NSID_ALL, cap_in_4k); + err = nvme_change_cap(hdl, NVME_NSID_ALL, cap_in_4k); if (err < 0) { perror("sfx-change-cap"); } else if (err) { nvme_show_status(err); } else { printf("ScaleFlux change-capacity: success\n"); - ioctl(dev_fd(dev), BLKRRPART); + ioctl(nvme_transport_handle_get_fd(hdl), BLKRRPART); } - dev_close(dev); return err; } -static int sfx_verify_chr(int fd) +static int sfx_verify_chr(struct nvme_transport_handle *hdl) { static struct stat nvme_stat; - int err = fstat(fd, &nvme_stat); + int err = fstat(nvme_transport_handle_get_fd(hdl), &nvme_stat); if (err < 0) { perror("fstat"); @@ -900,14 +896,14 @@ static int sfx_verify_chr(int fd) return 0; } -static int sfx_clean_card(int fd) +static int sfx_clean_card(struct nvme_transport_handle *hdl) { int ret; - ret = sfx_verify_chr(fd); + ret = sfx_verify_chr(hdl); if (ret) return ret; - ret = ioctl(fd, NVME_IOCTL_CLR_CARD); + ret = ioctl(nvme_transport_handle_get_fd(hdl), NVME_IOCTL_CLR_CARD); if (ret) perror("Ioctl Fail."); else @@ -928,7 +924,7 @@ char *sfx_feature_to_string(int feature) } } -static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int sfx_set_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { char *desc = "ScaleFlux internal set features\n" "feature id 1: ATOMIC\n" @@ -938,7 +934,8 @@ static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct pl const char *feature_id = "hex feature name (required)"; const char *namespace_id = "desired namespace"; const char *force = "The \"I know what I'm doing\" flag, skip confirmation before sending command"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct nvme_id_ns ns; int err = 0; @@ -963,70 +960,62 @@ static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct pl OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; if (!cfg.feature_id) { fprintf(stderr, "feature-id required param\n"); - dev_close(dev); - return -EINVAL; + return -EINVAL; } if (cfg.feature_id == SFX_FEAT_CLR_CARD) { /*Warning for clean card*/ if (!cfg.force && !sfx_confirm_change("Going to clean device's data, confirm umount fs and try again")) { - dev_close(dev); - return 0; + return 0; } else { - return sfx_clean_card(dev_fd(dev)); + return sfx_clean_card(hdl); } } if (cfg.feature_id == SFX_FEAT_ATOMIC && cfg.value) { if (cfg.namespace_id != NVME_NSID_ALL) { - err = nvme_identify_ns(dev_fd(dev), cfg.namespace_id, - &ns); + err = nvme_identify_ns(hdl, cfg.namespace_id, &ns); if (err) { if (err < 0) perror("identify-namespace"); else nvme_show_status(err); - dev_close(dev); - return err; + return err; } /* * atomic only support with sector-size = 4k now */ if ((ns.flbas & 0xf) != 1) { printf("Please change-sector size to 4K, then retry\n"); - dev_close(dev); - return -EFAULT; + return -EFAULT; } } } else if (cfg.feature_id == SFX_FEAT_UP_P_CAP) { if (cfg.value <= 0) { fprintf(stderr, "Invalid Param\n"); - dev_close(dev); - return -EINVAL; + return -EINVAL; } /*Warning for change pacp by GB*/ if (!cfg.force && !sfx_confirm_change("Changing physical capacity may irrevocably delete this device's data")) { - dev_close(dev); - return 0; + return 0; } } - err = nvme_sfx_set_features(dev_fd(dev), cfg.namespace_id, + err = nvme_sfx_set_features(hdl, cfg.namespace_id, cfg.feature_id, cfg.value); if (err < 0) { perror("ScaleFlux-set-feature"); - dev_close(dev); - return errno; + return errno; } else if (!err) { printf("ScaleFlux set-feature:%#02x (%s), value:%d\n", cfg.feature_id, sfx_feature_to_string(cfg.feature_id), cfg.value); @@ -1034,17 +1023,17 @@ static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct pl nvme_show_status(err); } - dev_close(dev); return err; } -static int sfx_get_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int sfx_get_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { char *desc = "ScaleFlux internal set features\n" "feature id 1: ATOMIC"; const char *feature_id = "hex feature name (required)"; const char *namespace_id = "desired namespace"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 result = 0; int err = 0; @@ -1063,22 +1052,20 @@ static int sfx_get_feature(int argc, char **argv, struct command *cmd, struct pl OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; if (!cfg.feature_id) { fprintf(stderr, "feature-id required param\n"); - dev_close(dev); - return -EINVAL; + return -EINVAL; } - err = nvme_sfx_get_features(dev_fd(dev), cfg.namespace_id, + err = nvme_sfx_get_features(hdl, cfg.namespace_id, cfg.feature_id, &result); if (err < 0) { perror("ScaleFlux-get-feature"); - dev_close(dev); - return errno; + return errno; } else if (!err) { printf("ScaleFlux get-feature:%02x (%s), value:%d\n", cfg.feature_id, sfx_feature_to_string(cfg.feature_id), result); @@ -1086,7 +1073,6 @@ static int sfx_get_feature(int argc, char **argv, struct command *cmd, struct pl nvme_show_status(err); } - dev_close(dev); return err; } @@ -1218,36 +1204,23 @@ static int nvme_parse_evtlog(void *pevent_log_info, __u32 log_len, char *output) return err; } -static int nvme_dump_evtlog(struct nvme_dev *dev, __u32 namespace_id, __u32 storage_medium, +static int nvme_dump_evtlog(struct nvme_transport_handle *hdl, __u32 namespace_id, __u32 storage_medium, char *file, bool parse, char *output) { + _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; struct nvme_persistent_event_log *pevent; void *pevent_log_info; - _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; - __u8 lsp_base; + __u8 lsp_base, lsp; __u32 offset = 0; __u32 length = 0; - __u32 log_len; __u32 single_len; + __u32 log_len; + __u32 len; + __u64 lpo; + void *log; int err = 0; FILE *fd = NULL; - struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .lid = NVME_LOG_LID_PERSISTENT_EVENT, - .nsid = namespace_id, - .lpo = NVME_LOG_LPO_NONE, - .lsp = NVME_LOG_LSP_NONE, - .lsi = NVME_LOG_LSI_NONE, - .rae = false, - .uuidx = NVME_UUID_NONE, - .csi = NVME_CSI_NVM, - .ot = false, - .len = 0, - .log = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; + struct nvme_passthru_cmd cmd; if (!storage_medium) { lsp_base = 0; @@ -1263,20 +1236,31 @@ static int nvme_dump_evtlog(struct nvme_dev *dev, __u32 namespace_id, __u32 stor goto ret; } - args.lsp = lsp_base + NVME_PEVENT_LOG_RELEASE_CTX; - args.log = pevent; - args.len = sizeof(*pevent); - - err = nvme_get_log(&args); + lsp = lsp_base + NVME_PEVENT_LOG_RELEASE_CTX; + log = pevent; + len = sizeof(*pevent); + nvme_init_get_log(&cmd, NVME_NSID_NONE, NVME_LOG_LID_PERSISTENT_EVENT, + NVME_CSI_NVM, log, len); + cmd.cdw10 |= NVME_FIELD_ENCODE(lsp, + NVME_LOG_CDW10_LSP_SHIFT, + NVME_LOG_CDW10_LSP_MASK); + err = nvme_get_log(hdl, &cmd, false, NVME_LOG_PAGE_PDU_SIZE, NULL); if (err) { - fprintf(stderr, "Unable to get evtlog lsp=0x%x, ret = 0x%x\n", args.lsp, err); + fprintf(stderr, "Unable to get evtlog lsp=0x%x, ret = 0x%x\n", + lsp, err); goto free_pevent; } - args.lsp = lsp_base + NVME_PEVENT_LOG_EST_CTX_AND_READ; - err = nvme_get_log(&args); + lsp = lsp_base + NVME_PEVENT_LOG_EST_CTX_AND_READ; + nvme_init_get_log(&cmd, NVME_NSID_NONE, NVME_LOG_LID_PERSISTENT_EVENT, + NVME_CSI_NVM, log, len); + cmd.cdw10 |= NVME_FIELD_ENCODE(lsp, + NVME_LOG_CDW10_LSP_SHIFT, + NVME_LOG_CDW10_LSP_MASK); + err = nvme_get_log(hdl, &cmd, false, NVME_LOG_PAGE_PDU_SIZE, NULL); if (err) { - fprintf(stderr, "Unable to get evtlog lsp=0x%x, ret = 0x%x\n", args.lsp, err); + fprintf(stderr, "Unable to get evtlog lsp=0x%x, ret = 0x%x\n", + lsp, err); goto free_pevent; } @@ -1297,30 +1281,40 @@ static int nvme_dump_evtlog(struct nvme_dev *dev, __u32 namespace_id, __u32 stor goto free_pevent; } - args.lsp = lsp_base + NVME_PEVENT_LOG_READ; - args.log = pevent_log_info; + lsp = lsp_base + NVME_PEVENT_LOG_READ; + log = pevent_log_info; length = log_len; while (length > 0) { - args.lpo = offset; + lpo = offset; if (length > single_len) { - args.len = single_len; + len = single_len; } else { - memset(args.log, 0, args.len); - args.len = length; + memset(log, 0, len); + len = length; } - err = nvme_get_log(&args); + nvme_init_get_log(&cmd, NVME_NSID_NONE, + NVME_LOG_LID_PERSISTENT_EVENT, + NVME_CSI_NVM, log, len); + cmd.cdw10 |= NVME_FIELD_ENCODE(lsp, + NVME_LOG_CDW10_LSP_SHIFT, + NVME_LOG_CDW10_LSP_MASK); + nvme_init_get_log_lpo(&cmd, lpo); + err = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (err) { - fprintf(stderr, "Unable to get evtlog offset=0x%x len 0x%x ret = 0x%x\n", offset, args.len, err); + fprintf(stderr, + "Unable to get evtlog offset=0x%x len 0x%x ret = 0x%x\n", + offset, len, err); goto close_fd; } - if (fwrite(args.log, 1, args.len, fd) != args.len) { + if (fwrite(log, 1, len, fd) != len) { fprintf(stderr, "Failed to write evtlog to file\n"); goto close_fd; } - offset += args.len; - length -= args.len; + offset += len; + length -= len; util_spinner("Parse", (float) (offset) / (float) (log_len)); } @@ -1358,7 +1352,7 @@ static int nvme_dump_evtlog(struct nvme_dev *dev, __u32 namespace_id, __u32 stor return err; } -static int sfx_dump_evtlog(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int sfx_dump_evtlog(int argc, char **argv, struct command *acmd, struct plugin *plugin) { char *desc = "dump evtlog into file and parse"; const char *file = "evtlog file(required)"; @@ -1367,7 +1361,8 @@ static int sfx_dump_evtlog(int argc, char **argv, struct command *cmd, struct pl "0: nand(default) 1: nor"; const char *parse = "parse error & warning evtlog from evtlog file"; const char *output = "parse result output file"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err = 0; struct config { @@ -1394,31 +1389,26 @@ static int sfx_dump_evtlog(int argc, char **argv, struct command *cmd, struct pl OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) - goto ret; + return err; if (!cfg.file) { fprintf(stderr, "file required param\n"); - err = EINVAL; - goto close_dev; + return -EINVAL; } if (cfg.parse && !cfg.output) { fprintf(stderr, "output file required if evtlog need be parsed\n"); - err = EINVAL; - goto close_dev; + return -EINVAL; } - err = nvme_dump_evtlog(dev, cfg.namespace_id, cfg.storage_medium, cfg.file, cfg.parse, cfg.output); + err = nvme_dump_evtlog(hdl, cfg.namespace_id, cfg.storage_medium, cfg.file, cfg.parse, cfg.output); -close_dev: - dev_close(dev); -ret: - return err; + return 0; } -static int nvme_expand_cap(struct nvme_dev *dev, __u32 namespace_id, __u64 namespace_size, +static int nvme_expand_cap(struct nvme_transport_handle *hdl, __u32 namespace_id, __u64 namespace_size, __u64 namespace_cap, __u32 lbaf, __u32 units) { struct dirent **devices; @@ -1435,10 +1425,10 @@ static int nvme_expand_cap(struct nvme_dev *dev, __u32 namespace_id, __u64 names __u8 reserve1[5]; } __packed; - if (S_ISCHR(dev->direct.stat.st_mode)) - snprintf(dev_name, 32, "%sn%u", dev->name, namespace_id); + if (nvme_transport_handle_is_chardev(hdl)) + snprintf(dev_name, 32, "%sn%u", nvme_transport_handle_get_name(hdl), namespace_id); else - strcpy(dev_name, dev->name); + strcpy(dev_name, nvme_transport_handle_get_name(hdl)); num = scandir("/dev", &devices, nvme_namespace_filter, alphasort); if (num <= 0) { @@ -1471,7 +1461,7 @@ static int nvme_expand_cap(struct nvme_dev *dev, __u32 namespace_id, __u64 names .cdw10 = 0x0e, }; - err = nvme_submit_admin_passthru(dev_fd(dev), &cmd, NULL); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (err) { fprintf(stderr, "Create ns failed\n"); nvme_show_status(err); @@ -1486,7 +1476,7 @@ static int nvme_expand_cap(struct nvme_dev *dev, __u32 namespace_id, __u64 names return err; } -static int sfx_expand_cap(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int sfx_expand_cap(int argc, char **argv, struct command *acmd, struct plugin *plugin) { char *desc = "expand capacity"; const char *namespace_id = "desired namespace"; @@ -1496,7 +1486,8 @@ static int sfx_expand_cap(int argc, char **argv, struct command *cmd, struct plu "0: 512(default) 1: 4096"; const char *units = "namespace size/capacity units\n" "0: GB(default) 1: LBA"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err = 0; struct config { @@ -1521,55 +1512,49 @@ static int sfx_expand_cap(int argc, char **argv, struct command *cmd, struct plu OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) - goto ret; + return err; if (cfg.namespace_id == NVME_NSID_ALL) { - if (S_ISCHR(dev->direct.stat.st_mode)) { + if (nvme_transport_handle_is_chardev(hdl)) { fprintf(stderr, "namespace_id or blk device required\n"); - err = EINVAL; - goto ret; + return -EINVAL; } else { - cfg.namespace_id = atoi(&dev->name[strlen(dev->name) - 1]); + cfg.namespace_id = atoi(&nvme_transport_handle_get_name(hdl)[strlen(nvme_transport_handle_get_name(hdl)) - 1]); } } if (!cfg.namespace_size) { fprintf(stderr, "namespace_size required param\n"); - err = EINVAL; - goto close_dev; + return -EINVAL; } if (!cfg.namespace_cap) { fprintf(stderr, "namespace_cap required param\n"); - err = EINVAL; - goto close_dev; + return -EINVAL; } - err = nvme_expand_cap(dev, cfg.namespace_id, cfg.namespace_size, cfg.namespace_cap, cfg.lbaf, cfg.units); + err = nvme_expand_cap(hdl, cfg.namespace_id, cfg.namespace_size, cfg.namespace_cap, cfg.lbaf, cfg.units); if (err) - goto close_dev; + return err; - printf("%s: Success, create nsid:%d\n", cmd->name, cfg.namespace_id); + printf("%s: Success, create nsid:%d\n", acmd->name, cfg.namespace_id); -close_dev: - dev_close(dev); -ret: - return err; + return 0; } -static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int sfx_status(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get ScaleFlux specific status information and print it"; const char *json_desc = "Print output in JSON format, otherwise human readable"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct nvme_id_ctrl id_ctrl = { 0 }; struct extended_health_info_myrtle sfx_smart = { 0 }; struct nvme_smart_log smart_log = { 0 }; struct nvme_additional_smart_log additional_smart_log = { 0 }; struct sfx_freespace_ctx sfx_freespace = { 0 }; - struct nvme_get_features_args get_feat_args = { 0 }; unsigned int get_feat_result, pcie_correctable, pcie_fatal, pcie_nonfatal; unsigned long long capacity; bool capacity_valid = false; @@ -1592,14 +1577,13 @@ static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); - + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) - goto ret; + return err; //Calculate formatted capacity, not concerned with errors, we may have a char device memset(&path, 0, 512); - snprintf(path, 512, "/dev/%s", dev->name); + snprintf(path, 512, "/dev/%s", nvme_transport_handle_get_name(hdl)); fd = open(path, O_RDONLY | O_NONBLOCK); if (fd >= 0) { err = ioctl(fd, BLKSSZGET, §or_size); @@ -1616,7 +1600,7 @@ static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin capacity = capacity / (1000 * 1000 * 1000); //B --> GB memset(&chr_dev, 0, 8); - strcpy(chr_dev, dev->name); + strcpy(chr_dev, nvme_transport_handle_get_name(hdl)); for (len = 2; len < 8; len++) { if (chr_dev[len] == 'n') chr_dev[len] = '\0'; @@ -1627,16 +1611,14 @@ static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin fd = open(path, O_RDONLY); if (fd < 0) { perror("Could not open PCIe VID in /sys/"); - err = errno; - goto close_dev; + return -errno; } memset(&pci_vid, 0, 7); len = read(fd, pci_vid, 6); if (len < 1) { perror("Could not read PCIe VID in /sys/"); close(fd); - err = errno; - goto close_dev; + return -errno; } close(fd); @@ -1644,16 +1626,14 @@ static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin fd = open(path, O_RDONLY); if (fd < 0) { perror("Could not open PCIe DID in /sys/"); - err = errno; - goto close_dev; + return -errno; } memset(&pci_did, 0, 7); len = read(fd, pci_did, 6); if (len < 1) { perror("Could not read PCIe DID in /sys/"); close(fd); - err = errno; - goto close_dev; + return -errno; } close(fd); @@ -1663,24 +1643,21 @@ static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin strncpy(vendor, "DIGISTOR", 10); else { fprintf(stderr, "Please use on a ScaleFlux device\n"); - err = -1; - goto close_dev; + return -1; } snprintf(path, 512, "/sys/class/nvme/%s/device/subsystem_vendor", chr_dev); fd = open(path, O_RDONLY); if (fd < 0) { perror("Could not open PCIe Subsystem Vendor ID in /sys/"); - err = errno; - goto close_dev; + return -errno; } memset(&pci_ssvid, 0, 7); len = read(fd, pci_ssvid, 6); if (len < 1) { perror("could not read PCIe Subsystem Vendor ID in /sys/"); close(fd); - err = errno; - goto close_dev; + return -errno; } close(fd); @@ -1688,16 +1665,14 @@ static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin fd = open(path, O_RDONLY); if (fd < 0) { perror("Could not open link speed in /sys/"); - err = errno; - goto close_dev; + return -errno; } memset(&link_speed, 0, 20); len = read(fd, link_speed, 20); if (len < 1) { perror("Could not read link speed in /sys/"); close(fd); - err = errno; - goto close_dev; + return -errno; } close(fd); // Ending string before "PCIe" and newline @@ -1710,16 +1685,14 @@ static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin fd = open(path, O_RDONLY); if (fd < 0) { perror("Could not open link width in /sys/"); - err = errno; - goto close_dev; + return -errno; } memset(&link_width, 0, 5); len = read(fd, link_width, 5); if (len < 1) { perror("Could not read link width in /sys/"); close(fd); - err = errno; - goto close_dev; + return -errno; } close(fd); // Ending string before newline @@ -1734,16 +1707,14 @@ static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin fd = open(path, O_RDONLY); if (fd < 0) { perror("Could not open NUMA node in /sys/"); - err = errno; - goto close_dev; + return -errno; } memset(&numa_node, 0, 5); len = read(fd, numa_node, 5); if (len < 1) { perror("Could not read NUMA node in /sys/"); close(fd); - err = errno; - goto close_dev; + return -errno; } close(fd); @@ -1757,78 +1728,69 @@ static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin fd = open(path, O_RDONLY); if (fd < 0) { perror("Could not open PCIe AER Correctable errors in /sys/"); - err = errno; - goto close_dev; + return -errno; } len = read(fd, path, 512); if (len < 1) { perror("Could not read PCIe AER Correctable errors in /sys/"); close(fd); - err = errno; - goto close_dev; + return -errno; } close(fd); len = sscanf(path, "%*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d TOTAL_ERR_COR %d", &pcie_correctable); len = 1; if (len < 1 || len == EOF) { perror("Could not parse PCIe AER Correctable errors in /sys/"); - err = -1; - goto close_dev; + return -1; } snprintf(path, 512, "/sys/class/nvme/%s/device/aer_dev_nonfatal", chr_dev); fd = open(path, O_RDONLY); if (fd < 0) { perror("Could not open PCIe AER Non-Fatal errors in /sys/"); - err = errno; - goto close_dev; + return -errno; } len = read(fd, path, 512); if (len < 1) { perror("Could not read PCIe AER Non-Fatal errors in /sys/"); - err = errno; - goto close_dev; + return -errno; } close(fd); len = sscanf(path, "%*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d TOTAL_ERR_NONFATAL %d", &pcie_nonfatal); if (len < 1) { perror("Could not parse PCIe AER Non-Fatal errors in /sys/"); - err = -1; - goto close_dev; + return -1; } snprintf(path, 512, "/sys/class/nvme/%s/device/aer_dev_fatal", chr_dev); fd = open(path, O_RDONLY); if (fd < 0) { perror("Could not open PCIe AER Fatal errors in /sys/"); - err = errno; - goto close_dev; + return -errno; } len = read(fd, path, 512); if (len < 1) { perror("Could not read PCIe AER Fatal errors in /sys/"); close(fd); - err = errno; - goto close_dev; + return -errno; } close(fd); len = sscanf(path, "%*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d %*s %*d TOTAL_ERR_FATAL %d", &pcie_fatal); if (len < 1) { perror("Could not parse PCIe AER Fatal errors in /sys/"); close(fd); - err = -1; - goto close_dev; + return -1; } snprintf(pcie_status, 9, "%s", (pcie_fatal != 0 || pcie_nonfatal != 0 || pcie_correctable != 0) ? "Warning":"Good"); //Populate id-ctrl - err = nvme_identify_ctrl(dev_fd(dev), &id_ctrl); + err = nvme_identify_ctrl(hdl, &id_ctrl); if (err) { fprintf(stderr, "Unable to read nvme_identify_ctrl() error code:%x\n", err); - goto close_dev; + return err; } //Re-format specific fields so they can be safely treated as strings later serial_number[20] = '\0'; @@ -1839,30 +1801,30 @@ static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin memcpy(firmware_revision, id_ctrl.fr, 8); //Populate SMART log (0x02) - err = nvme_cli_get_log_smart(dev, NVME_NSID_ALL, false, &smart_log); + err = nvme_get_log_smart(hdl, NVME_NSID_ALL, &smart_log); if (err < 0) { perror("Could not read SMART log (0x02)"); - err = errno; - goto close_dev; + return -errno; } else if (err > 0) { nvme_show_status(err); - goto close_dev; + return err; } snprintf(temperature, 10, "%li", kelvin_to_celsius(smart_log.temperature[1]<<8 | smart_log.temperature[0])); //Populate SFX Extended Health log (0xC2) or if PCIe DID ==0x20 (Quince) use 0xD2 if (strncmp("0x0020", pci_did, 6) == 0) - err = nvme_get_log_simple(dev_fd(dev), SFX_LOG_EXTENDED_HEALTH_ALT, sizeof(sfx_smart), (void *)&sfx_smart); + err = nvme_get_log_simple(hdl, SFX_LOG_EXTENDED_HEALTH_ALT, (void *)&sfx_smart, + sizeof(sfx_smart)); else - err = nvme_get_log_simple(dev_fd(dev), SFX_LOG_EXTENDED_HEALTH, sizeof(sfx_smart), (void *)&sfx_smart); + err = nvme_get_log_simple(hdl, SFX_LOG_EXTENDED_HEALTH, (void *)&sfx_smart, + sizeof(sfx_smart)); if (err < 0) { perror("Could not read ScaleFlux SMART log"); - err = errno; - goto close_dev; + return -errno; } else if (err > 0) { nvme_show_status(err); - goto close_dev; + return err; } //Make sure the OPN can be printed safely @@ -1883,28 +1845,27 @@ static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin } //Populate Additional SMART log (0xCA) - err = nvme_get_nsid_log(dev_fd(dev), false, 0xca, NVME_NSID_ALL, sizeof(struct nvme_additional_smart_log), (void *)&additional_smart_log); + err = nvme_get_nsid_log(hdl, NVME_NSID_ALL, false, 0xca, (void *)&additional_smart_log, + sizeof(struct nvme_additional_smart_log)); if (err < 0) { perror("Could not read ScaleFlux SMART log"); - err = errno; - goto close_dev; + return -errno; } else if (err > 0) { nvme_show_status(err); - goto close_dev; + return err; } //OK with the '-nan' if host_bytes_written is zero write_amp = int48_to_long(additional_smart_log.nand_bytes_written.raw)/(1.0 * int48_to_long(additional_smart_log.host_bytes_written.raw)); //Get SFX freespace information - err = nvme_query_cap(dev_fd(dev), NVME_NSID_ALL, sizeof(sfx_freespace), &sfx_freespace); + err = nvme_query_cap(hdl, NVME_NSID_ALL, sizeof(sfx_freespace), &sfx_freespace); if (err < 0) { perror("Could not query freespace information (0xD6)"); - err = errno; - goto close_dev; + return -errno; } else if (err > 0) { nvme_show_status(err); - goto close_dev; + return err; } //Parse IO Speed information @@ -1935,23 +1896,18 @@ static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin sfx_smart.comp_ratio = 800; //Get status of atomic write feature - get_feat_args.args_size = sizeof(get_feat_args); - get_feat_args.fid = 0x0A; - get_feat_args.timeout = NVME_DEFAULT_IOCTL_TIMEOUT; - get_feat_args.result = &get_feat_result; - err = nvme_cli_get_features(dev, &get_feat_args); + err = nvme_get_features(hdl, 0, 0x0A, 0, 0, 0, NULL, 0, &get_feat_result); if (err < 0) { perror("Could not get feature (0x0A)"); - err = errno; - goto close_dev; + return -errno; } else if (err > 0) { nvme_show_status(err); - goto close_dev; + return err; } if (cfg.json) { root = json_create_object(); - json_object_add_value_string(root, "ScaleFlux Status", dev->name); + json_object_add_value_string(root, "ScaleFlux Status", nvme_transport_handle_get_name(hdl)); dev_stats = json_create_object(); link_stats = json_create_object(); @@ -2031,7 +1987,7 @@ static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin if (len < 11) strcpy(path, "None"); - printf("%-35s%s%s\n", "ScaleFlux Drive:", "/dev/", dev->name); + printf("%-35s%s%s\n", "ScaleFlux Drive:", "/dev/", nvme_transport_handle_get_name(hdl)); printf("%-35s%s\n", "PCIe Vendor ID:", pci_vid); printf("%-35s%s\n", "PCIe Subsystem Vendor ID:", pci_ssvid); printf("%-35s%s\n", "Manufacturer:", vendor); @@ -2078,8 +2034,5 @@ static int sfx_status(int argc, char **argv, struct command *cmd, struct plugin printf("%-35s%s\n", "Critical Warning(s):", path); } -close_dev: - dev_close(dev); -ret: - return err; + return 0; } diff --git a/plugins/seagate/seagate-nvme.c b/plugins/seagate/seagate-nvme.c index 96bbbb6349..d1d48cbea1 100644 --- a/plugins/seagate/seagate-nvme.c +++ b/plugins/seagate/seagate-nvme.c @@ -143,15 +143,16 @@ static void json_log_pages_supp(log_page_map *logPageMap) json_free_object(root); } -static int log_pages_supp(int argc, char **argv, struct command *cmd, - struct plugin *plugin) +static int log_pages_supp(int argc, char **argv, struct command *acmd, + struct plugin *plugin) { int err = 0; __u32 i = 0; log_page_map logPageMap; const char *desc = "Retrieve Seagate Supported Log-Page information for the given device "; const char *output_format = "output in binary format"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int fmt; struct config { @@ -167,11 +168,10 @@ static int log_pages_supp(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = nvme_get_log_simple(dev_fd(dev), 0xc5, - sizeof(logPageMap), &logPageMap); + err = nvme_get_log_simple(hdl, 0xc5, &logPageMap, sizeof(logPageMap)); if (!err) { if (strcmp(cfg.output_format, "json")) { printf("Seagate Supported Log-pages count :%d\n", @@ -196,7 +196,7 @@ static int log_pages_supp(int argc, char **argv, struct command *cmd, if (err > 0) nvme_show_status(err); - dev_close(dev); + return err; } @@ -885,7 +885,7 @@ static void json_print_stx_smart_log_C0(struct json_object *root, STX_EXT_SMART_ json_array_add_value_object(logPages, lbaf); } -static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int vs_smart_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { struct nvme_id_ctrl ctrl; char modelNo[40]; @@ -898,7 +898,8 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi const char *desc = "Retrieve the Firmware Activation History for Seagate NVMe drives"; const char *output_format = "output in binary format"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err, index = 0; struct config { char *output_format; @@ -913,7 +914,7 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { printf("\nDevice not found\n"); return -1; @@ -929,7 +930,7 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi * to determine drive family. */ - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (!err) { memcpy(modelNo, ctrl.mn, sizeof(modelNo)); } else { @@ -938,7 +939,7 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi } if (!stx_is_jag_pan(modelNo)) { - err = nvme_get_log_simple(dev_fd(dev), 0xC4, sizeof(ExtdSMARTInfo), &ExtdSMARTInfo); + err = nvme_get_log_simple(hdl, 0xC4, &ExtdSMARTInfo, sizeof(ExtdSMARTInfo)); if (!err) { if (strcmp(cfg.output_format, "json")) { printf("%-39s %-15s %-19s\n", "Description", "Ext-Smart-Id", "Ext-Smart-Value"); @@ -960,7 +961,7 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi * Next get Log Page 0xCF */ - err = nvme_get_log_simple(dev_fd(dev), 0xCF, sizeof(logPageCF), &logPageCF); + err = nvme_get_log_simple(hdl, 0xCF, &logPageCF, sizeof(logPageCF)); if (!err) { if (strcmp(cfg.output_format, "json")) { print_smart_log_CF(&logPageCF); @@ -978,7 +979,7 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi nvme_show_status(err); } } else { - err = nvme_get_log_simple(dev_fd(dev), 0xC0, sizeof(ehExtSmart), &ehExtSmart); + err = nvme_get_log_simple(hdl, 0xC0, &ehExtSmart, sizeof(ehExtSmart)); if (!err) { if (strcmp(cfg.output_format, "json")) { @@ -999,8 +1000,8 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi nvme_show_status(err); } - err = nvme_get_log_simple(dev_fd(dev), 0xC4, - sizeof(ExtdSMARTInfo), &ExtdSMARTInfo); + err = nvme_get_log_simple(hdl, 0xC4, + &ExtdSMARTInfo, sizeof(ExtdSMARTInfo)); if (!err) { if (strcmp(cfg.output_format, "json")) { printf("%-39s %-15s %-19s\n", "Description", "Ext-Smart-Id", "Ext-Smart-Value"); @@ -1022,8 +1023,8 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi * Next get Log Page 0xCF */ - err = nvme_get_log_simple(dev_fd(dev), 0xCF, - sizeof(logPageCF), &logPageCF); + err = nvme_get_log_simple(hdl, 0xCF, + &logPageCF, sizeof(logPageCF)); if (!err) { if (strcmp(cfg.output_format, "json")) { print_smart_log_CF(&logPageCF); @@ -1040,8 +1041,6 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi nvme_show_status(err); } - dev_close(dev); - return err; } @@ -1050,8 +1049,9 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi /*************************************** * Temperature-Stats information ***************************************/ -static void json_temp_stats(__u32 temperature, __u32 PcbTemp, __u32 SocTemp, __u32 maxTemperature, - __u32 MaxSocTemp, __u32 cf_err, __u32 scCurrentTemp, __u32 scMaxTem) +static void json_temp_stats(__u32 temperature, __u32 PcbTemp, __u32 SocTemp, + __u32 maxTemperature, __u32 MaxSocTemp, + __u32 cf_err, __u32 scCurrentTemp, __u32 scMaxTem) { struct json_object *root = json_create_object(); @@ -1068,7 +1068,7 @@ static void json_temp_stats(__u32 temperature, __u32 PcbTemp, __u32 SocTemp, __u json_print_object(root, NULL); } -static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int temp_stats(int argc, char **argv, struct command *acmd, struct plugin *plugin) { struct nvme_smart_log smart_log; EXTENDED_SMART_INFO_T ExtdSMARTInfo; @@ -1081,7 +1081,8 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin nvme_print_flags_t flags; unsigned int temperature = 0, PcbTemp = 0, SocTemp = 0, scCurrentTemp = 0, scMaxTemp = 0; unsigned long long maxTemperature = 0, MaxSocTemp = 0; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct config { char *output_format; }; @@ -1095,7 +1096,7 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { printf("\nDevice not found\n"); return -1; @@ -1110,7 +1111,7 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin if (flags & NORMAL) printf("Seagate Temperature Stats Information :\n"); /*STEP-1 : Get Current Temperature from SMART */ - err = nvme_get_log_smart(dev_fd(dev), 0xffffffff, false, &smart_log); + err = nvme_get_log_smart(hdl, NVME_NSID_ALL, &smart_log); if (!err) { temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]); temperature = temperature ? temperature - 273 : 0; @@ -1126,8 +1127,8 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin } /* STEP-2 : Get Max temperature form Ext SMART-id 194 */ - err = nvme_get_log_simple(dev_fd(dev), 0xC4, - sizeof(ExtdSMARTInfo), &ExtdSMARTInfo); + err = nvme_get_log_simple(hdl, 0xC4, + &ExtdSMARTInfo, sizeof(ExtdSMARTInfo)); if (!err) { for (index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES; index++) { if (ExtdSMARTInfo.vendorData[index].AttributeNumber == VS_ATTR_ID_MAX_LIFE_TEMPERATURE) { @@ -1149,8 +1150,8 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin nvme_show_status(err); } - cf_err = nvme_get_log_simple(dev_fd(dev), 0xCF, - sizeof(ExtdSMARTInfo), &logPageCF); + cf_err = nvme_get_log_simple(hdl, 0xCF, + &logPageCF, sizeof(ExtdSMARTInfo)); if (!cf_err) { scCurrentTemp = logPageCF.AttrCF.SuperCapCurrentTemperature; @@ -1165,7 +1166,6 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin if (flags & JSON) json_temp_stats(temperature, PcbTemp, SocTemp, maxTemperature, MaxSocTemp, cf_err, scCurrentTemp, scMaxTemp); - dev_close(dev); return err; } /* EOF Temperature Stats information */ @@ -1173,7 +1173,7 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin /*************************************** * PCIe error-log information ***************************************/ -static void print_vs_pcie_error_log(pcie_error_log_page pcieErrorLog) +static void print_vs_pcie_error_log(pcie_error_log_page pcieErrorLog) { __u32 correctPcieEc = pcieErrorLog.BadDllpErrCnt + pcieErrorLog.BadTlpErrCnt + pcieErrorLog.RcvrErrCnt + pcieErrorLog.ReplayTOErrCnt + @@ -1247,10 +1247,11 @@ static void json_vs_pcie_error_log(pcie_error_log_page pcieErrorLog) json_print_object(root, NULL); } -static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int vs_pcie_error_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { pcie_error_log_page pcieErrorLog; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; const char *desc = "Retrieve Seagate PCIe error counters for the given device "; const char *output_format = "output in binary format"; @@ -1269,7 +1270,7 @@ static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { printf("\nDevice not found\n"); return -1; @@ -1284,8 +1285,8 @@ static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct if (flags & NORMAL) printf("Seagate PCIe error counters Information :\n"); - err = nvme_get_log_simple(dev_fd(dev), 0xCB, - sizeof(pcieErrorLog), &pcieErrorLog); + err = nvme_get_log_simple(hdl, 0xCB, + &pcieErrorLog, sizeof(pcieErrorLog)); if (!err) { if (flags & NORMAL) print_vs_pcie_error_log(pcieErrorLog); @@ -1296,7 +1297,7 @@ static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct nvme_show_status(err); } - dev_close(dev); + return err; } /* EOF PCIE error-log information */ @@ -1392,10 +1393,11 @@ static void json_stx_vs_fw_activate_history(stx_fw_activ_history_log_page fwActi json_free_object(root); } -static int stx_vs_fw_activate_history(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int stx_vs_fw_activate_history(int argc, char **argv, struct command *acmd, struct plugin *plugin) { stx_fw_activ_history_log_page fwActivHis; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; const char *desc = "Retrieve FW Activate History for Seagate device "; const char *output_format = "output in binary format"; @@ -1414,7 +1416,7 @@ static int stx_vs_fw_activate_history(int argc, char **argv, struct command *cmd OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err < 0) { printf("\nDevice not found\n"); return -1; @@ -1429,7 +1431,7 @@ static int stx_vs_fw_activate_history(int argc, char **argv, struct command *cmd if (flags & NORMAL) printf("Seagate FW Activation History Information :\n"); - err = nvme_get_log_simple(dev_fd(dev), 0xC2, sizeof(fwActivHis), &fwActivHis); + err = nvme_get_log_simple(hdl, 0xC2, &fwActivHis, sizeof(fwActivHis)); if (!err) { if (flags & NORMAL) print_stx_vs_fw_activate_history(fwActivHis); @@ -1439,18 +1441,18 @@ static int stx_vs_fw_activate_history(int argc, char **argv, struct command *cmd nvme_show_status(err); } - dev_close(dev); return err; } /* EOF FW Activation History log information */ -static int clear_fw_activate_history(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int clear_fw_activate_history(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Clear FW Activation History for the given Seagate device "; const char *save = "specifies that the controller shall save the attribute"; int err; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct nvme_id_ctrl ctrl; char modelNo[40]; __u32 result; @@ -1468,13 +1470,13 @@ static int clear_fw_activate_history(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err < 0) { printf("\nDevice not found\n"); return -1; } - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (!err) { memcpy(modelNo, ctrl.mn, sizeof(modelNo)); } else { @@ -1485,25 +1487,11 @@ static int clear_fw_activate_history(int argc, char **argv, struct command *cmd, if (!stx_is_jag_pan(modelNo)) { printf("\nDevice does not support Clear FW Activation History\n"); } else { - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = 0xC1, - .nsid = 0, - .cdw11 = 0x80000000, - .cdw12 = 0, - .save = 0, - .uuidx = 0, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); - if (err) - fprintf(stderr, "%s: couldn't clear PCIe correctable errors\n", - __func__); + err = nvme_set_features(hdl, 0, 0xC1, 0, 0x80000000, 0, 0, 0, 0, NULL, + 0, &result); + if (err) + fprintf(stderr, "%s: couldn't clear PCIe correctable errors\n", + __func__); } if (err < 0) { @@ -1511,12 +1499,11 @@ static int clear_fw_activate_history(int argc, char **argv, struct command *cmd, return errno; } - dev_close(dev); return err; } -static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Clear Seagate PCIe Correctable counters for the given device "; const char *save = "specifies that the controller shall save the attribute"; @@ -1524,7 +1511,8 @@ static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *c struct nvme_id_ctrl ctrl; char modelNo[40]; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 result; int err; @@ -1542,14 +1530,14 @@ static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *c OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { printf("\nDevice not found\n"); return -1; } - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (!err) { memcpy(modelNo, ctrl.mn, sizeof(modelNo)); } else { @@ -1558,40 +1546,25 @@ static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *c } if (!stx_is_jag_pan(modelNo)) { - err = nvme_set_features_simple(dev_fd(dev), 0xE1, 0, 0xCB, cfg.save, &result); + err = nvme_set_features_simple(hdl, 0, 0xE1, cfg.save, 0xCB, &result); } else { - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = 0xC3, - .nsid = 0, - .cdw11 = 0x80000000, - .cdw12 = 0, - .save = 0, - .uuidx = 0, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); + err = nvme_set_features(hdl, 0, 0xC3, 0, 0x80000000, 0, 0, 0, 0, NULL, + 0, &result); if (err) fprintf(stderr, "%s: couldn't clear PCIe correctable errors\n", __func__); } - err = nvme_set_features_simple(dev_fd(dev), 0xE1, 0, 0xCB, cfg.save, &result); + err = nvme_set_features_simple(hdl, 0, 0xE1, cfg.save, 0xCB, &result); if (err < 0) { perror("set-feature"); return errno; } - dev_close(dev); return err; } -static int get_host_tele(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_host_tele(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Capture the Telemetry Host-Initiated Data in either hex-dump (default) or binary format"; @@ -1602,7 +1575,9 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug const char *raw = "output in raw format"; struct nvme_temetry_log_hdr tele_log; int blkCnt, maxBlk = 0, blksToGet; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; unsigned char *log; __le64 offset = 0; int err, dump_fd; @@ -1625,22 +1600,21 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; dump_fd = STDOUT_FILENO; cfg.log_id = (cfg.log_id << 8) | 0x07; - err = nvme_get_nsid_log(dev_fd(dev), false, cfg.log_id, - cfg.namespace_id, - sizeof(tele_log), (void *)(&tele_log)); + err = nvme_get_nsid_log(hdl, cfg.namespace_id, false, cfg.log_id, + (void *)(&tele_log), sizeof(tele_log)); if (!err) { maxBlk = tele_log.tele_data_area3; offset += 512; if (!cfg.raw_binary) { printf("Device:%s log-id:%d namespace-id:%#x\n", - dev->name, cfg.log_id, + nvme_transport_handle_get_name(hdl), cfg.log_id, cfg.namespace_id); printf("Data Block 1 Last Block:%d Data Block 2 Last Block:%d Data Block 3 Last Block:%d\n", tele_log.tele_data_area1, tele_log.tele_data_area2, tele_log.tele_data_area3); @@ -1662,7 +1636,7 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug blksToGet = ((maxBlk - blkCnt) >= TELEMETRY_BLOCKS_TO_READ) ? TELEMETRY_BLOCKS_TO_READ : (maxBlk - blkCnt); if (!blksToGet) { - dev_close(dev); + return err; } @@ -1671,30 +1645,17 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug if (!log) { fprintf(stderr, "could not alloc buffer for log\n"); - dev_close(dev); + return -EINVAL; } memset(log, 0, bytesToGet); - struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .lid = cfg.log_id, - .nsid = cfg.namespace_id, - .lpo = offset, - .lsp = 0, - .lsi = 0, - .rae = true, - .uuidx = 0, - .csi = NVME_CSI_NVM, - .ot = false, - .len = bytesToGet, - .log = (void *)log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - err = nvme_get_log(&args); + nvme_init_get_log(&cmd, cfg.namespace_id, cfg.log_id, + NVME_CSI_NVM, log, bytesToGet); + nvme_init_get_log_lpo(&cmd, offset); + err = nvme_get_log(hdl, &cmd, true, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (!err) { offset += (__le64)bytesToGet; @@ -1715,17 +1676,18 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug free(log); } - dev_close(dev); return err; } -static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_ctrl_tele(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Capture the Telemetry Controller-Initiated Data in either hex-dump (default) or binary format"; const char *namespace_id = "desired namespace"; const char *raw = "output in raw format"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; int err, dump_fd; struct nvme_temetry_log_hdr tele_log; __le64 offset = 0; @@ -1748,22 +1710,22 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; dump_fd = STDOUT_FILENO; log_id = 0x08; - err = nvme_get_nsid_log(dev_fd(dev), false, log_id, cfg.namespace_id, - sizeof(tele_log), (void *)(&tele_log)); + err = nvme_get_nsid_log(hdl, cfg.namespace_id, false, log_id, + (void *)(&tele_log), sizeof(tele_log)); if (!err) { maxBlk = tele_log.tele_data_area3; offset += 512; if (!cfg.raw_binary) { printf("Device:%s namespace-id:%#x\n", - dev->name, cfg.namespace_id); + nvme_transport_handle_get_name(hdl), cfg.namespace_id); printf("Data Block 1 Last Block:%d Data Block 2 Last Block:%d Data Block 3 Last Block:%d\n", tele_log.tele_data_area1, tele_log.tele_data_area2, tele_log.tele_data_area3); @@ -1796,24 +1758,11 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug memset(log, 0, bytesToGet); - struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .lid = log_id, - .nsid = cfg.namespace_id, - .lpo = offset, - .lsp = 0, - .lsi = 0, - .rae = true, - .uuidx = 0, - .csi = NVME_CSI_NVM, - .ot = false, - .len = bytesToGet, - .log = (void *)log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - err = nvme_get_log(&args); + nvme_init_get_log(&cmd, cfg.namespace_id, log_id, + NVME_CSI_NVM, log, bytesToGet); + nvme_init_get_log_lpo(&cmd, offset); + err = nvme_get_log(hdl, &cmd, true, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (!err) { offset += (__le64)bytesToGet; @@ -1834,24 +1783,27 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug free(log); } - dev_close(dev); + return err; } -void seaget_d_raw(unsigned char *buf, int len, int fd) +void +seaget_d_raw(unsigned char *buf, int len, int fd) { if (write(fd, (void *)buf, len) <= 0) printf("%s: Write Failed\n", __func__); } -static int vs_internal_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int vs_internal_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Capture the Telemetry Controller-Initiated Data in binary format"; const char *namespace_id = "desired namespace"; const char *file = "dump file"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; int err, dump_fd; int flags = O_WRONLY | O_CREAT; int mode = 0664; @@ -1877,7 +1829,7 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -1886,14 +1838,13 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl dump_fd = open(cfg.file, flags, mode); if (dump_fd < 0) { perror(cfg.file); - dev_close(dev); return -EINVAL; } } log_id = 0x08; - err = nvme_get_nsid_log(dev_fd(dev), false, log_id, cfg.namespace_id, - sizeof(tele_log), (void *)(&tele_log)); + err = nvme_get_nsid_log(hdl, cfg.namespace_id, false, log_id, + (void *)(&tele_log), sizeof(tele_log)); if (!err) { maxBlk = tele_log.tele_data_area3; offset += 512; @@ -1926,24 +1877,12 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl memset(log, 0, bytesToGet); - struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .lid = log_id, - .nsid = cfg.namespace_id, - .lpo = offset, - .lsp = 0, - .lsi = 0, - .rae = true, - .uuidx = 0, - .csi = NVME_CSI_NVM, - .ot = false, - .len = bytesToGet, - .log = (void *)log, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - err = nvme_get_log(&args); + nvme_init_get_log_lpo(&cmd, offset); + nvme_init_get_log(&cmd, cfg.namespace_id, log_id, + NVME_CSI_NVM, log, bytesToGet); + nvme_init_get_log_lpo(&cmd, offset); + err = nvme_get_log(hdl, &cmd, true, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (!err) { offset += (__le64)bytesToGet; @@ -1963,12 +1902,11 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl if (strlen(cfg.file)) close(dump_fd); - dev_close(dev); return err; } /*SEAGATE-PLUGIN Version */ -static int seagate_plugin_version(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int seagate_plugin_version(int argc, char **argv, struct command *acmd, struct plugin *plugin) { printf("Seagate-Plugin version : %d.%d\n", SEAGATE_PLUGIN_VERSION_MAJOR, @@ -1978,7 +1916,7 @@ static int seagate_plugin_version(int argc, char **argv, struct command *cmd, st /*EOF SEAGATE-PLUGIN Version */ /*OCP SEAGATE-PLUGIN Version */ -static int stx_ocp_plugin_version(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int stx_ocp_plugin_version(int argc, char **argv, struct command *acmd, struct plugin *plugin) { printf("Seagate-OCP-Plugin version : %d.%d\n", SEAGATE_OCP_PLUGIN_VERSION_MAJOR, diff --git a/plugins/sed/sed.c b/plugins/sed/sed.c index 3d6052a927..9cfbebd764 100644 --- a/plugins/sed/sed.c +++ b/plugins/sed/sed.c @@ -62,138 +62,137 @@ OPT_ARGS(discovery_opts) = { * Open the NVMe device specified on the command line. It must be the * NVMe block device (e.g. /dev/nvme0n1). */ -static int sed_opal_open_device(struct nvme_dev **dev, int argc, char **argv, +static int sed_opal_open_device(struct nvme_global_ctx **ctx, struct nvme_transport_handle **hdl, int argc, char **argv, const char *desc, struct argconfig_commandline_options *opts) { int err; - err = parse_and_open(dev, argc, argv, desc, opts); + err = parse_and_open(ctx, hdl, argc, argv, desc, opts); if (err) return err; - if (!S_ISBLK((*dev)->direct.stat.st_mode)) { + if (!nvme_transport_handle_is_blkdev(*hdl)) { fprintf(stderr, "ERROR : The NVMe block device must be specified\n"); err = -EINVAL; - dev_close(*dev); } return err; } -static int sed_opal_discover(int argc, char **argv, struct command *cmd, +static int sed_opal_discover(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - int err; const char *desc = "Query SED device and display locking features"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + int err; - err = sed_opal_open_device(&dev, argc, argv, desc, discovery_opts); + err = sed_opal_open_device(&ctx, &hdl, argc, argv, desc, discovery_opts); if (err) return err; - err = sedopal_cmd_discover(dev->direct.fd); + err = sedopal_cmd_discover(nvme_transport_handle_get_fd(hdl)); - dev_close(dev); return err; } -static int sed_opal_initialize(int argc, char **argv, struct command *cmd, +static int sed_opal_initialize(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - int err; const char *desc = "Initialize a SED device for locking"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + int err; - err = sed_opal_open_device(&dev, argc, argv, desc, init_opts); + err = sed_opal_open_device(&ctx, &hdl, argc, argv, desc, init_opts); if (err) return err; - err = sedopal_cmd_initialize(dev->direct.fd); + err = sedopal_cmd_initialize(nvme_transport_handle_get_fd(hdl)); if ((err != 0) && (err != -EOPNOTSUPP)) fprintf(stderr, "initialize: SED error - %s\n", sedopal_error_to_text(err)); - dev_close(dev); return err; } -static int sed_opal_revert(int argc, char **argv, struct command *cmd, +static int sed_opal_revert(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - int err; const char *desc = "Revert a SED device from locking state"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + int err; - err = sed_opal_open_device(&dev, argc, argv, desc, revert_opts); + err = sed_opal_open_device(&ctx, &hdl, argc, argv, desc, revert_opts); if (err) return err; - err = sedopal_cmd_revert(dev->direct.fd); + err = sedopal_cmd_revert(nvme_transport_handle_get_fd(hdl)); if ((err != 0) && (err != -EOPNOTSUPP) && (err != EPERM)) fprintf(stderr, "revert: SED error - %s\n", sedopal_error_to_text(err)); - dev_close(dev); return err; } -static int sed_opal_lock(int argc, char **argv, struct command *cmd, +static int sed_opal_lock(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - int err; const char *desc = "Lock a SED device"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + int err; - err = sed_opal_open_device(&dev, argc, argv, desc, lock_opts); + err = sed_opal_open_device(&ctx, &hdl, argc, argv, desc, lock_opts); if (err) return err; - err = sedopal_cmd_lock(dev->direct.fd); + err = sedopal_cmd_lock(nvme_transport_handle_get_fd(hdl)); if ((err != 0) && (err != -EOPNOTSUPP)) fprintf(stderr, "lock: SED error - %s\n", sedopal_error_to_text(err)); - dev_close(dev); return err; } -static int sed_opal_unlock(int argc, char **argv, struct command *cmd, +static int sed_opal_unlock(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - int err; const char *desc = "Unlock a SED device"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + int err; - err = sed_opal_open_device(&dev, argc, argv, desc, lock_opts); + err = sed_opal_open_device(&ctx, &hdl, argc, argv, desc, lock_opts); if (err) return err; - err = sedopal_cmd_unlock(dev->direct.fd); + err = sedopal_cmd_unlock(nvme_transport_handle_get_fd(hdl)); if ((err != 0) && (err != -EOPNOTSUPP)) fprintf(stderr, "unlock: SED error - %s\n", sedopal_error_to_text(err)); - dev_close(dev); return err; } -static int sed_opal_password(int argc, char **argv, struct command *cmd, +static int sed_opal_password(int argc, char **argv, struct command *acmd, struct plugin *plugin) { int err; const char *desc = "Change the locking password of a SED device"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; - err = sed_opal_open_device(&dev, argc, argv, desc, no_opts); + err = sed_opal_open_device(&ctx, &hdl, argc, argv, desc, no_opts); if (err) return err; - err = sedopal_cmd_password(dev->direct.fd); + err = sedopal_cmd_password(nvme_transport_handle_get_fd(hdl)); if ((err != 0) && (err != EPERM)) fprintf(stderr, "password: SED error - %s\n", sedopal_error_to_text(err)); - dev_close(dev); return err; } diff --git a/plugins/sed/sedopal_cmd.c b/plugins/sed/sedopal_cmd.c index bbcf16b4cf..40d7a7ffcd 100644 --- a/plugins/sed/sedopal_cmd.c +++ b/plugins/sed/sedopal_cmd.c @@ -11,6 +11,9 @@ #include #include #include + +#include + #include "sedopal_spec.h" #include "sedopal_cmd.h" diff --git a/plugins/shannon/shannon-nvme.c b/plugins/shannon/shannon-nvme.c index b4c02fb79d..1a44f32743 100644 --- a/plugins/shannon/shannon-nvme.c +++ b/plugins/shannon/shannon-nvme.c @@ -60,8 +60,8 @@ struct nvme_shannon_smart_log { __u8 vend_spec_resv; }; -static void show_shannon_smart_log(struct nvme_shannon_smart_log *smart, unsigned int nsid, - const char *devname) +static void show_shannon_smart_log(struct nvme_shannon_smart_log *smart, + unsigned int nsid, const char *devname) { printf("Additional Smart Log for NVME device:%s namespace-id:%x\n", devname, nsid); @@ -113,14 +113,15 @@ static void show_shannon_smart_log(struct nvme_shannon_smart_log *smart, unsigne int48_to_long(smart->items[SRAM_ERROR_CNT].item_val)); } -static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_additional_smart_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { struct nvme_shannon_smart_log smart_log; char *desc = "Get Shannon vendor specific additional smart log (optionally, for the specified namespace), and show it."; const char *namespace = "(optional) desired namespace"; const char *raw = "dump output in binary format"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct config { __u32 namespace_id; bool raw_binary; @@ -137,24 +138,26 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = nvme_get_nsid_log(dev_fd(dev), false, 0xca, cfg.namespace_id, - sizeof(smart_log), &smart_log); + err = nvme_get_nsid_log(hdl, cfg.namespace_id, false, 0xca, + &smart_log, sizeof(smart_log)); if (!err) { if (!cfg.raw_binary) - show_shannon_smart_log(&smart_log, cfg.namespace_id, dev->name); + show_shannon_smart_log( + &smart_log, cfg.namespace_id, + nvme_transport_handle_get_name(hdl)); else d_raw((unsigned char *)&smart_log, sizeof(smart_log)); } else if (err > 0) { nvme_show_status(err); } - dev_close(dev); + return err; } -static int get_additional_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_additional_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Read operating parameters of the\n" "specified controller. Operating parameters are grouped\n" @@ -174,7 +177,8 @@ static int get_additional_feature(int argc, char **argv, struct command *cmd, st const char *data_len = "buffer len (if) data is returned"; const char *cdw11 = "dword 11 for interrupt vector config"; const char *human_readable = "show infos in readable format"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; void *buf = NULL; __u32 result; int err; @@ -208,49 +212,33 @@ static int get_additional_feature(int argc, char **argv, struct command *cmd, st OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; if (cfg.sel > 7) { fprintf(stderr, "invalid 'select' param:%d\n", cfg.sel); - dev_close(dev); return -EINVAL; } if (!cfg.feature_id) { fprintf(stderr, "feature-id required param\n"); - dev_close(dev); return -EINVAL; } if (cfg.data_len) { - if (posix_memalign(&buf, getpagesize(), cfg.data_len)) { - dev_close(dev); - exit(ENOMEM); - } + if (posix_memalign(&buf, getpagesize(), cfg.data_len)) + return -ENOMEM; memset(buf, 0, cfg.data_len); } - struct nvme_get_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = cfg.feature_id, - .nsid = cfg.namespace_id, - .sel = cfg.sel, - .cdw11 = cfg.cdw11, - .uuidx = 0, - .data_len = cfg.data_len, - .data = buf, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_get_features(&args); + err = nvme_get_features(hdl, cfg.namespace_id, cfg.feature_id, cfg.sel, + cfg.cdw11, 0, buf, cfg.data_len, &result); if (err > 0) nvme_show_status(err); free(buf); return err; } -static int set_additional_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int set_additional_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Modify the saveable or changeable\n" "current operating parameters of the controller. Operating\n" @@ -269,9 +257,10 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st const char *data = "optional file for feature data (default stdin)"; const char *value = "new value of feature (required)"; const char *save = "specifies that the controller shall save the attribute"; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_free_ void *buf = NULL; int ffd = STDIN_FILENO; - struct nvme_dev *dev; - void *buf = NULL; __u32 result; int err; @@ -303,20 +292,18 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; if (!cfg.feature_id) { fprintf(stderr, "feature-id required param\n"); - dev_close(dev); return -EINVAL; } if (cfg.data_len) { if (posix_memalign(&buf, getpagesize(), cfg.data_len)) { fprintf(stderr, "can not allocate feature payload\n"); - dev_close(dev); return -ENOMEM; } memset(buf, 0, cfg.data_len); @@ -327,37 +314,21 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st ffd = open(cfg.file, O_RDONLY); if (ffd <= 0) { fprintf(stderr, "no firmware file provided\n"); - err = EINVAL; - goto free; + return -EINVAL; } } err = read(ffd, (void *)buf, cfg.data_len); if (err < 0) { fprintf(stderr, "failed to read data buffer from input file\n"); - err = EINVAL; - goto free; + return -EINVAL; } } - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = cfg.feature_id, - .nsid = cfg.namespace_id, - .cdw11 = cfg.value, - .cdw12 = 0, - .save = cfg.save, - .uuidx = 0, - .cdw15 = 0, - .data_len = cfg.data_len, - .data = buf, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); + err = nvme_set_features(hdl, cfg.namespace_id, cfg.feature_id, cfg.save, + cfg.value, 0, 0, 0, 0, buf, cfg.data_len, &result); if (err < 0) { perror("set-feature"); - goto free; + return -errno; } if (!err) { if (buf) @@ -365,15 +336,11 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st } else if (err > 0) nvme_show_status(err); -free: - free(buf); return err; } -static int shannon_id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int shannon_id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return __id_ctrl(argc, argv, cmd, plugin, NULL); + return __id_ctrl(argc, argv, acmd, plugin, NULL); } - - diff --git a/plugins/solidigm/solidigm-garbage-collection.c b/plugins/solidigm/solidigm-garbage-collection.c index 3c046b0ed4..3e91205162 100644 --- a/plugins/solidigm/solidigm-garbage-collection.c +++ b/plugins/solidigm/solidigm-garbage-collection.c @@ -65,11 +65,13 @@ static void vu_gc_log_show(struct garbage_control_collection_log *payload, const } } -int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get and parse Solidigm vendor specific garbage collection event log."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; - struct nvme_dev *dev; int err; __u8 uuid_index; @@ -86,53 +88,38 @@ int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *c OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; err = validate_output_format(cfg.output_format, &flags); if (err) { fprintf(stderr, "Invalid output format '%s'\n", cfg.output_format); - dev_close(dev); return -EINVAL; } - sldgm_get_uuid_index(dev, &uuid_index); + sldgm_get_uuid_index(hdl, &uuid_index); struct garbage_control_collection_log gc_log; const int solidigm_vu_gc_log_id = 0xfd; - struct nvme_get_log_args args = { - .lpo = 0, - .result = NULL, - .log = &gc_log, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = solidigm_vu_gc_log_id, - .len = sizeof(gc_log), - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, - .uuidx = uuid_index, - .rae = false, - .ot = false, - }; - - err = nvme_get_log(&args); + nvme_init_get_log(&cmd, NVME_NSID_ALL, + solidigm_vu_gc_log_id, NVME_CSI_NVM, + &gc_log, sizeof(gc_log)); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_index, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + err = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (!err) { if (flags & BINARY) d_raw((unsigned char *)&gc_log, sizeof(gc_log)); else if (flags & JSON) - vu_gc_log_show_json(&gc_log, dev->name); + vu_gc_log_show_json(&gc_log, nvme_transport_handle_get_name(hdl)); else - vu_gc_log_show(&gc_log, dev->name, uuid_index); + vu_gc_log_show(&gc_log, nvme_transport_handle_get_name(hdl), uuid_index); } else if (err > 0) { nvme_show_status(err); } - /* Redundant close() to make static code analysis happy */ - close(dev->direct.fd); - dev_close(dev); return err; } diff --git a/plugins/solidigm/solidigm-garbage-collection.h b/plugins/solidigm/solidigm-garbage-collection.h index a3e34b2b8b..7dd8041804 100644 --- a/plugins/solidigm/solidigm-garbage-collection.h +++ b/plugins/solidigm/solidigm-garbage-collection.h @@ -5,4 +5,4 @@ * Author: leonardo.da.cunha@solidigm.com */ -int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *cmd, struct plugin *plugin); +int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); diff --git a/plugins/solidigm/solidigm-get-drive-info.c b/plugins/solidigm/solidigm-get-drive-info.c index c783fa8abd..866b3c07a9 100644 --- a/plugins/solidigm/solidigm-get-drive-info.c +++ b/plugins/solidigm/solidigm-get-drive-info.c @@ -7,17 +7,16 @@ #include #include "nvme-print.h" -#include "nvme-wrap.h" #include "common.h" -int sldgm_get_drive_info(int argc, char **argv, struct command *cmd, struct plugin *plugin) +int sldgm_get_drive_info(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; const char *desc = "Get drive HW information"; const char *FTL_unit_size_str = "FTL_unit_size"; char *output_format = "normal"; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; - nvme_root_t r; nvme_ctrl_t c; nvme_ns_t n; struct nvme_id_ns ns = { 0 }; @@ -31,7 +30,7 @@ int sldgm_get_drive_info(int argc, char **argv, struct command *cmd, struct plug OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -41,12 +40,19 @@ int sldgm_get_drive_info(int argc, char **argv, struct command *cmd, struct plug return err; } - r = nvme_scan(NULL); - c = nvme_scan_ctrl(r, dev->name); - n = c ? nvme_ctrl_first_ns(c) : nvme_scan_namespace(dev->name); - if (!n) { - nvme_show_error("solidigm-vs-drive-info: drive missing namespace"); - return -EINVAL; + err = nvme_scan_topology(ctx, NULL, NULL); + if (err) + return err; + + err = nvme_scan_ctrl(ctx, nvme_transport_handle_get_name(hdl), &c); + if (err) + n = nvme_ctrl_first_ns(c); + else { + err = nvme_scan_namespace(nvme_transport_handle_get_name(hdl), &n); + if (err) { + nvme_show_error("solidigm-vs-drive-info: drive missing namespace"); + return err; + } } err = nvme_ns_identify(n, &ns); diff --git a/plugins/solidigm/solidigm-get-drive-info.h b/plugins/solidigm/solidigm-get-drive-info.h index ffc1bd2468..859fbeaad4 100644 --- a/plugins/solidigm/solidigm-get-drive-info.h +++ b/plugins/solidigm/solidigm-get-drive-info.h @@ -5,4 +5,4 @@ * Author: leonardo.da.cunha@solidigm.com */ -int sldgm_get_drive_info(int argc, char **argv, struct command *cmd, struct plugin *plugin); +int sldgm_get_drive_info(int argc, char **argv, struct command *acmd, struct plugin *plugin); diff --git a/plugins/solidigm/solidigm-internal-logs.c b/plugins/solidigm/solidigm-internal-logs.c index 303d471275..8388d47649 100644 --- a/plugins/solidigm/solidigm-internal-logs.c +++ b/plugins/solidigm/solidigm-internal-logs.c @@ -132,7 +132,6 @@ struct config { }; struct ilog { - struct nvme_dev *dev; struct config *cfg; int count; struct nvme_id_ctrl id_ctrl; @@ -173,7 +172,7 @@ static void print_nlog_header(__u8 *buffer) #define INTERNAL_LOG_MAX_DWORD_TRANSFER (INTERNAL_LOG_MAX_BYTE_TRANSFER / 4) static int cmd_dump_repeat(struct nvme_passthru_cmd *cmd, __u32 total_dw_size, - int out_fd, int ioctl_fd, bool force_max_transfer) + int out_fd, struct nvme_transport_handle *hdl, bool force_max_transfer) { int err = 0; @@ -182,7 +181,7 @@ static int cmd_dump_repeat(struct nvme_passthru_cmd *cmd, __u32 total_dw_size, cmd->cdw10 = force_max_transfer ? INTERNAL_LOG_MAX_DWORD_TRANSFER : dword_tfer; cmd->data_len = dword_tfer * 4; - err = nvme_submit_admin_passthru(ioctl_fd, cmd, NULL); + err = nvme_submit_admin_passthru(hdl, cmd, NULL); if (err) return err; @@ -207,18 +206,18 @@ static int write_header(__u8 *buf, int fd, size_t amnt) return 0; } -static int read_header(struct nvme_passthru_cmd *cmd, int ioctl_fd) +static int read_header(struct nvme_passthru_cmd *cmd, struct nvme_transport_handle *hdl) { memset((void *)(uintptr_t)cmd->addr, 0, INTERNAL_LOG_MAX_BYTE_TRANSFER); - return cmd_dump_repeat(cmd, INTERNAL_LOG_MAX_DWORD_TRANSFER, -1, ioctl_fd, false); + return cmd_dump_repeat(cmd, INTERNAL_LOG_MAX_DWORD_TRANSFER, -1, hdl, false); } -static int get_serial_number(char *str, int fd) +static int get_serial_number(char *str, struct nvme_transport_handle *hdl) { struct nvme_id_ctrl ctrl = {0}; int err; - err = nvme_identify_ctrl(fd, &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) return err; @@ -229,7 +228,7 @@ static int get_serial_number(char *str, int fd) return err; } -static int ilog_dump_assert_logs(struct ilog *ilog) +static int ilog_dump_assert_logs(struct nvme_transport_handle *hdl, struct ilog *ilog) { __u8 buf[INTERNAL_LOG_MAX_BYTE_TRANSFER]; __u8 head_buf[INTERNAL_LOG_MAX_BYTE_TRANSFER]; @@ -245,7 +244,7 @@ static int ilog_dump_assert_logs(struct ilog *ilog) }; int output, err; - err = read_header(&cmd, dev_fd(ilog->dev)); + err = read_header(&cmd, hdl); if (err) return err; @@ -276,7 +275,7 @@ static int ilog_dump_assert_logs(struct ilog *ilog) continue; cmd.cdw13 = ad->core[i].coreoffset; err = cmd_dump_repeat(&cmd, ad->core[i].assertsize, output, - dev_fd(ilog->dev), false); + hdl, false); if (err) { close(output); return err; @@ -287,7 +286,7 @@ static int ilog_dump_assert_logs(struct ilog *ilog) return err; } -static int ilog_dump_event_logs(struct ilog *ilog) +static int ilog_dump_event_logs(struct nvme_transport_handle *hdl, struct ilog *ilog) { __u8 buf[INTERNAL_LOG_MAX_BYTE_TRANSFER]; __u8 head_buf[INTERNAL_LOG_MAX_BYTE_TRANSFER]; @@ -303,7 +302,7 @@ static int ilog_dump_event_logs(struct ilog *ilog) int output; int core_num, err; - err = read_header(&cmd, dev_fd(ilog->dev)); + err = read_header(&cmd, hdl); if (err) return err; if (asprintf(&file_path, "%s/EventLog.bin", ilog->cfg->out_dir)) @@ -334,7 +333,7 @@ static int ilog_dump_event_logs(struct ilog *ilog) } cmd.cdw13 = ehdr->edumps[j].coreoffset; err = cmd_dump_repeat(&cmd, ehdr->edumps[j].coresize, - output, dev_fd(ilog->dev), false); + output, hdl, false); if (err) { close(output); return err; @@ -361,7 +360,7 @@ static size_t get_nlog_header_size(struct nlog_dump_header_common *nlog_header) } /* dumps nlogs from specified core or all cores when core = -1 */ -static int ilog_dump_nlogs(struct ilog *ilog, int core) +static int ilog_dump_nlogs(struct nvme_transport_handle *hdl, struct ilog *ilog, int core) { int err = 0; __u32 count, core_num; @@ -394,7 +393,7 @@ static int ilog_dump_nlogs(struct ilog *ilog, int core) do { cmd.cdw13 = 0; cmd.cdw12 = log_select.raw; - err = read_header(&cmd, dev_fd(ilog->dev)); + err = read_header(&cmd, hdl); if (err) { if (is_open) close(output); @@ -420,7 +419,7 @@ static int ilog_dump_nlogs(struct ilog *ilog, int core) print_nlog_header(buf); cmd.cdw13 = 0x400; err = cmd_dump_repeat(&cmd, nlog_header->nlogbytesize / 4, - output, dev_fd(ilog->dev), true); + output, hdl, true); if (err) break; } while (++log_select.selectNlog < count); @@ -490,23 +489,28 @@ static int log_save(struct log *log, const char *parent_dir_name, const char *su return 0; } -static int ilog_dump_identify_page(struct ilog *ilog, struct log *cns, __u32 nsid) +static int ilog_dump_identify_page(struct nvme_transport_handle *hdl, + struct ilog *ilog, struct log *cns, __u32 nsid) { __u8 data[NVME_IDENTIFY_DATA_SIZE]; __u8 *buff = cns->buffer ? cns->buffer : data; _cleanup_free_ char *filename = NULL; - int err = nvme_identify_cns_nsid(dev_fd(ilog->dev), cns->id, nsid, buff); + int err; + err = nvme_identify(hdl, nsid, NVME_CSI_NVM, cns->id, buff, 0); if (err) return err; - if (asprintf(&filename, "cntid_0_cns_%d_nsid_%d_nvmsetid_0_csi_0.bin", cns->id, nsid) < 0) + if (asprintf(&filename, "cntid_0_cns_%d_nsid_%d_nvmsetid_0_csi_0.bin", + cns->id, nsid) < 0) return -errno; - return log_save(cns, ilog->cfg->out_dir, "identify", filename, buff, sizeof(data)); + return log_save(cns, ilog->cfg->out_dir, "identify", filename, buff, + sizeof(data)); } -static int ilog_ensure_dump_id_ctrl(struct ilog *ilog) +static int ilog_ensure_dump_id_ctrl(struct nvme_transport_handle *hdl, + struct ilog *ilog) { static bool first = true; static int err; @@ -517,7 +521,7 @@ static int ilog_ensure_dump_id_ctrl(struct ilog *ilog) return err; first = false; - err = ilog_dump_identify_page(ilog, &idctrl, 0); + err = ilog_dump_identify_page(hdl, ilog, &idctrl, 0); if (err) return err; @@ -532,7 +536,7 @@ static int ilog_ensure_dump_id_ctrl(struct ilog *ilog) return err; } -static int ilog_dump_telemetry(struct ilog *ilog, enum log_type ttype) +static int ilog_dump_telemetry(struct nvme_transport_handle *hdl, struct ilog *ilog, enum log_type ttype) { int err = 0; enum nvme_telemetry_da da; @@ -540,9 +544,10 @@ static int ilog_dump_telemetry(struct ilog *ilog, enum log_type ttype) const char *file_name; struct nvme_feat_host_behavior prev = {0}; bool host_behavior_changed = false; + struct nvme_passthru_cmd cmd; struct log log = {0}; - err = ilog_ensure_dump_id_ctrl(ilog); + err = ilog_ensure_dump_id_ctrl(hdl, ilog); if (err) return err; @@ -551,13 +556,15 @@ static int ilog_dump_telemetry(struct ilog *ilog, enum log_type ttype) if (da == 4) { __u32 result; - int err = nvme_get_features_host_behavior(dev_fd(ilog->dev), 0, &prev, &result); + nvme_init_get_features_host_behavior(&cmd, 0, &prev); + int err = nvme_submit_admin_passthru(hdl, &cmd, &result); if (!err && !prev.etdas) { struct nvme_feat_host_behavior da4_enable = prev; da4_enable.etdas = 1; - nvme_set_features_host_behavior(dev_fd(ilog->dev), 0, &da4_enable); + nvme_init_set_features_host_behavior(&cmd, 0, &da4_enable); + nvme_submit_admin_passthru(hdl, &cmd, NULL); host_behavior_changed = true; } } @@ -566,14 +573,14 @@ static int ilog_dump_telemetry(struct ilog *ilog, enum log_type ttype) case HIT: file_name = "lid_0x07_lsp_0x01_lsi_0x0000.bin"; log.desc = "Host Initiated Telemetry"; - err = sldgm_dynamic_telemetry(dev_fd(ilog->dev), true, false, false, mdts, + err = sldgm_dynamic_telemetry(hdl, true, false, false, mdts, da, (struct nvme_telemetry_log **) &log.buffer, &log.buffer_size); break; case CIT: file_name = "lid_0x08_lsp_0x00_lsi_0x0000.bin"; log.desc = "Controller Initiated Telemetry"; - err = sldgm_dynamic_telemetry(dev_fd(ilog->dev), false, true, true, mdts, + err = sldgm_dynamic_telemetry(hdl, false, true, true, mdts, da, (struct nvme_telemetry_log **) &log.buffer, &log.buffer_size); break; @@ -581,8 +588,10 @@ static int ilog_dump_telemetry(struct ilog *ilog, enum log_type ttype) return -EINVAL; } - if (host_behavior_changed) - nvme_set_features_host_behavior(dev_fd(ilog->dev), 0, &prev); + if (host_behavior_changed) { + nvme_init_set_features_host_behavior(&cmd, 0, &prev); + nvme_submit_admin_passthru(hdl, &cmd, NULL); + } if (err) return err; @@ -592,7 +601,7 @@ static int ilog_dump_telemetry(struct ilog *ilog, enum log_type ttype) return err; } -static int ilog_dump_identify_pages(struct ilog *ilog) +static int ilog_dump_identify_pages(struct nvme_transport_handle *hdl, struct ilog *ilog) { struct nvme_ns_list ns_attached_list; struct nvme_ns_list ns_allocated_list; @@ -619,10 +628,10 @@ static int ilog_dump_identify_pages(struct ilog *ilog) struct log allocated = {NVME_IDENTIFY_CNS_ALLOCATED_NS, "Allocated Namespace Data", NVME_IDENTIFY_DATA_SIZE, NULL}; - ilog_ensure_dump_id_ctrl(ilog); + ilog_ensure_dump_id_ctrl(hdl, ilog); for (int i = 0; i < ARRAY_SIZE(identify_base_list); i++) { - int err = ilog_dump_identify_page(ilog, &identify_base_list[i], 0); + int err = ilog_dump_identify_page(hdl, ilog, &identify_base_list[i], 0); if (err == 0) ilog->count++; @@ -630,7 +639,7 @@ static int ilog_dump_identify_pages(struct ilog *ilog) while (ns_attached_list.ns[j]) { for (int i = 0; i < ARRAY_SIZE(identify_ns_required_list); i++) { - int err = ilog_dump_identify_page(ilog, &identify_ns_required_list[i], + int err = ilog_dump_identify_page(hdl, ilog, &identify_ns_required_list[i], ns_attached_list.ns[j]); if (err == 0) @@ -641,7 +650,7 @@ static int ilog_dump_identify_pages(struct ilog *ilog) j = 0; while (ns_allocated_list.ns[j]) { - int err = ilog_dump_identify_page(ilog, &allocated, ns_allocated_list.ns[j]); + int err = ilog_dump_identify_page(hdl, ilog, &allocated, ns_allocated_list.ns[j]); if (err == 0) ilog->count++; @@ -651,7 +660,7 @@ static int ilog_dump_identify_pages(struct ilog *ilog) return 0; } -static int ilog_dump_log_page(struct ilog *ilog, struct log *lp, __u32 nsid) +static int ilog_dump_log_page(struct nvme_transport_handle *hdl, struct ilog *ilog, struct log *lp, __u32 nsid) { __u8 *buff = lp->buffer; _cleanup_free_ char *filename = NULL; @@ -664,7 +673,7 @@ static int ilog_dump_log_page(struct ilog *ilog, struct log *lp, __u32 nsid) if (!buff) return -ENOMEM; } - err = nvme_get_nsid_log(dev_fd(ilog->dev), 0, lp->id, 0, lp->buffer_size, buff); + err = nvme_get_nsid_log(hdl, 0, 0, lp->id, buff, lp->buffer_size); if (err) return err; @@ -674,7 +683,7 @@ static int ilog_dump_log_page(struct ilog *ilog, struct log *lp, __u32 nsid) return log_save(lp, ilog->cfg->out_dir, "log_pages", filename, buff, lp->buffer_size); } -static int ilog_dump_no_lsp_log_pages(struct ilog *ilog) +static int ilog_dump_no_lsp_log_pages(struct nvme_transport_handle *hdl, struct ilog *ilog) { struct lba_status_info { __u32 lslplen; @@ -722,7 +731,7 @@ static int ilog_dump_no_lsp_log_pages(struct ilog *ilog) log_page_base_list[i].desc = log_page_base_list[i].desc ? log_page_base_list[i].desc : nvme_log_to_string(log_page_base_list[i].id); - if (!ilog_dump_log_page(ilog, &log_page_base_list[i], 0)) + if (!ilog_dump_log_page(hdl, ilog, &log_page_base_list[i], 0)) ilog->count++; } @@ -737,29 +746,26 @@ static int ilog_dump_no_lsp_log_pages(struct ilog *ilog) log_page_dependent_list[i].desc = log_page_dependent_list[i].desc ? log_page_dependent_list[i].desc : nvme_log_to_string(log_page_dependent_list[i].id); - ilog_dump_log_page(ilog, &log_page_dependent_list[i], 0); + ilog_dump_log_page(hdl, ilog, &log_page_dependent_list[i], 0); } return 0; } -static int ilog_dump_pel(struct ilog *ilog) +static int ilog_dump_pel(struct nvme_transport_handle *hdl, struct ilog *ilog) { + _cleanup_free_ struct nvme_persistent_event_log *pevent = NULL; + _cleanup_huge_ struct nvme_mem_huge mh = {0}; + void *pevent_log_full; + size_t max_data_tx; struct log lp = { NVME_LOG_LID_PERSISTENT_EVENT, nvme_log_to_string(NVME_LOG_LID_PERSISTENT_EVENT) }; - void *pevent_log_full; int err; - struct nvme_get_log_args args; - size_t max_data_tx; - _cleanup_free_ struct nvme_persistent_event_log *pevent = NULL; - - _cleanup_huge_ struct nvme_mem_huge mh = {0}; - - err = nvme_get_log_persistent_event(dev_fd(ilog->dev), NVME_PEVENT_LOG_RELEASE_CTX, - sizeof(*pevent), pevent); + err = nvme_get_log_persistent_event(hdl, NVME_PEVENT_LOG_RELEASE_CTX, + pevent, sizeof(*pevent)); if (err) return err; @@ -768,8 +774,8 @@ static int ilog_dump_pel(struct ilog *ilog) if (!pevent) return -ENOMEM; - err = nvme_get_log_persistent_event(dev_fd(ilog->dev), NVME_PEVENT_LOG_EST_CTX_AND_READ, - sizeof(*pevent), pevent); + err = nvme_get_log_persistent_event(hdl, NVME_PEVENT_LOG_EST_CTX_AND_READ, + pevent, sizeof(*pevent)); if (err) return err; @@ -779,29 +785,12 @@ static int ilog_dump_pel(struct ilog *ilog) if (!pevent_log_full) return -ENOMEM; - err = nvme_get_log_persistent_event(dev_fd(ilog->dev), NVME_PEVENT_LOG_READ, - lp.buffer_size, pevent_log_full); - args = (struct nvme_get_log_args) { - .lpo = 0, - .result = NULL, - .log = pevent_log_full, - .args_size = sizeof(args), - .fd = dev_fd(ilog->dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = NVME_LOG_LID_PERSISTENT_EVENT, - .len = lp.buffer_size, - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_PEVENT_LOG_READ, - .uuidx = NVME_UUID_NONE, - .rae = false, - .ot = false, - }; - + err = nvme_get_log_persistent_event(hdl, NVME_PEVENT_LOG_READ, + pevent_log_full, lp.buffer_size); max_data_tx = (1 << ilog->id_ctrl.mdts) * NVME_LOG_PAGE_PDU_SIZE; do { - err = nvme_get_log_page(dev_fd(ilog->dev), max_data_tx, &args); + err = nvme_get_log_persistent_event(hdl, NVME_PEVENT_LOG_READ, + pevent_log_full, lp.buffer_size); max_data_tx /= 2; } while (err == -EPERM && max_data_tx >= NVME_LOG_PAGE_PDU_SIZE); @@ -811,13 +800,13 @@ static int ilog_dump_pel(struct ilog *ilog) err = log_save(&lp, ilog->cfg->out_dir, "log_pages", "lid_0x0d_lsp_0x00_lsi_0x0000.bin", pevent_log_full, lp.buffer_size); - nvme_get_log_persistent_event(dev_fd(ilog->dev), NVME_PEVENT_LOG_RELEASE_CTX, - sizeof(*pevent), pevent); + nvme_get_log_persistent_event(hdl, NVME_PEVENT_LOG_RELEASE_CTX, + pevent, sizeof(*pevent)); return err; } -int solidigm_get_internal_log(int argc, char **argv, struct command *command, +int solidigm_get_internal_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { char sn_prefix[sizeof(((struct nvme_id_ctrl *)0)->sn)+1]; @@ -825,12 +814,12 @@ int solidigm_get_internal_log(int argc, char **argv, struct command *command, _cleanup_free_ char *full_folder = NULL; _cleanup_free_ char *unique_folder = NULL; _cleanup_free_ char *zip_name = NULL; - + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; char *initial_folder; char *output_path; struct ilog ilog = {0}; int err; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; enum log_type log_type = ALL; char type_ALL[] = "ALL"; time_t current_time; @@ -853,10 +842,9 @@ int solidigm_get_internal_log(int argc, char **argv, struct command *command, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - ilog.dev = dev; ilog.cfg = &cfg; for (char *p = cfg.type; *p; ++p) @@ -889,7 +877,7 @@ int solidigm_get_internal_log(int argc, char **argv, struct command *command, initial_folder = cfg.out_dir; - err = get_serial_number(sn_prefix, dev_fd(dev)); + err = get_serial_number(sn_prefix, hdl); if (err) return err; @@ -910,50 +898,50 @@ int solidigm_get_internal_log(int argc, char **argv, struct command *command, /* Retrieve first logs that records actions to retrieve other logs */ if (log_type == ALL || log_type == HIT) { - err = ilog_dump_telemetry(&ilog, HIT); + err = ilog_dump_telemetry(hdl, &ilog, HIT); if (err == 0) ilog.count++; else if (err < 0) perror("Error retrieving Host Initiated Telemetry"); } if (log_type == ALL || log_type == NLOG) { - err = ilog_dump_nlogs(&ilog, -1); + err = ilog_dump_nlogs(hdl, &ilog, -1); if (err == 0) ilog.count++; else if (err < 0) perror("Error retrieving Nlog"); } if (log_type == ALL || log_type == CIT) { - err = ilog_dump_telemetry(&ilog, CIT); + err = ilog_dump_telemetry(hdl, &ilog, CIT); if (err == 0) ilog.count++; else if (err < 0) perror("Error retrieving Controller Initiated Telemetry"); } if (log_type == ALL || log_type == ASSERTLOG) { - err = ilog_dump_assert_logs(&ilog); + err = ilog_dump_assert_logs(hdl, &ilog); if (err == 0) ilog.count++; else if (err < 0) perror("Error retrieving Assert log"); } if (log_type == ALL || log_type == EVENTLOG) { - err = ilog_dump_event_logs(&ilog); + err = ilog_dump_event_logs(hdl, &ilog); if (err == 0) ilog.count++; else if (err < 0) perror("Error retrieving Event log"); } if (log_type == ALL) { - err = ilog_dump_identify_pages(&ilog); + err = ilog_dump_identify_pages(hdl, &ilog); if (err < 0) perror("Error retrieving Identify pages"); - err = ilog_dump_pel(&ilog); + err = ilog_dump_pel(hdl, &ilog); if (err < 0) perror("Error retrieving Persistent Event Log page"); - err = ilog_dump_no_lsp_log_pages(&ilog); + err = ilog_dump_no_lsp_log_pages(hdl, &ilog); if (err < 0) perror("Error retrieving no LSP Log pages"); } diff --git a/plugins/solidigm/solidigm-internal-logs.h b/plugins/solidigm/solidigm-internal-logs.h index 801af246c7..ed851763dc 100644 --- a/plugins/solidigm/solidigm-internal-logs.h +++ b/plugins/solidigm/solidigm-internal-logs.h @@ -5,4 +5,4 @@ * Author: leonardo.da.cunha@solidigm.com */ -int solidigm_get_internal_log(int argc, char **argv, struct command *cmd, struct plugin *plugin); +int solidigm_get_internal_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); diff --git a/plugins/solidigm/solidigm-latency-tracking.c b/plugins/solidigm/solidigm-latency-tracking.c index 899075d7ac..e51db52f66 100644 --- a/plugins/solidigm/solidigm-latency-tracking.c +++ b/plugins/solidigm/solidigm-latency-tracking.c @@ -42,7 +42,7 @@ struct config { }; struct latency_tracker { - int fd; + struct nvme_transport_handle *hdl; __u8 uuid_index; struct config cfg; nvme_print_flags_t print_flags; @@ -271,20 +271,9 @@ static void latency_tracker_parse(struct latency_tracker *lt) static int latency_tracking_is_enable(struct latency_tracker *lt, __u32 *enabled) { - struct nvme_get_features_args args_get = { - .args_size = sizeof(args_get), - .fd = lt->fd, - .uuidx = lt->uuid_index, - .fid = LATENCY_TRACKING_FID, - .nsid = 0, - .sel = 0, - .cdw11 = 0, - .data_len = LATENCY_TRACKING_FID_DATA_LEN, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = enabled, - }; - return nvme_get_features(&args_get); + return nvme_get_features(lt->hdl, 0, LATENCY_TRACKING_FID, 0, 0, + lt->uuid_index, NULL, + LATENCY_TRACKING_FID_DATA_LEN, enabled); } static int latency_tracking_enable(struct latency_tracker *lt) @@ -300,23 +289,9 @@ static int latency_tracking_enable(struct latency_tracker *lt) return -EINVAL; } - struct nvme_set_features_args args_set = { - .args_size = sizeof(args_set), - .fd = lt->fd, - .uuidx = lt->uuid_index, - .fid = LATENCY_TRACKING_FID, - .nsid = 0, - .cdw11 = lt->cfg.enable, - .cdw12 = 0, - .save = 0, - .cdw15 = 0, - .data_len = LATENCY_TRACKING_FID_DATA_LEN, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - err = nvme_set_features(&args_set); + err = nvme_set_features(lt->hdl, 0, LATENCY_TRACKING_FID, 0, + lt->cfg.enable, 0, 0, lt->uuid_index, 0, NULL, + LATENCY_TRACKING_FID_DATA_LEN, &result); if (err > 0) { nvme_show_status(err); } else if (err < 0) { @@ -336,6 +311,7 @@ static int latency_tracking_enable(struct latency_tracker *lt) static int latency_tracker_get_log(struct latency_tracker *lt) { + struct nvme_passthru_cmd cmd; int err; if (lt->cfg.read && lt->cfg.write) { @@ -346,25 +322,17 @@ static int latency_tracker_get_log(struct latency_tracker *lt) if (!(lt->cfg.read || lt->cfg.write)) return 0; - struct nvme_get_log_args args = { - .lpo = 0, - .result = NULL, - .log = <->stats, - .args_size = sizeof(args), - .fd = lt->fd, - .uuidx = lt->uuid_index, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = lt->cfg.write ? WRITE_LOG_ID : READ_LOG_ID, - .len = sizeof(lt->stats), - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = lt->cfg.type, - .rae = false, - .ot = false, - }; - - err = nvme_get_log(&args); + nvme_init_get_log(&cmd, NVME_NSID_ALL, + lt->cfg.write ? WRITE_LOG_ID : READ_LOG_ID, + NVME_CSI_NVM, <->stats, sizeof(lt->stats)); + cmd.cdw10 |= NVME_FIELD_ENCODE(lt->cfg.type, + NVME_LOG_CDW10_LSP_SHIFT, + NVME_LOG_CDW10_LSP_MASK); + cmd.cdw14 |= NVME_FIELD_ENCODE(lt->uuid_index, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + err = nvme_get_log(lt->hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (err) return err; @@ -377,11 +345,12 @@ static int latency_tracker_get_log(struct latency_tracker *lt) return err; } -int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd, +int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get and Parse Solidigm Latency Tracking Statistics log."; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 enabled; int err; @@ -405,49 +374,40 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - lt.fd = dev_fd(dev); + lt.hdl = hdl; err = validate_output_format(lt.cfg.output_format, <.print_flags); if (err < 0) { fprintf(stderr, "Invalid output format '%s'\n", lt.cfg.output_format); - dev_close(dev); return -EINVAL; } if (lt.cfg.type > 0xf) { fprintf(stderr, "Invalid Log type value '%d'\n", lt.cfg.type); - dev_close(dev); return -EINVAL; } if (lt.cfg.type && !(lt.cfg.read || lt.cfg.write)) { fprintf(stderr, "Log type option valid only when retrieving statistics\n"); - dev_close(dev); return -EINVAL; } - sldgm_get_uuid_index(dev, <.uuid_index); + sldgm_get_uuid_index(hdl, <.uuid_index); err = latency_tracking_enable(<); - if (err) { - dev_close(dev); + if (err) return err; - } err = latency_tracker_get_log(<); - if (err) { - dev_close(dev); + if (err) return err; - } - if ((lt.cfg.read || lt.cfg.write || lt.cfg.enable || lt.cfg.disable)) { - dev_close(dev); + if ((lt.cfg.read || lt.cfg.write || lt.cfg.enable || lt.cfg.disable)) return 0; - } err = latency_tracking_is_enable(<, &enabled); if (!err) { @@ -467,8 +427,5 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd } else { fprintf(stderr, "Could not read feature id 0xE2.\n"); } - /* Redundant close() to make static code analysis happy */ - close(dev->direct.fd); - dev_close(dev); return err; } diff --git a/plugins/solidigm/solidigm-latency-tracking.h b/plugins/solidigm/solidigm-latency-tracking.h index 9a763a9067..e5329c6af0 100644 --- a/plugins/solidigm/solidigm-latency-tracking.h +++ b/plugins/solidigm/solidigm-latency-tracking.h @@ -5,5 +5,5 @@ * Author: leonardo.da.cunha@solidigm.com */ -int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd, +int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); diff --git a/plugins/solidigm/solidigm-log-page-dir.c b/plugins/solidigm/solidigm-log-page-dir.c index c3f08bb4c8..7590956300 100644 --- a/plugins/solidigm/solidigm-log-page-dir.c +++ b/plugins/solidigm/solidigm-log-page-dir.c @@ -40,29 +40,20 @@ static void init_lid_dir(struct lid_dir *lid_dir) } } -static int get_supported_log_pages_log(struct nvme_dev *dev, int uuid_index, +static int get_supported_log_pages_log(struct nvme_transport_handle *hdl, int uuid_index, struct nvme_supported_log_pages *supported) { - memset(supported, 0, sizeof(*supported)); - struct nvme_get_log_args args = { - .lpo = 0, - .result = NULL, - .log = supported, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = NVME_LOG_LID_SUPPORTED_LOG_PAGES, - .len = sizeof(*supported), - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = 0, - .uuidx = uuid_index, - .rae = false, - .ot = false, - }; + struct nvme_passthru_cmd cmd; - return nvme_get_log(&args); + memset(supported, 0, sizeof(*supported)); + nvme_init_get_log(&cmd, NVME_NSID_ALL, + NVME_LOG_LID_SUPPORTED_LOG_PAGES, NVME_CSI_NVM, + supported, sizeof(*supported)); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_index, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + return nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); } static struct lid_dir *get_standard_lids(struct nvme_supported_log_pages *supported) @@ -188,7 +179,7 @@ static void supported_log_pages_json(struct lid_dir *lid_dir[SOLIDIGM_MAX_UUID + printf("\n"); } -int solidigm_get_log_page_directory_log(int argc, char **argv, struct command *cmd, +int solidigm_get_log_page_directory_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const int NO_UUID_INDEX = 0; @@ -201,9 +192,10 @@ int solidigm_get_log_page_directory_log(int argc, char **argv, struct command *c OPT_END() }; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - int err = parse_and_open(&dev, argc, argv, description, options); + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + int err = parse_and_open(&ctx, &hdl, argc, argv, description, options); if (err) return err; @@ -211,13 +203,13 @@ int solidigm_get_log_page_directory_log(int argc, char **argv, struct command *c struct nvme_id_uuid_list uuid_list = { 0 }; struct nvme_supported_log_pages supported = { 0 }; - err = get_supported_log_pages_log(dev, NO_UUID_INDEX, &supported); + err = get_supported_log_pages_log(hdl, NO_UUID_INDEX, &supported); if (!err) { lid_dirs[NO_UUID_INDEX] = get_standard_lids(&supported); // Assume VU logs are the Solidigm log pages if UUID not supported. - if (nvme_identify_uuid(dev_fd(dev), &uuid_list)) { + if (!nvme_identify_uuid_list(hdl, &uuid_list)) { struct lid_dir *solidigm_lid_dir = get_solidigm_lids(&supported); // Transfer supported Solidigm lids to lid directory at UUID index 0 @@ -233,12 +225,12 @@ int solidigm_get_log_page_directory_log(int argc, char **argv, struct command *c ocp_find_uuid_index(&uuid_list, &ocp_idx); if (sldgm_idx && (sldgm_idx <= SOLIDIGM_MAX_UUID)) { - err = get_supported_log_pages_log(dev, sldgm_idx, &supported); + err = get_supported_log_pages_log(hdl, sldgm_idx, &supported); if (!err) lid_dirs[sldgm_idx] = get_solidigm_lids(&supported); } if (ocp_idx && (ocp_idx <= SOLIDIGM_MAX_UUID)) { - err = get_supported_log_pages_log(dev, ocp_idx, &supported); + err = get_supported_log_pages_log(hdl, ocp_idx, &supported); if (!err) lid_dirs[ocp_idx] = get_ocp_lids(&supported); } diff --git a/plugins/solidigm/solidigm-log-page-dir.h b/plugins/solidigm/solidigm-log-page-dir.h index 48777df7d8..d87eeeaca2 100644 --- a/plugins/solidigm/solidigm-log-page-dir.h +++ b/plugins/solidigm/solidigm-log-page-dir.h @@ -11,7 +11,7 @@ struct command; struct plugin; -int solidigm_get_log_page_directory_log(int argc, char **argv, struct command *cmd, +int solidigm_get_log_page_directory_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); #endif diff --git a/plugins/solidigm/solidigm-market-log.c b/plugins/solidigm/solidigm-market-log.c index e0934df5e5..38e29acdc2 100644 --- a/plugins/solidigm/solidigm-market-log.c +++ b/plugins/solidigm/solidigm-market-log.c @@ -23,12 +23,14 @@ #define MARKET_LOG_LID 0xDD #define MARKET_LOG_MAX_SIZE 512 -int sldgm_get_market_log(int argc, char **argv, struct command *command, +int sldgm_get_market_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Solidigm Marketing Name log and show it."; const char *raw = "dump output in binary format"; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; char log[MARKET_LOG_MAX_SIZE]; int err; __u8 uuid_idx; @@ -40,31 +42,20 @@ int sldgm_get_market_log(int argc, char **argv, struct command *command, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - sldgm_get_uuid_index(dev, &uuid_idx); + sldgm_get_uuid_index(hdl, &uuid_idx); - struct nvme_get_log_args args = { - .lpo = 0, - .result = NULL, - .log = log, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .uuidx = uuid_idx, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = MARKET_LOG_LID, - .len = sizeof(log), - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, - .rae = false, - .ot = false, - }; - - err = nvme_get_log(&args); + nvme_init_get_log(&cmd, NVME_NSID_ALL, + MARKET_LOG_LID, NVME_CSI_NVM, + log, sizeof(log)); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_idx, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + err = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (err) { nvme_show_status(err); return err; diff --git a/plugins/solidigm/solidigm-market-log.h b/plugins/solidigm/solidigm-market-log.h index 6f808c4ed3..3361e49ae1 100644 --- a/plugins/solidigm/solidigm-market-log.h +++ b/plugins/solidigm/solidigm-market-log.h @@ -5,4 +5,4 @@ * Author: hardeep.dhillon@solidigm.com */ -int sldgm_get_market_log(int argc, char **argv, struct command *cmd, struct plugin *plugin); +int sldgm_get_market_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); diff --git a/plugins/solidigm/solidigm-nvme.c b/plugins/solidigm/solidigm-nvme.c index 8a7db07843..b8165db760 100644 --- a/plugins/solidigm/solidigm-nvme.c +++ b/plugins/solidigm/solidigm-nvme.c @@ -27,90 +27,90 @@ #include "plugins/ocp/ocp-smart-extended-log.h" #include "plugins/ocp/ocp-fw-activation-history.h" -static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return __id_ctrl(argc, argv, cmd, plugin, sldgm_id_ctrl); + return __id_ctrl(argc, argv, acmd, plugin, sldgm_id_ctrl); } -static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_additional_smart_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return solidigm_get_additional_smart_log(argc, argv, cmd, plugin); + return solidigm_get_additional_smart_log(argc, argv, acmd, plugin); } -static int get_internal_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_internal_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return solidigm_get_internal_log(argc, argv, cmd, plugin); + return solidigm_get_internal_log(argc, argv, acmd, plugin); } -static int get_garbage_collection_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_garbage_collection_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return solidigm_get_garbage_collection_log(argc, argv, cmd, plugin); + return solidigm_get_garbage_collection_log(argc, argv, acmd, plugin); } -static int get_latency_tracking_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_latency_tracking_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return solidigm_get_latency_tracking_log(argc, argv, cmd, plugin); + return solidigm_get_latency_tracking_log(argc, argv, acmd, plugin); } -static int get_telemetry_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_telemetry_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return solidigm_get_telemetry_log(argc, argv, cmd, plugin); + return solidigm_get_telemetry_log(argc, argv, acmd, plugin); } -static int clear_fw_update_history(int argc, char **argv, struct command *cmd, +static int clear_fw_update_history(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return ocp_clear_fw_update_history(argc, argv, cmd, plugin); + return ocp_clear_fw_update_history(argc, argv, acmd, plugin); } -static int clear_pcie_correctable_error_counters(int argc, char **argv, struct command *cmd, +static int clear_pcie_correctable_error_counters(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return ocp_clear_pcie_correctable_errors(argc, argv, cmd, plugin); + return ocp_clear_pcie_correctable_errors(argc, argv, acmd, plugin); } -static int smart_cloud(int argc, char **argv, struct command *cmd, +static int smart_cloud(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return ocp_smart_add_log(argc, argv, cmd, plugin); + return ocp_smart_add_log(argc, argv, acmd, plugin); } -static int fw_activation_history(int argc, char **argv, struct command *cmd, +static int fw_activation_history(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return ocp_fw_activation_history_log(argc, argv, cmd, plugin); + return ocp_fw_activation_history_log(argc, argv, acmd, plugin); } -static int get_log_page_directory_log(int argc, char **argv, struct command *cmd, +static int get_log_page_directory_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return solidigm_get_log_page_directory_log(argc, argv, cmd, plugin); + return solidigm_get_log_page_directory_log(argc, argv, acmd, plugin); } -static int get_market_log(int argc, char **argv, struct command *cmd, +static int get_market_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return sldgm_get_market_log(argc, argv, cmd, plugin); + return sldgm_get_market_log(argc, argv, acmd, plugin); } -static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_temp_stats_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return sldgm_get_temp_stats_log(argc, argv, cmd, plugin); + return sldgm_get_temp_stats_log(argc, argv, acmd, plugin); } -static int get_drive_info(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_drive_info(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return sldgm_get_drive_info(argc, argv, cmd, plugin); + return sldgm_get_drive_info(argc, argv, acmd, plugin); } -static int get_cloud_SSDplugin_version(int argc, char **argv, struct command *cmd, +static int get_cloud_SSDplugin_version(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return sldgm_ocp_version(argc, argv, cmd, plugin); + return sldgm_ocp_version(argc, argv, acmd, plugin); } -static int get_workload_tracker(int argc, char **argv, struct command *cmd, +static int get_workload_tracker(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return sldgm_get_workload_tracker(argc, argv, cmd, plugin); + return sldgm_get_workload_tracker(argc, argv, acmd, plugin); } diff --git a/plugins/solidigm/solidigm-ocp-version.c b/plugins/solidigm/solidigm-ocp-version.c index 4048cc1bd3..5904f87c6b 100644 --- a/plugins/solidigm/solidigm-ocp-version.c +++ b/plugins/solidigm/solidigm-ocp-version.c @@ -8,7 +8,7 @@ #include #include "nvme.h" -int sldgm_ocp_version(int argc, char **argv, struct command *cmd, struct plugin *plugin) +int sldgm_ocp_version(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Prints OCP extensions version of Solidigm plugin"; diff --git a/plugins/solidigm/solidigm-ocp-version.h b/plugins/solidigm/solidigm-ocp-version.h index d79452cbcc..8fbb333b44 100644 --- a/plugins/solidigm/solidigm-ocp-version.h +++ b/plugins/solidigm/solidigm-ocp-version.h @@ -5,4 +5,4 @@ * Author: leonardo.da.cunha@solidigm.com */ -int sldgm_ocp_version(int argc, char **argv, struct command *cmd, struct plugin *plugin); +int sldgm_ocp_version(int argc, char **argv, struct command *acmd, struct plugin *plugin); diff --git a/plugins/solidigm/solidigm-smart.c b/plugins/solidigm/solidigm-smart.c index 70869ce927..3edcbbaa27 100644 --- a/plugins/solidigm/solidigm-smart.c +++ b/plugins/solidigm/solidigm-smart.c @@ -222,14 +222,16 @@ static void vu_smart_log_show(struct vu_smart_log *payload, unsigned int nsid, c smart_log_item_print(&item[i]); } -int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +int solidigm_get_additional_smart_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Solidigm vendor specific smart log (optionally, for the specified namespace), and show it."; const int solidigm_vu_smart_log_id = 0xCA; struct vu_smart_log smart_log_payload; nvme_print_flags_t flags; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; int err; __u8 uuid_index; @@ -250,47 +252,35 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; err = validate_output_format(cfg.output_format, &flags); if (err < 0) { fprintf(stderr, "Invalid output format '%s'\n", cfg.output_format); - dev_close(dev); return err; } - sldgm_get_uuid_index(dev, &uuid_index); - - struct nvme_get_log_args args = { - .lpo = 0, - .result = NULL, - .log = &smart_log_payload, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = solidigm_vu_smart_log_id, - .len = sizeof(smart_log_payload), - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, - .uuidx = uuid_index, - .rae = false, - .ot = false, - }; + sldgm_get_uuid_index(hdl, &uuid_index); - err = nvme_get_log(&args); + nvme_init_get_log(&cmd, NVME_NSID_ALL, + solidigm_vu_smart_log_id, NVME_CSI_NVM, + &smart_log_payload, sizeof(smart_log_payload)); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_index, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + err = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (!err) { if (flags & JSON) vu_smart_log_show_json(&smart_log_payload, - cfg.namespace_id, dev->name); + cfg.namespace_id, nvme_transport_handle_get_name(hdl)); else if (flags & BINARY) d_raw((unsigned char *)&smart_log_payload, sizeof(smart_log_payload)); else vu_smart_log_show(&smart_log_payload, cfg.namespace_id, - dev->name, uuid_index); + nvme_transport_handle_get_name(hdl), uuid_index); } else if (err > 0) { nvme_show_status(err); } diff --git a/plugins/solidigm/solidigm-smart.h b/plugins/solidigm/solidigm-smart.h index e19ebe5170..0000240cae 100644 --- a/plugins/solidigm/solidigm-smart.h +++ b/plugins/solidigm/solidigm-smart.h @@ -5,4 +5,4 @@ * Author: leonardo.da.cunha@solidigm.com */ -int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin); +int solidigm_get_additional_smart_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); diff --git a/plugins/solidigm/solidigm-telemetry.c b/plugins/solidigm/solidigm-telemetry.c index 24926e46d4..7f189c0cbf 100644 --- a/plugins/solidigm/solidigm-telemetry.c +++ b/plugins/solidigm/solidigm-telemetry.c @@ -60,7 +60,7 @@ static void cleanup_json_object(struct json_object **jobj_ptr) *jobj_ptr = NULL; } -int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +int solidigm_get_telemetry_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Parse Solidigm Telemetry log"; const char *hgen = "Controls when to generate new host initiated report. Default value '1' generates new host initiated report, value '0' causes retrieval of existing log."; @@ -69,9 +69,8 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc const char *cfile = "JSON configuration file"; const char *sfile = "binary file containing log dump"; bool has_binary_file = false; - - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; - + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; _cleanup_free_ struct nvme_telemetry_log *tlog = NULL; __attribute__((cleanup(cleanup_json_object))) struct json_object *configuration = NULL; @@ -122,7 +121,7 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc } err = read_file2buffer(cfg.binary_file, (char **)&tlog, &tl.log_size); } else { - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); } if (err) { nvme_show_status(err); @@ -166,7 +165,7 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc size_t power2; __u8 mdts = 0; - err = nvme_get_telemetry_max(dev_fd(dev), NULL, &max_data_tx); + err = nvme_get_telemetry_max(hdl, NULL, &max_data_tx); if (err < 0) { SOLIDIGM_LOG_WARNING("identify_ctrl: %s", nvme_strerror(errno)); @@ -182,7 +181,7 @@ int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struc mdts++; } - err = sldgm_dynamic_telemetry(dev_fd(dev), cfg.host_gen, cfg.ctrl_init, true, + err = sldgm_dynamic_telemetry(hdl, cfg.host_gen, cfg.ctrl_init, true, mdts, cfg.data_area, &tlog, &tl.log_size); if (err < 0) { SOLIDIGM_LOG_WARNING("get-telemetry-log: %s", diff --git a/plugins/solidigm/solidigm-telemetry.h b/plugins/solidigm/solidigm-telemetry.h index 971ee2acb0..3f62fae97c 100644 --- a/plugins/solidigm/solidigm-telemetry.h +++ b/plugins/solidigm/solidigm-telemetry.h @@ -5,4 +5,4 @@ * Author: leonardo.da.cunha@solidigm.com */ -int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struct plugin *plugin); +int solidigm_get_telemetry_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); diff --git a/plugins/solidigm/solidigm-temp-stats.c b/plugins/solidigm/solidigm-temp-stats.c index 7f385db96b..d9d4df1d27 100644 --- a/plugins/solidigm/solidigm-temp-stats.c +++ b/plugins/solidigm/solidigm-temp-stats.c @@ -38,10 +38,12 @@ static void show_temp_stats(struct temp_stats *stats) printf("Estimated offset : %"PRIu64"\n", le64_to_cpu(stats->est_offset)); } -int sldgm_get_temp_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +int sldgm_get_temp_stats_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; unsigned char buffer[4096] = {0}; - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; + struct nvme_passthru_cmd cmd; __u8 uuid_idx; int err; @@ -60,34 +62,29 @@ int sldgm_get_temp_stats_log(int argc, char **argv, struct command *cmd, struct OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - sldgm_get_uuid_index(dev, &uuid_idx); + sldgm_get_uuid_index(hdl, &uuid_idx); - struct nvme_get_log_args args = { - .lpo = 0, - .result = NULL, - .log = buffer, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .uuidx = uuid_idx, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = SLDGM_TEMP_STATS_LID, - .len = sizeof(buffer), - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_LSP_NONE, - .rae = false, - .ot = false, - }; - - err = nvme_get_log(&args); + nvme_init_get_log(&cmd, NVME_NSID_ALL, + SLDGM_TEMP_STATS_LID, NVME_CSI_NVM, + buffer, sizeof(buffer)); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_idx, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + err = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (err > 0) { - args.lid = SLDGM_LEGACY_TEMP_STATS_LID; - err = nvme_get_log(&args); + nvme_init_get_log(&cmd, NVME_NSID_ALL, + SLDGM_LEGACY_TEMP_STATS_LID, NVME_CSI_NVM, + buffer, sizeof(buffer)); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_idx, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + err = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (!err) { uint64_t *guid = (uint64_t *)&buffer[4080]; diff --git a/plugins/solidigm/solidigm-temp-stats.h b/plugins/solidigm/solidigm-temp-stats.h index 58d5a86801..bca59ff134 100644 --- a/plugins/solidigm/solidigm-temp-stats.h +++ b/plugins/solidigm/solidigm-temp-stats.h @@ -5,4 +5,4 @@ * Author: leonardo.da.cunha@solidigm.com */ -int sldgm_get_temp_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin); +int sldgm_get_temp_stats_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); diff --git a/plugins/solidigm/solidigm-util.c b/plugins/solidigm/solidigm-util.c index 8206ef8cf0..11b3ba1647 100644 --- a/plugins/solidigm/solidigm-util.c +++ b/plugins/solidigm/solidigm-util.c @@ -26,27 +26,31 @@ int sldgm_find_uuid_index(struct nvme_id_uuid_list *uuid_list, __u8 *index) return 0; } -int sldgm_get_uuid_index(struct nvme_dev *dev, __u8 *index) +int sldgm_get_uuid_index(struct nvme_transport_handle *hdl, __u8 *index) { struct nvme_id_uuid_list uuid_list; - int err = nvme_identify_uuid(dev_fd(dev), &uuid_list); + int err; *index = 0; + + err = nvme_identify_uuid_list(hdl, &uuid_list); if (err) return err; return sldgm_find_uuid_index(&uuid_list, index); } -int sldgm_dynamic_telemetry(int dev_fd, bool create, bool ctrl, bool log_page, __u8 mtds, - enum nvme_telemetry_da da, struct nvme_telemetry_log **log_buffer, +int sldgm_dynamic_telemetry(struct nvme_transport_handle *hdl, bool create, + bool ctrl, bool log_page, __u8 mtds, + enum nvme_telemetry_da da, + struct nvme_telemetry_log **log_buffer, size_t *log_buffer_size) { - int err; size_t max_data_tx = (1 << mtds) * NVME_LOG_PAGE_PDU_SIZE; + int err; do { - err = nvme_get_telemetry_log(dev_fd, create, ctrl, log_page, max_data_tx, da, + err = nvme_get_telemetry_log(hdl, create, ctrl, log_page, max_data_tx, da, log_buffer, log_buffer_size); max_data_tx /= 2; create = false; diff --git a/plugins/solidigm/solidigm-util.h b/plugins/solidigm/solidigm-util.h index 85adbf9a20..7ab27ac3da 100644 --- a/plugins/solidigm/solidigm-util.h +++ b/plugins/solidigm/solidigm-util.h @@ -8,7 +8,7 @@ #include "nvme.h" int sldgm_find_uuid_index(struct nvme_id_uuid_list *uuid_list, __u8 *index); -int sldgm_get_uuid_index(struct nvme_dev *dev, __u8 *index); -int sldgm_dynamic_telemetry(int dev_fd, bool create, bool ctrl, bool log_page, __u8 mtds, +int sldgm_get_uuid_index(struct nvme_transport_handle *hdl, __u8 *index); +int sldgm_dynamic_telemetry(struct nvme_transport_handle *hdl, bool create, bool ctrl, bool log_page, __u8 mtds, enum nvme_telemetry_da da, struct nvme_telemetry_log **log_buffer, size_t *log_buffer_size); diff --git a/plugins/solidigm/solidigm-workload-tracker.c b/plugins/solidigm/solidigm-workload-tracker.c index f2e3913a6b..3d07f1ec9f 100644 --- a/plugins/solidigm/solidigm-workload-tracker.c +++ b/plugins/solidigm/solidigm-workload-tracker.c @@ -196,7 +196,7 @@ struct workloadLog { // Full WL Log Structure #pragma pack(pop) struct wltracker { - int fd; + struct nvme_transport_handle *hdl; __u8 uuid_index; struct workloadLog workload_log; size_t poll_count; @@ -273,40 +273,28 @@ __u64 micros(void) int wltracker_config(struct wltracker *wlt, union WorkloadLogEnable *we) { - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = wlt->fd, - .fid = FID, - .cdw11 = we->dword, - .uuidx = wlt->uuid_index, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - }; - return nvme_set_features(&args); + return nvme_set_features(wlt->hdl, 0, FID, 0, we->dword, 0, 0, 0, + wlt->uuid_index, NULL, 0, NULL); } static int wltracker_show_newer_entries(struct wltracker *wlt) { struct workloadLog *log = &wlt->workload_log; - __u8 cnt; - __u8 content_group; + union WorkloadLogEnable workloadEnable; static __u64 last_timestamp_us; + struct nvme_passthru_cmd cmd; __u64 timestamp_us = 0; __u64 timestamp = 0; - union WorkloadLogEnable workloadEnable; - - struct nvme_get_log_args args = { - .lpo = 0, - .result = NULL, - .log = log, - .args_size = sizeof(args), - .fd = wlt->fd, - .uuidx = wlt->uuid_index, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = LID, - .len = sizeof(*log), - }; - int err = nvme_get_log(&args); + __u8 content_group; + __u8 cnt; + int err; + nvme_init_get_log(&cmd, NVME_NSID_NONE, LID, NVME_CSI_NVM, + log, sizeof(*log)); + cmd.cdw14 |= NVME_FIELD_ENCODE(wlt->uuid_index, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + err = nvme_get_log(wlt->hdl, &cmd, false, NVME_LOG_PAGE_PDU_SIZE, NULL); if (err > 0) { nvme_show_status(err); return err; @@ -358,7 +346,7 @@ static int wltracker_show_newer_entries(struct wltracker *wlt) if (!err) { struct workloadLog tl; - err = nvme_get_log_simple(wlt->fd, LID, sizeof(tl), &tl); + err = nvme_get_log_simple(wlt->hdl, LID, &tl, sizeof(tl)); tle = tl.timestamp_lastEntry; } if (err) { @@ -496,17 +484,17 @@ static void join_fields(char *dest, struct field *fields) } } -int sldgm_get_workload_tracker(int argc, char **argv, struct command *cmd, struct plugin *plugin) +int sldgm_get_workload_tracker(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - struct wltracker wlt = {0}; - union WorkloadLogEnable we = {0}; - - _cleanup_nvme_dev_ struct nvme_dev *dev = NULL; const char *desc = "Real Time capture Workload Tracker samples"; const char *sample_interval = "Sample interval"; const char *run_time = "Limit runtime capture time in seconds"; const char *flush_frequency = "Samples (1 to 126) to wait for extracting data. Default 100 samples"; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct wltracker wlt = {0}; + union WorkloadLogEnable we = {0}; char type_options[80] = {0}; char sample_options[80] = {0}; __u64 stop_time_us; @@ -558,7 +546,7 @@ int sldgm_get_workload_tracker(int argc, char **argv, struct command *cmd, struc OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; @@ -567,7 +555,7 @@ int sldgm_get_workload_tracker(int argc, char **argv, struct command *cmd, struc return -1; } - wlt.fd = dev_fd(dev); + wlt.hdl = hdl; if ((cfg.flush_frequency < 1) || (cfg.flush_frequency > MAX_WORKLOAD_LOG_ENTRIES)) { nvme_show_error("Invalid number of samples: %s. Valid values: 1-%d", @@ -615,15 +603,8 @@ int sldgm_get_workload_tracker(int argc, char **argv, struct command *cmd, struc we.triggerEnable = true; we.triggerDelta = cfg.trigger_on_delta; we.triggerSynchronous = !cfg.trigger_on_latency; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = wlt.fd, - .fid = 0xf5, - .cdw11 = cfg.trigger_treshold, - .uuidx = wlt.uuid_index, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - }; - err = nvme_set_features(&args); + err = nvme_set_features(wlt.hdl, 0, 0xf5, 0, cfg.trigger_treshold, 0, + 0, wlt.uuid_index, 0, NULL, 0, NULL); if (err < 0) { nvme_show_error("Trigger Threshold set-feature: %s", nvme_strerror(errno)); return err; diff --git a/plugins/solidigm/solidigm-workload-tracker.h b/plugins/solidigm/solidigm-workload-tracker.h index d3ecc1623e..f48c7b5268 100644 --- a/plugins/solidigm/solidigm-workload-tracker.h +++ b/plugins/solidigm/solidigm-workload-tracker.h @@ -5,4 +5,4 @@ * Author: leonardo.da.cunha@solidigm.com */ -int sldgm_get_workload_tracker(int argc, char **argv, struct command *cmd, struct plugin *plugin); +int sldgm_get_workload_tracker(int argc, char **argv, struct command *acmd, struct plugin *plugin); diff --git a/plugins/ssstc/ssstc-nvme.c b/plugins/ssstc/ssstc-nvme.c index f90ad6054d..90571f7b1f 100644 --- a/plugins/ssstc/ssstc-nvme.c +++ b/plugins/ssstc/ssstc-nvme.c @@ -375,7 +375,7 @@ void show_ssstc_add_smart_log(struct nvme_additional_smart_log *smart, } static -int ssstc_get_add_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +int ssstc_get_add_smart_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = @@ -388,7 +388,8 @@ int ssstc_get_add_smart_log(int argc, char **argv, struct command *cmd, struct p #endif /* CONFIG_JSONC */ struct nvme_additional_smart_log smart_log_add; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; struct config { @@ -408,25 +409,25 @@ int ssstc_get_add_smart_log(int argc, char **argv, struct command *cmd, struct p OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = nvme_get_log_simple(dev_fd(dev), 0xca, sizeof(smart_log_add), - &smart_log_add); + err = nvme_get_log_simple(hdl, 0xca, &smart_log_add, sizeof(smart_log_add)); if (!err) { if (cfg.json) - show_ssstc_add_smart_log_jsn(&smart_log_add, cfg.namespace_id, - dev->name); + show_ssstc_add_smart_log_jsn( + &smart_log_add, cfg.namespace_id, + nvme_transport_handle_get_name(hdl)); else if (!cfg.raw_binary) - show_ssstc_add_smart_log(&smart_log_add, cfg.namespace_id, - dev->name); + show_ssstc_add_smart_log( + &smart_log_add, cfg.namespace_id, + nvme_transport_handle_get_name(hdl)); else d_raw((unsigned char *)&smart_log_add, sizeof(smart_log_add)); } else if (err > 0) { nvme_show_status(err); } - dev_close(dev); return err; } diff --git a/plugins/toshiba/toshiba-nvme.c b/plugins/toshiba/toshiba-nvme.c index 3ae1bc4096..6f427333d8 100644 --- a/plugins/toshiba/toshiba-nvme.c +++ b/plugins/toshiba/toshiba-nvme.c @@ -48,8 +48,8 @@ enum { CODE_1 = 0x10 }; - -static int nvme_sct_op(int fd, __u32 opcode, __u32 cdw10, __u32 cdw11, void *data, __u32 data_len) +static int nvme_sct_op(struct nvme_transport_handle *hdl, __u32 opcode, + __u32 cdw10, __u32 cdw11, void *data, __u32 data_len) { void *metadata = NULL; const __u32 cdw2 = 0; @@ -65,12 +65,12 @@ static int nvme_sct_op(int fd, __u32 opcode, __u32 cdw10, __u32 cdw11, void *dat const __u32 rsvd = 0; __u32 result; - return nvme_admin_passthru(fd, opcode, flags, rsvd, namespace_id, cdw2, cdw3, cdw10, cdw11, + return nvme_admin_passthru(hdl, opcode, flags, rsvd, namespace_id, cdw2, cdw3, cdw10, cdw11, cdw12, cdw13, cdw14, cdw15, data_len, data, metadata_len, metadata, timeout, &result); } -static int nvme_get_sct_status(int fd, __u32 device_mask) +static int nvme_get_sct_status(struct nvme_transport_handle *hdl, __u32 device_mask) { int err; void *data = NULL; @@ -82,7 +82,7 @@ static int nvme_get_sct_status(int fd, __u32 device_mask) return -ENOMEM; memset(data, 0, data_len); - err = nvme_sct_op(fd, OP_SCT_STATUS, DW10_SCT_STATUS_COMMAND, DW11_SCT_STATUS_COMMAND, data, data_len); + err = nvme_sct_op(hdl, OP_SCT_STATUS, DW10_SCT_STATUS_COMMAND, DW11_SCT_STATUS_COMMAND, data, data_len); if (err) { fprintf(stderr, "%s: SCT status failed :%d\n", __func__, err); goto end; @@ -122,7 +122,7 @@ static int nvme_get_sct_status(int fd, __u32 device_mask) return err; } -static int nvme_sct_command_transfer_log(int fd, bool current) +static int nvme_sct_command_transfer_log(struct nvme_transport_handle *hdl, bool current) { int err; void *data = NULL; @@ -141,12 +141,13 @@ static int nvme_sct_command_transfer_log(int fd, bool current) memcpy(data, &action_code, sizeof(action_code)); memcpy(data + 2, &function_code, sizeof(function_code)); - err = nvme_sct_op(fd, OP_SCT_COMMAND_TRANSFER, DW10_SCT_COMMAND_TRANSFER, DW11_SCT_COMMAND_TRANSFER, data, data_len); + err = nvme_sct_op(hdl, OP_SCT_COMMAND_TRANSFER, DW10_SCT_COMMAND_TRANSFER, DW11_SCT_COMMAND_TRANSFER, data, data_len); free(data); return err; } -static int nvme_sct_data_transfer(int fd, void *data, size_t data_len, size_t offset) +static int nvme_sct_data_transfer(struct nvme_transport_handle *hdl, void *data, + size_t data_len, size_t offset) { __u32 dw10, dw11, lba_count = (data_len) / 512; @@ -160,7 +161,7 @@ static int nvme_sct_data_transfer(int fd, void *data, size_t data_len, size_t of dw10 = (offset << 16) | lba_count; dw11 = (offset >> 16); - return nvme_sct_op(fd, OP_SCT_DATA_TRANSFER, dw10, dw11, data, data_len); + return nvme_sct_op(hdl, OP_SCT_DATA_TRANSFER, dw10, dw11, data, data_len); } static int d_raw_to_fd(const unsigned char *buf, unsigned int len, int fd) @@ -204,7 +205,8 @@ static void progress_runner(float progress) fflush(stdout); } -static int nvme_get_internal_log(int fd, const char *const filename, bool current) +static int nvme_get_internal_log(struct nvme_transport_handle *hdl, + const char *const filename, bool current) { int err; int o_fd = -1; @@ -226,7 +228,7 @@ static int nvme_get_internal_log(int fd, const char *const filename, bool curren unsigned int j; float progress = 0.0; - err = nvme_sct_command_transfer_log(fd, current); + err = nvme_sct_command_transfer_log(hdl, current); if (err) { fprintf(stderr, "%s: SCT command transfer failed\n", __func__); goto end; @@ -239,7 +241,7 @@ static int nvme_get_internal_log(int fd, const char *const filename, bool curren memset(page_data, 0, max_pages * page_data_len); /* Read the header to get the last log page - offsets 8->11, 12->15, 16->19 */ - err = nvme_sct_data_transfer(fd, page_data, page_data_len, 0); + err = nvme_sct_data_transfer(hdl, page_data, page_data_len, 0); if (err) { fprintf(stderr, "%s: SCT data transfer failed, page 0\n", __func__); goto end; @@ -283,7 +285,7 @@ static int nvme_get_internal_log(int fd, const char *const filename, bool curren if (pages_chunk + i >= pages) pages_chunk = pages - i; - err = nvme_sct_data_transfer(fd, page_data, + err = nvme_sct_data_transfer(hdl, page_data, pages_chunk * page_data_len, i * page_sector_len); if (err) { @@ -312,7 +314,7 @@ static int nvme_get_internal_log(int fd, const char *const filename, bool curren progress = 1.0f; progress_runner(progress); fprintf(stdout, "\n"); - err = nvme_get_sct_status(fd, MASK_IGNORE); + err = nvme_get_sct_status(hdl, MASK_IGNORE); if (err) { fprintf(stderr, "%s: bad SCT status\n", __func__); goto end; @@ -324,14 +326,15 @@ static int nvme_get_internal_log(int fd, const char *const filename, bool curren return err; } -static int nvme_get_internal_log_file(int fd, const char *const filename, bool current) +static int nvme_get_internal_log_file(struct nvme_transport_handle *hdl, + const char *const filename, bool current) { int err; /* Check device supported */ - err = nvme_get_sct_status(fd, MASK_0 | MASK_1); + err = nvme_get_sct_status(hdl, MASK_0 | MASK_1); if (!err) - err = nvme_get_internal_log(fd, filename, current); + err = nvme_get_internal_log(hdl, filename, current); return err; } @@ -351,11 +354,12 @@ struct nvme_xdn_smart_log_c0 { __u8 resv[512 - NR_SMART_ITEMS_C0]; }; -static void default_show_vendor_log_c0(struct nvme_dev *dev, __u32 nsid, - struct nvme_xdn_smart_log_c0 *smart) +static void default_show_vendor_log_c0(struct nvme_transport_handle *hdl, + __u32 nsid, + struct nvme_xdn_smart_log_c0 *smart) { printf("Vendor Log Page Directory 0xC0 for NVME device:%s namespace-id:%x\n", - dev->name, nsid); + nvme_transport_handle_get_name(hdl), nsid); printf("Error Log : %u\n", smart->items[ERROR_LOG_C0]); printf("SMART Health Log : %u\n", smart->items[SMART_HEALTH_LOG_C0]); printf("Firmware Slot Info : %u\n", smart->items[FIRMWARE_SLOT_INFO_C0]); @@ -365,8 +369,9 @@ static void default_show_vendor_log_c0(struct nvme_dev *dev, __u32 nsid, printf("SMART Attributes : %u\n", smart->items[SMART_ATTRIBUTES_C0]); } -static int nvme_get_vendor_log(struct nvme_dev *dev, __u32 namespace_id, - int log_page, const char *const filename) +static int nvme_get_vendor_log(struct nvme_transport_handle *hdl, + __u32 namespace_id, int log_page, + const char *const filename) { int err; void *log = NULL; @@ -378,11 +383,11 @@ static int nvme_get_vendor_log(struct nvme_dev *dev, __u32 namespace_id, } /* Check device supported */ - err = nvme_get_sct_status(dev_fd(dev), MASK_0 | MASK_1); + err = nvme_get_sct_status(hdl, MASK_0 | MASK_1); if (err) goto end; - err = nvme_get_nsid_log(dev_fd(dev), false, log_page, namespace_id, - log_len, log); + err = nvme_get_nsid_log(hdl, namespace_id, false, log_page, + log, log_len); if (err) { fprintf(stderr, "%s: couldn't get log 0x%x\n", __func__, log_page); @@ -409,7 +414,7 @@ static int nvme_get_vendor_log(struct nvme_dev *dev, __u32 namespace_id, } } else { if (log_page == 0xc0) - default_show_vendor_log_c0(dev, namespace_id, log); + default_show_vendor_log_c0(hdl, namespace_id, log); else d(log, log_len, 16, 1); } @@ -418,13 +423,14 @@ static int nvme_get_vendor_log(struct nvme_dev *dev, __u32 namespace_id, return err; } -static int vendor_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int vendor_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { char *desc = "Get extended SMART information and show it."; const char *namespace = "(optional) desired namespace"; const char *output_file = "(optional) binary output filename"; const char *log = "(optional) log ID (0xC0, or 0xCA), default 0xCA"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; struct config { @@ -446,7 +452,7 @@ static int vendor_log(int argc, char **argv, struct command *cmd, struct plugin OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { fprintf(stderr, "%s: failed to parse arguments\n", __func__); return -EINVAL; @@ -458,23 +464,24 @@ static int vendor_log(int argc, char **argv, struct command *cmd, struct plugin goto end; } - err = nvme_get_vendor_log(dev, cfg.namespace_id, cfg.log, + err = nvme_get_vendor_log(hdl, cfg.namespace_id, cfg.log, cfg.output_file); if (err) fprintf(stderr, "%s: couldn't get vendor log 0x%x\n", __func__, cfg.log); end: if (err > 0) nvme_show_status(err); - dev_close(dev); + return err; } -static int internal_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int internal_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { char *desc = "Get internal status log and show it."; const char *output_file = "(optional) binary output filename"; const char *prev_log = "(optional) use previous log. Otherwise uses current log."; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int err; struct config { @@ -493,7 +500,7 @@ static int internal_log(int argc, char **argv, struct command *cmd, struct plugi OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { fprintf(stderr, "%s: failed to parse arguments\n", __func__); return -EINVAL; @@ -504,27 +511,27 @@ static int internal_log(int argc, char **argv, struct command *cmd, struct plugi else printf("Getting current log\n"); - err = nvme_get_internal_log_file(dev_fd(dev), cfg.output_file, + err = nvme_get_internal_log_file(hdl, cfg.output_file, !cfg.prev_log); if (err < 0) fprintf(stderr, "%s: couldn't get fw log\n", __func__); if (err > 0) nvme_show_status(err); - dev_close(dev); return err; } -static int clear_correctable_errors(int argc, char **argv, struct command *cmd, - struct plugin *plugin) +static int clear_correctable_errors(int argc, char **argv, struct command *acmd, + struct plugin *plugin) { char *desc = "Clear PCIe correctable error count."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; const __u32 namespace_id = 0xFFFFFFFF; const __u32 feature_id = 0xCA; const __u32 value = 1; /* Bit0 - reset clear PCIe correctable count */ const __u32 cdw12 = 0; const bool save = false; - struct nvme_dev *dev; __u32 result; int err; @@ -532,39 +539,25 @@ static int clear_correctable_errors(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { fprintf(stderr, "%s: failed to parse arguments\n", __func__); return -EINVAL; } /* Check device supported */ - err = nvme_get_sct_status(dev_fd(dev), MASK_0 | MASK_1); + err = nvme_get_sct_status(hdl, MASK_0 | MASK_1); if (err) goto end; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = feature_id, - .nsid = namespace_id, - .cdw11 = value, - .cdw12 = cdw12, - .save = save, - .uuidx = 0, - .cdw15 = 0, - .data_len = 0, - .data = NULL, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - err = nvme_set_features(&args); + err = nvme_set_features(hdl, namespace_id, feature_id, save, value, cdw12, + 0, 0, 0, NULL, 0, &result); if (err) fprintf(stderr, "%s: couldn't clear PCIe correctable errors\n", __func__); end: if (err > 0) nvme_show_status(err); - dev_close(dev); + return err; } diff --git a/plugins/transcend/transcend-nvme.c b/plugins/transcend/transcend-nvme.c index 547fbf4ea9..f80be2b659 100644 --- a/plugins/transcend/transcend-nvme.c +++ b/plugins/transcend/transcend-nvme.c @@ -17,24 +17,25 @@ static const __u32 OP_BAD_BLOCK = 0xc2; static const __u32 DW10_BAD_BLOCK = 0x400; static const __u32 DW12_BAD_BLOCK = 0x5a; -static int getHealthValue(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int getHealthValue(int argc, char **argv, struct command *acmd, struct plugin *plugin) { struct nvme_smart_log smart_log; char *desc = "Get nvme health percentage."; int percent_used = 0, healthvalue = 0; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int result; OPT_ARGS(opts) = { OPT_END() }; - result = parse_and_open(&dev, argc, argv, desc, opts); + result = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (result) { printf("\nDevice not found\n"); return -1; } - result = nvme_get_log_smart(dev_fd(dev), 0xffffffff, false, &smart_log); + result = nvme_get_log_smart(hdl, NVME_NSID_ALL, &smart_log); if (!result) { printf("Transcend NVME heath value: "); percent_used = smart_log.percent_used; @@ -46,28 +47,29 @@ static int getHealthValue(int argc, char **argv, struct command *cmd, struct plu printf("%d%%\n", healthvalue); } } - dev_close(dev); + return result; } -static int getBadblock(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int getBadblock(int argc, char **argv, struct command *acmd, struct plugin *plugin) { char *desc = "Get nvme bad block number."; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd nvmecmd; + unsigned char data[1] = {0}; int result; OPT_ARGS(opts) = { OPT_END() }; - result = parse_and_open(&dev, argc, argv, desc, opts); + result = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (result) { printf("\nDevice not found\n"); return -1; } - unsigned char data[1] = {0}; - struct nvme_passthru_cmd nvmecmd; memset(&nvmecmd, 0, sizeof(nvmecmd)); nvmecmd.opcode = OP_BAD_BLOCK; @@ -75,12 +77,13 @@ static int getBadblock(int argc, char **argv, struct command *cmd, struct plugin nvmecmd.cdw12 = DW12_BAD_BLOCK; nvmecmd.addr = (__u64)(uintptr_t)data; nvmecmd.data_len = 0x1; - result = nvme_submit_admin_passthru(dev_fd(dev), &nvmecmd, NULL); + + result = nvme_submit_admin_passthru(hdl, &nvmecmd, NULL); if (!result) { int badblock = data[0]; printf("Transcend NVME badblock count: %d\n", badblock); } - dev_close(dev); + return result; } diff --git a/plugins/virtium/virtium-nvme.c b/plugins/virtium/virtium-nvme.c index 50b2a5433b..88ec40db2c 100644 --- a/plugins/virtium/virtium-nvme.c +++ b/plugins/virtium/virtium-nvme.c @@ -262,7 +262,9 @@ static void vt_process_string(char *str, const size_t size) } } -static int vt_add_entry_to_log(const int fd, const char *path, const struct vtview_save_log_settings *cfg) +static int vt_add_entry_to_log(struct nvme_transport_handle *hdl, + const char *path, + const struct vtview_save_log_settings *cfg) { struct vtview_smart_log_entry smart; const char *filename; @@ -277,26 +279,26 @@ static int vt_add_entry_to_log(const int fd, const char *path, const struct vtvi filename = cfg->output_file; smart.time_stamp = time(NULL); - ret = nvme_get_nsid(fd, &nsid); + ret = nvme_get_nsid(hdl, &nsid); if (ret < 0) { printf("Cannot read namespace-id\n"); return -1; } - ret = nvme_identify_ns(fd, nsid, &smart.raw_ns); + ret = nvme_identify_ns(hdl, nsid, &smart.raw_ns); if (ret) { printf("Cannot read namespace identify\n"); return -1; } - ret = nvme_identify_ctrl(fd, &smart.raw_ctrl); + ret = nvme_identify_ctrl(hdl, &smart.raw_ctrl); if (ret) { printf("Cannot read device identify controller\n"); return -1; } - ret = nvme_get_log_smart(fd, NVME_NSID_ALL, false, &smart.raw_smart); + ret = nvme_get_log_smart(hdl, NVME_NSID_ALL, &smart.raw_smart); if (ret) { printf("Cannot read device SMART log\n"); return -1; @@ -309,7 +311,9 @@ static int vt_add_entry_to_log(const int fd, const char *path, const struct vtvi return ret; } -static int vt_update_vtview_log_header(const int fd, const char *path, const struct vtview_save_log_settings *cfg) +static int +vt_update_vtview_log_header(struct nvme_transport_handle *hdl, const char *path, + const struct vtview_save_log_settings *cfg) { struct vtview_log_header header; const char *filename; @@ -342,13 +346,13 @@ static int vt_update_vtview_log_header(const int fd, const char *path, const str printf("Log file: %s\n", filename); header.time_stamp = time(NULL); - ret = nvme_identify_ctrl(fd, &header.raw_ctrl); + ret = nvme_identify_ctrl(hdl, &header.raw_ctrl); if (ret) { printf("Cannot read identify device\n"); return -1; } - ret = nvme_get_log_fw_slot(fd, false, &header.raw_fw); + ret = nvme_get_log_fw_slot(hdl, false, &header.raw_fw); if (ret) { printf("Cannot read device firmware log\n"); return -1; @@ -918,7 +922,9 @@ static void vt_parse_detail_identify(const struct nvme_id_ctrl *ctrl) printf("\"}\n"); } -static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int vt_save_smart_to_vtview_log(int argc, char **argv, + struct command *command, + struct plugin *plugin) { int ret, err = 0; long total_time = 0; @@ -941,7 +947,8 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm const char *freq = "(optional) How often you want to log SMART data (0.25 = 15' , 0.5 = 30' , 1 = 1 hour, 2 = 2 hours, etc.). Default = 10 hours."; const char *output_file = "(optional) Name of the log file (give it a name that easy for you to remember what the test is). You can leave it blank too, we will take care it for you."; const char *test_name = "(optional) Name of the test you are doing. We use this as part of the name of the log file."; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct vtview_save_log_settings cfg = { .run_time_hrs = 20, @@ -968,7 +975,7 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm strcpy(path, argv[1]); } - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { printf("Error parse and open (err = %d)\n", err); return err; @@ -979,12 +986,9 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm printf("Running for %lf hour(s)\n", cfg.run_time_hrs); printf("Logging SMART data for every %lf hour(s)\n", cfg.log_record_frequency_hrs); - ret = vt_update_vtview_log_header(dev_fd(dev), path, &cfg); - if (ret) { - err = EINVAL; - dev_close(dev); - return err; - } + ret = vt_update_vtview_log_header(hdl, path, &cfg); + if (ret) + return ret; total_time = cfg.run_time_hrs * (float)HOUR_IN_SECONDS; freq_time = cfg.log_record_frequency_hrs * (float)HOUR_IN_SECONDS; @@ -1002,7 +1006,7 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm if (cur_time >= end_time) break; - ret = vt_add_entry_to_log(dev_fd(dev), path, &cfg); + ret = vt_add_entry_to_log(hdl, path, &cfg); if (ret) { printf("Cannot update driver log\n"); break; @@ -1014,33 +1018,32 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm fflush(stdout); } - dev_close(dev); return err; } -static int vt_show_identify(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int vt_show_identify(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - int ret, err = 0; - struct nvme_id_ctrl ctrl; - struct nvme_dev *dev; char *desc = "Parse identify data to json format\n\n" "Typical usages:\n\n" "virtium show-identify /dev/yourDevice\n"; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_id_ctrl ctrl; + int ret, err = 0; OPT_ARGS(opts) = { OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) { printf("Error parse and open (err = %d)\n", err); return err; } - ret = nvme_identify_ctrl(dev_fd(dev), &ctrl); + ret = nvme_identify_ctrl(hdl, &ctrl); if (ret) { printf("Cannot read identify device\n"); - dev_close(dev); return -1; } @@ -1048,6 +1051,5 @@ static int vt_show_identify(int argc, char **argv, struct command *cmd, struct p vt_process_string(ctrl.mn, sizeof(ctrl.mn)); vt_parse_detail_identify(&ctrl); - dev_close(dev); return err; } diff --git a/plugins/wdc/wdc-nvme-cmds.h b/plugins/wdc/wdc-nvme-cmds.h index 2dea9b06c2..4153dbf169 100644 --- a/plugins/wdc/wdc-nvme-cmds.h +++ b/plugins/wdc/wdc-nvme-cmds.h @@ -106,7 +106,7 @@ int run_wdc_vs_device_waf(int argc, char **argv, struct plugin *plugin); int run_wdc_set_latency_monitor_feature(int argc, char **argv, - struct command *cmd, + struct command *command, struct plugin *plugin); int run_wdc_vs_temperature_stats(int argc, char **argv, @@ -117,11 +117,12 @@ int run_wdc_cu_smart_log(int argc, char **argv, struct command *command, struct plugin *plugin); -bool run_wdc_nvme_check_supported_log_page(nvme_root_t r, - struct nvme_dev *dev, +bool run_wdc_nvme_check_supported_log_page(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl, __u8 log_id); -__u32 run_wdc_get_fw_cust_id(nvme_root_t r, - struct nvme_dev *dev); +__u32 run_wdc_get_fw_cust_id(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl); -__u64 run_wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev); +__u64 run_wdc_get_drive_capabilities(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl); diff --git a/plugins/wdc/wdc-nvme.c b/plugins/wdc/wdc-nvme.c index e657f65129..62c3979492 100644 --- a/plugins/wdc/wdc-nvme.c +++ b/plugins/wdc/wdc-nvme.c @@ -924,63 +924,63 @@ struct __packed feature_latency_monitor { __u8 reserved[4083]; }; -static int wdc_get_serial_name(struct nvme_dev *dev, char *file, size_t len, const char *suffix); +static int wdc_get_serial_name(struct nvme_transport_handle *hdl, char *file, size_t len, const char *suffix); static int wdc_create_log_file(const char *file, const __u8 *drive_log_data, __u32 drive_log_length); -static int wdc_do_clear_dump(struct nvme_dev *dev, __u8 opcode, __u32 cdw12); -static int wdc_do_dump(struct nvme_dev *dev, __u32 opcode, __u32 data_len, __u32 cdw12, +static int wdc_do_clear_dump(struct nvme_transport_handle *hdl, __u8 opcode, __u32 cdw12); +static int wdc_do_dump(struct nvme_transport_handle *hdl, __u32 opcode, __u32 data_len, __u32 cdw12, const char *file, __u32 xfer_size); -static int wdc_do_crash_dump(struct nvme_dev *dev, char *file, int type); -static int wdc_crash_dump(struct nvme_dev *dev, const char *file, int type); -static int wdc_get_crash_dump(int argc, char **argv, struct command *command, +static int wdc_do_crash_dump(struct nvme_transport_handle *hdl, char *file, int type); +static int wdc_crash_dump(struct nvme_transport_handle *hdl, const char *file, int type); +static int wdc_get_crash_dump(int argc, char **argv, struct command *acmd, struct plugin *plugin); -static int wdc_do_drive_log(struct nvme_dev *dev, const char *file); -static int wdc_drive_log(int argc, char **argv, struct command *command, struct plugin *plugin); +static int wdc_do_drive_log(struct nvme_transport_handle *hdl, const char *file); +static int wdc_drive_log(int argc, char **argv, struct command *acmd, struct plugin *plugin); static const char *wdc_purge_mon_status_to_string(__u32 status); -static int wdc_purge(int argc, char **argv, struct command *command, struct plugin *plugin); -static int wdc_purge_monitor(int argc, char **argv, struct command *command, struct plugin *plugin); -static bool wdc_nvme_check_supported_log_page(nvme_root_t r, - struct nvme_dev *dev, +static int wdc_purge(int argc, char **argv, struct command *acmd, struct plugin *plugin); +static int wdc_purge_monitor(int argc, char **argv, struct command *acmd, struct plugin *plugin); +static bool wdc_nvme_check_supported_log_page(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl, __u8 log_id, __u8 uuid_index); -static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct command *command, +static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct command *acmd, struct plugin *plugin); -static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev, char *dir, char *key); -static int wdc_drive_essentials(int argc, char **argv, struct command *command, +static int wdc_do_drive_essentials(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, char *dir, char *key); +static int wdc_drive_essentials(int argc, char **argv, struct command *acmd, struct plugin *plugin); -static int wdc_drive_status(int argc, char **argv, struct command *command, struct plugin *plugin); -static int wdc_clear_assert_dump(int argc, char **argv, struct command *command, +static int wdc_drive_status(int argc, char **argv, struct command *acmd, struct plugin *plugin); +static int wdc_clear_assert_dump(int argc, char **argv, struct command *acmd, struct plugin *plugin); -static int wdc_drive_resize(int argc, char **argv, struct command *command, struct plugin *plugin); -static int wdc_do_drive_resize(struct nvme_dev *dev, uint64_t new_size); -static int wdc_namespace_resize(int argc, char **argv, struct command *command, +static int wdc_drive_resize(int argc, char **argv, struct command *acmd, struct plugin *plugin); +static int wdc_do_drive_resize(struct nvme_transport_handle *hdl, uint64_t new_size); +static int wdc_namespace_resize(int argc, char **argv, struct command *acmd, struct plugin *plugin); -static int wdc_do_namespace_resize(struct nvme_dev *dev, __u32 nsid, __u32 op_option); -static int wdc_reason_identifier(int argc, char **argv, struct command *command, +static int wdc_do_namespace_resize(struct nvme_transport_handle *hdl, __u32 nsid, __u32 op_option); +static int wdc_reason_identifier(int argc, char **argv, struct command *acmd, struct plugin *plugin); -static int wdc_do_get_reason_id(struct nvme_dev *dev, const char *file, int log_id); -static int wdc_save_reason_id(struct nvme_dev *dev, __u8 *rsn_ident, int size); -static int wdc_clear_reason_id(struct nvme_dev *dev); -static int wdc_log_page_directory(int argc, char **argv, struct command *command, +static int wdc_do_get_reason_id(struct nvme_transport_handle *hdl, const char *file, int log_id); +static int wdc_save_reason_id(struct nvme_transport_handle *hdl, __u8 *rsn_ident, int size); +static int wdc_clear_reason_id(struct nvme_transport_handle *hdl); +static int wdc_log_page_directory(int argc, char **argv, struct command *acmd, struct plugin *plugin); -static int wdc_do_drive_info(struct nvme_dev *dev, __u32 *result); -static int wdc_vs_drive_info(int argc, char **argv, struct command *command, struct plugin *plugin); -static int wdc_vs_temperature_stats(int argc, char **argv, struct command *command, +static int wdc_do_drive_info(struct nvme_transport_handle *hdl, __u32 *result); +static int wdc_vs_drive_info(int argc, char **argv, struct command *acmd, struct plugin *plugin); +static int wdc_vs_temperature_stats(int argc, char **argv, struct command *acmd, struct plugin *plugin); -static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r, struct nvme_dev *dev); -static int wdc_enc_get_nic_log(struct nvme_dev *dev, __u8 log_id, __u32 xfer_size, __u32 data_len, +static __u64 wdc_get_enc_drive_capabilities(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl); +static int wdc_enc_get_nic_log(struct nvme_transport_handle *hdl, __u8 log_id, __u32 xfer_size, __u32 data_len, FILE *out); -static int wdc_enc_submit_move_data(struct nvme_dev *dev, char *cmd, int len, int xfer_size, +static int wdc_enc_submit_move_data(struct nvme_transport_handle *hdl, char *cmd, int len, int xfer_size, FILE *out, int data_id, int cdw14, int cdw15); -static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev, __u8 log_id, +static bool get_dev_mgment_cbs_data(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, __u8 log_id, void **cbs_data); -static __u32 wdc_get_fw_cust_id(nvme_root_t r, struct nvme_dev *dev); +static __u32 wdc_get_fw_cust_id(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl); static int wdc_print_c0_cloud_attr_log(void *data, int fmt, - struct nvme_dev *dev); + struct nvme_transport_handle *hdl); static int wdc_print_c0_eol_log(void *data, int fmt); static void wdc_show_cloud_smart_log_normal(struct ocp_cloud_smart_log *log, - struct nvme_dev *dev); + struct nvme_transport_handle *hdl); static void wdc_show_cloud_smart_log_json(struct ocp_cloud_smart_log *log); /* Drive log data size */ @@ -1447,26 +1447,27 @@ static double calc_percent(uint64_t numerator, uint64_t denominator) (uint64_t)(((double)numerator / (double)denominator) * 100) : 0; } -static int wdc_get_pci_ids(nvme_root_t r, struct nvme_dev *dev, +static int wdc_get_pci_ids(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, uint32_t *device_id, uint32_t *vendor_id) { + const char *name = nvme_transport_handle_get_name(hdl); char vid[256], did[256], id[32]; nvme_ctrl_t c = NULL; nvme_ns_t n = NULL; int fd, ret; - c = nvme_scan_ctrl(r, dev->name); - if (c) { + ret = nvme_scan_ctrl(ctx, name, &c); + if (!ret) { snprintf(vid, sizeof(vid), "%s/device/vendor", nvme_ctrl_get_sysfs_dir(c)); snprintf(did, sizeof(did), "%s/device/device", nvme_ctrl_get_sysfs_dir(c)); nvme_free_ctrl(c); } else { - n = nvme_scan_namespace(dev->name); - if (!n) { - fprintf(stderr, "Unable to find %s\n", dev->name); - return -1; + ret = nvme_scan_namespace(name, &n); + if (ret) { + fprintf(stderr, "Unable to find %s\n", name); + return ret; } snprintf(vid, sizeof(vid), "%s/device/device/vendor", @@ -1517,13 +1518,13 @@ static int wdc_get_pci_ids(nvme_root_t r, struct nvme_dev *dev, return 0; } -static int wdc_get_vendor_id(struct nvme_dev *dev, uint32_t *vendor_id) +static int wdc_get_vendor_id(struct nvme_transport_handle *hdl, uint32_t *vendor_id) { - int ret; struct nvme_id_ctrl ctrl; + int ret; memset(&ctrl, 0, sizeof(struct nvme_id_ctrl)); - ret = nvme_identify_ctrl(dev_fd(dev), &ctrl); + ret = nvme_identify_ctrl(hdl, &ctrl); if (ret) { fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", ret); return -1; @@ -1607,13 +1608,13 @@ static bool wdc_check_power_of_2(int num) return num && (!(num & (num-1))); } -static int wdc_get_model_number(struct nvme_dev *dev, char *model) +static int wdc_get_model_number(struct nvme_transport_handle *hdl, char *model) { - int ret, i; struct nvme_id_ctrl ctrl; + int ret, i; memset(&ctrl, 0, sizeof(struct nvme_id_ctrl)); - ret = nvme_identify_ctrl(dev_fd(dev), &ctrl); + ret = nvme_identify_ctrl(hdl, &ctrl); if (ret) { fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", ret); return -1; @@ -1629,16 +1630,16 @@ static int wdc_get_model_number(struct nvme_dev *dev, char *model) return ret; } -static bool wdc_check_device(nvme_root_t r, struct nvme_dev *dev) +static bool wdc_check_device(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl) { int ret; bool supported; uint32_t read_device_id = -1, read_vendor_id = -1; - ret = wdc_get_pci_ids(r, dev, &read_device_id, &read_vendor_id); + ret = wdc_get_pci_ids(ctx, hdl, &read_device_id, &read_vendor_id); if (ret < 0) { /* Use the identify nvme command to get vendor id due to NVMeOF device. */ - if (wdc_get_vendor_id(dev, &read_vendor_id) < 0) + if (wdc_get_vendor_id(hdl, &read_vendor_id) < 0) return false; } @@ -1656,13 +1657,13 @@ static bool wdc_check_device(nvme_root_t r, struct nvme_dev *dev) return supported; } -static bool wdc_enc_check_model(struct nvme_dev *dev) +static bool wdc_enc_check_model(struct nvme_transport_handle *hdl) { int ret; bool supported; char model[NVME_ID_CTRL_MODEL_NUMBER_SIZE+1]; - ret = wdc_get_model_number(dev, model); + ret = wdc_get_model_number(hdl, model); if (ret < 0) return false; @@ -1676,22 +1677,22 @@ static bool wdc_enc_check_model(struct nvme_dev *dev) return supported; } -static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev) +static __u64 wdc_get_drive_capabilities(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl) { int ret; uint32_t read_device_id = -1, read_vendor_id = -1; __u64 capabilities = 0; __u32 cust_id; - ret = wdc_get_pci_ids(r, dev, &read_device_id, &read_vendor_id); + ret = wdc_get_pci_ids(ctx, hdl, &read_device_id, &read_vendor_id); if (ret < 0) { - if (wdc_get_vendor_id(dev, &read_vendor_id) < 0) + if (wdc_get_vendor_id(hdl, &read_vendor_id) < 0) return capabilities; } /* below check condition is added due in NVMeOF device we dont have device_id so we need to use only vendor_id*/ if (read_device_id == -1 && read_vendor_id != -1) { - capabilities = wdc_get_enc_drive_capabilities(r, dev); + capabilities = wdc_get_enc_drive_capabilities(ctx, hdl); return capabilities; } @@ -1710,12 +1711,12 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev) WDC_DRIVE_CAP_PURGE); /* verify the 0xCA log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE, 0)) capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE; /* verify the 0xC1 log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_ADD_LOG_OPCODE, 0)) capabilities |= WDC_DRIVE_CAP_C1_LOG_PAGE; break; @@ -1733,12 +1734,12 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev) WDC_DRIVE_CAP_DRIVE_STATUS | WDC_DRIVE_CAP_CLEAR_ASSERT | WDC_DRIVE_CAP_RESIZE | WDC_DRIVE_CAP_CLEAR_PCIE); /* verify the 0xCA log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE, 0)) capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE; /* verify the 0xD0 log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_VU_SMART_LOG_OPCODE, 0)) capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE; break; @@ -1752,7 +1753,7 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev) case WDC_NVME_SN560_DEV_ID_3: case WDC_NVME_SN660_DEV_ID: /* verify the 0xC0 log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID, 0) == true) { capabilities |= WDC_DRIVE_CAP_C0_LOG_PAGE; @@ -1765,36 +1766,36 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev) WDC_DRIVE_CAP_LOG_PAGE_DIR); /* verify the 0xC1 (OCP Error Recovery) log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_ERROR_REC_LOG_ID, 0)) capabilities |= WDC_DRIVE_CAP_OCP_C1_LOG_PAGE; /* verify the 0xC3 (OCP Latency Monitor) log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_LATENCY_MON_LOG_ID, 0)) capabilities |= WDC_DRIVE_CAP_C3_LOG_PAGE; /* verify the 0xC4 (OCP Device Capabilities) log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_DEV_CAP_LOG_ID, 0)) capabilities |= WDC_DRIVE_CAP_OCP_C4_LOG_PAGE; /* verify the 0xC5 (OCP Unsupported Requirements) log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_UNSUPPORTED_REQS_LOG_ID, 0)) capabilities |= WDC_DRIVE_CAP_OCP_C5_LOG_PAGE; /* verify the 0xCA log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE, 0)) capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE; /* verify the 0xD0 log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_VU_SMART_LOG_OPCODE, 0)) capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE; - cust_id = wdc_get_fw_cust_id(r, dev); + cust_id = wdc_get_fw_cust_id(ctx, hdl); /* Can still determine some capabilities in this case, but log an error */ if (cust_id == WDC_INVALID_CUSTOMER_ID) fprintf(stderr, @@ -1814,7 +1815,7 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev) case WDC_NVME_SN840_DEV_ID_1: case WDC_NVME_SN860_DEV_ID: /* verify the 0xC0 log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE, 0)) capabilities |= WDC_DRIVE_CAP_C0_LOG_PAGE; fallthrough; @@ -1828,12 +1829,12 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev) WDC_DRIVE_CAP_LOG_PAGE_DIR); /* verify the 0xCA log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE, 0)) capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE; /* verify the 0xD0 log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_VU_SMART_LOG_OPCODE, 0)) capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE; break; @@ -1847,27 +1848,27 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev) case WDC_NVME_SN655_DEV_ID_1: case WDC_NVME_SN550_DEV_ID: /* verify the 0xC0 log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID, 0)) capabilities |= WDC_DRIVE_CAP_C0_LOG_PAGE; /* verify the 0xC1 (OCP Error Recovery) log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_ERROR_REC_LOG_ID, 0)) capabilities |= WDC_DRIVE_CAP_OCP_C1_LOG_PAGE; /* verify the 0xC3 (OCP Latency Monitor) log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_LATENCY_MON_LOG_ID, 0)) capabilities |= WDC_DRIVE_CAP_C3_LOG_PAGE; /* verify the 0xC4 (OCP Device Capabilities) log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_DEV_CAP_LOG_ID, 0)) capabilities |= WDC_DRIVE_CAP_OCP_C4_LOG_PAGE; /* verify the 0xC5 (OCP Unsupported Requirements) log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_UNSUPPORTED_REQS_LOG_ID, 0)) capabilities |= WDC_DRIVE_CAP_OCP_C5_LOG_PAGE; @@ -1877,7 +1878,7 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev) WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG | WDC_DRIVE_CAP_REASON_ID | WDC_DRIVE_CAP_LOG_PAGE_DIR); - cust_id = wdc_get_fw_cust_id(r, dev); + cust_id = wdc_get_fw_cust_id(ctx, hdl); /* Can still determine some capabilities in this case, but log an error */ if (cust_id == WDC_INVALID_CUSTOMER_ID) fprintf(stderr, @@ -2048,15 +2049,15 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev) return capabilities; } -static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r, - struct nvme_dev *dev) +static __u64 wdc_get_enc_drive_capabilities(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl) { int ret; uint32_t read_vendor_id; __u64 capabilities = 0; __u32 cust_id; - ret = wdc_get_vendor_id(dev, &read_vendor_id); + ret = wdc_get_vendor_id(hdl, &read_vendor_id); if (ret < 0) return capabilities; @@ -2066,12 +2067,12 @@ static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r, WDC_DRIVE_CAP_DRIVE_LOG | WDC_DRIVE_CAP_CRASH_DUMP | WDC_DRIVE_CAP_PFAIL_DUMP); /* verify the 0xCA log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE, 0) == true) capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE; /* verify the 0xC1 log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_ADD_LOG_OPCODE, 0) == true) capabilities |= WDC_DRIVE_CAP_C1_LOG_PAGE; break; @@ -2081,26 +2082,26 @@ static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r, WDC_DRIVE_CAP_RESIZE); /* verify the 0xC3 log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_LATENCY_MON_LOG_ID, 0) == true) capabilities |= WDC_DRIVE_CAP_C3_LOG_PAGE; /* verify the 0xCB log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID, 0) == true) capabilities |= WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY; /* verify the 0xCA log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE, 0) == true) capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE; /* verify the 0xD0 log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_VU_SMART_LOG_OPCODE, 0) == true) capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE; - cust_id = wdc_get_fw_cust_id(r, dev); + cust_id = wdc_get_fw_cust_id(ctx, hdl); if (cust_id == WDC_INVALID_CUSTOMER_ID) { fprintf(stderr, "%s: ERROR: WDC: invalid customer id\n", __func__); return -1; @@ -2123,7 +2124,7 @@ static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r, return capabilities; } -static int wdc_get_serial_name(struct nvme_dev *dev, char *file, size_t len, +static int wdc_get_serial_name(struct nvme_transport_handle *hdl, char *file, size_t len, const char *suffix) { int i; @@ -2137,7 +2138,7 @@ static int wdc_get_serial_name(struct nvme_dev *dev, char *file, size_t len, strncpy(orig, file, PATH_MAX - 1); memset(file, 0, len); memset(&ctrl, 0, sizeof(struct nvme_id_ctrl)); - ret = nvme_identify_ctrl(dev_fd(dev), &ctrl); + ret = nvme_identify_ctrl(hdl, &ctrl); if (ret) { fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", ret); return -1; @@ -2460,14 +2461,15 @@ bool wdc_get_dev_mng_log_entry(__u32 log_length, __u32 entry_id, return valid_log; } -static bool get_dev_mgmt_log_page_data(struct nvme_dev *dev, void **log_data, +static bool get_dev_mgmt_log_page_data(struct nvme_transport_handle *hdl, void **log_data, __u8 uuid_ix) { - void *data; struct wdc_c2_log_page_header *hdr_ptr; + struct nvme_passthru_cmd cmd; + bool valid = false; __u32 length = 0; + void *data; int ret = 0; - bool valid = false; data = (__u8 *)malloc(sizeof(__u8) * WDC_C2_LOG_BUF_LEN); if (!data) { @@ -2478,24 +2480,13 @@ static bool get_dev_mgmt_log_page_data(struct nvme_dev *dev, void **log_data, memset(data, 0, sizeof(__u8) * WDC_C2_LOG_BUF_LEN); /* get the log page length */ - struct nvme_get_log_args args_len = { - .args_size = sizeof(args_len), - .fd = dev_fd(dev), - .lid = WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_ID, - .nsid = 0xFFFFFFFF, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = 0, - .rae = false, - .uuidx = uuid_ix, - .csi = NVME_CSI_NVM, - .ot = false, - .len = WDC_C2_LOG_BUF_LEN, - .log = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - ret = nvme_get_log(&args_len); + nvme_init_get_log(&cmd, NVME_NSID_ALL, + WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_ID, NVME_CSI_NVM, data, + WDC_C2_LOG_BUF_LEN); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_ix, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + ret = nvme_get_log(hdl, &cmd, false, NVME_LOG_PAGE_PDU_SIZE, NULL); if (ret) { fprintf(stderr, "ERROR: WDC: Unable to get 0x%x Log Page with uuid %d, ret = 0x%x\n", @@ -2516,25 +2507,14 @@ static bool get_dev_mgmt_log_page_data(struct nvme_dev *dev, void **log_data, } /* get the log page data with the increased length */ - struct nvme_get_log_args args_data = { - .args_size = sizeof(args_data), - .fd = dev_fd(dev), - .lid = WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_ID, - .nsid = 0xFFFFFFFF, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = 0, - .rae = false, - .uuidx = uuid_ix, - .csi = NVME_CSI_NVM, - .ot = false, - .len = length, - .log = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - ret = nvme_get_log(&args_data); - + nvme_init_get_log(&cmd, NVME_NSID_ALL, + WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_ID, NVME_CSI_NVM, data, + length); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_ix, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + ret = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (ret) { fprintf(stderr, "ERROR: WDC: Unable to read 0x%x Log with uuid %d, ret = 0x%x\n", @@ -2563,7 +2543,7 @@ static bool get_dev_mgmt_log_page_data(struct nvme_dev *dev, void **log_data, return valid; } -static bool get_dev_mgmt_log_page_lid_data(struct nvme_dev *dev, +static bool get_dev_mgmt_log_page_lid_data(struct nvme_transport_handle *hdl, void **cbs_data, __u8 lid, __u8 log_id, @@ -2572,6 +2552,7 @@ static bool get_dev_mgmt_log_page_lid_data(struct nvme_dev *dev, void *data; struct wdc_c2_log_page_header *hdr_ptr; struct wdc_c2_log_subpage_header *sph; + struct nvme_passthru_cmd cmd; __u32 length = 0; int ret = 0; bool found = false; @@ -2585,24 +2566,12 @@ static bool get_dev_mgmt_log_page_lid_data(struct nvme_dev *dev, memset(data, 0, sizeof(__u8) * WDC_C2_LOG_BUF_LEN); /* get the log page length */ - struct nvme_get_log_args args_len = { - .args_size = sizeof(args_len), - .fd = dev_fd(dev), - .lid = lid, - .nsid = 0xFFFFFFFF, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = 0, - .rae = false, - .uuidx = uuid_ix, - .csi = NVME_CSI_NVM, - .ot = false, - .len = WDC_C2_LOG_BUF_LEN, - .log = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - ret = nvme_get_log(&args_len); + nvme_init_get_log(&cmd, NVME_NSID_ALL, lid, NVME_CSI_NVM, data, + WDC_C2_LOG_BUF_LEN); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_ix, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + ret = nvme_get_log(hdl, &cmd, false, NVME_LOG_PAGE_PDU_SIZE, NULL); if (ret) { fprintf(stderr, "ERROR: WDC: Unable to get 0x%x Log Page length with uuid %d, ret = 0x%x\n", @@ -2623,25 +2592,13 @@ static bool get_dev_mgmt_log_page_lid_data(struct nvme_dev *dev, } /* get the log page data with the increased length */ - struct nvme_get_log_args args_data = { - .args_size = sizeof(args_data), - .fd = dev_fd(dev), - .lid = lid, - .nsid = 0xFFFFFFFF, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = 0, - .rae = false, - .uuidx = uuid_ix, - .csi = NVME_CSI_NVM, - .ot = false, - .len = length, - .log = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - ret = nvme_get_log(&args_data); - + nvme_init_get_log(&cmd, NVME_NSID_ALL, lid, NVME_CSI_NVM, data, + length); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_ix, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + ret = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (ret) { fprintf(stderr, "ERROR: WDC: Unable to read 0x%x Log Page data with uuid %d, ret = 0x%x\n", @@ -2673,7 +2630,7 @@ static bool get_dev_mgmt_log_page_lid_data(struct nvme_dev *dev, return found; } -static bool get_dev_mgment_data(nvme_root_t r, struct nvme_dev *dev, +static bool get_dev_mgment_data(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, void **data) { bool found = false; @@ -2689,17 +2646,17 @@ static bool get_dev_mgment_data(nvme_root_t r, struct nvme_dev *dev, * initialized to 0 so the code can continue on without issue for * both cases: wdc_get_pci_ids successful or failed. */ - wdc_get_pci_ids(r, dev, &device_id, &vendor_id); + wdc_get_pci_ids(ctx, hdl, &device_id, &vendor_id); memset(&uuid_list, 0, sizeof(struct nvme_id_uuid_list)); - if (wdc_CheckUuidListSupport(dev, &uuid_list)) { + if (wdc_CheckUuidListSupport(hdl, &uuid_list)) { uuid_index = nvme_uuid_find(&uuid_list, WDC_UUID); if (uuid_index < 0 && (wdc_is_sn640_3(device_id) || wdc_is_sn655(device_id))) uuid_index = nvme_uuid_find(&uuid_list, WDC_UUID_SN640_3); if (uuid_index >= 0) - found = get_dev_mgmt_log_page_data(dev, data, uuid_index); + found = get_dev_mgmt_log_page_data(hdl, data, uuid_index); } else if (needs_c2_log_page_check(device_id)) { /* In certain devices that don't support UUID lists, there are multiple * definitions of the C2 logpage. In those cases, the code @@ -2708,7 +2665,7 @@ static bool get_dev_mgment_data(nvme_root_t r, struct nvme_dev *dev, */ uuid_index = 1; - found = get_dev_mgmt_log_page_data(dev, data, uuid_index); + found = get_dev_mgmt_log_page_data(hdl, data, uuid_index); if (!found) { /* not found with uuid = 1 try with uuid = 0 */ @@ -2716,18 +2673,18 @@ static bool get_dev_mgment_data(nvme_root_t r, struct nvme_dev *dev, fprintf(stderr, "Not found, requesting log page with uuid_index %d\n", uuid_index); - found = get_dev_mgmt_log_page_data(dev, data, uuid_index); + found = get_dev_mgmt_log_page_data(hdl, data, uuid_index); } } else { /* Default to uuid-index 0 for cases where UUID lists are not supported */ uuid_index = 0; - found = get_dev_mgmt_log_page_data(dev, data, uuid_index); + found = get_dev_mgmt_log_page_data(hdl, data, uuid_index); } return found; } -static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev, +static bool get_dev_mgment_cbs_data(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, __u8 log_id, void **cbs_data) { bool found = false; @@ -2744,12 +2701,12 @@ static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev, * initialized to 0 so the code can continue on without issue for * both cases: wdc_get_pci_ids successful or failed. */ - wdc_get_pci_ids(r, dev, &device_id, &vendor_id); + wdc_get_pci_ids(ctx, hdl, &device_id, &vendor_id); lid = WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_ID; memset(&uuid_list, 0, sizeof(struct nvme_id_uuid_list)); - if (wdc_CheckUuidListSupport(dev, &uuid_list)) { + if (wdc_CheckUuidListSupport(hdl, &uuid_list)) { uuid_index = nvme_uuid_find(&uuid_list, WDC_UUID); if (uuid_index < 0 && (wdc_is_sn640_3(device_id) || wdc_is_sn655(device_id))) { @@ -2757,7 +2714,7 @@ static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev, } if (uuid_index >= 0) - found = get_dev_mgmt_log_page_lid_data(dev, cbs_data, lid, + found = get_dev_mgmt_log_page_lid_data(hdl, cbs_data, lid, log_id, uuid_index); } else if (needs_c2_log_page_check(device_id)) { /* In certain devices that don't support UUID lists, there are multiple @@ -2766,53 +2723,42 @@ static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev, * to determine which is returning the correct log page data. */ uuid_index = 1; - found = get_dev_mgmt_log_page_lid_data(dev, cbs_data, lid, log_id, uuid_index); + found = get_dev_mgmt_log_page_lid_data(hdl, cbs_data, lid, log_id, uuid_index); if (!found) { /* not found with uuid = 1 try with uuid = 0 */ uuid_index = 0; fprintf(stderr, "Not found, requesting log page with uuid_index %d\n", uuid_index); - found = get_dev_mgmt_log_page_lid_data(dev, cbs_data, lid, log_id, + found = get_dev_mgmt_log_page_lid_data(hdl, cbs_data, lid, log_id, uuid_index); } } else { /* Default to uuid-index 0 for cases where UUID lists are not supported */ uuid_index = 0; - found = get_dev_mgmt_log_page_lid_data(dev, cbs_data, lid, log_id, uuid_index); + found = get_dev_mgmt_log_page_lid_data(hdl, cbs_data, lid, log_id, uuid_index); } return found; } -static int wdc_get_supported_log_pages(struct nvme_dev *dev, +static int wdc_get_supported_log_pages(struct nvme_transport_handle *hdl, struct nvme_supported_log_pages *supported, int uuid_index) { - memset(supported, 0, sizeof(*supported)); - struct nvme_get_log_args args = { - .lpo = 0, - .result = NULL, - .log = supported, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = NVME_LOG_LID_SUPPORTED_LOG_PAGES, - .len = sizeof(*supported), - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = 0, - .uuidx = uuid_index, - .rae = false, - .ot = false, - }; + struct nvme_passthru_cmd cmd; - return nvme_get_log(&args); + memset(supported, 0, sizeof(*supported)); + nvme_init_get_log(&cmd, NVME_NSID_ALL, NVME_LOG_LID_SUPPORTED_LOG_PAGES, + NVME_CSI_NVM, supported, sizeof(*supported)); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_index, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + return nvme_get_log(hdl, &cmd, false, NVME_LOG_PAGE_PDU_SIZE, NULL); } -static bool wdc_nvme_check_supported_log_page(nvme_root_t r, - struct nvme_dev *dev, +static bool wdc_nvme_check_supported_log_page(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl, __u8 log_id, __u8 uuid_index) { @@ -2828,7 +2774,7 @@ static bool wdc_nvme_check_supported_log_page(nvme_root_t r, if (!supports) return -ENOMEM; - err = wdc_get_supported_log_pages(dev, + err = wdc_get_supported_log_pages(hdl, supports, uuid_index); @@ -2843,8 +2789,7 @@ static bool wdc_nvme_check_supported_log_page(nvme_root_t r, * check the WDC C2 log page */ if (!found) { - if (get_dev_mgment_cbs_data(r, - dev, + if (get_dev_mgment_cbs_data(ctx, hdl, WDC_C2_LOG_PAGES_SUPPORTED_ID, (void *)&cbs_data)) { if (cbs_data) { @@ -2894,12 +2839,12 @@ static bool wdc_nvme_parse_dev_status_log_entry(void *log_data, __u32 *ret_data, return false; } -static bool wdc_nvme_get_dev_status_log_data(nvme_root_t r, struct nvme_dev *dev, __le32 *ret_data, +static bool wdc_nvme_get_dev_status_log_data(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, __le32 *ret_data, __u8 log_id) { __u32 *cbs_data = NULL; - if (get_dev_mgment_cbs_data(r, dev, log_id, (void *)&cbs_data)) { + if (get_dev_mgment_cbs_data(ctx, hdl, log_id, (void *)&cbs_data)) { if (cbs_data) { memcpy((void *)ret_data, (void *)cbs_data, 4); free(cbs_data); @@ -2912,7 +2857,7 @@ static bool wdc_nvme_get_dev_status_log_data(nvme_root_t r, struct nvme_dev *dev return false; } -static int wdc_do_clear_dump(struct nvme_dev *dev, __u8 opcode, __u32 cdw12) +static int wdc_do_clear_dump(struct nvme_transport_handle *hdl, __u8 opcode, __u32 cdw12) { int ret; struct nvme_passthru_cmd admin_cmd; @@ -2920,14 +2865,14 @@ static int wdc_do_clear_dump(struct nvme_dev *dev, __u8 opcode, __u32 cdw12) memset(&admin_cmd, 0, sizeof(struct nvme_passthru_cmd)); admin_cmd.opcode = opcode; admin_cmd.cdw12 = cdw12; - ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (ret) fprintf(stdout, "ERROR: WDC: Crash dump erase failed\n"); nvme_show_status(ret); return ret; } -static __u32 wdc_dump_length(int fd, __u32 opcode, __u32 cdw10, __u32 cdw12, __u32 *dump_length) +static __u32 wdc_dump_length(struct nvme_transport_handle *link, __u32 opcode, __u32 cdw10, __u32 cdw12, __u32 *dump_length) { int ret; __u8 buf[WDC_NVME_LOG_SIZE_DATA_LEN] = {0}; @@ -2942,7 +2887,7 @@ static __u32 wdc_dump_length(int fd, __u32 opcode, __u32 cdw10, __u32 cdw12, __u admin_cmd.cdw10 = cdw10; admin_cmd.cdw12 = cdw12; - ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(link, &admin_cmd, NULL); if (ret) { l->log_size = 0; ret = -1; @@ -2958,7 +2903,7 @@ static __u32 wdc_dump_length(int fd, __u32 opcode, __u32 cdw10, __u32 cdw12, __u return ret; } -static __u32 wdc_dump_length_e6(int fd, __u32 opcode, __u32 cdw10, __u32 cdw12, struct wdc_e6_log_hdr *dump_hdr) +static __u32 wdc_dump_length_e6(struct nvme_transport_handle *hdl, __u32 opcode, __u32 cdw10, __u32 cdw12, struct wdc_e6_log_hdr *dump_hdr) { int ret; struct nvme_passthru_cmd admin_cmd; @@ -2970,7 +2915,7 @@ static __u32 wdc_dump_length_e6(int fd, __u32 opcode, __u32 cdw10, __u32 cdw12, admin_cmd.cdw10 = cdw10; admin_cmd.cdw12 = cdw12; - ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (ret) { fprintf(stderr, "ERROR: WDC: reading dump length failed\n"); nvme_show_status(ret); @@ -2979,7 +2924,7 @@ static __u32 wdc_dump_length_e6(int fd, __u32 opcode, __u32 cdw10, __u32 cdw12, return ret; } -static __u32 wdc_dump_dui_data(int fd, __u32 dataLen, __u32 offset, __u8 *dump_data, bool last_xfer) +static __u32 wdc_dump_dui_data(struct nvme_transport_handle *hdl, __u32 dataLen, __u32 offset, __u8 *dump_data, bool last_xfer) { int ret; struct nvme_passthru_cmd admin_cmd; @@ -2997,7 +2942,7 @@ static __u32 wdc_dump_dui_data(int fd, __u32 dataLen, __u32 offset, __u8 *dump_d admin_cmd.cdw14 = WDC_NVME_CAP_DUI_DISABLE_IO; - ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (ret) { fprintf(stderr, "ERROR: WDC: reading DUI data failed\n"); nvme_show_status(ret); @@ -3006,7 +2951,7 @@ static __u32 wdc_dump_dui_data(int fd, __u32 dataLen, __u32 offset, __u8 *dump_d return ret; } -static __u32 wdc_dump_dui_data_v2(int fd, __u32 dataLen, __u64 offset, __u8 *dump_data, bool last_xfer) +static __u32 wdc_dump_dui_data_v2(struct nvme_transport_handle *hdl, __u32 dataLen, __u64 offset, __u8 *dump_data, bool last_xfer) { int ret; struct nvme_passthru_cmd admin_cmd; @@ -3028,7 +2973,7 @@ static __u32 wdc_dump_dui_data_v2(int fd, __u32 dataLen, __u64 offset, __u8 *dum else admin_cmd.cdw14 = WDC_NVME_CAP_DUI_DISABLE_IO; - ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (ret) { fprintf(stderr, "ERROR: WDC: reading DUI data V2 failed\n"); nvme_show_status(ret); @@ -3037,7 +2982,7 @@ static __u32 wdc_dump_dui_data_v2(int fd, __u32 dataLen, __u64 offset, __u8 *dum return ret; } -static int wdc_do_dump(struct nvme_dev *dev, __u32 opcode, __u32 data_len, +static int wdc_do_dump(struct nvme_transport_handle *hdl, __u32 opcode, __u32 data_len, __u32 cdw12, const char *file, __u32 xfer_size) { int ret = 0; @@ -3066,7 +3011,7 @@ static int wdc_do_dump(struct nvme_dev *dev, __u32 opcode, __u32 data_len, admin_cmd.cdw13 = curr_data_offset; while (curr_data_offset < data_len) { - ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (ret) { nvme_show_status(ret); @@ -3096,7 +3041,7 @@ static int wdc_do_dump(struct nvme_dev *dev, __u32 opcode, __u32 data_len, return ret; } -static int wdc_do_dump_e6(int fd, __u32 opcode, __u32 data_len, +static int wdc_do_dump_e6(struct nvme_transport_handle *hdl, __u32 opcode, __u32 data_len, __u32 cdw12, char *file, __u32 xfer_size, __u8 *log_hdr) { int ret = 0; @@ -3142,7 +3087,7 @@ static int wdc_do_dump_e6(int fd, __u32 opcode, __u32 data_len, admin_cmd.cdw10 = xfer_size >> 2; admin_cmd.cdw13 = curr_data_offset >> 2; - ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (ret) { nvme_show_status(ret); fprintf(stderr, "%s: ERROR: WDC: Get chunk %d, size = 0x%x, offset = 0x%x, addr = 0x%lx\n", @@ -3171,8 +3116,9 @@ static int wdc_do_dump_e6(int fd, __u32 opcode, __u32 data_len, return ret; } -static int wdc_do_cap_telemetry_log(struct nvme_dev *dev, const char *file, - __u32 bs, int type, int data_area) +static int wdc_do_cap_telemetry_log(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl, const char *file, + __u32 bs, int type, int data_area) { struct nvme_telemetry_log *log; size_t full_size = 0; @@ -3185,10 +3131,9 @@ static int wdc_do_cap_telemetry_log(struct nvme_dev *dev, const char *file, int data_written = 0, data_remaining = 0; struct nvme_id_ctrl ctrl; __u64 capabilities = 0; - nvme_root_t r; memset(&ctrl, 0, sizeof(struct nvme_id_ctrl)); - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) { fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", err); return err; @@ -3199,8 +3144,13 @@ static int wdc_do_cap_telemetry_log(struct nvme_dev *dev, const char *file, return -EINVAL; } - r = nvme_scan(NULL); - capabilities = wdc_get_drive_capabilities(r, dev); + err = nvme_scan_topology(ctx, NULL, NULL); + if (err) { + fprintf(stderr, "Failed to scan nvme subsystems\n"); + return err; + } + + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (type == WDC_TELEMETRY_TYPE_HOST) { host_gen = 1; @@ -3208,9 +3158,10 @@ static int wdc_do_cap_telemetry_log(struct nvme_dev *dev, const char *file, } else if (type == WDC_TELEMETRY_TYPE_CONTROLLER) { if ((capabilities & WDC_DRIVE_CAP_INTERNAL_LOG) == WDC_DRIVE_CAP_INTERNAL_LOG) { /* Verify the Controller Initiated Option is enabled */ - err = nvme_get_features_data(dev_fd(dev), - WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, - 0, 4, buf, &result); + err = nvme_get_features(hdl, 0, + WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, + NVME_GET_FEATURES_SEL_CURRENT, 0, 0, + buf, 4, &result); if (!err) { if (!result) { /* enabled */ @@ -3247,13 +3198,13 @@ static int wdc_do_cap_telemetry_log(struct nvme_dev *dev, const char *file, } if (ctrl_init) - err = nvme_get_ctrl_telemetry(dev_fd(dev), true, &log, + err = nvme_get_ctrl_telemetry(hdl, true, &log, data_area, &full_size); else if (host_gen) - err = nvme_get_new_host_telemetry(dev_fd(dev), &log, + err = nvme_get_new_host_telemetry(hdl, &log, data_area, &full_size); else - err = nvme_get_host_telemetry(dev_fd(dev), &log, data_area, + err = nvme_get_host_telemetry(hdl, &log, data_area, &full_size); if (err < 0) { @@ -3301,7 +3252,7 @@ static int wdc_do_cap_telemetry_log(struct nvme_dev *dev, const char *file, return err; } -static int wdc_do_cap_diag(nvme_root_t r, struct nvme_dev *dev, char *file, +static int wdc_do_cap_diag(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, char *file, __u32 xfer_size, int type, int data_area) { int ret = -1; @@ -3318,7 +3269,7 @@ static int wdc_do_cap_diag(nvme_root_t r, struct nvme_dev *dev, char *file, memset(log_hdr, 0, e6_log_hdr_size); if (type == WDC_TELEMETRY_TYPE_NONE) { - ret = wdc_dump_length_e6(dev_fd(dev), + ret = wdc_dump_length_e6(hdl, WDC_NVME_CAP_DIAG_OPCODE, WDC_NVME_CAP_DIAG_HEADER_TOC_SIZE>>2, 0x00, @@ -3334,7 +3285,7 @@ static int wdc_do_cap_diag(nvme_root_t r, struct nvme_dev *dev, char *file, if (!cap_diag_length) { fprintf(stderr, "INFO: WDC: Capture Diagnostics log is empty\n"); } else { - ret = wdc_do_dump_e6(dev_fd(dev), + ret = wdc_do_dump_e6(hdl, WDC_NVME_CAP_DIAG_OPCODE, cap_diag_length, (WDC_NVME_CAP_DIAG_SUBCMD << WDC_NVME_SUBCMD_SHIFT) | WDC_NVME_CAP_DIAG_CMD, @@ -3345,7 +3296,8 @@ static int wdc_do_cap_diag(nvme_root_t r, struct nvme_dev *dev, char *file, } else if ((type == WDC_TELEMETRY_TYPE_HOST) || (type == WDC_TELEMETRY_TYPE_CONTROLLER)) { /* Get the desired telemetry log page */ - ret = wdc_do_cap_telemetry_log(dev, file, xfer_size, type, data_area); + ret = wdc_do_cap_telemetry_log(ctx, hdl, file, xfer_size, + type, data_area); } else { fprintf(stderr, "%s: ERROR: Invalid type : %d\n", __func__, type); } @@ -3355,7 +3307,7 @@ static int wdc_do_cap_diag(nvme_root_t r, struct nvme_dev *dev, char *file, return ret; } -static int wdc_do_cap_dui_v1(int fd, char *file, __u32 xfer_size, int data_area, int verbose, +static int wdc_do_cap_dui_v1(struct nvme_transport_handle *hdl, char *file, __u32 xfer_size, int data_area, int verbose, struct wdc_dui_log_hdr *log_hdr, __s64 *total_size) { __s32 log_size = 0; @@ -3435,7 +3387,7 @@ static int wdc_do_cap_dui_v1(int fd, char *file, __u32 xfer_size, int data_area, if (log_size <= xfer_size) last_xfer = true; - ret = wdc_dump_dui_data(fd, xfer_size, curr_data_offset, buffer_addr, last_xfer); + ret = wdc_dump_dui_data(hdl, xfer_size, curr_data_offset, buffer_addr, last_xfer); if (ret) { fprintf(stderr, "%s: ERROR: WDC: Get chunk %d, size = 0x%"PRIx64", offset = 0x%x, addr = %p\n", @@ -3465,7 +3417,7 @@ static int wdc_do_cap_dui_v1(int fd, char *file, __u32 xfer_size, int data_area, return ret; } -static int wdc_do_cap_dui_v2_v3(int fd, char *file, __u32 xfer_size, int data_area, int verbose, +static int wdc_do_cap_dui_v2_v3(struct nvme_transport_handle *hdl, char *file, __u32 xfer_size, int data_area, int verbose, struct wdc_dui_log_hdr *log_hdr, __s64 *total_size, __u64 file_size, __u64 offset) { @@ -3578,7 +3530,7 @@ static int wdc_do_cap_dui_v2_v3(int fd, char *file, __u32 xfer_size, int data_ar if (log_size <= xfer_size_long) last_xfer = true; - ret = wdc_dump_dui_data_v2(fd, (__u32)xfer_size_long, curr_data_offset, buffer_addr, + ret = wdc_dump_dui_data_v2(hdl, (__u32)xfer_size_long, curr_data_offset, buffer_addr, last_xfer); if (ret) { fprintf(stderr, @@ -3610,7 +3562,7 @@ static int wdc_do_cap_dui_v2_v3(int fd, char *file, __u32 xfer_size, int data_ar return ret; } -static int wdc_do_cap_dui_v4(int fd, char *file, __u32 xfer_size, int data_area, int verbose, +static int wdc_do_cap_dui_v4(struct nvme_transport_handle *hdl, char *file, __u32 xfer_size, int data_area, int verbose, struct wdc_dui_log_hdr *log_hdr, __s64 *total_size, __u64 file_size, __u64 offset) { @@ -3719,7 +3671,7 @@ static int wdc_do_cap_dui_v4(int fd, char *file, __u32 xfer_size, int data_area, if (log_size <= xfer_size_long) last_xfer = true; - ret = wdc_dump_dui_data_v2(fd, (__u32)xfer_size_long, curr_data_offset, buffer_addr, last_xfer); + ret = wdc_dump_dui_data_v2(hdl, (__u32)xfer_size_long, curr_data_offset, buffer_addr, last_xfer); if (ret) { fprintf(stderr, "%s: ERROR: WDC: Get chunk %d, size = 0x%"PRIx64", offset = 0x%"PRIx64", addr = %p\n", @@ -3750,7 +3702,7 @@ static int wdc_do_cap_dui_v4(int fd, char *file, __u32 xfer_size, int data_area, return ret; } -static int wdc_do_cap_dui(int fd, char *file, __u32 xfer_size, int data_area, int verbose, +static int wdc_do_cap_dui(struct nvme_transport_handle *hdl, char *file, __u32 xfer_size, int data_area, int verbose, __u64 file_size, __u64 offset) { int ret = 0; @@ -3768,7 +3720,7 @@ static int wdc_do_cap_dui(int fd, char *file, __u32 xfer_size, int data_area, in memset(log_hdr, 0, dui_log_hdr_size); /* get the dui telemetry and log headers */ - ret = wdc_dump_dui_data(fd, WDC_NVME_CAP_DUI_HEADER_SIZE, 0x00, (__u8 *)log_hdr, last_xfer); + ret = wdc_dump_dui_data(hdl, WDC_NVME_CAP_DUI_HEADER_SIZE, 0x00, (__u8 *)log_hdr, last_xfer); if (ret) { fprintf(stderr, "%s: ERROR: WDC: Get DUI headers failed\n", __func__); fprintf(stderr, "%s: ERROR: WDC: ", __func__); @@ -3778,19 +3730,19 @@ static int wdc_do_cap_dui(int fd, char *file, __u32 xfer_size, int data_area, in /* Check the Log Header version */ if ((log_hdr->hdr_version & 0xFF) == 0x00 || (log_hdr->hdr_version & 0xFF) == 0x01) { - ret = wdc_do_cap_dui_v1(fd, file, xfer_size, data_area, verbose, log_hdr, + ret = wdc_do_cap_dui_v1(hdl, file, xfer_size, data_area, verbose, log_hdr, &total_size); if (ret) goto out; } else if ((log_hdr->hdr_version & 0xFF) == 0x02 || (log_hdr->hdr_version & 0xFF) == 0x03) { /* Process Version 2 or 3 header */ - ret = wdc_do_cap_dui_v2_v3(fd, file, xfer_size, data_area, verbose, log_hdr, + ret = wdc_do_cap_dui_v2_v3(hdl, file, xfer_size, data_area, verbose, log_hdr, &total_size, file_size, offset); if (ret) goto out; } else if ((log_hdr->hdr_version & 0xFF) == 0x04) { - ret = wdc_do_cap_dui_v4(fd, file, xfer_size, data_area, verbose, log_hdr, + ret = wdc_do_cap_dui_v4(hdl, file, xfer_size, data_area, verbose, log_hdr, &total_size, file_size, offset); if (ret) goto out; @@ -3810,16 +3762,16 @@ static int wdc_do_cap_dui(int fd, char *file, __u32 xfer_size, int data_area, in return ret; } -static int wdc_cap_diag(int argc, char **argv, struct command *command, +static int wdc_cap_diag(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; const char *desc = "Capture Diagnostics Log."; const char *file = "Output file pathname."; const char *size = "Data retrieval transfer size."; __u64 capabilities = 0; char f[PATH_MAX] = {0}; - struct nvme_dev *dev; __u32 xfer_size = 0; int ret = 0; @@ -3839,42 +3791,40 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret) + return ret; if (cfg.file) strncpy(f, cfg.file, PATH_MAX - 1); if (cfg.xfer_size) xfer_size = cfg.xfer_size; - ret = wdc_get_serial_name(dev, f, PATH_MAX, "cap_diag"); + ret = wdc_get_serial_name(hdl, f, PATH_MAX, "cap_diag"); if (ret) { fprintf(stderr, "ERROR: WDC: failed to generate file name\n"); - goto out; + return ret; } if (!cfg.file) { if (strlen(f) > PATH_MAX - 5) { fprintf(stderr, "ERROR: WDC: file name overflow\n"); - ret = -1; - goto out; + return -1; } strcat(f, ".bin"); } - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if ((capabilities & WDC_DRIVE_CAP_CAP_DIAG) == WDC_DRIVE_CAP_CAP_DIAG) - ret = wdc_do_cap_diag(r, dev, f, xfer_size, 0, 0); + ret = wdc_do_cap_diag(ctx, hdl, f, xfer_size, 0, 0); else fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); -out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_do_get_sn730_log_len(int fd, uint32_t *len_buf, uint32_t subopcode) +static int wdc_do_get_sn730_log_len(struct nvme_transport_handle *hdl, uint32_t *len_buf, uint32_t subopcode) { int ret; uint32_t *output = NULL; @@ -3894,14 +3844,14 @@ static int wdc_do_get_sn730_log_len(int fd, uint32_t *len_buf, uint32_t subopcod admin_cmd.cdw12 = subopcode; admin_cmd.cdw10 = SN730_LOG_CHUNK_SIZE / 4; - ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (!ret) *len_buf = *output; free(output); return ret; } -static int wdc_do_get_sn730_log(int fd, void *log_buf, uint32_t offset, uint32_t subopcode) +static int wdc_do_get_sn730_log(struct nvme_transport_handle *hdl, void *log_buf, uint32_t offset, uint32_t subopcode) { int ret; uint8_t *output = NULL; @@ -3920,13 +3870,13 @@ static int wdc_do_get_sn730_log(int fd, void *log_buf, uint32_t offset, uint32_t admin_cmd.cdw13 = offset; admin_cmd.cdw10 = SN730_LOG_CHUNK_SIZE / 4; - ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (!ret) memcpy(log_buf, output, SN730_LOG_CHUNK_SIZE); return ret; } -static int get_sn730_log_chunks(int fd, uint8_t *log_buf, uint32_t log_len, uint32_t subopcode) +static int get_sn730_log_chunks(struct nvme_transport_handle *hdl, uint8_t *log_buf, uint32_t log_len, uint32_t subopcode) { int ret = 0; uint8_t *chunk_buf = NULL; @@ -3942,7 +3892,7 @@ static int get_sn730_log_chunks(int fd, uint8_t *log_buf, uint32_t log_len, uint while (remaining > 0) { memset(chunk_buf, 0, SN730_LOG_CHUNK_SIZE); - ret = wdc_do_get_sn730_log(fd, chunk_buf, curr_offset, subopcode); + ret = wdc_do_get_sn730_log(hdl, chunk_buf, curr_offset, subopcode); if (!ret) { if (remaining >= SN730_LOG_CHUNK_SIZE) { memcpy(log_buf + (curr_offset * SN730_LOG_CHUNK_SIZE), @@ -3962,7 +3912,7 @@ static int get_sn730_log_chunks(int fd, uint8_t *log_buf, uint32_t log_len, uint return ret; } -static int wdc_do_sn730_get_and_tar(int fd, char *outputName) +static int wdc_do_sn730_get_and_tar(struct nvme_transport_handle *hdl, char *outputName) { int ret = 0; void *retPtr; @@ -4011,22 +3961,22 @@ static int wdc_do_sn730_get_and_tar(int fd, char *outputName) fprintf(stderr, "Stored log files in directory: %s\n", tarInfo->bufferFolderPath); } - ret = wdc_do_get_sn730_log_len(fd, &full_log_len, SN730_GET_FULL_LOG_LENGTH); + ret = wdc_do_get_sn730_log_len(hdl, &full_log_len, SN730_GET_FULL_LOG_LENGTH); if (ret) { nvme_show_status(ret); goto free_buf; } - ret = wdc_do_get_sn730_log_len(fd, &key_log_len, SN730_GET_KEY_LOG_LENGTH); + ret = wdc_do_get_sn730_log_len(hdl, &key_log_len, SN730_GET_KEY_LOG_LENGTH); if (ret) { nvme_show_status(ret); goto free_buf; } - ret = wdc_do_get_sn730_log_len(fd, &core_dump_log_len, SN730_GET_COREDUMP_LOG_LENGTH); + ret = wdc_do_get_sn730_log_len(hdl, &core_dump_log_len, SN730_GET_COREDUMP_LOG_LENGTH); if (ret) { nvme_show_status(ret); goto free_buf; } - ret = wdc_do_get_sn730_log_len(fd, &extended_log_len, SN730_GET_EXTENDED_LOG_LENGTH); + ret = wdc_do_get_sn730_log_len(hdl, &extended_log_len, SN730_GET_EXTENDED_LOG_LENGTH); if (ret) { nvme_show_status(ret); goto free_buf; @@ -4044,28 +3994,28 @@ static int wdc_do_sn730_get_and_tar(int fd, char *outputName) } /* Get the full log */ - ret = get_sn730_log_chunks(fd, full_log_buf, full_log_len, SN730_GET_FULL_LOG_SUBOPCODE); + ret = get_sn730_log_chunks(hdl, full_log_buf, full_log_len, SN730_GET_FULL_LOG_SUBOPCODE); if (ret) { nvme_show_status(ret); goto free_buf; } /* Get the key log */ - ret = get_sn730_log_chunks(fd, key_log_buf, key_log_len, SN730_GET_KEY_LOG_SUBOPCODE); + ret = get_sn730_log_chunks(hdl, key_log_buf, key_log_len, SN730_GET_KEY_LOG_SUBOPCODE); if (ret) { nvme_show_status(ret); goto free_buf; } /* Get the core dump log */ - ret = get_sn730_log_chunks(fd, core_dump_log_buf, core_dump_log_len, SN730_GET_CORE_LOG_SUBOPCODE); + ret = get_sn730_log_chunks(hdl, core_dump_log_buf, core_dump_log_len, SN730_GET_CORE_LOG_SUBOPCODE); if (ret) { nvme_show_status(ret); goto free_buf; } /* Get the extended log */ - ret = get_sn730_log_chunks(fd, extended_log_buf, extended_log_len, SN730_GET_EXTEND_LOG_SUBOPCODE); + ret = get_sn730_log_chunks(hdl, extended_log_buf, extended_log_len, SN730_GET_EXTEND_LOG_SUBOPCODE); if (ret) { nvme_show_status(ret); goto free_buf; @@ -4107,12 +4057,13 @@ static int wdc_do_sn730_get_and_tar(int fd, char *outputName) return ret; } -static int dump_internal_logs(struct nvme_dev *dev, const char *dir_name, int verbose) +static int dump_internal_logs(struct nvme_transport_handle *hdl, const char *dir_name, int verbose) { char file_path[PATH_MAX]; void *telemetry_log; const size_t bs = 512; struct nvme_telemetry_log *hdr; + struct nvme_passthru_cmd cmd; size_t full_size, offset = bs; int err, output; @@ -4136,25 +4087,12 @@ static int dump_internal_logs(struct nvme_dev *dev, const char *dir_name, int ve goto free_mem; } - struct nvme_get_log_args args = { - .lpo = 0, - .result = NULL, - .log = hdr, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = NVME_LOG_LID_TELEMETRY_HOST, - .len = bs, - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = NVME_LOG_TELEM_HOST_LSP_CREATE, - .uuidx = NVME_UUID_NONE, - .rae = true, - .ot = false, - }; - - err = nvme_get_log(&args); + nvme_init_get_log(&cmd, NVME_NSID_ALL, NVME_LOG_LID_TELEMETRY_HOST, + NVME_CSI_NVM, hdr, bs); + cmd.cdw10 |= NVME_FIELD_ENCODE(NVME_LOG_TELEM_HOST_LSP_CREATE, + NVME_LOG_CDW10_LSP_SHIFT, + NVME_LOG_CDW10_LSP_MASK); + err = nvme_get_log(hdl, &cmd, true, NVME_LOG_PAGE_PDU_SIZE, NULL); if (err < 0) perror("get-telemetry-log"); else if (err > 0) { @@ -4172,10 +4110,10 @@ static int dump_internal_logs(struct nvme_dev *dev, const char *dir_name, int ve full_size = (le16_to_cpu(hdr->dalb3) * bs) + offset; while (offset != full_size) { - args.log = telemetry_log; - args.lpo = offset; - args.lsp = NVME_LOG_LSP_NONE; - err = nvme_get_log(&args); + nvme_init_get_log(&cmd, NVME_NSID_ALL, NVME_LOG_LID_TELEMETRY_HOST, + NVME_CSI_NVM, telemetry_log, bs); + nvme_init_get_log_lpo(&cmd, offset); + err = nvme_get_log(hdl, &cmd, true, NVME_LOG_PAGE_PDU_SIZE, NULL); if (err < 0) { perror("get-telemetry-log"); break; @@ -4203,7 +4141,7 @@ static int dump_internal_logs(struct nvme_dev *dev, const char *dir_name, int ve return err; } -static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command, +static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Internal Firmware Log."; @@ -4220,8 +4158,8 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command char f[PATH_MAX] = {0}; char fb[PATH_MAX/2] = {0}; char fileSuffix[PATH_MAX] = {0}; - struct nvme_dev *dev; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 xfer_size = 0; int telemetry_type = 0, telemetry_data_area = 0; UtilsTimeInfo timeInfo; @@ -4263,12 +4201,12 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); - if (!wdc_check_device(r, dev)) + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !wdc_check_device(ctx, hdl)) goto out; if (cfg.xfer_size) { @@ -4278,7 +4216,7 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command goto out; } - ret = wdc_get_pci_ids(r, dev, &device_id, &read_vendor_id); + ret = wdc_get_pci_ids(ctx, hdl, &device_id, &read_vendor_id); if (!wdc_is_sn861(device_id)) { if (cfg.file) { @@ -4302,7 +4240,7 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command timeInfo.second); snprintf(fileSuffix, PATH_MAX, "_internal_fw_log_%s", (char *)timeStamp); - ret = wdc_get_serial_name(dev, f, PATH_MAX, fileSuffix); + ret = wdc_get_serial_name(hdl, f, PATH_MAX, fileSuffix); if (ret) { fprintf(stderr, "ERROR: WDC: failed to generate file name\n"); goto out; @@ -4355,7 +4293,7 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command timeInfo.second); snprintf(fileSuffix, PATH_MAX, "_internal_fw_log_%s", (char *)timeStamp); - ret = wdc_get_serial_name(dev, fb, PATH_MAX/2 - 7, fileSuffix); + ret = wdc_get_serial_name(hdl, fb, PATH_MAX/2 - 7, fileSuffix); if (ret) { fprintf(stderr, "ERROR: WDC: failed to generate file name\n"); goto out; @@ -4383,14 +4321,14 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command } } - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if ((capabilities & WDC_DRIVE_CAP_INTERNAL_LOG) == WDC_DRIVE_CAP_INTERNAL_LOG) { if (!wdc_is_sn861(device_id)) { /* Set the default DA to 3 if not specified */ if (!telemetry_data_area) telemetry_data_area = 3; - ret = wdc_do_cap_diag(r, dev, f, xfer_size, + ret = wdc_do_cap_diag(ctx, hdl, f, xfer_size, telemetry_type, telemetry_data_area); } else { if (cfg.verbose) @@ -4402,7 +4340,7 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command goto out; } - ret = dump_internal_logs(dev, fb, cfg.verbose); + ret = dump_internal_logs(hdl, fb, cfg.verbose); if (ret < 0) perror("vs-internal-log"); @@ -4429,7 +4367,7 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command if (!telemetry_data_area) telemetry_data_area = 3; /* Set the default DA to 3 if not specified */ /* Get the desired telemetry log page */ - ret = wdc_do_cap_telemetry_log(dev, f, xfer_size, + ret = wdc_do_cap_telemetry_log(ctx, hdl, f, xfer_size, telemetry_type, telemetry_data_area); goto out; } else { @@ -4439,7 +4377,7 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command /* FW requirement - xfer size must be 256k for data area 4 */ if (cfg.data_area >= 4) xfer_size = 0x40000; - ret = wdc_do_cap_dui(dev_fd(dev), f, xfer_size, + ret = wdc_do_cap_dui(hdl, f, xfer_size, cfg.data_area, cfg.verbose, cfg.file_size, cfg.offset); @@ -4452,29 +4390,27 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command if (!telemetry_data_area) telemetry_data_area = 3; /* Set the default DA to 3 if not specified */ /* Get the desired telemetry log page */ - ret = wdc_do_cap_telemetry_log(dev, f, xfer_size, + ret = wdc_do_cap_telemetry_log(ctx, hdl, f, xfer_size, telemetry_type, telemetry_data_area); goto out; } else { - ret = wdc_do_cap_dui(dev_fd(dev), f, xfer_size, + ret = wdc_do_cap_dui(hdl, f, xfer_size, WDC_NVME_DUI_MAX_DATA_AREA, cfg.verbose, 0, 0); goto out; } } if ((capabilities & WDC_SN730B_CAP_VUC_LOG) == WDC_SN730B_CAP_VUC_LOG) { - ret = wdc_do_sn730_get_and_tar(dev_fd(dev), f); + ret = wdc_do_sn730_get_and_tar(hdl, f); } else { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; } out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_do_crash_dump(struct nvme_dev *dev, char *file, int type) +static int wdc_do_crash_dump(struct nvme_transport_handle *hdl, char *file, int type) { int ret; __u32 crash_dump_length; @@ -4511,7 +4447,7 @@ static int wdc_do_crash_dump(struct nvme_dev *dev, char *file, int type) WDC_NVME_CLEAR_CRASH_DUMP_CMD); } - ret = wdc_dump_length(dev_fd(dev), + ret = wdc_dump_length(hdl, opcode, cdw10_size, cdw12_size, @@ -4532,7 +4468,7 @@ static int wdc_do_crash_dump(struct nvme_dev *dev, char *file, int type) else fprintf(stderr, "INFO: WDC: Crash dump is empty\n"); } else { - ret = wdc_do_dump(dev, + ret = wdc_do_dump(hdl, opcode, crash_dump_length, cdw12, @@ -4540,13 +4476,13 @@ static int wdc_do_crash_dump(struct nvme_dev *dev, char *file, int type) crash_dump_length); if (!ret) - ret = wdc_do_clear_dump(dev, WDC_NVME_CLEAR_DUMP_OPCODE, + ret = wdc_do_clear_dump(hdl, WDC_NVME_CLEAR_DUMP_OPCODE, cdw12_clear); } return ret; } -static int wdc_crash_dump(struct nvme_dev *dev, const char *file, int type) +static int wdc_crash_dump(struct nvme_transport_handle *hdl, const char *file, int type) { char f[PATH_MAX] = {0}; const char *dump_type; @@ -4560,22 +4496,22 @@ static int wdc_crash_dump(struct nvme_dev *dev, const char *file, int type) else dump_type = "_crash_dump"; - ret = wdc_get_serial_name(dev, f, PATH_MAX, dump_type); + ret = wdc_get_serial_name(hdl, f, PATH_MAX, dump_type); if (ret) fprintf(stderr, "ERROR: WDC: failed to generate file name\n"); else - ret = wdc_do_crash_dump(dev, f, type); + ret = wdc_do_crash_dump(hdl, f, type); return ret; } -static int wdc_do_drive_log(struct nvme_dev *dev, const char *file) +static int wdc_do_drive_log(struct nvme_transport_handle *hdl, const char *file) { int ret; __u8 *drive_log_data; __u32 drive_log_length; struct nvme_passthru_cmd admin_cmd; - ret = wdc_dump_length(dev_fd(dev), WDC_NVME_DRIVE_LOG_SIZE_OPCODE, + ret = wdc_dump_length(hdl, WDC_NVME_DRIVE_LOG_SIZE_OPCODE, WDC_NVME_DRIVE_LOG_SIZE_NDT, (WDC_NVME_DRIVE_LOG_SIZE_SUBCMD << WDC_NVME_SUBCMD_SHIFT | WDC_NVME_DRIVE_LOG_SIZE_CMD), @@ -4598,7 +4534,7 @@ static int wdc_do_drive_log(struct nvme_dev *dev, const char *file) admin_cmd.cdw12 = ((WDC_NVME_DRIVE_LOG_SUBCMD << WDC_NVME_SUBCMD_SHIFT) | WDC_NVME_DRIVE_LOG_SIZE_CMD); - ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); nvme_show_status(ret); if (!ret) ret = wdc_create_log_file(file, drive_log_data, drive_log_length); @@ -4606,15 +4542,15 @@ static int wdc_do_drive_log(struct nvme_dev *dev, const char *file) return ret; } -static int wdc_drive_log(int argc, char **argv, struct command *command, +static int wdc_drive_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Capture Drive Log."; const char *file = "Output file pathname."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; char f[PATH_MAX] = {0}; - struct nvme_dev *dev; int ret; - nvme_root_t r; __u64 capabilities = 0; struct config { char *file; @@ -4629,18 +4565,15 @@ static int wdc_drive_log(int argc, char **argv, struct command *command, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); - - if (!wdc_check_device(r, dev)) { - nvme_free_tree(r); - dev_close(dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !wdc_check_device(ctx, hdl)) return -1; - } - capabilities = wdc_get_drive_capabilities(r, dev); + + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_DRIVE_LOG)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); @@ -4648,25 +4581,23 @@ static int wdc_drive_log(int argc, char **argv, struct command *command, } else { if (cfg.file) strncpy(f, cfg.file, PATH_MAX - 1); - ret = wdc_get_serial_name(dev, f, PATH_MAX, "drive_log"); + ret = wdc_get_serial_name(hdl, f, PATH_MAX, "drive_log"); if (ret) fprintf(stderr, "ERROR: WDC: failed to generate file name\n"); else - ret = wdc_do_drive_log(dev, f); + ret = wdc_do_drive_log(hdl, f); } - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_get_crash_dump(int argc, char **argv, struct command *command, +static int wdc_get_crash_dump(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Crash Dump."; const char *file = "Output file pathname."; __u64 capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret; struct config { @@ -4682,45 +4613,38 @@ static int wdc_get_crash_dump(int argc, char **argv, struct command *command, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); - - if (!wdc_check_device(r, dev)) { - nvme_free_tree(r); - dev_close(dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !wdc_check_device(ctx, hdl)) return -1; - } - - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_CRASH_DUMP)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; } else { - ret = wdc_crash_dump(dev, cfg.file, WDC_NVME_CRASH_DUMP_TYPE); + ret = wdc_crash_dump(hdl, cfg.file, WDC_NVME_CRASH_DUMP_TYPE); if (ret) fprintf(stderr, "ERROR: WDC: failed to read crash dump\n"); } - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_get_pfail_dump(int argc, char **argv, struct command *command, +static int wdc_get_pfail_dump(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Pfail Crash Dump."; const char *file = "Output file pathname."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u64 capabilities = 0; - struct nvme_dev *dev; struct config { char *file; }; - nvme_root_t r; int ret; struct config cfg = { @@ -4732,29 +4656,23 @@ static int wdc_get_pfail_dump(int argc, char **argv, struct command *command, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); - - if (!wdc_check_device(r, dev)) { - nvme_free_tree(r); - dev_close(dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !wdc_check_device(ctx, hdl)) return -1; - } - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_PFAIL_DUMP)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; } else { - ret = wdc_crash_dump(dev, cfg.file, WDC_NVME_PFAIL_DUMP_TYPE); + ret = wdc_crash_dump(hdl, cfg.file, WDC_NVME_PFAIL_DUMP_TYPE); if (ret) fprintf(stderr, "ERROR: WDC: failed to read pfail crash dump\n"); } - nvme_free_tree(r); - dev_close(dev); return ret; } @@ -4771,9 +4689,9 @@ static void wdc_do_id_ctrl(__u8 *vs, struct json_object *root) printf("wdc vsn: %s\n", strlen(vsn) > 1 ? vsn : "NULL"); } -static int wdc_id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int wdc_id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - return __id_ctrl(argc, argv, cmd, plugin, wdc_do_id_ctrl); + return __id_ctrl(argc, argv, acmd, plugin, wdc_do_id_ctrl); } static const char *wdc_purge_mon_status_to_string(__u32 status) @@ -4808,30 +4726,26 @@ static int wdc_purge(int argc, char **argv, struct command *command, struct plugin *plugin) { const char *desc = "Send a Purge command."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct nvme_passthru_cmd admin_cmd; __u64 capabilities = 0; - struct nvme_dev *dev; char *err_str; - nvme_root_t r; int ret; OPT_ARGS(opts) = { OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); - - if (!wdc_check_device(r, dev)) { - nvme_free_tree(r); - dev_close(dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !wdc_check_device(ctx, hdl)) return -1; - } - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_PURGE)) { ret = -1; fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); @@ -4840,7 +4754,7 @@ static int wdc_purge(int argc, char **argv, memset(&admin_cmd, 0, sizeof(admin_cmd)); admin_cmd.opcode = WDC_NVME_PURGE_CMD_OPCODE; - ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (ret > 0) { switch (ret) { @@ -4858,8 +4772,6 @@ static int wdc_purge(int argc, char **argv, fprintf(stderr, "%s", err_str); nvme_show_status(ret); } - nvme_free_tree(r); - dev_close(dev); return ret; } @@ -4868,30 +4780,27 @@ static int wdc_purge_monitor(int argc, char **argv, { const char *desc = "Send a Purge Monitor command."; __u8 output[WDC_NVME_PURGE_MONITOR_DATA_LEN]; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; double progress_percent; struct nvme_passthru_cmd admin_cmd; struct wdc_nvme_purge_monitor_data *mon; - struct nvme_dev *dev; __u64 capabilities; - nvme_root_t r; int ret; OPT_ARGS(opts) = { OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); - if (!wdc_check_device(r, dev)) { - nvme_free_tree(r); - dev_close(dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !wdc_check_device(ctx, hdl)) return -1; - } - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_PURGE)) { ret = -1; fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); @@ -4904,7 +4813,7 @@ static int wdc_purge_monitor(int argc, char **argv, admin_cmd.cdw10 = WDC_NVME_PURGE_MONITOR_CMD_CDW10; admin_cmd.timeout_ms = WDC_NVME_PURGE_MONITOR_TIMEOUT; - ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (!ret) { mon = (struct wdc_nvme_purge_monitor_data *) output; @@ -4920,8 +4829,6 @@ static int wdc_purge_monitor(int argc, char **argv, nvme_show_status(ret); } - nvme_free_tree(r); - dev_close(dev); return ret; } @@ -5054,16 +4961,16 @@ static int wdc_print_log(struct wdc_ssd_perf_stats *perf, int fmt) return 0; } -static int wdc_print_latency_monitor_log_normal(struct nvme_dev *dev, +static int wdc_print_latency_monitor_log_normal(struct nvme_transport_handle *hdl, struct wdc_ssd_latency_monitor_log *log_data) { printf("Latency Monitor/C3 Log Page Data\n"); - printf(" Controller : %s\n", dev->name); + printf(" Controller : %s\n", nvme_transport_handle_get_name(hdl)); int err = -1, i, j; struct nvme_id_ctrl ctrl; char ts_buf[128]; - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (!err) { printf(" Serial Number: %-.*s\n", (int)sizeof(ctrl.sn), ctrl.sn); } else { @@ -5539,7 +5446,7 @@ static void wdc_print_fb_ca_log_json(struct wdc_ssd_ca_perf_stats *perf) json_free_object(root); } -static void wdc_print_bd_ca_log_normal(struct nvme_dev *dev, void *data) +static void wdc_print_bd_ca_log_normal(struct nvme_transport_handle *hdl, void *data) { struct wdc_bd_ca_log_format *bd_data = (struct wdc_bd_ca_log_format *)data; __u64 *raw; @@ -5558,7 +5465,7 @@ static void wdc_print_bd_ca_log_normal(struct nvme_dev *dev, void *data) switch (bd_data->field_id) { case 0x0: printf("Additional Smart Log for NVME device:%s namespace-id:%x\n", - dev->name, WDC_DE_GLOBAL_NSID); + nvme_transport_handle_get_name(hdl), WDC_DE_GLOBAL_NSID); printf("key normalized raw\n"); printf("program_fail_count : %3"PRIu8"%% %"PRIu64"\n", bd_data->normalized_value, (uint64_t)rawSwapped); @@ -6252,15 +6159,15 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, json_free_object(root); } -static int nvme_get_print_ocp_cloud_smart_log(struct nvme_dev *dev, +static int nvme_get_print_ocp_cloud_smart_log(struct nvme_transport_handle *hdl, int uuid_index, __u32 namespace_id, int fmt) { + __u32 length = WDC_NVME_SMART_CLOUD_ATTR_LEN; struct ocp_cloud_smart_log *log_ptr = NULL; + struct nvme_passthru_cmd cmd; int ret, i; - __u32 length = WDC_NVME_SMART_CLOUD_ATTR_LEN; - int fd = dev_fd(dev); log_ptr = (struct ocp_cloud_smart_log *)malloc(sizeof(__u8) * length); if (!log_ptr) { @@ -6269,31 +6176,20 @@ static int nvme_get_print_ocp_cloud_smart_log(struct nvme_dev *dev, } if (namespace_id == NVME_NSID_ALL) { - ret = nvme_get_nsid(fd, &namespace_id); + ret = nvme_get_nsid(hdl, &namespace_id); if (ret < 0) namespace_id = NVME_NSID_ALL; } /* Get the 0xC0 log data */ - struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = fd, - .lid = WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID, - .nsid = namespace_id, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = 0, - .rae = false, - .uuidx = uuid_index, - .csi = NVME_CSI_NVM, - .ot = false, - .len = length, - .log = log_ptr, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - ret = nvme_get_log(&args); - + nvme_init_get_log(&cmd, namespace_id, + WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID, NVME_CSI_NVM, + log_ptr, length); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_index, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + ret = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (fmt == JSON) nvme_show_status(ret); @@ -6319,7 +6215,7 @@ static int nvme_get_print_ocp_cloud_smart_log(struct nvme_dev *dev, if (!ret) /* parse the data */ - wdc_print_c0_cloud_attr_log(log_ptr, fmt, dev); + wdc_print_c0_cloud_attr_log(log_ptr, fmt, hdl); } else { fprintf(stderr, "ERROR: WDC: Unable to read C0 Log Page data\n"); ret = -1; @@ -6329,15 +6225,15 @@ static int nvme_get_print_ocp_cloud_smart_log(struct nvme_dev *dev, return ret; } -static int nvme_get_print_c0_eol_log(struct nvme_dev *dev, +static int nvme_get_print_c0_eol_log(struct nvme_transport_handle *hdl, int uuid_index, __u32 namespace_id, int fmt) { + __u32 length = WDC_NVME_EOL_STATUS_LOG_LEN; + struct nvme_passthru_cmd cmd; void *log_ptr = NULL; int ret; - __u32 length = WDC_NVME_EOL_STATUS_LOG_LEN; - int fd = dev_fd(dev); log_ptr = (void *)malloc(sizeof(__u8) * length); if (!log_ptr) { @@ -6346,31 +6242,20 @@ static int nvme_get_print_c0_eol_log(struct nvme_dev *dev, } if (namespace_id == NVME_NSID_ALL) { - ret = nvme_get_nsid(fd, &namespace_id); + ret = nvme_get_nsid(hdl, &namespace_id); if (ret < 0) namespace_id = NVME_NSID_ALL; } /* Get the 0xC0 log data */ - struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = fd, - .lid = WDC_NVME_GET_EOL_STATUS_LOG_OPCODE, - .nsid = namespace_id, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = 0, - .rae = false, - .uuidx = uuid_index, - .csi = NVME_CSI_NVM, - .ot = false, - .len = length, - .log = log_ptr, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - ret = nvme_get_log(&args); - + nvme_init_get_log(&cmd, namespace_id, + WDC_NVME_GET_EOL_STATUS_LOG_OPCODE, NVME_CSI_NVM, + log_ptr, length); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_index, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + ret = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (fmt == JSON) nvme_show_status(ret); @@ -6387,10 +6272,11 @@ static int nvme_get_print_c0_eol_log(struct nvme_dev *dev, return ret; } -static int nvme_get_ext_smart_cloud_log(int fd, __u8 **data, int uuid_index, __u32 namespace_id) +static int nvme_get_ext_smart_cloud_log(struct nvme_transport_handle *hdl, __u8 **data, int uuid_index, __u32 namespace_id) { - int ret, i; + struct nvme_passthru_cmd cmd; __u8 *log_ptr = NULL; + int ret, i; log_ptr = (__u8 *)malloc(sizeof(__u8) * WDC_NVME_SMART_CLOUD_ATTR_LEN); if (!log_ptr) { @@ -6399,25 +6285,14 @@ static int nvme_get_ext_smart_cloud_log(int fd, __u8 **data, int uuid_index, __u } /* Get the 0xC0 log data */ - struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = fd, - .lid = WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID, - .nsid = namespace_id, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = 0, - .rae = false, - .uuidx = uuid_index, - .csi = NVME_CSI_NVM, - .ot = false, - .len = WDC_NVME_SMART_CLOUD_ATTR_LEN, - .log = log_ptr, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - ret = nvme_get_log(&args); - + nvme_init_get_log(&cmd, namespace_id, + WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID, NVME_CSI_NVM, + log_ptr, WDC_NVME_SMART_CLOUD_ATTR_LEN); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_index, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + ret = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (!ret) { /* Verify GUID matches */ for (i = 0; i < WDC_C0_GUID_LENGTH; i++) { @@ -6445,10 +6320,11 @@ static int nvme_get_ext_smart_cloud_log(int fd, __u8 **data, int uuid_index, __u } -static int nvme_get_hw_rev_log(int fd, __u8 **data, int uuid_index, __u32 namespace_id) +static int nvme_get_hw_rev_log(struct nvme_transport_handle *hdl, __u8 **data, int uuid_index, __u32 namespace_id) { - int ret, i; struct wdc_nvme_hw_rev_log *log_ptr = NULL; + struct nvme_passthru_cmd cmd; + int ret, i; log_ptr = (struct wdc_nvme_hw_rev_log *)malloc(sizeof(__u8) * WDC_NVME_HW_REV_LOG_PAGE_LEN); if (!log_ptr) { @@ -6457,25 +6333,14 @@ static int nvme_get_hw_rev_log(int fd, __u8 **data, int uuid_index, __u32 namesp } /* Get the 0xC0 log data */ - struct nvme_get_log_args args = { - .args_size = sizeof(args), - .fd = fd, - .lid = WDC_NVME_GET_HW_REV_LOG_OPCODE, - .nsid = namespace_id, - .lpo = 0, - .lsp = NVME_LOG_LSP_NONE, - .lsi = 0, - .rae = false, - .uuidx = uuid_index, - .csi = NVME_CSI_NVM, - .ot = false, - .len = WDC_NVME_HW_REV_LOG_PAGE_LEN, - .log = log_ptr, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - ret = nvme_get_log(&args); - + nvme_init_get_log(&cmd, namespace_id, + WDC_NVME_GET_HW_REV_LOG_OPCODE, NVME_CSI_NVM, + log_ptr, WDC_NVME_HW_REV_LOG_PAGE_LEN); + cmd.cdw14 |= NVME_FIELD_ENCODE(uuid_index, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + ret = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (!ret) { /* Verify GUID matches */ for (i = 0; i < WDC_NVME_C6_GUID_LENGTH; i++) { @@ -7137,7 +7002,7 @@ static int wdc_print_ext_smart_cloud_log(void *data, int fmt) static int wdc_print_c0_cloud_attr_log(void *data, int fmt, - struct nvme_dev *dev) + struct nvme_transport_handle *hdl) { struct ocp_cloud_smart_log *log = (struct ocp_cloud_smart_log *)data; @@ -7151,7 +7016,7 @@ static int wdc_print_c0_cloud_attr_log(void *data, d_raw((unsigned char *)log, sizeof(struct ocp_cloud_smart_log)); break; case NORMAL: - wdc_show_cloud_smart_log_normal(log, dev); + wdc_show_cloud_smart_log_normal(log, hdl); break; case JSON: wdc_show_cloud_smart_log_json(log); @@ -7180,18 +7045,18 @@ static int wdc_print_c0_eol_log(void *data, int fmt) return 0; } -static int wdc_get_c0_log_page_sn_customer_id_0x100X(struct nvme_dev *dev, int uuid_index, +static int wdc_get_c0_log_page_sn_customer_id_0x100X(struct nvme_transport_handle *hdl, int uuid_index, char *format, __u32 namespace_id, int fmt) { int ret; if (!uuid_index) { - ret = nvme_get_print_ocp_cloud_smart_log(dev, + ret = nvme_get_print_ocp_cloud_smart_log(hdl, uuid_index, namespace_id, fmt); } else if (uuid_index == 1) { - ret = nvme_get_print_c0_eol_log(dev, + ret = nvme_get_print_c0_eol_log(hdl, uuid_index, namespace_id, fmt); @@ -7203,13 +7068,13 @@ static int wdc_get_c0_log_page_sn_customer_id_0x100X(struct nvme_dev *dev, int u return ret; } -static int wdc_get_c0_log_page_sn(nvme_root_t r, struct nvme_dev *dev, int uuid_index, char *format, +static int wdc_get_c0_log_page_sn(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, int uuid_index, char *format, __u32 namespace_id, int fmt) { int ret = 0; __u32 cust_id; - cust_id = wdc_get_fw_cust_id(r, dev); + cust_id = wdc_get_fw_cust_id(ctx, hdl); if (cust_id == WDC_INVALID_CUSTOMER_ID) { fprintf(stderr, "%s: ERROR: WDC: invalid customer id\n", __func__); return -1; @@ -7217,10 +7082,10 @@ static int wdc_get_c0_log_page_sn(nvme_root_t r, struct nvme_dev *dev, int uuid_ if ((cust_id == WDC_CUSTOMER_ID_0x1004) || (cust_id == WDC_CUSTOMER_ID_0x1008) || (cust_id == WDC_CUSTOMER_ID_0x1005)) { - ret = wdc_get_c0_log_page_sn_customer_id_0x100X(dev, uuid_index, format, + ret = wdc_get_c0_log_page_sn_customer_id_0x100X(hdl, uuid_index, format, namespace_id, fmt); } else { - ret = nvme_get_print_c0_eol_log(dev, + ret = nvme_get_print_c0_eol_log(hdl, 0, namespace_id, fmt); @@ -7229,7 +7094,7 @@ static int wdc_get_c0_log_page_sn(nvme_root_t r, struct nvme_dev *dev, int uuid_ return ret; } -static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format, int uuid_index, +static int wdc_get_c0_log_page(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, char *format, int uuid_index, __u32 namespace_id) { uint32_t device_id, read_vendor_id; @@ -7237,7 +7102,7 @@ static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format int ret; __u8 *data; - if (!wdc_check_device(r, dev)) + if (!wdc_check_device(ctx, hdl)) return -1; ret = validate_output_format(format, &fmt); if (ret < 0) { @@ -7245,7 +7110,7 @@ static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format return ret; } - ret = wdc_get_pci_ids(r, dev, &device_id, &read_vendor_id); + ret = wdc_get_pci_ids(ctx, hdl, &device_id, &read_vendor_id); switch (device_id) { case WDC_NVME_SN640_DEV_ID: @@ -7259,7 +7124,7 @@ static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format case WDC_NVME_SN560_DEV_ID_2: case WDC_NVME_SN560_DEV_ID_3: case WDC_NVME_SN550_DEV_ID: - ret = wdc_get_c0_log_page_sn(r, dev, uuid_index, format, namespace_id, fmt); + ret = wdc_get_c0_log_page_sn(ctx, hdl, uuid_index, format, namespace_id, fmt); break; case WDC_NVME_SN650_DEV_ID: case WDC_NVME_SN650_DEV_ID_1: @@ -7271,12 +7136,12 @@ static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format case WDC_NVME_SNTMP_DEV_ID: case WDC_NVME_SNTMP_DEV_ID_1: if (uuid_index == 0) { - ret = nvme_get_print_ocp_cloud_smart_log(dev, + ret = nvme_get_print_ocp_cloud_smart_log(hdl, uuid_index, namespace_id, fmt); } else { - ret = nvme_get_print_c0_eol_log(dev, + ret = nvme_get_print_c0_eol_log(hdl, uuid_index, namespace_id, fmt); @@ -7284,7 +7149,7 @@ static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format break; case WDC_NVME_ZN350_DEV_ID: case WDC_NVME_ZN350_DEV_ID_1: - ret = nvme_get_print_ocp_cloud_smart_log(dev, + ret = nvme_get_print_ocp_cloud_smart_log(hdl, 0, NVME_NSID_ALL, fmt); @@ -7292,7 +7157,7 @@ static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format case WDC_NVME_SN820CL_DEV_ID: /* Get the 0xC0 Extended Smart Cloud Attribute log data */ data = NULL; - ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data, + ret = nvme_get_ext_smart_cloud_log(hdl, &data, uuid_index, namespace_id); if (strcmp(format, "json")) @@ -7318,7 +7183,7 @@ static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format return ret; } -static int wdc_print_latency_monitor_log(struct nvme_dev *dev, +static int wdc_print_latency_monitor_log(struct nvme_transport_handle *hdl, struct wdc_ssd_latency_monitor_log *log_data, int fmt) { @@ -7328,7 +7193,7 @@ static int wdc_print_latency_monitor_log(struct nvme_dev *dev, } switch (fmt) { case NORMAL: - wdc_print_latency_monitor_log_normal(dev, log_data); + wdc_print_latency_monitor_log_normal(hdl, log_data); break; case JSON: wdc_print_latency_monitor_log_json(log_data); @@ -7405,7 +7270,7 @@ static int wdc_print_fb_ca_log(struct wdc_ssd_ca_perf_stats *perf, int fmt) return 0; } -static int wdc_print_bd_ca_log(struct nvme_dev *dev, void *bd_data, int fmt) +static int wdc_print_bd_ca_log(struct nvme_transport_handle *hdl, void *bd_data, int fmt) { if (!bd_data) { fprintf(stderr, "ERROR: WDC: Invalid buffer to read data\n"); @@ -7413,7 +7278,7 @@ static int wdc_print_bd_ca_log(struct nvme_dev *dev, void *bd_data, int fmt) } switch (fmt) { case NORMAL: - wdc_print_bd_ca_log_normal(dev, bd_data); + wdc_print_bd_ca_log_normal(hdl, bd_data); break; case JSON: wdc_print_bd_ca_log_json(bd_data); @@ -7464,7 +7329,7 @@ static int wdc_print_fw_act_history_log(__u8 *data, int num_entries, int fmt, return 0; } -static int wdc_get_ca_log_page(nvme_root_t r, struct nvme_dev *dev, char *format) +static int wdc_get_ca_log_page(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, char *format) { uint32_t read_device_id, read_vendor_id; struct wdc_ssd_ca_perf_stats *perf; @@ -7473,7 +7338,7 @@ static int wdc_get_ca_log_page(nvme_root_t r, struct nvme_dev *dev, char *format __u8 *data; int ret; - if (!wdc_check_device(r, dev)) + if (!wdc_check_device(ctx, hdl)) return -1; ret = validate_output_format(format, &fmt); if (ret < 0) { @@ -7482,20 +7347,20 @@ static int wdc_get_ca_log_page(nvme_root_t r, struct nvme_dev *dev, char *format } /* verify the 0xCA log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE, 0) == false) { fprintf(stderr, "ERROR: WDC: 0xCA Log Page not supported\n"); return -1; } /* get the FW customer id */ - cust_id = wdc_get_fw_cust_id(r, dev); + cust_id = wdc_get_fw_cust_id(ctx, hdl); if (cust_id == WDC_INVALID_CUSTOMER_ID) { fprintf(stderr, "%s: ERROR: WDC: invalid customer id\n", __func__); return -1; } - ret = wdc_get_pci_ids(r, dev, &read_device_id, &read_vendor_id); + ret = wdc_get_pci_ids(ctx, hdl, &read_device_id, &read_vendor_id); switch (read_device_id) { case WDC_NVME_SN200_DEV_ID: @@ -7508,9 +7373,9 @@ static int wdc_get_ca_log_page(nvme_root_t r, struct nvme_dev *dev, char *format memset(data, 0, sizeof(__u8) * WDC_FB_CA_LOG_BUF_LEN); - ret = nvme_get_log_simple(dev_fd(dev), + ret = nvme_get_log_simple(hdl, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE, - WDC_FB_CA_LOG_BUF_LEN, data); + data, WDC_FB_CA_LOG_BUF_LEN); if (strcmp(format, "json")) nvme_show_status(ret); @@ -7544,9 +7409,9 @@ static int wdc_get_ca_log_page(nvme_root_t r, struct nvme_dev *dev, char *format memset(data, 0, sizeof(__u8) * WDC_FB_CA_LOG_BUF_LEN); - ret = nvme_get_log_simple(dev_fd(dev), + ret = nvme_get_log_simple(hdl, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE, - WDC_FB_CA_LOG_BUF_LEN, data); + data, WDC_FB_CA_LOG_BUF_LEN); if (strcmp(format, "json")) nvme_show_status(ret); @@ -7567,15 +7432,15 @@ static int wdc_get_ca_log_page(nvme_root_t r, struct nvme_dev *dev, char *format } memset(data, 0, sizeof(__u8) * WDC_BD_CA_LOG_BUF_LEN); - ret = nvme_get_log_simple(dev_fd(dev), + ret = nvme_get_log_simple(hdl, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE, - WDC_BD_CA_LOG_BUF_LEN, data); + data, WDC_BD_CA_LOG_BUF_LEN); if (strcmp(format, "json")) nvme_show_status(ret); if (!ret) { /* parse the data */ - ret = wdc_print_bd_ca_log(dev, data, fmt); + ret = wdc_print_bd_ca_log(hdl, data, fmt); } else { fprintf(stderr, "ERROR: WDC: Unable to read CA Log Page data\n"); ret = -1; @@ -7594,8 +7459,9 @@ static int wdc_get_ca_log_page(nvme_root_t r, struct nvme_dev *dev, char *format return ret; } -static int wdc_get_c1_log_page(nvme_root_t r, struct nvme_dev *dev, - char *format, uint8_t interval) +static int wdc_get_c1_log_page(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl, char *format, + uint8_t interval) { struct wdc_log_page_subpage_header *sph; struct wdc_ssd_perf_stats *perf; @@ -7608,7 +7474,7 @@ static int wdc_get_c1_log_page(nvme_root_t r, struct nvme_dev *dev, int i; int ret; - if (!wdc_check_device(r, dev)) + if (!wdc_check_device(ctx, hdl)) return -1; ret = validate_output_format(format, &fmt); @@ -7629,8 +7495,8 @@ static int wdc_get_c1_log_page(nvme_root_t r, struct nvme_dev *dev, } memset(data, 0, sizeof(__u8) * WDC_ADD_LOG_BUF_LEN); - ret = nvme_get_log_simple(dev_fd(dev), WDC_NVME_ADD_LOG_OPCODE, - WDC_ADD_LOG_BUF_LEN, data); + ret = nvme_get_log_simple(hdl, WDC_NVME_ADD_LOG_OPCODE, + data, WDC_ADD_LOG_BUF_LEN); if (strcmp(format, "json")) nvme_show_status(ret); if (!ret) { @@ -7654,7 +7520,7 @@ static int wdc_get_c1_log_page(nvme_root_t r, struct nvme_dev *dev, return ret; } -static int wdc_get_c3_log_page(nvme_root_t r, struct nvme_dev *dev, char *format) +static int wdc_get_c3_log_page(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, char *format) { struct wdc_ssd_latency_monitor_log *log_data; nvme_print_flags_t fmt; @@ -7662,7 +7528,7 @@ static int wdc_get_c3_log_page(nvme_root_t r, struct nvme_dev *dev, char *format int ret; int i; - if (!wdc_check_device(r, dev)) + if (!wdc_check_device(ctx, hdl)) return -1; ret = validate_output_format(format, &fmt); @@ -7678,8 +7544,8 @@ static int wdc_get_c3_log_page(nvme_root_t r, struct nvme_dev *dev, char *format } memset(data, 0, sizeof(__u8) * WDC_LATENCY_MON_LOG_BUF_LEN); - ret = nvme_get_log_simple(dev_fd(dev), WDC_LATENCY_MON_LOG_ID, - WDC_LATENCY_MON_LOG_BUF_LEN, data); + ret = nvme_get_log_simple(hdl, WDC_LATENCY_MON_LOG_ID, + data, WDC_LATENCY_MON_LOG_BUF_LEN); if (strcmp(format, "json")) fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret); @@ -7715,7 +7581,7 @@ static int wdc_get_c3_log_page(nvme_root_t r, struct nvme_dev *dev, char *format } /* parse the data */ - wdc_print_latency_monitor_log(dev, log_data, fmt); + wdc_print_latency_monitor_log(hdl, log_data, fmt); } else { fprintf(stderr, "ERROR: WDC: Unable to read C3 data from buffer\n"); } @@ -7726,7 +7592,7 @@ static int wdc_get_c3_log_page(nvme_root_t r, struct nvme_dev *dev, char *format } -static int wdc_get_ocp_c1_log_page(nvme_root_t r, struct nvme_dev *dev, char *format) +static int wdc_get_ocp_c1_log_page(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, char *format) { struct wdc_ocp_c1_error_recovery_log *log_data; nvme_print_flags_t fmt; @@ -7734,7 +7600,7 @@ static int wdc_get_ocp_c1_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo int ret; int i; - if (!wdc_check_device(r, dev)) + if (!wdc_check_device(ctx, hdl)) return -1; ret = validate_output_format(format, &fmt); @@ -7750,8 +7616,8 @@ static int wdc_get_ocp_c1_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo } memset(data, 0, sizeof(__u8) * WDC_ERROR_REC_LOG_BUF_LEN); - ret = nvme_get_log_simple(dev_fd(dev), WDC_ERROR_REC_LOG_ID, - WDC_ERROR_REC_LOG_BUF_LEN, data); + ret = nvme_get_log_simple(hdl, WDC_ERROR_REC_LOG_ID, + data, WDC_ERROR_REC_LOG_BUF_LEN); if (strcmp(format, "json")) fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret); @@ -7798,7 +7664,7 @@ static int wdc_get_ocp_c1_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo return ret; } -static int wdc_get_ocp_c4_log_page(nvme_root_t r, struct nvme_dev *dev, char *format) +static int wdc_get_ocp_c4_log_page(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, char *format) { struct wdc_ocp_C4_dev_cap_log *log_data; nvme_print_flags_t fmt; @@ -7806,7 +7672,7 @@ static int wdc_get_ocp_c4_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo int ret; int i; - if (!wdc_check_device(r, dev)) + if (!wdc_check_device(ctx, hdl)) return -1; ret = validate_output_format(format, &fmt); @@ -7822,8 +7688,8 @@ static int wdc_get_ocp_c4_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo } memset(data, 0, sizeof(__u8) * WDC_DEV_CAP_LOG_BUF_LEN); - ret = nvme_get_log_simple(dev_fd(dev), WDC_DEV_CAP_LOG_ID, - WDC_DEV_CAP_LOG_BUF_LEN, data); + ret = nvme_get_log_simple(hdl, WDC_DEV_CAP_LOG_ID, + data, WDC_DEV_CAP_LOG_BUF_LEN); if (strcmp(format, "json")) fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret); @@ -7868,7 +7734,7 @@ static int wdc_get_ocp_c4_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo return ret; } -static int wdc_get_ocp_c5_log_page(nvme_root_t r, struct nvme_dev *dev, char *format) +static int wdc_get_ocp_c5_log_page(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, char *format) { struct wdc_ocp_C5_unsupported_reqs *log_data; nvme_print_flags_t fmt; @@ -7876,7 +7742,7 @@ static int wdc_get_ocp_c5_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo __u8 *data; int i; - if (!wdc_check_device(r, dev)) + if (!wdc_check_device(ctx, hdl)) return -1; ret = validate_output_format(format, &fmt); @@ -7892,8 +7758,8 @@ static int wdc_get_ocp_c5_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo } memset(data, 0, sizeof(__u8) * WDC_UNSUPPORTED_REQS_LOG_BUF_LEN); - ret = nvme_get_log_simple(dev_fd(dev), WDC_UNSUPPORTED_REQS_LOG_ID, - WDC_UNSUPPORTED_REQS_LOG_BUF_LEN, data); + ret = nvme_get_log_simple(hdl, WDC_UNSUPPORTED_REQS_LOG_ID, + data, WDC_UNSUPPORTED_REQS_LOG_BUF_LEN); if (strcmp(format, "json")) fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret); @@ -7940,14 +7806,14 @@ static int wdc_get_ocp_c5_log_page(nvme_root_t r, struct nvme_dev *dev, char *fo return ret; } -static int wdc_get_d0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format) +static int wdc_get_d0_log_page(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, char *format) { struct wdc_ssd_d0_smart_log *perf; nvme_print_flags_t fmt; int ret = 0; __u8 *data; - if (!wdc_check_device(r, dev)) + if (!wdc_check_device(ctx, hdl)) return -1; ret = validate_output_format(format, &fmt); @@ -7957,7 +7823,7 @@ static int wdc_get_d0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format } /* verify the 0xD0 log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_VU_SMART_LOG_OPCODE, 0) == false) { fprintf(stderr, "ERROR: WDC: 0xD0 Log Page not supported\n"); return -1; @@ -7970,9 +7836,9 @@ static int wdc_get_d0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format } memset(data, 0, sizeof(__u8) * WDC_NVME_VU_SMART_LOG_LEN); - ret = nvme_get_log_simple(dev_fd(dev), + ret = nvme_get_log_simple(hdl, WDC_NVME_GET_VU_SMART_LOG_OPCODE, - WDC_NVME_VU_SMART_LOG_LEN, data); + data, WDC_NVME_VU_SMART_LOG_LEN); if (strcmp(format, "json")) nvme_show_status(ret); @@ -8164,12 +8030,13 @@ static void wdc_show_cloud_smart_log_json(struct ocp_cloud_smart_log *log) } static void wdc_show_cloud_smart_log_normal(struct ocp_cloud_smart_log *log, - struct nvme_dev *dev) + struct nvme_transport_handle *hdl) { char buf[2 * sizeof(log->log_page_guid) + 3]; uint16_t smart_log_ver = (uint16_t)le16_to_cpu(log->log_page_version); - printf("SMART Cloud Attributes for NVMe device : %s\n", dev->name); + printf("SMART Cloud Attributes for NVMe device : %s\n", + nvme_transport_handle_get_name(hdl)); printf("Physical Media Units Written : %'.0Lf\n", le_to_float(log->physical_media_units_written, 16)); printf("Physical Media Units Read : %'.0Lf\n", @@ -8264,7 +8131,7 @@ static void wdc_show_cloud_smart_log_normal(struct ocp_cloud_smart_log *log, printf("\n\n"); } -static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command, +static int wdc_vs_smart_add_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve additional performance statistics."; @@ -8273,8 +8140,8 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command, const char *log_page_mask = "Log Page Mask, comma separated list: 0xC0, 0xC1, 0xCA, 0xD0"; const char *namespace_id = "desired namespace id"; nvme_print_flags_t fmt; - struct nvme_dev *dev; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = 0; int uuid_index = 0; int page_mask = 0, num, i; @@ -8307,11 +8174,14 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); + if (ret) + return ret; + + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret) return ret; - r = nvme_scan(NULL); if (!cfg.log_page_version) { uuid_index = 0; } else if (cfg.log_page_version == 1) { @@ -8348,9 +8218,9 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command, if (!page_mask) fprintf(stderr, "ERROR: WDC: Unknown log page mask - %s\n", cfg.log_page_mask); - ret = wdc_get_pci_ids(r, dev, &device_id, &read_vendor_id); + ret = wdc_get_pci_ids(ctx, hdl, &device_id, &read_vendor_id); - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_SMART_LOG_MASK)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; @@ -8361,7 +8231,7 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command, (page_mask & WDC_C0_PAGE_MASK)) { /* Get 0xC0 log page if possible. */ if (!wdc_is_sn861(device_id)) { - ret = wdc_get_c0_log_page(r, dev, cfg.output_format, + ret = wdc_get_c0_log_page(ctx, hdl, cfg.output_format, uuid_index, cfg.namespace_id); if (ret) fprintf(stderr, @@ -8374,7 +8244,7 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command, goto out; } - ret = nvme_get_print_ocp_cloud_smart_log(dev, + ret = nvme_get_print_ocp_cloud_smart_log(hdl, 0, NVME_NSID_ALL, fmt); @@ -8384,14 +8254,14 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command, (page_mask & WDC_CA_PAGE_MASK) && (!wdc_is_sn861(device_id))) { /* Get the CA Log Page */ - ret = wdc_get_ca_log_page(r, dev, cfg.output_format); + ret = wdc_get_ca_log_page(ctx, hdl, cfg.output_format); if (ret) fprintf(stderr, "ERROR: WDC: Failure reading the CA Log Page, ret = %d\n", ret); } if (((capabilities & WDC_DRIVE_CAP_C1_LOG_PAGE) == WDC_DRIVE_CAP_C1_LOG_PAGE) && (page_mask & WDC_C1_PAGE_MASK)) { /* Get the C1 Log Page */ - ret = wdc_get_c1_log_page(r, dev, cfg.output_format, + ret = wdc_get_c1_log_page(ctx, hdl, cfg.output_format, cfg.interval); if (ret) fprintf(stderr, "ERROR: WDC: Failure reading the C1 Log Page, ret = %d\n", ret); @@ -8399,24 +8269,23 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command, if (((capabilities & WDC_DRIVE_CAP_D0_LOG_PAGE) == WDC_DRIVE_CAP_D0_LOG_PAGE) && (page_mask & WDC_D0_PAGE_MASK)) { /* Get the D0 Log Page */ - ret = wdc_get_d0_log_page(r, dev, cfg.output_format); + ret = wdc_get_d0_log_page(ctx, hdl, cfg.output_format); if (ret) fprintf(stderr, "ERROR: WDC: Failure reading the D0 Log Page, ret = %d\n", ret); } out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_cu_smart_log(int argc, char **argv, struct command *command, +static int wdc_cu_smart_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve customer unique smart log statistics."; const char *uuid_index = "The uuid index to select the correct log page implementation."; - struct nvme_dev *dev; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; int ret = 0; __u64 capabilities = 0; uint32_t read_device_id, read_vendor_id; @@ -8439,13 +8308,15 @@ static int wdc_cu_smart_log(int argc, char **argv, struct command *command, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret) + return ret; - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_SMART_LOG_MASK)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; @@ -8453,7 +8324,7 @@ static int wdc_cu_smart_log(int argc, char **argv, struct command *command, } if ((capabilities & WDC_DRIVE_CAP_CA_LOG_PAGE) == WDC_DRIVE_CAP_CA_LOG_PAGE) { - if (!wdc_check_device(r, dev)) + if (!wdc_check_device(ctx, hdl)) return -1; ret = validate_output_format(cfg.output_format, &fmt); @@ -8464,13 +8335,13 @@ static int wdc_cu_smart_log(int argc, char **argv, struct command *command, } /* verify the 0xCA log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE, 0) == false) { fprintf(stderr, "ERROR: WDC: 0xCA Log Page not supported\n"); return -1; } - ret = wdc_get_pci_ids(r, dev, &read_device_id, &read_vendor_id); + ret = wdc_get_pci_ids(ctx, hdl, &read_device_id, &read_vendor_id); switch (read_device_id) { case WDC_NVME_SN861_DEV_ID: @@ -8483,33 +8354,23 @@ static int wdc_cu_smart_log(int argc, char **argv, struct command *command, } memset(data, 0, sizeof(__u8) * WDC_BD_CA_LOG_BUF_LEN); - struct nvme_get_log_args args = { - .lpo = 0, - .result = NULL, - .log = data, - .args_size = sizeof(args), - .fd = dev_fd(dev), - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .lid = WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE, - .len = WDC_BD_CA_LOG_BUF_LEN, - .nsid = NVME_NSID_ALL, - .csi = NVME_CSI_NVM, - .lsi = NVME_LOG_LSI_NONE, - .lsp = 0, - .uuidx = cfg.uuid_index, - .rae = false, - .ot = false, - }; /* Get the CA Log Page */ - ret = nvme_get_log(&args); + nvme_init_get_log(&cmd, NVME_NSID_ALL, + WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID, + NVME_CSI_NVM, data, WDC_BD_CA_LOG_BUF_LEN); + cmd.cdw14 |= NVME_FIELD_ENCODE(cfg.uuid_index, + NVME_LOG_CDW14_UUID_SHIFT, + NVME_LOG_CDW14_UUID_MASK); + ret = nvme_get_log(hdl, &cmd, false, + NVME_LOG_PAGE_PDU_SIZE, NULL); if (strcmp(cfg.output_format, "json")) nvme_show_status(ret); if (!ret) { /* parse the data */ - ret = wdc_print_bd_ca_log(dev, data, fmt); + ret = wdc_print_bd_ca_log(hdl, data, fmt); } else { fprintf(stderr, "ERROR: WDC: Unable to read CA Log Page data\n"); ret = -1; @@ -8527,20 +8388,18 @@ static int wdc_cu_smart_log(int argc, char **argv, struct command *command, } out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_vs_cloud_log(int argc, char **argv, struct command *command, +static int wdc_vs_cloud_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Cloud Log Smart/Health Information"; const char *namespace_id = "desired namespace id"; nvme_print_flags_t fmt; __u64 capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret; __u8 *data; @@ -8560,13 +8419,15 @@ static int wdc_vs_cloud_log(int argc, char **argv, struct command *command, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret) + return ret; - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_CLOUD_LOG_PAGE)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); @@ -8575,7 +8436,7 @@ static int wdc_vs_cloud_log(int argc, char **argv, struct command *command, } data = NULL; - ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data, 0, + ret = nvme_get_ext_smart_cloud_log(hdl, &data, 0, cfg.namespace_id); if (strcmp(cfg.output_format, "json")) @@ -8597,22 +8458,20 @@ static int wdc_vs_cloud_log(int argc, char **argv, struct command *command, free(data); out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *command, +static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Hardware Revision Log Information"; const char *namespace_id = "desired namespace id"; nvme_print_flags_t fmt; __u64 capabilities = 0; - struct nvme_dev *dev; + struct nvme_transport_handle *hdl; int ret; __u8 *data = NULL; - nvme_root_t r; + struct nvme_global_ctx *ctx; struct config { char *output_format; @@ -8630,13 +8489,15 @@ static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *command, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret) + return ret; - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_HW_REV_LOG_PAGE)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); @@ -8644,7 +8505,7 @@ static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *command, goto out; } - ret = nvme_get_hw_rev_log(dev_fd(dev), &data, 0, cfg.namespace_id); + ret = nvme_get_hw_rev_log(hdl, &data, 0, cfg.namespace_id); if (strcmp(cfg.output_format, "json")) nvme_show_status(ret); @@ -8680,21 +8541,19 @@ static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *command, free(data); out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_vs_device_waf(int argc, char **argv, struct command *command, +static int wdc_vs_device_waf(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Device Write Amplication Factor"; const char *namespace_id = "desired namespace id"; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct nvme_smart_log smart_log; nvme_print_flags_t fmt; - struct nvme_dev *dev; __u8 *data; - nvme_root_t r; int ret = 0; __u64 capabilities = 0; struct __packed wdc_nvme_ext_smart_log * ext_smart_log_ptr; @@ -8721,13 +8580,15 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret) + return ret; - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_DEVICE_WAF)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); @@ -8736,8 +8597,7 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command, } /* get data units written from the smart log page */ - ret = nvme_get_log_smart(dev_fd(dev), cfg.namespace_id, false, - &smart_log); + ret = nvme_get_log_smart(hdl, cfg.namespace_id, &smart_log); if (!ret) { data_units_written = int128_to_double(smart_log.data_units_written); } else if (ret > 0) { @@ -8752,7 +8612,7 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command, /* get Physical Media Units Written from extended smart/C0 log page */ data = NULL; - ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data, 0, + ret = nvme_get_ext_smart_cloud_log(hdl, &data, 0, cfg.namespace_id); if (!ret) { @@ -8802,18 +8662,16 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command, } out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *command, +static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve latency monitor log data."; __u64 capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = 0; struct config { @@ -8829,12 +8687,14 @@ static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *co OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); - capabilities = wdc_get_drive_capabilities(r, dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret) + return ret; + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_C3_LOG_PAGE)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); @@ -8842,23 +8702,21 @@ static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *co goto out; } - ret = wdc_get_c3_log_page(r, dev, cfg.output_format); + ret = wdc_get_c3_log_page(ctx, hdl, cfg.output_format); if (ret) fprintf(stderr, "ERROR: WDC: Failure reading the Latency Monitor (C3) Log Page, ret = %d\n", ret); out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_get_error_recovery_log(int argc, char **argv, struct command *command, +static int wdc_get_error_recovery_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve error recovery log data."; __u64 capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = 0; struct config { @@ -8874,12 +8732,15 @@ static int wdc_get_error_recovery_log(int argc, char **argv, struct command *com OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); + if (ret) + return ret; + + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret) return ret; - r = nvme_scan(NULL); - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_OCP_C1_LOG_PAGE)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); @@ -8887,23 +8748,21 @@ static int wdc_get_error_recovery_log(int argc, char **argv, struct command *com goto out; } - ret = wdc_get_ocp_c1_log_page(r, dev, cfg.output_format); + ret = wdc_get_ocp_c1_log_page(ctx, hdl, cfg.output_format); if (ret) fprintf(stderr, "ERROR: WDC: Failure reading the Error Recovery (C1) Log Page, ret = 0x%x\n", ret); out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_get_dev_capabilities_log(int argc, char **argv, struct command *command, +static int wdc_get_dev_capabilities_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve device capabilities log data."; __u64 capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = 0; struct config { @@ -8919,12 +8778,15 @@ static int wdc_get_dev_capabilities_log(int argc, char **argv, struct command *c OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); - capabilities = wdc_get_drive_capabilities(r, dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret) + return ret; + + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_OCP_C4_LOG_PAGE)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); @@ -8932,23 +8794,21 @@ static int wdc_get_dev_capabilities_log(int argc, char **argv, struct command *c goto out; } - ret = wdc_get_ocp_c4_log_page(r, dev, cfg.output_format); + ret = wdc_get_ocp_c4_log_page(ctx, hdl, cfg.output_format); if (ret) fprintf(stderr, "ERROR: WDC: Failure reading the Device Capabilities (C4) Log Page, ret = 0x%x\n", ret); out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_get_unsupported_reqs_log(int argc, char **argv, struct command *command, +static int wdc_get_unsupported_reqs_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve unsupported requirements log data."; __u64 capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = 0; struct config { @@ -8964,12 +8824,15 @@ static int wdc_get_unsupported_reqs_log(int argc, char **argv, struct command *c OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); + if (ret) + return ret; + + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret) return ret; - r = nvme_scan(NULL); - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_OCP_C5_LOG_PAGE)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); @@ -8977,17 +8840,15 @@ static int wdc_get_unsupported_reqs_log(int argc, char **argv, struct command *c goto out; } - ret = wdc_get_ocp_c5_log_page(r, dev, cfg.output_format); + ret = wdc_get_ocp_c5_log_page(ctx, hdl, cfg.output_format); if (ret) fprintf(stderr, "ERROR: WDC: Failure reading the Unsupported Requirements (C5) Log Page, ret = 0x%x\n", ret); out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_do_clear_pcie_correctable_errors(int fd) +static int wdc_do_clear_pcie_correctable_errors(struct nvme_transport_handle *hdl) { int ret; struct nvme_passthru_cmd admin_cmd; @@ -8997,12 +8858,12 @@ static int wdc_do_clear_pcie_correctable_errors(int fd) admin_cmd.cdw12 = ((WDC_NVME_CLEAR_PCIE_CORR_SUBCMD << WDC_NVME_SUBCMD_SHIFT) | WDC_NVME_CLEAR_PCIE_CORR_CMD); - ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); nvme_show_status(ret); return ret; } -static int wdc_do_clear_pcie_correctable_errors_vuc(int fd) +static int wdc_do_clear_pcie_correctable_errors_vuc(struct nvme_transport_handle *hdl) { int ret; struct nvme_passthru_cmd admin_cmd; @@ -9010,48 +8871,46 @@ static int wdc_do_clear_pcie_correctable_errors_vuc(int fd) memset(&admin_cmd, 0, sizeof(admin_cmd)); admin_cmd.opcode = WDC_NVME_CLEAR_PCIE_CORR_OPCODE_VUC; - ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); nvme_show_status(ret); return ret; } -static int wdc_do_clear_pcie_correctable_errors_fid(int fd) +static int wdc_do_clear_pcie_correctable_errors_fid(struct nvme_transport_handle *hdl) { int ret; __u32 result; __u32 value = 1 << 31; /* Bit 31 - clear PCIe correctable count */ - ret = nvme_set_features_simple(fd, WDC_NVME_CLEAR_PCIE_CORR_FEATURE_ID, 0, value, - false, &result); + ret = nvme_set_features_simple(hdl, 0, WDC_NVME_CLEAR_PCIE_CORR_FEATURE_ID, false, + value, &result); nvme_show_status(ret); return ret; } -static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct command *command, +static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Clear PCIE Correctable Errors."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u64 capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; int ret; OPT_ARGS(opts) = { OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); - if (!wdc_check_device(r, dev)) { - ret = -1; - goto out; - } + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !wdc_check_device(ctx, hdl)) + return -1; - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_CLEAR_PCIE_MASK)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; @@ -9059,26 +8918,24 @@ static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct comma } if (capabilities & WDC_DRIVE_CAP_CLEAR_PCIE) - ret = wdc_do_clear_pcie_correctable_errors(dev_fd(dev)); + ret = wdc_do_clear_pcie_correctable_errors(hdl); else if (capabilities & WDC_DRIVE_CAP_VUC_CLEAR_PCIE) - ret = wdc_do_clear_pcie_correctable_errors_vuc(dev_fd(dev)); + ret = wdc_do_clear_pcie_correctable_errors_vuc(hdl); else - ret = wdc_do_clear_pcie_correctable_errors_fid(dev_fd(dev)); + ret = wdc_do_clear_pcie_correctable_errors_fid(hdl); out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_drive_status(int argc, char **argv, struct command *command, +static int wdc_drive_status(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Drive Status."; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = 0; int uuid_index; - nvme_root_t r; void *dev_mng_log = NULL; __u32 system_eol_state; __u32 user_eol_state; @@ -9093,12 +8950,16 @@ static int wdc_drive_status(int argc, char **argv, struct command *command, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); + if (ret) + return ret; + + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret) return ret; - r = nvme_scan(NULL); - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); + if ((capabilities & WDC_DRIVE_CAP_DRIVE_STATUS) != WDC_DRIVE_CAP_DRIVE_STATUS) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; @@ -9109,7 +8970,7 @@ static int wdc_drive_status(int argc, char **argv, struct command *command, /* Find the WDC UUID index */ memset(&uuid_list, 0, sizeof(struct nvme_id_uuid_list)); - if (wdc_CheckUuidListSupport(dev, &uuid_list)) + if (wdc_CheckUuidListSupport(hdl, &uuid_list)) uuid_index = nvme_uuid_find(&uuid_list, WDC_UUID); /* WD UUID not found, use default uuid index - 0 */ @@ -9117,7 +8978,7 @@ static int wdc_drive_status(int argc, char **argv, struct command *command, uuid_index = 0; /* verify the 0xC2 Device Manageability log page is supported */ - if (wdc_nvme_check_supported_log_page(r, dev, + if (wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_ID, uuid_index) == false) { fprintf(stderr, "ERROR: WDC: 0xC2 Log Page not supported, uuid_index: %d\n", @@ -9126,7 +8987,7 @@ static int wdc_drive_status(int argc, char **argv, struct command *command, goto out; } - if (!get_dev_mgment_data(r, dev, &dev_mng_log)) { + if (!get_dev_mgment_data(ctx, hdl, &dev_mng_log)) { fprintf(stderr, "ERROR: WDC: 0xC2 Log Page not found\n"); ret = -1; goto out; @@ -9209,18 +9070,16 @@ static int wdc_drive_status(int argc, char **argv, struct command *command, free(dev_mng_log); out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_clear_assert_dump(int argc, char **argv, struct command *command, +static int wdc_clear_assert_dump(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Clear Assert Dump Present Status."; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = -1; - nvme_root_t r; __le32 assert_status = cpu_to_le32(0xFFFFFFFF); __u64 capabilities = 0; struct nvme_passthru_cmd admin_cmd; @@ -9229,18 +9088,22 @@ static int wdc_clear_assert_dump(int argc, char **argv, struct command *command, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); + if (ret) + return ret; + + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret) return ret; - r = nvme_scan(NULL); - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); + if ((capabilities & WDC_DRIVE_CAP_CLEAR_ASSERT) != WDC_DRIVE_CAP_CLEAR_ASSERT) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; goto out; } - if (!wdc_nvme_get_dev_status_log_data(r, dev, &assert_status, + if (!wdc_nvme_get_dev_status_log_data(ctx, hdl, &assert_status, WDC_C2_ASSERT_DUMP_PRESENT_ID)) { fprintf(stderr, "ERROR: WDC: Get Assert Status Failed\n"); ret = -1; @@ -9254,19 +9117,17 @@ static int wdc_clear_assert_dump(int argc, char **argv, struct command *command, admin_cmd.cdw12 = ((WDC_NVME_CLEAR_ASSERT_DUMP_SUBCMD << WDC_NVME_SUBCMD_SHIFT) | WDC_NVME_CLEAR_ASSERT_DUMP_CMD); - ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); nvme_show_status(ret); } else fprintf(stderr, "INFO: WDC: No Assert Dump Present\n"); out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_get_fw_act_history(nvme_root_t r, struct nvme_dev *dev, +static int wdc_get_fw_act_history(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, char *format) { struct wdc_fw_act_history_log_hdr *fw_act_history_hdr; @@ -9274,7 +9135,7 @@ static int wdc_get_fw_act_history(nvme_root_t r, struct nvme_dev *dev, int ret; __u8 *data; - if (!wdc_check_device(r, dev)) + if (!wdc_check_device(ctx, hdl)) return -1; ret = validate_output_format(format, &fmt); @@ -9284,7 +9145,7 @@ static int wdc_get_fw_act_history(nvme_root_t r, struct nvme_dev *dev, } /* verify the FW Activate History log page is supported */ - if (!wdc_nvme_check_supported_log_page(r, dev, + if (!wdc_nvme_check_supported_log_page(ctx, hdl, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID, 0)) { fprintf(stderr, "ERROR: WDC: %d Log Page not supported\n", WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID); @@ -9299,9 +9160,9 @@ static int wdc_get_fw_act_history(nvme_root_t r, struct nvme_dev *dev, memset(data, 0, sizeof(__u8) * WDC_FW_ACT_HISTORY_LOG_BUF_LEN); - ret = nvme_get_log_simple(dev_fd(dev), + ret = nvme_get_log_simple(hdl, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID, - WDC_FW_ACT_HISTORY_LOG_BUF_LEN, data); + data, WDC_FW_ACT_HISTORY_LOG_BUF_LEN); if (strcmp(format, "json")) nvme_show_status(ret); @@ -9332,13 +9193,13 @@ static int wdc_get_fw_act_history(nvme_root_t r, struct nvme_dev *dev, return ret; } -static __u32 wdc_get_fw_cust_id(nvme_root_t r, struct nvme_dev *dev) +static __u32 wdc_get_fw_cust_id(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl) { __u32 cust_id = WDC_INVALID_CUSTOMER_ID; __u32 *cust_id_ptr = NULL; - if (!get_dev_mgment_cbs_data(r, dev, WDC_C2_CUSTOMER_ID_ID, (void *)&cust_id_ptr)) + if (!get_dev_mgment_cbs_data(ctx, hdl, WDC_C2_CUSTOMER_ID_ID, (void *)&cust_id_ptr)) fprintf(stderr, "%s: ERROR: WDC: 0xC2 Log Page entry ID 0x%x not found\n", __func__, WDC_C2_CUSTOMER_ID_ID); else @@ -9348,7 +9209,7 @@ static __u32 wdc_get_fw_cust_id(nvme_root_t r, struct nvme_dev *dev) return cust_id; } -static int wdc_get_fw_act_history_C2(nvme_root_t r, struct nvme_dev *dev, +static int wdc_get_fw_act_history_C2(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, char *format) { struct wdc_fw_act_history_log_format_c2 *fw_act_history_log; @@ -9360,7 +9221,7 @@ static int wdc_get_fw_act_history_C2(nvme_root_t r, struct nvme_dev *dev, int ret; bool c2GuidMatch = false; - if (!wdc_check_device(r, dev)) + if (!wdc_check_device(ctx, hdl)) return -1; ret = validate_output_format(format, &fmt); @@ -9369,7 +9230,7 @@ static int wdc_get_fw_act_history_C2(nvme_root_t r, struct nvme_dev *dev, return ret; } - ret = wdc_get_pci_ids(r, dev, &device_id, &vendor_id); + ret = wdc_get_pci_ids(ctx, hdl, &device_id, &vendor_id); data = (__u8 *)malloc(sizeof(__u8) * WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN); if (!data) { @@ -9379,9 +9240,9 @@ static int wdc_get_fw_act_history_C2(nvme_root_t r, struct nvme_dev *dev, memset(data, 0, sizeof(__u8) * WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN); - ret = nvme_get_log_simple(dev_fd(dev), + ret = nvme_get_log_simple(hdl, WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID, - WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN, data); + data, WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN); if (strcmp(format, "json")) nvme_show_status(ret); @@ -9401,7 +9262,7 @@ static int wdc_get_fw_act_history_C2(nvme_root_t r, struct nvme_dev *dev, if (tot_entries > 0) { /* get the FW customer id */ if (!wdc_is_sn861(device_id)) { - cust_id = wdc_get_fw_cust_id(r, dev); + cust_id = wdc_get_fw_cust_id(ctx, hdl); if (cust_id == WDC_INVALID_CUSTOMER_ID) { fprintf(stderr, "%s: ERROR: WDC: invalid customer id\n", @@ -9432,13 +9293,13 @@ static int wdc_get_fw_act_history_C2(nvme_root_t r, struct nvme_dev *dev, return ret; } -static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *command, +static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve FW activate history table."; __u64 capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret = -1; struct config { @@ -9454,12 +9315,16 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); - capabilities = wdc_get_drive_capabilities(r, dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret) + return ret; + + capabilities = wdc_get_drive_capabilities(ctx, hdl); + if (!(capabilities & WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_MASK)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; @@ -9469,7 +9334,7 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com if (capabilities & WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY) { __u32 cust_fw_id = 0; /* get the FW customer id */ - cust_fw_id = wdc_get_fw_cust_id(r, dev); + cust_fw_id = wdc_get_fw_cust_id(ctx, hdl); if (cust_fw_id == WDC_INVALID_CUSTOMER_ID) { fprintf(stderr, "%s: ERROR: WDC: invalid customer id\n", __func__); ret = -1; @@ -9480,22 +9345,20 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com (cust_fw_id == WDC_CUSTOMER_ID_0x1008) || (cust_fw_id == WDC_CUSTOMER_ID_0x1005) || (cust_fw_id == WDC_CUSTOMER_ID_0x1304)) - ret = wdc_get_fw_act_history_C2(r, dev, cfg.output_format); + ret = wdc_get_fw_act_history_C2(ctx, hdl, cfg.output_format); else - ret = wdc_get_fw_act_history(r, dev, cfg.output_format); + ret = wdc_get_fw_act_history(ctx, hdl, cfg.output_format); } else if (capabilities & WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_C2) { - ret = wdc_get_fw_act_history_C2(r, dev, cfg.output_format); + ret = wdc_get_fw_act_history_C2(ctx, hdl, cfg.output_format); } if (ret) fprintf(stderr, "ERROR: WDC: Failure reading the FW Activate History, ret = %d\n", ret); out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_do_clear_fw_activate_history_vuc(int fd) +static int wdc_do_clear_fw_activate_history_vuc(struct nvme_transport_handle *hdl) { int ret = -1; struct nvme_passthru_cmd admin_cmd; @@ -9505,44 +9368,48 @@ static int wdc_do_clear_fw_activate_history_vuc(int fd) admin_cmd.cdw12 = ((WDC_NVME_CLEAR_FW_ACT_HIST_SUBCMD << WDC_NVME_SUBCMD_SHIFT) | WDC_NVME_CLEAR_FW_ACT_HIST_CMD); - ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); nvme_show_status(ret); return ret; } -static int wdc_do_clear_fw_activate_history_fid(int fd) +static int wdc_do_clear_fw_activate_history_fid(struct nvme_transport_handle *hdl) { int ret = -1; __u32 result; __u32 value = 1 << 31; /* Bit 31 - Clear Firmware Update History Log */ - ret = nvme_set_features_simple(fd, WDC_NVME_CLEAR_FW_ACT_HIST_VU_FID, 0, value, - false, &result); + ret = nvme_set_features_simple(hdl, 0, WDC_NVME_CLEAR_FW_ACT_HIST_VU_FID, false, + value, &result); nvme_show_status(ret); return ret; } -static int wdc_clear_fw_activate_history(int argc, char **argv, struct command *command, +static int wdc_clear_fw_activate_history(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Clear FW activate history table."; __u64 capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret; OPT_ARGS(opts) = { OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); - capabilities = wdc_get_drive_capabilities(r, dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret) + return ret; + + capabilities = wdc_get_drive_capabilities(ctx, hdl); + if (!(capabilities & WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY_MASK)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; @@ -9550,17 +9417,15 @@ static int wdc_clear_fw_activate_history(int argc, char **argv, struct command * } if (capabilities & WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY) - ret = wdc_do_clear_fw_activate_history_vuc(dev_fd(dev)); + ret = wdc_do_clear_fw_activate_history_vuc(hdl); else - ret = wdc_do_clear_fw_activate_history_fid(dev_fd(dev)); + ret = wdc_do_clear_fw_activate_history_fid(hdl); out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct command *command, +static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Disable/Enable Controller Option of the Telemetry Log Page."; @@ -9568,8 +9433,8 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm const char *enable = "Enable controller option of the telemetry log page."; const char *status = "Displays the current state of the controller initiated log page."; __u64 capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u32 result; int ret = -1; @@ -9593,12 +9458,16 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); + if (ret) + return ret; + + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret) return ret; - r = nvme_scan(NULL); - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); + if ((capabilities & WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG) != WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; @@ -9614,20 +9483,21 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm } if (cfg.disable) { - ret = nvme_set_features_simple(dev_fd(dev), - WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, - 0, 1, false, &result); + ret = nvme_set_features_simple(hdl, 0, + WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, + false, 1, &result); - wdc_clear_reason_id(dev); + wdc_clear_reason_id(hdl); } else { if (cfg.enable) { - ret = nvme_set_features_simple(dev_fd(dev), - WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, - 0, 0, false, &result); + ret = nvme_set_features_simple(hdl, 0, + WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, + false, 0, &result); } else if (cfg.status) { - ret = nvme_get_features_simple(dev_fd(dev), - WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, - 0, &result); + ret = nvme_get_features_simple(hdl, + WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, + NVME_GET_FEATURES_SEL_CURRENT, + &result); if (!ret) { if (result) fprintf(stderr, "Controller Option Telemetry Log Page State: Disabled\n"); @@ -9645,23 +9515,21 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm } out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_get_serial_and_fw_rev(struct nvme_dev *dev, char *sn, char *fw_rev) +static int wdc_get_serial_and_fw_rev(struct nvme_transport_handle *hdl, char *sn, char *fw_rev) { - int i; - int ret; struct nvme_id_ctrl ctrl; + int ret; + int i; i = sizeof(ctrl.sn) - 1; memset(sn, 0, WDC_SERIAL_NO_LEN); memset(fw_rev, 0, WDC_NVME_FIRMWARE_REV_LEN); memset(&ctrl, 0, sizeof(struct nvme_id_ctrl)); - ret = nvme_identify_ctrl(dev_fd(dev), &ctrl); + ret = nvme_identify_ctrl(hdl, &ctrl); if (ret) { fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", ret); return -1; @@ -9677,15 +9545,15 @@ static int wdc_get_serial_and_fw_rev(struct nvme_dev *dev, char *sn, char *fw_re return 0; } -static int wdc_get_max_transfer_len(struct nvme_dev *dev, __u32 *maxTransferLen) +static int wdc_get_max_transfer_len(struct nvme_transport_handle *hdl, __u32 *maxTransferLen) { - int ret = 0; struct nvme_id_ctrl ctrl; + int ret = 0; __u32 maxTransferLenDevice = 0; memset(&ctrl, 0, sizeof(struct nvme_id_ctrl)); - ret = nvme_identify_ctrl(dev_fd(dev), &ctrl); + ret = nvme_identify_ctrl(hdl, &ctrl); if (ret) { fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", ret); return -1; @@ -9697,12 +9565,12 @@ static int wdc_get_max_transfer_len(struct nvme_dev *dev, __u32 *maxTransferLen) return ret; } -static int wdc_de_VU_read_size(struct nvme_dev *dev, __u32 fileId, __u16 spiDestn, __u32 *logSize) +static int wdc_de_VU_read_size(struct nvme_transport_handle *hdl, __u32 fileId, __u16 spiDestn, __u32 *logSize) { int ret = WDC_STATUS_FAILURE; struct nvme_passthru_cmd cmd; - if (!dev || !logSize) { + if (!logSize) { ret = WDC_STATUS_INVALID_PARAMETER; goto end; } @@ -9713,7 +9581,7 @@ static int wdc_de_VU_read_size(struct nvme_dev *dev, __u32 fileId, __u16 spiDest cmd.cdw13 = fileId << 16; cmd.cdw14 = spiDestn; - ret = nvme_submit_admin_passthru(dev_fd(dev), &cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!ret && logSize) *logSize = cmd.result; @@ -9726,14 +9594,14 @@ static int wdc_de_VU_read_size(struct nvme_dev *dev, __u32 fileId, __u16 spiDest return ret; } -static int wdc_de_VU_read_buffer(struct nvme_dev *dev, __u32 fileId, __u16 spiDestn, +static int wdc_de_VU_read_buffer(struct nvme_transport_handle *hdl, __u32 fileId, __u16 spiDestn, __u32 offsetInDwords, __u8 *dataBuffer, __u32 *bufferSize) { int ret = WDC_STATUS_FAILURE; struct nvme_passthru_cmd cmd; __u32 noOfDwordExpected = 0; - if (!dev || !dataBuffer || !bufferSize) { + if (!dataBuffer || !bufferSize) { ret = WDC_STATUS_INVALID_PARAMETER; goto end; } @@ -9750,7 +9618,7 @@ static int wdc_de_VU_read_buffer(struct nvme_dev *dev, __u32 fileId, __u16 spiDe cmd.addr = (__u64)(__u64)(uintptr_t)dataBuffer; cmd.data_len = *bufferSize; - ret = nvme_submit_admin_passthru(dev_fd(dev), &cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (ret != WDC_STATUS_SUCCESS) { fprintf(stderr, "ERROR: WDC: VUReadBuffer() failed, "); @@ -9761,7 +9629,7 @@ static int wdc_de_VU_read_buffer(struct nvme_dev *dev, __u32 fileId, __u16 spiDe return ret; } -static int wdc_get_log_dir_max_entries(struct nvme_dev *dev, __u32 *maxNumOfEntries) +static int wdc_get_log_dir_max_entries(struct nvme_transport_handle *hdl, __u32 *maxNumOfEntries) { int ret = WDC_STATUS_FAILURE; __u32 headerPayloadSize = 0; @@ -9771,12 +9639,12 @@ static int wdc_get_log_dir_max_entries(struct nvme_dev *dev, __u32 *maxNumOfEntr __u16 fileOffset = 0; - if (!dev || !maxNumOfEntries) { + if (!maxNumOfEntries) { ret = WDC_STATUS_INVALID_PARAMETER; return ret; } /* 1.Get log directory first four bytes */ - ret = wdc_de_VU_read_size(dev, 0, 5, (__u32 *)&headerPayloadSize); + ret = wdc_de_VU_read_size(hdl, 0, 5, (__u32 *)&headerPayloadSize); if (ret != WDC_STATUS_SUCCESS) { fprintf(stderr, "ERROR: WDC: %s: Failed to get headerPayloadSize from file directory 0x%x\n", @@ -9789,7 +9657,7 @@ static int wdc_get_log_dir_max_entries(struct nvme_dev *dev, __u32 *maxNumOfEntr fileIdOffsetsBuffer = (__u8 *)calloc(1, fileIdOffsetsBufferSize); /* 2.Read to get file offsets */ - ret = wdc_de_VU_read_buffer(dev, 0, 5, 0, fileIdOffsetsBuffer, &fileIdOffsetsBufferSize); + ret = wdc_de_VU_read_buffer(hdl, 0, 5, 0, fileIdOffsetsBuffer, &fileIdOffsetsBufferSize); if (ret != WDC_STATUS_SUCCESS) { fprintf(stderr, "ERROR: WDC: %s: Failed to get fileIdOffsets from file directory 0x%x\n", @@ -9828,7 +9696,7 @@ static enum WDC_DRIVE_ESSENTIAL_TYPE wdc_get_essential_type(__u8 fileName[]) return essentialType; } -static int wdc_fetch_log_directory(struct nvme_dev *dev, struct WDC_DE_VU_LOG_DIRECTORY *directory) +static int wdc_fetch_log_directory(struct nvme_transport_handle *hdl, struct WDC_DE_VU_LOG_DIRECTORY *directory) { int ret = WDC_STATUS_FAILURE; __u8 *fileOffset = NULL; @@ -9839,12 +9707,12 @@ static int wdc_fetch_log_directory(struct nvme_dev *dev, struct WDC_DE_VU_LOG_DI __u32 entryId = 0; __u32 fileDirectorySize = 0; - if (!dev || !directory) { + if (!directory) { ret = WDC_STATUS_INVALID_PARAMETER; goto end; } - ret = wdc_de_VU_read_size(dev, 0, 5, &fileDirectorySize); + ret = wdc_de_VU_read_size(hdl, 0, 5, &fileDirectorySize); if (ret != WDC_STATUS_SUCCESS) { fprintf(stderr, "ERROR: WDC: %s: Failed to get filesystem directory size, ret = %d\n", @@ -9853,7 +9721,7 @@ static int wdc_fetch_log_directory(struct nvme_dev *dev, struct WDC_DE_VU_LOG_DI } fileDirectory = (__u8 *)calloc(1, fileDirectorySize); - ret = wdc_de_VU_read_buffer(dev, 0, 5, 0, fileDirectory, &fileDirectorySize); + ret = wdc_de_VU_read_buffer(hdl, 0, 5, 0, fileDirectory, &fileDirectorySize); if (ret != WDC_STATUS_SUCCESS) { fprintf(stderr, "ERROR: WDC: %s: Failed to get filesystem directory, ret = %d\n", __func__, ret); @@ -9901,7 +9769,7 @@ static int wdc_fetch_log_directory(struct nvme_dev *dev, struct WDC_DE_VU_LOG_DI return ret; } -static int wdc_fetch_log_file_from_device(struct nvme_dev *dev, __u32 fileId, +static int wdc_fetch_log_file_from_device(struct nvme_transport_handle *hdl, __u32 fileId, __u16 spiDestn, __u64 fileSize, __u8 *dataBuffer) { int ret = WDC_STATUS_FAILURE; @@ -9910,12 +9778,12 @@ static int wdc_fetch_log_file_from_device(struct nvme_dev *dev, __u32 fileId, __u32 buffSize = 0; __u64 offsetIdx = 0; - if (!dev || !dataBuffer || !fileSize) { + if (!dataBuffer || !fileSize) { ret = WDC_STATUS_INVALID_PARAMETER; goto end; } - if (wdc_get_max_transfer_len(dev, &maximumTransferLength) < 0) { + if (wdc_get_max_transfer_len(hdl, &maximumTransferLength) < 0) { ret = WDC_STATUS_FAILURE; goto end; } @@ -9931,7 +9799,7 @@ static int wdc_fetch_log_file_from_device(struct nvme_dev *dev, __u32 fileId, if (((offsetIdx * chunckSize) + buffSize) > fileSize) buffSize = (__u32)(fileSize - (offsetIdx * chunckSize)); /* Limitation in VU read buffer - offsetIdx and bufferSize are not greater than u32 */ - ret = wdc_de_VU_read_buffer(dev, fileId, spiDestn, + ret = wdc_de_VU_read_buffer(hdl, fileId, spiDestn, (__u32)((offsetIdx * chunckSize) / sizeof(__u32)), dataBuffer + (offsetIdx * chunckSize), &buffSize); if (ret != WDC_STATUS_SUCCESS) { fprintf(stderr, "ERROR: WDC: %s: wdc_de_VU_read_buffer failed with ret = %d, fileId = 0x%x, fileSize = 0x%lx\n", @@ -9941,7 +9809,7 @@ static int wdc_fetch_log_file_from_device(struct nvme_dev *dev, __u32 fileId, } } else { buffSize = (__u32)fileSize; - ret = wdc_de_VU_read_buffer(dev, fileId, spiDestn, + ret = wdc_de_VU_read_buffer(hdl, fileId, spiDestn, (__u32)((offsetIdx * chunckSize) / sizeof(__u32)), dataBuffer, &buffSize); if (ret != WDC_STATUS_SUCCESS) { @@ -9954,7 +9822,7 @@ static int wdc_fetch_log_file_from_device(struct nvme_dev *dev, __u32 fileId, return ret; } -static int wdc_de_get_dump_trace(struct nvme_dev *dev, const char *filePath, __u16 binFileNameLen, +static int wdc_de_get_dump_trace(struct nvme_transport_handle *hdl, const char *filePath, __u16 binFileNameLen, const char *binFileName) { int ret = WDC_STATUS_FAILURE; @@ -9969,17 +9837,17 @@ static int wdc_de_get_dump_trace(struct nvme_dev *dev, const char *filePath, __u __u32 i; __u32 maximumTransferLength = 0; - if (!dev || !binFileName || !filePath) { + if (!binFileName || !filePath) { ret = WDC_STATUS_INVALID_PARAMETER; return ret; } - if (wdc_get_max_transfer_len(dev, &maximumTransferLength) < 0) + if (wdc_get_max_transfer_len(hdl, &maximumTransferLength) < 0) return WDC_STATUS_FAILURE; do { /* Get dumptrace size */ - ret = wdc_de_VU_read_size(dev, 0, WDC_DE_DUMPTRACE_DESTINATION, &dumptraceSize); + ret = wdc_de_VU_read_size(hdl, 0, WDC_DE_DUMPTRACE_DESTINATION, &dumptraceSize); if (ret != WDC_STATUS_SUCCESS) { fprintf(stderr, "ERROR: WDC: %s: wdc_de_VU_read_size failed with ret = %d\n", __func__, ret); @@ -10022,7 +9890,7 @@ static int wdc_de_get_dump_trace(struct nvme_dev *dev, const char *filePath, __u if (i == (chunks - 1)) readBufferLen = lastPktReadBufferLen; - ret = wdc_de_VU_read_buffer(dev, 0, WDC_DE_DUMPTRACE_DESTINATION, 0, + ret = wdc_de_VU_read_buffer(hdl, 0, WDC_DE_DUMPTRACE_DESTINATION, 0, readBuffer + offset, &readBufferLen); if (ret != WDC_STATUS_SUCCESS) { fprintf(stderr, @@ -10048,11 +9916,11 @@ static int wdc_de_get_dump_trace(struct nvme_dev *dev, const char *filePath, __u return ret; } -int wdc_fetch_vu_file_directory(struct nvme_dev *dev, +int wdc_fetch_vu_file_directory(struct nvme_transport_handle *hdl, struct WDC_DE_VU_LOG_DIRECTORY deEssentialsList, __s8 *bufferFolderPath, __u8 *serialNo, __u8 *timeString) { - int ret = wdc_fetch_log_directory(dev, &deEssentialsList); + int ret = wdc_fetch_log_directory(hdl, &deEssentialsList); __u32 listIdx; char *dataBuffer; char fileName[MAX_PATH_LEN]; @@ -10071,7 +9939,7 @@ int wdc_fetch_vu_file_directory(struct nvme_dev *dev, } else { /* Fetch Log File Data */ dataBuffer = (char *)calloc(1, (size_t)deEssentialsList.logEntry[listIdx].metaData.fileSize); - ret = wdc_fetch_log_file_from_device(dev, + ret = wdc_fetch_log_file_from_device(hdl, deEssentialsList.logEntry[listIdx].metaData.fileID, WDC_DE_DESTN_SPI, deEssentialsList.logEntry[listIdx].metaData.fileSize, @@ -10099,11 +9967,11 @@ int wdc_fetch_vu_file_directory(struct nvme_dev *dev, return ret; } -int wdc_read_debug_directory(struct nvme_dev *dev, __s8 *bufferFolderPath, __u8 *serialNo, +int wdc_read_debug_directory(struct nvme_transport_handle *hdl, __s8 *bufferFolderPath, __u8 *serialNo, __u8 *timeString) { __u32 maxNumOfVUFiles = 0; - int ret = wdc_get_log_dir_max_entries(dev, &maxNumOfVUFiles); + int ret = wdc_get_log_dir_max_entries(hdl, &maxNumOfVUFiles); struct WDC_DE_VU_LOG_DIRECTORY deEssentialsList; if (ret != WDC_STATUS_SUCCESS) { @@ -10116,7 +9984,7 @@ int wdc_read_debug_directory(struct nvme_dev *dev, __s8 *bufferFolderPath, __u8 (struct WDC_DRIVE_ESSENTIALS *)calloc(1, sizeof(struct WDC_DRIVE_ESSENTIALS) * maxNumOfVUFiles); deEssentialsList.maxNumLogEntries = maxNumOfVUFiles; - ret = wdc_fetch_vu_file_directory(dev, deEssentialsList, bufferFolderPath, serialNo, + ret = wdc_fetch_vu_file_directory(hdl, deEssentialsList, bufferFolderPath, serialNo, timeString); free(deEssentialsList.logEntry); @@ -10125,7 +9993,7 @@ int wdc_read_debug_directory(struct nvme_dev *dev, __s8 *bufferFolderPath, __u8 return ret; } -static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev, +static int wdc_do_drive_essentials(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl, char *dir, char *key) { int ret = 0; @@ -10164,7 +10032,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev, memset(tarCmd, 0, sizeof(tarCmd)); memset(&timeInfo, 0, sizeof(timeInfo)); - if (wdc_get_serial_and_fw_rev(dev, (char *)idSerialNo, (char *)idFwRev)) { + if (wdc_get_serial_and_fw_rev(hdl, (char *)idSerialNo, (char *)idFwRev)) { fprintf(stderr, "ERROR: WDC: get serial # and fw revision failed\n"); return -1; } @@ -10215,7 +10083,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev, /* Get Identify Controller Data */ memset(&ctrl, 0, sizeof(struct nvme_id_ctrl)); - ret = nvme_identify_ctrl(dev_fd(dev), &ctrl); + ret = nvme_identify_ctrl(hdl, &ctrl); if (ret) { fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed, ret = %d\n", ret); return -1; @@ -10227,7 +10095,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev, wdc_WriteToFile(fileName, (char *)&ctrl, sizeof(struct nvme_id_ctrl)); memset(&ns, 0, sizeof(struct nvme_id_ns)); - ret = nvme_identify_ns(dev_fd(dev), 1, &ns); + ret = nvme_identify_ns(hdl, 1, &ns); if (ret) { fprintf(stderr, "ERROR: WDC: nvme_identify_ns() failed, ret = %d\n", ret); } else { @@ -10242,8 +10110,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev, dataBuffer = calloc(1, elogBufferSize); elogBuffer = (struct nvme_error_log_page *)dataBuffer; - ret = nvme_get_log_error(dev_fd(dev), elogNumEntries, false, - elogBuffer); + ret = nvme_get_log_error(hdl, NVME_NSID_ALL, elogNumEntries, elogBuffer); if (ret) { fprintf(stderr, "ERROR: WDC: nvme_error_log() failed, ret = %d\n", ret); } else { @@ -10257,8 +10124,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev, /* Get Smart log page */ memset(&smart_log, 0, sizeof(struct nvme_smart_log)); - ret = nvme_get_log_smart(dev_fd(dev), NVME_NSID_ALL, false, - &smart_log); + ret = nvme_get_log_smart(hdl, NVME_NSID_ALL, &smart_log); if (ret) { fprintf(stderr, "ERROR: WDC: nvme_smart_log() failed, ret = %d\n", ret); } else { @@ -10269,7 +10135,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev, /* Get FW Slot log page */ memset(&fw_log, 0, sizeof(struct nvme_firmware_slot)); - ret = nvme_get_log_fw_slot(dev_fd(dev), false, &fw_log); + ret = nvme_get_log_fw_slot(hdl, false, &fw_log); if (ret) { fprintf(stderr, "ERROR: WDC: nvme_fw_log() failed, ret = %d\n", ret); } else { @@ -10288,9 +10154,9 @@ static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev, dataBuffer = calloc(1, dataBufferSize); memset(dataBuffer, 0, dataBufferSize); - ret = nvme_get_log_simple(dev_fd(dev), + ret = nvme_get_log_simple(hdl, deVULogPagesList[vuLogIdx].logPageId, - dataBufferSize, dataBuffer); + dataBuffer, dataBufferSize); if (ret) { fprintf(stderr, "ERROR: WDC: nvme_get_log() for log page 0x%x failed, ret = %d\n", deVULogPagesList[vuLogIdx].logPageId, ret); @@ -10313,12 +10179,10 @@ static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev, /* skipping LbaRangeType as it is an optional nvme command and not supported */ if (deFeatureIdList[listIdx].featureId == FID_LBA_RANGE_TYPE) continue; - ret = nvme_get_features_data(dev_fd(dev), - (enum nvme_features_id)deFeatureIdList[listIdx].featureId, - WDC_DE_GLOBAL_NSID, - sizeof(featureIdBuff), - &featureIdBuff, &result); - + ret = nvme_get_features(hdl, WDC_DE_GLOBAL_NSID, + (enum nvme_features_id)deFeatureIdList[listIdx].featureId, + NVME_GET_FEATURES_SEL_CURRENT, 0, 0, &featureIdBuff, + sizeof(featureIdBuff), &result); if (ret) { fprintf(stderr, "ERROR: WDC: nvme_get_feature id 0x%x failed, ret = %d\n", deFeatureIdList[listIdx].featureId, ret); @@ -10330,11 +10194,11 @@ static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev, } } - ret = wdc_read_debug_directory(dev, bufferFolderPath, serialNo, timeString); + ret = wdc_read_debug_directory(hdl, bufferFolderPath, serialNo, timeString); /* Get Dump Trace Data */ wdc_UtilsSnprintf(fileName, MAX_PATH_LEN, "%s%s%s_%s_%s.bin", (char *)bufferFolderPath, WDC_DE_PATH_SEPARATOR, "dumptrace", serialNo, timeString); - ret = wdc_de_get_dump_trace(dev, (char *)bufferFolderPath, 0, fileName); + ret = wdc_de_get_dump_trace(hdl, (char *)bufferFolderPath, 0, fileName); if (ret != WDC_STATUS_SUCCESS) fprintf(stderr, "ERROR: WDC: wdc_de_get_dump_trace failed, ret = %d\n", ret); @@ -10356,20 +10220,19 @@ static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev, ret); fprintf(stderr, "Get of Drive Essentials data successful\n"); - nvme_free_tree(r); return 0; } -static int wdc_drive_essentials(int argc, char **argv, struct command *command, +static int wdc_drive_essentials(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Capture Drive Essentials."; const char *dirName = "Output directory pathname."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; char d[PATH_MAX] = {0}; char k[PATH_MAX] = {0}; __u64 capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; char *d_ptr; int ret; @@ -10387,12 +10250,16 @@ static int wdc_drive_essentials(int argc, char **argv, struct command *command, }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); + if (ret) + return ret; + + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret) return ret; - r = nvme_scan(NULL); - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); + if ((capabilities & WDC_DRIVE_CAP_DRIVE_ESSENTIALS) != WDC_DRIVE_CAP_DRIVE_ESSENTIALS) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; @@ -10406,14 +10273,12 @@ static int wdc_drive_essentials(int argc, char **argv, struct command *command, d_ptr = NULL; } - ret = wdc_do_drive_essentials(r, dev, d_ptr, k); + ret = wdc_do_drive_essentials(ctx, hdl, d_ptr, k); out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_do_drive_resize(struct nvme_dev *dev, uint64_t new_size) +static int wdc_do_drive_resize(struct nvme_transport_handle *hdl, uint64_t new_size) { int ret; struct nvme_passthru_cmd admin_cmd; @@ -10424,11 +10289,11 @@ static int wdc_do_drive_resize(struct nvme_dev *dev, uint64_t new_size) WDC_NVME_DRIVE_RESIZE_CMD); admin_cmd.cdw13 = new_size; - ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); return ret; } -static int wdc_do_namespace_resize(struct nvme_dev *dev, __u32 nsid, __u32 op_option) +static int wdc_do_namespace_resize(struct nvme_transport_handle *hdl, __u32 nsid, __u32 op_option) { int ret; struct nvme_passthru_cmd admin_cmd; @@ -10438,11 +10303,11 @@ static int wdc_do_namespace_resize(struct nvme_dev *dev, __u32 nsid, __u32 op_op admin_cmd.nsid = nsid; admin_cmd.cdw10 = op_option; - ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); return ret; } -static int wdc_do_drive_info(struct nvme_dev *dev, __u32 *result) +static int wdc_do_drive_info(struct nvme_transport_handle *hdl, __u32 *result) { int ret; struct nvme_passthru_cmd admin_cmd; @@ -10452,7 +10317,7 @@ static int wdc_do_drive_info(struct nvme_dev *dev, __u32 *result) admin_cmd.cdw12 = ((WDC_NVME_DRIVE_INFO_SUBCMD << WDC_NVME_SUBCMD_SHIFT) | WDC_NVME_DRIVE_INFO_CMD); - ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (!ret && result) *result = admin_cmd.result; @@ -10465,9 +10330,9 @@ static int wdc_drive_resize(int argc, char **argv, { const char *desc = "Send a Resize command."; const char *size = "The new size (in GB) to resize the drive to."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; uint64_t capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; int ret; struct config { @@ -10483,15 +10348,18 @@ static int wdc_drive_resize(int argc, char **argv, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); - wdc_check_device(r, dev); - capabilities = wdc_get_drive_capabilities(r, dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !wdc_check_device(ctx, hdl)) + return -1; + + capabilities = wdc_get_drive_capabilities(ctx, hdl); + if ((capabilities & WDC_DRIVE_CAP_RESIZE) == WDC_DRIVE_CAP_RESIZE) { - ret = wdc_do_drive_resize(dev, cfg.size); + ret = wdc_do_drive_resize(hdl, cfg.size); } else { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; @@ -10501,8 +10369,6 @@ static int wdc_drive_resize(int argc, char **argv, printf("New size: %" PRIu64 " GB\n", cfg.size); nvme_show_status(ret); - nvme_free_tree(r); - dev_close(dev); return ret; } @@ -10512,9 +10378,9 @@ static int wdc_namespace_resize(int argc, char **argv, const char *desc = "Send a Namespace Resize command."; const char *namespace_id = "The namespace id to resize."; const char *op_option = "The over provisioning option to set for namespace."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; uint64_t capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; int ret; struct config { @@ -10533,22 +10399,24 @@ static int wdc_namespace_resize(int argc, char **argv, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; if ((cfg.op_option != 0x1) && (cfg.op_option != 0x2) && (cfg.op_option != 0x3) && (cfg.op_option != 0xF)) { fprintf(stderr, "ERROR: WDC: unsupported OP option parameter\n"); - dev_close(dev); return -1; } - r = nvme_scan(NULL); - wdc_check_device(r, dev); - capabilities = wdc_get_drive_capabilities(r, dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !wdc_check_device(ctx, hdl)) + return -1; + + capabilities = wdc_get_drive_capabilities(ctx, hdl); + if ((capabilities & WDC_DRIVE_CAP_NS_RESIZE) == WDC_DRIVE_CAP_NS_RESIZE) { - ret = wdc_do_namespace_resize(dev, cfg.namespace_id, + ret = wdc_do_namespace_resize(hdl, cfg.namespace_id, cfg.op_option); if (ret) @@ -10559,8 +10427,6 @@ static int wdc_namespace_resize(int argc, char **argv, } nvme_show_status(ret); - nvme_free_tree(r); - dev_close(dev); return ret; } @@ -10570,8 +10436,8 @@ static int wdc_reason_identifier(int argc, char **argv, const char *desc = "Retrieve telemetry log reason identifier."; const char *log_id = "Log ID to retrieve - host - 7 or controller - 8"; const char *fname = "File name to save raw binary identifier"; - struct nvme_dev *dev; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; int ret; uint64_t capabilities = 0; char f[PATH_MAX] = {0}; @@ -10595,18 +10461,19 @@ static int wdc_reason_identifier(int argc, char **argv, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; - r = nvme_scan(NULL); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret) + return ret; if (cfg.log_id != NVME_LOG_LID_TELEMETRY_HOST && cfg.log_id != NVME_LOG_LID_TELEMETRY_CTRL) { fprintf(stderr, "ERROR: WDC: Invalid Log ID. It must be 7 (Host) or 8 (Controller)\n"); - ret = -1; - goto close_dev; + return -1; } if (cfg.file) { @@ -10616,8 +10483,7 @@ static int wdc_reason_identifier(int argc, char **argv, verify_file = open(cfg.file, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (verify_file < 0) { fprintf(stderr, "ERROR: WDC: open: %s\n", strerror(errno)); - ret = -1; - goto close_dev; + return -1; } close(verify_file); strncpy(f, cfg.file, PATH_MAX - 1); @@ -10632,24 +10498,22 @@ static int wdc_reason_identifier(int argc, char **argv, else snprintf(fileSuffix, PATH_MAX, "_error_reason_identifier_host_%s", (char *)timeStamp); - if (wdc_get_serial_name(dev, f, PATH_MAX, fileSuffix) == -1) { + if (wdc_get_serial_name(hdl, f, PATH_MAX, fileSuffix) == -1) { fprintf(stderr, "ERROR: WDC: failed to generate file name\n"); - ret = -1; - goto close_dev; + return -1; } if (strlen(f) > PATH_MAX - 5) { fprintf(stderr, "ERROR: WDC: file name overflow\n"); - ret = -1; - goto close_dev; + return -1; } strcat(f, ".bin"); } fprintf(stderr, "%s: filename = %s\n", __func__, f); - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if ((capabilities & WDC_DRIVE_CAP_REASON_ID) == WDC_DRIVE_CAP_REASON_ID) { - ret = wdc_do_get_reason_id(dev, f, cfg.log_id); + ret = wdc_do_get_reason_id(hdl, f, cfg.log_id); } else { fprintf(stderr, "ERROR: WDC:unsupported device for this command\n"); ret = -1; @@ -10657,9 +10521,6 @@ static int wdc_reason_identifier(int argc, char **argv, nvme_show_status(ret); -close_dev: - dev_close(dev); - nvme_free_tree(r); return ret; } @@ -10688,7 +10549,7 @@ static const char *nvme_log_id_to_string(__u8 log_id) return "ANA Log ID"; case NVME_LOG_LID_PERSISTENT_EVENT: return "Persistent Event Log ID"; - case NVME_LOG_LID_DISCOVER: + case NVME_LOG_LID_DISCOVERY: return "Discovery Log ID"; case NVME_LOG_LID_RESERVATION: return "Reservation Notification Log ID"; @@ -10832,14 +10693,14 @@ static void __show_log_page_directory(struct log_page_directory *directory) } } -static int wdc_log_page_directory(int argc, char **argv, struct command *command, +static int wdc_log_page_directory(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Log Page Directory."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t fmt; - struct nvme_dev *dev; int ret = 0; - nvme_root_t r; __u64 capabilities = 0; struct wdc_c2_cbs_data *cbs_data = NULL; int i, uuid_index = 0; @@ -10861,26 +10722,28 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; ret = validate_output_format(cfg.output_format, &fmt); if (ret < 0) { fprintf(stderr, "%s: ERROR: WDC: invalid output format\n", __func__); - dev_close(dev); return ret; } - r = nvme_scan(NULL); - capabilities = wdc_get_drive_capabilities(r, dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret) + return ret; + + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_LOG_PAGE_DIR)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; } else { memset(&uuid_list, 0, sizeof(struct nvme_id_uuid_list)); - if (wdc_CheckUuidListSupport(dev, &uuid_list)) + if (wdc_CheckUuidListSupport(hdl, &uuid_list)) uuid_supported = true; if (uuid_supported) @@ -10889,7 +10752,7 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command fprintf(stderr, "WDC: UUID lists NOT supported\n"); - ret = wdc_get_pci_ids(r, dev, &device_id, &read_vendor_id); + ret = wdc_get_pci_ids(ctx, hdl, &device_id, &read_vendor_id); log_id = wdc_is_zn350(device_id) ? WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_ID_C8 : WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_ID; @@ -10903,14 +10766,14 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command uuid_index = 0; /* verify the 0xC2 Device Manageability log page is supported */ - if (!wdc_nvme_check_supported_log_page(r, dev, log_id, uuid_index)) { + if (!wdc_nvme_check_supported_log_page(ctx, hdl, log_id, uuid_index)) { fprintf(stderr, "%s: ERROR: WDC: 0x%x Log Page not supported\n", __func__, log_id); ret = -1; goto out; } - if (!get_dev_mgment_cbs_data(r, dev, + if (!get_dev_mgment_cbs_data(ctx, hdl, WDC_C2_LOG_PAGES_SUPPORTED_ID, (void *)&cbs_data)) { fprintf(stderr, @@ -10965,7 +10828,7 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command } dir = (struct log_page_directory *)data; - ret = nvme_admin_passthru(dev_fd(dev), WDC_NVME_ADMIN_VUC_OPCODE_D2, 0, 0, + ret = nvme_admin_passthru(hdl, WDC_NVME_ADMIN_VUC_OPCODE_D2, 0, 0, 0, 0, 0, 8, 0, WDC_VUC_SUBOPCODE_LOG_PAGE_DIR_D2, 0, 0, 0, 32, data, 0, NULL, @@ -10990,24 +10853,22 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command } out: - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_get_drive_reason_id(struct nvme_dev *dev, char *drive_reason_id, size_t len) +static int wdc_get_drive_reason_id(struct nvme_transport_handle *hdl, char *drive_reason_id, size_t len) { + const char *reason_id_str = "reason_id"; + struct nvme_id_ctrl ctrl; + int res_len = 0; int i, j; int ret; - int res_len = 0; - struct nvme_id_ctrl ctrl; - const char *reason_id_str = "reason_id"; i = sizeof(ctrl.sn) - 1; j = sizeof(ctrl.mn) - 1; memset(drive_reason_id, 0, len); memset(&ctrl, 0, sizeof(struct nvme_id_ctrl)); - ret = nvme_identify_ctrl(dev_fd(dev), &ctrl); + ret = nvme_identify_ctrl(hdl, &ctrl); if (ret) { fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", ret); return -1; @@ -11033,7 +10894,7 @@ static int wdc_get_drive_reason_id(struct nvme_dev *dev, char *drive_reason_id, return 0; } -static int wdc_save_reason_id(struct nvme_dev *dev, __u8 *rsn_ident, int size) +static int wdc_save_reason_id(struct nvme_transport_handle *hdl, __u8 *rsn_ident, int size) { int ret = 0; char *reason_id_file; @@ -11041,7 +10902,7 @@ static int wdc_save_reason_id(struct nvme_dev *dev, __u8 *rsn_ident, int size) char reason_id_path[PATH_MAX] = WDC_REASON_ID_PATH_NAME; struct stat st = {0}; - if (wdc_get_drive_reason_id(dev, drive_reason_id, PATH_MAX) == -1) { + if (wdc_get_drive_reason_id(hdl, drive_reason_id, PATH_MAX) == -1) { fprintf(stderr, "%s: ERROR: failed to get drive reason id\n", __func__); return -1; } @@ -11068,14 +10929,14 @@ static int wdc_save_reason_id(struct nvme_dev *dev, __u8 *rsn_ident, int size) return ret; } -static int wdc_clear_reason_id(struct nvme_dev *dev) +static int wdc_clear_reason_id(struct nvme_transport_handle *hdl) { int ret = -1; int verify_file; char *reason_id_file; char drive_reason_id[PATH_MAX] = {0}; - if (wdc_get_drive_reason_id(dev, drive_reason_id, PATH_MAX) == -1) { + if (wdc_get_drive_reason_id(hdl, drive_reason_id, PATH_MAX) == -1) { fprintf(stderr, "%s: ERROR: failed to get drive reason id\n", __func__); return -1; } @@ -11101,15 +10962,14 @@ static int wdc_clear_reason_id(struct nvme_dev *dev) return ret; } -static int wdc_dump_telemetry_hdr(struct nvme_dev *dev, int log_id, struct nvme_telemetry_log *log_hdr) +static int wdc_dump_telemetry_hdr(struct nvme_transport_handle *hdl, int log_id, struct nvme_telemetry_log *log_hdr) { int ret = 0; if (log_id == NVME_LOG_LID_TELEMETRY_HOST) - ret = nvme_get_log_create_telemetry_host(dev_fd(dev), log_hdr); + ret = nvme_get_log_create_telemetry_host(hdl, log_hdr); else - ret = nvme_get_log_telemetry_ctrl(dev_fd(dev), false, 0, 512, - (void *)log_hdr); + ret = nvme_get_log_telemetry_ctrl(hdl, false, 0, (void *)log_hdr, 512); if (ret < 0) { perror("get-telemetry-log"); @@ -11121,7 +10981,7 @@ static int wdc_dump_telemetry_hdr(struct nvme_dev *dev, int log_id, struct nvme_ return ret; } -static int wdc_do_get_reason_id(struct nvme_dev *dev, const char *file, int log_id) +static int wdc_do_get_reason_id(struct nvme_transport_handle *hdl, const char *file, int log_id) { int ret; struct nvme_telemetry_log *log_hdr; @@ -11136,7 +10996,7 @@ static int wdc_do_get_reason_id(struct nvme_dev *dev, const char *file, int log_ } memset(log_hdr, 0, log_hdr_size); - ret = wdc_dump_telemetry_hdr(dev, log_id, log_hdr); + ret = wdc_dump_telemetry_hdr(hdl, log_id, log_hdr); if (ret) { fprintf(stderr, "%s: ERROR: get telemetry header failed, ret : %d\n", __func__, ret); ret = -1; @@ -11146,7 +11006,7 @@ static int wdc_do_get_reason_id(struct nvme_dev *dev, const char *file, int log_ reason_id_size = sizeof(log_hdr->rsnident); if (log_id == NVME_LOG_LID_TELEMETRY_CTRL) - wdc_save_reason_id(dev, log_hdr->rsnident, reason_id_size); + wdc_save_reason_id(hdl, log_hdr->rsnident, reason_id_size); ret = wdc_create_log_file(file, (__u8 *)log_hdr->rsnident, reason_id_size); @@ -11498,14 +11358,14 @@ static void wdc_print_pcie_stats_json(struct wdc_vs_pcie_stats *pcie_stats) json_free_object(root); } -static int wdc_do_vs_nand_stats_sn810_2(struct nvme_dev *dev, char *format) +static int wdc_do_vs_nand_stats_sn810_2(struct nvme_transport_handle *hdl, char *format) { nvme_print_flags_t fmt; uint8_t *data = NULL; int ret; data = NULL; - ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data, 0, + ret = nvme_get_ext_smart_cloud_log(hdl, &data, 0, NVME_NSID_ALL); if (ret) { @@ -11536,7 +11396,7 @@ static int wdc_do_vs_nand_stats_sn810_2(struct nvme_dev *dev, char *format) return ret; } -static int wdc_do_vs_nand_stats(struct nvme_dev *dev, char *format) +static int wdc_do_vs_nand_stats(struct nvme_transport_handle *hdl, char *format) { nvme_print_flags_t fmt; uint8_t *output = NULL; @@ -11550,8 +11410,8 @@ static int wdc_do_vs_nand_stats(struct nvme_dev *dev, char *format) goto out; } - ret = nvme_get_log_simple(dev_fd(dev), WDC_NVME_NAND_STATS_LOG_ID, - WDC_NVME_NAND_STATS_SIZE, (void *)output); + ret = nvme_get_log_simple(hdl, WDC_NVME_NAND_STATS_LOG_ID, + (void *)output, WDC_NVME_NAND_STATS_SIZE); if (ret) { fprintf(stderr, "ERROR: WDC: %s : Failed to retrieve NAND stats\n", __func__); goto out; @@ -11582,12 +11442,12 @@ static int wdc_do_vs_nand_stats(struct nvme_dev *dev, char *format) return ret; } -static int wdc_vs_nand_stats(int argc, char **argv, struct command *command, +static int wdc_vs_nand_stats(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve NAND statistics."; - struct nvme_dev *dev; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; __u64 capabilities = 0; uint32_t read_device_id = 0, read_vendor_id = 0; int ret; @@ -11605,18 +11465,21 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); + if (ret) + return ret; + + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret) return ret; - r = nvme_scan(NULL); - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_NAND_STATS)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; } else { - ret = wdc_get_pci_ids(r, dev, &read_device_id, &read_vendor_id); + ret = wdc_get_pci_ids(ctx, hdl, &read_device_id, &read_vendor_id); if (ret < 0) { fprintf(stderr, "ERROR: WDC: %s: failure to get pci ids, ret = %d\n", __func__, ret); return -1; @@ -11624,11 +11487,11 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command, switch (read_device_id) { case WDC_NVME_SN820CL_DEV_ID: - ret = wdc_do_vs_nand_stats_sn810_2(dev, + ret = wdc_do_vs_nand_stats_sn810_2(hdl, cfg.output_format); break; default: - ret = wdc_do_vs_nand_stats(dev, cfg.output_format); + ret = wdc_do_vs_nand_stats(hdl, cfg.output_format); break; } } @@ -11636,12 +11499,10 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command, if (ret) fprintf(stderr, "ERROR: WDC: Failure reading NAND statistics, ret = %d\n", ret); - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_do_vs_pcie_stats(struct nvme_dev *dev, +static int wdc_do_vs_pcie_stats(struct nvme_transport_handle *hdl, struct wdc_vs_pcie_stats *pcieStatsPtr) { int ret; @@ -11653,18 +11514,18 @@ static int wdc_do_vs_pcie_stats(struct nvme_dev *dev, admin_cmd.addr = (__u64)(uintptr_t)pcieStatsPtr; admin_cmd.data_len = pcie_stats_size; - ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); return ret; } -static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command, +static int wdc_vs_pcie_stats(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve PCIE statistics."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t fmt; - struct nvme_dev *dev; - nvme_root_t r; int ret; __u64 capabilities = 0; _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; @@ -11684,11 +11545,14 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); + if (ret) + return ret; + + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret) return ret; - r = nvme_scan(NULL); ret = validate_output_format(cfg.output_format, &fmt); if (ret < 0) { fprintf(stderr, "ERROR: WDC: invalid output format\n"); @@ -11704,13 +11568,13 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command, memset((void *)pcieStatsPtr, 0, pcie_stats_size); - capabilities = wdc_get_drive_capabilities(r, dev); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_PCIE_STATS)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; } else { - ret = wdc_do_vs_pcie_stats(dev, pcieStatsPtr); + ret = wdc_do_vs_pcie_stats(hdl, pcieStatsPtr); if (ret) { fprintf(stderr, "ERROR: WDC: Failure reading PCIE statistics, ret = 0x%x\n", ret); } else { @@ -11728,8 +11592,6 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command, } } out: - nvme_free_tree(r); - dev_close(dev); return ret; } @@ -11737,10 +11599,10 @@ static int wdc_vs_drive_info(int argc, char **argv, struct command *command, struct plugin *plugin) { const char *desc = "Send a vs-drive-info command."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t fmt; - nvme_root_t r; uint64_t capabilities = 0; - struct nvme_dev *dev; int ret; __le32 result; __u16 size; @@ -11773,31 +11635,31 @@ static int wdc_vs_drive_info(int argc, char **argv, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; ret = validate_output_format(cfg.output_format, &fmt); if (ret < 0) { fprintf(stderr, "ERROR: WDC %s invalid output format\n", __func__); - dev_close(dev); return ret; } /* get the id ctrl data used to fill in drive info below */ - ret = nvme_identify_ctrl(dev_fd(dev), &ctrl); - + ret = nvme_identify_ctrl(hdl, &ctrl); if (ret) { fprintf(stderr, "ERROR: WDC %s: Identify Controller failed\n", __func__); - dev_close(dev); return ret; } - r = nvme_scan(NULL); - wdc_check_device(r, dev); - capabilities = wdc_get_drive_capabilities(r, dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !wdc_check_device(ctx, hdl)) + return -1; + + capabilities = wdc_get_drive_capabilities(ctx, hdl); + if ((capabilities & WDC_DRIVE_CAP_INFO) == WDC_DRIVE_CAP_INFO) { - ret = wdc_get_pci_ids(r, dev, &read_device_id, &read_vendor_id); + ret = wdc_get_pci_ids(ctx, hdl, &read_device_id, &read_vendor_id); if (ret < 0) { fprintf(stderr, "ERROR: WDC: %s: failure to get pci ids, ret = %d\n", __func__, ret); goto out; @@ -11821,7 +11683,7 @@ static int wdc_vs_drive_info(int argc, char **argv, case WDC_NVME_SN550_DEV_ID: case WDC_NVME_ZN350_DEV_ID: case WDC_NVME_ZN350_DEV_ID_1: - ret = wdc_do_drive_info(dev, &result); + ret = wdc_do_drive_info(hdl, &result); if (!ret) { size = (__u16)((cpu_to_le32(result) & 0xffff0000) >> 16); @@ -11871,7 +11733,7 @@ static int wdc_vs_drive_info(int argc, char **argv, break; case WDC_NVME_SN820CL_DEV_ID: /* Get the Drive HW Rev from the C6 Log page */ - ret = nvme_get_hw_rev_log(dev_fd(dev), &data, 0, + ret = nvme_get_hw_rev_log(hdl, &data, 0, NVME_NSID_ALL); if (!ret) { struct wdc_nvme_hw_rev_log *log_data = (struct wdc_nvme_hw_rev_log *)data; @@ -11893,7 +11755,7 @@ static int wdc_vs_drive_info(int argc, char **argv, goto out; } - ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data, + ret = nvme_get_ext_smart_cloud_log(hdl, &data, 0, NVME_NSID_ALL); if (!ret) { @@ -11945,7 +11807,7 @@ static int wdc_vs_drive_info(int argc, char **argv, if (data_len % 4 != 0) num_dwords += 1; - ret = nvme_admin_passthru(dev_fd(dev), + ret = nvme_admin_passthru(hdl, WDC_NVME_ADMIN_VUC_OPCODE_D2, 0, 0, 0, 0, 0, num_dwords, 0, WDC_VUC_SUBOPCODE_VS_DRIVE_INFO_D2, @@ -11995,8 +11857,6 @@ static int wdc_vs_drive_info(int argc, char **argv, out: nvme_show_status(ret); - nvme_free_tree(r); - dev_close(dev); return ret; } @@ -12004,11 +11864,11 @@ static int wdc_vs_temperature_stats(int argc, char **argv, struct command *command, struct plugin *plugin) { const char *desc = "Send a vs-temperature-stats command."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct nvme_smart_log smart_log; struct nvme_id_ctrl id_ctrl; nvme_print_flags_t fmt; - struct nvme_dev *dev; - nvme_root_t r; uint64_t capabilities = 0; __u32 hctm_tmt; int temperature, temp_tmt1, temp_tmt2; @@ -12027,11 +11887,14 @@ static int wdc_vs_temperature_stats(int argc, char **argv, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); + if (ret) + return ret; + + ret = nvme_scan_topology(ctx, NULL, NULL); if (ret) return ret; - r = nvme_scan(NULL); ret = validate_output_format(cfg.output_format, &fmt); if (ret < 0) { fprintf(stderr, "ERROR: WDC: invalid output format\n"); @@ -12039,8 +11902,8 @@ static int wdc_vs_temperature_stats(int argc, char **argv, } /* check if command is supported */ - wdc_check_device(r, dev); - capabilities = wdc_get_drive_capabilities(r, dev); + wdc_check_device(ctx, hdl); + capabilities = wdc_get_drive_capabilities(ctx, hdl); if ((capabilities & WDC_DRIVE_CAP_TEMP_STATS) != WDC_DRIVE_CAP_TEMP_STATS) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); ret = -1; @@ -12048,11 +11911,10 @@ static int wdc_vs_temperature_stats(int argc, char **argv, } /* get the temperature stats or report errors */ - ret = nvme_identify_ctrl(dev_fd(dev), &id_ctrl); + ret = nvme_identify_ctrl(hdl, &id_ctrl); if (ret) goto out; - ret = nvme_get_log_smart(dev_fd(dev), NVME_NSID_ALL, false, - &smart_log); + ret = nvme_get_log_smart(hdl, NVME_NSID_ALL, &smart_log); if (ret) goto out; @@ -12060,14 +11922,15 @@ static int wdc_vs_temperature_stats(int argc, char **argv, temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]) - 273; /* retrieve HCTM Thermal Management Temperatures */ - nvme_get_features_simple(dev_fd(dev), 0x10, 0, &hctm_tmt); + nvme_get_features_simple(hdl, 0x10, + NVME_GET_FEATURES_SEL_CURRENT, &hctm_tmt); temp_tmt1 = ((hctm_tmt >> 16) & 0xffff) ? ((hctm_tmt >> 16) & 0xffff) - 273 : 0; temp_tmt2 = (hctm_tmt & 0xffff) ? (hctm_tmt & 0xffff) - 273 : 0; if (fmt == NORMAL) { /* print the temperature stats */ printf("Temperature Stats for NVME device:%s namespace-id:%x\n", - dev->name, WDC_DE_GLOBAL_NSID); + nvme_transport_handle_get_name(hdl), WDC_DE_GLOBAL_NSID); printf("Current Composite Temperature : %d °C\n", temperature); printf("WCTEMP : %"PRIu16" °C\n", id_ctrl.wctemp - 273); @@ -12113,34 +11976,34 @@ static int wdc_vs_temperature_stats(int argc, char **argv, out: nvme_show_status(ret); - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_capabilities(int argc, char **argv, struct command *command, struct plugin *plugin) +static int wdc_capabilities(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send a capabilities command."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; uint64_t capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; int ret; OPT_ARGS(opts) = { OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; /* get capabilities */ - r = nvme_scan(NULL); - wdc_check_device(r, dev); - capabilities = wdc_get_drive_capabilities(r, dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !wdc_check_device(ctx, hdl)) + return -1; + + capabilities = wdc_get_drive_capabilities(ctx, hdl); /* print command and supported status */ - printf("WDC Plugin Capabilities for NVME device:%s\n", dev->name); + printf("WDC Plugin Capabilities for NVME device:%s\n", nvme_transport_handle_get_name(hdl)); printf("cap-diag : %s\n", capabilities & WDC_DRIVE_CAP_CAP_DIAG ? "Supported" : "Not Supported"); printf("drive-log : %s\n", @@ -12219,32 +12082,32 @@ static int wdc_capabilities(int argc, char **argv, struct command *command, stru printf("set-latency-monitor-feature : %s\n", capabilities & WDC_DRIVE_CAP_SET_LATENCY_MONITOR ? "Supported" : "Not Supported"); printf("capabilities : Supported\n"); - nvme_free_tree(r); - dev_close(dev); return 0; } -static int wdc_cloud_ssd_plugin_version(int argc, char **argv, struct command *command, +static int wdc_cloud_ssd_plugin_version(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Cloud SSD Plugin Version command."; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; uint64_t capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; int ret; OPT_ARGS(opts) = { OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; /* get capabilities */ - r = nvme_scan(NULL); - wdc_check_device(r, dev); - capabilities = wdc_get_drive_capabilities(r, dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !wdc_check_device(ctx, hdl)) + return -1; + + capabilities = wdc_get_drive_capabilities(ctx, hdl); if ((capabilities & WDC_DRIVE_CAP_CLOUD_SSD_VERSION) == WDC_DRIVE_CAP_CLOUD_SSD_VERSION) { /* print command and supported status */ @@ -12253,19 +12116,17 @@ static int wdc_cloud_ssd_plugin_version(int argc, char **argv, struct command *c fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); } - nvme_free_tree(r); - dev_close(dev); return 0; } -static int wdc_cloud_boot_SSD_version(int argc, char **argv, struct command *command, +static int wdc_cloud_boot_SSD_version(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Cloud Boot SSD Version command."; const char *namespace_id = "desired namespace id"; - nvme_root_t r; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; uint64_t capabilities = 0; - struct nvme_dev *dev; int ret; int major = 0, minor = 0; __u8 *data = NULL; @@ -12284,18 +12145,20 @@ static int wdc_cloud_boot_SSD_version(int argc, char **argv, struct command *com OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) return ret; /* get capabilities */ - r = nvme_scan(NULL); - wdc_check_device(r, dev); - capabilities = wdc_get_drive_capabilities(r, dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !wdc_check_device(ctx, hdl)) + return -1; + + capabilities = wdc_get_drive_capabilities(ctx, hdl); if ((capabilities & WDC_DRIVE_CAP_CLOUD_BOOT_SSD_VERSION) == WDC_DRIVE_CAP_CLOUD_BOOT_SSD_VERSION) { /* Get the 0xC0 Smart Cloud Attribute V1 log data */ - ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data, 0, + ret = nvme_get_ext_smart_cloud_log(hdl, &data, 0, cfg.namespace_id); ext_smart_log_ptr = (struct __packed wdc_nvme_ext_smart_log *)data; @@ -12315,18 +12178,17 @@ static int wdc_cloud_boot_SSD_version(int argc, char **argv, struct command *com fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); } - nvme_free_tree(r); - dev_close(dev); return ret; } -static int wdc_enc_get_log(int argc, char **argv, struct command *command, struct plugin *plugin) +static int wdc_enc_get_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Get Enclosure Log."; const char *file = "Output file pathname."; const char *size = "Data retrieval transfer size."; const char *log = "Enclosure Log Page ID."; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; FILE *output_fd; int xfer_size = 0; int len; @@ -12351,20 +12213,18 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command, struc OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) - goto ret; + return err; - if (!wdc_enc_check_model(dev)) { - err = -EINVAL; - goto closed_fd; - } + if (!wdc_enc_check_model(hdl)) + return -EINVAL; if (cfg.log_id > 0xff) { fprintf(stderr, "Invalid log identifier: %d. Valid 0xd1, 0xd2, 0xd3, 0xd4, 0xe2, 0xe4\n", cfg.log_id); - goto closed_fd; + return -EINVAL; } if (cfg.xfer_size) { @@ -12372,8 +12232,7 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command, struc if (!wdc_check_power_of_2(cfg.xfer_size)) { fprintf(stderr, "%s: ERROR: xfer-size (%d) must be a power of 2\n", __func__, cfg.xfer_size); - err = -EINVAL; - goto closed_fd; + return -EINVAL; } } @@ -12386,8 +12245,7 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command, struc if (!output_fd) { fprintf(stderr, "%s: ERROR: opening:%s: %s\n", __func__, cfg.file, strerror(errno)); - err = -EINVAL; - goto closed_fd; + return -EINVAL; } } else { output_fd = stdout; @@ -12398,12 +12256,12 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command, struc cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_4) { fprintf(stderr, "args - sz:%x logid:%x of:%s\n", xfer_size, cfg.log_id, cfg.file); - err = wdc_enc_get_nic_log(dev, cfg.log_id, xfer_size, + err = wdc_enc_get_nic_log(hdl, cfg.log_id, xfer_size, WDC_NVME_ENC_NIC_LOG_SIZE, output_fd); } else { fprintf(stderr, "args - sz:%x logid:%x of:%s\n", xfer_size, cfg.log_id, cfg.file); - err = wdc_enc_submit_move_data(dev, NULL, 0, xfer_size, output_fd, + err = wdc_enc_submit_move_data(hdl, NULL, 0, xfer_size, output_fd, cfg.log_id, 0, 0); } @@ -12415,13 +12273,10 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command, struc cfg.log_id); } } -closed_fd: - dev_close(dev); -ret: return err; } -static int wdc_enc_submit_move_data(struct nvme_dev *dev, char *cmd, int len, +static int wdc_enc_submit_move_data(struct nvme_transport_handle *hdl, char *cmd, int len, int xfer_size, FILE *out, int log_id, int cdw14, int cdw15) { @@ -12473,7 +12328,7 @@ static int wdc_enc_submit_move_data(struct nvme_dev *dev, char *cmd, int len, nvme_cmd.timeout_ms, nvme_cmd.result, md, d); #endif nvme_cmd.result = 0; - err = nvme_submit_admin_passthru(dev_fd(dev), &nvme_cmd, NULL); + err = nvme_submit_admin_passthru(hdl, &nvme_cmd, NULL); if (nvme_status_equals(err, NVME_STATUS_TYPE_NVME, NVME_SC_INTERNAL)) { fprintf(stderr, "%s: WARNING : WDC: No log ID:x%x available\n", __func__, log_id); } else if (err) { @@ -12498,7 +12353,7 @@ static int wdc_enc_submit_move_data(struct nvme_dev *dev, char *cmd, int len, nvme_cmd.cdw14 = cdw14; nvme_cmd.cdw15 = cdw15; nvme_cmd.result = 0; /* returned result !=0 indicates more data available */ - err = nvme_submit_admin_passthru(dev_fd(dev), + err = nvme_submit_admin_passthru(hdl, &nvme_cmd, NULL); if (err) { more = 0; @@ -12521,7 +12376,7 @@ static int wdc_enc_submit_move_data(struct nvme_dev *dev, char *cmd, int len, return err; } -static int wdc_enc_get_nic_log(struct nvme_dev *dev, __u8 log_id, __u32 xfer_size, __u32 data_len, FILE *out) +static int wdc_enc_get_nic_log(struct nvme_transport_handle *hdl, __u8 log_id, __u32 xfer_size, __u32 data_len, FILE *out) { __u8 *dump_data; __u32 curr_data_offset, curr_data_len; @@ -12559,7 +12414,7 @@ static int wdc_enc_get_nic_log(struct nvme_dev *dev, __u8 log_id, __u32 xfer_siz admin_cmd.nsid, admin_cmd.addr, admin_cmd.data_len, admin_cmd.cdw10, admin_cmd.cdw11, admin_cmd.cdw12, admin_cmd.cdw13, admin_cmd.cdw14); #endif - ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL); + ret = nvme_submit_admin_passthru(hdl, &admin_cmd, NULL); if (ret) { nvme_show_status(ret); fprintf(stderr, "%s: ERROR: WDC: Get chunk %d, size = 0x%x, offset = 0x%x, addr = 0x%lx\n", @@ -12591,17 +12446,17 @@ static int wdc_enc_get_nic_log(struct nvme_dev *dev, __u8 log_id, __u32 xfer_siz //------------------------------------------------------------------------------------ // Description: set latency monitor feature // -int wdc_set_latency_monitor_feature(int argc, char **argv, struct command *cmd, +int wdc_set_latency_monitor_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Set Latency Monitor feature."; + struct feature_latency_monitor buf = {0,}; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; uint64_t capabilities = 0; - struct nvme_dev *dev; - nvme_root_t r; - int ret; __u32 result; - struct feature_latency_monitor buf = {0,}; + int ret; const char *active_bucket_timer_threshold = "This is the value that loads the Active Bucket Timer Threshold."; @@ -12675,15 +12530,17 @@ int wdc_set_latency_monitor_feature(int argc, char **argv, struct command *cmd, OPT_END() }; - ret = parse_and_open(&dev, argc, argv, desc, opts); + ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret < 0) return ret; /* get capabilities */ - r = nvme_scan(NULL); - wdc_check_device(r, dev); - capabilities = wdc_get_drive_capabilities(r, dev); + ret = nvme_scan_topology(ctx, NULL, NULL); + if (ret || !wdc_check_device(ctx, hdl)) + return -1; + + capabilities = wdc_get_drive_capabilities(ctx, hdl); if (!(capabilities & WDC_DRIVE_CAP_SET_LATENCY_MONITOR)) { fprintf(stderr, "ERROR: WDC: unsupported device for this command\n"); @@ -12703,20 +12560,8 @@ int wdc_set_latency_monitor_feature(int argc, char **argv, struct command *cmd, buf.discard_debug_log = cfg.discard_debug_log; buf.latency_monitor_feature_enable = cfg.latency_monitor_feature_enable; - struct nvme_set_features_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .fid = NVME_FEAT_OCP_LATENCY_MONITOR, - .nsid = 0, - .cdw12 = 0, - .save = 1, - .data_len = sizeof(struct feature_latency_monitor), - .data = (void *)&buf, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - - ret = nvme_set_features(&args); + ret = nvme_set_features(hdl, 0, NVME_FEAT_OCP_LATENCY_MONITOR, 1, 0, 0, 0, + 0, 0, (void *)&buf, sizeof(struct feature_latency_monitor), &result); if (ret < 0) { perror("set-feature"); @@ -12937,22 +12782,19 @@ int run_wdc_cu_smart_log(int argc, char **argv, } -__u32 run_wdc_get_fw_cust_id(nvme_root_t r, struct nvme_dev *dev) +__u32 run_wdc_get_fw_cust_id(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl) { - return wdc_get_fw_cust_id(r, dev); + return wdc_get_fw_cust_id(ctx, hdl); } -bool run_wdc_nvme_check_supported_log_page(nvme_root_t r, - struct nvme_dev *dev, +bool run_wdc_nvme_check_supported_log_page(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl, __u8 log_id) { - return wdc_nvme_check_supported_log_page(r, - dev, - log_id, - 0); + return wdc_nvme_check_supported_log_page(ctx, hdl, log_id, 0); } -__u64 run_wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev) +__u64 run_wdc_get_drive_capabilities(struct nvme_global_ctx *ctx, struct nvme_transport_handle *hdl) { - return wdc_get_drive_capabilities(r, dev); + return wdc_get_drive_capabilities(ctx, hdl); } diff --git a/plugins/wdc/wdc-utils.c b/plugins/wdc/wdc-utils.c index 9988ff1d12..9fb708e0d7 100644 --- a/plugins/wdc/wdc-utils.c +++ b/plugins/wdc/wdc-utils.c @@ -165,20 +165,21 @@ void wdc_StrFormat(char *formatter, size_t fmt_sz, char *tofmt, size_t tofmtsz) } } -bool wdc_CheckUuidListSupport(struct nvme_dev *dev, struct nvme_id_uuid_list *uuid_list) +bool wdc_CheckUuidListSupport(struct nvme_transport_handle *hdl, + struct nvme_id_uuid_list *uuid_list) { - int err; struct nvme_id_ctrl ctrl; + int err; memset(&ctrl, 0, sizeof(struct nvme_id_ctrl)); - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) { fprintf(stderr, "ERROR: WDC: nvme_identify_ctrl() failed 0x%x\n", err); return false; } if ((ctrl.ctratt & NVME_CTRL_CTRATT_UUID_LIST) == NVME_CTRL_CTRATT_UUID_LIST) { - err = nvme_identify_uuid(dev_fd(dev), uuid_list); + err = nvme_identify_uuid_list(hdl, uuid_list); if (!err) return true; else if (err > 0) diff --git a/plugins/wdc/wdc-utils.h b/plugins/wdc/wdc-utils.h index 545f0675f8..1ea1ec49cc 100644 --- a/plugins/wdc/wdc-utils.h +++ b/plugins/wdc/wdc-utils.h @@ -77,4 +77,4 @@ int wdc_UtilsStrCompare(const char *pcSrc, const char *pcDst); int wdc_UtilsCreateDir(const char *path); int wdc_WriteToFile(const char *fileName, const char *buffer, unsigned int bufferLen); void wdc_StrFormat(char *formatter, size_t fmt_sz, char *tofmt, size_t tofmtsz); -bool wdc_CheckUuidListSupport(struct nvme_dev *dev, struct nvme_id_uuid_list *uuid_list); +bool wdc_CheckUuidListSupport(struct nvme_transport_handle *hdl, struct nvme_id_uuid_list *uuid_list); diff --git a/plugins/ymtc/ymtc-nvme.c b/plugins/ymtc/ymtc-nvme.c index 40013fe534..945b2315bf 100644 --- a/plugins/ymtc/ymtc-nvme.c +++ b/plugins/ymtc/ymtc-nvme.c @@ -21,7 +21,7 @@ static void get_ymtc_smart_info(struct nvme_ymtc_smart_log *smart, int index, u8 memcpy(raw_val, smart->itemArr[index].rawVal, RAW_SIZE); } -static int show_ymtc_smart_log(struct nvme_dev *dev, __u32 nsid, +static int show_ymtc_smart_log(struct nvme_transport_handle *hdl, __u32 nsid, struct nvme_ymtc_smart_log *smart) { struct nvme_id_ctrl ctrl; @@ -39,7 +39,7 @@ static int show_ymtc_smart_log(struct nvme_dev *dev, __u32 nsid, free(nm); return -1; } - err = nvme_identify_ctrl(dev_fd(dev), &ctrl); + err = nvme_identify_ctrl(hdl, &ctrl); if (err) { free(nm); free(raw); @@ -52,7 +52,7 @@ static int show_ymtc_smart_log(struct nvme_dev *dev, __u32 nsid, /* Table Title */ printf("Additional Smart Log for NVME device:%s namespace-id:%x\n", - dev->name, nsid); + nvme_transport_handle_get_name(hdl), nsid); /* Column Name*/ printf("key normalized raw\n"); /* 00 SI_VD_PROGRAM_FAIL */ @@ -116,14 +116,15 @@ static int show_ymtc_smart_log(struct nvme_dev *dev, __u32 nsid, return err; } -static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int get_additional_smart_log(int argc, char **argv, struct command *acmd, struct plugin *plugin) { struct nvme_ymtc_smart_log smart_log; char *desc = "Get Ymtc vendor specific additional smart log (optionally, for the specified namespace), and show it."; const char *namespace = "(optional) desired namespace"; const char *raw = "dump output in binary format"; - struct nvme_dev *dev; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct config { __u32 namespace_id; bool raw_binary; @@ -140,21 +141,20 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd, OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return err; - err = nvme_get_nsid_log(dev_fd(dev), false, 0xca, cfg.namespace_id, - sizeof(smart_log), &smart_log); + err = nvme_get_nsid_log(hdl, cfg.namespace_id, false, 0xca, + &smart_log, sizeof(smart_log)); if (!err) { if (!cfg.raw_binary) - err = show_ymtc_smart_log(dev, cfg.namespace_id, &smart_log); + err = show_ymtc_smart_log(hdl, cfg.namespace_id, &smart_log); else d_raw((unsigned char *)&smart_log, sizeof(smart_log)); } if (err > 0) nvme_show_status(err); - dev_close(dev); return err; } diff --git a/plugins/zns/zns.c b/plugins/zns/zns.c index 94336d781b..0b753b00f4 100644 --- a/plugins/zns/zns.c +++ b/plugins/zns/zns.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-or-later +#include #include #include #include @@ -56,7 +57,7 @@ static int print_zns_list_ns(nvme_ns_t ns) return err; } -static int print_zns_list(nvme_root_t nvme_root) +static int print_zns_list(struct nvme_global_ctx *ctx) { int err = 0; nvme_host_t h; @@ -64,7 +65,7 @@ static int print_zns_list(nvme_root_t nvme_root) nvme_ctrl_t c; nvme_ns_t n; - nvme_for_each_host(nvme_root, h) { + nvme_for_each_host(ctx, h) { nvme_for_each_subsystem(h, s) { nvme_subsystem_for_each_ns(s, n) { err = print_zns_list_ns(n); @@ -85,38 +86,42 @@ static int print_zns_list(nvme_root_t nvme_root) return err; } -static int list(int argc, char **argv, struct command *cmd, - struct plugin *plugin) +static int list(int argc, char **argv, struct command *acmd, struct plugin *plugin) { - int err = 0; - nvme_root_t nvme_root; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + int err; + + ctx = nvme_create_global_ctx(stdout, DEFAULT_LOGLEVEL); + if (ctx) { + fprintf(stderr, "Failed to create root object\n"); + return -ENOMEM; + } + + err = nvme_scan_topology(ctx, NULL, NULL); + if (err) { + fprintf(stderr, "Failed to scan nvme subsystems\n"); + return err; + } printf("%-21s %-20s %-40s %-9s %-26s %-16s %-8s\n", "Node", "SN", "Model", "Namespace", "Usage", "Format", "FW Rev"); printf("%-.21s %-.20s %-.40s %-.9s %-.26s %-.16s %-.8s\n", dash, dash, dash, dash, dash, dash, dash); - nvme_root = nvme_scan(NULL); - if (nvme_root) { - err = print_zns_list(nvme_root); - nvme_free_tree(nvme_root); - } else { - fprintf(stderr, "Failed to scan nvme subsystems\n"); - err = -errno; - } - - return err; + return print_zns_list(ctx); } -static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int id_ctrl(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send a ZNS specific Identify Controller command to\n" "the given device and report information about the specified\n" "controller in various formats."; - nvme_print_flags_t flags; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + struct nvme_passthru_cmd cmd; struct nvme_zns_id_ctrl ctrl; - struct nvme_dev *dev; + nvme_print_flags_t flags; int err = -1; struct config { @@ -132,27 +137,27 @@ static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *pl OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return errno; err = validate_output_format(cfg.output_format, &flags); if (err < 0) - goto close_dev; + return err; - err = nvme_zns_identify_ctrl(dev_fd(dev), &ctrl); + nvme_init_zns_identify_ctrl(&cmd, &ctrl); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) nvme_show_zns_id_ctrl(&ctrl, flags); else if (err > 0) nvme_show_status(err); else perror("zns identify controller"); -close_dev: - dev_close(dev); + return err; } -static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int id_ns(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Send a ZNS specific Identify Namespace command to\n" "the given device and report information about the specified\n" @@ -160,10 +165,11 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug const char *vendor_specific = "dump binary vendor fields"; const char *human_readable = "show identify in readable format"; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; nvme_print_flags_t flags; struct nvme_zns_id_ns ns; struct nvme_id_ns id_ns; - struct nvme_dev *dev; int err = -1; struct config { @@ -185,53 +191,54 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return errno; err = validate_output_format(cfg.output_format, &flags); if (err < 0) - goto close_dev; + return err; if (cfg.vendor_specific) flags |= VS; if (cfg.human_readable) flags |= VERBOSE; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); - goto close_dev; + return err; } } - err = nvme_identify_ns(dev_fd(dev), cfg.namespace_id, &id_ns); + err = nvme_identify_ns(hdl, cfg.namespace_id, &id_ns); if (err) { nvme_show_status(err); - goto close_dev; + return err; } - err = nvme_zns_identify_ns(dev_fd(dev), cfg.namespace_id, &ns); + err = nvme_zns_identify_ns(hdl, cfg.namespace_id, &ns); if (!err) nvme_show_zns_id_ns(&ns, &id_ns, flags); else if (err > 0) nvme_show_status(err); else perror("zns identify namespace"); -close_dev: - dev_close(dev); + return err; } -static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plugin *plugin, +static int zns_mgmt_send(int argc, char **argv, struct command *acmd, struct plugin *plugin, const char *desc, enum nvme_zns_send_action zsa) { const char *zslba = "starting LBA of the zone for this command"; const char *select_all = "send command to all zones"; const char *timeout = "timeout value, in milliseconds"; - struct nvme_dev *dev; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; int err, zcapc = 0; - char *command; + char *cmdstr; __u32 result; struct config { @@ -251,42 +258,31 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) - goto ret; + return err; - err = asprintf(&command, "%s-%s", plugin->name, cmd->name); + err = asprintf(&cmdstr, "%s-%s", plugin->name, acmd->name); if (err < 0) - goto close_dev; + return err; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); goto free; } } - struct nvme_zns_mgmt_send_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .slba = cfg.zslba, - .zsa = zsa, - .select_all = cfg.select_all, - .zsaso = 0, - .data_len = 0, - .data = NULL, - .timeout = cfg.timeout, - .result = &result, - }; - err = nvme_zns_mgmt_send(&args); + nvme_init_zns_mgmt_send(&cmd, cfg.namespace_id, cfg.zslba, zsa, + cfg.select_all, 0, 0, NULL, 0); + err = nvme_submit_admin_passthru(hdl, &cmd, &result); if (!err) { if (zsa == NVME_ZNS_ZSA_RESET) zcapc = result & 0x1; printf("%s: Success, action:%d zone:%"PRIx64" all:%d zcapc:%u nsid:%d\n", - command, zsa, (uint64_t)cfg.zslba, (int)cfg.select_all, + cmdstr, zsa, (uint64_t)cfg.zslba, (int)cfg.select_all, zcapc, cfg.namespace_id); } else if (err > 0) { nvme_show_status(err); @@ -294,21 +290,18 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug perror(desc); } free: - free(command); -close_dev: - dev_close(dev); -ret: + free(cmdstr); return err; } -static int get_zdes_bytes(int fd, __u32 nsid) +static int get_zdes_bytes(struct nvme_transport_handle *hdl, __u32 nsid) { struct nvme_zns_id_ns ns; struct nvme_id_ns id_ns; __u8 lbaf; int err; - err = nvme_identify_ns(fd, nsid, &id_ns); + err = nvme_identify_ns(hdl, nsid, &id_ns); if (err > 0) { nvme_show_status(err); return -1; @@ -317,7 +310,7 @@ static int get_zdes_bytes(int fd, __u32 nsid) return -1; } - err = nvme_zns_identify_ns(fd, nsid, &ns); + err = nvme_zns_identify_ns(hdl, nsid, &ns); if (err > 0) { nvme_show_status(err); return -1; @@ -330,7 +323,7 @@ static int get_zdes_bytes(int fd, __u32 nsid) return ns.lbafe[lbaf].zdes << 6; } -static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int zone_mgmt_send(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Zone Management Send"; const char *zslba = @@ -342,8 +335,10 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu const char *data = "optional file for data (default stdin)"; const char *timeout = "timeout value, in milliseconds"; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; int ffd = STDIN_FILENO, err = -1; - struct nvme_dev *dev; + struct nvme_passthru_cmd cmd; void *buf = NULL; struct config { @@ -371,41 +366,39 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return errno; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); - goto close_dev; + return err; } } if (!cfg.zsa) { fprintf(stderr, "zone send action must be specified\n"); - err = -EINVAL; - goto close_dev; + return -EINVAL; } if (cfg.zsa == NVME_ZNS_ZSA_SET_DESC_EXT) { if (!cfg.data_len) { - int data_len = get_zdes_bytes(dev_fd(dev), + int data_len = get_zdes_bytes(hdl, cfg.namespace_id); if (data_len == 0) { fprintf(stderr, "Zone Descriptor Extensions are not supported\n"); - goto close_dev; + return -EINVAL; } else if (data_len < 0) { - err = data_len; - goto close_dev; + return data_len; } cfg.data_len = data_len; } if (posix_memalign(&buf, getpagesize(), cfg.data_len)) { fprintf(stderr, "can not allocate feature payload\n"); - goto close_dev; + return -ENOMEM; } memset(buf, 0, cfg.data_len); @@ -425,25 +418,14 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu } else { if (cfg.file || cfg.data_len) { fprintf(stderr, "data, data_len only valid with set extended descriptor\n"); - err = -EINVAL; - goto close_dev; + return -EINVAL; } } - struct nvme_zns_mgmt_send_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .slba = cfg.zslba, - .zsa = cfg.zsa, - .select_all = cfg.select_all, - .zsaso = cfg.zsaso, - .data_len = cfg.data_len, - .data = buf, - .timeout = cfg.timeout, - .result = NULL, - }; - err = nvme_zns_mgmt_send(&args); + nvme_init_zns_mgmt_send(&cmd, cfg.namespace_id, cfg.zslba, cfg.zsa, + cfg.select_all, cfg.zsaso, 0, buf, + cfg.data_len); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) printf("zone-mgmt-send: Success, action:%d zone:%"PRIx64" all:%d nsid:%d\n", cfg.zsa, (uint64_t)cfg.zslba, (int)cfg.select_all, cfg.namespace_id); @@ -457,33 +439,33 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu close(ffd); free: free(buf); -close_dev: - dev_close(dev); return err; } -static int close_zone(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int close_zone(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Close zones\n"; - return zns_mgmt_send(argc, argv, cmd, plugin, desc, NVME_ZNS_ZSA_CLOSE); + return zns_mgmt_send(argc, argv, acmd, plugin, desc, NVME_ZNS_ZSA_CLOSE); } -static int finish_zone(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int finish_zone(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Finish zones\n"; - return zns_mgmt_send(argc, argv, cmd, plugin, desc, NVME_ZNS_ZSA_FINISH); + return zns_mgmt_send(argc, argv, acmd, plugin, desc, NVME_ZNS_ZSA_FINISH); } -static int open_zone(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int open_zone(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Open zones\n"; const char *zslba = "starting LBA of the zone for this command"; const char *zrwaa = "Allocate Zone Random Write Area to zone"; const char *select_all = "send command to all zones"; const char *timeout = "timeout value, in milliseconds"; - struct nvme_dev *dev; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; int err; struct config { @@ -506,57 +488,48 @@ static int open_zone(int argc, char **argv, struct command *cmd, struct plugin * OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return errno; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); - goto close_dev; + return err; } } - struct nvme_zns_mgmt_send_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .slba = cfg.zslba, - .zsa = NVME_ZNS_ZSA_OPEN, - .select_all = cfg.select_all, - .zsaso = cfg.zrwaa, - .data_len = 0, - .data = NULL, - .timeout = cfg.timeout, - .result = NULL, - }; - err = nvme_zns_mgmt_send(&args); + nvme_init_zns_mgmt_send(&cmd, cfg.namespace_id, cfg.zslba, + NVME_ZNS_ZSA_OPEN, cfg.select_all, cfg.zrwaa, 0, + NULL, 0); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) printf("zns-open-zone: Success zone slba:%"PRIx64" nsid:%d\n", (uint64_t)cfg.zslba, cfg.namespace_id); - else + else if (err > 0) nvme_show_status(err); -close_dev: - dev_close(dev); + else + perror("zns open-zone"); + return err; } -static int reset_zone(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int reset_zone(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Reset zones\n"; - return zns_mgmt_send(argc, argv, cmd, plugin, desc, NVME_ZNS_ZSA_RESET); + return zns_mgmt_send(argc, argv, acmd, plugin, desc, NVME_ZNS_ZSA_RESET); } -static int offline_zone(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int offline_zone(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Offline zones\n"; - return zns_mgmt_send(argc, argv, cmd, plugin, desc, NVME_ZNS_ZSA_OFFLINE); + return zns_mgmt_send(argc, argv, acmd, plugin, desc, NVME_ZNS_ZSA_OFFLINE); } -static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int set_zone_desc(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Set Zone Descriptor Extension\n"; const char *zslba = "starting LBA of the zone for this command"; @@ -564,8 +537,10 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug const char *data = "optional file for zone extension data (default stdin)"; const char *timeout = "timeout value, in milliseconds"; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; int ffd = STDIN_FILENO, err; - struct nvme_dev *dev; void *buf = NULL; int data_len; @@ -588,33 +563,30 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return errno; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); - goto close_dev; + return err; } } - data_len = get_zdes_bytes(dev_fd(dev), cfg.namespace_id); + data_len = get_zdes_bytes(hdl, cfg.namespace_id); if (!data_len || data_len < 0) { fprintf(stderr, "zone format does not provide descriptor extension\n"); - errno = EINVAL; - err = -1; - goto close_dev; + return -EINVAL; } buf = calloc(1, data_len); if (!buf) { perror("could not alloc memory for zone desc"); - err = -ENOMEM; - goto close_dev; + return -ENOMEM; } if (cfg.file) { @@ -632,20 +604,10 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug goto close_ffd; } - struct nvme_zns_mgmt_send_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .slba = cfg.zslba, - .zsa = NVME_ZNS_ZSA_SET_DESC_EXT, - .select_all = 0, - .zsaso = cfg.zrwaa, - .data_len = data_len, - .data = buf, - .timeout = cfg.timeout, - .result = NULL, - }; - err = nvme_zns_mgmt_send(&args); + nvme_init_zns_mgmt_send(&cmd, cfg.namespace_id, cfg.zslba, + NVME_ZNS_ZSA_SET_DESC_EXT, 0, cfg.zrwaa, 0, buf, + data_len); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) printf("set-zone-desc: Success, zone:%"PRIx64" nsid:%d\n", (uint64_t)cfg.zslba, cfg.namespace_id); @@ -658,18 +620,19 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug close(ffd); free: free(buf); -close_dev: - dev_close(dev); + return err; } -static int zrwa_flush_zone(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int zrwa_flush_zone(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Flush Explicit ZRWA Range"; const char *slba = "LBA to flush up to"; const char *timeout = "timeout value, in milliseconds"; - struct nvme_dev *dev; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; int err; struct config { @@ -687,43 +650,33 @@ static int zrwa_flush_zone(int argc, char **argv, struct command *cmd, struct pl OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return errno; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); - goto close_dev; + return err; } } - struct nvme_zns_mgmt_send_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .slba = cfg.lba, - .zsa = NVME_ZNS_ZSA_ZRWA_FLUSH, - .select_all = 0, - .zsaso = 0, - .data_len = 0, - .data = NULL, - .timeout = cfg.timeout, - .result = NULL, - }; - err = nvme_zns_mgmt_send(&args); + nvme_init_zns_mgmt_send(&cmd, cfg.namespace_id, cfg.lba, + NVME_ZNS_ZSA_ZRWA_FLUSH, 0, 0, 0, NULL, 0); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) printf("zrwa-flush-zone: Success, lba:%"PRIx64" nsid:%d\n", (uint64_t)cfg.lba, cfg.namespace_id); - else + else if (err > 0) nvme_show_status(err); -close_dev: - dev_close(dev); + else + perror("zns zrwa-flush-zone"); + return err; } -static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int zone_mgmt_recv(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Zone Management Receive"; const char *zslba = "starting LBA of the zone"; @@ -732,8 +685,10 @@ static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plu const char *partial = "Zone Receive Action Specific Features(Partial Report)"; const char *data_len = "length of data in bytes"; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; - struct nvme_dev *dev; void *data = NULL; int err = -1; @@ -762,50 +717,37 @@ static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plu OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return errno; err = validate_output_format(cfg.output_format, &flags); if (err < 0) - goto close_dev; + return err; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); - goto close_dev; + return err; } } if (cfg.zra == NVME_ZNS_ZRA_REPORT_ZONES && !cfg.data_len) { fprintf(stderr, "error: data len is needed for NVME_ZRA_ZONE_REPORT\n"); - err = -EINVAL; - goto close_dev; + return -EINVAL; } if (cfg.data_len) { data = calloc(1, cfg.data_len); if (!data) { perror("could not alloc memory for zone mgmt receive data"); - err = -ENOMEM; - goto close_dev; + return -ENOMEM; } } - struct nvme_zns_mgmt_recv_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .slba = cfg.zslba, - .zra = cfg.zra, - .zrasf = cfg.zrasf, - .zras_feat = cfg.partial, - .data_len = cfg.data_len, - .data = data, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = NULL, - }; - err = nvme_zns_mgmt_recv(&args); + nvme_init_zns_mgmt_recv(&cmd, cfg.namespace_id, cfg.zslba, cfg.zra, + cfg.zrasf, cfg.partial, data, cfg.data_len); + err = nvme_submit_admin_passthru(hdl, &cmd, NULL); if (!err) printf("zone-mgmt-recv: Success, action:%d zone:%"PRIx64" nsid:%d\n", cfg.zra, (uint64_t)cfg.zslba, cfg.namespace_id); @@ -815,12 +757,11 @@ static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plu perror("zns zone-mgmt-recv"); free(data); -close_dev: - dev_close(dev); + return err; } -static int report_zones(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int report_zones(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve the Report Zones data structure"; const char *zslba = "starting LBA of the zone"; @@ -830,12 +771,14 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi const char *part = "set to use the partial report"; const char *verbose = "show report zones verbosity"; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; + struct nvme_zone_report *report, *buff; + struct nvme_passthru_cmd cmd; nvme_print_flags_t flags; int zdes = 0, err = -1; - struct nvme_dev *dev; __u32 report_size; - struct nvme_zone_report *report, *buff; - _cleanup_huge_ struct nvme_mem_huge mh = { 0, }; unsigned int nr_zones_chunks = 1024, /* 1024 entries * 64 bytes per entry = 64k byte transfer */ nr_zones_retrieved = 0, @@ -877,59 +820,55 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return errno; err = validate_output_format(cfg.output_format, &flags); if (err < 0) - goto close_dev; + return err; if (cfg.verbose) flags |= VERBOSE; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); - goto close_dev; + return err; } } if (cfg.extended) { - zdes = get_zdes_bytes(dev_fd(dev), cfg.namespace_id); - if (zdes < 0) { - err = zdes; - goto close_dev; - } + zdes = get_zdes_bytes(hdl, cfg.namespace_id); + if (zdes < 0) + return zdes; } - err = nvme_identify_ns(dev_fd(dev), cfg.namespace_id, &id_ns); + err = nvme_identify_ns(hdl, cfg.namespace_id, &id_ns); if (err) { nvme_show_status(err); - goto close_dev; + return err; } - err = nvme_zns_identify_ns(dev_fd(dev), cfg.namespace_id, &id_zns); + err = nvme_zns_identify_ns(hdl, cfg.namespace_id, &id_zns); if (!err) { /* get zsze field from zns id ns data - needed for offset calculation */ nvme_id_ns_flbas_to_lbaf_inuse(id_ns.flbas, &lbaf); zsze = le64_to_cpu(id_zns.lbafe[lbaf].zsze); } else { nvme_show_status(err); - goto close_dev; + return err; } log_len = sizeof(struct nvme_zone_report); buff = calloc(1, log_len); if (!buff) { - err = -ENOMEM; - goto close_dev; + return -ENOMEM; } - err = nvme_zns_report_zones(dev_fd(dev), cfg.namespace_id, 0, - cfg.state, false, false, - log_len, buff, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + nvme_init_zns_report_zones(&cmd, cfg.namespace_id, 0, cfg.state, false, + false, buff, log_len); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); if (err > 0) { nvme_show_status(err); goto free_buff; @@ -953,8 +892,7 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi report = nvme_alloc_huge(report_size, &mh); if (!report) { perror("alloc"); - err = -ENOMEM; - goto close_dev; + return -ENOMEM; } offset = cfg.zslba; @@ -970,15 +908,15 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi log_len = sizeof(struct nvme_zone_report) + ((sizeof(struct nvme_zns_desc) * nr_zones_chunks) + (nr_zones_chunks * zdes)); } - err = nvme_zns_report_zones(dev_fd(dev), cfg.namespace_id, - offset, - cfg.state, cfg.extended, - cfg.partial, log_len, report, - NVME_DEFAULT_IOCTL_TIMEOUT, NULL); + nvme_init_zns_report_zones(&cmd, cfg.namespace_id, offset, + cfg.state, cfg.extended, cfg.partial, + report, log_len); + err = nvme_submit_io_passthru(hdl, &cmd, NULL); if (err > 0) { nvme_show_status(err); break; } + // QUESTION: should we also check for < 0 here? if (!err) nvme_show_zns_report_zones(report, nr_zones_chunks, @@ -992,12 +930,11 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi free_buff: free(buff); -close_dev: - dev_close(dev); + return err; } -static int zone_append(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int zone_append(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "The zone append command is used to write to a zone\n" "using the slba of the zone, and the write will be appended from the\n" @@ -1009,21 +946,21 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin const char *fua = "force unit access"; const char *prinfo = "protection information action and checks field"; const char *piremap = "protection information remap (for type 1 PI)"; - const char *ref_tag = "reference tag for end-to-end PI"; - const char *lbat = "logical block application tag for end-to-end PI"; - const char *lbatm = "logical block application tag mask for end-to-end PI"; const char *metadata_size = "size of metadata in bytes"; const char *data_size = "size of data in bytes"; const char *latency = "output latency statistics"; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; int err = -1, dfd = STDIN_FILENO, mfd = STDIN_FILENO; + struct timeval start_time, end_time; unsigned int lba_size, meta_size; void *buf = NULL, *mbuf = NULL; + struct nvme_passthru_cmd64 cmd; __u16 nblocks, control = 0; - struct nvme_dev *dev; - __u64 result; + __u16 cev = 0, dspec = 0; __u8 lba_index; - struct timeval start_time, end_time; + __u64 result; struct nvme_id_ns ns; @@ -1036,9 +973,6 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin bool limited_retry; bool fua; __u32 namespace_id; - __u64 ref_tag; - __u16 lbat; - __u16 lbatm; __u8 prinfo; bool piremap; bool latency; @@ -1055,37 +989,33 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin OPT_FILE("metadata", 'M', &cfg.metadata, metadata), OPT_FLAG("limited-retry", 'l', &cfg.limited_retry, limited_retry), OPT_FLAG("force-unit-access", 'f', &cfg.fua, fua), - OPT_SUFFIX("ref-tag", 'r', &cfg.ref_tag, ref_tag), - OPT_SHRT("app-tag-mask", 'm', &cfg.lbatm, lbatm), - OPT_SHRT("app-tag", 'a', &cfg.lbat, lbat), OPT_BYTE("prinfo", 'p', &cfg.prinfo, prinfo), OPT_FLAG("piremap", 'P', &cfg.piremap, piremap), OPT_FLAG("latency", 't', &cfg.latency, latency), OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return errno; if (!cfg.data_size) { fprintf(stderr, "Append size not provided\n"); - errno = EINVAL; - goto close_dev; + return -EINVAL; } if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); - goto close_dev; + return err;; } } - err = nvme_identify_ns(dev_fd(dev), cfg.namespace_id, &ns); + err = nvme_identify_ns(hdl, cfg.namespace_id, &ns); if (err) { nvme_show_status(err); - goto close_dev; + return err; } nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index); @@ -1094,8 +1024,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin fprintf(stderr, "Data size:%#"PRIx64" not aligned to lba size:%#x\n", (uint64_t)cfg.data_size, lba_size); - errno = EINVAL; - goto close_dev; + return -EINVAL; } meta_size = ns.lbaf[lba_index].ms; @@ -1104,21 +1033,19 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin fprintf(stderr, "Metadata size:%#"PRIx64" not aligned to metadata size:%#x\n", (uint64_t)cfg.metadata_size, meta_size); - errno = EINVAL; - goto close_dev; + return -EINVAL; } if (cfg.prinfo > 0xf) { fprintf(stderr, "Invalid value for prinfo:%#x\n", cfg.prinfo); - errno = EINVAL; - goto close_dev; + return -EINVAL; } if (cfg.data) { dfd = open(cfg.data, O_RDONLY); if (dfd < 0) { perror(cfg.data); - goto close_dev; + return -errno; } } @@ -1169,26 +1096,11 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin if (cfg.piremap) control |= NVME_IO_ZNS_APPEND_PIREMAP; - struct nvme_zns_append_args args = { - .args_size = sizeof(args), - .fd = dev_fd(dev), - .nsid = cfg.namespace_id, - .zslba = cfg.zslba, - .nlb = nblocks, - .control = control, - .ilbrt_u64 = cfg.ref_tag, - .lbat = cfg.lbat, - .lbatm = cfg.lbatm, - .data_len = cfg.data_size, - .data = buf, - .metadata_len = cfg.metadata_size, - .metadata = mbuf, - .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, - .result = &result, - }; - gettimeofday(&start_time, NULL); - err = nvme_zns_append(&args); + nvme_init_zns_append(&cmd, cfg.namespace_id, cfg.zslba, nblocks, + control, cev, dspec, buf, cfg.data_size, mbuf, + cfg.metadata_size); + err = nvme_submit_admin_passthru64(hdl, &cmd, &result); gettimeofday(&end_time, NULL); if (cfg.latency) printf(" latency: zone append: %llu us\n", @@ -1211,19 +1123,19 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin close_dfd: if (cfg.data) close(dfd); -close_dev: - dev_close(dev); + return err; } -static int changed_zone_list(int argc, char **argv, struct command *cmd, struct plugin *plugin) +static int changed_zone_list(int argc, char **argv, struct command *acmd, struct plugin *plugin) { const char *desc = "Retrieve Changed Zone log for the given device"; const char *rae = "retain an asynchronous event"; + _cleanup_nvme_global_ctx_ struct nvme_global_ctx *ctx = NULL; + _cleanup_nvme_transport_handle_ struct nvme_transport_handle *hdl = NULL; struct nvme_zns_changed_zone_log log; nvme_print_flags_t flags; - struct nvme_dev *dev; int err = -1; struct config { @@ -1243,23 +1155,23 @@ static int changed_zone_list(int argc, char **argv, struct command *cmd, struct OPT_END() }; - err = parse_and_open(&dev, argc, argv, desc, opts); + err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) return errno; err = validate_output_format(cfg.output_format, &flags); if (err < 0) - goto close_dev; + return err; if (!cfg.namespace_id) { - err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id); + err = nvme_get_nsid(hdl, &cfg.namespace_id); if (err < 0) { perror("get-namespace-id"); - goto close_dev; + return err; } } - err = nvme_get_log_zns_changed_zones(dev_fd(dev), cfg.namespace_id, + err = nvme_get_log_zns_changed_zones(hdl, cfg.namespace_id, cfg.rae, &log); if (!err) nvme_show_zns_changed(&log, flags); @@ -1268,7 +1180,5 @@ static int changed_zone_list(int argc, char **argv, struct command *cmd, struct else perror("zns changed-zone-list"); -close_dev: - dev_close(dev); return err; } diff --git a/subprojects/libnvme.wrap b/subprojects/libnvme.wrap index 8aee6de194..3ad72ee728 100644 --- a/subprojects/libnvme.wrap +++ b/subprojects/libnvme.wrap @@ -1,7 +1,6 @@ [wrap-git] -url = https://github.com/linux-nvme/libnvme.git -revision = a6497f6e8cb3bc3607e4a772b648a7887b0ab875 +url = https://github.com/nvme-experiments/libnvme.git +revision = libnvme3 [provide] libnvme = libnvme_dep -libnvme-mi = libnvme_mi_dep diff --git a/types.h b/types.h new file mode 100644 index 0000000000..2b976d046f --- /dev/null +++ b/types.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef TYPES_H +#define TYPES_H + +#include "nvme/types.h" + +/** + * struct nvme_get_log_args - Arguments for the NVMe Admin Get Log command + * @nsid: Namespace identifier, if applicable + * @rae: Retain asynchronous events + * @lsp: Log specific field + * @lid: Log page identifier, see &enum nvme_cmd_get_log_lid for known + * values + * @lsi: Log Specific Identifier + * @csi: Command set identifier, see &enum nvme_csi for known values + * @ot: Offset Type; if set @lpo specifies the index into the list + * of data structures, otherwise @lpo specifies the byte offset + * into the log page. + * @uidx: UUID selection, if supported + * @lpo: Log page offset for partial log transfers + * @log: User space destination address to transfer the data + * @len: Length of provided user buffer to hold the log data in bytes + * @result: The command completion result from CQE dword0 + */ +struct nvme_get_log_args { + __u32 nsid; + bool rae; + __u8 lsp; + enum nvme_cmd_get_log_lid lid; + __u16 lsi; + enum nvme_csi csi; + bool ot; + __u8 uidx; + __u64 lpo; + void *log; + __u32 len; + __u32 *result; +}; + +#endif diff --git a/util/cleanup.h b/util/cleanup.h index ff26cda3e9..bb11d32842 100644 --- a/util/cleanup.h +++ b/util/cleanup.h @@ -36,11 +36,11 @@ static inline void cleanup_fd(int *fd) } #define _cleanup_fd_ __cleanup__(cleanup_fd) -static inline void cleanup_nvme_root(nvme_root_t *r) +static inline void cleanup_nvme_global_ctx(struct nvme_global_ctx **ctx) { - nvme_free_tree(*r); + nvme_free_global_ctx(*ctx); } -#define _cleanup_nvme_root_ __cleanup__(cleanup_nvme_root) +#define _cleanup_nvme_global_ctx_ __cleanup__(cleanup_nvme_global_ctx) static inline DEFINE_CLEANUP_FUNC(cleanup_nvme_ctrl, nvme_ctrl_t, nvme_free_ctrl) #define _cleanup_nvme_ctrl_ __cleanup__(cleanup_nvme_ctrl)