summaryrefslogtreecommitdiffstats
path: root/plugins/solidigm/solidigm-get-drive-info.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/solidigm/solidigm-get-drive-info.c')
-rw-r--r--plugins/solidigm/solidigm-get-drive-info.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/plugins/solidigm/solidigm-get-drive-info.c b/plugins/solidigm/solidigm-get-drive-info.c
new file mode 100644
index 0000000..21f59bb
--- /dev/null
+++ b/plugins/solidigm/solidigm-get-drive-info.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 Solidigm.
+ *
+ * Authors: leonardo.da.cunha@solidigm.com
+ */
+
+#include <errno.h>
+#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)
+{
+ _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";
+ enum nvme_print_flags flags;
+ nvme_root_t r;
+ nvme_ctrl_t c;
+ nvme_ns_t n;
+ struct nvme_id_ns ns = { 0 };
+ __u8 flbaf_inUse;
+ __u16 lba_size;
+ __u16 ftl_unit_size;
+ int err;
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("output-format", 'o', &output_format, "normal|json"),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ err = validate_output_format(output_format, &flags);
+ if ((err < 0) || !(flags == NORMAL || flags == JSON)) {
+ nvme_show_error("Invalid output format");
+ 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_ns_identify(n, &ns);
+ if (err) {
+ nvme_show_error("identify namespace: %s", nvme_strerror(errno));
+ return err;
+ }
+
+ if (!(ns.nsfeat & 0x10)) {
+ nvme_show_error("solidigm-vs-drive-info: performance options not available");
+ return -EINVAL;
+ }
+
+ nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &flbaf_inUse);
+ lba_size = 1 << ns.lbaf[flbaf_inUse].ds;
+ ftl_unit_size = (le16_to_cpu(ns.npwg) + 1) * lba_size / 1024;
+
+ if (flags == JSON) {
+ struct json_object *root = json_create_object();
+
+ json_object_add_value_int(root, FTL_unit_size_str, ftl_unit_size);
+ json_print_object(root, NULL);
+ printf("\n");
+ json_free_object(root);
+ } else {
+ printf("%s: %d\n", FTL_unit_size_str, ftl_unit_size);
+ }
+
+ return err;
+}